16 #include <QMouseEvent>
24 QgsIdentifyMenu::CustomActionRegistry::CustomActionRegistry( QObject* parent )
33 , mAllowMultipleReturn( true )
34 , mExecWithSingleResult( false )
35 , mShowFeatureActions( false )
36 , mResultsIfExternalAction( false )
37 , mMaxLayerDisplay( 10 )
38 , mMaxFeatureDisplay( 10 )
39 , mDefaultActionName(
tr(
"Identify" ) )
40 , mCustomActionRegistry( CustomActionRegistry::instance() )
52 if ( maxLayerDisplay < 0 )
54 QgsDebugMsg(
"invalid value for number of layers displayed." );
62 if ( maxFeatureDisplay < 0 )
64 QgsDebugMsg(
"invalid value for number of layers displayed." );
70 QList<QgsMapToolIdentify::IdentifyResult>
QgsIdentifyMenu::exec(
const QList<QgsMapToolIdentify::IdentifyResult> idResults, QPoint pos )
73 mLayerIdResults.clear();
75 QList<QgsMapToolIdentify::IdentifyResult> returnResults = QList<QgsMapToolIdentify::IdentifyResult>();
77 if ( idResults.count() == 0 )
81 if ( idResults.count() == 1 && !mExecWithSingleResult )
83 returnResults << idResults[0];
91 if ( mLayerIdResults.contains( layer ) )
93 mLayerIdResults[layer].append( result );
97 mLayerIdResults.insert( layer, QList<QgsMapToolIdentify::IdentifyResult>() << result );
102 bool singleLayer = mLayerIdResults.count() == 1;
104 QMapIterator< QgsMapLayer*, QList<QgsMapToolIdentify::IdentifyResult> > it( mLayerIdResults );
105 while ( it.hasNext() )
107 if ( mMaxLayerDisplay != 0 && count > mMaxLayerDisplay )
114 addRasterLayer( layer );
121 addVectorLayer( vl, it.value(), singleLayer );
126 if ( !singleLayer && mAllowMultipleReturn && idResults.count() > 1 )
129 QAction* allAction =
new QAction(
QgsApplication::getThemeIcon(
"/mActionIdentify.svg" ),
tr(
"%1 all (%2)" ).arg( mDefaultActionName ).arg( idResults.count() ),
this );
130 allAction->setData( QVariant::fromValue<ActionData>(
ActionData( 0 ) ) );
131 connect( allAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
132 addAction( allAction );
138 returnResults = results( selectedAction, externalAction );
143 qDeleteAll( findChildren<QgsActionMenu*>() );
145 if ( externalAction && !mResultsIfExternalAction )
147 return QList<QgsMapToolIdentify::IdentifyResult>();
151 return returnResults;
161 void QgsIdentifyMenu::addRasterLayer(
QgsMapLayer* layer )
163 QAction* layerAction;
164 QMenu* layerMenu = 0;
166 QList<QgsMapLayerAction*> separators = QList<QgsMapLayerAction*>();
168 int nCustomActions = layerActions.count();
169 if ( nCustomActions )
171 separators.append( layerActions[0] );
173 if ( mShowFeatureActions )
176 if ( layerActions.count() > nCustomActions )
178 separators.append( layerActions[nCustomActions] );
183 if ( !layerActions.count() )
185 layerAction =
new QAction( layer->
name(), this );
189 layerMenu =
new QMenu( layer->
name(), this );
190 layerAction = layerMenu->menuAction();
195 layerAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
196 connect( layerAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
197 addAction( layerAction );
204 QAction* identifyFeatureAction =
new QAction( mDefaultActionName, layerMenu );
205 connect( identifyFeatureAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
206 identifyFeatureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
207 layerMenu->addAction( identifyFeatureAction );
212 QAction* action =
new QAction( mapLayerAction->icon(), mapLayerAction->text(), layerMenu );
213 action->setData( QVariant::fromValue<ActionData>( ActionData( layer,
true ) ) );
214 connect( action, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
215 connect( action, SIGNAL( triggered() ),
this, SLOT( triggerMapLayerAction() ) );
216 layerMenu->addAction( action );
217 if ( separators.contains( mapLayerAction ) )
219 layerMenu->insertSeparator( action );
224 void QgsIdentifyMenu::addVectorLayer(
QgsVectorLayer* layer,
const QList<QgsMapToolIdentify::IdentifyResult> results,
bool singleLayer )
226 QAction* layerAction = 0;
227 QMenu* layerMenu = 0;
233 QList<QgsMapLayerAction*> separators = QList<QgsMapLayerAction*>();
234 QList<QgsMapLayerAction*> layerActions = mCustomActionRegistry.mapLayerActions( layer, targets );
235 int nCustomActions = layerActions.count();
236 if ( nCustomActions )
238 separators << layerActions[0];
240 if ( mShowFeatureActions )
244 if ( layerActions.count() > nCustomActions )
246 separators << layerActions[nCustomActions];
255 bool createMenu = results.count() > 1 || layerActions.count() > 0;
262 if ( !createMenu && mShowFeatureActions )
265 createMenu = featureActionMenu->actions().count() > 0;
266 delete featureActionMenu;
274 layerAction =
new QAction( layer->
name(), this );
286 layerMenu =
new QMenu( layer->
name(), this );
287 layerAction = layerMenu->menuAction();
311 layerAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
312 connect( layerAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
313 addAction( layerAction );
324 if ( mMaxFeatureDisplay != 0 && count > mMaxFeatureDisplay )
328 QAction* featureAction = 0;
329 QMenu* featureMenu = 0;
333 if ( mShowFeatureActions )
340 if ( featureTitle.isEmpty() )
341 featureTitle = QString(
"%1" ).arg( result.
mFeature.
id() );
343 if ( !customFeatureActions.count() && ( !featureActionMenu || !featureActionMenu->actions().count() ) )
345 featureAction =
new QAction( featureTitle, layerMenu );
347 featureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.
mFeature.
id() ) ) );
348 connect( featureAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
349 layerMenu->addAction( featureAction );
351 else if ( results.count() == 1 )
356 featureMenu = layerMenu;
360 featureMenu =
new QMenu( featureTitle, layerMenu );
363 featureAction = featureMenu->menuAction();
365 featureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.
mFeature.
id() ) ) );
366 connect( featureAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
367 layerMenu->addAction( featureAction );
375 QAction* identifyFeatureAction =
new QAction(
QgsApplication::getThemeIcon(
"/mActionIdentify.svg" ), mDefaultActionName, featureMenu );
376 connect( identifyFeatureAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
377 identifyFeatureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.
mFeature.
id() ) ) );
378 featureMenu->addAction( identifyFeatureAction );
379 featureMenu->addSeparator();
384 QAction* action =
new QAction( mapLayerAction->icon(), mapLayerAction->text(), featureMenu );
385 action->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.
mFeature.
id(), mapLayerAction ) ) );
386 connect( action, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
387 connect( action, SIGNAL( triggered() ),
this, SLOT( triggerMapLayerAction() ) );
388 featureMenu->addAction( action );
391 if ( featureActionMenu )
393 Q_FOREACH ( QAction* action, featureActionMenu->actions() )
395 connect( action, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
396 featureMenu->addAction( action );
404 if ( mAllowMultipleReturn && results.count() > 1 )
406 layerMenu->addSeparator();
407 QAction* allAction =
new QAction(
QgsApplication::getThemeIcon(
"/mActionIdentify.svg" ),
tr(
"%1 all (%2)" ).arg( mDefaultActionName ).arg( results.count() ), layerMenu );
408 allAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
409 connect( allAction, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
410 layerMenu->addAction( allAction );
416 QString title = mapLayerAction->text();
418 title.append( QString(
" (%1)" ).arg( results.count() ) );
419 QAction* action =
new QAction( mapLayerAction->icon(), title, layerMenu );
420 action->setData( QVariant::fromValue<ActionData>( ActionData( layer, mapLayerAction ) ) );
421 connect( action, SIGNAL( hovered() ),
this, SLOT( handleMenuHover() ) );
422 connect( action, SIGNAL( triggered() ),
this, SLOT( triggerMapLayerAction() ) );
423 layerMenu->addAction( action );
424 if ( separators.contains( mapLayerAction ) )
426 layerMenu->insertSeparator( action );
431 void QgsIdentifyMenu::triggerMapLayerAction()
433 QAction* action = qobject_cast<QAction*>( sender() );
436 QVariant varData = action->data();
437 if ( !varData.isValid() || !varData.canConvert<ActionData>() )
440 ActionData actData = action->data().value<ActionData>();
442 if ( actData.mIsValid && actData.mMapLayerAction )
447 actData.mMapLayerAction->triggerForLayer( actData.mLayer );
453 QList<QgsFeature> featureList;
458 actData.mMapLayerAction->triggerForFeatures( actData.mLayer, featureList );
466 if ( result.
mFeature.
id() == actData.mFeatureId )
468 actData.mMapLayerAction->triggerForFeature( actData.mLayer,
new QgsFeature( result.
mFeature ) );
472 QgsDebugMsg( QString(
"Identify menu: could not retrieve feature for action %1" ).arg( action->text() ) );
478 QList<QgsMapToolIdentify::IdentifyResult> QgsIdentifyMenu::results( QAction* action,
bool &externalAction )
480 QList<QgsMapToolIdentify::IdentifyResult> idResults = QList<QgsMapToolIdentify::IdentifyResult>();
482 externalAction =
false;
485 bool hasData =
false;
490 QVariant varData = action->data();
491 if ( !varData.isValid() )
493 QgsDebugMsg(
"Identify menu: could not retrieve results from menu entry (invalid data)" );
497 if ( varData.canConvert<ActionData>() )
499 actData = action->data().value<ActionData>();
500 if ( actData.mIsValid )
502 externalAction = actData.mIsExternalAction;
512 externalAction =
true;
520 QgsDebugMsg(
"Identify menu: could not retrieve results from menu entry (no data found)" );
525 if ( actData.mAllResults )
528 QMapIterator< QgsMapLayer*, QList<QgsMapToolIdentify::IdentifyResult> > it( mLayerIdResults );
529 while ( it.hasNext() )
532 idResults << it.value();
537 if ( !mLayerIdResults.contains( actData.mLayer ) )
539 QgsDebugMsg(
"Identify menu: could not retrieve results from menu entry (layer not found)" );
545 return mLayerIdResults[actData.mLayer];
552 if ( res.
mFeature.
id() == actData.mFeatureId )
560 QgsDebugMsg(
"Identify menu: could not retrieve results from menu entry (don't know what happened')" );
564 void QgsIdentifyMenu::handleMenuHover()
571 QAction* senderAction = qobject_cast<QAction*>( sender() );
576 QList<QgsMapToolIdentify::IdentifyResult> idResults = results( senderAction, externalAction );
591 color.setAlpha( alpha );
595 mRubberBands.append( hl );
596 connect( vl, SIGNAL( destroyed() ),
this, SLOT( layerDestroyed() ) );
600 void QgsIdentifyMenu::deleteRubberBands()
602 QList<QgsHighlight*>::const_iterator it = mRubberBands.constBegin();
603 for ( ; it != mRubberBands.constEnd(); ++it )
605 mRubberBands.clear();
608 void QgsIdentifyMenu::layerDestroyed()
610 QList<QgsHighlight*>::iterator it = mRubberBands.begin();
611 while ( it != mRubberBands.end() )
613 if (( *it )->layer() == sender() )
616 it = mRubberBands.erase( it );
627 mCustomActionRegistry.clear();