do not use qaction in the result, build context menu in the widget

This commit is contained in:
Denis Rouzaud 2018-11-29 08:02:37 -04:00
parent c48a706e49
commit d272f3cf2a
10 changed files with 67 additions and 32 deletions

View File

@ -48,10 +48,23 @@ Constructor for QgsLocatorResult.
QString group; QString group;
QMap<int, QAction *> contextMenuActions = QMap<int, QAction *>(); struct ResultAction
{
public:
ResultAction();
%Docstring
Constructor for ResultAction
%End
ResultAction( int id, QString text );
int id;
QString text;
};
QList<ResultAction> actions;
}; };
class QgsLocatorFilter : QObject class QgsLocatorFilter : QObject
{ {
%Docstring %Docstring
@ -177,10 +190,10 @@ E.g. a file search filter would open file associated with the triggered
result. result.
%End %End
virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ); virtual void triggerResultFromAction( const QgsLocatorResult &result, const int actionId );
%Docstring %Docstring
Triggers a filter ``result`` from this filter for an entry in the context menu. 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. The entry is identified by its ``actionId`` as specified in the result of this filter.
.. seealso:: :py:func:`triggerResult` .. seealso:: :py:func:`triggerResult`

View File

@ -36,7 +36,7 @@ in order to ensure correct sorting of results by priority and match level.
ResultScoreRole, ResultScoreRole,
ResultFilterNameRole, ResultFilterNameRole,
ResultFilterGroupSortingRole, ResultFilterGroupSortingRole,
ResultContextMenuActionsRole, ResultActionsRole,
}; };
QgsLocatorModel( QObject *parent /TransferThis/ = 0 ); QgsLocatorModel( QObject *parent /TransferThis/ = 0 );

View File

@ -402,7 +402,7 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con
result.icon = preparedLayer.layerIcon; result.icon = preparedLayer.layerIcon;
result.score = static_cast< double >( string.length() ) / result.displayString.size(); result.score = static_cast< double >( string.length() ) / result.displayString.size();
result.contextMenuActions.insert( OpenForm, new QAction( tr( "Open form" ) ) ); result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form" ) );
emit resultFetched( result ); emit resultFetched( result );
foundInCurrentLayer++; foundInCurrentLayer++;
@ -417,10 +417,10 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con
void QgsAllLayersFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result ) void QgsAllLayersFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result )
{ {
triggerResultFromContextMenu( result, NoEntry ); triggerResultFromAction( result, NoEntry );
} }
void QgsAllLayersFeaturesLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ) void QgsAllLayersFeaturesLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId )
{ {
QVariantList dataList = result.userData.toList(); QVariantList dataList = result.userData.toList();
QgsFeatureId fid = dataList.at( 0 ).toLongLong(); QgsFeatureId fid = dataList.at( 0 ).toLongLong();
@ -429,7 +429,7 @@ void QgsAllLayersFeaturesLocatorFilter::triggerResultFromContextMenu( const QgsL
if ( !layer ) if ( !layer )
return; return;
if ( id == OpenForm ) if ( actionId == OpenForm )
{ {
QgsFeature f; QgsFeature f;
QgsFeatureRequest request; QgsFeatureRequest request;

View File

@ -146,7 +146,7 @@ class APP_EXPORT QgsAllLayersFeaturesLocatorFilter : public QgsLocatorFilter
void prepare( const QString &string, const QgsLocatorContext &context ) override; void prepare( const QString &string, const QgsLocatorContext &context ) override;
void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override; void fetchResults( const QString &string, const QgsLocatorContext &context, QgsFeedback *feedback ) override;
void triggerResult( const QgsLocatorResult &result ) override; void triggerResult( const QgsLocatorResult &result ) override;
void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ) override; void triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) override;
private: private:
int mMaxResultsPerLayer = 6; int mMaxResultsPerLayer = 6;

View File

@ -33,10 +33,10 @@ QgsLocatorFilter::Flags QgsLocatorFilter::flags() const
return nullptr; return nullptr;
} }
void QgsLocatorFilter::triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ) void QgsLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId )
{ {
Q_UNUSED( result ); Q_UNUSED( result );
Q_UNUSED( id ); Q_UNUSED( actionId );
} }
bool QgsLocatorFilter::stringMatches( const QString &candidate, const QString &search ) bool QgsLocatorFilter::stringMatches( const QString &candidate, const QString &search )

View File

