play around with Scintilla and Lexilla

This commit is contained in:
2024-07-02 23:47:26 +08:00
parent d7c71f41b2
commit 727a2ec214
992 changed files with 281111 additions and 195 deletions

View File

@ -0,0 +1,32 @@
README for building of Scintilla on Qt
There are two different Scintilla libraries that can be produced:
ScintillaEditBase
A basic widget callable from C++ which is small and can be used just as is
or with higher level functionality added.
ScintillaEdit
A more complete C++ widget with a method for every Scintilla API and a
secondary API allowing direct access to document objects.
Building a library
ScintillaEditBase can be built without performing any generation steps.
The ScintillaEditBase/ScintillaEditBase.pro project can be loaded into
Qt Creator and the "Build All" command performed.
Alternatively, run "qmake" to build make files and then use the platform
make to build. Most commonly, use "make" on Unix and "nmake"
on Windows.
On Linux, qmake may be called qmake-qt5 or qmake-qt4.
ScintillaEdit requires a generation command be run first. From the
ScintillaEdit directory:
python WidgetGen.py
After the generation command has run, the ScintillaEdit.h and
ScintillaEdit.cpp files will have been populated with the Scintilla API
methods.
To build, use Qt Creator or qmake and make as for ScintillaEditBase.

View File

@ -0,0 +1,277 @@
// @file ScintillaDocument.cpp
// Wrapper for Scintilla document object so it can be manipulated independently.
// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
#include <stdexcept>
#include <string_view>
#include <vector>
#include <map>
#include <set>
#include <optional>
#include <memory>
#include "ScintillaTypes.h"
#include "ScintillaMessages.h"
#include "ScintillaStructures.h"
#include "ScintillaDocument.h"
#include "Debugging.h"
#include "Geometry.h"
#include "Platform.h"
#include "ILoader.h"
#include "ILexer.h"
#include "Scintilla.h"
#include "CharacterCategoryMap.h"
#include "Position.h"
#include "UniqueString.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "ContractionState.h"
#include "CellBuffer.h"
#include "KeyMap.h"
#include "Indicator.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "CaseFolder.h"
#include "Document.h"
using namespace Scintilla;
using namespace Scintilla::Internal;
class WatcherHelper : public DocWatcher {
ScintillaDocument *owner;
public:
explicit WatcherHelper(ScintillaDocument *owner_);
void NotifyModifyAttempt(Document *doc, void *userData) override;
void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) override;
void NotifyModified(Document *doc, DocModification mh, void *userData) override;
void NotifyDeleted(Document *doc, void *userData) noexcept override;
void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endPos) override;
void NotifyErrorOccurred(Document *doc, void *userData, Status status) override;
};
WatcherHelper::WatcherHelper(ScintillaDocument *owner_) : owner(owner_) {
}
void WatcherHelper::NotifyModifyAttempt(Document *, void *) {
emit owner->modify_attempt();
}
void WatcherHelper::NotifySavePoint(Document *, void *, bool atSavePoint) {
emit owner->save_point(atSavePoint);
}
void WatcherHelper::NotifyModified(Document *, DocModification mh, void *) {
int length = mh.length;
if (!mh.text)
length = 0;
QByteArray ba = QByteArray::fromRawData(mh.text, length);
emit owner->modified(mh.position, static_cast<int>(mh.modificationType), ba, length,
mh.linesAdded, mh.line, static_cast<int>(mh.foldLevelNow), static_cast<int>(mh.foldLevelPrev));
}
void WatcherHelper::NotifyDeleted(Document *, void *) noexcept {
}
void WatcherHelper::NotifyStyleNeeded(Document *, void *, Sci::Position endPos) {
emit owner->style_needed(endPos);
}
void WatcherHelper::NotifyErrorOccurred(Document *, void *, Status status) {
emit owner->error_occurred(static_cast<int>(status));
}
ScintillaDocument::ScintillaDocument(QObject *parent, void *pdoc_) :
QObject(parent), pdoc(static_cast<Scintilla::IDocumentEditable *>(pdoc_)), docWatcher(nullptr) {
if (!pdoc) {
pdoc = new Document(DocumentOption::Default);
}
docWatcher = new WatcherHelper(this);
(static_cast<Document *>(pdoc))->AddRef();
(static_cast<Document *>(pdoc))->AddWatcher(docWatcher, pdoc);
}
ScintillaDocument::~ScintillaDocument() {
Document *doc = static_cast<Document *>(pdoc);
if (doc) {
doc->RemoveWatcher(docWatcher, doc);
doc->Release();
}
pdoc = nullptr;
delete docWatcher;
docWatcher = nullptr;
}
void *ScintillaDocument::pointer() {
return pdoc;
}
int ScintillaDocument::line_from_position(int pos) {
return (static_cast<Document *>(pdoc))->LineFromPosition(pos);
}
bool ScintillaDocument::is_cr_lf(int pos) {
return (static_cast<Document *>(pdoc))->IsCrLf(pos);
}
bool ScintillaDocument::delete_chars(int pos, int len) {
return (static_cast<Document *>(pdoc))->DeleteChars(pos, len);
}
int ScintillaDocument::undo() {
return (static_cast<Document *>(pdoc))->Undo();
}
int ScintillaDocument::redo() {
return (static_cast<Document *>(pdoc))->Redo();
}
bool ScintillaDocument::can_undo() {
return (static_cast<Document *>(pdoc))->CanUndo();
}
bool ScintillaDocument::can_redo() {
return (static_cast<Document *>(pdoc))->CanRedo();
}
void ScintillaDocument::delete_undo_history() {
(static_cast<Document *>(pdoc))->DeleteUndoHistory();
}
bool ScintillaDocument::set_undo_collection(bool collect_undo) {
return (static_cast<Document *>(pdoc))->SetUndoCollection(collect_undo);
}
bool ScintillaDocument::is_collecting_undo() {
return (static_cast<Document *>(pdoc))->IsCollectingUndo();
}
void ScintillaDocument::begin_undo_action(bool coalesceWithPrior) {
(static_cast<Document *>(pdoc))->BeginUndoAction(coalesceWithPrior);
}
void ScintillaDocument::end_undo_action() {
(static_cast<Document *>(pdoc))->EndUndoAction();
}
void ScintillaDocument::set_save_point() {
(static_cast<Document *>(pdoc))->SetSavePoint();
}
bool ScintillaDocument::is_save_point() {
return (static_cast<Document *>(pdoc))->IsSavePoint();
}
void ScintillaDocument::set_read_only(bool read_only) {
(static_cast<Document *>(pdoc))->SetReadOnly(read_only);
}
bool ScintillaDocument::is_read_only() {
return (static_cast<Document *>(pdoc))->IsReadOnly();
}
void ScintillaDocument::insert_string(int position, QByteArray &str) {
(static_cast<Document *>(pdoc))->InsertString(position, str.data(), str.size());
}
QByteArray ScintillaDocument::get_char_range(int position, int length) {
const Document *doc = static_cast<Document *>(pdoc);
if (position < 0 || length <= 0 || position + length > doc->Length())
return QByteArray();
QByteArray ba(length, '\0');
doc->GetCharRange(ba.data(), position, length);
return ba;
}
char ScintillaDocument::style_at(int position) {
return (static_cast<Document *>(pdoc))->StyleAt(position);
}
int ScintillaDocument::line_start(int lineno) {
return (static_cast<Document *>(pdoc))->LineStart(lineno);
}
int ScintillaDocument::line_end(int lineno) {
return (static_cast<Document *>(pdoc))->LineEnd(lineno);
}
int ScintillaDocument::line_end_position(int pos) {
return (static_cast<Document *>(pdoc))->LineEndPosition(pos);
}
int ScintillaDocument::length() {
return (static_cast<Document *>(pdoc))->Length();
}
int ScintillaDocument::lines_total() {
return (static_cast<Document *>(pdoc))->LinesTotal();
}
void ScintillaDocument::start_styling(int position) {
(static_cast<Document *>(pdoc))->StartStyling(position);
}
bool ScintillaDocument::set_style_for(int length, char style) {
return (static_cast<Document *>(pdoc))->SetStyleFor(length, style);
}
int ScintillaDocument::get_end_styled() {
return (static_cast<Document *>(pdoc))->GetEndStyled();
}
void ScintillaDocument::ensure_styled_to(int position) {
(static_cast<Document *>(pdoc))->EnsureStyledTo(position);
}
void ScintillaDocument::set_current_indicator(int indic) {
(static_cast<Document *>(pdoc))->decorations->SetCurrentIndicator(indic);
}
void ScintillaDocument::decoration_fill_range(int position, int value, int fillLength) {
(static_cast<Document *>(pdoc))->DecorationFillRange(position, value, fillLength);
}
int ScintillaDocument::decorations_value_at(int indic, int position) {
return (static_cast<Document *>(pdoc))->decorations->ValueAt(indic, position);
}
int ScintillaDocument::decorations_start(int indic, int position) {
return (static_cast<Document *>(pdoc))->decorations->Start(indic, position);
}
int ScintillaDocument::decorations_end(int indic, int position) {
return (static_cast<Document *>(pdoc))->decorations->End(indic, position);
}
int ScintillaDocument::get_code_page() {
return (static_cast<Document *>(pdoc))->CodePage();
}
void ScintillaDocument::set_code_page(int code_page) {
(static_cast<Document *>(pdoc))->dbcsCodePage = code_page;
}
int ScintillaDocument::get_eol_mode() {
return static_cast<int>((static_cast<Document *>(pdoc))->eolMode);
}
void ScintillaDocument::set_eol_mode(int eol_mode) {
(static_cast<Document *>(pdoc))->eolMode = static_cast<EndOfLine>(eol_mode);
}
int ScintillaDocument::move_position_outside_char(int pos, int move_dir, bool check_line_end) {
return (static_cast<Document *>(pdoc))->MovePositionOutsideChar(pos, move_dir, check_line_end);
}
int ScintillaDocument::get_character(int pos) {
return (static_cast<Document *>(pdoc))->GetCharacterAndWidth(pos, nullptr);
}

View File

@ -0,0 +1,95 @@
// @file ScintillaDocument.h
// Wrapper for Scintilla document object so it can be manipulated independently.
// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
#ifndef SCINTILLADOCUMENT_H
#define SCINTILLADOCUMENT_H
#include <QObject>
class WatcherHelper;
#ifndef EXPORT_IMPORT_API
#ifdef WIN32
#ifdef MAKING_LIBRARY
#define EXPORT_IMPORT_API __declspec(dllexport)
#else
// Defining dllimport upsets moc
#define EXPORT_IMPORT_API __declspec(dllimport)
//#define EXPORT_IMPORT_API
#endif
#else
#define EXPORT_IMPORT_API
#endif
#endif
// Forward declaration
namespace Scintilla {
class IDocumentEditable;
}
class EXPORT_IMPORT_API ScintillaDocument : public QObject
{
Q_OBJECT
Scintilla::IDocumentEditable *pdoc;
WatcherHelper *docWatcher;
public:
explicit ScintillaDocument(QObject *parent = 0, void *pdoc_=0);
virtual ~ScintillaDocument();
void *pointer();
int line_from_position(int pos);
bool is_cr_lf(int pos);
bool delete_chars(int pos, int len);
int undo();
int redo();
bool can_undo();
bool can_redo();
void delete_undo_history();
bool set_undo_collection(bool collect_undo);
bool is_collecting_undo();
void begin_undo_action(bool coalesceWithPrior = false);
void end_undo_action();
void set_save_point();
bool is_save_point();
void set_read_only(bool read_only);
bool is_read_only();
void insert_string(int position, QByteArray &str);
QByteArray get_char_range(int position, int length);
char style_at(int position);
int line_start(int lineno);
int line_end(int lineno);
int line_end_position(int pos);
int length();
int lines_total();
void start_styling(int position);
bool set_style_for(int length, char style);
int get_end_styled();
void ensure_styled_to(int position);
void set_current_indicator(int indic);
void decoration_fill_range(int position, int value, int fillLength);
int decorations_value_at(int indic, int position);
int decorations_start(int indic, int position);
int decorations_end(int indic, int position);
int get_code_page();
void set_code_page(int code_page);
int get_eol_mode();
void set_eol_mode(int eol_mode);
int move_position_outside_char(int pos, int move_dir, bool check_line_end);
int get_character(int pos); // Calls GetCharacterAndWidth(pos, NULL)
signals:
void modify_attempt();
void save_point(bool atSavePoint);
void modified(int position, int modification_type, const QByteArray &text, int length,
int linesAdded, int line, int foldLevelNow, int foldLevelPrev);
void style_needed(int pos);
void error_occurred(int status);
friend class ::WatcherHelper;
};
#endif /* SCINTILLADOCUMENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
// @file ScintillaEdit.cpp
// Extended version of ScintillaEditBase with a method for each API
// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
#include "ScintillaEdit.h"
using namespace Scintilla;
ScintillaEdit::ScintillaEdit(QWidget *parent) : ScintillaEditBase(parent) {
}
ScintillaEdit::~ScintillaEdit() {
}
QByteArray ScintillaEdit::TextReturner(int message, uptr_t wParam) const {
// While Scintilla can return strings longer than maximum(int), QByteArray uses int size
const int length = static_cast<int>(send(message, wParam, 0));
QByteArray ba(length + 1, '\0');
send(message, wParam, (sptr_t)ba.data());
// Remove extra NULs
if (ba.at(ba.size()-1) == 0)
ba.chop(1);
return ba;
}
QPair<int, int>ScintillaEdit::find_text(int flags, const char *text, int cpMin, int cpMax) {
struct Sci_TextToFind ft = {{0, 0}, 0, {0, 0}};
ft.chrg.cpMin = cpMin;
ft.chrg.cpMax = cpMax;
ft.chrgText.cpMin = cpMin;
ft.chrgText.cpMax = cpMax;
ft.lpstrText = text;
int start = send(SCI_FINDTEXT, flags, (uptr_t) (&ft));
return QPair<int,int>(start, ft.chrgText.cpMax);
}
QByteArray ScintillaEdit::get_text_range(int start, int end) {
if (start > end)
start = end;
int length = end-start;
QByteArray ba(length+1, '\0');
struct Sci_TextRange tr = {{start, end}, ba.data()};
send(SCI_GETTEXTRANGE, 0, (sptr_t)&tr);
ba.chop(1); // Remove extra NUL
return ba;
}
ScintillaDocument *ScintillaEdit::get_doc() {
return new ScintillaDocument(0, (void *)send(SCI_GETDOCPOINTER, 0, 0));
}
void ScintillaEdit::set_doc(ScintillaDocument *pdoc_) {
send(SCI_SETDOCPOINTER, 0, (sptr_t)(pdoc_->pointer()));
}
long ScintillaEdit::format_range(bool draw, QPaintDevice* target, QPaintDevice* measure,
const QRect& print_rect, const QRect& page_rect,
long range_start, long range_end)
{
Sci_RangeToFormat to_format;
to_format.hdc = target;
to_format.hdcTarget = measure;
to_format.rc.left = print_rect.left();
to_format.rc.top = print_rect.top();
to_format.rc.right = print_rect.right();
to_format.rc.bottom = print_rect.bottom();
to_format.rcPage.left = page_rect.left();
to_format.rcPage.top = page_rect.top();
to_format.rcPage.right = page_rect.right();
to_format.rcPage.bottom = page_rect.bottom();
to_format.chrg.cpMin = range_start;
to_format.chrg.cpMax = range_end;
return send(SCI_FORMATRANGE, draw, reinterpret_cast<sptr_t>(&to_format));
}
/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */

View File

