Avoid creating temporary project properties and options dialogs

for locator filter

This is expensive and results in a lengthy delay when first
using the locator in a QGIS session.

Replace with an alternative approach which doesn't rely on
creation of temporary dialogs, yet should still ensure that
these dialogs don't go out of sync with the locator.
This commit is contained in:
Nyall Dawson 2018-10-29 13:12:31 +10:00
parent 1dd36f132d
commit 0035b7c369
7 changed files with 107 additions and 53 deletions

View File

@ -235,7 +235,7 @@ void QgsActiveLayerFeaturesLocatorFilter::prepare( const QString &string, const
}
else if ( allowNumeric && field.isNumeric() )
{
expressionParts << QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( field.name() ) ).arg( QString::number( numericalValue, 'g', 17 ) );
expressionParts << QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( field.name() ), QString::number( numericalValue, 'g', 17 ) );
}
}
@ -352,8 +352,8 @@ void QgsAllLayersFeaturesLocatorFilter::prepare( const QString &string, const Qg
if ( !expression.needsGeometry() )
req.setFlags( QgsFeatureRequest::NoGeometry );
req.setFilterExpression( QStringLiteral( "%1 ILIKE '%%2%'" )
.arg( layer->displayExpression() )
.arg( string ) );
.arg( layer->displayExpression(),
string ) );
req.setLimit( 30 );
PreparedLayer preparedLayer;
@ -474,13 +474,13 @@ void QgsSettingsLocatorFilter::fetchResults( const QString &string, const QgsLoc
{
QMap<QString, QMap<QString, QString>> matchingSettingsPagesMap;
QMap<QString, QString> optionsPagesMap = QgisApp::instance()->optionsPagesMap();
QMap<QString, int > optionsPagesMap = QgisApp::instance()->optionsPagesMap();
for ( auto optionsPagesIterator = optionsPagesMap.constBegin(); optionsPagesIterator != optionsPagesMap.constEnd(); ++optionsPagesIterator )
{
QString title = optionsPagesIterator.key();
if ( stringMatches( title, string ) || ( context.usingPrefix && string.isEmpty() ) )
{
matchingSettingsPagesMap.insert( title + " (" + tr( "Options" ) + ")", settingsPage( QStringLiteral( "optionpage" ), optionsPagesIterator.value() ) );
matchingSettingsPagesMap.insert( title + " (" + tr( "Options" ) + ")", settingsPage( QStringLiteral( "optionpage" ), QString::number( optionsPagesIterator.value() ) ) );
}
}
@ -534,7 +534,8 @@ void QgsSettingsLocatorFilter::triggerResult( const QgsLocatorResult &result )
if ( type == QLatin1String( "optionpage" ) )
{
QgisApp::instance()->showOptionsDialog( QgisApp::instance(), page );
const int pageNumber = page.toInt();
QgisApp::instance()->showOptionsDialog( QgisApp::instance(), QString(), pageNumber );
}
else if ( type == QLatin1String( "projectpropertypage" ) )
{

View File

@ -10296,12 +10296,22 @@ void QgisApp::options()
QMap< QString, QString > QgisApp::projectPropertiesPagesMap()
{
if ( mProjectPropertiesPagesMap.isEmpty() )
static QMap< QString, QString > sProjectPropertiesPagesMap;
static std::once_flag initialized;
std::call_once( initialized, []
{
std::unique_ptr< QgsProjectProperties > pp( new QgsProjectProperties( mMapCanvas, this ) );
mProjectPropertiesPagesMap = pp->pageWidgetNameMap();
}
return mProjectPropertiesPagesMap;
sProjectPropertiesPagesMap.insert( tr( "General" ), QStringLiteral( "mProjOptsGeneral" ) );
sProjectPropertiesPagesMap.insert( tr( "Metadata" ), QStringLiteral( "mMetadataPage" ) );
sProjectPropertiesPagesMap.insert( tr( "CRS" ), QStringLiteral( "mProjOptsCRS" ) );
sProjectPropertiesPagesMap.insert( tr( "Default Styles" ), QStringLiteral( "mProjOptsSymbols" ) );
sProjectPropertiesPagesMap.insert( tr( "Data Sources" ), QStringLiteral( "mTab_DataSources" ) );
sProjectPropertiesPagesMap.insert( tr( "Relations" ), QStringLiteral( "mTabRelations" ) );
sProjectPropertiesPagesMap.insert( tr( "Variables" ), QStringLiteral( "mTab_Variables" ) );
sProjectPropertiesPagesMap.insert( tr( "Macros" ), QStringLiteral( "mProjOptsMacros" ) );
sProjectPropertiesPagesMap.insert( tr( "QGIS Server" ), QStringLiteral( "mProjOptsOWS" ) );
} );
return sProjectPropertiesPagesMap;
}
void QgisApp::showProjectProperties( const QString &page )
@ -10311,14 +10321,17 @@ void QgisApp::showProjectProperties( const QString &page )
QMap< QString, QString > QgisApp::settingPagesMap()
{
if ( mSettingPagesMap.isEmpty() )
static QMap< QString, QString > sSettingPagesMap;
static std::once_flag initialized;
std::call_once( initialized, []
{
mSettingPagesMap.insert( tr( "Style Manager" ), QStringLiteral( "stylemanager" ) );
mSettingPagesMap.insert( tr( "Keyboard Shortcuts" ), QStringLiteral( "shortcuts" ) );
mSettingPagesMap.insert( tr( "Custom Projections" ), QStringLiteral( "customprojection" ) );
mSettingPagesMap.insert( tr( "Interface Customization" ), QStringLiteral( "customize" ) );
}
return mSettingPagesMap;
sSettingPagesMap.insert( tr( "Style Manager" ), QStringLiteral( "stylemanager" ) );
sSettingPagesMap.insert( tr( "Keyboard Shortcuts" ), QStringLiteral( "shortcuts" ) );
sSettingPagesMap.insert( tr( "Custom Projections" ), QStringLiteral( "customprojection" ) );
sSettingPagesMap.insert( tr( "Interface Customization" ), QStringLiteral( "customize" ) );
} );
return sSettingPagesMap;
}
void QgisApp::showSettings( const QString &page )
@ -10341,21 +10354,44 @@ void QgisApp::showSettings( const QString &page )
}
}
QMap< QString, QString > QgisApp::optionsPagesMap()
QMap< QString, int > QgisApp::optionsPagesMap()
{
if ( mOptionsPagesMap.isEmpty() )
static QMap< QString, int > sOptionsPagesMap;
static std::once_flag initialized;
std::call_once( initialized, []
{
QList< QgsOptionsWidgetFactory * > factories;
Q_FOREACH ( const QPointer< QgsOptionsWidgetFactory > &f, mOptionsWidgetFactories )
sOptionsPagesMap.insert( tr( "General" ), 0 );
sOptionsPagesMap.insert( tr( "System" ), 1 );
sOptionsPagesMap.insert( tr( "CRS" ), 2 );
sOptionsPagesMap.insert( tr( "Data Sources" ), 3 );
sOptionsPagesMap.insert( tr( "Rendering" ), 4 );
sOptionsPagesMap.insert( tr( "Canvas & Legend" ), 5 );
sOptionsPagesMap.insert( tr( "Map Tools" ), 6 );
sOptionsPagesMap.insert( tr( "Colors" ), 7 );
sOptionsPagesMap.insert( tr( "Digitizing" ), 8 );
sOptionsPagesMap.insert( tr( "Layouts" ), 9 );
sOptionsPagesMap.insert( tr( "GDAL" ), 10 );
sOptionsPagesMap.insert( tr( "Variables" ), 11 );
sOptionsPagesMap.insert( tr( "Authentication" ), 12 );
sOptionsPagesMap.insert( tr( "Network" ), 13 );
sOptionsPagesMap.insert( tr( "Locator" ), 14 );
sOptionsPagesMap.insert( tr( "Advanced" ), 15 );
sOptionsPagesMap.insert( tr( "Acceleration" ), 16 );
} );
QMap< QString, int > map = sOptionsPagesMap;
int idx = map.count();
for ( const QPointer< QgsOptionsWidgetFactory > &f : qgis::as_const( mOptionsWidgetFactories ) )
{
// remove any deleted factories
if ( f )
{
// remove any deleted factories
if ( f )
factories << f;
map.insert( f->title(), idx );
}
std::unique_ptr< QgsOptions > f( new QgsOptions( this, QgsGuiUtils::ModalDialogFlags, factories ) );
mOptionsPagesMap = f->pageWidgetNameMap();
idx++;
}
return mOptionsPagesMap;
return map;
}
QgsOptions *QgisApp::createOptionsDialog( QWidget *parent )
@ -10370,7 +10406,7 @@ QgsOptions *QgisApp::createOptionsDialog( QWidget *parent )
return new QgsOptions( parent, QgsGuiUtils::ModalDialogFlags, factories );
}
void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )
void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage, int pageNumber )
{
std::unique_ptr< QgsOptions > optionsDialog( createOptionsDialog( parent ) );
@ -10382,6 +10418,11 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )
optionsDialog->setCurrentPage( currentPage );
}
if ( pageNumber >= 0 )
{
optionsDialog->setCurrentPage( pageNumber );
}
if ( optionsDialog->exec() )
{
QgsProject::instance()->layerTreeRegistryBridge()->setNewLayersVisible( mySettings.value( QStringLiteral( "qgis/new_layers_visible" ), true ).toBool() );

View File

@ -959,7 +959,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
* Settings pages section
*/
//! Gets map of option pages
QMap< QString, QString > optionsPagesMap();
QMap<QString, int> optionsPagesMap();
//! Gets map of project property pages
QMap< QString, QString > projectPropertiesPagesMap();
//! Gets map of setting pages
@ -970,7 +970,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
// End Settings pages section
//! Opens the options dialog
void showOptionsDialog( QWidget *parent = nullptr, const QString &currentPage = QString() );
void showOptionsDialog( QWidget *parent = nullptr, const QString &currentPage = QString(), int pageNumber = -1 );
/**
* Refreshes the state of the layer actions toolbar action
@ -2282,11 +2282,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsFeature duplicateFeatures( QgsMapLayer *mlayer, const QgsFeature &feature );
QgsFeature duplicateFeatureDigitized( QgsMapLayer *mlayer, const QgsFeature &feature );
//! Internal vars supporting Settings Pages function
QMap< QString, QString > mOptionsPagesMap;
QMap< QString, QString > mProjectPropertiesPagesMap;
QMap< QString, QString > mSettingPagesMap;
QgsProxyProgressTask *mProjectLoadingProxyTask = nullptr;
//! True if we are blocking the activeLayerChanged signal from being emitted

View File

@ -1128,6 +1128,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
connect( mRestoreDefaultWindowStateBtn, &QAbstractButton::clicked, this, &QgsOptions::restoreDefaultWindowState );
restoreOptionsBaseUi();
#ifdef QGISDEBUG
checkPageWidgetNameMap();
#endif
}
@ -1136,21 +1140,22 @@ QgsOptions::~QgsOptions()
delete mSettings;
}
QMap< QString, QString > QgsOptions::pageWidgetNameMap()
void QgsOptions::checkPageWidgetNameMap()
{
QMap< QString, QString > pageNames;
const QMap< QString, int > pageNames = QgisApp::instance()->optionsPagesMap();
Q_ASSERT_X( pageNames.count() == mOptionsListWidget->count(), "QgsOptions::checkPageWidgetNameMap()", "QgisApp::optionsPagesMap() is outdated, contains too many entries" );
for ( int idx = 0; idx < mOptionsListWidget->count(); ++idx )
{
QWidget *currentPage = mOptionsStackedWidget->widget( idx );
QListWidgetItem *item = mOptionsListWidget->item( idx );
if ( currentPage && item )
{
QString title = item->text();
QString name = currentPage->objectName();
pageNames.insert( title, name );
const QString title = item->text();
Q_ASSERT_X( pageNames.contains( title ), "QgsOptions::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::optionsPagesMap() is outdated, please update. Missing %1" ).arg( title ).toLocal8Bit().constData() );
Q_ASSERT_X( pageNames.value( title ) == idx, "QgsOptions::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::optionsPagesMap() is outdated, please update. %1 should be %2 not %3" ).arg( title ).arg( idx ).arg( pageNames.value( title ) ).toLocal8Bit().constData() );
}
}
return pageNames;
}
void QgsOptions::setCurrentPage( const QString &pageWidgetName )
@ -1168,6 +1173,12 @@ void QgsOptions::setCurrentPage( const QString &pageWidgetName )
}
}
void QgsOptions::setCurrentPage( const int pageNumber )
{
if ( pageNumber >= 0 && pageNumber < mOptionsStackedWidget->count() )
mOptionsStackedWidget->setCurrentIndex( pageNumber );
}
void QgsOptions::mProxyTypeComboBox_currentIndexChanged( int idx )
{
frameManualProxy->setEnabled( idx != 0 );

View File

@ -61,8 +61,7 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
*/
void setCurrentPage( const QString &pageWidgetName );
QMap<QString, QString> pageWidgetNameMap();
void setCurrentPage( int pageNumber );
public slots:
void cbxProjectDefaultNew_toggled( bool checked );
@ -272,6 +271,8 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void updateActionsForCurrentColorScheme( QgsColorScheme *scheme );
void checkPageWidgetNameMap();
friend class QgsAppScreenShots;
};

