Skip to content
Permalink
Browse files
Merge pull request #1446 from volaya/new_modeler
[processing] overhaul of graphical modeler
  • Loading branch information
alexbruy committed Jun 29, 2014
2 parents a2a26c2 + 05cfd69 commit 6def4b60ff57d71d2e4efdeb90f69c92b69dec54
Showing with 1,046 additions and 2,268 deletions.
  1. +0 −2 python/plugins/processing/algs/grass/GrassUtils.py
  2. +0 −2 python/plugins/processing/algs/grass7/Grass7Utils.py
  3. +10 −41 python/plugins/processing/core/Processing.py
  4. +28 −25 python/plugins/processing/gui/HelpEditionDialog.py
  5. +1 −1 python/plugins/processing/gui/MultipleInputPanel.py
  6. +3 −2 python/plugins/processing/gui/ProcessingToolbox.py
  7. +3 −3 python/plugins/processing/gui/ScriptEditorDialog.py
  8. +3 −2 python/plugins/processing/modeler/AddModelFromFileAction.py
  9. +84 −15 python/plugins/processing/modeler/CalculatorModelerAlgorithm.py
  10. +0 −164 python/plugins/processing/modeler/CalculatorModelerParametersDialog.py
  11. +361 −612 python/plugins/processing/modeler/ModelerAlgorithm.py
  12. +6 −12 python/plugins/processing/modeler/ModelerAlgorithmProvider.py
  13. +25 −34 python/plugins/processing/modeler/ModelerArrowItem.py
  14. +122 −82 python/plugins/processing/modeler/ModelerDialog.py
  15. +91 −100 python/plugins/processing/modeler/ModelerGraphicItem.py
  16. +9 −11 python/plugins/processing/modeler/ModelerParameterDefinitionDialog.py
  17. +227 −482 python/plugins/processing/modeler/ModelerParametersDialog.py
  18. +58 −99 python/plugins/processing/modeler/ModelerScene.py
  19. +3 −3 python/plugins/processing/modeler/ModelerUtils.py
  20. +7 −11 python/plugins/processing/modeler/MultilineTextPanel.py
  21. +0 −31 python/plugins/processing/modeler/Providers.py
  22. +0 −126 python/plugins/processing/modeler/SaveAsPythonScriptAction.py
  23. +0 −21 python/plugins/processing/modeler/models/Extract_raster_to_CSV.model
  24. +0 −21 python/plugins/processing/modeler/models/Extract_raster_to_shape.model
  25. +0 −43 python/plugins/processing/modeler/models/contours.model
  26. +0 −20 python/plugins/processing/modeler/models/emptystring.model
  27. +0 −21 python/plugins/processing/modeler/models/fieldautoextent.model
  28. +0 −23 python/plugins/processing/modeler/models/fieldextent.model
  29. +0 −26 python/plugins/processing/modeler/models/modelscript.model
  30. +0 −27 python/plugins/processing/modeler/models/noinputs.model
  31. +0 −39 python/plugins/processing/modeler/models/notinorder.model
  32. +0 −32 python/plugins/processing/modeler/models/numericaloutput.model
  33. +0 −12 python/plugins/processing/modeler/models/optionalfield.model
  34. +0 −29 python/plugins/processing/modeler/models/sagagrass.model
  35. +0 −15 python/plugins/processing/modeler/models/simplemodel.model
  36. +0 −79 python/plugins/processing/modeler/models/watersheds.model
  37. +5 −0 python/plugins/processing/parameters/Parameter.py
@@ -28,7 +28,6 @@
import stat
import shutil
import codecs
import traceback
import subprocess
from qgis.core import QgsApplication
from PyQt4.QtCore import *
@@ -385,7 +384,6 @@ def checkGrassIsInstalled(ignorePreviousState=False):
configured in your system.\nPlease install it before \
running GRASS algorithms.'
except:
s = traceback.format_exc()
return 'Error while checking GRASS installation. GRASS might not \
be correctly configured.\n' + s

@@ -27,7 +27,6 @@

import stat
import shutil
import traceback
import subprocess
from qgis.core import QgsApplication
from PyQt4.QtCore import *
@@ -387,7 +386,6 @@ def checkGrass7IsInstalled(ignorePreviousState=False):
configured in your system.\nPlease install it before \
running GRASS GIS 7 algorithms.'
except:
s = traceback.format_exc()
return 'Error while checking GRASS GIS 7 installation. GRASS GIS 7 might not \
be correctly configured.\n' + s

