Skip to content

Commit

Permalink
[FEATURE] Add welcome screen with recent projects
Browse files Browse the repository at this point in the history
Refs #7626
  • Loading branch information
m-kuhn committed Aug 19, 2015
1 parent 1465e9b commit 831131d
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 45 deletions.
5 changes: 4 additions & 1 deletion src/app/CMakeLists.txt
Expand Up @@ -50,6 +50,8 @@ SET(QGIS_APP_SRCS
qgsmapmouseevent.cpp
qgssavestyletodbdialog.cpp
qgsguivectorlayertools.cpp
qgswelcomepageitemsmodel.cpp
qgswelcomedialog.cpp

qgsmaptooladdfeature.cpp
qgsmaptooladdpart.cpp
Expand Down Expand Up @@ -108,7 +110,6 @@ SET(QGIS_APP_SRCS
qgsstatisticalsummarydockwidget.cpp
qgstextannotationdialog.cpp
qgsshortcutsmanager.cpp
qgsguivectorlayertools.h
qgssnappingdialog.cpp
qgssvgannotationdialog.cpp
qgsundowidget.cpp
Expand Down Expand Up @@ -209,6 +210,8 @@ SET (QGIS_APP_MOC_HDRS
qgsshortcutsmanager.h
qgsapplayertreeviewmenuprovider.h
qgsguivectorlayertools.h
qgswelcomepageitemsmodel.h
qgswelcomedialog.h

qgsmaptooladdfeature.h
qgsmaptoolcapture.h
Expand Down
118 changes: 78 additions & 40 deletions src/app/qgisapp.cpp
Expand Up @@ -211,6 +211,8 @@
#include "qgsmessagelogviewer.h"
#include "qgsdataitem.h"
#include "qgsmaplayeractionregistry.h"
#include "qgswelcomedialog.h"
#include "qgsmaprendererparalleljob.h"

#include "qgssublayersdialog.h"
#include "ogr/qgsopenvectorlayerdialog.h"
Expand Down Expand Up @@ -869,6 +871,10 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
#ifdef ANDROID
toggleFullScreen();
#endif

QgsWelcomeDialog dlg;
dlg.setRecentProjects( mRecentProjects );
dlg.exec();
} // QgisApp ctor

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

// Add the recently accessed project file paths to the Project menu
mRecentProjectPaths = settings.value( "/UI/recentProjectsList" ).toStringList();
settings.beginGroup( "/UI/recentProjects" );
QStringList projectKeys = settings.childGroups();

mRecentProjects.clear();

Q_FOREACH( const QString& key, projectKeys )
{
QgsWelcomePageItemsModel::RecentProjectData data;
settings.beginGroup( key );
data.title = settings.value( "title" ).toString();
data.path = settings.value( "path" ).toString();
data.previewImagePath = settings.value( "previewImage" ).toString();
settings.endGroup();
mRecentProjects.prepend( data );
}
settings.endGroup();

// this is a new session! reset enable macros value to "ask"
// whether set to "just for this session"
Expand Down Expand Up @@ -2673,52 +2693,74 @@ void QgisApp::projectReadDecorationItems()
// Update project menu with the current list of recently accessed projects
void QgisApp::updateRecentProjectPaths()
{
// Remove existing paths from the recent projects menu
int i;

int menusize = mRecentProjectsMenu->actions().size();
mRecentProjectsMenu->clear();

for ( i = menusize; i < mRecentProjectPaths.size(); i++ )
Q_FOREACH( const QgsWelcomePageItemsModel::RecentProjectData& recentProject, mRecentProjects )
{
mRecentProjectsMenu->addAction( "Dummy text" );
}

QList<QAction *> menulist = mRecentProjectsMenu->actions();

assert( menulist.size() == mRecentProjectPaths.size() );

for ( i = 0; i < mRecentProjectPaths.size(); i++ )
{
menulist.at( i )->setText( mRecentProjectPaths.at( i ) );

// Disable this menu item if the file has been removed, if not enable it
menulist.at( i )->setEnabled( QFile::exists(( mRecentProjectPaths.at( i ) ) ) );

QAction* action = mRecentProjectsMenu->addAction( QString( "%1 (%2)" ).arg( recentProject.title ).arg( recentProject.path ) );
action->setEnabled( QFile::exists(( recentProject.path ) ) );
action->setData( recentProject.path );
}
} // QgisApp::updateRecentProjectPaths

// add this file to the recently opened/saved projects list
void QgisApp::saveRecentProjectPath( QString projectPath, QSettings & settings )
void QgisApp::saveRecentProjectPath( QString projectPath, bool savePreviewImage )
{
QSettings settings;

// Get canonical absolute path
QFileInfo myFileInfo( projectPath );
projectPath = myFileInfo.absoluteFilePath();
QgsWelcomePageItemsModel::RecentProjectData projectData;
projectData.path = myFileInfo.absoluteFilePath();
projectData.title = QgsProject::instance()->title();
if ( projectData.title.isEmpty() )
projectData.title = projectData.path;

if ( savePreviewImage )
{
QgsMapSettings mapSettings = mMapCanvas->mapSettings();
mapSettings.setOutputSize( QSize( 200, 70 ) );
QgsMapRendererParallelJob job( mapSettings );
job.start();
job.waitForFinished();
QString fileName( QCryptographicHash::hash( ( projectData.path.toUtf8() ), QCryptographicHash::Md5 ).toHex() );
QString previewDir = QString( "%1/previewImages" ).arg( QgsApplication::qgisSettingsDirPath() );
projectData.previewImagePath = QString( "%1/%2.png" ).arg( previewDir ).arg( fileName );
QDir().mkdir( previewDir );
job.renderedImage().save( projectData.previewImagePath );
}
else
{
int idx = mRecentProjects.indexOf( projectData );
if ( idx != -1 )
projectData.previewImagePath = mRecentProjects.at( idx ).previewImagePath;
}

// If this file is already in the list, remove it
mRecentProjectPaths.removeAll( projectPath );
mRecentProjects.removeAll( projectData );

// Prepend this file to the list
mRecentProjectPaths.prepend( projectPath );
mRecentProjects.prepend( projectData );

// Keep the list to 8 items by trimming excess off the bottom
while ( mRecentProjectPaths.count() > 8 )
while ( mRecentProjects.count() > 8 )
{
mRecentProjectPaths.pop_back();
mRecentProjects.pop_back();
}

// Persist the list
settings.setValue( "/UI/recentProjectsList", mRecentProjectPaths );
settings.remove( "/UI/recentProjects" );
int idx = 0;

// Persist the list
Q_FOREACH( const QgsWelcomePageItemsModel::RecentProjectData& recentProject, mRecentProjects )
{
++idx;
settings.beginGroup( QString( "/UI/recentProjects/%1" ).arg( idx ) );
settings.setValue( "title", recentProject.title );
settings.setValue( "path", recentProject.path );
settings.setValue( "previewImage", recentProject.previewImagePath );
settings.endGroup();
}

// Update menu list of paths
updateRecentProjectPaths();
Expand Down Expand Up @@ -3832,9 +3874,9 @@ void QgisApp::fileOpenAfterLaunch()

// get path of project file to open, or was attempted
QString projPath = QString();
if ( projOpen == 1 && mRecentProjectPaths.size() > 0 ) // most recent project
if ( projOpen == 1 && mRecentProjects.size() > 0 ) // most recent project
{
projPath = mRecentProjectPaths.at( 0 );
projPath = mRecentProjects.at( 0 ).path;
}
if ( projOpen == 2 ) // specific project
{
Expand Down Expand Up @@ -4145,7 +4187,7 @@ bool QgisApp::addProject( QString projectFile )
// specific plug-in state

// add this to the list of recently used project files
saveRecentProjectPath( projectFile, settings );
saveRecentProjectPath( projectFile, false );

QApplication::restoreOverrideCursor();

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

if ( isNewProject )
{
// add this to the list of recently used project files
QSettings settings;
saveRecentProjectPath( fullPath.filePath(), settings );
}
saveRecentProjectPath( fullPath.filePath() );

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

debugme = action->text();
debugme = action->data().toString();

if ( saveDirty() )
{
Expand Down
7 changes: 5 additions & 2 deletions src/app/qgisapp.h
Expand Up @@ -104,6 +104,7 @@ class QgsTileScaleWidget;
#include "qgspluginmanager.h"
#include "qgsmessagebar.h"
#include "qgsbookmarks.h"
#include "qgswelcomepageitemsmodel.h"

#include "ui_qgisapp.h"

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

QSplashScreen *mSplash;
//! list of recently opened/saved project files
QStringList mRecentProjectPaths;
QList<QgsWelcomePageItemsModel::RecentProjectData> mRecentProjects;
//! Print composers of this project, accessible by id string
QSet<QgsComposer*> mPrintComposers;
//! The number of decimal places to use if not automatic
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -564,7 +564,7 @@ QString QgsProjectProperties::title() const
void QgsProjectProperties::title( QString const & title )
{
titleEdit->setText( title );
QgsProject::instance()->title( title );
QgsProject::instance()->setTitle( title );
} // QgsProjectProperties::title( QString const & title )

//when user clicks apply button
Expand Down Expand Up @@ -627,7 +627,7 @@ void QgsProjectProperties::apply()
}

// Set the project title
QgsProject::instance()->title( title() );
QgsProject::instance()->setTitle( title() );

// set the mouse display precision method and the
// number of decimal places for the manual option
Expand Down
59 changes: 59 additions & 0 deletions src/app/qgswelcomedialog.cpp
@@ -0,0 +1,59 @@
/***************************************************************************
----------------------------------------------------
date : 18.8.2015
copyright : (C) 2015 by Matthias Kuhn
email : matthias (at) opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgswelcomedialog.h"
#include "qgsproject.h"
#include "qgisapp.h"

#include <QHBoxLayout>
#include <QListView>
#include <QSettings>

QgsWelcomeDialog::QgsWelcomeDialog()
{
QHBoxLayout* layout = new QHBoxLayout();
setLayout( layout );

QListView* welcomeScreenListView = new QListView();
mModel = new QgsWelcomePageItemsModel();
welcomeScreenListView->setModel( mModel );
layout->addWidget( welcomeScreenListView );

setWindowTitle( tr( "Recent Projects..." ) );

QSettings settings;
restoreGeometry( settings.value( "/Windows/WelcomeDialog/geometry" ).toByteArray() );

connect( welcomeScreenListView, SIGNAL( doubleClicked( QModelIndex ) ), this, SLOT( itemDoubleClicked( QModelIndex ) ) );
}

void QgsWelcomeDialog::setRecentProjects(const QList<QgsWelcomePageItemsModel::RecentProjectData>& recentProjects)
{
mModel->setRecentProjects( recentProjects );
}

void QgsWelcomeDialog::itemDoubleClicked( const QModelIndex& index )
{
QgisApp::instance()->openProject( mModel->data( index, Qt::ToolTipRole ).toString() );
accept();
}


void QgsWelcomeDialog::done( int result )
{
QDialog::done( result );
QSettings settings;
settings.setValue( "/Windows/WelcomeDialog/geometry", saveGeometry() );
}
42 changes: 42 additions & 0 deletions src/app/qgswelcomedialog.h
@@ -0,0 +1,42 @@
/***************************************************************************
----------------------------------------------------
date : 18.8.2015
copyright : (C) 2015 by Matthias Kuhn
email : matthias (at) opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSWELCOMEDIALOG_H
#define QGSWELCOMEDIALOG_H

#include <QDialog>

#include "qgswelcomepageitemsmodel.h"

class QgsWelcomeDialog : public QDialog
{
Q_OBJECT

public:
QgsWelcomeDialog();

void setRecentProjects( const QList<QgsWelcomePageItemsModel::RecentProjectData>& recentProjects );

private slots:
void itemDoubleClicked(const QModelIndex& index );

private:
QgsWelcomePageItemsModel* mModel;

public slots:
void done( int result );
};

#endif // QGSWELCOMEDIALOG_H

0 comments on commit 831131d

Please sign in to comment.