Skip to content

Commit b52828f

Browse files
committed
[processing] allow creating new plugin from toolbox with scripts
1 parent 9c2721b commit b52828f

File tree

4 files changed

+383
-1
lines changed

4 files changed

+383
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
CreateScriptCollectionPluginAction.py
6+
---------------------
7+
Date : May 2016
8+
Copyright : (C) 2016 by Victor Olaya
9+
Email : volayaf at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Victor Olaya'
21+
__date__ = 'May 2016'
22+
__copyright__ = '(C) 2016, Victor Olaya'
23+
24+
# This will get replaced with a git SHA1 when you do a git archive
25+
26+
__revision__ = '$Format:%H$'
27+
28+
import os
29+
30+
from qgis.PyQt.QtGui import QIcon
31+
from processing.gui.ToolboxAction import ToolboxAction
32+
from processing.script.ScriptSelector import ScriptSelector
33+
from processing.tools.system import mkdir
34+
35+
pluginPath = os.path.split(os.path.dirname(__file__))[0]
36+
37+
initTemplate = '''from .plugin import ProcessingScriptCollectionPlugin
38+
39+
def classFactory(iface):
40+
return ProcessingScriptCollectionPlugin()
41+
'''
42+
metadataTemplate = '''[general]
43+
name=$name$
44+
description=$description$
45+
category=Analysis
46+
version=1.0
47+
qgisMinimumVersion=2.0
48+
49+
author=$author$
50+
email=$email$
51+
52+
tags=analysis,processing
53+
54+
homepage=http://qgis.org
55+
tracker=https://hub.qgis.org/projects/QGIS/issues
56+
repository=https://github.com/qgis/QGIS
57+
'''
58+
59+
pluginTemplate = '''import os
60+
61+
from processing.core.Processing import Processing
62+
63+
class ProcessingScriptCollectionPlugin:
64+
65+
def initGui(self):
66+
Processing.addScripts(os.path.join(os.path.dirname(__file__), "scripts"))
67+
68+
def unload(self):
69+
Processing.removeScripts(os.path.join(os.path.dirname(__file__), "scripts"))
70+
'''
71+
72+
class CreateScriptCollectionPluginAction(ToolboxAction):
73+
74+
def __init__(self):
75+
self.name, self.i18n_name = self.trAction('Create script collection plugin')
76+
self.group, self.i18n_group = self.trAction('Tools')
77+
78+
def getIcon(self):
79+
return QIcon(os.path.join(pluginPath, 'images', 'script.png'))
80+
81+
def execute(self):
82+
dlg = ScriptSelector()
83+
dlg.exec_()
84+
if dlg.scripts:
85+
mkdir(dlg.folder)
86+
initFile = os.path.join(dlg.folder, "__init__.py")
87+
with open(initFile, "w") as f:
88+
f.write(initTemplate)
89+
metadataFile = os.path.join(dlg.folder, "metadata.txt")
90+
with open(metadataFile, "w") as f:
91+
f.write(metadataTemplate.replace("$name$", dlg.name).replace("$description$", dlg.description)
92+
.replace("$author$", dlg.author).replace("$email$", dlg.email))
93+
pluginFile = os.path.join(dlg.folder, "plugin.py")
94+
with open(pluginFile, "w") as f:
95+
f.write(pluginTemplate)
96+
scriptsFolder = os.path.join(dlg.folder, "scripts")
97+
mkdir(scriptsFolder)
98+
for script in dlg.scripts:
99+
scriptFile = os.path.join(scriptsFolder, os.path.basename(script.descriptionFile))
100+
with open(scriptFile, "w") as f:
101+
f.write(script.script)
102+

python/plugins/processing/script/ScriptAlgorithmProvider.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from processing.script.ScriptUtils import ScriptUtils
3838
from processing.script.AddScriptFromFileAction import AddScriptFromFileAction
3939
from processing.gui.GetScriptsAndModels import GetScriptsAction
40+
from processing.script.CreateScriptCollectionPluginAction import CreateScriptCollectionPluginAction
4041

4142
pluginPath = os.path.split(os.path.dirname(__file__))[0]
4243

