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.

(cherry picked from commit 0035b7c)
  • Loading branch information
nyalldawson committed Oct 29, 2018
1 parent 3aafedb commit e15e4f021d6c3c54bdf4d6a10ee2b065411120d9
@@ -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" ) )
{
@@ -69,6 +69,7 @@
#include <QVBoxLayout>
#include <QWhatsThis>
#include <QWidgetAction>
#include <mutex>

#include "qgssettings.h"
#include "qgsnetworkaccessmanager.h"
@@ -10290,12 +10291,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 )
@@ -10305,14 +10316,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 )
@@ -10335,21 +10349,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 )
@@ -10364,7 +10401,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 ) );

@@ -10376,6 +10413,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 e15e4f0

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