@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from processing.modeler.ModelerUtils import ModelerUtils

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -41,7 +42,6 @@
from processing.gui.Postprocessing import handleAlgorithmResults
from processing.gui.UnthreadedAlgorithmExecutor import \
UnthreadedAlgorithmExecutor
from processing.modeler.Providers import Providers
from processing.modeler.ModelerAlgorithmProvider import \
ModelerAlgorithmProvider
from processing.modeler.ModelerOnlyAlgorithmProvider import \
@@ -119,8 +119,7 @@ def removeProvider(provider):

@staticmethod
def getProviderFromName(name):
"""Returns the provider with the given name.
"""
"""Returns the provider with the given name."""
for provider in Processing.providers:
if provider.getName() == name:
return provider
@@ -139,8 +138,9 @@ def initialize():
Processing.addProvider(SagaAlgorithmProvider())
Processing.addProvider(GrassAlgorithmProvider())
Processing.addProvider(Grass7AlgorithmProvider())
Processing.addProvider(ScriptAlgorithmProvider())
Processing.addProvider(ScriptAlgorithmProvider())
Processing.addProvider(TauDEMAlgorithmProvider())
Processing.addProvider(ModelerAlgorithmProvider())
Processing.modeler.initializeSettings()

# And initialize
@@ -173,7 +173,8 @@ def updateProviders():

@staticmethod
def addAlgListListener(listener):
"""Listener should implement a algsListHasChanged() method.
"""
Listener should implement a algsListHasChanged() method.
Whenever the list of algorithms changes, that method will be
called for all registered listeners.
@@ -196,33 +197,11 @@ def loadAlgorithms():
algs[alg.commandLineName()] = alg
Processing.algs[provider.getName()] = algs

# This is a special provider, since it depends on others.
# TODO: Fix circular imports, so this provider can be
# incorporated as a normal one.
provider = Processing.modeler
provider.setAlgsList(Processing.algs)
provider.loadAlgorithms()
providerAlgs = provider.algs
algs = {}
for alg in providerAlgs:
algs[alg.commandLineName()] = alg
Processing.algs[provider.getName()] = algs

# And we do it again, in case there are models containing
# models.
# TODO: Improve this
provider.setAlgsList(Processing.algs)
provider.loadAlgorithms()
providerAlgs = provider.algs
algs = {}
for alg in providerAlgs:
algs[alg.commandLineName()] = alg
Processing.algs[provider.getName()] = algs
provs = {}
for provider in Processing.providers:
provs[provider.getName()] = provider
provs[Processing.modeler.getName()] = Processing.modeler
Providers.providers = provs
ModelerUtils.allAlgs = Processing.algs
ModelerUtils.providers = provs

@staticmethod
def loadActions():
@@ -232,11 +211,7 @@ def loadActions():
for action in providerActions:
actions.append(action)
Processing.actions[provider.getName()] = actions

provider = Processing.modeler
actions = list()
for action in provider.actions:
actions.append(action)

Processing.actions[provider.getName()] = actions

@staticmethod
@@ -247,11 +222,6 @@ def loadContextMenuActions():
for action in providerActions:
Processing.contextMenuActions.append(action)

provider = Processing.modeler
providerActions = provider.contextMenuActions
for action in providerActions:
Processing.contextMenuActions.append(action)

@staticmethod
def getAlgorithm(name):
for provider in Processing.algs.values():
@@ -269,8 +239,7 @@ def getAlgorithmFromFullName(name):

@staticmethod
def getObject(uri):
"""Returns the QGIS object identified by the given URI.
"""
"""Returns the QGIS object identified by the given URI."""
return dataobjects.getObjectFromUri(uri)

@staticmethod
@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm


__author__ = 'Victor Olaya'
@@ -44,21 +45,21 @@ class HelpEditionDialog(QDialog, Ui_DlgHelpEdition):

def __init__(self, alg):
QDialog.__init__(self)

self.setupUi(self)

self.alg = alg
self.descriptions = {}
if self.alg.descriptionFile is not None:
helpfile = alg.descriptionFile + '.help'
if os.path.exists(helpfile):
try:
with open(helpfile) as f:
self.descriptions = json.load(f)
except Exception, e:
print e
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "Cannot open help file: " + helpfile)

if isinstance(self.alg, ModelerAlgorithm):
self.descriptions = self.alg.helpContent
else:
if self.alg.descriptionFile is not None:
helpfile = alg.descriptionFile + '.help'
if os.path.exists(helpfile):
try:
with open(helpfile) as f:
self.descriptions = json.load(f)
except Exception, e:
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "Cannot open help file: " + helpfile)

self.currentName = self.ALG_DESC
if self.ALG_DESC in self.descriptions:
self.text.setText(self.descriptions[self.ALG_DESC])
@@ -73,17 +74,20 @@ def reject(self):

