don't reload the whole browser model when the project home changes (fixes #7520)

This commit is contained in:
Juergen E. Fischer 2013-05-11 21:30:42 +02:00
parent d8dac0cbbd
commit fa0a9b75fe
10 changed files with 149 additions and 82 deletions

View File

@ -54,9 +54,6 @@ class QgsBrowserModel : QAbstractItemModel
bool hasChildren( const QModelIndex &parent = QModelIndex() ) const; bool hasChildren( const QModelIndex &parent = QModelIndex() ) const;
// Reload the whole model
void reload();
// Refresh item specified by path // Refresh item specified by path
void refresh( QString path ); void refresh( QString path );
@ -68,14 +65,23 @@ class QgsBrowserModel : QAbstractItemModel
void connectItem( QgsDataItem *item ); void connectItem( QgsDataItem *item );
bool canFetchMore( const QModelIndex & parent ) const;
void fetchMore( const QModelIndex & parent );
public slots: public slots:
// Reload the whole model
void reload();
void beginInsertItems( QgsDataItem *parent, int first, int last ); void beginInsertItems( QgsDataItem *parent, int first, int last );
void endInsertItems(); void endInsertItems();
void beginRemoveItems( QgsDataItem *parent, int first, int last ); void beginRemoveItems( QgsDataItem *parent, int first, int last );
void endRemoveItems(); void endRemoveItems();
protected: void addFavouriteDirectory( QString favDir );
void removeFavourite( const QModelIndex &index );
void updateProjectHome();
protected:
// populates the model // populates the model
void addRootItems(); void addRootItems();
void removeRootItems(); void removeRootItems();

View File

@ -29,6 +29,7 @@ class QgsDataItem : QObject
// Populate children using children vector created by createChildren() // Populate children using children vector created by createChildren()
virtual void populate(); virtual void populate();
bool isPopulated();
// Insert new child using alphabetical order based on mName, emits necessary signal to model before and after, sets parent and connects signals // Insert new child using alphabetical order based on mName, emits necessary signal to model before and after, sets parent and connects signals
// refresh - refresh populated item, emit signals to model // refresh - refresh populated item, emit signals to model
@ -212,6 +213,22 @@ class QgsErrorItem : QgsDataItem
}; };
// ---------
class CORE_EXPORT QgsDirectoryParamWidget : public QTreeWidget
{
Q_OBJECT
public:
QgsDirectoryParamWidget( QString path, QWidget* parent = NULL );
protected:
void mousePressEvent( QMouseEvent* event );
public slots:
void showHideColumn();
};
/** Contains various Favourites directories */ /** Contains various Favourites directories */
class QgsFavouritesItem : QgsDataCollectionItem class QgsFavouritesItem : QgsDataCollectionItem
{ {
@ -224,6 +241,9 @@ class QgsFavouritesItem : QgsDataCollectionItem
QVector<QgsDataItem*> createChildren(); QVector<QgsDataItem*> createChildren();
void addDirectory( QString favIcon );
void removeDirectory( QgsDirectoryItem *item );
static const QIcon &iconFavourites(); static const QIcon &iconFavourites();
}; };

View File

