diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index c613af8b086..66f7b57da0a 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1240,7 +1240,8 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh mRasterFileFilter = QgsProviderRegistry::instance()->fileRasterFilters(); // set handler for missing layers (will be owned by QgsProject) - QgsProject::instance()->setBadLayerHandler( new QgsHandleBadLayersHandler() ); + mAppBadLayersHandler = new QgsHandleBadLayersHandler(); + QgsProject::instance()->setBadLayerHandler( mAppBadLayersHandler ); #if 0 // Set the background color for toolbox and overview as they default to @@ -5806,7 +5807,12 @@ void QgisApp::enableProjectMacros() bool QgisApp::addProject( const QString &projectFile ) { - MAYBE_UNUSED QgsProjectDirtyBlocker dirtyBlocker( QgsProject::instance() ); + + bool returnCode = false; + std::unique_ptr< QgsProjectDirtyBlocker > dirtyBlocker = qgis::make_unique< QgsProjectDirtyBlocker >( QgsProject::instance() ); + QObject connectionScope; // manually control scope of layersChanged lambda connection - we need the connection automatically destroyed when this function finishes + bool badLayersHandled = false; + connect( mAppBadLayersHandler, &QgsHandleBadLayersHandler::layersChanged, &connectionScope, [&badLayersHandled] { badLayersHandled = true; } ); // close the previous opened project if any closeProject(); @@ -5849,107 +5855,120 @@ bool QgisApp::addProject( const QString &projectFile ) QgsProject::instance()->setFileName( projectFile ); QgsProject::instance()->setDirty( true ); mProjectLastModified = QgsProject::instance()->lastModified(); - return true; + returnCode = true; } + else + { + mMapCanvas->freeze( false ); + mMapCanvas->refresh(); + returnCode = false; + } + } + else + { + + mProjectLastModified = QgsProject::instance()->lastModified(); + + setTitleBarText_( *this ); + int myRedInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorRedPart" ), 255 ); + int myGreenInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorGreenPart" ), 255 ); + int myBlueInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorBluePart" ), 255 ); + QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt ); + mOverviewCanvas->setBackgroundColor( myColor ); + + applyProjectSettingsToCanvas( mMapCanvas ); + + //load project scales + bool projectScales = QgsProject::instance()->readBoolEntry( QStringLiteral( "Scales" ), QStringLiteral( "/useProjectScales" ) ); + if ( projectScales ) + { + mScaleWidget->updateScales( QgsProject::instance()->readListEntry( QStringLiteral( "Scales" ), QStringLiteral( "/ScalesList" ) ) ); + } + + mMapCanvas->updateScale(); + QgsDebugMsg( QStringLiteral( "Scale restored..." ) ); + + mActionFilterLegend->setChecked( QgsProject::instance()->readBoolEntry( QStringLiteral( "Legend" ), QStringLiteral( "filterByMap" ) ) ); + + // Select the first layer + if ( mLayerTreeView->layerTreeModel()->rootGroup()->findLayers().count() > 0 ) + { + mLayerTreeView->setCurrentLayer( mLayerTreeView->layerTreeModel()->rootGroup()->findLayers().at( 0 )->layer() ); + } + + QgsSettings settings; + +#ifdef WITH_BINDINGS + // does the project have any macros? + if ( mPythonUtils && mPythonUtils->isEnabled() ) + { + if ( !QgsProject::instance()->readEntry( QStringLiteral( "Macros" ), QStringLiteral( "/pythonCode" ), QString() ).isEmpty() ) + { + int enableMacros = settings.value( QStringLiteral( "qgis/enableMacros" ), 1 ).toInt(); + // 0 = never, 1 = ask, 2 = just for this session, 3 = always + + if ( enableMacros == 3 || enableMacros == 2 ) + { + enableProjectMacros(); + } + else if ( enableMacros == 1 ) // ask + { + // create the notification widget for macros + + + QToolButton *btnEnableMacros = new QToolButton(); + btnEnableMacros->setText( tr( "Enable Macros" ) ); + btnEnableMacros->setStyleSheet( QStringLiteral( "background-color: rgba(255, 255, 255, 0); color: black; text-decoration: underline;" ) ); + btnEnableMacros->setCursor( Qt::PointingHandCursor ); + btnEnableMacros->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ); + + QgsMessageBarItem *macroMsg = new QgsMessageBarItem( + tr( "Security warning" ), + tr( "project macros have been disabled." ), + btnEnableMacros, + Qgis::Warning, + 0, + mInfoBar ); + + connect( btnEnableMacros, &QToolButton::clicked, this, [this, macroMsg] + { + enableProjectMacros(); + mInfoBar->popWidget( macroMsg ); + } ); + + // display the macros notification widget + mInfoBar->pushItem( macroMsg ); + } + } + } +#endif + + emit projectRead(); // let plug-ins know that we've read in a new + // project so that they can check any project + // specific plug-in state + + // add this to the list of recently used project files + saveRecentProjectPath( false ); + + QApplication::restoreOverrideCursor(); + + if ( autoSetupOnFirstLayer ) + mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( true ); mMapCanvas->freeze( false ); mMapCanvas->refresh(); - return false; + + mStatusBar->showMessage( tr( "Project loaded" ), 3000 ); + returnCode = true; } - mProjectLastModified = QgsProject::instance()->lastModified(); - - setTitleBarText_( *this ); - int myRedInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorRedPart" ), 255 ); - int myGreenInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorGreenPart" ), 255 ); - int myBlueInt = QgsProject::instance()->readNumEntry( QStringLiteral( "Gui" ), QStringLiteral( "/CanvasColorBluePart" ), 255 ); - QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt ); - mOverviewCanvas->setBackgroundColor( myColor ); - - applyProjectSettingsToCanvas( mMapCanvas ); - - //load project scales - bool projectScales = QgsProject::instance()->readBoolEntry( QStringLiteral( "Scales" ), QStringLiteral( "/useProjectScales" ) ); - if ( projectScales ) + if ( badLayersHandled ) { - mScaleWidget->updateScales( QgsProject::instance()->readListEntry( QStringLiteral( "Scales" ), QStringLiteral( "/ScalesList" ) ) ); + dirtyBlocker.reset(); // allow project dirtying again + QgsProject::instance()->setDirty( true ); } - mMapCanvas->updateScale(); - QgsDebugMsg( QStringLiteral( "Scale restored..." ) ); - - mActionFilterLegend->setChecked( QgsProject::instance()->readBoolEntry( QStringLiteral( "Legend" ), QStringLiteral( "filterByMap" ) ) ); - - // Select the first layer - if ( mLayerTreeView->layerTreeModel()->rootGroup()->findLayers().count() > 0 ) - { - mLayerTreeView->setCurrentLayer( mLayerTreeView->layerTreeModel()->rootGroup()->findLayers().at( 0 )->layer() ); - } - - QgsSettings settings; - -#ifdef WITH_BINDINGS - // does the project have any macros? - if ( mPythonUtils && mPythonUtils->isEnabled() ) - { - if ( !QgsProject::instance()->readEntry( QStringLiteral( "Macros" ), QStringLiteral( "/pythonCode" ), QString() ).isEmpty() ) - { - int enableMacros = settings.value( QStringLiteral( "qgis/enableMacros" ), 1 ).toInt(); - // 0 = never, 1 = ask, 2 = just for this session, 3 = always - - if ( enableMacros == 3 || enableMacros == 2 ) - { - enableProjectMacros(); - } - else if ( enableMacros == 1 ) // ask - { - // create the notification widget for macros - - - QToolButton *btnEnableMacros = new QToolButton(); - btnEnableMacros->setText( tr( "Enable Macros" ) ); - btnEnableMacros->setStyleSheet( QStringLiteral( "background-color: rgba(255, 255, 255, 0); color: black; text-decoration: underline;" ) ); - btnEnableMacros->setCursor( Qt::PointingHandCursor ); - btnEnableMacros->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ); - - QgsMessageBarItem *macroMsg = new QgsMessageBarItem( - tr( "Security warning" ), - tr( "project macros have been disabled." ), - btnEnableMacros, - Qgis::Warning, - 0, - mInfoBar ); - - connect( btnEnableMacros, &QToolButton::clicked, this, [this, macroMsg] - { - enableProjectMacros(); - mInfoBar->popWidget( macroMsg ); - } ); - - // display the macros notification widget - mInfoBar->pushItem( macroMsg ); - } - } - } -#endif - - emit projectRead(); // let plug-ins know that we've read in a new - // project so that they can check any project - // specific plug-in state - - // add this to the list of recently used project files - saveRecentProjectPath( false ); - - QApplication::restoreOverrideCursor(); - - if ( autoSetupOnFirstLayer ) - mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( true ); - - mMapCanvas->freeze( false ); - mMapCanvas->refresh(); - - mStatusBar->showMessage( tr( "Project loaded" ), 3000 ); - return true; + return returnCode; } // QgisApp::addProject(QString projectFile) diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 2bf34d117af..bf74ca4a83d 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -105,6 +105,7 @@ class QgsGeometryValidationDock; class QgsGeometryValidationModel; class QgsUserProfileManagerWidgetFactory; class Qgs3DMapCanvasDockWidget; +class QgsHandleBadLayersHandler; class QDomDocument; class QNetworkReply; @@ -2310,6 +2311,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow std::unique_ptr mGeometryValidationService; QgsGeometryValidationModel *mGeometryValidationModel = nullptr; QgsGeometryValidationDock *mGeometryValidationDock = nullptr; + QgsHandleBadLayersHandler *mAppBadLayersHandler = nullptr; friend class TestQgisAppPython; friend class QgisAppInterface; diff --git a/src/app/qgshandlebadlayers.cpp b/src/app/qgshandlebadlayers.cpp index 0ff73b605de..1b5949d34c3 100644 --- a/src/app/qgshandlebadlayers.cpp +++ b/src/app/qgshandlebadlayers.cpp @@ -57,7 +57,12 @@ void QgsHandleBadLayersHandler::handleBadLayers( const QList &layers ) Qgis::Warning, QgisApp::instance()->messageTimeout() ); if ( dialog->layerCount() > 0 ) - dialog->exec(); + { + if ( dialog->exec() == dialog->Accepted ) + { + emit layersChanged(); + } + } delete dialog; QApplication::restoreOverrideCursor(); diff --git a/src/app/qgshandlebadlayers.h b/src/app/qgshandlebadlayers.h index 96d3e786a57..796a8722ab7 100644 --- a/src/app/qgshandlebadlayers.h +++ b/src/app/qgshandlebadlayers.h @@ -32,6 +32,15 @@ class APP_EXPORT QgsHandleBadLayersHandler //! Implementation of the handler void handleBadLayers( const QList &layers ) override; + + signals: + + /** + * Emitted when layers have changed + * \since QGIS 3.6 + */ + void layersChanged(); + };