Skip to content

Commit fa4092f

Browse files
author
cpolymeris@gmail.com
committed
Base class for dialogs. WIP
git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@302 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
1 parent 6dfff31 commit fa4092f

File tree

3 files changed

+287
-103
lines changed

3 files changed

+287
-103
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#!/usr/bin/env python
2+
# -*- coding: latin-1 -*-
3+
from PyQt4.QtCore import *
4+
from PyQt4.QtGui import *
5+
from PyQt4 import QtCore, QtGui, QtWebKit
6+
from sextante.core.QGisLayers import QGisLayers
7+
from sextante.parameters.ParameterRaster import ParameterRaster
8+
from sextante.parameters.ParameterVector import ParameterVector
9+
from sextante.parameters.ParameterBoolean import ParameterBoolean
10+
from sextante.parameters.ParameterSelection import ParameterSelection
11+
from sextante.parameters.ParameterMultipleInput import ParameterMultipleInput
12+
from sextante.parameters.ParameterFixedTable import ParameterFixedTable
13+
from sextante.parameters.ParameterTableField import ParameterTableField
14+
from sextante.parameters.ParameterTable import ParameterTable
15+
from sextante.gui.AlgorithmExecutor import AlgorithmExecutor
16+
from sextante.core.SextanteLog import SextanteLog
17+
from sextante.gui.SextantePostprocessing import SextantePostprocessing
18+
from sextante.parameters.ParameterRange import ParameterRange
19+
from sextante.parameters.ParameterNumber import ParameterNumber
20+
21+
from sextante.gui.ParametersPanel import ParametersPanel
22+
from sextante.parameters.ParameterFile import ParameterFile
23+
from sextante.parameters.ParameterCrs import ParameterCrs
24+
from sextante.core.SextanteConfig import SextanteConfig
25+
from sextante.parameters.ParameterExtent import ParameterExtent
26+
from sextante.outputs.OutputHTML import OutputHTML
27+
from sextante.outputs.OutputRaster import OutputRaster
28+
from sextante.outputs.OutputVector import OutputVector
29+
from sextante.outputs.OutputTable import OutputTable
30+
from sextante.core.WrongHelpFileException import WrongHelpFileException
31+
import os
32+
from sextante.gui.UnthreadedAlgorithmExecutor import UnthreadedAlgorithmExecutor
33+
34+
try:
35+
_fromUtf8 = QtCore.QString.fromUtf8
36+
except AttributeError:
37+
_fromUtf8 = lambda s: s
38+
39+
class AlgorithmExecutionDialog(QtGui.QDialog):
40+
'''Base class for dialogs that execute algorithms'''
41+
def __init__(self, alg, mainWidget):
42+
QtGui.QDialog.__init__(self, None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
43+
self.executed = False
44+
self.mainWidget = mainWidget
45+
self.alg = alg
46+
self.resize(650, 450)
47+
self.buttonBox = QtGui.QDialogButtonBox()
48+
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
49+
self.buttonBox.setStandardButtons(
50+
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.Ok)
51+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
52+
53+
self.scrollArea = QtGui.QScrollArea()
54+
if self.mainWidget:
55+
self.scrollArea.setWidget(self.mainWidget)
56+
self.scrollArea.setWidgetResizable(True)
57+
self.setWindowTitle(self.alg.name)
58+
self.progressLabel = QtGui.QLabel()
59+
self.progress = QtGui.QProgressBar()
60+
self.progress.setMinimum(0)
61+
self.progress.setMaximum(100)
62+
self.progress.setValue(0)
63+
self.verticalLayout = QtGui.QVBoxLayout(self)
64+
self.verticalLayout.setSpacing(2)
65+
self.verticalLayout.setMargin(0)
66+
self.tabWidget = QtGui.QTabWidget()
67+
self.tabWidget.setMinimumWidth(300)
68+
self.tabWidget.addTab(self.scrollArea, "Parameters")
69+
self.verticalLayout.addWidget(self.tabWidget)
70+
self.webView = QtWebKit.QWebView()
71+
cssUrl = QtCore.QUrl(os.path.join(os.path.dirname(__file__), "help", "help.css"))
72+
self.webView.settings().setUserStyleSheetUrl(cssUrl)
73+
html = None
74+
try:
75+
if self.alg.helpFile():
76+
helpFile = self.alg.helpFile()
77+
else:
78+
html = "<h2>Sorry, no help is available for this algorithm.</h2>"
79+
except WrongHelpFileException, e:
80+
html = e.msg
81+
self.webView.setHtml("<h2>Could not open help file :-( </h2>")
82+
try:
83+
if html:
84+
self.webView.setHtml(html)
85+
else:
86+
url = QtCore.QUrl(helpFile)
87+
self.webView.load(url)
88+
except:
89+
self.webView.setHtml("<h2>Could not open help file :-( </h2>")
90+
self.tabWidget.addTab(self.webView, "Help")
91+
self.verticalLayout.addWidget(self.progressLabel)
92+
self.verticalLayout.addWidget(self.progress)
93+
self.verticalLayout.addWidget(self.buttonBox)
94+
self.setLayout(self.verticalLayout)
95+
self.buttonBox.accepted.connect(self.accept)
96+
self.buttonBox.rejected.connect(self.close)
97+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).clicked.connect(self.cancel)
98+
#~ QtCore.QMetaObject.connectSlotsByName(self)
99+
100+
101+
def setParamValues(self):
102+
params = self.alg.parameters
103+
outputs = self.alg.outputs
104+
105+
for param in params:
106+
if not self.setParamValue(param, self.paramTable.valueItems[param.name]):
107+
return False
108+
109+
for output in outputs:
110+
if output.hidden:
111+
continue
112+
output.value = self.paramTable.valueItems[output.name].getValue()
113+
if not SextanteConfig.getSetting(SextanteConfig.TABLE_LIKE_PARAM_PANEL):
114+
if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML)):
115+
output.open = self.paramTable.checkBoxes[output.name].isChecked()
116+
117+
return True
118+
119+
def setParamValue(self, param, widget):
120+
if isinstance(param, ParameterRaster):
121+
return param.setValue(widget.getValue())
122+
elif isinstance(param, (ParameterVector, ParameterTable)):
123+
try:
124+
return param.setValue(widget.itemData(widget.currentIndex()).toPyObject())
125+
except:
126+
return param.setValue(widget.getValue())
127+
elif isinstance(param, ParameterBoolean):
128+
return param.setValue(widget.currentIndex() == 0)
129+
elif isinstance(param, ParameterSelection):
130+
return param.setValue(widget.currentIndex())
131+
elif isinstance(param, ParameterFixedTable):
132+
return param.setValue(widget.table)
133+
elif isinstance(param, ParameterRange):
134+
return param.setValue(widget.getValue())
135+
if isinstance(param, ParameterTableField):
136+
return param.setValue(widget.currentText())
137+
elif isinstance(param, ParameterMultipleInput):
138+
if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
139+
options = QGisLayers.getVectorLayers()
140+
else:
141+
options = QGisLayers.getRasterLayers()
142+
value = []
143+
for index in widget.selectedoptions:
144+
value.append(options[index])
145+
return param.setValue(value)
146+
elif isinstance(param, (ParameterNumber, ParameterFile, ParameterCrs, ParameterExtent)):
147+
return param.setValue(widget.getValue())
148+
else:
149+
return param.setValue(str(widget.text()))
150+
151+
@pyqtSlot()
152+
def accept(self):
153+
#~ try:
154+
if self.setParamValues():
155+
msg = self.alg.checkParameterValuesBeforeExecuting()
156+
if msg:
157+
QMessageBox.critical(self, "Unable to execute algorithm", msg)
158+
return
159+
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
160+
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(False)
161+
buttons = self.paramTable.iterateButtons
162+
iterateParam = None
163+
164+
for i in range(len(buttons.values())):
165+
button = buttons.values()[i]
166+
if button.isChecked():
167+
iterateParam = buttons.keys()[i]
168+
break
169+
170+
self.progress.setMaximum(0)
171+
self.progressLabel.setText("Processing algorithm...")
172+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
173+
useThread = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
174+
if useThread:
175+
if iterateParam:
176+
self.algEx = AlgorithmExecutor(self.alg, iterateParam)
177+
else:
178+
command = self.alg.getAsCommand()
179+
if command:
180+
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, command)
181+
self.algEx = AlgorithmExecutor(self.alg)
182+
self.algEx.finished.connect(self.finish)
183+
self.algEx.error.connect(self.error)
184+
self.algEx.percentageChanged.connect(self.setPercentage)
185+
self.algEx.textChanged.connect(self.setText)
186+
self.algEx.iterated.connect(self.iterate)
187+
self.algEx.start()
188+
SextanteLog.addToLog(SextanteLog.LOG_INFO,
189+
"Algorithm %s started" % self.alg.name)
190+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(True)
191+
self.finish()
192+
else:
193+
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
194+
if iterateParam:
195+
UnthreadedAlgorithmExecutor.runalgIterating(self.alg, iterateParam, self)
196+
else:
197+
command = self.alg.getAsCommand()
198+
if command:
199+
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, command)
200+
if UnthreadedAlgorithmExecutor.runalg(self.alg, self):
201+
SextantePostprocessing.handleAlgorithmResults(self.alg, not keepOpen)
202+
self.executed = True
203+
QApplication.restoreOverrideCursor()
204+
if not keepOpen:
205+
self.close()
206+
else:
207+
self.progressLabel.setText("")
208+
self.progress.setMaximum(100)
209+
self.progress.setValue(0)
210+
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
211+
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(True)
212+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
213+
214+
215+
else:
216+
QMessageBox.critical(self, "Unable to execute algorithm", "Wrong or missing parameter values")
217+
218+
@pyqtSlot()
219+
def finish(self):
220+
self.executed = True
221+
SextanteLog.addToLog(SextanteLog.LOG_INFO,
222+
"Algorithm %s finished correctly" % self.alg.name)
223+
QApplication.restoreOverrideCursor()
224+
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
225+
if not keepOpen:
226+
self.close()
227+
else:
228+
self.progressLabel.setText("")
229+
self.progress.setMaximum(100)
230+
self.progress.setValue(0)
231+
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
232+
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(True)
233+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
234+
235+
@pyqtSlot(str)
236+
def error(self, msg):
237+
self.algEx.finished.disconnect()
238+
QApplication.restoreOverrideCursor()
239+
QMessageBox.critical(self, "Error", msg)
240+
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
241+
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
242+
if not keepOpen:
243+
self.close()
244+
else:
245+
self.progressLabel.setText("")
246+
self.progress.setValue(0)
247+
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
248+
249+
@pyqtSlot(int)
250+
def iterate(self, i):
251+
SextanteLog.addToLog(SextanteLog.LOG_INFO,
252+
"Algorithm %s iteration #%i completed" % (self.alg.name, i))
253+
254+
@pyqtSlot()
255+
def cancel(self):
256+
SextanteLog.addToLog(SextanteLog.LOG_INFO,
257+
"Algorithm %s canceled" % self.alg.name)
258+
try:
259+
self.algEx.finished.disconnect()
260+
self.algEx.terminate()
261+
QApplication.restoreOverrideCursor()
262+
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
263+
except:
264+
pass
265+
266+
def setPercentage(self, i):
267+
if self.progress.maximum() == 0:
268+
self.progress.setMaximum(100)
269+
self.progress.setValue(i)
270+
271+
def setText(self, text):
272+
self.progressLabel.setText(text)

0 commit comments

Comments
 (0)