diff --git a/python/plugins/processing/gui/ContextAction.py b/python/plugins/processing/gui/ContextAction.py index d943a39a0c5..c5eacab9ddd 100644 --- a/python/plugins/processing/gui/ContextAction.py +++ b/python/plugins/processing/gui/ContextAction.py @@ -37,5 +37,5 @@ class ContextAction: def tr(self, string, context=''): if context == '': - context = 'ContextAction' + context = self.__class__.__name__ return QCoreApplication.translate(context, string) diff --git a/python/plugins/processing/gui/ScriptEdit.py b/python/plugins/processing/gui/ScriptEdit.py deleted file mode 100644 index 17d5c100744..00000000000 --- a/python/plugins/processing/gui/ScriptEdit.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - ScriptEdit.py - --------------------- - Date : April 2013 - Copyright : (C) 2013 by Alexander Bruy - Email : alexander dot bruy 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__ = 'Alexander Bruy' -__date__ = 'April 2013' -__copyright__ = '(C) 2013, Alexander Bruy' - -# This will get replaced with a git SHA1 when you do a git archive - -__revision__ = '$Format:%H$' - -import os - -from qgis.PyQt.QtCore import Qt -from qgis.PyQt.QtGui import QFont, QColor, QKeySequence -from qgis.PyQt.QtWidgets import QShortcut -from qgis.core import QgsApplication, QgsSettings - -from qgis.PyQt.Qsci import QsciScintilla, QsciLexerPython, QsciAPIs - - -class ScriptEdit(QsciScintilla): - - LEXER_PYTHON = 0 - LEXER_R = 1 - - def __init__(self, parent=None): - QsciScintilla.__init__(self, parent) - - self.lexer = None - self.api = None - self.lexerType = -1 - - self.setCommonOptions() - self.initShortcuts() - - def setCommonOptions(self): - # Enable non-ASCII characters - self.setUtf8(True) - - # Default font - font = QFont() - font.setFamily('Courier') - font.setFixedPitch(True) - font.setPointSize(20) - self.setFont(font) - self.setMarginsFont(font) - - self.initLexer() - - self.setBraceMatching(QsciScintilla.SloppyBraceMatch) - - self.setWrapMode(QsciScintilla.WrapWord) - self.setWrapVisualFlags(QsciScintilla.WrapFlagByText, - QsciScintilla.WrapFlagNone, 4) - - self.setSelectionForegroundColor(QColor('#2e3436')) - self.setSelectionBackgroundColor(QColor('#babdb6')) - - # Show line numbers - self.setMarginWidth(1, '000') - self.setMarginLineNumbers(1, True) - self.setMarginsForegroundColor(QColor('#2e3436')) - self.setMarginsBackgroundColor(QColor('#babdb6')) - - # Highlight current line - self.setCaretLineVisible(True) - self.setCaretLineBackgroundColor(QColor('#d3d7cf')) - - # Folding - self.setFolding(QsciScintilla.BoxedTreeFoldStyle) - self.setFoldMarginColors(QColor('#d3d7cf'), QColor('#d3d7cf')) - - # Mark column 80 with vertical line - self.setEdgeMode(QsciScintilla.EdgeLine) - self.setEdgeColumn(80) - self.setEdgeColor(QColor('#eeeeec')) - - # Indentation - self.setAutoIndent(True) - self.setIndentationsUseTabs(False) - self.setIndentationWidth(4) - self.setTabIndents(True) - self.setBackspaceUnindents(True) - self.setTabWidth(4) - - # Autocomletion - self.setAutoCompletionThreshold(2) - self.setAutoCompletionSource(QsciScintilla.AcsAPIs) - - self.setFonts(10) - - def setFonts(self, size): - - # Load font from Python console settings - settings = QgsSettings() - fontName = settings.value('pythonConsole/fontfamilytext', 'Monospace') - fontSize = int(settings.value('pythonConsole/fontsize', size)) - - self.defaultFont = QFont(fontName) - self.defaultFont.setFixedPitch(True) - self.defaultFont.setPointSize(fontSize) - self.defaultFont.setStyleHint(QFont.TypeWriter) - self.defaultFont.setStretch(QFont.SemiCondensed) - self.defaultFont.setLetterSpacing(QFont.PercentageSpacing, 87.0) - self.defaultFont.setBold(False) - - self.boldFont = QFont(self.defaultFont) - self.boldFont.setBold(True) - - self.italicFont = QFont(self.defaultFont) - self.italicFont.setItalic(True) - - self.setFont(self.defaultFont) - self.setMarginsFont(self.defaultFont) - - def initShortcuts(self): - (ctrl, shift) = (self.SCMOD_CTRL << 16, self.SCMOD_SHIFT << 16) - - # Disable some shortcuts - self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord('D') + ctrl) - self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord('L') + ctrl) - self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord('L') + ctrl + - shift) - self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord('T') + ctrl) - - # self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord("Z") + ctrl) - # self.SendScintilla(QsciScintilla.SCI_CLEARCMDKEY, ord("Y") + ctrl) - - # Use Ctrl+Space for autocompletion - self.shortcutAutocomplete = QShortcut(QKeySequence(Qt.CTRL + - Qt.Key_Space), self) - self.shortcutAutocomplete.setContext(Qt.WidgetShortcut) - self.shortcutAutocomplete.activated.connect(self.autoComplete) - - def autoComplete(self): - self.autoCompleteFromAll() - - def setLexerType(self, lexerType): - self.lexerType = lexerType - self.initLexer() - - def initLexer(self): - if self.lexerType == self.LEXER_PYTHON: - self.lexer = QsciLexerPython() - - colorDefault = QColor('#2e3436') - colorComment = QColor('#c00') - colorCommentBlock = QColor('#3465a4') - colorNumber = QColor('#4e9a06') - colorType = QColor('#4e9a06') - colorKeyword = QColor('#204a87') - colorString = QColor('#ce5c00') - - self.lexer.setDefaultFont(self.defaultFont) - self.lexer.setDefaultColor(colorDefault) - - self.lexer.setColor(colorComment, 1) - self.lexer.setColor(colorNumber, 2) - self.lexer.setColor(colorString, 3) - self.lexer.setColor(colorString, 4) - self.lexer.setColor(colorKeyword, 5) - self.lexer.setColor(colorString, 6) - self.lexer.setColor(colorString, 7) - self.lexer.setColor(colorType, 8) - self.lexer.setColor(colorCommentBlock, 12) - self.lexer.setColor(colorString, 15) - - self.lexer.setFont(self.italicFont, 1) - self.lexer.setFont(self.boldFont, 5) - self.lexer.setFont(self.boldFont, 8) - self.lexer.setFont(self.italicFont, 12) - - self.api = QsciAPIs(self.lexer) - - settings = QgsSettings() - useDefaultAPI = bool(settings.value('pythonConsole/preloadAPI', - True)) - if useDefaultAPI: - # Load QGIS API shipped with Python console - self.api.loadPrepared( - os.path.join(QgsApplication.pkgDataPath(), - 'python', 'qsci_apis', 'pyqgis.pap')) - else: - # Load user-defined API files - apiPaths = settings.value('pythonConsole/userAPI', []) - for path in apiPaths: - self.api.load(path) - self.api.prepare() - self.lexer.setAPIs(self.api) - - self.setLexer(self.lexer) diff --git a/python/plugins/processing/script/AddScriptFromFileAction.py b/python/plugins/processing/script/AddScriptFromFileAction.py index ab6bc81d319..011cf054925 100644 --- a/python/plugins/processing/script/AddScriptFromFileAction.py +++ b/python/plugins/processing/script/AddScriptFromFileAction.py @@ -32,8 +32,9 @@ from qgis.PyQt.QtCore import QFileInfo from qgis.core import QgsApplication, QgsSettings -from processing.script.ScriptAlgorithm import ScriptAlgorithm from processing.gui.ToolboxAction import ToolboxAction + +from processing.script.ScriptAlgorithm import ScriptAlgorithm from processing.script.WrongScriptException import WrongScriptException from processing.script.ScriptUtils import ScriptUtils @@ -53,8 +54,9 @@ class AddScriptFromFileAction(ToolboxAction): settings = QgsSettings() lastDir = settings.value('Processing/lastScriptsDir', '') filenames, selected_filter = QFileDialog.getOpenFileNames(self.toolbox, - self.tr('Script files', 'AddScriptFromFileAction'), lastDir, - self.tr('Script files (*.py *.PY)', 'AddScriptFromFileAction')) + self.tr('Script files'), + lastDir, + self.tr('Script files (*.py *.PY)')) if filenames: validAlgs = 0 wrongAlgs = [] @@ -73,6 +75,6 @@ class AddScriptFromFileAction(ToolboxAction): QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() if wrongAlgs: QMessageBox.warning(self.toolbox, - self.tr('Error reading scripts', 'AddScriptFromFileAction'), - self.tr('The following files do not contain a valid script:\n-', 'AddScriptFromFileAction') + - "\n-".join(wrongAlgs)) + self.tr('Error reading scripts'), + self.tr('The following files do not contain a valid script:\n') + + "\n- ".join(wrongAlgs)) diff --git a/python/plugins/processing/gui/CreateNewScriptAction.py b/python/plugins/processing/script/CreateNewScriptAction.py similarity index 77% rename from python/plugins/processing/gui/CreateNewScriptAction.py rename to python/plugins/processing/script/CreateNewScriptAction.py index d3950e53c1d..b438efe4768 100644 --- a/python/plugins/processing/gui/CreateNewScriptAction.py +++ b/python/plugins/processing/script/CreateNewScriptAction.py @@ -30,27 +30,20 @@ import os from qgis.core import QgsApplication from processing.gui.ToolboxAction import ToolboxAction -from processing.gui.ScriptEditorDialog import ScriptEditorDialog + +from processing.script.ScriptEditorDialog import ScriptEditorDialog pluginPath = os.path.split(os.path.dirname(__file__))[0] class CreateNewScriptAction(ToolboxAction): - - SCRIPT_PYTHON = 0 - - def __init__(self, actionName, scriptType): + def __init__(self, actionName): self.name, self.i18n_name = self.trAction(actionName) self.group, self.i18n_group = self.trAction('Tools') - self.scriptType = scriptType - def getIcon(self): - if self.scriptType == self.SCRIPT_PYTHON: - return QgsApplication.getThemeIcon("/processingScript.svg") + return QgsApplication.getThemeIcon("/processingScript.svg") def execute(self): - dlg = None - if self.scriptType == self.SCRIPT_PYTHON: - dlg = ScriptEditorDialog(ScriptEditorDialog.SCRIPT_PYTHON, None) + dlg = ScriptEditorDialog(None) dlg.show() diff --git a/python/plugins/processing/gui/DeleteScriptAction.py b/python/plugins/processing/script/DeleteScriptAction.py similarity index 73% rename from python/plugins/processing/gui/DeleteScriptAction.py rename to python/plugins/processing/script/DeleteScriptAction.py index c4661a0294c..af7cea8640b 100644 --- a/python/plugins/processing/gui/DeleteScriptAction.py +++ b/python/plugins/processing/script/DeleteScriptAction.py @@ -37,25 +37,18 @@ from processing.script.ScriptAlgorithm import ScriptAlgorithm class DeleteScriptAction(ContextAction): - - SCRIPT_PYTHON = 0 - - def __init__(self, scriptType): - self.name = self.tr('Delete script', 'DeleteScriptAction') - self.scriptType = scriptType + def __init__(self): + self.name = self.tr('Delete script') def isEnabled(self): - if self.scriptType == self.SCRIPT_PYTHON: - return isinstance(self.itemData, ScriptAlgorithm) and self.itemData.allowEdit + return isinstance(self.itemData, ScriptAlgorithm) and self.itemData.allowEdit def execute(self): reply = QMessageBox.question(None, - self.tr('Confirmation', 'DeleteScriptAction'), - self.tr('Are you sure you want to delete this script?', - 'DeleteScriptAction'), + self.tr('Confirmation'), + self.tr('Are you sure you want to delete this script?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: os.remove(self.itemData.descriptionFile) - if self.scriptType == self.SCRIPT_PYTHON: - QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() + QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() diff --git a/python/plugins/processing/gui/EditScriptAction.py b/python/plugins/processing/script/EditScriptAction.py similarity index 75% rename from python/plugins/processing/gui/EditScriptAction.py rename to python/plugins/processing/script/EditScriptAction.py index 4840a706b99..e1d9334b52c 100644 --- a/python/plugins/processing/gui/EditScriptAction.py +++ b/python/plugins/processing/script/EditScriptAction.py @@ -26,22 +26,18 @@ __copyright__ = '(C) 2012, Victor Olaya' __revision__ = '$Format:%H$' from processing.gui.ContextAction import ContextAction -from processing.gui.ScriptEditorDialog import ScriptEditorDialog + +from processing.script.ScriptEditorDialog import ScriptEditorDialog from processing.script.ScriptAlgorithm import ScriptAlgorithm class EditScriptAction(ContextAction): - - SCRIPT_PYTHON = 0 - - def __init__(self, scriptType): - self.name = self.tr('Edit script', 'EditScriptAction') - self.scriptType = scriptType + def __init__(self): + self.name = self.tr('Edit script') def isEnabled(self): - if self.scriptType == ScriptEditorDialog.SCRIPT_PYTHON: - return isinstance(self.itemData, ScriptAlgorithm) and self.itemData.allowEdit + return isinstance(self.itemData, ScriptAlgorithm) and self.itemData.allowEdit def execute(self): - dlg = ScriptEditorDialog(self.scriptType, self.itemData) + dlg = ScriptEditorDialog(self.itemData) dlg.show() diff --git a/python/plugins/processing/script/ScriptAlgorithmProvider.py b/python/plugins/processing/script/ScriptAlgorithmProvider.py index adebdc1bae0..3496bbf49d8 100644 --- a/python/plugins/processing/script/ScriptAlgorithmProvider.py +++ b/python/plugins/processing/script/ScriptAlgorithmProvider.py @@ -31,14 +31,15 @@ from qgis.core import (QgsApplication, QgsProcessingProvider) from processing.core.ProcessingConfig import ProcessingConfig, Setting -from processing.gui.EditScriptAction import EditScriptAction -from processing.gui.DeleteScriptAction import DeleteScriptAction -from processing.gui.CreateNewScriptAction import CreateNewScriptAction -from processing.script.ScriptUtils import ScriptUtils -from processing.script.AddScriptFromFileAction import AddScriptFromFileAction from processing.gui.ProviderActions import (ProviderActions, ProviderContextMenuActions) + +from processing.script.AddScriptFromFileAction import AddScriptFromFileAction +from processing.script.CreateNewScriptAction import CreateNewScriptAction +from processing.script.DeleteScriptAction import DeleteScriptAction +from processing.script.EditScriptAction import EditScriptAction from processing.script.CreateScriptCollectionPluginAction import CreateScriptCollectionPluginAction +from processing.script.ScriptUtils import ScriptUtils pluginPath = os.path.split(os.path.dirname(__file__))[0] @@ -49,13 +50,11 @@ class ScriptAlgorithmProvider(QgsProcessingProvider): super().__init__() self.algs = [] self.folder_algorithms = [] - self.actions = [CreateNewScriptAction('Create new script', - CreateNewScriptAction.SCRIPT_PYTHON), + self.actions = [CreateNewScriptAction('Create new script'), AddScriptFromFileAction(), CreateScriptCollectionPluginAction()] - self.contextMenuActions = \ - [EditScriptAction(EditScriptAction.SCRIPT_PYTHON), - DeleteScriptAction(DeleteScriptAction.SCRIPT_PYTHON)] + self.contextMenuActions = [EditScriptAction(), + DeleteScriptAction()] def load(self): ProcessingConfig.settingIcons[self.name()] = self.icon() diff --git a/python/plugins/processing/gui/ScriptEditorDialog.py b/python/plugins/processing/script/ScriptEditorDialog.py similarity index 85% rename from python/plugins/processing/gui/ScriptEditorDialog.py rename to python/plugins/processing/script/ScriptEditorDialog.py index 2245348d927..ed88eb14046 100644 --- a/python/plugins/processing/gui/ScriptEditorDialog.py +++ b/python/plugins/processing/script/ScriptEditorDialog.py @@ -42,6 +42,7 @@ from qgis.utils import iface, OverrideCursor from processing.gui.AlgorithmDialog import AlgorithmDialog from processing.gui.HelpEditionDialog import HelpEditionDialog + from processing.script.ScriptAlgorithm import ScriptAlgorithm from processing.script.ScriptUtils import ScriptUtils @@ -51,12 +52,9 @@ WIDGET, BASE = uic.loadUiType( class ScriptEditorDialog(BASE, WIDGET): - - SCRIPT_PYTHON = 0 - hasChanged = False - def __init__(self, algType, alg): + def __init__(self, alg): super(ScriptEditorDialog, self).__init__(None) self.setupUi(self) @@ -120,25 +118,23 @@ class ScriptEditorDialog(BASE, WIDGET): self.lastSearch = None self.alg = alg - self.algType = algType self.snippets = {} - if self.algType == self.SCRIPT_PYTHON: - 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) + 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: # self.btnSnippets.setVisible(False) @@ -154,8 +150,6 @@ class ScriptEditorDialog(BASE, WIDGET): self.setHasChanged(False) - self.editor.setLexerType(self.algType) - #def showSnippets(self, evt): # popupmenu = QMenu() # for name, snippet in list(self.snippets.items()): @@ -181,13 +175,11 @@ class ScriptEditorDialog(BASE, WIDGET): def updateProviders(self): if self.update: - if self.algType == self.SCRIPT_PYTHON: - QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() + QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() def editHelp(self): if self.alg is None: - if self.algType == self.SCRIPT_PYTHON: - alg = ScriptAlgorithm(None, self.editor.text()) + alg = ScriptAlgorithm(None, self.editor.text()) else: alg = self.alg @@ -205,10 +197,8 @@ class ScriptEditorDialog(BASE, WIDGET): if ret == QMessageBox.No: return - if self.algType == self.SCRIPT_PYTHON: - scriptDir = ScriptUtils.scriptsFolders()[0] - filterName = self.tr('Python scripts (*.py)') - + scriptDir = ScriptUtils.scriptsFolders()[0] + filterName = self.tr('Python scripts (*.py)') self.filename, fileFilter = QFileDialog.getOpenFileName( self, self.tr('Open script'), scriptDir, filterName) @@ -232,16 +222,13 @@ class ScriptEditorDialog(BASE, WIDGET): def saveScript(self, saveAs): if self.filename is None or saveAs: - if self.algType == self.SCRIPT_PYTHON: - scriptDir = ScriptUtils.scriptsFolders()[0] - filterName = self.tr('Python scripts (*.py)') - + scriptDir = ScriptUtils.scriptsFolders()[0] + filterName = self.tr('Python scripts (*.py)') self.filename, fileFilter = QFileDialog.getSaveFileName( self, self.tr('Save script'), scriptDir, filterName) if self.filename: - if self.algType == self.SCRIPT_PYTHON and \ - not self.filename.lower().endswith('.py'): + if not self.filename.lower().endswith('.py'): self.filename += '.py' text = self.editor.text() @@ -273,9 +260,8 @@ class ScriptEditorDialog(BASE, WIDGET): self.actionSaveScript.setEnabled(hasChanged) def runAlgorithm(self): - if self.algType == self.SCRIPT_PYTHON: - alg = ScriptAlgorithm(None, script=self.editor.text()) - alg.setProvider(QgsApplication.processingRegistry().providerById('script')) + alg = ScriptAlgorithm(None, script=self.editor.text()) + alg.setProvider(QgsApplication.processingRegistry().providerById('script')) dlg = alg.createCustomParametersWidget(self) if not dlg: diff --git a/python/plugins/processing/ui/DlgScriptEditor.ui b/python/plugins/processing/ui/DlgScriptEditor.ui index e3de69b7a8e..bc19d084b48 100644 --- a/python/plugins/processing/ui/DlgScriptEditor.ui +++ b/python/plugins/processing/ui/DlgScriptEditor.ui @@ -16,7 +16,7 @@ - + @@ -257,9 +257,9 @@ - ScriptEdit + QgsCodeEditorPython QTextEdit -
processing.gui.ScriptEdit
+
qgis.gui