Skip to content

Commit

Permalink
Also pass complete list of all selected items to createContextMenu,
Browse files Browse the repository at this point in the history
so that actions can operate on ALL selected items

E.g. delete multiple layers from a geopackage at once
  • Loading branch information
nyalldawson committed Nov 4, 2018
1 parent c98d13d commit 153f1b1
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 7 deletions.
11 changes: 8 additions & 3 deletions python/gui/auto_generated/qgsdataitemguiprovider.sip.in
Expand Up @@ -72,17 +72,22 @@ Providers must be registered via :py:class:`QgsDataItemGuiProviderRegistry`.
Returns the provider's name.
%End

virtual void populateContextMenu( const QList<QgsDataItem *> &items, QMenu *menu, QgsDataItemGuiContext context );
virtual void populateContextMenu( QgsDataItem *item, QMenu *menu,
const QList<QgsDataItem *> &selectedItems, QgsDataItemGuiContext context );
%Docstring
Called when the given context ``menu`` is being populated for the given selected ``items``, allowing the provider
Called when the given context ``menu`` is being populated for the given ``item``, allowing the provider
to add its own actions and submenus to the context menu. Additionally,
providers could potentially alter menus and actions added by other providers
if desired, or use standard QMenu API to insert their items and submenus into
the desired location within the context menu.

The ``selectedItems`` list contains a list of ALL currently selected items within the browser view.
Subclasses can utilise this list in order to create actions which operate on multiple items
at once, e.g. to allow deletion of multiple layers from a database at once.

When creating a context menu, this method is called for EVERY QgsDataItemGuiProvider
within the QgsDataItemGuiProviderRegistry. It is the QgsDataItemGuiProvider subclass'
responsibility to test the selected ``items`` for their properties and classes and decide what actions
responsibility to test the ``item`` and ``selectedItems`` for their properties and classes and decide what actions
(if any) are appropriate to add to the context ``menu``.

Care must be taken to correctly parent newly created sub menus and actions to the
Expand Down
19 changes: 19 additions & 0 deletions src/gui/qgsbrowserdockwidget.cpp
Expand Up @@ -36,6 +36,8 @@
#include "qgsgui.h"
#include "qgswindowmanagerinterface.h"
#include "qgsnative.h"
#include "qgsdataitemguiproviderregistry.h"
#include "qgsdataitemguiprovider.h"

// browser layer properties dialog
#include "qgsapplication.h"
Expand Down Expand Up @@ -208,6 +210,15 @@ void QgsBrowserDockWidget::showContextMenu( QPoint pt )
if ( !item )
return;

const QModelIndexList selection = mBrowserView->selectionModel()->selectedIndexes();
QList< QgsDataItem * > selectedItems;
for ( const QModelIndex &selectedIndex : selection )
{
QgsDataItem *selectedItem = mProxyModel->dataItem( selectedIndex );
if ( selectedItem )
selectedItems << selectedItem;
}

QMenu *menu = new QMenu( this );

if ( item->type() == QgsDataItem::Directory )
Expand Down Expand Up @@ -327,6 +338,14 @@ void QgsBrowserDockWidget::showContextMenu( QPoint pt )
menu->addActions( actions );
}

QgsDataItemGuiContext context;

const QList< QgsDataItemGuiProvider * > providers = QgsGui::instance()->dataItemGuiProviderRegistry()->providers();
for ( QgsDataItemGuiProvider *provider : providers )
{
provider->populateContextMenu( item, menu, selectedItems, context );
}

if ( menu->actions().isEmpty() )
{
delete menu;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsdataitemguiprovider.cpp
Expand Up @@ -34,7 +34,7 @@ void QgsDataItemGuiContext::setMessageBar( QgsMessageBar *messageBar )
// QgsDataItemGuiProvider
//

void QgsDataItemGuiProvider::populateContextMenu( const QList<QgsDataItem *> &, QMenu *, QgsDataItemGuiContext )
void QgsDataItemGuiProvider::populateContextMenu( QgsDataItem *, QMenu *, const QList<QgsDataItem *> &, QgsDataItemGuiContext )
{

}
11 changes: 8 additions & 3 deletions src/gui/qgsdataitemguiprovider.h
Expand Up @@ -87,15 +87,19 @@ class GUI_EXPORT QgsDataItemGuiProvider
virtual QString name() = 0;

/**
* Called when the given context \a menu is being populated for the given selected \a items, allowing the provider
* Called when the given context \a menu is being populated for the given \a item, allowing the provider
* to add its own actions and submenus to the context menu. Additionally,
* providers could potentially alter menus and actions added by other providers
* if desired, or use standard QMenu API to insert their items and submenus into
* the desired location within the context menu.
*
* The \a selectedItems list contains a list of ALL currently selected items within the browser view.
* Subclasses can utilise this list in order to create actions which operate on multiple items
* at once, e.g. to allow deletion of multiple layers from a database at once.
*
* When creating a context menu, this method is called for EVERY QgsDataItemGuiProvider
* within the QgsDataItemGuiProviderRegistry. It is the QgsDataItemGuiProvider subclass'
* responsibility to test the selected \a items for their properties and classes and decide what actions
* responsibility to test the \a item and \a selectedItems for their properties and classes and decide what actions
* (if any) are appropriate to add to the context \a menu.
*
* Care must be taken to correctly parent newly created sub menus and actions to the
Expand All @@ -106,7 +110,8 @@ class GUI_EXPORT QgsDataItemGuiProvider
*
* The base class method has no effect.
*/
virtual void populateContextMenu( const QList<QgsDataItem *> &items, QMenu *menu, QgsDataItemGuiContext context );
virtual void populateContextMenu( QgsDataItem *item, QMenu *menu,
const QList<QgsDataItem *> &selectedItems, QgsDataItemGuiContext context );

};

Expand Down

0 comments on commit 153f1b1

Please sign in to comment.