reuse qscintilla
This commit is contained in:
parent
11f3089ad9
commit
0049f4f1e1
|
@ -17,17 +17,6 @@ SOURCES += \
|
||||||
editorlist.cpp \
|
editorlist.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
qsynedit/CodeFolding.cpp \
|
|
||||||
qsynedit/Constants.cpp \
|
|
||||||
qsynedit/KeyStrokes.cpp \
|
|
||||||
qsynedit/MiscClasses.cpp \
|
|
||||||
qsynedit/MiscProcs.cpp \
|
|
||||||
qsynedit/SynEdit.cpp \
|
|
||||||
qsynedit/TextBuffer.cpp \
|
|
||||||
qsynedit/TextDrawer.cpp \
|
|
||||||
qsynedit/highlighter/base.cpp \
|
|
||||||
qsynedit/highlighter/composition.cpp \
|
|
||||||
qsynedit/highlighter/cpp.cpp \
|
|
||||||
settingsdialog/compilersetdirectorieswidget.cpp \
|
settingsdialog/compilersetdirectorieswidget.cpp \
|
||||||
settingsdialog/compilersetoptionwidget.cpp \
|
settingsdialog/compilersetoptionwidget.cpp \
|
||||||
settings.cpp \
|
settings.cpp \
|
||||||
|
@ -45,18 +34,6 @@ HEADERS += \
|
||||||
editor.h \
|
editor.h \
|
||||||
editorlist.h \
|
editorlist.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
qsynedit/CodeFolding.h \
|
|
||||||
qsynedit/Constants.h \
|
|
||||||
qsynedit/KeyStrokes.h \
|
|
||||||
qsynedit/MiscClasses.h \
|
|
||||||
qsynedit/MiscProcs.h \
|
|
||||||
qsynedit/SynEdit.h \
|
|
||||||
qsynedit/TextBuffer.h \
|
|
||||||
qsynedit/TextDrawer.h \
|
|
||||||
qsynedit/Types.h \
|
|
||||||
qsynedit/highlighter/base.h \
|
|
||||||
qsynedit/highlighter/composition.h \
|
|
||||||
qsynedit/highlighter/cpp.h \
|
|
||||||
settingsdialog/compilersetdirectorieswidget.h \
|
settingsdialog/compilersetdirectorieswidget.h \
|
||||||
settingsdialog/compilersetoptionwidget.h \
|
settingsdialog/compilersetoptionwidget.h \
|
||||||
settings.h \
|
settings.h \
|
||||||
|
@ -84,3 +61,9 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
icons.qrc
|
icons.qrc
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../QScintilla/src/release/ -lqscintilla2_qt5d
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../QScintilla/src/debug/ -lqscintilla2_qt5d
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../../QScintilla/src/ -lqscintilla2_qt5d
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../QScintilla/src
|
||||||
|
DEPENDPATH += $$PWD/../../QScintilla/src
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "systemconsts.h"
|
#include "systemconsts.h"
|
||||||
#include <Qsci/qscilexercpp.h>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <Qsci/qscilexercpp.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -290,8 +290,9 @@ void Editor::onCursorPositionChanged(int line, int index) {
|
||||||
long pos = getCursorPosition();
|
long pos = getCursorPosition();
|
||||||
long start = SendScintilla(SCI_WORDSTARTPOSITION,pos,false);
|
long start = SendScintilla(SCI_WORDSTARTPOSITION,pos,false);
|
||||||
long end = SendScintilla(SCI_WORDENDPOSITION,pos,false);
|
long end = SendScintilla(SCI_WORDENDPOSITION,pos,false);
|
||||||
|
long style = SendScintilla(SCI_GETSTYLEAT,pos,false);
|
||||||
|
|
||||||
qDebug()<<start<<end<<text(start,end);
|
qDebug()<<start<<end<<style<<text(start,end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::onLinesChanged(int startLine, int count) {
|
void Editor::onLinesChanged(int startLine, int count) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
|
||||||
class SaveException: public std::exception {
|
class SaveException: public std::exception {
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#include "CodeFolding.h"
|
|
||||||
|
|
||||||
int SynEditFoldRegions::count()
|
|
||||||
{
|
|
||||||
return fRegions.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditFoldRegions::add(bool addEnding, const QChar &openSymbol, const QChar &closeSymbol, const QString &highlight)
|
|
||||||
{
|
|
||||||
PSynEditFoldRegion region = std::make_shared<SynEditFoldRegion>();
|
|
||||||
region->addEnding = addEnding;
|
|
||||||
region->openSymbol = openSymbol;
|
|
||||||
region->closeSymbol = closeSymbol;
|
|
||||||
region->highlight = highlight;
|
|
||||||
fRegions.push_back(region);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditFoldRegion SynEditFoldRegions::get(int index)
|
|
||||||
{
|
|
||||||
return fRegions.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditCodeFolding::SynEditCodeFolding():
|
|
||||||
indentGuides(true),
|
|
||||||
showCollapsedLine(true),
|
|
||||||
collapsedLineColor(QColor("black")),
|
|
||||||
folderBarLinesColor(QColor("black")),
|
|
||||||
indentGuidesColor("gray")
|
|
||||||
{
|
|
||||||
foldRegions.add(true,'{','}',"Symbol");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SynEditFoldRange::parentCollapsed()
|
|
||||||
{
|
|
||||||
PSynEditFoldRange parentFold = parent;
|
|
||||||
// Find first parent that is collapsed
|
|
||||||
while (parentFold) {
|
|
||||||
if (parentFold->collapsed) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
parentFold = parentFold->parent;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditFoldRange::move(int count)
|
|
||||||
{
|
|
||||||
fromLine += count;
|
|
||||||
toLine += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditFoldRange::SynEditFoldRange(PSynEditFoldRange aParent, PSynEditFoldRanges aAllFold, int aFromLine, PSynEditFoldRegion aFoldRegion, int aToLine):
|
|
||||||
fromLine(aFromLine),
|
|
||||||
toLine(aToLine),
|
|
||||||
linesCollapsed(0),
|
|
||||||
collapsed(false),
|
|
||||||
allFoldRanges(aAllFold),
|
|
||||||
foldRegion(aFoldRegion),
|
|
||||||
hintMarkLeft(0),
|
|
||||||
parent(aParent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PSynEditFoldRange SynEditFoldRanges::foldRange(int index)
|
|
||||||
{
|
|
||||||
return ranges[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditFoldRanges::count()
|
|
||||||
{
|
|
||||||
return ranges.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditFoldRanges::SynEditFoldRanges()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditFoldRange SynEditFoldRanges::addByParts(PSynEditFoldRange aParent, PSynEditFoldRanges aAllFold, int aFromLine, PSynEditFoldRegion aFoldRegion, int aToLine)
|
|
||||||
{
|
|
||||||
PSynEditFoldRange range=std::make_shared<SynEditFoldRange>(aParent,aAllFold, aFromLine,aFoldRegion,aToLine);
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditFoldRanges::remove(int index)
|
|
||||||
{
|
|
||||||
ranges.erase(ranges.begin()+index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditFoldRanges::addObject(PSynEditFoldRange foldRange)
|
|
||||||
{
|
|
||||||
ranges.push_back(foldRange);
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
#ifndef CODEFOLDING_H
|
|
||||||
#define CODEFOLDING_H
|
|
||||||
#include <QColor>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <QVector>
|
|
||||||
|
|
||||||
struct SynEditFoldRegion;
|
|
||||||
typedef std::shared_ptr<SynEditFoldRegion> PSynEditFoldRegion;
|
|
||||||
|
|
||||||
class SynEditFoldRegions {
|
|
||||||
private:
|
|
||||||
std::vector<PSynEditFoldRegion> fRegions;
|
|
||||||
public:
|
|
||||||
int count();
|
|
||||||
int add(bool addEnding, const QChar& openSymbol, const QChar& closeSymbol, const QString& highlight);
|
|
||||||
PSynEditFoldRegion get(int index);
|
|
||||||
};
|
|
||||||
typedef std::shared_ptr<SynEditFoldRegions> PSynFoldRegions;
|
|
||||||
|
|
||||||
|
|
||||||
struct SynEditFoldRegion {
|
|
||||||
bool addEnding;
|
|
||||||
SynEditFoldRegions subFoldRegions;
|
|
||||||
QChar openSymbol;
|
|
||||||
QChar closeSymbol;
|
|
||||||
QString highlight;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SynEditCodeFolding {
|
|
||||||
bool indentGuides;
|
|
||||||
bool showCollapsedLine;
|
|
||||||
QColor collapsedLineColor;
|
|
||||||
QColor folderBarLinesColor;
|
|
||||||
QColor indentGuidesColor;
|
|
||||||
SynEditFoldRegions foldRegions;
|
|
||||||
SynEditCodeFolding();
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynEditFoldRange;
|
|
||||||
typedef std::shared_ptr<SynEditFoldRange> PSynEditFoldRange;
|
|
||||||
class SynEditFoldRanges;
|
|
||||||
typedef std::shared_ptr<SynEditFoldRanges> PSynEditFoldRanges;
|
|
||||||
|
|
||||||
class SynEditFoldRanges{
|
|
||||||
public:
|
|
||||||
QVector<PSynEditFoldRange> ranges;
|
|
||||||
PSynEditFoldRange foldRange(int index);
|
|
||||||
int count();
|
|
||||||
SynEditFoldRanges();
|
|
||||||
PSynEditFoldRange addByParts(PSynEditFoldRange aParent, PSynEditFoldRanges aAllFold,
|
|
||||||
int aFromLine, PSynEditFoldRegion aFoldRegion, int aToLine);
|
|
||||||
|
|
||||||
int remove(int index);
|
|
||||||
void addObject(PSynEditFoldRange foldRange);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A single fold
|
|
||||||
class SynEditFoldRange {
|
|
||||||
public:
|
|
||||||
int fromLine; // Beginning line
|
|
||||||
int toLine; // End line
|
|
||||||
int linesCollapsed; // Number of collapsed lines
|
|
||||||
SynEditFoldRanges subFoldRanges; // Sub fold ranges
|
|
||||||
bool collapsed; // Is collapsed?
|
|
||||||
PSynEditFoldRanges allFoldRanges;// TAllFoldRanges pointer
|
|
||||||
PSynEditFoldRegion foldRegion; // FoldRegion
|
|
||||||
int hintMarkLeft;
|
|
||||||
PSynEditFoldRange parent;
|
|
||||||
bool parentCollapsed();
|
|
||||||
void move(int count);
|
|
||||||
explicit SynEditFoldRange(PSynEditFoldRange aParent, PSynEditFoldRanges aAllFold,
|
|
||||||
int aFromLine, PSynEditFoldRegion aFoldRegion, int aToLine);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CODEFOLDING_H
|
|
|
@ -1,5 +0,0 @@
|
||||||
#include "Constants.h"
|
|
||||||
const QSet<QChar> SynWordBreakChars{'.', ',', ';', ':',
|
|
||||||
'"', '\'', '!', '?', '[', ']', '(', ')', '{', '}', '^', '-', '=', '+',
|
|
||||||
'-', '*', '/', '\\', '|'};
|
|
||||||
const QChar SynTabChar('\t');
|
|
|
@ -1,160 +0,0 @@
|
||||||
#ifndef CONSTANTS_H
|
|
||||||
#define CONSTANTS_H
|
|
||||||
#include <QSet>
|
|
||||||
#include <QChar>
|
|
||||||
|
|
||||||
extern const QSet<QChar> SynWordBreakChars;
|
|
||||||
extern const QChar SynTabChar;
|
|
||||||
|
|
||||||
#define SYN_ATTR_COMMENT 0
|
|
||||||
#define SYN_ATTR_IDENTIFIER 1
|
|
||||||
#define SYN_ATTR_KEYWORD 2
|
|
||||||
#define SYN_ATTR_STRING 3
|
|
||||||
#define SYN_ATTR_WHITESPACE 4
|
|
||||||
#define SYN_ATTR_SYMBOL 5
|
|
||||||
|
|
||||||
// names for highlighter attributes
|
|
||||||
#define SYNS_AttrAreaAIdentifier "Area A Identifier"
|
|
||||||
#define SYNS_AttrArrowHead "ArrowHead"
|
|
||||||
#define SYNS_AttrAsm "Asm"
|
|
||||||
#define SYNS_AttrAsmComment "Asm Comment"
|
|
||||||
#define SYNS_AttrAsmKey "Asm Key"
|
|
||||||
#define SYNS_AttrAssembler "Assembler"
|
|
||||||
#define SYNS_AttrAttribute "Attribute"
|
|
||||||
#define SYNS_AttrAttributeName "Attribute Name"
|
|
||||||
#define SYNS_AttrAttributeValue "Attribute Value"
|
|
||||||
#define SYNS_AttrBasicTypes "Basic Types"
|
|
||||||
#define SYNS_AttrBlock "Block"
|
|
||||||
#define SYNS_AttrBoolean "Boolean value"
|
|
||||||
#define SYNS_AttrBrackets "Brackets"
|
|
||||||
#define SYNS_AttrCDATASection "CDATA Section"
|
|
||||||
#define SYNS_AttrCharacter "Character"
|
|
||||||
#define SYNS_AttrClass "Class"
|
|
||||||
#define SYNS_AttrColor "Color Value"
|
|
||||||
#define SYNS_AttrComment "Comment"
|
|
||||||
#define SYNS_AttrCondition "Condition"
|
|
||||||
#define SYNS_AttrConditionalComment "Conditional Comment"
|
|
||||||
#define SYNS_AttrDataType "Data Type"
|
|
||||||
#define SYNS_AttrDebugLines "Debugging Lines"
|
|
||||||
#define SYNS_AttrDefaultPackage "Default Packages"
|
|
||||||
#define SYNS_AttrDelimitedIdentifier "Delimited Identifier"
|
|
||||||
#define SYNS_AttrDir "Direction"
|
|
||||||
#define SYNS_AttrDirections "Directions"
|
|
||||||
#define SYNS_AttrDirective "Directive"
|
|
||||||
#define SYNS_AttrDOCTYPESection "DOCTYPE Section"
|
|
||||||
#define SYNS_AttrDocumentation "Documentation"
|
|
||||||
#define SYNS_AttrElementName "Element Name"
|
|
||||||
#define SYNS_AttrEmbedSQL "Embedded SQL"
|
|
||||||
#define SYNS_AttrEmbedText "Embedded Text"
|
|
||||||
#define SYNS_AttrEntityReference "Entity Reference"
|
|
||||||
#define SYNS_AttrEscapeAmpersand "Escape Ampersand"
|
|
||||||
#define SYNS_AttrEvent "Event"
|
|
||||||
#define SYNS_AttrException "Exception"
|
|
||||||
#define SYNS_AttrFirstTri "FirstTri"
|
|
||||||
#define SYNS_AttrFloat "Float"
|
|
||||||
#define SYNS_AttrForm "Form"
|
|
||||||
#define SYNS_AttrFourthTri "FourthTri"
|
|
||||||
#define SYNS_AttrFunction "Function"
|
|
||||||
#define SYNS_AttrFunctionParameter "Function Parameter"
|
|
||||||
#define SYNS_AttrGlobalVariable "Global variable"
|
|
||||||
#define SYNS_AttrHexadecimal "Hexadecimal"
|
|
||||||
#define SYNS_AttrIcon "Icon Reference"
|
|
||||||
#define SYNS_AttrIdentifier "Identifier"
|
|
||||||
#define SYNS_AttrIllegalChar "Illegal Char"
|
|
||||||
#define SYNS_AttrInclude "Include"
|
|
||||||
#define SYNS_AttrIndicator "Indicator Area"
|
|
||||||
#define SYNS_AttrIndirect "Indirect"
|
|
||||||
#define SYNS_AttrInvalidSymbol "Invalid Symbol"
|
|
||||||
#define SYNS_AttrInternalFunction "Internal Function"
|
|
||||||
#define SYNS_AttrKey "Key"
|
|
||||||
#define SYNS_AttrLabel "Label"
|
|
||||||
#define SYNS_AttrLace "Lace"
|
|
||||||
#define SYNS_AttrLocalVariable "Local Variable"
|
|
||||||
#define SYNS_AttrLine "Line"
|
|
||||||
#define SYNS_AttrMacro "Macro"
|
|
||||||
#define SYNS_AttrMarker "Marker"
|
|
||||||
#define SYNS_AttrMathMode "Math Mode"
|
|
||||||
#define SYNS_AttrMessage "Message"
|
|
||||||
#define SYNS_AttrMiscellaneous "Miscellaneous"
|
|
||||||
#define SYNS_AttrNamespaceAttrName "Namespace Attribute Name"
|
|
||||||
#define SYNS_AttrNamespaceAttrValue "Namespace Attribute Value"
|
|
||||||
#define SYNS_AttrNonReservedKeyword "Non-reserved Keyword"
|
|
||||||
#define SYNS_AttrNull "Null"
|
|
||||||
#define SYNS_AttrNumber "Number"
|
|
||||||
#define SYNS_AttrOctal "Octal"
|
|
||||||
#define SYNS_AttrOperator "Operator"
|
|
||||||
#define SYNS_AttrOperatorAndSymbols "Operator And Symbols"
|
|
||||||
#define SYNS_AttrOpLine "OpLine"
|
|
||||||
#define SYNS_AttrPLSQL "PL/SQL Reserved Word"
|
|
||||||
#define SYNS_AttrPragma "Pragma"
|
|
||||||
#define SYNS_AttrPredefined "Predefined"
|
|
||||||
#define SYNS_AttrPreprocessor "Preprocessor"
|
|
||||||
#define SYNS_AttrProcessingInstr "Processing Instruction"
|
|
||||||
#define SYNS_AttrQuad "Quad"
|
|
||||||
#define SYNS_AttrQualifier "Qualifier"
|
|
||||||
#define SYNS_AttrRegister "Register"
|
|
||||||
#define SYNS_AttrReservedWord "Reserved Word"
|
|
||||||
#define SYNS_AttrResultValue "Result Value"
|
|
||||||
#define SYNS_AttrRoundBracket "Round Bracket"
|
|
||||||
#define SYNS_AttrRpl "Rpl"
|
|
||||||
#define SYNS_AttrRplKey "Rpl Key"
|
|
||||||
#define SYNS_AttrRplComment "Rpl Comment"
|
|
||||||
#define SYNS_AttrSASM "SASM"
|
|
||||||
#define SYNS_AttrSASMComment "SASM Comment"
|
|
||||||
#define SYNS_AttrSASMKey "SASM Key"
|
|
||||||
#define SYNS_AttrSecondReservedWord "Second Reserved Word"
|
|
||||||
#define SYNS_AttrSecondTri "SecondTri"
|
|
||||||
#define SYNS_AttrSection "Section"
|
|
||||||
#define SYNS_AttrSequence "Sequence Number Area"
|
|
||||||
#define SYNS_AttrShape "Shape"
|
|
||||||
#define SYNS_AttrSingleString "Single Quoted String"
|
|
||||||
#define SYNS_AttrSpace "Space"
|
|
||||||
#define SYNS_AttrSpecialVariable "Special Variable"
|
|
||||||
#define SYNS_AttrSQLKey "SQL Keyword"
|
|
||||||
#define SYNS_AttrSQLPlus "SQL*Plus Command"
|
|
||||||
#define SYNS_AttrSquareBracket "Square Bracket"
|
|
||||||
#define SYNS_AttrString "String"
|
|
||||||
#define SYNS_AttrStringEscapeSequences "Escape sequences"
|
|
||||||
#define SYNS_AttrSymbol "Symbol"
|
|
||||||
#define SYNS_AttrSyntaxError "Syntax Error"
|
|
||||||
#define SYNS_AttrSystem "System Functions and Variables"
|
|
||||||
#define SYNS_AttrSystemValue "System Value"
|
|
||||||
#define SYNS_AttrTagArea "Tag Area"
|
|
||||||
#define SYNS_AttrTableName "Table Name"
|
|
||||||
#define SYNS_AttrTerminator "Terminator"
|
|
||||||
#define SYNS_AttrTeXCommand "TeX Command"
|
|
||||||
#define SYNS_AttrText "Text"
|
|
||||||
#define SYNS_AttrTextMathMode "Text in Math Mode"
|
|
||||||
#define SYNS_AttrThirdTri "ThirdTri"
|
|
||||||
#define SYNS_AttrTriangle "Triangle"
|
|
||||||
#define SYNS_AttrUnknownWord "Unknown Word"
|
|
||||||
#define SYNS_AttrURI "URI"
|
|
||||||
#define SYNS_AttrUser "User Functions and Variables"
|
|
||||||
#define SYNS_AttrUserFunction "User Functions"
|
|
||||||
#define SYNS_AttrValue "Value"
|
|
||||||
#define SYNS_AttrVariable "Variable"
|
|
||||||
#define SYNS_AttrVisitedURI "Visited URI"
|
|
||||||
#define SYNS_AttrVrmlAppearance "Vrml_Appearance"
|
|
||||||
#define SYNS_AttrVrmlAttribute "Vrml_Attribute"
|
|
||||||
#define SYNS_AttrVrmlDefinition "Vrml_Definition"
|
|
||||||
#define SYNS_AttrVrmlEvent "Vrml_Event"
|
|
||||||
#define SYNS_AttrVrmlGrouping "Vrml_Grouping"
|
|
||||||
#define SYNS_AttrVrmlInterpolator "Vrml_Interpolator"
|
|
||||||
#define SYNS_AttrVrmlLight "Vrml_Light"
|
|
||||||
#define SYNS_AttrVrmlNode "Vrml_Node"
|
|
||||||
#define SYNS_AttrVrmlParameter "Vrml_Parameter"
|
|
||||||
#define SYNS_AttrVrmlProto "Vrml_Proto"
|
|
||||||
#define SYNS_AttrVrmlSensor "Vrml_Sensor"
|
|
||||||
#define SYNS_AttrVrmlShape "Vrml_Shape"
|
|
||||||
#define SYNS_AttrVrmlShape_Hint "Vrml_Shape_Hint"
|
|
||||||
#define SYNS_AttrVrmlTime_dependent "Vrml_Time_dependent"
|
|
||||||
#define SYNS_AttrVrmlViewpoint "Vrml_Viewpoint"
|
|
||||||
#define SYNS_AttrVrmlWorldInfo "Vrml_WorldInfo"
|
|
||||||
#define SYNS_AttrWhitespace "Whitespace"
|
|
||||||
#define SYNS_AttrX3DDocType "X3DDocType"
|
|
||||||
#define SYNS_AttrX3DHeader "X3DHeader"
|
|
||||||
// names of exporter output formats
|
|
||||||
#define SYNS_ExporterFormatHTML "HTML"
|
|
||||||
#define SYNS_ExporterFormatRTF "RTF"
|
|
||||||
#define SYNS_ExporterFormatTeX "TeX"
|
|
||||||
#endif // CONSTANTS_H
|
|
|
@ -1,243 +0,0 @@
|
||||||
#include "KeyStrokes.h"
|
|
||||||
|
|
||||||
SynEditKeyStroke::SynEditKeyStroke()
|
|
||||||
{
|
|
||||||
mKey = 0;
|
|
||||||
mKeyModifiers = Qt::NoModifier;
|
|
||||||
mKey2 = 0;
|
|
||||||
mKeyModifiers2 = Qt::NoModifier;
|
|
||||||
mCommand = SynEditorCommand::ecNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
QKeySequence SynEditKeyStroke::keySequence() const
|
|
||||||
{
|
|
||||||
if (mKey2 == 0) {
|
|
||||||
return QKeySequence(mKey + mKeyModifiers);
|
|
||||||
} else {
|
|
||||||
return QKeySequence(mKey + mKeyModifiers, mKey2+mKeyModifiers2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setKeySequence(QKeySequence &keySequence)
|
|
||||||
{
|
|
||||||
if (keySequence.isEmpty()<=0)
|
|
||||||
return;
|
|
||||||
decodeKey(keySequence[0],mKey,mKeyModifiers);
|
|
||||||
if (keySequence.count()>1) {
|
|
||||||
decodeKey(keySequence[1],mKey2,mKeyModifiers2);
|
|
||||||
} else {
|
|
||||||
mKey2=0;
|
|
||||||
mKeyModifiers2=Qt::NoModifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditKeyStroke::key() const
|
|
||||||
{
|
|
||||||
return mKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setKey(int key)
|
|
||||||
{
|
|
||||||
mKey = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers SynEditKeyStroke::keyModifiers() const
|
|
||||||
{
|
|
||||||
return mKeyModifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setKeyModifiers(const Qt::KeyboardModifiers &keyModifiers)
|
|
||||||
{
|
|
||||||
mKeyModifiers = keyModifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditKeyStroke::key2() const
|
|
||||||
{
|
|
||||||
return mKey2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setKey2(int key2)
|
|
||||||
{
|
|
||||||
mKey2 = key2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers SynEditKeyStroke::keyModifiers2() const
|
|
||||||
{
|
|
||||||
return mKeyModifiers2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setKeyModifiers2(const Qt::KeyboardModifiers &keyModifiers2)
|
|
||||||
{
|
|
||||||
mKeyModifiers2 = keyModifiers2;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditorCommand SynEditKeyStroke::command() const
|
|
||||||
{
|
|
||||||
return mCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStroke::setCommand(const SynEditorCommand &command)
|
|
||||||
{
|
|
||||||
mCommand = command;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynKeyError::SynKeyError(const QString &reason):BaseError(reason)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditKeyStroke SynEditKeyStrokes::add(SynEditorCommand command, int key, Qt::KeyboardModifiers modifiers)
|
|
||||||
{
|
|
||||||
PSynEditKeyStroke keyStroke = std::make_shared<SynEditKeyStroke>();
|
|
||||||
keyStroke->setKey(key);
|
|
||||||
keyStroke->setKeyModifiers(modifiers);
|
|
||||||
keyStroke->setCommand(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditKeyStroke SynEditKeyStrokes::findCommand(SynEditorCommand command)
|
|
||||||
{
|
|
||||||
for (PSynEditKeyStroke& keyStroke:mList) {
|
|
||||||
if (keyStroke->command() == command)
|
|
||||||
return keyStroke;
|
|
||||||
}
|
|
||||||
return PSynEditKeyStroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditKeyStroke SynEditKeyStrokes::findKeycode(int key, Qt::KeyboardModifiers modifiers)
|
|
||||||
{
|
|
||||||
for (PSynEditKeyStroke& keyStroke:mList) {
|
|
||||||
if (keyStroke->key() == key && keyStroke->keyModifiers()==modifiers && keyStroke->key2()==0)
|
|
||||||
return keyStroke;
|
|
||||||
}
|
|
||||||
return PSynEditKeyStroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditKeyStroke SynEditKeyStrokes::findKeycode2(int key, Qt::KeyboardModifiers modifiers,
|
|
||||||
int key2, Qt::KeyboardModifiers modifiers2)
|
|
||||||
{
|
|
||||||
for (PSynEditKeyStroke& keyStroke:mList) {
|
|
||||||
if (keyStroke->key() == key && keyStroke->keyModifiers()==modifiers && keyStroke->key2()==key2
|
|
||||||
&& keyStroke->keyModifiers2() ==modifiers2)
|
|
||||||
return keyStroke;
|
|
||||||
}
|
|
||||||
return PSynEditKeyStroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditKeyStroke SynEditKeyStrokes::findKeySequence(const QKeySequence &keySeq)
|
|
||||||
{
|
|
||||||
switch (keySeq.count()) {
|
|
||||||
case 1: {
|
|
||||||
int key;
|
|
||||||
Qt::KeyboardModifiers modifiers;
|
|
||||||
decodeKey(keySeq[0],key,modifiers);
|
|
||||||
return findKeycode(key,modifiers);
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
Qt::KeyboardModifiers modifiers;
|
|
||||||
int key2;
|
|
||||||
Qt::KeyboardModifiers modifiers2;
|
|
||||||
decodeKey(keySeq[0],key,modifiers);
|
|
||||||
decodeKey(keySeq[1],key2,modifiers2);
|
|
||||||
return findKeycode2(key,modifiers,key2,modifiers2);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return PSynEditKeyStroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStrokes::clear()
|
|
||||||
{
|
|
||||||
return mList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditKeyStrokes::resetDefaults()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
add(SynEditorCommand::ecUp, Qt::Key_Up, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelUp, Qt::Key_Up, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecScrollUp, Qt::Key_Up, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecDown, Qt::Key_Down, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelDown, Qt::Key_Down, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecScrollDown, Qt::Key_Down, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecLeft, Qt::Key_Left, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelLeft, Qt::Key_Left, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecWordLeft, Qt::Key_Left, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelWordLeft, Qt::Key_Left, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecRight, Qt::Key_Right, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelRight, Qt::Key_Right, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecWordRight, Qt::Key_Right, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelWordRight, Qt::Key_Right, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecPageDown, Qt::Key_PageDown, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelPageDown, Qt::Key_PageDown, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecPageBottom, Qt::Key_PageDown, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelPageBottom, Qt::Key_PageDown, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecPageUp, Qt::Key_PageUp, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelPageUp, Qt::Key_PageUp, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecPageTop, Qt::Key_PageUp, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelPageTop, Qt::Key_PageUp, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecLineStart, Qt::Key_Home, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelLineStart, Qt::Key_Home, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecEditorTop, Qt::Key_Home, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelEditorTop, Qt::Key_Home, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecLineEnd, Qt::Key_End, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecSelLineEnd, Qt::Key_End, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecEditorBottom, Qt::Key_End, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSelEditorBottom, Qt::Key_End, Qt::ShiftModifier|Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecToggleMode, Qt::Key_Insert, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecCopy, Qt::Key_Insert, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecCut, Qt::Key_Delete, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecPaste, Qt::Key_Insert, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteChar, Qt::Key_Delete, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteLastChar, Qt::Key_Backspace, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteLastChar, Qt::Key_Backspace, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteLastWord, Qt::Key_Backspace, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecUndo, Qt::Key_Backspace, Qt::AltModifier);
|
|
||||||
add(SynEditorCommand::ecRedo, Qt::Key_Backspace, Qt::AltModifier|Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecLineBreak, Qt::Key_Return, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecLineBreak, Qt::Key_Return, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecTab, Qt::Key_Tab, Qt::NoModifier);
|
|
||||||
add(SynEditorCommand::ecShiftTab, Qt::Key_Tab, Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecContextHelp, Qt::Key_F1, Qt::NoModifier);
|
|
||||||
|
|
||||||
add(SynEditorCommand::ecSelectAll, Qt::Key_A, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecCopy, Qt::Key_C, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecPaste, Qt::Key_V, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecCut, Qt::Key_X, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecBlockIndent, Qt::Key_I, Qt::ControlModifier|Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecBlockUnindent, Qt::Key_U, Qt::ControlModifier|Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecLineBreak, Qt::Key_M, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecInsertLine, Qt::Key_N, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteWord, Qt::Key_T, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteLine, Qt::Key_Y, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecDeleteEOL, Qt::Key_Y, Qt::ControlModifier|Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecUndo, Qt::Key_Z, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecRedo, Qt::Key_Z, Qt::ControlModifier|Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker0, Qt::Key_0, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker1, Qt::Key_1, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker2, Qt::Key_2, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker3, Qt::Key_3, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker4, Qt::Key_4, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker5, Qt::Key_5, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker6, Qt::Key_6, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker7, Qt::Key_7, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker8, Qt::Key_8, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecGotoMarker9, Qt::Key_9, Qt::ControlModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker0, Qt::Key_0, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker1, Qt::Key_1, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker2, Qt::Key_2, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker3, Qt::Key_3, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker4, Qt::Key_4, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker5, Qt::Key_5, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker6, Qt::Key_6, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker7, Qt::Key_7, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker8, Qt::Key_8, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecSetMarker9, Qt::Key_9, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecNormalSelect, Qt::Key_N, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecColumnSelect, Qt::Key_C, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecLineSelect, Qt::Key_L, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
add(SynEditorCommand::ecMatchBracket, Qt::Key_B, Qt::ControlModifier | Qt::ShiftModifier);
|
|
||||||
}
|
|
|
@ -1,225 +0,0 @@
|
||||||
#ifndef SYNEDITKEYSTROKE_H
|
|
||||||
#define SYNEDITKEYSTROKE_H
|
|
||||||
|
|
||||||
#include "../utils.h"
|
|
||||||
#include <QKeySequence>
|
|
||||||
#include <QList>
|
|
||||||
#include <memory>
|
|
||||||
//****************************************************************************
|
|
||||||
// NOTE! If you add an editor command, you must also update the
|
|
||||||
// EditorCommandStrs constant array in implementation section below, or the
|
|
||||||
// command will not show up in the IDE.
|
|
||||||
//****************************************************************************
|
|
||||||
|
|
||||||
// "Editor Commands". Key strokes are translated from a table into these
|
|
||||||
// I used constants instead of a set so that additional commands could be
|
|
||||||
// added in descendants (you can't extend a set)
|
|
||||||
|
|
||||||
// There are two ranges of editor commands: the ecViewXXX commands are always
|
|
||||||
// valid, while the ecEditXXX commands are ignored when the editor is in
|
|
||||||
// read-only mode
|
|
||||||
|
|
||||||
enum class SynEditorCommand {
|
|
||||||
ecNone = 0, // Nothing. Useful for user event to handle command
|
|
||||||
ecViewCommandFirst = 0,
|
|
||||||
ecViewCommandLast = 500,
|
|
||||||
ecEditCommandFirst = 501,
|
|
||||||
ecEditCommandLast = 1000,
|
|
||||||
|
|
||||||
ecLeft = 1, // Move cursor left one char
|
|
||||||
ecRight = 2, // Move cursor right one char
|
|
||||||
ecUp = 3, // Move cursor up one line
|
|
||||||
ecDown = 4, // Move cursor down one line
|
|
||||||
ecWordLeft = 5, // Move cursor left one word
|
|
||||||
ecWordRight = 6, // Move cursor right one word
|
|
||||||
ecLineStart = 7, // Move cursor to beginning of line
|
|
||||||
ecLineEnd = 8, // Move cursor to end of line
|
|
||||||
ecPageUp = 9, // Move cursor up one page
|
|
||||||
ecPageDown = 10, // Move cursor down one page
|
|
||||||
ecPageLeft = 11, // Move cursor right one page
|
|
||||||
ecPageRight = 12, // Move cursor left one page
|
|
||||||
ecPageTop = 13, // Move cursor to top of page
|
|
||||||
ecPageBottom = 14, // Move cursor to bottom of page
|
|
||||||
ecEditorTop = 15, // Move cursor to absolute beginning
|
|
||||||
ecEditorBottom = 16, // Move cursor to absolute end
|
|
||||||
ecGotoXY = 17, // Move cursor to specific coordinates, Data = PPoint
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Maybe the command processor should just take a boolean that signifies if
|
|
||||||
// selection is affected or not?
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
ecSelection = 100, // Add this to ecXXX command to get equivalent
|
|
||||||
// command, but with selection enabled. This is not
|
|
||||||
// a command itself.
|
|
||||||
// Same as commands above, except they affect selection, too
|
|
||||||
ecSelLeft = ecLeft + ecSelection,
|
|
||||||
ecSelRight = ecRight + ecSelection,
|
|
||||||
ecSelUp = ecUp + ecSelection,
|
|
||||||
ecSelDown = ecDown + ecSelection,
|
|
||||||
ecSelWordLeft = ecWordLeft + ecSelection,
|
|
||||||
ecSelWordRight = ecWordRight + ecSelection,
|
|
||||||
ecSelLineStart = ecLineStart + ecSelection,
|
|
||||||
ecSelLineEnd = ecLineEnd + ecSelection,
|
|
||||||
ecSelPageUp = ecPageUp + ecSelection,
|
|
||||||
ecSelPageDown = ecPageDown + ecSelection,
|
|
||||||
ecSelPageLeft = ecPageLeft + ecSelection,
|
|
||||||
ecSelPageRight = ecPageRight + ecSelection,
|
|
||||||
ecSelPageTop = ecPageTop + ecSelection,
|
|
||||||
ecSelPageBottom = ecPageBottom + ecSelection,
|
|
||||||
ecSelEditorTop = ecEditorTop + ecSelection,
|
|
||||||
ecSelEditorBottom = ecEditorBottom + ecSelection,
|
|
||||||
ecSelGotoXY = ecGotoXY + ecSelection, // Data = PPoint
|
|
||||||
|
|
||||||
ecSelWord = 198,
|
|
||||||
ecSelectAll = 199, // Select entire contents of editor, cursor to end
|
|
||||||
|
|
||||||
ecCopy = 201, // Copy selection to clipboard
|
|
||||||
|
|
||||||
ecScrollUp = 211, // Scroll up one line leaving cursor position unchanged.
|
|
||||||
ecScrollDown = 212, // Scroll down one line leaving cursor position unchanged.
|
|
||||||
ecScrollLeft = 213, // Scroll left one char leaving cursor position unchanged.
|
|
||||||
ecScrollRight = 214, // Scroll right one char leaving cursor position unchanged.
|
|
||||||
|
|
||||||
ecInsertMode = 221, // Set insert mode
|
|
||||||
ecOverwriteMode = 222, // Set overwrite mode
|
|
||||||
ecToggleMode = 223, // Toggle ins/ovr mode
|
|
||||||
|
|
||||||
ecNormalSelect = 231, // Normal selection mode
|
|
||||||
ecColumnSelect = 232, // Column selection mode
|
|
||||||
ecLineSelect = 233, // Line selection mode
|
|
||||||
|
|
||||||
ecMatchBracket = 250, // Go to matching bracket
|
|
||||||
|
|
||||||
ecGotoMarker0 = 301, // Goto marker
|
|
||||||
ecGotoMarker1 = 302, // Goto marker
|
|
||||||
ecGotoMarker2 = 303, // Goto marker
|
|
||||||
ecGotoMarker3 = 304, // Goto marker
|
|
||||||
ecGotoMarker4 = 305, // Goto marker
|
|
||||||
ecGotoMarker5 = 306, // Goto marker
|
|
||||||
ecGotoMarker6 = 307, // Goto marker
|
|
||||||
ecGotoMarker7 = 308, // Goto marker
|
|
||||||
ecGotoMarker8 = 309, // Goto marker
|
|
||||||
ecGotoMarker9 = 310, // Goto marker
|
|
||||||
ecSetMarker0 = 351, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker1 = 352, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker2 = 353, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker3 = 354, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker4 = 355, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker5 = 356, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker6 = 357, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker7 = 358, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker8 = 359, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
ecSetMarker9 = 360, // Set marker, Data = PPoint - X, Y Pos
|
|
||||||
|
|
||||||
ecGotFocus = 480,
|
|
||||||
ecLostFocus = 481,
|
|
||||||
|
|
||||||
ecContextHelp = 490, // Help on Word, Data = Word
|
|
||||||
|
|
||||||
ecDeleteLastChar = 501, // Delete last char (i.e. backspace key)
|
|
||||||
ecDeleteChar = 502, // Delete char at cursor (i.e. delete key)
|
|
||||||
ecDeleteWord = 503, // Delete from cursor to end of word
|
|
||||||
ecDeleteLastWord = 504, // Delete from cursor to start of word
|
|
||||||
ecDeleteBOL = 505, // Delete from cursor to beginning of line
|
|
||||||
ecDeleteEOL = 506, // Delete from cursor to end of line
|
|
||||||
ecDeleteLine = 507, // Delete current line
|
|
||||||
ecClearAll = 508, // Delete everything
|
|
||||||
ecLineBreak = 509, // Break line at current position, move caret to new line
|
|
||||||
ecInsertLine = 510, // Break line at current position, leave caret
|
|
||||||
ecChar = 511, // Insert a character at current position
|
|
||||||
ecDuplicateLine = 512, // Duplicate current line
|
|
||||||
ecMoveSelUp = 513, // Move selection up
|
|
||||||
ecMoveSelDown = 514, // Move selection down
|
|
||||||
ecImeStr = 550, // Insert character(s) from IME
|
|
||||||
|
|
||||||
ecUndo = 601, // Perform undo if available
|
|
||||||
ecRedo = 602, // Perform redo if available
|
|
||||||
ecCut = 603, // Cut selection to clipboard
|
|
||||||
ecPaste = 604, // Paste clipboard to current position
|
|
||||||
|
|
||||||
ecBlockIndent = 610, // Indent selection
|
|
||||||
ecBlockUnindent = 611, // Unindent selection
|
|
||||||
ecTab = 612, // Tab key
|
|
||||||
ecShiftTab = 613, // Shift+Tab key
|
|
||||||
ecComment = 614,
|
|
||||||
ecUncomment = 615,
|
|
||||||
ecToggleComment = 616,
|
|
||||||
ecCommentInline = 617,
|
|
||||||
|
|
||||||
ecAutoCompletion = 650,
|
|
||||||
|
|
||||||
ecUpperCase = 620, // apply to the current or previous word
|
|
||||||
ecLowerCase = 621,
|
|
||||||
ecToggleCase = 622,
|
|
||||||
ecTitleCase = 623,
|
|
||||||
ecUpperCaseBlock = 625, // apply to current selection, or current char if no selection
|
|
||||||
ecLowerCaseBlock = 626,
|
|
||||||
ecToggleCaseBlock = 627,
|
|
||||||
|
|
||||||
ecString = 630, //Insert a whole string
|
|
||||||
|
|
||||||
ecUserFirst = 1001, // Start of user-defined commands
|
|
||||||
|
|
||||||
//### Code Folding ###
|
|
||||||
ecCollapse = ecUserFirst + 100,
|
|
||||||
ecUncollapse = ecUserFirst + 101,
|
|
||||||
ecCollapseLevel = ecUserFirst + 102,
|
|
||||||
ecUncollapseLevel = ecUserFirst + 103,
|
|
||||||
ecCollapseAll = ecUserFirst + 104,
|
|
||||||
ecUncollapseAll = ecUserFirst + 105,
|
|
||||||
//### End Code Folding ###
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynKeyError: public BaseError {
|
|
||||||
public:
|
|
||||||
explicit SynKeyError(const QString& reason);
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynEditKeyStroke
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SynEditKeyStroke();
|
|
||||||
QKeySequence keySequence() const;
|
|
||||||
void setKeySequence(QKeySequence& keySequence);
|
|
||||||
int key() const;
|
|
||||||
void setKey(int key);
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers keyModifiers() const;
|
|
||||||
void setKeyModifiers(const Qt::KeyboardModifiers &keyModifiers);
|
|
||||||
|
|
||||||
int key2() const;
|
|
||||||
void setKey2(int key2);
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers keyModifiers2() const;
|
|
||||||
void setKeyModifiers2(const Qt::KeyboardModifiers &keyModifiers2);
|
|
||||||
|
|
||||||
SynEditorCommand command() const;
|
|
||||||
void setCommand(const SynEditorCommand &command);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int mKey; // Virtual keycode, i.e. VK_xxx
|
|
||||||
Qt::KeyboardModifiers mKeyModifiers;
|
|
||||||
int mKey2;
|
|
||||||
Qt::KeyboardModifiers mKeyModifiers2;
|
|
||||||
SynEditorCommand mCommand;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynEditKeyStroke = std::shared_ptr<SynEditKeyStroke>;
|
|
||||||
using SynEditKeyStrokeList = QList<PSynEditKeyStroke>;
|
|
||||||
|
|
||||||
class SynEditKeyStrokes {
|
|
||||||
public:
|
|
||||||
PSynEditKeyStroke add(SynEditorCommand command, int key, Qt::KeyboardModifiers modifiers);
|
|
||||||
PSynEditKeyStroke findCommand(SynEditorCommand command);
|
|
||||||
PSynEditKeyStroke findKeycode(int key, Qt::KeyboardModifiers modifiers);
|
|
||||||
PSynEditKeyStroke findKeycode2(int key, Qt::KeyboardModifiers modifiers,
|
|
||||||
int key2, Qt::KeyboardModifiers modifiers2);
|
|
||||||
PSynEditKeyStroke findKeySequence(const QKeySequence& keySeq);
|
|
||||||
void clear();
|
|
||||||
void resetDefaults();
|
|
||||||
SynEditKeyStrokeList mList;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SYNEDITKEYSTROKE_H
|
|
|
@ -1,480 +0,0 @@
|
||||||
#include "MiscClasses.h"
|
|
||||||
#include "algorithm"
|
|
||||||
|
|
||||||
SynGutter::SynGutter(QObject *parent):
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
mFont = QFont("Courier New",9);
|
|
||||||
mColor= QColorConstants::Svg::lightgray;
|
|
||||||
mBorderColor = QColorConstants::Transparent;
|
|
||||||
mWidth = 30;
|
|
||||||
mShowLineNumbers = true;
|
|
||||||
mDigitCount = 4;
|
|
||||||
mLeadingZeros = false;
|
|
||||||
mLeftOffset = 16;
|
|
||||||
mRightOffset = 2;
|
|
||||||
mVisible = true;
|
|
||||||
mUseFontStyle = false;
|
|
||||||
mAutoSize = true;
|
|
||||||
mAutoSizeDigitCount = mDigitCount;
|
|
||||||
mBorderStyle = SynGutterBorderStyle::Middle;
|
|
||||||
mLineNumberStart = 1;
|
|
||||||
mGradient = false;
|
|
||||||
mGradientStartColor = QColorConstants::Transparent;
|
|
||||||
mGradientEndColor = QColorConstants::Transparent;
|
|
||||||
mGradientSteps = 48;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFont SynGutter::font() const
|
|
||||||
{
|
|
||||||
return mFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setFont(const QFont &font)
|
|
||||||
{
|
|
||||||
if (mFont != font) {
|
|
||||||
mFont = font;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::autoSize() const
|
|
||||||
{
|
|
||||||
return mAutoSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setAutoSize(bool value)
|
|
||||||
{
|
|
||||||
if (mAutoSize != value) {
|
|
||||||
mAutoSize = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setChanged()
|
|
||||||
{
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::width() const
|
|
||||||
{
|
|
||||||
return mWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setWidth(int width)
|
|
||||||
{
|
|
||||||
if (mWidth != width ) {
|
|
||||||
mWidth = width;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::autoSizeDigitCount(int linesCount)
|
|
||||||
{
|
|
||||||
if (mVisible && mAutoSize && mShowLineNumbers) {
|
|
||||||
linesCount += (mLineNumberStart - 1);
|
|
||||||
}
|
|
||||||
int nDigits = std::max(QString::number(linesCount).length(), mDigitCount);
|
|
||||||
if (mAutoSizeDigitCount!=nDigits) {
|
|
||||||
mAutoSizeDigitCount = nDigits;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynGutter::formatLineNumber(int line)
|
|
||||||
{
|
|
||||||
line += (mLineNumberStart - 1);
|
|
||||||
QString result = QString::number(line);
|
|
||||||
return QString(mAutoSizeDigitCount - result.length(),'0') + result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::realGutterWidth(int charWidth)
|
|
||||||
{
|
|
||||||
if (!mVisible) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (mShowLineNumbers) {
|
|
||||||
return mLeftOffset + mRightOffset + mAutoSizeDigitCount * charWidth + 2;
|
|
||||||
}
|
|
||||||
return mWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::visible() const
|
|
||||||
{
|
|
||||||
return mVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setVisible(bool visible)
|
|
||||||
{
|
|
||||||
if (mVisible!=visible) {
|
|
||||||
mVisible = visible;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::useFontStyle() const
|
|
||||||
{
|
|
||||||
return mUseFontStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setUseFontStyle(bool useFontStyle)
|
|
||||||
{
|
|
||||||
if (mUseFontStyle!=useFontStyle) {
|
|
||||||
mUseFontStyle = useFontStyle;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::showLineNumbers() const
|
|
||||||
{
|
|
||||||
return mShowLineNumbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setShowLineNumbers(bool showLineNumbers)
|
|
||||||
{
|
|
||||||
if (mShowLineNumbers!=showLineNumbers) {
|
|
||||||
mShowLineNumbers = showLineNumbers;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::rightOffset() const
|
|
||||||
{
|
|
||||||
return mRightOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setRightOffset(int rightOffset)
|
|
||||||
{
|
|
||||||
int value = std::max(0, rightOffset);
|
|
||||||
if (mRightOffset != value) {
|
|
||||||
mRightOffset = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::lineNumberStart() const
|
|
||||||
{
|
|
||||||
return mLineNumberStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setLineNumberStart(int lineNumberStart)
|
|
||||||
{
|
|
||||||
int value = std::max(0,lineNumberStart);
|
|
||||||
if (mLineNumberStart!=value) {
|
|
||||||
mLineNumberStart = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::zeroStart()
|
|
||||||
{
|
|
||||||
return mLineNumberStart == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::leftOffset() const
|
|
||||||
{
|
|
||||||
return mLeftOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setLeftOffset(int leftOffset)
|
|
||||||
{
|
|
||||||
int value = std::max(0,leftOffset);
|
|
||||||
if (mLeftOffset != value) {
|
|
||||||
mLeftOffset = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::leadingZeros() const
|
|
||||||
{
|
|
||||||
return mLeadingZeros;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setLeadingZeros(bool value)
|
|
||||||
{
|
|
||||||
if (mLeadingZeros!=value) {
|
|
||||||
mLeadingZeros = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::gradientSteps() const
|
|
||||||
{
|
|
||||||
return mGradientSteps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setGradientSteps(int value)
|
|
||||||
{
|
|
||||||
if (mGradientSteps!=value) {
|
|
||||||
mGradientSteps = value;
|
|
||||||
if (mGradientSteps<2)
|
|
||||||
mGradientSteps = 2;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynGutter::gradientEndColor() const
|
|
||||||
{
|
|
||||||
return mGradientEndColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setGradientEndColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mGradientEndColor!=value) {
|
|
||||||
mGradientEndColor = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynGutter::gradientStartColor() const
|
|
||||||
{
|
|
||||||
return mGradientStartColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setGradientStartColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mGradientStartColor!=value) {
|
|
||||||
mGradientStartColor = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynGutter::gradient() const
|
|
||||||
{
|
|
||||||
return mGradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setGradient(bool value)
|
|
||||||
{
|
|
||||||
if (mGradient!=value){
|
|
||||||
mGradient = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynGutterBorderStyle SynGutter::borderStyle() const
|
|
||||||
{
|
|
||||||
return mBorderStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setBorderStyle(const SynGutterBorderStyle &value)
|
|
||||||
{
|
|
||||||
if (mBorderStyle!=value) {
|
|
||||||
mBorderStyle = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynGutter::digitCount() const
|
|
||||||
{
|
|
||||||
return mDigitCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setDigitCount(int value)
|
|
||||||
{
|
|
||||||
if (mDigitCount != value ) {
|
|
||||||
mDigitCount = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynGutter::color() const
|
|
||||||
{
|
|
||||||
return mColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mColor!=value) {
|
|
||||||
mColor = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynGutter::borderColor() const
|
|
||||||
{
|
|
||||||
return mBorderColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynGutter::setBorderColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mBorderColor!=value) {
|
|
||||||
mBorderColor = value;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SynEditMark::SynEditMark(QObject *parent)
|
|
||||||
{
|
|
||||||
mBookmarkNum = -1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditMark::Char() const
|
|
||||||
{
|
|
||||||
return mChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setChar(int value)
|
|
||||||
{
|
|
||||||
if (value != mChar) {
|
|
||||||
mChar = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditMark::image() const
|
|
||||||
{
|
|
||||||
return mImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setImage(int image)
|
|
||||||
{
|
|
||||||
if (mImage != image) {
|
|
||||||
mImage = image;
|
|
||||||
if (mVisible)
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditMark::visible() const
|
|
||||||
{
|
|
||||||
return mVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setVisible(bool visible)
|
|
||||||
{
|
|
||||||
if (mVisible!=visible) {
|
|
||||||
mVisible = visible;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditMark::bookmarkNum() const
|
|
||||||
{
|
|
||||||
return mBookmarkNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setBookmarkNum(int bookmarkNum)
|
|
||||||
{
|
|
||||||
mBookmarkNum = bookmarkNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditMark::internalImage() const
|
|
||||||
{
|
|
||||||
return mInternalImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setInternalImage(bool internalImage)
|
|
||||||
{
|
|
||||||
if (mInternalImage!=internalImage) {
|
|
||||||
mInternalImage = internalImage;
|
|
||||||
if (mVisible)
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditMark::isBookmark() const
|
|
||||||
{
|
|
||||||
return (mBookmarkNum>=0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditMark::line() const
|
|
||||||
{
|
|
||||||
return mLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditMark::setLine(int line)
|
|
||||||
{
|
|
||||||
if (mLine!=line) {
|
|
||||||
if (mVisible && mLine>0)
|
|
||||||
emit changed();
|
|
||||||
mLine = line;
|
|
||||||
if (mVisible && mLine>0)
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynBookMarkOpt::SynBookMarkOpt(QObject *parent)
|
|
||||||
{
|
|
||||||
mDrawBookmarksFirst = true;
|
|
||||||
mEnableKeys = true;
|
|
||||||
mGlyphsVisible = true;
|
|
||||||
mLeftMargin = 2;
|
|
||||||
mXOffset = 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynIconList SynBookMarkOpt::bookmarkImages() const
|
|
||||||
{
|
|
||||||
return mBookmarkImages;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setBookmarkImages(const PSynIconList &images)
|
|
||||||
{
|
|
||||||
if (mBookmarkImages != images) {
|
|
||||||
mBookmarkImages = images;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynBookMarkOpt::drawBookmarksFirst() const
|
|
||||||
{
|
|
||||||
return mDrawBookmarksFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setDrawBookmarksFirst(bool drawBookmarksFirst)
|
|
||||||
{
|
|
||||||
if (mDrawBookmarksFirst != drawBookmarksFirst) {
|
|
||||||
mDrawBookmarksFirst = drawBookmarksFirst;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynBookMarkOpt::enableKeys() const
|
|
||||||
{
|
|
||||||
return mEnableKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setEnableKeys(bool enableKeys)
|
|
||||||
{
|
|
||||||
mEnableKeys = enableKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynBookMarkOpt::glyphsVisible() const
|
|
||||||
{
|
|
||||||
return mGlyphsVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setGlyphsVisible(bool glyphsVisible)
|
|
||||||
{
|
|
||||||
if (mGlyphsVisible!=glyphsVisible) {
|
|
||||||
mGlyphsVisible = glyphsVisible;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynBookMarkOpt::leftMargin() const
|
|
||||||
{
|
|
||||||
return mLeftMargin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setLeftMargin(int leftMargin)
|
|
||||||
{
|
|
||||||
if (leftMargin!=mLeftMargin) {
|
|
||||||
mLeftMargin = leftMargin;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynBookMarkOpt::xOffset() const
|
|
||||||
{
|
|
||||||
return mXOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynBookMarkOpt::setXOffset(int xOffset)
|
|
||||||
{
|
|
||||||
if (mXOffset!=xOffset) {
|
|
||||||
mXOffset = xOffset;
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
#ifndef MISCCLASSES_H
|
|
||||||
#define MISCCLASSES_H
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QFont>
|
|
||||||
#include <QObject>
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
enum class SynGutterBorderStyle {
|
|
||||||
None,
|
|
||||||
Middle,
|
|
||||||
Right
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynGutter : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynGutter(QObject* parent = nullptr);
|
|
||||||
QFont font() const;
|
|
||||||
void setFont(const QFont &value);
|
|
||||||
|
|
||||||
bool autoSize() const;
|
|
||||||
void setAutoSize(bool value);
|
|
||||||
|
|
||||||
QColor borderColor() const;
|
|
||||||
void setBorderColor(const QColor &value);
|
|
||||||
|
|
||||||
QColor color() const;
|
|
||||||
void setColor(const QColor &value);
|
|
||||||
|
|
||||||
int digitCount() const;
|
|
||||||
void setDigitCount(int value);
|
|
||||||
|
|
||||||
SynGutterBorderStyle borderStyle() const;
|
|
||||||
void setBorderStyle(const SynGutterBorderStyle &value);
|
|
||||||
|
|
||||||
bool gradient() const;
|
|
||||||
void setGradient(bool value);
|
|
||||||
|
|
||||||
QColor gradientStartColor() const;
|
|
||||||
void setGradientStartColor(const QColor &value);
|
|
||||||
|
|
||||||
QColor gradientEndColor() const;
|
|
||||||
void setGradientEndColor(const QColor &value);
|
|
||||||
|
|
||||||
int gradientSteps() const;
|
|
||||||
void setGradientSteps(int value);
|
|
||||||
|
|
||||||
bool leadingZeros() const;
|
|
||||||
void setLeadingZeros(bool value);
|
|
||||||
|
|
||||||
|
|
||||||
int leftOffset() const;
|
|
||||||
void setLeftOffset(int leftOffset);
|
|
||||||
|
|
||||||
int lineNumberStart() const;
|
|
||||||
void setLineNumberStart(int lineNumberStart);
|
|
||||||
|
|
||||||
bool zeroStart();
|
|
||||||
int rightOffset() const;
|
|
||||||
void setRightOffset(int rightOffset);
|
|
||||||
|
|
||||||
bool showLineNumbers() const;
|
|
||||||
void setShowLineNumbers(bool showLineNumbers);
|
|
||||||
|
|
||||||
bool useFontStyle() const;
|
|
||||||
void setUseFontStyle(bool useFontStyle);
|
|
||||||
|
|
||||||
bool visible() const;
|
|
||||||
void setVisible(bool visible);
|
|
||||||
|
|
||||||
int width() const;
|
|
||||||
void setWidth(int width);
|
|
||||||
|
|
||||||
void autoSizeDigitCount(int linesCount);
|
|
||||||
QString formatLineNumber(int line);
|
|
||||||
int realGutterWidth(int charWidth);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changed();
|
|
||||||
private:
|
|
||||||
void setChanged();
|
|
||||||
private:
|
|
||||||
bool mAutoSize;
|
|
||||||
QColor mBorderColor;
|
|
||||||
QColor mColor;
|
|
||||||
int mDigitCount;
|
|
||||||
QFont mFont;
|
|
||||||
bool mGradient;
|
|
||||||
QColor mGradientStartColor;
|
|
||||||
QColor mGradientEndColor;
|
|
||||||
int mGradientSteps;
|
|
||||||
bool mLeadingZeros;
|
|
||||||
int mLeftOffset;
|
|
||||||
int mLineNumberStart;
|
|
||||||
int mRightOffset;
|
|
||||||
bool mShowLineNumbers;
|
|
||||||
SynGutterBorderStyle mBorderStyle;
|
|
||||||
bool mUseFontStyle;
|
|
||||||
bool mVisible;
|
|
||||||
int mWidth;
|
|
||||||
int mAutoSizeDigitCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynGutter = std::shared_ptr<SynGutter>;
|
|
||||||
|
|
||||||
class SynEditMark : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynEditMark(QObject* parent = nullptr);
|
|
||||||
int Char() const;
|
|
||||||
void setChar(int value);
|
|
||||||
|
|
||||||
int image() const;
|
|
||||||
void setImage(int image);
|
|
||||||
|
|
||||||
bool visible() const;
|
|
||||||
void setVisible(bool visible);
|
|
||||||
|
|
||||||
int bookmarkNum() const;
|
|
||||||
void setBookmarkNum(int bookmarkNum);
|
|
||||||
|
|
||||||
bool internalImage() const;
|
|
||||||
void setInternalImage(bool internalImage);
|
|
||||||
|
|
||||||
bool isBookmark() const ;
|
|
||||||
|
|
||||||
int line() const;
|
|
||||||
void setLine(int line);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changed();
|
|
||||||
protected:
|
|
||||||
int mLine;
|
|
||||||
int mChar;
|
|
||||||
int mImage;
|
|
||||||
bool mVisible;
|
|
||||||
bool mInternalImage;
|
|
||||||
int mBookmarkNum;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynEditMark = std::shared_ptr<SynEditMark>;
|
|
||||||
|
|
||||||
using SynEditMarkList = QList<SynEditMark>;
|
|
||||||
|
|
||||||
using PSynEditMarkList = std::shared_ptr<SynEditMarkList>;
|
|
||||||
|
|
||||||
class SynBookMarkOpt: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynBookMarkOpt(QObject* parent=nullptr);
|
|
||||||
PSynIconList bookmarkImages() const;
|
|
||||||
void setBookmarkImages(const PSynIconList &images);
|
|
||||||
|
|
||||||
bool drawBookmarksFirst() const;
|
|
||||||
void setDrawBookmarksFirst(bool drawBookmarksFirst);
|
|
||||||
|
|
||||||
bool enableKeys() const;
|
|
||||||
void setEnableKeys(bool enableKeys);
|
|
||||||
|
|
||||||
bool glyphsVisible() const;
|
|
||||||
void setGlyphsVisible(bool glyphsVisible);
|
|
||||||
|
|
||||||
int leftMargin() const;
|
|
||||||
void setLeftMargin(int leftMargin);
|
|
||||||
|
|
||||||
int xOffset() const;
|
|
||||||
void setXOffset(int xOffset);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changed();
|
|
||||||
private:
|
|
||||||
PSynIconList mBookmarkImages;
|
|
||||||
bool mDrawBookmarksFirst;
|
|
||||||
bool mEnableKeys;
|
|
||||||
bool mGlyphsVisible;
|
|
||||||
int mLeftMargin;
|
|
||||||
int mXOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynBookMarkOpt = std::shared_ptr<SynBookMarkOpt>;
|
|
||||||
#endif // MISCCLASSES_H
|
|
|
@ -1,533 +0,0 @@
|
||||||
#include "MiscProcs.h"
|
|
||||||
#include <QFile>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
int MinMax(int x, int mi, int ma)
|
|
||||||
{
|
|
||||||
x = std::min(x, ma );
|
|
||||||
return std::max( x, mi );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwapInt(int &l, int &r)
|
|
||||||
{
|
|
||||||
int tmp = r;
|
|
||||||
r = l;
|
|
||||||
l = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint MaxPoint(const QPoint &P1, const QPoint &P2)
|
|
||||||
{
|
|
||||||
if ( (P2.y() > P1.y()) || ( (P2.y() == P1.y()) && (P2.x() > P1.x())) ) {
|
|
||||||
return P2;
|
|
||||||
} else {
|
|
||||||
return P1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint MinPoint(const QPoint &P1, const QPoint &P2)
|
|
||||||
{
|
|
||||||
if ( (P2.y() < P1.y()) || ( (P2.y() == P1.y()) && (P2.x() < P1.x())) ) {
|
|
||||||
return P2;
|
|
||||||
} else {
|
|
||||||
return P1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PIntArray GetIntArray(size_t Count, int InitialValue)
|
|
||||||
{
|
|
||||||
return std::make_shared<IntArray>(Count,InitialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalFillRect(QPainter *painter, const QRect &rcPaint, const QColor& color)
|
|
||||||
{
|
|
||||||
painter->fillRect(rcPaint,color);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool IsPowerOfTwo(int TabWidth) {
|
|
||||||
if (TabWidth<2)
|
|
||||||
return false;
|
|
||||||
int nW = 2;
|
|
||||||
do {
|
|
||||||
if (nW >= TabWidth)
|
|
||||||
break;
|
|
||||||
nW <<= 1;
|
|
||||||
} while (nW<0x10000);
|
|
||||||
return (nW == TabWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabs1Ex(const QString &Line, int TabWidth, bool &HasTabs) {
|
|
||||||
QString Result = Line; // increment reference count only
|
|
||||||
int nBeforeTab;
|
|
||||||
if (GetHasTabs(Line, nBeforeTab)) {
|
|
||||||
QChar* pDest;
|
|
||||||
HasTabs = true;
|
|
||||||
pDest = Result.data()+nBeforeTab+1;
|
|
||||||
// this will make a copy of Line
|
|
||||||
// We have at least one tab in the string, and the tab width is 1.
|
|
||||||
// pDest points to the first tab char. We overwrite all tabs with spaces.
|
|
||||||
while (*pDest!=0) {
|
|
||||||
if (*pDest == '\t') {
|
|
||||||
*pDest = ' ';
|
|
||||||
};
|
|
||||||
pDest++;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
HasTabs = false;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabs1(const QString &Line, int TabWidth) {
|
|
||||||
bool HasTabs;
|
|
||||||
return ConvertTabs1Ex(Line, TabWidth, HasTabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabs2nEx(const QString &Line, int TabWidth, bool &HasTabs) {
|
|
||||||
QString Result = Line; // increment reference count only
|
|
||||||
int DestLen;
|
|
||||||
if (GetHasTabs(Line, DestLen)) {
|
|
||||||
HasTabs = true;
|
|
||||||
int pSrc = 1 + DestLen;
|
|
||||||
// We have at least one tab in the string, and the tab width equals 2^n.
|
|
||||||
// pSrc points to the first tab char in Line. We get the number of tabs
|
|
||||||
// and the length of the expanded string now.
|
|
||||||
int TabCount = 0;
|
|
||||||
int TabMask = (TabWidth - 1) ^ 0x7FFFFFFF;
|
|
||||||
do {
|
|
||||||
if (Line[pSrc] == '\t') {
|
|
||||||
DestLen = (DestLen + TabWidth) & TabMask;
|
|
||||||
TabCount++;
|
|
||||||
} else
|
|
||||||
DestLen ++ ;
|
|
||||||
} while (pSrc < Line.length());
|
|
||||||
// Set the length of the expanded string.
|
|
||||||
Result.resize(DestLen);
|
|
||||||
DestLen = 0;
|
|
||||||
pSrc = 0;
|
|
||||||
QChar * pDest = Result.data();
|
|
||||||
// We use another TabMask here to get the difference to 2^n.
|
|
||||||
TabMask = TabWidth - 1;
|
|
||||||
do {
|
|
||||||
if (Line[pSrc] == '\t') {
|
|
||||||
int i = TabWidth - (DestLen & TabMask);
|
|
||||||
DestLen += i;
|
|
||||||
//This is used for both drawing and other stuff and is meant to be #9 and not #32
|
|
||||||
do {
|
|
||||||
*pDest = '\t';
|
|
||||||
pDest ++ ;
|
|
||||||
i--;
|
|
||||||
} while (i > 0);
|
|
||||||
TabCount -- ;
|
|
||||||
if (TabCount == 0) {
|
|
||||||
do {
|
|
||||||
pSrc++ ;
|
|
||||||
*pDest = Line[pSrc];
|
|
||||||
pDest++;
|
|
||||||
} while (pSrc < Line.length());
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*pDest = Line[pSrc];
|
|
||||||
pDest ++ ;
|
|
||||||
DestLen ++;
|
|
||||||
}
|
|
||||||
pSrc++;
|
|
||||||
} while (pSrc < Line.length());
|
|
||||||
|
|
||||||
} else
|
|
||||||
HasTabs = false;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabs2n(const QString &Line, int TabWidth) {
|
|
||||||
bool HasTabs;
|
|
||||||
return ConvertTabs2nEx(Line, TabWidth, HasTabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConvertTabsProc GetBestConvertTabsProc(int TabWidth)
|
|
||||||
{
|
|
||||||
if (TabWidth < 2)
|
|
||||||
return &ConvertTabs1;
|
|
||||||
else if (IsPowerOfTwo(TabWidth))
|
|
||||||
return &ConvertTabs2n;
|
|
||||||
else
|
|
||||||
return &ConvertTabs;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabs(const QString &Line, int TabWidth)
|
|
||||||
{
|
|
||||||
bool HasTabs;
|
|
||||||
return ConvertTabsEx(Line, TabWidth, HasTabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConvertTabsProcEx GetBestConvertTabsProcEx(int TabWidth)
|
|
||||||
{
|
|
||||||
if (TabWidth < 2)
|
|
||||||
return &ConvertTabs1Ex;
|
|
||||||
else if (IsPowerOfTwo(TabWidth))
|
|
||||||
return &ConvertTabs2nEx;
|
|
||||||
else
|
|
||||||
return &ConvertTabsEx;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ConvertTabsEx(const QString &Line, int TabWidth, bool &HasTabs)
|
|
||||||
{
|
|
||||||
QString Result = Line; // increment reference count only
|
|
||||||
int DestLen;
|
|
||||||
int pSrc;
|
|
||||||
QChar* pDest;
|
|
||||||
if (GetHasTabs(Line, DestLen)) {
|
|
||||||
HasTabs = true;
|
|
||||||
pSrc = (DestLen+1);
|
|
||||||
// We have at least one tab in the string, and the tab width is greater
|
|
||||||
// than 1. pSrc points to the first tab char in Line. We get the number
|
|
||||||
// of tabs and the length of the expanded string now.
|
|
||||||
int TabCount = 0;
|
|
||||||
do {
|
|
||||||
if (Line[pSrc] == '\t') {
|
|
||||||
DestLen = DestLen + TabWidth - DestLen % TabWidth;
|
|
||||||
TabCount++;
|
|
||||||
} else {
|
|
||||||
DestLen ++;
|
|
||||||
}
|
|
||||||
pSrc++;
|
|
||||||
} while (pSrc<Line.length());
|
|
||||||
// Set the length of the expanded string.
|
|
||||||
Result.resize(DestLen);
|
|
||||||
DestLen = 0;
|
|
||||||
pSrc = 0;
|
|
||||||
pDest = Result.data();
|
|
||||||
do {
|
|
||||||
if (Line[pSrc] == '\t') {
|
|
||||||
int i = TabWidth - (DestLen % TabWidth);
|
|
||||||
DestLen+=i;
|
|
||||||
do {
|
|
||||||
*pDest = '\t';
|
|
||||||
pDest++;
|
|
||||||
i--;
|
|
||||||
} while (i != 0);
|
|
||||||
TabCount--;
|
|
||||||
if (TabCount == 0) {
|
|
||||||
do {
|
|
||||||
pSrc++;
|
|
||||||
*pDest = Line[pSrc];
|
|
||||||
pDest++;
|
|
||||||
} while (pSrc<Line.length());
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*pDest = Line[pSrc];
|
|
||||||
pDest++;
|
|
||||||
DestLen++;
|
|
||||||
}
|
|
||||||
pSrc++;
|
|
||||||
} while (pSrc<Line.length());
|
|
||||||
} else
|
|
||||||
HasTabs = false;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetHasTabs(const QString &line, int &CharsBefore)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
CharsBefore = 0;
|
|
||||||
if (!line.isEmpty()) {
|
|
||||||
for (const QChar& ch:line) {
|
|
||||||
if (ch == '\t') {
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
CharsBefore ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetExpandedLength(const QString &aStr, int aTabWidth)
|
|
||||||
{
|
|
||||||
int Result = 0;
|
|
||||||
for (const QChar& ch : aStr) {
|
|
||||||
if (ch == '\t') {
|
|
||||||
Result += aTabWidth - (Result % aTabWidth);
|
|
||||||
} else {
|
|
||||||
Result ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CharIndex2CaretPos(int Index, int TabWidth, const QString &Line)
|
|
||||||
{
|
|
||||||
int Result;
|
|
||||||
int iChar;
|
|
||||||
if (Index > 1) {
|
|
||||||
if ((TabWidth <= 1) || !GetHasTabs(Line, iChar) ) {
|
|
||||||
Result = Index;
|
|
||||||
} else {
|
|
||||||
if (iChar + 1 >= Index) {
|
|
||||||
Result = Index;
|
|
||||||
} else {
|
|
||||||
// iChar is number of chars before first Tab
|
|
||||||
Result = iChar;
|
|
||||||
// Index is *not* zero-based
|
|
||||||
iChar++;
|
|
||||||
Index -= iChar;
|
|
||||||
int pNext = iChar;
|
|
||||||
while (Index > 0) {
|
|
||||||
if (pNext>=Line.length()) {
|
|
||||||
Result += Index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Line[pNext] == '\t') {
|
|
||||||
Result += TabWidth;
|
|
||||||
Result -= Result % TabWidth;
|
|
||||||
} else
|
|
||||||
Result++;
|
|
||||||
Index--;
|
|
||||||
pNext++;
|
|
||||||
}
|
|
||||||
// done with zero-based computation
|
|
||||||
Result++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
Result = 1;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CaretPos2CharIndex(int Position, int TabWidth, const QString &Line, bool &InsideTabChar)
|
|
||||||
{
|
|
||||||
int Result;
|
|
||||||
int iPos;
|
|
||||||
InsideTabChar = false;
|
|
||||||
if (Position > 1) {
|
|
||||||
if ( (TabWidth <= 1) || !GetHasTabs(Line, iPos) ) {
|
|
||||||
Result = Position;
|
|
||||||
} else {
|
|
||||||
if (iPos + 1 >= Position) {
|
|
||||||
Result = Position;
|
|
||||||
} else {
|
|
||||||
// iPos is number of chars before first #9
|
|
||||||
Result = iPos + 1;
|
|
||||||
int pNext = Result;
|
|
||||||
// for easier computation go zero-based (mod-operation)
|
|
||||||
Position -=1;
|
|
||||||
while (iPos < Position) {
|
|
||||||
if (pNext>=Line.length())
|
|
||||||
break;
|
|
||||||
if (Line[pNext] == '\t') {
|
|
||||||
iPos+=TabWidth;
|
|
||||||
iPos-=iPos % TabWidth;
|
|
||||||
if (iPos > Position) {
|
|
||||||
InsideTabChar = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
iPos++;
|
|
||||||
Result++;
|
|
||||||
pNext++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
Result = Position;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int StrScanForCharInSet(const QString &Line, int Start, const QSet<QChar>& AChars)
|
|
||||||
{
|
|
||||||
for (int i=Start;i<Line.length();i++) {
|
|
||||||
if (AChars.contains(Line[i])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int StrRScanForCharInSet(const QString &Line, int Start, const QSet<QChar> &AChars)
|
|
||||||
{
|
|
||||||
for (int i=Line.size()-1;i>=Start;i--) {
|
|
||||||
if (AChars.contains(Line[i])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetEOL(const QString &Line, int start)
|
|
||||||
{
|
|
||||||
if (start<0 || start>=Line.size()) {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
for (int i=start;i<Line.size();i++) {
|
|
||||||
if (Line[i] == '\n' || Line[i] == '\r') {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Line.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString EncodeString(const QString &s)
|
|
||||||
{
|
|
||||||
QString Result;
|
|
||||||
Result.resize(s.length()*2); // worst case
|
|
||||||
int j=0;
|
|
||||||
for (const QChar& ch: s) {
|
|
||||||
if (ch == '\\' ) {
|
|
||||||
Result[j] = '\\';
|
|
||||||
Result[j+1] = '\\';
|
|
||||||
j+=2;
|
|
||||||
} else if (ch == '/') {
|
|
||||||
Result[j] = '\\';
|
|
||||||
Result[j+1] = '.';
|
|
||||||
j+=2;
|
|
||||||
} else {
|
|
||||||
Result[j]=ch;
|
|
||||||
j+=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Result.resize(j);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DecodeString(const QString &s)
|
|
||||||
{
|
|
||||||
QString Result;
|
|
||||||
Result.resize(s.length()); // worst case
|
|
||||||
int j = 0;
|
|
||||||
int i = 0;
|
|
||||||
while (i < s.length()) {
|
|
||||||
if (i<s.length()-1 && s[i] == '\\' ) {
|
|
||||||
if (s[i+1] == '\\') {
|
|
||||||
Result[j]= '\\';
|
|
||||||
i+=2;
|
|
||||||
j+=1;
|
|
||||||
continue;
|
|
||||||
} else if (s[i+1] == '.') {
|
|
||||||
Result[j]= '/';
|
|
||||||
i+=2;
|
|
||||||
j+=1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Result[j] = Result[i];
|
|
||||||
i+=1;
|
|
||||||
j+=1;
|
|
||||||
}
|
|
||||||
Result.resize(j);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InternalEnumHighlighterAttris(PSynHighlighter Highlighter,
|
|
||||||
bool SkipDuplicates,
|
|
||||||
HighlighterAttriProc highlighterAttriProc,
|
|
||||||
std::initializer_list<void *>& Params,
|
|
||||||
SynHighlighterList& HighlighterList) {
|
|
||||||
bool Result = true;
|
|
||||||
if (HighlighterList.indexOf(Highlighter)>0) {
|
|
||||||
if (SkipDuplicates)
|
|
||||||
return Result;
|
|
||||||
} else {
|
|
||||||
HighlighterList.append(Highlighter);
|
|
||||||
}
|
|
||||||
if (Highlighter->getClass() == SynHighlighterClass::Composition) {
|
|
||||||
//todo: handle composition highlighter
|
|
||||||
} else if (Highlighter) {
|
|
||||||
for (PSynHighlighterAttribute pAttr: Highlighter->attributes()){
|
|
||||||
QString UniqueAttriName = Highlighter->getName()
|
|
||||||
+ HighlighterList.indexOf(Highlighter) + '.'
|
|
||||||
+ pAttr->name();
|
|
||||||
Result = highlighterAttriProc(Highlighter, pAttr,
|
|
||||||
UniqueAttriName, Params);
|
|
||||||
if (!Result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EnumHighlighterAttris(PSynHighlighter Highlighter, bool SkipDuplicates,
|
|
||||||
HighlighterAttriProc highlighterAttriProc,
|
|
||||||
std::initializer_list<void *> Params)
|
|
||||||
{
|
|
||||||
if (!Highlighter || !highlighterAttriProc) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynHighlighterList HighlighterList;
|
|
||||||
return InternalEnumHighlighterAttris(Highlighter, SkipDuplicates,
|
|
||||||
highlighterAttriProc, Params, HighlighterList);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t fcstab[] = {
|
|
||||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
|
||||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
|
||||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
|
||||||
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
|
||||||
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
|
||||||
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
|
||||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
|
||||||
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
|
||||||
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
|
||||||
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
|
||||||
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
|
||||||
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
|
||||||
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
|
||||||
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
|
||||||
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
|
||||||
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
|
||||||
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
|
||||||
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
|
||||||
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
|
||||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
|
||||||
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
|
||||||
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
|
||||||
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
|
||||||
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
|
||||||
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
|
||||||
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
|
||||||
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
|
||||||
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
|
||||||
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
|
||||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
|
||||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
|
||||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t CalcFCS(unsigned char *ABuf, int ABufSize)
|
|
||||||
{
|
|
||||||
uint16_t CurFCS = 0xffff;
|
|
||||||
unsigned char* P = ABuf;
|
|
||||||
while (ABufSize>0) {
|
|
||||||
CurFCS = (CurFCS >> 8) ^ fcstab[(CurFCS ^ *P) & 0xff];
|
|
||||||
ABufSize -- ;
|
|
||||||
P ++ ;
|
|
||||||
}
|
|
||||||
return CurFCS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynDrawGradient(QPaintDevice *ACanvas, const QColor &AStartColor, const QColor &AEndColor, int , const QRect &ARect, bool AHorizontal)
|
|
||||||
{
|
|
||||||
QPainter painter(ACanvas);
|
|
||||||
if (AHorizontal) {
|
|
||||||
int Size = ARect.right() - ARect.left();
|
|
||||||
QLinearGradient gradient(0,0,Size,0);
|
|
||||||
gradient.setColorAt(0,AStartColor);
|
|
||||||
gradient.setColorAt(1,AEndColor);
|
|
||||||
painter.fillRect(ARect,gradient);
|
|
||||||
} else {
|
|
||||||
int Size = ARect.bottom() - ARect.top();
|
|
||||||
QLinearGradient gradient(0,0,0,Size);
|
|
||||||
gradient.setColorAt(0,AStartColor);
|
|
||||||
gradient.setColorAt(1,AEndColor);
|
|
||||||
painter.fillRect(ARect,gradient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int MulDiv(int a, int b, int c)
|
|
||||||
{
|
|
||||||
//todo: handle overflow?
|
|
||||||
return a*b/c;
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
#ifndef MISCPROCS_H
|
|
||||||
#define MISCPROCS_H
|
|
||||||
#include <QPoint>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <QString>
|
|
||||||
#include <QSet>
|
|
||||||
#include "highlighter/base.h"
|
|
||||||
#include <QPaintDevice>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QVector>
|
|
||||||
#include <initializer_list>
|
|
||||||
//#include <QRect>
|
|
||||||
//#include <QColor>
|
|
||||||
|
|
||||||
class QPainter;
|
|
||||||
class QRect;
|
|
||||||
class QColor;
|
|
||||||
|
|
||||||
using IntArray = QVector<int>;
|
|
||||||
using PIntArray = std::shared_ptr<IntArray>;
|
|
||||||
|
|
||||||
int MinMax(int x, int mi, int ma);
|
|
||||||
int MulDiv(int a, int b, int c);
|
|
||||||
void SwapInt(int& l, int &r);
|
|
||||||
QPoint MaxPoint(const QPoint& P1, const QPoint& P2);
|
|
||||||
QPoint MinPoint(const QPoint& P1, const QPoint& P2);
|
|
||||||
|
|
||||||
PIntArray GetIntArray(size_t Count, int InitialValue);
|
|
||||||
|
|
||||||
void InternalFillRect(QPainter* painter, const QRect& rcPaint, const QColor& color);
|
|
||||||
|
|
||||||
// Converting tabs to spaces: To use the function several times it's better
|
|
||||||
// to use a function pointer that is set to the fastest conversion function.
|
|
||||||
using ConvertTabsProc = std::function<QString(const QString&, int)>;
|
|
||||||
|
|
||||||
ConvertTabsProc GetBestConvertTabsProc(int TabWidth);
|
|
||||||
|
|
||||||
// This is the slowest conversion function which can handle TabWidth <> 2^n.
|
|
||||||
QString ConvertTabs(const QString& Line, int TabWidth);
|
|
||||||
|
|
||||||
using ConvertTabsProcEx = std::function<QString(const QString&, int, bool& )>;
|
|
||||||
|
|
||||||
ConvertTabsProcEx GetBestConvertTabsProcEx(int TabWidth);
|
|
||||||
// This is the slowest conversion function which can handle TabWidth <> 2^n.
|
|
||||||
QString ConvertTabsEx(const QString& Line, int TabWidth, bool& HasTabs);
|
|
||||||
|
|
||||||
bool GetHasTabs(const QString& line, int& CharsBefore);
|
|
||||||
|
|
||||||
int GetExpandedLength(const QString& aStr, int aTabWidth);
|
|
||||||
|
|
||||||
int CharIndex2CaretPos(int Index, int TabWidth,
|
|
||||||
const QString& Line);
|
|
||||||
|
|
||||||
int CaretPos2CharIndex(int Position, int TabWidth, const QString& Line,
|
|
||||||
bool& InsideTabChar);
|
|
||||||
|
|
||||||
// search for the first char of set AChars in Line, starting at index Start
|
|
||||||
int StrScanForCharInSet(const QString& Line, int Start, const QSet<QChar>& AChars);
|
|
||||||
// the same, but searching backwards
|
|
||||||
int StrRScanForCharInSet(const QString& Line, int Start, const QSet<QChar>& AChars);
|
|
||||||
|
|
||||||
int GetEOL(const QString& Line, int start);
|
|
||||||
|
|
||||||
// Remove all '/' characters from string by changing them into '\.'.
|
|
||||||
// Change all '\' characters into '\\' to allow for unique decoding.
|
|
||||||
QString EncodeString(const QString & s);
|
|
||||||
|
|
||||||
// Decodes string, encoded with EncodeString.
|
|
||||||
QString DecodeString(const QString& s);
|
|
||||||
|
|
||||||
using HighlighterAttriProc = std::function<bool(PSynHighlighter Highlighter,
|
|
||||||
PSynHighlighterAttribute Attri, const QString& UniqueAttriName,
|
|
||||||
std::initializer_list<void *> Params)>;
|
|
||||||
|
|
||||||
// Enums all child highlighters and their attributes of a TSynMultiSyn through a
|
|
||||||
// callback function.
|
|
||||||
// This function also handles nested TSynMultiSyns including their MarkerAttri.
|
|
||||||
bool EnumHighlighterAttris(PSynHighlighter Highlighter,
|
|
||||||
bool SkipDuplicates, HighlighterAttriProc highlighterAttriProc,
|
|
||||||
std::initializer_list<void *> Params);
|
|
||||||
|
|
||||||
|
|
||||||
// Calculates Frame Check Sequence (FCS) 16-bit Checksum (as defined in RFC 1171)
|
|
||||||
uint16_t CalcFCS(unsigned char* ABuf, int ABufSize);
|
|
||||||
|
|
||||||
void SynDrawGradient(QPaintDevice* ACanvas, const QColor& AStartColor, const QColor& AEndColor,
|
|
||||||
int ASteps, const QRect& ARect, bool AHorizontal);
|
|
||||||
|
|
||||||
#endif // MISCPROCS_H
|
|
|
@ -1,771 +0,0 @@
|
||||||
#include "SynEdit.h"
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QFontMetrics>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
SynEdit::SynEdit(QWidget *parent, Qt::WindowFlags f) : QFrame(parent,f)
|
|
||||||
{
|
|
||||||
mPaintLock = 0;
|
|
||||||
mPainting = false;
|
|
||||||
mLines = std::make_shared<SynEditStringList>();
|
|
||||||
mOrigLines = mLines;
|
|
||||||
//fPlugins := TList.Create;
|
|
||||||
mMouseMoved = false;
|
|
||||||
mUndoing = false;
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::changed, this, &SynEdit::linesChanged);
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::changing, this, &SynEdit::linesChanging);
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::cleared, this, &SynEdit::linesCleared);
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::deleted, this, &SynEdit::linesDeleted);
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::inserted, this, &SynEdit::linesInserted);
|
|
||||||
mLines->connect(mLines.get(), &SynEditStringList::putted, this, &SynEdit::linesPutted);
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
mFontDummy = QFont("Consolas",10);
|
|
||||||
#elif Q_OS_LINUX
|
|
||||||
mFontDummy = QFont("terminal",14);
|
|
||||||
#else
|
|
||||||
#error "Not supported!"
|
|
||||||
#endif
|
|
||||||
mUndoList = std::make_shared<SynEditUndoList>();
|
|
||||||
mUndoList->connect(mUndoList.get(), &SynEditUndoList::addedUndo, this, &SynEdit::undoAdded);
|
|
||||||
mOrigUndoList = mUndoList;
|
|
||||||
mRedoList = std::make_shared<SynEditUndoList>();
|
|
||||||
mRedoList->connect(mRedoList.get(), &SynEditUndoList::addedUndo, this, &SynEdit::redoAdded);
|
|
||||||
mOrigRedoList = mRedoList;
|
|
||||||
//DoubleBuffered = false;
|
|
||||||
mActiveLineColor = QColor();
|
|
||||||
mSelectedBackground = QColor();
|
|
||||||
mSelectedForeground = QColor();
|
|
||||||
|
|
||||||
mBookMarkOpt.connect(&mBookMarkOpt, &SynBookMarkOpt::changed, this, &SynEdit::bookMarkOptionsChanged);
|
|
||||||
// fRightEdge has to be set before FontChanged is called for the first time
|
|
||||||
mRightEdge = 80;
|
|
||||||
mGutter.setRightOffset(21);
|
|
||||||
mGutter.connect(&mGutter, &SynGutter::changed, this, &SynEdit::gutterChanged);
|
|
||||||
mGutterWidth = mGutter.width();
|
|
||||||
mTextOffset = mGutterWidth + 2;
|
|
||||||
//ControlStyle := ControlStyle + [csOpaque, csSetCaption, csNeedsBorderPaint];
|
|
||||||
//Height := 150;
|
|
||||||
//Width := 200;
|
|
||||||
this->setCursor(Qt::CursorShape::IBeamCursor);
|
|
||||||
//TabStop := True;
|
|
||||||
mInserting = true;
|
|
||||||
mMaxScrollWidth = 1024;
|
|
||||||
mScrollBars = SynScrollStyle::ssBoth;
|
|
||||||
this->setFrameShape(QFrame::Panel);
|
|
||||||
this->setFrameShadow(QFrame::Sunken);
|
|
||||||
this->setLineWidth(1);
|
|
||||||
mInsertCaret = SynEditCaretType::ctVerticalLine;
|
|
||||||
mOverwriteCaret = SynEditCaretType::ctBlock;
|
|
||||||
mSelectionMode = SynSelectionMode::smNormal;
|
|
||||||
mActiveSelectionMode = SynSelectionMode::smNormal;
|
|
||||||
//stop qt to auto fill background
|
|
||||||
setAutoFillBackground(false);
|
|
||||||
//fFocusList := TList.Create;
|
|
||||||
//fKbdHandler := TSynEditKbdHandler.Create;
|
|
||||||
//fMarkList.OnChange := MarkListChange;
|
|
||||||
setDefaultKeystrokes();
|
|
||||||
mRightEdgeColor = QColorConstants::Svg::silver;
|
|
||||||
/* IME input */
|
|
||||||
mImeCount = 0;
|
|
||||||
mMBCSStepAside = false;
|
|
||||||
/* end of IME input */
|
|
||||||
mWantReturns = true;
|
|
||||||
mWantTabs = false;
|
|
||||||
mTabWidth = 4;
|
|
||||||
mLeftChar = 1;
|
|
||||||
mTopLine = 1;
|
|
||||||
mCaretX = 1;
|
|
||||||
mLastCaretX = 1;
|
|
||||||
mCaretY = 1;
|
|
||||||
mBlockBegin.Char = 1;
|
|
||||||
mBlockBegin.Line = 1;
|
|
||||||
mBlockEnd = mBlockBegin;
|
|
||||||
mOptions = eoAutoIndent | eoDragDropEditing | eoEnhanceEndKey |
|
|
||||||
eoScrollPastEol | eoShowScrollHint | eoSmartTabs | eoTabsToSpaces |
|
|
||||||
eoSmartTabDelete| eoGroupUndo;
|
|
||||||
mScrollTimer = new QTimer(this);
|
|
||||||
mScrollTimer->setInterval(100);
|
|
||||||
connect(mScrollTimer, &QTimer::timeout,this, &SynEdit::scrollTimerHandler);
|
|
||||||
|
|
||||||
mScrollHintColor = QColorConstants::Yellow;
|
|
||||||
mScrollHintFormat = SynScrollHintFormat::shfTopLineOnly;
|
|
||||||
|
|
||||||
synFontChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::displayLineCount()
|
|
||||||
{
|
|
||||||
return lineToRow(mLines->count());
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferCoord SynEdit::caretXY()
|
|
||||||
{
|
|
||||||
BufferCoord result;
|
|
||||||
result.Char = caretX();
|
|
||||||
result.Line = caretY();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::caretX()
|
|
||||||
{
|
|
||||||
return mCaretX;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::caretY()
|
|
||||||
{
|
|
||||||
return mCaretY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::setCaretXY(const BufferCoord &value)
|
|
||||||
{
|
|
||||||
setCaretXYCentered(false,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::setCaretXYEx(bool CallEnsureCursorPos, BufferCoord value)
|
|
||||||
{
|
|
||||||
bool vTriggerPaint=true; //how to test it?
|
|
||||||
|
|
||||||
if (vTriggerPaint)
|
|
||||||
doOnPaintTransient(SynTransientType::ttBefore);
|
|
||||||
int nMaxX = mMaxScrollWidth + 1;
|
|
||||||
if (value.Line > mLines->count())
|
|
||||||
value.Line = mLines->count();
|
|
||||||
if (value.Line < 1) {
|
|
||||||
// this is just to make sure if Lines stringlist should be empty
|
|
||||||
value.Line = 1;
|
|
||||||
if (!mOptions.testFlag(SynEditorOption::eoScrollPastEol)) {
|
|
||||||
nMaxX = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!mOptions.testFlag(SynEditorOption::eoScrollPastEol))
|
|
||||||
nMaxX = mLines->getString(value.Line-1).length();
|
|
||||||
}
|
|
||||||
if ((value.Char > nMaxX) && (! (mOptions.testFlag(SynEditorOption::eoScrollPastEol)) ||
|
|
||||||
!(mOptions.testFlag(SynEditorOption::eoAutoSizeMaxScrollWidth))) )
|
|
||||||
value.Char = nMaxX;
|
|
||||||
if (value.Char < 1)
|
|
||||||
value.Char = 1;
|
|
||||||
if ((value.Char != mCaretX) || (value.Line != mCaretY)) {
|
|
||||||
incPaintLock();
|
|
||||||
auto action = finally([this]{
|
|
||||||
decPaintLock();
|
|
||||||
});
|
|
||||||
// simply include the flags, fPaintLock is > 0
|
|
||||||
if (mCaretX != value.Char) {
|
|
||||||
mCaretX = value.Char;
|
|
||||||
mStatusChanges.setFlag(SynStatusChange::scCaretX);
|
|
||||||
}
|
|
||||||
if (mCaretY != value.Line) {
|
|
||||||
if (!mActiveLineColor.isValid()) {
|
|
||||||
invalidateLine(value.Line);
|
|
||||||
invalidateLine(mCaretY);
|
|
||||||
}
|
|
||||||
mCaretY = value.Line;
|
|
||||||
mStatusChanges.setFlag(SynStatusChange::scCaretY);
|
|
||||||
}
|
|
||||||
// Call UpdateLastCaretX before DecPaintLock because the event handler it
|
|
||||||
// calls could raise an exception, and we don't want fLastCaretX to be
|
|
||||||
// left in an undefined state if that happens.
|
|
||||||
updateLastCaretX();
|
|
||||||
if (CallEnsureCursorPos)
|
|
||||||
ensureCursorPosVisible();
|
|
||||||
mStateFlags.setFlag(SynStateFlag::sfCaretChanged);
|
|
||||||
mStateFlags.setFlag(SynStateFlag::sfScrollbarChanged);
|
|
||||||
} else {
|
|
||||||
// Also call UpdateLastCaretX if the caret didn't move. Apps don't know
|
|
||||||
// anything about fLastCaretX and they shouldn't need to. So, to avoid any
|
|
||||||
// unwanted surprises, always update fLastCaretX whenever CaretXY is
|
|
||||||
// assigned to.
|
|
||||||
// Note to SynEdit developers: If this is undesirable in some obscure
|
|
||||||
// case, just save the value of fLastCaretX before assigning to CaretXY and
|
|
||||||
// restore it afterward as appropriate.
|
|
||||||
updateLastCaretX();
|
|
||||||
}
|
|
||||||
if (vTriggerPaint)
|
|
||||||
doOnPaintTransient(SynTransientType::ttAfter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::setCaretXYCentered(bool ForceToMiddle, const BufferCoord &value)
|
|
||||||
{
|
|
||||||
incPaintLock();
|
|
||||||
auto action = finally([this] {
|
|
||||||
decPaintLock();
|
|
||||||
});
|
|
||||||
mStatusChanges.setFlag(SynStatusChange::scSelection);
|
|
||||||
setCaretXYEx(ForceToMiddle,value);
|
|
||||||
if selAvail() then
|
|
||||||
invalidateSelection();
|
|
||||||
mBlockBegin.Char = mCaretX;
|
|
||||||
mBlockBegin.Line = mCaretY;
|
|
||||||
mBlockEnd = mBlockBegin;
|
|
||||||
if (ForceToMiddle)
|
|
||||||
ensureCursorPosVisibleEx(true); // but here after block has been set
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::invalidateGutter()
|
|
||||||
{
|
|
||||||
invalidateGutterLines(-1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::invalidateGutterLine(int aLine)
|
|
||||||
{
|
|
||||||
if ((aLine < 1) || (aLine > mLines->count()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
invalidateGutterLines(aLine, aLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::invalidateGutterLines(int FirstLine, int LastLine)
|
|
||||||
{
|
|
||||||
QRect rcInval;
|
|
||||||
if (!isVisible())
|
|
||||||
return;
|
|
||||||
if (FirstLine == -1 && LastLine == -1) {
|
|
||||||
rcInval = QRect(clientLeft(), clientTop(), mGutterWidth, clientHeight());
|
|
||||||
if (mStateFlags.testFlag(SynStateFlag::sfLinesChanging))
|
|
||||||
mInvalidateRect = mInvalidateRect.united(rcInval);
|
|
||||||
else
|
|
||||||
update(rcInval);
|
|
||||||
} else {
|
|
||||||
// find the visible lines first
|
|
||||||
if (LastLine < FirstLine)
|
|
||||||
std::swap(LastLine, FirstLine);
|
|
||||||
if (mUseCodeFolding) {
|
|
||||||
FirstLine = lineToRow(FirstLine);
|
|
||||||
if (LastLine <= mLines->count())
|
|
||||||
LastLine = lineToRow(LastLine);
|
|
||||||
else
|
|
||||||
LastLine = INT_MAX;
|
|
||||||
}
|
|
||||||
FirstLine = std::max(FirstLine, topLine());
|
|
||||||
LastLine = std::min(LastLine, topLine() + linesInWindow());
|
|
||||||
// any line visible?
|
|
||||||
if (LastLine >= FirstLine) {
|
|
||||||
rcInval = {clientLeft(), clientTop()+mTextHeight * (FirstLine - topLine()),
|
|
||||||
mGutterWidth, mTextHeight * (LastLine - topLine() + 1)};
|
|
||||||
if (mStateFlags.testFlag(SynStateFlag::sfLinesChanging)) {
|
|
||||||
mInvalidateRect = mInvalidateRect.united(rcInval);
|
|
||||||
} else {
|
|
||||||
update(rcInval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert point on the edit (x,y) to (row,column)
|
|
||||||
* @param aX
|
|
||||||
* @param aY
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
DisplayCoord SynEdit::pixelsToNearestRowColumn(int aX, int aY)
|
|
||||||
{
|
|
||||||
// Result is in display coordinates
|
|
||||||
float f;
|
|
||||||
f = (aX - mGutterWidth - 2.0) / mCharWidth;
|
|
||||||
// don't return a partially visible last line
|
|
||||||
if (aY >= mLinesInWindow * mTextHeight) {
|
|
||||||
aY = mLinesInWindow * mTextHeight - 1;
|
|
||||||
if (aY < 0)
|
|
||||||
aY = 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
.Column = std::max(1, leftChar() + round(f)),
|
|
||||||
.Row = std::max(1, topLine() + (aY % mTextHeight))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief takes a position in the text and transforms it into
|
|
||||||
* the row and column it appears to be on the screen
|
|
||||||
* @param p
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
DisplayCoord SynEdit::bufferToDisplayPos(const BufferCoord &p)
|
|
||||||
{
|
|
||||||
DisplayCoord result {p.Char,p.Line};
|
|
||||||
// Account for tabs
|
|
||||||
if (p.Line-1 < mLines->count()) {
|
|
||||||
QString s = mLines->getString(p.Line - 1);
|
|
||||||
int l = s.length();
|
|
||||||
int x = 0;
|
|
||||||
for (int i=0;i<p.Char-1;i++) {
|
|
||||||
if (i<=l && s[i] == '\t')
|
|
||||||
x+=mTabWidth - (x % mTabWidth);
|
|
||||||
else
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
result.Column = x + 1;
|
|
||||||
}
|
|
||||||
// Account for code folding
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
result.Row = foldLineToRow(result.Row);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief takes a position on screen and transfrom it into position of text
|
|
||||||
* @param p
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
BufferCoord SynEdit::displayToBufferPos(const DisplayCoord &p)
|
|
||||||
{
|
|
||||||
BufferCoord Result{p.Column,p.Row};
|
|
||||||
// Account for code folding
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
Result.Line = foldRowToLine(Result.Line);
|
|
||||||
// Account for tabs
|
|
||||||
if (Result.Line <= mLines->count() ) {
|
|
||||||
QString s = mLines->getString(Result.Line - 1);
|
|
||||||
int l = s.length();
|
|
||||||
int x = 0;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (x < p.Column) {
|
|
||||||
if (i < l && s[i] == '\t')
|
|
||||||
x += mTabWidth - (x % mTabWidth);
|
|
||||||
else
|
|
||||||
x += 1;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
Result.Char = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::rowToLine(int aRow)
|
|
||||||
{
|
|
||||||
return displayToBufferPos({1, aRow}).Line;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::lineToRow(int aLine)
|
|
||||||
{
|
|
||||||
return bufferToDisplayPos({1, aLine}).Row;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::foldRowToLine(int Row)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int result = Row;
|
|
||||||
for (int i=0;i<mAllFoldRanges.count();i++) {
|
|
||||||
PSynEditFoldRange range = mAllFoldRanges.ranges[i];
|
|
||||||
if (range->collapsed && !range->parentCollapsed() && range->fromLine < result) {
|
|
||||||
result += range->linesCollapsed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::foldLineToRow(int Line)
|
|
||||||
{
|
|
||||||
int result = Line;
|
|
||||||
for (int i=mAllFoldRanges.count()-1;i>=0;i--) {
|
|
||||||
PSynEditFoldRange range =mAllFoldRanges.ranges[i];
|
|
||||||
if (range->collapsed && !range->parentCollapsed()) {
|
|
||||||
// Line is found after fold
|
|
||||||
if (range->toLine < Line)
|
|
||||||
result -= range->linesCollapsed;
|
|
||||||
// Inside fold
|
|
||||||
else if (range->fromLine < Line && Line <= range->toLine)
|
|
||||||
result -= Line - range->fromLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::setDefaultKeystrokes()
|
|
||||||
{
|
|
||||||
mKeyStrokes.resetDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::invalidateLine(int Line)
|
|
||||||
{
|
|
||||||
QRect rcInval;
|
|
||||||
if (mPaintLock >0)
|
|
||||||
return;
|
|
||||||
if (Line<1 || Line>mLines.count() || !isVisible())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// invalidate text area of this line
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
Line = foldLineToRow(Line);
|
|
||||||
if (Line >= topLine() && Line <= topLine() + linesInWindow()) {
|
|
||||||
rcInval = { clientLeft() + mGutterWidth,
|
|
||||||
clientTop() + mTextHeight * (Line - topLine()),
|
|
||||||
clientWidth(),
|
|
||||||
mTextHeight};
|
|
||||||
if (mStateFlags.testFlag(SynStateFlag::sfLinesChanging))
|
|
||||||
mInvalidateRect = mInvalidateRect.united(rcInval);
|
|
||||||
else
|
|
||||||
update(rcInval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::lockPainter()
|
|
||||||
{
|
|
||||||
incPaintLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::unlockPainter()
|
|
||||||
{
|
|
||||||
decPaintLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::clearAreaList(SynEditingAreaList areaList)
|
|
||||||
{
|
|
||||||
areaList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::computeCaret(int X, int Y)
|
|
||||||
{
|
|
||||||
DisplayCoord vCaretNearestPos = pixelsToNearestRowColumn(X, Y);
|
|
||||||
vCaretNearestPos.Row = MinMax(vCaretNearestPos.Row, 1, displayLineCount());
|
|
||||||
setInternalDisplayXY(vCaretNearestPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::computeScroll(int X, int Y)
|
|
||||||
{
|
|
||||||
QRect iScrollBounds; // relative to the client area
|
|
||||||
// don't scroll if dragging text from other control
|
|
||||||
// if (not MouseCapture) and (not Dragging) then begin
|
|
||||||
// fScrollTimer.Enabled := False;
|
|
||||||
// Exit;
|
|
||||||
// end;
|
|
||||||
|
|
||||||
iScrollBounds = QRect(mGutterWidth+this->frameWidth(), this->frameWidth(), mCharsInWindow * mCharWidth,
|
|
||||||
mLinesInWindow * mTextHeight);
|
|
||||||
|
|
||||||
if (X < iScrollBounds.left())
|
|
||||||
mScrollDeltaX = (X - iScrollBounds.left()) % mCharWidth - 1;
|
|
||||||
else if (X >= iScrollBounds.right())
|
|
||||||
mScrollDeltaX = (X - iScrollBounds.right()) % mCharWidth + 1;
|
|
||||||
else
|
|
||||||
mScrollDeltaX = 0;
|
|
||||||
|
|
||||||
if (Y < iScrollBounds.top())
|
|
||||||
mScrollDeltaY = (Y - iScrollBounds.top()) % mTextHeight - 1;
|
|
||||||
else if (Y >= iScrollBounds.bottom())
|
|
||||||
mScrollDeltaY = (Y - iScrollBounds.bottom()) % mTextHeight + 1;
|
|
||||||
else
|
|
||||||
mScrollDeltaY = 0;
|
|
||||||
|
|
||||||
if (mScrollDeltaX!=0 || mScrollDeltaY!=0)
|
|
||||||
mScrollTimer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::doBlockIndent()
|
|
||||||
{
|
|
||||||
BufferCoord OrgCaretPos;
|
|
||||||
BufferCoord BB, BE;
|
|
||||||
QString StrToInsert;
|
|
||||||
int Run;
|
|
||||||
int e,x,i,InsertStrLen;
|
|
||||||
QString Spaces;
|
|
||||||
SynSelectionMode OrgSelectionMode;
|
|
||||||
BufferCoord InsertionPos;
|
|
||||||
|
|
||||||
OrgSelectionMode = mActiveSelectionMode;
|
|
||||||
OrgCaretPos = caretXY();
|
|
||||||
StrToInsert = nullptr;
|
|
||||||
if (selAvail()) {
|
|
||||||
auto action = finally([&,this]{
|
|
||||||
if (BE.Char > 1)
|
|
||||||
BE.Char+=Spaces.length();
|
|
||||||
setCaretAndSelection(OrgCaretPos,
|
|
||||||
{BB.Char + Spaces.length(), BB.Line}, BE);
|
|
||||||
setActiveSelectionMode(OrgSelectionMode);
|
|
||||||
});
|
|
||||||
// keep current selection detail
|
|
||||||
BB = blockBegin();
|
|
||||||
BE = blockEnd();
|
|
||||||
// build text to insert
|
|
||||||
if (BE.Char == 1) {
|
|
||||||
e = BE.Line - 1;
|
|
||||||
x = 1;
|
|
||||||
} else {
|
|
||||||
e = BE.Line;
|
|
||||||
if (mOptions.testFlag(SynEditorOption::eoTabsToSpaces))
|
|
||||||
x = caretX() + mTabWidth;
|
|
||||||
else
|
|
||||||
x = caretX() + 1;
|
|
||||||
}
|
|
||||||
if (mOptions.testFlag(eoTabsToSpaces)) {
|
|
||||||
InsertStrLen = (mTabWidth + 2) * (e - BB.Line) + mTabWidth + 1;
|
|
||||||
// chars per line * lines-1 + last line + null char
|
|
||||||
StrToInsert.resize(InsertStrLen);
|
|
||||||
Run = 0;
|
|
||||||
Spaces = QString(mTabWidth,' ') ;
|
|
||||||
} else {
|
|
||||||
InsertStrLen = 3 * (e - BB.Line) + 2;
|
|
||||||
// #9#13#10 * lines-1 + (last line's #9 + null char)
|
|
||||||
StrToInsert.resize(InsertStrLen);
|
|
||||||
Run = 0;
|
|
||||||
Spaces = "\t";
|
|
||||||
}
|
|
||||||
for (i = BB.Line; i<e;i++) {
|
|
||||||
StrToInsert.replace(Run,Spaces.length()+2,Spaces+"\r\n");
|
|
||||||
Run+=Spaces.length()+2;
|
|
||||||
}
|
|
||||||
StrToInsert.replace(Run,Spaces.length(),Spaces);
|
|
||||||
|
|
||||||
{
|
|
||||||
mUndoList->BeginBlock();
|
|
||||||
auto action2=finally([this]{
|
|
||||||
mUndoList->EndBlock();
|
|
||||||
});
|
|
||||||
InsertionPos.Line = BB.Line;
|
|
||||||
if (mActiveSelectionMode == SynSelectionMode::smColumn)
|
|
||||||
InsertionPos.Char = std::min(BB.Char, BE.Char);
|
|
||||||
else
|
|
||||||
InsertionPos.Char = 1;
|
|
||||||
insertBlock(InsertionPos, InsertionPos, StrToInsert, true);
|
|
||||||
mUndoList->AddChange(SynChangeReason::crIndent, BB, BE, "", SynSelectionMode::smColumn);
|
|
||||||
//We need to save the position of the end block for redo
|
|
||||||
mUndoList.AddChange(SynChangeReason::crIndent,
|
|
||||||
{BB.Char + Spaces.length(), BB.Line},
|
|
||||||
{BE.Char + Spaces.length(), BE.Line},
|
|
||||||
"", SynSelectionMode::smColumn);
|
|
||||||
//adjust the x position of orgcaretpos appropriately
|
|
||||||
OrgCaretPos.Char = X;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::incPaintLock()
|
|
||||||
{
|
|
||||||
mPaintLock ++ ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::decPaintLock()
|
|
||||||
{
|
|
||||||
Q_ASSERT(mPaintLock > 0);
|
|
||||||
mPaintLock--;
|
|
||||||
if (mPaintLock == 0 ) {
|
|
||||||
if (mStateFlags.testFlag(SynStateFlag::sfScrollbarChanged))
|
|
||||||
updateScrollbars();
|
|
||||||
if (mStateFlags.testFlag(SynStateFlag::sfCaretChanged))
|
|
||||||
updateCaret();
|
|
||||||
if (mStatusChanges!=0)
|
|
||||||
doOnStatusChange(mStatusChanges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEdit::mouseCapture()
|
|
||||||
{
|
|
||||||
return hasMouseTracking();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::clientWidth()
|
|
||||||
{
|
|
||||||
return frameRect().width()-2*frameWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::clientHeight()
|
|
||||||
{
|
|
||||||
return frameRect().height()-2*frameWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::clientTop()
|
|
||||||
{
|
|
||||||
return frameRect().top()+frameWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEdit::clientLeft()
|
|
||||||
{
|
|
||||||
return frameRect().left()+frameWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect SynEdit::clientRect()
|
|
||||||
{
|
|
||||||
return QRect(frameRect().left()+frameWidth(),frameRect().top()+frameWidth(), frameRect().width()-2*frameWidth(), frameRect().height()-2*frameWidth());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::synFontChanged()
|
|
||||||
{
|
|
||||||
recalcCharExtent();
|
|
||||||
sizeOrFontChanged(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::doOnPaintTransient(SynTransientType TransientType)
|
|
||||||
{
|
|
||||||
doOnPaintTransientEx(TransientType, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::bookMarkOptionsChanged()
|
|
||||||
{
|
|
||||||
invalidateGutter();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesChanged()
|
|
||||||
{
|
|
||||||
SynSelectionMode vOldMode;
|
|
||||||
mStateFlags.setFlag(SynStateFlag::sfLinesChanging, false);
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
rescan();
|
|
||||||
|
|
||||||
updateScrollBars();
|
|
||||||
vOldMode = mActiveSelectionMode;
|
|
||||||
setBlockBegin(caretXY());
|
|
||||||
mActiveSelectionMode = vOldMode;
|
|
||||||
update(mInvalidateRect);
|
|
||||||
mInvalidateRect = {0,0,0,0};
|
|
||||||
|
|
||||||
if (mGutter.showLineNumbers() && (mGutter.autoSize()))
|
|
||||||
mGutter.autoSizeDigitCount(mLines->count());
|
|
||||||
if (!mOptions.testFlag(SynEditorOption::eoScrollPastEof))
|
|
||||||
setTopLine(mTopLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesChanging()
|
|
||||||
{
|
|
||||||
mStateFlags.setFlag(SynStateFlag::sfLinesChanging);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesCleared()
|
|
||||||
{
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
foldOnListCleared();
|
|
||||||
clearUndo();
|
|
||||||
// invalidate the *whole* client area
|
|
||||||
mInvalidateRect={0,0,0,0};
|
|
||||||
update();
|
|
||||||
// set caret and selected block to start of text
|
|
||||||
setCaretXY({1,1});
|
|
||||||
// scroll to start of text
|
|
||||||
setTopLine(1);
|
|
||||||
setLeftChar(1);
|
|
||||||
mStatusChanges.setFlag(SynStatusChange::scAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesDeleted(int index, int count)
|
|
||||||
{
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
foldOnListDeleted(index + 1, count);
|
|
||||||
if (mHighlighter && mLines->count() > 0)
|
|
||||||
scanFrom(index);
|
|
||||||
invalidateLines(index + 1, INT_MAX);
|
|
||||||
invalidateGutterLines(index + 1, INT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesInserted(int index, int count)
|
|
||||||
{
|
|
||||||
if (mUseCodeFolding)
|
|
||||||
foldOnListInserted(index + 1, count);
|
|
||||||
if (mHighlighter && mLines->count() > 0) {
|
|
||||||
int vLastScan = index;
|
|
||||||
do {
|
|
||||||
vLastScan = scanFrom(vLastScan);
|
|
||||||
vLastScan++;
|
|
||||||
} while (vLastScan < index + count) ;
|
|
||||||
}
|
|
||||||
invalidateLines(index + 1, INT_MAX);
|
|
||||||
invalidateGutterLines(index + 1, INT_MAX);
|
|
||||||
if (mOptions.setFlag(SynEditorOption::eoAutoSizeMaxScrollWidth)) {
|
|
||||||
int L = mLines->expandedStringLength(index);
|
|
||||||
if (L > mMaxScrollWidth)
|
|
||||||
setMaxScrollWidth(L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::linesPutted(int index, int count)
|
|
||||||
{
|
|
||||||
int vEndLine = index + 1;
|
|
||||||
if (mHighlighter) {
|
|
||||||
vEndLine = std::max(vEndLine, scanFrom(index) + 1);
|
|
||||||
// If this editor is chained then the real owner of text buffer will probably
|
|
||||||
// have already parsed the changes, so ScanFrom will return immediately.
|
|
||||||
if (mLines != mOrigLines)
|
|
||||||
vEndLine = INT_MAX;
|
|
||||||
}
|
|
||||||
invalidateLines(index + 1, vEndLine);
|
|
||||||
|
|
||||||
if (mOptions.setFlag(SynEditorOption::eoAutoSizeMaxScrollWidth)) {
|
|
||||||
int L = mLines->expandedStringLength(index);
|
|
||||||
if (L > mMaxScrollWidth)
|
|
||||||
setMaxScrollWidth(L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::undoAdded()
|
|
||||||
{
|
|
||||||
updateModifiedStatus();
|
|
||||||
|
|
||||||
// we have to clear the redo information, since adding undo info removes
|
|
||||||
// the necessary context to undo earlier edit actions
|
|
||||||
if (! mUndoList->insideRedo() &&
|
|
||||||
mUndoList->PeekItem() && (mUndoList->PeekItem()->changeReason()!=SynChangeReason::crGroupBreak))
|
|
||||||
mRedoList->Clear();
|
|
||||||
if (mUndoList->blockCount() == 0 )
|
|
||||||
doChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::redoAdded()
|
|
||||||
{
|
|
||||||
updateModifiedStatus();
|
|
||||||
|
|
||||||
if (mRedoList->blockCount() == 0 )
|
|
||||||
doChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::gutterChanged()
|
|
||||||
{
|
|
||||||
if (mGutter.showLineNumbers() && mGutter.autoSize())
|
|
||||||
mGutter.autoSizeDigitCount(mLines->count());
|
|
||||||
int nW;
|
|
||||||
if (mGutter.useFontStyle()) {
|
|
||||||
QFontMetrics fm=QFontMetrics(mGutter.font());
|
|
||||||
nW = mGutter.realGutterWidth(fm.averageCharWidth());
|
|
||||||
} else {
|
|
||||||
nW = mGutter.realGutterWidth(mCharWidth);
|
|
||||||
}
|
|
||||||
if (nW == mGutterWidth)
|
|
||||||
invalidateGutter();
|
|
||||||
else
|
|
||||||
setGutterWidth(nW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEdit::scrollTimerHandler()
|
|
||||||
{
|
|
||||||
QPoint iMousePos;
|
|
||||||
DisplayCoord C;
|
|
||||||
int X, Y;
|
|
||||||
|
|
||||||
iMousePos = QCursor::pos();
|
|
||||||
iMousePos = mapFromGlobal(iMousePos);
|
|
||||||
C = pixelsToRowColumn(iMousePos.x(), iMousePos.y());
|
|
||||||
C.Row = MinMax(C.Row, 1, displayLineCount());
|
|
||||||
if (mScrollDeltaX != 0) {
|
|
||||||
setLeftChar(leftChar() + mScrollDeltaX);
|
|
||||||
X = leftChar();
|
|
||||||
if (mScrollDeltaX > 0) // scrolling right?
|
|
||||||
X+=charsInWindow();
|
|
||||||
C.Column = X;
|
|
||||||
}
|
|
||||||
if (mScrollDeltaY != 0) {
|
|
||||||
if (QApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier))
|
|
||||||
setTopLine(topLine() + mScrollDeltaY * linesInWindow());
|
|
||||||
else
|
|
||||||
setTopLine(topLine()) + mScrollDeltaY);
|
|
||||||
Y = topLine();
|
|
||||||
if (mScrollDeltaY > 0) // scrolling down?
|
|
||||||
Y+=linesInWindow() - 1;
|
|
||||||
C.Row = MinMax(Y, 1, displayLineCount());
|
|
||||||
}
|
|
||||||
BufferCoord vCaret = displayToBufferPos(C);
|
|
||||||
if ((caretX() <> vCaret.Char) || (caretY() != vCaret.Line)) {
|
|
||||||
// changes to line / column in one go
|
|
||||||
incPaintLock();
|
|
||||||
auto action = finally([this]{
|
|
||||||
decPaintLock();
|
|
||||||
});
|
|
||||||
setInternalCaretXY(vCaret);
|
|
||||||
|
|
||||||
// if MouseCapture is True we're changing selection. otherwise we're dragging
|
|
||||||
if (mouseCapture())
|
|
||||||
setBlockEnd(caretXY());
|
|
||||||
}
|
|
||||||
computeScroll(iMousePos.x(), iMousePos.y());
|
|
||||||
}
|
|
|
@ -1,338 +0,0 @@
|
||||||
#ifndef SYNEDIT_H
|
|
||||||
#define SYNEDIT_H
|
|
||||||
|
|
||||||
#include <QCursor>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QWidget>
|
|
||||||
#include "MiscClasses.h"
|
|
||||||
#include "CodeFolding.h"
|
|
||||||
#include "Types.h"
|
|
||||||
#include "TextBuffer.h"
|
|
||||||
#include "KeyStrokes.h"
|
|
||||||
|
|
||||||
enum class SynFontSmoothMethod {
|
|
||||||
None, AntiAlias, ClearType
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum class SynScrollHintFormat {
|
|
||||||
shfTopLineOnly, shfTopToBottom
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynScrollStyle {
|
|
||||||
ssNone, ssHorizontal, ssVertical, ssBoth
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynEditCaretType {
|
|
||||||
ctVerticalLine, ctHorizontalLine, ctHalfBlock, ctBlock
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynStatusChange {
|
|
||||||
scAll = 0x0001,
|
|
||||||
scCaretX = 0x0002,
|
|
||||||
scCaretY = 0x0004,
|
|
||||||
scLeftChar = 0x0008,
|
|
||||||
scTopLine = 0x0010,
|
|
||||||
scInsertMode = 0x0020,
|
|
||||||
scModified = 0x0040,
|
|
||||||
scSelection = 0x0080,
|
|
||||||
scReadOnly = 0x0100,
|
|
||||||
scOpenFile = 0x0200
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(SynStatusChanges, SynStatusChange)
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SynStatusChanges)
|
|
||||||
|
|
||||||
enum class SynStateFlag {
|
|
||||||
sfCaretChanged = 0x0001,
|
|
||||||
sfScrollbarChanged = 0x0002,
|
|
||||||
sfLinesChanging = 0x0004,
|
|
||||||
sfIgnoreNextChar = 0x0008,
|
|
||||||
sfCaretVisible = 0x0010,
|
|
||||||
sfDblClicked = 0x0020,
|
|
||||||
sfWaitForDragging = 0x0040
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(SynStateFlags,SynStateFlag)
|
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SynStateFlags)
|
|
||||||
|
|
||||||
enum SynEditorOption {
|
|
||||||
eoAltSetsColumnMode = 0x00000001, //Holding down the Alt Key will put the selection mode into columnar format
|
|
||||||
eoAutoIndent = 0x00000002, //Will indent the caret on new lines with the same amount of leading white space as the preceding line
|
|
||||||
eoAddIndent = 0x00000004, //Will add one tab width of indent when typing { and :, and remove the same amount when typing }
|
|
||||||
eoAutoSizeMaxScrollWidth = 0x00000008, //Automatically resizes the MaxScrollWidth property when inserting text
|
|
||||||
eoDisableScrollArrows = 0x00000010 , //Disables the scroll bar arrow buttons when you can't scroll in that direction any more
|
|
||||||
eoDragDropEditing = 0x00000020, //Allows you to select a block of text and drag it within the document to another location
|
|
||||||
eoDropFiles = 0x00000040, //Allows the editor accept OLE file drops
|
|
||||||
eoEnhanceHomeKey = 0x00000080, //enhances home key positioning, similar to visual studio
|
|
||||||
eoEnhanceEndKey = 0x00000100, //enhances End key positioning, similar to JDeveloper
|
|
||||||
eoGroupUndo = 0x00000200, //When undoing/redoing actions, handle all continous changes of the same kind in one call instead undoing/redoing each command separately
|
|
||||||
eoHalfPageScroll = 0x00000400, //When scrolling with page-up and page-down commands, only scroll a half page at a time
|
|
||||||
eoHideShowScrollbars = 0x00000800, //if enabled, then the scrollbars will only show when necessary. If you have ScrollPastEOL, then it the horizontal bar will always be there (it uses MaxLength instead)
|
|
||||||
eoKeepCaretX = 0x00001000 , //When moving through lines w/o Cursor Past EOL, keeps the X position of the cursor
|
|
||||||
eoNoCaret = 0x00002000, //Makes it so the caret is never visible
|
|
||||||
eoNoSelection = 0x00004000, //Disables selecting text
|
|
||||||
eoRightMouseMovesCursor = 0x00008000, //When clicking with the right mouse for a popup menu, move the cursor to that location
|
|
||||||
eoScrollByOneLess = 0x00010000, //Forces scrolling to be one less
|
|
||||||
eoScrollHintFollows = 0x00020000, //The scroll hint follows the mouse when scrolling vertically
|
|
||||||
eoScrollPastEof = 0x00040000, //Allows the cursor to go past the end of file marker
|
|
||||||
eoScrollPastEol = 0x00080000, //Allows the cursor to go past the last character into the white space at the end of a line
|
|
||||||
eoShowScrollHint = 0x00100000, //Shows a hint of the visible line numbers when scrolling vertically
|
|
||||||
eoShowSpecialChars = 0x00200000, //Shows the special Characters
|
|
||||||
eoSmartTabDelete = 0x00400000, //similar to Smart Tabs, but when you delete characters
|
|
||||||
eoSmartTabs = 0x00800000, //When tabbing, the cursor will go to the next non-white space character of the previous line
|
|
||||||
eoSpecialLineDefaultFg = 0x01000000, //disables the foreground text color override when using the OnSpecialLineColor event
|
|
||||||
eoTabIndent = 0x02000000, //When active <Tab> and <Shift><Tab> act as block indent, unindent when text is selected
|
|
||||||
eoTabsToSpaces = 0x04000000, //Converts a tab character to a specified number of space characters
|
|
||||||
eoShowRainbowColor = 0x08000000,
|
|
||||||
eoTrimTrailingSpaces = 0x10000000 //Spaces at the end of lines will be trimmed and not saved
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(SynEditorOptions, SynEditorOption)
|
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SynEditorOptions)
|
|
||||||
|
|
||||||
enum class SynReplaceAction {
|
|
||||||
raCancel, raSkip, raReplace, raReplaceAll
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SynEditingArea {
|
|
||||||
int beginX;
|
|
||||||
int endX;
|
|
||||||
QColor color;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
using PSynEditingArea = std::shared_ptr<SynEditingArea>;
|
|
||||||
using SynEditingAreaList = QList<PSynEditingArea>;
|
|
||||||
enum class SynEditingAreaType {
|
|
||||||
eatRectangleBorder,
|
|
||||||
eatWaveUnderLine,
|
|
||||||
eatUnderLine
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynTransientType {
|
|
||||||
ttBefore, ttAfter
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynScrollBarKind {
|
|
||||||
sbHorizontal, sbVertical
|
|
||||||
};
|
|
||||||
|
|
||||||
using SynPaintTransientProc = std::function<void(const QPaintDevice& paintDevice,
|
|
||||||
SynTransientType transientType)>;
|
|
||||||
using SynPlaceMarkProc = std::function<void(PSynEditMark& Mark)>;
|
|
||||||
using SynProcessCommandProc = std::function<void(SynEditorCommand& command, QChar& AChar, void* data)>;
|
|
||||||
using SynMouseCursorProc = std::function<void(const BufferCoord& aLineCharPos, QCursor & aCursor)>;
|
|
||||||
using SynPaintProc = std::function<void(const QPaintDevice& paintDevice )>;
|
|
||||||
using SynPreparePaintHighlightTokenProc = std::function<void(int row,
|
|
||||||
int column, const QString& token, PSynHighlighterAttribute attr,
|
|
||||||
SynFontStyles& style, QColor& foreground, QColor& background)>;
|
|
||||||
using SynReplaceTextProc = std::function<void(const QString& ASearch, const QString& AReplace,
|
|
||||||
int Line, int Column, int wordLen, SynReplaceAction& action)>;
|
|
||||||
using SynSpecialLineColorsProc = std::function<void(int Line,
|
|
||||||
bool& Special, QColor& foreground, QColor& backgroundColor)>;
|
|
||||||
using SynEditingAreasProc = std::function<void(int Line, SynEditingAreaList& areaList,
|
|
||||||
QColor& borderColor,SynEditingAreaType& areaType)>;
|
|
||||||
using SynGutterGetTextProc = std::function<void(int aLine, QString& aText)>;
|
|
||||||
using SynTGutterPaintProc = std::function<void(int aLine, int X, int Y)>;
|
|
||||||
|
|
||||||
class SynEdit;
|
|
||||||
using PSynEdit = std::shared_ptr<SynEdit>;
|
|
||||||
|
|
||||||
class SynEdit : public QFrame
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynEdit(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
|
||||||
|
|
||||||
int displayLineCount();
|
|
||||||
BufferCoord caretXY();
|
|
||||||
int caretX();
|
|
||||||
int caretY();
|
|
||||||
|
|
||||||
void setCaretXY(const BufferCoord& value);
|
|
||||||
void setCaretXYEx(bool CallEnsureCursorPos, BufferCoord value);
|
|
||||||
void setCaretXYCentered(bool ForceToMiddle, const BufferCoord& value);
|
|
||||||
|
|
||||||
void invalidateGutter();
|
|
||||||
void invalidateGutterLine(int aLine);
|
|
||||||
void invalidateGutterLines(int FirstLine, int LastLine);
|
|
||||||
DisplayCoord pixelsToNearestRowColumn(int aX, int aY);
|
|
||||||
DisplayCoord bufferToDisplayPos(const BufferCoord& p);
|
|
||||||
BufferCoord displayToBufferPos(const DisplayCoord& p);
|
|
||||||
int rowToLine(int aRow);
|
|
||||||
int lineToRow(int aLine);
|
|
||||||
int foldRowToLine(int Row);
|
|
||||||
int foldLineToRow(int Line);
|
|
||||||
void setDefaultKeystrokes();
|
|
||||||
void invalidateLine(int Line);
|
|
||||||
void lockPainter();
|
|
||||||
void unlockPainter();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void Changed();
|
|
||||||
|
|
||||||
void ChainUndoAdded();
|
|
||||||
void ChainRedoAdded();
|
|
||||||
void ChainLinesChanging();
|
|
||||||
void ChainLinesChanged();
|
|
||||||
void ChainListCleared();
|
|
||||||
|
|
||||||
void ChainListDeleted(int Index, int Count);
|
|
||||||
void ChainListInserted(int Index, int Count);
|
|
||||||
void ChainListPutted(int Index, int Count);
|
|
||||||
|
|
||||||
void FilesDropped(int X,int Y, const QStringList& AFiles);
|
|
||||||
void GutterClicked(Qt::MouseButton button, int x, int y, int line, PSynEditMark mark);
|
|
||||||
void ImeInputed(const QString& s);
|
|
||||||
|
|
||||||
void contextHelp(const QString& word);
|
|
||||||
|
|
||||||
void scrolled(SynScrollBarKind ScrollBar);
|
|
||||||
void statusChange(SynStatusChanges changes);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void clearAreaList(SynEditingAreaList areaList);
|
|
||||||
void computeCaret(int X, int Y);
|
|
||||||
void computeScroll(int X, int Y);
|
|
||||||
void doBlockIndent();
|
|
||||||
|
|
||||||
void incPaintLock();
|
|
||||||
void decPaintLock();
|
|
||||||
bool mouseCapture();
|
|
||||||
int clientWidth();
|
|
||||||
int clientHeight();
|
|
||||||
int clientTop();
|
|
||||||
int clientLeft();
|
|
||||||
QRect clientRect();
|
|
||||||
void synFontChanged();
|
|
||||||
void doOnPaintTransient(SynTransientType TransientType);
|
|
||||||
|
|
||||||
//todo
|
|
||||||
void setInternalDisplayXY(const DisplayCoord& aPos);
|
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void bookMarkOptionsChanged();
|
|
||||||
void gutterChanged();
|
|
||||||
void linesChanged();
|
|
||||||
void linesChanging();
|
|
||||||
void linesCleared();
|
|
||||||
void linesDeleted(int index, int count);
|
|
||||||
void linesInserted(int index, int count);
|
|
||||||
void linesPutted(int index, int count);
|
|
||||||
void redoAdded();
|
|
||||||
void scrollTimerHandler();
|
|
||||||
void undoAdded();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SynEditFoldRanges mAllFoldRanges;
|
|
||||||
SynEditCodeFolding mCodeFolding;
|
|
||||||
bool mUseCodeFolding;
|
|
||||||
bool mAlwaysShowCaret;
|
|
||||||
BufferCoord mBlockBegin;
|
|
||||||
BufferCoord mBlockEnd;
|
|
||||||
int mCaretX;
|
|
||||||
int mLastCaretX;
|
|
||||||
int mCaretY;
|
|
||||||
int mCharsInWindow;
|
|
||||||
int mCharWidth;
|
|
||||||
QFont mFontDummy;
|
|
||||||
SynFontSmoothMethod mFontSmoothing;
|
|
||||||
bool mMouseMoved;
|
|
||||||
/* IME input */
|
|
||||||
int mImeCount;
|
|
||||||
bool mMBCSStepAside;
|
|
||||||
/* end of IME input */
|
|
||||||
bool mInserting;
|
|
||||||
bool mPainting;
|
|
||||||
PSynEditStringList mLines;
|
|
||||||
PSynEditStringList mOrigLines;
|
|
||||||
PSynEditUndoList mOrigUndoList;
|
|
||||||
PSynEditUndoList mOrigRedoList;
|
|
||||||
int mLinesInWindow;
|
|
||||||
int mLeftChar;
|
|
||||||
int mMaxScrollWidth;
|
|
||||||
int mPaintLock;
|
|
||||||
bool mReadOnly;
|
|
||||||
int mRightEdge;
|
|
||||||
QColor mRightEdgeColor;
|
|
||||||
QColor mScrollHintColor;
|
|
||||||
SynScrollHintFormat mScrollHintFormat;
|
|
||||||
SynScrollStyle mScrollBars;
|
|
||||||
int mTextHeight;
|
|
||||||
int mTextOffset;
|
|
||||||
int mTopLine;
|
|
||||||
PSynHighlighter mHighlighter;
|
|
||||||
QColor mSelectedForeground;
|
|
||||||
QColor mSelectedBackground;
|
|
||||||
QColor mActiveLineColor;
|
|
||||||
PSynEditUndoList mUndoList;
|
|
||||||
PSynEditUndoList mRedoList;
|
|
||||||
SynEditMarkList mBookMarks;
|
|
||||||
int mMouseDownX;
|
|
||||||
int mMouseDownY;
|
|
||||||
SynBookMarkOpt mBookMarkOpt;
|
|
||||||
bool mHideSelection;
|
|
||||||
int mMouseWheelAccumulator;
|
|
||||||
SynEditCaretType mOverwriteCaret;
|
|
||||||
SynEditCaretType mInsertCaret;
|
|
||||||
QPoint mCaretOffset;
|
|
||||||
SynEditKeyStrokes mKeyStrokes;
|
|
||||||
bool mModified;
|
|
||||||
QDateTime mLastModifyTime;
|
|
||||||
SynEditMarkList mMarkList;
|
|
||||||
int mExtraLineSpacing;
|
|
||||||
SynSelectionMode mSelectionMode;
|
|
||||||
SynSelectionMode mActiveSelectionMode; //mode of the active selection
|
|
||||||
bool mWantReturns;
|
|
||||||
bool mWantTabs;
|
|
||||||
SynGutter mGutter;
|
|
||||||
int mTabWidth;
|
|
||||||
QRect mInvalidateRect;
|
|
||||||
SynStateFlags mStateFlags;
|
|
||||||
SynEditorOptions mOptions;
|
|
||||||
SynStatusChanges mStatusChanges;
|
|
||||||
int mLastKey;
|
|
||||||
Qt::KeyboardModifiers mLastKeyModifiers;
|
|
||||||
//fSearchEngine: TSynEditSearchCustom;
|
|
||||||
//fHookedCommandHandlers: TList;
|
|
||||||
//fKbdHandler: TSynEditKbdHandler;
|
|
||||||
// fFocusList: TList;
|
|
||||||
// fPlugins: TList;
|
|
||||||
QTimer* mScrollTimer;
|
|
||||||
int mScrollDeltaX;
|
|
||||||
int mScrollDeltaY;
|
|
||||||
|
|
||||||
PSynEdit fChainedEditor;
|
|
||||||
|
|
||||||
bool mShowSpecChar;
|
|
||||||
int mPaintTransientLock;
|
|
||||||
bool mIsScrolling;
|
|
||||||
//int mPainterLock;
|
|
||||||
bool mUndoing;
|
|
||||||
// event handlers
|
|
||||||
SynPlaceMarkProc mOnClearMark;
|
|
||||||
SynProcessCommandProc mOnCommandProcessed;
|
|
||||||
SynMouseCursorProc mOnMouseCursor;
|
|
||||||
SynPaintProc mOnPaint;
|
|
||||||
SynPreparePaintHighlightTokenProc mOnPaintHighlightToken;
|
|
||||||
SynPlaceMarkProc mOnPlaceMark;
|
|
||||||
SynProcessCommandProc mOnProcessingCommand;
|
|
||||||
SynProcessCommandProc mOnProcessingUserCommand;
|
|
||||||
|
|
||||||
SynReplaceTextProc mOnReplaceText;
|
|
||||||
SynSpecialLineColorsProc mOnSpecialLineColors;
|
|
||||||
SynEditingAreasProc mOnEditingAreas;
|
|
||||||
SynPaintTransientProc mOnPaintTransient;
|
|
||||||
SynGutterGetTextProc mOnGutterGetText;
|
|
||||||
SynTGutterPaintProc mOnGutterPaint;
|
|
||||||
int mGutterWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SYNEDIT_H
|
|
|
@ -1,906 +0,0 @@
|
||||||
#include "TextBuffer.h"
|
|
||||||
#include <QDataStream>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QTextCodec>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "../utils.h"
|
|
||||||
|
|
||||||
SynEditStringList::SynEditStringList(QObject* parent):
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
mAppendNewLineAtEOF = true;
|
|
||||||
mFileEndingType = FileEndingType::Windows;
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
mUpdateCount = 0;
|
|
||||||
setTabWidth(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ListIndexOutOfBounds(int index) {
|
|
||||||
throw IndexOutOfRange(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::parenthesisLevels(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
return mList[Index]->fParenthesisLevel;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::bracketLevels(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
return mList[Index]->fBracketLevel;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::braceLevels(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
return mList[Index]->fBraceLevel;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditStringList::expandedStrings(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
if (mList[Index]->fFlags & SynEditStringFlag::sfHasNoTabs)
|
|
||||||
return mList[Index]->fString;
|
|
||||||
else
|
|
||||||
return ExpandString(Index);
|
|
||||||
} else
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::expandedStringLength(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
if (mList[Index]->fFlags & sfExpandedLengthUnknown)
|
|
||||||
return ExpandString(Index).length();
|
|
||||||
else
|
|
||||||
return mList[Index]->fExpandedLength;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::lengthOfLongestLine()
|
|
||||||
{
|
|
||||||
if (mIndexOfLongestLine < 0) {
|
|
||||||
int MaxLen = -1;
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
if (mList.count() > 0 ) {
|
|
||||||
for (int i=0;i<mList.size();i++) {
|
|
||||||
int len = expandedStringLength(i);
|
|
||||||
if (len > MaxLen) {
|
|
||||||
MaxLen = len;
|
|
||||||
mIndexOfLongestLine = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mIndexOfLongestLine >= 0)
|
|
||||||
return mList[mIndexOfLongestLine]->fExpandedLength;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynRangeState SynEditStringList::ranges(int Index)
|
|
||||||
{
|
|
||||||
if (Index>=0 && Index < mList.size()) {
|
|
||||||
return mList[Index]->fRange;
|
|
||||||
} else
|
|
||||||
return {0,0};
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::InsertItem(int Index, const QString &s)
|
|
||||||
{
|
|
||||||
beginUpdate();
|
|
||||||
PSynEditStringRec line = std::make_shared<SynEditStringRec>();
|
|
||||||
line->fString = s;
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
mList.insert(Index,line);
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConvertTabsProcEx SynEditStringList::getConvertTabsProc() const
|
|
||||||
{
|
|
||||||
return mConvertTabsProc;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditStringList::getAppendNewLineAtEOF() const
|
|
||||||
{
|
|
||||||
return mAppendNewLineAtEOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setAppendNewLineAtEOF(bool appendNewLineAtEOF)
|
|
||||||
{
|
|
||||||
mAppendNewLineAtEOF = appendNewLineAtEOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setRange(int Index, SynRangeState ARange)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList[Index]->fRange = ARange;
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setParenthesisLevel(int Index, int level)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList[Index]->fParenthesisLevel = level;
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setBracketLevel(int Index, int level)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList[Index]->fBracketLevel = level;
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setBraceLevel(int Index, int level)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList[Index]->fBraceLevel = level;
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditStringList::getString(int Index)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return mList[Index]->fString;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::count()
|
|
||||||
{
|
|
||||||
return mList.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
void *SynEditStringList::getObject(int Index)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return mList[Index]->fObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditStringList::text()
|
|
||||||
{
|
|
||||||
return GetTextStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setText(const QString &text)
|
|
||||||
{
|
|
||||||
PutTextStr(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::beginUpdate()
|
|
||||||
{
|
|
||||||
if (mUpdateCount == 0) {
|
|
||||||
SetUpdateState(true);
|
|
||||||
}
|
|
||||||
mUpdateCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::endUpdate()
|
|
||||||
{
|
|
||||||
mUpdateCount--;
|
|
||||||
if (mUpdateCount == 0) {
|
|
||||||
SetUpdateState(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::tabWidth()
|
|
||||||
{
|
|
||||||
return mTabWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setTabWidth(int value)
|
|
||||||
{
|
|
||||||
if (value != mTabWidth) {
|
|
||||||
mTabWidth = value;
|
|
||||||
mConvertTabsProc = GetBestConvertTabsProcEx(mTabWidth);
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
for (PSynEditStringRec& line:mList) {
|
|
||||||
line->fExpandedLength = -1;
|
|
||||||
line->fFlags = SynEditStringFlag::sfExpandedLengthUnknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::add(const QString &s)
|
|
||||||
{
|
|
||||||
beginUpdate();
|
|
||||||
int Result = mList.count();
|
|
||||||
InsertItem(Result, s);
|
|
||||||
emit inserted(Result,1);
|
|
||||||
endUpdate();
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::addStrings(const QStringList &Strings)
|
|
||||||
{
|
|
||||||
if (Strings.count() > 0) {
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
int FirstAdded = mList.count();
|
|
||||||
|
|
||||||
for (const QString& s:Strings) {
|
|
||||||
add(s);
|
|
||||||
}
|
|
||||||
emit inserted(FirstAdded,Strings.count());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditStringList::getTextLength()
|
|
||||||
{
|
|
||||||
int Result = 0;
|
|
||||||
for (const PSynEditStringRec& line: mList ) {
|
|
||||||
Result += line->fString.length();
|
|
||||||
if (mFileEndingType == FileEndingType::Windows) {
|
|
||||||
Result += 2;
|
|
||||||
} else {
|
|
||||||
Result += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::clear()
|
|
||||||
{
|
|
||||||
if (!mList.isEmpty()) {
|
|
||||||
beginUpdate();
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
mList.clear();
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::deleteLines(int Index, int NumLines)
|
|
||||||
{
|
|
||||||
if (NumLines<=0)
|
|
||||||
return;
|
|
||||||
if ((Index < 0) || (Index >= mList.count())) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
if (mIndexOfLongestLine>=Index && (mIndexOfLongestLine <Index+NumLines)) {
|
|
||||||
mIndexOfLongestLine = - 1;
|
|
||||||
}
|
|
||||||
int LinesAfter = mList.count() - (Index + NumLines);
|
|
||||||
if (LinesAfter < 0) {
|
|
||||||
NumLines = mList.count() - Index;
|
|
||||||
}
|
|
||||||
mList.remove(Index,NumLines);
|
|
||||||
emit deleted(Index,NumLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::Exchange(int Index1, int Index2)
|
|
||||||
{
|
|
||||||
if ((Index1 < 0) || (Index1 >= mList.count())) {
|
|
||||||
ListIndexOutOfBounds(Index1);
|
|
||||||
}
|
|
||||||
if ((Index2 < 0) || (Index2 >= mList.count())) {
|
|
||||||
ListIndexOutOfBounds(Index2);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList.swapItemsAt(Index1,Index2);
|
|
||||||
if (mIndexOfLongestLine == Index1) {
|
|
||||||
mIndexOfLongestLine = Index2;
|
|
||||||
} else if (mIndexOfLongestLine == Index2) {
|
|
||||||
mIndexOfLongestLine = Index1;
|
|
||||||
}
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::Insert(int Index, const QString &s)
|
|
||||||
{
|
|
||||||
if ((Index < 0) || (Index > mList.count())) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
InsertItem(Index, s);
|
|
||||||
emit inserted(Index,1);
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::deleteAt(int Index)
|
|
||||||
{
|
|
||||||
if ((Index < 0) || (Index >= mList.count())) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
if (mIndexOfLongestLine == Index)
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
mList.removeAt(Index);
|
|
||||||
emit deleted(Index,1);
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditStringList::GetTextStr()
|
|
||||||
{
|
|
||||||
QString Result;
|
|
||||||
for (PSynEditStringRec& line:mList) {
|
|
||||||
Result.append(line->fString);
|
|
||||||
switch(mFileEndingType) {
|
|
||||||
case FileEndingType::Linux:
|
|
||||||
Result.append('\n');
|
|
||||||
case FileEndingType::Windows:
|
|
||||||
Result.append("\r\n");
|
|
||||||
case FileEndingType::Mac:
|
|
||||||
Result.append("\r");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::putString(int Index, const QString &s) {
|
|
||||||
if (Index == mList.count()) {
|
|
||||||
add(s);
|
|
||||||
} else {
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mIndexOfLongestLine = -1;
|
|
||||||
mList[Index]->fFlags = SynEditStringFlag::sfExpandedLengthUnknown;
|
|
||||||
mList[Index]->fString = s;
|
|
||||||
emit putted(Index,1);
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::putObject(int Index, void *AObject)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
beginUpdate();
|
|
||||||
mList[Index]->fObject = AObject;
|
|
||||||
endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::SetUpdateState(bool Updating)
|
|
||||||
{
|
|
||||||
if (Updating)
|
|
||||||
emit changing();
|
|
||||||
else
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditStringList::ExpandString(int Index)
|
|
||||||
{
|
|
||||||
QString Result("");
|
|
||||||
PSynEditStringRec line = mList[Index];
|
|
||||||
if (line->fString.isEmpty()) {
|
|
||||||
line->fFlags = SynEditStringFlag::sfHasNoTabs;
|
|
||||||
line->fExpandedLength = 0;
|
|
||||||
} else {
|
|
||||||
bool hasTabs;
|
|
||||||
Result = mConvertTabsProc(line->fString,mTabWidth,hasTabs);
|
|
||||||
line->fExpandedLength = Result.length();
|
|
||||||
if (hasTabs) {
|
|
||||||
line->fFlags = SynEditStringFlag::sfHasTabs;
|
|
||||||
} else {
|
|
||||||
line->fFlags = SynEditStringFlag::sfHasNoTabs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::InsertLines(int Index, int NumLines)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
if (NumLines<=0)
|
|
||||||
return;
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
PSynEditStringRec line;
|
|
||||||
mList.insert(Index,NumLines,line);
|
|
||||||
for (int i=Index;i<Index+NumLines;i++) {
|
|
||||||
line = std::make_shared<SynEditStringRec>();
|
|
||||||
mList[i]=line;
|
|
||||||
}
|
|
||||||
emit inserted(Index,NumLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::InsertStrings(int Index, const QStringList &NewStrings)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
if (NewStrings.isEmpty())
|
|
||||||
return;
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
PSynEditStringRec line;
|
|
||||||
mList.insert(Index,NewStrings.length(),line);
|
|
||||||
for (int i=0;i<NewStrings.length();i++) {
|
|
||||||
line = std::make_shared<SynEditStringRec>();
|
|
||||||
line->fString = NewStrings[i];
|
|
||||||
mList[i+Index]=line;
|
|
||||||
}
|
|
||||||
emit inserted(Index,NewStrings.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::InsertText(int Index, const QString &NewText)
|
|
||||||
{
|
|
||||||
if (Index<0 || Index>=mList.count()) {
|
|
||||||
ListIndexOutOfBounds(Index);
|
|
||||||
}
|
|
||||||
if (NewText.isEmpty())
|
|
||||||
return;
|
|
||||||
QStringList lines = TextToLines(NewText);
|
|
||||||
InsertStrings(Index,lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::LoadFromFile(QFile &file, const QByteArray& encoding, QByteArray& realEncoding)
|
|
||||||
{
|
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text))
|
|
||||||
throw FileError(tr("Can't open file '%1' for read!").arg(file.fileName()));
|
|
||||||
if (!file.canReadLine())
|
|
||||||
throw FileError(tr("Can't read from file '%1'!").arg(file.fileName()));
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
|
|
||||||
//test for utf8 / utf 8 bom
|
|
||||||
if (encoding == ENCODING_AUTO_DETECT) {
|
|
||||||
QByteArray line = file.readLine();
|
|
||||||
QTextCodec* codec;
|
|
||||||
QTextCodec::ConverterState * state;
|
|
||||||
bool needReread = false;
|
|
||||||
bool allAscii = true;
|
|
||||||
//test for BOM
|
|
||||||
if (line.isEmpty()) {
|
|
||||||
realEncoding = ENCODING_ASCII;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((line.length()>=3) && ((unsigned char)line[0]==0xEF) && ((unsigned char)line[1]==0xBB) && ((unsigned char)line[2]==0xBF) ) {
|
|
||||||
realEncoding = ENCODING_UTF8_BOM;
|
|
||||||
line = line.mid(3);
|
|
||||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
|
||||||
} else {
|
|
||||||
realEncoding = ENCODING_UTF8;
|
|
||||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
|
||||||
}
|
|
||||||
clear();
|
|
||||||
do {
|
|
||||||
if (allAscii) {
|
|
||||||
allAscii = isTextAllAscii(line);
|
|
||||||
}
|
|
||||||
if (allAscii) {
|
|
||||||
add(QString::fromLatin1(line));
|
|
||||||
} else {
|
|
||||||
QString newLine = codec->toUnicode(line.constData(),line.length(),state);
|
|
||||||
if (state->invalidChars>0) {
|
|
||||||
needReread = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
add(newLine);
|
|
||||||
}
|
|
||||||
line = file.readLine();
|
|
||||||
} while (!file.atEnd());
|
|
||||||
if (!needReread) {
|
|
||||||
if (allAscii)
|
|
||||||
realEncoding = ENCODING_ASCII;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
realEncoding = ENCODING_SYSTEM_DEFAULT;
|
|
||||||
} else {
|
|
||||||
realEncoding = encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (realEncoding == ENCODING_SYSTEM_DEFAULT) {
|
|
||||||
realEncoding = QTextCodec::codecForLocale()->name();
|
|
||||||
}
|
|
||||||
file.reset();
|
|
||||||
QTextStream textStream(&file);
|
|
||||||
if (realEncoding == ENCODING_UTF8_BOM) {
|
|
||||||
textStream.setAutoDetectUnicode(true);
|
|
||||||
textStream.setCodec(ENCODING_UTF8);
|
|
||||||
} else {
|
|
||||||
textStream.setAutoDetectUnicode(false);
|
|
||||||
textStream.setCodec(realEncoding);
|
|
||||||
}
|
|
||||||
QString line;
|
|
||||||
clear();
|
|
||||||
while (textStream.readLineInto(&line)) {
|
|
||||||
add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SynEditStringList::SaveToFile(QFile &file, const QByteArray& encoding, QByteArray& realEncoding)
|
|
||||||
{
|
|
||||||
if (!file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text))
|
|
||||||
throw FileError(tr("Can't open file '%1' for save!").arg(file.fileName()));
|
|
||||||
if (mList.isEmpty())
|
|
||||||
return;
|
|
||||||
bool allAscii = true;
|
|
||||||
|
|
||||||
QTextCodec* codec;
|
|
||||||
if (realEncoding == ENCODING_UTF8_BOM) {
|
|
||||||
codec = QTextCodec::codecForName(ENCODING_UTF8_BOM);
|
|
||||||
} else if (realEncoding == ENCODING_ASCII) {
|
|
||||||
codec = QTextCodec::codecForLocale();
|
|
||||||
}
|
|
||||||
for (PSynEditStringRec& line:mList) {
|
|
||||||
if (allAscii) {
|
|
||||||
allAscii = isTextAllAscii(line->fString);
|
|
||||||
}
|
|
||||||
if (!allAscii) {
|
|
||||||
file.write(codec->fromUnicode(line->fString));
|
|
||||||
} else {
|
|
||||||
file.write(line->fString.toLatin1());
|
|
||||||
}
|
|
||||||
switch (mFileEndingType) {
|
|
||||||
case FileEndingType::Windows:
|
|
||||||
file.write("\r\n");
|
|
||||||
break;
|
|
||||||
case FileEndingType::Linux:
|
|
||||||
file.write("\n");
|
|
||||||
break;
|
|
||||||
case FileEndingType::Mac:
|
|
||||||
file.write("\r");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (encoding == ENCODING_AUTO_DETECT && allAscii) {
|
|
||||||
realEncoding = ENCODING_ASCII;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SynEditStringList::PutTextStr(const QString &text)
|
|
||||||
{
|
|
||||||
beginUpdate();
|
|
||||||
auto action = finally([this]{
|
|
||||||
endUpdate();
|
|
||||||
});
|
|
||||||
clear();
|
|
||||||
int pos = 0;
|
|
||||||
int start;
|
|
||||||
while (pos < text.length()) {
|
|
||||||
start = pos;
|
|
||||||
while (pos<text.length()) {
|
|
||||||
if (text[pos] == '\r' || text[pos] == '\n') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
add(text.mid(start,pos-start));
|
|
||||||
if (pos>=text.length())
|
|
||||||
break;
|
|
||||||
if (text[pos] == '\r')
|
|
||||||
pos++;
|
|
||||||
if (text[pos] == '\n')
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileEndingType SynEditStringList::getFileEndingType() const
|
|
||||||
{
|
|
||||||
return mFileEndingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditStringList::setFileEndingType(const FileEndingType &fileEndingType)
|
|
||||||
{
|
|
||||||
mFileEndingType = fileEndingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditStringRec::SynEditStringRec():
|
|
||||||
fString(),
|
|
||||||
fObject(nullptr),
|
|
||||||
fRange{0,0},
|
|
||||||
fExpandedLength(-1),
|
|
||||||
fParenthesisLevel(0),
|
|
||||||
fBracketLevel(0),
|
|
||||||
fBraceLevel(0),
|
|
||||||
fFlags(SynEditStringFlag::sfExpandedLengthUnknown)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SynEditUndoList::SynEditUndoList():QObject()
|
|
||||||
{
|
|
||||||
mMaxUndoActions = 1024;
|
|
||||||
mNextChangeNumber = 1;
|
|
||||||
mInsideRedo = false;
|
|
||||||
|
|
||||||
mBlockChangeNumber=0;
|
|
||||||
mBlockCount=0;
|
|
||||||
mFullUndoImposible=false;
|
|
||||||
mLockCount = 0;
|
|
||||||
mInitialChangeNumber = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::AddChange(SynChangeReason AReason, const BufferCoord &AStart,
|
|
||||||
const BufferCoord &AEnd, const QString &ChangeText,
|
|
||||||
SynSelectionMode SelMode)
|
|
||||||
{
|
|
||||||
if (mLockCount != 0)
|
|
||||||
return;
|
|
||||||
int changeNumber;
|
|
||||||
if (mBlockChangeNumber != 0) {
|
|
||||||
changeNumber = mBlockChangeNumber;
|
|
||||||
} else {
|
|
||||||
changeNumber = mNextChangeNumber;
|
|
||||||
if (mBlockCount == 0) {
|
|
||||||
mNextChangeNumber++;
|
|
||||||
if (mNextChangeNumber == 0) {
|
|
||||||
mNextChangeNumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PSynEditUndoItem NewItem = std::make_shared<SynEditUndoItem>(AReason,
|
|
||||||
SelMode,AStart,AEnd,ChangeText,
|
|
||||||
changeNumber);
|
|
||||||
PushItem(NewItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::AddGroupBreak()
|
|
||||||
{
|
|
||||||
//Add the GroupBreak even if ItemCount = 0. Since items are stored in
|
|
||||||
//reverse order in TCustomSynEdit.fRedoList, a GroupBreak could be lost.
|
|
||||||
if (LastChangeReason() != SynChangeReason::crGroupBreak) {
|
|
||||||
AddChange(SynChangeReason::crGroupBreak, {0,0}, {0,0}, "", SynSelectionMode::smNormal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::BeginBlock()
|
|
||||||
{
|
|
||||||
mBlockCount++;
|
|
||||||
mBlockChangeNumber = mNextChangeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::Clear()
|
|
||||||
{
|
|
||||||
mItems.clear();
|
|
||||||
mFullUndoImposible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::DeleteItem(int index)
|
|
||||||
{
|
|
||||||
if (index <0 || index>=mItems.count()) {
|
|
||||||
ListIndexOutOfBounds(index);
|
|
||||||
}
|
|
||||||
mItems.removeAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::EndBlock()
|
|
||||||
{
|
|
||||||
if (mBlockCount > 0) {
|
|
||||||
mBlockCount--;
|
|
||||||
if (mBlockCount == 0) {
|
|
||||||
int iBlockID = mBlockChangeNumber;
|
|
||||||
mBlockChangeNumber = 0;
|
|
||||||
mNextChangeNumber++;
|
|
||||||
if (mNextChangeNumber == 0)
|
|
||||||
mNextChangeNumber++;
|
|
||||||
if (mItems.count() > 0 && PeekItem()->changeNumber() == iBlockID)
|
|
||||||
emit addedUndo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynChangeReason SynEditUndoList::LastChangeReason()
|
|
||||||
{
|
|
||||||
if (mItems.count() == 0)
|
|
||||||
return SynChangeReason::crNothing;
|
|
||||||
else
|
|
||||||
mItems.last()->changeReason();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::Lock()
|
|
||||||
{
|
|
||||||
mLockCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditUndoItem SynEditUndoList::PeekItem()
|
|
||||||
{
|
|
||||||
if (mItems.count() == 0)
|
|
||||||
return PSynEditUndoItem();
|
|
||||||
else
|
|
||||||
return mItems.last();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditUndoItem SynEditUndoList::PopItem()
|
|
||||||
{
|
|
||||||
if (mItems.count() == 0)
|
|
||||||
return PSynEditUndoItem();
|
|
||||||
else {
|
|
||||||
PSynEditUndoItem item = mItems.last();
|
|
||||||
mItems.removeLast();
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::PushItem(PSynEditUndoItem Item)
|
|
||||||
{
|
|
||||||
if (!Item)
|
|
||||||
return;
|
|
||||||
mItems.append(Item);
|
|
||||||
EnsureMaxEntries();
|
|
||||||
if (Item->changeReason()!= SynChangeReason::crGroupBreak)
|
|
||||||
addedUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::Unlock()
|
|
||||||
{
|
|
||||||
if (mLockCount > 0)
|
|
||||||
mLockCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditUndoList::CanUndo()
|
|
||||||
{
|
|
||||||
return mItems.count()>0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditUndoList::ItemCount()
|
|
||||||
{
|
|
||||||
return mItems.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditUndoList::maxUndoActions() const
|
|
||||||
{
|
|
||||||
return mMaxUndoActions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::setMaxUndoActions(int maxUndoActions)
|
|
||||||
{
|
|
||||||
mMaxUndoActions = maxUndoActions;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditUndoList::initialState()
|
|
||||||
{
|
|
||||||
if (ItemCount() == 0) {
|
|
||||||
return mInitialChangeNumber == 0;
|
|
||||||
} else {
|
|
||||||
return PeekItem()->changeNumber() == mInitialChangeNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynEditUndoItem SynEditUndoList::item(int index)
|
|
||||||
{
|
|
||||||
if (index <0 || index>=mItems.count()) {
|
|
||||||
ListIndexOutOfBounds(index);
|
|
||||||
}
|
|
||||||
return mItems[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::setInitialState(const bool Value)
|
|
||||||
{
|
|
||||||
if (Value) {
|
|
||||||
if (ItemCount() == 0)
|
|
||||||
mInitialChangeNumber = 0;
|
|
||||||
else
|
|
||||||
mInitialChangeNumber = PeekItem()->changeNumber();
|
|
||||||
} else if (ItemCount() == 0) {
|
|
||||||
if (mInitialChangeNumber == 0) {
|
|
||||||
mInitialChangeNumber = -1;
|
|
||||||
}
|
|
||||||
} else if (PeekItem()->changeNumber() == mInitialChangeNumber) {
|
|
||||||
mInitialChangeNumber = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::setItem(int index, PSynEditUndoItem Value)
|
|
||||||
{
|
|
||||||
if (index <0 || index>=mItems.count()) {
|
|
||||||
ListIndexOutOfBounds(index);
|
|
||||||
}
|
|
||||||
mItems[index]=Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditUndoList::blockChangeNumber() const
|
|
||||||
{
|
|
||||||
return mBlockChangeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::setBlockChangeNumber(int blockChangeNumber)
|
|
||||||
{
|
|
||||||
mBlockChangeNumber = blockChangeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditUndoList::blockCount() const
|
|
||||||
{
|
|
||||||
return mBlockCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditUndoList::insideRedo() const
|
|
||||||
{
|
|
||||||
return mInsideRedo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::setInsideRedo(bool insideRedo)
|
|
||||||
{
|
|
||||||
mInsideRedo = insideRedo;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynEditUndoList::fullUndoImposible() const
|
|
||||||
{
|
|
||||||
return mFullUndoImposible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynEditUndoList::EnsureMaxEntries()
|
|
||||||
{
|
|
||||||
if (mItems.count() > mMaxUndoActions){
|
|
||||||
mFullUndoImposible = true;
|
|
||||||
while (mItems.count() > mMaxUndoActions) {
|
|
||||||
mItems.removeFirst();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynSelectionMode SynEditUndoItem::changeSelMode() const
|
|
||||||
{
|
|
||||||
return mChangeSelMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferCoord SynEditUndoItem::changeStartPos() const
|
|
||||||
{
|
|
||||||
return mChangeStartPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferCoord SynEditUndoItem::changeEndPos() const
|
|
||||||
{
|
|
||||||
return mChangeEndPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynEditUndoItem::changeStr() const
|
|
||||||
{
|
|
||||||
return mChangeStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynEditUndoItem::changeNumber() const
|
|
||||||
{
|
|
||||||
return mChangeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynEditUndoItem::SynEditUndoItem(SynChangeReason reason, SynSelectionMode selMode,
|
|
||||||
BufferCoord startPos, BufferCoord endPos,
|
|
||||||
const QString &str, int number)
|
|
||||||
{
|
|
||||||
mChangeReason = reason;
|
|
||||||
mChangeSelMode = selMode;
|
|
||||||
mChangeStartPos = startPos;
|
|
||||||
mChangeEndPos = endPos;
|
|
||||||
mChangeStr = str;
|
|
||||||
mChangeNumber = number;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynChangeReason SynEditUndoItem::changeReason() const
|
|
||||||
{
|
|
||||||
return mChangeReason;
|
|
||||||
}
|
|
|
@ -1,228 +0,0 @@
|
||||||
#ifndef SYNEDITSTRINGLIST_H
|
|
||||||
#define SYNEDITSTRINGLIST_H
|
|
||||||
|
|
||||||
#include <QStringList>
|
|
||||||
#include "highlighter/base.h"
|
|
||||||
#include <QVector>
|
|
||||||
#include <memory>
|
|
||||||
#include "MiscProcs.h"
|
|
||||||
#include "../utils.h"
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
enum SynEditStringFlag {
|
|
||||||
sfHasTabs = 0x0001,
|
|
||||||
sfHasNoTabs = 0x0002,
|
|
||||||
sfExpandedLengthUnknown = 0x0004
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int SynEditStringFlags;
|
|
||||||
|
|
||||||
struct SynEditStringRec {
|
|
||||||
QString fString;
|
|
||||||
void * fObject;
|
|
||||||
SynRangeState fRange;
|
|
||||||
int fExpandedLength;
|
|
||||||
SynEditStringFlags fFlags;
|
|
||||||
int fParenthesisLevel;
|
|
||||||
int fBracketLevel;
|
|
||||||
int fBraceLevel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit SynEditStringRec();
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<SynEditStringRec> PSynEditStringRec;
|
|
||||||
|
|
||||||
typedef QVector<PSynEditStringRec> SynEditStringRecList;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<SynEditStringRecList> PSynEditStringRecList;
|
|
||||||
|
|
||||||
class SynEditStringList;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<SynEditStringList> PSynEditStringList;
|
|
||||||
|
|
||||||
using StringListChangeCallback = std::function<void(PSynEditStringList* object, int index, int count)>;
|
|
||||||
|
|
||||||
class QFile;
|
|
||||||
class SynEditStringList : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynEditStringList(QObject* parent=nullptr);
|
|
||||||
|
|
||||||
int parenthesisLevels(int Index);
|
|
||||||
int bracketLevels(int Index);
|
|
||||||
int braceLevels(int Index);
|
|
||||||
QString expandedStrings(int Index);
|
|
||||||
int expandedStringLength(int Index);
|
|
||||||
int lengthOfLongestLine();
|
|
||||||
SynRangeState ranges(int Index);
|
|
||||||
void setRange(int Index, SynRangeState ARange);
|
|
||||||
void setParenthesisLevel(int Index, int level);
|
|
||||||
void setBracketLevel(int Index, int level);
|
|
||||||
void setBraceLevel(int Index, int level);
|
|
||||||
QString getString(int Index);
|
|
||||||
int count();
|
|
||||||
void* getObject(int Index);
|
|
||||||
QString text();
|
|
||||||
void setText(const QString& text);
|
|
||||||
|
|
||||||
void putString(int Index, const QString& s);
|
|
||||||
void putObject(int Index, void * AObject);
|
|
||||||
|
|
||||||
void beginUpdate();
|
|
||||||
void endUpdate();
|
|
||||||
|
|
||||||
int tabWidth();
|
|
||||||
void setTabWidth(int value);
|
|
||||||
int add(const QString& s);
|
|
||||||
int addStrings(const QStringList& Strings);
|
|
||||||
|
|
||||||
int getTextLength();
|
|
||||||
void clear();
|
|
||||||
void deleteAt(int Index);
|
|
||||||
void deleteLines(int Index, int NumLines);
|
|
||||||
void Exchange(int Index1, int Index2);
|
|
||||||
void Insert(int Index, const QString& s);
|
|
||||||
void InsertLines(int Index, int NumLines);
|
|
||||||
void InsertStrings(int Index, const QStringList& NewStrings);
|
|
||||||
void InsertText(int Index,const QString& NewText);
|
|
||||||
void LoadFromFile(QFile& file, const QByteArray& encoding, QByteArray& realEncoding);
|
|
||||||
void SaveToFile(QFile& file, const QByteArray& encoding, QByteArray& realEncoding);
|
|
||||||
|
|
||||||
bool getAppendNewLineAtEOF() const;
|
|
||||||
void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
|
|
||||||
|
|
||||||
ConvertTabsProcEx getConvertTabsProc() const;
|
|
||||||
|
|
||||||
FileEndingType getFileEndingType() const;
|
|
||||||
void setFileEndingType(const FileEndingType &fileEndingType);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changed();
|
|
||||||
void changing();
|
|
||||||
void cleared();
|
|
||||||
void deleted(int index, int count);
|
|
||||||
void inserted(int index, int count);
|
|
||||||
void putted(int index, int count);
|
|
||||||
protected:
|
|
||||||
QString GetTextStr();
|
|
||||||
void SetUpdateState(bool Updating);
|
|
||||||
void InsertItem(int Index, const QString& s);
|
|
||||||
void PutTextStr(const QString& text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SynEditStringRecList mList;
|
|
||||||
|
|
||||||
//int mCount;
|
|
||||||
//int mCapacity;
|
|
||||||
FileEndingType mFileEndingType;
|
|
||||||
bool mAppendNewLineAtEOF;
|
|
||||||
ConvertTabsProcEx mConvertTabsProc;
|
|
||||||
int mIndexOfLongestLine;
|
|
||||||
int mTabWidth;
|
|
||||||
int mUpdateCount;
|
|
||||||
|
|
||||||
QString ExpandString(int Index);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SynChangeReason {crInsert, crPaste, crDragDropInsert,
|
|
||||||
//several undo entries can be chained together via the ChangeNumber
|
|
||||||
//see also TCustomSynEdit.[Begin|End]UndoBlock methods
|
|
||||||
crDeleteAfterCursor, crDelete,
|
|
||||||
crLineBreak, crIndent, crUnindent,
|
|
||||||
crSilentDelete, crSilentDeleteAfterCursor,
|
|
||||||
crAutoCompleteBegin, crAutoCompleteEnd,
|
|
||||||
crPasteBegin, crPasteEnd, //for pasting, since it might do a lot of operations
|
|
||||||
crSpecial1Begin, crSpecial1End,
|
|
||||||
crSpecial2Begin, crSpecial2End,
|
|
||||||
crCaret, //just restore the Caret, allowing better Undo behavior
|
|
||||||
crSelection, //restore Selection
|
|
||||||
crNothing,
|
|
||||||
crGroupBreak,
|
|
||||||
crDeleteAll
|
|
||||||
};
|
|
||||||
class SynEditUndoItem {
|
|
||||||
private:
|
|
||||||
SynChangeReason mChangeReason;
|
|
||||||
SynSelectionMode mChangeSelMode;
|
|
||||||
BufferCoord mChangeStartPos;
|
|
||||||
BufferCoord mChangeEndPos;
|
|
||||||
QString mChangeStr;
|
|
||||||
int mChangeNumber;
|
|
||||||
public:
|
|
||||||
SynEditUndoItem(SynChangeReason reason,
|
|
||||||
SynSelectionMode selMode,
|
|
||||||
BufferCoord startPos,
|
|
||||||
BufferCoord endPos,
|
|
||||||
const QString& str,
|
|
||||||
int number);
|
|
||||||
|
|
||||||
SynChangeReason changeReason() const;
|
|
||||||
SynSelectionMode changeSelMode() const;
|
|
||||||
BufferCoord changeStartPos() const;
|
|
||||||
BufferCoord changeEndPos() const;
|
|
||||||
QString changeStr() const;
|
|
||||||
int changeNumber() const;
|
|
||||||
};
|
|
||||||
using PSynEditUndoItem = std::shared_ptr<SynEditUndoItem>;
|
|
||||||
|
|
||||||
class SynEditUndoList : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynEditUndoList();
|
|
||||||
|
|
||||||
void AddChange(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
|
|
||||||
const QString& ChangeText, SynSelectionMode SelMode);
|
|
||||||
|
|
||||||
void AddGroupBreak();
|
|
||||||
void BeginBlock();
|
|
||||||
void Clear();
|
|
||||||
void DeleteItem(int index);
|
|
||||||
void EndBlock();
|
|
||||||
SynChangeReason LastChangeReason();
|
|
||||||
void Lock();
|
|
||||||
PSynEditUndoItem PeekItem();
|
|
||||||
PSynEditUndoItem PopItem();
|
|
||||||
void PushItem(PSynEditUndoItem Item);
|
|
||||||
void Unlock();
|
|
||||||
|
|
||||||
bool CanUndo();
|
|
||||||
int ItemCount();
|
|
||||||
|
|
||||||
int maxUndoActions() const;
|
|
||||||
void setMaxUndoActions(int maxUndoActions);
|
|
||||||
bool initialState();
|
|
||||||
PSynEditUndoItem item(int index);
|
|
||||||
void setInitialState(const bool Value);
|
|
||||||
void setItem(int index, PSynEditUndoItem Value);
|
|
||||||
|
|
||||||
int blockChangeNumber() const;
|
|
||||||
void setBlockChangeNumber(int blockChangeNumber);
|
|
||||||
|
|
||||||
int blockCount() const;
|
|
||||||
|
|
||||||
bool insideRedo() const;
|
|
||||||
void setInsideRedo(bool insideRedo);
|
|
||||||
|
|
||||||
bool fullUndoImposible() const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void addedUndo();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int mBlockChangeNumber;
|
|
||||||
int mBlockCount;
|
|
||||||
bool mFullUndoImposible;
|
|
||||||
QVector<PSynEditUndoItem> mItems;
|
|
||||||
int mLockCount;
|
|
||||||
int mMaxUndoActions;
|
|
||||||
int mNextChangeNumber;
|
|
||||||
int mInitialChangeNumber;
|
|
||||||
bool mInsideRedo;
|
|
||||||
void EnsureMaxEntries();
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynEditUndoList = std::shared_ptr<SynEditUndoList>;
|
|
||||||
|
|
||||||
#endif // SYNEDITSTRINGLIST_H
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "TextDrawer.h"
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef SYNTEXTDRAWER_H
|
|
||||||
#define SYNTEXTDRAWER_H
|
|
||||||
|
|
||||||
#include "Types.h"
|
|
||||||
|
|
||||||
#endif // SYNTEXTDRAWER_H
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QList>
|
|
||||||
#include <QFlags>
|
|
||||||
|
|
||||||
enum class SynSelectionMode {smNormal, smLine, smColumn};
|
|
||||||
|
|
||||||
struct BufferCoord {
|
|
||||||
int Char;
|
|
||||||
int Line;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DisplayCoord {
|
|
||||||
int Column;
|
|
||||||
int Row;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SynFontStyle {
|
|
||||||
fsBold = 0x0001,
|
|
||||||
fsItalic = 0x0002,
|
|
||||||
fsUnderline = 0x0004,
|
|
||||||
fsStrikeOut = 0x0008
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(SynFontStyles,SynFontStyle)
|
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SynFontStyles)
|
|
||||||
|
|
||||||
using PSynIcon = std::shared_ptr<QIcon>;
|
|
||||||
using SynIconList = QList<PSynIcon>;
|
|
||||||
using PSynIconList = std::shared_ptr<SynIconList>;
|
|
||||||
|
|
||||||
#endif // TYPES_H
|
|
|
@ -1,228 +0,0 @@
|
||||||
#include "base.h"
|
|
||||||
#include "../Constants.h"
|
|
||||||
|
|
||||||
SynHighlighter::SynHighlighter(QObject *parent) : QObject(parent),
|
|
||||||
mWordBreakChars{ SynWordBreakChars },
|
|
||||||
mEnabled(true),
|
|
||||||
mUpdateCount(0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const QMap<QString, PSynHighlighterAttribute>& SynHighlighter::attributes() const
|
|
||||||
{
|
|
||||||
return mAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QSet<QChar>& SynHighlighter::wordBreakChars() const
|
|
||||||
{
|
|
||||||
return mWordBreakChars;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::commentAttribute() const
|
|
||||||
{
|
|
||||||
return mCommentAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::identifierAttribute() const
|
|
||||||
{
|
|
||||||
return mIdentifierAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::keywordAttribute() const
|
|
||||||
{
|
|
||||||
return mKeywordAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::stringAttribute() const
|
|
||||||
{
|
|
||||||
return mStringAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::whitespaceAttribute() const
|
|
||||||
{
|
|
||||||
return mWhitespaceAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::symbolAttribute() const
|
|
||||||
{
|
|
||||||
return mSymbolAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::onAttributeChanged()
|
|
||||||
{
|
|
||||||
setAttributesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::setAttributesChanged()
|
|
||||||
{
|
|
||||||
if (mUpdateCount == 0) {
|
|
||||||
emit attributesChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::beginUpdate()
|
|
||||||
{
|
|
||||||
mUpdateCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::endUpdate()
|
|
||||||
{
|
|
||||||
mUpdateCount--;
|
|
||||||
if (mUpdateCount == 0) {
|
|
||||||
setAttributesChanged();
|
|
||||||
}
|
|
||||||
if (mUpdateCount<0) {
|
|
||||||
throw new std::out_of_range("mUpdateCount in SynHighlighterBase < 0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynRangeState SynHighlighter::getRangeState() const
|
|
||||||
{
|
|
||||||
return {0,0};
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynHighlighter::getBraceLevel() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynHighlighter::getBracketLevel() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynHighlighter::getParenthesisLevel() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SynHighlighterTokenType SynHighlighter::getTokenType()
|
|
||||||
{
|
|
||||||
return SynHighlighterTokenType::Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynHighlighter::isKeyword(const QString &)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::nextToEol()
|
|
||||||
{
|
|
||||||
while (!eol())
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynHighlighter::isSpaceChar(const QChar &ch)
|
|
||||||
{
|
|
||||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynHighlighter::isIdentChar(const QChar &ch) const
|
|
||||||
{
|
|
||||||
if (ch == '_') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ch>='0' && ch <= '9') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ch>='a' && ch <= 'z') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ch>='A' && ch <= 'A') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::addAttribute(PSynHighlighterAttribute attribute)
|
|
||||||
{
|
|
||||||
mAttributes[attribute->name()]=attribute;
|
|
||||||
connect(attribute.get(), &SynHighlighterAttribute::changed,
|
|
||||||
this, &SynHighlighter::setAttributesChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighter::clearAttributes()
|
|
||||||
{
|
|
||||||
mAttributes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynHighlighter::attributesCount() const
|
|
||||||
{
|
|
||||||
return mAttributes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynHighlighter::getAttribute(const QString &name) const
|
|
||||||
{
|
|
||||||
auto search = mAttributes.find(name);
|
|
||||||
if (search!=mAttributes.end()) {
|
|
||||||
return search.value();
|
|
||||||
}
|
|
||||||
return PSynHighlighterAttribute();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighterAttribute::setChanged()
|
|
||||||
{
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
SynFontStyles SynHighlighterAttribute::styles() const
|
|
||||||
{
|
|
||||||
return mStyles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighterAttribute::setStyles(const SynFontStyles &styles)
|
|
||||||
{
|
|
||||||
if (mStyles!=styles) {
|
|
||||||
mStyles = styles;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynHighlighterAttribute::name() const
|
|
||||||
{
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighterAttribute::setName(const QString &name)
|
|
||||||
{
|
|
||||||
if (mName!=name) {
|
|
||||||
mName = name;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynHighlighterAttribute::foreground() const
|
|
||||||
{
|
|
||||||
return mForeground;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighterAttribute::setForeground(const QColor &foreground)
|
|
||||||
{
|
|
||||||
if (mForeground!=foreground) {
|
|
||||||
mForeground = foreground;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SynHighlighterAttribute::SynHighlighterAttribute(const QString &name, QObject *parent):
|
|
||||||
QObject(parent),
|
|
||||||
mName(name),
|
|
||||||
mForeground(QColorConstants::Black),
|
|
||||||
mBackground(QColorConstants::White)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynHighlighterAttribute::background() const
|
|
||||||
{
|
|
||||||
return mBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynHighlighterAttribute::setBackground(const QColor &background)
|
|
||||||
{
|
|
||||||
if (mBackground!=background) {
|
|
||||||
mBackground = background;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,146 +0,0 @@
|
||||||
#ifndef SYNHIGHLIGTERBASE_H
|
|
||||||
#define SYNHIGHLIGTERBASE_H
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QObject>
|
|
||||||
#include <memory>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QVector>
|
|
||||||
#include "../Types.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int state;
|
|
||||||
int spaceState;
|
|
||||||
} SynRangeState;
|
|
||||||
|
|
||||||
typedef int SynTokenKind;
|
|
||||||
|
|
||||||
enum class SynHighlighterTokenType {
|
|
||||||
Default, Space, Comment,
|
|
||||||
PreprocessDirective, String, StringEscapeSequence,
|
|
||||||
Identifier, Symbol,
|
|
||||||
Character, Keyword, Number};
|
|
||||||
|
|
||||||
enum class SynHighlighterClass {
|
|
||||||
Composition,
|
|
||||||
CppHighlighter,
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynHighlighterAttribute : public QObject{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynHighlighterAttribute(const QString& name, QObject* parent = nullptr);
|
|
||||||
QColor background() const;
|
|
||||||
void setBackground(const QColor &background);
|
|
||||||
|
|
||||||
QColor foreground() const;
|
|
||||||
void setForeground(const QColor &foreground);
|
|
||||||
|
|
||||||
QString name() const;
|
|
||||||
void setName(const QString &name);
|
|
||||||
|
|
||||||
SynFontStyles styles() const;
|
|
||||||
void setStyles(const SynFontStyles &styles);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changed();
|
|
||||||
private:
|
|
||||||
void setChanged();
|
|
||||||
private:
|
|
||||||
QColor mBackground;
|
|
||||||
QColor mForeground;
|
|
||||||
QString mName;
|
|
||||||
SynFontStyles mStyles;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<SynHighlighterAttribute> PSynHighlighterAttribute;
|
|
||||||
using SynHighlighterAttributeList = QVector<PSynHighlighterAttribute>;
|
|
||||||
|
|
||||||
class SynHighlighter : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynHighlighter(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
const QMap<QString, PSynHighlighterAttribute>& attributes() const;
|
|
||||||
|
|
||||||
const QSet<QChar>& wordBreakChars() const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PSynHighlighterAttribute commentAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute identifierAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute keywordAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute stringAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute whitespaceAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute symbolAttribute() const;
|
|
||||||
|
|
||||||
virtual bool isIdentChar(const QChar& ch) const;
|
|
||||||
|
|
||||||
virtual SynHighlighterClass getClass() const = 0;
|
|
||||||
virtual QString getName() const = 0;
|
|
||||||
|
|
||||||
void beginUpdate();
|
|
||||||
void endUpdate();
|
|
||||||
virtual bool getTokenFinished() const = 0;
|
|
||||||
virtual bool isLastLineCommentNotFinished(int state) const = 0;
|
|
||||||
virtual bool isLastLineStringNotFinished(int state) const = 0;
|
|
||||||
virtual bool eol() const = 0;
|
|
||||||
virtual SynRangeState getRangeState() const;
|
|
||||||
virtual int getBraceLevel() const;
|
|
||||||
virtual int getBracketLevel() const;
|
|
||||||
virtual int getParenthesisLevel() const;
|
|
||||||
virtual QString getToken() const=0;
|
|
||||||
virtual PSynHighlighterAttribute getTokenAttribute() const=0;
|
|
||||||
virtual SynHighlighterTokenType getTokenType();
|
|
||||||
virtual SynTokenKind getTokenKind() = 0;
|
|
||||||
virtual int getTokenPos() = 0;
|
|
||||||
virtual bool isKeyword(const QString& word);
|
|
||||||
virtual void next() = 0;
|
|
||||||
virtual void nextToEol();
|
|
||||||
virtual void setState(SynRangeState rangeState, int braceLevel, int bracketLevel, int parenthesisLevel) = 0;
|
|
||||||
virtual void setLine(const QString& newLine, int lineNumber) = 0;
|
|
||||||
virtual void resetState() = 0;
|
|
||||||
|
|
||||||
virtual QString languageName();
|
|
||||||
|
|
||||||
static bool isSpaceChar(const QChar& ch);
|
|
||||||
signals:
|
|
||||||
void attributesChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void onAttributeChanged();
|
|
||||||
void setAttributesChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
PSynHighlighterAttribute mCommentAttribute;
|
|
||||||
PSynHighlighterAttribute mIdentifierAttribute;
|
|
||||||
PSynHighlighterAttribute mKeywordAttribute;
|
|
||||||
PSynHighlighterAttribute mStringAttribute;
|
|
||||||
PSynHighlighterAttribute mWhitespaceAttribute;
|
|
||||||
PSynHighlighterAttribute mSymbolAttribute;
|
|
||||||
|
|
||||||
void addAttribute(PSynHighlighterAttribute attribute);
|
|
||||||
void clearAttributes();
|
|
||||||
virtual int attributesCount() const;
|
|
||||||
|
|
||||||
virtual PSynHighlighterAttribute getAttribute(const QString& name) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMap<QString,PSynHighlighterAttribute> mAttributes;
|
|
||||||
int mUpdateCount;
|
|
||||||
bool mEnabled;
|
|
||||||
QSet<QChar> mWordBreakChars;
|
|
||||||
};
|
|
||||||
|
|
||||||
using PSynHighlighter = std::shared_ptr<SynHighlighter>;
|
|
||||||
using SynHighlighterList = QVector<PSynHighlighter>;
|
|
||||||
|
|
||||||
#endif // SYNHIGHLIGTERBASE_H
|
|
|
@ -1,93 +0,0 @@
|
||||||
#include "composition.h"
|
|
||||||
#include "../Constants.h"
|
|
||||||
|
|
||||||
SynHighlightComposition::SynHighlightComposition(QObject *parent):
|
|
||||||
SynHighlighter(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SynHighlighterClass SynHighlightComposition::getClass() const
|
|
||||||
{
|
|
||||||
return SynHighlighterClass::Composition;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynHighlightComposition::getName() const
|
|
||||||
{
|
|
||||||
return "SynHighlightComposition";
|
|
||||||
}
|
|
||||||
|
|
||||||
SynScheme::SynScheme(QObject *parent):
|
|
||||||
QObject(parent),
|
|
||||||
mCaseSensitive(true)
|
|
||||||
{
|
|
||||||
mMarkerAttribute = std::make_shared<SynHighlighterAttribute>(SYNS_AttrMarker);
|
|
||||||
connect(mMarkerAttribute.get(),&SynHighlighterAttribute::changed,
|
|
||||||
this, &SynScheme::MarkerAttriChanged);
|
|
||||||
mMarkerAttribute->setBackground(QColorConstants::Yellow);
|
|
||||||
mMarkerAttribute->setBold(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynScheme::endExpr() const
|
|
||||||
{
|
|
||||||
return mEndExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynScheme::setEndExpr(const QString &endExpr)
|
|
||||||
{
|
|
||||||
mEndExpr = endExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynScheme::getStartExpr() const
|
|
||||||
{
|
|
||||||
return StartExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynScheme::setStartExpr(const QString &value)
|
|
||||||
{
|
|
||||||
StartExpr = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighter SynScheme::getHighlighter() const
|
|
||||||
{
|
|
||||||
return mHighlighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynScheme::setHighlighter(const PSynHighlighter &highlighter)
|
|
||||||
{
|
|
||||||
mHighlighter = highlighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSynHighlighterAttribute SynScheme::getMarkerAttribute() const
|
|
||||||
{
|
|
||||||
return mMarkerAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynScheme::getSchemeName() const
|
|
||||||
{
|
|
||||||
return mSchemeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynScheme::setSchemeName(const QString &schemeName)
|
|
||||||
{
|
|
||||||
mSchemeName = schemeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynScheme::getCaseSensitive() const
|
|
||||||
{
|
|
||||||
return mCaseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynScheme::setCaseSensitive(int caseSensitive)
|
|
||||||
{
|
|
||||||
mCaseSensitive = caseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynScheme::ConvertExpression(const QString &Value)
|
|
||||||
{
|
|
||||||
if (!mCaseSensitive) {
|
|
||||||
return Value.toUpper();
|
|
||||||
} else {
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef SYNHIGHLIGHTCOMPOSITION_H
|
|
||||||
#define SYNHIGHLIGHTCOMPOSITION_H
|
|
||||||
#include "base.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class SynSchema;
|
|
||||||
using PSynSchema = std::shared_ptr<SynSchema>;
|
|
||||||
|
|
||||||
using OnCheckMarker = std::function<void(PSynSchema Sender,int &StartPos, int &MarkerLen,
|
|
||||||
std::shared_ptr<QString>& MarkerText , int Line)>;
|
|
||||||
|
|
||||||
class SynScheme : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynScheme(QObject* parent=nullptr);
|
|
||||||
QString endExpr() const;
|
|
||||||
void setEndExpr(const QString &endExpr);
|
|
||||||
|
|
||||||
QString getStartExpr() const;
|
|
||||||
void setStartExpr(const QString &value);
|
|
||||||
|
|
||||||
PSynHighlighter getHighlighter() const;
|
|
||||||
void setHighlighter(const PSynHighlighter &highlighter);
|
|
||||||
|
|
||||||
PSynHighlighterAttribute getMarkerAttribute() const;
|
|
||||||
|
|
||||||
QString getSchemeName() const;
|
|
||||||
void setSchemeName(const QString &schemeName);
|
|
||||||
|
|
||||||
int getCaseSensitive() const;
|
|
||||||
void setCaseSensitive(int caseSensitive);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString mEndExpr;
|
|
||||||
QString StartExpr;
|
|
||||||
PSynHighlighter mHighlighter;
|
|
||||||
PSynHighlighterAttribute mMarkerAttribute;
|
|
||||||
QString mSchemeName;
|
|
||||||
int mCaseSensitive;
|
|
||||||
OnCheckMarker mOnCheckStartMarker;
|
|
||||||
OnCheckMarker mOnCheckEndMarker;
|
|
||||||
QString ConvertExpression(const QString& Value);
|
|
||||||
private slots:
|
|
||||||
void MarkerAttriChanged();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SynHighlightComposition : public SynHighlighter
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SynHighlightComposition(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
SynHighlighterClass getClass() const override;
|
|
||||||
QString getName() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SYNHIGHLIGHTCOMPOSITION_H
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,212 +0,0 @@
|
||||||
#ifndef SYNEDITCPPHIGHLIGHTER_H
|
|
||||||
#define SYNEDITCPPHIGHLIGHTER_H
|
|
||||||
#include "base.h"
|
|
||||||
#include <QSet>
|
|
||||||
|
|
||||||
class SynEditCppHighlighter: public SynHighlighter
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
enum TokenKind {
|
|
||||||
Asm = 1,
|
|
||||||
Comment,
|
|
||||||
Directive,
|
|
||||||
Identifier,
|
|
||||||
Key,
|
|
||||||
Null,
|
|
||||||
Number,
|
|
||||||
Space,
|
|
||||||
String,
|
|
||||||
StringEscapeSeq,
|
|
||||||
Symbol,
|
|
||||||
Unknown,
|
|
||||||
Char,
|
|
||||||
Float,
|
|
||||||
Hex,
|
|
||||||
HexFloat,
|
|
||||||
Octal,
|
|
||||||
RawString
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ExtTokenKind {
|
|
||||||
Add, AddAssign, And, AndAssign, Arrow, Assign,
|
|
||||||
BitComplement, BraceClose, BraceOpen, Colon, Comma,
|
|
||||||
Decrement, Divide, DivideAssign, Ellipse, GreaterThan,
|
|
||||||
GreaterThanEqual, IncOr, IncOrAssign, Increment, LessThan,
|
|
||||||
LessThanEqual, LogAnd, LogComplement, LogEqual, LogOr,
|
|
||||||
Mod, ModAssign, MultiplyAssign, NotEqual, Point, Question,
|
|
||||||
RoundClose, RoundOpen, ScopeResolution, SemiColon, ShiftLeft,
|
|
||||||
ShiftLeftAssign, ShiftRight, ShiftRightAssign, SquareClose,
|
|
||||||
SquareOpen, Star, Subtract, SubtractAssign, Xor,
|
|
||||||
XorAssign
|
|
||||||
};
|
|
||||||
|
|
||||||
enum RangeState {
|
|
||||||
rsUnknown, rsAnsiC, rsAnsiCAsm, rsAnsiCAsmBlock, rsAsm,
|
|
||||||
rsAsmBlock, rsDirective, rsDirectiveComment, rsString,
|
|
||||||
rsMultiLineString, rsMultiLineDirective, rsCppComment,
|
|
||||||
rsStringEscapeSeq, rsMultiLineStringEscapeSeq,
|
|
||||||
rsRawString, rsSpace,rsRawStringEscaping,rsRawStringNotEscaping,rsChar
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit SynEditCppHighlighter(QObject* parent = nullptr);
|
|
||||||
|
|
||||||
PSynHighlighterAttribute asmAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute direcAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute invalidAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute keyAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute numberAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute floatAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute hexAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute octAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute stringEscapeSequenceAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute charAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute variableAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute functionAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute classAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute globalVarAttribute() const;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute localVarAttribute() const;
|
|
||||||
|
|
||||||
static const QSet<QString> Keywords;
|
|
||||||
|
|
||||||
ExtTokenKind getExtTokenId();
|
|
||||||
SynTokenKind getTokenId();
|
|
||||||
private:
|
|
||||||
void andSymbolProc();
|
|
||||||
void ansiCppProc();
|
|
||||||
void ansiCProc();
|
|
||||||
void asciiCharProc();
|
|
||||||
void atSymbolProc();
|
|
||||||
void braceCloseProc();
|
|
||||||
void braceOpenProc();
|
|
||||||
void colonProc();
|
|
||||||
void commaProc();
|
|
||||||
void directiveProc();
|
|
||||||
void directiveEndProc();
|
|
||||||
void equalProc();
|
|
||||||
void greaterProc();
|
|
||||||
void identProc();
|
|
||||||
void lowerProc();
|
|
||||||
void minusProc();
|
|
||||||
void modSymbolProc();
|
|
||||||
void notSymbolProc();
|
|
||||||
void nullProc();
|
|
||||||
void numberProc();
|
|
||||||
void orSymbolProc();
|
|
||||||
void plusProc();
|
|
||||||
void pointProc();
|
|
||||||
void questionProc();
|
|
||||||
void rawStringProc();
|
|
||||||
void roundCloseProc();
|
|
||||||
void roundOpenProc();
|
|
||||||
void semiColonProc();
|
|
||||||
void slashProc();
|
|
||||||
void spaceProc();
|
|
||||||
void squareCloseProc();
|
|
||||||
void squareOpenProc();
|
|
||||||
void starProc();
|
|
||||||
void stringEndProc();
|
|
||||||
void stringEscapeSeqProc();
|
|
||||||
void stringProc();
|
|
||||||
void stringStartProc();
|
|
||||||
void tildeProc();
|
|
||||||
void unknownProc();
|
|
||||||
void xorSymbolProc();
|
|
||||||
void processChar();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool mAsmStart;
|
|
||||||
SynRangeState mRange;
|
|
||||||
// SynRangeState mSpaceRange;
|
|
||||||
int mParenthesisLevel;
|
|
||||||
int mBracketLevel;
|
|
||||||
int mBraceLevel;
|
|
||||||
QString mLineString;
|
|
||||||
QChar* mLine;
|
|
||||||
int mLineSize;
|
|
||||||
int mRun;
|
|
||||||
int mStringLen;
|
|
||||||
int mToIdent;
|
|
||||||
int mTokenPos;
|
|
||||||
int mTokenId;
|
|
||||||
ExtTokenKind mExtTokenId;
|
|
||||||
int mLineNumber;
|
|
||||||
|
|
||||||
PSynHighlighterAttribute mAsmAttribute;
|
|
||||||
PSynHighlighterAttribute mDirecAttribute;
|
|
||||||
PSynHighlighterAttribute mInvalidAttribute;
|
|
||||||
PSynHighlighterAttribute mKeyAttribute;
|
|
||||||
PSynHighlighterAttribute mNumberAttribute;
|
|
||||||
PSynHighlighterAttribute mFloatAttribute;
|
|
||||||
PSynHighlighterAttribute mHexAttribute;
|
|
||||||
PSynHighlighterAttribute mOctAttribute;
|
|
||||||
PSynHighlighterAttribute mStringEscapeSequenceAttribute;
|
|
||||||
PSynHighlighterAttribute mCharAttribute;
|
|
||||||
PSynHighlighterAttribute mVariableAttribute;
|
|
||||||
PSynHighlighterAttribute mFunctionAttribute;
|
|
||||||
PSynHighlighterAttribute mClassAttribute;
|
|
||||||
PSynHighlighterAttribute mGlobalVarAttribute;
|
|
||||||
PSynHighlighterAttribute mLocalVarAttribute;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
bool getTokenFinished() const override;
|
|
||||||
bool isLastLineCommentNotFinished(int state) const override;
|
|
||||||
bool isLastLineStringNotFinished(int state) const override;
|
|
||||||
bool eol() const override;
|
|
||||||
QString getToken() const override;
|
|
||||||
PSynHighlighterAttribute getTokenAttribute() const override;
|
|
||||||
SynTokenKind getTokenKind() override;
|
|
||||||
int getTokenPos() override;
|
|
||||||
void next() override;
|
|
||||||
void setLine(const QString &newLine, int lineNumber) override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
int getBraceLevel() const override;
|
|
||||||
int getBracketLevel() const override;
|
|
||||||
int getParenthesisLevel() const override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
bool isKeyword(const QString &word) override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
SynHighlighterTokenType getTokenType() override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
void setState(SynRangeState rangeState, int braceLevel, int bracketLevel, int parenthesisLevel) override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
void resetState() override;
|
|
||||||
|
|
||||||
// SynHighligterBase interface
|
|
||||||
public:
|
|
||||||
SynHighlighterClass getClass() const override;
|
|
||||||
|
|
||||||
// SynHighlighter interface
|
|
||||||
public:
|
|
||||||
QString getName() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SYNEDITCPPHIGHLIGHTER_H
|
|
|
@ -1,4 +1,5 @@
|
||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
|
../QScintilla/src/qscintilla.pro \
|
||||||
RedPandaIDE
|
RedPandaIDE
|
||||||
|
|
Loading…
Reference in New Issue