Skip to content

Commit

Permalink
Multi item selection work
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 12, 2020
1 parent bb82c12 commit b22e669
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 107 deletions.
Expand Up @@ -81,6 +81,29 @@ Returns the current combination of flags set for the scene.
void createItems( QgsProcessingModelAlgorithm *model, QgsProcessingContext &context );
%Docstring
Populates the scene by creating items representing the specified ``model``.
%End

QList<QgsModelComponentGraphicItem *> selectedComponentItems();
%Docstring
Returns list of selected component items.
%End

QgsModelComponentGraphicItem *componentItemAt( QPointF position ) const;
%Docstring
Returns the topmost component item at a specified ``position``.
%End

void deselectAll();
%Docstring
Clears any selected items in the scene.

Call this method rather than QGraphicsScene.clearSelection, as the latter does
not correctly emit signals to allow the scene's model to update.
%End

void setSelectedItem( QgsModelComponentGraphicItem *item );
%Docstring
Clears any selected items and sets ``item`` as the current selection.
%End

signals:
Expand All @@ -101,6 +124,12 @@ optional ``id`` can be used to group the associated undo commands.
void componentChanged();
%Docstring
Emitted whenever a component of the model is changed.
%End

void selectedItemChanged( QgsModelComponentGraphicItem *selected );
%Docstring
Emitted whenever the selected item changes.
If ``None``, no item is selected.
%End

protected:
Expand Down
Expand Up @@ -54,30 +54,15 @@ Constructor for QgsModelGraphicsView, with the specified ``parent`` widget.
virtual void keyReleaseEvent( QKeyEvent *event );


QgsModelViewTool *tool();
QgsModelGraphicsScene *modelScene() const;
%Docstring
Returns the currently active tool for the view.
Returns the scene associated with the tool.

.. seealso:: :py:func:`setTool`
.. seealso:: :py:func:`view`
%End

void setTool( QgsModelViewTool *tool );
%Docstring
Sets the ``tool`` currently being used in the view.

.. seealso:: :py:func:`unsetTool`

.. seealso:: :py:func:`tool`
%End

void unsetTool( QgsModelViewTool *tool );
%Docstring
Unsets the current view tool, if it matches the specified ``tool``.

This is called from destructor of view tools to make sure
that the tool won't be used any more.
You don't have to call it manually, QgsModelViewTool takes care of it.
%End

signals:

Expand All @@ -91,12 +76,6 @@ Emitted when an algorithm is dropped onto the view.
Emitted when an input parameter is dropped onto the view.
%End

void toolSet( QgsModelViewTool *tool );
%Docstring
Emitted when the current ``tool`` is changed.

.. seealso:: :py:func:`setTool`
%End

void itemFocused( QgsModelComponentGraphicItem *item );
%Docstring
Expand Down
57 changes: 57 additions & 0 deletions src/gui/processing/models/qgsmodelgraphicsscene.cpp
Expand Up @@ -186,6 +186,63 @@ void QgsModelGraphicsScene::createItems( QgsProcessingModelAlgorithm *model, Qgs
}
}

QList<QgsModelComponentGraphicItem *> QgsModelGraphicsScene::selectedComponentItems()
{
QList<QgsModelComponentGraphicItem *> componentItemList;

const QList<QGraphicsItem *> graphicsItemList = selectedItems();
for ( QGraphicsItem *item : graphicsItemList )
{
if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
{
componentItemList.push_back( componentItem );
}
}

return componentItemList;
}

QgsModelComponentGraphicItem *QgsModelGraphicsScene::componentItemAt( QPointF position ) const
{
//get a list of items which intersect the specified position, in descending z order
const QList<QGraphicsItem *> itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );

for ( QGraphicsItem *graphicsItem : itemList )
{
if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( graphicsItem ) )
{
return componentItem;
}
}
return nullptr;
}

void QgsModelGraphicsScene::deselectAll()
{
//we can't use QGraphicsScene::clearSelection, as that emits no signals
//and we don't know which items are being deselected
//instead, do the clear selection manually...
const QList<QGraphicsItem *> selectedItemList = selectedItems();
for ( QGraphicsItem *item : selectedItemList )
{
if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
{
componentItem->setSelected( false );
}
}
emit selectedItemChanged( nullptr );
}

