From f79dbcd8973991bc621c4ab0c8aaaaef4556d65a Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Mon, 15 Dec 2014 12:30:40 +0100 Subject: [PATCH] browser restore state fix --- src/app/qgsbrowserdockwidget.cpp | 7 ++- src/app/qgsbrowserdockwidget.h | 4 +- src/core/qgsbrowsermodel.cpp | 17 ++++++- src/core/qgsbrowsermodel.h | 5 +- src/core/qgsdataitem.cpp | 79 ++++++++++++++++++++------------ src/core/qgsdataitem.h | 15 ++++-- 6 files changed, 85 insertions(+), 42 deletions(-) diff --git a/src/app/qgsbrowserdockwidget.cpp b/src/app/qgsbrowserdockwidget.cpp index d2210496efd..474b17039d5 100644 --- a/src/app/qgsbrowserdockwidget.cpp +++ b/src/app/qgsbrowserdockwidget.cpp @@ -296,7 +296,7 @@ void QgsBrowserDockWidget::showEvent( QShowEvent * e ) mModel = new QgsBrowserModel( mBrowserView ); connect( QgisApp::instance(), SIGNAL( newProject() ), mModel, SLOT( updateProjectHome() ) ); - connect( mModel, SIGNAL( fetchFinished( const QModelIndex & ) ), SLOT( fetchFinished( const QModelIndex & ) ) ); + connect( mModel, SIGNAL( stateChanged( const QModelIndex &, QgsDataItem::State ) ), SLOT( stateChanged( const QModelIndex &, QgsDataItem::State ) ) ); mProxyModel = new QgsBrowserTreeFilterProxyModel( this ); mProxyModel->setBrowserModel( mModel ); @@ -744,12 +744,15 @@ void QgsBrowserDockWidget::restoreState() } } -void QgsBrowserDockWidget::fetchFinished( const QModelIndex & index ) +void QgsBrowserDockWidget::stateChanged( const QModelIndex & index, QgsDataItem::State oldState ) { QgsDataItem *item = mModel->dataItem( index ); if ( !item ) return; + if ( oldState != QgsDataItem::Populating || item->state() != QgsDataItem::Populated ) + return; + QgsDebugMsg( "path = " + item->path() ); QSettings settings; diff --git a/src/app/qgsbrowserdockwidget.h b/src/app/qgsbrowserdockwidget.h index 52b7c20b194..2d1338bb367 100644 --- a/src/app/qgsbrowserdockwidget.h +++ b/src/app/qgsbrowserdockwidget.h @@ -18,6 +18,8 @@ #include #include +#include "qgsdataitem.h" + class QgsBrowserModel; class QModelIndex; class QgsBrowserTreeView; @@ -54,7 +56,7 @@ class APP_EXPORT QgsBrowserDockWidget : public QDockWidget, private Ui::QgsBrows void showProperties(); void toggleFastScan(); - void fetchFinished( const QModelIndex & index ); + void stateChanged( const QModelIndex & index, QgsDataItem::State oldState ); protected: void refreshModel( const QModelIndex& index ); diff --git a/src/core/qgsbrowsermodel.cpp b/src/core/qgsbrowsermodel.cpp index aefcb5e41b0..4262a71c97a 100644 --- a/src/core/qgsbrowsermodel.cpp +++ b/src/core/qgsbrowsermodel.cpp @@ -392,7 +392,7 @@ void QgsBrowserModel::endRemoveItems() QgsDebugMsgLevel( "Entered", 3 ); endRemoveRows(); } -void QgsBrowserModel::dataItemChanged( QgsDataItem * item ) +void QgsBrowserModel::itemDataChanged( QgsDataItem * item ) { QgsDebugMsgLevel( "Entered", 3 ); QModelIndex idx = findItem( item ); @@ -400,6 +400,17 @@ void QgsBrowserModel::dataItemChanged( QgsDataItem * item ) return; emit dataChanged( idx, idx ); } +void QgsBrowserModel::itemStateChanged( QgsDataItem * item, QgsDataItem::State oldState ) +{ + QgsDebugMsg( "Entered" ); + if ( !item ) + return; + QModelIndex idx = findItem( item ); + if ( !idx.isValid() ) + return; + QgsDebugMsg( QString( "item %1 state changed %2 -> %3" ).arg( item->path() ).arg( oldState ).arg( item->state() ) ); + emit stateChanged( idx, oldState ); +} void QgsBrowserModel::connectItem( QgsDataItem* item ) { connect( item, SIGNAL( beginInsertItems( QgsDataItem*, int, int ) ), @@ -411,7 +422,9 @@ void QgsBrowserModel::connectItem( QgsDataItem* item ) connect( item, SIGNAL( endRemoveItems() ), this, SLOT( endRemoveItems() ) ); connect( item, SIGNAL( dataChanged( QgsDataItem* ) ), - this, SLOT( dataItemChanged( QgsDataItem* ) ) ); + this, SLOT( itemDataChanged( QgsDataItem* ) ) ); + connect( item, SIGNAL( stateChanged( QgsDataItem*, QgsDataItem::State ) ), + this, SLOT( itemStateChanged( QgsDataItem*, QgsDataItem::State ) ) ); } QStringList QgsBrowserModel::mimeTypes() const diff --git a/src/core/qgsbrowsermodel.h b/src/core/qgsbrowsermodel.h index 0657a991d47..8d77f9c0421 100644 --- a/src/core/qgsbrowsermodel.h +++ b/src/core/qgsbrowsermodel.h @@ -116,7 +116,7 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel signals: /** Emitted when item children fetch was finished */ - void fetchFinished( const QModelIndex & index ); + void stateChanged( const QModelIndex & index, QgsDataItem::State oldState ); public slots: // Reload the whole model @@ -125,7 +125,8 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel void endInsertItems(); void beginRemoveItems( QgsDataItem *parent, int first, int last ); void endRemoveItems(); - void dataItemChanged( QgsDataItem * item ); + void itemDataChanged( QgsDataItem * item ); + void itemStateChanged( QgsDataItem * item, QgsDataItem::State oldState ); void addFavouriteDirectory( QString favDir ); void removeFavourite( const QModelIndex &index ); diff --git a/src/core/qgsdataitem.cpp b/src/core/qgsdataitem.cpp index 17eed3017b7..ff2dd63f767 100644 --- a/src/core/qgsdataitem.cpp +++ b/src/core/qgsdataitem.cpp @@ -151,9 +151,9 @@ const QIcon &QgsZipItem::iconZip() QMap QgsDataItem::mIconMap = QMap(); -int QgsDataItem::mLoadingCount = 0; -QMovie * QgsDataItem::mLoadingMovie = 0; -QIcon QgsDataItem::mLoadingIcon = QIcon(); +int QgsDataItem::mPopulatingCount = 0; +QMovie * QgsDataItem::mPopulatingMovie = 0; +QIcon QgsDataItem::mPopulatingIcon = QIcon(); QgsDataItem::QgsDataItem( QgsDataItem::Type type, QgsDataItem* parent, QString name, QString path ) // Do not pass parent to QObject, Qt would delete this when parent is deleted @@ -177,7 +177,7 @@ QgsDataItem::~QgsDataItem() QIcon QgsDataItem::icon() { if ( state() == Populating ) - return mLoadingIcon; + return mPopulatingIcon; if ( !mIcon.isNull() ) return mIcon; @@ -215,6 +215,14 @@ void QgsDataItem::emitDataChanged() emit dataChanged( this ); } +void QgsDataItem::emitStateChanged( QgsDataItem* item, QgsDataItem::State oldState ) +{ + if ( !item ) + return; + QgsDebugMsg( QString( "item %1 state changed %2 -> %3" ).arg( item->path() ).arg( oldState ).arg( item->state() ) ); + emit stateChanged( item, oldState ); +} + QVector QgsDataItem::createChildren() { return QVector(); @@ -248,10 +256,10 @@ void QgsDataItem::populate() QVector QgsDataItem::runCreateChildren( QgsDataItem* item ) { QgsDebugMsg( "path = " + item->path() ); - //QTime time; - //time.start(); + QTime time; + time.start(); QVector children = item->createChildren(); - //QgsDebugMsg( QString( "%1 children created in %2 ms" ).arg( children.size() ).arg( time.elapsed() ) ); + QgsDebugMsg( QString( "%1 children created in %2 ms" ).arg( children.size() ).arg( time.elapsed() ) ); // Children objects must be pushed to main thread. foreach ( QgsDataItem* child, children ) { @@ -425,6 +433,8 @@ void QgsDataItem::addChildItem( QgsDataItem * child, bool refresh ) this, SLOT( emitEndRemoveItems() ) ); connect( child, SIGNAL( dataChanged( QgsDataItem* ) ), this, SLOT( emitDataChanged( QgsDataItem* ) ) ); + connect( child, SIGNAL( stateChanged( QgsDataItem*, QgsDataItem::State ) ), + this, SLOT( emitStateChanged( QgsDataItem*, QgsDataItem::State ) ) ); if ( refresh ) emit endInsertItems(); @@ -458,6 +468,8 @@ QgsDataItem * QgsDataItem::removeChildItem( QgsDataItem * child ) this, SLOT( emitEndRemoveItems() ) ); disconnect( child, SIGNAL( dataChanged( QgsDataItem* ) ), this, SLOT( emitDataChanged( QgsDataItem* ) ) ); + disconnect( child, SIGNAL( stateChanged( QgsDataItem*, QgsDataItem::State ) ), + this, SLOT( emitStateChanged( QgsDataItem*, QgsDataItem::State ) ) ); child->setParent( 0 ); return child; } @@ -483,9 +495,9 @@ bool QgsDataItem::equal( const QgsDataItem *other ) return false; } -void QgsDataItem::setLoadingIcon() +void QgsDataItem::setPopulatingIcon() { - mLoadingIcon = QIcon( mLoadingMovie->currentPixmap() ); + mPopulatingIcon = QIcon( mPopulatingMovie->currentPixmap() ); } QgsDataItem::State QgsDataItem::state() const @@ -499,30 +511,33 @@ QgsDataItem::State QgsDataItem::state() const void QgsDataItem::setState( State state ) { + QgsDebugMsg( QString( "item %1 set state %2 -> %3" ).arg( path() ).arg( this->state() ).arg( state ) ); if ( state == mState ) return; + State oldState = mState; + if ( state == Populating ) // start loading { - if ( !mLoadingMovie ) + if ( !mPopulatingMovie ) { // QApplication as parent to ensure that it is deleted before QApplication - mLoadingMovie = new QMovie( QApplication::instance() ); - mLoadingMovie->setFileName( QgsApplication::iconPath( "/mIconLoading.gif" ) ); - mLoadingMovie->setCacheMode( QMovie::CacheAll ); - connect( mLoadingMovie, SIGNAL( frameChanged( int ) ), SLOT( setLoadingIcon() ) ); + mPopulatingMovie = new QMovie( QApplication::instance() ); + mPopulatingMovie->setFileName( QgsApplication::iconPath( "/mIconLoading.gif" ) ); + mPopulatingMovie->setCacheMode( QMovie::CacheAll ); + connect( mPopulatingMovie, SIGNAL( frameChanged( int ) ), SLOT( setPopulatingIcon() ) ); } - connect( mLoadingMovie, SIGNAL( frameChanged( int ) ), SLOT( emitDataChanged() ) ); - mLoadingCount++; - mLoadingMovie->setPaused( false ); + connect( mPopulatingMovie, SIGNAL( frameChanged( int ) ), SLOT( emitDataChanged() ) ); + mPopulatingCount++; + mPopulatingMovie->setPaused( false ); } - else if ( mState == Populating && mLoadingMovie ) // stop loading + else if ( mState == Populating && mPopulatingMovie ) // stop loading { - disconnect( mLoadingMovie, SIGNAL( frameChanged( int ) ), this, SLOT( emitDataChanged() ) ); - mLoadingCount--; - if ( mLoadingCount == 0 ) + disconnect( mPopulatingMovie, SIGNAL( frameChanged( int ) ), this, SLOT( emitDataChanged() ) ); + mPopulatingCount--; + if ( mPopulatingCount == 0 ) { - mLoadingMovie->setPaused( true ); + mPopulatingMovie->setPaused( true ); } } @@ -530,6 +545,8 @@ void QgsDataItem::setState( State state ) // for backward compatibility (if subclass access mPopulated directly) // TODO: remove in 3.0 mPopulated = state == Populated; + + emit stateChanged( this, oldState ); } // --------------------------------------------------------------------- @@ -657,6 +674,8 @@ QgsDirectoryItem::~QgsDirectoryItem() QIcon QgsDirectoryItem::icon() { + if ( state() == Populating ) + return populatingIcon(); return iconDir(); } @@ -969,13 +988,13 @@ QVector QgsZipItem::mDataItemPtr = QVector(); QgsZipItem::QgsZipItem( QgsDataItem* parent, QString name, QString path ) : QgsDataCollectionItem( parent, name, path ) { - mDirPath = path; + mFilePath = path; init(); } -QgsZipItem::QgsZipItem( QgsDataItem* parent, QString name, QString dirPath, QString path ) +QgsZipItem::QgsZipItem( QgsDataItem* parent, QString name, QString filePath, QString path ) : QgsDataCollectionItem( parent, name, path ) - , mDirPath( dirPath ) + , mFilePath( filePath ) { init(); } @@ -984,7 +1003,7 @@ void QgsZipItem::init() { mType = Collection; //Zip?? mIconName = "/mIconZip.png"; - mVsiPrefix = vsiPrefix( mDirPath ); + mVsiPrefix = vsiPrefix( mFilePath ); if ( mProviderNames.size() == 0 ) { @@ -1137,7 +1156,7 @@ QVector QgsZipItem::createChildren() foreach ( QString fileName, mZipFileList ) { QFileInfo info( fileName ); - tmpPath = mVsiPrefix + path() + "/" + fileName; + tmpPath = mVsiPrefix + mFilePath + "/" + fileName; QgsDebugMsgLevel( "tmpPath = " + tmpPath, 3 ); // foreach( dataItem_t *dataItem, mDataItemPtr ) @@ -1295,7 +1314,7 @@ const QStringList & QgsZipItem::getZipFileList() QSettings settings; QString scanZipSetting = settings.value( "/qgis/scanZipInBrowser2", "basic" ).toString(); - QgsDebugMsgLevel( QString( "mDirPath = %1 name= %2 scanZipSetting= %3 vsiPrefix= %4" ).arg( mDirPath ).arg( name() ).arg( scanZipSetting ).arg( mVsiPrefix ), 3 ); + QgsDebugMsgLevel( QString( "mFIlePath = %1 name= %2 scanZipSetting= %3 vsiPrefix= %4" ).arg( mFilePath ).arg( name() ).arg( scanZipSetting ).arg( mVsiPrefix ), 3 ); // if scanZipBrowser == no: skip to the next file if ( scanZipSetting == "no" ) @@ -1305,7 +1324,7 @@ const QStringList & QgsZipItem::getZipFileList() // get list of files inside zip file QgsDebugMsgLevel( QString( "Open file %1 with gdal vsi" ).arg( mVsiPrefix + path() ), 3 ); - char **papszSiblingFiles = VSIReadDirRecursive1( QString( mVsiPrefix + mDirPath ).toLocal8Bit().constData() ); + char **papszSiblingFiles = VSIReadDirRecursive1( QString( mVsiPrefix + mFilePath ).toLocal8Bit().constData() ); if ( papszSiblingFiles ) { for ( int i = 0; i < CSLCount( papszSiblingFiles ); i++ ) @@ -1320,7 +1339,7 @@ const QStringList & QgsZipItem::getZipFileList() } else { - QgsDebugMsg( QString( "Error reading %1" ).arg( mDirPath ) ); + QgsDebugMsg( QString( "Error reading %1" ).arg( mFilePath ) ); } return mZipFileList; diff --git a/src/core/qgsdataitem.h b/src/core/qgsdataitem.h index 65a8e92ed4b..5414b11b14b 100644 --- a/src/core/qgsdataitem.h +++ b/src/core/qgsdataitem.h @@ -41,6 +41,8 @@ typedef QgsDataItem * dataItem_t( QString, QgsDataItem* ); class CORE_EXPORT QgsDataItem : public QObject { Q_OBJECT + Q_ENUMS( Type ) + Q_ENUMS( State ) public: enum Type { @@ -157,6 +159,7 @@ class CORE_EXPORT QgsDataItem : public QObject protected: virtual void populate( QVector children ); virtual void refresh( QVector children ); + QIcon populatingIcon() { return mPopulatingIcon; } Type mType; Capabilities mCapabilities; @@ -183,8 +186,9 @@ class CORE_EXPORT QgsDataItem : public QObject void emitEndRemoveItems(); void emitDataChanged( QgsDataItem* item ); void emitDataChanged( ); + void emitStateChanged( QgsDataItem* item, QgsDataItem::State oldState ); void childrenCreated(); - void setLoadingIcon(); + void setPopulatingIcon(); signals: void beginInsertItems( QgsDataItem* parent, int first, int last ); @@ -192,15 +196,16 @@ class CORE_EXPORT QgsDataItem : public QObject void beginRemoveItems( QgsDataItem* parent, int first, int last ); void endRemoveItems(); void dataChanged( QgsDataItem * item ); + void stateChanged( QgsDataItem * item, QgsDataItem::State oldState ); private: static QVector runCreateChildren( QgsDataItem* item ); QFutureWatcher< QVector > *mWatcher; // number of items currently in loading (populating) state - static int mLoadingCount; - static QMovie * mLoadingMovie; - static QIcon mLoadingIcon; + static int mPopulatingCount; + static QMovie * mPopulatingMovie; + static QIcon mPopulatingIcon; }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsDataItem::Capabilities ) @@ -366,7 +371,7 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem Q_OBJECT protected: - QString mDirPath; + QString mFilePath; QString mVsiPrefix; QStringList mZipFileList;