Skip to content

Commit

Permalink
Fix #10339 (crash when reordering layers)
Browse files Browse the repository at this point in the history
This was caused by the recent addition of currentNode handling in model.
Changed to use persistent indices which are auto-updated when model changes.
  • Loading branch information
wonder-sk committed May 25, 2014
1 parent e4b2d43 commit 2c51dcb
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 29 deletions.
23 changes: 8 additions & 15 deletions src/gui/layertree/qgslayertreemodel.cpp
Expand Up @@ -32,7 +32,6 @@ QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *pare
: QAbstractItemModel( parent )
, mRootNode( rootNode )
, mFlags( ShowSymbology )
, mCurrentNode( 0 )
{
Q_ASSERT( mRootNode );

Expand Down Expand Up @@ -242,7 +241,7 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
f.setItalic( true );
if ( QgsLayerTree::isLayer( node ) )
f.setBold( true );
if ( node == mCurrentNode )
if ( index == mCurrentIndex )
f.setUnderline( true );
return f;
}
Expand Down Expand Up @@ -402,21 +401,15 @@ void QgsLayerTreeModel::refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer )
addSymbologyToLayer( nodeLayer );
}

void QgsLayerTreeModel::setCurrentNode( QgsLayerTreeNode* currentNode )
void QgsLayerTreeModel::setCurrentIndex( const QModelIndex& currentIndex )
{
if ( mCurrentNode )
{
QModelIndex idx = node2index( mCurrentNode );
emit dataChanged( idx, idx );
}

mCurrentNode = currentNode;
QModelIndex oldIndex = mCurrentIndex;
mCurrentIndex = currentIndex;

if ( mCurrentNode )
{
QModelIndex idx = node2index( mCurrentNode );
emit dataChanged( idx, idx );
}
if ( oldIndex.isValid() )
emit dataChanged( oldIndex, oldIndex );
if ( currentIndex.isValid() )
emit dataChanged( currentIndex, currentIndex );
}

void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
Expand Down
6 changes: 3 additions & 3 deletions src/gui/layertree/qgslayertreemodel.h
Expand Up @@ -96,8 +96,8 @@ class GUI_EXPORT QgsLayerTreeModel : public QAbstractItemModel

void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer );

QgsLayerTreeNode* currentNode() const { return mCurrentNode; }
void setCurrentNode( QgsLayerTreeNode* currentNode );
QModelIndex currentIndex() const { return mCurrentIndex; }
void setCurrentIndex( const QModelIndex& currentIndex );

signals:

Expand Down Expand Up @@ -132,7 +132,7 @@ class GUI_EXPORT QgsLayerTreeModel : public QAbstractItemModel

QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelSymbologyNode*> > mSymbologyNodes;

QgsLayerTreeNode* mCurrentNode;
QPersistentModelIndex mCurrentIndex;
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayerTreeModel::Flags )
Expand Down
27 changes: 17 additions & 10 deletions src/gui/layertree/qgslayertreeview.cpp
Expand Up @@ -53,10 +53,11 @@ void QgsLayerTreeView::setModel( QAbstractItemModel* model )
return;

connect( model, SIGNAL( rowsInserted( QModelIndex, int, int ) ), this, SLOT( modelRowsInserted( QModelIndex, int, int ) ) );
connect( model, SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelRowsRemoved( QModelIndex, int, int ) ) );

QTreeView::setModel( model );

connect( selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ), this, SLOT( onCurrentChanged( QModelIndex, QModelIndex ) ) );
connect( selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ), this, SLOT( onCurrentChanged() ) );

updateExpandedStateFromNode( layerTreeModel()->rootGroup() );
}
Expand Down Expand Up @@ -123,6 +124,15 @@ void QgsLayerTreeView::modelRowsInserted( QModelIndex index, int start, int end
{
updateExpandedStateFromNode( parentNode->children()[i] );
}

// make sure we still have correct current layer
onCurrentChanged();
}

void QgsLayerTreeView::modelRowsRemoved()
{
// make sure we still have correct current layer
onCurrentChanged();
}

void QgsLayerTreeView::updateExpandedStateToNode( QModelIndex index )
Expand All @@ -134,19 +144,16 @@ void QgsLayerTreeView::updateExpandedStateToNode( QModelIndex index )
node->setExpanded( isExpanded( index ) );
}

void QgsLayerTreeView::onCurrentChanged( QModelIndex current, QModelIndex previous )
void QgsLayerTreeView::onCurrentChanged()
{
QgsMapLayer* layerPrevious = layerForIndex( previous );
QgsMapLayer* layerCurrent = layerForIndex( current );

if ( layerPrevious == layerCurrent )
QgsMapLayer* layerCurrent = layerForIndex( currentIndex() );
QModelIndex layerCurrentIndex = layerCurrent ? layerTreeModel()->node2index( layerTreeModel()->rootGroup()->findLayer( layerCurrent->id() ) ) : QModelIndex();
if ( mCurrentIndex == layerCurrentIndex )
return;

if ( layerCurrent )
layerTreeModel()->setCurrentNode( layerTreeModel()->rootGroup()->findLayer( layerCurrent->id() ) );
else
layerTreeModel()->setCurrentNode( 0 );
layerTreeModel()->setCurrentIndex( layerCurrentIndex );

mCurrentIndex = layerCurrentIndex;
emit currentLayerChanged( layerCurrent );
}

Expand Down
4 changes: 3 additions & 1 deletion src/gui/layertree/qgslayertreeview.h
Expand Up @@ -70,14 +70,16 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView
protected slots:

void modelRowsInserted( QModelIndex index, int start, int end );
void modelRowsRemoved();

void updateExpandedStateToNode( QModelIndex index );

void onCurrentChanged( QModelIndex current, QModelIndex previous );
void onCurrentChanged();

protected:
QgsLayerTreeViewDefaultActions* mDefaultActions;
QgsLayerTreeViewMenuProvider* mMenuProvider;
QPersistentModelIndex mCurrentIndex;
};

/** interface to allow custom menus */
Expand Down

0 comments on commit 2c51dcb

Please sign in to comment.