Skip to content

Commit 49090a5

Browse files
klavspcnyalldawson
authored andcommittedMay 14, 2018
[FEATURE][locator] Add search for settings pages to locator bar (#6625)
* [FEATURE][locator] Add search for settings pages to locator bar Search Settings, Options, and Project Properties pages. Double clicking a search result will open the correct page and tab. Short video: https://www.youtube.com/watch?v=duB2YekUmV0 The new filter presents itself with a prefix of "s" and with tr( "Settings" ) as displayname. A settings locator filter is added to the built in locator filters (class QgsSettingsLocatorFilter is added to qgsinbuiltlocatorfilters.cpp). The wiring between the new filter and QgsApp has been implemented in: For reading misc. pages: * QgisApp::getProjectPropertiesPagesMap(), * QgisApp::getSettingPagesMap(), and * QgisApp::getOptionsPagesMap() For navigating to selected page * QgisApp::showProjectProperties( const QString &page ) and * QgisApp::showSettings( const QString &page ) * Implement requested changes * Implement required changes
1 parent 3ea6432 commit 49090a5

File tree

9 files changed

+261
-9
lines changed

9 files changed

+261
-9
lines changed
 

‎src/app/locator/qgsinbuiltlocatorfilters.cpp

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,94 @@ void QgsExpressionCalculatorLocatorFilter::triggerResult( const QgsLocatorResult
339339
{
340340
QApplication::clipboard()->setText( result.userData.toString() );
341341
}
342+
343+
// SettingsLocatorFilter
344+
//
345+
QgsSettingsLocatorFilter::QgsSettingsLocatorFilter( QObject *parent )
346+
: QgsLocatorFilter( parent )
347+
{}
348+
349+
QgsSettingsLocatorFilter *QgsSettingsLocatorFilter::clone() const
350+
{
351+
return new QgsSettingsLocatorFilter();
352+
}
353+
354+
void QgsSettingsLocatorFilter::fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback * )
355+
{
356+
QMap<QString, QMap<QString, QString>> matchingSettingsPagesMap;
357+
358+
QMap<QString, QString> optionsPagesMap = QgisApp::instance()->optionsPagesMap();
359+
for ( auto optionsPagesIterator = optionsPagesMap.constBegin(); optionsPagesIterator != optionsPagesMap.constEnd(); ++optionsPagesIterator )
360+
{
361+
QString title = optionsPagesIterator.key();
362+
if ( stringMatches( title, string ) || ( context.usingPrefix && string.isEmpty() ) )
363+
{
364+
matchingSettingsPagesMap.insert( title + " (" + tr( "Options" ) + ")", settingsPage( QStringLiteral( "optionpage" ), optionsPagesIterator.value() ) );
365+
}
366+
}
367+
368+
QMap<QString, QString> projectPropertyPagesMap = QgisApp::instance()->projectPropertiesPagesMap();
369+
for ( auto projectPropertyPagesIterator = projectPropertyPagesMap.constBegin(); projectPropertyPagesIterator != projectPropertyPagesMap.constEnd(); ++projectPropertyPagesIterator )
370+
{
371+
QString title = projectPropertyPagesIterator.key();
372+
if ( stringMatches( title, string ) || ( context.usingPrefix && string.isEmpty() ) )
373+
{
374+
matchingSettingsPagesMap.insert( title + " (" + tr( "Project Properties" ) + ")", settingsPage( QStringLiteral( "projectpropertypage" ), projectPropertyPagesIterator.value() ) );
375+
}
376+
}
377+
378+
QMap<QString, QString> settingPagesMap = QgisApp::instance()->settingPagesMap();
379+
for ( auto settingPagesIterator = settingPagesMap.constBegin(); settingPagesIterator != settingPagesMap.constEnd(); ++settingPagesIterator )
380+
{
381+
QString title = settingPagesIterator.key();
382+
if ( stringMatches( title, string ) || ( context.usingPrefix && string.isEmpty() ) )
383+
{
384+
matchingSettingsPagesMap.insert( title, settingsPage( QStringLiteral( "settingspage" ), settingPagesIterator.value() ) );
385+
}
386+
}
387+
388+
for ( auto matchingSettingsPagesIterator = matchingSettingsPagesMap.constBegin(); matchingSettingsPagesIterator != matchingSettingsPagesMap.constEnd(); ++matchingSettingsPagesIterator )
389+
{
390+
QString title = matchingSettingsPagesIterator.key();
391+
QMap<QString, QString> settingsPage = matchingSettingsPagesIterator.value();
392+
QgsLocatorResult result;
393+
result.filter = this;
394+
result.displayString = title;
395+
result.userData.setValue( settingsPage );
396+
result.score = static_cast< double >( string.length() ) / title.length();
397+
emit resultFetched( result );
398+
}
399+
}
400+
401+
QMap<QString, QString> QgsSettingsLocatorFilter::settingsPage( const QString &type, const QString &page )
402+
{
403+
QMap<QString, QString> returnPage;
404+
returnPage.insert( "type", type );
405+
returnPage.insert( "page", page );
406+
return returnPage;
407+
}
408+
409+
void QgsSettingsLocatorFilter::triggerResult( const QgsLocatorResult &result )
410+
{
411+
412+
QMap<QString, QString> settingsPage = qvariant_cast<QMap<QString, QString>>( result.userData );
413+
QString type = settingsPage.value( "type" );
414+
QString page = settingsPage.value( "page" );
415+
416+
if ( type == "optionpage" )
417+
{
418+
QgisApp::instance()->showOptionsDialog( QgisApp::instance(), page );
419+
}
420+
else if ( type == "projectpropertypage" )
421+
{
422+
QgisApp::instance()->showProjectProperties( page );
423+
}
424+
else if ( type == "settingspage" )
425+
{
426+
QgisApp::instance()->showSettings( page );
427+
}
428+
}
429+
342430
// QgBookmarkLocatorFilter
343431
//
344432

@@ -372,13 +460,12 @@ void QgsBookmarkLocatorFilter::fetchResults( const QString &string, const QgsLoc
372460
result.filter = this;
373461
result.displayString = name;
374462
result.userData = index;
375-
//TODO Create svg for "Bookmark"?
376-
//result.icon = TBD
463+
//TODO Create svg for "Bookmark"
464+
//TODO result.icon =
377465
result.score = static_cast< double >( string.length() ) / name.length();
378466
emit resultFetched( result );
379467
}
380468
}
381-
382469
}
383470

