ModelerParameterDefinitionDialog.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. """
  2. ***************************************************************************
  3. ModelerParameterDefinitionDialog.py
  4. ---------------------
  5. Date : August 2012
  6. Copyright : (C) 2012 by Victor Olaya
  7. Email : volayaf at gmail dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Victor Olaya'
  18. __date__ = 'August 2012'
  19. __copyright__ = '(C) 2012, Victor Olaya'
  20. import math
  21. from qgis.PyQt.QtCore import (Qt,
  22. QByteArray,
  23. QCoreApplication)
  24. from qgis.PyQt.QtWidgets import (QDialog,
  25. QVBoxLayout,
  26. QLabel,
  27. QLineEdit,
  28. QComboBox,
  29. QCheckBox,
  30. QDialogButtonBox,
  31. QMessageBox,
  32. QTabWidget,
  33. QWidget,
  34. QTextEdit,
  35. QHBoxLayout)
  36. from qgis.PyQt.QtGui import QColor
  37. from qgis.gui import (QgsProcessingLayerOutputDestinationWidget,
  38. QgsColorButton)
  39. from qgis.core import (QgsApplication,
  40. QgsSettings,
  41. QgsProcessing,
  42. QgsProcessingParameterDefinition,
  43. QgsProcessingDestinationParameter,
  44. QgsProcessingParameterFeatureSink,
  45. QgsProcessingParameterFileDestination,
  46. QgsProcessingParameterFolderDestination,
  47. QgsProcessingParameterRasterDestination,
  48. QgsProcessingParameterVectorDestination,
  49. QgsProcessingModelAlgorithm)
  50. from processing.core import parameters
  51. from processing.modeler.exceptions import UndefinedParameterException
  52. class ModelerParameterDefinitionDialog(QDialog):
  53. @staticmethod
  54. def use_legacy_dialog(param=None, paramType=None):
  55. if isinstance(param, QgsProcessingDestinationParameter):
  56. return True
  57. # yay, use new API!
  58. return False
  59. def __init__(self, alg, paramType=None, param=None):
  60. self.alg = alg
  61. self.paramType = paramType
  62. self.param = param
  63. QDialog.__init__(self)
  64. self.setModal(True)
  65. self.setupUi()
  66. settings = QgsSettings()
  67. self.restoreGeometry(settings.value("/Processing/modelParametersDefinitionDialogGeometry", QByteArray()))
  68. def closeEvent(self, event):
  69. settings = QgsSettings()
  70. settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry())
  71. super().closeEvent(event)
  72. def switchToCommentTab(self):
  73. self.tab.setCurrentIndex(1)
  74. self.commentEdit.setFocus()
  75. self.commentEdit.selectAll()
  76. def setupUi(self):
  77. type_metadata = QgsApplication.processingRegistry().parameterType(self.param.type() if self.param else self.paramType)
  78. self.setWindowTitle(self.tr('{} Parameter Definition').format(type_metadata.name()))
  79. self.mainLayout = QVBoxLayout()
  80. self.tab = QTabWidget()
  81. self.mainLayout.addWidget(self.tab)
  82. self.setMinimumWidth(300)
  83. self.verticalLayout = QVBoxLayout()
  84. self.label = QLabel(self.tr('Parameter name'))
  85. self.verticalLayout.addWidget(self.label)
  86. self.nameTextBox = QLineEdit()
  87. self.verticalLayout.addWidget(self.nameTextBox)
  88. if isinstance(self.param, QgsProcessingParameterDefinition):
  89. self.nameTextBox.setText(self.param.description())
  90. if isinstance(self.param, QgsProcessingDestinationParameter):
  91. self.verticalLayout.addWidget(QLabel(self.tr('Default value')))
  92. self.defaultWidget = QgsProcessingLayerOutputDestinationWidget(self.param, defaultSelection=True)
  93. self.verticalLayout.addWidget(self.defaultWidget)
  94. self.verticalLayout.addSpacing(20)
  95. self.requiredCheck = QCheckBox()
  96. self.requiredCheck.setText(self.tr('Mandatory'))
  97. self.requiredCheck.setChecked(True)
  98. if self.param is not None:
  99. self.requiredCheck.setChecked(not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
  100. self.verticalLayout.addWidget(self.requiredCheck)
  101. self.advancedCheck = QCheckBox()
  102. self.advancedCheck.setText(self.tr('Advanced'))
  103. self.advancedCheck.setChecked(False)
  104. if self.param is not None:
  105. self.advancedCheck.setChecked(self.param.flags() & QgsProcessingParameterDefinition.FlagAdvanced)
  106. self.verticalLayout.addWidget(self.advancedCheck)
  107. # If child algorithm output is mandatory, disable checkbox
  108. if isinstance(self.param, QgsProcessingDestinationParameter):
  109. child = self.alg.childAlgorithms()[self.param.metadata()['_modelChildId']]
  110. model_output = child.modelOutput(self.param.metadata()['_modelChildOutputName'])
  111. param_def = child.algorithm().parameterDefinition(model_output.childOutputName())
  112. if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional):
  113. self.requiredCheck.setEnabled(False)
  114. self.requiredCheck.setChecked(True)
  115. self.advancedCheck.setEnabled(False)
  116. self.advancedCheck.setChecked(False)
  117. self.verticalLayout.addStretch()
  118. w = QWidget()
  119. w.setLayout(self.verticalLayout)
  120. self.tab.addTab(w, self.tr('Properties'))
  121. self.commentLayout = QVBoxLayout()
  122. self.commentEdit = QTextEdit()
  123. self.commentEdit.setAcceptRichText(False)
  124. self.commentLayout.addWidget(self.commentEdit, 1)
  125. hl = QHBoxLayout()
  126. hl.setContentsMargins(0, 0, 0, 0)
  127. hl.addWidget(QLabel(self.tr('Color')))
  128. self.comment_color_button = QgsColorButton()
  129. self.comment_color_button.setAllowOpacity(True)
  130. self.comment_color_button.setWindowTitle(self.tr('Comment Color'))
  131. self.comment_color_button.setShowNull(True, self.tr('Default'))
  132. hl.addWidget(self.comment_color_button)
  133. self.commentLayout.addLayout(hl)
  134. w2 = QWidget()
  135. w2.setLayout(self.commentLayout)
  136. self.tab.addTab(w2, self.tr('Comments'))
  137. self.buttonBox = QDialogButtonBox(self)
  138. self.buttonBox.setOrientation(Qt.Horizontal)
  139. self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel |
  140. QDialogButtonBox.Ok)
  141. self.buttonBox.setObjectName('buttonBox')
  142. self.buttonBox.accepted.connect(self.accept)
  143. self.buttonBox.rejected.connect(self.reject)
  144. self.mainLayout.addWidget(self.buttonBox)
  145. self.setLayout(self.mainLayout)
  146. def setComments(self, text):
  147. self.commentEdit.setPlainText(text)
  148. def comments(self):
  149. return self.commentEdit.toPlainText()
  150. def setCommentColor(self, color):
  151. if color.isValid():
  152. self.comment_color_button.setColor(color)
  153. else:
  154. self.comment_color_button.setToNull()
  155. def commentColor(self):
  156. return self.comment_color_button.color() if not self.comment_color_button.isNull() else QColor()
  157. def accept(self):
  158. description = self.nameTextBox.text()
  159. if description.strip() == '':
  160. QMessageBox.warning(self, self.tr('Unable to define parameter'),
  161. self.tr('Invalid parameter name'))
  162. return
  163. safeName = QgsProcessingModelAlgorithm.safeName(description)
  164. name = safeName.lower()
  165. # Destination parameter
  166. if (isinstance(self.param, QgsProcessingParameterFeatureSink)):
  167. self.param = QgsProcessingParameterFeatureSink(
  168. name=name,
  169. description=description,
  170. type=self.param.dataType(),
  171. defaultValue=self.defaultWidget.value())
  172. elif (isinstance(self.param, QgsProcessingParameterFileDestination)):
  173. self.param = QgsProcessingParameterFileDestination(
  174. name=name,
  175. description=description,
  176. fileFilter=self.param.fileFilter(),
  177. defaultValue=self.defaultWidget.value())
  178. elif (isinstance(self.param, QgsProcessingParameterFolderDestination)):
  179. self.param = QgsProcessingParameterFolderDestination(
  180. name=name,
  181. description=description,
  182. defaultValue=self.defaultWidget.value())
  183. elif (isinstance(self.param, QgsProcessingParameterRasterDestination)):
  184. self.param = QgsProcessingParameterRasterDestination(
  185. name=name,
  186. description=description,
  187. defaultValue=self.defaultWidget.value())
  188. elif (isinstance(self.param, QgsProcessingParameterVectorDestination)):
  189. self.param = QgsProcessingParameterVectorDestination(
  190. name=name,
  191. description=description,
  192. type=self.param.dataType(),
  193. defaultValue=self.defaultWidget.value())
  194. else:
  195. if self.paramType:
  196. typeId = self.paramType
  197. else:
  198. typeId = self.param.type()
  199. paramTypeDef = QgsApplication.instance().processingRegistry().parameterType(typeId)
  200. if not paramTypeDef:
  201. msg = self.tr('The parameter `{}` is not registered, are you missing a required plugin?').format(typeId)
  202. raise UndefinedParameterException(msg)
  203. self.param = paramTypeDef.create(name)
  204. self.param.setDescription(description)
  205. self.param.setMetadata(paramTypeDef.metadata())
  206. if not self.requiredCheck.isChecked():
  207. self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagOptional)
  208. else:
  209. self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagOptional)
  210. if self.advancedCheck.isChecked():
  211. self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  212. else:
  213. self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagAdvanced)
  214. settings = QgsSettings()
  215. settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry())
  216. QDialog.accept(self)
  217. def reject(self):
  218. self.param = None
  219. settings = QgsSettings()
  220. settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry())
  221. QDialog.reject(self)