@ -90,13 +90,10 @@ class QgsProject : QObject
- Registers maplayers - Registers maplayers
@note it's presumed that the caller has already reset the map canvas, map registry, and legend @note it's presumed that the caller has already reset the map canvas, map registry, and legend
@exception
*/ */
//@{ //@{
bool read( const QFileInfo & file ); bool read( const QFileInfo & file );
bool read( ); bool read();
//@} //@}
@ -126,7 +123,7 @@ class QgsProject : QObject
*/ */
//@{ //@{
bool write( const QFileInfo & file ); bool write( const QFileInfo & file );
bool write( ); bool write();
//@} //@}
@ -252,7 +249,8 @@ class QgsProject : QObject
/**Creates a maplayer instance defined in an arbitrary project file. Caller takes ownership /**Creates a maplayer instance defined in an arbitrary project file. Caller takes ownership
@return the layer or 0 in case of error @return the layer or 0 in case of error
@note: added in version 1.8*/ @note: added in version 1.8
*/
/* /*
bool createEmbeddedLayer( const QString& layerId, const QString& projectFilePath, QList<QDomNode>& brokenNodes, bool createEmbeddedLayer( const QString& layerId, const QString& projectFilePath, QList<QDomNode>& brokenNodes,
QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList, bool saveFlag = true ); QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList, bool saveFlag = true );
@ -276,6 +274,11 @@ class QgsProject : QObject
@note added in version 1.9*/ @note added in version 1.9*/
bool topologicalEditing() const; bool topologicalEditing() const;
/** Return project's home path
@return home path of project (or QString::null if not set)
@note added in version 2.0 */
QString homePath() const;
protected: protected:
/** Set error message from read/write operation /** Set error message from read/write operation
@ -290,7 +293,6 @@ class QgsProject : QObject
// bool addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList ); // bool addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList );
signals: signals:
//! emitted when project is being read //! emitted when project is being read
void readProject( const QDomDocument & ); void readProject( const QDomDocument & );
@ -298,24 +300,27 @@ class QgsProject : QObject
void writeProject( QDomDocument & ); void writeProject( QDomDocument & );
/** /**
* Emitted, after the basic initialisation of a layer from the project * Emitted, after the basic initialisation of a layer from the project
* file is done. You can use this signal to read additional information * file is done. You can use this signal to read additional information
* from the project file. * from the project file.
* *
* @param mapLayer The map layer which is being initialized * @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file * @param layerNode The layer node from the project file
*/ */
void readMapLayer( QgsMapLayer* mapLayer, const QDomElement& layerNode ); void readMapLayer( QgsMapLayer *mapLayer, const QDomElement &layerNode );
/** /**
* Emitted, when a layer is being saved. You can use this method to save * Emitted, when a layer is being saved. You can use this method to save
* additional information to the layer. * additional information to the layer.
* *
* @param mapLayer The map layer which is being initialized * @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file * @param layerElem The layer element from the project file
* @param doc The document * @param doc The document
*/ */
void writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc ); void writeMapLayer( QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc );
//! emitted when the project file has been written and closed
void projectSaved();
//! emitted when an old project file is read. //! emitted when an old project file is read.
void oldProjectVersionWarning( QString ); void oldProjectVersionWarning( QString );
@ -325,6 +330,8 @@ class QgsProject : QObject
// @param n number of layers // @param n number of layers
void layerLoaded( int i, int n ); void layerLoaded( int i, int n );
void loadingLayer( QString );
void snapSettingsChanged(); void snapSettingsChanged();
private: private:

View File

@ -92,8 +92,8 @@ class QgsBrowserTreeFilterProxyModel : public QSortFilterProxyModel
public: public:
QgsBrowserTreeFilterProxyModel( QObject *parent ) QgsBrowserTreeFilterProxyModel( QObject *parent )
: QSortFilterProxyModel( parent ), mModel( 0 ), : QSortFilterProxyModel( parent ), mModel( 0 )
mFilter( "" ), mPatternSyntax( QRegExp::Wildcard ) , mFilter( "" ), mPatternSyntax( QRegExp::Wildcard )
{ {
setDynamicSortFilter( true ); setDynamicSortFilter( true );
} }
@ -266,10 +266,12 @@ QgsBrowserDockWidget::QgsBrowserDockWidget( QString name, QWidget * parent ) :
void QgsBrowserDockWidget::showEvent( QShowEvent * e ) void QgsBrowserDockWidget::showEvent( QShowEvent * e )
{ {
// delayed initialization of the model // delayed initialization of the model
if ( mModel == NULL ) if ( !mModel )
{ {
mModel = new QgsBrowserModel( mBrowserView ); mModel = new QgsBrowserModel( mBrowserView );
connect( QgisApp::instance(), SIGNAL( newProject() ), mModel, SLOT( updateProjectHome() ) );
mProxyModel = new QgsBrowserTreeFilterProxyModel( this ); mProxyModel = new QgsBrowserTreeFilterProxyModel( this );
mProxyModel->setBrowserModel( mModel ); mProxyModel->setBrowserModel( mModel );
mBrowserView->setModel( mProxyModel ); mBrowserView->setModel( mProxyModel );
@ -286,10 +288,6 @@ void QgsBrowserDockWidget::showEvent( QShowEvent * e )
if ( item && item->type() == QgsDataItem::Favourites ) if ( item && item->type() == QgsDataItem::Favourites )
mBrowserView->expand( index ); mBrowserView->expand( index );
} }
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), mModel, SLOT( reload() ) );
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ), mModel, SLOT( reload() ) );
connect( QgisApp::instance(), SIGNAL( newProject() ), mModel, SLOT( reload() ) );
} }
QDockWidget::showEvent( e ); QDockWidget::showEvent( e );
@ -380,34 +378,12 @@ void QgsBrowserDockWidget::addFavouriteDirectory()
void QgsBrowserDockWidget::addFavouriteDirectory( QString favDir ) void QgsBrowserDockWidget::addFavouriteDirectory( QString favDir )
{ {
QSettings settings; mModel->addFavouriteDirectory( favDir );
QStringList favDirs = settings.value( "/browser/favourites" ).toStringList();
favDirs.append( favDir );
settings.setValue( "/browser/favourites", favDirs );
// reload the browser model so that the newly added favourite directory is shown
mModel->reload();
} }
void QgsBrowserDockWidget::removeFavourite() void QgsBrowserDockWidget::removeFavourite()
{ {
QModelIndex index = mProxyModel->mapToSource( mBrowserView->currentIndex() ); mModel->removeFavourite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
QgsDataItem* item = mModel->dataItem( index );
if ( !item )
return;
if ( item->type() != QgsDataItem::Directory )
return;
QString favDir = item->path();
QSettings settings;
QStringList favDirs = settings.value( "/browser/favourites" ).toStringList();
favDirs.removeAll( favDir );
settings.setValue( "/browser/favourites", favDirs );
// reload the browser model so that the favourite directory is not shown anymore
mModel->reload();
} }
void QgsBrowserDockWidget::refresh() void QgsBrowserDockWidget::refresh()

