Skip to content

Commit a136995

Browse files
committed
allow to search and higlight options
1 parent f3102bb commit a136995

File tree

4 files changed

+242
-1
lines changed

4 files changed

+242
-1
lines changed

src/app/qgsoptions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ void QgsOptions::iconSizeChanged( const QString &iconSize )
10231023
QgisApp::instance()->setIconSizes( iconSize.toInt() );
10241024
}
10251025

1026+
10261027
void QgsOptions::uiThemeChanged( const QString &theme )
10271028
{
10281029
if ( theme == QgsApplication::themeName() )

src/gui/qgsoptionsdialogbase.cpp

Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,26 @@
1616

1717
#include "qgsoptionsdialogbase.h"
1818

19+
#include <QCheckBox>
1920
#include <QDialog>
2021
#include <QDialogButtonBox>
22+
#include <QGroupBox>
23+
#include <QLabel>
2124
#include <QLayout>
2225
#include <QListWidget>
26+
#include <QListWidgetItem>
2327
#include <QMessageBox>
28+
#include <QPainter>
2429
#include <QScrollBar>
25-
#include <QStackedWidget>
2630
#include <QSplitter>
31+
#include <QStackedWidget>
2732
#include <QTimer>
2833

2934

35+
#include "qgsfilterlineedit.h"
36+
37+
#include "qgslogger.h"
38+
3039
QgsOptionsDialogBase::QgsOptionsDialogBase( const QString& settingsKey, QWidget* parent, Qt::WindowFlags fl, QSettings* settings )
3140
: QDialog( parent, fl )
3241
, mOptsKey( settingsKey )
@@ -35,6 +44,7 @@ QgsOptionsDialogBase::QgsOptionsDialogBase( const QString& settingsKey, QWidget*
3544
, mOptStackedWidget( nullptr )
3645
, mOptSplitter( nullptr )
3746
, mOptButtonBox( nullptr )
47+
, mSearchLineEdit( nullptr )
3848
, mDialogTitle( QLatin1String( "" ) )
3949
, mIconOnly( false )
4050
, mSettings( settings )
@@ -92,6 +102,7 @@ void QgsOptionsDialogBase::initOptionsBase( bool restoreUi, const QString& title
92102
mOptSplitter = findChild<QSplitter*>( QStringLiteral( "mOptionsSplitter" ) );
93103
mOptButtonBox = findChild<QDialogButtonBox*>( QStringLiteral( "buttonBox" ) );
94104
QFrame* buttonBoxFrame = findChild<QFrame*>( QStringLiteral( "mButtonBoxFrame" ) );
105+
mSearchLineEdit = findChild<QgsFilterLineEdit*>( "mSearchLineEdit" );
95106

96107
if ( !mOptListWidget || !mOptStackedWidget || !mOptSplitter || !optionsFrame )
97108
{
@@ -130,6 +141,12 @@ void QgsOptionsDialogBase::initOptionsBase( bool restoreUi, const QString& title
130141
connect( mOptStackedWidget, SIGNAL( currentChanged( int ) ), this, SLOT( optionsStackedWidget_CurrentChanged( int ) ) );
131142
connect( mOptStackedWidget, SIGNAL( widgetRemoved( int ) ), this, SLOT( optionsStackedWidget_WidgetRemoved( int ) ) );
132143

144+
if ( mSearchLineEdit )
145+
{
146+
mSearchLineEdit->setShowSearchIcon( true );
147+
connect( mSearchLineEdit, &QgsFilterLineEdit::textChanged, this, &QgsOptionsDialogBase::searchText );
148+
}
149+
133150
mInit = true;
134151

135152
if ( restoreUi )
@@ -196,6 +213,70 @@ void QgsOptionsDialogBase::restoreOptionsBaseUi( const QString& title )
196213
mOptListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );
197214
}
198215

216+
void QgsOptionsDialogBase::searchText( QString text )
217+
{
218+
if ( !mOptStackedWidget )
219+
return;
220+
221+
mOptStackedWidget->show();
222+
if ( mOptButtonBox )
223+
mOptButtonBox->show();
224+
// hide all page if text has to be search, show them all otherwise
225+
for ( int r = 0; r < mOptListWidget->count(); ++r )
226+
{
227+
mOptListWidget->setRowHidden( r, !text.isEmpty() );
228+
}
229+
230+
QPair< QgsSearchHighlightOptionWidget, int > rsw;
231+
Q_FOREACH ( rsw, mRegisteredSearchWidgets )
232+
{
233+
rsw.first.reset();
234+
if ( !text.isEmpty() && rsw.first.searchHighlight( text ) )
235+
{
236+
QgsDebugMsg( QString( "Found %1 in %2 (tab: %3)" )
237+
.arg( text )
238+
.arg( rsw.first.widgetName() )
239+
.arg( mOptListWidget->item( rsw.second )->text() ) );
240+
mOptListWidget->setRowHidden( rsw.second, false );
241+
}
242+
}
243+
244+
if ( mOptListWidget->isRowHidden( mOptStackedWidget->currentIndex() ) )
245+
{
246+
for ( int r = 0; r < mOptListWidget->count(); ++r )
247+
{
248+
if ( !mOptListWidget->isRowHidden( r ) )
249+
{
250+
mOptListWidget->setCurrentRow( r );
251+
return;
252+
}
253+
}
254+
255+
// if no page can be shown, hide stack widget
256+
mOptStackedWidget->hide();
257+
if ( mOptButtonBox )
258+
mOptButtonBox->hide();
259+
}
260+
}
261+
262+
void QgsOptionsDialogBase::registerTextSearch()
263+
{
264+
mRegisteredSearchWidgets.clear();
265+
266+
for ( int i = 0; i < mOptStackedWidget->count(); i++ )
267+
{
268+
Q_FOREACH ( QWidget* w, mOptStackedWidget->widget( i )->findChildren<QWidget*>() )
269+
{
270+
QgsSearchHighlightOptionWidget shw = QgsSearchHighlightOptionWidget( w );
271+
QgsDebugMsg( QString( "Registering: %1 %2" ).arg( w->objectName() ).arg( shw.isValid() ? "valid" : "invalid" ) );
272+
if ( shw.isValid() )
273+
{
274+
mRegisteredSearchWidgets.append( qMakePair( shw, i ) );
275+
}
276+
}
277+
}
278+
}
279+
199280
void QgsOptionsDialogBase::showEvent( QShowEvent* e )
200281
{
201282
if ( mInit )
@@ -208,6 +289,11 @@ void QgsOptionsDialogBase::showEvent( QShowEvent* e )
208289
QTimer::singleShot( 0, this, SLOT( warnAboutMissingObjects() ) );
209290
}
210291

292+
if ( mSearchLineEdit )
293+
{
294+
registerTextSearch();
295+
}
296+
211297
QDialog::showEvent( e );
212298
}
213299

@@ -281,6 +367,8 @@ void QgsOptionsDialogBase::optionsStackedWidget_WidgetRemoved( int indx )
281367
{
282368
// will need to take item first, if widgets are set for item in future
283369
delete mOptListWidget->item( indx );
370+
371+
registerTextSearch();
284372
}
285373

286374
void QgsOptionsDialogBase::warnAboutMissingObjects()
@@ -292,3 +380,91 @@ void QgsOptionsDialogBase::warnAboutMissingObjects()
292380
QMessageBox::Ok,
293381
QMessageBox::Ok );
294382
}
383+
384+
385+
QgsSearchHighlightOptionWidget::QgsSearchHighlightOptionWidget( QWidget* widget )
386+
: mWidget( nullptr )
387+
, mOriginalPalette( QPalette() )
388+
, mColorRole( QPalette::Window )
389+
, mColor( Qt::yellow )
390+
, mText( [=]( QWidget* ) {return QString();} )
391+
{
392+
if ( !widget )
393+
{
394+
return;
395+
}
396+
397+
if ( qobject_cast<QLabel*>( widget ) )
398+
{
399+
mColorRole = QPalette::Window;
400+
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QLabel*>( widget )->text() : QString(); };
401+
}
402+
else if ( qobject_cast<QCheckBox*>( widget ) )
403+
{
404+
mColorRole = QPalette::Button;
405+
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QCheckBox*>( widget )->text() : QString(); };
406+
}
407+
else if ( qobject_cast<QGroupBox*>( widget ) )
408+
{
409+
mColorRole = QPalette::WindowText;
410+
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QGroupBox*>( widget )->title() : QString(); };
411+
}
412+
else
413+
{
414+
return;
415+
}
416+
mWidget = widget;
417+
mOriginalPalette = mWidget->palette();
418+
}
419+
420+
QgsSearchHighlightOptionWidget::~QgsSearchHighlightOptionWidget()
421+
{
422+
}
423+
424+
bool QgsSearchHighlightOptionWidget::isValid()
425+
{
426+
return mWidget;
427+
}
428+
429+
bool QgsSearchHighlightOptionWidget::searchHighlight( QString searchText )
430+
{
431+
bool found = false;
432+
if ( !mWidget )
433+
return found;
434+
435+
if ( !searchText.isEmpty() )
436+
{
437+
QString origText = mText( mWidget );
438+
if ( origText.contains( searchText, Qt::CaseInsensitive ) )
439+
{
440+
found = true;
441+
}
442+
}
443+
444+
if ( found )
445+
{
446+
QPalette pal( mOriginalPalette );
447+
pal.setColor( mColorRole, mColor );
448+
449+
mWidget->setAutoFillBackground( true );
450+
mWidget->setPalette( pal );
451+
}
452+
453+
return found;
454+
}
455+
456+
void QgsSearchHighlightOptionWidget::reset()
457+
{
458+
if ( mWidget )
459+
{
460+
mWidget->setPalette( mOriginalPalette );
461+
}
462+
}
463+
464+
QString QgsSearchHighlightOptionWidget::widgetName()
465+
{
466+
QString name;
467+
if ( mWidget )
468+
name = mWidget->objectName();
469+
return name;
470+
}