@ -0,0 +1,863 @@
// @file ScintillaEdit.h
// Extended version of ScintillaEditBase with a method for each API
// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
#ifndef SCINTILLAEDIT_H
#define SCINTILLAEDIT_H
#include <QPair>
#include "ScintillaEditBase.h"
#include "ScintillaDocument.h"
#ifndef EXPORT_IMPORT_API
#ifdef WIN32
#ifdef MAKING_LIBRARY
#define EXPORT_IMPORT_API __declspec(dllexport)
#else
// Defining dllimport upsets moc
#define EXPORT_IMPORT_API __declspec(dllimport)
//#define EXPORT_IMPORT_API
#endif
#else
#define EXPORT_IMPORT_API
#endif
#endif
class EXPORT_IMPORT_API ScintillaEdit : public ScintillaEditBase {
Q_OBJECT
public:
ScintillaEdit(QWidget *parent = 0);
virtual ~ScintillaEdit();
QByteArray TextReturner(int message, uptr_t wParam) const;
QPair<int, int>find_text(int flags, const char *text, int cpMin, int cpMax);
QByteArray get_text_range(int start, int end);
ScintillaDocument *get_doc();
void set_doc(ScintillaDocument *pdoc_);
// Same as previous two methods but with Qt style names
QPair<int, int>findText(int flags, const char *text, int cpMin, int cpMax) {
return find_text(flags, text, cpMin, cpMax);
}
QByteArray textRange(int start, int end) {
return get_text_range(start, end);
}
// Exposing the FORMATRANGE api with both underscore & qt style names
long format_range(bool draw, QPaintDevice* target, QPaintDevice* measure,
const QRect& print_rect, const QRect& page_rect,
long range_start, long range_end);
long formatRange(bool draw, QPaintDevice* target, QPaintDevice* measure,
const QRect& print_rect, const QRect& page_rect,
long range_start, long range_end) {
return format_range(draw, target, measure, print_rect, page_rect,
range_start, range_end);
}
/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
void addText(sptr_t length, const char * text);
void addStyledText(sptr_t length, const char * c);
void insertText(sptr_t pos, const char * text);
void changeInsertion(sptr_t length, const char * text);
void clearAll();
void deleteRange(sptr_t start, sptr_t lengthDelete);
void clearDocumentStyle();
sptr_t length() const;
sptr_t charAt(sptr_t pos) const;
sptr_t currentPos() const;
sptr_t anchor() const;
sptr_t styleAt(sptr_t pos) const;
sptr_t styleIndexAt(sptr_t pos) const;
void redo();
void setUndoCollection(bool collectUndo);
void selectAll();
void setSavePoint();
bool canRedo();
sptr_t markerLineFromHandle(sptr_t markerHandle);
void markerDeleteHandle(sptr_t markerHandle);
sptr_t markerHandleFromLine(sptr_t line, sptr_t which);
sptr_t markerNumberFromLine(sptr_t line, sptr_t which);
bool undoCollection() const;
sptr_t viewWS() const;
void setViewWS(sptr_t viewWS);
sptr_t tabDrawMode() const;
void setTabDrawMode(sptr_t tabDrawMode);
sptr_t positionFromPoint(sptr_t x, sptr_t y);
sptr_t positionFromPointClose(sptr_t x, sptr_t y);
void gotoLine(sptr_t line);
void gotoPos(sptr_t caret);
void setAnchor(sptr_t anchor);
QByteArray getCurLine(sptr_t length);
sptr_t endStyled() const;
void convertEOLs(sptr_t eolMode);
sptr_t eOLMode() const;
void setEOLMode(sptr_t eolMode);
void startStyling(sptr_t start, sptr_t unused);
void setStyling(sptr_t length, sptr_t style);
bool bufferedDraw() const;
void setBufferedDraw(bool buffered);
void setTabWidth(sptr_t tabWidth);
sptr_t tabWidth() const;
void setTabMinimumWidth(sptr_t pixels);
sptr_t tabMinimumWidth() const;
void clearTabStops(sptr_t line);
void addTabStop(sptr_t line, sptr_t x);
sptr_t getNextTabStop(sptr_t line, sptr_t x);
void setCodePage(sptr_t codePage);
void setFontLocale(const char * localeName);
QByteArray fontLocale() const;
sptr_t iMEInteraction() const;
void setIMEInteraction(sptr_t imeInteraction);
void markerDefine(sptr_t markerNumber, sptr_t markerSymbol);
void markerSetFore(sptr_t markerNumber, sptr_t fore);
void markerSetBack(sptr_t markerNumber, sptr_t back);
void markerSetBackSelected(sptr_t markerNumber, sptr_t back);
void markerSetForeTranslucent(sptr_t markerNumber, sptr_t fore);
void markerSetBackTranslucent(sptr_t markerNumber, sptr_t back);
void markerSetBackSelectedTranslucent(sptr_t markerNumber, sptr_t back);
void markerSetStrokeWidth(sptr_t markerNumber, sptr_t hundredths);
void markerEnableHighlight(bool enabled);
sptr_t markerAdd(sptr_t line, sptr_t markerNumber);
void markerDelete(sptr_t line, sptr_t markerNumber);
void markerDeleteAll(sptr_t markerNumber);
sptr_t markerGet(sptr_t line);
sptr_t markerNext(sptr_t lineStart, sptr_t markerMask);
sptr_t markerPrevious(sptr_t lineStart, sptr_t markerMask);
void markerDefinePixmap(sptr_t markerNumber, const char * pixmap);
void markerAddSet(sptr_t line, sptr_t markerSet);
void markerSetAlpha(sptr_t markerNumber, sptr_t alpha);
sptr_t markerLayer(sptr_t markerNumber) const;
void markerSetLayer(sptr_t markerNumber, sptr_t layer);
void setMarginTypeN(sptr_t margin, sptr_t marginType);
sptr_t marginTypeN(sptr_t margin) const;
void setMarginWidthN(sptr_t margin, sptr_t pixelWidth);
sptr_t marginWidthN(sptr_t margin) const;
void setMarginMaskN(sptr_t margin, sptr_t mask);
sptr_t marginMaskN(sptr_t margin) const;
void setMarginSensitiveN(sptr_t margin, bool sensitive);
bool marginSensitiveN(sptr_t margin) const;
void setMarginCursorN(sptr_t margin, sptr_t cursor);
sptr_t marginCursorN(sptr_t margin) const;
void setMarginBackN(sptr_t margin, sptr_t back);
sptr_t marginBackN(sptr_t margin) const;
void setMargins(sptr_t margins);
sptr_t margins() const;
void styleClearAll();
void styleSetFore(sptr_t style, sptr_t fore);
void styleSetBack(sptr_t style, sptr_t back);
void styleSetBold(sptr_t style, bool bold);
void styleSetItalic(sptr_t style, bool italic);
void styleSetSize(sptr_t style, sptr_t sizePoints);
void styleSetFont(sptr_t style, const char * fontName);
void styleSetEOLFilled(sptr_t style, bool eolFilled);
void styleResetDefault();
void styleSetUnderline(sptr_t style, bool underline);
sptr_t styleFore(sptr_t style) const;
sptr_t styleBack(sptr_t style) const;
bool styleBold(sptr_t style) const;
bool styleItalic(sptr_t style) const;
sptr_t styleSize(sptr_t style) const;
QByteArray styleFont(sptr_t style) const;
bool styleEOLFilled(sptr_t style) const;
bool styleUnderline(sptr_t style) const;
sptr_t styleCase(sptr_t style) const;
sptr_t styleCharacterSet(sptr_t style) const;
bool styleVisible(sptr_t style) const;
bool styleChangeable(sptr_t style) const;
bool styleHotSpot(sptr_t style) const;
void styleSetCase(sptr_t style, sptr_t caseVisible);
void styleSetSizeFractional(sptr_t style, sptr_t sizeHundredthPoints);
sptr_t styleSizeFractional(sptr_t style) const;
void styleSetWeight(sptr_t style, sptr_t weight);
sptr_t styleWeight(sptr_t style) const;
void styleSetCharacterSet(sptr_t style, sptr_t characterSet);
void styleSetHotSpot(sptr_t style, bool hotspot);
void styleSetCheckMonospaced(sptr_t style, bool checkMonospaced);
bool styleCheckMonospaced(sptr_t style) const;
void styleSetInvisibleRepresentation(sptr_t style, const char * representation);
QByteArray styleInvisibleRepresentation(sptr_t style) const;
void setElementColour(sptr_t element, sptr_t colourElement);
sptr_t elementColour(sptr_t element) const;
void resetElementColour(sptr_t element);
bool elementIsSet(sptr_t element) const;
bool elementAllowsTranslucent(sptr_t element) const;
sptr_t elementBaseColour(sptr_t element) const;
void setSelFore(bool useSetting, sptr_t fore);
void setSelBack(bool useSetting, sptr_t back);
sptr_t selAlpha() const;
void setSelAlpha(sptr_t alpha);
bool selEOLFilled() const;
void setSelEOLFilled(bool filled);
sptr_t selectionLayer() const;
void setSelectionLayer(sptr_t layer);
sptr_t caretLineLayer() const;
void setCaretLineLayer(sptr_t layer);
bool caretLineHighlightSubLine() const;
void setCaretLineHighlightSubLine(bool subLine);
void setCaretFore(sptr_t fore);
void assignCmdKey(sptr_t keyDefinition, sptr_t sciCommand);
void clearCmdKey(sptr_t keyDefinition);
void clearAllCmdKeys();
void setStylingEx(sptr_t length, const char * styles);
void styleSetVisible(sptr_t style, bool visible);
sptr_t caretPeriod() const;
void setCaretPeriod(sptr_t periodMilliseconds);
void setWordChars(const char * characters);
QByteArray wordChars() const;
void setCharacterCategoryOptimization(sptr_t countCharacters);
sptr_t characterCategoryOptimization() const;
void beginUndoAction();
void endUndoAction();
sptr_t undoActions() const;
void setUndoSavePoint(sptr_t action);
sptr_t undoSavePoint() const;
void setUndoDetach(sptr_t action);
sptr_t undoDetach() const;
void setUndoTentative(sptr_t action);
sptr_t undoTentative() const;
void setUndoCurrent(sptr_t action);
sptr_t undoCurrent() const;
void pushUndoActionType(sptr_t type, sptr_t pos);
void changeLastUndoActionText(sptr_t length, const char * text);
sptr_t undoActionType(sptr_t action) const;
sptr_t undoActionPosition(sptr_t action) const;
QByteArray undoActionText(sptr_t action) const;
void indicSetStyle(sptr_t indicator, sptr_t indicatorStyle);
sptr_t indicStyle(sptr_t indicator) const;
void indicSetFore(sptr_t indicator, sptr_t fore);
sptr_t indicFore(sptr_t indicator) const;
void indicSetUnder(sptr_t indicator, bool under);
bool indicUnder(sptr_t indicator) const;
void indicSetHoverStyle(sptr_t indicator, sptr_t indicatorStyle);
sptr_t indicHoverStyle(sptr_t indicator) const;
void indicSetHoverFore(sptr_t indicator, sptr_t fore);
sptr_t indicHoverFore(sptr_t indicator) const;
void indicSetFlags(sptr_t indicator, sptr_t flags);
sptr_t indicFlags(sptr_t indicator) const;
void indicSetStrokeWidth(sptr_t indicator, sptr_t hundredths);
sptr_t indicStrokeWidth(sptr_t indicator) const;
void setWhitespaceFore(bool useSetting, sptr_t fore);
void setWhitespaceBack(bool useSetting, sptr_t back);
void setWhitespaceSize(sptr_t size);
sptr_t whitespaceSize() const;
void setLineState(sptr_t line, sptr_t state);
sptr_t lineState(sptr_t line) const;
sptr_t maxLineState() const;
bool caretLineVisible() const;
void setCaretLineVisible(bool show);
sptr_t caretLineBack() const;
void setCaretLineBack(sptr_t back);
sptr_t caretLineFrame() const;
void setCaretLineFrame(sptr_t width);
void styleSetChangeable(sptr_t style, bool changeable);
void autoCShow(sptr_t lengthEntered, const char * itemList);
void autoCCancel();
bool autoCActive();
sptr_t autoCPosStart();
void autoCComplete();
void autoCStops(const char * characterSet);
void autoCSetSeparator(sptr_t separatorCharacter);
sptr_t autoCSeparator() const;
void autoCSelect(const char * select);
void autoCSetCancelAtStart(bool cancel);
bool autoCCancelAtStart() const;
void autoCSetFillUps(const char * characterSet);
void autoCSetChooseSingle(bool chooseSingle);
bool autoCChooseSingle() const;
void autoCSetIgnoreCase(bool ignoreCase);
bool autoCIgnoreCase() const;
void userListShow(sptr_t listType, const char * itemList);
void autoCSetAutoHide(bool autoHide);
bool autoCAutoHide() const;
void autoCSetOptions(sptr_t options);
sptr_t autoCOptions() const;
void autoCSetDropRestOfWord(bool dropRestOfWord);
bool autoCDropRestOfWord() const;
void registerImage(sptr_t type, const char * xpmData);
void clearRegisteredImages();
sptr_t autoCTypeSeparator() const;
void autoCSetTypeSeparator(sptr_t separatorCharacter);
void autoCSetMaxWidth(sptr_t characterCount);
sptr_t autoCMaxWidth() const;
void autoCSetMaxHeight(sptr_t rowCount);
sptr_t autoCMaxHeight() const;
void setIndent(sptr_t indentSize);
sptr_t indent() const;
void setUseTabs(bool useTabs);
bool useTabs() const;
void setLineIndentation(sptr_t line, sptr_t indentation);
sptr_t lineIndentation(sptr_t line) const;
sptr_t lineIndentPosition(sptr_t line) const;
sptr_t column(sptr_t pos) const;
sptr_t countCharacters(sptr_t start, sptr_t end);
sptr_t countCodeUnits(sptr_t start, sptr_t end);
void setHScrollBar(bool visible);
bool hScrollBar() const;
void setIndentationGuides(sptr_t indentView);
sptr_t indentationGuides() const;
void setHighlightGuide(sptr_t column);
sptr_t highlightGuide() const;
sptr_t lineEndPosition(sptr_t line) const;
sptr_t codePage() const;
sptr_t caretFore() const;
bool readOnly() const;
void setCurrentPos(sptr_t caret);
void setSelectionStart(sptr_t anchor);
sptr_t selectionStart() const;
void setSelectionEnd(sptr_t caret);
sptr_t selectionEnd() const;
void setEmptySelection(sptr_t caret);
void setPrintMagnification(sptr_t magnification);
sptr_t printMagnification() const;
void setPrintColourMode(sptr_t mode);
sptr_t printColourMode() const;
void setChangeHistory(sptr_t changeHistory);
sptr_t changeHistory() const;
sptr_t firstVisibleLine() const;
QByteArray getLine(sptr_t line);
sptr_t lineCount() const;
void allocateLines(sptr_t lines);
void setMarginLeft(sptr_t pixelWidth);
sptr_t marginLeft() const;
void setMarginRight(sptr_t pixelWidth);
sptr_t marginRight() const;
bool modify() const;
void setSel(sptr_t anchor, sptr_t caret);
QByteArray getSelText();
void hideSelection(bool hide);
bool selectionHidden() const;
sptr_t pointXFromPosition(sptr_t pos);
sptr_t pointYFromPosition(sptr_t pos);
sptr_t lineFromPosition(sptr_t pos);
sptr_t positionFromLine(sptr_t line);
void lineScroll(sptr_t columns, sptr_t lines);
void scrollCaret();
void scrollRange(sptr_t secondary, sptr_t primary);
void replaceSel(const char * text);
void setReadOnly(bool readOnly);
void null();
bool canPaste();
bool canUndo();
void emptyUndoBuffer();
void undo();
void cut();
void copy();
void paste();
void clear();
void setText(const char * text);
QByteArray getText(sptr_t length);
sptr_t textLength() const;
sptr_t directFunction() const;
sptr_t directStatusFunction() const;
sptr_t directPointer() const;
void setOvertype(bool overType);
bool overtype() const;
void setCaretWidth(sptr_t pixelWidth);
sptr_t caretWidth() const;
void setTargetStart(sptr_t start);
sptr_t targetStart() const;
void setTargetStartVirtualSpace(sptr_t space);
sptr_t targetStartVirtualSpace() const;
void setTargetEnd(sptr_t end);
sptr_t targetEnd() const;
void setTargetEndVirtualSpace(sptr_t space);
sptr_t targetEndVirtualSpace() const;
void setTargetRange(sptr_t start, sptr_t end);
QByteArray targetText() const;
void targetFromSelection();
void targetWholeDocument();
sptr_t replaceTarget(sptr_t length, const char * text);
sptr_t replaceTargetRE(sptr_t length, const char * text);
sptr_t replaceTargetMinimal(sptr_t length, const char * text);
sptr_t searchInTarget(sptr_t length, const char * text);
void setSearchFlags(sptr_t searchFlags);
sptr_t searchFlags() const;
void callTipShow(sptr_t pos, const char * definition);
void callTipCancel();
bool callTipActive();
sptr_t callTipPosStart();
void callTipSetPosStart(sptr_t posStart);
void callTipSetHlt(sptr_t highlightStart, sptr_t highlightEnd);
void callTipSetBack(sptr_t back);
void callTipSetFore(sptr_t fore);
void callTipSetForeHlt(sptr_t fore);
void callTipUseStyle(sptr_t tabSize);
void callTipSetPosition(bool above);
sptr_t visibleFromDocLine(sptr_t docLine);
sptr_t docLineFromVisible(sptr_t displayLine);
sptr_t wrapCount(sptr_t docLine);
void setFoldLevel(sptr_t line, sptr_t level);
sptr_t foldLevel(sptr_t line) const;
sptr_t lastChild(sptr_t line, sptr_t level) const;
sptr_t foldParent(sptr_t line) const;
void showLines(sptr_t lineStart, sptr_t lineEnd);
void hideLines(sptr_t lineStart, sptr_t lineEnd);
bool lineVisible(sptr_t line) const;
bool allLinesVisible() const;
void setFoldExpanded(sptr_t line, bool expanded);
bool foldExpanded(sptr_t line) const;
void toggleFold(sptr_t line);
void toggleFoldShowText(sptr_t line, const char * text);
void foldDisplayTextSetStyle(sptr_t style);
sptr_t foldDisplayTextStyle() const;
void setDefaultFoldDisplayText(const char * text);
QByteArray getDefaultFoldDisplayText();
void foldLine(sptr_t line, sptr_t action);
void foldChildren(sptr_t line, sptr_t action);
void expandChildren(sptr_t line, sptr_t level);
void foldAll(sptr_t action);
void ensureVisible(sptr_t line);
void setAutomaticFold(sptr_t automaticFold);
sptr_t automaticFold() const;
void setFoldFlags(sptr_t flags);
void ensureVisibleEnforcePolicy(sptr_t line);
void setTabIndents(bool tabIndents);
bool tabIndents() const;
void setBackSpaceUnIndents(bool bsUnIndents);
bool backSpaceUnIndents() const;
void setMouseDwellTime(sptr_t periodMilliseconds);
sptr_t mouseDwellTime() const;
sptr_t wordStartPosition(sptr_t pos, bool onlyWordCharacters);
sptr_t wordEndPosition(sptr_t pos, bool onlyWordCharacters);
bool isRangeWord(sptr_t start, sptr_t end);
void setIdleStyling(sptr_t idleStyling);
sptr_t idleStyling() const;
void setWrapMode(sptr_t wrapMode);
sptr_t wrapMode() const;
void setWrapVisualFlags(sptr_t wrapVisualFlags);
sptr_t wrapVisualFlags() const;
void setWrapVisualFlagsLocation(sptr_t wrapVisualFlagsLocation);
sptr_t wrapVisualFlagsLocation() const;
void setWrapStartIndent(sptr_t indent);
sptr_t wrapStartIndent() const;
void setWrapIndentMode(sptr_t wrapIndentMode);
sptr_t wrapIndentMode() const;
void setLayoutCache(sptr_t cacheMode);
sptr_t layoutCache() const;
void setScrollWidth(sptr_t pixelWidth);
sptr_t scrollWidth() const;
void setScrollWidthTracking(bool tracking);
bool scrollWidthTracking() const;
sptr_t textWidth(sptr_t style, const char * text);
void setEndAtLastLine(bool endAtLastLine);
bool endAtLastLine() const;
sptr_t textHeight(sptr_t line);
void setVScrollBar(bool visible);
bool vScrollBar() const;
void appendText(sptr_t length, const char * text);
sptr_t phasesDraw() const;
void setPhasesDraw(sptr_t phases);
void setFontQuality(sptr_t fontQuality);
sptr_t fontQuality() const;
void setFirstVisibleLine(sptr_t displayLine);
void setMultiPaste(sptr_t multiPaste);
sptr_t multiPaste() const;
QByteArray tag(sptr_t tagNumber) const;
void linesJoin();
void linesSplit(sptr_t pixelWidth);
void setFoldMarginColour(bool useSetting, sptr_t back);
void setFoldMarginHiColour(bool useSetting, sptr_t fore);
void setAccessibility(sptr_t accessibility);
sptr_t accessibility() const;
void lineDown();
void lineDownExtend();
void lineUp();
void lineUpExtend();
void charLeft();
void charLeftExtend();
void charRight();
void charRightExtend();
void wordLeft();
void wordLeftExtend();
void wordRight();
void wordRightExtend();
void home();
void homeExtend();
void lineEnd();
void lineEndExtend();
void documentStart();
void documentStartExtend();
void documentEnd();
void documentEndExtend();
void pageUp();
void pageUpExtend();
void pageDown();
void pageDownExtend();
void editToggleOvertype();
void cancel();
void deleteBack();
void tab();
void backTab();
void newLine();
void formFeed();
void vCHome();
void vCHomeExtend();
void zoomIn();
void zoomOut();
void delWordLeft();
void delWordRight();
void delWordRightEnd();
void lineCut();
void lineDelete();
void lineTranspose();
void lineReverse();
void lineDuplicate();
void lowerCase();
void upperCase();
void lineScrollDown();
void lineScrollUp();
void deleteBackNotLine();
void homeDisplay();
void homeDisplayExtend();
void lineEndDisplay();
void lineEndDisplayExtend();
void homeWrap();
void homeWrapExtend();
void lineEndWrap();
void lineEndWrapExtend();
void vCHomeWrap();
void vCHomeWrapExtend();
void lineCopy();
void moveCaretInsideView();
sptr_t lineLength(sptr_t line);
void braceHighlight(sptr_t posA, sptr_t posB);
void braceHighlightIndicator(bool useSetting, sptr_t indicator);
void braceBadLight(sptr_t pos);
void braceBadLightIndicator(bool useSetting, sptr_t indicator);
sptr_t braceMatch(sptr_t pos, sptr_t maxReStyle);
sptr_t braceMatchNext(sptr_t pos, sptr_t startPos);
bool viewEOL() const;
void setViewEOL(bool visible);
sptr_t docPointer() const;
void setDocPointer(sptr_t doc);
void setModEventMask(sptr_t eventMask);
sptr_t edgeColumn() const;
void setEdgeColumn(sptr_t column);
sptr_t edgeMode() const;
void setEdgeMode(sptr_t edgeMode);
sptr_t edgeColour() const;
void setEdgeColour(sptr_t edgeColour);
void multiEdgeAddLine(sptr_t column, sptr_t edgeColour);
void multiEdgeClearAll();
sptr_t multiEdgeColumn(sptr_t which) const;
void searchAnchor();
sptr_t searchNext(sptr_t searchFlags, const char * text);
sptr_t searchPrev(sptr_t searchFlags, const char * text);
sptr_t linesOnScreen() const;
void usePopUp(sptr_t popUpMode);
bool selectionIsRectangle() const;
void setZoom(sptr_t zoomInPoints);
sptr_t zoom() const;
sptr_t createDocument(sptr_t bytes, sptr_t documentOptions);
void addRefDocument(sptr_t doc);
void releaseDocument(sptr_t doc);
sptr_t documentOptions() const;
sptr_t modEventMask() const;
void setCommandEvents(bool commandEvents);
bool commandEvents() const;
void setFocus(bool focus);
bool focus() const;
void setStatus(sptr_t status);
sptr_t status() const;
void setMouseDownCaptures(bool captures);
bool mouseDownCaptures() const;
void setMouseWheelCaptures(bool captures);
bool mouseWheelCaptures() const;
void setCursor(sptr_t cursorType);
sptr_t cursor() const;
void setControlCharSymbol(sptr_t symbol);
sptr_t controlCharSymbol() const;
void wordPartLeft();
void wordPartLeftExtend();
void wordPartRight();
void wordPartRightExtend();
void setVisiblePolicy(sptr_t visiblePolicy, sptr_t visibleSlop);
void delLineLeft();
void delLineRight();
void setXOffset(sptr_t xOffset);
sptr_t xOffset() const;
void chooseCaretX();
void grabFocus();
void setXCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop);
void setYCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop);
void setPrintWrapMode(sptr_t wrapMode);
sptr_t printWrapMode() const;
void setHotspotActiveFore(bool useSetting, sptr_t fore);
sptr_t hotspotActiveFore() const;
void setHotspotActiveBack(bool useSetting, sptr_t back);
sptr_t hotspotActiveBack() const;
void setHotspotActiveUnderline(bool underline);
bool hotspotActiveUnderline() const;
void setHotspotSingleLine(bool singleLine);
bool hotspotSingleLine() const;
void paraDown();
void paraDownExtend();
void paraUp();
void paraUpExtend();
sptr_t positionBefore(sptr_t pos);
sptr_t positionAfter(sptr_t pos);
sptr_t positionRelative(sptr_t pos, sptr_t relative);
sptr_t positionRelativeCodeUnits(sptr_t pos, sptr_t relative);
void copyRange(sptr_t start, sptr_t end);
void copyText(sptr_t length, const char * text);
void setSelectionMode(sptr_t selectionMode);
void changeSelectionMode(sptr_t selectionMode);
sptr_t selectionMode() const;
void setMoveExtendsSelection(bool moveExtendsSelection);
bool moveExtendsSelection() const;
sptr_t getLineSelStartPosition(sptr_t line);
sptr_t getLineSelEndPosition(sptr_t line);
void lineDownRectExtend();
void lineUpRectExtend();
void charLeftRectExtend();
void charRightRectExtend();
void homeRectExtend();
void vCHomeRectExtend();
void lineEndRectExtend();
void pageUpRectExtend();
void pageDownRectExtend();
void stutteredPageUp();
void stutteredPageUpExtend();
void stutteredPageDown();
void stutteredPageDownExtend();
void wordLeftEnd();
void wordLeftEndExtend();
void wordRightEnd();
void wordRightEndExtend();
void setWhitespaceChars(const char * characters);
QByteArray whitespaceChars() const;
void setPunctuationChars(const char * characters);
QByteArray punctuationChars() const;
void setCharsDefault();
sptr_t autoCCurrent() const;
QByteArray autoCCurrentText() const;
void autoCSetCaseInsensitiveBehaviour(sptr_t behaviour);
sptr_t autoCCaseInsensitiveBehaviour() const;
void autoCSetMulti(sptr_t multi);
sptr_t autoCMulti() const;
void autoCSetOrder(sptr_t order);
sptr_t autoCOrder() const;
void allocate(sptr_t bytes);
QByteArray targetAsUTF8();
void setLengthForEncode(sptr_t bytes);
QByteArray encodedFromUTF8(const char * utf8);
sptr_t findColumn(sptr_t line, sptr_t column);
sptr_t caretSticky() const;
void setCaretSticky(sptr_t useCaretStickyBehaviour);
void toggleCaretSticky();
void setPasteConvertEndings(bool convert);
bool pasteConvertEndings() const;
void replaceRectangular(sptr_t length, const char * text);
void selectionDuplicate();
void setCaretLineBackAlpha(sptr_t alpha);
sptr_t caretLineBackAlpha() const;
void setCaretStyle(sptr_t caretStyle);
sptr_t caretStyle() const;
void setIndicatorCurrent(sptr_t indicator);
sptr_t indicatorCurrent() const;
void setIndicatorValue(sptr_t value);
sptr_t indicatorValue() const;
void indicatorFillRange(sptr_t start, sptr_t lengthFill);
void indicatorClearRange(sptr_t start, sptr_t lengthClear);
sptr_t indicatorAllOnFor(sptr_t pos);
sptr_t indicatorValueAt(sptr_t indicator, sptr_t pos);
sptr_t indicatorStart(sptr_t indicator, sptr_t pos);
sptr_t indicatorEnd(sptr_t indicator, sptr_t pos);
void setPositionCache(sptr_t size);
sptr_t positionCache() const;
void setLayoutThreads(sptr_t threads);
sptr_t layoutThreads() const;
void copyAllowLine();
sptr_t characterPointer() const;
sptr_t rangePointer(sptr_t start, sptr_t lengthRange) const;
sptr_t gapPosition() const;
void indicSetAlpha(sptr_t indicator, sptr_t alpha);
sptr_t indicAlpha(sptr_t indicator) const;
void indicSetOutlineAlpha(sptr_t indicator, sptr_t alpha);
sptr_t indicOutlineAlpha(sptr_t indicator) const;
void setExtraAscent(sptr_t extraAscent);
sptr_t extraAscent() const;
void setExtraDescent(sptr_t extraDescent);
sptr_t extraDescent() const;
sptr_t markerSymbolDefined(sptr_t markerNumber);
void marginSetText(sptr_t line, const char * text);
QByteArray marginText(sptr_t line) const;
void marginSetStyle(sptr_t line, sptr_t style);
sptr_t marginStyle(sptr_t line) const;
void marginSetStyles(sptr_t line, const char * styles);
QByteArray marginStyles(sptr_t line) const;
void marginTextClearAll();
void marginSetStyleOffset(sptr_t style);
sptr_t marginStyleOffset() const;
void setMarginOptions(sptr_t marginOptions);
sptr_t marginOptions() const;
void annotationSetText(sptr_t line, const char * text);
QByteArray annotationText(sptr_t line) const;
void annotationSetStyle(sptr_t line, sptr_t style);
sptr_t annotationStyle(sptr_t line) const;
void annotationSetStyles(sptr_t line, const char * styles);
QByteArray annotationStyles(sptr_t line) const;
sptr_t annotationLines(sptr_t line) const;
void annotationClearAll();
void annotationSetVisible(sptr_t visible);
sptr_t annotationVisible() const;
void annotationSetStyleOffset(sptr_t style);
sptr_t annotationStyleOffset() const;
void releaseAllExtendedStyles();
sptr_t allocateExtendedStyles(sptr_t numberStyles);
void addUndoAction(sptr_t token, sptr_t flags);
sptr_t charPositionFromPoint(sptr_t x, sptr_t y);
sptr_t charPositionFromPointClose(sptr_t x, sptr_t y);
void setMouseSelectionRectangularSwitch(bool mouseSelectionRectangularSwitch);
bool mouseSelectionRectangularSwitch() const;
void setMultipleSelection(bool multipleSelection);
bool multipleSelection() const;
void setAdditionalSelectionTyping(bool additionalSelectionTyping);
bool additionalSelectionTyping() const;
void setAdditionalCaretsBlink(bool additionalCaretsBlink);
bool additionalCaretsBlink() const;
void setAdditionalCaretsVisible(bool additionalCaretsVisible);
bool additionalCaretsVisible() const;
sptr_t selections() const;
bool selectionEmpty() const;
void clearSelections();
void setSelection(sptr_t caret, sptr_t anchor);
void addSelection(sptr_t caret, sptr_t anchor);
sptr_t selectionFromPoint(sptr_t x, sptr_t y);
void dropSelectionN(sptr_t selection);
void setMainSelection(sptr_t selection);
sptr_t mainSelection() const;
void setSelectionNCaret(sptr_t selection, sptr_t caret);
sptr_t selectionNCaret(sptr_t selection) const;
void setSelectionNAnchor(sptr_t selection, sptr_t anchor);
sptr_t selectionNAnchor(sptr_t selection) const;
void setSelectionNCaretVirtualSpace(sptr_t selection, sptr_t space);
sptr_t selectionNCaretVirtualSpace(sptr_t selection) const;
void setSelectionNAnchorVirtualSpace(sptr_t selection, sptr_t space);
sptr_t selectionNAnchorVirtualSpace(sptr_t selection) const;
void setSelectionNStart(sptr_t selection, sptr_t anchor);
sptr_t selectionNStart(sptr_t selection) const;
sptr_t selectionNStartVirtualSpace(sptr_t selection) const;
void setSelectionNEnd(sptr_t selection, sptr_t caret);
sptr_t selectionNEndVirtualSpace(sptr_t selection) const;
sptr_t selectionNEnd(sptr_t selection) const;
void setRectangularSelectionCaret(sptr_t caret);
sptr_t rectangularSelectionCaret() const;
void setRectangularSelectionAnchor(sptr_t anchor);
sptr_t rectangularSelectionAnchor() const;
void setRectangularSelectionCaretVirtualSpace(sptr_t space);
sptr_t rectangularSelectionCaretVirtualSpace() const;
void setRectangularSelectionAnchorVirtualSpace(sptr_t space);
sptr_t rectangularSelectionAnchorVirtualSpace() const;
void setVirtualSpaceOptions(sptr_t virtualSpaceOptions);
sptr_t virtualSpaceOptions() const;
void setRectangularSelectionModifier(sptr_t modifier);
sptr_t rectangularSelectionModifier() const;
void setAdditionalSelFore(sptr_t fore);
void setAdditionalSelBack(sptr_t back);
void setAdditionalSelAlpha(sptr_t alpha);
sptr_t additionalSelAlpha() const;
void setAdditionalCaretFore(sptr_t fore);
sptr_t additionalCaretFore() const;
void rotateSelection();
void swapMainAnchorCaret();
void multipleSelectAddNext();
void multipleSelectAddEach();
sptr_t changeLexerState(sptr_t start, sptr_t end);
sptr_t contractedFoldNext(sptr_t lineStart);
void verticalCentreCaret();
void moveSelectedLinesUp();
void moveSelectedLinesDown();
void setIdentifier(sptr_t identifier);
sptr_t identifier() const;
void rGBAImageSetWidth(sptr_t width);
void rGBAImageSetHeight(sptr_t height);
void rGBAImageSetScale(sptr_t scalePercent);
void markerDefineRGBAImage(sptr_t markerNumber, const char * pixels);
void registerRGBAImage(sptr_t type, const char * pixels);
void scrollToStart();
void scrollToEnd();
void setTechnology(sptr_t technology);
sptr_t technology() const;
sptr_t createLoader(sptr_t bytes, sptr_t documentOptions);
void findIndicatorShow(sptr_t start, sptr_t end);
void findIndicatorFlash(sptr_t start, sptr_t end);
void findIndicatorHide();
void vCHomeDisplay();
void vCHomeDisplayExtend();
bool caretLineVisibleAlways() const;
void setCaretLineVisibleAlways(bool alwaysVisible);
void setLineEndTypesAllowed(sptr_t lineEndBitSet);
sptr_t lineEndTypesAllowed() const;
sptr_t lineEndTypesActive() const;
void setRepresentation(const char * encodedCharacter, const char * representation);
QByteArray representation(const char * encodedCharacter) const;
void clearRepresentation(const char * encodedCharacter);
void clearAllRepresentations();
void setRepresentationAppearance(const char * encodedCharacter, sptr_t appearance);
sptr_t representationAppearance(const char * encodedCharacter) const;
void setRepresentationColour(const char * encodedCharacter, sptr_t colour);
sptr_t representationColour(const char * encodedCharacter) const;
void eOLAnnotationSetText(sptr_t line, const char * text);
QByteArray eOLAnnotationText(sptr_t line) const;
void eOLAnnotationSetStyle(sptr_t line, sptr_t style);
sptr_t eOLAnnotationStyle(sptr_t line) const;
void eOLAnnotationClearAll();
void eOLAnnotationSetVisible(sptr_t visible);
sptr_t eOLAnnotationVisible() const;
void eOLAnnotationSetStyleOffset(sptr_t style);
sptr_t eOLAnnotationStyleOffset() const;
bool supportsFeature(sptr_t feature) const;
sptr_t lineCharacterIndex() const;
void allocateLineCharacterIndex(sptr_t lineCharacterIndex);
void releaseLineCharacterIndex(sptr_t lineCharacterIndex);
sptr_t lineFromIndexPosition(sptr_t pos, sptr_t lineCharacterIndex);
sptr_t indexPositionFromLine(sptr_t line, sptr_t lineCharacterIndex);
void startRecord();
void stopRecord();
sptr_t lexer() const;
void colourise(sptr_t start, sptr_t end);
void setProperty(const char * key, const char * value);
void setKeyWords(sptr_t keyWordSet, const char * keyWords);
QByteArray property(const char * key) const;
QByteArray propertyExpanded(const char * key) const;
sptr_t propertyInt(const char * key, sptr_t defaultValue) const;
QByteArray lexerLanguage() const;
sptr_t privateLexerCall(sptr_t operation, sptr_t pointer);
QByteArray propertyNames();
sptr_t propertyType(const char * name);
QByteArray describeProperty(const char * name);
QByteArray describeKeyWordSets();
sptr_t lineEndTypesSupported() const;
sptr_t allocateSubStyles(sptr_t styleBase, sptr_t numberStyles);
sptr_t subStylesStart(sptr_t styleBase) const;
sptr_t subStylesLength(sptr_t styleBase) const;
sptr_t styleFromSubStyle(sptr_t subStyle) const;
sptr_t primaryStyleFromStyle(sptr_t style) const;
void freeSubStyles();
void setIdentifiers(sptr_t style, const char * identifiers);
sptr_t distanceToSecondaryStyles() const;
QByteArray subStyleBases() const;
sptr_t namedStyles() const;
QByteArray nameOfStyle(sptr_t style);
QByteArray tagsOfStyle(sptr_t style);
QByteArray descriptionOfStyle(sptr_t style);
void setILexer(sptr_t ilexer);
sptr_t bidirectional() const;
void setBidirectional(sptr_t bidirectional);
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
};
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#if !defined(__clang__) && (__GNUC__ >= 8)
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#endif
#endif /* SCINTILLAEDIT_H */