384471
void QgsBookmarkLocatorFilter::triggerResult( const QgsLocatorResult &result )

‎src/app/locator/qgsinbuiltlocatorfilters.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,35 @@ class QgsBookmarkLocatorFilter : public QgsLocatorFilter
141141
QgsBookmarkLocatorFilter( QObject *parent = nullptr );
142142
QgsBookmarkLocatorFilter *clone() const override;
143143
QString name() const override { return QStringLiteral( "bookmarks" ); }
144-
QString displayName() const override { return tr( "Spatial bookmarks" ); }
144+
QString displayName() const override { return tr( "Spatial Bookmarks" ); }
145145
Priority priority() const override { return Highest; }
146146
QString prefix() const override { return QStringLiteral( "b" ); }
147147
QgsLocatorFilter::Flags flags() const override { return QgsLocatorFilter::FlagFast; }
148148

149149
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
150150
void triggerResult( const QgsLocatorResult &result ) override;
151+
};
152+
153+
class QgsSettingsLocatorFilter : public QgsLocatorFilter
154+
{
155+
Q_OBJECT
156+
157+
public:
158+
159+
QgsSettingsLocatorFilter( QObject *parent = nullptr );
160+
QgsSettingsLocatorFilter *clone() const override;
161+
QString name() const override { return QStringLiteral( "optionpages" ); }
162+
QString displayName() const override { return tr( "Settings" ); }
163+
Priority priority() const override { return Highest; }
164+
QString prefix() const override { return QStringLiteral( "set" ); }
165+
QgsLocatorFilter::Flags flags() const override { return QgsLocatorFilter::FlagFast; }
166+
167+
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
168+
void triggerResult( const QgsLocatorResult &result ) override;
169+
170+
private:
151171

172+
QMap<QString, QString> settingsPage( const QString &type, const QString &page );
152173
};
153174

