RedPanda-CPP/RedPandaIDE/widgets/searchdialog.cpp

263 lines
7.9 KiB
C++
Raw Normal View History

2021-08-02 21:58:39 +08:00
#include "searchdialog.h"
#include "ui_searchdialog.h"
#include <QCompleter>
#include <QMessageBox>
#include <memory>
2023-01-11 16:22:26 +08:00
#include <qsynedit/searcher/basicsearcher.h>
#include <qsynedit/searcher/regexsearcher.h>
#include "../utils.h"
#include "../editor.h"
#include "../editorlist.h"
#include "../mainwindow.h"
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),
mSearchOptions()
2021-08-02 21:58:39 +08:00
{
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
2021-08-02 21:58:39 +08:00
ui->setupUi(this);
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<QSynedit::BasicSearcher>();
mRegexSearchEngine = std::make_shared<QSynedit::RegexSearcher>();
ui->cbFind->completer()->setCaseSensitivity(Qt::CaseSensitive);
ui->cbReplace->completer()->setCaseSensitivity(Qt::CaseSensitive);
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(mSearchTabIdx);
if (!text.isEmpty())
ui->cbFind->setCurrentText(text);
ui->btnNext->setFocus();
show();
}
void SearchDialog::replace(const QString &text)
{
mTabBar->setCurrentIndex(mReplaceTabIdx);
if (!text.isEmpty()) {
ui->cbFind->setCurrentText(text);
ui->cbReplace->setCurrentText(text);
}
ui->btnNext->setFocus();
2021-08-02 23:42:10 +08:00
show();
}
void SearchDialog::findNext()
{
doSearch(false);
if (ui->chkCloseAfterSearch->isChecked())
close();
}
void SearchDialog::findPrevious()
2021-08-02 23:42:10 +08:00
{
doSearch(true);
if (ui->chkCloseAfterSearch->isChecked())
close();
2021-08-02 23:42:10 +08:00
}
void SearchDialog::doSearch(bool backward)
2021-08-02 23:42:10 +08:00
{
saveComboHistory(ui->cbFind,ui->cbFind->currentText());
prepareOptions(backward);
2021-08-03 23:55:57 +08:00
Editor *editor = pMainWindow->editorList()->getEditor();
if (editor) {
// Modify the caret when using 'from cursor' and when the selection is ignored
if (!mSearchOptions.testFlag(QSynedit::ssoEntireScope) && !mSearchOptions.testFlag(QSynedit::ssoSelectedOnly)
&& editor->selAvail()) {
// start at end of selection
if (mSearchOptions.testFlag(QSynedit::ssoBackwards)) {
editor->setCaretXY(editor->blockBegin());
} else {
editor->setCaretXY(editor->blockEnd());
}
2021-08-05 12:31:53 +08:00
}
QSynedit::PSynSearchBase searchEngine;
if (mSearchOptions.testFlag(QSynedit::ssoRegExp)) {
searchEngine = mRegexSearchEngine;
2021-08-03 23:55:57 +08:00
} else {
searchEngine = mBasicSearchEngine;
2021-08-03 23:55:57 +08:00
}
editor->searchReplace(
ui->cbFind->currentText(),
"",
mSearchOptions,
searchEngine, nullptr, [this,backward](){
QString msg;
if (backward) {
msg = tr("Beginning of file has been reached. ")
+tr("Do you want to continue from file's end?");
} else {
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;
});
2021-08-03 23:55:57 +08:00
}
2021-08-05 12:31:53 +08:00
}
2021-08-03 23:55:57 +08:00
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)
2021-08-05 12:31:53 +08:00
{
ui->btnNext->setEnabled(!value.isEmpty());
ui->btnPrevious->setEnabled(!value.isEmpty());
ui->btnReplace->setEnabled(!value.isEmpty());
ui->btnReplaceAll->setEnabled(!value.isEmpty());
2021-08-03 23:55:57 +08:00
}
void SearchDialog::on_btnClose_clicked()
{
close();
}
void SearchDialog::on_btnNext_clicked()
{
findNext();
}
void SearchDialog::on_btnPrevious_clicked()
2021-08-03 23:55:57 +08:00
{
findPrevious();
}
void SearchDialog::on_btnReplace_clicked()
{
doReplace(false);
}
void SearchDialog::on_btnReplaceAll_clicked()
{
doReplace(true);
close();
}