View File

@ -30,8 +30,7 @@ class QgsBrowserDockWidget : public QDockWidget, private Ui::QgsBrowserDockWidge
Q_OBJECT Q_OBJECT
public: public:
explicit QgsBrowserDockWidget( QString name, QWidget *parent = 0 ); explicit QgsBrowserDockWidget( QString name, QWidget *parent = 0 );
void addFavouriteDirectory( QString favDir );
signals:
public slots: public slots:
void addLayerAtIndex( const QModelIndex& index ); void addLayerAtIndex( const QModelIndex& index );
@ -54,16 +53,12 @@ class QgsBrowserDockWidget : public QDockWidget, private Ui::QgsBrowserDockWidge
void toggleFastScan(); void toggleFastScan();
protected: protected:
void addFavouriteDirectory( QString favDir );
void refreshModel( const QModelIndex& index ); void refreshModel( const QModelIndex& index );
void showEvent( QShowEvent * event ); void showEvent( QShowEvent * event );
void addLayer( QgsLayerItem *layerItem ); void addLayer( QgsLayerItem *layerItem );
// removed dataItem(), call mModel->dataItem directly (to avoid passing index from the wrong model)
QgsBrowserTreeView* mBrowserView; QgsBrowserTreeView* mBrowserView;
QgsBrowserModel* mModel; QgsBrowserModel* mModel;
QgsBrowserTreeFilterProxyModel* mProxyModel; QgsBrowserTreeFilterProxyModel* mProxyModel;

View File

