From d3fde7ab53935fe60b9fe09731dbc635fa49c1fa Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 28 Feb 2023 16:17:56 +0800 Subject: [PATCH] =?UTF-8?q?-=20change:=20Merge=20search=20and=20replace=20?= =?UTF-8?q?to=20one=20dialog.=20=20=20-=20fix:=20Search=20dialog's=20"Matc?= =?UTF-8?q?h=20whole=20word"=20option=20doesn't=20work=20with=20"Use=20Reg?= =?UTF-8?q?ular=20expresion".=20=20=20-=20fix=EF=BC=9ASearch=20dialog's=20?= =?UTF-8?q?"Close=20after=20search"=20option=20doesn't=20work.=20=20=20-?= =?UTF-8?q?=20change:=20Fill=20the=20search=20dialog=20with=20the=20curren?= =?UTF-8?q?t=20selection=20if=20it's=20available.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NEWS.md | 4 + RedPandaIDE/RedPandaIDE.pro | 7 +- RedPandaIDE/editor.cpp | 4 +- RedPandaIDE/mainwindow.cpp | 29 +- RedPandaIDE/mainwindow.h | 3 - RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 66 +- RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 815 +++++++++--------- RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 111 +-- RedPandaIDE/utils.cpp | 2 +- RedPandaIDE/widgets/searchdialog.cpp | 184 +++- RedPandaIDE/widgets/searchdialog.h | 16 +- RedPandaIDE/widgets/searchdialog.ui | 593 +++++++------ .../qsynedit/searcher/baseseacher.cpp | 5 + libs/qsynedit/qsynedit/searcher/baseseacher.h | 2 + .../qsynedit/searcher/basicsearcher.cpp | 4 - .../qsynedit/searcher/basicsearcher.h | 2 - .../qsynedit/searcher/regexsearcher.cpp | 16 +- 17 files changed, 983 insertions(+), 880 deletions(-) diff --git a/NEWS.md b/NEWS.md index 59bb0b3e..87342c52 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,10 @@ Red Panda C++ Version 2.15 - enhancement: Generate asm with/without SEH directives. - enhancement: Generate asm using intel style/att style. - enhancement: make description for jump/cmov/setb instructions more explicit. (used for signed or unsigned) + - fix: Lead and end spaces in search/replace text is wrongly trimmed. + - change: Merge search and replace to one dialog. + - fix: Search dialog's "Match whole word" option doesn't work with "Use Regular expresion". + - fix:Search dialog's "Close after search" option doesn't work. Red Panda C++ Version 2.14 diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 7b8574fb..11212ee6 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -1,6 +1,4 @@ -QT += core gui printsupport network svg xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +QT += core gui printsupport network svg xml widgets CONFIG += c++17 CONFIG += nokey @@ -213,7 +211,6 @@ SOURCES += \ widgets/projectalreadyopendialog.cpp \ widgets/qconsole.cpp \ widgets/qpatchedcombobox.cpp \ - widgets/replacedialog.cpp \ widgets/searchdialog.cpp \ widgets/searchinfiledialog.cpp \ widgets/searchresultview.cpp \ @@ -349,7 +346,6 @@ HEADERS += \ widgets/projectalreadyopendialog.h \ widgets/qconsole.h \ widgets/qpatchedcombobox.h \ - widgets/replacedialog.h \ widgets/searchdialog.h \ widgets/searchinfiledialog.h \ widgets/searchresultview.h \ @@ -417,7 +413,6 @@ FORMS += \ widgets/newtemplatedialog.ui \ widgets/ojproblempropertywidget.ui \ widgets/projectalreadyopendialog.ui \ - widgets/replacedialog.ui \ widgets/searchdialog.ui \ widgets/searchinfiledialog.ui \ widgets/signalmessagedialog.ui diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 6a3be7ee..de4e5a86 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1902,10 +1902,10 @@ void Editor::onTooltipTimer() } break; case TipType::Identifier: - if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning()) + if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning()) { if (mParentPageControl) s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging - else if (!mCompletionPopup->isVisible() + } else if (!mCompletionPopup->isVisible() && !mHeaderCompletionPopup->isVisible()) { expression = getExpressionAtPosition(p); s = expression.join(""); // information during coding diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 66c7b08b..6993228d 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -114,7 +114,6 @@ MainWindow::MainWindow(QWidget *parent) mFullInitialized{false}, mSearchInFilesDialog{nullptr}, mSearchDialog{nullptr}, - mReplaceDialog{nullptr}, mQuitting{false}, mClosingProject{false}, mCheckSyntaxInBack{false}, @@ -1070,8 +1069,6 @@ int MainWindow::calIconSize(const QString &fontName, int fontPointSize) void MainWindow::hideAllSearchDialogs() { - if (mReplaceDialog) - mReplaceDialog->hide(); if (mSearchDialog) mSearchDialog->hide(); if (mSearchInFilesDialog) @@ -1084,12 +1081,6 @@ void MainWindow::prepareSearchDialog() mSearchDialog = new SearchDialog(this); } -void MainWindow::prepareReplaceDialog() -{ - if (!mReplaceDialog) - mReplaceDialog = new ReplaceDialog(this); -} - void MainWindow::prepareSearchInFilesDialog() { if (mSearchInFilesDialog==nullptr) { @@ -6296,10 +6287,12 @@ void MainWindow::on_actionFind_triggered() Editor *e = mEditorList->getEditor(); if (!e) return; - QString s = e->wordAtCursor(); hideAllSearchDialogs(); prepareSearchDialog(); - mSearchDialog->find(s); + if (e->selAvail()) + mSearchDialog->find(e->selText()); + else + mSearchDialog->find(e->wordAtCursor()); } void MainWindow::on_actionFind_in_files_triggered() @@ -6308,8 +6301,10 @@ void MainWindow::on_actionFind_in_files_triggered() prepareSearchInFilesDialog(); Editor *e = mEditorList->getEditor(); if (e) { - QString s = e->wordAtCursor(); - mSearchInFilesDialog->findInFiles(s); + if (e->selAvail()) + mSearchInFilesDialog->findInFiles(e->selText()); + else + mSearchInFilesDialog->findInFiles(e->wordAtCursor()); } else { mSearchInFilesDialog->findInFiles(""); } @@ -6321,10 +6316,12 @@ void MainWindow::on_actionReplace_triggered() if (!e) return; - QString s = e->wordAtCursor(); hideAllSearchDialogs(); - prepareReplaceDialog(); - mReplaceDialog->replace(s); + prepareSearchDialog(); + if (e->selAvail()) + mSearchDialog->replace(e->selText()); + else + mSearchDialog->replace(e->wordAtCursor()); } void MainWindow::on_actionFind_Next_triggered() diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 6a088e09..1c0aa813 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -67,7 +67,6 @@ class CPUDialog; class QPlainTextEdit; class SearchInFileDialog; class SearchDialog; -class ReplaceDialog; class Project; struct ProjectModelNode; class ProjectUnit; @@ -276,7 +275,6 @@ private: int calIconSize(const QString &fontName, int fontPointSize); void hideAllSearchDialogs(); void prepareSearchDialog(); - void prepareReplaceDialog(); void prepareSearchInFilesDialog(); void prepareProjectForCompile(); void closeProject(bool refreshEditor); @@ -818,7 +816,6 @@ private: CPUDialog *mCPUDialog; SearchInFileDialog *mSearchInFilesDialog; SearchDialog *mSearchDialog; - ReplaceDialog *mReplaceDialog; bool mQuitting; bool mClosingProject; QElapsedTimer mParserTimer; diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index 400a6967..5a656971 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -6754,55 +6754,55 @@ ReplaceDialog Replace - Substituir + Substituir Text to Find: - Texto a procurar: + Texto a procurar: Replace with: - Substituir por: + Substituir por: Scope: - Escopo: + Escopo: Global - Global + Global Selection - Seleção + Seleção Origin: - Origem: + Origem: From cursor - A partir do cursor + A partir do cursor Entire scope - Escopo inteiro + Escopo inteiro Options: - Opções: + Opções: Whole words only - Apenas palavras inteiras + Apenas palavras inteiras Wrap Around - Wrap Around + Wrap Around Regular Expression - Expressão regular + Expressão regular Prompt on replace @@ -6810,43 +6810,27 @@ Case Sensitive - Sensibilidade a maiúsculas/minúsculas + Sensibilidade a maiúsculas/minúsculas Find Previous - Procurar anterior + Procurar anterior Find Next - Procurar outro - - - Replace All - - - - Close - - - - Beginning of file has been reached. - - - - Do you want to continue from file's end? - + Procurar outro End of file has been reached. - Encontrado fim de arquivo. + Encontrado fim de arquivo. Do you want to continue from file's beginning? - Quer continuar a partir do início do arquivo? + Quer continuar a partir do início do arquivo? Continue Search - Continuar a procura + Continuar a procura @@ -6861,7 +6845,7 @@ Replace with: - Substituir por: + Substituir por: Options: @@ -6949,7 +6933,7 @@ Replace - Substituir + Substituir Find in files @@ -7003,6 +6987,14 @@ Do you want to continue from file's end? + + Replace All + + + + Search + Procurar + SearchInFileDialog diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index 5bc0e225..c58d7b41 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -1488,9 +1488,9 @@ Are you really want to continue? 打印文档 - - - + + + Ctrl+click for more info Ctrl+单击以获取更多信息 @@ -1499,27 +1499,27 @@ Are you really want to continue? 未找到符号'%1'! - + astyle not found 找不到astyle程序 - + Can't find astyle in "%1". 找不到astyle程序"%1". - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Readonly 只读 @@ -4233,18 +4233,18 @@ Are you really want to continue? MainWindow - + Red Panda C++ 小熊猫C++ - - - - - + + + + + Issues 编译器 @@ -4318,7 +4318,7 @@ Are you really want to continue? - + Debug Console 调试主控台 @@ -4394,7 +4394,7 @@ Are you really want to continue? 工具栏2 - + New 新建 @@ -4528,9 +4528,9 @@ Are you really want to continue? - - - + + + Copy 复制 @@ -4541,7 +4541,7 @@ Are you really want to continue? - + Paste 粘贴 @@ -4552,8 +4552,8 @@ Are you really want to continue? - - + + Select All 选择全部 @@ -4676,38 +4676,38 @@ Are you really want to continue? - - + + New Problem Set 新建试题集 - + Add Problem 添加试题 - + Remove Problem 删除试题 - - + + Save Problem Set 保存试题集 - - + + Load Problem Set 载入试题集 @@ -4755,7 +4755,7 @@ Are you really want to continue? - + Remove Problem Case Remove Problem Set 删除试题集 @@ -4763,21 +4763,21 @@ Are you really want to continue? - + Open Anwser Source File 打开答案源代码文件 - + Run All Cases Run Current Case 运行所有案例 - + Problem Cases Validation Options 测试案例验证选项 @@ -4837,15 +4837,15 @@ Are you really want to continue? - - + + Import FPS Problem Set 导入FPS试题集 - - + + Export FPS Problem Set 导出FPS试题集 @@ -5092,7 +5092,7 @@ Are you really want to continue? - + Clear all breakpoints 删除所有断点 @@ -5332,7 +5332,7 @@ Are you really want to continue? 保存为模板... - + New File 新建文件 @@ -5373,7 +5373,7 @@ Are you really want to continue? - + Rename Symbol 重命名符号 @@ -5394,13 +5394,13 @@ Are you really want to continue? - + Export As RTF 导出为RTF - + Export As HTML 导出为HTML @@ -5669,42 +5669,42 @@ Are you really want to continue? 运行参数... - + File Encoding 文件编码 - + Recent Files 文件历史 - - - - - - + + + + + + Debugging 正在调试 - - - - - - + + + + + + Running 正在运行 - - - - - - + + + + + + Compiling 正在编译 @@ -5718,17 +5718,17 @@ Are you really want to continue? 行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 @@ -5745,7 +5745,7 @@ Are you really want to continue? 确认 - + Source file is not compiled. 源文件尚未编译。 @@ -5762,44 +5762,44 @@ Are you really want to continue? 重新编译? - - - - + + + + Wrong Compiler Settings 错误的编译器设置 - - - - + + + + Compiler is set not to generate executable. 编译器被设置为不生成可执行文件。 - - + + We need the executabe to run problem case. 我们需要可执行文件来运行试题案例。 - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 - + Enable debugging 启用调试参数 @@ -5816,33 +5816,33 @@ Are you really want to continue? 项目尚未构建。是否构建? - + Host applcation missing 宿主程序不存在 - + DLL project needs a host application to run. 动态链接库(DLL)需要一个宿主程序来运行。 - + But it's missing. 但它不存在。 - + Host application not exists 宿主程序不存在 - + Host application file '%1' doesn't exist. 宿主程序'%1'不存在。 - - + + Please correct this before start debugging 请在调试前改正设置。 @@ -5851,8 +5851,8 @@ Are you really want to continue? 重新编译? - - + + Save last open info error 保存上次打开信息失败 @@ -5861,60 +5861,60 @@ Are you really want to continue? 无法删除旧上次打开信息文件'%1' - + Can't save last open info file '%1' 无法保存上次打开信息文件'%1' - - + + Load last open info error 载入上次打开信息失败 - - + + Can't load last open info file '%1' 无法载入上次打开信息文件'%1' - + Open Source File 打开源代码文件 - - + + Batch Set Cases 批量设置案例 - + Show detail debug logs 显示详细调试器日志 - + Copy all 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? @@ -5922,25 +5922,25 @@ Are you really want to continue? - - - + + + Clear 清除 - + Export 导出 - + Insert Snippet 插入代码段 - - + + Problem Set %1 试题集%1 @@ -5969,56 +5969,56 @@ Are you really want to continue? 项目已经被修改过,是否需要重新构建? - + Auto Save Error 自动保存出错 - + Auto save "%1" to "%2" failed:%3 自动保存"%1"到"%2"失败:%3 - + Properties... 试题属性... - + Set Problem Set Name 设置试题集名称 - + Problem Set Name: 试题集名称: - + Remove 删除 - + Remove All Bookmarks 删除全部书签 - + Modify Description 修改描述 - - - + + + Bookmark Description 书签描述 - - - + + + Description: 描述: @@ -6027,65 +6027,65 @@ Are you really want to continue? 在调试主控台中显示调试器输出 - + Remove this search 清除这次搜索 - + Clear all searches 删除所有搜索 - + Breakpoint condition... 断点条件... - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Remove All Breakpoints Remove all breakpoints 删除所有断点 - + Remove Breakpoint 删除当前断点 - + Rename File 重命名文件 - - + + Add Folder 添加文件夹 - - + + New folder 新文件夹 - + Folder name: 文件夹: - + Rename Folder 重命名 @@ -6098,207 +6098,207 @@ Are you really want to continue? 要现在去修改设置吗? - + Rename Problem Set 修改试题集名称 - + Can't open last open information file '%1' for write! 无法写入配置文件'%1'。 - + Rename Problem 修改试题名称 - + Line: %1 Col: %2 Lines: %3 行: %1 列: %2 总行数: %3 - + Correct compiler setting 改正编译器设置 - - + + You are using a Debug compiler set with wrong compile/link settings: 您使用的Debug编译器配置集中存在错误的“编译/链接”选项设置: - - + + - "Generate debug info (-g3)" should be turned on - 应勾选"生成调试信息(-g3)"选项 - + - "Strip executable (-s)" should be turned off - 应取消"剥除附加信息(-s)"选项 - - + + Do you want to correct it now? 是否现在去改正? - - + + Can't Debug 无法调试 - - + + Your compiler set's "Strip executable (-s)" options is turnned on 您的编译器配置集中的“剥除附加信息(-s)”选项被勾选了。 - - + + Please correct it, recompile and retry debug. 请取消该设置,重新编译然后重新启动调试。 - + Goto Url 跳转到试题网址 - + Add Problem Case 添加试题案例 - + Run Current Case 运行当前案例 - + Remove Folder 删除文件夹 - + Switch to normal view 切换为普通视图 - + Switch to custom view 切换为自定义视图 - + Sort By Type 按类型排序 - + Sort alphabetically 按名称排序 - + Show inherited members 显示继承的成员 - + Goto declaration 跳转到声明处 - + Goto definition 跳转到定义处 - + In current file 仅当前文件 - + In current project 整个项目 - - + + New Folder 新建文件夹 - + Rename 重命名 - - - - + + + + Delete 删除 - + Open in Editor 在编辑器中打开 - + Open in External Program 使用外部程序打开 - + Open in Terminal 在终端中打开 - + Open in Windows Explorer 在Windows浏览器中打开 - + Character sets 字符集 - + Convert to %1 转换为%1编码 - + Newline 换行符 - + %1 files autosaved 已自动保存%1个文件 - + Set answer to... 设置答案源代码... - + select other file... 选择其他文件... - + Select Answer Source File 选择答案源代码文件 @@ -6307,17 +6307,17 @@ Are you really want to continue? 中止 - + FPS Problem Set Files (*.fps;*.xml) FPS试题集文件(*.fps;*.xml) - + FPS Problem Set Files (*.fps) FPS试题集文件(*.fps) - + Export Error 导出时出错 @@ -6327,7 +6327,7 @@ Are you really want to continue? C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + New Folder %1 新建文件夹%1 @@ -6340,70 +6340,70 @@ Are you really want to continue? 无标题%1 - + Do you really want to delete %1? 你真的要删除%1吗? - + Do you really want to delete %1 files? 你真的要删除%1个文件吗? - + Save project 保存项目 - + The project '%1' has modifications. 项目'%1'有改动。 - - + + Do you want to save it? 需要保存吗? - - + + File Changed 文件已发生变化 - - + + New Project File? 新建项目文件? - - + + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? - - - - + + + + Save Error 保存失败 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - - + + Do you really want to do that? 你真的想要那么做吗? @@ -6412,12 +6412,12 @@ Are you really want to continue? 批量设置案例 - + Choose input files 选择输入数据文件 - + Input data files (*.in) 输入数据文件 (*.in) @@ -6426,78 +6426,78 @@ Are you really want to continue? 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? @@ -6506,28 +6506,28 @@ Are you really want to continue? 正在删除试题... - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -6539,59 +6539,59 @@ Are you really want to continue? - + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -6600,22 +6600,22 @@ Are you really want to continue? 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? @@ -6624,27 +6624,27 @@ Are you really want to continue? 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 @@ -6661,27 +6661,27 @@ Are you really want to continue? 请在工具栏中选择Debug编译器配置集,或者在“编译器配置集”设置的“编译/链接选项”页中<b>启用</b>“生成调试信息(-g3)”、<b>禁用</b>“剥除附件信息(-3)”。 - + C/C++ Source Files (*.c *.cpp *.cc *.cxx) C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + This operation will remove all cases for the current problem. 本操作会删除此试题的所有案例。 - + Debug Failed 调试失败 - + The executable doesn't have symbol table, and can't be debugged. 可执行文件中没有符号表信息,无法调试。 - + Please turn off your compiler set's "Strip executable (-s)" option, recompile and retry debug. 请在选项对话框的编译器配置集页中取消“剥除附加信息(-s)”选项,重新编译后再调试。 @@ -6702,134 +6702,134 @@ Are you really want to continue? 您也可以删除所有断点,打开“CPU信息窗口”,然后调试汇编代码。 - + Failed to generate the executable. 未能生成可执行文件。 - + Please check detail info in "Tools Output" panel. 请查看“工具输出”面板中的详细信息。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - - - + + + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - - + + Load Error 载入失败 - - + + Problem Case %1 试题案例%1 - - - - - - - - - - - - - - + + + + + + + + + + + + + + Error 错误 - + Recent Projects 项目历史 - + Load Theme Error 载入主题失败 - - + + Clear History 清除历史 - - + + The generated executable doesn't have symbol table, and can't be debugged. 编译生成的可执行文件中没有符号表,无法被调试。 - - + + Version Control 版本控制 @@ -6838,80 +6838,80 @@ Are you really want to continue? 请在工具栏中选用Debug编译器配置集,或者在选项对话框的编辑器配置集页中勾选“生成调试信息(-g3)"选项。 - + 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个文件) @@ -8196,13 +8196,13 @@ Are you really want to continue? QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -9263,127 +9263,100 @@ Are you really want to continue? ReplaceDialog - - Replace - 替换 + 替换 - Text to Find: - 查找字符串: + 查找字符串: - Replace with: - 替换为: + 替换为: - Scope: - 范围: + 范围: - Global - 全局 + 全局 - Selection - 选中内容 + 选中内容 - Origin: - 起点: + 起点: - From cursor - 从光标处 + 从光标处 - Entire scope - 整个范围 + 整个范围 - Options: - 选项: + 选项: - Whole words only - 整个单词 + 整个单词 - Wrap Around - 循环查找 + 循环查找 - Regular Expression - 正则表达式 + 正则表达式 Prompt on replace 替换时提示 - Case Sensitive - 区分大小写 + 区分大小写 - Find Previous - 查找前一个 + 查找前一个 - Find Next - 查找下一个 + 查找下一个 - Replace All - 全部替换 + 全部替换 - Close - 关闭 + 关闭 - Beginning of file has been reached. - 已到达文件开头。 + 已到达文件开头。 - Do you want to continue from file's end? - 是否需要从文件末尾开始继续查找? + 是否需要从文件末尾开始继续查找? - - End of file has been reached. - 已到达文件结尾。 + 已到达文件结尾。 - - Do you want to continue from file's beginning? - 是否从文件开头继续? + 是否从文件开头继续? - - Continue Search - 继续查找 + 继续查找 @@ -9393,36 +9366,37 @@ Are you really want to continue? 对话框 - + Text to Find: 要查找的关键字 + Replace with: - 替换为: + 替换为: - + Options: 选项: - + Case Sensitive 区分大小写 - + Whole words only 整个单词 - + Wrap Around 循环查找 - + Regular Expression 正则表达式 @@ -9431,52 +9405,57 @@ Are you really want to continue? 替换时提示 - + Scope: 范围: - + Global 全局 - + Selection 选中文字 - + Origin: 起点: - + From cursor 从光标处 - + Entire scope 整个范围 - + Close after search 找到后关闭对话框 - + Find Previous 查找前一个 - + Find Next 查找下一个 - + + Replace All + 全部替换 + + + Close 关闭 @@ -9522,37 +9501,47 @@ Are you really want to continue? 在文件中查找 + + Replace - 替换 + 替换 Replace in files 在文件中替换 - + + Continue Search Search Around 继续查找 - + + End of file has been reached. End of file has been reached. 已到达文件结尾。 - + + Search + 查找 + + + Beginning of file has been reached. 已到达文件开头 - + Do you want to continue from file's end? 是否从文件结尾继续? - + + Do you want to continue from file's beginning? Do you want to start from beginning? 是否从文件开头继续? @@ -9919,18 +9908,18 @@ Are you really want to continue? 性能 - - - + + + Compiler Set 编译器配置集 - - - + + + Compiler @@ -9942,7 +9931,7 @@ Are you really want to continue? 自动链接 - + @@ -10018,15 +10007,15 @@ Are you really want to continue? 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index 0ffbbef6..6584f183 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -6331,101 +6331,6 @@ - - ReplaceDialog - - Replace - - - - Text to Find: - - - - Replace with: - - - - Scope: - - - - Global - - - - Selection - - - - Origin: - - - - From cursor - - - - Entire scope - - - - Options: - - - - Whole words only - - - - Wrap Around - - - - Regular Expression - - - - Case Sensitive - - - - Find Previous - - - - Find Next - - - - Replace All - - - - Close - - - - Beginning of file has been reached. - - - - Do you want to continue from file's end? - - - - End of file has been reached. - - - - Do you want to continue from file's beginning? - - - - Continue Search - - - SearchDialog @@ -6516,6 +6421,22 @@ Do you want to continue from file's end? + + Replace with: + + + + Replace + + + + Replace All + + + + Search + + SearchInFileDialog diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp index ac6bc102..55e5a3b6 100644 --- a/RedPandaIDE/utils.cpp +++ b/RedPandaIDE/utils.cpp @@ -530,7 +530,7 @@ QString getSizeString(int size) } void saveComboHistory(QComboBox* cb,const QString& text) { - QString s = text.trimmed(); + QString s = text; if (s.isEmpty()) return; int i = cb->findText(s); diff --git a/RedPandaIDE/widgets/searchdialog.cpp b/RedPandaIDE/widgets/searchdialog.cpp index 0159fae5..45d5dee6 100644 --- a/RedPandaIDE/widgets/searchdialog.cpp +++ b/RedPandaIDE/widgets/searchdialog.cpp @@ -15,9 +15,20 @@ SearchDialog::SearchDialog(QWidget *parent) : ui(new Ui::SearchDialog), mSearchOptions() { + setWindowFlag(Qt::WindowContextHelpButtonHint,false); ui->setupUi(this); - mBasicSearchEngine= std::make_shared(); - mRegexSearchEngine= std::make_shared(); + mTabBar=new QTabBar(this); + mTabBar->setExpanding(false); + mSearchTabIdx = mTabBar->addTab(tr("Search")); + mReplaceTabIdx = mTabBar->addTab(tr("Replace")); + ui->dialogLayout->insertWidget(0,mTabBar); + + mTabBar->setCurrentIndex(mSearchTabIdx); + connect(mTabBar, &QTabBar::currentChanged, this, + &SearchDialog::onTabBarCurrentChanged); + onTabBarCurrentChanged(mSearchTabIdx); + mBasicSearchEngine = std::make_shared(); + mRegexSearchEngine = std::make_shared(); } SearchDialog::~SearchDialog() @@ -27,62 +38,39 @@ SearchDialog::~SearchDialog() void SearchDialog::find(const QString &text) { + mTabBar->setCurrentIndex(mSearchTabIdx); ui->cbFind->setCurrentText(text); ui->cbFind->setFocus(); show(); } +void SearchDialog::replace(const QString &text) +{ + mTabBar->setCurrentIndex(mReplaceTabIdx); + ui->cbFind->setCurrentText(text); + ui->cbFind->setFocus(); + //ui->cbReplace->setCurrentText(""); + show(); +} + void SearchDialog::findNext() { doSearch(false); - if (ui->chkCloseAfterSearch) + if (ui->chkCloseAfterSearch->isChecked()) close(); } void SearchDialog::findPrevious() { doSearch(true); - if (ui->chkCloseAfterSearch) + if (ui->chkCloseAfterSearch->isChecked()) close(); } void SearchDialog::doSearch(bool backward) { saveComboHistory(ui->cbFind,ui->cbFind->currentText()); - - mSearchOptions&=0; - - // Apply options - if (backward) { - mSearchOptions.setFlag(QSynedit::ssoBackwards); - } - - if (ui->chkRegExp->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoRegExp); - } - if (ui->chkCaseSensetive->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoMatchCase); - } - if (ui->chkWholeWord->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoWholeWord); - } - if (ui->chkWrapAround->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoWrapAround); - } - - // Apply scope, when enabled - if (ui->grpScope->isEnabled()) { - if (ui->rbSelection->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoSelectedOnly); - } - } - - // Apply origin, when enabled - if (ui->grpOrigin->isEnabled()) { - if (ui->rbEntireScope->isChecked()) { - mSearchOptions.setFlag(QSynedit::ssoEntireScope); - } - } + prepareOptions(backward); Editor *editor = pMainWindow->editorList()->getEditor(); if (editor) { @@ -130,10 +118,113 @@ void SearchDialog::doSearch(bool backward) } } +void SearchDialog::doReplace(bool replaceAll) +{ + saveComboHistory(ui->cbFind,ui->cbFind->currentText()); + saveComboHistory(ui->cbReplace,ui->cbReplace->currentText()); + prepareOptions(false); + Editor *editor = pMainWindow->editorList()->getEditor(); + if (editor) { + QSynedit::PSynSearchBase searchEngine; + if (mSearchOptions.testFlag(QSynedit::ssoRegExp)) { + searchEngine = mRegexSearchEngine; + } else { + searchEngine = mBasicSearchEngine; + } + editor->searchReplace( + ui->cbFind->currentText(), + ui->cbReplace->currentText(), + mSearchOptions, + searchEngine, + [&replaceAll](const QString& /*sSearch*/, + const QString& /*sReplace*/, int /*Line*/, int /*ch*/, int /*wordLen*/){ + if (replaceAll) { + return QSynedit::SearchAction::ReplaceAll; + } else { + return QSynedit::SearchAction::ReplaceAndExit; + } + }, + [this](){ + QString msg = tr("End of file has been reached. ") + +tr("Do you want to continue from file's beginning?"); + QWidget *p; + if (isVisible()) { + p=this; + } else { + p=pMainWindow; + } + return QMessageBox::question(p, + tr("Continue Search"), + msg, + QMessageBox::Yes|QMessageBox::No, + QMessageBox::Yes) == QMessageBox::Yes; + }); + } +} + +void SearchDialog::prepareOptions(bool backward) +{ + mSearchOptions&=0; + + // Apply options + if (backward) { + mSearchOptions.setFlag(QSynedit::ssoBackwards); + } + + if (ui->chkRegExp->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoRegExp); + } + if (ui->chkCaseSensetive->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoMatchCase); + } + if (ui->chkWholeWord->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoWholeWord); + } + if (ui->chkWrapAround->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoWrapAround); + } + + // Apply scope, when enabled + if (ui->grpScope->isEnabled()) { + if (ui->rbSelection->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoSelectedOnly); + } + } + + // Apply origin, when enabled + if (ui->grpOrigin->isEnabled()) { + if (ui->rbEntireScope->isChecked()) { + mSearchOptions.setFlag(QSynedit::ssoEntireScope); + } + } + +} + + + +void SearchDialog::onTabBarCurrentChanged(int currentIndex) +{ + if(currentIndex==mSearchTabIdx) { + ui->lbReplace->setVisible(false); + ui->cbReplace->setVisible(false); + ui->chkCloseAfterSearch->setVisible(true); + ui->btnReplace->setVisible(false); + ui->btnReplaceAll->setVisible(false); + } else { + ui->lbReplace->setVisible(true); + ui->cbReplace->setVisible(true); + ui->chkCloseAfterSearch->setVisible(false); + ui->btnReplace->setVisible(true); + ui->btnReplaceAll->setVisible(true); + } +} + void SearchDialog::on_cbFind_currentTextChanged(const QString &value) { ui->btnNext->setEnabled(!value.isEmpty()); ui->btnPrevious->setEnabled(!value.isEmpty()); + ui->btnReplace->setEnabled(!value.isEmpty()); + ui->btnReplaceAll->setEnabled(!value.isEmpty()); } void SearchDialog::on_btnClose_clicked() @@ -143,10 +234,23 @@ void SearchDialog::on_btnClose_clicked() void SearchDialog::on_btnNext_clicked() { - doSearch(false); + findNext(); } void SearchDialog::on_btnPrevious_clicked() { - doSearch(true); + findPrevious(); +} + + +void SearchDialog::on_btnReplace_clicked() +{ + doReplace(false); +} + + +void SearchDialog::on_btnReplaceAll_clicked() +{ + doReplace(true); + close(); } diff --git a/RedPandaIDE/widgets/searchdialog.h b/RedPandaIDE/widgets/searchdialog.h index 78658558..f3313938 100644 --- a/RedPandaIDE/widgets/searchdialog.h +++ b/RedPandaIDE/widgets/searchdialog.h @@ -2,6 +2,7 @@ #define SEARCHDIALOG_H #include +#include #include namespace Ui { @@ -16,22 +17,35 @@ public: explicit SearchDialog(QWidget *parent = nullptr); ~SearchDialog(); void find(const QString& text); + void replace(const QString& text); void findNext(); void findPrevious(); private: void doSearch(bool backward); + + void doReplace(bool replaceAll); + + void prepareOptions(bool backward); private slots: + void onTabBarCurrentChanged(int currentIndex); + void on_cbFind_currentTextChanged(const QString &arg1); void on_btnClose_clicked(); void on_btnNext_clicked(); - void on_btnPrevious_clicked(); + void on_btnReplace_clicked(); + + void on_btnReplaceAll_clicked(); + private: Ui::SearchDialog *ui; + QTabBar * mTabBar; + int mSearchTabIdx; + int mReplaceTabIdx; QSynedit::SearchOptions mSearchOptions; QSynedit::PSynSearchBase mBasicSearchEngine; QSynedit::PSynSearchBase mRegexSearchEngine; diff --git a/RedPandaIDE/widgets/searchdialog.ui b/RedPandaIDE/widgets/searchdialog.ui index d5781555..f7d959d2 100644 --- a/RedPandaIDE/widgets/searchdialog.ui +++ b/RedPandaIDE/widgets/searchdialog.ui @@ -13,28 +13,40 @@ Find - + + + 0 + + + 0 + + + 0 + + + 0 + - - - - 7 - + + - 0 + 5 - 0 + 5 - 0 + 5 - 0 + 5 - - + + + + 7 + 0 @@ -48,287 +60,352 @@ 0 - - - Text to Find: - - - - - - - - 0 - 0 - - - - true - - - QComboBox::InsertAtTop - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Scope: - - + + - 7 + 0 - 7 + 0 - 7 + 0 - 7 + 0 - - + + - Global + Text to Find: - - - - Selection - - - - - - - - - - Origin: - - - - 7 - - - 7 - - - 7 - - - 7 - - - - - From cursor - - - true - - - - - - - Entire scope - - - - - - - - - - Options: - - - - 7 - - - 7 - - - 7 - - - 7 - - - - - Wrap Around - - - true - - - - - + + 0 0 - - Regular Expression + + true + + + QComboBox::InsertAtTop + + + + + + + true + + + QComboBox::InsertAtTop + + + QComboBox::AdjustToContentsOnFirstShow - + - Whole words only - - - - - - - Case Sensitive - - - - - - - - 0 - 0 - - - - <html><head/><body><p><a href="https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference"><span style=" text-decoration: underline; color:#0000ff;">(?)</span></a></p></body></html> - - - true - - - - - - - Close after search + Replace with: + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Scope: + + + + 7 + + + 7 + + + 7 + + + 7 + + + + + Global + + + + + + + Selection + + + + + + + + + + Origin: + + + + 7 + + + 7 + + + 7 + + + 7 + + + + + From cursor + + + true + + + + + + + Entire scope + + + + + + + + + + Options: + + + + 7 + + + 7 + + + 7 + + + 7 + + + + + + 0 + 0 + + + + <html><head/><body><p><a href="https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference"><span style=" text-decoration: underline; color:#0000ff;">(?)</span></a></p></body></html> + + + true + + + + + + + + 0 + 0 + + + + Regular Expression + + + + + + + Close after search + + + + + + + Whole words only + + + + + + + Case Sensitive + + + + + + + Wrap Around + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Find Previous - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Find Previous + + + + + + + Find Next + + + true + + + + + + + Replace + + + + + + + Replace All + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 15 + + + + + + + + Close + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - Find Next - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 15 - - - - - - - - Close - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/libs/qsynedit/qsynedit/searcher/baseseacher.cpp b/libs/qsynedit/qsynedit/searcher/baseseacher.cpp index 1140c46d..2676801d 100644 --- a/libs/qsynedit/qsynedit/searcher/baseseacher.cpp +++ b/libs/qsynedit/qsynedit/searcher/baseseacher.cpp @@ -41,4 +41,9 @@ void BaseSearcher::setOptions(const SearchOptions &options) { mOptions = options; } + +bool BaseSearcher::isDelimitChar(const QChar& ch) const +{ + return !(ch == '_' || ch.isLetterOrNumber()); +} } diff --git a/libs/qsynedit/qsynedit/searcher/baseseacher.h b/libs/qsynedit/qsynedit/searcher/baseseacher.h index 62d5d9c8..6eb6ad5e 100644 --- a/libs/qsynedit/qsynedit/searcher/baseseacher.h +++ b/libs/qsynedit/qsynedit/searcher/baseseacher.h @@ -49,6 +49,8 @@ public: virtual QString replace(const QString& aOccurrence, const QString& aReplacement) = 0; SearchOptions options() const; virtual void setOptions(const SearchOptions &options); +protected: + bool isDelimitChar(const QChar& ch) const; private: QString mPattern; diff --git a/libs/qsynedit/qsynedit/searcher/basicsearcher.cpp b/libs/qsynedit/qsynedit/searcher/basicsearcher.cpp index 235e3e57..208650b9 100644 --- a/libs/qsynedit/qsynedit/searcher/basicsearcher.cpp +++ b/libs/qsynedit/qsynedit/searcher/basicsearcher.cpp @@ -79,8 +79,4 @@ QString BasicSearcher::replace(const QString &, const QString &aReplacement) return aReplacement; } -bool BasicSearcher::isDelimitChar(QChar ch) -{ - return !(ch == '_' || ch.isLetterOrNumber()); -} } diff --git a/libs/qsynedit/qsynedit/searcher/basicsearcher.h b/libs/qsynedit/qsynedit/searcher/basicsearcher.h index 4b6db9f5..bd2ca5ca 100644 --- a/libs/qsynedit/qsynedit/searcher/basicsearcher.h +++ b/libs/qsynedit/qsynedit/searcher/basicsearcher.h @@ -33,8 +33,6 @@ public: int resultCount() override; int findAll(const QString &text) override; QString replace(const QString &aOccurrence, const QString &aReplacement) override; -private: - bool isDelimitChar(QChar ch); private: QList mResults; }; diff --git a/libs/qsynedit/qsynedit/searcher/regexsearcher.cpp b/libs/qsynedit/qsynedit/searcher/regexsearcher.cpp index a9c2765c..b75dd2a6 100644 --- a/libs/qsynedit/qsynedit/searcher/regexsearcher.cpp +++ b/libs/qsynedit/qsynedit/searcher/regexsearcher.cpp @@ -53,8 +53,20 @@ int RegexSearcher::findAll(const QString &text) QRegularExpressionMatchIterator it = mRegex.globalMatch(text); while (it.hasNext()) { QRegularExpressionMatch match = it.next(); - mLengths.append(match.capturedLength()); - mResults.append(match.capturedStart()); + if (options().testFlag(ssoWholeWord)) { + int start = match.capturedStart(); + int end = match.capturedStart()+match.capturedLength(); + if (((start<=0) || isDelimitChar(text[start-1])) + && + ( (end>=text.length()) || isDelimitChar(text[end]) ) + ) { + mLengths.append(match.capturedLength()); + mResults.append(match.capturedStart()); + } + } else { + mLengths.append(match.capturedLength()); + mResults.append(match.capturedStart()); + } } return mResults.size(); }