QGIS/python/plugins/processing/modeler/ModelerDialog.py

663 lines
26 KiB
Python
Raw Normal View History

2012-10-04 19:33:47 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
ModelerDialog.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : 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. *
* *
***************************************************************************
"""
2016-09-21 18:24:26 +02:00
from builtins import str
2012-10-04 19:33:47 +02:00
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
2012-10-04 19:33:47 +02:00
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import codecs
import sys
import os
2016-04-29 11:39:26 +02:00
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt, QRectF, QMimeData, QPoint, QPointF, QByteArray, QSize, QSizeF, pyqtSignal
from qgis.PyQt.QtWidgets import QGraphicsView, QTreeWidget, QMessageBox, QFileDialog, QTreeWidgetItem, QSizePolicy, QMainWindow, QShortcut
from qgis.PyQt.QtGui import QIcon, QImage, QPainter, QKeySequence
from qgis.PyQt.QtSvg import QSvgGenerator
from qgis.PyQt.QtPrintSupport import QPrinter
from qgis.core import (QgsApplication,
QgsProcessingAlgorithm,
QgsSettings,
QgsMessageLog,
QgsProcessingUtils)
from qgis.gui import QgsMessageBar
2013-08-12 20:44:27 +02:00
from processing.gui.HelpEditionDialog import HelpEditionDialog
from processing.gui.AlgorithmDialog import AlgorithmDialog
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm, ModelerParameter
2013-08-12 20:44:27 +02:00
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
from processing.modeler.ModelerUtils import ModelerUtils
from processing.modeler.ModelerScene import ModelerScene
from processing.modeler.WrongModelException import WrongModelException
pluginPath = os.path.split(os.path.dirname(__file__))[0]
2015-05-18 21:04:20 +03:00
WIDGET, BASE = uic.loadUiType(
os.path.join(pluginPath, 'ui', 'DlgModeler.ui'))
2015-05-18 21:04:20 +03:00
class ModelerDialog(BASE, WIDGET):
2013-05-01 23:45:20 +02:00
CANVAS_SIZE = 4000
2013-05-01 23:45:20 +02:00
update_model = pyqtSignal()
2012-09-15 18:25:25 +03:00
def __init__(self, alg=None):
2015-05-18 21:04:20 +03:00
super(ModelerDialog, self).__init__(None)
2012-12-01 20:21:42 +02:00
self.setupUi(self)
2014-07-02 07:46:03 +02:00
self.bar = QgsMessageBar()
self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
self.centralWidget().layout().insertWidget(0, self.bar)
try:
self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging)
except:
pass
self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
self.inputsDock.raise_()
self.zoom = 1
2012-12-01 20:21:42 +02:00
2016-05-26 14:43:18 +03:00
self.setWindowFlags(Qt.WindowMinimizeButtonHint |
Qt.WindowMaximizeButtonHint |
Qt.WindowCloseButtonHint)
2015-09-12 12:22:20 +02:00
settings = QgsSettings()
self.restoreState(settings.value("/Processing/stateModeler", QByteArray()))
self.restoreGeometry(settings.value("/Processing/geometryModeler", QByteArray()))
2012-12-01 20:21:42 +02:00
self.scene = ModelerScene(self)
self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
2014-07-02 07:46:03 +02:00
2012-12-01 20:21:42 +02:00
self.view.setScene(self.scene)
self.view.setAcceptDrops(True)
2012-12-01 20:21:42 +02:00
self.view.ensureVisible(0, 0, 10, 10)
def _dragEnterEvent(event):
if event.mimeData().hasText():
event.acceptProposedAction()
else:
event.ignore()
def _dropEvent(event):
if event.mimeData().hasText():
text = event.mimeData().text()
if text in ModelerParameterDefinitionDialog.paramTypes:
self.addInputOfType(text, event.pos())
else:
alg = QgsApplication.processingRegistry().algorithmById(text)
if alg is not None:
self._addAlgorithm(alg.getCopy(), event.pos())
event.accept()
else:
event.ignore()
def _dragMoveEvent(event):
if event.mimeData().hasText():
event.accept()
else:
event.ignore()
def _wheelEvent(event):
self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
settings = QgsSettings()
factor = settings.value('/qgis/zoom_favor', 2.0)
if (event.modifiers() == Qt.ControlModifier):
factor = 1.0 + (factor - 1.0) / 20.0
if event.angleDelta().y() < 0:
factor = 1 / factor
self.view.scale(factor, factor)
self.repaintModel()
2014-07-02 07:46:03 +02:00
def _enterEvent(e):
QGraphicsView.enterEvent(self.view, e)
self.view.viewport().setCursor(Qt.ArrowCursor)
2014-07-02 07:46:03 +02:00
def _mouseReleaseEvent(e):
QGraphicsView.mouseReleaseEvent(self.view, e)
self.view.viewport().setCursor(Qt.ArrowCursor)
2014-07-02 07:46:03 +02:00
def _mousePressEvent(e):
if e.button() == Qt.MidButton:
self.previousMousePos = e.pos()
else:
QGraphicsView.mousePressEvent(self.view, e)
def _mouseMoveEvent(e):
if e.buttons() == Qt.MidButton:
offset = self.previousMousePos - e.pos()
self.previousMousePos = e.pos()
self.view.verticalScrollBar().setValue(self.view.verticalScrollBar().value() + offset.y())
self.view.horizontalScrollBar().setValue(self.view.horizontalScrollBar().value() + offset.x())
else:
QGraphicsView.mouseMoveEvent(self.view, e)
self.view.setDragMode(QGraphicsView.ScrollHandDrag)
self.view.dragEnterEvent = _dragEnterEvent
self.view.dropEvent = _dropEvent
self.view.dragMoveEvent = _dragMoveEvent
self.view.wheelEvent = _wheelEvent
self.view.enterEvent = _enterEvent
self.view.mousePressEvent = _mousePressEvent
self.view.mouseMoveEvent = _mouseMoveEvent
def _mimeDataInput(items):
mimeData = QMimeData()
text = items[0].text(0)
mimeData.setText(text)
return mimeData
self.inputsTree.mimeData = _mimeDataInput
self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
self.inputsTree.setDropIndicatorShown(True)
def _mimeDataAlgorithm(items):
item = items[0]
if isinstance(item, TreeAlgorithmItem):
mimeData = QMimeData()
mimeData.setText(item.alg.id())
return mimeData
self.algorithmTree.mimeData = _mimeDataAlgorithm
self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
self.algorithmTree.setDropIndicatorShown(True)
2012-12-01 20:21:42 +02:00
if hasattr(self.searchBox, 'setPlaceholderText'):
self.searchBox.setPlaceholderText(self.tr('Search...'))
2012-12-01 20:21:42 +02:00
if hasattr(self.textName, 'setPlaceholderText'):
self.textName.setPlaceholderText(self.tr('Enter model name here'))
2012-12-01 20:21:42 +02:00
if hasattr(self.textGroup, 'setPlaceholderText'):
self.textGroup.setPlaceholderText(self.tr('Enter group name here'))
2012-12-01 20:21:42 +02:00
# Connect signals and slots
2012-12-01 20:21:42 +02:00
self.inputsTree.doubleClicked.connect(self.addInput)
self.searchBox.textChanged.connect(self.fillAlgorithmTree)
self.algorithmTree.doubleClicked.connect(self.addAlgorithm)
# Ctrl+= should also trigger a zoom in action
ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
ctrlEquals.activated.connect(self.zoomIn)
try:
iconSize = int(settings.value("iconsize", 24))
except:
iconSize = 24
self.mToolbar.setIconSize(QSize(iconSize, iconSize))
self.mActionOpen.triggered.connect(self.openModel)
self.mActionSave.triggered.connect(self.save)
self.mActionSaveAs.triggered.connect(self.saveAs)
self.mActionZoomIn.triggered.connect(self.zoomIn)
self.mActionZoomOut.triggered.connect(self.zoomOut)
self.mActionZoomActual.triggered.connect(self.zoomActual)
self.mActionZoomToItems.triggered.connect(self.zoomToItems)
self.mActionExportImage.triggered.connect(self.exportAsImage)
self.mActionExportPdf.triggered.connect(self.exportAsPdf)
self.mActionExportSvg.triggered.connect(self.exportAsSvg)
self.mActionExportPython.triggered.connect(self.exportAsPython)
self.mActionEditHelp.triggered.connect(self.editHelp)
self.mActionRun.triggered.connect(self.runModel)
2012-12-01 20:21:42 +02:00
2012-09-15 18:25:25 +03:00
if alg is not None:
self.alg = alg
self.textGroup.setText(alg._group)
self.textName.setText(alg.displayName())
self.repaintModel()
2014-05-21 21:25:18 +02:00
2012-09-15 18:25:25 +03:00
else:
2014-05-21 21:25:18 +02:00
self.alg = ModelerAlgorithm()
self.alg.modelerdialog = self
2012-12-01 20:21:42 +02:00
self.fillInputsTree()
self.fillAlgorithmTree()
self.view.centerOn(0, 0)
2012-09-15 18:25:25 +03:00
self.alg.setModelerView(self)
self.help = None
2014-05-21 21:25:18 +02:00
self.hasChanged = False
2012-09-15 18:25:25 +03:00
def closeEvent(self, evt):
settings = QgsSettings()
settings.setValue("/Processing/stateModeler", self.saveState())
settings.setValue("/Processing/geometryModeler", self.saveGeometry())
2015-09-12 12:22:20 +02:00
if self.hasChanged:
ret = QMessageBox.question(
self, self.tr('Save?'),
self.tr('There are unsaved changes in this model, do you want to keep those?'),
QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard, QMessageBox.Cancel)
if ret == QMessageBox.Save:
self.saveModel(False)
evt.accept()
elif ret == QMessageBox.Discard:
evt.accept()
else:
evt.ignore()
else:
evt.accept()
2012-09-15 18:25:25 +03:00
def editHelp(self):
2015-01-22 12:51:06 +01:00
alg = self.alg.getCopy()
dlg = HelpEditionDialog(alg)
2012-09-15 18:25:25 +03:00
dlg.exec_()
2014-11-23 14:03:32 +01:00
if dlg.descriptions:
self.alg.helpContent = dlg.descriptions
2014-11-23 14:03:32 +01:00
self.hasChanged = True
2012-09-15 18:25:25 +03:00
def runModel(self):
if len(self.alg.algs) == 0:
self.bar.pushMessage("", "Model doesn't contain any algorithm and/or parameter and can't be executed", level=QgsMessageBar.WARNING, duration=5)
return
2017-05-01 17:00:10 +10:00
# hack - remove when above getCopy is removed
provider = self.alg.provider()
alg = self.alg.getCopy()
2017-05-01 17:00:10 +10:00
# hack pt 2
alg.setProvider(provider)
dlg = AlgorithmDialog(alg)
dlg.exec_()
2013-03-31 21:18:27 +02:00
def save(self):
self.saveModel(False)
2013-03-31 21:18:27 +02:00
def saveAs(self):
2013-03-31 21:18:27 +02:00
self.saveModel(True)
def zoomIn(self):
self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
settings = QgsSettings()
factor = settings.value('/qgis/zoom_favor', 2.0)
self.view.scale(factor, factor)
self.view.centerOn(point)
self.repaintModel()
def zoomOut(self):
self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
settings = QgsSettings()
factor = settings.value('/qgis/zoom_favor', 2.0)
factor = 1 / factor
self.view.scale(factor, factor)
self.view.centerOn(point)
self.repaintModel()
def zoomActual(self):
point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
self.view.resetTransform()
self.view.centerOn(point)
def zoomToItems(self):
totalRect = self.scene.itemsBoundingRect()
totalRect.adjust(-10, -10, 10, 10)
self.view.fitInView(totalRect, Qt.KeepAspectRatio)
def exportAsImage(self):
self.repaintModel(controls=False)
filename, fileFilter = QFileDialog.getSaveFileName(self,
self.tr('Save Model As Image'), '',
self.tr('PNG files (*.png *.PNG)'))
if not filename:
return
if not filename.lower().endswith('.png'):
filename += '.png'
totalRect = self.scene.itemsBoundingRect()
totalRect.adjust(-10, -10, 10, 10)
imgRect = QRectF(0, 0, totalRect.width(), totalRect.height())
img = QImage(totalRect.width(), totalRect.height(),
QImage.Format_ARGB32_Premultiplied)
img.fill(Qt.white)
painter = QPainter()
painter.setRenderHint(QPainter.Antialiasing)
painter.begin(img)
self.scene.render(painter, imgRect, totalRect)
painter.end()
img.save(filename)
self.bar.pushMessage("", "Model was correctly exported as image", level=QgsMessageBar.SUCCESS, duration=5)
self.repaintModel(controls=True)
def exportAsPdf(self):
self.repaintModel(controls=False)
filename, fileFilter = QFileDialog.getSaveFileName(self,
self.tr('Save Model As PDF'), '',
2017-01-25 02:19:33 +01:00
self.tr('PDF files (*.pdf *.PDF)'))
if not filename:
return
if not filename.lower().endswith('.pdf'):
filename += '.pdf'
totalRect = self.scene.itemsBoundingRect()
totalRect.adjust(-10, -10, 10, 10)
printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(filename)
printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel)
printer.setFullPage(True)
painter = QPainter(printer)
self.scene.render(painter, printerRect, totalRect)
painter.end()
self.bar.pushMessage("", "Model was correctly exported as PDF", level=QgsMessageBar.SUCCESS, duration=5)
self.repaintModel(controls=True)
def exportAsSvg(self):
self.repaintModel(controls=False)
filename, fileFilter = QFileDialog.getSaveFileName(self,
self.tr('Save Model As SVG'), '',
self.tr('SVG files (*.svg *.SVG)'))
if not filename:
return
if not filename.lower().endswith('.svg'):
filename += '.svg'
totalRect = self.scene.itemsBoundingRect()
totalRect.adjust(-10, -10, 10, 10)
svgRect = QRectF(0, 0, totalRect.width(), totalRect.height())
svg = QSvgGenerator()
svg.setFileName(filename)
svg.setSize(QSize(totalRect.width(), totalRect.height()))
svg.setViewBox(svgRect)
svg.setTitle(self.alg.displayName())
painter = QPainter(svg)
self.scene.render(painter, svgRect, totalRect)
painter.end()
self.bar.pushMessage("", "Model was correctly exported as SVG", level=QgsMessageBar.SUCCESS, duration=5)
self.repaintModel(controls=True)
def exportAsPython(self):
filename, filter = QFileDialog.getSaveFileName(self,
2016-01-08 12:52:19 +01:00
self.tr('Save Model As Python Script'), '',
self.tr('Python files (*.py *.PY)'))
if not filename:
return
if not filename.lower().endswith('.py'):
filename += '.py'
text = self.alg.toPython()
with codecs.open(filename, 'w', encoding='utf-8') as fout:
fout.write(text)
self.bar.pushMessage("", "Model was correctly exported as python script", level=QgsMessageBar.SUCCESS, duration=5)
def saveModel(self, saveAs):
2016-09-21 18:24:26 +02:00
if str(self.textGroup.text()).strip() == '' \
or str(self.textName.text()).strip() == '':
QMessageBox.warning(
self, self.tr('Warning'), self.tr('Please enter group and model names before saving')
)
2012-09-15 18:25:25 +03:00
return
self.alg._name = str(self.textName.text())
self.alg._group = str(self.textGroup.text())
if self.alg.descriptionFile is not None and not saveAs:
2012-09-15 18:25:25 +03:00
filename = self.alg.descriptionFile
else:
filename, filter = QFileDialog.getSaveFileName(self,
2016-01-08 12:52:19 +01:00
self.tr('Save Model'),
ModelerUtils.modelsFolders()[0],
self.tr('Processing models (*.model)'))
2012-09-15 18:25:25 +03:00
if filename:
if not filename.endswith('.model'):
filename += '.model'
2012-09-15 18:25:25 +03:00
self.alg.descriptionFile = filename
if filename:
text = self.alg.toJson()
try:
with codecs.open(filename, 'w', encoding='utf-8') as fout:
fout.write(text)
except:
if saveAs:
QMessageBox.warning(self, self.tr('I/O error'),
2017-03-04 16:23:36 +01:00
self.tr('Unable to save edits. Reason:\n {0}').format(str(sys.exc_info()[1])))
else:
QMessageBox.warning(self, self.tr("Can't save model"),
self.tr("This model can't be saved in its "
"original location (probably you do not "
"have permission to do it). Please, use "
"the 'Save as...' option."))
return
self.update_model.emit()
self.bar.pushMessage("", "Model was correctly saved", level=QgsMessageBar.SUCCESS, duration=5)
self.hasChanged = False
2012-09-15 18:25:25 +03:00
def openModel(self):
2017-02-09 11:05:09 +01:00
filename, selected_filter = QFileDialog.getOpenFileName(self,
self.tr('Open Model'),
ModelerUtils.modelsFolders()[0],
self.tr('Processing models (*.model *.MODEL)'))
2012-09-15 18:25:25 +03:00
if filename:
try:
alg = ModelerAlgorithm.fromFile(filename)
self.alg = alg
2012-09-15 18:25:25 +03:00
self.alg.setModelerView(self)
self.textGroup.setText(alg._group)
self.textName.setText(alg._name)
2012-09-15 18:25:25 +03:00
self.repaintModel()
self.view.centerOn(0, 0)
self.hasChanged = False
except WrongModelException as e:
QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.msg),
self.tr('Processing'),
QgsMessageLog.CRITICAL)
QMessageBox.critical(self, self.tr('Could not open model'),
self.tr('The selected model could not be loaded.\n'
'See the log for more information.'))
except Exception as e:
QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.args[0]),
self.tr('Processing'), QgsMessageLog.CRITICAL)
QMessageBox.critical(self, self.tr('Could not open model'),
self.tr('The selected model could not be loaded.\n'
'See the log for more information.'))
2012-09-15 18:25:25 +03:00
def repaintModel(self, controls=True):
2012-09-15 18:25:25 +03:00
self.scene = ModelerScene()
self.scene.setSceneRect(QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE,
2016-01-08 12:52:19 +01:00
ModelerAlgorithm.CANVAS_SIZE))
self.scene.paintModel(self.alg, controls)
2013-03-31 21:18:27 +02:00
self.view.setScene(self.scene)
2012-09-15 18:25:25 +03:00
def addInput(self):
item = self.inputsTree.currentItem()
2016-09-21 18:24:26 +02:00
paramType = str(item.text(0))
2014-07-02 07:46:03 +02:00
self.addInputOfType(paramType)
def addInputOfType(self, paramType, pos=None):
2012-09-15 18:25:25 +03:00
if paramType in ModelerParameterDefinitionDialog.paramTypes:
dlg = ModelerParameterDefinitionDialog(self.alg, paramType)
dlg.exec_()
if dlg.param is not None:
if pos is None:
pos = self.getPositionForParameterItem()
if isinstance(pos, QPoint):
pos = QPointF(pos)
self.alg.addParameter(ModelerParameter(dlg.param, pos))
2012-09-15 18:25:25 +03:00
self.repaintModel()
# self.view.ensureVisible(self.scene.getLastParameterItem())
self.hasChanged = True
2014-07-02 07:46:03 +02:00
def getPositionForParameterItem(self):
MARGIN = 20
BOX_WIDTH = 200
BOX_HEIGHT = 80
if self.alg.inputs:
2016-09-21 18:24:26 +02:00
maxX = max([i.pos.x() for i in list(self.alg.inputs.values())])
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
else:
newX = MARGIN + BOX_WIDTH / 2
2014-07-02 07:46:03 +02:00
return QPointF(newX, MARGIN + BOX_HEIGHT / 2)
2012-09-15 18:25:25 +03:00
def fillInputsTree(self):
icon = QIcon(os.path.join(pluginPath, 'images', 'input.svg'))
parametersItem = QTreeWidgetItem()
parametersItem.setText(0, self.tr('Parameters'))
2012-09-15 18:25:25 +03:00
for paramType in ModelerParameterDefinitionDialog.paramTypes:
2012-12-01 20:21:42 +02:00
paramItem = QTreeWidgetItem()
2012-09-15 18:25:25 +03:00
paramItem.setText(0, paramType)
paramItem.setIcon(0, icon)
paramItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled)
2012-09-15 18:25:25 +03:00
parametersItem.addChild(paramItem)
self.inputsTree.addTopLevelItem(parametersItem)
parametersItem.setExpanded(True)
def addAlgorithm(self):
item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem):
alg = QgsApplication.processingRegistry().algorithmById(item.alg.id())
self._addAlgorithm(alg.getCopy())
def _addAlgorithm(self, alg, pos=None):
2016-01-08 12:52:19 +01:00
dlg = alg.getCustomModelerParametersDialog(self.alg)
if not dlg:
dlg = ModelerParametersDialog(alg, self.alg)
dlg.exec_()
if dlg.alg is not None:
if pos is None:
dlg.alg.pos = self.getPositionForAlgorithmItem()
else:
dlg.alg.pos = pos
if isinstance(dlg.alg.pos, QPoint):
dlg.alg.pos = QPointF(pos)
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
for i, out in enumerate(dlg.alg.outputs):
2017-03-03 20:44:03 +01:00
dlg.alg.outputs[out].pos = dlg.alg.pos + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
ModelerGraphicItem.BOX_HEIGHT)
2016-01-08 12:52:19 +01:00
self.alg.addAlgorithm(dlg.alg)
self.repaintModel()
self.hasChanged = True
2014-07-02 07:46:03 +02:00
def getPositionForAlgorithmItem(self):
MARGIN = 20
BOX_WIDTH = 200
BOX_HEIGHT = 80
if self.alg.algs:
2016-09-21 18:24:26 +02:00
maxX = max([alg.pos.x() for alg in list(self.alg.algs.values())])
maxY = max([alg.pos.y() for alg in list(self.alg.algs.values())])
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
2017-03-03 20:44:03 +01:00
newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE -
BOX_HEIGHT)
else:
newX = MARGIN + BOX_WIDTH / 2
newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2
return QPointF(newX, newY)
2014-07-02 07:46:03 +02:00
2012-12-10 00:12:07 +01:00
def fillAlgorithmTree(self):
self.fillAlgorithmTreeUsingProviders()
self.algorithmTree.sortItems(0, Qt.AscendingOrder)
2013-02-28 22:08:32 +01:00
2016-09-21 18:24:26 +02:00
text = str(self.searchBox.text())
if text != '':
self.algorithmTree.expandAll()
2016-01-08 10:32:43 +02:00
def fillAlgorithmTreeUsingProviders(self):
self.algorithmTree.clear()
2016-09-21 18:24:26 +02:00
text = str(self.searchBox.text())
search_strings = text.split(' ')
for provider in QgsApplication.processingRegistry().providers():
if not provider.isActive():
continue
2012-09-15 18:25:25 +03:00
groups = {}
# Add algorithms
for alg in provider.algorithms():
if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler:
2012-09-15 18:25:25 +03:00
continue
if alg.id() == self.alg.id():
continue
item_text = [alg.displayName().lower()]
item_text.extend(alg.tags())
show = not search_strings or all(
any(part in t for t in item_text)
for part in search_strings)
if show:
if alg.group() in groups:
groupItem = groups[alg.group()]
2012-09-15 18:25:25 +03:00
else:
2012-12-01 20:21:42 +02:00
groupItem = QTreeWidgetItem()
name = alg.group()
groupItem.setText(0, name)
groupItem.setToolTip(0, name)
groups[alg.group()] = groupItem
2012-09-15 18:25:25 +03:00
algItem = TreeAlgorithmItem(alg)
groupItem.addChild(algItem)
if len(groups) > 0:
2012-12-01 20:21:42 +02:00
providerItem = QTreeWidgetItem()
providerItem.setText(0, provider.name())
providerItem.setToolTip(0, provider.name())
providerItem.setIcon(0, provider.icon())
2016-09-21 18:24:26 +02:00
for groupItem in list(groups.values()):
2012-09-15 18:25:25 +03:00
providerItem.addChild(groupItem)
self.algorithmTree.addTopLevelItem(providerItem)
providerItem.setExpanded(text != '')
2016-09-21 18:24:26 +02:00
for groupItem in list(groups.values()):
if text != '':
2012-09-15 18:25:25 +03:00
groupItem.setExpanded(True)
self.algorithmTree.sortItems(0, Qt.AscendingOrder)
2012-12-01 20:21:42 +02:00
class TreeAlgorithmItem(QTreeWidgetItem):
2012-09-15 18:25:25 +03:00
def __init__(self, alg):
QTreeWidgetItem.__init__(self)
2013-02-28 22:08:32 +01:00
self.alg = alg
icon = alg.icon()
name = alg.displayName()
self.setIcon(0, icon)
self.setToolTip(0, name)
self.setText(0, name)