mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			243 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- 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.                                   *
 | 
						|
*                                                                         *
 | 
						|
***************************************************************************
 | 
						|
"""
 | 
						|
 | 
						|
__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 qgis.PyQt.QtCore import Qt, QSize
 | 
						|
from qgis.PyQt.QtWidgets import QDialog, QLabel, QSpacerItem, QHBoxLayout, QVBoxLayout, QSizePolicy, QComboBox, QCompleter
 | 
						|
from qgis.PyQt.QtCore import QSortFilterProxyModel
 | 
						|
from qgis.utils import iface
 | 
						|
from processing.core.Processing import Processing
 | 
						|
from processing.core.alglist import algList
 | 
						|
from processing.gui.MessageDialog import MessageDialog
 | 
						|
from processing.gui.AlgorithmDialog import AlgorithmDialog
 | 
						|
from processing.tools.system import userFolder, mkdir
 | 
						|
 | 
						|
ITEMHEIGHT = 30
 | 
						|
OFFSET = 20
 | 
						|
HEIGHT = 60
 | 
						|
 | 
						|
 | 
						|
class CommanderWindow(QDialog):
 | 
						|
 | 
						|
    def __init__(self, parent, canvas):
 | 
						|
        self.canvas = canvas
 | 
						|
        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
 | 
						|
        self.commands = imp.load_source('commands', self.commandsFile())
 | 
						|
        self.initGui()
 | 
						|
 | 
						|
    def commandsFolder(self):
 | 
						|
        folder = unicode(os.path.join(userFolder(), 'commander'))
 | 
						|
        mkdir(folder)
 | 
						|
        return os.path.abspath(folder)
 | 
						|
 | 
						|
    def commandsFile(self):
 | 
						|
        f = os.path.join(self.commandsFolder(), 'commands.py')
 | 
						|
        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')
 | 
						|
            out.close()
 | 
						|
        return f
 | 
						|
 | 
						|
    def algsListHasChanged(self):
 | 
						|
        self.fillCombo()
 | 
						|
 | 
						|
    def initGui(self):
 | 
						|
        self.combo = ExtendedComboBox()
 | 
						|
        self.fillCombo()
 | 
						|
 | 
						|
        self.combo.setEditable(True)
 | 
						|
        self.label = QLabel('Enter command:')
 | 
						|
        self.errorLabel = QLabel('Enter command:')
 | 
						|
        self.vlayout = QVBoxLayout()
 | 
						|
        self.vlayout.setSpacing(2)
 | 
						|
        self.vlayout.setMargin(0)
 | 
						|
        self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
 | 
						|
                                               QSizePolicy.Maximum, QSizePolicy.Expanding))
 | 
						|
        self.hlayout = QHBoxLayout()
 | 
						|
        self.hlayout.addWidget(self.label)
 | 
						|
        self.vlayout.addLayout(self.hlayout)
 | 
						|
        self.hlayout2 = QHBoxLayout()
 | 
						|
        self.hlayout2.addWidget(self.combo)
 | 
						|
        self.vlayout.addLayout(self.hlayout2)
 | 
						|
        self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
 | 
						|
                                               QSizePolicy.Maximum, QSizePolicy.Expanding))
 | 
						|
        self.setLayout(self.vlayout)
 | 
						|
        self.combo.lineEdit().returnPressed.connect(self.run)
 | 
						|
        self.prepareGui()
 | 
						|
 | 
						|
    def fillCombo(self):
 | 
						|
        self.combo.clear()
 | 
						|
 | 
						|
        # Add algorithms
 | 
						|
        for algs in algList.algs.values():
 | 
						|
            for alg in algs:
 | 
						|
                self.combo.addItem('Processing algorithm: ' + alg.name)
 | 
						|
 | 
						|
        # Add functions
 | 
						|
        for command in dir(self.commands):
 | 
						|
            if isinstance(self.commands.__dict__.get(command),
 | 
						|
                          types.FunctionType):
 | 
						|
                self.combo.addItem('Command: ' + command)
 | 
						|
 | 
						|
        # Add menu entries
 | 
						|
        menuActions = []
 | 
						|
        actions = iface.mainWindow().menuBar().actions()
 | 
						|
        for action in actions:
 | 
						|
            menuActions.extend(self.getActions(action))
 | 
						|
        for action in menuActions:
 | 
						|
            self.combo.addItem('Menu action: ' + unicode(action.text()))
 | 
						|
 | 
						|
    def prepareGui(self):
 | 
						|
        self.combo.setEditText('')
 | 
						|
        self.combo.setMaximumSize(QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT))
 | 
						|
        self.combo.view().setStyleSheet('min-height: 150px')
 | 
						|
        self.combo.setFocus(Qt.OtherFocusReason)
 | 
						|
        self.label.setMaximumSize(self.combo.maximumSize())
 | 
						|
        self.label.setVisible(False)
 | 
						|
        self.adjustSize()
 | 
						|
        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;}')
 | 
						|
 | 
						|
    def getActions(self, action):
 | 
						|
        menuActions = []
 | 
						|
        menu = action.menu()
 | 
						|
        if menu is None:
 | 
						|
            menuActions.append(action)
 | 
						|
            return menuActions
 | 
						|
        else:
 | 
						|
            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)
 | 
						|
 | 
						|
        return menuActions
 | 
						|
 | 
						|
    def run(self):
 | 
						|
        s = unicode(self.combo.currentText())
 | 
						|
        if s.startswith('Processing algorithm: '):
 | 
						|
            algName = s[len('Processing algorithm: '):]
 | 
						|
            alg = Processing.getAlgorithmFromFullName(algName)
 | 
						|
            if alg is not None:
 | 
						|
                self.close()
 | 
						|
                self.runAlgorithm(alg)
 | 
						|
        elif s.startswith("Command: "):
 | 
						|
            command = s[len("Command: "):]
 | 
						|
            try:
 | 
						|
                self.runCommand(command)
 | 
						|
                self.close()
 | 
						|
            except Exception as e:
 | 
						|
                self.label.setVisible(True)
 | 
						|
                self.label.setText('Error:' + unicode(e))
 | 
						|
 | 
						|
        elif s.startswith('Menu action: '):
 | 
						|
            actionName = s[len('Menu action: '):]
 | 
						|
            menuActions = []
 | 
						|
            actions = iface.mainWindow().menuBar().actions()
 | 
						|
            for action in actions:
 | 
						|
                menuActions.extend(self.getActions(action))
 | 
						|
            for action in menuActions:
 | 
						|
                if action.text() == actionName:
 | 
						|
                    self.close()
 | 
						|
                    action.trigger()
 | 
						|
                    return
 | 
						|
        else:
 | 
						|
            try:
 | 
						|
                self.runCommand(s)
 | 
						|
                self.close()
 | 
						|
            except Exception as e:
 | 
						|
                self.label.setVisible(True)
 | 
						|
                self.label.setText('Error:' + unicode(e))
 | 
						|
 | 
						|
    def runCommand(self, command):
 | 
						|
        tokens = command.split(' ')
 | 
						|
        if len(tokens) == 1:
 | 
						|
            method = self.commands.__dict__.get(command)
 | 
						|
            if method is not None:
 | 
						|
                method()
 | 
						|
            else:
 | 
						|
                raise Exception('Wrong command')
 | 
						|
        else:
 | 
						|
            method = self.commands.__dict__.get(tokens[0])
 | 
						|
            if method is not None:
 | 
						|
                method(*tokens[1:])
 | 
						|
            else:
 | 
						|
                raise Exception('Wrong command')
 | 
						|
 | 
						|
    def runAlgorithm(self, alg):
 | 
						|
        alg = alg.getCopy()
 | 
						|
        message = alg.checkBeforeOpeningParametersDialog()
 | 
						|
        if message:
 | 
						|
            dlg = MessageDialog()
 | 
						|
            dlg.setTitle(self.tr('Missing dependency'))
 | 
						|
            dlg.setMessage(message)
 | 
						|
            dlg.exec_()
 | 
						|
            return
 | 
						|
        dlg = alg.getCustomParametersDialog()
 | 
						|
        if not dlg:
 | 
						|
            dlg = AlgorithmDialog(alg)
 | 
						|
        canvas = iface.mapCanvas()
 | 
						|
        prevMapTool = canvas.mapTool()
 | 
						|
        dlg.show()
 | 
						|
        dlg.exec_()
 | 
						|
        if canvas.mapTool() != prevMapTool:
 | 
						|
            try:
 | 
						|
                canvas.mapTool().reset()
 | 
						|
            except:
 | 
						|
                pass
 | 
						|
            canvas.setMapTool(prevMapTool)
 | 
						|
 | 
						|
 | 
						|
class ExtendedComboBox(QComboBox):
 | 
						|
 | 
						|
    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')
 | 
						|
        self.completer.popup().setAlternatingRowColors(True)
 | 
						|
        self.setCompleter(self.completer)
 | 
						|
        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
 |