2021-12-26 23:18:28 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2021-08-02 21:58:39 +08:00
|
|
|
#include "searchdialog.h"
|
|
|
|
#include "ui_searchdialog.h"
|
2021-08-02 23:42:10 +08:00
|
|
|
#include <QTabBar>
|
2021-08-03 23:55:57 +08:00
|
|
|
#include "../editor.h"
|
|
|
|
#include "../mainwindow.h"
|
|
|
|
#include "../editorlist.h"
|
|
|
|
#include "../qsynedit/Search.h"
|
|
|
|
#include "../qsynedit/SearchRegex.h"
|
2021-09-29 20:45:03 +08:00
|
|
|
#include "../project.h"
|
2021-08-03 23:55:57 +08:00
|
|
|
#include <QMessageBox>
|
2021-08-05 12:31:53 +08:00
|
|
|
#include <QDebug>
|
2021-08-03 23:55:57 +08:00
|
|
|
|
2021-08-02 21:58:39 +08:00
|
|
|
|
|
|
|
SearchDialog::SearchDialog(QWidget *parent) :
|
|
|
|
QDialog(parent),
|
2021-08-03 23:55:57 +08:00
|
|
|
ui(new Ui::SearchDialog),
|
|
|
|
mSearchEngine()
|
2021-08-02 21:58:39 +08:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2021-08-02 23:42:10 +08:00
|
|
|
mTabBar = new QTabBar();
|
|
|
|
mTabBar->addTab(tr("Find"));
|
|
|
|
mTabBar->addTab(tr("Find in files"));
|
|
|
|
mTabBar->addTab(tr("Replace"));
|
2021-10-04 12:49:55 +08:00
|
|
|
mTabBar->addTab(tr("Replace in files"));
|
2021-08-03 23:55:57 +08:00
|
|
|
mTabBar->setExpanding(false);
|
2021-08-02 23:42:10 +08:00
|
|
|
ui->dialogLayout->insertWidget(0,mTabBar);
|
|
|
|
connect(mTabBar,&QTabBar::currentChanged,this, &SearchDialog::onTabChanged);
|
2021-08-03 23:55:57 +08:00
|
|
|
mSearchOptions&=0;
|
|
|
|
mBasicSearchEngine= PSynSearchBase(new SynSearch());
|
|
|
|
mRegexSearchEngine= PSynSearchBase(new SynSearchRegex());
|
2021-08-02 21:58:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SearchDialog::~SearchDialog()
|
|
|
|
{
|
|
|
|
delete ui;
|
|
|
|
}
|
2021-08-02 23:42:10 +08:00
|
|
|
|
|
|
|
void SearchDialog::find(const QString &text)
|
|
|
|
{
|
2021-08-04 09:13:41 +08:00
|
|
|
if (mTabBar->currentIndex()==0) {
|
|
|
|
this->onTabChanged();
|
|
|
|
} else {
|
|
|
|
mTabBar->setCurrentIndex(0);
|
|
|
|
}
|
2021-08-02 23:42:10 +08:00
|
|
|
ui->cbFind->setCurrentText(text);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2021-08-04 00:17:38 +08:00
|
|
|
void SearchDialog::findNext()
|
|
|
|
{
|
|
|
|
if (mTabBar->currentIndex()==0) { // it's a find action
|
|
|
|
|
|
|
|
// Disable entire scope searching
|
|
|
|
ui->rbEntireScope->setChecked(false);
|
|
|
|
|
|
|
|
// Always search forwards
|
|
|
|
ui->rbForward->setChecked(true);
|
|
|
|
|
|
|
|
ui->btnExecute->click();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-02 23:42:10 +08:00
|
|
|
void SearchDialog::findInFiles(const QString &text)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(1);
|
|
|
|
ui->cbFind->setCurrentText(text);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2021-08-05 19:58:32 +08:00
|
|
|
void SearchDialog::findInFiles(const QString &keyword, SearchFileScope scope, SynSearchOptions options)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(1);
|
2021-09-29 20:45:03 +08:00
|
|
|
|
2021-08-05 19:58:32 +08:00
|
|
|
ui->cbFind->setCurrentText(keyword);
|
|
|
|
switch(scope) {
|
|
|
|
case SearchFileScope::currentFile:
|
|
|
|
ui->rbCurrentFile->setChecked(true);
|
|
|
|
break;
|
|
|
|
case SearchFileScope::openedFiles:
|
|
|
|
ui->rbOpenFiles->setChecked(true);
|
|
|
|
break;
|
|
|
|
case SearchFileScope::wholeProject:
|
|
|
|
ui->rbProject->setChecked(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Apply options
|
2021-10-20 18:05:43 +08:00
|
|
|
ui->chkRegExp->setChecked(options.testFlag(ssoRegExp));
|
|
|
|
ui->chkCaseSensetive->setChecked(options.testFlag(ssoMatchCase));
|
|
|
|
ui->chkWholeWord->setChecked(options.testFlag(ssoWholeWord));
|
2022-01-13 12:55:55 +08:00
|
|
|
ui->chkWrapAround->setChecked(options.testFlag(ssoWholeWord));
|
2021-08-05 19:58:32 +08:00
|
|
|
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2021-08-02 23:42:10 +08:00
|
|
|
void SearchDialog::replace(const QString &sFind, const QString &sReplace)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(2);
|
|
|
|
ui->cbFind->setCurrentText(sFind);
|
|
|
|
ui->cbReplace->setCurrentText(sReplace);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::onTabChanged()
|
|
|
|
{
|
|
|
|
bool isfind = (mTabBar->currentIndex() == 0);
|
2021-10-04 12:49:55 +08:00
|
|
|
bool isfindfiles = (mTabBar->currentIndex() == 1 || mTabBar->currentIndex() == 3 );
|
2021-08-02 23:42:10 +08:00
|
|
|
bool isreplace = (mTabBar->currentIndex() == 2);
|
|
|
|
|
2021-08-04 09:13:41 +08:00
|
|
|
ui->lblReplace->setVisible(isreplace);
|
|
|
|
ui->cbReplace->setVisible(isreplace);
|
2021-08-02 23:42:10 +08:00
|
|
|
|
|
|
|
ui->grpOrigin->setVisible(isfind || isreplace);
|
2021-08-04 00:17:38 +08:00
|
|
|
ui->grpOrigin->setEnabled(isfind || isreplace);
|
|
|
|
|
2021-08-02 23:42:10 +08:00
|
|
|
ui->grpScope->setVisible(isfind || isreplace);
|
2021-08-04 00:17:38 +08:00
|
|
|
ui->grpScope->setEnabled(isreplace);
|
2021-08-04 09:13:41 +08:00
|
|
|
ui->grpWhere->setVisible(isfindfiles);
|
|
|
|
ui->grpWhere->setEnabled(isfindfiles);
|
2021-08-02 23:42:10 +08:00
|
|
|
ui->grpDirection->setVisible(isfind || isreplace);
|
2021-08-04 00:17:38 +08:00
|
|
|
ui->grpDirection->setEnabled(isfind || isreplace);
|
|
|
|
|
2021-08-02 23:42:10 +08:00
|
|
|
// grpOption is always visible
|
|
|
|
|
|
|
|
// Disable project search option when none is open
|
|
|
|
// rbProjectFiles.Enabled := Assigned(MainForm.Project);
|
2021-09-29 20:45:03 +08:00
|
|
|
ui->rbProject->setEnabled(pMainWindow->project()!=nullptr);
|
|
|
|
ui->rbOpenFiles->setEnabled(pMainWindow->editorList()->pageCount()>0);
|
2021-08-02 23:42:10 +08:00
|
|
|
// if not Assigned(MainForm.Project) then
|
|
|
|
// rbOpenFiles.Checked := true;
|
|
|
|
|
|
|
|
// Disable prompt when doing finds
|
2021-08-04 09:13:41 +08:00
|
|
|
ui->chkPrompt->setEnabled(isreplace);
|
2022-01-13 12:55:55 +08:00
|
|
|
ui->chkWrapAround->setEnabled(!isfindfiles);
|
2021-08-02 23:42:10 +08:00
|
|
|
|
2021-08-04 09:13:41 +08:00
|
|
|
if (isfind || isfindfiles) {
|
2021-08-02 23:42:10 +08:00
|
|
|
ui->btnExecute->setText(tr("Find"));
|
|
|
|
} else {
|
|
|
|
ui->btnExecute->setText(tr("Replace"));
|
|
|
|
}
|
|
|
|
setWindowTitle(mTabBar->tabText(mTabBar->currentIndex()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::on_cbFind_currentTextChanged(const QString &)
|
|
|
|
{
|
|
|
|
ui->btnExecute->setEnabled(!ui->cbFind->currentText().isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::on_btnCancel_clicked()
|
|
|
|
{
|
|
|
|
this->close();
|
|
|
|
}
|
|
|
|
|
2021-11-05 10:44:23 +08:00
|
|
|
static void saveComboHistory(QComboBox* cb,const QString& text) {
|
|
|
|
QString s = text.trimmed();
|
|
|
|
if (s.isEmpty())
|
|
|
|
return;
|
|
|
|
int i = cb->findText(s);
|
|
|
|
if (i>=0) {
|
|
|
|
cb->removeItem(i);
|
|
|
|
}
|
|
|
|
cb->insertItem(0,s);
|
|
|
|
cb->setCurrentText(s);
|
|
|
|
}
|
|
|
|
|
2021-08-03 23:55:57 +08:00
|
|
|
void SearchDialog::on_btnExecute_clicked()
|
2021-08-02 23:42:10 +08:00
|
|
|
{
|
2021-08-05 12:31:53 +08:00
|
|
|
int findCount = 0;
|
2021-11-05 10:44:23 +08:00
|
|
|
saveComboHistory(ui->cbFind,ui->cbFind->currentText());
|
|
|
|
saveComboHistory(ui->cbReplace,ui->cbReplace->currentText());
|
2021-08-03 23:55:57 +08:00
|
|
|
|
|
|
|
SearchAction actionType;
|
|
|
|
switch (mTabBar->currentIndex()) {
|
|
|
|
case 0:
|
|
|
|
actionType = SearchAction::Find;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
actionType = SearchAction::FindFiles;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
actionType = SearchAction::Replace;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
actionType = SearchAction::ReplaceFiles;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mSearchOptions&=0;
|
|
|
|
|
|
|
|
// Apply options
|
|
|
|
if (ui->chkRegExp->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoRegExp);
|
|
|
|
}
|
|
|
|
if (ui->chkCaseSensetive->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoMatchCase);
|
|
|
|
}
|
|
|
|
if (ui->chkWholeWord->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoWholeWord);
|
|
|
|
}
|
2022-01-13 12:55:55 +08:00
|
|
|
if (ui->chkWrapAround->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoWrapAround);
|
|
|
|
}
|
2021-08-03 23:55:57 +08:00
|
|
|
|
2021-08-04 00:17:38 +08:00
|
|
|
// Apply scope, when enabled
|
|
|
|
if (ui->grpScope->isEnabled()) {
|
2021-08-03 23:55:57 +08:00
|
|
|
if (ui->rbSelection->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoSelectedOnly);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-04 00:17:38 +08:00
|
|
|
// Apply direction, when enabled
|
|
|
|
if (ui->grpDirection->isEnabled()) {
|
2021-08-03 23:55:57 +08:00
|
|
|
if (ui->rbBackward->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoBackwards);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-04 00:17:38 +08:00
|
|
|
// Apply origin, when enabled
|
|
|
|
if (ui->grpOrigin->isEnabled()) {
|
2021-08-03 23:55:57 +08:00
|
|
|
if (ui->rbEntireScope->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoEntireScope);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use entire scope for file finding/replacing
|
|
|
|
if (actionType == SearchAction::FindFiles || actionType == SearchAction::ReplaceFiles) {
|
|
|
|
mSearchOptions.setFlag(ssoEntireScope);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->close();
|
|
|
|
|
|
|
|
// Find the first one, then quit
|
|
|
|
if (actionType == SearchAction::Find) {
|
|
|
|
Editor *e = pMainWindow->editorList()->getEditor();
|
|
|
|
if (e!=nullptr) {
|
2022-01-24 18:03:35 +08:00
|
|
|
findCount+=execute(e,ui->cbFind->currentText(),"",nullptr,
|
|
|
|
[](){
|
|
|
|
return QMessageBox::question(pMainWindow,
|
|
|
|
tr("Continue Search"),
|
|
|
|
tr("End of file has been reached. ")
|
|
|
|
+tr("Do you want to continue from file's beginning?"),
|
|
|
|
QMessageBox::Yes|QMessageBox::No,
|
|
|
|
QMessageBox::Yes) == QMessageBox::Yes;
|
|
|
|
});
|
2021-08-03 23:55:57 +08:00
|
|
|
}
|
2021-08-05 12:31:53 +08:00
|
|
|
} else if (actionType == SearchAction::Replace) {
|
2021-08-04 09:13:41 +08:00
|
|
|
Editor *e = pMainWindow->editorList()->getEditor();
|
|
|
|
if (e!=nullptr) {
|
|
|
|
bool doPrompt = ui->chkPrompt->isChecked();
|
2021-08-05 12:31:53 +08:00
|
|
|
findCount+=execute(e,ui->cbFind->currentText(),ui->cbReplace->currentText(),
|
2021-08-04 09:13:41 +08:00
|
|
|
[&doPrompt](const QString& sSearch,
|
2021-10-20 18:05:43 +08:00
|
|
|
const QString& /*sReplace*/, int /*Line*/, int /*ch*/, int /*wordLen*/){
|
2021-08-04 09:13:41 +08:00
|
|
|
if (doPrompt) {
|
|
|
|
switch(QMessageBox::question(pMainWindow,
|
|
|
|
tr("Replace"),
|
|
|
|
tr("Replace this occurrence of ''%1''?").arg(sSearch),
|
|
|
|
QMessageBox::Yes|QMessageBox::YesAll|QMessageBox::No|QMessageBox::Cancel,
|
|
|
|
QMessageBox::Yes)) {
|
|
|
|
case QMessageBox::Yes:
|
|
|
|
return SynSearchAction::Replace;
|
|
|
|
case QMessageBox::YesAll:
|
|
|
|
return SynSearchAction::ReplaceAll;
|
|
|
|
case QMessageBox::No:
|
|
|
|
return SynSearchAction::Skip;
|
|
|
|
case QMessageBox::Cancel:
|
|
|
|
return SynSearchAction::Exit;
|
|
|
|
default:
|
|
|
|
return SynSearchAction::Exit;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return SynSearchAction::ReplaceAll;
|
|
|
|
}
|
2022-01-24 18:03:35 +08:00
|
|
|
},
|
|
|
|
[](){
|
|
|
|
return QMessageBox::question(pMainWindow,
|
|
|
|
tr("Continue Replace"),
|
|
|
|
tr("End of file has been reached. ")
|
|
|
|
+tr("Do you want to continue from file's beginning?"),
|
|
|
|
QMessageBox::Yes|QMessageBox::No,
|
|
|
|
QMessageBox::Yes) == QMessageBox::Yes;
|
2021-08-04 09:13:41 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-10-04 12:49:55 +08:00
|
|
|
} else if (actionType == SearchAction::FindFiles || actionType == SearchAction::ReplaceFiles) {
|
2021-08-05 12:31:53 +08:00
|
|
|
int fileSearched = 0;
|
|
|
|
int fileHitted = 0;
|
|
|
|
QString keyword = ui->cbFind->currentText();
|
|
|
|
if (ui->rbOpenFiles->isChecked()) {
|
|
|
|
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
|
|
|
|
keyword,
|
|
|
|
mSearchOptions,
|
|
|
|
SearchFileScope::openedFiles
|
|
|
|
);
|
|
|
|
// loop through editors, add results to message control
|
|
|
|
for (int i=0;i<pMainWindow->editorList()->pageCount();i++) {
|
|
|
|
Editor * e=pMainWindow->editorList()->operator[](i);
|
|
|
|
if (e!=nullptr) {
|
|
|
|
fileSearched++;
|
2021-11-02 13:12:36 +08:00
|
|
|
PSearchResultTreeItem parentItem = batchFindInEditor(
|
|
|
|
e,
|
|
|
|
e->filename(),
|
|
|
|
keyword);
|
2021-08-05 12:31:53 +08:00
|
|
|
int t = parentItem->results.size();
|
|
|
|
findCount+=t;
|
|
|
|
if (t>0) {
|
|
|
|
fileHitted++;
|
|
|
|
results->results.append(parentItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
|
|
|
|
} else if (ui->rbCurrentFile->isChecked()) {
|
|
|
|
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
|
|
|
|
keyword,
|
|
|
|
mSearchOptions,
|
2021-11-04 21:14:58 +08:00
|
|
|
SearchFileScope::currentFile
|
2021-08-05 12:31:53 +08:00
|
|
|
);
|
|
|
|
Editor * e= pMainWindow->editorList()->getEditor();
|
|
|
|
if (e!=nullptr) {
|
|
|
|
fileSearched++;
|
2021-11-02 13:12:36 +08:00
|
|
|
PSearchResultTreeItem parentItem = batchFindInEditor(
|
|
|
|
e,
|
|
|
|
e->filename(),
|
|
|
|
keyword);
|
2021-08-05 12:31:53 +08:00
|
|
|
int t = parentItem->results.size();
|
|
|
|
findCount+=t;
|
|
|
|
if (t>0) {
|
|
|
|
fileHitted++;
|
|
|
|
results->results.append(parentItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
|
|
|
|
} else if (ui->rbProject->isChecked()) {
|
2021-09-29 20:45:03 +08:00
|
|
|
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
|
|
|
|
keyword,
|
|
|
|
mSearchOptions,
|
|
|
|
SearchFileScope::wholeProject
|
|
|
|
);
|
|
|
|
for (int i=0;i<pMainWindow->project()->units().count();i++) {
|
|
|
|
Editor * e = pMainWindow->project()->units()[i]->editor();
|
|
|
|
QString curFilename = pMainWindow->project()->units()[i]->fileName();
|
|
|
|
if (e) {
|
|
|
|
fileSearched++;
|
2021-11-02 13:12:36 +08:00
|
|
|
PSearchResultTreeItem parentItem = batchFindInEditor(
|
|
|
|
e,
|
|
|
|
e->filename(),
|
|
|
|
keyword);
|
2021-09-29 20:45:03 +08:00
|
|
|
int t = parentItem->results.size();
|
|
|
|
findCount+=t;
|
|
|
|
if (t>0) {
|
|
|
|
fileHitted++;
|
|
|
|
results->results.append(parentItem);
|
|
|
|
}
|
|
|
|
} else if (fileExists(curFilename)) {
|
2021-11-02 13:12:36 +08:00
|
|
|
SynEdit editor;
|
|
|
|
QByteArray realEncoding;
|
|
|
|
editor.lines()->loadFromFile(curFilename,ENCODING_AUTO_DETECT, realEncoding);
|
2021-09-29 20:45:03 +08:00
|
|
|
fileSearched++;
|
2021-11-02 13:12:36 +08:00
|
|
|
PSearchResultTreeItem parentItem = batchFindInEditor(
|
|
|
|
&editor,
|
|
|
|
curFilename,
|
|
|
|
keyword);
|
2021-09-29 20:45:03 +08:00
|
|
|
int t = parentItem->results.size();
|
|
|
|
findCount+=t;
|
|
|
|
if (t>0) {
|
|
|
|
fileHitted++;
|
|
|
|
results->results.append(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2021-11-02 13:12:36 +08:00
|
|
|
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
|
2021-08-05 12:31:53 +08:00
|
|
|
}
|
2021-11-04 21:14:58 +08:00
|
|
|
pMainWindow->showSearchPanel(actionType == SearchAction::ReplaceFiles);
|
2021-08-03 23:55:57 +08:00
|
|
|
}
|
2021-08-02 23:42:10 +08:00
|
|
|
}
|
|
|
|
|
2022-01-24 18:03:35 +08:00
|
|
|
int SearchDialog::execute(SynEdit *editor, const QString &sSearch, const QString &sReplace,
|
|
|
|
SynSearchMathedProc matchCallback,
|
|
|
|
SynSearchConfirmAroundProc confirmAroundCallback)
|
2021-08-02 23:42:10 +08:00
|
|
|
{
|
2021-08-03 23:55:57 +08:00
|
|
|
if (editor==nullptr)
|
|
|
|
return 0;
|
|
|
|
// Modify the caret when using 'from cursor' and when the selection is ignored
|
|
|
|
if (!mSearchOptions.testFlag(ssoEntireScope) && !mSearchOptions.testFlag(ssoSelectedOnly)
|
|
|
|
&& editor->selAvail()) {
|
|
|
|
// start at end of selection
|
|
|
|
if (mSearchOptions.testFlag(ssoBackwards)) {
|
|
|
|
editor->setCaretXY(editor->blockBegin());
|
|
|
|
} else {
|
|
|
|
editor->setCaretXY(editor->blockEnd());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mSearchOptions.testFlag(ssoRegExp)) {
|
|
|
|
mSearchEngine = mRegexSearchEngine;
|
|
|
|
} else {
|
|
|
|
mSearchEngine = mBasicSearchEngine;
|
|
|
|
}
|
|
|
|
|
2021-08-04 09:13:41 +08:00
|
|
|
return editor->searchReplace(sSearch, sReplace, mSearchOptions,
|
2022-01-24 18:03:35 +08:00
|
|
|
mSearchEngine, matchCallback, confirmAroundCallback);
|
2021-08-05 12:31:53 +08:00
|
|
|
}
|
2021-08-03 23:55:57 +08:00
|
|
|
|
2021-11-02 13:12:36 +08:00
|
|
|
std::shared_ptr<SearchResultTreeItem> SearchDialog::batchFindInEditor(SynEdit *e, const QString& filename,const QString &keyword)
|
2021-08-05 12:31:53 +08:00
|
|
|
{
|
|
|
|
//backup
|
|
|
|
BufferCoord caretBackup = e->caretXY();
|
|
|
|
BufferCoord blockBeginBackup = e->blockBegin();
|
|
|
|
BufferCoord blockEndBackup = e->blockEnd();
|
|
|
|
int toplineBackup = e->topLine();
|
|
|
|
int leftCharBackup = e->leftChar();
|
|
|
|
|
|
|
|
PSearchResultTreeItem parentItem = std::make_shared<SearchResultTreeItem>();
|
2021-11-02 13:12:36 +08:00
|
|
|
parentItem->filename = filename;
|
2021-08-05 12:31:53 +08:00
|
|
|
parentItem->parent = nullptr;
|
|
|
|
execute(e,keyword,"",
|
2021-11-02 13:12:36 +08:00
|
|
|
[e,&parentItem, filename](const QString&,
|
2021-08-05 12:31:53 +08:00
|
|
|
const QString&, int Line, int ch, int wordLen){
|
|
|
|
PSearchResultTreeItem item = std::make_shared<SearchResultTreeItem>();
|
2021-11-02 13:12:36 +08:00
|
|
|
item->filename = filename;
|
2021-08-05 12:31:53 +08:00
|
|
|
item->line = Line;
|
|
|
|
item->start = ch;
|
|
|
|
item->len = wordLen;
|
|
|
|
item->parent = parentItem.get();
|
|
|
|
item->text = e->lines()->getString(Line-1);
|
2021-08-05 19:58:32 +08:00
|
|
|
item->text.replace('\t',' ');
|
2021-08-05 12:31:53 +08:00
|
|
|
parentItem->results.append(item);
|
|
|
|
return SynSearchAction::Skip;
|
|
|
|
});
|
|
|
|
|
|
|
|
// restore
|
|
|
|
e->setCaretXY(caretBackup);
|
|
|
|
e->setTopLine(toplineBackup);
|
|
|
|
e->setLeftChar(leftCharBackup);
|
|
|
|
e->setCaretAndSelection(
|
|
|
|
caretBackup,
|
|
|
|
blockBeginBackup,
|
|
|
|
blockEndBackup
|
|
|
|
);
|
|
|
|
return parentItem;
|
2021-08-03 23:55:57 +08:00
|
|
|
}
|
|
|
|
|
2021-08-04 00:17:38 +08:00
|
|
|
QTabBar *SearchDialog::tabBar() const
|
|
|
|
{
|
|
|
|
return mTabBar;
|
|
|
|
}
|
|
|
|
|
2021-08-03 23:55:57 +08:00
|
|
|
PSynSearchBase SearchDialog::searchEngine() const
|
|
|
|
{
|
|
|
|
return mSearchEngine;
|
2021-08-02 23:42:10 +08:00
|
|
|
}
|
2021-08-04 00:17:38 +08:00
|
|
|
|
|
|
|
void SearchDialog::findPrevious()
|
|
|
|
{
|
|
|
|
if (mTabBar->currentIndex()==0) { // it's a find action
|
|
|
|
|
|
|
|
// Disable entire scope searching
|
|
|
|
ui->rbEntireScope->setChecked(false);
|
|
|
|
|
|
|
|
// Always search backward
|
|
|
|
ui->rbBackward->setChecked(true);
|
|
|
|
|
|
|
|
ui->btnExecute->click();
|
|
|
|
}
|
|
|
|
}
|