mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-10-31 00:06:02 -04: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.parameters:
 | |
|             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 three empty rows by default
 | |
|         for i in range(3):
 | |
|             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)
 |