Skip to content

Commit 831131d

Browse files
committed
[FEATURE] Add welcome screen with recent projects
Refs #7626
1 parent 1465e9b commit 831131d

8 files changed

+295
-45
lines changed

src/app/CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ SET(QGIS_APP_SRCS
5050
qgsmapmouseevent.cpp
5151
qgssavestyletodbdialog.cpp
5252
qgsguivectorlayertools.cpp
53+
qgswelcomepageitemsmodel.cpp
54+
qgswelcomedialog.cpp
5355

5456
qgsmaptooladdfeature.cpp
5557
qgsmaptooladdpart.cpp
@@ -108,7 +110,6 @@ SET(QGIS_APP_SRCS
108110
qgsstatisticalsummarydockwidget.cpp
109111
qgstextannotationdialog.cpp
110112
qgsshortcutsmanager.cpp
111-
qgsguivectorlayertools.h
112113
qgssnappingdialog.cpp
113114
qgssvgannotationdialog.cpp
114115
qgsundowidget.cpp
@@ -209,6 +210,8 @@ SET (QGIS_APP_MOC_HDRS
209210
qgsshortcutsmanager.h
210211
qgsapplayertreeviewmenuprovider.h
211212
qgsguivectorlayertools.h
213+
qgswelcomepageitemsmodel.h
214+
qgswelcomedialog.h
212215

213216
qgsmaptooladdfeature.h
214217
qgsmaptoolcapture.h

src/app/qgisapp.cpp

+78-40
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@
211211
#include "qgsmessagelogviewer.h"
212212
#include "qgsdataitem.h"
213213
#include "qgsmaplayeractionregistry.h"
214+
#include "qgswelcomedialog.h"
215+
#include "qgsmaprendererparalleljob.h"
214216

215217
#include "qgssublayersdialog.h"
216218
#include "ogr/qgsopenvectorlayerdialog.h"
@@ -869,6 +871,10 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
869871
#ifdef ANDROID
870872
toggleFullScreen();
871873
#endif
874+
875+
QgsWelcomeDialog dlg;
876+
dlg.setRecentProjects( mRecentProjects );
877+
dlg.exec();
872878
} // QgisApp ctor
873879

874880
QgisApp::QgisApp()
@@ -1123,8 +1129,22 @@ void QgisApp::readSettings()
11231129
// 'gis' theme is new /themes/default directory (2013-04-15)
11241130
setTheme( settings.value( "/Themes", "default" ).toString() );
11251131

1126-
// Add the recently accessed project file paths to the Project menu
1127-
mRecentProjectPaths = settings.value( "/UI/recentProjectsList" ).toStringList();
1132+
settings.beginGroup( "/UI/recentProjects" );
1133+
QStringList projectKeys = settings.childGroups();
1134+
1135+
mRecentProjects.clear();
1136+
1137+
Q_FOREACH( const QString& key, projectKeys )
1138+
{
1139+
QgsWelcomePageItemsModel::RecentProjectData data;
1140+
settings.beginGroup( key );
1141+
data.title = settings.value( "title" ).toString();
1142+
data.path = settings.value( "path" ).toString();
1143+
data.previewImagePath = settings.value( "previewImage" ).toString();
1144+
settings.endGroup();
1145+
mRecentProjects.prepend( data );
1146+
}
1147+
settings.endGroup();
11281148

11291149
// this is a new session! reset enable macros value to "ask"
11301150
// whether set to "just for this session"
@@ -2673,52 +2693,74 @@ void QgisApp::projectReadDecorationItems()
26732693
// Update project menu with the current list of recently accessed projects
26742694
void QgisApp::updateRecentProjectPaths()
26752695
{
2676-
// Remove existing paths from the recent projects menu
2677-
int i;
2678-
2679-
int menusize = mRecentProjectsMenu->actions().size();
2696+
mRecentProjectsMenu->clear();
26802697

2681-
for ( i = menusize; i < mRecentProjectPaths.size(); i++ )
2698+
Q_FOREACH( const QgsWelcomePageItemsModel::RecentProjectData& recentProject, mRecentProjects )
26822699
{
2683-
mRecentProjectsMenu->addAction( "Dummy text" );
2684-
}
2685-
2686-
QList<QAction *> menulist = mRecentProjectsMenu->actions();
2687-
2688-
assert( menulist.size() == mRecentProjectPaths.size() );
2689-
2690-
for ( i = 0; i < mRecentProjectPaths.size(); i++ )
2691-
{
2692-
menulist.at( i )->setText( mRecentProjectPaths.at( i ) );
2693-
2694-
// Disable this menu item if the file has been removed, if not enable it
2695-
menulist.at( i )->setEnabled( QFile::exists(( mRecentProjectPaths.at( i ) ) ) );
2696-
2700+
QAction* action = mRecentProjectsMenu->addAction( QString( "%1 (%2)" ).arg( recentProject.title ).arg( recentProject.path ) );
2701+
action->setEnabled( QFile::exists(( recentProject.path ) ) );
2702+
action->setData( recentProject.path );
26972703
}
26982704
} // QgisApp::updateRecentProjectPaths
26992705

27002706
// add this file to the recently opened/saved projects list
2701-
void QgisApp::saveRecentProjectPath( QString projectPath, QSettings & settings )
2707+
void QgisApp::saveRecentProjectPath( QString projectPath, bool savePreviewImage )
27022708
{
2709+
QSettings settings;
2710+
27032711
// Get canonical absolute path
27042712
QFileInfo myFileInfo( projectPath );
2705-
projectPath = myFileInfo.absoluteFilePath();
2713+
QgsWelcomePageItemsModel::RecentProjectData projectData;
2714+
projectData.path = myFileInfo.absoluteFilePath();
2715+
projectData.title = QgsProject::instance()->title();
2716+
if ( projectData.title.isEmpty() )
2717+
projectData.title = projectData.path;
2718+
2719+
if ( savePreviewImage )
2720+
{
2721+
QgsMapSettings mapSettings = mMapCanvas->mapSettings();
2722+
mapSettings.setOutputSize( QSize( 200, 70 ) );
2723+
QgsMapRendererParallelJob job( mapSettings );
2724+
job.start();
2725+
job.waitForFinished();
2726+
QString fileName( QCryptographicHash::hash( ( projectData.path.toUtf8() ), QCryptographicHash::Md5 ).toHex() );
2727+
QString previewDir = QString( "%1/previewImages" ).arg( QgsApplication::qgisSettingsDirPath() );
2728+
projectData.previewImagePath = QString( "%1/%2.png" ).arg( previewDir ).arg( fileName );
2729+
QDir().mkdir( previewDir );
2730+
job.renderedImage().save( projectData.previewImagePath );
2731+
}
2732+
else
2733+
{
2734+
int idx = mRecentProjects.indexOf( projectData );
2735+
if ( idx != -1 )
2736+
projectData.previewImagePath = mRecentProjects.at( idx ).previewImagePath;
2737+
}
27062738

27072739
// If this file is already in the list, remove it
2708-
mRecentProjectPaths.removeAll( projectPath );
2740+
mRecentProjects.removeAll( projectData );
27092741

27102742
// Prepend this file to the list
2711-
mRecentProjectPaths.prepend( projectPath );
2743+
mRecentProjects.prepend( projectData );
27122744

27132745
// Keep the list to 8 items by trimming excess off the bottom
2714-
while ( mRecentProjectPaths.count() > 8 )
2746+
while ( mRecentProjects.count() > 8 )
27152747
{
2716-
mRecentProjectPaths.pop_back();
2748+
mRecentProjects.pop_back();
27172749
}
27182750

2719-
// Persist the list
2720-
settings.setValue( "/UI/recentProjectsList", mRecentProjectPaths );
2751+
settings.remove( "/UI/recentProjects" );
2752+
int idx = 0;
27212753

2754+
// Persist the list
2755+
Q_FOREACH( const QgsWelcomePageItemsModel::RecentProjectData& recentProject, mRecentProjects )
2756+
{
2757+
++idx;
2758+
settings.beginGroup( QString( "/UI/recentProjects/%1" ).arg( idx ) );
2759+
settings.setValue( "title", recentProject.title );
2760+
settings.setValue( "path", recentProject.path );
2761+
settings.setValue( "previewImage", recentProject.previewImagePath );
2762+
settings.endGroup();
2763+
}
27222764

27232765
// Update menu list of paths
27242766
updateRecentProjectPaths();
@@ -3832,9 +3874,9 @@ void QgisApp::fileOpenAfterLaunch()
38323874

38333875
// get path of project file to open, or was attempted
38343876
QString projPath = QString();
3835-
if ( projOpen == 1 && mRecentProjectPaths.size() > 0 ) // most recent project
3877+
if ( projOpen == 1 && mRecentProjects.size() > 0 ) // most recent project
38363878
{
3837-
projPath = mRecentProjectPaths.at( 0 );
3879+
projPath = mRecentProjects.at( 0 ).path;
38383880
}
38393881
if ( projOpen == 2 ) // specific project
38403882
{
@@ -4145,7 +4187,7 @@ bool QgisApp::addProject( QString projectFile )
41454187
// specific plug-in state
41464188

41474189
// add this to the list of recently used project files
4148-
saveRecentProjectPath( projectFile, settings );
4190+
saveRecentProjectPath( projectFile, false );
41494191

41504192
QApplication::restoreOverrideCursor();
41514193

@@ -4199,6 +4241,7 @@ bool QgisApp::fileSave()
41994241
else
42004242
{
42014243
QFileInfo fi( QgsProject::instance()->fileName() );
4244+
fullPath = fi.absoluteFilePath();
42024245
if ( fi.exists() && !mProjectLastModified.isNull() && mProjectLastModified != fi.lastModified() )
42034246
{
42044247
if ( QMessageBox::warning( this,
@@ -4226,12 +4269,7 @@ bool QgisApp::fileSave()
42264269
setTitleBarText_( *this ); // update title bar
42274270
statusBar()->showMessage( tr( "Saved project to: %1" ).arg( QgsProject::instance()->fileName() ), 5000 );
42284271

4229-
if ( isNewProject )
4230-
{
4231-
// add this to the list of recently used project files
4232-
QSettings settings;
4233-
saveRecentProjectPath( fullPath.filePath(), settings );
4234-
}
4272+
saveRecentProjectPath( fullPath.filePath() );
42354273

42364274
QFileInfo fi( QgsProject::instance()->fileName() );
42374275
mProjectLastModified = fi.lastModified();
@@ -4283,7 +4321,7 @@ void QgisApp::fileSaveAs()
42834321
setTitleBarText_( *this ); // update title bar
42844322
statusBar()->showMessage( tr( "Saved project to: %1" ).arg( QgsProject::instance()->fileName() ), 5000 );
42854323
// add this to the list of recently used project files
4286-
saveRecentProjectPath( fullPath.filePath(), settings );
4324+
saveRecentProjectPath( fullPath.filePath() );
42874325
}
42884326
else
42894327
{
@@ -4350,7 +4388,7 @@ void QgisApp::openProject( QAction *action )
43504388
QString debugme;
43514389
assert( action != NULL );
43524390

4353-
debugme = action->text();
4391+
debugme = action->data().toString();
43544392

43554393
if ( saveDirty() )
43564394
{

src/app/qgisapp.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class QgsTileScaleWidget;
104104
#include "qgspluginmanager.h"
105105
#include "qgsmessagebar.h"
106106
#include "qgsbookmarks.h"
107+
#include "qgswelcomepageitemsmodel.h"
107108

108109
#include "ui_qgisapp.h"
109110

@@ -1308,8 +1309,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
13081309
/** Add this file to the recently opened/saved projects list
13091310
* pass settings by reference since creating more than one
13101311
* instance simultaneously results in data loss.
1312+
*
1313+
* @param savePreviewImage Set to false when the preview image should not be saved. E.g. project load.
13111314
*/
1312-
void saveRecentProjectPath( QString projectPath, QSettings & settings );
1315+
void saveRecentProjectPath( QString projectPath, bool savePreviewImage = true );
13131316
//! Update project menu with the current list of recently accessed projects
13141317
void updateRecentProjectPaths();
13151318
//! Read Well Known Binary stream from PostGIS
@@ -1570,7 +1573,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
15701573

15711574
QSplashScreen *mSplash;
15721575
//! list of recently opened/saved project files
1573-
QStringList mRecentProjectPaths;
1576+
QList<QgsWelcomePageItemsModel::RecentProjectData> mRecentProjects;
15741577
//! Print composers of this project, accessible by id string
15751578
QSet<QgsComposer*> mPrintComposers;
15761579
//! The number of decimal places to use if not automatic

src/app/qgsprojectproperties.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ QString QgsProjectProperties::title() const
564564
void QgsProjectProperties::title( QString const & title )
565565
{
566566
titleEdit->setText( title );
567-
QgsProject::instance()->title( title );
567+
QgsProject::instance()->setTitle( title );
568568
} // QgsProjectProperties::title( QString const & title )
569569

570570
//when user clicks apply button
@@ -627,7 +627,7 @@ void QgsProjectProperties::apply()
627627
}
628628

629629
// Set the project title
630-
QgsProject::instance()->title( title() );
630+
QgsProject::instance()->setTitle( title() );
631631

632632
// set the mouse display precision method and the
633633
// number of decimal places for the manual option

src/app/qgswelcomedialog.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/***************************************************************************
2+
3+
----------------------------------------------------
4+
date : 18.8.2015
5+
copyright : (C) 2015 by Matthias Kuhn
6+
email : matthias (at) opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgswelcomedialog.h"
17+
#include "qgsproject.h"
18+
#include "qgisapp.h"
19+
20+
#include <QHBoxLayout>
21+
#include <QListView>
22+
#include <QSettings>
23+
24+
QgsWelcomeDialog::QgsWelcomeDialog()
25+
{
26+
QHBoxLayout* layout = new QHBoxLayout();
27+
setLayout( layout );
28+
29+
QListView* welcomeScreenListView = new QListView();
30+
mModel = new QgsWelcomePageItemsModel();
31+
welcomeScreenListView->setModel( mModel );
32+
layout->addWidget( welcomeScreenListView );
33+
34+
setWindowTitle( tr( "Recent Projects..." ) );
35+
36+
QSettings settings;
37+
restoreGeometry( settings.value( "/Windows/WelcomeDialog/geometry" ).toByteArray() );
38+
39+
connect( welcomeScreenListView, SIGNAL( doubleClicked( QModelIndex ) ), this, SLOT( itemDoubleClicked( QModelIndex ) ) );
40+
}
41+
42+
void QgsWelcomeDialog::setRecentProjects(const QList<QgsWelcomePageItemsModel::RecentProjectData>& recentProjects)
43+
{
44+
mModel->setRecentProjects( recentProjects );
45+
}
46+
47+
void QgsWelcomeDialog::itemDoubleClicked( const QModelIndex& index )
48+
{
49+
QgisApp::instance()->openProject( mModel->data( index, Qt::ToolTipRole ).toString() );
50+
accept();
51+
}
52+
53+
54+
void QgsWelcomeDialog::done( int result )
55+
{
56+
QDialog::done( result );
57+
QSettings settings;
58+
settings.setValue( "/Windows/WelcomeDialog/geometry", saveGeometry() );
59+
}

src/app/qgswelcomedialog.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/***************************************************************************
2+
3+
----------------------------------------------------
4+
date : 18.8.2015
5+
copyright : (C) 2015 by Matthias Kuhn
6+
email : matthias (at) opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSWELCOMEDIALOG_H
17+
#define QGSWELCOMEDIALOG_H
18+
19+
#include <QDialog>
20+
21+
#include "qgswelcomepageitemsmodel.h"
22+
23+
class QgsWelcomeDialog : public QDialog
24+
{
25+
Q_OBJECT
26+
27+
public:
28+
QgsWelcomeDialog();
29+
30+
void setRecentProjects( const QList<QgsWelcomePageItemsModel::RecentProjectData>& recentProjects );
31+
32+
private slots:
33+
void itemDoubleClicked(const QModelIndex& index );
34+
35+
private:
36+
QgsWelcomePageItemsModel* mModel;
37+
38+
public slots:
39+
void done( int result );
40+
};
41+
42+
#endif // QGSWELCOMEDIALOG_H

0 commit comments

Comments
 (0)