Skip to content
Permalink
Browse files

[FEATURE][processsing] Add support for comments attached to components

This allows users to create comments attached to model components (inputs,
algorithms or outputs). Comments are shown linked to the associated component,
and can be freely moved around the model.
  • Loading branch information
nyalldawson committed Mar 4, 2020
1 parent 542c183 commit 13fc85d740a4a5bd60ccac2dd20515e745430b72
Showing with 779 additions and 81 deletions.
  1. +3 −0 python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in
  2. +56 −0 python/core/auto_generated/processing/models/qgsprocessingmodelcomment.sip.in
  3. +16 −0 python/core/auto_generated/processing/models/qgsprocessingmodelcomponent.sip.in
  4. +3 −0 python/core/auto_generated/processing/models/qgsprocessingmodeloutput.sip.in
  5. +3 −0 python/core/auto_generated/processing/models/qgsprocessingmodelparameter.sip.in
  6. +1 −0 python/core/core_auto.sip
  7. +79 −0 python/gui/auto_generated/processing/models/qgsmodelcomponentgraphicitem.sip.in
  8. +7 −0 python/gui/auto_generated/processing/models/qgsmodelgraphicsscene.sip.in
  9. +55 −5 python/plugins/processing/modeler/ModelerGraphicItem.py
  10. +81 −52 python/plugins/processing/modeler/ModelerParameterDefinitionDialog.py
  11. +35 −7 python/plugins/processing/modeler/ModelerParametersDialog.py
  12. +5 −1 python/plugins/processing/modeler/ModelerScene.py
  13. +2 −0 src/core/CMakeLists.txt
  14. +4 −0 src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp
  15. +7 −0 src/core/processing/models/qgsprocessingmodelchildalgorithm.h
  16. +47 −0 src/core/processing/models/qgsprocessingmodelcomment.cpp
  17. +59 −0 src/core/processing/models/qgsprocessingmodelcomment.h
  18. +5 −0 src/core/processing/models/qgsprocessingmodelcomponent.cpp
  19. +20 −0 src/core/processing/models/qgsprocessingmodelcomponent.h
  20. +2 −0 src/core/processing/models/qgsprocessingmodeloutput.cpp
  21. +8 −0 src/core/processing/models/qgsprocessingmodeloutput.h
  22. +2 −0 src/core/processing/models/qgsprocessingmodelparameter.cpp
  23. +7 −0 src/core/processing/models/qgsprocessingmodelparameter.h
  24. +22 −1 src/core/qgsxmlutils.cpp
  25. +138 −9 src/gui/processing/models/qgsmodelcomponentgraphicitem.cpp
  26. +73 −0 src/gui/processing/models/qgsmodelcomponentgraphicitem.h
  27. +28 −6 src/gui/processing/models/qgsmodelgraphicsscene.cpp
  28. +11 −0 src/gui/processing/models/qgsmodelgraphicsscene.h
@@ -275,6 +275,9 @@ The ``currentIndent`` and ``indentSize`` are used to set the base line indent an
The ``friendlyChildNames`` argument gives a map of child id to a friendly algorithm name, to be used in the code to identify that algorithm instead of the raw child id.
%End

virtual QgsProcessingModelComment *comment();
virtual void setComment( const QgsProcessingModelComment &comment );

};


@@ -0,0 +1,56 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/models/qgsprocessingmodelcomment.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsProcessingModelComment : QgsProcessingModelComponent
{
%Docstring
Represents a comment in a model.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsprocessingmodelcomment.h"
%End
public:

QgsProcessingModelComment( const QString &description = QString() );
%Docstring
Constructor for QgsProcessingModelComment with the specified ``description``.
%End

virtual QgsProcessingModelComment *clone() const /Factory/;


QVariant toVariant() const;
%Docstring
Saves this comment to a QVariant.

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

bool loadVariant( const QVariantMap &map );
%Docstring
Loads this comment from a QVariantMap.

.. seealso:: :py:func:`toVariant`
%End
};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/models/qgsprocessingmodelcomment.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -10,6 +10,7 @@




class QgsProcessingModelComponent
{
%Docstring
@@ -86,6 +87,21 @@ in the graphical modeler.
.. seealso:: :py:func:`linksCollapsed`
%End


virtual QgsProcessingModelComment *comment();
%Docstring
Returns the comment attached to this component (may be ``None``)

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

virtual void setComment( const QgsProcessingModelComment &comment );
%Docstring
Sets the ``comment`` attached to this component.

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

virtual QgsProcessingModelComponent *clone() const = 0 /Factory/;
%Docstring
Clones the component.
@@ -127,6 +127,9 @@ Loads this output from a QVariantMap.
.. seealso:: :py:func:`toVariant`
%End

virtual QgsProcessingModelComment *comment();
virtual void setComment( const QgsProcessingModelComment &comment );

};


