Skip to content
Permalink
Browse files

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.
  • Loading branch information
nyalldawson committed Oct 29, 2018
1 parent 1dd36f1 commit 0035b7c36965b144dc5e6c1b6684c4edcc9286e7
@@ -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" ) )
{
@@ -10296,12 +10296,22 @@ void QgisApp::options()

QMap< QString, QString > QgisApp::projectPropertiesPagesMap()
{
if ( mProjectPropertiesPagesMap.isEmpty() )
{
std::unique_ptr< QgsProjectProperties > pp( new QgsProjectProperties( mMapCanvas, this ) );
mProjectPropertiesPagesMap = pp->pageWidgetNameMap();
}
return mProjectPropertiesPagesMap;
static QMap< QString, QString > sProjectPropertiesPagesMap;
static std::once_flag initialized;
std::call_once( initialized, []
{
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()
{
if ( mOptionsPagesMap.isEmpty() )
QMap< QString, int > QgisApp::optionsPagesMap()
{
static QMap< QString, int > sOptionsPagesMap;
static std::once_flag initialized;
std::call_once( initialized, []
{
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 ) )
{
QList< QgsOptionsWidgetFactory * > factories;
Q_FOREACH ( const QPointer< QgsOptionsWidgetFactory > &f, 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() );
@@ -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
@@ -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 );
@@ -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;
};

@@ -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 )
@@ -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 );

0 comments on commit 0035b7c

Please sign in to comment.
You can’t perform that action at this time.