-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathseilaplanRun.py
116 lines (96 loc) · 4.85 KB
/
seilaplanRun.py
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
from qgis.core import QgsApplication
# Main dialog window
from SEILAPLAN.gui.seilaplanPluginDialog import SeilaplanPluginDialog
# Further dialog windows and helpers
from SEILAPLAN.gui.progressDialog import ProgressDialog
from SEILAPLAN.gui.adjustmentDialog import AdjustmentDialog
from SEILAPLAN.tools.configHandler import ConfigHandler
from SEILAPLAN.tools.processingThread import ProcessingTask
class SeilaplanRun:
"""Handles the program flow, manages settings/configuration and keeps a
hold on the plugin state and calculation results between different dialog
windows. Allows to run the plugin multiple times in parallel."""
def __init__(self, interface):
self.iface = interface
# Each run of the plugin has its own ConfigHandler instance
self.confHandler: ConfigHandler = ConfigHandler()
self.projectWindow = None
self.workerThread = None
self.progressDialog = None
self.adjustmentWindow = None
def showProjectWindow(self):
if not self.projectWindow:
# Initialize first dialog window
self.projectWindow = SeilaplanPluginDialog(self.iface, self.confHandler, self.onCloseProjectWindow)
# Setup dialog for first show
self.projectWindow.setupContentForFirstRun()
else:
# Updating dialog state when coming back from the adjustment window
self.projectWindow.setupContent()
# Show dialog and start event loop. No exec() because we don't want to
# block the event loop in case a second Seilaplan instance is started.
self.projectWindow.show()
def onCloseProjectWindow(self, runOptimization: bool):
"""Gets called by the Project dialog on closing."""
if runOptimization is True:
# Continue with optimization algorithm
self.startOptimization()
elif runOptimization is False:
# Continue by skipping over optimization and go straight to the
# adjustment window
result, resultQuality = self.confHandler.prepareResultWithoutOptimization()
self.showAdjustmentWindow(result, resultQuality)
else: # None: runOptimization not set --> user canceled dialog
self.close()
def startOptimization(self):
# Create separate thread for calculations so QGIS stays responsive
self.workerThread = ProcessingTask(self.confHandler.project)
# To see progress, a new dialog window shows a progress bar
self.progressDialog = ProgressDialog(self.iface.mainWindow(), self.onCloseProgressWindow)
self.progressDialog.setThread(self.workerThread)
# Add task to task manager of QGIS and start the calculations
QgsApplication.taskManager().addTask(self.workerThread)
# Show progress bar and start event loop
self.progressDialog.show()
def onCloseProgressWindow(self, continueToAdjustment: bool):
"""Gets called by the Progress dialog on closing."""
# Get result if calculation was successful
result, resultQuality = None, None
if continueToAdjustment:
result, resultQuality = self.workerThread.getResult()
# Cleanup
self.progressDialog.deleteLater()
del self.workerThread
if continueToAdjustment is True:
self.showAdjustmentWindow(result, resultQuality)
elif continueToAdjustment is False:
# User chose to go back to project window
self.showProjectWindow()
else: # None: continueToAdjustment not set --> user canceled dialog
self.close()
def showAdjustmentWindow(self, result, resultQuality):
# Show adjustment window to modify calculated cable line
self.adjustmentWindow = AdjustmentDialog(self.iface, self.confHandler, self.onCloseAdjustmentWindow)
self.adjustmentWindow.initData(result, resultQuality)
self.adjustmentWindow.show()
def onCloseAdjustmentWindow(self, returnToProjectWindow: bool):
"""Gets called by the Adjustment dialog on closing."""
if returnToProjectWindow is True:
self.adjustmentWindow.deleteLater()
# Reset configuration
self.confHandler.reset()
self.showProjectWindow()
else: # User clicked cancel or close
self.close()
def close(self):
# Save user settings
self.confHandler.updateUserSettings()
# Cleanup any markers in map and delete dialogs
for dialog in [self.projectWindow, self.progressDialog, self.adjustmentWindow]:
if dialog:
try:
dialog.cleanUp(True)
dialog.deleteLater()
except RuntimeError:
# Already deleted
pass