diff --git a/python/gui/auto_generated/qgscustomprojectopenhandler.sip.in b/python/gui/auto_generated/qgscustomprojectopenhandler.sip.in index ace8223056d..7353a839fd4 100644 --- a/python/gui/auto_generated/qgscustomprojectopenhandler.sip.in +++ b/python/gui/auto_generated/qgscustomprojectopenhandler.sip.in @@ -46,6 +46,18 @@ The base class implementation does nothing. Returns file filters associated with this handler, e.g. "MXD Documents (*.mxd)", "MapInfo Workspaces (*.wor)". Each individual filter should be reflected as one entry in the returned list. +%End + + virtual bool createDocumentThumbnailAfterOpen() const; +%Docstring +Returns ``True`` if a document thumbnail should automatically be created after opening the project. + +The default behavior is to return ``False``. +%End + + virtual QIcon icon() const; +%Docstring +Returns a custom icon used to represent this handler. %End }; diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index cc2296655dc..92d0af33e75 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -4897,7 +4897,7 @@ void QgisApp::updateRecentProjectPaths() } // add this file to the recently opened/saved projects list -void QgisApp::saveRecentProjectPath( bool savePreviewImage ) +void QgisApp::saveRecentProjectPath( bool savePreviewImage, const QIcon &iconOverlay ) { // first, re-read the recent project paths. This prevents loss of recent // projects when multiple QGIS sessions are open @@ -4933,7 +4933,7 @@ void QgisApp::saveRecentProjectPath( bool savePreviewImage ) projectData.previewImagePath = QStringLiteral( "%1/%2.png" ).arg( previewDir, fileName ); QDir().mkdir( previewDir ); - createPreviewImage( projectData.previewImagePath ); + createPreviewImage( projectData.previewImagePath, iconOverlay ); } else { @@ -6682,17 +6682,21 @@ bool QgisApp::addProject( const QString &projectFile ) mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( false ); // give custom handlers a chance first - bool handled = false; + bool usedCustomHandler = false; + bool customHandlerWantsThumbnail = false; + QIcon customHandlerIcon; for ( QgsCustomProjectOpenHandler *handler : qgis::as_const( mCustomProjectOpenHandlers ) ) { if ( handler && handler->handleProjectOpen( projectFile ) ) { - handled = true; + usedCustomHandler = true; + customHandlerWantsThumbnail = handler->createDocumentThumbnailAfterOpen(); + customHandlerIcon = handler->icon(); break; } } - if ( !handled && !QgsProject::instance()->read( projectFile ) && !QgsZipUtils::isZipFile( projectFile ) ) + if ( !usedCustomHandler && !QgsProject::instance()->read( projectFile ) && !QgsZipUtils::isZipFile( projectFile ) ) { QString backupFile = projectFile + "~"; QString loadBackupPrompt; @@ -6785,7 +6789,20 @@ bool QgisApp::addProject( const QString &projectFile ) // specific plug-in state // add this to the list of recently used project files - saveRecentProjectPath( false ); + // if a custom handler was used, then we generate a thumbnail + if ( !usedCustomHandler || !customHandlerWantsThumbnail ) + saveRecentProjectPath( false ); + else if ( !QgsProject::instance()->fileName().isEmpty() ) + { + // we have to delay the thumbnail creation until after the canvas has refreshed for the first time + QMetaObject::Connection *connection = new QMetaObject::Connection(); + *connection = connect( mMapCanvas, &QgsMapCanvas::mapCanvasRefreshed, [ = ]() + { + QObject::disconnect( *connection ); + delete connection; + saveRecentProjectPath( true, customHandlerIcon ); + } ); + } QApplication::restoreOverrideCursor(); @@ -14636,7 +14653,7 @@ void QgisApp::generateProjectAttachedFiles( QgsStringMap &files ) previewImage->deleteLater(); } -void QgisApp::createPreviewImage( const QString &path ) +void QgisApp::createPreviewImage( const QString &path, const QIcon &icon ) { // Render the map canvas QSize previewSize( 250, 177 ); // h = w / std::sqrt(2) @@ -14648,6 +14665,13 @@ void QgisApp::createPreviewImage( const QString &path ) QPainter previewPainter( &previewImage ); mMapCanvas->render( &previewPainter, QRect( QPoint(), previewSize ), previewRect ); + if ( !icon.isNull() ) + { + QPixmap pixmap = icon.pixmap( QSize( 24, 24 ) ); + previewPainter.drawPixmap( QPointF( 250 - 24 - 5, 177 - 24 - 5 ), pixmap ); + } + previewPainter.end(); + // Save previewImage.save( path ); } diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index fd698291328..2b71718dbfb 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -1863,7 +1863,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow void activeLayerChanged( QgsMapLayer *layer ); private: - void createPreviewImage( const QString &path ); + void createPreviewImage( const QString &path, const QIcon &overlayIcon = QIcon() ); void startProfile( const QString &name ); void endProfile(); void functionProfile( void ( QgisApp::*fnc )(), QgisApp *instance, const QString &name ); @@ -1918,8 +1918,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow * instance simultaneously results in data loss. * * \param savePreviewImage Set to false when the preview image should not be saved. E.g. project load. + * \param iconOverlay optional icon to overlay when saving a preview image */ - void saveRecentProjectPath( bool savePreviewImage = true ); + void saveRecentProjectPath( bool savePreviewImage = true, const QIcon &iconOverlay = QIcon() ); //! Save recent projects list to settings void saveRecentProjects(); //! Update project menu with the current list of recently accessed projects diff --git a/src/gui/qgscustomprojectopenhandler.cpp b/src/gui/qgscustomprojectopenhandler.cpp index 3d2b9dada5d..2c16c743989 100644 --- a/src/gui/qgscustomprojectopenhandler.cpp +++ b/src/gui/qgscustomprojectopenhandler.cpp @@ -14,3 +14,14 @@ ***************************************************************************/ #include "qgscustomprojectopenhandler.h" +#include + +bool QgsCustomProjectOpenHandler::createDocumentThumbnailAfterOpen() const +{ + return false; +} + +QIcon QgsCustomProjectOpenHandler::icon() const +{ + return QIcon(); +} diff --git a/src/gui/qgscustomprojectopenhandler.h b/src/gui/qgscustomprojectopenhandler.h index 25f54e7e522..fd90d561342 100644 --- a/src/gui/qgscustomprojectopenhandler.h +++ b/src/gui/qgscustomprojectopenhandler.h @@ -58,6 +58,18 @@ class GUI_EXPORT QgsCustomProjectOpenHandler : public QObject * Each individual filter should be reflected as one entry in the returned list. */ virtual QStringList filters() const = 0; + + /** + * Returns TRUE if a document thumbnail should automatically be created after opening the project. + * + * The default behavior is to return FALSE. + */ + virtual bool createDocumentThumbnailAfterOpen() const; + + /** + * Returns a custom icon used to represent this handler. + */ + virtual QIcon icon() const; }; #endif // QgsCustomProjectOpenHandler_H