Skip to content

Commit

Permalink
[processing] ressurect script execution from editor (work in progress)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Feb 5, 2018
1 parent 53ff800 commit 263702e
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 113 deletions.
Expand Up @@ -47,7 +47,7 @@ def execute(self):
settings = QgsSettings() settings = QgsSettings()
lastDir = settings.value("processing/lastScriptsDir", "") lastDir = settings.value("processing/lastScriptsDir", "")
files, _ = QFileDialog.getOpenFileNames(self.toolbox, files, _ = QFileDialog.getOpenFileNames(self.toolbox,
self.tr("Script file"), self.tr("Add script(s)"),
lastDir, lastDir,
self.tr("Script files (*.py *.PY)")) self.tr("Script files (*.py *.PY)"))
if files: if files:
Expand Down
216 changes: 104 additions & 112 deletions python/plugins/processing/script/ScriptEditorDialog.py
Expand Up @@ -25,30 +25,25 @@


__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'


import codecs
import sys
import json
import os import os
import codecs


from qgis.PyQt import uic from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt, QSize, QByteArray from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtWidgets import (QMessageBox, from qgis.PyQt.QtWidgets import (QMessageBox,
QFileDialog, QFileDialog)
QApplication)


from qgis.gui import QgsGui
from qgis.core import QgsApplication, QgsSettings from qgis.core import QgsApplication, QgsSettings
from qgis.utils import iface, OverrideCursor from qgis.utils import iface, OverrideCursor


from processing.gui.AlgorithmDialog import AlgorithmDialog from processing.gui.AlgorithmDialog import AlgorithmDialog
from processing.gui.HelpEditionDialog import HelpEditionDialog

from processing.script.ScriptAlgorithm import ScriptAlgorithm
from processing.script import ScriptUtils from processing.script import ScriptUtils


pluginPath = os.path.split(os.path.dirname(__file__))[0] pluginPath = os.path.split(os.path.dirname(__file__))[0]
WIDGET, BASE = uic.loadUiType( WIDGET, BASE = uic.loadUiType(
os.path.join(pluginPath, 'ui', 'DlgScriptEditor.ui')) os.path.join(pluginPath, "ui", "DlgScriptEditor.ui"))




class ScriptEditorDialog(BASE, WIDGET): class ScriptEditorDialog(BASE, WIDGET):
Expand All @@ -58,16 +53,14 @@ def __init__(self, filePath=None, parent=None):
super(ScriptEditorDialog, self).__init__(parent) super(ScriptEditorDialog, self).__init__(parent)
self.setupUi(self) self.setupUi(self)


QgsGui.instance().enableAutoGeometryRestore(self)

#~ self.setWindowFlags(Qt.WindowMinimizeButtonHint | #~ self.setWindowFlags(Qt.WindowMinimizeButtonHint |
#~ Qt.WindowMaximizeButtonHint | #~ Qt.WindowMaximizeButtonHint |
#~ Qt.WindowCloseButtonHint) #~ Qt.WindowCloseButtonHint)


self.searchWidget.setVisible(False) self.searchWidget.setVisible(False)


settings = QgsSettings()
self.restoreState(settings.value("/Processing/stateScriptEditor", QByteArray()))
self.restoreGeometry(settings.value("/Processing/geometryScriptEditor", QByteArray()))

self.toolBar.setIconSize(iface.iconSize()) self.toolBar.setIconSize(iface.iconSize())


