BatchOutputSelectionPanel.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """
  2. ***************************************************************************
  3. BatchOutputSelectionPanel.py
  4. ---------------------
  5. Date : August 2012
  6. Copyright : (C) 2012 by Victor Olaya
  7. Email : volayaf at gmail dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Victor Olaya'
  18. __date__ = 'August 2012'
  19. __copyright__ = '(C) 2012, Victor Olaya'
  20. import os
  21. import re
  22. from qgis.core import (QgsMapLayer,
  23. QgsSettings,
  24. QgsProcessingParameterFolderDestination,
  25. QgsProcessingParameterRasterLayer,
  26. QgsProcessingParameterFeatureSource,
  27. QgsProcessingParameterVectorLayer,
  28. QgsProcessingParameterMultipleLayers,
  29. QgsProcessingParameterMapLayer,
  30. QgsProcessingParameterBoolean,
  31. QgsProcessingParameterEnum,
  32. QgsProject,
  33. QgsProcessingParameterMatrix)
  34. from qgis.PyQt.QtWidgets import QWidget, QPushButton, QLineEdit, QHBoxLayout, QSizePolicy, QFileDialog
  35. from processing.gui.AutofillDialog import AutofillDialog
  36. class BatchOutputSelectionPanel(QWidget):
  37. def __init__(self, output, alg, row, col, panel):
  38. super().__init__(None)
  39. self.alg = alg
  40. self.row = row
  41. self.col = col
  42. self.output = output
  43. self.panel = panel
  44. self.table = self.panel.tblParameters
  45. self.horizontalLayout = QHBoxLayout(self)
  46. self.horizontalLayout.setSpacing(2)
  47. self.horizontalLayout.setMargin(0)
  48. self.text = QLineEdit()
  49. self.text.setText('')
  50. self.text.setMinimumWidth(300)
  51. self.text.setSizePolicy(QSizePolicy.Expanding,
  52. QSizePolicy.Expanding)
  53. self.horizontalLayout.addWidget(self.text)
  54. self.pushButton = QPushButton()
  55. self.pushButton.setText('…')
  56. self.pushButton.clicked.connect(self.showSelectionDialog)
  57. self.horizontalLayout.addWidget(self.pushButton)
  58. self.setLayout(self.horizontalLayout)
  59. def showSelectionDialog(self):
  60. if isinstance(self.output, QgsProcessingParameterFolderDestination):
  61. self.selectDirectory()
  62. return
  63. filefilter = self.output.createFileFilter()
  64. settings = QgsSettings()
  65. if settings.contains('/Processing/LastBatchOutputPath'):
  66. path = str(settings.value('/Processing/LastBatchOutputPath'))
  67. else:
  68. path = ''
  69. filename, selectedFileFilter = QFileDialog.getSaveFileName(self,
  70. self.tr('Save File'), path, filefilter)
  71. if filename:
  72. if not filename.lower().endswith(
  73. tuple(re.findall("\\*(\\.[a-z]{1,10})", filefilter))):
  74. ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter)
  75. if ext:
  76. filename += ext.group(1)
  77. settings.setValue('/Processing/LastBatchOutputPath', os.path.dirname(filename))
  78. dlg = AutofillDialog(self.alg)
  79. dlg.exec_()
  80. if dlg.mode is not None:
  81. if dlg.mode == AutofillDialog.DO_NOT_AUTOFILL:
  82. self.table.cellWidget(self.row,
  83. self.col).setValue(filename)
  84. elif dlg.mode == AutofillDialog.FILL_WITH_NUMBERS:
  85. n = self.table.rowCount() - self.row
  86. for i in range(n):
  87. name = filename[:filename.rfind('.')] \
  88. + str(i + 1) + filename[filename.rfind('.'):]
  89. self.table.cellWidget(i + self.row,
  90. self.col).setValue(name)
  91. elif dlg.mode == AutofillDialog.FILL_WITH_PARAMETER:
  92. for row in range(self.row, self.table.rowCount()):
  93. v = self.panel.valueForParameter(row - 1, dlg.param_name)
  94. param = self.alg.parameterDefinition(dlg.param_name)
  95. if isinstance(param, (QgsProcessingParameterRasterLayer,
  96. QgsProcessingParameterFeatureSource,
  97. QgsProcessingParameterVectorLayer,
  98. QgsProcessingParameterMultipleLayers,
  99. QgsProcessingParameterMapLayer)):
  100. if isinstance(v, QgsMapLayer):
  101. s = v.name()
  102. else:
  103. if v in QgsProject.instance().mapLayers():
  104. layer = QgsProject.instance().mapLayer(v)
  105. # value is a layer ID, but we'd prefer to show a layer name if it's unique in the project
  106. if len([l for _, l in QgsProject.instance().mapLayers().items() if l.name().lower() == layer.name().lower()]) == 1:
  107. s = layer.name()
  108. else:
  109. # otherwise fall back to layer id
  110. s = v
  111. else:
  112. # else try to use file base name
  113. # TODO: this is bad for database sources!!
  114. s = os.path.basename(v)
  115. s = os.path.splitext(s)[0]
  116. elif isinstance(param, QgsProcessingParameterBoolean):
  117. s = 'true' if v else 'false'
  118. elif isinstance(param, QgsProcessingParameterEnum):
  119. s = param.options()[v]
  120. else:
  121. s = str(v)
  122. name = filename[:filename.rfind('.')] + s \
  123. + filename[filename.rfind('.'):]
  124. self.table.cellWidget(row,
  125. self.col).setValue(name)
  126. def selectDirectory(self):
  127. settings = QgsSettings()
  128. if settings.contains('/Processing/LastBatchOutputPath'):
  129. lastDir = str(settings.value('/Processing/LastBatchOutputPath'))
  130. else:
  131. lastDir = ''
  132. dirName = QFileDialog.getExistingDirectory(self,
  133. self.tr('Output Directory'), lastDir, QFileDialog.ShowDirsOnly)
  134. if dirName:
  135. self.table.cellWidget(self.row, self.col).setValue(dirName)
  136. settings.setValue('/Processing/LastBatchOutputPath', dirName)
  137. def setValue(self, text):
  138. return self.text.setText(text)
  139. def getValue(self):
  140. return str(self.text.text())