@ -28,9 +28,13 @@
#include <QSettings> #include <QSettings>
QgsBrowserModel::QgsBrowserModel( QObject *parent ) : QgsBrowserModel::QgsBrowserModel( QObject *parent )
QAbstractItemModel( parent ) : QAbstractItemModel( parent )
, mFavourites( 0 )
, mProjectHome( 0 )
{ {
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), this, SLOT( updateProjectHome() ) );
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ), this, SLOT( updateProjectHome() ) );
addRootItems(); addRootItems();
} }
@ -39,20 +43,35 @@ QgsBrowserModel::~QgsBrowserModel()
removeRootItems(); removeRootItems();
} }
void QgsBrowserModel::addRootItems() void QgsBrowserModel::updateProjectHome()
{ {
QgsDirectoryItem *item; int idx = mRootItems.indexOf( mProjectHome );
QString home = QgsProject::instance()->homePath(); QString home = QgsProject::instance()->homePath();
if ( !home.isNull() ) delete mProjectHome;
mProjectHome = home.isNull() ? 0 : new QgsDirectoryItem( NULL, tr( "Project home" ), home );
if ( mProjectHome )
{ {
item = new QgsDirectoryItem( NULL, tr( "Project home" ), home ); connectItem( mProjectHome );
mRootItems << item; if ( idx < 0 )
mRootItems.insert( 0, mProjectHome );
else
mRootItems.replace( idx, mProjectHome );
} }
else if ( idx >= 0 )
{
mRootItems.remove( idx );
}
emit layoutChanged();
}
void QgsBrowserModel::addRootItems()
{
updateProjectHome();
// give the home directory a prominent second place // give the home directory a prominent second place
item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() ); QgsDirectoryItem *item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
QStyle *style = QApplication::style(); QStyle *style = QApplication::style();
QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) ); QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) );
item->setIcon( homeIcon ); item->setIcon( homeIcon );
@ -60,11 +79,11 @@ void QgsBrowserModel::addRootItems()
mRootItems << item; mRootItems << item;
// add favourite directories // add favourite directories
QgsFavouritesItem *favitem = new QgsFavouritesItem( NULL, tr( "Favourites" ) ); mFavourites = new QgsFavouritesItem( NULL, tr( "Favourites" ) );
if ( favitem ) if ( mFavourites )
{ {
connectItem( favitem ); connectItem( mFavourites );
mRootItems << favitem; mRootItems << mFavourites ;
} }
// add drives // add drives
@ -107,7 +126,7 @@ void QgsBrowserModel::addRootItems()
continue; continue;
} }
dataItem_t * dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) ); dataItem_t *dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
if ( !dataItem ) if ( !dataItem )
{ {
QgsDebugMsg( library->fileName() + " does not have dataItem" ); QgsDebugMsg( library->fileName() + " does not have dataItem" );
@ -426,3 +445,18 @@ void QgsBrowserModel::fetchMore( const QModelIndex & parent )
item->populate(); item->populate();
QgsDebugMsg( "path = " + item->path() ); QgsDebugMsg( "path = " + item->path() );
} }
void QgsBrowserModel::addFavouriteDirectory( QString favDir )
{
Q_ASSERT( mFavourites );
mFavourites->addDirectory( favDir );
}
void QgsBrowserModel::removeFavourite( const QModelIndex &index )
{
QgsDirectoryItem *item = dynamic_cast<QgsDirectoryItem *>( dataItem( index ) );
if ( !item )
return;
mFavourites->removeDirectory( item );
}

View File

@ -92,19 +92,24 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
public slots: public slots:
// Reload the whole model // Reload the whole model
void reload(); void reload();
void beginInsertItems( QgsDataItem *parent, int first, int last ); void beginInsertItems( QgsDataItem *parent, int first, int last );
void endInsertItems(); void endInsertItems();
void beginRemoveItems( QgsDataItem *parent, int first, int last ); void beginRemoveItems( QgsDataItem *parent, int first, int last );
void endRemoveItems(); void endRemoveItems();
protected: void addFavouriteDirectory( QString favDir );
void removeFavourite( const QModelIndex &index );
void updateProjectHome();
protected:
// populates the model // populates the model
void addRootItems(); void addRootItems();
void removeRootItems(); void removeRootItems();
QVector<QgsDataItem*> mRootItems; QVector<QgsDataItem*> mRootItems;
QgsFavouritesItem *mFavourites;
QgsDirectoryItem *mProjectHome;
}; };
#endif // QGSBROWSERMODEL_H #endif // QGSBROWSERMODEL_H

View File

