Provide custom project open handlers a method to create thumbnail images

for the welcome screen
This commit is contained in:
Nyall Dawson 2020-04-06 10:41:47 +10:00
parent 27164156e1
commit 878ac9d4f7
5 changed files with 69 additions and 9 deletions

View File

@ -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)". 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. 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 %End
}; };

View File

@ -4897,7 +4897,7 @@ void QgisApp::updateRecentProjectPaths()
} }
// add this file to the recently opened/saved projects list // 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 // first, re-read the recent project paths. This prevents loss of recent
// projects when multiple QGIS sessions are open // 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 ); projectData.previewImagePath = QStringLiteral( "%1/%2.png" ).arg( previewDir, fileName );
QDir().mkdir( previewDir ); QDir().mkdir( previewDir );
createPreviewImage( projectData.previewImagePath ); createPreviewImage( projectData.previewImagePath, iconOverlay );
} }
else else
{ {
@ -6682,17 +6682,21 @@ bool QgisApp::addProject( const QString &projectFile )
mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( false ); mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( false );
// give custom handlers a chance first // give custom handlers a chance first
bool handled = false; bool usedCustomHandler = false;
bool customHandlerWantsThumbnail = false;
QIcon customHandlerIcon;
for ( QgsCustomProjectOpenHandler *handler : qgis::as_const( mCustomProjectOpenHandlers ) ) for ( QgsCustomProjectOpenHandler *handler : qgis::as_const( mCustomProjectOpenHandlers ) )
{ {
if ( handler && handler->handleProjectOpen( projectFile ) ) if ( handler && handler->handleProjectOpen( projectFile ) )
{ {
handled = true; usedCustomHandler = true;
customHandlerWantsThumbnail = handler->createDocumentThumbnailAfterOpen();
customHandlerIcon = handler->icon();
break; break;
} }
} }
if ( !handled && !QgsProject::instance()->read( projectFile ) && !QgsZipUtils::isZipFile( projectFile ) ) if ( !usedCustomHandler && !QgsProject::instance()->read( projectFile ) && !QgsZipUtils::isZipFile( projectFile ) )
{ {
QString backupFile = projectFile + "~"; QString backupFile = projectFile + "~";
QString loadBackupPrompt; QString loadBackupPrompt;
@ -6785,7 +6789,20 @@ bool QgisApp::addProject( const QString &projectFile )
// specific plug-in state // specific plug-in state
// add this to the list of recently used project files // 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(); QApplication::restoreOverrideCursor();
@ -14636,7 +14653,7 @@ void QgisApp::generateProjectAttachedFiles( QgsStringMap &files )
previewImage->deleteLater(); previewImage->deleteLater();
} }
void QgisApp::createPreviewImage( const QString &path ) void QgisApp::createPreviewImage( const QString &path, const QIcon &icon )
{ {
// Render the map canvas // Render the map canvas
QSize previewSize( 250, 177 ); // h = w / std::sqrt(2) QSize previewSize( 250, 177 ); // h = w / std::sqrt(2)
@ -14648,6 +14665,13 @@ void QgisApp::createPreviewImage( const QString &path )
QPainter previewPainter( &previewImage ); QPainter previewPainter( &previewImage );
mMapCanvas->render( &previewPainter, QRect( QPoint(), previewSize ), previewRect ); 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 // Save
previewImage.save( path ); previewImage.save( path );
} }

View File

@ -1863,7 +1863,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void activeLayerChanged( QgsMapLayer *layer ); void activeLayerChanged( QgsMapLayer *layer );
private: private:
void createPreviewImage( const QString &path ); void createPreviewImage( const QString &path, const QIcon &overlayIcon = QIcon() );
void startProfile( const QString &name ); void startProfile( const QString &name );
void endProfile(); void endProfile();
void functionProfile( void ( QgisApp::*fnc )(), QgisApp *instance, const QString &name ); 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. * instance simultaneously results in data loss.
* *
* \param savePreviewImage Set to false when the preview image should not be saved. E.g. project load. * \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 //! Save recent projects list to settings
void saveRecentProjects(); void saveRecentProjects();
//! Update project menu with the current list of recently accessed projects //! Update project menu with the current list of recently accessed projects

View File

@ -14,3 +14,14 @@
***************************************************************************/ ***************************************************************************/
#include "qgscustomprojectopenhandler.h" #include "qgscustomprojectopenhandler.h"
#include <QIcon>
bool QgsCustomProjectOpenHandler::createDocumentThumbnailAfterOpen() const
{
return false;
}
QIcon QgsCustomProjectOpenHandler::icon() const
{
return QIcon();
}

View File

@ -58,6 +58,18 @@ class GUI_EXPORT QgsCustomProjectOpenHandler : public QObject
* Each individual filter should be reflected as one entry in the returned list. * Each individual filter should be reflected as one entry in the returned list.
*/ */
virtual QStringList filters() const = 0; 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 #endif // QgsCustomProjectOpenHandler_H