154175
#endif // QGSINBUILTLOCATORFILTERS_H

‎src/app/qgisapp.cpp

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
731731

732732
QgsSettings settings;
733733

734+
734735
startProfile( QStringLiteral( "Building style sheet" ) );
735736
// set up stylesheet builder and apply saved or default style options
736737
mStyleSheetBuilder = new QgisAppStyleSheet( this );
@@ -2096,7 +2097,7 @@ void QgisApp::createActions()
20962097
connect( mActionToggleFullScreen, &QAction::triggered, this, &QgisApp::toggleFullScreen );
20972098
connect( mActionTogglePanelsVisibility, &QAction::triggered, this, &QgisApp::togglePanelsVisibility );
20982099
connect( mActionToggleMapOnly, &QAction::triggered, this, &QgisApp::toggleMapOnly );
2099-
connect( mActionProjectProperties, &QAction::triggered, this, &QgisApp::projectProperties );
2100+
connect( mActionProjectProperties, &QAction::triggered, this, [ = ] {projectProperties( QString() );} );
21002101
connect( mActionOptions, &QAction::triggered, this, &QgisApp::options );
21012102
connect( mActionCustomProjection, &QAction::triggered, this, &QgisApp::customProjection );
21022103
connect( mActionConfigureShortcuts, &QAction::triggered, this, &QgisApp::configureShortcuts );
@@ -3012,6 +3013,7 @@ void QgisApp::createStatusBar()
30123013
mLocatorWidget->locator()->registerFilter( new QgsActiveLayerFeaturesLocatorFilter() );
30133014
mLocatorWidget->locator()->registerFilter( new QgsExpressionCalculatorLocatorFilter() );
30143015
mLocatorWidget->locator()->registerFilter( new QgsBookmarkLocatorFilter() );
3016+
mLocatorWidget->locator()->registerFilter( new QgsSettingsLocatorFilter() );
30153017
}
30163018

30173019
void QgisApp::setIconSizes( int size )
@@ -9960,6 +9962,70 @@ void QgisApp::options()
99609962
showOptionsDialog( this );
99619963
}
99629964

