Skip to content

Commit d897aa5

Browse files
committed
browser refresh and restore fixes and improvements
1 parent 44a334b commit d897aa5

15 files changed

+406
-221
lines changed

src/app/qgsbrowserdockwidget.cpp

Lines changed: 148 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ QgsBrowserDockWidget::QgsBrowserDockWidget( QString name, QWidget * parent ) :
288288

289289
connect( mBrowserView, SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( showContextMenu( const QPoint & ) ) );
290290
connect( mBrowserView, SIGNAL( doubleClicked( const QModelIndex& ) ), this, SLOT( addLayerAtIndex( const QModelIndex& ) ) );
291-
connect( mBrowserView, SIGNAL( expanded( const QModelIndex& ) ), this, SLOT( itemExpanded( const QModelIndex& ) ) );
292291
}
293292

294293
void QgsBrowserDockWidget::showEvent( QShowEvent * e )
@@ -309,28 +308,20 @@ void QgsBrowserDockWidget::showEvent( QShowEvent * e )
309308
mBrowserView->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
310309
mBrowserView->header()->setStretchLastSection( false );
311310

312-
QSettings settings;
313-
mInitPath = settings.value( lastExpandedKey() ).toString();
314-
315-
// expand root favourites item
316-
for ( int i = 0; i < mModel->rowCount(); i++ )
317-
{
318-
QModelIndex index = mModel->index( i, 0 );
319-
QgsDataItem* item = mModel->dataItem( index );
320-
if ( item && item->type() == QgsDataItem::Favourites )
321-
{
322-
QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
323-
mBrowserView->expand( proxyIndex );
324-
}
325-
}
326-
327-
// expand last expanded path from previous session
328-
expandPath( mInitPath );
311+
restoreState();
329312
}
330313

331314
QDockWidget::showEvent( e );
332315
}
333316

317+
// closeEvent is not called when application is closed
318+
void QgsBrowserDockWidget::hideEvent( QHideEvent * e )
319+
{
320+
QgsDebugMsg( "Entered" );
321+
saveState();
322+
QDockWidget::hideEvent( e );
323+
}
324+
334325
void QgsBrowserDockWidget::showContextMenu( const QPoint & pt )
335326
{
336327
QModelIndex index = mProxyModel->mapToSource( mBrowserView->indexAt( pt ) );
@@ -426,38 +417,61 @@ void QgsBrowserDockWidget::removeFavourite()
426417

427418
void QgsBrowserDockWidget::refresh()
428419
{
429-
//QApplication::setOverrideCursor( Qt::WaitCursor );
430420
refreshModel( QModelIndex() );
431-
//QApplication::restoreOverrideCursor();
432421
}
433422

434423
void QgsBrowserDockWidget::refreshModel( const QModelIndex& index )
435424
{
436425
QgsDebugMsg( "Entered" );
437-
if ( index.isValid() )
426+
QgsDataItem *item = mModel->dataItem( index );
427+
if ( item )
438428
{
439-
QgsDataItem *item = mModel->dataItem( index );
440-
if ( item )
441-
{
442-
QgsDebugMsg( "path = " + item->path() );
443-
}
444-
else
445-
{
446-
QgsDebugMsg( "invalid item" );
447-
}
429+
QgsDebugMsg( "path = " + item->path() );
430+
}
431+
else
432+
{
433+
QgsDebugMsg( "invalid item" );
448434
}
449435

450-
mModel->refresh( index );
436+
if ( item && ( item->capabilities2() & QgsDataItem::Fertile ) )
437+
{
438+
mModel->refresh( index );
439+
}
451440

452441
for ( int i = 0 ; i < mModel->rowCount( index ); i++ )
453442
{
454443
QModelIndex idx = mModel->index( i, 0, index );
455444
QModelIndex proxyIdx = mProxyModel->mapFromSource( idx );
456-
if ( mBrowserView->isExpanded( proxyIdx ) || !mProxyModel->hasChildren( proxyIdx ) )
445+
QgsDataItem *child = mModel->dataItem( idx );
446+
447+
// Check also expanded descendants so that the whole expanded path does not get collapsed if one item is collapsed.
448+
// Fast items (usually root items) are refreshed so that when collapsed, it is obvious they are if empty (no expand symbol).
449+
if ( mBrowserView->isExpanded( proxyIdx ) || hasExpandedDescendant( proxyIdx ) || ( child && child->capabilities2() & QgsDataItem::Fast ) )
457450
{
458451
refreshModel( idx );
459452
}
453+
else
454+
{
455+
if ( child && ( child->capabilities2() & QgsDataItem::Fertile ) )
456+
{
457+
child->depopulate();
458+
}
459+
}
460+
}
461+
}
462+
463+
bool QgsBrowserDockWidget::hasExpandedDescendant( const QModelIndex& proxyIndex ) const
464+
{
465+
for ( int i = 0 ; i < mProxyModel->rowCount( proxyIndex ); i++ )
466+
{
467+
QModelIndex proxyIdx = mProxyModel->index( i, 0, proxyIndex );
468+
if ( mBrowserView->isExpanded( proxyIdx ) )
469+
return true;
470+
471+
if ( hasExpandedDescendant( proxyIdx ) )
472+
return true;
460473
}
474+
return false;
461475
}
462476

463477
void QgsBrowserDockWidget::addLayer( QgsLayerItem *layerItem )
@@ -690,83 +704,134 @@ void QgsBrowserDockWidget::setCaseSensitive( bool caseSensitive )
690704
mProxyModel->setCaseSensitive( caseSensitive );
691705
}
692706

