From 842daf38a580274812f7e9d306767788dfa4172e Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Fri, 3 Sep 2021 16:39:20 +0800 Subject: [PATCH] - feature done: find symbol occurencies - feature: open containing folder - feature: open terminal --- RedPandaIDE/RedPandaIDE.pro | 4 + RedPandaIDE/RedPandaIDE_zh_CN.qm | Bin 55333 -> 56768 bytes RedPandaIDE/RedPandaIDE_zh_CN.ts | 630 ++++++++++++++++------------ RedPandaIDE/cpprefacter.cpp | 121 ++++++ RedPandaIDE/cpprefacter.h | 27 ++ RedPandaIDE/editor.cpp | 76 ++-- RedPandaIDE/editor.h | 13 +- RedPandaIDE/mainwindow.cpp | 90 +++- RedPandaIDE/mainwindow.h | 7 + RedPandaIDE/mainwindow.ui | 27 +- RedPandaIDE/qsynedit/SynEdit.h | 4 +- RedPandaIDE/qsynedit/TextBuffer.cpp | 20 + RedPandaIDE/qsynedit/TextBuffer.h | 1 + 13 files changed, 704 insertions(+), 316 deletions(-) create mode 100644 RedPandaIDE/cpprefacter.cpp create mode 100644 RedPandaIDE/cpprefacter.h diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 03fb769c..2e7aa2f1 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -22,6 +22,7 @@ SOURCES += \ compiler/executablerunner.cpp \ compiler/filecompiler.cpp \ compiler/stdincompiler.cpp \ + cpprefacter.cpp \ parser/cppparser.cpp \ parser/cpppreprocessor.cpp \ parser/cpptokenizer.cpp \ @@ -94,6 +95,7 @@ HEADERS += \ compiler/executablerunner.h \ compiler/filecompiler.h \ compiler/stdincompiler.h \ + cpprefacter.h \ parser/cppparser.h \ parser/cpppreprocessor.h \ parser/cpptokenizer.h \ @@ -195,6 +197,8 @@ RESOURCES += \ icons.qrc \ translations.qrc +RC_ICONS = images/devcpp.ico + #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 diff --git a/RedPandaIDE/RedPandaIDE_zh_CN.qm b/RedPandaIDE/RedPandaIDE_zh_CN.qm index 7bd5b8b72680f6ab34ff760a75ca6134ea59b78e..eb769ff7326b9f875d1e08d1f0b569eb309c791f 100644 GIT binary patch delta 6619 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 diff --git a/RedPandaIDE/RedPandaIDE_zh_CN.ts b/RedPandaIDE/RedPandaIDE_zh_CN.ts index 72ce78f8..34c3bda3 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 条件 @@ -132,32 +132,32 @@ [说明] - + The compiler process failed to start. 无法启动编译进程。 - + The compiler process crashed after starting successfully. 编译进程启动后崩溃。 - + The last waitFor...() function timed out. waitFor()函数等待超时。 - + An error occurred when attempting to write to the compiler process. 在向编译进程输入内容时出错。 - + An error occurred when attempting to read from the compiler process. 在从编译进程读取内容时出错。 - + An unknown error occurred. 发生了未知错误。 @@ -236,12 +236,12 @@ - - - - - - + + + + + + ... ... @@ -251,12 +251,12 @@ 基本选项 - + Add the following arguments when calling the compiler 编译时加入下列选项: - + Add the following arguments when calling the linker 链接时加入下列选项 @@ -266,92 +266,97 @@ 编译时自动加入字符编码选项 - + + Statically link libraries + 静态链接所有库 + + + Settings 编译/链接选项 - + Directories 文件夹 - + Programs 程序 - + TextLabel 选项 - + Resource Compiler(windres) 资源编辑器(winres) - + C++ Compiler(g++) C++编译器(g++) - + Choose C++ Compiler 选择C++编译器 - + Choose C Compiler 选择C编译器 - + C Compiler(gcc) C编译器(gcc) - + Debugger(gdb) 调试器(gdb) - + Profiler(gprof) 性能分析器(gprof) - + make - + Choose make 选择make - + Choose Debugger 选择调试器 - + Choose Resource Compiler 选择资源编译器 - + Choose Profiler 选择性能分析器 - + Confirm 确认 - + Red Panda C++ will clear current compiler list and search for compilers in the following locations: '%1' '%2' @@ -362,35 +367,35 @@ Are you really want to continue? 你确定要继续吗? - - + + Failed 失败 - - + + Can't find any compiler. 找不到编译器 - - + + Compiler Set Name 编译器配置名称 - + Name 名称 - + Compiler Set Folder 编译器所在文件夹 - + New name 新名称 @@ -490,28 +495,28 @@ Are you really want to continue? 找不到调试器程序"%1" - - + + Execute to evaluate 执行以求值 - + Not found in current context 不在当前语境中 - + Compile 编译 - + Source file is more recent than executable. 源文件比程序文件新。 - + Recompile? 重新编译? @@ -523,7 +528,7 @@ Are you really want to continue? 无标题 - + untitled%1 无标题%1 @@ -532,61 +537,71 @@ Are you really want to continue? 失败 - - - - + + + - + + Error 错误 - + File %1 is not writable! 无法写入文件"%1" - + Save As 另存为 - + 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'! - + + Break point condition + 断点条件 + + + + Enter the condition of the breakpoint: + 输入当前断点的生效条件: + + + Readonly 只读 @@ -1879,22 +1894,22 @@ Are you really want to continue? IssuesModel - + Filename 文件名 - + Line - + Col - + Description 描述 @@ -1908,33 +1923,33 @@ Are you really want to continue? - + Issues 编译器 - + Compile Log 编译日志 - + File 文件 - + Tools 工具 - - + + Run 运行 - + Edit 编辑 @@ -1959,539 +1974,610 @@ Are you really want to continue? 文件 - + Resource 资源 - - - + + + Debug 调试 - + Evaluate: 求值 - + Debug Console 调试主控台 - + Call Stack 调用栈 - + Breakpoints 断点 - + Locals 本地变量 - - + + Search 查找 - + History: 历史: - + Search Again 重新查找 - + Replace with: 替换为: - + Replace 替换 - - + + Close 关闭 - + Execute - 执行 + 运行 - + Code 代码 - + Window 窗口 - - - - + + + + toolBar 工具栏 - + toolBar_2 工具栏2 - + New 新建 - + Ctrl+N Ctrl+N - + Open... 打开... - + Ctrl+O Ctrl+O - + Save 保存 - + Ctrl+S Ctrl+S - + Save As... 另存为... - + Save As 另存为 - + Save All 全部保存 - + Ctrl+Shift+S Ctrl+Shift+S - + Options 选项 - - - - - - + + + + + + Compile 编译 - + F9 F9 - + F10 F10 - + Undo 恢复 - + Ctrl+Z Ctrl+Z - + Redo 重做 - + Ctrl+Y Ctrl+Y - + Cut 剪切 - + Ctrl+X Ctrl+X - + Copy 复制 - + Ctrl+C Ctrl+C - + Paste 粘贴 - + Ctrl+V Ctrl+V - + Select All 选择全部 - + Ctrl+A Ctrl+A - + Indent 缩进 - + UnIndent 取消缩进 - + Toggle Comment 切换注释 - + Ctrl+/ Ctrl+/ - + Collapse All 全部收起 - + Uncollapse All 全部展开 - + Encode in ANSI 使用ANSI编码 - + Encode in UTF-8 使用UTF-8编码 - + Auto Detect 自动检测 - + Convert to ANSI 转换为ANSI编码 - + Convert to UTF-8 转换为UTF-8编码 - - + + Compile & Run 编译运行 - + F11 F11 - - + + Rebuild All 全部重编译 - + F12 F12 - + Stop Execution 停止执行 - + F6 F6 - + F5 F5 - + Step Over 单步跳过 - + F7 F7 - + Step Into 单步进入 - + F8 F8 - + Step Out 单步跳出 - + Ctrl+F8 Ctrl+F8 - + Run To Cursor 执行到光标处 - + Ctrl+F5 Ctrl+F5 - + Continue 继续执行 - + F4 F4 - + Add Watch... 添加监视 - + View CPU Window... 打开CPU信息窗口... - + Exit 退出 - + Find... 查找... - + Ctrl+F Ctrl+F - + Find in Files... 在文件中查找... - + Ctrl+Shift+F Ctrl+Shift+F - + Replace... 替换 - + Ctrl+R Ctrl+R - + Find Next 查找下一个 - + F3 F3 - + Find Previous 查找前一个 - + Shift+F3 Shift+F3 - + Remove Watch 删除监视 - + Remove All 清除全部监视 - + Modify Watch... 修改监视值 - + Reformat Code 对代码重新排版 - + Ctrl+Shift+A Ctrl+Shift+A - + Go back 前一次编辑位置 - + Ctrl+Alt+Left Ctrl+Alt+Left - + Forward 后一次编辑位置 - + Ctrl+Alt+Right Ctrl+Alt+Right - + Ctrl+W Ctrl+W - + Close All 全部关闭 - + Ctrl+Shift+W Ctrl+Shift+W - + Maximize Editor 最大化编辑器 - + Ctrl+F11 Ctrl+F11 - + + Next + 下一窗口 + + + + Ctrl+Tab + Ctrl+Tab + + + + Previous + 前一窗口 + + + + Ctrl+Shift+Tab + Ctrl+Shift+Tab + + + + Toggle breakpoint + 切换断点 + + + + Ctrl+F4 + Ctrl+F4 + + + + + Clear all breakpoints + 删除所有断点 + + + + Breakpoint property... + 设置断点条件... + + + + Goto Declaration + 跳转到声明处 + + + + Goto Definition + 跳转到定义处 + + + + Find references + 查找符号的引用 + + + + Open containing folder + 打开所在的文件夹 + + + + Ctrl+B + Ctrl+B + + + + Open a terminal here + 打开命令行窗口 + + + File Encoding 文件编码 - + Recent Files 文件历史 - - + + Debugging 正在调试 - - + + Running 正在运行 - - + + Compiling 正在编译 @@ -2500,172 +2586,177 @@ 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个文件 - - - - - - - - + + Do you really want to clear all breakpoints in this file? + 您真的要清除该文件的所有断点吗? + + + + + + + + + + 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个文件) @@ -2934,23 +3025,23 @@ Are you really want to continue? 只生成汇编代码(-S) - - + + Confirm 确认 - + The following problems were found during validation of compiler set "%1": 在验证编译器设置"%1"时遇到了下列问题: - + Compiler set not configuared. 未配置编译器设置。 - + Would you like Red Panda C++ to search for compilers in the following locations: <BR />'%1'<BR />'%2'? 您需要小熊猫C++在下列位置搜索编译器吗:<br />%1<br />%2 @@ -2986,7 +3077,7 @@ Are you really want to continue? - + untitled 无标题 @@ -3265,17 +3356,17 @@ Are you really want to continue? RegisterModel - + Register 寄存器 - + Value(Hex) 值(HEX) - + Value(Dec) 值(DEC) @@ -3420,25 +3511,30 @@ Are you really want to continue? SearchResultListModel - + Current File: 当前文件: - + Files In Project: 项目中的文件: - + Open Files: 打开的文件: + + + References to symbol '%1' at '%2':%3 + 符号'%1'出现在'%2':'%3' + SearchResultTreeModel - + Line @@ -3446,8 +3542,8 @@ Are you really want to continue? SearchResultTreeViewDelegate - - + + Line @@ -3764,12 +3860,12 @@ Are you really want to continue? SynEditStringList - + Can't open file '%1' for read! 无法读取文件'%1'! - + Can't open file '%1' for save! 无法写入文件'%2'! diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp new file mode 100644 index 00000000..e93a90cb --- /dev/null +++ b/RedPandaIDE/cpprefacter.cpp @@ -0,0 +1,121 @@ +#include "cpprefacter.h" +#include "mainwindow.h" +#include "settings.h" +#include "editor.h" +#include "editorlist.h" +#include +#include "HighlighterManager.h" + +CppRefacter::CppRefacter(QObject *parent) : QObject(parent) +{ + +} + +bool CppRefacter::findOccurence(Editor *editor, const BufferCoord &pos) +{ + if (!editor->parser()->freeze()) + return false; + auto action = finally([&editor]{ + editor->parser()->unFreeze(); + }); + // get full phrase (such as s.name instead of name) + BufferCoord pBeginPos,pEndPos; + QString phrase = getWordAtPosition(editor,pos,pBeginPos,pEndPos,Editor::WordPurpose::wpInformation); + // Find it's definition + PStatement statement = editor->parser()->findStatementOf( + editor->filename(), + phrase, + pos.Line); + // definition of the symbol not found + if (!statement) + return false; + + PSearchResults results = pMainWindow->searchResultModel()->addSearchResults( + phrase, + editor->filename(), + pos.Line + ); + + + PSearchResultTreeItem item = findOccurenceInFile( + editor->filename(), + statement, + editor->parser()); + if (item && !(item->results.isEmpty())) { + results->results.append(item); + } + pMainWindow->searchResultModel()->notifySearchResultsUpdated(); + return true; +} + +PSearchResultTreeItem CppRefacter::findOccurenceInFile( + const QString &filename, + const PStatement &statement, + const PCppParser& parser) +{ + PSearchResultTreeItem parentItem = std::make_shared(); + parentItem->filename = filename; + parentItem->parent = nullptr; + QStringList buffer; + SynEdit editor; + if (pMainWindow->editorList()->getContentFromOpenedEditor( + filename,buffer)){ + editor.lines()->setContents(buffer); + } else { + QByteArray encoding; + QFile file(filename); + editor.lines()->LoadFromFile(file,ENCODING_AUTO_DETECT,encoding); + } + editor.setHighlighter(HighlighterManager().getCppHighlighter()); + int posY = 0; + while (posY < editor.lines()->count()) { + QString line = editor.lines()->getString(posY); + if (line.isEmpty()) { + posY++; + continue; + } + + if (posY == 0) { + editor.highlighter()->resetState(); + } else { + editor.highlighter()->setState( + editor.lines()->ranges(posY-1), + editor.lines()->braceLevels(posY-1), + editor.lines()->bracketLevels(posY-1), + editor.lines()->parenthesisLevels(posY-1) + ); + } + editor.highlighter()->setLine(line,posY); + while (!editor.highlighter()->eol()) { + int start = editor.highlighter()->getTokenPos() + 1; + QString token = editor.highlighter()->getToken(); + if (token == statement->command) { + //same name symbol , test if the same statement; + BufferCoord p,pBeginPos,pEndPos; + p.Line = posY+1; + p.Char = start; + QString phrase = getWordAtPosition(&editor, p, pBeginPos,pEndPos, + Editor::WordPurpose::wpInformation); + PStatement tokenStatement = parser->findStatementOf( + filename, + phrase, p.Line); + if (tokenStatement + && (tokenStatement->line == statement->line) + && (tokenStatement->fileName == statement->fileName)) { + PSearchResultTreeItem item = std::make_shared(); + item->filename = filename; + item->line = p.Line; + item->start = start; + item->len = phrase.length(); + item->parent = parentItem.get(); + item->text = line; + item->text.replace('\t',' '); + parentItem->results.append(item); + } + } + editor.highlighter()->next(); + } + posY++; + } + return parentItem; +} diff --git a/RedPandaIDE/cpprefacter.h b/RedPandaIDE/cpprefacter.h new file mode 100644 index 00000000..81cba0ab --- /dev/null +++ b/RedPandaIDE/cpprefacter.h @@ -0,0 +1,27 @@ +#ifndef CPPREFACTER_H +#define CPPREFACTER_H + +#include +#include "parser/parserutils.h" +#include "widgets/searchresultview.h" +#include "parser/cppparser.h" + +class Editor; +class BufferCoord; +class CppRefacter : public QObject +{ + Q_OBJECT +public: + explicit CppRefacter(QObject *parent = nullptr); + + bool findOccurence(Editor * editor, const BufferCoord& pos); +signals: +private: + PSearchResultTreeItem findOccurenceInFile( + const QString& filename, + const PStatement& statement, + const PCppParser& parser); + +}; + +#endif // CPPREFACTER_H diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index e10eac36..d6c3ac8c 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -647,7 +647,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to if (mParser && mCompletionPopup && (attr->name() == SYNS_AttrIdentifier)) { BufferCoord p{aChar,line}; BufferCoord pBeginPos,pEndPos; - QString s= getWordAtPosition(p, pBeginPos,pEndPos, WordPurpose::wpInformation); + QString s= getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpInformation); // qDebug()<findStatementOf(mFilename, s , p.Line); @@ -702,11 +702,11 @@ bool Editor::event(QEvent *event) break; case TipType::Identifier: if (pMainWindow->debugger()->executing()) - s = getWordAtPosition(p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging + s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging else if (//devEditor.ParserHints and !mCompletionPopup->isVisible() && !mHeaderCompletionPopup->isVisible()) - s = getWordAtPosition(p, pBeginPos,pEndPos, WordPurpose::wpInformation); // information during coding + s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpInformation); // information during coding break; case TipType::Selection: s = selText(); // when a selection is available, always only use that @@ -1669,13 +1669,13 @@ void Editor::showCompletion(bool autoComplete) BufferCoord{caretX() - 1, caretY()}, s, tokenFinished,tokenType, attr)) { if (tokenType == SynHighlighterTokenType::PreprocessDirective) {//Preprocessor - word = getWordAtPosition(caretXY(),pBeginPos,pEndPos, WordPurpose::wpDirective); + word = getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpDirective); if (!word.startsWith('#')) { //showTabnineCompletion(); return; } } else if (tokenType == SynHighlighterTokenType::Comment) { //Comment, javadoc tag - word = getWordAtPosition(caretXY(),pBeginPos,pEndPos, WordPurpose::wpJavadoc); + word = getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpJavadoc); if (!word.startsWith('@')) { return; } @@ -1721,7 +1721,7 @@ void Editor::showCompletion(bool autoComplete) ); if (word.isEmpty()) - word=getWordAtPosition(caretXY(),pBeginPos,pEndPos, WordPurpose::wpCompletion); + word=getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpCompletion); //if not fCompletionBox.Visible then mCompletionPopup->prepareSearch(word, mFilename, pBeginPos.Line); @@ -1760,7 +1760,7 @@ void Editor::showHeaderCompletion(bool autoComplete) mHeaderCompletionPopup->setParser(mParser); BufferCoord pBeginPos,pEndPos; - QString word = getWordAtPosition(caretXY(),pBeginPos,pEndPos, + QString word = getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpHeaderCompletionStart); if (word.isEmpty()) return; @@ -1943,7 +1943,7 @@ bool Editor::onCompletionKeyPressed(QKeyEvent *event) ExecuteCommand( SynEditorCommand::ecDeleteLastChar, QChar(), nullptr); // Simulate backspace in editor - phrase = getWordAtPosition(caretXY(), + phrase = getWordAtPosition(this,caretXY(), pBeginPos,pEndPos, purpose); mLastIdCharPressed = phrase.length(); @@ -1967,7 +1967,7 @@ bool Editor::onCompletionKeyPressed(QKeyEvent *event) QChar ch = event->text().front(); if (isIdentChar(ch)) { setSelText(ch); - phrase = getWordAtPosition(caretXY(), + phrase = getWordAtPosition(this,caretXY(), pBeginPos,pEndPos, purpose); mLastIdCharPressed = phrase.length(); @@ -1994,7 +1994,7 @@ bool Editor::onHeaderCompletionKeyPressed(QKeyEvent *event) ExecuteCommand( SynEditorCommand::ecDeleteLastChar, QChar(), nullptr); // Simulate backspace in editor - phrase = getWordAtPosition(caretXY(), + phrase = getWordAtPosition(this,caretXY(), pBeginPos,pEndPos, WordPurpose::wpHeaderCompletion); mLastIdCharPressed = phrase.length(); @@ -2019,7 +2019,7 @@ bool Editor::onHeaderCompletionKeyPressed(QKeyEvent *event) QChar ch = event->text().front(); if (isIdentChar(ch)) { setSelText(ch); - phrase = getWordAtPosition(caretXY(), + phrase = getWordAtPosition(this,caretXY(), pBeginPos,pEndPos, WordPurpose::wpHeaderCompletion); mLastIdCharPressed = phrase.length(); @@ -2177,7 +2177,7 @@ void Editor::gotoDeclaration(const BufferCoord &pos) { // Exit early, don't bother creating a stream (which is slow) BufferCoord pBeginPos, pEndPos; - QString phrase = getWordAtPosition(pos,pBeginPos,pEndPos, WordPurpose::wpInformation); + QString phrase = getWordAtPosition(this,pos,pBeginPos,pEndPos, WordPurpose::wpInformation); if (phrase.isEmpty()) return; @@ -2207,7 +2207,7 @@ void Editor::gotoDefinition(const BufferCoord &pos) { // Exit early, don't bother creating a stream (which is slow) BufferCoord pBeginPos, pEndPos; - QString phrase = getWordAtPosition(pos,pBeginPos,pEndPos, WordPurpose::wpInformation); + QString phrase = getWordAtPosition(this,pos,pBeginPos,pEndPos, WordPurpose::wpInformation); if (phrase.isEmpty()) return; @@ -2228,31 +2228,31 @@ void Editor::gotoDefinition(const BufferCoord &pos) } } -QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, WordPurpose purpose) +QString getWordAtPosition(SynEdit *editor, const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, Editor::WordPurpose purpose) { QString result = ""; QString s; - if ((p.Line<1) || (p.Line>lines()->count())) { + if ((p.Line<1) || (p.Line>editor->lines()->count())) { pWordBegin = p; pWordEnd = p; return ""; } - s = lines()->getString(p.Line - 1); + s = editor->lines()->getString(p.Line - 1); int len = s.length(); int wordBegin = p.Char - 1 - 1; //BufferCoord::Char starts with 1 int wordEnd = p.Char - 1 - 1; // Copy forward until end of word - if (purpose == WordPurpose::wpEvaluation - || purpose == WordPurpose::wpInformation) { + if (purpose == Editor::WordPurpose::wpEvaluation + || purpose == Editor::WordPurpose::wpInformation) { while (wordEnd + 1 < len) { - if ((purpose == WordPurpose::wpEvaluation) + if ((purpose == Editor::WordPurpose::wpEvaluation) && (s[wordEnd + 1] == '[')) { if (!findComplement(s, '[', ']', wordEnd, 1)) break; - } else if (isIdentChar(s[wordEnd + 1])) { + } else if (editor->isIdentChar(s[wordEnd + 1])) { wordEnd++; } else break; @@ -2260,9 +2260,9 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, } // Copy backward until # - if (purpose == WordPurpose::wpDirective) { + if (purpose == Editor::WordPurpose::wpDirective) { while ((wordBegin >= 0) && (wordBegin < len)) { - if (isIdentChar(s[wordBegin])) + if (editor->isIdentChar(s[wordBegin])) wordBegin--; else if (s[wordBegin] == '#') { wordBegin--; @@ -2273,9 +2273,9 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, } // Copy backward until @ - if (purpose == WordPurpose::wpJavadoc) { + if (purpose == Editor::WordPurpose::wpJavadoc) { while ((wordBegin >= 0) && (wordBegin < len)) { - if (isIdentChar(s[wordBegin])) + if (editor->isIdentChar(s[wordBegin])) wordBegin--; else if (s[wordBegin] == '@') { wordBegin--; @@ -2286,9 +2286,9 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, } // Copy backward until begin of path - if (purpose == WordPurpose::wpHeaderCompletion) { + if (purpose == Editor::WordPurpose::wpHeaderCompletion) { while ((wordBegin >= 0) && (wordBegin < len)) { - if (isIdentChar(s[wordBegin])) + if (editor->isIdentChar(s[wordBegin])) wordBegin--; else if (s[wordBegin] == '/' || s[wordBegin] == '\\' @@ -2300,7 +2300,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, } } - if (purpose == WordPurpose::wpHeaderCompletionStart) { + if (purpose == Editor::WordPurpose::wpHeaderCompletionStart) { while ((wordBegin >= 0) && (wordBegin < len)) { if (s[wordBegin] == '"' || s[wordBegin] == '<') { @@ -2310,7 +2310,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, || s[wordBegin] == '\\' || s[wordBegin] == '.') { wordBegin--; - } else if (isIdentChar(s[wordBegin])) + } else if (editor->isIdentChar(s[wordBegin])) wordBegin--; else break; @@ -2319,16 +2319,16 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, // && ( wordBegin < len) // Copy backward until begin of word - if (purpose == WordPurpose::wpCompletion - || purpose == WordPurpose::wpEvaluation - || purpose == WordPurpose::wpInformation) { + if (purpose == Editor::WordPurpose::wpCompletion + || purpose == Editor::WordPurpose::wpEvaluation + || purpose == Editor::WordPurpose::wpInformation) { while ((wordBegin >= 0) && (wordBeginisIdentChar(s[wordBegin])) { wordBegin--; } else if (s[wordBegin] == '.' || s[wordBegin] == ':' @@ -2375,9 +2375,9 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, && ( result[0] == '.' || result[0] == '-') - && (purpose == WordPurpose::wpCompletion - || purpose == WordPurpose::wpEvaluation - || purpose == WordPurpose::wpInformation)) { + && (purpose == Editor::WordPurpose::wpCompletion + || purpose == Editor::WordPurpose::wpEvaluation + || purpose == Editor::WordPurpose::wpInformation)) { int i = wordBegin; int line=p.Line; while (line>=1) { @@ -2391,7 +2391,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, if (i<0) { line--; if (line>=1) { - s=lines()->getString(line-1); + s=editor->lines()->getString(line-1); i=s.length(); continue; } else @@ -2401,7 +2401,7 @@ QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord pDummy; highlightPos.Line = line; highlightPos.Char = i+1; - result = getWordAtPosition(highlightPos,pWordBegin,pDummy,purpose)+result; + result = getWordAtPosition(editor, highlightPos,pWordBegin,pDummy,purpose)+result; break; } } @@ -2527,7 +2527,7 @@ void Editor::checkSyntaxInBack() pMainWindow->checkSyntaxInBack(this); } -const PCppParser &Editor::parser() const +const PCppParser &Editor::parser() { return mParser; } diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index aec3da4f..a22dd5e8 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -137,17 +137,13 @@ public: void removeBreakpointFocus(); void modifyBreakpointProperty(int line); void setActiveBreakpointFocus(int Line, bool setFocus=true); - QString getWordAtPosition(const BufferCoord& p, - BufferCoord& pWordBegin, - BufferCoord& pWordEnd, - WordPurpose purpose); QString getPreviousWordAtPositionForSuggestion(const BufferCoord& p); void reformat(); void checkSyntaxInBack(); void gotoDeclaration(const BufferCoord& pos); void gotoDefinition(const BufferCoord& pos); - const PCppParser &parser() const; + const PCppParser &parser(); private slots: void onModificationChanged(bool status) ; @@ -260,4 +256,11 @@ protected: void mouseReleaseEvent(QMouseEvent *event) override; }; +QString getWordAtPosition(SynEdit* editor, + const BufferCoord& p, + BufferCoord& pWordBegin, + BufferCoord& pWordEnd, + Editor::WordPurpose purpose); + + #endif // EDITOR_H diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 757bb27e..1958dc8c 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1,3 +1,4 @@ +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "editorlist.h" @@ -11,6 +12,7 @@ #include #include +#include #include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include "cpprefacter.h" #include @@ -1102,6 +1105,39 @@ void MainWindow::maximizeEditor() } } +void MainWindow::openShell(const QString &folder, const QString &shellCommand) +{ + QProcess process; + process.setWorkingDirectory(folder); + process.setProgram(shellCommand); + process.setCreateProcessArgumentsModifier([](QProcess::CreateProcessArguments * args){ + args->flags |= CREATE_NEW_CONSOLE; + args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES; // + }); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString path = env.value("PATH"); + + if (pSettings->compilerSets().defaultSet()) { + foreach(const QString& dir, pSettings->compilerSets().defaultSet()->binDirs()) { +#ifdef Q_OS_WIN + path+=";"; +#else + path+=":"; +#endif + path+=dir; + } + } +#ifdef Q_OS_WIN + path+=";"; +#else + path+=":"; +#endif + path+=pSettings->dirs().app(); + env.insert("PATH",path); + process.setProcessEnvironment(env); + process.startDetached(); +} + void MainWindow::onAutoSaveTimeout() { if (!pSettings->editor().enableAutoSave()) @@ -1154,6 +1190,15 @@ void MainWindow::onEditorContextMenu(const QPoint &pos) menu.addAction(ui->actionGoto_Declaration); menu.addAction(ui->actionGoto_Definition); menu.addAction(ui->actionFind_references); + + menu.addSeparator(); + menu.addAction(ui->actionOpen_Containing_Folder); + menu.addAction(ui->actionOpen_Terminal); + + //these actions needs parser + ui->actionGoto_Declaration->setEnabled(!editor->parser()->parsing()); + ui->actionGoto_Definition->setEnabled(!editor->parser()->parsing()); + ui->actionFind_references->setEnabled(!editor->parser()->parsing()); } else { //mouse on gutter int line; @@ -1996,8 +2041,13 @@ void MainWindow::on_actionFind_Previous_triggered() void MainWindow::on_cbSearchHistory_currentIndexChanged(int index) { - ui->btnSearchAgin->setEnabled(!ui->cbSearchHistory->currentText().isEmpty()); mSearchResultModel.setCurrentIndex(index); + PSearchResults results = mSearchResultModel.results(index); + if (results && results->searchType == SearchType::Search) { + ui->btnSearchAgin->setEnabled(true); + } else { + ui->btnSearchAgin->setEnabled(false); + } } void MainWindow::on_btnSearchAgin_clicked() @@ -2206,3 +2256,41 @@ void MainWindow::on_actionGoto_Definition_triggered() } } + +void MainWindow::on_actionFind_references_triggered() +{ + Editor * editor = mEditorList->getEditor(); + BufferCoord pos; + if (editor && editor->PointToCharLine(mContextMenuPos,pos)) { + CppRefacter refactor; + refactor.findOccurence(editor,pos); + ui->tabMessages->setCurrentWidget(ui->tabSearch); + openCloseBottomPanel(true); + } +} + + +void MainWindow::on_actionOpen_Containing_Folder_triggered() +{ + Editor* editor = mEditorList->getEditor(); + if (editor) { + QFileInfo info(editor->filename()); + if (!info.path().isEmpty()) { + QDesktopServices::openUrl(info.path()); + } + } +} + + +void MainWindow::on_actionOpen_Terminal_triggered() +{ + Editor* editor = mEditorList->getEditor(); + if (editor) { + QFileInfo info(editor->filename()); + if (!info.path().isEmpty()) { + openShell(info.path(),"cmd.exe"); + } + } + +} + diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 40ca89de..7661f0af 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -132,6 +132,7 @@ private: void doAutoSave(Editor *e); void buildContextMenus(); void maximizeEditor(); + void openShell(const QString& folder, const QString& shellCommand); private slots: void onAutoSaveTimeout(); @@ -274,6 +275,12 @@ private slots: void on_actionGoto_Definition_triggered(); + void on_actionFind_references_triggered(); + + void on_actionOpen_Containing_Folder_triggered(); + + void on_actionOpen_Terminal_triggered(); + private: Ui::MainWindow *ui; EditorList *mEditorList; diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 853fb0b8..10005b9e 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -255,7 +255,7 @@ QTabWidget::South - 0 + 3 @@ -467,7 +467,7 @@ QTabWidget::North - 0 + 1 @@ -1552,6 +1552,29 @@ Find references + + + + :/icons/images/newlook24/090-explorer.png + + + + Open containing folder + + + Ctrl+B + + + + + + :/icons/images/newlook24/030-dos.png + + + + Open a terminal here + + diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index 95922afa..e08689b6 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -254,6 +254,7 @@ public: bool GetLineOfMouse(int& line); bool PointToCharLine(const QPoint& point, BufferCoord& coord); bool PointToLine(const QPoint& point, int& line); + bool isIdentChar(const QChar& ch); // setter && getters @@ -369,9 +370,6 @@ signals: void fontChanged(); void tabSizeChanged(); -protected: - bool isIdentChar(const QChar& ch); - protected: virtual bool onGetSpecialLineColors(int Line, QColor& foreground, QColor& backgroundColor) ; diff --git a/RedPandaIDE/qsynedit/TextBuffer.cpp b/RedPandaIDE/qsynedit/TextBuffer.cpp index d3bb9c7f..908b8ea1 100644 --- a/RedPandaIDE/qsynedit/TextBuffer.cpp +++ b/RedPandaIDE/qsynedit/TextBuffer.cpp @@ -217,6 +217,24 @@ void SynEditStringList::setText(const QString &text) PutTextStr(text); } +void SynEditStringList::setContents(const QStringList &text) +{ + beginUpdate(); + auto action = finally([this]{ + endUpdate(); + }); + clear(); + if (text.count() > 0) { + mIndexOfLongestLine = -1; + int FirstAdded = mList.count(); + + foreach (const QString& s,text) { + addItem(s); + } + emit inserted(FirstAdded,text.count()); + } +} + QStringList SynEditStringList::contents() { QStringList Result; @@ -288,8 +306,10 @@ void SynEditStringList::clear() { if (!mList.isEmpty()) { beginUpdate(); + int oldCount = mList.count(); mIndexOfLongestLine = -1; mList.clear(); + emit deleted(0,oldCount); endUpdate(); } } diff --git a/RedPandaIDE/qsynedit/TextBuffer.h b/RedPandaIDE/qsynedit/TextBuffer.h index 627c3e5e..46410b91 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); + void setContents(const QStringList& text); QStringList contents(); void putString(int Index, const QString& s);