9965+
QMap< QString, QString > QgisApp::projectPropertiesPagesMap()
9966+
{
9967+
if ( mProjectPropertiesPagesMap.isEmpty() )
9968+
{
9969+
std::unique_ptr< QgsProjectProperties > pp( new QgsProjectProperties( mMapCanvas, this ) );
9970+
mProjectPropertiesPagesMap = pp->pageWidgetNameMap();
9971+
}
9972+
return mProjectPropertiesPagesMap;
9973+
}
9974+
9975+
void QgisApp::showProjectProperties( const QString &page )
9976+
{
9977+
projectProperties( page );
9978+
}
9979+
9980+
QMap< QString, QString > QgisApp::settingPagesMap()
9981+
{
9982+
if ( mSettingPagesMap.isEmpty() )
9983+
{
9984+
mSettingPagesMap.insert( tr( "Style Manager" ), "stylemanager" );
9985+
mSettingPagesMap.insert( tr( "Keyboard Shortcuts" ), "shortcuts" );
9986+
mSettingPagesMap.insert( tr( "Custom Projections" ), "customprojection" );
9987+
mSettingPagesMap.insert( tr( "Interface Customization" ), "customize" );
9988+
}
9989+
return mSettingPagesMap;
9990+
}
9991+
9992+
void QgisApp::showSettings( const QString &page )
9993+
{
9994+
if ( page == "stylemanager" )
9995+
{
9996+
showStyleManager();
9997+
}
9998+
else if ( page == "shortcuts" )
9999+
{
10000+
configureShortcuts();
10001+
}
10002+
else if ( page == "customprojection" )
10003+
{
10004+
customProjection();
10005+
}
10006+
else if ( page == "customize" )
10007+
{
10008+
customize();
10009+
}
10010+
}
10011+
10012+
QMap< QString, QString > QgisApp::optionsPagesMap()
10013+
{
10014+
if ( mOptionsPagesMap.isEmpty() )
10015+
{
10016+
QList< QgsOptionsWidgetFactory * > factories;
10017+
Q_FOREACH ( const QPointer< QgsOptionsWidgetFactory > &f, mOptionsWidgetFactories )
10018+
{
10019+
// remove any deleted factories
10020+
if ( f )
10021+
factories << f;
10022+
}
10023+
std::unique_ptr< QgsOptions > f( new QgsOptions( this, QgsGuiUtils::ModalDialogFlags, factories ) );
10024+
mOptionsPagesMap = f->pageWidgetNameMap();
10025+
}
10026+
return mOptionsPagesMap;
10027+
}
10028+
996310029
void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )
996410030
{
996510031
QgsSettings mySettings;
@@ -10238,11 +10304,15 @@ void QgisApp::unregisterMapLayerPropertiesFactory( QgsMapLayerConfigWidgetFactor
1023810304
void QgisApp::registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
1023910305
{
1024010306
mOptionsWidgetFactories << factory;
10307+
//clear mOptionsPagesMap forcing it to be repopulated next time optionsPagesMap() is called
10308+
mOptionsPagesMap.clear();
1024110309
}
1024210310

1024310311
void QgisApp::unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
1024410312
{
1024510313
mOptionsWidgetFactories.removeAll( factory );
10314+
//clear mOptionsPagesMap forcing it to be repopulated next time optionsPagesMap() is called
10315+
mOptionsPagesMap.clear();
1024610316
}
1024710317

1024810318
QgsMapLayer *QgisApp::activeLayer()
@@ -11545,7 +11615,7 @@ void QgisApp::projectPropertiesProjections()
1154511615
projectProperties();
1154611616
}
1154711617

11548-
void QgisApp::projectProperties()
11618+
void QgisApp::projectProperties( const QString &currentPage )
1154911619
{
1155011620
/* Display the property sheet for the Project */
1155111621
// set wait cursor since construction of the project properties
@@ -11569,6 +11639,10 @@ void QgisApp::projectProperties()
1156911639
&QgsStatusBarScaleWidget::updateScales );
1157011640
QApplication::restoreOverrideCursor();
1157111641

11642+
if ( !currentPage.isEmpty() )
11643+
{
11644+
pp->setCurrentPage( currentPage );
11645+
}
1157211646
// Display the modal dialog box.
1157311647
pp->exec();
1157411648

‎src/app/qgisapp.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,20 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
932932
//! Update project menu with the project templates
933933
void updateProjectFromTemplates();
934934

935+
/**
936+
* Settings pages section
937+
*/
938+
//! Get map of option pages
939+
QMap< QString, QString > optionsPagesMap();
940+
//! Get map of project property pages
941+
QMap< QString, QString > projectPropertiesPagesMap();
942+
//! Get map of setting pages
943+
QMap< QString, QString > settingPagesMap();
944+
945+
void showProjectProperties( const QString &page = QString() );
946+
void showSettings( const QString &page );
947+
// End Settings pages section
948+
935949
//! Opens the options dialog
936950
void showOptionsDialog( QWidget *parent = nullptr, const QString &currentPage = QString() );
937951

@@ -1333,8 +1347,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
13331347
void options();
13341348
//! Whats-this help slot
13351349
void whatsThis();
1336-
//! Set project properties, including map untis
1337-
void projectProperties();
13381350
//! Open project properties dialog and show the projections tab
13391351
void projectPropertiesProjections();
13401352
/* void urlData(); */
@@ -1786,6 +1798,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
17861798

17871799
void saveAsVectorFileGeneral( QgsVectorLayer *vlayer = nullptr, bool symbologyOption = true, bool onlySelected = false );
17881800

1801+
//! Set project properties, including map untis
1802+
void projectProperties( const QString &currentPage = QString() );
1803+
17891804
/**
17901805
* Paste features from clipboard into a new memory layer.
17911806
* If no features are in clipboard an empty layer is returned.
@@ -2213,6 +2228,11 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
22132228
QgsFeature duplicateFeatures( QgsMapLayer *mlayer, const QgsFeature &feature );
22142229
QgsFeature duplicateFeatureDigitized( QgsMapLayer *mlayer, const QgsFeature &feature );
22152230

2231+
//! Internal vars supporting Settings Pages function
2232+
QMap< QString, QString > mOptionsPagesMap;
2233+
QMap< QString, QString > mProjectPropertiesPagesMap;
2234+
QMap< QString, QString > mSettingPagesMap;
2235+
22162236
friend class TestQgisAppPython;
22172237
};
22182238

‎src/app/qgsoptions.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,20 @@ QgsOptions::~QgsOptions()
10681068
delete mSettings;
10691069
}
10701070

1071+
QMap< QString, QString > QgsOptions::pageWidgetNameMap()
1072+
{
1073+
QMap< QString, QString > pageNames;
1074+
for ( int idx = 0; idx < mOptionsListWidget->count(); ++idx )
1075+
{
1076+
QWidget *currentPage = mOptionsStackedWidget->widget( idx );
1077+
QListWidgetItem *item = mOptionsListWidget->item( idx );
1078+
QString title = item->text();
1079+
QString name = currentPage->objectName();
1080+
pageNames.insert( title, name );
1081+
}
1082+
return pageNames;
1083+
}
1084+
10711085
void QgsOptions::setCurrentPage( const QString &pageWidgetName )
10721086
{
10731087
//find the page with a matching widget name

‎src/app/qgsoptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
6161
*/
6262
void setCurrentPage( const QString &pageWidgetName );
6363

64+
QMap<QString, QString> pageWidgetNameMap();
65+
66+
6467
public slots:
6568
void cbxProjectDefaultNew_toggled( bool checked );
6669
void setCurrentProjectDefault();

‎src/app/qgsprojectproperties.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,3 +2159,32 @@ void QgsProjectProperties::applyRequiredLayers()
21592159
}
21602160
QgsProject::instance()->setRequiredLayers( requiredLayers );
21612161
}
2162+
2163+
QMap< QString, QString > QgsProjectProperties::pageWidgetNameMap()
2164+
{
2165+
QMap< QString, QString > pageNames;
2166+
for ( int idx = 0; idx < mOptionsListWidget->count(); ++idx )
2167+
{
2168+
QWidget *currentPage = mOptionsStackedWidget->widget( idx );
2169+
QListWidgetItem *item = mOptionsListWidget->item( idx );
2170+
QString title = item->text();
2171+
QString name = currentPage->objectName();
2172+
pageNames.insert( title, name );
2173+
}
2174+
return pageNames;
2175+
}
2176+
2177+
void QgsProjectProperties::setCurrentPage( const QString &pageWidgetName )
2178+
{
2179+
//find the page with a matching widget name
2180+
for ( int idx = 0; idx < mOptionsStackedWidget->count(); ++idx )
2181+
{
2182+
QWidget *currentPage = mOptionsStackedWidget->widget( idx );
2183+
if ( currentPage->objectName() == pageWidgetName )
2184+
{
2185+
//found the page, set it as current
2186+
mOptionsStackedWidget->setCurrentIndex( idx );
2187+
return;
2188+
}
2189+
}
2190+
}

‎src/app/qgsprojectproperties.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
4646
//! Constructor
4747
QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *parent = nullptr, Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags );
4848

49+
QMap< QString, QString > pageWidgetNameMap();
50+
51+
void setCurrentPage( const QString & );
4952

5053
~QgsProjectProperties() override;
5154

‎src/core/locator/qgslocator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ const QList<QString> QgsLocator::CORE_FILTERS = QList<QString>() << QStringLiter
2626
<< QStringLiteral( "layouts" )
2727
<< QStringLiteral( "features" )
2828
<< QStringLiteral( "calculator" )
29-
<< QStringLiteral( "bookmarks" );
29+
<< QStringLiteral( "bookmarks" )
30+
<< QStringLiteral( "optionpages" );
3031

3132
QgsLocator::QgsLocator( QObject *parent )
3233
: QObject( parent )

0 commit comments

Comments
 (0)
Please sign in to comment.