Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing][FEATURE] Add api for setting model component colors, and…
… expose

the option to set manual colors for individual model comments
  • Loading branch information
nyalldawson committed Apr 1, 2020
1 parent 25b2ba4 commit e788be9
Show file tree
Hide file tree
Showing 19 changed files with 397 additions and 43 deletions.
Expand Up @@ -69,6 +69,27 @@ Sets the ``size`` of the model component within the graphical modeler.

.. seealso:: :py:func:`size`

.. versionadded:: 3.14
%End

QColor color() const;
%Docstring
Returns the color of the model component within the graphical modeler.

An invalid color indicates that the default color for the component should be used.

.. seealso:: :py:func:`setColor`

.. versionadded:: 3.14
%End

void setColor( const QColor &color );
%Docstring
Sets the ``color`` of the model component within the graphical modeler. An invalid ``color``
indicates that the default color for the component should be used.

.. seealso:: :py:func:`color`

.. versionadded:: 3.14
%End

Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -428,6 +428,7 @@
%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/qgsprocessingmodelgroupbox.sip
%Include auto_generated/processing/models/qgsprocessingmodeloutput.sip
%Include auto_generated/processing/models/qgsprocessingmodelparameter.sip
%Include auto_generated/processing/qgsprocessing.sip
Expand Down
Expand Up @@ -157,6 +157,24 @@ Returns the comments for the parameter.

.. seealso:: :py:func:`setComments`

.. versionadded:: 3.14
%End

void setCommentColor( const QColor &color );
%Docstring
Sets the color for the comments for the parameter.

.. seealso:: :py:func:`commentColor`

.. versionadded:: 3.14
%End

QColor commentColor() const;
%Docstring
Returns the color for the comments for the parameter.

.. seealso:: :py:func:`setCommentColor`

.. versionadded:: 3.14
%End

Expand Down
3 changes: 2 additions & 1 deletion python/gui/auto_generated/qgscolorbutton.sip.in
Expand Up @@ -210,11 +210,12 @@ Sets the string to use for the "no color" option in the button's drop-down menu.
dialog
%End

void setShowNull( bool showNull );
void setShowNull( bool showNull, const QString &nullString = QString() );
%Docstring
Sets whether a set to null (clear) option is shown in the button's drop-down menu.

:param showNull: set to ``True`` to show a null option
:param nullString: translated string to use for the null option. If not set, a default "Clear Color" string will be used.

.. seealso:: :py:func:`showNull`

Expand Down
9 changes: 9 additions & 0 deletions python/plugins/processing/modeler/ModelerGraphicItem.py
Expand Up @@ -63,17 +63,20 @@ def create_widget_context(self):
def edit(self, edit_comment=False):
existing_param = self.model().parameterDefinition(self.component().parameterName())
comment = self.component().comment().description()
comment_color = self.component().comment().color()
new_param = None
if ModelerParameterDefinitionDialog.use_legacy_dialog(param=existing_param):
# boo, old api
dlg = ModelerParameterDefinitionDialog(self.model(),
param=existing_param)
dlg.setComments(comment)
dlg.setCommentColor(comment_color)
if edit_comment:
dlg.switchToCommentTab()
if dlg.exec_():
new_param = dlg.param
comment = dlg.comments()
comment_color = dlg.commentColor()
else:
# yay, use new API!
context = createContext()
Expand All @@ -84,19 +87,22 @@ def edit(self, edit_comment=False):
definition=existing_param,
algorithm=self.model())
dlg.setComments(comment)
dlg.setCommentColor(comment_color)
if edit_comment:
dlg.switchToCommentTab()

if dlg.exec_():
new_param = dlg.createParameter(existing_param.name())
comment = dlg.comments()
comment_color = dlg.commentColor()