void QgsModelGraphicsScene::setSelectedItem( QgsModelComponentGraphicItem *item )
{
whileBlocking( this )->deselectAll();
if ( item )
{
item->setSelected( true );
}
emit selectedItemChanged( item );
}

QList<QgsModelGraphicsScene::LinkSource> QgsModelGraphicsScene::linkSourcesForParameterValue( QgsProcessingModelAlgorithm *model, const QVariant &value, const QString &childId, QgsProcessingContext &context ) const
{
QList<QgsModelGraphicsScene::LinkSource> res;
Expand Down
29 changes: 29 additions & 0 deletions src/gui/processing/models/qgsmodelgraphicsscene.h
Expand Up @@ -93,6 +93,29 @@ class GUI_EXPORT QgsModelGraphicsScene : public QGraphicsScene
*/
void createItems( QgsProcessingModelAlgorithm *model, QgsProcessingContext &context );

/**
* Returns list of selected component items.
*/
QList<QgsModelComponentGraphicItem *> selectedComponentItems();

/**
* Returns the topmost component item at a specified \a position.
*/
QgsModelComponentGraphicItem *componentItemAt( QPointF position ) const;

/**
* Clears any selected items in the scene.
*
* Call this method rather than QGraphicsScene::clearSelection, as the latter does
* not correctly emit signals to allow the scene's model to update.
*/
void deselectAll();

/**
* Clears any selected items and sets \a item as the current selection.
*/
void setSelectedItem( QgsModelComponentGraphicItem *item );

signals:

/**
Expand All @@ -113,6 +136,12 @@ class GUI_EXPORT QgsModelGraphicsScene : public QGraphicsScene
*/
void componentChanged();

/**
* Emitted whenever the selected item changes.
* If NULLPTR, no item is selected.
*/
void selectedItemChanged( QgsModelComponentGraphicItem *selected );

protected:

/**
Expand Down
35 changes: 14 additions & 21 deletions src/gui/processing/models/qgsmodelgraphicsview.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsmodelviewtooltemporarymousepan.h"
#include "qgsmodelviewtooltemporarykeyzoom.h"
#include "qgsmodelcomponentgraphicitem.h"
#include "qgsmodelgraphicsscene.h"

#include <QDragEnterEvent>
#include <QScrollBar>
Expand Down Expand Up @@ -98,10 +99,8 @@ void QgsModelGraphicsView::dragMoveEvent( QDragMoveEvent *event )

void QgsModelGraphicsView::wheelEvent( QWheelEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !scene() )
return;
#endif

if ( mTool )
{
Expand Down Expand Up @@ -168,10 +167,8 @@ void QgsModelGraphicsView::scaleSafe( double scale )

void QgsModelGraphicsView::mousePressEvent( QMouseEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

if ( mTool )
{
Expand All @@ -197,10 +194,8 @@ void QgsModelGraphicsView::mousePressEvent( QMouseEvent *event )

void QgsModelGraphicsView::mouseReleaseEvent( QMouseEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

if ( mTool )
{
Expand All @@ -215,10 +210,8 @@ void QgsModelGraphicsView::mouseReleaseEvent( QMouseEvent *event )

void QgsModelGraphicsView::mouseMoveEvent( QMouseEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

mMouseCurrentXY = event->pos();

Expand Down Expand Up @@ -260,10 +253,9 @@ void QgsModelGraphicsView::mouseMoveEvent( QMouseEvent *event )

void QgsModelGraphicsView::mouseDoubleClickEvent( QMouseEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

if ( mTool )
{
std::unique_ptr<QgsModelViewMouseEvent> me( new QgsModelViewMouseEvent( this, event, mTool->flags() & QgsModelViewTool::FlagSnaps ) );
Expand All @@ -277,10 +269,8 @@ void QgsModelGraphicsView::mouseDoubleClickEvent( QMouseEvent *event )

void QgsModelGraphicsView::keyPressEvent( QKeyEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

if ( mTool )
{
Expand Down Expand Up @@ -330,10 +320,8 @@ void QgsModelGraphicsView::keyPressEvent( QKeyEvent *event )

void QgsModelGraphicsView::keyReleaseEvent( QKeyEvent *event )
{
#if 0
if ( !currentLayout() )
if ( !modelScene() )
return;
#endif

if ( mTool )
{
Expand All @@ -344,6 +332,11 @@ void QgsModelGraphicsView::keyReleaseEvent( QKeyEvent *event )
QGraphicsView::keyReleaseEvent( event );
}

QgsModelGraphicsScene *QgsModelGraphicsView::modelScene() const
{
return qobject_cast< QgsModelGraphicsScene * >( QgsModelGraphicsView::scene() );
}

QgsModelViewTool *QgsModelGraphicsView::tool()
{
return mTool;
Expand Down
15 changes: 11 additions & 4 deletions src/gui/processing/models/qgsmodelgraphicsview.h
Expand Up @@ -26,6 +26,7 @@ class QgsModelViewToolTemporaryKeyPan;
class QgsModelViewToolTemporaryKeyZoom;
class QgsModelViewToolTemporaryMousePan;
class QgsModelComponentGraphicItem;
class QgsModelGraphicsScene;

///@cond NOT_STABLE

Expand Down Expand Up @@ -58,18 +59,24 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
void keyPressEvent( QKeyEvent *event ) override;
void keyReleaseEvent( QKeyEvent *event ) override;

/**
* Returns the scene associated with the tool.
* \see view()
*/
QgsModelGraphicsScene *modelScene() const;

/**
* Returns the currently active tool for the view.
* \see setTool()
*/
QgsModelViewTool *tool();
QgsModelViewTool *tool() SIP_SKIP;

/**
* Sets the \a tool currently being used in the view.
* \see unsetTool()
* \see tool()
*/
void setTool( QgsModelViewTool *tool );
void setTool( QgsModelViewTool *tool ) SIP_SKIP;

/**
* Unsets the current view tool, if it matches the specified \a tool.
Expand All @@ -78,7 +85,7 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
* that the tool won't be used any more.
* You don't have to call it manually, QgsModelViewTool takes care of it.
*/
void unsetTool( QgsModelViewTool *tool );
void unsetTool( QgsModelViewTool *tool ) SIP_SKIP;

signals:

Expand All @@ -96,7 +103,7 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
* Emitted when the current \a tool is changed.
* \see setTool()
*/
void toolSet( QgsModelViewTool *tool );
void toolSet( QgsModelViewTool *tool ) SIP_SKIP;

/**
* Emitted when an \a item is "focused" in the view, i.e. it becomes the active
Expand Down
9 changes: 0 additions & 9 deletions src/gui/processing/models/qgsmodelviewrubberband.cpp
Expand Up @@ -30,15 +30,6 @@ QgsModelGraphicsView *QgsModelViewRubberBand::view() const
return mView;
}

QgsProcessingAlgorithmModel *QgsModelViewRubberBand::model() const
{
#if 0
return mView->currentLayout();
#endif

return nullptr;
}

QRectF QgsModelViewRubberBand::updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter )
{
double x = 0;
Expand Down
8 changes: 0 additions & 8 deletions src/gui/processing/models/qgsmodelviewrubberband.h
Expand Up @@ -28,7 +28,6 @@ class QgsModelGraphicsView;
class QGraphicsRectItem;
class QGraphicsEllipseItem;
class QGraphicsPolygonItem;
class QgsProcessingAlgorithmModel;

/**
* \ingroup gui
Expand Down Expand Up @@ -76,16 +75,9 @@ class GUI_EXPORT QgsModelViewRubberBand : public QObject

/**
* Returns the view associated with the rubber band.
* \see model()
*/
QgsModelGraphicsView *view() const;

/**
* Returns the model associated with the rubber band.
* \see view()
*/
QgsProcessingAlgorithmModel *model() const;

/**
* Returns the brush used for drawing the rubber band.
* \see setBrush()
Expand Down

0 comments on commit b22e669

Please sign in to comment.