View File

@ -0,0 +1,73 @@
// @file ScintillaEdit.h
// Extended version of ScintillaEditBase with a method for each API
// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
#ifndef SCINTILLAEDIT_H
#define SCINTILLAEDIT_H
#include <QPair>
#include "ScintillaEditBase.h"
#include "ScintillaDocument.h"
#ifndef EXPORT_IMPORT_API
#ifdef WIN32
#ifdef MAKING_LIBRARY
#define EXPORT_IMPORT_API __declspec(dllexport)
#else
// Defining dllimport upsets moc
#define EXPORT_IMPORT_API __declspec(dllimport)
//#define EXPORT_IMPORT_API
#endif
#else
#define EXPORT_IMPORT_API
#endif
#endif
class EXPORT_IMPORT_API ScintillaEdit : public ScintillaEditBase {
Q_OBJECT
public:
ScintillaEdit(QWidget *parent = 0);
virtual ~ScintillaEdit();
QByteArray TextReturner(int message, uptr_t wParam) const;
QPair<int, int>find_text(int flags, const char *text, int cpMin, int cpMax);
QByteArray get_text_range(int start, int end);
ScintillaDocument *get_doc();
void set_doc(ScintillaDocument *pdoc_);
// Same as previous two methods but with Qt style names
QPair<int, int>findText(int flags, const char *text, int cpMin, int cpMax) {
return find_text(flags, text, cpMin, cpMax);
}
QByteArray textRange(int start, int end) {
return get_text_range(start, end);
}
// Exposing the FORMATRANGE api with both underscore & qt style names
long format_range(bool draw, QPaintDevice* target, QPaintDevice* measure,
const QRect& print_rect, const QRect& page_rect,
long range_start, long range_end);
long formatRange(bool draw, QPaintDevice* target, QPaintDevice* measure,
const QRect& print_rect, const QRect& page_rect,
long range_start, long range_end) {
return format_range(draw, target, measure, print_rect, page_rect,
range_start, range_end);
}
/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
};
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#if !defined(__clang__) && (__GNUC__ >= 8)
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#endif
#endif /* SCINTILLAEDIT_H */

