mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			281 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
"""
 | 
						|
***************************************************************************
 | 
						|
    BatchPanel.py
 | 
						|
    ---------------------
 | 
						|
    Date                 : November 2014
 | 
						|
    Copyright            : (C) 2014 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.                                   *
 | 
						|
*                                                                         *
 | 
						|
***************************************************************************
 | 
						|
"""
 | 
						|
from builtins import range
 | 
						|
 | 
						|
__author__ = 'Alexander Bruy'
 | 
						|
__date__ = 'November 2014'
 | 
						|
__copyright__ = '(C) 2014, Alexander Bruy'
 | 
						|
 | 
						|
# This will get replaced with a git SHA1 when you do a git archive
 | 
						|
 | 
						|
__revision__ = '$Format:%H$'
 | 
						|
 | 
						|
import os
 | 
						|
import json
 | 
						|
 | 
						|
from qgis.PyQt import uic
 | 
						|
from qgis.PyQt.QtWidgets import QTableWidgetItem, QComboBox, QHeaderView, QFileDialog, QMessageBox
 | 
						|
 | 
						|
from qgis.core import (QgsApplication,
 | 
						|
                       QgsProcessingParameterDefinition)
 | 
						|
from qgis.gui import QgsMessageBar
 | 
						|
from processing.gui.wrappers import WidgetWrapperFactory
 | 
						|
 | 
						|
from processing.gui.BatchOutputSelectionPanel import BatchOutputSelectionPanel
 | 
						|
 | 
						|
from processing.core.parameters import ParameterFile  # NOQA
 | 
						|
from processing.core.parameters import ParameterRaster  # NOQA
 | 
						|
from processing.core.parameters import ParameterTable  # NOQA
 | 
						|
from processing.core.parameters import ParameterVector  # NOQA
 | 
						|
from processing.core.parameters import ParameterExtent  # NOQA
 | 
						|
from processing.core.parameters import ParameterCrs  # NOQA
 | 
						|
from processing.core.parameters import ParameterPoint  # NOQA
 | 
						|
from processing.core.parameters import ParameterSelection  # NOQA
 | 
						|
from processing.core.parameters import ParameterFixedTable  # NOQA
 | 
						|
from processing.core.parameters import ParameterMultipleInput  # NOQA
 | 
						|
from processing.tools import dataobjects
 | 
						|
 | 
						|
pluginPath = os.path.split(os.path.dirname(__file__))[0]
 | 
						|
WIDGET, BASE = uic.loadUiType(
 | 
						|
    os.path.join(pluginPath, 'ui', 'widgetBatchPanel.ui'))
 | 
						|
 | 
						|
 | 
						|
