-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathFragScape_dialog.py
More file actions
254 lines (221 loc) · 10.6 KB
/
FragScape_dialog.py
File metadata and controls
254 lines (221 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# -*- coding: utf-8 -*-
"""
/***************************************************************************
FragScape
A QGIS plugin
This plugin computes mesh effective size
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2018-11-05
git sha : $Format:%H$
copyright : (C) 2018 by Mathieu Chailloux
email : mathieu@chailloux.org
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
"""
import os
import sys
import traceback
from io import StringIO
import xml.etree.ElementTree as ET
from PyQt5 import uic
from PyQt5 import QtWidgets
from PyQt5.QtCore import QTranslator, qVersion, QCoreApplication
from qgis.gui import QgsFileWidget
from qgis.core import QgsApplication, QgsProcessingContext
from .qgis_lib_mc import utils, qgsUtils, feedbacks, config_parsing, log, qgsTreatments
from .algs.FragScape_algs_provider import FragScapeAlgorithmsProvider
from .algs.FragScape_global_alg import FragScapeAlgorithm
from .steps import params, landuse, fragm, reporting
from . import tabs
from .FragScape_model import FragScapeModel
#from FragScapeAbout_dialog import FragScapeAboutDialog
from .FragScape_dialog_base import Ui_FragScapeDialogBase
from .FragScapeAbout_dialog_base import Ui_FragScapeAbout
class FragScapeAboutDialog(QtWidgets.QDialog,Ui_FragScapeAbout):
def __init__(self,parent=None):
super(FragScapeAboutDialog,self).__init__(parent)
self.setupUi(self)
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'FragScape_dialog_base.ui'))
# class FragScapeDialog(QtWidgets.QDialog, Ui_FragScapeDialogBase):
class FragScapeDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(FragScapeDialog, self).__init__(parent)
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.provider = FragScapeAlgorithmsProvider()
fsGlobalAlg = FragScapeAlgorithm()
fsGlobalAlg.initAlgorithm()
self.provider.alglist.append(fsGlobalAlg)
self.setupUi(self)
def initTabs(self):
global progressFeedback
logConnector = log.LogConnector(self)
logConnector.initGui()
self.feedback = feedbacks.ProgressFeedback(self)
feedbacks.progressFeedback = self.feedback
self.feedback.pushDebugInfo("progressFeedback = " + str(feedbacks.progressFeedback))
self.context = QgsProcessingContext()
self.context.setFeedback(feedbacks.progressFeedback)
self.fsModel = FragScapeModel(self.context,self.feedback)
self.paramsConnector = params.ParamsConnector(self,self.fsModel.paramsModel)
params.params = self.paramsConnector.model
self.landuseConnector = landuse.LanduseConnector(self,self.fsModel.landuseModel)
self.fragmConnector = fragm.FragmConnector(self,self.fsModel.fragmModel)
self.reportingConnector = reporting.ReportingConnector(self,self.fsModel.reportingModel)
tabConnector = tabs.TabConnector(self)
self.connectors = {"Params" : self.paramsConnector,
"Log" : logConnector,
"Landuse" : self.landuseConnector,
"Fragm" : self.fragmConnector,
"Reporting" : self.reportingConnector,
"Progress" : feedbacks.progressFeedback,
"Tabs" : tabConnector}
self.recomputeParsers()
def initGui(self):
QgsApplication.processingRegistry().addProvider(self.provider)
self.switchLangEn()
for k, tab in self.connectors.items():
tab.initGui()
def modeIsVector(self):
return self.paramsConnector.modeIsVector()
def getVectorWidgets(self):
widgets = []
return widgets
def getRasterWidgets(self):
widgets = [self.rasterResolution]
return widgets
# Exception hook, i.e. function called when exception raised.
# Displays traceback and error message in log tab.
# Ignores CustomException : exception raised from FragScape and already displayed.
def exceptionHook(self,excType, excValue, tracebackobj):
self.feedback.pushDebugInfo("FragScapeHook")
if excType == utils.CustomException:
self.feedback.pushDebugInfo("Ignoring custom exception : " + str(excValue))
else:
tbinfofile = StringIO()
traceback.print_tb(tracebackobj, None, tbinfofile)
tbinfofile.seek(0)
tbinfo = tbinfofile.read()
errmsg = str(excType.__name__) + " : " + str(excValue)
separator = '-' * 80
#sections = [separator, errmsg, separator]
#self.feedback.pushDebugInfo(str(sections))
msg = separator + "\n" + errmsg + "\n" + separator
#msg = '\n'.join(sections)
self.feedback.pushDebugInfo(str(msg))
#final_msg = tbinfo + "\n" + msg
self.feedback.pushWarning("Traceback : " + tbinfo)
self.feedback.error_msg(msg,prefix="Unexpected error")
self.mTabWidget.setCurrentWidget(self.logTab)
#feedbacks.progressConnector.clear()
# Connects view and model components for each tab.
# Connects global elements such as project file and language management.
def connectComponents(self):
for k, tab in self.connectors.items():
tab.connectComponents()
# Main tab connectors
self.saveProjectAs.clicked.connect(self.saveModelAsAction)
self.saveProject.clicked.connect(self.saveModel)
self.openProject.clicked.connect(self.loadModelAction)
self.langEn.clicked.connect(self.switchLangEn)
self.langFr.clicked.connect(self.switchLangFr)
self.aboutButton.clicked.connect(self.openHelpDialog)
feedbacks.progressFeedback.connectComponents()
sys.excepthook = self.exceptionHook
# Initialize or re-initialize global variables.
def initializeGlobals(self):
pass
def unload(self):
self.fsModel = None
QgsApplication.processingRegistry().removeProvider(self.provider)
def initLog(self):
utils.print_func = self.txtLog.append
# Switch language to english.
def switchLang(self,lang):
self.feedback.pushDebugInfo("switchLang " + str(lang))
plugin_dir = os.path.dirname(__file__)
lang_path = os.path.join(plugin_dir,'i18n','FragScape_' + lang + '.qm')
if os.path.exists(lang_path):
self.translator = QTranslator()
self.translator.load(lang_path)
if qVersion() > '4.3.3':
self.feedback.pushDebugInfo("Installing translator " + str(lang_path))
QCoreApplication.installTranslator(self.translator)
else:
self.feedback.internal_error("Unexpected qVersion : " + str(qVersion()))
else:
self.feedback.pushWarning("No translation file : " + str(en_path))
self.retranslateUi(self)
utils.curr_language = lang
self.connectors["Tabs"].loadHelpFile()
def switchLangEn(self):
self.switchLang("en")
self.langEn.setChecked(True)
self.langFr.setChecked(False)
def switchLangFr(self):
self.switchLang("fr")
self.langEn.setChecked(False)
self.langFr.setChecked(True)
def openHelpDialog(self):
self.feedback.pushDebugInfo("openHelpDialog")
about_dlg = FragScapeAboutDialog(self)
about_dlg.show()
# Recompute self.parsers in case they have been reloaded
def recomputeParsers(self):
# self.parsers = [self.paramsConnector.model,
# self.landuseConnector.model,
# self.fragmConnector.model,
# self.reportingConnector.model]
self.parsers = [self.paramsConnector,
self.landuseConnector,
self.fragmConnector,
self.reportingConnector]
# Return XML string describing project
def toXML(self):
xmlStr = self.fsModel.toXML()
return xmlStr
# Save project to 'fname'
def saveModelAs(self,fname):
self.recomputeParsers()
xmlStr = self.fsModel.toXML()
self.paramsConnector.setProjectFile(fname)
utils.writeFile(fname,xmlStr)
self.feedback.pushInfo("FragScape model saved into file '" + fname + "'")
def saveModelAsAction(self):
fname = qgsUtils.saveFileDialog(parent=self,msg="Sauvegarder le projet sous",filter="*.xml")
if fname:
self.saveModelAs(fname)
# Save project to projectFile if existing
def saveModel(self):
fname = self.fsModel.paramsModel.projectFile
utils.checkFileExists(fname,"Project ")
self.saveModelAs(fname)
# Load project from 'fname' if existing
def loadModel(self,fname):
self.feedback.pushDebugInfo("loadModel " + str(fname))
utils.checkFileExists(fname)
config_parsing.setConfigParsers(self.parsers)
self.paramsConnector.setProjectFile(fname)
config_parsing.parseConfig(fname,feedback=self.feedback)
self.feedback.pushInfo("FragScape model loaded from file '" + fname + "'")
# Update UI for each tab
self.paramsConnector.updateUI()
self.landuseConnector.updateUI()
self.reportingConnector.updateUI()
def loadModelAction(self):
fname =qgsUtils.openFileDialog(parent=self,msg="Ouvrir le projet",filter="*.xml")
if fname:
self.loadModel(fname)