123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947 |
- """
- ***************************************************************************
- wrappers.py - Standard parameters widget wrappers
- ---------------------
- Date : May 2016
- Copyright : (C) 2016 by Arnaud Morvan, Victor Olaya
- Email : arnaud dot morvan at camptocamp dot com
- volayaf at gmail dot com
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************
- """
- __author__ = 'Arnaud Morvan'
- __date__ = 'May 2016'
- __copyright__ = '(C) 2016, Arnaud Morvan'
- import os
- import re
- from inspect import isclass
- from copy import deepcopy
- from qgis.core import (
- QgsApplication,
- QgsCoordinateReferenceSystem,
- QgsExpression,
- QgsFieldProxyModel,
- QgsSettings,
- QgsProject,
- QgsMapLayerType,
- QgsVectorLayer,
- QgsProcessing,
- QgsProcessingUtils,
- QgsProcessingParameterDefinition,
- QgsProcessingParameterBoolean,
- QgsProcessingParameterCrs,
- QgsProcessingParameterExtent,
- QgsProcessingParameterPoint,
- QgsProcessingParameterFile,
- QgsProcessingParameterMultipleLayers,
- QgsProcessingParameterNumber,
- QgsProcessingParameterRasterLayer,
- QgsProcessingParameterEnum,
- QgsProcessingParameterString,
- QgsProcessingParameterExpression,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMeshLayer,
- QgsProcessingParameterField,
- QgsProcessingParameterFeatureSource,
- QgsProcessingParameterMapLayer,
- QgsProcessingParameterBand,
- QgsProcessingParameterMatrix,
- QgsProcessingParameterDistance,
- QgsProcessingParameterDuration,
- QgsProcessingFeatureSourceDefinition,
- QgsProcessingOutputRasterLayer,
- QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers,
- QgsProcessingOutputFile,
- QgsProcessingOutputString,
- QgsProcessingOutputNumber,
- QgsProcessingModelChildParameterSource,
- NULL,
- Qgis)
- from qgis.PyQt.QtWidgets import (
- QCheckBox,
- QComboBox,
- QLabel,
- QDialog,
- QFileDialog,
- QHBoxLayout,
- QLineEdit,
- QPlainTextEdit,
- QToolButton,
- QWidget,
- QSizePolicy
- )
- from qgis.PyQt.QtGui import QIcon
- from qgis.gui import (
- QgsGui,
- QgsExpressionLineEdit,
- QgsExpressionBuilderDialog,
- QgsFieldComboBox,
- QgsFieldExpressionWidget,
- QgsProjectionSelectionDialog,
- QgsMapLayerComboBox,
- QgsProjectionSelectionWidget,
- QgsRasterBandComboBox,
- QgsProcessingGui,
- QgsAbstractProcessingParameterWidgetWrapper,
- QgsProcessingMapLayerComboBox
- )
- from qgis.PyQt.QtCore import QVariant, Qt
- from qgis.utils import iface
- from processing.core.ProcessingConfig import ProcessingConfig
- from processing.modeler.MultilineTextPanel import MultilineTextPanel
- from processing.gui.NumberInputPanel import NumberInputPanel, ModelerNumberInputPanel, DistanceInputPanel
- from processing.gui.RangePanel import RangePanel
- from processing.gui.PointSelectionPanel import PointSelectionPanel
- from processing.gui.FileSelectionPanel import FileSelectionPanel
- from processing.gui.CheckboxesPanel import CheckboxesPanel
- from processing.gui.MultipleInputPanel import MultipleInputPanel
- from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
- from processing.gui.FixedTablePanel import FixedTablePanel
- from processing.gui.ExtentSelectionPanel import ExtentSelectionPanel
- from processing.tools import dataobjects
- DIALOG_STANDARD = QgsProcessingGui.Standard
- DIALOG_BATCH = QgsProcessingGui.Batch
- DIALOG_MODELER = QgsProcessingGui.Modeler
- pluginPath = os.path.split(os.path.dirname(__file__))[0]
- class InvalidParameterValue(Exception):
- pass
- dialogTypes = {"AlgorithmDialog": DIALOG_STANDARD,
- "ModelerParametersDialog": DIALOG_MODELER,
- "BatchAlgorithmDialog": DIALOG_BATCH}
- def getExtendedLayerName(layer):
- authid = layer.crs().authid()
- if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF) and authid is not None:
- return f'{layer.name()} [{authid}]'
- else:
- return layer.name()
- class WidgetWrapper(QgsAbstractProcessingParameterWidgetWrapper):
- NOT_SET_OPTION = '~~~~!!!!NOT SET!!!!~~~~~~~'
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- self.dialogType = dialogTypes.get(dialog.__class__.__name__, QgsProcessingGui.Standard)
- super().__init__(param, self.dialogType)
- self.dialog = dialog
- self.row = row
- self.col = col
- self.widget = self.createWidget(**kwargs)
- self.label = self.createLabel()
- if param.defaultValue() is not None:
- self.setValue(param.defaultValue())
- def comboValue(self, validator=None, combobox=None):
- if combobox is None:
- combobox = self.widget
- idx = combobox.findText(combobox.currentText())
- if idx < 0:
- v = combobox.currentText().strip()
- if validator is not None and not validator(v):
- raise InvalidParameterValue()
- return v
- if combobox.currentData() == self.NOT_SET_OPTION:
- return None
- elif combobox.currentData() is not None:
- return combobox.currentData()
- else:
- return combobox.currentText()
- def createWidget(self, **kwargs):
- pass
- def createLabel(self):
- if self.dialogType == DIALOG_BATCH:
- return None
- desc = self.parameterDefinition().description()
- if isinstance(self.parameterDefinition(), QgsProcessingParameterExtent):
- desc += self.tr(' (xmin, xmax, ymin, ymax)')
- if isinstance(self.parameterDefinition(), QgsProcessingParameterPoint):
- desc += self.tr(' (x, y)')
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- desc += self.tr(' [optional]')
- label = QLabel(desc)
- label.setToolTip(self.parameterDefinition().name())
- return label
- def setValue(self, value):
- pass
- def value(self):
- return None
- def widgetValue(self):
- return self.value()
- def setWidgetValue(self, value, context):
- self.setValue(value)
- def setComboValue(self, value, combobox=None):
- if combobox is None:
- combobox = self.widget
- if isinstance(value, list):
- if value:
- value = value[0]
- else:
- value = None
- values = [combobox.itemData(i) for i in range(combobox.count())]
- try:
- idx = values.index(value)
- combobox.setCurrentIndex(idx)
- return
- except ValueError:
- pass
- if combobox.isEditable():
- if value is not None:
- combobox.setEditText(str(value))
- else:
- combobox.setCurrentIndex(0)
- def refresh(self):
- pass
- def getFileName(self, initial_value=''):
- """Shows a file open dialog"""
- settings = QgsSettings()
- if os.path.isdir(initial_value):
- path = initial_value
- elif os.path.isdir(os.path.dirname(initial_value)):
- path = os.path.dirname(initial_value)
- elif settings.contains('/Processing/LastInputPath'):
- path = str(settings.value('/Processing/LastInputPath'))
- else:
- path = ''
- # TODO: should use selectedFilter argument for default file format
- filename, selected_filter = QFileDialog.getOpenFileName(self.widget, self.tr('Select File'),
- path, self.parameterDefinition().createFileFilter())
- if filename:
- settings.setValue('/Processing/LastInputPath',
- os.path.dirname(str(filename)))
- return filename, selected_filter
- class BasicWidgetWrapper(WidgetWrapper):
- def createWidget(self):
- return QLineEdit()
- def setValue(self, value):
- self.widget.setText(value)
- def value(self):
- return self.widget.text()
- class BooleanWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("BooleanWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createLabel(self):
- if self.dialogType == DIALOG_STANDARD:
- return None
- else:
- return super().createLabel()
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- return QCheckBox()
- elif self.dialogType == DIALOG_BATCH:
- widget = QComboBox()
- widget.addItem(self.tr('Yes'), True)
- widget.addItem(self.tr('No'), False)
- return widget
- else:
- widget = QComboBox()
- widget.addItem(self.tr('Yes'), True)
- widget.addItem(self.tr('No'), False)
- bools = self.dialog.getAvailableValuesOfType(QgsProcessingParameterBoolean, None)
- for b in bools:
- widget.addItem(self.dialog.resolveValueDescription(b), b)
- return widget
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- self.widget.setChecked(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- return self.widget.isChecked()
- else:
- return self.comboValue()
- class CrsWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("CrsWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType == DIALOG_MODELER:
- self.combo = QComboBox()
- widget = QWidget()
- layout = QHBoxLayout()
- layout.setMargin(0)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(1)
- layout.addWidget(self.combo)
- btn = QToolButton()
- btn.setIcon(QgsApplication.getThemeIcon("mActionSetProjection.svg"))
- btn.setToolTip(self.tr("Select CRS"))
- btn.clicked.connect(self.selectProjection)
- layout.addWidget(btn)
- widget.setLayout(layout)
- self.combo.setEditable(True)
- crss = self.dialog.getAvailableValuesOfType((QgsProcessingParameterCrs, QgsProcessingParameterString), QgsProcessingOutputString)
- for crs in crss:
- self.combo.addItem(self.dialog.resolveValueDescription(crs), crs)
- layers = self.dialog.getAvailableValuesOfType([QgsProcessingParameterRasterLayer,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMeshLayer,
- QgsProcessingParameterFeatureSource],
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputRasterLayer,
- QgsProcessingOutputMapLayer])
- for l in layers:
- self.combo.addItem("Crs of layer " + self.dialog.resolveValueDescription(l), l)
- if self.parameterDefinition().defaultValue():
- self.combo.setEditText(self.parameterDefinition().defaultValue())
- return widget
- else:
- widget = QgsProjectionSelectionWidget()
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- widget.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, True)
- if self.parameterDefinition().defaultValue():
- if self.parameterDefinition().defaultValue() == 'ProjectCrs':
- crs = QgsProject.instance().crs()
- else:
- crs = QgsCoordinateReferenceSystem(self.parameterDefinition().defaultValue())
- widget.setCrs(crs)
- else:
- widget.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, True)
- widget.crsChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- def selectProjection(self):
- dialog = QgsProjectionSelectionDialog(self.widget)
- current_crs = QgsCoordinateReferenceSystem(self.combo.currentText())
- if current_crs.isValid():
- dialog.setCrs(current_crs)
- if dialog.exec_():
- self.setValue(dialog.crs().authid())
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_MODELER:
- self.setComboValue(value, self.combo)
- elif value == 'ProjectCrs':
- self.widget.setCrs(QgsProject.instance().crs())
- else:
- self.widget.setCrs(QgsCoordinateReferenceSystem(value))
- def value(self):
- if self.dialogType == DIALOG_MODELER:
- return self.comboValue(combobox=self.combo)
- else:
- crs = self.widget.crs()
- if crs.isValid():
- return self.widget.crs().authid()
- else:
- return None
- class ExtentWidgetWrapper(WidgetWrapper):
- USE_MIN_COVERING_EXTENT = "[Use min covering extent]"
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("ExtentWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- widget = ExtentSelectionPanel(self.dialog, self.parameterDefinition())
- widget.hasChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- widget = QComboBox()
- widget.setEditable(True)
- extents = self.dialog.getAvailableValuesOfType(QgsProcessingParameterExtent, (QgsProcessingOutputString))
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- widget.addItem(self.USE_MIN_COVERING_EXTENT, None)
- layers = self.dialog.getAvailableValuesOfType([QgsProcessingParameterFeatureSource,
- QgsProcessingParameterRasterLayer,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMeshLayer],
- [QgsProcessingOutputRasterLayer,
- QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer])
- for ex in extents:
- widget.addItem(self.dialog.resolveValueDescription(ex), ex)
- for l in layers:
- widget.addItem("Extent of " + self.dialog.resolveValueDescription(l), l)
- if not self.parameterDefinition().defaultValue():
- widget.setEditText(self.parameterDefinition().defaultValue())
- return widget
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.widget.setExtentFromString(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return self.widget.getValue()
- else:
- idx = self.widget.findText(self.widget.currentText())
- if idx < 0:
- s = str(self.widget.currentText()).strip()
- if s:
- try:
- tokens = s.split(',')
- if len(tokens) != 4:
- raise InvalidParameterValue()
- for token in tokens:
- float(token)
- except:
- raise InvalidParameterValue()
- elif self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- s = None
- else:
- raise InvalidParameterValue()
- return s
- else:
- return self.widget.currentData()
- class PointWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("PointWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return PointSelectionPanel(self.dialog, self.parameterDefinition().defaultValue())
- else:
- item = QComboBox()
- item.setEditable(True)
- points = self.dialog.getAvailableValuesOfType((QgsProcessingParameterPoint, QgsProcessingParameterString), (QgsProcessingOutputString))
- for p in points:
- item.addItem(self.dialog.resolveValueDescription(p), p)
- item.setEditText(str(self.parameterDefinition().defaultValue()))
- return item
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.widget.setPointFromString(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return self.widget.getValue()
- else:
- idx = self.widget.findText(self.widget.currentText())
- if idx < 0:
- s = str(self.widget.currentText()).strip()
- if s:
- try:
- tokens = s.split(',')
- if len(tokens) != 2:
- raise InvalidParameterValue()
- for token in tokens:
- float(token)
- except:
- raise InvalidParameterValue()
- elif self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- s = None
- else:
- raise InvalidParameterValue()
- return s
- else:
- return self.widget.currentData()
- class FileWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("FileWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return FileSelectionPanel(self.parameterDefinition().behavior() == QgsProcessingParameterFile.Folder,
- self.parameterDefinition().extension())
- else:
- self.combo = QComboBox()
- self.combo.setEditable(True)
- files = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFile, (QgsProcessingOutputRasterLayer, QgsProcessingOutputVectorLayer, QgsProcessingOutputMapLayer, QgsProcessingOutputFile, QgsProcessingOutputString))
- for f in files:
- self.combo.addItem(self.dialog.resolveValueDescription(f), f)
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combo.setEditText("")
- widget = QWidget()
- layout = QHBoxLayout()
- layout.setMargin(0)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(6)
- layout.addWidget(self.combo)
- btn = QToolButton()
- btn.setText('…')
- btn.setToolTip(self.tr("Select file"))
- btn.clicked.connect(self.selectFile)
- layout.addWidget(btn)
- widget.setLayout(layout)
- return widget
- def selectFile(self):
- settings = QgsSettings()
- if os.path.isdir(os.path.dirname(self.combo.currentText())):
- path = os.path.dirname(self.combo.currentText())
- if settings.contains('/Processing/LastInputPath'):
- path = settings.value('/Processing/LastInputPath')
- else:
- path = ''
- if self.parameterDefinition().extension():
- filter = self.tr('{} files').format(
- self.parameterDefinition().extension().upper()) + ' (*.' + self.parameterDefinition().extension() + self.tr(
- ');;All files (*.*)')
- else:
- filter = self.tr('All files (*.*)')
- filename, selected_filter = QFileDialog.getOpenFileName(self.widget,
- self.tr('Select File'), path,
- filter)
- if filename:
- self.combo.setEditText(filename)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.widget.setText(value)
- else:
- self.setComboValue(value, combobox=self.combo)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return self.widget.getValue()
- else:
- return self.comboValue(combobox=self.combo)
- class FixedTableWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("FixedTableWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return FixedTablePanel(self.parameterDefinition())
- else:
- self.combobox = QComboBox()
- values = self.dialog.getAvailableValuesOfType(QgsProcessingParameterMatrix)
- for v in values:
- self.combobox.addItem(self.dialog.resolveValueDescription(v), v)
- return self.combobox
- def setValue(self, value):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.widget.setValue(value)
- else:
- self.setComboValue(value, combobox=self.combobox)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- return self.widget.table
- else:
- return self.comboValue(combobox=self.combobox)
- class MultipleLayerWidgetWrapper(WidgetWrapper):
- def _getOptions(self):
- if self.parameterDefinition().layerType() == QgsProcessing.TypeVectorAnyGeometry:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeVector:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers],
- [QgsProcessing.TypeVector])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeVectorPoint:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers],
- [QgsProcessing.TypeVectorPoint,
- QgsProcessing.TypeVectorAnyGeometry])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeVectorLine:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers],
- [QgsProcessing.TypeVectorLine,
- QgsProcessing.TypeVectorAnyGeometry])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeVectorPolygon:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers],
- [QgsProcessing.TypeVectorPolygon,
- QgsProcessing.TypeVectorAnyGeometry])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeRaster:
- options = self.dialog.getAvailableValuesOfType(
- (QgsProcessingParameterRasterLayer, QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputRasterLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMesh:
- options = self.dialog.getAvailableValuesOfType(
- (QgsProcessingParameterMeshLayer, QgsProcessingParameterMultipleLayers),
- [])
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMapLayer:
- options = self.dialog.getAvailableValuesOfType((QgsProcessingParameterRasterLayer,
- QgsProcessingParameterFeatureSource,
- QgsProcessingParameterVectorLayer,
- QgsProcessingParameterMeshLayer,
- QgsProcessingParameterMultipleLayers),
- [QgsProcessingOutputRasterLayer,
- QgsProcessingOutputVectorLayer,
- QgsProcessingOutputMapLayer,
- QgsProcessingOutputMultipleLayers])
- else:
- options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFile, QgsProcessingOutputFile)
- options = sorted(options, key=lambda opt: self.dialog.resolveValueDescription(opt))
- return options
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- if self.parameterDefinition().layerType() == QgsProcessing.TypeFile:
- return MultipleInputPanel(datatype=QgsProcessing.TypeFile)
- else:
- if self.parameterDefinition().layerType() == QgsProcessing.TypeRaster:
- options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMesh:
- options = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() in (QgsProcessing.TypeVectorAnyGeometry, QgsProcessing.TypeVector):
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMapLayer:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- options.extend(QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False))
- options.extend(QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False))
- else:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.parameterDefinition().layerType()],
- False)
- opts = [getExtendedLayerName(opt) for opt in options]
- return MultipleInputPanel(opts, datatype=self.parameterDefinition().layerType())
- elif self.dialogType == DIALOG_BATCH:
- widget = BatchInputSelectionPanel(self.parameterDefinition(), self.row, self.col, self.dialog)
- widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- options = [self.dialog.resolveValueDescription(opt) for opt in self._getOptions()]
- return MultipleInputPanel(options, datatype=self.parameterDefinition().layerType())
- def refresh(self):
- if self.parameterDefinition().layerType() != QgsProcessing.TypeFile:
- if self.parameterDefinition().layerType() == QgsProcessing.TypeRaster:
- options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMesh:
- options = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() in (QgsProcessing.TypeVectorAnyGeometry, QgsProcessing.TypeVector):
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMapLayer:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- options.extend(QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False))
- options.extend(QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False))
- else:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.parameterDefinition().layerType()],
- False)
- opts = [getExtendedLayerName(opt) for opt in options]
- self.widget.updateForOptions(opts)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- pass # TODO
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.setValue(value)
- else:
- options = self._getOptions()
- if not isinstance(value, (tuple, list)):
- value = [value]
- selected_options = []
- for sel in value:
- if sel in options:
- selected_options.append(options.index(sel))
- elif isinstance(sel, QgsProcessingModelChildParameterSource):
- selected_options.append(sel.staticValue())
- else:
- selected_options.append(sel)
- self.widget.setSelectedItems(selected_options)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- if self.parameterDefinition().layerType() == QgsProcessing.TypeFile:
- return self.widget.selectedoptions
- else:
- if self.parameterDefinition().layerType() == QgsProcessing.TypeRaster:
- options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMesh:
- options = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False)
- elif self.parameterDefinition().layerType() in (QgsProcessing.TypeVectorAnyGeometry, QgsProcessing.TypeVector):
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- elif self.parameterDefinition().layerType() == QgsProcessing.TypeMapLayer:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
- options.extend(QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False))
- options.extend(QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance(), False))
- else:
- options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.parameterDefinition().layerType()],
- False)
- return [options[i] if isinstance(i, int) else i for i in self.widget.selectedoptions]
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.getValue()
- else:
- options = self._getOptions()
- values = [options[i] if isinstance(i, int) else QgsProcessingModelChildParameterSource.fromStaticValue(i)
- for i in self.widget.selectedoptions]
- if len(values) == 0 and not self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- raise InvalidParameterValue()
- return values
- class NumberWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("NumberWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- widget = NumberInputPanel(self.parameterDefinition())
- widget.hasChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- return ModelerNumberInputPanel(self.parameterDefinition(), self.dialog)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- self.widget.setValue(value)
- def value(self):
- return self.widget.getValue()
- def postInitialize(self, wrappers):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH) and self.parameterDefinition().isDynamic():
- for wrapper in wrappers:
- if wrapper.parameterDefinition().name() == self.parameterDefinition().dynamicLayerParameterName():
- self.widget.setDynamicLayer(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
- break
- def parentLayerChanged(self, wrapper):
- self.widget.setDynamicLayer(wrapper.parameterValue())
- class DistanceWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("DistanceWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- widget = DistanceInputPanel(self.parameterDefinition())
- widget.hasChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- return ModelerNumberInputPanel(self.parameterDefinition(), self.dialog)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- self.widget.setValue(value)
- def value(self):
- return self.widget.getValue()
- def postInitialize(self, wrappers):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- for wrapper in wrappers:
- if wrapper.parameterDefinition().name() == self.parameterDefinition().dynamicLayerParameterName():
- self.widget.setDynamicLayer(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.dynamicLayerChanged)
- if wrapper.parameterDefinition().name() == self.parameterDefinition().parentParameterName():
- self.widget.setUnitParameterValue(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.parentParameterChanged)
- def dynamicLayerChanged(self, wrapper):
- self.widget.setDynamicLayer(wrapper.parameterValue())
- def parentParameterChanged(self, wrapper):
- self.widget.setUnitParameterValue(wrapper.parameterValue())
- class RangeWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("RangeWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- widget = RangePanel(self.parameterDefinition())
- widget.hasChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- def setValue(self, value):
- if value is None or value == NULL:
- return
- self.widget.setValue(value)
- def value(self):
- return self.widget.getValue()
- class MapLayerWidgetWrapper(WidgetWrapper):
- NOT_SELECTED = '[Not selected]'
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("MapLayerWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- self.combo = QgsProcessingMapLayerComboBox(self.parameterDefinition())
- self.context = dataobjects.createContext()
- try:
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combo.setValue(self.parameterDefinition().defaultValue(), self.context)
- else:
- if self.parameterDefinition().defaultValue():
- self.combo.setValue(self.parameterDefinition().defaultValue(), self.context)
- else:
- self.combo.setLayer(iface.activeLayer())
- except:
- pass
- self.combo.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return self.combo
- elif self.dialogType == DIALOG_BATCH:
- widget = BatchInputSelectionPanel(self.parameterDefinition(), self.row, self.col, self.dialog)
- widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- self.combo = QComboBox()
- layers = self.getAvailableLayers()
- self.combo.setEditable(True)
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combo.addItem(self.NOT_SELECTED, self.NOT_SET_OPTION)
- for layer in layers:
- self.combo.addItem(self.dialog.resolveValueDescription(layer), layer)
- widget = QWidget()
- layout = QHBoxLayout()
- layout.setMargin(0)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(6)
- layout.addWidget(self.combo)
- btn = QToolButton()
- btn.setText('…')
- btn.setToolTip(self.tr("Select file"))
- btn.clicked.connect(self.selectFile)
- layout.addWidget(btn)
- widget.setLayout(layout)
- return widget
- def getAvailableLayers(self):
- return self.dialog.getAvailableValuesOfType(
- [QgsProcessingParameterRasterLayer, QgsProcessingParameterMeshLayer, QgsProcessingParameterVectorLayer, QgsProcessingParameterMapLayer, QgsProcessingParameterString],
- [QgsProcessingOutputRasterLayer, QgsProcessingOutputVectorLayer, QgsProcessingOutputMapLayer, QgsProcessingOutputString, QgsProcessingOutputFile])
- def selectFile(self):
- filename, selected_filter = self.getFileName(self.combo.currentText())
- if filename:
- if isinstance(self.combo, QgsProcessingMapLayerComboBox):
- self.combo.setValue(filename, self.context)
- elif isinstance(self.combo, QgsMapLayerComboBox):
- items = self.combo.additionalItems()
- items.append(filename)
- self.combo.setAdditionalItems(items)
- self.combo.setCurrentIndex(self.combo.findText(filename))
- else:
- self.combo.setEditText(filename)
- self.widgetValueHasChanged.emit(self)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- if isinstance(value, str):
- layer = QgsProject.instance().mapLayer(value)
- if layer is not None:
- value = layer
- self.combo.setValue(value, self.context)
- elif self.dialogType == DIALOG_BATCH:
- self.widget.setValue(value)
- else:
- self.setComboValue(value, combobox=self.combo)
- self.widgetValueHasChanged.emit(self)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- return self.combo.value()
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.getValue()
- else:
- def validator(v):
- if not bool(v):
- return self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- else:
- return os.path.exists(v)
- return self.comboValue(validator, combobox=self.combo)
- class RasterWidgetWrapper(MapLayerWidgetWrapper):
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("RasterWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- def getAvailableLayers(self):
- return self.dialog.getAvailableValuesOfType((QgsProcessingParameterRasterLayer, QgsProcessingParameterString),
- (QgsProcessingOutputRasterLayer, QgsProcessingOutputFile, QgsProcessingOutputString))
- def selectFile(self):
- filename, selected_filter = self.getFileName(self.combo.currentText())
- if filename:
- filename = dataobjects.getRasterSublayer(filename, self.parameterDefinition())
- if isinstance(self.combo, QgsProcessingMapLayerComboBox):
- self.combo.setValue(filename, self.context)
- elif isinstance(self.combo, QgsMapLayerComboBox):
- items = self.combo.additionalItems()
- items.append(filename)
- self.combo.setAdditionalItems(items)
- self.combo.setCurrentIndex(self.combo.findText(filename))
- else:
- self.combo.setEditText(filename)
- self.widgetValueHasChanged.emit(self)
- class MeshWidgetWrapper(MapLayerWidgetWrapper):
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("MeshWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- def getAvailableLayers(self):
- return self.dialog.getAvailableValuesOfType((QgsProcessingParameterMeshLayer, QgsProcessingParameterString),
- ())
- def selectFile(self):
- filename, selected_filter = self.getFileName(self.combo.currentText())
- if filename:
- if isinstance(self.combo, QgsProcessingMapLayerComboBox):
- self.combo.setValue(filename, self.context)
- elif isinstance(self.combo, QgsMapLayerComboBox):
- items = self.combo.additionalItems()
- items.append(filename)
- self.combo.setAdditionalItems(items)
- self.combo.setCurrentIndex(self.combo.findText(filename))
- else:
- self.combo.setEditText(filename)
- self.widgetValueHasChanged.emit(self)
- class EnumWidgetWrapper(WidgetWrapper):
- NOT_SELECTED = '[Not selected]'
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("EnumWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self, useCheckBoxes=False, columns=1):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self._useCheckBoxes = useCheckBoxes
- if self._useCheckBoxes and not self.dialogType == DIALOG_BATCH:
- return CheckboxesPanel(options=self.parameterDefinition().options(),
- multiple=self.parameterDefinition().allowMultiple(),
- columns=columns)
- if self.parameterDefinition().allowMultiple():
- return MultipleInputPanel(options=self.parameterDefinition().options())
- else:
- widget = QComboBox()
- for i, option in enumerate(self.parameterDefinition().options()):
- widget.addItem(option, i)
- if self.parameterDefinition().defaultValue():
- widget.setCurrentIndex(widget.findData(self.parameterDefinition().defaultValue()))
- return widget
- else:
- self.combobox = QComboBox()
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combobox.addItem(self.NOT_SELECTED, self.NOT_SET_OPTION)
- for i, option in enumerate(self.parameterDefinition().options()):
- self.combobox.addItem(option, i)
- values = self.dialog.getAvailableValuesOfType(QgsProcessingParameterEnum)
- for v in values:
- self.combobox.addItem(self.dialog.resolveValueDescription(v), v)
- return self.combobox
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self._useCheckBoxes and not self.dialogType == DIALOG_BATCH:
- self.widget.setValue(value)
- return
- if self.parameterDefinition().allowMultiple():
- self.widget.setSelectedItems(value)
- else:
- self.widget.setCurrentIndex(self.widget.findData(value))
- else:
- self.setComboValue(value, combobox=self.combobox)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self._useCheckBoxes and not self.dialogType == DIALOG_BATCH:
- return self.widget.value()
- if self.parameterDefinition().allowMultiple():
- return self.widget.selectedoptions
- else:
- return self.widget.currentData()
- else:
- return self.comboValue(combobox=self.combobox)
- class FeatureSourceWidgetWrapper(WidgetWrapper):
- NOT_SELECTED = '[Not selected]'
- def __init__(self, *args, **kwargs):
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("FeatureSourceWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- self.map_layer_combo = None
- super().__init__(*args, **kwargs)
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- self.map_layer_combo = QgsProcessingMapLayerComboBox(self.parameterDefinition())
- self.context = dataobjects.createContext()
- try:
- if iface.activeLayer().type() == QgsMapLayerType.VectorLayer:
- self.map_layer_combo.setLayer(iface.activeLayer())
- except:
- pass
- self.map_layer_combo.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return self.map_layer_combo
- elif self.dialogType == DIALOG_BATCH:
- widget = BatchInputSelectionPanel(self.parameterDefinition(), self.row, self.col, self.dialog)
- widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- self.combo = QComboBox()
- layers = self.dialog.getAvailableValuesOfType(
- (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer),
- (QgsProcessingOutputVectorLayer, QgsProcessingOutputMapLayer, QgsProcessingOutputString, QgsProcessingOutputFile), self.parameterDefinition().dataTypes())
- self.combo.setEditable(True)
- for layer in layers:
- self.combo.addItem(self.dialog.resolveValueDescription(layer), layer)
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combo.setEditText("")
- widget = QWidget()
- layout = QHBoxLayout()
- layout.setMargin(0)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(2)
- layout.addWidget(self.combo)
- btn = QToolButton()
- btn.setText('…')
- btn.setToolTip(self.tr("Select file"))
- btn.clicked.connect(self.selectFile)
- layout.addWidget(btn)
- widget.setLayout(layout)
- return widget
- def setWidgetContext(self, context):
- if self.map_layer_combo:
- self.map_layer_combo.setWidgetContext(context)
- super().setWidgetContext(context)
- def selectFile(self):
- filename, selected_filter = self.getFileName(self.combo.currentText())
- if filename:
- if isinstance(self.combo, QgsProcessingMapLayerComboBox):
- self.combo.setValue(filename, self.context)
- elif isinstance(self.combo, QgsMapLayerComboBox):
- items = self.combo.additionalItems()
- items.append(filename)
- self.combo.setAdditionalItems(items)
- self.combo.setCurrentIndex(self.combo.findText(filename))
- else:
- self.combo.setEditText(filename)
- self.widgetValueHasChanged.emit(self)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- if isinstance(value, str):
- layer = QgsProject.instance().mapLayer(value)
- if layer is not None:
- value = layer
- self.map_layer_combo.setValue(value, self.context)
- elif self.dialogType == DIALOG_BATCH:
- self.widget.setValue(value)
- else:
- self.setComboValue(value, combobox=self.combo)
- self.widgetValueHasChanged.emit(self)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- return self.map_layer_combo.value()
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.getValue()
- else:
- def validator(v):
- if not bool(v):
- return self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- else:
- return os.path.exists(v)
- if self.combo.currentText():
- return self.comboValue(validator, combobox=self.combo)
- else:
- return None
- class StringWidgetWrapper(WidgetWrapper):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("StringWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- if self.parameterDefinition().multiLine():
- widget = QPlainTextEdit()
- else:
- self._lineedit = QLineEdit()
- widget = self._lineedit
- elif self.dialogType == DIALOG_BATCH:
- widget = QLineEdit()
- else:
- # strings, numbers, files and table fields are all allowed input types
- strings = self.dialog.getAvailableValuesOfType(
- [QgsProcessingParameterString, QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterFile,
- QgsProcessingParameterField, QgsProcessingParameterExpression],
- [QgsProcessingOutputString, QgsProcessingOutputFile])
- options = [(self.dialog.resolveValueDescription(s), s) for s in strings]
- if self.parameterDefinition().multiLine():
- widget = MultilineTextPanel(options)
- else:
- widget = QComboBox()
- widget.setEditable(True)
- for desc, val in options:
- widget.addItem(desc, val)
- return widget
- def showExpressionsBuilder(self):
- context = dataobjects.createExpressionContext()
- value = self.value()
- if not isinstance(value, str):
- value = ''
- dlg = QgsExpressionBuilderDialog(None, value, self.widget, 'generic', context)
- dlg.setWindowTitle(self.tr('Expression based input'))
- if dlg.exec_() == QDialog.Accepted:
- exp = QgsExpression(dlg.expressionText())
- if not exp.hasParserError():
- if self.dialogType == DIALOG_STANDARD:
- self.setValue(str(exp.evaluate(context)))
- else:
- self.setValue(dlg.expressionText())
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- if self.parameterDefinition().multiLine():
- self.widget.setPlainText(value)
- else:
- self._lineedit.setText(value)
- elif self.dialogType == DIALOG_BATCH:
- self.widget.setText(value)
- else:
- if self.parameterDefinition().multiLine():
- self.widget.setValue(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- if self.parameterDefinition().multiLine():
- text = self.widget.toPlainText()
- else:
- text = self._lineedit.text()
- return text
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.text()
- else:
- if self.parameterDefinition().multiLine():
- value = self.widget.getValue()
- option = self.widget.getOption()
- if option == MultilineTextPanel.USE_TEXT:
- if value == '':
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- return None
- else:
- raise InvalidParameterValue()
- else:
- return value
- else:
- return value
- else:
- def validator(v):
- return bool(v) or self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- return self.comboValue(validator)
- class ExpressionWidgetWrapper(WidgetWrapper):
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.4
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("StringWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- self.context = dataobjects.createContext()
- def createWidget(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().parentLayerParameterName():
- widget = QgsFieldExpressionWidget()
- else:
- widget = QgsExpressionLineEdit()
- if self.parameterDefinition().defaultValue():
- widget.setExpression(self.parameterDefinition().defaultValue())
- else:
- strings = self.dialog.getAvailableValuesOfType(
- [QgsProcessingParameterExpression, QgsProcessingParameterString, QgsProcessingParameterNumber, QgsProcessingParameterDistance],
- (QgsProcessingOutputString, QgsProcessingOutputNumber))
- options = [(self.dialog.resolveValueDescription(s), s) for s in strings]
- widget = QComboBox()
- widget.setEditable(True)
- for desc, val in options:
- widget.addItem(desc, val)
- widget.setEditText(self.parameterDefinition().defaultValue() or "")
- return widget
- def postInitialize(self, wrappers):
- for wrapper in wrappers:
- if wrapper.parameterDefinition().name() == self.parameterDefinition().parentLayerParameterName():
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.setLayer(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
- break
- def parentLayerChanged(self, wrapper):
- self.setLayer(wrapper.parameterValue())
- def setLayer(self, layer):
- if isinstance(layer, QgsProcessingFeatureSourceDefinition):
- layer, ok = layer.source.valueAsString(self.context.expressionContext())
- if isinstance(layer, str):
- layer = QgsProcessingUtils.mapLayerFromString(layer, self.context)
- self.widget.setLayer(layer)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.widget.setExpression(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- try:
- return self.widget.asExpression()
- except:
- return self.widget.expression()
- else:
- def validator(v):
- return bool(v) or self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- return self.comboValue(validator)
- class VectorLayerWidgetWrapper(WidgetWrapper):
- NOT_SELECTED = '[Not selected]'
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("VectorLayerWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- def createWidget(self):
- if self.dialogType == DIALOG_STANDARD:
- self.combo = QgsProcessingMapLayerComboBox(self.parameterDefinition())
- self.context = dataobjects.createContext()
- try:
- if iface.activeLayer().type() == QgsMapLayerType.VectorLayer:
- self.combo.setLayer(iface.activeLayer())
- except:
- pass
- self.combo.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return self.combo
- elif self.dialogType == DIALOG_BATCH:
- widget = BatchInputSelectionPanel(self.parameterDefinition(), self.row, self.col, self.dialog)
- widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- self.combo = QComboBox()
- self.combo.setEditable(True)
- tables = self.dialog.getAvailableValuesOfType((QgsProcessingParameterVectorLayer, QgsProcessingParameterString),
- (QgsProcessingOutputVectorLayer, QgsProcessingOutputMapLayer, QgsProcessingOutputFile, QgsProcessingOutputString))
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- self.combo.addItem(self.NOT_SELECTED, self.NOT_SET_OPTION)
- for table in tables:
- self.combo.addItem(self.dialog.resolveValueDescription(table), table)
- widget = QWidget()
- layout = QHBoxLayout()
- layout.setMargin(0)
- layout.setContentsMargins(0, 0, 0, 0)
- layout.setSpacing(6)
- layout.addWidget(self.combo)
- btn = QToolButton()
- btn.setText('…')
- btn.setToolTip(self.tr("Select file"))
- btn.clicked.connect(self.selectFile)
- layout.addWidget(btn)
- widget.setLayout(layout)
- return widget
- def selectFile(self):
- filename, selected_filter = self.getFileName(self.combo.currentText())
- if filename:
- filename = dataobjects.getRasterSublayer(filename, self.parameterDefinition())
- if isinstance(self.combo, QgsProcessingMapLayerComboBox):
- self.combo.setValue(filename, self.context)
- elif isinstance(self.combo, QgsMapLayerComboBox):
- items = self.combo.additionalItems()
- items.append(filename)
- self.combo.setAdditionalItems(items)
- self.combo.setCurrentIndex(self.combo.findText(filename))
- else:
- self.combo.setEditText(filename)
- self.widgetValueHasChanged.emit(self)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType == DIALOG_STANDARD:
- if isinstance(value, str):
- layer = QgsProject.instance().mapLayer(value)
- if layer is not None:
- value = layer
- self.combo.setValue(value, self.context)
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.setValue(value)
- else:
- self.setComboValue(value, combobox=self.combo)
- self.widgetValueHasChanged.emit(self)
- def value(self):
- if self.dialogType == DIALOG_STANDARD:
- return self.combo.value()
- elif self.dialogType == DIALOG_BATCH:
- return self.widget.getValue()
- else:
- def validator(v):
- return bool(v) or self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- return self.comboValue(validator, combobox=self.combo)
- class TableFieldWidgetWrapper(WidgetWrapper):
- NOT_SET = '[Not set]'
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- super().__init__(param, dialog, row, col, **kwargs)
- """
- .. deprecated:: 3.12
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("TableFieldWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- self.context = dataobjects.createContext()
- def createWidget(self):
- self._layer = None
- self.parent_file_based_layers = {}
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- return MultipleInputPanel(options=[])
- else:
- widget = QgsFieldComboBox()
- widget.setAllowEmptyFieldName(self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional)
- widget.fieldChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- if self.parameterDefinition().dataType() == QgsProcessingParameterField.Numeric:
- widget.setFilters(QgsFieldProxyModel.Numeric)
- elif self.parameterDefinition().dataType() == QgsProcessingParameterField.String:
- widget.setFilters(QgsFieldProxyModel.String)
- elif self.parameterDefinition().dataType() == QgsProcessingParameterField.DateTime:
- widget.setFilters(QgsFieldProxyModel.Date | QgsFieldProxyModel.Time)
- return widget
- else:
- widget = QComboBox()
- widget.setEditable(True)
- fields = self.dialog.getAvailableValuesOfType([QgsProcessingParameterField, QgsProcessingParameterString],
- [QgsProcessingOutputString])
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- widget.addItem(self.NOT_SET, self.NOT_SET_OPTION)
- for f in fields:
- widget.addItem(self.dialog.resolveValueDescription(f), f)
- widget.setToolTip(
- self.tr(
- 'Input parameter, or name of field (separate field names with ; for multiple field parameters)'))
- return widget
- def postInitialize(self, wrappers):
- for wrapper in wrappers:
- if wrapper.parameterDefinition().name() == self.parameterDefinition().parentLayerParameterName():
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.setLayer(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.parentValueChanged)
- break
- def parentValueChanged(self, wrapper):
- value = wrapper.parameterValue()
- if isinstance(value, str) and value in self.parent_file_based_layers:
- self.setLayer(self.parent_file_based_layers[value])
- else:
- self.setLayer(value)
- if isinstance(value, str):
- self.parent_file_based_layers[value] = self._layer
- def setLayer(self, layer):
- if isinstance(layer, QgsProcessingFeatureSourceDefinition):
- layer, ok = layer.source.valueAsString(self.context.expressionContext())
- if isinstance(layer, str):
- if not layer: # empty string
- layer = None
- else:
- layer = QgsProcessingUtils.mapLayerFromString(layer, self.context)
- if not isinstance(layer, QgsVectorLayer) or not layer.isValid():
- self.dialog.messageBar().clearWidgets()
- self.dialog.messageBar().pushMessage("", self.tr("Could not load selected layer/table. Dependent field could not be populated"),
- level=Qgis.Warning, duration=5)
- return
- self._layer = layer
- self.refreshItems()
- if self.parameterDefinition().allowMultiple() and self.parameterDefinition().defaultToAllFields():
- self.setValue(self.getFields())
- def refreshItems(self):
- if self.parameterDefinition().allowMultiple():
- self.widget.updateForOptions(self.getFields())
- else:
- self.widget.setLayer(self._layer)
- self.widget.setCurrentIndex(0)
- if self.parameterDefinition().defaultValue() is not None:
- self.setValue(self.parameterDefinition().defaultValue())
- def getFields(self):
- if self._layer is None:
- return []
- fieldTypes = []
- if self.parameterDefinition().dataType() == QgsProcessingParameterField.String:
- fieldTypes = [QVariant.String]
- elif self.parameterDefinition().dataType() == QgsProcessingParameterField.Numeric:
- fieldTypes = [QVariant.Int, QVariant.Double, QVariant.LongLong,
- QVariant.UInt, QVariant.ULongLong]
- elif self.parameterDefinition().dataType() == QgsProcessingParameterField.DateTime:
- fieldTypes = [QVariant.Date, QVariant.Time, QVariant.DateTime]
- fieldNames = []
- for field in self._layer.fields():
- if not fieldTypes or field.type() in fieldTypes:
- fieldNames.append(str(field.name()))
- return fieldNames
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- options = self.widget.options
- selected = []
- if isinstance(value, str):
- value = value.split(';')
- for v in value:
- for i, opt in enumerate(options):
- if opt == v:
- selected.append(i)
- # case insensitive check - only do if matching case value is not present
- elif v not in options and opt.lower() == v.lower():
- selected.append(i)
- self.widget.setSelectedItems(selected)
- else:
- self.widget.setField(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- return [self.widget.options[i] for i in self.widget.selectedoptions]
- else:
- f = self.widget.currentField()
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional and not f:
- return None
- return f
- else:
- def validator(v):
- return bool(v) or self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- return self.comboValue(validator)
- class BandWidgetWrapper(WidgetWrapper):
- NOT_SET = '[Not set]'
- def __init__(self, param, dialog, row=0, col=0, **kwargs):
- """
- .. deprecated:: 3.14
- Do not use, will be removed in QGIS 4.0
- """
- from warnings import warn
- warn("BandWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)
- super().__init__(param, dialog, row, col, **kwargs)
- self.context = dataobjects.createContext()
- def createWidget(self):
- self._layer = None
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- return MultipleInputPanel(options=[])
- widget = QgsRasterBandComboBox()
- widget.setShowNotSetOption(self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional)
- widget.bandChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
- return widget
- else:
- widget = QComboBox()
- widget.setEditable(True)
- fields = self.dialog.getAvailableValuesOfType([QgsProcessingParameterBand, QgsProcessingParameterDistance, QgsProcessingParameterNumber],
- [QgsProcessingOutputNumber])
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional:
- widget.addItem(self.NOT_SET, self.NOT_SET_OPTION)
- for f in fields:
- widget.addItem(self.dialog.resolveValueDescription(f), f)
- return widget
- def postInitialize(self, wrappers):
- for wrapper in wrappers:
- if wrapper.parameterDefinition().name() == self.parameterDefinition().parentLayerParameterName():
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- self.setLayer(wrapper.parameterValue())
- wrapper.widgetValueHasChanged.connect(self.parentValueChanged)
- break
- def parentValueChanged(self, wrapper):
- self.setLayer(wrapper.parameterValue())
- def setLayer(self, layer):
- if isinstance(layer, QgsProcessingParameterRasterLayer):
- layer, ok = layer.source.valueAsString(self.context.expressionContext())
- if isinstance(layer, str):
- layer = QgsProcessingUtils.mapLayerFromString(layer, self.context)
- self._layer = layer
- self.refreshItems()
- def getBands(self):
- bands = []
- if self._layer is not None:
- provider = self._layer.dataProvider()
- for band in range(1, provider.bandCount() + 1):
- name = provider.generateBandName(band)
- interpretation = provider.colorInterpretationName(band)
- if interpretation != "Undefined":
- name = name + f' ({interpretation})'
- bands.append(name)
- return bands
- def refreshItems(self):
- if self.param.allowMultiple():
- self.widget.setSelectedItems([])
- self.widget.updateForOptions(self.getBands())
- else:
- self.widget.setLayer(self._layer)
- self.widget.setCurrentIndex(0)
- def setValue(self, value):
- if value is None or value == NULL:
- return
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- options = self.widget.options
- selected = []
- if isinstance(value, str):
- value = value.split(';')
- for v in value:
- for i, opt in enumerate(options):
- match = re.search(f'(?:\\A|[^0-9]){v}(?:\\Z|[^0-9]|)', opt)
- if match:
- selected.append(i)
- self.widget.setSelectedItems(selected)
- else:
- self.widget.setBand(value)
- else:
- self.setComboValue(value)
- def value(self):
- if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
- if self.parameterDefinition().allowMultiple():
- bands = []
- for i in self.widget.selectedoptions:
- match = re.search('(?:\\A|[^0-9])([0-9]+)(?:\\Z|[^0-9]|)', self.widget.options[i])
- if match:
- bands.append(match.group(1))
- return bands
- else:
- f = self.widget.currentBand()
- if self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional and not f:
- return None
- return f
- else:
- def validator(v):
- return bool(v) or self.parameterDefinition().flags() & QgsProcessingParameterDefinition.FlagOptional
- return self.comboValue(validator)
- class WidgetWrapperFactory:
- """
- Factory for parameter widget wrappers
- """
- @staticmethod
- def create_wrapper(param, dialog, row=0, col=0):
- wrapper_metadata = param.metadata().get('widget_wrapper', None)
- # VERY messy logic here to avoid breaking 3.0 API which allowed metadata "widget_wrapper" value to be either
- # a string name of a class OR a dict.
- # TODO QGIS 4.0 -- require widget_wrapper to be a dict.
- if wrapper_metadata and (not isinstance(wrapper_metadata, dict) or wrapper_metadata.get('class', None) is not None):
- return WidgetWrapperFactory.create_wrapper_from_metadata(param, dialog, row, col)
- else:
- # try from c++ registry first
- class_type = dialog.__class__.__name__
- if class_type == 'ModelerParametersDialog':
- wrapper = QgsGui.processingGuiRegistry().createModelerParameterWidget(dialog.model,
- dialog.childId,
- param,
- dialog.context)
- else:
- dialog_type = dialogTypes.get(class_type,
- QgsProcessingGui.Standard)
- wrapper = QgsGui.processingGuiRegistry().createParameterWidgetWrapper(param, dialog_type)
- if wrapper is not None:
- wrapper.setDialog(dialog)
- return wrapper
- # fallback to Python registry
- return WidgetWrapperFactory.create_wrapper_from_class(param, dialog, row, col)
- @staticmethod
- def create_wrapper_from_metadata(param, dialog, row=0, col=0):
- wrapper = param.metadata().get('widget_wrapper', None)
- params = {}
- # wrapper metadata should be a dict with class key
- if isinstance(wrapper, dict):
- params = deepcopy(wrapper)
- wrapper = params.pop('class')
- # wrapper metadata should be a class path
- if isinstance(wrapper, str):
- tokens = wrapper.split('.')
- mod = __import__('.'.join(tokens[:-1]), fromlist=[tokens[-1]])
- wrapper = getattr(mod, tokens[-1])
- # or directly a class object
- if isclass(wrapper):
- wrapper = wrapper(param, dialog, row, col, **params)
- # or a wrapper instance
- return wrapper
- @staticmethod
- def create_wrapper_from_class(param, dialog, row=0, col=0):
- wrapper = None
- if param.type() == 'boolean':
- # deprecated, moved to c++
- wrapper = BooleanWidgetWrapper
- elif param.type() == 'crs':
- # deprecated, moved to c++
- wrapper = CrsWidgetWrapper
- elif param.type() == 'extent':
- # deprecated, moved to c++
- wrapper = ExtentWidgetWrapper
- elif param.type() == 'point':
- # deprecated, moved to c++
- wrapper = PointWidgetWrapper
- elif param.type() == 'file':
- # deprecated, moved to c++
- wrapper = FileWidgetWrapper
- elif param.type() == 'multilayer':
- wrapper = MultipleLayerWidgetWrapper
- elif param.type() == 'number':
- # deprecated, moved to c++
- wrapper = NumberWidgetWrapper
- elif param.type() == 'distance':
- # deprecated, moved to c++
- wrapper = DistanceWidgetWrapper
- elif param.type() == 'raster':
- # deprecated, moved to c++
- wrapper = RasterWidgetWrapper
- elif param.type() == 'enum':
- # deprecated, moved to c++
- wrapper = EnumWidgetWrapper
- elif param.type() == 'string':
- # deprecated, moved to c++
- wrapper = StringWidgetWrapper
- elif param.type() == 'expression':
- # deprecated, moved to c++
- wrapper = ExpressionWidgetWrapper
- elif param.type() == 'vector':
- # deprecated, moved to c++
- wrapper = VectorLayerWidgetWrapper
- elif param.type() == 'field':
- # deprecated, moved to c++
- wrapper = TableFieldWidgetWrapper
- elif param.type() == 'source':
- # deprecated, moved to c++
- wrapper = FeatureSourceWidgetWrapper
- elif param.type() == 'band':
- # deprecated, moved to c++
- wrapper = BandWidgetWrapper
- elif param.type() == 'layer':
- # deprecated, moved to c++
- wrapper = MapLayerWidgetWrapper
- elif param.type() == 'range':
- # deprecated, moved to c++
- wrapper = RangeWidgetWrapper
- elif param.type() == 'matrix':
- # deprecated, moved to c++
- wrapper = FixedTableWidgetWrapper
- elif param.type() == 'mesh':
- # deprecated, moved to c++
- wrapper = MeshWidgetWrapper
- else:
- assert False, param.type()
- return wrapper(param, dialog, row, col)
|