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

View File

@ -29,6 +29,7 @@ class QgsDataItem : QObject
// Populate children using children vector created by createChildren()
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
// 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 */
class QgsFavouritesItem : QgsDataCollectionItem
{
@ -224,6 +241,9 @@ class QgsFavouritesItem : QgsDataCollectionItem
QVector<QgsDataItem*> createChildren();
void addDirectory( QString favIcon );
void removeDirectory( QgsDirectoryItem *item );
static const QIcon &iconFavourites();
};

View File

@ -90,13 +90,10 @@ class QgsProject : QObject
- Registers maplayers
@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( );
bool read();
//@}
@ -126,7 +123,7 @@ class QgsProject : QObject
*/
//@{
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
@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,
QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList, bool saveFlag = true );
@ -276,6 +274,11 @@ class QgsProject : QObject
@note added in version 1.9*/
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:
/** 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 );
signals:
//! emitted when project is being read
void readProject( const QDomDocument & );
@ -298,24 +300,27 @@ class QgsProject : QObject
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
* from the project file.
*
* @param mapLayer The map layer which is being initialized
* @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
* additional information to the layer.
*
* @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
*/
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.
void oldProjectVersionWarning( QString );
@ -325,6 +330,8 @@ class QgsProject : QObject
// @param n number of layers
void layerLoaded( int i, int n );
void loadingLayer( QString );
void snapSettingsChanged();
private:

View File

@ -92,8 +92,8 @@ class QgsBrowserTreeFilterProxyModel : public QSortFilterProxyModel
public:
QgsBrowserTreeFilterProxyModel( QObject *parent )
: QSortFilterProxyModel( parent ), mModel( 0 ),
mFilter( "" ), mPatternSyntax( QRegExp::Wildcard )
: QSortFilterProxyModel( parent ), mModel( 0 )
, mFilter( "" ), mPatternSyntax( QRegExp::Wildcard )
{
setDynamicSortFilter( true );
}
@ -266,10 +266,12 @@ QgsBrowserDockWidget::QgsBrowserDockWidget( QString name, QWidget * parent ) :
void QgsBrowserDockWidget::showEvent( QShowEvent * e )
{
// delayed initialization of the model
if ( mModel == NULL )
if ( !mModel )
{
mModel = new QgsBrowserModel( mBrowserView );
connect( QgisApp::instance(), SIGNAL( newProject() ), mModel, SLOT( updateProjectHome() ) );
mProxyModel = new QgsBrowserTreeFilterProxyModel( this );
mProxyModel->setBrowserModel( mModel );
mBrowserView->setModel( mProxyModel );
@ -286,10 +288,6 @@ void QgsBrowserDockWidget::showEvent( QShowEvent * e )
if ( item && item->type() == QgsDataItem::Favourites )
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 );
@ -380,34 +378,12 @@ void QgsBrowserDockWidget::addFavouriteDirectory()
void QgsBrowserDockWidget::addFavouriteDirectory( QString favDir )
{
QSettings settings;
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();
mModel->addFavouriteDirectory( favDir );
}
void QgsBrowserDockWidget::removeFavourite()
{
QModelIndex index = 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();
mModel->removeFavourite( mProxyModel->mapToSource( mBrowserView->currentIndex() ) );
}
void QgsBrowserDockWidget::refresh()

View File

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

View File

@ -28,9 +28,13 @@
#include <QSettings>
QgsBrowserModel::QgsBrowserModel( QObject *parent ) :
QAbstractItemModel( parent )
QgsBrowserModel::QgsBrowserModel( QObject *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();
}
@ -39,20 +43,35 @@ QgsBrowserModel::~QgsBrowserModel()
removeRootItems();
}
void QgsBrowserModel::addRootItems()
void QgsBrowserModel::updateProjectHome()
{
QgsDirectoryItem *item;
int idx = mRootItems.indexOf( mProjectHome );
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 );
mRootItems << item;
connectItem( mProjectHome );
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
item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
QgsDirectoryItem *item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
QStyle *style = QApplication::style();
QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) );
item->setIcon( homeIcon );
@ -60,11 +79,11 @@ void QgsBrowserModel::addRootItems()
mRootItems << item;
// add favourite directories
QgsFavouritesItem *favitem = new QgsFavouritesItem( NULL, tr( "Favourites" ) );
if ( favitem )
mFavourites = new QgsFavouritesItem( NULL, tr( "Favourites" ) );
if ( mFavourites )
{
connectItem( favitem );
mRootItems << favitem;
connectItem( mFavourites );
mRootItems << mFavourites ;
}
// add drives
@ -107,7 +126,7 @@ void QgsBrowserModel::addRootItems()
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 )
{
QgsDebugMsg( library->fileName() + " does not have dataItem" );
@ -426,3 +445,18 @@ void QgsBrowserModel::fetchMore( const QModelIndex & parent )
item->populate();
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:
// Reload the whole model
void reload();
void beginInsertItems( QgsDataItem *parent, int first, int last );
void endInsertItems();
void beginRemoveItems( QgsDataItem *parent, int first, int last );
void endRemoveItems();
protected:
void addFavouriteDirectory( QString favDir );
void removeFavourite( const QModelIndex &index );
void updateProjectHome();
protected:
// populates the model
void addRootItems();
void removeRootItems();
QVector<QgsDataItem*> mRootItems;
QgsFavouritesItem *mFavourites;
QgsDirectoryItem *mProjectHome;
};
#endif // QGSBROWSERMODEL_H

View File

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

View File

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

View File

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