Skip to content

Commit 96809eb

Browse files
committed
fix crash when triggering already destroyed map layer actions in identify
(alternative fix for PR#1319)
1 parent 83d30b8 commit 96809eb

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

src/app/qgsidentifyresultsdialog.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "qgslogger.h"
3232
#include "qgsnetworkaccessmanager.h"
3333
#include "qgsproject.h"
34+
#include "qgsmaplayeractionregistry.h"
3435

3536
#include <QCloseEvent>
3637
#include <QLabel>
@@ -242,6 +243,7 @@ void QgsIdentifyResultsWebViewItem::loadFinished( bool ok )
242243
// actions (if any) [userrole: "actions"]
243244
// edit [userrole: "edit"]
244245
// action [userrole: "action", idx]
246+
// action [userrole: "map_layer_action", QgsMapLayerAction]
245247
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
246248
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
247249
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
@@ -421,9 +423,9 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
421423
}
422424

423425
//get valid QgsMapLayerActions for this layer
424-
mMapLayerActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( vlayer );
426+
QList< QgsMapLayerAction* > registeredActions = QgsMapLayerActionRegistry::instance()->mapLayerActions( vlayer );
425427

426-
if ( vlayer->pendingFields().size() > 0 || vlayer->actions()->size() || mMapLayerActions.size() )
428+
if ( vlayer->pendingFields().size() > 0 || vlayer->actions()->size() || registeredActions.size() )
427429
{
428430
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
429431
actionItem->setData( 0, Qt::UserRole, "actions" );
@@ -452,20 +454,35 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
452454
}
453455

454456
//add actions from QgsMapLayerActionRegistry
455-
for ( int i = 0; i < mMapLayerActions.size(); i++ )
457+
for ( int i = 0; i < registeredActions.size(); i++ )
456458
{
457-
QgsMapLayerAction* action = mMapLayerActions.at( i );
459+
QgsMapLayerAction* action = registeredActions.at( i );
458460
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action->text() );
459461
twi->setIcon( 0, QgsApplication::getThemeIcon( "/mAction.svg" ) );
460462
twi->setData( 0, Qt::UserRole, "map_layer_action" );
461-
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
463+
twi->setData( 0, Qt::UserRole + 1, qVariantFromValue( qobject_cast<QObject *>( action ) ) );
462464
actionItem->addChild( twi );
465+
466+
connect( action, SIGNAL( destroyed() ), this, SLOT( mapLayerActionDestroyed() ) );
463467
}
464468
}
465469

466470
highlightFeature( featItem );
467471
}
468472

473+
void QgsIdentifyResultsDialog::mapLayerActionDestroyed()
474+
{
475+
QTreeWidgetItemIterator it( lstResults );
476+
while( *it )
477+
{
478+
if( (*it)->data( 0, Qt::UserRole ) == "map_layer_action" &&
479+
(*it)->data( 0, Qt::UserRole + 1 ).value< QObject *>() == sender() )
480+
delete *it;
481+
else
482+
++it;
483+
}
484+
}
485+
469486
void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,
470487
QString label,
471488
const QMap<QString, QString> &attributes,
@@ -692,11 +709,8 @@ void QgsIdentifyResultsDialog::itemClicked( QTreeWidgetItem *item, int column )
692709
}
693710
else if ( item->data( 0, Qt::UserRole ).toString() == "map_layer_action" )
694711
{
695-
QgsMapLayerAction* action = mMapLayerActions.at( item->data( 0, Qt::UserRole + 1 ).toInt() );
696-
if ( action )
697-
{
698-
doMapLayerAction( item, action );
699-
}
712+
QObject *action = item->data( 0, Qt::UserRole + 1 ).value<QObject *>();
713+
doMapLayerAction( item, qobject_cast<QgsMapLayerAction *>( action ) );
700714
}
701715
}
702716

@@ -939,6 +953,9 @@ void QgsIdentifyResultsDialog::doMapLayerAction( QTreeWidgetItem *item, QgsMapLa
939953
if ( !layer )
940954
return;
941955

956+
if ( !action )
957+
return;
958+
942959
int featIdx = featItem->data( 0, Qt::UserRole + 1 ).toInt();
943960
action->triggerForFeature( layer, &mFeatures[ featIdx ] );
944961
}

src/app/qgsidentifyresultsdialog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
191191

192192
void printCurrentItem();
193193

194+
void mapLayerActionDestroyed();
195+
194196
private:
195197
enum ItemDataRole
196198
{
@@ -202,8 +204,6 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
202204
QgsMapCanvas *mCanvas;
203205
QList<QgsFeature> mFeatures;
204206

205-
QList< QgsMapLayerAction* > mMapLayerActions;
206-
207207
QgsMapLayer *layer( QTreeWidgetItem *item );
208208
QgsVectorLayer *vectorLayer( QTreeWidgetItem *item );
209209
QgsRasterLayer *rasterLayer( QTreeWidgetItem *item );

src/gui/qgsmaptoolidentify.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,9 @@ void QgsMapToolIdentify::handleMenuHover()
663663

664664
void QgsMapToolIdentify::deleteRubberBands()
665665
{
666-
qDeleteAll( mRubberBands );
666+
QList<QgsHighlight*>::const_iterator it = mRubberBands.constBegin();
667+
for ( ; it != mRubberBands.constEnd(); ++it )
668+
delete *it;
667669
}
668670

669671
void QgsMapToolIdentify::layerDestroyed()

0 commit comments

Comments
 (0)