if new_param is not None:
self.aboutToChange.emit(self.tr('Edit {}').format(new_param.description()))
self.model().removeModelParameter(self.component().parameterName())
self.component().setParameterName(new_param.name())
self.component().setDescription(new_param.name())
self.component().comment().setDescription(comment)
self.component().comment().setColor(comment_color)
self.model().addModelParameter(new_param, self.component())
self.setLabel(new_param.description())
self.requestModelRepaint.emit()
Expand Down Expand Up @@ -125,6 +131,7 @@ def edit(self, edit_comment=False):
dlg = ModelerParametersDialog(elemAlg, self.model(), self.component().childId(),
self.component().configuration())
dlg.setComments(self.component().comment().description())
dlg.setCommentColor(self.component().comment().color())
if edit_comment:
dlg.switchToCommentTab()
if dlg.exec_():
Expand Down Expand Up @@ -160,6 +167,7 @@ def edit(self, edit_comment=False):
dlg = ModelerParameterDefinitionDialog(self.model(),
param=self.model().parameterDefinition(param_name))
dlg.setComments(self.component().comment().description())
dlg.setCommentColor(self.component().comment().color())
if edit_comment:
dlg.switchToCommentTab()

Expand All @@ -169,6 +177,7 @@ def edit(self, edit_comment=False):
model_output.setDefaultValue(dlg.param.defaultValue())
model_output.setMandatory(not (dlg.param.flags() & QgsProcessingParameterDefinition.FlagOptional))
model_output.comment().setDescription(dlg.comments())
model_output.comment().setColor(dlg.commentColor())
self.aboutToChange.emit(self.tr('Edit {}').format(model_output.description()))
self.model().updateDestinationParameters()
self.requestModelRepaint.emit()
Expand Down
Expand Up @@ -36,9 +36,12 @@
QMessageBox,
QTabWidget,
QWidget,
QTextEdit)
QTextEdit,
QHBoxLayout)
from qgis.PyQt.QtGui import QColor

from qgis.gui import (QgsProcessingLayerOutputDestinationWidget)
from qgis.gui import (QgsProcessingLayerOutputDestinationWidget,
QgsColorButton)
from qgis.core import (QgsApplication,
QgsSettings,
QgsProcessing,
Expand Down Expand Up @@ -210,8 +213,8 @@ def setupUi(self):
if self.param is not None:
self.shapetypeCombo.setCurrentIndex(self.shapetypeCombo.findData(self.param.dataTypes()[0]))
self.verticalLayout.addWidget(self.shapetypeCombo)
elif (self.paramType == parameters.PARAMETER_MULTIPLE
or isinstance(self.param, QgsProcessingParameterMultipleLayers)):
elif (self.paramType == parameters.PARAMETER_MULTIPLE or
isinstance(self.param, QgsProcessingParameterMultipleLayers)):
self.verticalLayout.addWidget(QLabel(self.tr('Data type')))
self.datatypeCombo = QComboBox()
self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer)
Expand All @@ -225,8 +228,8 @@ def setupUi(self):
if self.param is not None:
self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.layerType()))
self.verticalLayout.addWidget(self.datatypeCombo)
elif (self.paramType == parameters.PARAMETER_MAP_LAYER or
isinstance(self.param, QgsProcessingParameterMapLayer)):
elif (self.paramType == parameters.PARAMETER_MAP_LAYER
or isinstance(self.param, QgsProcessingParameterMapLayer)):
self.verticalLayout.addWidget(QLabel(self.tr('Data type')))
self.datatypeCombo = QComboBox()
self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer)
Expand All @@ -239,11 +242,11 @@ def setupUi(self):
if self.param is not None:
self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.dataTypes()[0]))
self.verticalLayout.addWidget(self.datatypeCombo)
elif (self.paramType in (parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE)
or isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale))):
elif (self.paramType in (parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE) or
isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale))):

if (self.paramType == parameters.PARAMETER_DISTANCE
or isinstance(self.param, QgsProcessingParameterDistance)):
if (self.paramType == parameters.PARAMETER_DISTANCE or
isinstance(self.param, QgsProcessingParameterDistance)):
self.verticalLayout.addWidget(QLabel(self.tr('Linked input')))
self.parentCombo = QComboBox()
self.parentCombo.addItem('', '')
Expand Down Expand Up @@ -334,15 +337,26 @@ def setupUi(self):
self.commentLayout = QVBoxLayout()
self.commentEdit = QTextEdit()
self.commentEdit.setAcceptRichText(False)
self.commentLayout.addWidget(self.commentEdit)
self.commentLayout.addWidget(self.commentEdit, 1)