View File

@ -0,0 +1,78 @@
#-------------------------------------------------
#
# Project created by QtCreator 2011-05-05T12:41:23
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
equals(QT_MAJOR_VERSION, 6): QT += core5compat
TARGET = ScintillaEdit
TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.5.0
SOURCES += \
ScintillaEdit.cpp \
ScintillaDocument.cpp \
../ScintillaEditBase/PlatQt.cpp \
../ScintillaEditBase/ScintillaQt.cpp \
../ScintillaEditBase/ScintillaEditBase.cpp \
../../src/XPM.cxx \
../../src/ViewStyle.cxx \
../../src/UndoHistory.cxx \
../../src/UniqueString.cxx \
../../src/UniConversion.cxx \
../../src/Style.cxx \
../../src/Selection.cxx \
../../src/ScintillaBase.cxx \
../../src/RunStyles.cxx \
../../src/RESearch.cxx \
../../src/PositionCache.cxx \
../../src/PerLine.cxx \
../../src/MarginView.cxx \
../../src/LineMarker.cxx \
../../src/KeyMap.cxx \
../../src/Indicator.cxx \
../../src/Geometry.cxx \
../../src/EditView.cxx \
../../src/Editor.cxx \
../../src/EditModel.cxx \
../../src/Document.cxx \
../../src/Decoration.cxx \
../../src/DBCS.cxx \
../../src/ContractionState.cxx \
../../src/CharClassify.cxx \
../../src/CharacterType.cxx \
../../src/CharacterCategoryMap.cxx \
../../src/ChangeHistory.cxx \
../../src/CellBuffer.cxx \
../../src/CaseFolder.cxx \
../../src/CaseConvert.cxx \
../../src/CallTip.cxx \
../../src/AutoComplete.cxx
HEADERS += \
ScintillaEdit.h \
ScintillaDocument.h \
../ScintillaEditBase/ScintillaEditBase.h \
../ScintillaEditBase/ScintillaQt.h
OTHER_FILES +=
INCLUDEPATH += ../ScintillaEditBase ../../include ../../src
DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1
CONFIG(release, debug|release) {
DEFINES += NDEBUG=1
}
DESTDIR = ../../bin
DLLDESTDIR = ../../bin
macx {
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/
}

View File

@ -0,0 +1,252 @@
#!/usr/bin/env python3
# WidgetGen.py - regenerate the ScintillaEdit.cpp and ScintillaEdit.h files
# Check that API includes all gtkscintilla2 functions
import sys
import os
import getopt
scintillaDirectory = "../.."
scintillaScriptsDirectory = os.path.join(scintillaDirectory, "scripts")
sys.path.append(scintillaScriptsDirectory)
import Face
from FileGenerator import GenerateFile
def underscoreName(s):
# Name conversion fixes to match gtkscintilla2
irregular = ['WS', 'EOL', 'AutoC', 'KeyWords', 'BackSpace', 'UnIndents', 'RE', 'RGBA']
for word in irregular:
replacement = word[0] + word[1:].lower()
s = s.replace(word, replacement)
out = ""
for c in s:
if c.isupper():
if out:
out += "_"
out += c.lower()
else:
out += c
return out
def normalisedName(s, options, role=None):
if options["qtStyle"]:
if role == "get":
s = s.replace("Get", "")
return s[0].lower() + s[1:]
else:
return underscoreName(s)
typeAliases = {
"position": "int",
"line": "int",
"pointer": "int",
"colour": "int",
"colouralpha": "int",
"keymod": "int",
"string": "const char *",
"stringresult": "const char *",
"cells": "const char *",
}
def cppAlias(s):
if s in typeAliases:
return typeAliases[s]
elif Face.IsEnumeration(s):
return "int"
else:
return s
understoodTypes = ["", "void", "int", "bool", "position", "line", "pointer",
"colour", "colouralpha", "keymod", "string", "stringresult", "cells"]
def understoodType(t):
return t in understoodTypes or Face.IsEnumeration(t)
def checkTypes(name, v):
understandAllTypes = True
if not understoodType(v["ReturnType"]):
#~ print("Do not understand", v["ReturnType"], "for", name)
understandAllTypes = False
if not understoodType(v["Param1Type"]):
#~ print("Do not understand", v["Param1Type"], "for", name)
understandAllTypes = False
if not understoodType(v["Param2Type"]):
#~ print("Do not understand", v["Param2Type"], "for", name)
understandAllTypes = False
return understandAllTypes
def arguments(v, stringResult, options):
ret = ""
p1Type = cppAlias(v["Param1Type"])
if p1Type == "int":
p1Type = "sptr_t"
if p1Type:
ret = ret + p1Type + " " + normalisedName(v["Param1Name"], options)
p2Type = cppAlias(v["Param2Type"])
if p2Type == "int":
p2Type = "sptr_t"
if p2Type and not stringResult:
if p1Type:
ret = ret + ", "
ret = ret + p2Type + " " + normalisedName(v["Param2Name"], options)
return ret
def printHFile(f, options):
out = []
for name in f.order:
v = f.features[name]
if v["Category"] != "Deprecated":
feat = v["FeatureType"]
if feat in ["fun", "get", "set"]:
if checkTypes(name, v):
constDeclarator = " const" if feat == "get" else ""
returnType = cppAlias(v["ReturnType"])
if returnType == "int":
returnType = "sptr_t"
stringResult = v["Param2Type"] == "stringresult"
if stringResult:
returnType = "QByteArray"
out.append("\t" + returnType + " " + normalisedName(name, options, feat) + "(" +
arguments(v, stringResult, options)+
")" + constDeclarator + ";")
return out
def methodNames(f, options):
for name in f.order:
v = f.features[name]
if v["Category"] != "Deprecated":
feat = v["FeatureType"]
if feat in ["fun", "get", "set"]:
if checkTypes(name, v):
yield normalisedName(name, options)
def printCPPFile(f, options):
out = []
for name in f.order:
v = f.features[name]
if v["Category"] != "Deprecated":
feat = v["FeatureType"]
if feat in ["fun", "get", "set"]:
if checkTypes(name, v):
constDeclarator = " const" if feat == "get" else ""
featureDefineName = "SCI_" + name.upper()
returnType = cppAlias(v["ReturnType"])
if returnType == "int":
returnType = "sptr_t"
stringResult = v["Param2Type"] == "stringresult"
if stringResult:
returnType = "QByteArray"
returnStatement = ""
if returnType != "void":
returnStatement = "return "
out.append(returnType + " ScintillaEdit::" + normalisedName(name, options, feat) + "(" +
arguments(v, stringResult, options) +
")" + constDeclarator + " {")
returns = ""
if stringResult:
returns += " " + returnStatement + "TextReturner(" + featureDefineName + ", "
if "*" in cppAlias(v["Param1Type"]):
returns += "(sptr_t)"
if v["Param1Name"]:
returns += normalisedName(v["Param1Name"], options)
else:
returns += "0"
returns += ");"
else:
returns += " " + returnStatement + "send(" + featureDefineName + ", "
if "*" in cppAlias(v["Param1Type"]):
returns += "(sptr_t)"
if v["Param1Name"]:
returns += normalisedName(v["Param1Name"], options)
else:
returns += "0"
returns += ", "
if "*" in cppAlias(v["Param2Type"]):
returns += "(sptr_t)"
if v["Param2Name"]:
returns += normalisedName(v["Param2Name"], options)
else:
returns += "0"
returns += ");"
out.append(returns)
out.append("}")
out.append("")
return out
def gtkNames():
# The full path on my machine: should be altered for anyone else
p = "C:/Users/Neil/Downloads/wingide-source-4.0.1-1/wingide-source-4.0.1-1/external/gtkscintilla2/gtkscintilla.c"
with open(p) as f:
for l in f.readlines():
if "gtk_scintilla_" in l:
name = l.split()[1][14:]
if '(' in name:
name = name.split('(')[0]
yield name
def usage():
print("WidgetGen.py [-c|--clean][-h|--help][-u|--underscore-names]")
print("")
print("Generate full APIs for ScintillaEdit class.")
print("")
print("options:")
print("")
print("-c --clean remove all generated code from files")
print("-h --help display this text")
print("-u --underscore-names use method_names consistent with GTK+ standards")
def readInterface(cleanGenerated):
f = Face.Face()
if not cleanGenerated:
f.ReadFromFile("../../include/Scintilla.iface")
return f
def main(argv):
# Using local path for gtkscintilla2 so don't default to checking
checkGTK = False
cleanGenerated = False
qtStyleInterface = True
# The --gtk-check option checks for full coverage of the gtkscintilla2 API but
# depends on a particular directory so is not mentioned in --help.
opts, args = getopt.getopt(argv, "hcgu", ["help", "clean", "gtk-check", "underscore-names"])
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-c", "--clean"):
cleanGenerated = True
elif opt in ("-g", "--gtk-check"):
checkGTK = True
elif opt in ("-u", "--underscore-names"):
qtStyleInterface = False
options = {"qtStyle": qtStyleInterface}
f = readInterface(cleanGenerated)
try:
GenerateFile("ScintillaEdit.cpp.template", "ScintillaEdit.cpp",
"/* ", True, printCPPFile(f, options))
GenerateFile("ScintillaEdit.h.template", "ScintillaEdit.h",
"/* ", True, printHFile(f, options))
if checkGTK:
names = set(methodNames(f))
#~ print("\n".join(names))
namesGtk = set(gtkNames())
for name in namesGtk:
if name not in names:
print(name, "not found in Qt version")
for name in names:
if name not in namesGtk:
print(name, "not found in GTK+ version")
except:
raise
if cleanGenerated:
for file in ["ScintillaEdit.cpp", "ScintillaEdit.h"]:
try:
os.remove(file)
except OSError:
pass
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,18 @@
Issues with Scintilla for Qt
Qt reports character descenders are 1 pixel shorter than they really are.
There is a tweak in the code to add a pixel in. This may have to be reviewed for Qt 5.
There's a comment in the Qt code for Windows:
// ### we subtract 1 to even out the historical +1 in QFontMetrics's
// ### height=asc+desc+1 equation. Fix in Qt5.
The clocks used aren't great. QTime is a time since midnight clock so wraps around and
is only accurate to, at best, milliseconds.
On macOS drawing text into a pixmap moves it around 1 pixel to the right compared to drawing
it directly onto a window. Buffered drawing turned off by default to avoid this.
Reported as QTBUG-19483.
Only one QPainter can be active on any widget at a time. Scintilla only draws into one
widget but reenters for measurement.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
// @file PlatQt.h
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may be distributed.
//
// Author: Jason Haslam
//
// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
// Scintilla platform layer for Qt
#ifndef PLATQT_H
#define PLATQT_H
#include <cstddef>
#include <string_view>
#include <vector>
#include <optional>
#include <memory>
#include "Debugging.h"
#include "Geometry.h"
#include "ScintillaTypes.h"
#include "ScintillaMessages.h"
#include "Platform.h"
#include <QUrl>
#include <QPaintDevice>
#include <QPainter>
#include <QHash>
#include <QTextCodec>
namespace Scintilla::Internal {
const char *CharacterSetID(Scintilla::CharacterSet characterSet);
inline QColor QColorFromColourRGBA(ColourRGBA ca)
{
return QColor(ca.GetRed(), ca.GetGreen(), ca.GetBlue(), ca.GetAlpha());
}
inline QRect QRectFromPRect(PRectangle pr)
{
return QRect(pr.left, pr.top, pr.Width(), pr.Height());
}
inline QRectF QRectFFromPRect(PRectangle pr)
{
return QRectF(pr.left, pr.top, pr.Width(), pr.Height());
}
inline PRectangle PRectFromQRect(QRect qr)
{
return PRectangle(qr.x(), qr.y(), qr.x() + qr.width(), qr.y() + qr.height());
}
inline Point PointFromQPoint(QPoint qp)
{
return Point(qp.x(), qp.y());
}
inline QPointF QPointFFromPoint(Point qp)
{
return QPointF(qp.x, qp.y);
}
constexpr PRectangle RectangleInset(PRectangle rc, XYPOSITION delta) noexcept {
return PRectangle(rc.left + delta, rc.top + delta, rc.right - delta, rc.bottom - delta);
}
class SurfaceImpl : public Surface {
private:
QPaintDevice *device = nullptr;
QPainter *painter = nullptr;
bool deviceOwned = false;
bool painterOwned = false;
SurfaceMode mode;
const char *codecName = nullptr;
QTextCodec *codec = nullptr;
void Clear();
public:
SurfaceImpl();
SurfaceImpl(int width, int height, SurfaceMode mode_);
virtual ~SurfaceImpl();
void Init(WindowID wid) override;
void Init(SurfaceID sid, WindowID wid) override;
std::unique_ptr<Surface> AllocatePixMap(int width, int height) override;
void SetMode(SurfaceMode mode) override;
void Release() noexcept override;
int SupportsFeature(Scintilla::Supports feature) noexcept override;
bool Initialised() override;
void PenColour(ColourRGBA fore);
void PenColourWidth(ColourRGBA fore, XYPOSITION strokeWidth);
int LogPixelsY() override;
int PixelDivisions() override;
int DeviceHeightFont(int points) override;
void LineDraw(Point start, Point end, Stroke stroke) override;
void PolyLine(const Point *pts, size_t npts, Stroke stroke) override;
void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override;
void RectangleDraw(PRectangle rc, FillStroke fillStroke) override;
void RectangleFrame(PRectangle rc, Stroke stroke) override;
void FillRectangle(PRectangle rc, Fill fill) override;
void FillRectangleAligned(PRectangle rc, Fill fill) override;
void FillRectangle(PRectangle rc, Surface &surfacePattern) override;
void RoundedRectangle(PRectangle rc, FillStroke fillStroke) override;
void AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke) override;
void GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options) override;
void DrawRGBAImage(PRectangle rc, int width, int height,
const unsigned char *pixelsImage) override;
void Ellipse(PRectangle rc, FillStroke fillStroke) override;
void Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) override;
void Copy(PRectangle rc, Point from, Surface &surfaceSource) override;
std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) override;
void DrawTextNoClip(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourRGBA fore, ColourRGBA back) override;
void DrawTextClipped(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourRGBA fore, ColourRGBA back) override;
void DrawTextTransparent(PRectangle rc, const Font *font, XYPOSITION ybase,
std::string_view text, ColourRGBA fore) override;
void MeasureWidths(const Font *font, std::string_view text,
XYPOSITION *positions) override;
XYPOSITION WidthText(const Font *font, std::string_view text) override;
void DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase,
std::string_view text, ColourRGBA fore, ColourRGBA back) override;
void DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase,
std::string_view text, ColourRGBA fore, ColourRGBA back) override;
void DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase,
std::string_view text, ColourRGBA fore) override;
void MeasureWidthsUTF8(const Font *font_, std::string_view text,
XYPOSITION *positions) override;
XYPOSITION WidthTextUTF8(const Font *font_, std::string_view text) override;
XYPOSITION Ascent(const Font *font) override;
XYPOSITION Descent(const Font *font) override;
XYPOSITION InternalLeading(const Font *font) override;
XYPOSITION Height(const Font *font) override;
XYPOSITION AverageCharWidth(const Font *font) override;
void SetClip(PRectangle rc) override;
void PopClip() override;
void FlushCachedState() override;
void FlushDrawing() override;
void BrushColour(ColourRGBA back);
void SetCodec(const Font *font);
void SetFont(const Font *font);
QPaintDevice *GetPaintDevice();
void SetPainter(QPainter *painter);
QPainter *GetPainter();
};
}
#endif