693-
void QgsBrowserDockWidget::itemExpanded( const QModelIndex& index )
707+
void QgsBrowserDockWidget::saveState()
694708
{
695-
if ( !mModel || !mProxyModel )
696-
return;
709+
QgsDebugMsg( "Entered" );
697710
QSettings settings;
698-
QModelIndex srcIndex = mProxyModel->mapToSource( index );
699-
QgsDataItem *item = mModel->dataItem( srcIndex );
700-
if ( !item )
701-
return;
702-
703-
settings.setValue( lastExpandedKey(), item->path() );
704-
QgsDebugMsg( "last expanded: " + item->path() );
711+
QStringList expandedPaths = expandedPathsList( QModelIndex() );
712+
settings.setValue( expandedPathsKey(), expandedPaths );
713+
QgsDebugMsg( "expandedPaths = " + expandedPaths.join( " " ) );
705714
}
706715

707-
void QgsBrowserDockWidget::expandPath( QString path )
716+
void QgsBrowserDockWidget::restoreState()
708717
{
709-
QgsDebugMsg( "path = " + path );
710-
711-
if ( path.isEmpty() )
712-
return;
713-
714-
if ( !mModel || !mProxyModel )
715-
return;
716-
717-
QModelIndex srcIndex = mModel->findPath( path, Qt::MatchStartsWith );
718-
QModelIndex index = mProxyModel->mapFromSource( srcIndex );
719-
QgsDebugMsg( QString( "srcIndex.isValid() = %1 index.isValid() = %2" ).arg( srcIndex.isValid() ).arg( index.isValid() ) );
720-
721-
if ( !index.isValid() )
722-
return;
723-
724-
QgsDataItem *item = mModel->dataItem( srcIndex );
725-
if ( !item )
726-
return;
718+
QgsDebugMsg( "Entered" );
719+
QSettings settings;
720+
QStringList expandedPaths = settings.value( expandedPathsKey(), QVariant() ).toStringList();
727721

728-
if ( item->isPopulated() ) // may be already populated if children were added with grandchildren
722+
if ( !expandedPaths.isEmpty() )
729723
{
730-
mBrowserView->expand( index );
724+
QSet<QModelIndex> expandIndexSet;
725+
foreach ( QString path, expandedPaths )
726+
{
727+
QModelIndex expandIndex = mModel->findPath( path, Qt::MatchStartsWith );
728+
if ( expandIndex.isValid() )
729+
expandIndexSet.insert( expandIndex );
730+
}
731+
foreach ( QModelIndex expandIndex, expandIndexSet )
732+
{
733+
QModelIndex proxyExpandIndex = mProxyModel->mapFromSource( expandIndex );
734+
expand( proxyExpandIndex );
735+
}
731736
}
732737
else
733738
{
734-
mModel->fetchMore( srcIndex ); // -> fetch in thread -> fetchFinished
739+
// expand root favourites item
740+
QModelIndex index = mModel->findPath( "favourites:" );
741+
QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
742+
mBrowserView->expand( proxyIndex );
735743
}
736-
mBrowserView->scrollTo( index, QAbstractItemView::PositionAtTop );
737744
}
738745