hl = QHBoxLayout()
hl.setContentsMargins(0, 0, 0, 0)
hl.addWidget(QLabel(self.tr('Color')))
self.comment_color_button = QgsColorButton()
self.comment_color_button.setAllowOpacity(True)
self.comment_color_button.setWindowTitle(self.tr('Comment Color'))
self.comment_color_button.setShowNull(True, self.tr('Default'))
hl.addWidget(self.comment_color_button)
self.commentLayout.addLayout(hl)

w2 = QWidget()
w2.setLayout(self.commentLayout)
self.tab.addTab(w2, self.tr('Comments'))

self.buttonBox = QDialogButtonBox(self)
self.buttonBox.setOrientation(Qt.Horizontal)
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
| QDialogButtonBox.Ok)
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel |
QDialogButtonBox.Ok)
self.buttonBox.setObjectName('buttonBox')
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
Expand All @@ -357,6 +371,15 @@ def setComments(self, text):
def comments(self):
return self.commentEdit.toPlainText()

def setCommentColor(self, color):
if color.isValid():
self.comment_color_button.setColor(color)
else:
self.comment_color_button.setToNull()

def commentColor(self):
return self.comment_color_button.color() if not self.comment_color_button.isNull() else QColor()

def accept(self):
description = self.nameTextBox.text()
if description.strip() == '':
Expand All @@ -374,8 +397,8 @@ def accept(self):
i += 1
else:
name = self.param.name()
if (self.paramType == parameters.PARAMETER_TABLE_FIELD
or isinstance(self.param, QgsProcessingParameterField)):
if (self.paramType == parameters.PARAMETER_TABLE_FIELD or
isinstance(self.param, QgsProcessingParameterField)):
if self.parentCombo.currentIndex() < 0:
QMessageBox.warning(self, self.tr('Unable to define parameter'),
self.tr('Wrong or missing parameter values'))
Expand All @@ -388,39 +411,39 @@ def accept(self):
self.param = QgsProcessingParameterField(name, description, defaultValue=default,
parentLayerParameterName=parent, type=datatype,
allowMultiple=self.multipleCheck.isChecked())
elif (self.paramType == parameters.PARAMETER_BAND
or isinstance(self.param, QgsProcessingParameterBand)):
elif (self.paramType == parameters.PARAMETER_BAND or
isinstance(self.param, QgsProcessingParameterBand)):
if self.parentCombo.currentIndex() < 0:
QMessageBox.warning(self, self.tr('Unable to define parameter'),
self.tr('Wrong or missing parameter values'))
return
parent = self.parentCombo.currentData()
self.param = QgsProcessingParameterBand(name, description, None, parent)
elif (self.paramType == parameters.PARAMETER_MAP_LAYER
or isinstance(self.param, QgsProcessingParameterMapLayer)):
elif (self.paramType == parameters.PARAMETER_MAP_LAYER or
isinstance(self.param, QgsProcessingParameterMapLayer)):
self.param = QgsProcessingParameterMapLayer(
name, description, types=[self.datatypeCombo.currentData()])
elif (self.paramType == parameters.PARAMETER_RASTER
or isinstance(self.param, QgsProcessingParameterRasterLayer)):
elif (self.paramType == parameters.PARAMETER_RASTER or
isinstance(self.param, QgsProcessingParameterRasterLayer)):
self.param = QgsProcessingParameterRasterLayer(
name, description)
elif (self.paramType == parameters.PARAMETER_TABLE
or isinstance(self.param, QgsProcessingParameterVectorLayer)):
elif (self.paramType == parameters.PARAMETER_TABLE or
isinstance(self.param, QgsProcessingParameterVectorLayer)):
self.param = QgsProcessingParameterVectorLayer(
name, description,
[self.shapetypeCombo.currentData()])
elif (self.paramType == parameters.PARAMETER_VECTOR
or isinstance(self.param, QgsProcessingParameterFeatureSource)):
elif (self.paramType == parameters.PARAMETER_VECTOR or
isinstance(self.param, QgsProcessingParameterFeatureSource)):
self.param = QgsProcessingParameterFeatureSource(
name, description,
[self.shapetypeCombo.currentData()])
elif (self.paramType == parameters.PARAMETER_MULTIPLE
or isinstance(self.param, QgsProcessingParameterMultipleLayers)):
elif (self.paramType == parameters.PARAMETER_MULTIPLE or
isinstance(self.param, QgsProcessingParameterMultipleLayers)):
self.param = QgsProcessingParameterMultipleLayers(
name, description,
self.datatypeCombo.currentData())
elif (self.paramType == parameters.PARAMETER_DISTANCE
or isinstance(self.param, QgsProcessingParameterDistance)):
elif (self.paramType == parameters.PARAMETER_DISTANCE or
isinstance(self.param, QgsProcessingParameterDistance)):
self.param = QgsProcessingParameterDistance(name, description,
self.defaultTextBox.text())
try:
Expand All @@ -442,12 +465,12 @@ def accept(self):
parent = self.parentCombo.currentData()
if parent:
self.param.setParentParameterName(parent)
elif (self.paramType == parameters.PARAMETER_SCALE
or isinstance(self.param, QgsProcessingParameterScale)):
elif (self.paramType == parameters.PARAMETER_SCALE or
isinstance(self.param, QgsProcessingParameterScale)):
self.param = QgsProcessingParameterScale(name, description,
self.defaultTextBox.text())
elif (self.paramType == parameters.PARAMETER_NUMBER
or isinstance(self.param, QgsProcessingParameterNumber)):
elif (self.paramType == parameters.PARAMETER_NUMBER or
isinstance(self.param, QgsProcessingParameterNumber)):