@@ -48,7 +49,8 @@ def __init__(self):
4849
self.actions.extend([CreateNewScriptAction('Create new script',
4950
CreateNewScriptAction.SCRIPT_PYTHON),
5051
AddScriptFromFileAction(),
51-
GetScriptsAction()])
52+
GetScriptsAction(),
53+
CreateScriptCollectionPluginAction(),])
5254
self.contextMenuActions = \
5355
[EditScriptAction(EditScriptAction.SCRIPT_PYTHON),
5456
DeleteScriptAction(DeleteScriptAction.SCRIPT_PYTHON)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
ScriptSelector.py
6+
---------------------
7+
Date : May 2016
8+
Copyright : (C) 2016 by Victor Olaya
9+
Email : volayaf at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Victor Olaya'
21+
__date__ = 'May 2016'
22+
__copyright__ = '(C) 2016, Victor Olaya'
23+
24+
# This will get replaced with a git SHA1 when you do a git archive
25+
from PyQt4 import QtGui, uic, QtCore
26+
import os
27+
from collections import defaultdict
28+
from processing.core.alglist import algList
29+
30+
WIDGET, BASE = uic.loadUiType(
31+
os.path.join(os.path.dirname(__file__), 'scriptselector.ui'))
32+
33+
class ScriptSelector(BASE, WIDGET):
34+
35+
def __init__(self):
36+
QtGui.QDialog.__init__(self)
37+
self.setupUi(self)
38+
39+
self.scripts = None
40+
41+
allScripts = defaultdict(list)
42+
alglist = algList.getProviderFromName("script").algs
43+
for script in alglist:
44+
allScripts[script.group].append(script)
45+
46+
for group, groupScripts in allScripts.iteritems():
47+
groupItem = QtGui.QTreeWidgetItem()
48+
groupItem.setText(0, group)
49+
groupItem.setFlags(groupItem.flags() | QtCore.Qt.ItemIsTristate);
50+
for script in groupScripts:
51+
scriptItem = QtGui.QTreeWidgetItem()
52+
scriptItem.setFlags(scriptItem.flags() | QtCore.Qt.ItemIsUserCheckable);
53+
scriptItem.setCheckState(0, QtCore.Qt.Checked);
54+
scriptItem.script = script
55+
scriptItem.setText(0, script.name)
56+
groupItem.addChild(scriptItem)
57+
self.scriptsTree.addTopLevelItem(groupItem)
58+
59+
self.scriptsTree.expandAll()
60+
61+
self.selectAllLabel.linkActivated.connect(lambda: self.checkScripts(True))
62+
self.unselectAllLabel.linkActivated.connect(lambda: self.checkScripts(False))
63+
64+
self.folderButton.clicked.connect(self.selectFolder)
65+
66+
self.buttonBox.accepted.connect(self.okPressed)
67+
self.buttonBox.rejected.connect(self.cancelPressed)
68+
69+
def selectFolder(self):
70+
folder = QtGui.QFileDialog.getExistingDirectory(self, 'Select folder')
71+
if folder:
72+
self.folderBox.setText(folder)
73+
74+
def checkScripts(self, b):
75+
state = QtCore.Qt.Checked if b else QtCore.Qt.Unchecked
76+
for i in xrange(self.scriptsTree.topLevelItemCount()):
77+
item = self.scriptsTree.topLevelItem(i)
78+
for j in xrange(item.childCount()):
79+
child = item.child(j)
80+
child.setCheckState(0, state)
81+
82+
def cancelPressed(self):
83+
self.close()
84+
85+
def _getValue(self, textBox):
86+
textBox.setStyleSheet("QLineEdit{background: white}")
87+
value = textBox.text()
88+
if value:
89+
return value
90+
textBox.setStyleSheet("QLineEdit{background: yellow}")
91+
raise Exception("wrong parameter value")
92+
93+
def okPressed(self):
94+
self.scripts = []
95+
for i in xrange(self.scriptsTree.topLevelItemCount()):
96+
groupItem = self.scriptsTree.topLevelItem(i)
97+
for j in xrange(groupItem.childCount()):
98+
scriptItem = groupItem.child(j)
99+
if scriptItem.checkState(0) == QtCore.Qt.Checked:
100+
self.scripts.append(scriptItem.script)
101+
self.folder = self._getValue(self.folderBox)
102+
try:
103+
self.name = self._getValue(self.nameBox)
104+
self.description = self._getValue(self.descriptionBox)
105+
self.author = self._getValue(self.authorBox)
106+
self.email = self._getValue(self.emailBox)
107+
except:
108+
return
109+
self.close()
110+

0 commit comments

Comments
 (0)