diff --git a/RedPandaIDE/RedPandaIDE_zh_CN.qm b/RedPandaIDE/RedPandaIDE_zh_CN.qm index 16c3f272..9eb9b421 100644 Binary files a/RedPandaIDE/RedPandaIDE_zh_CN.qm and b/RedPandaIDE/RedPandaIDE_zh_CN.qm differ diff --git a/RedPandaIDE/RedPandaIDE_zh_CN.ts b/RedPandaIDE/RedPandaIDE_zh_CN.ts index 2ff3b925..b231e253 100644 --- a/RedPandaIDE/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/RedPandaIDE_zh_CN.ts @@ -4,17 +4,17 @@ BacktraceModel - + Function 函数 - + Filename 文件名 - + Line @@ -22,17 +22,17 @@ BreakpointModel - + Filename 文件名 - + Line - + Condition 条件 @@ -491,27 +491,27 @@ Are you really want to continue? - + Execute to evaluate 执行以求值 - + Not found in current context 不在当前语境中 - + Compile 编译 - + Source file is more recent than executable. 源文件比程序文件新。 - + Recompile? 重新编译? @@ -534,11 +534,11 @@ Are you really want to continue? - - - - - + + + + + Error 错误 @@ -553,40 +553,40 @@ Are you really want to continue? 另存为 - + The text to be copied exceeds count limit! 要复制的内容超过了行数限制! - + The text to be copied exceeds character limit! 要复制的内容超过了字符数限制! - + The text to be cut exceeds count limit! 要剪切的内容超过了行数限制! - + The text to be cut exceeds character limit! 要剪切的内容超过了字符数限制! - - - + + + Ctrl+click for more info Ctrl+单击以获取更多信息 - - + + Symbol '%1' not found! 未找到符号'%1'! - + Readonly 只读 @@ -1337,7 +1337,7 @@ Are you really want to continue? - + Issues 编译器 @@ -1530,8 +1530,10 @@ Are you really want to continue? - - + + + + Compile 编译 @@ -1812,6 +1814,21 @@ Are you really want to continue? Shift+F3 Shift+F3 + + + Remove Watch + 删除监视 + + + + Remove All + 清除全部监视 + + + + Modify Watch... + 修改监视值 + File Encoding @@ -1823,20 +1840,20 @@ Are you really want to continue? 文件历史 - - + + Debugging 正在调试 - - + + Running 正在运行 - - + + Compiling 正在编译 @@ -1845,150 +1862,172 @@ Are you really want to continue? 行:%1 列:%2 已选择:%3 总行数:%4 总长度:%5 - + Line:%1 Col:%2 Selected:%3 Lines:%4 Length:%5 行:%1 列:%2 已选择:%3 总行数:%4 总长度:%5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 - - + + Confirm 确认 - - - + + + Source file is not compiled. 源文件尚未编译。 - - + + Compile now? 现在编译? - - + + Source file is more recent than executable. 源文件比可执行程序新。 - + Recompile now? 重新编译? - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 - + Enable debugging 启用调试参数 - + You have not enabled debugging info (-g3) and/or stripped it from the executable (-s) in Compiler Options.<BR /><BR />Do you want to correct this now? 当前编译设置中未启用调试选项(-g3),或启用了信息剥除选项(-s)<br /><br/>是否纠正这一问题? - + Recompile? 重新编译? - + %1 files autosaved 已自动保存%1个文件 - - - - - - + + + + + + + + Error 错误 - + + File '%1' was changed. + 磁盘文件'%1'已被修改。 + + + + Reload its content from disk? + 是否重新读取它的内容? + + + + File '%1' was removed. + 磁盘文件'%1'已被删除。 + + + + Keep it open? + 是否保持它在小熊猫C++中打开的编辑窗口? + + + Open 打开 - + Compile Failed 编译失败 - + Run Failed 运行失败 - - + + Confirm Convertion 确认转换 - - + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - - + + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -2004,12 +2043,12 @@ Are you really want to continue? QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -2584,17 +2623,17 @@ Are you really want to continue? RegisterModel - + Register 寄存器 - + Value(Hex) 值(HEX) - + Value(Dec) 值(DEC) @@ -3012,12 +3051,12 @@ Are you really want to continue? 调试器 - + Save Changes 保存修改 - + There are changes in the settings, do you want to save them before swtich to other page? 本页中有尚未保存的设置修改,是否保存后再切换到其他页? diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index fb55d627..1754fe4e 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -68,6 +68,8 @@ Editor::Editor(QWidget *parent, const QString& filename, mActiveBreakpointLine(-1), mLastIdCharPressed(0), mCurrentWord(), + mSelectionWord(), + mOldSelectionWord(), mCurrentTipType(TipType::None) { mUseCppSyntax = pSettings->editor().defaultFileCpp(); @@ -153,6 +155,12 @@ void Editor::loadFile() { default: mUseCppSyntax = pSettings->editor().defaultFileCpp(); } + if (highlighter() && mParser) { + reparse(); + if (pSettings->editor().syntaxCheck() && pSettings->editor().syntaxCheckWhenLineChanged()) { + pMainWindow->checkSyntaxInBack(this); + } + } } void Editor::saveFile(const QString &filename) { @@ -182,8 +190,10 @@ bool Editor::save(bool force, bool doReparse) { return false; } if (this->modified()|| force) { + pMainWindow->fileSystemWatcher()->removePath(mFilename); try { saveFile(mFilename); + pMainWindow->fileSystemWatcher()->addPath(mFilename); setModified(false); mIsNew = false; this->updateCaption(); @@ -192,6 +202,7 @@ bool Editor::save(bool force, bool doReparse) { QMessageBox::critical(pMainWindow,tr("Error"), exception.reason()); } + pMainWindow->fileSystemWatcher()->addPath(mFilename); return false; } } @@ -214,6 +225,9 @@ bool Editor::saveAs(){ if (newName.isEmpty()) { return false; } + pMainWindow->fileSystemWatcher()->removePath(mFilename); + if (pSettings->codeCompletion().enabled() && mParser) + mParser->invalidateFile(mFilename); try { mFilename = newName; saveFile(mFilename); @@ -225,6 +239,7 @@ bool Editor::saveAs(){ exception.reason()); return false; } + pMainWindow->fileSystemWatcher()->addPath(mFilename); switch(getFileType(mFilename)) { case FileType::CppSource: mUseCppSyntax = true; @@ -236,11 +251,22 @@ bool Editor::saveAs(){ mUseCppSyntax = pSettings->editor().defaultFileCpp(); } - //todo: update (reassign highlighter) - //todo: remove old file from parser and reparse file - //todo: unmoniter/ monitor file - //todo: update windows caption - //todo: update class browser; + + //update (reassign highlighter) + PSynHighlighter newHighlighter = HighlighterManager().getHighlighter(mFilename); + if (newHighlighter) { + setUseCodeFolding(true); + } else { + setUseCodeFolding(false); + } + setHighlighter(newHighlighter); + applyColorScheme(pSettings->editor().colorScheme()); + + reparse(); + + if (highlighter() && pSettings->editor().syntaxCheck() && pSettings->editor().syntaxCheckWhenLineChanged()) + pMainWindow->checkSyntaxInBack(this); + return true; } @@ -586,7 +612,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to || (attr->name() == SYNS_AttrReservedWord) || (attr->name() == SYNS_AttrPreprocessor) ) - && (token == selText())) { + && (token == mSelectionWord)) { foreground = selectedForeground(); background = selectedBackground(); return; @@ -629,7 +655,7 @@ bool Editor::event(QEvent *event) int line ; if (reason == TipType::Error) { pError = getSyntaxIssueAtPosition(p); - } else if ((reason == TipType::None) && PointToLine(helpEvent->pos(),line)) { + } else if (PointToLine(helpEvent->pos(),line)) { //it's on gutter //see if its error; PSyntaxIssueList issues = getSyntaxIssuesAtLine(line); @@ -671,7 +697,7 @@ bool Editor::event(QEvent *event) return true; } -// qDebug()<'') then s = s.trimmed(); @@ -994,7 +1020,7 @@ void Editor::onStatusChanged(SynStatusChanges changes) && (lines()->count()!=mLineCount) && (lines()->count()!=0) && ((mLineCount>0) || (lines()->count()>1))) { reparse(); - if (!readOnly() && pSettings->editor().syntaxCheck() && pSettings->editor().syntaxCheckWhenLineChanged()) + if (!readOnly() && highlighter() && pSettings->editor().syntaxCheck() && pSettings->editor().syntaxCheckWhenLineChanged()) pMainWindow->checkSyntaxInBack(this); } mLineCount = lines()->count(); @@ -1017,6 +1043,32 @@ void Editor::onStatusChanged(SynStatusChanges changes) // scSelection includes anything caret related if (changes.testFlag(SynStatusChange::scSelection)) { + mSelectionWord=""; + if (selAvail()) { + BufferCoord wordBegin,wordEnd,bb,be; + bb = blockBegin(); + be = blockEnd(); + wordBegin = WordStartEx(bb); + wordEnd = WordEndEx(be); + if (wordBegin.Line == bb.Line + && wordBegin.Char == bb.Char + && wordEnd.Line == be.Line + && wordEnd.Char == be.Char) { + if (wordBegin.Line>=1 && wordBegin.Line<=lines()->count()) { + QString line = lines()->getString(wordBegin.Line-1); + mSelectionWord = line.mid(wordBegin.Char-1,wordEnd.Char-wordBegin.Char); + } + } +// qDebug()<updateStatusbarForLineCol(); // // Update the function tip diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index 61d8864e..14e79fef 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -28,6 +28,9 @@ Editor* EditorList::newEditor(const QString& filename, const QByteArray& encodin parentPageControl = getNewEditorPageControl(); else parentPageControl = page; + if (!filename.isEmpty() && QFile(filename).exists()) { + pMainWindow->fileSystemWatcher()->addPath(filename); + } return new Editor(parentPageControl,filename,encoding,inProject,newFile,parentPageControl); //UpdateLayout; } @@ -90,6 +93,7 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) { pMainWindow->rebuildOpenedFileHisotryMenu(); } + pMainWindow->fileSystemWatcher()->removePath(editor->filename()); //editor->deleteLater(); delete editor; diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 71f16676..51e1ef79 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -122,6 +122,9 @@ MainWindow::MainWindow(QWidget *parent) //class browser ui->classBrowser->setModel(&mClassBrowserModel); + connect(&mFileSystemWatcher,&QFileSystemWatcher::fileChanged, + this, &MainWindow::onFileChanged); + mCompletionPopup = std::make_shared(); mHeaderCompletionPopup = std::make_shared(); @@ -277,6 +280,11 @@ void MainWindow::applySettings() updateDebuggerSettings(); } +QFileSystemWatcher *MainWindow::fileSystemWatcher() +{ + return &mFileSystemWatcher; +} + void MainWindow::removeActiveBreakpoints() { for (int i=0;ipageCount();i++) { @@ -506,10 +514,14 @@ void MainWindow::openFile(const QString &filename) editor->activate(); return; } - editor = mEditorList->newEditor(filename,ENCODING_AUTO_DETECT, - false,false); - editor->activate(); - this->updateForEncodingInfo(); + try { + editor = mEditorList->newEditor(filename,ENCODING_AUTO_DETECT, + false,false); + editor->activate(); + this->updateForEncodingInfo(); + } catch (FileError e) { + QMessageBox::critical(this,tr("Error"),e.reason()); + } } void MainWindow::setupActions() { @@ -1032,6 +1044,36 @@ void MainWindow::onAutoSaveTimeout() updateStatusbarMessage(tr("%1 files autosaved").arg(updateCount)); } +void MainWindow::onFileChanged(const QString &path) +{ + Editor *e = mEditorList->getOpenedEditorByFilename(path); + if (e) { + if (QFile(path).exists()) { + e->activate(); + if (QMessageBox::question(this,tr("Compile"), + tr("File '%1' was changed.").arg(path)+"

" + tr("Reload its content from disk?"), + QMessageBox::Yes|QMessageBox::No, + QMessageBox::No) == QMessageBox::Yes) { + try { + e->loadFile(); + } catch(FileError e) { + QMessageBox::critical(this,tr("Error"),e.reason()); + } + } + } else { + if (QMessageBox::question(this,tr("Compile"), + tr("File '%1' was removed.").arg(path)+"

" + tr("Keep it open?"), + QMessageBox::Yes|QMessageBox::No, + QMessageBox::Yes) == QMessageBox::No) { + mEditorList->closeEditor(e); + } else { + e->setModified(true); + e->updateCaption(); + } + } + } +} + const std::shared_ptr &MainWindow::headerCompletionPopup() const { return mHeaderCompletionPopup; diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 9a1e9e8a..2d45a206 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -1,6 +1,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include #include #include #include "common.h" @@ -68,6 +69,7 @@ public: void showSearchPanel(); void applySettings(); + QFileSystemWatcher* fileSystemWatcher(); void removeActiveBreakpoints(); void setActiveBreakpoint(QString FileName, int Line, bool setFocus=true); @@ -127,6 +129,7 @@ private: private slots: void onAutoSaveTimeout(); + void onFileChanged(const QString& path); void on_actionNew_triggered(); @@ -247,6 +250,7 @@ private: QList mRecentFileActions; bool mQuitting; QElapsedTimer mParserTimer; + QFileSystemWatcher mFileSystemWatcher; std::shared_ptr mCompletionPopup; std::shared_ptr mHeaderCompletionPopup; diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 601c17f4..0513151a 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -3379,7 +3379,7 @@ QString CppParser::splitPhrase(const QString &phrase, QString &sClazz, QString & firstOpEnd = i+2; sOperator = "::"; break; - } else if ((phrase[i] == '.') && (bracketLevel=0)) { + } else if ((phrase[i] == '.') && (bracketLevel==0)) { firstOpStart = i; firstOpEnd = i+1; sOperator = "."; @@ -3771,6 +3771,8 @@ void CppFileListParserThread::run() void parseFile(PCppParser parser, const QString& fileName, bool inProject, bool onlyIfNotParsed, bool updateView) { + if (!parser) + return; CppFileParserThread* thread = new CppFileParserThread(parser,fileName,inProject,onlyIfNotParsed,updateView); thread->connect(thread, &QThread::finished, @@ -3781,6 +3783,8 @@ void parseFile(PCppParser parser, const QString& fileName, bool inProject, bool void parseFileList(PCppParser parser, bool updateView) { + if (!parser) + return; CppFileListParserThread *thread = new CppFileListParserThread(parser,updateView); thread->connect(thread, &QThread::finished,