@ -190,7 +190,7 @@ void QgsDataItem::populate()
QApplication::setOverrideCursor( Qt::WaitCursor ); QApplication::setOverrideCursor( Qt::WaitCursor );
QVector<QgsDataItem*> children = createChildren( ); QVector<QgsDataItem*> children = createChildren();
foreach ( QgsDataItem *child, children ) foreach ( QgsDataItem *child, children )
{ {
// initialization, do not refresh! That would result in infinite loop (beginInsertItems->rowCount->populate) // initialization, do not refresh! That would result in infinite loop (beginInsertItems->rowCount->populate)
@ -301,7 +301,7 @@ void QgsDataItem::refresh()
QApplication::setOverrideCursor( Qt::WaitCursor ); QApplication::setOverrideCursor( Qt::WaitCursor );
QVector<QgsDataItem*> items = createChildren( ); QVector<QgsDataItem*> items = createChildren();
// Remove no more present items // Remove no more present items
QVector<QgsDataItem*> remove; QVector<QgsDataItem*> remove;
@ -448,7 +448,7 @@ QgsDirectoryItem::~QgsDirectoryItem()
{ {
} }
QVector<QgsDataItem*> QgsDirectoryItem::createChildren( ) QVector<QgsDataItem*> QgsDirectoryItem::createChildren()
{ {
QVector<QgsDataItem*> children; QVector<QgsDataItem*> children;
QDir dir( mPath ); QDir dir( mPath );
@ -692,17 +692,16 @@ QgsFavouritesItem::~QgsFavouritesItem()
{ {
} }
QVector<QgsDataItem*> QgsFavouritesItem::createChildren( ) QVector<QgsDataItem*> QgsFavouritesItem::createChildren()
{ {
QVector<QgsDataItem*> children; QVector<QgsDataItem*> children;
QgsDataItem* item;
QSettings settings; QSettings settings;
QStringList favDirs = settings.value( "/browser/favourites", QVariant() ).toStringList(); QStringList favDirs = settings.value( "/browser/favourites", QVariant() ).toStringList();
foreach ( QString favDir, favDirs ) foreach ( QString favDir, favDirs )
{ {
item = new QgsDirectoryItem( this, favDir, favDir ); QgsDataItem *item = new QgsDirectoryItem( this, favDir, favDir );
if ( item ) if ( item )
{ {
children.append( item ); children.append( item );
@ -712,6 +711,29 @@ QVector<QgsDataItem*> QgsFavouritesItem::createChildren( )
return children; return children;
} }
void QgsFavouritesItem::addDirectory( QString favDir )
{
QSettings settings;
QStringList favDirs = settings.value( "/browser/favourites" ).toStringList();
favDirs.append( favDir );
settings.setValue( "/browser/favourites", favDirs );
addChildItem( new QgsDirectoryItem( this, favDir, favDir ), true );
}
void QgsFavouritesItem::removeDirectory( QgsDirectoryItem *item )
{
if ( !item )
return;
QSettings settings;
QStringList favDirs = settings.value( "/browser/favourites" ).toStringList();
favDirs.removeAll( item->path() );
settings.setValue( "/browser/favourites", favDirs );
deleteChildItem( item );
}
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
QStringList QgsZipItem::mProviderNames = QStringList(); QStringList QgsZipItem::mProviderNames = QStringList();
QVector<dataItem_t *> QgsZipItem::mDataItemPtr = QVector<dataItem_t*>(); QVector<dataItem_t *> QgsZipItem::mDataItemPtr = QVector<dataItem_t*>();
@ -849,7 +871,7 @@ char **VSIReadDirRecursive1( const char *pszPath )
return papszOFiles; return papszOFiles;
} }
QVector<QgsDataItem*> QgsZipItem::createChildren( ) QVector<QgsDataItem*> QgsZipItem::createChildren()
{ {
QVector<QgsDataItem*> children; QVector<QgsDataItem*> children;
QString tmpPath; QString tmpPath;

View File

@ -241,7 +241,7 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
virtual bool equal( const QgsDataItem *other ); virtual bool equal( const QgsDataItem *other );
virtual QWidget * paramWidget(); virtual QWidget *paramWidget();
/* static QVector<QgsDataProvider*> mProviders; */ /* static QVector<QgsDataProvider*> mProviders; */
//! @note not available via python bindings //! @note not available via python bindings
@ -290,6 +290,9 @@ class CORE_EXPORT QgsFavouritesItem : public QgsDataCollectionItem
QVector<QgsDataItem*> createChildren(); QVector<QgsDataItem*> createChildren();
void addDirectory( QString favIcon );
void removeDirectory( QgsDirectoryItem *item );
static const QIcon &iconFavourites(); static const QIcon &iconFavourites();
}; };

View File

@ -136,7 +136,7 @@ class CORE_EXPORT QgsProject : public QObject
*/ */
//@{ //@{
bool read( const QFileInfo & file ); bool read( const QFileInfo & file );
bool read( ); bool read();
//@} //@}
@ -166,7 +166,7 @@ class CORE_EXPORT QgsProject : public QObject
*/ */
//@{ //@{
bool write( const QFileInfo & file ); bool write( const QFileInfo & file );
bool write( ); bool write();
//@} //@}
@ -307,12 +307,12 @@ class CORE_EXPORT QgsProject : public QObject
void setTopologicalEditing( bool enabled ); void setTopologicalEditing( bool enabled );
/**Convenience function to query topological editing status /**Convenience function to query topological editing status
@note added in version 1.9*/ @note added in version 1.9*/
bool topologicalEditing() const; bool topologicalEditing() const;
/** Return project's home path /** Return project's home path
@return home path of project (or QString::null if not set) @return home path of project (or QString::null if not set)
@note added in version 2.0 */ @note added in version 2.0 */
QString homePath() const; QString homePath() const;
protected: protected:
@ -330,7 +330,6 @@ class CORE_EXPORT QgsProject : public QObject
bool addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList ); bool addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList );
signals: signals:
//! emitted when project is being read //! emitted when project is being read
void readProject( const QDomDocument & ); void readProject( const QDomDocument & );