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
- Substituir
+ Substituir
- Texto a procurar:
+ Texto a procurar:
- Substituir por:
+ Substituir por:
- Escopo:
+ Escopo:
- Global
+ Global
- Seleção
+ Seleção
- Origem:
+ Origem:
- A partir do cursor
+ A partir do cursor
- Escopo inteiro
+ Escopo inteiro
- Opções:
+ Opções:
- Apenas palavras inteiras
+ Apenas palavras inteiras
- Wrap Around
+ Wrap Around
- Expressão regular
+ Expressão regular
@@ -6810,43 +6810,27 @@
- Sensibilidade a maiúsculas/minúsculas
+ Sensibilidade a maiúsculas/minúsculas
- Procurar anterior
+ Procurar anterior
- Procurar outro
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Procurar outro
- Encontrado fim de arquivo.
+ Encontrado fim de arquivo.
- Quer continuar a partir do início do arquivo?
+ Quer continuar a partir do início do arquivo?
- Continuar a procura
+ Continuar a procura
@@ -6861,7 +6845,7 @@
- Substituir por:
+ Substituir por:
@@ -6949,7 +6933,7 @@
- Substituir
+ Substituir
@@ -7003,6 +6987,14 @@
+
+
+
+
+
+
+ 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+单击以获取更多信息
@@ -1499,27 +1499,27 @@ Are you really want to continue?
未找到符号'%1'!
-
+
找不到astyle程序
-
+
找不到astyle程序"%1".
-
+
断点条件
-
+
输入当前断点的生效条件:
-
+
只读
@@ -4233,18 +4233,18 @@ Are you really want to continue?
MainWindow
-
+
小熊猫C++
-
-
-
-
-
+
+
+
+
+
编译器
@@ -4318,7 +4318,7 @@ Are you really want to continue?
-
+
调试主控台
@@ -4394,7 +4394,7 @@ Are you really want to continue?
工具栏2
-
+
新建
@@ -4528,9 +4528,9 @@ Are you really want to continue?
-
-
-
+
+
+
复制
@@ -4541,7 +4541,7 @@ Are you really want to continue?
-
+
粘贴
@@ -4552,8 +4552,8 @@ Are you really want to continue?
-
-
+
+
选择全部
@@ -4676,38 +4676,38 @@ Are you really want to continue?
-
-
+
+
新建试题集
-
+
添加试题
-
+
删除试题
-
-
+
+
保存试题集
-
-
+
+
载入试题集
@@ -4755,7 +4755,7 @@ Are you really want to continue?
-
+
Remove Problem Set
删除试题集
@@ -4763,21 +4763,21 @@ Are you really want to continue?
-
+
打开答案源代码文件
-
+
Run Current Case
运行所有案例
-
+
测试案例验证选项
@@ -4837,15 +4837,15 @@ Are you really want to continue?
-
-
+
+
导入FPS试题集
-
-
+
+
导出FPS试题集
@@ -5092,7 +5092,7 @@ Are you really want to continue?
-
+
删除所有断点
@@ -5332,7 +5332,7 @@ Are you really want to continue?
保存为模板...
-
+
新建文件
@@ -5373,7 +5373,7 @@ Are you really want to continue?
-
+
重命名符号
@@ -5394,13 +5394,13 @@ Are you really want to continue?
-
+
导出为RTF
-
+
导出为HTML
@@ -5669,42 +5669,42 @@ Are you really want to continue?
运行参数...
-
+
文件编码
-
+
文件历史
-
-
-
-
-
-
+
+
+
+
+
+
正在调试
-
-
-
-
-
-
+
+
+
+
+
+
正在运行
-
-
-
-
-
-
+
+
+
+
+
+
正在编译
@@ -5718,17 +5718,17 @@ Are you really want to continue?
行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5
-
+
只读
-
+
插入
-
+
覆写
@@ -5745,7 +5745,7 @@ Are you really want to continue?
确认
-
+
源文件尚未编译。
@@ -5762,44 +5762,44 @@ Are you really want to continue?
重新编译?
-
-
-
-
+
+
+
+
错误的编译器设置
-
-
-
-
+
+
+
+
编译器被设置为不生成可执行文件。
-
-
+
+
我们需要可执行文件来运行试题案例。
-
+
无编译器设置
-
+
没有配置编译器设置。
-
+
无法启动调试器
-
+
启用调试参数
@@ -5816,33 +5816,33 @@ Are you really want to continue?
项目尚未构建。是否构建?
-
+
宿主程序不存在
-
+
动态链接库(DLL)需要一个宿主程序来运行。
-
+
但它不存在。
-
+
宿主程序不存在
-
+
宿主程序'%1'不存在。
-
-
+
+
请在调试前改正设置。
@@ -5851,8 +5851,8 @@ Are you really want to continue?
重新编译?
-
-
+
+
保存上次打开信息失败
@@ -5861,60 +5861,60 @@ Are you really want to continue?
无法删除旧上次打开信息文件'%1'
-
+
无法保存上次打开信息文件'%1'
-
-
+
+
载入上次打开信息失败
-
-
+
+
无法载入上次打开信息文件'%1'
-
+
打开源代码文件
-
-
+
+
批量设置案例
-
+
显示详细调试器日志
-
+
全部复制
-
+
跳转到行
-
+
行
-
+
模板已存在
-
+
模板%1已存在。是否覆盖?
@@ -5922,25 +5922,25 @@ Are you really want to continue?
-
-
-
+
+
+
清除
-
+
导出
-
+
插入代码段
-
-
+
+
试题集%1
@@ -5969,56 +5969,56 @@ Are you really want to continue?
项目已经被修改过,是否需要重新构建?
-
+
自动保存出错
-
+
自动保存"%1"到"%2"失败:%3
-
+
试题属性...
-
+
设置试题集名称
-
+
试题集名称:
-
+
删除
-
+
删除全部书签
-
+
修改描述
-
-
-
+
+
+
书签描述
-
-
-
+
+
+
描述:
@@ -6027,65 +6027,65 @@ Are you really want to continue?
在调试主控台中显示调试器输出
-
+
清除这次搜索
-
+
删除所有搜索
-
+
断点条件...
-
+
断点条件
-
+
输入当前断点的生效条件:
-
+
Remove all breakpoints
删除所有断点
-
+
删除当前断点
-
+
重命名文件
-
-
+
+
添加文件夹
-
-
+
+
新文件夹
-
+
文件夹:
-
+
重命名
@@ -6098,207 +6098,207 @@ Are you really want to continue?
要现在去修改设置吗?
-
+
修改试题集名称
-
+
无法写入配置文件'%1'。
-
+
修改试题名称
-
+
行: %1 列: %2 总行数: %3
-
+
改正编译器设置
-
-
+
+
您使用的Debug编译器配置集中存在错误的“编译/链接”选项设置:
-
-
+
+
- 应勾选"生成调试信息(-g3)"选项
-
+
- 应取消"剥除附加信息(-s)"选项
-
-
+
+
是否现在去改正?
-
-
+
+
无法调试
-
-
+
+
您的编译器配置集中的“剥除附加信息(-s)”选项被勾选了。
-
-
+
+
请取消该设置,重新编译然后重新启动调试。
-
+
跳转到试题网址
-
+
添加试题案例
-
+
运行当前案例
-
+
删除文件夹
-
+
切换为普通视图
-
+
切换为自定义视图
-
+
按类型排序
-
+
按名称排序
-
+
显示继承的成员
-
+
跳转到声明处
-
+
跳转到定义处
-
+
仅当前文件
-
+
整个项目
-
-
+
+
新建文件夹
-
+
重命名
-
-
-
-
+
+
+
+
删除
-
+
在编辑器中打开
-
+
使用外部程序打开
-
+
在终端中打开
-
+
在Windows浏览器中打开
-
+
字符集
-
+
转换为%1编码
-
+
换行符
-
+
已自动保存%1个文件
-
+
设置答案源代码...
-
+
选择其他文件...
-
+
选择答案源代码文件
@@ -6307,17 +6307,17 @@ Are you really want to continue?
中止
-
+
FPS试题集文件(*.fps;*.xml)
-
+
FPS试题集文件(*.fps)
-
+
导出时出错
@@ -6327,7 +6327,7 @@ Are you really want to continue?
C/C++源代码文件 (*.c *.cpp *.cc *.cxx)
-
+
新建文件夹%1
@@ -6340,70 +6340,70 @@ Are you really want to continue?
无标题%1
-
+
你真的要删除%1吗?
-
+
你真的要删除%1个文件吗?
-
+
保存项目
-
+
项目'%1'有改动。
-
-
+
+
需要保存吗?
-
-
+
+
文件已发生变化
-
-
+
+
新建项目文件?
-
-
+
+
您是否要将新建的文件加入项目?
-
-
-
-
+
+
+
+
保存失败
-
+
改变项目编译器配置集
-
+
改变项目的编译器配置集会导致所有的自定义编译器选项被重置。
-
-
+
+
你真的想要那么做吗?
@@ -6412,12 +6412,12 @@ Are you really want to continue?
批量设置案例
-
+
选择输入数据文件
-
+
输入数据文件 (*.in)
@@ -6426,78 +6426,78 @@ Are you really want to continue?
无标题%1
-
+
修改监视表达式
-
+
监视表达式
-
+
您真的要清除该文件的所有断点吗?
-
+
新建项目
-
+
关闭'%1'以打开新项目?
-
+
文件夹不存在
-
+
文件夹'%1'不存在。是否创建?
-
+
无法创建文件夹
-
+
创建文件夹'%1'失败。
-
+
-
+
文件夹%1不是空的。
-
+
你真的要删除它吗?
-
+
改变工作文件夹
-
+
File '%1' is not in the current working folder
文件'%1'不在当前工作文件夹中。
-
+
是否将工作文件夹改设为'%1'?
@@ -6506,28 +6506,28 @@ Are you really want to continue?
正在删除试题...
-
+
无法提交
-
+
Git需要用信息进行提交。
-
+
选择输入数据文件
-
-
+
+
所有文件 (*.*)
-
+
Choose Expected Input Data File
选择期望输出文件
@@ -6539,59 +6539,59 @@ Are you really want to continue?
-
+
选择工作文件夹
-
-
+
+
头文件已存在
-
-
+
+
头文件"%1"已存在!
-
+
源文件已存在!
-
+
源文件"%1"已存在!
-
+
无法提交!
-
+
下列文件处于冲突状态,请解决后重新添加和提交:
-
+
提交信息
-
+
提交信息:
-
+
提交失败
-
+
提交信息不能为空!
@@ -6600,22 +6600,22 @@ Are you really want to continue?
小熊猫Dev-C++项目文件 (*.dev)
-
+
新建项目失败
-
+
无法使用模板创建项目
-
+
删除文件
-
+
同时从硬盘上删除文件?
@@ -6624,27 +6624,27 @@ Are you really want to continue?
无标题
-
+
新的项目文件名
-
+
文件名:
-
+
文件已存在!
-
+
文件'%1'已经存在!
-
+
添加到项目
@@ -6661,27 +6661,27 @@ Are you really want to continue?
请在工具栏中选择Debug编译器配置集,或者在“编译器配置集”设置的“编译/链接选项”页中<b>启用</b>“生成调试信息(-g3)”、<b>禁用</b>“剥除附件信息(-3)”。
-
+
C/C++源代码文件 (*.c *.cpp *.cc *.cxx)
-
+
本操作会删除此试题的所有案例。
-
+
调试失败
-
+
可执行文件中没有符号表信息,无法调试。
-
+
请在选项对话框的编译器配置集页中取消“剥除附加信息(-s)”选项,重新编译后再调试。
@@ -6702,134 +6702,134 @@ Are you really want to continue?
您也可以删除所有断点,打开“CPU信息窗口”,然后调试汇编代码。
-
+
未能生成可执行文件。
-
+
请查看“工具输出”面板中的详细信息。
-
+
小熊猫C++项目文件(*.dev)
-
+
重命名出错
-
+
符号'%1'在系统头文件中定义,无法修改。
-
+
新名称
-
-
-
-
+
+
+
+
替换出错
-
+
无法打开文件'%1'进行替换!
-
+
内容和上次查找时不一致。
-
+
RTF格式文件 (*.rtf)
-
+
HTML文件 (*.html)
-
+
当前的试题集不是空的。
-
+
试题%1
-
-
+
+
试题集文件 (*.pbs)
-
-
+
+
载入失败
-
-
+
+
试题案例%1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
错误
-
+
项目历史
-
+
载入主题失败
-
-
+
+
清除历史
-
-
+
+
编译生成的可执行文件中没有符号表,无法被调试。
-
-
+
+
版本控制
@@ -6838,80 +6838,80 @@ Are you really want to continue?
请在工具栏中选用Debug编译器配置集,或者在选项对话框的编辑器配置集页中勾选“生成调试信息(-g3)"选项。
-
+
磁盘文件'%1'已被修改。
-
+
是否重新读取它的内容?
-
+
磁盘文件'%1'已被删除。
-
+
是否保持它在小熊猫C++中打开的编辑窗口?
-
+
打开
-
-
+
+
编译失败
-
+
运行失败
-
-
-
-
+
+
+
+
确认转换
-
-
-
-
+
+
+
+
当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗?
-
+
新监视表达式
-
+
输入监视表达式
-
+
(%1/%2)正在解析文件"%3"
-
-
+
+
完成%1个文件的解析,用时%2秒
-
+
(每秒%1个文件)
@@ -8196,13 +8196,13 @@ Are you really want to continue?
QObject
-
+
保存
-
+
将修改保存到"%1"?
@@ -9263,127 +9263,100 @@ Are you really want to continue?
ReplaceDialog
-
-
- 替换
+ 替换
-
- 查找字符串:
+ 查找字符串:
-
- 替换为:
+ 替换为:
-
- 范围:
+ 范围:
-
- 全局
+ 全局
-
- 选中内容
+ 选中内容
-
- 起点:
+ 起点:
-
- 从光标处
+ 从光标处
-
- 整个范围
+ 整个范围
-
- 选项:
+ 选项:
-
- 整个单词
+ 整个单词
-
- 循环查找
+ 循环查找
-
- 正则表达式
+ 正则表达式
替换时提示
-
- 区分大小写
+ 区分大小写
-
- 查找前一个
+ 查找前一个
-
- 查找下一个
+ 查找下一个
-
- 全部替换
+ 全部替换
-
- 关闭
+ 关闭
-
- 已到达文件开头。
+ 已到达文件开头。
-
- 是否需要从文件末尾开始继续查找?
+ 是否需要从文件末尾开始继续查找?
-
-
- 已到达文件结尾。
+ 已到达文件结尾。
-
-
- 是否从文件开头继续?
+ 是否从文件开头继续?
-
-
- 继续查找
+ 继续查找
@@ -9393,36 +9366,37 @@ Are you really want to continue?
对话框
-
+
要查找的关键字
+
- 替换为:
+ 替换为:
-
+
选项:
-
+
区分大小写
-
+
整个单词
-
+
循环查找
-
+
正则表达式
@@ -9431,52 +9405,57 @@ Are you really want to continue?
替换时提示
-
+
范围:
-
+
全局
-
+
选中文字
-
+
起点:
-
+
从光标处
-
+
整个范围
-
+
找到后关闭对话框
-
+
查找前一个
-
+
查找下一个
-
+
+
+ 全部替换
+
+
+
关闭
@@ -9522,37 +9501,47 @@ Are you really want to continue?
在文件中查找
+
+
- 替换
+ 替换
在文件中替换
-
+
+
Search Around
继续查找
-
+
+
End of file has been reached.
已到达文件结尾。
-
+
+
+ 查找
+
+
+
已到达文件开头
-
+
是否从文件结尾继续?
-
+
+
Do you want to start from beginning?
是否从文件开头继续?
@@ -9919,18 +9908,18 @@ Are you really want to continue?
性能
-
-
-
+
+
+
编译器配置集
-
-
-
+
+
+
@@ -9942,7 +9931,7 @@ Are you really want to continue?
自动链接
-
+
@@ -10018,15 +10007,15 @@ Are you really want to continue?
杂项
-
-
+
+
程序运行
-
+
试题集
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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
SearchDialog
@@ -6516,6 +6421,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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();
}