View File

@ -850,7 +850,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
// sync metadata title and project title fields
connect( mMetadataWidget, &QgsMetadataWidget::titleChanged, titleEdit, &QLineEdit::setText, Qt::QueuedConnection );
connect( titleEdit, &QLineEdit::textChanged, [ = ] { whileBlocking( mMetadataWidget )->setTitle( title() ) ;} );
connect( titleEdit, &QLineEdit::textChanged, this, [ = ] { whileBlocking( mMetadataWidget )->setTitle( title() ) ;} );
//fill ts language checkbox
QString i18nPath = QgsApplication::i18nPath();
@ -877,6 +877,10 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
projectionSelectorInitialized();
restoreOptionsBaseUi();
restoreState();
#ifdef QGISDEBUG
checkPageWidgetNameMap();
#endif
}
QgsProjectProperties::~QgsProjectProperties()
@ -2305,18 +2309,19 @@ void QgsProjectProperties::showHelp()
QgsHelp::openHelp( link );
}
QMap< QString, QString > QgsProjectProperties::pageWidgetNameMap()
void QgsProjectProperties::checkPageWidgetNameMap()
{
QMap< QString, QString > pageNames;
const QMap< QString, QString > pageNames = QgisApp::instance()->projectPropertiesPagesMap();
Q_ASSERT_X( pageNames.count() == mOptionsListWidget->count(), "QgsProjectProperties::checkPageWidgetNameMap()", "QgisApp::projectPropertiesPagesMap() is outdated, contains too many entries" );
for ( int idx = 0; idx < mOptionsListWidget->count(); ++idx )
{
QWidget *currentPage = mOptionsStackedWidget->widget( idx );
QListWidgetItem *item = mOptionsListWidget->item( idx );
QString title = item->text();
QString name = currentPage->objectName();
pageNames.insert( title, name );
const QString title = item->text();
const QString name = currentPage->objectName();
Q_ASSERT_X( pageNames.contains( title ), "QgsProjectProperties::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::projectPropertiesPagesMap() is outdated, please update. Missing %1" ).arg( title ).toLocal8Bit().constData() );
Q_ASSERT_X( pageNames.value( title ) == name, "QgsProjectProperties::checkPageWidgetNameMap()", QStringLiteral( "QgisApp::projectPropertiesPagesMap() is outdated, please update. %1 should be %2 not %3" ).arg( title, name, pageNames.value( title ) ).toLocal8Bit().constData() );
}
return pageNames;
}
void QgsProjectProperties::setCurrentPage( const QString &pageWidgetName )

View File

@ -48,8 +48,6 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
//! Constructor
QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *parent = nullptr, Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags );
QMap< QString, QString > pageWidgetNameMap();
void setCurrentPage( const QString & );
~QgsProjectProperties() override;
@ -192,6 +190,8 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
QgsCoordinateReferenceSystem mCrs;
void checkPageWidgetNameMap();
void populateStyles();
void editSymbol( QComboBox *cbo );