self.actionOpenScript.setIcon( self.actionOpenScript.setIcon(
Expand Down Expand Up @@ -101,7 +94,7 @@ def __init__(self, filePath=None, parent=None):
self.actionOpenScript.triggered.connect(self.openScript) self.actionOpenScript.triggered.connect(self.openScript)
self.actionSaveScript.triggered.connect(self.save) self.actionSaveScript.triggered.connect(self.save)
self.actionSaveScriptAs.triggered.connect(self.saveAs) self.actionSaveScriptAs.triggered.connect(self.saveAs)
self.actionEditScriptHelp.triggered.connect(self.editHelp) #self.actionEditScriptHelp.triggered.connect(self.editHelp)
self.actionRunScript.triggered.connect(self.runAlgorithm) self.actionRunScript.triggered.connect(self.runAlgorithm)
self.actionCut.triggered.connect(self.editor.cut) self.actionCut.triggered.connect(self.editor.cut)
self.actionCopy.triggered.connect(self.editor.copy) self.actionCopy.triggered.connect(self.editor.copy)
Expand All @@ -120,25 +113,26 @@ def __init__(self, filePath=None, parent=None):
self.filePath = filePath self.filePath = filePath
if self.filePath is not None: if self.filePath is not None:
self._loadFile(self.filePath) self._loadFile(self.filePath)
#self.alg = alg

self.snippets = {}
path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "script", "snippets.py")
with codecs.open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
snippetlines = []
name = None
for line in lines:
if line.startswith("##"):
if snippetlines:
self.snippets[name] = "".join(snippetlines)
name = line[2:]
snippetlines = []
else:
snippetlines.append(line)
if snippetlines:
self.snippets[name] = "".join(snippetlines)


self.needUpdate = False
self.setHasChanged(False)

#self.snippets = {}
#path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "script", "snippets.py")
#with codecs.open(path, "r", encoding="utf-8") as f:
# lines = f.readlines()
#snippetlines = []
#name = None
#for line in lines:
# if line.startswith("##"):
# if snippetlines:
# self.snippets[name] = "".join(snippetlines)
# name = line[2:]
# snippetlines = []
# else:
# snippetlines.append(line)
#if snippetlines:
# self.snippets[name] = "".join(snippetlines)
#if self.snippets: #if self.snippets:
# self.btnSnippets.setVisible(False) # self.btnSnippets.setVisible(False)


Expand All @@ -149,11 +143,6 @@ def __init__(self, filePath=None, parent=None):
#else: #else:
# self.filename = None # self.filename = None


self.update = False
self.help = None

self.setHasChanged(False)

#def showSnippets(self, evt): #def showSnippets(self, evt):
# popupmenu = QMenu() # popupmenu = QMenu()
# for name, snippet in list(self.snippets.items()): # for name, snippet in list(self.snippets.items()):
Expand All @@ -162,57 +151,48 @@ def __init__(self, filePath=None, parent=None):
# popupmenu.addAction(action) # popupmenu.addAction(action)
# popupmenu.exec_(QCursor.pos()) # popupmenu.exec_(QCursor.pos())


def closeEvent(self, evt): def closeEvent(self, event):
if self.hasChanged: if self.hasChanged:
ret = QMessageBox.question(self, self.tr('Unsaved changes'), ret = QMessageBox.question(self,
self.tr('There are unsaved changes in script. Continue?'), self.tr("Unsaved changes"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No self.tr("There are unsaved changes in the script. Continue?"),
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
) )
if ret == QMessageBox.Yes: if ret == QMessageBox.Yes:
self.updateProviders() self.updateProvider()
evt.accept() event.accept()
else: else:
evt.ignore() event.ignore()
else: else:
self.updateProviders() self.updateProvider()
evt.accept() event.accept()

def updateProviders(self):
if self.update:
QgsApplication.processingRegistry().providerById('script').refreshAlgorithms()


def editHelp(self): def updateProvider(self):
#if self.alg is None: if self.needUpdate:
# alg = ScriptAlgorithm(None, self.editor.text()) QgsApplication.processingRegistry().providerById("script").refreshAlgorithms()
#else:
# alg = self.alg
#
#dlg = HelpEditionDialog(alg)
#dlg.exec_()
#if dlg.descriptions:
# self.help = dlg.descriptions
# self.setHasChanged(True)
pass


def openScript(self): def openScript(self):
if self.hasChanged: if self.hasChanged:
ret = QMessageBox.warning(self, ret = QMessageBox.warning(self,
self.tr("Unsaved changes"), self.tr("Unsaved changes"),
self.tr("There are unsaved changes in script. Continue?"), self.tr("There are unsaved changes in the script. Continue?"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if ret == QMessageBox.No: if ret == QMessageBox.No:
return return


scriptDir = ScriptUtils.scriptsFolders()[0] scriptDir = ScriptUtils.scriptsFolders()[0]
filterName = self.tr("Processing scripts (*.py *.PY)") fileName, _ = QFileDialog.getOpenFileName(self,
self.filename, fileFilter = QFileDialog.getOpenFileName( self.tr("Open script"),
self, self.tr("Open script"), scriptDir, filterName) scriptDir,
self.tr("Script files (*.py *.PY)"))


if self.filePath == "": if fileName == "":
return return


with OverrideCursor(Qt.WaitCursor): with OverrideCursor(Qt.WaitCursor):
self._loadFile(self.filePath) self._loadFile(fileName)
self.filePath = fileName


def save(self): def save(self):
self.saveScript(False) self.saveScript(False)
Expand All @@ -221,65 +201,77 @@ def saveAs(self):
self.saveScript(True) self.saveScript(True)


def saveScript(self, saveAs): def saveScript(self, saveAs):
if self.filename is None or saveAs: if self.filePath is None or saveAs:
scriptDir = ScriptUtils.scriptsFolders()[0] scriptDir = ScriptUtils.scriptsFolders()[0]
filterName = self.tr('Python scripts (*.py)') newPath, _ = QFileDialog.getSaveFileName(self,
self.filename, fileFilter = QFileDialog.getSaveFileName( self.tr("Save script"),
self, self.tr('Save script'), scriptDir, filterName) scriptDir,
self.tr("Script files (*.py *.PY)"))


if self.filename: if newPath:
if not self.filename.lower().endswith('.py'): if not newPath.lower().endswith(".py"):
self.filename += '.py' newPath += ".py"


text = self.editor.text() self.filePath = newPath
#if self.alg is not None:
# self.alg.script = text


text = self.editor.text()
try: try:
with codecs.open(self.filePath, 'w', encoding='utf-8') as f: with codecs.open(self.filePath, "w", encoding="utf-8") as f:
f.write(text) f.write(text)
except IOError: except IOError as e:
QMessageBox.warning(self, QMessageBox.warning(self,
self.tr('I/O error'), self.tr("I/O error"),
self.tr('Unable to save edits. Reason:\n{}').format(sys.exc_info()[1]) self.tr("Unable to save edits:\n{}").format(str(e))
) )
return return
self.update = True self.needUpdate = True

# If help strings were defined before saving the script for
# the first time, we do it here
#if self.help:
# with codecs.open(self.filename + '.help', 'w', encoding='utf-8') as f:
# json.dump(self.help, f)
# self.help = None
self.setHasChanged(False) self.setHasChanged(False)
else: #else:
self.filePath = None # self.filePath = None


def setHasChanged(self, hasChanged): def setHasChanged(self, hasChanged):
self.hasChanged = hasChanged self.hasChanged = hasChanged
self.actionSaveScript.setEnabled(hasChanged) self.actionSaveScript.setEnabled(hasChanged)


def runAlgorithm(self): def runAlgorithm(self):
#alg = ScriptAlgorithm(None, script=self.editor.text()) #~ if self.filePath is None or self.hasChanged:
#alg.setProvider(QgsApplication.processingRegistry().providerById('script')) #~ QMessageBox.warning(self,
# #~ self.tr("Unsaved changes"),
#dlg = alg.createCustomParametersWidget(self) #~ self.tr("There are unsaved changes in script. "
#if not dlg: #~ "Please save it and try again.")
# dlg = AlgorithmDialog(alg) #~ )
# #~ return
#canvas = iface.mapCanvas()
#prevMapTool = canvas.mapTool() #~ algName = os.path.splitext(os.path.basename(self.filePath))[0]
# #~ alg = ScriptUtils.loadAlgorithm(algName, self.filePath)
#dlg.show() #~ alg.setProvider(QgsApplication.processingRegistry().providerById("script"))
# #~ print("ALG", alg)
#if canvas.mapTool() != prevMapTool:
# try: d = {}
# canvas.mapTool().reset() #print(globals())
# except: #print(locals())
# pass exec(self.editor.text(), d)
# canvas.setMapTool(prevMapTool) #print(d)
pass #print(d.keys())
#print(d["SpatialIndex"])
alg = d["SpatialIndex"]()
alg.setProvider(QgsApplication.processingRegistry().providerById("script"))

dlg = alg.createCustomParametersWidget(self)
if not dlg:
dlg = AlgorithmDialog(alg)

canvas = iface.mapCanvas()
prevMapTool = canvas.mapTool()

dlg.show()

if canvas.mapTool() != prevMapTool:
try:
canvas.mapTool().reset()
except:
pass
canvas.setMapTool(prevMapTool)


def find(self): def find(self):
textToFind = self.leFindText.text() textToFind = self.leFindText.text()
Expand Down
2 changes: 2 additions & 0 deletions python/plugins/processing/script/ScriptUtils.py
Expand Up @@ -65,6 +65,8 @@ def loadAlgorithm(moduleName, filePath):
spec.loader.exec_module(module) spec.loader.exec_module(module)
for x in dir(module): for x in dir(module):
obj = getattr(module, x) obj = getattr(module, x)
if inspect.isclass(obj):
print(obj)
if inspect.isclass(obj) and issubclass(obj, QgsProcessingAlgorithm) and obj.__name__ == moduleName: if inspect.isclass(obj) and issubclass(obj, QgsProcessingAlgorithm) and obj.__name__ == moduleName:
return obj() return obj()
except ImportError as e: except ImportError as e:
Expand Down

0 comments on commit 263702e

Please sign in to comment.