Skip to content

Commit

Permalink
[processing] allow creating new plugin from toolbox with scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
volaya committed May 30, 2016
1 parent 9c2721b commit b52828f
Show file tree
Hide file tree
Showing 4 changed files with 383 additions and 1 deletion.
102 changes: 102 additions & 0 deletions python/plugins/processing/script/CreateScriptCollectionPluginAction.py
@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
CreateScriptCollectionPluginAction.py
---------------------
Date : May 2016
Copyright : (C) 2016 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. *
* *
***************************************************************************
"""

__author__ = 'Victor Olaya'
__date__ = 'May 2016'
__copyright__ = '(C) 2016, Victor Olaya'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os

from qgis.PyQt.QtGui import QIcon
from processing.gui.ToolboxAction import ToolboxAction
from processing.script.ScriptSelector import ScriptSelector
from processing.tools.system import mkdir

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

initTemplate = '''from .plugin import ProcessingScriptCollectionPlugin
def classFactory(iface):
return ProcessingScriptCollectionPlugin()
'''
metadataTemplate = '''[general]
name=$name$
description=$description$
category=Analysis
version=1.0
qgisMinimumVersion=2.0
author=$author$
email=$email$
tags=analysis,processing
homepage=http://qgis.org
tracker=https://hub.qgis.org/projects/QGIS/issues
repository=https://github.com/qgis/QGIS
'''

pluginTemplate = '''import os
from processing.core.Processing import Processing
class ProcessingScriptCollectionPlugin:
def initGui(self):
Processing.addScripts(os.path.join(os.path.dirname(__file__), "scripts"))
def unload(self):
Processing.removeScripts(os.path.join(os.path.dirname(__file__), "scripts"))
'''

class CreateScriptCollectionPluginAction(ToolboxAction):

def __init__(self):
self.name, self.i18n_name = self.trAction('Create script collection plugin')
self.group, self.i18n_group = self.trAction('Tools')

def getIcon(self):
return QIcon(os.path.join(pluginPath, 'images', 'script.png'))

def execute(self):
dlg = ScriptSelector()
dlg.exec_()
if dlg.scripts:
mkdir(dlg.folder)
initFile = os.path.join(dlg.folder, "__init__.py")
with open(initFile, "w") as f:
f.write(initTemplate)
metadataFile = os.path.join(dlg.folder, "metadata.txt")
with open(metadataFile, "w") as f:
f.write(metadataTemplate.replace("$name$", dlg.name).replace("$description$", dlg.description)
.replace("$author$", dlg.author).replace("$email$", dlg.email))
pluginFile = os.path.join(dlg.folder, "plugin.py")
with open(pluginFile, "w") as f:
f.write(pluginTemplate)
scriptsFolder = os.path.join(dlg.folder, "scripts")
mkdir(scriptsFolder)
for script in dlg.scripts:
scriptFile = os.path.join(scriptsFolder, os.path.basename(script.descriptionFile))
with open(scriptFile, "w") as f:
f.write(script.script)

4 changes: 3 additions & 1 deletion python/plugins/processing/script/ScriptAlgorithmProvider.py
Expand Up @@ -37,6 +37,7 @@
from processing.script.ScriptUtils import ScriptUtils
from processing.script.AddScriptFromFileAction import AddScriptFromFileAction
from processing.gui.GetScriptsAndModels import GetScriptsAction
from processing.script.CreateScriptCollectionPluginAction import CreateScriptCollectionPluginAction

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

Expand All @@ -48,7 +49,8 @@ def __init__(self):
self.actions.extend([CreateNewScriptAction('Create new script',
CreateNewScriptAction.SCRIPT_PYTHON),
AddScriptFromFileAction(),
GetScriptsAction()])
GetScriptsAction(),
CreateScriptCollectionPluginAction(),])
self.contextMenuActions = \
[EditScriptAction(EditScriptAction.SCRIPT_PYTHON),
DeleteScriptAction(DeleteScriptAction.SCRIPT_PYTHON)]
Expand Down
110 changes: 110 additions & 0 deletions python/plugins/processing/script/ScriptSelector.py
@@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
ScriptSelector.py
---------------------
Date : May 2016
Copyright : (C) 2016 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. *
* *
***************************************************************************
"""

__author__ = 'Victor Olaya'
__date__ = 'May 2016'
__copyright__ = '(C) 2016, Victor Olaya'

# This will get replaced with a git SHA1 when you do a git archive
from PyQt4 import QtGui, uic, QtCore
import os
from collections import defaultdict
from processing.core.alglist import algList

WIDGET, BASE = uic.loadUiType(
os.path.join(os.path.dirname(__file__), 'scriptselector.ui'))

class ScriptSelector(BASE, WIDGET):

def __init__(self):
QtGui.QDialog.__init__(self)
self.setupUi(self)

self.scripts = None

allScripts = defaultdict(list)
alglist = algList.getProviderFromName("script").algs
for script in alglist:
allScripts[script.group].append(script)

for group, groupScripts in allScripts.iteritems():
groupItem = QtGui.QTreeWidgetItem()
groupItem.setText(0, group)
groupItem.setFlags(groupItem.flags() | QtCore.Qt.ItemIsTristate);
for script in groupScripts:
scriptItem = QtGui.QTreeWidgetItem()
scriptItem.setFlags(scriptItem.flags() | QtCore.Qt.ItemIsUserCheckable);
scriptItem.setCheckState(0, QtCore.Qt.Checked);
scriptItem.script = script
scriptItem.setText(0, script.name)
groupItem.addChild(scriptItem)
self.scriptsTree.addTopLevelItem(groupItem)

self.scriptsTree.expandAll()

self.selectAllLabel.linkActivated.connect(lambda: self.checkScripts(True))
self.unselectAllLabel.linkActivated.connect(lambda: self.checkScripts(False))

self.folderButton.clicked.connect(self.selectFolder)

self.buttonBox.accepted.connect(self.okPressed)
self.buttonBox.rejected.connect(self.cancelPressed)

def selectFolder(self):
folder = QtGui.QFileDialog.getExistingDirectory(self, 'Select folder')
if folder:
self.folderBox.setText(folder)

def checkScripts(self, b):
state = QtCore.Qt.Checked if b else QtCore.Qt.Unchecked
for i in xrange(self.scriptsTree.topLevelItemCount()):
item = self.scriptsTree.topLevelItem(i)
for j in xrange(item.childCount()):
child = item.child(j)
child.setCheckState(0, state)

def cancelPressed(self):
self.close()

def _getValue(self, textBox):
textBox.setStyleSheet("QLineEdit{background: white}")
value = textBox.text()
if value:
return value
textBox.setStyleSheet("QLineEdit{background: yellow}")
raise Exception("wrong parameter value")

def okPressed(self):
self.scripts = []
for i in xrange(self.scriptsTree.topLevelItemCount()):
groupItem = self.scriptsTree.topLevelItem(i)
for j in xrange(groupItem.childCount()):
scriptItem = groupItem.child(j)
if scriptItem.checkState(0) == QtCore.Qt.Checked:
self.scripts.append(scriptItem.script)
self.folder = self._getValue(self.folderBox)
try:
self.name = self._getValue(self.nameBox)
self.description = self._getValue(self.descriptionBox)
self.author = self._getValue(self.authorBox)
self.email = self._getValue(self.emailBox)
except:
return
self.close()

0 comments on commit b52828f

Please sign in to comment.