Skip to content

Commit

Permalink
Add search option for regular expression based searching
Browse files Browse the repository at this point in the history
Adds regex search mode for use in code editor searching
  • Loading branch information
nyalldawson committed May 13, 2024
1 parent b8cfddd commit 406c67c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,7 @@
<file>themes/default/mIconSearchCaseSensitive.svg</file>
<file>themes/default/mIconSearchWholeWord.svg</file>
<file>themes/default/mIconSearchWrapAround.svg</file>
<file>themes/default/mIconSearchRegex.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/mIconSearchRegex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 26 additions & 5 deletions src/gui/codeeditors/qgscodeeditorwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ QgsCodeEditorWidget::QgsCodeEditorWidget(
mWholeWordButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mIconSearchWholeWord.svg" ) ) );
layoutFind->addWidget( mWholeWordButton );

mRegexButton = new QToolButton( );
mRegexButton->setToolTip( tr( "Use Regular Expressions" ) );
mRegexButton->setCheckable( true );
mRegexButton->setAutoRaise( true );
mRegexButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mIconSearchRegex.svg" ) ) );
layoutFind->addWidget( mRegexButton );

mWrapAroundButton = new QToolButton();
mWrapAroundButton->setToolTip( tr( "Wrap Around" ) );
mWrapAroundButton->setCheckable( true );
Expand All @@ -102,7 +109,8 @@ QgsCodeEditorWidget::QgsCodeEditorWidget(
connect( mFindNextButton, &QToolButton::clicked, this, &QgsCodeEditorWidget::findNext );
connect( mFindPrevButton, &QToolButton::clicked, this, &QgsCodeEditorWidget::findPrevious );
connect( mCaseSensitiveButton, &QToolButton::toggled, this, &QgsCodeEditorWidget::updateSearch );
connect( mCaseSensitiveButton, &QToolButton::toggled, this, &QgsCodeEditorWidget::updateSearch );
connect( mWholeWordButton, &QToolButton::toggled, this, &QgsCodeEditorWidget::updateSearch );
connect( mRegexButton, &QToolButton::toggled, this, &QgsCodeEditorWidget::updateSearch );
connect( mWrapAroundButton, &QCheckBox::toggled, this, &QgsCodeEditorWidget::updateSearch );

QShortcut *findShortcut = new QShortcut( QKeySequence::StandardKey::Find, mEditor );
Expand Down Expand Up @@ -255,17 +263,30 @@ void QgsCodeEditorWidget::addSearchHighlights()
mHighlightController->setLineHeight( QFontMetrics( mEditor->font() ).lineSpacing() );
mHighlightController->setVisibleRange( mEditor->viewport()->rect().height() );

int searchFlags = 0;
const bool isRegEx = mRegexButton->isChecked();
const bool isCaseSensitive = mCaseSensitiveButton->isChecked();
const bool isWholeWordOnly = mWholeWordButton->isChecked();
if ( isRegEx )
searchFlags |= QsciScintilla::SCFIND_REGEXP | QsciScintilla::SCFIND_CXX11REGEX;
if ( isCaseSensitive )
searchFlags |= QsciScintilla::SCFIND_MATCHCASE;
if ( isWholeWordOnly )
searchFlags |= QsciScintilla::SCFIND_WHOLEWORD;
mEditor->SendScintilla( QsciScintilla::SCI_SETSEARCHFLAGS, searchFlags );
while ( true )
{
mEditor->SendScintilla( QsciScintilla::SCI_SETTARGETRANGE, startPos, docEnd );
const int fstart = mEditor->SendScintilla( QsciScintilla::SCI_SEARCHINTARGET, searchString.length(), searchString.toLocal8Bit().constData() );
if ( fstart < 0 )
break;

startPos = fstart + searchString.length();
const int matchLength = mEditor->SendScintilla( QsciScintilla::SCI_GETTARGETTEXT, 0, static_cast< void * >( nullptr ) );

startPos = fstart + matchLength;

mEditor->SendScintilla( QsciScintilla::SCI_SETINDICATORCURRENT, QgsCodeEditor::SEARCH_RESULT_INDICATOR );
mEditor->SendScintilla( QsciScintilla::SCI_INDICATORFILLRANGE, fstart, searchString.length() );
mEditor->SendScintilla( QsciScintilla::SCI_INDICATORFILLRANGE, fstart, matchLength );

int thisLine = 0;
int thisIndex = 0;
Expand Down Expand Up @@ -310,13 +331,13 @@ void QgsCodeEditorWidget::findText( bool forward, bool findFirst, bool showNotFo
index = indexFrom;
}

const bool isRegEx = false;
const bool isRegEx = mRegexButton->isChecked();
const bool wrapAround = mWrapAroundButton->isChecked();
const bool isCaseSensitive = mCaseSensitiveButton->isChecked();
const bool isWholeWordOnly = mWholeWordButton->isChecked();

const bool found = mEditor->findFirst( searchString, isRegEx, isCaseSensitive, isWholeWordOnly, wrapAround, forward,
line, index );
line, index, true, true, isRegEx );

if ( !found )
{
Expand Down
2 changes: 2 additions & 0 deletions src/gui/codeeditors/qgscodeeditorwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget

void clearSearchHighlights();
void addSearchHighlights();
int searchFlags() const;
void findText( bool forward, bool findFirst, bool showNotFoundWarning = false );

enum HighlightCategory
Expand All @@ -143,6 +144,7 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget
QToolButton *mFindNextButton = nullptr;
QToolButton *mCaseSensitiveButton = nullptr;
QToolButton *mWholeWordButton = nullptr;
QToolButton *mRegexButton = nullptr;
QToolButton *mWrapAroundButton = nullptr;
int mBlockSearching = 0;
QgsMessageBar *mMessageBar = nullptr;
Expand Down

0 comments on commit 406c67c

Please sign in to comment.