From 2ea51696758b59029031253b9497bd778318db9d Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Wed, 26 May 2021 00:04:20 +0800 Subject: [PATCH] * work save --- RedPandaIDE/HighlighterManager.cpp | 55 ++++++++++ RedPandaIDE/HighlighterManager.h | 16 +++ RedPandaIDE/RedPandaIDE.pro | 2 + RedPandaIDE/editor.cpp | 7 +- RedPandaIDE/editor.h | 2 +- RedPandaIDE/qsynedit/SynEdit.cpp | 41 ++++++- RedPandaIDE/qsynedit/SynEdit.h | 4 + RedPandaIDE/qsynedit/highlighter/base.cpp | 100 +++++------------- RedPandaIDE/qsynedit/highlighter/base.h | 43 +++----- .../qsynedit/highlighter/composition.cpp | 7 +- .../qsynedit/highlighter/composition.h | 3 +- RedPandaIDE/qsynedit/highlighter/cpp.cpp | 23 +++- RedPandaIDE/qsynedit/highlighter/cpp.h | 28 +---- 13 files changed, 192 insertions(+), 139 deletions(-) create mode 100644 RedPandaIDE/HighlighterManager.cpp create mode 100644 RedPandaIDE/HighlighterManager.h diff --git a/RedPandaIDE/HighlighterManager.cpp b/RedPandaIDE/HighlighterManager.cpp new file mode 100644 index 00000000..11c55e41 --- /dev/null +++ b/RedPandaIDE/HighlighterManager.cpp @@ -0,0 +1,55 @@ +#include "HighlighterManager.h" +#include +#include +#include "qsynedit/highlighter/cpp.h" + +HighlighterManager highlighterManager; + +HighlighterManager::HighlighterManager() +{ + +} + +PSynHighlighter HighlighterManager::createHighlighter(const QString &filename) +{ + if (filename.isEmpty() || filename.startsWith(QObject::tr("untitled"))) { + return createCppHighlighter(); + } else { + QFileInfo info(filename); + QString suffix = info.suffix(); + if (suffix.isEmpty() || suffix == "c" || suffix == "cpp" || suffix == "cxx" + || suffix == "cc" || suffix == "h" || suffix == "hpp" + || suffix == "hxx" || suffix == "hh") { + return createCppHighlighter(); + } + } + return PSynHighlighter(); +} + +PSynHighlighter HighlighterManager::createCppHighlighter() +{ + SynEditCppHighlighter* highlighter = new SynEditCppHighlighter(); + PSynHighlighter pHighlighter(highlighter); + highlighter->asmAttribute()->setForeground(QColorConstants::Blue); + highlighter->charAttribute()->setForeground(QColorConstants::Black); + highlighter->commentAttribute()->setForeground(0x8C8C8C); + highlighter->commentAttribute()->setStyles(SynFontStyle::fsItalic); + highlighter->classAttribute()->setForeground(0x008080); + highlighter->floatAttribute()->setForeground(QColorConstants::Svg::purple); + highlighter->functionAttribute()->setForeground(0x00627A); + highlighter->globalVarAttribute()->setForeground(0x660E7A); + highlighter->hexAttribute()->setForeground(QColorConstants::Svg::purple); + highlighter->identifierAttribute()->setForeground(0x080808); + highlighter->invalidAttribute()->setForeground(QColorConstants::Svg::red); + highlighter->localVarAttribute()->setForeground(QColorConstants::Black); + highlighter->numberAttribute()->setForeground(0x1750EB); + highlighter->octAttribute()->setForeground(QColorConstants::Svg::purple); + highlighter->direcAttribute()->setForeground(0x1f542e); + highlighter->keyAttribute()->setForeground(0x0033b3); + highlighter->whitespaceAttribute()->setForeground(QColorConstants::Svg::silver); + highlighter->stringAttribute()->setForeground(0x007d17); + highlighter->stringEscapeSequenceAttribute()->setForeground(QColorConstants::Svg::red); + highlighter->symbolAttribute()->setForeground(0xc10000); + highlighter->variableAttribute()->setForeground(0x400080); + return pHighlighter; +} diff --git a/RedPandaIDE/HighlighterManager.h b/RedPandaIDE/HighlighterManager.h new file mode 100644 index 00000000..96950fd2 --- /dev/null +++ b/RedPandaIDE/HighlighterManager.h @@ -0,0 +1,16 @@ +#ifndef HIGHLIGHTERMANAGER_H +#define HIGHLIGHTERMANAGER_H +#include "qsynedit/highlighter/base.h" + +class HighlighterManager +{ +public: + HighlighterManager(); + + PSynHighlighter createHighlighter(const QString& filename); + PSynHighlighter createCppHighlighter(); +}; + +extern HighlighterManager highlighterManager; + +#endif // HIGHLIGHTERMANAGER_H diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 3805712f..883aeccf 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -9,6 +9,7 @@ CONFIG += c++14 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + HighlighterManager.cpp \ compiler/compiler.cpp \ compiler/compilermanager.cpp \ compiler/executablerunner.cpp \ @@ -38,6 +39,7 @@ SOURCES += \ widgets/issuestable.cpp HEADERS += \ + HighlighterManager.h \ compiler/compiler.h \ compiler/compilermanager.h \ compiler/executablerunner.h \ diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 1dba7969..6f3598ce 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -13,6 +13,7 @@ #include #include #include "qsynedit/highlighter/cpp.h" +#include "HighlighterManager.h" using namespace std; @@ -30,6 +31,7 @@ const char *SaveException::what() const noexcept { return mReason.toLocal8Bit(); } +int Editor::newfileCount=0; Editor::Editor(QWidget *parent, const QString& filename, const QByteArray& encoding, @@ -43,7 +45,8 @@ Editor::Editor(QWidget *parent, const QString& filename, mParentPageControl(parentPageControl) { if (mFilename.isEmpty()) { - mFilename = tr("untitled") + "1"; + newfileCount++; + mFilename = tr("untitled") + newfileCount; } QFileInfo fileInfo(mFilename); if (mParentPageControl!=NULL) { @@ -52,11 +55,13 @@ Editor::Editor(QWidget *parent, const QString& filename, } if (!isNew) { loadFile(); + setHighlighter(highlighterManager.createHighlighter(mFilename)); } else { if (mEncodingOption == ENCODING_AUTO_DETECT) mFileEncoding = ENCODING_ASCII; else mFileEncoding = mEncodingOption; + setHighlighter(highlighterManager.createCppHighlighter()); } //SynEditCppHighlighter highlighter; diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index c287ac40..aa904dd8 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -73,6 +73,7 @@ protected slots: void onLinesChanged(int startLine, int count) ; private: + static int newfileCount; QByteArray mEncodingOption; // the encoding type set by the user QByteArray mFileEncoding; // the real encoding of the file (auto detected) QString mFilename; @@ -80,7 +81,6 @@ private: bool mInProject; bool mIsNew; - // QWidget interface protected: void wheelEvent(QWheelEvent *event) override; diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 259b7fa9..c12ccfe8 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -1143,6 +1143,23 @@ int SynEdit::scanFrom(int Index) return Result; } +int SynEdit::scanRanges() +{ + if (mHighlighter && !mLines->empty()) { + mHighlighter->resetState(); + for (int i =0;icount();i++) { + mHighlighter->setLine(mLines->getString(i), i); + qDebug()<getString(i); + mHighlighter->nextToEol(); + mLines->setRange(i, mHighlighter->getRangeState()); + mLines->setParenthesisLevel(i, mHighlighter->getParenthesisLevel()); + mLines->setBracketLevel(i, mHighlighter->getBracketLevel()); + mLines->setBraceLevel(i, mHighlighter->getBraceLevel()); + } + qDebug()<<"finished."; + } +} + void SynEdit::uncollapse(PSynEditFoldRange FoldRange) { FoldRange->linesCollapsed = 0; @@ -1521,7 +1538,6 @@ void SynEdit::sizeOrFontChanged(bool bFont) gutterChanged(); else updateScrollbars(); - initializeCaret(); mStateFlags.setFlag(SynStateFlag::sfCaretChanged,false); invalidate(); } else @@ -1546,6 +1562,29 @@ void SynEdit::doScrolled(int) invalidate(); } +PSynHighlighter SynEdit::highlighter() const +{ + return mHighlighter; +} + +void SynEdit::setHighlighter(const PSynHighlighter &highlighter) +{ + PSynHighlighter oldHighlighter= mHighlighter; + mHighlighter = highlighter; + if (oldHighlighter && mHighlighter && + oldHighlighter->language() == highlighter->language()) { + } else { + recalcCharExtent(); + mLines->beginUpdate(); + auto action=finally([this]{ + mLines->endUpdate(); + }); + scanRanges(); + } + sizeOrFontChanged(true); + invalidate(); +} + PSynEditStringList SynEdit::lines() const { return mLines; diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index faf6d86e..696c12db 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -292,6 +292,7 @@ private: QString expandAtWideGlyphs(const QString& S); void updateModifiedStatus(); int scanFrom(int Index); + int scanRanges(); void uncollapse(PSynEditFoldRange FoldRange); void foldOnListInserted(int Line, int Count); void foldOnListDeleted(int Line, int Count); @@ -458,6 +459,9 @@ public: bool event(QEvent *event) override; // QWidget interface +PSynHighlighter highlighter() const; +void setHighlighter(const PSynHighlighter &highlighter); + protected: void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; diff --git a/RedPandaIDE/qsynedit/highlighter/base.cpp b/RedPandaIDE/qsynedit/highlighter/base.cpp index 776070e7..899c6207 100644 --- a/RedPandaIDE/qsynedit/highlighter/base.cpp +++ b/RedPandaIDE/qsynedit/highlighter/base.cpp @@ -1,10 +1,9 @@ #include "base.h" #include "../Constants.h" -SynHighlighter::SynHighlighter(QObject *parent) : QObject(parent), - mWordBreakChars{ SynWordBreakChars }, +SynHighlighter::SynHighlighter() : mEnabled(true), - mUpdateCount(0) + mWordBreakChars{ SynWordBreakChars } { } @@ -49,34 +48,6 @@ 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}; @@ -129,7 +100,7 @@ bool SynHighlighter::isIdentChar(const QChar &ch) const if (ch>='a' && ch <= 'z') { return true; } - if (ch>='A' && ch <= 'A') { + if (ch>='A' && ch <= 'Z') { return true; } @@ -138,8 +109,6 @@ bool SynHighlighter::isIdentChar(const QChar &ch) const void SynHighlighter::addAttribute(PSynHighlighterAttribute attribute) { mAttributes[attribute->name()]=attribute; - connect(attribute.get(), &SynHighlighterAttribute::changed, - this, &SynHighlighter::setAttributesChanged); } void SynHighlighter::clearAttributes() @@ -170,15 +139,9 @@ void SynHighlighter::setEnabled(bool value) { if (value != mEnabled) { mEnabled = value; - setAttributesChanged(); } } -void SynHighlighterAttribute::setChanged() -{ - emit changed(); -} - SynFontStyles SynHighlighterAttribute::styles() const { return mStyles; @@ -188,10 +151,29 @@ void SynHighlighterAttribute::setStyles(const SynFontStyles &styles) { if (mStyles!=styles) { mStyles = styles; - setChanged(); } } +QColor SynHighlighterAttribute::foreground() const +{ + return mForeground; +} + +void SynHighlighterAttribute::setForeground(const QColor &color) +{ + mForeground = color; +} + +QColor SynHighlighterAttribute::background() const +{ + return mBackground; +} + +void SynHighlighterAttribute::setBackground(const QColor &background) +{ + mBackground = background; +} + QString SynHighlighterAttribute::name() const { return mName; @@ -201,41 +183,13 @@ 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) +SynHighlighterAttribute::SynHighlighterAttribute(const QString &name): + mForeground(QColor()), + mBackground(QColor()), + mName(name) { } - -QColor SynHighlighterAttribute::background() const -{ - return mBackground; -} - -void SynHighlighterAttribute::setBackground(const QColor &background) -{ - if (mBackground!=background) { - mBackground = background; - setChanged(); - } -} diff --git a/RedPandaIDE/qsynedit/highlighter/base.h b/RedPandaIDE/qsynedit/highlighter/base.h index ae4dadcf..4b1b1600 100644 --- a/RedPandaIDE/qsynedit/highlighter/base.h +++ b/RedPandaIDE/qsynedit/highlighter/base.h @@ -28,15 +28,13 @@ enum class SynHighlighterClass { CppHighlighter, }; -class SynHighlighterAttribute : public QObject{ - Q_OBJECT -public: - explicit SynHighlighterAttribute(const QString& name, QObject* parent = nullptr); - QColor background() const; - void setBackground(const QColor &background); +enum class SynHighlighterLanguage { + Cpp +}; - QColor foreground() const; - void setForeground(const QColor &foreground); +class SynHighlighterAttribute { +public: + explicit SynHighlighterAttribute(const QString& name); QString name() const; void setName(const QString &name); @@ -44,13 +42,15 @@ public: SynFontStyles styles() const; void setStyles(const SynFontStyles &styles); -signals: - void changed(); + QColor foreground() const; + void setForeground(const QColor &color); + + QColor background() const; + void setBackground(const QColor &background); + private: - void setChanged(); -private: - QColor mBackground; QColor mForeground; + QColor mBackground; QString mName; SynFontStyles mStyles; }; @@ -58,11 +58,9 @@ private: typedef std::shared_ptr PSynHighlighterAttribute; using SynHighlighterAttributeList = QVector; -class SynHighlighter : public QObject -{ - Q_OBJECT +class SynHighlighter { public: - explicit SynHighlighter(QObject *parent = nullptr); + explicit SynHighlighter(); const QMap& attributes() const; @@ -87,8 +85,6 @@ public: 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; @@ -110,18 +106,12 @@ public: virtual void resetState() = 0; virtual QString languageName() = 0; + virtual SynHighlighterLanguage language() = 0; static bool isSpaceChar(const QChar& ch); bool enabled() const; void setEnabled(bool value); -signals: - void attributesChanged(); - -protected: - void onAttributeChanged(); - void setAttributesChanged(); - protected: PSynHighlighterAttribute mCommentAttribute; PSynHighlighterAttribute mIdentifierAttribute; @@ -138,7 +128,6 @@ protected: private: QMap mAttributes; - int mUpdateCount; bool mEnabled; QSet mWordBreakChars; }; diff --git a/RedPandaIDE/qsynedit/highlighter/composition.cpp b/RedPandaIDE/qsynedit/highlighter/composition.cpp index 576b5ffb..1b3b42ce 100644 --- a/RedPandaIDE/qsynedit/highlighter/composition.cpp +++ b/RedPandaIDE/qsynedit/highlighter/composition.cpp @@ -1,8 +1,7 @@ #include "composition.h" #include "../Constants.h" -SynHighlightComposition::SynHighlightComposition(QObject *parent): - SynHighlighter(parent) +SynHighlightComposition::SynHighlightComposition() { } @@ -22,9 +21,7 @@ SynScheme::SynScheme(QObject *parent): mCaseSensitive(true) { mMarkerAttribute = std::make_shared(SYNS_AttrMarker); - connect(mMarkerAttribute.get(),&SynHighlighterAttribute::changed, - this, &SynScheme::MarkerAttriChanged); - mMarkerAttribute->setBackground(QColorConstants::Yellow); + mMarkerAttribute->setForeground(QColorConstants::Yellow); mMarkerAttribute->setStyles(SynFontStyle::fsBold); } diff --git a/RedPandaIDE/qsynedit/highlighter/composition.h b/RedPandaIDE/qsynedit/highlighter/composition.h index a89e08c6..c5933a49 100644 --- a/RedPandaIDE/qsynedit/highlighter/composition.h +++ b/RedPandaIDE/qsynedit/highlighter/composition.h @@ -49,9 +49,8 @@ private slots: class SynHighlightComposition : public SynHighlighter { - Q_OBJECT public: - explicit SynHighlightComposition(QObject *parent = nullptr); + explicit SynHighlightComposition(); // SynHighligterBase interface public: diff --git a/RedPandaIDE/qsynedit/highlighter/cpp.cpp b/RedPandaIDE/qsynedit/highlighter/cpp.cpp index b8185c14..4e3bf873 100644 --- a/RedPandaIDE/qsynedit/highlighter/cpp.cpp +++ b/RedPandaIDE/qsynedit/highlighter/cpp.cpp @@ -110,14 +110,13 @@ const QSet SynEditCppHighlighter::Keywords { "nullptr", }; -SynEditCppHighlighter::SynEditCppHighlighter(QObject *parent): SynHighlighter(parent) +SynEditCppHighlighter::SynEditCppHighlighter(): SynHighlighter() { mAsmAttribute = std::make_shared(SYNS_AttrAssembler); addAttribute(mAsmAttribute); mCharAttribute = std::make_shared(SYNS_AttrCharacter); addAttribute(mCharAttribute); mCommentAttribute = std::make_shared(SYNS_AttrComment); - mCommentAttribute->setStyles(SynFontStyle::fsItalic); addAttribute(mCommentAttribute); mClassAttribute = std::make_shared(SYNS_AttrClass); addAttribute(mClassAttribute); @@ -142,7 +141,6 @@ SynEditCppHighlighter::SynEditCppHighlighter(QObject *parent): SynHighlighter(pa mDirecAttribute = std::make_shared(SYNS_AttrPreprocessor); addAttribute(mDirecAttribute); mKeyAttribute = std::make_shared(SYNS_AttrReservedWord); - mCommentAttribute->setStyles(SynFontStyle::fsBold); addAttribute(mKeyAttribute); mWhitespaceAttribute = std::make_shared(SYNS_AttrSpace); addAttribute(mWhitespaceAttribute); @@ -621,7 +619,6 @@ void SynEditCppHighlighter::numberProc() mRun+=1; mTokenId = TokenKind::Number; bool shouldExit = false; - double x=010.140; while (mLine[mRun]!=0) { switch(mLine[mRun].unicode()) { case '\'': @@ -772,8 +769,13 @@ void SynEditCppHighlighter::numberProc() return; } break; + default: + shouldExit=true; } - mRun+=1; + if (shouldExit) { + break; + } + mRun+=1; } if (mLine[mRun-1] == '\'') { mTokenId = TokenKind::Unknown; @@ -1162,6 +1164,7 @@ void SynEditCppHighlighter::stringProc() return; } } + mRun+=1; } mRange.state = RangeState::rsUnknown; } @@ -1570,3 +1573,13 @@ QString SynEditCppHighlighter::getName() const { return "SynCppHighlighter"; } + +QString SynEditCppHighlighter::languageName() +{ + return "cpp"; +} + +SynHighlighterLanguage SynEditCppHighlighter::language() +{ + return SynHighlighterLanguage::Cpp; +} diff --git a/RedPandaIDE/qsynedit/highlighter/cpp.h b/RedPandaIDE/qsynedit/highlighter/cpp.h index 99265a42..49798a04 100644 --- a/RedPandaIDE/qsynedit/highlighter/cpp.h +++ b/RedPandaIDE/qsynedit/highlighter/cpp.h @@ -5,8 +5,6 @@ class SynEditCppHighlighter: public SynHighlighter { - Q_OBJECT - enum TokenKind { Asm = 1, Comment, @@ -50,7 +48,7 @@ class SynEditCppHighlighter: public SynHighlighter }; public: - explicit SynEditCppHighlighter(QObject* parent = nullptr); + explicit SynEditCppHighlighter(); PSynHighlighterAttribute asmAttribute() const; @@ -177,36 +175,18 @@ public: 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; + + QString languageName() override; + SynHighlighterLanguage language() override; }; #endif // SYNEDITCPPHIGHLIGHTER_H