View File

@ -0,0 +1,828 @@
//
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may be distributed.
//
// Author: Jason Haslam
//
// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
// @file ScintillaEditBase.cpp - Qt widget that wraps ScintillaQt and provides events and scrolling
#include "ScintillaEditBase.h"
#include "ScintillaQt.h"
#include "PlatQt.h"
#include <QApplication>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QInputContext>
#endif
#include <QPainter>
#include <QVarLengthArray>
#include <QScrollBar>
#include <QTextFormat>
constexpr int IndicatorInput = static_cast<int>(Scintilla::IndicatorNumbers::Ime);
constexpr int IndicatorTarget = IndicatorInput + 1;
constexpr int IndicatorConverted = IndicatorInput + 2;
constexpr int IndicatorUnknown = IndicatorInput + 3;
// Q_WS_MAC and Q_WS_X11 aren't defined in Qt5
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#ifdef Q_OS_MAC
#define Q_WS_MAC 1
#endif
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
#define Q_WS_X11 1
#endif
#endif // QT_VERSION >= 5.0.0
using namespace Scintilla;
using namespace Scintilla::Internal;
ScintillaEditBase::ScintillaEditBase(QWidget *parent)
: QAbstractScrollArea(parent), sqt(new ScintillaQt(this)), preeditPos(-1), wheelDelta(0)
{
time.start();
// Set Qt defaults.
setAcceptDrops(true);
setMouseTracking(true);
setAutoFillBackground(false);
setFrameStyle(QFrame::NoFrame);
setFocusPolicy(Qt::StrongFocus);
setAttribute(Qt::WA_StaticContents);
viewport()->setAutoFillBackground(false);
setAttribute(Qt::WA_KeyCompression);
setAttribute(Qt::WA_InputMethodEnabled);
sqt->vs.indicators[IndicatorUnknown] = Indicator(IndicatorStyle::Hidden, colourIME);
sqt->vs.indicators[IndicatorInput] = Indicator(IndicatorStyle::Dots, colourIME);
sqt->vs.indicators[IndicatorConverted] = Indicator(IndicatorStyle::CompositionThick, colourIME);
sqt->vs.indicators[IndicatorTarget] = Indicator(IndicatorStyle::StraightBox, colourIME);
connect(sqt, SIGNAL(notifyParent(Scintilla::NotificationData)),
this, SLOT(notifyParent(Scintilla::NotificationData)));
// Connect scroll bars.
connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(scrollVertical(int)));
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(scrollHorizontal(int)));
// Connect pass-through signals.
connect(sqt, SIGNAL(horizontalRangeChanged(int,int)),
this, SIGNAL(horizontalRangeChanged(int,int)));
connect(sqt, SIGNAL(verticalRangeChanged(int,int)),
this, SIGNAL(verticalRangeChanged(int,int)));
connect(sqt, SIGNAL(horizontalScrolled(int)),
this, SIGNAL(horizontalScrolled(int)));
connect(sqt, SIGNAL(verticalScrolled(int)),
this, SIGNAL(verticalScrolled(int)));
connect(sqt, SIGNAL(notifyChange()),
this, SIGNAL(notifyChange()));
connect(sqt, SIGNAL(command(Scintilla::uptr_t,Scintilla::sptr_t)),
this, SLOT(event_command(Scintilla::uptr_t,Scintilla::sptr_t)));
connect(sqt, SIGNAL(aboutToCopy(QMimeData*)),
this, SIGNAL(aboutToCopy(QMimeData*)));
}
ScintillaEditBase::~ScintillaEditBase() = default;
sptr_t ScintillaEditBase::send(
unsigned int iMessage,
uptr_t wParam,
sptr_t lParam) const
{
return sqt->WndProc(static_cast<Message>(iMessage), wParam, lParam);
}
sptr_t ScintillaEditBase::sends(
unsigned int iMessage,
uptr_t wParam,
const char *s) const
{
return sqt->WndProc(static_cast<Message>(iMessage), wParam, reinterpret_cast<sptr_t>(s));
}
void ScintillaEditBase::scrollHorizontal(int value)
{
sqt->HorizontalScrollTo(value);
}
void ScintillaEditBase::scrollVertical(int value)
{
sqt->ScrollTo(value);
}
bool ScintillaEditBase::event(QEvent *event)
{
bool result = false;
if (event->type() == QEvent::KeyPress) {
// Circumvent the tab focus convention.
keyPressEvent(static_cast<QKeyEvent *>(event));
result = event->isAccepted();
} else if (event->type() == QEvent::Show) {
setMouseTracking(true);
result = QAbstractScrollArea::event(event);
} else if (event->type() == QEvent::Hide) {
setMouseTracking(false);
result = QAbstractScrollArea::event(event);
} else {
result = QAbstractScrollArea::event(event);
}
return result;
}
void ScintillaEditBase::paintEvent(QPaintEvent *event)
{
sqt->PartialPaint(PRectFromQRect(event->rect()));
}
namespace {
bool isWheelEventHorizontal(QWheelEvent *event) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
return event->angleDelta().y() == 0;
#else
return event->orientation() == Qt::Horizontal;
#endif
}
int wheelEventYDelta(QWheelEvent *event) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
return event->angleDelta().y();
#else
return event->delta();
#endif
}
}
void ScintillaEditBase::wheelEvent(QWheelEvent *event)
{
if (isWheelEventHorizontal(event)) {
QAbstractScrollArea::wheelEvent(event);
} else {
if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
// Zoom! We play with the font sizes in the styles.
// Number of steps/line is ignored, we just care if sizing up or down
if (wheelEventYDelta(event) > 0) {
sqt->KeyCommand(Message::ZoomIn);
} else {
sqt->KeyCommand(Message::ZoomOut);
}
} else {
// Scroll
QAbstractScrollArea::wheelEvent(event);
}
}
}
void ScintillaEditBase::focusInEvent(QFocusEvent *event)
{
sqt->SetFocusState(true);
QAbstractScrollArea::focusInEvent(event);
}
void ScintillaEditBase::focusOutEvent(QFocusEvent *event)
{
sqt->SetFocusState(false);
QAbstractScrollArea::focusOutEvent(event);
}
void ScintillaEditBase::resizeEvent(QResizeEvent *)
{
sqt->ChangeSize();
emit resized();
}
void ScintillaEditBase::keyPressEvent(QKeyEvent *event)
{
// All keystrokes containing the meta modifier are
// assumed to be shortcuts not handled by scintilla.
if (QApplication::keyboardModifiers() & Qt::MetaModifier) {
QAbstractScrollArea::keyPressEvent(event);
emit keyPressed(event);
return;
}
int key = 0;
switch (event->key()) {
case Qt::Key_Down: key = SCK_DOWN; break;
case Qt::Key_Up: key = SCK_UP; break;
case Qt::Key_Left: key = SCK_LEFT; break;
case Qt::Key_Right: key = SCK_RIGHT; break;
case Qt::Key_Home: key = SCK_HOME; break;
case Qt::Key_End: key = SCK_END; break;
case Qt::Key_PageUp: key = SCK_PRIOR; break;
case Qt::Key_PageDown: key = SCK_NEXT; break;
case Qt::Key_Delete: key = SCK_DELETE; break;
case Qt::Key_Insert: key = SCK_INSERT; break;
case Qt::Key_Escape: key = SCK_ESCAPE; break;
case Qt::Key_Backspace: key = SCK_BACK; break;
case Qt::Key_Plus: key = SCK_ADD; break;
case Qt::Key_Minus: key = SCK_SUBTRACT; break;
case Qt::Key_Backtab: // fall through
case Qt::Key_Tab: key = SCK_TAB; break;
case Qt::Key_Enter: // fall through
case Qt::Key_Return: key = SCK_RETURN; break;
case Qt::Key_Control: key = 0; break;
case Qt::Key_Alt: key = 0; break;
case Qt::Key_Shift: key = 0; break;
case Qt::Key_Meta: key = 0; break;
default: key = event->key(); break;
}
bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier;
bool alt = QApplication::keyboardModifiers() & Qt::AltModifier;
bool consumed = false;
bool added = sqt->KeyDownWithModifiers(static_cast<Keys>(key),
ModifierFlags(shift, ctrl, alt),
&consumed) != 0;
if (!consumed)
consumed = added;
if (!consumed) {
// Don't insert text if the control key was pressed unless
// it was pressed in conjunction with alt for AltGr emulation.
bool input = (!ctrl || alt);
// Additionally, on non-mac platforms, don't insert text
// if the alt key was pressed unless control is also present.
// On mac alt can be used to insert special characters.
#ifndef Q_WS_MAC
input &= (!alt || ctrl);
#endif
QString text = event->text();
if (input && !text.isEmpty() && text[0].isPrint()) {
const int strLen = text.length();
for (int i = 0; i < strLen;) {
const int ucWidth = text.at(i).isHighSurrogate() ? 2 : 1;
const QString oneCharUTF16 = text.mid(i, ucWidth);
const QByteArray oneChar = sqt->BytesForDocument(oneCharUTF16);
sqt->InsertCharacter(std::string_view(oneChar.data(), oneChar.length()), CharacterSource::DirectInput);
i += ucWidth;
}
} else {
event->ignore();
}
}
emit keyPressed(event);
}
static int modifierTranslated(int sciModifier)
{
switch (sciModifier) {
case SCMOD_SHIFT:
return Qt::ShiftModifier;
case SCMOD_CTRL:
return Qt::ControlModifier;
case SCMOD_ALT:
return Qt::AltModifier;
case SCMOD_SUPER:
return Qt::MetaModifier;
default:
return 0;
}
}
void ScintillaEditBase::mousePressEvent(QMouseEvent *event)
{
Point pos = PointFromQPoint(event->pos());
emit buttonPressed(event);
if (event->button() == Qt::MiddleButton &&
QApplication::clipboard()->supportsSelection()) {
SelectionPosition selPos = sqt->SPositionFromLocation(
pos, false, false, sqt->UserVirtualSpace());
sqt->sel.Clear();
sqt->SetSelection(selPos, selPos);
sqt->PasteFromMode(QClipboard::Selection);
return;
}
if (event->button() == Qt::LeftButton) {
bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier;
bool alt = QApplication::keyboardModifiers() & modifierTranslated(sqt->rectangularSelectionModifier);
sqt->ButtonDownWithModifiers(pos, time.elapsed(), ModifierFlags(shift, ctrl, alt));
}
if (event->button() == Qt::RightButton) {
sqt->RightButtonDownWithModifiers(pos, time.elapsed(), ModifiersOfKeyboard());
}
}
void ScintillaEditBase::mouseReleaseEvent(QMouseEvent *event)
{
const QPoint point = event->pos();
if (event->button() == Qt::LeftButton)
sqt->ButtonUpWithModifiers(PointFromQPoint(point), time.elapsed(), ModifiersOfKeyboard());
const sptr_t pos = send(SCI_POSITIONFROMPOINT, point.x(), point.y());
const sptr_t line = send(SCI_LINEFROMPOSITION, pos);
int modifiers = QApplication::keyboardModifiers();
emit textAreaClicked(line, modifiers);
emit buttonReleased(event);
}
void ScintillaEditBase::mouseDoubleClickEvent(QMouseEvent *event)
{
// Scintilla does its own double-click detection.
mousePressEvent(event);
}
void ScintillaEditBase::mouseMoveEvent(QMouseEvent *event)
{
Point pos = PointFromQPoint(event->pos());
bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier;
bool alt = QApplication::keyboardModifiers() & modifierTranslated(sqt->rectangularSelectionModifier);
const KeyMod modifiers = ModifierFlags(shift, ctrl, alt);
sqt->ButtonMoveWithModifiers(pos, time.elapsed(), modifiers);
}
void ScintillaEditBase::contextMenuEvent(QContextMenuEvent *event)
{
Point pos = PointFromQPoint(event->globalPos());
Point pt = PointFromQPoint(event->pos());
if (!sqt->PointInSelection(pt)) {
sqt->SetEmptySelection(sqt->PositionFromLocation(pt));
}
if (sqt->ShouldDisplayPopup(pt)) {
sqt->ContextMenu(pos);
event->accept();
} else {
event->ignore();
}
}
void ScintillaEditBase::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
Point point = PointFromQPoint(event->pos());
sqt->DragEnter(point);
} else {
event->ignore();
}
}
void ScintillaEditBase::dragLeaveEvent(QDragLeaveEvent * /* event */)
{
sqt->DragLeave();
}
void ScintillaEditBase::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
Point point = PointFromQPoint(event->pos());
sqt->DragMove(point);
} else {
event->ignore();
}
}
void ScintillaEditBase::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
sqt->DropUrls(event->mimeData());
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
Point point = PointFromQPoint(event->pos());
bool move = (event->source() == this &&
event->proposedAction() == Qt::MoveAction);
sqt->Drop(point, event->mimeData(), move);
} else {
event->ignore();
}
}
bool ScintillaEditBase::IsHangul(const QChar qchar)
{
unsigned int unicode = qchar.unicode();
// Korean character ranges used for preedit chars.
// http://www.programminginkorean.com/programming/hangul-in-unicode/
const bool HangulJamo = (0x1100 <= unicode && unicode <= 0x11FF);
const bool HangulCompatibleJamo = (0x3130 <= unicode && unicode <= 0x318F);
const bool HangulJamoExtendedA = (0xA960 <= unicode && unicode <= 0xA97F);
const bool HangulJamoExtendedB = (0xD7B0 <= unicode && unicode <= 0xD7FF);
const bool HangulSyllable = (0xAC00 <= unicode && unicode <= 0xD7A3);
return HangulJamo || HangulCompatibleJamo || HangulSyllable ||
HangulJamoExtendedA || HangulJamoExtendedB;
}
void ScintillaEditBase::MoveImeCarets(Scintilla::Position offset)
{
// Move carets relatively by bytes
for (size_t r=0; r < sqt->sel.Count(); r++) {
const Sci::Position positionInsert = sqt->sel.Range(r).Start().Position();
sqt->sel.Range(r).caret.SetPosition(positionInsert + offset);
sqt->sel.Range(r).anchor.SetPosition(positionInsert + offset);
}
}
void ScintillaEditBase::DrawImeIndicator(int indicator, int len)
{
// Emulate the visual style of IME characters with indicators.
// Draw an indicator on the character before caret by the character bytes of len
// so it should be called after InsertCharacter().
// It does not affect caret positions.
if (indicator < INDICATOR_CONTAINER || indicator > INDICATOR_MAX) {
return;
}
sqt->pdoc->DecorationSetCurrentIndicator(indicator);
for (size_t r=0; r< sqt-> sel.Count(); r++) {
const Sci::Position positionInsert = sqt->sel.Range(r).Start().Position();
sqt->pdoc->DecorationFillRange(positionInsert - len, 1, len);
}
}
static int GetImeCaretPos(QInputMethodEvent *event)
{
foreach (QInputMethodEvent::Attribute attr, event->attributes()) {
if (attr.type == QInputMethodEvent::Cursor)
return attr.start;
}
return 0;
}
static std::vector<int> MapImeIndicators(QInputMethodEvent *event)
{
std::vector<int> imeIndicator(event->preeditString().size(), IndicatorUnknown);
foreach (QInputMethodEvent::Attribute attr, event->attributes()) {
if (attr.type == QInputMethodEvent::TextFormat) {
QTextFormat format = attr.value.value<QTextFormat>();
QTextCharFormat charFormat = format.toCharFormat();
int indicator = IndicatorUnknown;
switch (charFormat.underlineStyle()) {
case QTextCharFormat::NoUnderline: // win32, linux
case QTextCharFormat::SingleUnderline: // osx
case QTextCharFormat::DashUnderline: // win32, linux
indicator = IndicatorInput;
break;
case QTextCharFormat::DotLine:
case QTextCharFormat::DashDotLine:
case QTextCharFormat::WaveUnderline:
case QTextCharFormat::SpellCheckUnderline:
indicator = IndicatorConverted;
break;
default:
indicator = IndicatorUnknown;
}
if (format.hasProperty(QTextFormat::BackgroundBrush)) // win32, linux
indicator = IndicatorTarget;
#ifdef Q_OS_OSX
if (charFormat.underlineStyle() == QTextCharFormat::SingleUnderline) {
QColor uc = charFormat.underlineColor();
if (uc.lightness() < 2) { // osx
indicator = IndicatorTarget;
}
}
#endif
for (int i = attr.start; i < attr.start+attr.length; i++) {
imeIndicator[i] = indicator;
}
}
}
return imeIndicator;
}
void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)
{
// Copy & paste by johnsonj with a lot of helps of Neil
// Great thanks for my forerunners, jiniya and BLUEnLIVE
if (sqt->pdoc->IsReadOnly() || sqt->SelectionContainsProtected()) {
// Here, a canceling and/or completing composition function is needed.
return;
}
bool initialCompose = false;
if (sqt->pdoc->TentativeActive()) {
sqt->pdoc->TentativeUndo();
} else {
// No tentative undo means start of this composition so
// Fill in any virtual spaces.
initialCompose = true;
}
sqt->view.imeCaretBlockOverride = false;
preeditPos = -1; // reset not to interrupt Qt::ImCursorRectangle.
const int rpLength = event->replacementLength();
if (rpLength != 0) {
// Qt has called setCommitString().
// Make room for the string to sit in.
const int rpStart = event->replacementStart();
const Scintilla::Position rpBase = sqt->CurrentPosition();
const Scintilla::Position start = sqt->pdoc->GetRelativePositionUTF16(rpBase, rpStart);
const Scintilla::Position end = sqt->pdoc->GetRelativePositionUTF16(start, rpLength);
sqt->pdoc->DeleteChars(start, end - start);
}
if (!event->commitString().isEmpty()) {
const QString &commitStr = event->commitString();
const int commitStrLen = commitStr.length();
for (int i = 0; i < commitStrLen;) {
const int ucWidth = commitStr.at(i).isHighSurrogate() ? 2 : 1;
const QString oneCharUTF16 = commitStr.mid(i, ucWidth);
const QByteArray oneChar = sqt->BytesForDocument(oneCharUTF16);
sqt->InsertCharacter(std::string_view(oneChar.data(), oneChar.length()), CharacterSource::DirectInput);
i += ucWidth;
}
} else if (!event->preeditString().isEmpty()) {
const QString preeditStr = event->preeditString();
const int preeditStrLen = preeditStr.length();
if (preeditStrLen == 0) {
sqt->ShowCaretAtCurrentPosition();
return;
}
if (initialCompose)
sqt->ClearBeforeTentativeStart();
sqt->pdoc->TentativeStart(); // TentativeActive() from now on.
// Fix candidate window position at the start of preeditString.
preeditPos = sqt->CurrentPosition();
std::vector<int> imeIndicator = MapImeIndicators(event);
for (int i = 0; i < preeditStrLen;) {
const int ucWidth = preeditStr.at(i).isHighSurrogate() ? 2 : 1;
const QString oneCharUTF16 = preeditStr.mid(i, ucWidth);
const QByteArray oneChar = sqt->BytesForDocument(oneCharUTF16);
const int oneCharLen = oneChar.length();
sqt->InsertCharacter(std::string_view(oneChar.data(), oneCharLen), CharacterSource::TentativeInput);
DrawImeIndicator(imeIndicator[i], oneCharLen);
i += ucWidth;
}
// Move IME carets.
int imeCaretPos = GetImeCaretPos(event);
int imeEndToImeCaretU16 = imeCaretPos - preeditStrLen;
const Sci::Position imeCaretPosDoc = sqt->pdoc->GetRelativePositionUTF16(sqt->CurrentPosition(), imeEndToImeCaretU16);
MoveImeCarets(- sqt->CurrentPosition() + imeCaretPosDoc);
if (IsHangul(preeditStr.at(0))) {
#ifndef Q_OS_WIN
if (imeCaretPos > 0) {
int oneCharBefore = sqt->pdoc->GetRelativePosition(sqt->CurrentPosition(), -1);
MoveImeCarets(- sqt->CurrentPosition() + oneCharBefore);
}
#endif
sqt->view.imeCaretBlockOverride = true;
}
sqt->EnsureCaretVisible();
}
sqt->ShowCaretAtCurrentPosition();
}
QVariant ScintillaEditBase::inputMethodQuery(Qt::InputMethodQuery query) const
{
const Scintilla::Position pos = send(SCI_GETCURRENTPOS);
const Scintilla::Position line = send(SCI_LINEFROMPOSITION, pos);
switch (query) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
// Qt 5 renamed ImMicroFocus to ImCursorRectangle then deprecated
// ImMicroFocus. Its the same value (2) and same description.
case Qt::ImCursorRectangle:
{
const Scintilla::Position startPos = (preeditPos >= 0) ? preeditPos : pos;
const Point pt = sqt->LocationFromPosition(startPos);
const int width = static_cast<int>(send(SCI_GETCARETWIDTH));
const int height = static_cast<int>(send(SCI_TEXTHEIGHT, line));
return QRectF(pt.x, pt.y, width, height).toRect();
}
#else
case Qt::ImMicroFocus:
{
const Scintilla::Position startPos = (preeditPos >= 0) ? preeditPos : pos;
const Point pt = sqt->LocationFromPosition(startPos);
const int width = static_cast<int>(send(SCI_GETCARETWIDTH));
const int height = static_cast<int>(send(SCI_TEXTHEIGHT, line));
return QRect(pt.x, pt.y, width, height);
}
#endif
case Qt::ImFont:
{
char fontName[64];
const sptr_t style = send(SCI_GETSTYLEAT, pos);
const int len = static_cast<int>(sends(SCI_STYLEGETFONT, style, fontName));
const int size = static_cast<int>(send(SCI_STYLEGETSIZE, style));
const bool italic = send(SCI_STYLEGETITALIC, style);
const int weight = send(SCI_STYLEGETBOLD, style) ? QFont::Bold : -1;
return QFont(QString::fromUtf8(fontName, len), size, weight, italic);
}
case Qt::ImCursorPosition:
{
const Scintilla::Position paraStart = sqt->pdoc->ParaUp(pos);
return static_cast<int>(sqt->pdoc->CountUTF16(paraStart, pos));
}
case Qt::ImSurroundingText:
{
const Scintilla::Position paraStart = sqt->pdoc->ParaUp(pos);
const Scintilla::Position paraEnd = sqt->pdoc->ParaDown(pos);
const std::string buffer = sqt->RangeText(paraStart, paraEnd);
return sqt->StringFromDocument(buffer.c_str());
}
case Qt::ImCurrentSelection:
{
QVarLengthArray<char,1024> buffer(send(SCI_GETSELTEXT)+1);
sends(SCI_GETSELTEXT, 0, buffer.data());
return sqt->StringFromDocument(buffer.constData());
}
default:
return QVariant();
}
}
void ScintillaEditBase::notifyParent(NotificationData scn)
{
emit notify(&scn);
switch (scn.nmhdr.code) {
case Notification::StyleNeeded:
emit styleNeeded(scn.position);
break;
case Notification::CharAdded:
emit charAdded(scn.ch);
break;
case Notification::SavePointReached:
emit savePointChanged(false);
break;
case Notification::SavePointLeft:
emit savePointChanged(true);
break;
case Notification::ModifyAttemptRO:
emit modifyAttemptReadOnly();
break;
case Notification::Key:
emit key(scn.ch);
break;
case Notification::DoubleClick:
emit doubleClick(scn.position, scn.line);
break;
case Notification::UpdateUI:
if (FlagSet(scn.updated, Update::Selection)) {
updateMicroFocus();
}
emit updateUi(scn.updated);
break;
case Notification::Modified:
{
const bool added = FlagSet(scn.modificationType, ModificationFlags::InsertText);
const bool deleted = FlagSet(scn.modificationType, ModificationFlags::DeleteText);
const Scintilla::Position length = send(SCI_GETTEXTLENGTH);
bool firstLineAdded = (added && length == 1) ||
(deleted && length == 0);
if (scn.linesAdded != 0) {
emit linesAdded(scn.linesAdded);
} else if (firstLineAdded) {
emit linesAdded(added ? 1 : -1);
}
const QByteArray bytes = QByteArray::fromRawData(scn.text, scn.text ? scn.length : 0);
emit modified(scn.modificationType, scn.position, scn.length,
scn.linesAdded, bytes, scn.line,
scn.foldLevelNow, scn.foldLevelPrev);
break;
}
case Notification::MacroRecord:
emit macroRecord(scn.message, scn.wParam, scn.lParam);
break;
case Notification::MarginClick:
emit marginClicked(scn.position, scn.modifiers, scn.margin);
break;
case Notification::NeedShown:
emit needShown(scn.position, scn.length);
break;
case Notification::Painted:
emit painted();
break;
case Notification::UserListSelection:
emit userListSelection();
break;
case Notification::URIDropped:
emit uriDropped(QString::fromUtf8(scn.text));
break;
case Notification::DwellStart:
emit dwellStart(scn.x, scn.y);
break;
case Notification::DwellEnd:
emit dwellEnd(scn.x, scn.y);
break;
case Notification::Zoom:
emit zoom(send(SCI_GETZOOM));
break;
case Notification::HotSpotClick:
emit hotSpotClick(scn.position, scn.modifiers);
break;
case Notification::HotSpotDoubleClick:
emit hotSpotDoubleClick(scn.position, scn.modifiers);
break;
case Notification::CallTipClick:
emit callTipClick();
break;
case Notification::AutoCSelection:
emit autoCompleteSelection(scn.lParam, QString::fromUtf8(scn.text));
break;
case Notification::AutoCCancelled:
emit autoCompleteCancelled();
break;
case Notification::FocusIn:
emit focusChanged(true);
break;
case Notification::FocusOut:
emit focusChanged(false);
break;
default:
return;
}
}
void ScintillaEditBase::event_command(uptr_t wParam, sptr_t lParam)
{
emit command(wParam, lParam);
}
KeyMod ScintillaEditBase::ModifiersOfKeyboard()
{
const bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier;
const bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier;
const bool alt = QApplication::keyboardModifiers() & Qt::AltModifier;
return ModifierFlags(shift, ctrl, alt);
}

