QGIS/python/plugins/processing/algs/qgis/ui/ExecuteSQLWidget.py
2024-11-29 15:38:02 +01:00

158 lines
5.4 KiB
Python

"""
***************************************************************************
ExecuteSQLWidget.py
---------------------
Date : November 2017
Copyright : (C) 2017 by Paul Blottiere
Email : blottiere dot paul 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__ = "Paul Blottiere"
__date__ = "November 2018"
__copyright__ = "(C) 2018, Paul Blottiere"
import os
from qgis.PyQt import uic
from qgis.core import (
Qgis,
QgsExpressionContextScope,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsExpression,
QgsProcessingModelChildParameterSource,
)
from qgis.gui import QgsFieldExpressionWidget
from processing.gui.wrappers import WidgetWrapper, dialogTypes, DIALOG_MODELER
pluginPath = os.path.dirname(__file__)
WIDGET, BASE = uic.loadUiType(os.path.join(pluginPath, "ExecuteSQLWidgetBase.ui"))
class ExecuteSQLWidget(BASE, WIDGET):
def __init__(self, dialog):
super().__init__(None)
self.setupUi(self)
self.dialog = dialog
self.dialogType = dialogTypes[dialog.__class__.__name__]
self.mExpressionWidget = QgsFieldExpressionWidget()
# add model parameters in context scope if called from modeler
if self.dialogType == DIALOG_MODELER:
strings = dialog.getAvailableValuesOfType(
[QgsProcessingParameterString, QgsProcessingParameterNumber], []
)
model_params = [dialog.resolveValueDescription(s) for s in strings]
scope = QgsExpressionContextScope()
for param in model_params:
var = QgsExpressionContextScope.StaticVariable(param)
scope.addVariable(var)
self.mExpressionWidget.appendScope(scope)
self.mHLayout.insertWidget(0, self.mExpressionWidget)
self.mInsert.clicked.connect(self.insert)
def insert(self):
if self.mExpressionWidget.currentText():
exp = f"[%{self.mExpressionWidget.currentText()}%]"
self.mText.insertPlainText(exp)
def setValue(self, value):
text = value
if self.dialogType == DIALOG_MODELER:
if isinstance(value, list):
for v in value:
if (
isinstance(v, QgsProcessingModelChildParameterSource)
and v.source()
== Qgis.ProcessingModelChildParameterSource.ExpressionText
):
text = v.expressionText()
# replace parameter's name by expression (diverging after model save)
names = QgsExpression.referencedVariables(text)
strings = self.dialog.getAvailableValuesOfType(
[
QgsProcessingParameterString,
QgsProcessingParameterNumber,
],
[],
)
model_params = [
(self.dialog.resolveValueDescription(s), s) for s in strings
]
for k, v in model_params:
if v.parameterName() in names:
text = text.replace(
f"[% @{v.parameterName()} %]", f"[% @{k} %]"
)
self.mText.setPlainText(text)
def value(self):
value = self.mText.toPlainText()
if self.dialogType == DIALOG_MODELER:
expression_values = self._expressionValues(value)
if len(expression_values) > 1:
value = expression_values
return value
def _expressionValues(self, text):
strings = self.dialog.getAvailableValuesOfType(
[QgsProcessingParameterString, QgsProcessingParameterNumber], []
)
model_params = [(self.dialog.resolveValueDescription(s), s) for s in strings]
variables = QgsExpression.referencedVariables(text)
# replace description by parameter's name (diverging after model save)
descriptions = QgsExpression.referencedVariables(text)
for k, v in model_params:
if k in descriptions:
text = text.replace(f"[% @{k} %]", f"[% @{v.parameterName()} %]")
src = QgsProcessingModelChildParameterSource.fromExpressionText(text)
# add parameters currently used by the expression
expression_values = [src]
for k, v in model_params:
if k in variables:
expression_values.append(v)
return expression_values
class ExecuteSQLWidgetWrapper(WidgetWrapper):
def createWidget(self):
return ExecuteSQLWidget(self.dialog)
def setValue(self, value):
self.widget.setValue(value)
def value(self):
return self.widget.value()