work save: replace done
This commit is contained in:
parent
590c7adc6e
commit
2be69f0758
|
@ -1296,7 +1296,7 @@
|
|||
<string>Find Previous</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+F3</string>
|
||||
<string>Shift+F3</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
|
|
@ -40,8 +40,18 @@ int SynSearch::findAll(const QString &newText)
|
|||
if (next<0) {
|
||||
break;
|
||||
}
|
||||
mResults.append(next);
|
||||
start = next + newText.length();
|
||||
if (options().testFlag(ssoWholeWord)) {
|
||||
if (((next<=0) || isDelimitChar(newText[next-1]))
|
||||
&&
|
||||
( (start>=newText.length()) || isDelimitChar(newText[start]) )
|
||||
) {
|
||||
mResults.append(next);
|
||||
}
|
||||
} else {
|
||||
mResults.append(next);
|
||||
}
|
||||
|
||||
}
|
||||
return mResults.size();
|
||||
}
|
||||
|
@ -50,3 +60,8 @@ QString SynSearch::replace(const QString &aOccurrence, const QString &aReplaceme
|
|||
{
|
||||
return aReplacement;
|
||||
}
|
||||
|
||||
bool SynSearch::isDelimitChar(QChar ch)
|
||||
{
|
||||
return !(ch == '_' || ch.isLetterOrNumber());
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ public:
|
|||
int resultCount() override;
|
||||
int findAll(const QString &newText) override;
|
||||
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
||||
private:
|
||||
bool isDelimitChar(QChar ch);
|
||||
private:
|
||||
QList<int> mResults;
|
||||
};
|
||||
|
|
|
@ -10,8 +10,6 @@ enum SynSearchOption {
|
|||
ssoBackwards = 0x0004,
|
||||
ssoEntireScope = 0x0008,
|
||||
ssoSelectedOnly = 0x0010,
|
||||
ssoFindAll = 0x0020,
|
||||
ssoPrompt = 0x0040,
|
||||
ssoRegExp = 0x0080
|
||||
};
|
||||
|
||||
|
|
|
@ -4155,29 +4155,27 @@ void SynEdit::setSelText(const QString &Value)
|
|||
mActiveSelectionMode);
|
||||
}
|
||||
|
||||
int SynEdit::search(const QString &ASearch, SynSearchOptions AOptions, PSynSearchBase searchEngine,
|
||||
int SynEdit::searchReplace(const QString &sSearch, const QString &sReplace, SynSearchOptions sOptions, PSynSearchBase searchEngine,
|
||||
SynSearchMathedProc matchedCallback)
|
||||
{
|
||||
if (!searchEngine)
|
||||
return 0;
|
||||
|
||||
// can't search for or replace an empty string
|
||||
if (ASearch.isEmpty()) {
|
||||
if (sSearch.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
// get the text range to search in, ignore the "Search in selection only"
|
||||
// option if nothing is selected
|
||||
bool bBackward = AOptions.testFlag(ssoBackwards);
|
||||
bool bPrompt = AOptions.testFlag(ssoPrompt);
|
||||
bool bFindAll = AOptions.testFlag(ssoFindAll);
|
||||
bool bFromCursor = !AOptions.testFlag(ssoEntireScope);
|
||||
bool bBackward = sOptions.testFlag(ssoBackwards);
|
||||
bool bFromCursor = !sOptions.testFlag(ssoEntireScope);
|
||||
BufferCoord ptCurrent;
|
||||
BufferCoord ptStart;
|
||||
BufferCoord ptEnd;
|
||||
if (!selAvail())
|
||||
AOptions.setFlag(ssoSelectedOnly,false);
|
||||
if (AOptions.testFlag(ssoSelectedOnly)) {
|
||||
sOptions.setFlag(ssoSelectedOnly,false);
|
||||
if (sOptions.testFlag(ssoSelectedOnly)) {
|
||||
ptStart = blockBegin();
|
||||
ptEnd = blockEnd();
|
||||
// search the whole line in the line selection mode
|
||||
|
@ -4212,14 +4210,18 @@ int SynEdit::search(const QString &ASearch, SynSearchOptions AOptions, PSynSearc
|
|||
ptCurrent = ptStart;
|
||||
}
|
||||
// initialize the search engine
|
||||
searchEngine->setOptions(AOptions);
|
||||
searchEngine->setPattern(ASearch);
|
||||
searchEngine->setOptions(sOptions);
|
||||
searchEngine->setPattern(sSearch);
|
||||
// search while the current search position is inside of the search range
|
||||
int nReplaceLen = 0;
|
||||
bool bEndUndoBlock =false;
|
||||
bool dobatchReplace = false;
|
||||
doOnPaintTransient(SynTransientType::ttBefore);
|
||||
{
|
||||
auto action = finally([&,this]{
|
||||
if (dobatchReplace) {
|
||||
decPaintLock();
|
||||
mUndoList->EndBlock();
|
||||
}
|
||||
doOnPaintTransient(SynTransientType::ttAfter);
|
||||
});
|
||||
int i;
|
||||
|
@ -4235,6 +4237,7 @@ int SynEdit::search(const QString &ASearch, SynSearchOptions AOptions, PSynSearc
|
|||
// An occurrence may have been replaced with a text of different length
|
||||
int nFound = searchEngine->result(i) + 1 + iResultOffset;
|
||||
int nSearchLen = searchEngine->length(i);
|
||||
int nReplaceLen = 0;
|
||||
if (bBackward)
|
||||
i--;
|
||||
else
|
||||
|
@ -4245,7 +4248,7 @@ int SynEdit::search(const QString &ASearch, SynSearchOptions AOptions, PSynSearc
|
|||
int first = nFound;
|
||||
int last = nFound + nSearchLen;
|
||||
if ((mActiveSelectionMode == SynSelectionMode::smNormal)
|
||||
|| !AOptions.testFlag(ssoSelectedOnly)) {
|
||||
|| !sOptions.testFlag(ssoSelectedOnly)) {
|
||||
if (((ptCurrent.Line == ptStart.Line) && (first < ptStart.Char)) ||
|
||||
((ptCurrent.Line == ptEnd.Line) && (last > ptEnd.Char)))
|
||||
isInValidSearchRange = false;
|
||||
|
@ -4273,23 +4276,38 @@ int SynEdit::search(const QString &ASearch, SynSearchOptions AOptions, PSynSearc
|
|||
else
|
||||
internalSetCaretXY(ptCurrent);
|
||||
// If it's a search only we can leave the procedure now.
|
||||
if (matchedCallback) {
|
||||
matchedCallback(ASearch,ptCurrent.Line,
|
||||
SynSearchAction searchAction = SynSearchAction::Exit;
|
||||
QString replaceText = searchEngine->replace(selText(), sReplace);
|
||||
if (matchedCallback && !dobatchReplace) {
|
||||
searchAction = matchedCallback(sSearch,replaceText,ptCurrent.Line,
|
||||
nFound,nSearchLen);
|
||||
}
|
||||
if (!bFindAll)
|
||||
if (searchAction==SynSearchAction::Exit) {
|
||||
return result;
|
||||
// fix the caret position and the remaining results
|
||||
// if (!bBackward) {
|
||||
// internalSetCaretX(nFound + nReplaceLen);
|
||||
// if ((nSearchLen != nReplaceLen) && (nAction != SynReplaceAction::raSkip)) {
|
||||
// iResultOffset += nReplaceLen - nSearchLen;
|
||||
// if ((mActiveSelectionMode != SynSelectionMode::smColumn) && (caretY() == ptEnd.Line)) {
|
||||
// ptEnd.Char+=nReplaceLen - nSearchLen;
|
||||
// setBlockEnd(ptEnd);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
} else if (searchAction == SynSearchAction::Skip) {
|
||||
continue;
|
||||
} else if (searchAction == SynSearchAction::Replace
|
||||
|| searchAction == SynSearchAction::ReplaceAll) {
|
||||
if (!dobatchReplace &&
|
||||
(searchAction == SynSearchAction::ReplaceAll) ){
|
||||
incPaintLock();
|
||||
mUndoList->BeginBlock();
|
||||
dobatchReplace = true;
|
||||
}
|
||||
setSelText(replaceText);
|
||||
nReplaceLen = caretX() - nFound;
|
||||
// fix the caret position and the remaining results
|
||||
if (!bBackward) {
|
||||
internalSetCaretX(nFound + nReplaceLen);
|
||||
if ((nSearchLen != nReplaceLen)) {
|
||||
iResultOffset += nReplaceLen - nSearchLen;
|
||||
if ((mActiveSelectionMode != SynSelectionMode::smColumn) && (caretY() == ptEnd.Line)) {
|
||||
ptEnd.Char+=nReplaceLen - nSearchLen;
|
||||
setBlockEnd(ptEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// search next / previous line
|
||||
if (bBackward)
|
||||
|
|
|
@ -100,8 +100,11 @@ Q_DECLARE_FLAGS(SynEditorOptions, SynEditorOption)
|
|||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SynEditorOptions)
|
||||
|
||||
enum class SynReplaceAction {
|
||||
raCancel, raSkip, raReplace, raReplaceAll
|
||||
enum class SynSearchAction {
|
||||
Replace,
|
||||
ReplaceAll,
|
||||
Skip,
|
||||
Exit
|
||||
};
|
||||
|
||||
|
||||
|
@ -125,8 +128,8 @@ using SynPaintProc = std::function<void(const QPaintDevice& paintDevice )>;
|
|||
using SynPreparePaintHighlightTokenProc = std::function<void(int row,
|
||||
int column, const QString& token, PSynHighlighterAttribute attr,
|
||||
SynFontStyles& style, QColor& foreground, QColor& background)>;
|
||||
using SynSearchMathedProc = std::function<void(const QString& ASearch,
|
||||
int Line, int ch, int wordLen)>;
|
||||
using SynSearchMathedProc = std::function<SynSearchAction(const QString& sSearch,
|
||||
const QString& sReplace, int Line, int ch, int wordLen)>;
|
||||
//using SynSpecialLineColorsProc = std::function<void(int Line,
|
||||
// bool& Special, QColor& foreground, QColor& backgroundColor)>;
|
||||
//using SynEditingAreasProc = std::function<void(int Line, SynEditingAreaList& areaList,
|
||||
|
@ -215,7 +218,7 @@ public:
|
|||
PSynEditFoldRange foldHidesLine(int line);
|
||||
void setSelText(const QString& Value);
|
||||
|
||||
int search(const QString& ASearch,SynSearchOptions AOptions,
|
||||
int searchReplace(const QString& sSearch, const QString& sReplace, SynSearchOptions options,
|
||||
PSynSearchBase searchEngine, SynSearchMathedProc matchedCallback = nullptr);
|
||||
|
||||
int maxScrollWidth() const;
|
||||
|
|
|
@ -19,7 +19,6 @@ SearchDialog::SearchDialog(QWidget *parent) :
|
|||
mTabBar->addTab(tr("Find"));
|
||||
mTabBar->addTab(tr("Find in files"));
|
||||
mTabBar->addTab(tr("Replace"));
|
||||
mTabBar->addTab(tr("Replace in files"));
|
||||
mTabBar->setExpanding(false);
|
||||
ui->dialogLayout->insertWidget(0,mTabBar);
|
||||
connect(mTabBar,&QTabBar::currentChanged,this, &SearchDialog::onTabChanged);
|
||||
|
@ -35,7 +34,11 @@ SearchDialog::~SearchDialog()
|
|||
|
||||
void SearchDialog::find(const QString &text)
|
||||
{
|
||||
mTabBar->setCurrentIndex(0);
|
||||
if (mTabBar->currentIndex()==0) {
|
||||
this->onTabChanged();
|
||||
} else {
|
||||
mTabBar->setCurrentIndex(0);
|
||||
}
|
||||
ui->cbFind->setCurrentText(text);
|
||||
show();
|
||||
}
|
||||
|
@ -69,31 +72,22 @@ void SearchDialog::replace(const QString &sFind, const QString &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->lblReplace->setVisible(isreplace);
|
||||
ui->cbReplace->setVisible(isreplace);
|
||||
|
||||
ui->grpOrigin->setVisible(isfind || isreplace);
|
||||
ui->grpOrigin->setEnabled(isfind || isreplace);
|
||||
|
||||
ui->grpScope->setVisible(isfind || isreplace);
|
||||
ui->grpScope->setEnabled(isreplace);
|
||||
ui->grpWhere->setVisible(isfindfiles || isreplacefiles);
|
||||
ui->grpWhere->setEnabled(isfindfiles || isreplacefiles);
|
||||
ui->grpWhere->setVisible(isfindfiles);
|
||||
ui->grpWhere->setEnabled(isfindfiles);
|
||||
ui->grpDirection->setVisible(isfind || isreplace);
|
||||
ui->grpDirection->setEnabled(isfind || isreplace);
|
||||
|
||||
|
@ -106,9 +100,9 @@ void SearchDialog::onTabChanged()
|
|||
// rbOpenFiles.Checked := true;
|
||||
|
||||
// Disable prompt when doing finds
|
||||
ui->chkPrompt->setEnabled(isreplace or isreplacefiles);
|
||||
ui->chkPrompt->setEnabled(isreplace);
|
||||
|
||||
if (isfind || not isfindfiles) {
|
||||
if (isfind || isfindfiles) {
|
||||
ui->btnExecute->setText(tr("Find"));
|
||||
} else {
|
||||
ui->btnExecute->setText(tr("Replace"));
|
||||
|
@ -160,9 +154,6 @@ void SearchDialog::on_btnExecute_clicked()
|
|||
if (ui->chkWholeWord->isChecked()) {
|
||||
mSearchOptions.setFlag(ssoWholeWord);
|
||||
}
|
||||
if (ui->chkPrompt->isChecked()) {
|
||||
mSearchOptions.setFlag(ssoPrompt);
|
||||
}
|
||||
|
||||
// Apply scope, when enabled
|
||||
if (ui->grpScope->isEnabled()) {
|
||||
|
@ -196,8 +187,38 @@ void SearchDialog::on_btnExecute_clicked()
|
|||
if (actionType == SearchAction::Find) {
|
||||
Editor *e = pMainWindow->editorList()->getEditor();
|
||||
if (e!=nullptr) {
|
||||
findcount+=execute(e,SearchAction::Find);
|
||||
findcount+=execute(e,ui->cbFind->currentText(),"");
|
||||
}
|
||||
} else {
|
||||
Editor *e = pMainWindow->editorList()->getEditor();
|
||||
if (e!=nullptr) {
|
||||
bool doPrompt = ui->chkPrompt->isChecked();
|
||||
findcount+=execute(e,ui->cbFind->currentText(),ui->cbReplace->currentText(),
|
||||
[&doPrompt](const QString& sSearch,
|
||||
const QString& sReplace, int Line, int ch, int wordLen){
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// // Replace first, find to next
|
||||
|
@ -359,7 +380,7 @@ void SearchDialog::on_btnExecute_clicked()
|
|||
//end;
|
||||
}
|
||||
|
||||
int SearchDialog::execute(Editor *editor, SearchDialog::SearchAction actionType)
|
||||
int SearchDialog::execute(Editor *editor, const QString &sSearch, const QString &sReplace, SynSearchMathedProc matchCallback)
|
||||
{
|
||||
if (editor==nullptr)
|
||||
return 0;
|
||||
|
@ -380,9 +401,8 @@ int SearchDialog::execute(Editor *editor, SearchDialog::SearchAction actionType)
|
|||
mSearchEngine = mBasicSearchEngine;
|
||||
}
|
||||
|
||||
return editor->search(ui->cbFind->currentText(),
|
||||
mSearchOptions,
|
||||
mSearchEngine);
|
||||
return editor->searchReplace(sSearch, sReplace, mSearchOptions,
|
||||
mSearchEngine, matchCallback);
|
||||
|
||||
|
||||
// // When using find in files, report each find using OnReplaceText
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define SEARCHDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "../qsynedit/SearchBase.h"
|
||||
#include "../qsynedit/SynEdit.h"
|
||||
|
||||
namespace Ui {
|
||||
class SearchDialog;
|
||||
|
@ -29,7 +29,6 @@ public:
|
|||
void findPrevious();
|
||||
void findInFiles(const QString& text);
|
||||
void replace(const QString& sFind, const QString& sReplace);
|
||||
void replaceInFiles(const QString& sFind, const QString& sReplace);
|
||||
PSynSearchBase searchEngine() const;
|
||||
|
||||
QTabBar *tabBar() const;
|
||||
|
@ -42,7 +41,8 @@ private slots:
|
|||
|
||||
void on_btnExecute_clicked();
|
||||
private:
|
||||
int execute(Editor* editor, SearchAction actionType);
|
||||
int execute(Editor* editor, const QString& sSearch,
|
||||
const QString& sReplace, SynSearchMathedProc matchCallback = nullptr);
|
||||
private:
|
||||
Ui::SearchDialog *ui;
|
||||
QTabBar *mTabBar;
|
||||
|
|
Loading…
Reference in New Issue