QGIS/python/plugins/processing/gui/CommanderWindow.py

243 lines
8.9 KiB
Python
Raw Normal View History

2013-04-13 15:05:19 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
CommanderWindow.py
---------------------
Date : April 2013
Copyright : (C) 2012 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. *
* *
***************************************************************************
"""
2013-04-13 15:05:19 +02:00
__author__ = 'Victor Olaya'
__date__ = 'April 2013'
__copyright__ = '(C) 2013, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import types
import os
import imp
from PyQt4.QtCore import Qt, QSize
from PyQt4.QtGui import QDialog, QLabel, QSpacerItem, QHBoxLayout, QVBoxLayout, QSizePolicy, QComboBox, QCompleter, QSortFilterProxyModel
from qgis.utils import iface
2013-08-12 20:44:27 +02:00
from processing.core.Processing import Processing
from processing.gui.MessageDialog import MessageDialog
from processing.gui.AlgorithmDialog import AlgorithmDialog
from processing.tools.system import userFolder, mkdir
2013-04-13 15:05:19 +02:00
ITEMHEIGHT = 30
2013-05-01 23:45:20 +02:00
OFFSET = 20
2013-04-13 15:05:19 +02:00
HEIGHT = 60
class CommanderWindow(QDialog):
2013-05-01 23:45:20 +02:00
def __init__(self, parent, canvas):
2013-04-13 15:05:19 +02:00
self.canvas = canvas
QDialog.__init__(self, parent, Qt.FramelessWindowHint)
self.commands = imp.load_source('commands', self.commandsFile())
2013-05-01 23:45:20 +02:00
self.initGui()
def commandsFolder(self):
folder = unicode(os.path.join(userFolder(), 'commander'))
2013-04-13 15:05:19 +02:00
mkdir(folder)
return os.path.abspath(folder)
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
def commandsFile(self):
f = os.path.join(self.commandsFolder(), 'commands.py')
2013-04-13 15:05:19 +02:00
if not os.path.exists(f):
out = open(f, 'w')
out.write('from qgis.core import *\n')
out.write('import processing\n\n')
out.write('def removeall():\n')
out.write('\tmapreg = QgsMapLayerRegistry.instance()\n')
out.write('\tmapreg.removeAllMapLayers()\n\n')
out.write('def load(*args):\n')
out.write('\tprocessing.load(args[0])\n')
2013-04-13 15:05:19 +02:00
out.close()
2013-05-01 23:45:20 +02:00
return f
2013-04-27 00:34:57 +02:00
def algsListHasChanged(self):
self.fillCombo()
2013-05-01 23:45:20 +02:00
def initGui(self):
self.combo = ExtendedComboBox()
2013-05-01 23:45:20 +02:00
self.fillCombo()
2013-04-13 15:05:19 +02:00
self.combo.setEditable(True)
self.label = QLabel('Enter command:')
self.errorLabel = QLabel('Enter command:')
self.vlayout = QVBoxLayout()
2013-04-13 15:05:19 +02:00
self.vlayout.setSpacing(2)
self.vlayout.setMargin(0)
self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
QSizePolicy.Maximum, QSizePolicy.Expanding))
self.hlayout = QHBoxLayout()
2013-04-13 15:05:19 +02:00
self.hlayout.addWidget(self.label)
self.vlayout.addLayout(self.hlayout)
self.hlayout2 = QHBoxLayout()
2013-04-13 15:05:19 +02:00
self.hlayout2.addWidget(self.combo)
self.vlayout.addLayout(self.hlayout2)
self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
QSizePolicy.Maximum, QSizePolicy.Expanding))
2013-04-13 15:05:19 +02:00
self.setLayout(self.vlayout)
self.combo.lineEdit().returnPressed.connect(self.run)
2013-04-27 00:34:57 +02:00
self.prepareGui()
2013-05-01 23:45:20 +02:00
2013-04-27 00:34:57 +02:00
def fillCombo(self):
self.combo.clear()
# Add algorithms
2013-08-12 20:44:27 +02:00
for providerName in Processing.algs.keys():
provider = Processing.algs[providerName]
2013-05-01 23:45:20 +02:00
algs = provider.values()
2013-04-27 00:34:57 +02:00
for alg in algs:
self.combo.addItem('Processing algorithm: ' + alg.name)
# Add functions
2013-04-27 00:34:57 +02:00
for command in dir(self.commands):
if isinstance(self.commands.__dict__.get(command),
types.FunctionType):
self.combo.addItem('Command: ' + command)
#Add menu entries
2013-04-27 00:34:57 +02:00
menuActions = []
actions = iface.mainWindow().menuBar().actions()
2013-04-27 00:34:57 +02:00
for action in actions:
menuActions.extend(self.getActions(action))
for action in menuActions:
self.combo.addItem('Menu action: ' + unicode(action.text()))
2013-05-01 23:45:20 +02:00
2013-04-27 00:34:57 +02:00
def prepareGui(self):
self.combo.setEditText('')
self.combo.setMaximumSize(QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT))
self.combo.view().setStyleSheet('min-height: 150px')
2013-05-01 23:45:20 +02:00
self.combo.setFocus(Qt.OtherFocusReason)
2013-04-13 15:05:19 +02:00
self.label.setMaximumSize(self.combo.maximumSize())
2013-05-01 23:45:20 +02:00
self.label.setVisible(False)
self.adjustSize()
2013-04-13 15:05:19 +02:00
pt = self.canvas.rect().topLeft()
absolutePt = self.canvas.mapToGlobal(pt)
self.move(absolutePt)
self.resize(self.canvas.rect().width(), HEIGHT)
self.setStyleSheet('CommanderWindow {background-color: #e7f5fe; \
border: 1px solid #b9cfe4;}')
2013-04-13 15:05:19 +02:00
def getActions(self, action):
menuActions = []
menu = action.menu()
if menu is None:
menuActions.append(action)
return menuActions
2013-05-01 23:45:20 +02:00
else:
2013-04-13 15:05:19 +02:00
actions = menu.actions()
for subaction in actions:
if subaction.menu() is not None:
menuActions.extend(self.getActions(subaction))
elif not subaction.isSeparator():
menuActions.append(subaction)
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
return menuActions
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
def run(self):
s = unicode(self.combo.currentText())
if s.startswith('Processing algorithm: '):
algName = s[len('Processing algorithm: '):]
2013-08-12 20:44:27 +02:00
alg = Processing.getAlgorithmFromFullName(algName)
2013-04-13 15:05:19 +02:00
if alg is not None:
self.close()
2013-05-01 23:45:20 +02:00
self.runAlgorithm(alg)
2013-04-13 15:05:19 +02:00
elif s.startswith("Command: "):
2013-05-01 23:45:20 +02:00
command = s[len("Command: "):]
2013-04-13 15:05:19 +02:00
try:
self.runCommand(command)
self.close()
except Exception as e:
2013-05-01 23:45:20 +02:00
self.label.setVisible(True)
self.label.setText('Error:' + unicode(e))
2013-05-01 23:45:20 +02:00
elif s.startswith('Menu action: '):
actionName = s[len('Menu action: '):]
2013-04-13 15:05:19 +02:00
menuActions = []
actions = iface.mainWindow().menuBar().actions()
2013-04-13 15:05:19 +02:00
for action in actions:
menuActions.extend(self.getActions(action))
for action in menuActions:
if action.text() == actionName:
self.close()
2013-05-01 23:45:20 +02:00
action.trigger()
return
2013-04-13 15:05:19 +02:00
else:
try:
self.runCommand(s)
self.close()
except Exception as e:
2013-05-01 23:45:20 +02:00
self.label.setVisible(True)
self.label.setText('Error:' + unicode(e))
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
def runCommand(self, command):
tokens = command.split(' ')
2013-04-13 15:05:19 +02:00
if len(tokens) == 1:
method = self.commands.__dict__.get(command)
if method is not None:
2013-05-01 23:45:20 +02:00
method()
2013-04-13 15:05:19 +02:00
else:
raise Exception('Wrong command')
2013-04-13 15:05:19 +02:00
else:
method = self.commands.__dict__.get(tokens[0])
if method is not None:
2013-05-01 23:45:20 +02:00
method(*tokens[1:])
2013-04-13 15:05:19 +02:00
else:
raise Exception('Wrong command')
2013-05-01 23:45:20 +02:00
def runAlgorithm(self, alg):
2013-04-13 15:05:19 +02:00
alg = alg.getCopy()
message = alg.checkBeforeOpeningParametersDialog()
if message:
dlg = MessageDialog()
dlg.setTitle(self.tr('Missing dependency'))
dlg.setMessage(message)
2013-05-01 23:45:20 +02:00
dlg.exec_()
2013-04-13 15:05:19 +02:00
return
dlg = alg.getCustomParametersDialog()
if not dlg:
dlg = AlgorithmDialog(alg)
canvas = iface.mapCanvas()
2013-04-13 15:05:19 +02:00
prevMapTool = canvas.mapTool()
dlg.show()
dlg.exec_()
if canvas.mapTool() != prevMapTool:
2013-04-13 15:05:19 +02:00
try:
canvas.mapTool().reset()
except:
pass
canvas.setMapTool(prevMapTool)
2013-05-01 23:45:20 +02:00
2013-04-13 15:05:19 +02:00
class ExtendedComboBox(QComboBox):
2013-04-13 15:05:19 +02:00
def __init__(self, parent=None):
super(ExtendedComboBox, self).__init__(parent)
self.setFocusPolicy(Qt.StrongFocus)
self.setEditable(True)
self.pFilterModel = QSortFilterProxyModel(self)
self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
self.pFilterModel.setSourceModel(self.model())
self.completer = QCompleter(self.pFilterModel, self)
self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
self.completer.popup().setStyleSheet('min-height: 150px')
2013-04-13 15:05:19 +02:00
self.completer.popup().setAlternatingRowColors(True)
self.setCompleter(self.completer)
self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)