Skip to content
Browse files
Change in handling of missing layers within QgsProject. Instead of th…
…rowing an exception, now a custom handler is called

that might try to fix the missing layers. There's a default handler (QgsProjectBadLayerDefaultHandler) which simply ignores
all missing layers. Then there's a GUI handler (QgsProjectBadLayerGuiHandler) in GUI library which asks user about
the path for missing layers. QGIS application automatically installs the GUI handler on startup.

This should allow python plugins/applications to work with QgsProject without a fear of a segfault as there are no more
exceptions thrown during load/save of the project files.

Some further notes:
- removed QgsProjectBadLayerException class and (now empty) qgsexception.cpp file
- openFilesRememberingFilter() moved to QgisGui namespace (was duplicated: QgisApp vs QgsOpenVectorLayerDialog)
- removed deprecated buildVectorFilters_ methods
- added python bindings for new classes/methods

git-svn-id: c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Dec 7, 2009
1 parent 90eac5e commit 4bb5cad
Show file tree
Hide file tree
Showing 16 changed files with 589 additions and 755 deletions.
@@ -235,6 +235,11 @@ public:
@note added in 1.4 */
QString error() const;

/** Change handler for missing layers.
Deletes old handler and takes ownership of the new one.
@note added in 1.4 */
void setBadLayerHandler( QgsProjectBadLayerHandler* handler );


/** Set error message from read/write operation
@@ -259,3 +264,30 @@ public:

}; // QgsProject

/** Interface for classes that handle missing layer files when reading project file.
@note added in 1.4 */
class QgsProjectBadLayerHandler
#include <qgsproject.h>

virtual void handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom ) = 0;
virtual ~QgsProjectBadLayerHandler();

/** Default bad layer handler which ignores any missing layers.
@note added in 1.4 */
class QgsProjectBadLayerDefaultHandler : QgsProjectBadLayerHandler
#include <qgsproject.h>

virtual void handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom );

@@ -22,6 +22,7 @@
%Include qgsmaptoolzoom.sip
%Include qgsmapoverviewcanvas.sip
%Include qgsmessageviewer.sip
%Include qgsprojectbadlayerguihandler.sip
%Include qgsprojectionselector.sip
%Include qgsquickprint.sip
%Include qgsrubberband.sip
@@ -0,0 +1,21 @@

/** \ingroup gui
Handler for missing layers within project.

Gives user a chance to select path to the missing layers.

@note added in 1.4
class QgsProjectBadLayerGuiHandler : QObject, QgsProjectBadLayerHandler
#include <qgsprojectbadlayerguihandler.h>


/** implementation of the handler */
virtual void handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom );

@@ -97,11 +97,11 @@ QStringList QgsOpenVectorLayerDialog::openFile()

QStringList selectedFiles;
QgsDebugMsg( "Vector file filters: " + mVectorFileFilter );
QString enc;
QString enc = encoding();
QString title = tr( "Open an OGR Supported Vector Layer" );
openFilesRememberingFilter( "lastVectorFileFilter", mVectorFileFilter, selectedFiles,
title );
mEnc = enc;
QgisGui::openFilesRememberingFilter( "lastVectorFileFilter", mVectorFileFilter, selectedFiles, enc,
title );

return selectedFiles;

@@ -306,68 +306,6 @@ void QgsOpenVectorLayerDialog::on_buttonSelectSrc_clicked()


Open files, preferring to have the default file selector be the
last one used, if any; also, prefer to start in the last directory
associated with filterName.
@param filterName the name of the filter; used for persistent store
@param filters the file filters used for QFileDialog
@param selectedFiles string list of selected files; will be empty
if none selected
@param title the title for the dialog
Stores persistent settings under /UI/. The sub-keys will be
filterName and filterName + "Dir".
Opens dialog on last directory associated with the filter name, or
the current working directory if this is the first time invoked
with the current filter name.
void QgsOpenVectorLayerDialog::openFilesRememberingFilter( QString const &filterName,
QString const &filters, QStringList & selectedFiles, QString &title )

bool haveLastUsedFilter = false; // by default, there is no last
// used filter

QSettings settings; // where we keep last used filter in

// persistant state

haveLastUsedFilter = settings.contains( "/UI/" + filterName );
QString lastUsedFilter = settings.value( "/UI/" + filterName,
QVariant( QString::null ) ).toString();

QString lastUsedDir = settings.value( "/UI/" + filterName + "Dir", "." ).toString();
QgsDebugMsg( "Opening file dialog with filters: " + filters );

if ( haveLastUsedFilter )
selectedFiles = QFileDialog::getOpenFileNames( 0, title, lastUsedDir, filters, &lastUsedFilter );
selectedFiles = QFileDialog::getOpenFileNames( 0, title, lastUsedDir, filters );

if ( !selectedFiles.isEmpty() )
QString myFirstFileName = selectedFiles.first();
QFileInfo myFI( myFirstFileName );
QString myPath = myFI.path();

QgsDebugMsg( "Writing last used dir: " + myPath );

settings.setValue( "/UI/" + filterName, lastUsedFilter );
settings.setValue( "/UI/" + filterName + "Dir", myPath );
} // openFilesRememberingFilter_

//********************auto connected slots *****************/
@@ -46,9 +46,6 @@ class QgsOpenVectorLayerDialog : public QDialog, private Ui::QgsOpenVectorLayerD
//! Returns the connection type
QString dataSourceType();
//! Shows a dialog remembering the last directory and filter selected */
void openFilesRememberingFilter( QString const &filterName,
QString const &filters, QStringList & selectedFiles, QString &title );
//! Stores the file vector filters */
QString mVectorFileFilter;
//! Stores the selected datasources */

0 comments on commit 4bb5cad

Please sign in to comment.