class BatchPanel(BASE, WIDGET):
 | 
						|
 | 
						|
    PARAMETERS = "PARAMETERS"
 | 
						|
    OUTPUTS = "OUTPUTS"
 | 
						|
 | 
						|
    def __init__(self, parent, alg):
 | 
						|
        super(BatchPanel, self).__init__(None)
 | 
						|
        self.setupUi(self)
 | 
						|
 | 
						|
        self.wrappers = []
 | 
						|
 | 
						|
        self.btnAdvanced.hide()
 | 
						|
 | 
						|
        # Set icons
 | 
						|
        self.btnAdd.setIcon(QgsApplication.getThemeIcon('/symbologyAdd.svg'))
 | 
						|
        self.btnRemove.setIcon(QgsApplication.getThemeIcon('/symbologyRemove.svg'))
 | 
						|
        self.btnOpen.setIcon(QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
 | 
						|
        self.btnSave.setIcon(QgsApplication.getThemeIcon('/mActionFileSave.svg'))
 | 
						|
        self.btnAdvanced.setIcon(QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
 | 
						|
 | 
						|
        self.alg = alg
 | 
						|
        self.parent = parent
 | 
						|
 | 
						|
        self.btnAdd.clicked.connect(self.addRow)
 | 
						|
        self.btnRemove.clicked.connect(self.removeRows)
 | 
						|
        self.btnOpen.clicked.connect(self.load)
 | 
						|
        self.btnSave.clicked.connect(self.save)
 | 
						|
        self.btnAdvanced.toggled.connect(self.toggleAdvancedMode)
 | 
						|
        self.tblParameters.horizontalHeader().sectionDoubleClicked.connect(
 | 
						|
            self.fillParameterValues)
 | 
						|
 | 
						|
        self.initWidgets()
 | 
						|
 | 
						|
    def layerRegistryChanged(self):
 | 
						|
        pass
 | 
						|
 | 
						|
    def initWidgets(self):
 | 
						|
        # If there are advanced parameters — show corresponding button
 | 
						|
        for param in self.alg.parameterDefinitions():
 | 
						|
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
 | 
						|
                self.btnAdvanced.show()
 | 
						|
                break
 | 
						|
 | 
						|
        # Determine column count
 | 
						|
        nOutputs = len(self.alg.destinationParameterDefinitions()) + 1
 | 
						|
        if nOutputs == 1:
 | 
						|
            nOutputs = 0
 | 
						|
 | 
						|
        self.tblParameters.setColumnCount(
 | 
						|
            self.alg.countVisibleParameters())
 | 
						|
 | 
						|
        # Table headers
 | 
						|
        column = 0
 | 
						|
        for param in self.alg.parameterDefinitions():
 | 
						|
            if param.isDestination():
 | 
						|
                continue
 | 
						|
            self.tblParameters.setHorizontalHeaderItem(
 | 
						|
                column, QTableWidgetItem(param.description()))
 | 
						|
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
 | 
						|
                self.tblParameters.setColumnHidden(column, True)
 | 
						|
            column += 1
 | 
						|
 | 
						|
        for out in self.alg.destinationParameterDefinitions():
 | 
						|
            if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                self.tblParameters.setHorizontalHeaderItem(
 | 
						|
                    column, QTableWidgetItem(out.description()))
 | 
						|
                column += 1
 | 
						|
 | 
						|
        # Last column for indicating if output will be added to canvas
 | 
						|
        if len(self.alg.destinationParameterDefinitions()) > 0:
 | 
						|
            self.tblParameters.setHorizontalHeaderItem(
 | 
						|
                column, QTableWidgetItem(self.tr('Load in QGIS')))
 | 
						|
 | 
						|
        # Add two empty rows by default
 | 
						|
        for i in range(2):
 | 
						|
            self.addRow()
 | 
						|
 | 
						|
        self.tblParameters.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
 | 
						|
        self.tblParameters.horizontalHeader().setDefaultSectionSize(250)
 | 
						|
        self.tblParameters.horizontalHeader().setMinimumSectionSize(150)
 | 
						|
        self.tblParameters.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
 | 
						|
        self.tblParameters.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
 | 
						|
        self.tblParameters.horizontalHeader().setStretchLastSection(True)
 | 
						|
 | 
						|
    def load(self):
 | 
						|
        filename, selected_filter = QFileDialog.getOpenFileName(self,
 | 
						|
                                                                self.tr('Open batch'), None,
 | 
						|
                                                                self.tr('JSON files (*.json)'))
 | 
						|
        if filename:
 | 
						|
            with open(filename) as f:
 | 
						|
                values = json.load(f)
 | 
						|
        else:
 | 
						|
            # If the user clicked on the cancel button.
 | 
						|
            return
 | 
						|
 | 
						|
        self.tblParameters.setRowCount(0)
 | 
						|
        try:
 | 
						|
            for row, alg in enumerate(values):
 | 
						|
                self.addRow()
 | 
						|
                params = alg[self.PARAMETERS]
 | 
						|
                outputs = alg[self.OUTPUTS]
 | 
						|
                column = 0
 | 
						|
                for param in self.alg.parameterDefinitions():
 | 
						|
                    if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                        continue
 | 
						|
                    if param.name() in params:
 | 
						|
                        value = params[param.name()].strip('"')
 | 
						|
                        wrapper = self.wrappers[row][column]
 | 
						|
                        wrapper.setValue(value)
 | 
						|
                    column += 1
 | 
						|
 | 
						|
                for out in self.alg.outputs:
 | 
						|
                    if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                        continue
 | 
						|
                    if out.name() in outputs:
 | 
						|
                        value = outputs[out.name()].strip('"')
 | 
						|
                        widget = self.tblParameters.cellWidget(row, column)
 | 
						|
                        widget.setValue(value)
 | 
						|
                    column += 1
 | 
						|
        except TypeError:
 | 
						|
            QMessageBox.critical(
 | 
						|
                self,
 | 
						|
                self.tr('Error'),
 | 
						|
                self.tr('An error occurred while reading your file.'))
 | 
						|
 | 
						|
    def save(self):
 | 
						|
        toSave = []
 | 
						|
        context = dataobjects.createContext()
 | 
						|
        for row in range(self.tblParameters.rowCount()):
 | 
						|
            algParams = {}
 | 
						|
            algOutputs = {}
 | 
						|
            col = 0
 | 
						|
            alg = self.alg
 | 
						|
            for param in alg.parameterDefinitions():
 | 
						|
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                    continue
 | 
						|
                wrapper = self.wrappers[row][col]
 | 
						|
                if not param.checkValueIsAcceptable(wrapper.value, context):
 | 
						|
                    self.parent.bar.pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
 | 
						|
                                                param.description(), row + 1),
 | 
						|
                                                level=QgsMessageBar.WARNING, duration=5)
 | 
						|
                    return
 | 
						|
                algParams[param.name()] = param.getValueAsCommandLineParameter()
 | 
						|
                col += 1
 | 
						|
            for out in alg.outputs:
 | 
						|
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                    continue
 | 
						|
                widget = self.tblParameters.cellWidget(row, col)
 | 
						|
                text = widget.getValue()
 | 
						|
                if text.strip() != '':
 | 
						|
                    algOutputs[out.name] = text.strip()
 | 
						|
                    col += 1
 | 
						|
                else:
 | 
						|
                    self.parent.bar.pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
 | 
						|
                                                out.description(), row + 1),
 | 
						|
                                                level=QgsMessageBar.WARNING, duration=5)
 | 
						|
                    return
 | 
						|
            toSave.append({self.PARAMETERS: algParams, self.OUTPUTS: algOutputs})
 | 
						|
 | 
						|
        filename, __ = QFileDialog.getSaveFileName(self,
 | 
						|
                                                   self.tr('Save batch'),
 | 
						|
                                                   None,
 | 
						|
                                                   self.tr('JSON files (*.json)'))
 | 
						|
        if filename:
 | 
						|
            if not filename.endswith('.json'):
 | 
						|
                filename += '.json'
 | 
						|
            with open(filename, 'w') as f:
 | 
						|
                json.dump(toSave, f)
 | 
						|
 | 
						|
    def setCellWrapper(self, row, column, wrapper):
 | 
						|
        self.wrappers[row][column] = wrapper
 | 
						|
        self.tblParameters.setCellWidget(row, column, wrapper.widget)
 | 
						|
 | 
						|
    def addRow(self):
 | 
						|
        self.wrappers.append([None] * self.tblParameters.columnCount())
 | 
						|
        self.tblParameters.setRowCount(self.tblParameters.rowCount() + 1)
 | 
						|
 | 
						|
        wrappers = {}
 | 
						|
        row = self.tblParameters.rowCount() - 1
 | 
						|
        column = 0
 | 
						|
        for param in self.alg.parameterDefinitions():
 | 
						|
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
 | 
						|
                continue
 | 
						|
 | 
						|
            wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent, row, column)
 | 
						|
            wrappers[param.name()] = wrapper
 | 
						|
            self.setCellWrapper(row, column, wrapper)
 | 
						|
            column += 1
 | 
						|
 | 
						|
        for out in self.alg.destinationParameterDefinitions():
 | 
						|
            if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
 | 
						|
                continue
 | 
						|
 | 
						|
            self.tblParameters.setCellWidget(
 | 
						|
                row, column, BatchOutputSelectionPanel(
 | 
						|
                    out, self.alg, row, column, self))
 | 
						|
            column += 1
 | 
						|
 | 
						|
        if len(self.alg.destinationParameterDefinitions()) > 0:
 | 
						|
            item = QComboBox()
 | 
						|
            item.addItem(self.tr('Yes'))
 | 
						|
            item.addItem(self.tr('No'))
 | 
						|
            item.setCurrentIndex(0)
 | 
						|
            self.tblParameters.setCellWidget(row, column, item)
 | 
						|
 | 
						|
        for wrapper in list(wrappers.values()):
 | 
						|
            wrapper.postInitialize(list(wrappers.values()))
 | 
						|
 | 
						|
    def removeRows(self):
 | 
						|
        if self.tblParameters.rowCount() > 2:
 | 
						|
            self.wrappers.pop()
 | 
						|
            self.tblParameters.setRowCount(self.tblParameters.rowCount() - 1)
 | 
						|
 | 
						|
    def fillParameterValues(self, column):
 | 
						|
        wrapper = self.wrappers[0][column]
 | 
						|
        for row in range(1, self.tblParameters.rowCount()):
 | 
						|
            self.wrappers[row][column].setValue(wrapper.value())
 | 
						|
 | 
						|
    def toggleAdvancedMode(self, checked):
 | 
						|
        for column, param in enumerate(self.alg.parameters):
 | 
						|
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
 | 
						|
                self.tblParameters.setColumnHidden(column, not checked)
 |