From efef9c35f44c8919f6d4b916e7fe9574a3dee947 Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Mon, 23 Aug 2021 10:16:06 +0800 Subject: [PATCH] work save --- RedPandaIDE/editor.cpp | 29 ++++++++-- RedPandaIDE/editor.h | 4 ++ RedPandaIDE/editorlist.cpp | 9 ++++ RedPandaIDE/editorlist.h | 2 + RedPandaIDE/parser/cppparser.cpp | 79 ++++++++++++++++++++++++++++ RedPandaIDE/parser/cppparser.h | 59 +++++++++++++++++++++ RedPandaIDE/qsynedit/SynEdit.h | 6 --- RedPandaIDE/qsynedit/TextBuffer.cpp | 9 ++++ RedPandaIDE/qsynedit/TextBuffer.h | 1 + RedPandaIDE/utils.cpp | 41 +++++++++++++++ RedPandaIDE/utils.h | 4 ++ RedPandaIDE/widgets/classbrowser.cpp | 16 +----- 12 files changed, 233 insertions(+), 26 deletions(-) diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index f6b56e7e..08db9217 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -23,7 +23,7 @@ #include #include "iconsmanager.h" #include "debugger.h" - +#include "editorlist.h" using namespace std; @@ -130,7 +130,7 @@ void Editor::convertToEncoding(const QByteArray &encoding) save(); } -bool Editor::save(bool force, bool reparse) { +bool Editor::save(bool force, bool doReparse) { if (this->mIsNew) { return saveAs(); } @@ -148,14 +148,16 @@ bool Editor::save(bool force, bool reparse) { mIsNew = false; this->updateCaption(); } catch (SaveException& exception) { - QMessageBox::critical(pMainWindow,tr("Error"), + if (!force) { + QMessageBox::critical(pMainWindow,tr("Error"), exception.reason()); + } return false; } } - if (reparse) { - //todo: reparse the file + if (doReparse && mParser) { + reparse(); } return true; } @@ -648,6 +650,7 @@ void Editor::onStatusChanged(SynStatusChanges changes) && !changes.testFlag(SynStatusChange::scInsertMode) && (lines()->count()!=mLineCount) && (lines()->count()!=0) && ((mLineCount>0) || (lines()->count()>1))) { + reparse(); if (!readOnly() && pSettings->editor().syntaxCheck() && pSettings->editor().syntaxCheckWhenLineChanged()) pMainWindow->checkSyntaxInBack(this); } @@ -1057,6 +1060,17 @@ bool Editor::handleGlobalIncludeSkip() return false; } +void Editor::initParser() +{ + mParser = std::make_shared(); + mParser->setOnGetFileStream( + std::bind( + &EditorList::getContentFromOpenedEditor,pMainWindow->editorList(), + std::placeholders::_1, std::placeholders::_2)); + resetCppParser(mParser); + mParser->setEnabled((highlighter() && highlighter()->getClass() == SynHighlighterClass::CppHighlighter)); +} + Editor::QuoteStatus Editor::getQuoteStatus() { QuoteStatus Result = QuoteStatus::NotQuote; @@ -1166,6 +1180,11 @@ Editor::QuoteStatus Editor::getQuoteStatus() return Result; } +void Editor::reparse() +{ + parseFile(mParser,mFilename,mInProject); +} + int Editor::gutterClickedLine() const { return mGutterClickedLine; diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index f2963c20..56c09bc9 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -7,6 +7,7 @@ #include "qsynedit/SynEdit.h" #include "colorscheme.h" #include "common.h" +#include "parser/cppparser.h" class SaveException: public std::exception { @@ -136,8 +137,10 @@ private: bool handleDoubleQuoteCompletion(); bool handleGlobalIncludeCompletion(); bool handleGlobalIncludeSkip(); + void initParser(); void undoSymbolCompletion(int pos); QuoteStatus getQuoteStatus(); + void reparse(); private: static int newfileCount; @@ -159,6 +162,7 @@ private: int mGutterClickedLine; QSet mBreakpointLines; int mActiveBreakpointLine; + PCppParser mParser; // QWidget interface protected: diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index 2de955c1..85a37c64 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -221,3 +221,12 @@ Editor *EditorList::getEditorByFilename(const QString &filename) return newEditor(fullname,ENCODING_AUTO_DETECT,false,false); return nullptr; } + +bool EditorList::getContentFromOpenedEditor(const QString &filename, QStringList &buffer) +{ + Editor * e= getOpenedEditorByFilename(filename); + if (!e) + return false; + buffer = e->lines()->contents(); + return true; +} diff --git a/RedPandaIDE/editorlist.h b/RedPandaIDE/editorlist.h index df2c9e4a..4c05da6e 100644 --- a/RedPandaIDE/editorlist.h +++ b/RedPandaIDE/editorlist.h @@ -36,6 +36,8 @@ public: Editor* getEditorByFilename(const QString& filename); + bool getContentFromOpenedEditor(const QString& filename, QStringList& buffer); + void beginUpdate(); void endUpdate(); void applySettings(); diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 7e4acf25..ba4c3640 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -3517,6 +3517,26 @@ void CppParser::updateSerialId() mSerialId = QString("%1 %2").arg(mParserId).arg(mSerialCount); } +bool CppParser::parseGlobalHeaders() const +{ + return mParseGlobalHeaders; +} + +void CppParser::setParseGlobalHeaders(bool newParseGlobalHeaders) +{ + mParseGlobalHeaders = newParseGlobalHeaders; +} + +bool CppParser::parseLocalHeaders() const +{ + return mParseLocalHeaders; +} + +void CppParser::setParseLocalHeaders(bool newParseLocalHeaders) +{ + mParseLocalHeaders = newParseLocalHeaders; +} + const QString &CppParser::serialId() const { return mSerialId; @@ -3551,3 +3571,62 @@ void CppParser::setEnabled(bool newEnabled) { mEnabled = newEnabled; } + +CppFileParserThread::CppFileParserThread( + PCppParser parser, + QString fileName, + bool inProject, + bool onlyIfNotParsed, + bool updateView, + QObject *parent):QThread(parent), + mParser(parser), + mFileName(fileName), + mInProject(inProject), + mOnlyIfNotParsed(onlyIfNotParsed), + mUpdateView(updateView) +{ + +} + +void CppFileParserThread::run() +{ + if (mParser && !mParser->parsing()) { + mParser->parseFile(mFileName,mInProject,mOnlyIfNotParsed,mUpdateView); + } +} + +CppFileListParserThread::CppFileListParserThread(PCppParser parser, + bool updateView, QObject *parent): + QThread(parent), + mParser(parser), + mUpdateView(updateView) +{ + +} + +void CppFileListParserThread::run() +{ + if (mParser && !mParser->parsing()) { + mParser->parseFileList(mUpdateView); + } +} + +void parseFile(PCppParser parser, QString fileName, bool inProject, bool onlyIfNotParsed, bool updateView) +{ + CppFileParserThread* thread = new CppFileParserThread(parser,fileName,inProject,onlyIfNotParsed,updateView); + thread->connect(thread, + &QThread::finished, + thread, + &QThread::deleteLater); + thread->start(); +} + +void parseFileList(PCppParser parser, bool updateView) +{ + CppFileListParserThread *thread = new CppFileListParserThread(parser,updateView); + thread->connect(thread, + &QThread::finished, + thread, + &QThread::deleteLater); + thread->start(); +} diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 303174ae..c60ae112 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -3,6 +3,7 @@ #include #include +#include #include "statementmodel.h" #include "cpptokenizer.h" #include "cpppreprocessor.h" @@ -112,6 +113,12 @@ public: const QString &serialId() const; + bool parseLocalHeaders() const; + void setParseLocalHeaders(bool newParseLocalHeaders); + + bool parseGlobalHeaders() const; + void setParseGlobalHeaders(bool newParseGlobalHeaders); + signals: void onProgress(const QString& fileName, int total, int current); void onBusy(); @@ -349,4 +356,56 @@ private: GetFileStreamCallBack mOnGetFileStream; }; using PCppParser = std::shared_ptr; + +class CppFileParserThread : public QThread { + Q_OBJECT +public: + explicit CppFileParserThread( + PCppParser parser, + QString fileName, + bool inProject, + bool onlyIfNotParsed = false, + bool updateView = true, + QObject *parent = nullptr); + +private: + PCppParser mParser; + QString mFileName; + bool mInProject; + bool mOnlyIfNotParsed; + bool mUpdateView; + + // QThread interface +protected: + void run() override; +}; +using PCppParserThread = std::shared_ptr; + +class CppFileListParserThread: public QThread { + Q_OBJECT +public: + explicit CppFileListParserThread( + PCppParser parser, + bool updateView = true, + QObject *parent = nullptr); +private: + PCppParser mParser; + bool mUpdateView; + // QThread interface +protected: + void run() override; +}; + +void parseFile( + PCppParser parser, + QString fileName, + bool inProject, + bool onlyIfNotParsed = false, + bool updateView = true); + +void parseFileList( + PCppParser parser, + bool updateView = true); + + #endif // CPPPARSER_H diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index 8f2131ee..e552c56d 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -130,12 +130,6 @@ using SynPreparePaintHighlightTokenProc = std::function; using SynSearchMathedProc = std::function; -//using SynSpecialLineColorsProc = std::function; -//using SynEditingAreasProc = std::function; -//using SynGutterGetTextProc = std::function; -//using SynTGutterPaintProc = std::function; class SynEdit; using PSynEdit = std::shared_ptr; diff --git a/RedPandaIDE/qsynedit/TextBuffer.cpp b/RedPandaIDE/qsynedit/TextBuffer.cpp index decd8d56..93b963d5 100644 --- a/RedPandaIDE/qsynedit/TextBuffer.cpp +++ b/RedPandaIDE/qsynedit/TextBuffer.cpp @@ -217,6 +217,15 @@ void SynEditStringList::setText(const QString &text) PutTextStr(text); } +QStringList SynEditStringList::contents() +{ + QStringList Result; + for (PSynEditStringRec& line:mList) { + Result.append(line->fString); + } + return Result; +} + void SynEditStringList::beginUpdate() { if (mUpdateCount == 0) { diff --git a/RedPandaIDE/qsynedit/TextBuffer.h b/RedPandaIDE/qsynedit/TextBuffer.h index 99297d03..627c3e5e 100644 --- a/RedPandaIDE/qsynedit/TextBuffer.h +++ b/RedPandaIDE/qsynedit/TextBuffer.h @@ -67,6 +67,7 @@ public: void* getObject(int Index); QString text(); void setText(const QString& text); + QStringList contents(); void putString(int Index, const QString& s); void putObject(int Index, void * AObject); diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp index 3bade542..b5482c36 100644 --- a/RedPandaIDE/utils.cpp +++ b/RedPandaIDE/utils.cpp @@ -15,6 +15,8 @@ #include #include #include +#include "parser/cppparser.h" +#include "settings.h" const QByteArray GuessTextEncoding(const QByteArray& text){ bool allAscii; @@ -500,3 +502,42 @@ void StringsToFile(const QStringList &list, const QString &fileName) } } } + +void resetCppParser(std::shared_ptr parser) +{ + if (!parser) + return; + // Configure parser + parser->reset(); + //paser->enabled = pSettings-> devCodeCompletion.Enabled; +// CppParser.ParseLocalHeaders := devCodeCompletion.ParseLocalHeaders; +// CppParser.ParseGlobalHeaders := devCodeCompletion.ParseGlobalHeaders; + parser->setEnabled(true); + parser->setParseGlobalHeaders(true); + parser->setParseLocalHeaders(true); + // Set options depending on the current compiler set + // TODO: do this every time OnCompilerSetChanged + Settings::PCompilerSet compilerSet = pSettings->compilerSets().defaultSet(); + parser->clearIncludePaths(); + if (compilerSet) { + for (QString file:compilerSet->CIncludeDirs()) { + parser->addIncludePath(file); + } + for (QString file:compilerSet->CppIncludeDirs()) { + parser->addIncludePath(file); + } + //TODO: Add default include dirs last, just like gcc does + // Set defines + for (QString define:compilerSet->defines()) { + parser->addHardDefineByLine(define); // predefined constants from -dM -E + } + // add a dev-cpp's own macro + parser->addHardDefineByLine("#define EGE_FOR_AUTO_CODE_COMPLETETION_ONLY"); + // add C/C++ default macro + parser->addHardDefineByLine("#define __FILE__ 1"); + parser->addHardDefineByLine("#define __LINE__ 1"); + parser->addHardDefineByLine("#define __DATE__ 1"); + parser->addHardDefineByLine("#define __TIME__ 1"); + } + parser->parseHardDefines(); +} diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h index 8ac7f271..42bbc960 100644 --- a/RedPandaIDE/utils.h +++ b/RedPandaIDE/utils.h @@ -103,6 +103,10 @@ bool StringIsBlank(const QString& s); int compareFileModifiedTime(const QString& filename1, const QString& filename2); void changeTheme(const QString& themeName); + +class CppParser; +void resetCppParser(std::shared_ptr parser); + template class final_action { diff --git a/RedPandaIDE/widgets/classbrowser.cpp b/RedPandaIDE/widgets/classbrowser.cpp index 562690bc..2d6fe6b9 100644 --- a/RedPandaIDE/widgets/classbrowser.cpp +++ b/RedPandaIDE/widgets/classbrowser.cpp @@ -179,26 +179,12 @@ void ClassBrowserModel::fillStatements() } } -void ClassBrowserModel::calculateChildrenCounts(const QModelIndex &index) -{ - ClassBrowserNode *parentNode; - if (!index.isValid()) { // top level - parentNode = mRoot; - } else { - parentNode = static_cast(index.internalPointer()); - } - if (!parentNode->childrenFetched && parentNode->statement) { - parentNode->childrenFetched = true; - filterChildren(parentNode, parentNode->statement->children); - } -} - void ClassBrowserModel::addChild(ClassBrowserNode *node, PStatement statement) { PClassBrowserNode newNode = std::make_shared(); newNode->parent = node; newNode->statement = statement; - newNode->childrenInited = false; + newNode->childrenFetched = false; node->children.append(newNode.get()); mNodes.append(newNode); }