739746
void QgsBrowserDockWidget::fetchFinished( const QModelIndex & index )
740747
{
741-
Q_UNUSED( index );
742-
QgsDebugMsg( "Entered" );
743-
QSettings settings;
744-
745-
// Continue expanding mInitPath if user has not expanded another item
746-
if ( mInitPath.isEmpty() )
748+
QgsDataItem *item = mModel->dataItem( index );
749+
if ( !item )
747750
return;
748751

749-
QString lastExpanded = settings.value( lastExpandedKey() ).toString();
752+
QgsDebugMsg( "path = " + item->path() );
753+
754+
QSettings settings;
755+
QStringList expandedPaths = settings.value( expandedPathsKey(), QVariant() ).toStringList();
750756

751-
if ( !mInitPath.startsWith( lastExpanded ) )
757+
// Check if user did not collapse it in the meantime
758+
QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
759+
if ( !treeExpanded( proxyIndex ) )
752760
{
753-
// User expanded another -> stop mInitPath expansion
754-
QgsDebugMsg( "Stop init path expansion" );
755-
mInitPath.clear();
761+
foreach ( QString path, expandedPaths )
762+
{
763+
if ( path.startsWith( item->path() + "/" ) )
764+
expandedPaths.removeOne( path );
765+
}
766+
settings.setValue( expandedPathsKey(), expandedPaths );
756767
return;
757768
}
758769

759-
// Expand fetched children in init path
760-
QModelIndex proxyIndex = mProxyModel->mapFromSource( index );
761-
if ( index.isValid() )
770+
QSet<QModelIndex> expandIndexSet;
771+
foreach ( QString path, expandedPaths )
762772
{
763-
mBrowserView->expand( proxyIndex );
773+
if ( path.startsWith( item->path() + "/" ) )
774+
{
775+
QModelIndex expandIndex = mModel->findPath( path, Qt::MatchStartsWith );
776+
if ( expandIndex.isValid() )
777+
expandIndexSet.insert( expandIndex );
778+
}
779+
}
780+
foreach ( QModelIndex expandIndex, expandIndexSet )
781+
{
782+
QModelIndex proxyExpandIndex = mProxyModel->mapFromSource( expandIndex );
783+
expand( proxyExpandIndex );
764784
}
785+
}
786+
787+
void QgsBrowserDockWidget::expand( const QModelIndex & proxyIndex )
788+
{
789+
mBrowserView->expand( proxyIndex );
790+
QModelIndex parentIndex = mProxyModel->parent( proxyIndex );
791+
if ( parentIndex.isValid() )
792+
expand( parentIndex );
793+
}
794+
795+
bool QgsBrowserDockWidget::treeExpanded( const QModelIndex & proxyIndex )
796+
{
797+
if ( !mBrowserView->isExpanded( proxyIndex ) )
798+
return false;
799+
QModelIndex parentIndex = mProxyModel->parent( proxyIndex );
800+
if ( parentIndex.isValid() )
801+
return treeExpanded( parentIndex );
765802

766-
expandPath( mInitPath );
803+
return true; // root
804+
}
805+
806+
QString QgsBrowserDockWidget::expandedPathsKey() const
807+
{
808+
return "/" + objectName().toLower() + "/expandedPaths";
767809
}
768810

769-
QString QgsBrowserDockWidget::lastExpandedKey() const
811+
QStringList QgsBrowserDockWidget::expandedPathsList( const QModelIndex & proxyIndex )
770812
{
771-
return "/" + objectName().toLower() + "/lastExpanded";
813+
QStringList paths;
814+
815+
for ( int i = 0; i < mProxyModel->rowCount( proxyIndex ); i++ )
816+
{
817+
QModelIndex childProxyIndex = mProxyModel->index( i, 0, proxyIndex );
818+
if ( mBrowserView->isExpanded( childProxyIndex ) )
819+
{
820+
QStringList childrenPaths = expandedPathsList( childProxyIndex );
821+
if ( !childrenPaths.isEmpty() )
822+
{
823+
paths.append( childrenPaths );
824+
}
825+
else
826+
{
827+
QModelIndex childIndex = mProxyModel->mapToSource( childProxyIndex );
828+
QgsDataItem* item = mModel->dataItem( childIndex );
829+
if ( item )
830+
{
831+
paths.append( item->path() );
832+
}
833+
}
834+
}
835+
}
836+
return paths;
772837
}

src/app/qgsbrowserdockwidget.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ class APP_EXPORT QgsBrowserDockWidget : public QDockWidget, private Ui::QgsBrows
3030
Q_OBJECT
3131
public:
3232
explicit QgsBrowserDockWidget( QString name, QWidget *parent = 0 );
33+
//~QgsBrowserDockWidget();
3334
void addFavouriteDirectory( QString favDir );
3435

35-
/* Expand next not expanded item in path */
36-
void expandPath( QString path );
37-
3836
public slots:
3937
void addLayerAtIndex( const QModelIndex& index );
4038
void showContextMenu( const QPoint & );
@@ -56,22 +54,36 @@ class APP_EXPORT QgsBrowserDockWidget : public QDockWidget, private Ui::QgsBrows
5654
void showProperties();
5755
void toggleFastScan();
5856

59-
void itemExpanded( const QModelIndex& index );
6057
void fetchFinished( const QModelIndex & index );
6158

6259
protected:
6360
void refreshModel( const QModelIndex& index );
6461

6562
void showEvent( QShowEvent * event );
6663

67-
void addLayer( QgsLayerItem *layerItem );
64+
void hideEvent( QHideEvent * event );
6865

69-
QString lastExpandedKey() const;
66+
void addLayer( QgsLayerItem *layerItem );
7067

7168
QgsBrowserTreeView* mBrowserView;
7269
QgsBrowserModel* mModel;
7370
QgsBrowserTreeFilterProxyModel* mProxyModel;
7471
QString mInitPath;
72+
73+
private:
74+
QString expandedPathsKey() const;
75+
// Get list of expanded items paths recursively
76+
QStringList expandedPathsList( const QModelIndex & proxyIndex );
77+
78+
// Expand path recursively to root
79+
void expand( const QModelIndex & proxyIndex );
80+
// returns true if expanded from root to item
81+
bool treeExpanded( const QModelIndex & proxyIndex );
82+
83+
void saveState();
84+
void restoreState();
85+
// returns true if at least one descendat is expanded, used in refresh
86+
bool hasExpandedDescendant( const QModelIndex& proxyIndex ) const;
7587
};
7688

7789
#endif // QGSBROWSERDOCKWIDGET_H

0 commit comments

Comments
 (0)