src/gui/qgsoptionsdialogbase.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,50 @@
1818
#define QGSOPTIONSDIALOGBASE_H
1919

2020
#include "qgisgui.h"
21+
#include <functional>
2122

2223
#include <QDialog>
2324
#include <QPointer>
2425
#include <QSettings>
26+
#include <QStyledItemDelegate>
2527
#include "qgis_gui.h"
2628

29+
2730
class QDialogButtonBox;
2831
class QListWidget;
32+
class QModelIndex;
33+
class QPalette;
34+
class QPainter;
2935
class QStackedWidget;
36+
class QStyleOptionViewItem;
3037
class QSplitter;
3138

39+
class QgsFilterLineEdit;
40+
41+
42+
class GUI_EXPORT QgsSearchHighlightOptionWidget
43+
{
44+
public:
45+
explicit QgsSearchHighlightOptionWidget( QWidget* widget = 0 );
46+
~QgsSearchHighlightOptionWidget();
47+
48+
bool isValid();
49+
50+
bool searchHighlight( QString searchText );
51+
52+
void reset();
53+
54+
QString widgetName();
55+
56+
private:
57+
QWidget* mWidget;
58+
QPalette mOriginalPalette;
59+
QPalette::ColorRole mColorRole;
60+
QColor mColor;
61+
std::function < QString( QWidget* ) > mText;
62+
};
63+
64+
3265
/** \ingroup gui
3366
* \class QgsOptionsDialogBase
3467
* A base dialog for options and properties dialogs that offers vertical tabs.
@@ -80,6 +113,14 @@ class GUI_EXPORT QgsOptionsDialogBase : public QDialog
80113
*/
81114
bool iconOnly() {return mIconOnly;}
82115

