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

228 lines
9.0 KiB
Python
Raw Normal View History

2012-10-05 23:28:47 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
MultipleInputDialog.py
---------------------
Date : August 2012
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__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
2015-05-18 21:04:20 +03:00
import os
import warnings
from pathlib import Path
2015-05-18 21:04:20 +03:00
from qgis.core import (QgsSettings,
QgsProcessing,
QgsVectorFileWriter,
QgsProviderRegistry,
QgsProcessingModelChildParameterSource)
2016-04-29 11:39:26 +02:00
from qgis.PyQt import uic
2017-08-19 13:51:43 +02:00
from qgis.PyQt.QtCore import Qt, QByteArray, QCoreApplication
from qgis.PyQt.QtWidgets import QDialog, QAbstractItemView, QPushButton, QDialogButtonBox, QFileDialog
2016-04-22 10:38:48 +02:00
from qgis.PyQt.QtGui import QStandardItemModel, QStandardItem
2012-09-15 18:25:25 +03:00
2015-05-18 21:04:20 +03:00
pluginPath = os.path.split(os.path.dirname(__file__))[0]
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
WIDGET, BASE = uic.loadUiType(
os.path.join(pluginPath, 'ui', 'DlgMultipleSelection.ui'))
2015-05-18 21:04:20 +03:00
class MultipleInputDialog(BASE, WIDGET):
def __init__(self, options, selectedoptions=None, datatype=None):
2015-05-18 21:04:20 +03:00
super(MultipleInputDialog, self).__init__(None)
self.setupUi(self)
self.datatype = datatype
self.model = None
self.options = []
for i, option in enumerate(options):
if option is None or isinstance(option, str):
self.options.append((i, option))
else:
self.options.append((option[0], option[1]))
self.selectedoptions = selectedoptions or []
2012-09-15 18:25:25 +03:00
# Additional buttons
2018-09-25 12:41:12 +10:00
self.btnSelectAll = QPushButton(self.tr('Select All'))
self.buttonBox.addButton(self.btnSelectAll,
QDialogButtonBox.ActionRole)
2018-09-25 12:41:12 +10:00
self.btnClearSelection = QPushButton(self.tr('Clear Selection'))
self.buttonBox.addButton(self.btnClearSelection,
QDialogButtonBox.ActionRole)
2018-09-25 12:41:12 +10:00
self.btnToggleSelection = QPushButton(self.tr('Toggle Selection'))
self.buttonBox.addButton(self.btnToggleSelection,
QDialogButtonBox.ActionRole)
if self.datatype is not None:
2018-09-25 12:41:12 +10:00
btnAddFile = QPushButton(QCoreApplication.translate("MultipleInputDialog", 'Add File(s)…'))
btnAddFile.clicked.connect(self.addFiles)
self.buttonBox.addButton(btnAddFile,
QDialogButtonBox.ActionRole)
btnAddDir = QPushButton(QCoreApplication.translate("MultipleInputDialog", 'Add Directory…'))
btnAddDir.clicked.connect(self.addDirectory)
self.buttonBox.addButton(btnAddDir,
QDialogButtonBox.ActionRole)
self.btnSelectAll.clicked.connect(lambda: self.selectAll(True))
self.btnClearSelection.clicked.connect(lambda: self.selectAll(False))
self.btnToggleSelection.clicked.connect(self.toggleSelection)
self.settings = QgsSettings()
self.restoreGeometry(self.settings.value("/Processing/multipleInputDialogGeometry", QByteArray()))
self.lstLayers.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.lstLayers.setDragDropMode(QAbstractItemView.InternalMove)
self.populateList()
self.finished.connect(self.saveWindowGeometry)
def saveWindowGeometry(self):
self.settings.setValue("/Processing/multipleInputDialogGeometry", self.saveGeometry())
2012-09-15 18:25:25 +03:00
def populateList(self):
self.model = QStandardItemModel()
for value, text in self.options:
item = QStandardItem(text)
item.setData(value, Qt.UserRole)
item.setCheckState(Qt.Checked if value in self.selectedoptions else Qt.Unchecked)
item.setCheckable(True)
item.setDropEnabled(False)
self.model.appendRow(item)
# add extra options (e.g. manually added layers)
for t in [o for o in self.selectedoptions if not isinstance(o, int)]:
if isinstance(t, QgsProcessingModelChildParameterSource):
item = QStandardItem(t.staticValue())
else:
item = QStandardItem(t)
item.setData(item.text(), Qt.UserRole)
item.setCheckState(Qt.Checked)
item.setCheckable(True)
item.setDropEnabled(False)
self.model.appendRow(item)
self.lstLayers.setModel(self.model)
2012-09-15 18:25:25 +03:00
def accept(self):
2012-09-15 18:25:25 +03:00
self.selectedoptions = []
model = self.lstLayers.model()
2016-09-21 18:24:26 +02:00
for i in range(model.rowCount()):
item = model.item(i)
if item.checkState() == Qt.Checked:
self.selectedoptions.append(item.data(Qt.UserRole))
QDialog.accept(self)
2012-09-15 18:25:25 +03:00
def reject(self):
2012-09-15 18:25:25 +03:00
self.selectedoptions = None
QDialog.reject(self)
2012-09-15 18:25:25 +03:00
def getItemsToModify(self):
items = []
if len(self.lstLayers.selectedIndexes()) > 1:
for i in self.lstLayers.selectedIndexes():
items.append(self.model.itemFromIndex(i))
else:
for i in range(self.model.rowCount()):
items.append(self.model.item(i))
return items
2014-05-21 21:25:18 +02:00
def selectAll(self, value):
for item in self.getItemsToModify():
item.setCheckState(Qt.Checked if value else Qt.Unchecked)
2014-05-21 21:25:18 +02:00
def toggleSelection(self):
for item in self.getItemsToModify():
checked = item.checkState() == Qt.Checked
item.setCheckState(Qt.Unchecked if checked else Qt.Checked)
def getFileFilter(self, datatype):
"""
Returns a suitable file filter pattern for the specified parameter definition
:param param:
:return:
"""
if datatype == QgsProcessing.TypeRaster:
return QgsProviderRegistry.instance().fileRasterFilters()
elif datatype == QgsProcessing.TypeFile:
return self.tr('All files (*.*)')
else:
exts = QgsVectorFileWriter.supportedFormatExtensions()
for i in range(len(exts)):
exts[i] = self.tr('{0} files (*.{1})').format(exts[i].upper(), exts[i].lower())
return self.tr('All files (*.*)') + ';;' + ';;'.join(exts)
def addFiles(self):
filter = self.getFileFilter(self.datatype)
settings = QgsSettings()
path = str(settings.value('/Processing/LastInputPath'))
2018-02-21 18:44:04 +10:00
ret, selected_filter = QFileDialog.getOpenFileNames(self, self.tr('Select File(s)'),
path, filter)
if ret:
files = list(ret)
settings.setValue('/Processing/LastInputPath',
os.path.dirname(str(files[0])))
for filename in files:
item = QStandardItem(filename)
item.setData(filename, Qt.UserRole)
item.setCheckState(Qt.Checked)
item.setCheckable(True)
item.setDropEnabled(False)
self.model.appendRow(item)
def addDirectory(self):
settings = QgsSettings()
path = str(settings.value('/Processing/LastInputPath'))
ret = QFileDialog.getExistingDirectory(self, self.tr('Select File(s)'), path)
if ret:
exts = []
if self.datatype == QgsProcessing.TypeVector:
exts = QgsVectorFileWriter.supportedFormatExtensions()
elif self.datatype == QgsProcessing.TypeRaster:
for t in QgsProviderRegistry.instance().fileRasterFilters().split(';;')[1:]:
for e in t[t.index('(') + 1:-1].split(' '):
if e != "*.*" and e.startswith("*."):
exts.append(e[2:])
files = []
for pp in Path(ret).rglob("*"):
if not pp.is_file():
continue
if exts and pp.suffix[1:] not in exts:
continue
p = pp.as_posix()
files.append(p)
settings.setValue('/Processing/LastInputPath', ret)
for filename in files:
item = QStandardItem(filename)
item.setData(filename, Qt.UserRole)
item.setCheckState(Qt.Checked)
item.setCheckable(True)
item.setDropEnabled(False)
self.model.appendRow(item)