def accept(self):
self.descriptions[self.currentName] = unicode(self.text.toPlainText())
if self.alg.descriptionFile is not None:
try:
with open(self.alg.descriptionFile + '.help', 'w') as f:
json.dump(self.descriptions, f)
except Exception, e:
QMessageBox.warning(self, 'Error saving help file',
'Help file could not be saved.\n'
'Check that you have permission to modify the help\n'
'file. You might not have permission if you are \n'
'editing an example model or script, since they \n'
'are stored on the installation folder')
if isinstance(self.alg, ModelerAlgorithm):
self.alg.helpContent = self.descriptions
else:
if self.alg.descriptionFile is not None:
try:
with open(self.alg.descriptionFile + '.help', 'w') as f:
json.dump(self.descriptions, f)
except Exception, e:
QMessageBox.warning(self, 'Error saving help file',
'Help file could not be saved.\n'
'Check that you have permission to modify the help\n'
'file. You might not have permission if you are \n'
'editing an example model or script, since they \n'
'are stored on the installation folder')

QDialog.accept(self)

@@ -126,8 +130,7 @@ def changeItem(self):
item = self.tree.currentItem()
if isinstance(item, TreeDescriptionItem):
if self.currentName:
self.descriptions[self.currentName] = \
unicode(self.text.toPlainText())
self.descriptions[self.currentName] = unicode(self.text.toPlainText())
name = item.name
if name:
self.text.setEnabled(True)
@@ -25,7 +25,7 @@

__revision__ = '$Format:%H$'

from PyQt4 import QtCore, QtGui
from PyQt4 import QtGui
from processing.gui.MultipleInputDialog import MultipleInputDialog


@@ -17,6 +17,7 @@
***************************************************************************
"""


__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
@@ -28,6 +29,7 @@
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.utils import iface
from processing.modeler.ModelerUtils import ModelerUtils
from processing.core.Processing import Processing
from processing.core.ProcessingLog import ProcessingLog
from processing.core.ProcessingConfig import ProcessingConfig
@@ -37,7 +39,6 @@
from processing.gui.ParametersDialog import ParametersDialog
from processing.gui.BatchProcessingDialog import BatchProcessingDialog
from processing.gui.EditRenderingStylesDialog import EditRenderingStylesDialog
from processing.modeler.Providers import Providers

from processing.ui.ui_ProcessingToolbox import Ui_ProcessingToolbox

@@ -259,7 +260,7 @@ def fillTreeUsingCategories(self):
if not ProcessingConfig.getSetting(name):
continue
if providerName in providersToExclude \
or len(Providers.providers[providerName].actions) != 0:
or len(ModelerUtils.providers[providerName].actions) != 0:
continue
algs = provider.values()

@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from processing.modeler.ModelerUtils import ModelerUtils

__author__ = 'Alexander Bruy'
__date__ = 'December 2012'
@@ -38,7 +39,6 @@

from processing.gui.ParametersDialog import ParametersDialog
from processing.gui.HelpEditionDialog import HelpEditionDialog
from processing.modeler.Providers import Providers
from processing.algs.r.RAlgorithm import RAlgorithm
from processing.algs.r.RUtils import RUtils
from processing.script.ScriptAlgorithm import ScriptAlgorithm
@@ -180,10 +180,10 @@ def setHasChanged(self, hasChanged):
def runAlgorithm(self):
if self.algType == self.SCRIPT_PYTHON:
alg = ScriptAlgorithm(None, unicode(self.editor.text()))
alg.provider = Providers.providers['script']
alg.provider = ModelerUtils.providers['script']
if self.algType == self.SCRIPT_R:
alg = RAlgorithm(None, unicode(self.editor.text()))
alg.provider = Providers.providers['r']
alg.provider = ModelerUtils.providers['r']

dlg = alg.getCustomParametersDialog()
if not dlg:
@@ -47,11 +47,12 @@ def execute(self):
'*.model')
if filename:
try:
model = ModelerAlgorithm()
model.openModel(filename)
ModelerAlgorithm.fromJsonFile(filename)
except WrongModelException:
QtGui.QMessageBox.warning(self.toolbox, "Error reading model", "The selected file does not contain a valid model")
return
except:
QtGui.QMessageBox.warning(self.toolbox, "Error reading model", "Cannot read file")
destFilename = os.path.join(ModelerUtils.modelsFolder(), os.path.basename(filename))
shutil.copyfile(filename,destFilename)
self.toolbox.updateProvider('script')

0 comments on commit 6def4b6

Please sign in to comment.