Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
use int as IDs to recognize context menu entries
  • Loading branch information
3nids committed Nov 28, 2018
1 parent 91736fd commit c48a706
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 37 deletions.
9 changes: 4 additions & 5 deletions python/core/auto_generated/locator/qgslocatorfilter.sip.in
Expand Up @@ -48,7 +48,7 @@ Constructor for QgsLocatorResult.

QString group;

QList<QAction *> contextMenuActions;
QMap<int, QAction *> contextMenuActions = QMap<int, QAction *>();

};

Expand Down Expand Up @@ -177,11 +177,10 @@ E.g. a file search filter would open file associated with the triggered
result.
%End

virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const QAction *action );
virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id );
%Docstring
Triggers a filter ``result`` from this filter for a given action.
Actions are specified in the result given by this filter and shown
as context menu entries.
Triggers a filter ``result`` from this filter for an entry in the context menu.
The entry is identified by its \id as specified in the result of this filter.

.. seealso:: :py:func:`triggerResult`

Expand Down
Expand Up @@ -57,7 +57,7 @@ Returns true if some text to be search is pending in the queue
Returns true if the a search is currently running
%End

void triggerResult( const QModelIndex &index, const QAction *action = 0 );
void triggerResult( const QModelIndex &index, const int id = -1 );
%Docstring
Triggers the result at given ``index`` and with optional ``action`` if context menu entry was triggered
%End
Expand Down
21 changes: 10 additions & 11 deletions src/app/locator/qgsinbuiltlocatorfilters.cpp
Expand Up @@ -402,7 +402,7 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con
result.icon = preparedLayer.layerIcon;
result.score = static_cast< double >( string.length() ) / result.displayString.size();

result.contextMenuActions << new QAction( tr( "Open form" ) );
result.contextMenuActions.insert( OpenForm, new QAction( tr( "Open form" ) ) );
emit resultFetched( result );

foundInCurrentLayer++;
Expand All @@ -417,28 +417,23 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con

void QgsAllLayersFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result )
{
triggerResultFromContextMenu( result, nullptr );
triggerResultFromContextMenu( result, NoEntry );
}

void QgsAllLayersFeaturesLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const QAction *action )
void QgsAllLayersFeaturesLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const int id )
{
QVariantList dataList = result.userData.toList();
QgsFeatureId id = dataList.at( 0 ).toLongLong();
QgsFeatureId fid = dataList.at( 0 ).toLongLong();
QString layerId = dataList.at( 1 ).toString();
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgsProject::instance()->mapLayer( layerId ) );
if ( !layer )
return;

if ( !action )
{
QgisApp::instance()->mapCanvas()->zoomToFeatureIds( layer, QgsFeatureIds() << id );
}
else
if ( id == OpenForm )
{
// no need to check for which action, since the filter shows only one
QgsFeature f;
QgsFeatureRequest request;
request.setFilterFid( id );
request.setFilterFid( fid );
bool fetched = layer->getFeatures( request ).nextFeature( f );
if ( !fetched )
return;
Expand All @@ -452,6 +447,10 @@ void QgsAllLayersFeaturesLocatorFilter::triggerResultFromContextMenu( const QgsL
action.viewFeatureForm();
}
}
else
{
QgisApp::instance()->mapCanvas()->zoomToFeatureIds( layer, QgsFeatureIds() << fid );
}
}

//
Expand Down
10 changes: 8 additions & 2 deletions src/app/locator/qgsinbuiltlocatorfilters.h
Expand Up @@ -119,6 +119,12 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
Q_OBJECT

public:
enum ContextMenuEntry
{
NoEntry,
OpenForm
};

struct PreparedLayer
{
public:
Expand All @@ -128,7 +134,7 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
QString layerName;
QString layerId;
QIcon layerIcon;
} ;
};

QgsAllLayersFeaturesLocatorFilter( QObject *parent = nullptr );
QgsAllLayersFeaturesLocatorFilter *clone() const override;
Expand All @@ -140,7 +146,7 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
void prepare( const QString &string, const QgsLocatorContext &context ) override;
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
void triggerResult( const QgsLocatorResult &result ) override;
void triggerResultFromContextMenu( const QgsLocatorResult &result, const QAction *action ) override;
void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ) override;

private:
int mMaxResultsPerLayer = 6;
Expand Down
4 changes: 2 additions & 2 deletions src/core/locator/qgslocatorfilter.cpp
Expand Up @@ -33,10 +33,10 @@ QgsLocatorFilter::Flags QgsLocatorFilter::flags() const
return nullptr;
}

void QgsLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const QAction *action )
void QgsLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const int id )
{
Q_UNUSED( result );
Q_UNUSED( action );
Q_UNUSED( id );
}

bool QgsLocatorFilter::stringMatches( const QString &candidate, const QString &search )
Expand Down
18 changes: 11 additions & 7 deletions src/core/locator/qgslocatorfilter.h
Expand Up @@ -89,14 +89,19 @@ class CORE_EXPORT QgsLocatorResult
* If left as empty string, this means that results are all shown without being grouped.
* If a group is given, the results will be grouped by \a group under a header.
* \note This should be translated.
* \since 3.2
* \since QGIS 3.2
*/
QString group = QString();

/**
* Actions to be used in a context menu for the result
* Actions to be used in a context menu for the result.
* The key of the map is populated with IDs used to recognized
* entry when the result is triggered. The IDs should be 0 or greater
* otherwise, the result will be triggered normally.
* Entries in the context menu will be ordered by IDs.
* \since QGIS 3.6
*/
QList<QAction *> contextMenuActions = QList<QAction *>();
QMap<int, QAction *> contextMenuActions = QMap<int, QAction *>();

};

Expand Down Expand Up @@ -217,13 +222,12 @@ class CORE_EXPORT QgsLocatorFilter : public QObject
virtual void triggerResult( const QgsLocatorResult &result ) = 0;

/**
* Triggers a filter \a result from this filter for a given action.
* Actions are specified in the result given by this filter and shown
* as context menu entries.
* Triggers a filter \a result from this filter for an entry in the context menu.
* The entry is identified by its \id as specified in the result of this filter.
* \see triggerResult()
* \since QGIS 3.6
*/
virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const QAction *action );
virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id );

/**
* This method will be called on main thread on the original filter (not a clone)
Expand Down
6 changes: 3 additions & 3 deletions src/core/locator/qgslocatormodelbridge.cpp
Expand Up @@ -37,14 +37,14 @@ bool QgsLocatorModelBridge::isRunning() const
return mIsRunning;
}

void QgsLocatorModelBridge::triggerResult( const QModelIndex &index, const QAction *action )
void QgsLocatorModelBridge::triggerResult( const QModelIndex &index, const int id )
{
mLocator->clearPreviousResults();
QgsLocatorResult result = mProxyModel->data( index, QgsLocatorModel::ResultDataRole ).value< QgsLocatorResult >();
if ( result.filter )
{
if ( action )
result.filter->triggerResultFromContextMenu( result, action );
if ( id >= 0 )
result.filter->triggerResultFromContextMenu( result, id );
else
result.filter->triggerResult( result );
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/locator/qgslocatormodelbridge.h
Expand Up @@ -64,7 +64,7 @@ class CORE_EXPORT QgsLocatorModelBridge : public QObject
bool isRunning() const;

//! Triggers the result at given \a index and with optional \a action if context menu entry was triggered
void triggerResult( const QModelIndex &index, const QAction *action = nullptr );
void triggerResult( const QModelIndex &index, const int id = -1 );

signals:
//! Emitted when a result is added
Expand Down
10 changes: 5 additions & 5 deletions src/gui/locator/qgslocatorwidget.cpp
Expand Up @@ -181,14 +181,14 @@ void QgsLocatorWidget::showContextMenu( const QPoint &point )
if ( !index.isValid() )
return;

const QList<QAction *> actions = mResultsView->model()->data( index, QgsLocatorModel::ResultContextMenuActionsRole ).value<QList<QAction *>>();
for ( const QAction *action : actions )
const QMap<int, QAction *> actions = mResultsView->model()->data( index, QgsLocatorModel::ResultContextMenuActionsRole ).value<QMap<int, QAction *>>();
QMap<int, QAction *>::const_iterator it = actions.constBegin();
for ( ; it != actions.constEnd(); ++it )
{
connect( action, &QAction::triggered, this, [ = ]() {mModelBridge->triggerResult( index, action );} );
connect( it.value(), &QAction::triggered, this, [ = ]() {mModelBridge->triggerResult( index, it.key() );} );
}

QMenu *contextMenu = new QMenu( mResultsView );
contextMenu->addActions( actions );
contextMenu->addActions( actions.values() );
contextMenu->exec( mResultsView->viewport()->mapToGlobal( point ) );
}

Expand Down

0 comments on commit c48a706

Please sign in to comment.