type = self.type_combo.currentData()
self.param = QgsProcessingParameterNumber(name, description, type,
Expand Down
33 changes: 31 additions & 2 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Expand Up @@ -27,6 +27,7 @@
from qgis.PyQt.QtWidgets import (QDialog, QDialogButtonBox, QLabel, QLineEdit,
QFrame, QPushButton, QSizePolicy, QVBoxLayout,
QHBoxLayout, QWidget, QTabWidget, QTextEdit)
from qgis.PyQt.QtGui import QColor

from qgis.core import (Qgis,
QgsProject,
Expand All @@ -50,7 +51,8 @@
QgsProcessingModelerParameterWidget,
QgsProcessingParameterWidgetContext,
QgsPanelWidget,
QgsPanelWidgetStack)
QgsPanelWidgetStack,
QgsColorButton)
from qgis.utils import iface

from processing.gui.wrappers import WidgetWrapperFactory
Expand Down Expand Up @@ -101,6 +103,12 @@ def setComments(self, text):
def comments(self):
return self.widget.comments()

def setCommentColor(self, color):
self.widget.setCommentColor(color)

def commentColor(self):
return self.widget.commentColor()

def switchToCommentTab(self):
self.widget.switchToCommentTab()

Expand Down Expand Up @@ -534,7 +542,18 @@ def setupUi(self):
self.commentLayout = QVBoxLayout()
self.commentEdit = QTextEdit()
self.commentEdit.setAcceptRichText(False)
self.commentLayout.addWidget(self.commentEdit)
self.commentLayout.addWidget(self.commentEdit, 1)

hl = QHBoxLayout()
hl.setContentsMargins(0, 0, 0, 0)
hl.addWidget(QLabel(self.tr('Color')))
self.comment_color_button = QgsColorButton()
self.comment_color_button.setAllowOpacity(True)
self.comment_color_button.setWindowTitle(self.tr('Comment Color'))
self.comment_color_button.setShowNull(True, self.tr('Default'))
hl.addWidget(self.comment_color_button)
self.commentLayout.addLayout(hl)

w2 = QWidget()
w2.setLayout(self.commentLayout)
self.tab.addTab(w2, self.tr('Comments'))
Expand All @@ -547,6 +566,15 @@ def setComments(self, text):
def comments(self):
return self.commentEdit.toPlainText()

def setCommentColor(self, color):
if color.isValid():
self.comment_color_button.setColor(color)
else:
self.comment_color_button.setToNull()

def commentColor(self):
return self.comment_color_button.color() if not self.comment_color_button.isNull() else QColor()

def getAvailableDependencies(self):
return self.widget.getAvailableDependencies()

Expand All @@ -566,4 +594,5 @@ def createAlgorithm(self):
alg = self.widget.createAlgorithm()
if alg:
alg.comment().setDescription(self.comments())
alg.comment().setColor(self.commentColor())
return alg

0 comments on commit e788be9

Please sign in to comment.