@ -94,17 +94,39 @@ class CORE_EXPORT QgsLocatorResult
QString group = QString(); QString group = QString();
/** /**
* Actions to be used in a context menu for the result. * The ResultActions stores basic informations for additional
* The key of the map is populated with IDs used to recognized * actions to be used in a locator widget, in a context menu
* entry when the result is triggered. The IDs should be 0 or greater * for instance.
* otherwise, the result will be triggered normally. * The \a id used to recognized the action when the result is triggered.
* Entries in the context menu will be ordered by IDs. * It should be 0 or greater as otherwise, the result will be triggered
* normally.
* \since QGIS 3.6
*/
struct CORE_EXPORT ResultAction
{
public:
//! Constructor for ResultAction
ResultAction() = default;
ResultAction( int id, QString text )
: id( id )
, text( text )
{}
int id = -1;
QString text;
};
/**
* Additional actions to be used in a locator widget
* for the given result. They could be displayed in
* a context menu.
* \since QGIS 3.6 * \since QGIS 3.6
*/ */
QMap<int, QAction *> contextMenuActions = QMap<int, QAction *>(); QList<ResultAction> actions;
}; };
Q_DECLARE_METATYPE( QgsLocatorResult::ResultAction )
/** /**
* \class QgsLocatorFilter * \class QgsLocatorFilter
* \ingroup core * \ingroup core
@ -223,11 +245,11 @@ class CORE_EXPORT QgsLocatorFilter : public QObject
/** /**
* Triggers a filter \a result from this filter for an entry in the context menu. * 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. * The entry is identified by its \a actionId as specified in the result of this filter.
* \see triggerResult() * \see triggerResult()
* \since QGIS 3.6 * \since QGIS 3.6
*/ */
virtual void triggerResultFromContextMenu( const QgsLocatorResult &result, const int id ); virtual void triggerResultFromAction( const QgsLocatorResult &result, const int actionId );
/** /**
* This method will be called on main thread on the original filter (not a clone) * This method will be called on main thread on the original filter (not a clone)

View File

@ -161,8 +161,8 @@ QVariant QgsLocatorModel::data( const QModelIndex &index, int role ) const
else else
return 0; return 0;
case ResultContextMenuActionsRole: case ResultActionsRole:
return QVariant::fromValue( mResults.at( index.row() ).result.contextMenuActions ); return QVariant::fromValue( mResults.at( index.row() ).result.actions );
} }
return QVariant(); return QVariant();
@ -191,7 +191,7 @@ QHash<int, QByteArray> QgsLocatorModel::roleNames() const
roles[ResultScoreRole] = "ResultScore"; roles[ResultScoreRole] = "ResultScore";
roles[ResultFilterNameRole] = "ResultFilterName"; roles[ResultFilterNameRole] = "ResultFilterName";
roles[ResultFilterGroupSortingRole] = "ResultFilterGroupSorting"; roles[ResultFilterGroupSortingRole] = "ResultFilterGroupSorting";
roles[ResultContextMenuActionsRole] = "ResultContextMenuActions"; roles[ResultActionsRole] = "ResultContextMenuActions";
roles[Qt::DisplayRole] = "Text"; roles[Qt::DisplayRole] = "Text";
return roles; return roles;
} }

View File

@ -56,7 +56,7 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles. ResultScoreRole, //!< Result match score, used by QgsLocatorProxyModel for sorting roles.
ResultFilterNameRole, //!< Associated filter name which created the result ResultFilterNameRole, //!< Associated filter name which created the result
ResultFilterGroupSortingRole, //!< Group results within the same filter results ResultFilterGroupSortingRole, //!< Group results within the same filter results
ResultContextMenuActionsRole, //!< The actions to be shown for the given result in a context menu ResultActionsRole, //!< The actions to be shown for the given result in a context menu
}; };
/** /**

View File

@ -44,7 +44,7 @@ void QgsLocatorModelBridge::triggerResult( const QModelIndex &index, const int i
if ( result.filter ) if ( result.filter )
{ {
if ( id >= 0 ) if ( id >= 0 )
result.filter->triggerResultFromContextMenu( result, id ); result.filter->triggerResultFromAction( result, id );
else else
result.filter->triggerResult( result ); result.filter->triggerResult( result );
} }

View File

@ -181,14 +181,14 @@ void QgsLocatorWidget::showContextMenu( const QPoint &point )
if ( !index.isValid() ) if ( !index.isValid() )
return; return;
const QMap<int, QAction *> actions = mResultsView->model()->data( index, QgsLocatorModel::ResultContextMenuActionsRole ).value<QMap<int, QAction *>>(); const QList<QgsLocatorResult::ResultAction> actions = mResultsView->model()->data( index, QgsLocatorModel::ResultActionsRole ).value<QList<QgsLocatorResult::ResultAction>>();
QMap<int, QAction *>::const_iterator it = actions.constBegin();
for ( ; it != actions.constEnd(); ++it )
{
connect( it.value(), &QAction::triggered, this, [ = ]() {mModelBridge->triggerResult( index, it.key() );} );
}
QMenu *contextMenu = new QMenu( mResultsView ); QMenu *contextMenu = new QMenu( mResultsView );
contextMenu->addActions( actions.values() ); for ( auto action : actions )
{
QAction *menuAction = new QAction( action.text, contextMenu );
connect( menuAction, &QAction::triggered, this, [ = ]() {mModelBridge->triggerResult( index, action.id );} );
contextMenu->addAction( menuAction );
}
contextMenu->exec( mResultsView->viewport()->mapToGlobal( point ) ); contextMenu->exec( mResultsView->viewport()->mapToGlobal( point ) );
} }