116+
public slots:
117+
118+
/**
119+
* searchText searches for a text in all the pages of the stacked widget and highlight the results
120+
* @param text the text to search
121+
*/
122+
void searchText( QString text );
123+
83124
protected slots:
84125
void updateOptionsListVerticalTabs();
85126
void optionsStackedWidget_CurrentChanged( int indx );
@@ -92,12 +133,17 @@ class GUI_EXPORT QgsOptionsDialogBase : public QDialog
92133

93134
virtual void updateWindowTitle();
94135

136+
void registerTextSearch();
137+
138+
QList< QPair< QgsSearchHighlightOptionWidget, int > > mRegisteredSearchWidgets;
139+
95140
QString mOptsKey;
96141
bool mInit;
97142
QListWidget* mOptListWidget;
98143
QStackedWidget* mOptStackedWidget;
99144
QSplitter* mOptSplitter;
100145
QDialogButtonBox* mOptButtonBox;
146+
QgsFilterLineEdit* mSearchLineEdit;
101147
QString mDialogTitle;
102148
bool mIconOnly;
103149
// pointer to app or custom, external QSettings

src/ui/qgsoptionsbase.ui

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
<property name="bottomMargin">
5858
<number>0</number>
5959
</property>
60+
<item>
61+
<widget class="QgsFilterLineEdit" name="mSearchLineEdit"/>
62+
</item>
6063
<item>
6164
<widget class="QListWidget" name="mOptionsListWidget">
6265
<property name="minimumSize">
@@ -1806,6 +1809,16 @@
18061809
</property>
18071810
</widget>
18081811
</item>
1812+
<item>
1813+
<widget class="QCheckBox" name="cbxEvaluateDefaultValues">
1814+
<property name="toolTip">
1815+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When digitizing a new feature, default values are retrieved from the database. With this option turned on, the default values will be evaluated at the time of digitizing. With this option turned off, the default values will be evaluated at the time of saving.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
1816+
</property>
1817+
<property name="text">
1818+
<string>Evaluate default values</string>
1819+
</property>
1820+
</widget>
1821+
</item>
18091822
</layout>
18101823
</widget>
18111824
</item>
@@ -5466,6 +5479,11 @@
54665479
<header>qgsautheditorwidgets.h</header>
54675480
<container>1</container>
54685481
</customwidget>
5482+
<customwidget>
5483+
<class>QgsFilterLineEdit</class>
5484+
<extends>QLineEdit</extends>
5485+
<header>qgsfilterlineedit.h</header>
5486+
</customwidget>
54695487
</customwidgets>
54705488
<tabstops>
54715489
<tabstop>mOptionsListWidget</tabstop>

0 commit comments

Comments
 (0)