@@ -63,6 +63,9 @@ Loads this parameter from a QVariantMap.
.. seealso:: :py:func:`toVariant`
%End

virtual QgsProcessingModelComment *comment();
virtual void setComment( const QgsProcessingModelComment &comment );

};


@@ -415,6 +415,7 @@
%Include auto_generated/processing/models/qgsprocessingmodelalgorithm.sip
%Include auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip
%Include auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip
%Include auto_generated/processing/models/qgsprocessingmodelcomment.sip
%Include auto_generated/processing/models/qgsprocessingmodelcomponent.sip
%Include auto_generated/processing/models/qgsprocessingmodeloutput.sip
%Include auto_generated/processing/models/qgsprocessingmodelparameter.sip
@@ -147,6 +147,13 @@ Returns the best link point to use for a link originating at a specified ``other
- edge: item edge for calculated best link point
%End

virtual void editComment();
%Docstring
Called when the comment attached to the item should be edited.

The default implementation does nothing.
%End

signals:


@@ -208,6 +215,11 @@ Returns the stroke color for the item for the specified ``state``.
virtual QColor textColor( State state ) const = 0;
%Docstring
Returns the label text color for the item for the specified ``state``.
%End

virtual Qt::PenStyle strokeStyle( State state ) const;
%Docstring
Returns the stroke style to use while rendering the outline of the item.
%End

virtual QPicture iconPicture() const;
@@ -218,6 +230,11 @@ Returns a QPicture version of the item's icon, if available.
virtual QPixmap iconPixmap() const;
%Docstring
Returns a QPixmap version of the item's icon, if available.
%End

virtual void updateStoredComponentPosition( const QPointF &pos ) = 0;
%Docstring
Updates the position stored in the model for the associated comment
%End

};
@@ -264,6 +281,8 @@ Ownership of ``parameter`` is transferred to the item.

virtual QPicture iconPicture() const;

virtual void updateStoredComponentPosition( const QPointF &pos );


protected slots:

@@ -320,6 +339,8 @@ Ownership of ``child`` is transferred to the item.

virtual QString linkPointText( Qt::Edge edge, int index ) const;

virtual void updateStoredComponentPosition( const QPointF &pos );


protected slots:

@@ -368,11 +389,69 @@ Ownership of ``output`` is transferred to the item.

virtual QPicture iconPicture() const;

virtual void updateStoredComponentPosition( const QPointF &pos );


protected slots:

virtual void deleteComponent();


};



class QgsModelCommentGraphicItem : QgsModelComponentGraphicItem
{
%Docstring
A graphic item representing a model comment in the model designer.

.. warning::

Not stable API

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsmodelcomponentgraphicitem.h"
%End
public:

QgsModelCommentGraphicItem( QgsProcessingModelComment *comment /Transfer/,
QgsModelComponentGraphicItem *parentItem,
QgsProcessingModelAlgorithm *model,
QGraphicsItem *parent /TransferThis/ );
%Docstring
Constructor for QgsModelCommentGraphicItem for the specified ``comment``, with the specified ``parent`` item.

The ``model`` argument specifies the associated processing model. Ownership of ``model`` is not transferred, and
it must exist for the lifetime of this object.

Ownership of ``output`` is transferred to the item.
%End
~QgsModelCommentGraphicItem();
virtual void contextMenuEvent( QGraphicsSceneContextMenuEvent *event );


protected:

virtual QColor fillColor( State state ) const;

virtual QColor strokeColor( State state ) const;

virtual QColor textColor( State state ) const;

virtual Qt::PenStyle strokeStyle( State state ) const;

virtual void updateStoredComponentPosition( const QPointF &pos );


protected slots:

virtual void deleteComponent();

virtual void editComponent();

};

@@ -110,6 +110,13 @@ Creates a new graphic item for a model child algorithm.
Creates a new graphic item for a model output.
%End

virtual QgsModelComponentGraphicItem *createCommentGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelComment *comment,
QgsModelComponentGraphicItem *parentItem ) const /Factory/;
%Docstring
Creates a new graphic item for a model comment.
%End


};


