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"
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
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"));
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(0);
|
|
|
|
ui->cbFind->setCurrentText(text);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::findInFiles(const QString &text)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(1);
|
|
|
|
ui->cbFind->setCurrentText(text);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::replace(const QString &sFind, const QString &sReplace)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(2);
|
|
|
|
ui->cbFind->setCurrentText(sFind);
|
|
|
|
ui->cbReplace->setCurrentText(sReplace);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::replaceInFiles(const QString &sFind, const QString &sReplace)
|
|
|
|
{
|
|
|
|
mTabBar->setCurrentIndex(3);
|
|
|
|
ui->cbFind->setCurrentText(sFind);
|
|
|
|
ui->cbReplace->setCurrentText(sReplace);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchDialog::onTabChanged()
|
|
|
|
{
|
|
|
|
bool isfind = (mTabBar->currentIndex() == 0);
|
|
|
|
bool isfindfiles = (mTabBar->currentIndex() == 1);
|
|
|
|
bool isreplace = (mTabBar->currentIndex() == 2);
|
|
|
|
bool isreplacefiles = (mTabBar->currentIndex() == 3);
|
|
|
|
|
|
|
|
ui->lblReplace->setVisible(isreplace || isreplacefiles);
|
|
|
|
ui->cbReplace->setVisible(isreplace || isreplacefiles);
|
|
|
|
|
|
|
|
ui->grpOrigin->setVisible(isfind || isreplace);
|
|
|
|
ui->grpScope->setVisible(isfind || isreplace);
|
|
|
|
ui->grpWhere->setVisible(isfindfiles || isreplacefiles);
|
|
|
|
ui->grpDirection->setVisible(isfind || isreplace);
|
|
|
|
// grpOption is always visible
|
|
|
|
|
|
|
|
// Disable project search option when none is open
|
|
|
|
// rbProjectFiles.Enabled := Assigned(MainForm.Project);
|
|
|
|
ui->rbProject->setEnabled(false);
|
|
|
|
// if not Assigned(MainForm.Project) then
|
|
|
|
// rbOpenFiles.Checked := true;
|
|
|
|
|
|
|
|
// Disable prompt when doing finds
|
|
|
|
ui->chkPrompt->setEnabled(isreplace or isreplacefiles);
|
|
|
|
|
|
|
|
if (isfind || not isfindfiles) {
|
|
|
|
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-08-03 23:55:57 +08:00
|
|
|
void SearchDialog::on_btnExecute_clicked()
|
2021-08-02 23:42:10 +08:00
|
|
|
{
|
2021-08-03 23:55:57 +08:00
|
|
|
int findcount = 0;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
if (ui->chkPrompt->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoPrompt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply scope, when visible
|
|
|
|
if (ui->grpScope->isVisible()) {
|
|
|
|
if (ui->rbSelection->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoSelectedOnly);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply direction, when visible
|
|
|
|
if (ui->grpDirection->isVisible()) {
|
|
|
|
if (ui->rbBackward->isChecked()) {
|
|
|
|
mSearchOptions.setFlag(ssoBackwards);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply origin, when visible
|
|
|
|
if (ui->grpOrigin->isVisible()) {
|
|
|
|
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) {
|
|
|
|
findcount+=execute(e,SearchAction::Find);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// // Replace first, find to next
|
|
|
|
//end else if actiontype = faReplace then begin
|
|
|
|
// e := MainForm.EditorList.GetEditor;
|
|
|
|
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// Inc(findcount, Execute(e.Text, faReplace));
|
|
|
|
// if findcount > 0 then begin
|
|
|
|
// Exclude(fSearchOptions, ssoReplace);
|
|
|
|
// Inc(findcount, Execute(e.Text, faFind));
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
// // Or find everything
|
|
|
|
//end else if actiontype = faFindFiles then begin
|
|
|
|
// fileSearched:=0;
|
|
|
|
// fileHitted:=0;
|
|
|
|
// MainForm.FindOutput.BeginFind(cboFindText.Text);
|
|
|
|
// try
|
|
|
|
|
|
|
|
// // loop through pagecontrol
|
|
|
|
// if rbOpenFiles.Checked then begin
|
|
|
|
|
|
|
|
// // loop through editors, add results to message control
|
|
|
|
// for I := 0 to MainForm.EditorList.PageCount - 1 do begin
|
|
|
|
// e := MainForm.EditorList[i];
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// inc(fileSearched);
|
|
|
|
// fCurFile := e.FileName;
|
|
|
|
// t:=Execute(e.Text, actiontype);
|
|
|
|
// Inc(findcount, t);
|
|
|
|
// if t>0 then
|
|
|
|
// inc(filehitted);
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
|
|
|
|
// // loop through project
|
|
|
|
// end else if rbProjectFiles.Checked then begin
|
|
|
|
// for I := 0 to MainForm.Project.Units.Count - 1 do begin
|
|
|
|
// e := MainForm.Project.Units[i].Editor;
|
|
|
|
// fCurFile := MainForm.Project.Units[i].FileName;
|
|
|
|
|
|
|
|
// // file is already open, use memory
|
|
|
|
// if Assigned(e) then begin begin
|
|
|
|
// inc(fileSearched);
|
|
|
|
// t:=Execute(e.Text, actiontype);
|
|
|
|
// Inc(findcount, t);
|
|
|
|
// if t>0 then
|
|
|
|
// inc(filehitted);
|
|
|
|
// end;
|
|
|
|
|
|
|
|
// // not open? load from disk
|
|
|
|
// end else if FileExists(fCurFile) then begin
|
|
|
|
// // Only finding...
|
|
|
|
// fTempSynEdit.Lines.LoadFromFile(fCurFile);
|
|
|
|
// inc(fileSearched);
|
|
|
|
// t:=Execute(fTempSynEdit, actiontype);
|
|
|
|
// Inc(findcount, t);
|
|
|
|
// if t>0 then
|
|
|
|
// inc(filehitted);
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
|
|
|
|
// // Don't loop, only pass single file
|
|
|
|
// end else if rbCurFile.Checked then begin
|
|
|
|
// e := MainForm.EditorList.GetEditor;
|
|
|
|
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
|
|
|
|
// fCurFile := e.FileName;
|
|
|
|
|
|
|
|
// inc(fileSearched);
|
|
|
|
// t:=Execute(e.Text, actiontype);
|
|
|
|
// Inc(findcount, t);
|
|
|
|
// if t>0 then
|
|
|
|
// inc(filehitted);
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
// finally
|
|
|
|
// MainForm.FindOutput.EndFind(cboFindText.Text,findCount,
|
|
|
|
// filehitted,filesearched);
|
|
|
|
// end;
|
|
|
|
//end else if actiontype = faReplaceFiles then begin
|
|
|
|
// // loop through pagecontrol
|
|
|
|
// if rbOpenFiles.Checked then begin
|
|
|
|
|
|
|
|
// // loop through editors, add results to message control
|
|
|
|
// for I := 0 to MainForm.EditorList.PageCount - 1 do begin
|
|
|
|
// e := MainForm.EditorList[i];
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// fCurFile := e.FileName;
|
|
|
|
// if (ssoPrompt in fSearchOptions) then
|
|
|
|
// e.Activate;
|
|
|
|
// Inc(findcount, Execute(e.Text, actiontype));
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
|
|
|
|
// // loop through project
|
|
|
|
// end else if rbProjectFiles.Checked then begin
|
|
|
|
// for I := 0 to MainForm.Project.Units.Count - 1 do begin
|
|
|
|
// e := MainForm.Project.Units[i].Editor;
|
|
|
|
// fCurFile := MainForm.Project.Units[i].FileName;
|
|
|
|
|
|
|
|
// // file is already open, use memory
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// if (ssoPrompt in fSearchOptions) then
|
|
|
|
// e.Activate;
|
|
|
|
// Inc(findcount, Execute(e.Text, actiontype));
|
|
|
|
|
|
|
|
// // not open? load from disk
|
|
|
|
// end else if FileExists(fCurFile) then begin
|
|
|
|
// // we have to open an editor...
|
|
|
|
// if ssoPrompt in fSearchOptions then begin
|
|
|
|
// e := MainForm.EditorList.GetEditorFromFileName(fCurFile);
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// e.Activate;
|
|
|
|
|
|
|
|
// Inc(findcount, Execute(e.Text, actiontype));
|
|
|
|
|
|
|
|
// // Save and close
|
|
|
|
// e.Save;
|
|
|
|
// MainForm.Project.CloseUnit(MainForm.Project.Units.Indexof(e));
|
|
|
|
// end;
|
|
|
|
// end else begin
|
|
|
|
// // Stealth replace
|
|
|
|
// fTempSynEdit.Lines.LoadFromFile(fCurFile);
|
|
|
|
// Inc(findcount, Execute(fTempSynEdit, actiontype));
|
|
|
|
// fTempSynEdit.Lines.SaveToFile(fCurFile);
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
// // Don't loop, only pass single file
|
|
|
|
// end else if rbCurFile.Checked then begin
|
|
|
|
// e := MainForm.EditorList.GetEditor;
|
|
|
|
|
|
|
|
// if Assigned(e) then begin
|
|
|
|
// fCurFile := e.FileName;
|
|
|
|
// Inc(findcount, Execute(e.Text, actiontype));
|
|
|
|
// end;
|
|
|
|
// end;
|
|
|
|
//end;
|
|
|
|
|
|
|
|
//if actiontype = faFindFiles then begin
|
|
|
|
// MainForm.MessageControl.ActivePageIndex := 4; // Find Tab
|
|
|
|
// if findcount > 0 then
|
|
|
|
// MainForm.FindSheet.Caption := Lang[ID_SHEET_FIND];
|
|
|
|
// MainForm.OpenCloseMessageSheet(TRUE);
|
|
|
|
// self.Close;
|
|
|
|
//end else if findcount = 0 then begin
|
|
|
|
// MessageBox(
|
|
|
|
// Self.Handle,
|
|
|
|
// PAnsiChar(Format(Lang[ID_MSG_TEXTNOTFOUND], [cboFindText.Text])),
|
|
|
|
// PAnsiChar(Lang[ID_INFO]),
|
|
|
|
// MB_ICONINFORMATION or MB_TOPMOST);
|
|
|
|
// cboFindText.SetFocus;
|
|
|
|
//end;
|
|
|
|
//if actiontype = faFind then begin
|
|
|
|
// self.Close;
|
|
|
|
//end;
|
2021-08-02 23:42:10 +08:00
|
|
|
}
|
|
|
|
|
2021-08-03 23:55:57 +08:00
|
|
|
int SearchDialog::execute(Editor *editor, SearchDialog::SearchAction actionType)
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return editor->search(ui->cbFind->currentText(),
|
|
|
|
mSearchOptions,
|
|
|
|
mSearchEngine);
|
|
|
|
|
2021-08-02 23:42:10 +08:00
|
|
|
|
2021-08-03 23:55:57 +08:00
|
|
|
// // When using find in files, report each find using OnReplaceText
|
|
|
|
// if action = faFindFiles then
|
|
|
|
// editor.OnReplaceText := FindAllAction;
|
|
|
|
|
|
|
|
// // Swap search engire for ours
|
|
|
|
// if (ssoRegExp in fSearchOptions) then
|
|
|
|
// editor.SearchEngine := fRegExpSearchEngine
|
|
|
|
// else
|
|
|
|
// editor.SearchEngine := fSearchEngine;
|
|
|
|
// result := editor.SearchReplace(cboFindText.Text, cboReplaceText.Text, fSearchOptions);
|
|
|
|
|
|
|
|
// // Don't touch editors which we are only scanning
|
|
|
|
// if action in [faFindFiles] then begin
|
|
|
|
// // Put backup back into place
|
|
|
|
// editor.CaretXY := caretbackup;
|
|
|
|
// editor.BlockBegin := blockbeginbackup;
|
|
|
|
// editor.BlockEnd := blockendbackup;
|
|
|
|
// editor.TopLine := toplinebackup;
|
|
|
|
// end;
|
|
|
|
|
|
|
|
// editor.OnReplaceText := onreplacebackup;
|
|
|
|
// editor.SearchEngine := enginebackup;
|
|
|
|
}
|
|
|
|
|
|
|
|
PSynSearchBase SearchDialog::searchEngine() const
|
|
|
|
{
|
|
|
|
return mSearchEngine;
|
2021-08-02 23:42:10 +08:00
|
|
|
}
|