View File

@ -0,0 +1,167 @@
//
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may be distributed.
//
// Author: Jason Haslam
//
// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
// @file ScintillaEditBase.h - Qt widget that wraps ScintillaQt and provides events and scrolling
#ifndef SCINTILLAEDITBASE_H
#define SCINTILLAEDITBASE_H
#include <cstddef>
#include <string_view>
#include <vector>
#include <optional>
#include <memory>
#include "Debugging.h"
#include "Geometry.h"
#include "ScintillaTypes.h"
#include "ScintillaMessages.h"
#include "ScintillaStructures.h"
#include "Platform.h"
#include "Scintilla.h"
#include <QAbstractScrollArea>
#include <QMimeData>
#include <QElapsedTimer>
namespace Scintilla::Internal {
class ScintillaQt;
class SurfaceImpl;
}
#ifndef EXPORT_IMPORT_API
#ifdef WIN32
#ifdef MAKING_LIBRARY
#define EXPORT_IMPORT_API __declspec(dllexport)
#else
// Defining dllimport upsets moc
#define EXPORT_IMPORT_API __declspec(dllimport)
//#define EXPORT_IMPORT_API
#endif
#else
#define EXPORT_IMPORT_API
#endif
#endif
class EXPORT_IMPORT_API ScintillaEditBase : public QAbstractScrollArea {
Q_OBJECT
public:
explicit ScintillaEditBase(QWidget *parent = 0);
virtual ~ScintillaEditBase();
virtual sptr_t send(
unsigned int iMessage,
uptr_t wParam = 0,
sptr_t lParam = 0) const;
virtual sptr_t sends(
unsigned int iMessage,
uptr_t wParam = 0,
const char *s = 0) const;
public slots:
// Scroll events coming from GUI to be sent to Scintilla.
void scrollHorizontal(int value);
void scrollVertical(int value);
// Emit Scintilla notifications as signals.
void notifyParent(Scintilla::NotificationData scn);
void event_command(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
signals:
void horizontalScrolled(int value);
void verticalScrolled(int value);
void horizontalRangeChanged(int max, int page);
void verticalRangeChanged(int max, int page);
void notifyChange();
void linesAdded(Scintilla::Position linesAdded);
// Clients can use this hook to add additional
// formats (e.g. rich text) to the MIME data.
void aboutToCopy(QMimeData *data);
// Scintilla Notifications
void styleNeeded(Scintilla::Position position);
void charAdded(int ch);
void savePointChanged(bool dirty);
void modifyAttemptReadOnly();
void key(int key);
void doubleClick(Scintilla::Position position, Scintilla::Position line);
void updateUi(Scintilla::Update updated);
void modified(Scintilla::ModificationFlags type, Scintilla::Position position, Scintilla::Position length, Scintilla::Position linesAdded,
const QByteArray &text, Scintilla::Position line, Scintilla::FoldLevel foldNow, Scintilla::FoldLevel foldPrev);
void macroRecord(Scintilla::Message message, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
void marginClicked(Scintilla::Position position, Scintilla::KeyMod modifiers, int margin);
void textAreaClicked(Scintilla::Position line, int modifiers);
void needShown(Scintilla::Position position, Scintilla::Position length);
void painted();
void userListSelection(); // Wants some args.
void uriDropped(const QString &uri);
void dwellStart(int x, int y);
void dwellEnd(int x, int y);
void zoom(int zoom);
void hotSpotClick(Scintilla::Position position, Scintilla::KeyMod modifiers);
void hotSpotDoubleClick(Scintilla::Position position, Scintilla::KeyMod modifiers);
void callTipClick();
void autoCompleteSelection(Scintilla::Position position, const QString &text);
void autoCompleteCancelled();
void focusChanged(bool focused);
// Base notifications for compatibility with other Scintilla implementations
void notify(Scintilla::NotificationData *pscn);
void command(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
// GUI event notifications needed under Qt
void buttonPressed(QMouseEvent *event);
void buttonReleased(QMouseEvent *event);
void keyPressed(QKeyEvent *event);
void resized();
protected:
bool event(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void inputMethodEvent(QInputMethodEvent *event) override;
QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
void scrollContentsBy(int, int) override {}
private:
Scintilla::Internal::ScintillaQt *sqt;
QElapsedTimer time;
Scintilla::Position preeditPos;
QString preeditString;
int wheelDelta;
static bool IsHangul(const QChar qchar);
void MoveImeCarets(Scintilla::Position offset);
void DrawImeIndicator(int indicator, int len);
static Scintilla::KeyMod ModifiersOfKeyboard();
};
#endif /* SCINTILLAEDITBASE_H */

View File

@ -0,0 +1,107 @@
#-------------------------------------------------
#
# Project created by QtCreator 2011-05-05T12:41:23
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
equals(QT_MAJOR_VERSION, 6): QT += core5compat
TARGET = ScintillaEditBase
TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.5.0
SOURCES += \
PlatQt.cpp \
ScintillaQt.cpp \
ScintillaEditBase.cpp \
../../src/XPM.cxx \
../../src/ViewStyle.cxx \
../../src/UniqueString.cxx \
../../src/UniConversion.cxx \
../../src/UndoHistory.cxx \
../../src/Style.cxx \
../../src/Selection.cxx \
../../src/ScintillaBase.cxx \
../../src/RunStyles.cxx \
../../src/RESearch.cxx \
../../src/PositionCache.cxx \
../../src/PerLine.cxx \
../../src/MarginView.cxx \
../../src/LineMarker.cxx \
../../src/KeyMap.cxx \
../../src/Indicator.cxx \
../../src/Geometry.cxx \
../../src/EditView.cxx \
../../src/Editor.cxx \
../../src/EditModel.cxx \
../../src/Document.cxx \
../../src/Decoration.cxx \
../../src/DBCS.cxx \
../../src/ContractionState.cxx \
../../src/CharClassify.cxx \
../../src/CharacterType.cxx \
../../src/CharacterCategoryMap.cxx \
../../src/ChangeHistory.cxx \
../../src/CellBuffer.cxx \
../../src/CaseFolder.cxx \
../../src/CaseConvert.cxx \
../../src/CallTip.cxx \
../../src/AutoComplete.cxx
HEADERS += \
PlatQt.h \
ScintillaQt.h \
ScintillaEditBase.h \
../../src/XPM.h \
../../src/ViewStyle.h \
../../src/UndoHistory.h \
../../src/UniConversion.h \
../../src/Style.h \
../../src/SplitVector.h \
../../src/Selection.h \
../../src/ScintillaBase.h \
../../src/RunStyles.h \
../../src/RESearch.h \
../../src/PositionCache.h \
../../src/Platform.h \
../../src/PerLine.h \
../../src/Partitioning.h \
../../src/LineMarker.h \
../../src/KeyMap.h \
../../src/Indicator.h \
../../src/Geometry.h \
../../src/Editor.h \
../../src/Document.h \
../../src/Decoration.h \
../../src/ContractionState.h \
../../src/CharClassify.h \
../../src/CharacterType.h \
../../src/CharacterCategoryMap.h \
../../src/ChangeHistory.h \
../../src/CellBuffer.h \
../../src/CaseFolder.h \
../../src/CaseConvert.h \
../../src/CallTip.h \
../../src/AutoComplete.h \
../../include/Scintilla.h \
../../include/ILexer.h
OTHER_FILES +=
INCLUDEPATH += ../../include ../../src
DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1
CONFIG(release, debug|release) {
DEFINES += NDEBUG=1
}
DESTDIR = ../../bin
macx {
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/
}

View File

@ -0,0 +1,872 @@
//
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may be distributed.
//
// Author: Jason Haslam
//
// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
// @file ScintillaQt.cpp - Qt specific subclass of ScintillaBase
#include "ScintillaQt.h"
#include "PlatQt.h"
#include <QApplication>
#include <QDrag>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QInputContext>
#endif
#include <QMimeData>
#include <QMenu>
#include <QTextCodec>
#include <QScrollBar>
#include <QTimer>
using namespace Scintilla;
using namespace Scintilla::Internal;
ScintillaQt::ScintillaQt(QAbstractScrollArea *parent)
: QObject(parent), scrollArea(parent), vMax(0), hMax(0), vPage(0), hPage(0),
haveMouseCapture(false), dragWasDropped(false),
rectangularSelectionModifier(SCMOD_ALT)
{
wMain = scrollArea->viewport();
imeInteraction = IMEInteraction::Inline;
// On macOS drawing text into a pixmap moves it around 1 pixel to
// the right compared to drawing it directly onto a window.
// Buffered drawing turned off by default to avoid this.
view.bufferedDraw = false;
Init();
std::fill(timers, std::end(timers), 0);
}
ScintillaQt::~ScintillaQt()
{
CancelTimers();
ChangeIdle(false);
}
void ScintillaQt::execCommand(QAction *action)
{
const int commandNum = action->data().toInt();
Command(commandNum);
}
#if defined(Q_OS_WIN)
static const QString sMSDEVColumnSelect("MSDEVColumnSelect");
static const QString sWrappedMSDEVColumnSelect("application/x-qt-windows-mime;value=\"MSDEVColumnSelect\"");
static const QString sVSEditorLineCutCopy("VisualStudioEditorOperationsLineCutCopyClipboardTag");
static const QString sWrappedVSEditorLineCutCopy("application/x-qt-windows-mime;value=\"VisualStudioEditorOperationsLineCutCopyClipboardTag\"");
#elif defined(Q_OS_MAC)
static const QString sScintillaRecPboardType("com.scintilla.utf16-plain-text.rectangular");
static const QString sScintillaRecMimeType("text/x-scintilla.utf16-plain-text.rectangular");
#else
// Linux
static const QString sMimeRectangularMarker("text/x-rectangular-marker");
#endif
#if defined(Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
class ScintillaRectangularMime : public QMacPasteboardMime {
public:
ScintillaRectangularMime() : QMacPasteboardMime(MIME_ALL) {
}
QString convertorName() {
return QString("ScintillaRectangularMime");
}
bool canConvert(const QString &mime, QString flav) {
return mimeFor(flav) == mime;
}
QString mimeFor(QString flav) {
if (flav == sScintillaRecPboardType)
return sScintillaRecMimeType;
return QString();
}
QString flavorFor(const QString &mime) {
if (mime == sScintillaRecMimeType)
return sScintillaRecPboardType;
return QString();
}
QVariant convertToMime(const QString & /* mime */, QList<QByteArray> data, QString /* flav */) {
QByteArray all;
foreach (QByteArray i, data) {
all += i;
}
return QVariant(all);
}
QList<QByteArray> convertFromMime(const QString & /* mime */, QVariant data, QString /* flav */) {
QByteArray a = data.toByteArray();
QList<QByteArray> l;
l.append(a);
return l;
}
};
// The Mime object registers itself but only want one for all Scintilla instances.
// Should delete at exit to help memory leak detection but that would be extra work
// and, since the clipboard exists after last Scintilla instance, may be complex.
static ScintillaRectangularMime *singletonMime = 0;
#endif
void ScintillaQt::Init()
{
rectangularSelectionModifier = SCMOD_ALT;
#if defined(Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
if (!singletonMime) {
singletonMime = new ScintillaRectangularMime();
QStringList slTypes(sScintillaRecPboardType);
qRegisterDraggedTypes(slTypes);
}
#endif
connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
this, SLOT(SelectionChanged()));
}
void ScintillaQt::Finalise()
{
CancelTimers();
ScintillaBase::Finalise();
}
void ScintillaQt::SelectionChanged()
{
bool nowPrimary = QApplication::clipboard()->ownsSelection();
if (nowPrimary != primarySelection) {
primarySelection = nowPrimary;
Redraw();
}
}
bool ScintillaQt::DragThreshold(Point ptStart, Point ptNow)
{
int xMove = std::abs(ptStart.x - ptNow.x);
int yMove = std::abs(ptStart.y - ptNow.y);
return (xMove > QApplication::startDragDistance()) ||
(yMove > QApplication::startDragDistance());
}
static QString StringFromSelectedText(const SelectionText &selectedText)
{
if (selectedText.codePage == SC_CP_UTF8) {
return QString::fromUtf8(selectedText.Data(), static_cast<int>(selectedText.Length()));
} else {
QTextCodec *codec = QTextCodec::codecForName(
CharacterSetID(selectedText.characterSet));
return codec->toUnicode(selectedText.Data(), static_cast<int>(selectedText.Length()));
}
}
static void AddRectangularToMime(QMimeData *mimeData, [[maybe_unused]] const QString &su)
{
#if defined(Q_OS_WIN)
// Add an empty marker
mimeData->setData(sMSDEVColumnSelect, QByteArray());
#elif defined(Q_OS_MAC)
// macOS gets marker + data to work with other implementations.
// Don't understand how this works but it does - the
// clipboard format is supposed to be UTF-16, not UTF-8.
mimeData->setData(sScintillaRecMimeType, su.toUtf8());
#else
// Linux
// Add an empty marker
mimeData->setData(sMimeRectangularMarker, QByteArray());
#endif
}
static void AddLineCutCopyToMime([[maybe_unused]] QMimeData *mimeData)
{
#if defined(Q_OS_WIN)
// Add an empty marker
mimeData->setData(sVSEditorLineCutCopy, QByteArray());
#endif
}
static bool IsRectangularInMime(const QMimeData *mimeData)
{
QStringList formats = mimeData->formats();
for (int i = 0; i < formats.size(); ++i) {
#if defined(Q_OS_WIN)
// Windows rectangular markers
// If rectangular copies made by this application, see base name.
if (formats[i] == sMSDEVColumnSelect)
return true;
// Otherwise see wrapped name.
if (formats[i] == sWrappedMSDEVColumnSelect)
return true;
#elif defined(Q_OS_MAC)
if (formats[i] == sScintillaRecMimeType)
return true;
#else
// Linux
if (formats[i] == sMimeRectangularMarker)
return true;
#endif
}
return false;
}
static bool IsLineCutCopyInMime(const QMimeData *mimeData)
{
QStringList formats = mimeData->formats();
for (int i = 0; i < formats.size(); ++i) {
#if defined(Q_OS_WIN)
// Visual Studio Line Cut/Copy markers
// If line cut/copy made by this application, see base name.
if (formats[i] == sVSEditorLineCutCopy)
return true;
// Otherwise see wrapped name.
if (formats[i] == sWrappedVSEditorLineCutCopy)
return true;
#endif
}
return false;
}
bool ScintillaQt::ValidCodePage(int codePage) const
{
return codePage == 0
|| codePage == SC_CP_UTF8
|| codePage == 932
|| codePage == 936
|| codePage == 949
|| codePage == 950
|| codePage == 1361;
}
std::string ScintillaQt::UTF8FromEncoded(std::string_view encoded) const {
if (IsUnicodeMode()) {
return std::string(encoded);
} else {
QTextCodec *codec = QTextCodec::codecForName(
CharacterSetID(CharacterSetOfDocument()));
QString text = codec->toUnicode(encoded.data(), static_cast<int>(encoded.length()));
return text.toStdString();
}
}
std::string ScintillaQt::EncodedFromUTF8(std::string_view utf8) const {
if (IsUnicodeMode()) {
return std::string(utf8);
} else {
QString text = QString::fromUtf8(utf8.data(), static_cast<int>(utf8.length()));
QTextCodec *codec = QTextCodec::codecForName(
CharacterSetID(CharacterSetOfDocument()));
QByteArray ba = codec->fromUnicode(text);
return std::string(ba.data(), ba.length());
}
}
void ScintillaQt::ScrollText(Sci::Line linesToMove)
{
int dy = vs.lineHeight * (linesToMove);
scrollArea->viewport()->scroll(0, dy);
}
void ScintillaQt::SetVerticalScrollPos()
{
scrollArea->verticalScrollBar()->setValue(topLine);
emit verticalScrolled(topLine);
}
void ScintillaQt::SetHorizontalScrollPos()
{
scrollArea->horizontalScrollBar()->setValue(xOffset);
emit horizontalScrolled(xOffset);
}
bool ScintillaQt::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage)
{
bool modified = false;
int vNewPage = nPage;
int vNewMax = nMax - vNewPage + 1;
if (vMax != vNewMax || vPage != vNewPage) {
vMax = vNewMax;
vPage = vNewPage;
modified = true;
scrollArea->verticalScrollBar()->setMaximum(vMax);
scrollArea->verticalScrollBar()->setPageStep(vPage);
emit verticalRangeChanged(vMax, vPage);
}
int hNewPage = GetTextRectangle().Width();
int hNewMax = (scrollWidth > hNewPage) ? scrollWidth - hNewPage : 0;
int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
if (hMax != hNewMax || hPage != hNewPage ||
scrollArea->horizontalScrollBar()->singleStep() != charWidth) {
hMax = hNewMax;
hPage = hNewPage;
modified = true;
scrollArea->horizontalScrollBar()->setMaximum(hMax);
scrollArea->horizontalScrollBar()->setPageStep(hPage);
scrollArea->horizontalScrollBar()->setSingleStep(charWidth);
emit horizontalRangeChanged(hMax, hPage);
}
return modified;
}
void ScintillaQt::ReconfigureScrollBars()
{
if (verticalScrollBarVisible) {
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
} else {
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
if (horizontalScrollBarVisible && !Wrapping()) {
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
} else {
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
}
void ScintillaQt::CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_)
{
QClipboard *clipboard = QApplication::clipboard();
QString su = StringFromSelectedText(selectedText);
QMimeData *mimeData = new QMimeData();
mimeData->setText(su);
if (selectedText.rectangular) {
AddRectangularToMime(mimeData, su);
}
if (selectedText.lineCopy) {
AddLineCutCopyToMime(mimeData);
}
// Allow client code to add additional data (e.g rich text).
emit aboutToCopy(mimeData);
clipboard->setMimeData(mimeData, clipboardMode_);
}
void ScintillaQt::Copy()
{
if (!sel.Empty()) {
SelectionText st;
CopySelectionRange(&st);
CopyToClipboard(st);
}
}
void ScintillaQt::CopyToClipboard(const SelectionText &selectedText)
{
CopyToModeClipboard(selectedText, QClipboard::Clipboard);
}
void ScintillaQt::PasteFromMode(QClipboard::Mode clipboardMode_)
{
QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(clipboardMode_);
bool isRectangular = IsRectangularInMime(mimeData);
bool isLine = SelectionEmpty() && IsLineCutCopyInMime(mimeData);
QString text = clipboard->text(clipboardMode_);
QByteArray utext = BytesForDocument(text);
std::string dest(utext.constData(), utext.length());
SelectionText selText;
selText.Copy(dest, pdoc->dbcsCodePage, CharacterSetOfDocument(), isRectangular, false);
UndoGroup ug(pdoc);
ClearSelection(multiPasteMode == MultiPaste::Each);
InsertPasteShape(selText.Data(), selText.Length(),
isRectangular ? PasteShape::rectangular : (isLine ? PasteShape::line : PasteShape::stream));
EnsureCaretVisible();
}
void ScintillaQt::Paste()
{
PasteFromMode(QClipboard::Clipboard);
}
void ScintillaQt::ClaimSelection()
{
if (QApplication::clipboard()->supportsSelection()) {
// X Windows has a 'primary selection' as well as the clipboard.
// Whenever the user selects some text, we become the primary selection
if (!sel.Empty()) {
primarySelection = true;
SelectionText st;
CopySelectionRange(&st);
CopyToModeClipboard(st, QClipboard::Selection);
} else {
primarySelection = false;
}
}
}
void ScintillaQt::NotifyChange()
{
emit notifyChange();
emit command(
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE),
reinterpret_cast<sptr_t>(wMain.GetID()));
}
void ScintillaQt::NotifyFocus(bool focus)
{
if (commandEvents) {
emit command(
Platform::LongFromTwoShorts
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS),
reinterpret_cast<sptr_t>(wMain.GetID()));
}
Editor::NotifyFocus(focus);
}
void ScintillaQt::NotifyParent(NotificationData scn)
{
scn.nmhdr.hwndFrom = wMain.GetID();
scn.nmhdr.idFrom = GetCtrlID();
emit notifyParent(scn);
}
void ScintillaQt::NotifyURIDropped(const char *uri)
{
NotificationData scn = {};
scn.nmhdr.code = Notification::URIDropped;
scn.text = uri;
NotifyParent(scn);
}
bool ScintillaQt::FineTickerRunning(TickReason reason)
{
return timers[static_cast<size_t>(reason)] != 0;
}
void ScintillaQt::FineTickerStart(TickReason reason, int millis, int /* tolerance */)
{
FineTickerCancel(reason);
timers[static_cast<size_t>(reason)] = startTimer(millis);
}
// CancelTimers cleans up all fine-ticker timers and is non-virtual to avoid warnings when
// called during destruction.
void ScintillaQt::CancelTimers()
{
for (size_t tr = static_cast<size_t>(TickReason::caret); tr <= static_cast<size_t>(TickReason::dwell); tr++) {
if (timers[tr]) {
killTimer(timers[tr]);
timers[tr] = 0;
}
}
}
void ScintillaQt::FineTickerCancel(TickReason reason)
{
const size_t reasonIndex = static_cast<size_t>(reason);
if (timers[reasonIndex]) {
killTimer(timers[reasonIndex]);
timers[reasonIndex] = 0;
}
}
void ScintillaQt::onIdle()
{
bool continueIdling = Idle();
if (!continueIdling) {
SetIdle(false);
}
}
bool ScintillaQt::ChangeIdle(bool on)
{
if (on) {
// Start idler, if it's not running.
if (!idler.state) {
idler.state = true;
QTimer *qIdle = new QTimer;
connect(qIdle, SIGNAL(timeout()), this, SLOT(onIdle()));
qIdle->start(0);
idler.idlerID = qIdle;
}
} else {
// Stop idler, if it's running
if (idler.state) {
idler.state = false;
QTimer *qIdle = static_cast<QTimer *>(idler.idlerID);
qIdle->stop();
disconnect(qIdle, SIGNAL(timeout()), nullptr, nullptr);
delete qIdle;
idler.idlerID = {};
}
}
return true;
}
bool ScintillaQt::SetIdle(bool on)
{
return ChangeIdle(on);
}
CharacterSet ScintillaQt::CharacterSetOfDocument() const
{
return vs.styles[STYLE_DEFAULT].characterSet;
}
const char *ScintillaQt::CharacterSetIDOfDocument() const
{
return CharacterSetID(CharacterSetOfDocument());
}
QString ScintillaQt::StringFromDocument(const char *s) const
{
if (IsUnicodeMode()) {
return QString::fromUtf8(s);
} else {
QTextCodec *codec = QTextCodec::codecForName(
CharacterSetID(CharacterSetOfDocument()));
return codec->toUnicode(s);
}
}
QByteArray ScintillaQt::BytesForDocument(const QString &text) const
{
if (IsUnicodeMode()) {
return text.toUtf8();
} else {
QTextCodec *codec = QTextCodec::codecForName(
CharacterSetID(CharacterSetOfDocument()));
return codec->fromUnicode(text);
}
}
namespace {
class CaseFolderDBCS : public CaseFolderTable {
QTextCodec *codec;
public:
explicit CaseFolderDBCS(QTextCodec *codec_) : codec(codec_) {
}
size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) override {
if ((lenMixed == 1) && (sizeFolded > 0)) {
folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
return 1;
} else if (codec) {
QString su = codec->toUnicode(mixed, static_cast<int>(lenMixed));
QString suFolded = su.toCaseFolded();
QByteArray bytesFolded = codec->fromUnicode(suFolded);
if (bytesFolded.length() < static_cast<int>(sizeFolded)) {
memcpy(folded, bytesFolded, bytesFolded.length());
return bytesFolded.length();
}
}
// Something failed so return a single NUL byte
folded[0] = '\0';
return 1;
}
};
}
std::unique_ptr<CaseFolder> ScintillaQt::CaseFolderForEncoding()
{
if (pdoc->dbcsCodePage == SC_CP_UTF8) {
return std::make_unique<CaseFolderUnicode>();
} else {
const char *charSetBuffer = CharacterSetIDOfDocument();
if (charSetBuffer) {
if (pdoc->dbcsCodePage == 0) {
std::unique_ptr<CaseFolderTable> pcf = std::make_unique<CaseFolderTable>();
QTextCodec *codec = QTextCodec::codecForName(charSetBuffer);
// Only for single byte encodings
for (int i=0x80; i<0x100; i++) {
char sCharacter[2] = "A";
sCharacter[0] = static_cast<char>(i);
QString su = codec->toUnicode(sCharacter, 1);
QString suFolded = su.toCaseFolded();
if (codec->canEncode(suFolded)) {
QByteArray bytesFolded = codec->fromUnicode(suFolded);
if (bytesFolded.length() == 1) {
pcf->SetTranslation(sCharacter[0], bytesFolded[0]);
}
}
}
return pcf;
} else {
return std::make_unique<CaseFolderDBCS>(QTextCodec::codecForName(charSetBuffer));
}
}
return nullptr;
}
}
std::string ScintillaQt::CaseMapString(const std::string &s, CaseMapping caseMapping)
{
if (s.empty() || (caseMapping == CaseMapping::same))
return s;
if (IsUnicodeMode()) {
std::string retMapped(s.length() * maxExpansionCaseConversion, 0);
size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(),
(caseMapping == CaseMapping::upper) ? CaseConversion::upper : CaseConversion::lower);
retMapped.resize(lenMapped);
return retMapped;
}
QTextCodec *codec = QTextCodec::codecForName(CharacterSetIDOfDocument());
QString text = codec->toUnicode(s.c_str(), static_cast<int>(s.length()));
if (caseMapping == CaseMapping::upper) {
text = text.toUpper();
} else {
text = text.toLower();
}
QByteArray bytes = BytesForDocument(text);
return std::string(bytes.data(), bytes.length());
}
void ScintillaQt::SetMouseCapture(bool on)
{
// This is handled automatically by Qt
if (mouseDownCaptures) {
haveMouseCapture = on;
}
}
bool ScintillaQt::HaveMouseCapture()
{
return haveMouseCapture;
}
void ScintillaQt::StartDrag()
{
inDragDrop = DragDrop::dragging;
dropWentOutside = true;
if (drag.Length()) {
QMimeData *mimeData = new QMimeData;
QString sText = StringFromSelectedText(drag);
mimeData->setText(sText);
if (drag.rectangular) {
AddRectangularToMime(mimeData, sText);
}
// This QDrag is not freed as that causes a crash on Linux
QDrag *dragon = new QDrag(scrollArea);
dragon->setMimeData(mimeData);
Qt::DropAction dropAction = dragon->exec(static_cast<Qt::DropActions>(Qt::CopyAction|Qt::MoveAction));
if ((dropAction == Qt::MoveAction) && dropWentOutside) {
// Remove dragged out text
ClearSelection();
}
}
inDragDrop = DragDrop::none;
SetDragPosition(SelectionPosition(Sci::invalidPosition));
}
class CallTipImpl : public QWidget {
public:
explicit CallTipImpl(CallTip *pct_)
: QWidget(nullptr, Qt::ToolTip),
pct(pct_)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
setWindowFlag(Qt::WindowTransparentForInput);
#endif
}
void paintEvent(QPaintEvent *) override
{
if (pct->inCallTipMode) {
std::unique_ptr<Surface> surfaceWindow = Surface::Allocate(Technology::Default);
surfaceWindow->Init(this);
surfaceWindow->SetMode(SurfaceMode(pct->codePage, false));
pct->PaintCT(surfaceWindow.get());
}
}
private:
CallTip *pct;
};
void ScintillaQt::CreateCallTipWindow(PRectangle rc)
{
if (!ct.wCallTip.Created()) {
QWidget *pCallTip = new CallTipImpl(&ct);
ct.wCallTip = pCallTip;
pCallTip->move(rc.left, rc.top);
pCallTip->resize(rc.Width(), rc.Height());
}
}
void ScintillaQt::AddToPopUp(const char *label,
int cmd,
bool enabled)
{
QMenu *menu = static_cast<QMenu *>(popup.GetID());
QString text(label);
if (text.isEmpty()) {
menu->addSeparator();
} else {
QAction *action = menu->addAction(text);
action->setData(cmd);
action->setEnabled(enabled);
}
// Make sure the menu's signal is connected only once.
menu->disconnect();
connect(menu, SIGNAL(triggered(QAction*)),
this, SLOT(execCommand(QAction*)));
}
sptr_t ScintillaQt::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam)
{
try {
switch (iMessage) {
case Message::SetIMEInteraction:
// Only inline IME supported on Qt
break;
case Message::GrabFocus:
scrollArea->setFocus(Qt::OtherFocusReason);
break;
case Message::GetDirectFunction:
return reinterpret_cast<sptr_t>(DirectFunction);
case Message::GetDirectStatusFunction:
return reinterpret_cast<sptr_t>(DirectStatusFunction);
case Message::GetDirectPointer:
return reinterpret_cast<sptr_t>(this);
case Message::SetRectangularSelectionModifier:
rectangularSelectionModifier = static_cast<int>(wParam);
break;
case Message::GetRectangularSelectionModifier:
return rectangularSelectionModifier;
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
} catch (std::bad_alloc &) {
errorStatus = Status::BadAlloc;
} catch (...) {
errorStatus = Status::Failure;
}
return 0;
}
sptr_t ScintillaQt::DefWndProc(Message, uptr_t, sptr_t)
{
return 0;
}
sptr_t ScintillaQt::DirectFunction(
sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam)
{
ScintillaQt *sci = reinterpret_cast<ScintillaQt *>(ptr);
return sci->WndProc(static_cast<Message>(iMessage), wParam, lParam);
}
sptr_t ScintillaQt::DirectStatusFunction(
sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus)
{
ScintillaQt *sci = reinterpret_cast<ScintillaQt *>(ptr);
const sptr_t returnValue = sci->WndProc(static_cast<Message>(iMessage), wParam, lParam);
*pStatus = static_cast<int>(sci->errorStatus);
return returnValue;
}
// Additions to merge in Scientific Toolworks widget structure
void ScintillaQt::PartialPaint(const PRectangle &rect)
{
rcPaint = rect;
paintState = PaintState::painting;
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
AutoSurface surfacePaint(this);
Paint(surfacePaint, rcPaint);
surfacePaint->Release();
if (paintState == PaintState::abandoned) {
// FIXME: Failure to paint the requested rectangle in each
// paint event causes flicker on some platforms (Mac?)
// Paint rect immediately.
paintState = PaintState::painting;
paintingAllText = true;
AutoSurface surface(this);
Paint(surface, rcPaint);
surface->Release();
// Queue a full repaint.
scrollArea->viewport()->update();
}
paintState = PaintState::notPainting;
}
void ScintillaQt::DragEnter(const Point &point)
{
SetDragPosition(SPositionFromLocation(point,
false, false, UserVirtualSpace()));
}
void ScintillaQt::DragMove(const Point &point)
{
SetDragPosition(SPositionFromLocation(point,
false, false, UserVirtualSpace()));
}
void ScintillaQt::DragLeave()
{
SetDragPosition(SelectionPosition(Sci::invalidPosition));
}
void ScintillaQt::Drop(const Point &point, const QMimeData *data, bool move)
{
QString text = data->text();
bool rectangular = IsRectangularInMime(data);
QByteArray bytes = BytesForDocument(text);
int len = bytes.length();
SelectionPosition movePos = SPositionFromLocation(point,
false, false, UserVirtualSpace());
DropAt(movePos, bytes, len, move, rectangular);
}
void ScintillaQt::DropUrls(const QMimeData *data)
{
foreach(const QUrl &url, data->urls()) {
NotifyURIDropped(url.toString().toUtf8().constData());
}
}
void ScintillaQt::timerEvent(QTimerEvent *event)
{
for (size_t tr=static_cast<size_t>(TickReason::caret); tr<=static_cast<size_t>(TickReason::dwell); tr++) {
if (timers[tr] == event->timerId()) {
TickFor(static_cast<TickReason>(tr));
}
}
}

View File

@ -0,0 +1,185 @@
//
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may be distributed.
//
// Author: Jason Haslam
//
// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware
// @file ScintillaQt.h - Qt specific subclass of ScintillaBase
#ifndef SCINTILLAQT_H
#define SCINTILLAQT_H
#include <cstddef>
#include <cstdlib>
#include <cstdint>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include <map>
#include <set>
#include <optional>
#include <algorithm>
#include <memory>
#include "ScintillaTypes.h"
#include "ScintillaMessages.h"
#include "ScintillaStructures.h"
#include "Scintilla.h"
#include "Debugging.h"
#include "Geometry.h"
#include "Platform.h"
#include "ILoader.h"
#include "ILexer.h"
#include "CharacterCategoryMap.h"
#include "Position.h"
#include "UniqueString.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "ContractionState.h"
#include "CellBuffer.h"
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
#include "LineMarker.h"
#include "Style.h"
#include "AutoComplete.h"
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "CaseFolder.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
#include "EditModel.h"
#include "MarginView.h"
#include "EditView.h"
#include "Editor.h"
#include "ScintillaBase.h"
#include "CaseConvert.h"
#include <QObject>
#include <QAbstractScrollArea>
#include <QAction>
#include <QClipboard>
#include <QPaintEvent>
class ScintillaEditBase;
namespace Scintilla::Internal {
class ScintillaQt : public QObject, public ScintillaBase {
Q_OBJECT
public:
explicit ScintillaQt(QAbstractScrollArea *parent);
virtual ~ScintillaQt();
signals:
void horizontalScrolled(int value);
void verticalScrolled(int value);
void horizontalRangeChanged(int max, int page);
void verticalRangeChanged(int max, int page);
void notifyParent(Scintilla::NotificationData scn);
void notifyChange();
// Clients can use this hook to add additional
// formats (e.g. rich text) to the MIME data.
void aboutToCopy(QMimeData *data);
void command(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
private slots:
void onIdle();
void execCommand(QAction *action);
void SelectionChanged();
private:
void Init();
void Finalise() override;
bool DragThreshold(Point ptStart, Point ptNow) override;
bool ValidCodePage(int codePage) const override;
std::string UTF8FromEncoded(std::string_view encoded) const override;
std::string EncodedFromUTF8(std::string_view utf8) const override;
private:
void ScrollText(Sci::Line linesToMove) override;
void SetVerticalScrollPos() override;
void SetHorizontalScrollPos() override;
bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override;
void ReconfigureScrollBars() override;
void CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_);
void Copy() override;
void CopyToClipboard(const SelectionText &selectedText) override;
void PasteFromMode(QClipboard::Mode clipboardMode_);
void Paste() override;
void ClaimSelection() override;
void NotifyChange() override;
void NotifyFocus(bool focus) override;
void NotifyParent(Scintilla::NotificationData scn) override;
void NotifyURIDropped(const char *uri);
int timers[static_cast<size_t>(TickReason::dwell)+1]{};
bool FineTickerRunning(TickReason reason) override;
void FineTickerStart(TickReason reason, int millis, int tolerance) override;
void CancelTimers();
void FineTickerCancel(TickReason reason) override;
bool ChangeIdle(bool on);
bool SetIdle(bool on) override;
void SetMouseCapture(bool on) override;
bool HaveMouseCapture() override;
void StartDrag() override;
Scintilla::CharacterSet CharacterSetOfDocument() const;
const char *CharacterSetIDOfDocument() const;
QString StringFromDocument(const char *s) const;
QByteArray BytesForDocument(const QString &text) const;
std::unique_ptr<CaseFolder> CaseFolderForEncoding() override;
std::string CaseMapString(const std::string &s, CaseMapping caseMapping) override;
void CreateCallTipWindow(PRectangle rc) override;
void AddToPopUp(const char *label, int cmd, bool enabled) override;
sptr_t WndProc(Scintilla::Message iMessage, uptr_t wParam, sptr_t lParam) override;
sptr_t DefWndProc(Scintilla::Message iMessage, uptr_t wParam, sptr_t lParam) override;
static sptr_t DirectFunction(sptr_t ptr,
unsigned int iMessage, uptr_t wParam, sptr_t lParam);
static sptr_t DirectStatusFunction(sptr_t ptr,
unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus);
protected:
void PartialPaint(const PRectangle &rect);
void DragEnter(const Point &point);
void DragMove(const Point &point);
void DragLeave();
void Drop(const Point &point, const QMimeData *data, bool move);
void DropUrls(const QMimeData *data);
void timerEvent(QTimerEvent *event) override;
private:
QAbstractScrollArea *scrollArea;
int vMax, hMax; // Scroll bar maximums.
int vPage, hPage; // Scroll bar page sizes.
bool haveMouseCapture;
bool dragWasDropped;
int rectangularSelectionModifier;
friend class ::ScintillaEditBase;
};
}
#endif /* SCINTILLAQT_H */