@@ -29,7 +29,8 @@
QgsProcessingParameterWidgetContext,
QgsModelParameterGraphicItem,
QgsModelChildAlgorithmGraphicItem,
QgsModelOutputGraphicItem
QgsModelOutputGraphicItem,
QgsModelCommentGraphicItem
)
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
@@ -59,15 +60,20 @@ def create_widget_context(self):
widget_context.setModel(self.model())
return widget_context

def editComponent(self):
def edit(self, edit_comment=False):
existing_param = self.model().parameterDefinition(self.component().parameterName())
comment = self.component().comment().description()
new_param = None
if ModelerParameterDefinitionDialog.use_legacy_dialog(param=existing_param):
# boo, old api
dlg = ModelerParameterDefinitionDialog(self.model(),
param=existing_param)
dlg.setComments(comment)
if edit_comment:
dlg.switchToCommentTab()
if dlg.exec_():
new_param = dlg.param
comment = dlg.comments()
else:
# yay, use new API!
context = createContext()
@@ -84,11 +90,18 @@ def editComponent(self):
self.model().removeModelParameter(self.component().parameterName())
self.component().setParameterName(new_param.name())
self.component().setDescription(new_param.name())
self.component().comment().setDescription(comment)
self.model().addModelParameter(new_param, self.component())
self.setLabel(new_param.description())
self.requestModelRepaint.emit()
self.changed.emit()

def editComponent(self):
self.edit()

def editComment(self):
self.edit(edit_comment=True)


class ModelerChildAlgorithmGraphicItem(QgsModelChildAlgorithmGraphicItem):
"""
@@ -101,22 +114,32 @@ class ModelerChildAlgorithmGraphicItem(QgsModelChildAlgorithmGraphicItem):
def __init__(self, element, model):
super().__init__(element, model, None)

def editComponent(self):
def edit(self, edit_comment=False):
elemAlg = self.component().algorithm()
dlg = ModelerParametersDialog(elemAlg, self.model(), self.component().childId(),
self.component().configuration())
dlg.setComments(self.component().comment().description())
if edit_comment:
dlg.switchToCommentTab()
if dlg.exec_():
alg = dlg.createAlgorithm()
alg.setChildId(self.component().childId())
self.updateAlgorithm(alg)
self.requestModelRepaint.emit()
self.changed.emit()

def editComponent(self):
self.edit()

def editComment(self):
self.edit(edit_comment=True)

def updateAlgorithm(self, alg):
existing_child = self.model().childAlgorithm(alg.childId())
alg.setPosition(existing_child.position())
alg.setLinksCollapsed(Qt.TopEdge, existing_child.linksCollapsed(Qt.TopEdge))
alg.setLinksCollapsed(Qt.BottomEdge, existing_child.linksCollapsed(Qt.BottomEdge))
alg.comment().setPosition(existing_child.comment().position())
for i, out in enumerate(alg.modelOutputs().keys()):
alg.modelOutput(out).setPosition(alg.modelOutput(out).position()
or alg.position() + QPointF(
@@ -136,15 +159,42 @@ class ModelerOutputGraphicItem(QgsModelOutputGraphicItem):
def __init__(self, element, model):
super().__init__(element, model, None)

def editComponent(self):
def edit(self, edit_comment=False):
child_alg = self.model().childAlgorithm(self.component().childId())
param_name = '{}:{}'.format(self.component().childId(), self.component().name())
dlg = ModelerParameterDefinitionDialog(self.model(),
param=self.model().parameterDefinition(param_name))
if dlg.exec_() and dlg.param is not None:
dlg.setComments(self.component().comment().description())
if edit_comment:
dlg.switchToCommentTab()

if dlg.exec_():
model_output = child_alg.modelOutput(self.component().name())
model_output.setDescription(dlg.param.description())
model_output.setDefaultValue(dlg.param.defaultValue())
model_output.setMandatory(not (dlg.param.flags() & QgsProcessingParameterDefinition.FlagOptional))
model_output.comment().setDescription(dlg.comments())
self.model().updateDestinationParameters()
self.requestModelRepaint.emit()
self.changed.emit()

def editComponent(self):
self.edit()

def editComment(self):
self.edit(edit_comment=True)


class ModelerCommentGraphicItem(QgsModelCommentGraphicItem):
"""
IMPORTANT! This is intentionally a MINIMAL class, only containing code which HAS TO BE HERE
because it contains Python code for compatibility with deprecated methods ONLY.
Don't add anything here -- edit the c++ base class instead!
"""

def __init__(self, model, element, parent_component):
super().__init__(element, parent_component, model, None)

def editComponent(self):
pass

0 comments on commit 13fc85d

Please sign in to comment.
You can’t perform that action at this time.