35 |
36 |
36 class UMLDialog(EricMainWindow): |
37 class UMLDialog(EricMainWindow): |
37 """ |
38 """ |
38 Class implementing a dialog showing UML like diagrams. |
39 Class implementing a dialog showing UML like diagrams. |
39 """ |
40 """ |
40 FileVersions = ("1.0", ) |
41 |
41 JsonFileVersions = ("1.0", ) |
42 FileVersions = ("1.0",) |
42 |
43 JsonFileVersions = ("1.0",) |
|
44 |
43 UMLDialogType2String = { |
45 UMLDialogType2String = { |
44 UMLDialogType.CLASS_DIAGRAM: |
46 UMLDialogType.CLASS_DIAGRAM: QCoreApplication.translate( |
45 QCoreApplication.translate("UMLDialog", "Class Diagram"), |
47 "UMLDialog", "Class Diagram" |
46 UMLDialogType.PACKAGE_DIAGRAM: |
48 ), |
47 QCoreApplication.translate("UMLDialog", "Package Diagram"), |
49 UMLDialogType.PACKAGE_DIAGRAM: QCoreApplication.translate( |
48 UMLDialogType.IMPORTS_DIAGRAM: |
50 "UMLDialog", "Package Diagram" |
49 QCoreApplication.translate("UMLDialog", "Imports Diagram"), |
51 ), |
50 UMLDialogType.APPLICATION_DIAGRAM: |
52 UMLDialogType.IMPORTS_DIAGRAM: QCoreApplication.translate( |
51 QCoreApplication.translate("UMLDialog", "Application Diagram"), |
53 "UMLDialog", "Imports Diagram" |
|
54 ), |
|
55 UMLDialogType.APPLICATION_DIAGRAM: QCoreApplication.translate( |
|
56 "UMLDialog", "Application Diagram" |
|
57 ), |
52 } |
58 } |
53 |
59 |
54 def __init__(self, diagramType, project, path="", parent=None, |
60 def __init__( |
55 initBuilder=True, **kwargs): |
61 self, diagramType, project, path="", parent=None, initBuilder=True, **kwargs |
|
62 ): |
56 """ |
63 """ |
57 Constructor |
64 Constructor |
58 |
65 |
59 @param diagramType type of the diagram |
66 @param diagramType type of the diagram |
60 @type UMLDialogType |
67 @type UMLDialogType |
61 @param project reference to the project object |
68 @param project reference to the project object |
62 @type Project |
69 @type Project |
63 @param path file or directory path to build the diagram from |
70 @param path file or directory path to build the diagram from |
70 @keyparam kwargs diagram specific data |
77 @keyparam kwargs diagram specific data |
71 @type dict |
78 @type dict |
72 """ |
79 """ |
73 super().__init__(parent) |
80 super().__init__(parent) |
74 self.setObjectName("UMLDialog") |
81 self.setObjectName("UMLDialog") |
75 |
82 |
76 self.__project = project |
83 self.__project = project |
77 self.__diagramType = diagramType |
84 self.__diagramType = diagramType |
78 |
85 |
79 from .UMLGraphicsView import UMLGraphicsView |
86 from .UMLGraphicsView import UMLGraphicsView |
|
87 |
80 self.scene = QGraphicsScene(0.0, 0.0, 800.0, 600.0) |
88 self.scene = QGraphicsScene(0.0, 0.0, 800.0, 600.0) |
81 self.umlView = UMLGraphicsView(self.scene, parent=self) |
89 self.umlView = UMLGraphicsView(self.scene, parent=self) |
82 self.builder = self.__diagramBuilder( |
90 self.builder = self.__diagramBuilder(self.__diagramType, path, **kwargs) |
83 self.__diagramType, path, **kwargs) |
|
84 if self.builder and initBuilder: |
91 if self.builder and initBuilder: |
85 self.builder.initialize() |
92 self.builder.initialize() |
86 |
93 |
87 self.__fileName = "" |
94 self.__fileName = "" |
88 |
95 |
89 self.__initActions() |
96 self.__initActions() |
90 self.__initToolBars() |
97 self.__initToolBars() |
91 |
98 |
92 self.setCentralWidget(self.umlView) |
99 self.setCentralWidget(self.umlView) |
93 |
100 |
94 self.umlView.relayout.connect(self.__relayout) |
101 self.umlView.relayout.connect(self.__relayout) |
95 |
102 |
96 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
103 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
97 |
104 |
98 def __getDiagramTitel(self, diagramType): |
105 def __getDiagramTitel(self, diagramType): |
99 """ |
106 """ |
100 Private method to get a textual description for the diagram type. |
107 Private method to get a textual description for the diagram type. |
101 |
108 |
102 @param diagramType diagram type string |
109 @param diagramType diagram type string |
103 @type str |
110 @type str |
104 @return titel of the diagram |
111 @return titel of the diagram |
105 @rtype str |
112 @rtype str |
106 """ |
113 """ |
107 return UMLDialog.UMLDialogType2String.get( |
114 return UMLDialog.UMLDialogType2String.get( |
108 diagramType, self.tr("Illegal Diagram Type") |
115 diagramType, self.tr("Illegal Diagram Type") |
109 ) |
116 ) |
110 |
117 |
111 def __initActions(self): |
118 def __initActions(self): |
112 """ |
119 """ |
113 Private slot to initialize the actions. |
120 Private slot to initialize the actions. |
114 """ |
121 """ |
115 self.closeAct = QAction( |
122 self.closeAct = QAction(UI.PixmapCache.getIcon("close"), self.tr("Close"), self) |
116 UI.PixmapCache.getIcon("close"), |
|
117 self.tr("Close"), self) |
|
118 self.closeAct.triggered.connect(self.close) |
123 self.closeAct.triggered.connect(self.close) |
119 |
124 |
120 self.openAct = QAction( |
125 self.openAct = QAction(UI.PixmapCache.getIcon("open"), self.tr("Load"), self) |
121 UI.PixmapCache.getIcon("open"), |
|
122 self.tr("Load"), self) |
|
123 self.openAct.triggered.connect(self.load) |
126 self.openAct.triggered.connect(self.load) |
124 |
127 |
125 self.saveAct = QAction( |
128 self.saveAct = QAction( |
126 UI.PixmapCache.getIcon("fileSave"), |
129 UI.PixmapCache.getIcon("fileSave"), self.tr("Save"), self |
127 self.tr("Save"), self) |
130 ) |
128 self.saveAct.triggered.connect(self.__save) |
131 self.saveAct.triggered.connect(self.__save) |
129 |
132 |
130 self.saveAsAct = QAction( |
133 self.saveAsAct = QAction( |
131 UI.PixmapCache.getIcon("fileSaveAs"), |
134 UI.PixmapCache.getIcon("fileSaveAs"), self.tr("Save As..."), self |
132 self.tr("Save As..."), self) |
135 ) |
133 self.saveAsAct.triggered.connect(self.__saveAs) |
136 self.saveAsAct.triggered.connect(self.__saveAs) |
134 |
137 |
135 self.saveImageAct = QAction( |
138 self.saveImageAct = QAction( |
136 UI.PixmapCache.getIcon("fileSavePixmap"), |
139 UI.PixmapCache.getIcon("fileSavePixmap"), self.tr("Save as Image"), self |
137 self.tr("Save as Image"), self) |
140 ) |
138 self.saveImageAct.triggered.connect(self.umlView.saveImage) |
141 self.saveImageAct.triggered.connect(self.umlView.saveImage) |
139 |
142 |
140 self.printAct = QAction( |
143 self.printAct = QAction(UI.PixmapCache.getIcon("print"), self.tr("Print"), self) |
141 UI.PixmapCache.getIcon("print"), |
|
142 self.tr("Print"), self) |
|
143 self.printAct.triggered.connect(self.umlView.printDiagram) |
144 self.printAct.triggered.connect(self.umlView.printDiagram) |
144 |
145 |
145 self.printPreviewAct = QAction( |
146 self.printPreviewAct = QAction( |
146 UI.PixmapCache.getIcon("printPreview"), |
147 UI.PixmapCache.getIcon("printPreview"), self.tr("Print Preview"), self |
147 self.tr("Print Preview"), self) |
148 ) |
148 self.printPreviewAct.triggered.connect( |
149 self.printPreviewAct.triggered.connect(self.umlView.printPreviewDiagram) |
149 self.umlView.printPreviewDiagram) |
150 |
150 |
|
151 def __initToolBars(self): |
151 def __initToolBars(self): |
152 """ |
152 """ |
153 Private slot to initialize the toolbars. |
153 Private slot to initialize the toolbars. |
154 """ |
154 """ |
155 self.windowToolBar = QToolBar(self.tr("Window"), self) |
155 self.windowToolBar = QToolBar(self.tr("Window"), self) |
156 self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) |
156 self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) |
157 self.windowToolBar.addAction(self.closeAct) |
157 self.windowToolBar.addAction(self.closeAct) |
158 |
158 |
159 self.fileToolBar = QToolBar(self.tr("File"), self) |
159 self.fileToolBar = QToolBar(self.tr("File"), self) |
160 self.fileToolBar.setIconSize(UI.Config.ToolBarIconSize) |
160 self.fileToolBar.setIconSize(UI.Config.ToolBarIconSize) |
161 self.fileToolBar.addAction(self.openAct) |
161 self.fileToolBar.addAction(self.openAct) |
162 self.fileToolBar.addSeparator() |
162 self.fileToolBar.addSeparator() |
163 self.fileToolBar.addAction(self.saveAct) |
163 self.fileToolBar.addAction(self.saveAct) |
164 self.fileToolBar.addAction(self.saveAsAct) |
164 self.fileToolBar.addAction(self.saveAsAct) |
165 self.fileToolBar.addAction(self.saveImageAct) |
165 self.fileToolBar.addAction(self.saveImageAct) |
166 self.fileToolBar.addSeparator() |
166 self.fileToolBar.addSeparator() |
167 self.fileToolBar.addAction(self.printPreviewAct) |
167 self.fileToolBar.addAction(self.printPreviewAct) |
168 self.fileToolBar.addAction(self.printAct) |
168 self.fileToolBar.addAction(self.printAct) |
169 |
169 |
170 self.umlToolBar = self.umlView.initToolBar() |
170 self.umlToolBar = self.umlView.initToolBar() |
171 |
171 |
172 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.fileToolBar) |
172 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.fileToolBar) |
173 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.windowToolBar) |
173 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.windowToolBar) |
174 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.umlToolBar) |
174 self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.umlToolBar) |
175 |
175 |
176 def show(self, fromFile=False): |
176 def show(self, fromFile=False): |
177 """ |
177 """ |
178 Public method to show the dialog. |
178 Public method to show the dialog. |
179 |
179 |
180 @param fromFile flag indicating, that the diagram was loaded |
180 @param fromFile flag indicating, that the diagram was loaded |
181 from file |
181 from file |
182 @type bool |
182 @type bool |
183 """ |
183 """ |
184 if not fromFile and self.builder: |
184 if not fromFile and self.builder: |
185 self.builder.buildDiagram() |
185 self.builder.buildDiagram() |
186 super().show() |
186 super().show() |
187 |
187 |
188 def __relayout(self): |
188 def __relayout(self): |
189 """ |
189 """ |
190 Private method to re-layout the diagram. |
190 Private method to re-layout the diagram. |
191 """ |
191 """ |
192 if self.builder: |
192 if self.builder: |
193 self.builder.buildDiagram() |
193 self.builder.buildDiagram() |
194 |
194 |
195 def __diagramBuilder(self, diagramType, path, **kwargs): |
195 def __diagramBuilder(self, diagramType, path, **kwargs): |
196 """ |
196 """ |
197 Private method to instantiate a diagram builder object. |
197 Private method to instantiate a diagram builder object. |
198 |
198 |
199 @param diagramType type of the diagram |
199 @param diagramType type of the diagram |
200 @type UMLDialogType |
200 @type UMLDialogType |
201 @param path file or directory path to build the diagram from |
201 @param path file or directory path to build the diagram from |
202 @type str |
202 @type str |
203 @keyparam kwargs diagram specific data |
203 @keyparam kwargs diagram specific data |
205 @return reference to the instantiated diagram builder |
205 @return reference to the instantiated diagram builder |
206 @rtype UMLDiagramBuilder |
206 @rtype UMLDiagramBuilder |
207 """ |
207 """ |
208 if diagramType == UMLDialogType.CLASS_DIAGRAM: |
208 if diagramType == UMLDialogType.CLASS_DIAGRAM: |
209 from .UMLClassDiagramBuilder import UMLClassDiagramBuilder |
209 from .UMLClassDiagramBuilder import UMLClassDiagramBuilder |
|
210 |
210 return UMLClassDiagramBuilder( |
211 return UMLClassDiagramBuilder( |
211 self, self.umlView, self.__project, path, **kwargs) |
212 self, self.umlView, self.__project, path, **kwargs |
|
213 ) |
212 elif diagramType == UMLDialogType.PACKAGE_DIAGRAM: |
214 elif diagramType == UMLDialogType.PACKAGE_DIAGRAM: |
213 from .PackageDiagramBuilder import PackageDiagramBuilder |
215 from .PackageDiagramBuilder import PackageDiagramBuilder |
|
216 |
214 return PackageDiagramBuilder( |
217 return PackageDiagramBuilder( |
215 self, self.umlView, self.__project, path, **kwargs) |
218 self, self.umlView, self.__project, path, **kwargs |
|
219 ) |
216 elif diagramType == UMLDialogType.IMPORTS_DIAGRAM: |
220 elif diagramType == UMLDialogType.IMPORTS_DIAGRAM: |
217 from .ImportsDiagramBuilder import ImportsDiagramBuilder |
221 from .ImportsDiagramBuilder import ImportsDiagramBuilder |
|
222 |
218 return ImportsDiagramBuilder( |
223 return ImportsDiagramBuilder( |
219 self, self.umlView, self.__project, path, **kwargs) |
224 self, self.umlView, self.__project, path, **kwargs |
|
225 ) |
220 elif diagramType == UMLDialogType.APPLICATION_DIAGRAM: |
226 elif diagramType == UMLDialogType.APPLICATION_DIAGRAM: |
221 from .ApplicationDiagramBuilder import ApplicationDiagramBuilder |
227 from .ApplicationDiagramBuilder import ApplicationDiagramBuilder |
|
228 |
222 return ApplicationDiagramBuilder( |
229 return ApplicationDiagramBuilder( |
223 self, self.umlView, self.__project, **kwargs) |
230 self, self.umlView, self.__project, **kwargs |
|
231 ) |
224 else: |
232 else: |
225 return None |
233 return None |
226 |
234 |
227 def __save(self): |
235 def __save(self): |
228 """ |
236 """ |
229 Private slot to save the diagram with the current name. |
237 Private slot to save the diagram with the current name. |
230 """ |
238 """ |
231 self.__saveAs(self.__fileName) |
239 self.__saveAs(self.__fileName) |
232 |
240 |
233 @pyqtSlot() |
241 @pyqtSlot() |
234 def __saveAs(self, filename=""): |
242 def __saveAs(self, filename=""): |
235 """ |
243 """ |
236 Private slot to save the diagram. |
244 Private slot to save the diagram. |
237 |
245 |
238 @param filename name of the file to write to |
246 @param filename name of the file to write to |
239 @type str |
247 @type str |
240 """ |
248 """ |
241 if not filename: |
249 if not filename: |
242 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
250 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
243 self, |
251 self, |
244 self.tr("Save Diagram"), |
252 self.tr("Save Diagram"), |
245 "", |
253 "", |
246 self.tr("Eric Graphics File (*.egj);;" |
254 self.tr( |
247 "Eric Text Graphics File (*.e5g);;" |
255 "Eric Graphics File (*.egj);;" |
248 "All Files (*)"), |
256 "Eric Text Graphics File (*.e5g);;" |
|
257 "All Files (*)" |
|
258 ), |
249 "", |
259 "", |
250 EricFileDialog.DontConfirmOverwrite) |
260 EricFileDialog.DontConfirmOverwrite, |
|
261 ) |
251 if not fname: |
262 if not fname: |
252 return |
263 return |
253 |
264 |
254 fpath = pathlib.Path(fname) |
265 fpath = pathlib.Path(fname) |
255 if not fpath.suffix: |
266 if not fpath.suffix: |
256 ex = selectedFilter.split("(*")[1].split(")")[0] |
267 ex = selectedFilter.split("(*")[1].split(")")[0] |
257 if ex: |
268 if ex: |
258 fpath = fpath.with_suffix(ex) |
269 fpath = fpath.with_suffix(ex) |
259 if fpath.exists(): |
270 if fpath.exists(): |
260 res = EricMessageBox.yesNo( |
271 res = EricMessageBox.yesNo( |
261 self, |
272 self, |
262 self.tr("Save Diagram"), |
273 self.tr("Save Diagram"), |
263 self.tr("<p>The file <b>{0}</b> already exists." |
274 self.tr( |
264 " Overwrite it?</p>").format(fpath), |
275 "<p>The file <b>{0}</b> already exists." " Overwrite it?</p>" |
265 icon=EricMessageBox.Warning) |
276 ).format(fpath), |
|
277 icon=EricMessageBox.Warning, |
|
278 ) |
266 if not res: |
279 if not res: |
267 return |
280 return |
268 filename = str(fpath) |
281 filename = str(fpath) |
269 |
282 |
270 res = self.__writeJsonGraphicsFile(filename) |
283 res = self.__writeJsonGraphicsFile(filename) |
271 |
284 |
272 if res: |
285 if res: |
273 # save the file name only in case of success |
286 # save the file name only in case of success |
274 self.__fileName = filename |
287 self.__fileName = filename |
275 |
288 |
276 # Note: remove loading of eric6 line based diagram format after 22.6 |
289 # Note: remove loading of eric6 line based diagram format after 22.6 |
277 def load(self, filename=""): |
290 def load(self, filename=""): |
278 """ |
291 """ |
279 Public method to load a diagram from a file. |
292 Public method to load a diagram from a file. |
280 |
293 |
281 @param filename name of the file to be loaded |
294 @param filename name of the file to be loaded |
282 @type str |
295 @type str |
283 @return flag indicating success |
296 @return flag indicating success |
284 @rtype bool |
297 @rtype bool |
285 """ |
298 """ |
286 if not filename: |
299 if not filename: |
287 filename = EricFileDialog.getOpenFileName( |
300 filename = EricFileDialog.getOpenFileName( |
288 self, |
301 self, |
289 self.tr("Load Diagram"), |
302 self.tr("Load Diagram"), |
290 "", |
303 "", |
291 self.tr("Eric Graphics File (*.egj);;" |
304 self.tr( |
292 "Eric Text Graphics File (*.e5g);;" |
305 "Eric Graphics File (*.egj);;" |
293 "All Files (*)")) |
306 "Eric Text Graphics File (*.e5g);;" |
|
307 "All Files (*)" |
|
308 ), |
|
309 ) |
294 if not filename: |
310 if not filename: |
295 # Canceled by user |
311 # Canceled by user |
296 return False |
312 return False |
297 |
313 |
298 return ( |
314 return ( |
299 self.__readLineBasedGraphicsFile(filename) |
315 self.__readLineBasedGraphicsFile(filename) |
300 if filename.endswith(".e5g") else |
316 if filename.endswith(".e5g") |
|
317 else |
301 # JSON format is the default |
318 # JSON format is the default |
302 self.__readJsonGraphicsFile(filename) |
319 self.__readJsonGraphicsFile(filename) |
303 ) |
320 ) |
304 |
321 |
305 ####################################################################### |
322 ####################################################################### |
306 ## Methods to read and write eric graphics files of the old line |
323 ## Methods to read and write eric graphics files of the old line |
307 ## based file format. |
324 ## based file format. |
308 ####################################################################### |
325 ####################################################################### |
309 |
326 |
310 def __readLineBasedGraphicsFile(self, filename): |
327 def __readLineBasedGraphicsFile(self, filename): |
311 """ |
328 """ |
312 Private method to read an eric graphics file using the old line |
329 Private method to read an eric graphics file using the old line |
313 based file format. |
330 based file format. |
314 |
331 |
315 @param filename name of the file to be read |
332 @param filename name of the file to be read |
316 @type str |
333 @type str |
317 @return flag indicating success |
334 @return flag indicating success |
318 @rtype bool |
335 @rtype bool |
319 """ |
336 """ |
372 width, height = [float(v.strip()) for v in value.split(";")] |
388 width, height = [float(v.strip()) for v in value.split(";")] |
373 except ValueError: |
389 except ValueError: |
374 self.__showInvalidDataMessage(filename, linenum) |
390 self.__showInvalidDataMessage(filename, linenum) |
375 return False |
391 return False |
376 self.umlView.setSceneSize(width, height) |
392 self.umlView.setSceneSize(width, height) |
377 |
393 |
378 # step 4: extract builder data if available |
394 # step 4: extract builder data if available |
379 linenum += 1 |
395 linenum += 1 |
380 key, value = lines[linenum].split(": ", 1) |
396 key, value = lines[linenum].split(": ", 1) |
381 if key.strip() == "builder_data": |
397 if key.strip() == "builder_data": |
382 ok = self.builder.parsePersistenceData(version, value) |
398 ok = self.builder.parsePersistenceData(version, value) |
383 if not ok: |
399 if not ok: |
384 self.__showInvalidDataMessage(filename, linenum) |
400 self.__showInvalidDataMessage(filename, linenum) |
385 return False |
401 return False |
386 linenum += 1 |
402 linenum += 1 |
387 |
403 |
388 # step 5: extract the graphics items |
404 # step 5: extract the graphics items |
389 ok, vlinenum = self.umlView.parsePersistenceData( |
405 ok, vlinenum = self.umlView.parsePersistenceData(version, lines[linenum:]) |
390 version, lines[linenum:]) |
|
391 if not ok: |
406 if not ok: |
392 self.__showInvalidDataMessage(filename, linenum + vlinenum) |
407 self.__showInvalidDataMessage(filename, linenum + vlinenum) |
393 return False |
408 return False |
394 |
409 |
395 except IndexError: |
410 except IndexError: |
396 self.__showInvalidDataMessage(filename) |
411 self.__showInvalidDataMessage(filename) |
397 return False |
412 return False |
398 |
413 |
399 # everything worked fine, so remember the file name and set the |
414 # everything worked fine, so remember the file name and set the |
400 # window title |
415 # window title |
401 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
416 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
402 self.__fileName = filename |
417 self.__fileName = filename |
403 |
418 |
404 return True |
419 return True |
405 |
420 |
406 def __showInvalidDataMessage(self, filename, linenum=-1): |
421 def __showInvalidDataMessage(self, filename, linenum=-1): |
407 """ |
422 """ |
408 Private slot to show a message dialog indicating an invalid data file. |
423 Private slot to show a message dialog indicating an invalid data file. |
409 |
424 |
410 @param filename name of the file containing the invalid data |
425 @param filename name of the file containing the invalid data |
411 @type str |
426 @type str |
412 @param linenum number of the invalid line |
427 @param linenum number of the invalid line |
413 @type int |
428 @type int |
414 """ |
429 """ |
415 msg = ( |
430 msg = ( |
416 self.tr("""<p>The file <b>{0}</b> does not contain""" |
431 self.tr( |
417 """ valid data.</p>""").format(filename) |
432 """<p>The file <b>{0}</b> does not contain""" """ valid data.</p>""" |
418 if linenum < 0 else |
433 ).format(filename) |
419 self.tr("""<p>The file <b>{0}</b> does not contain""" |
434 if linenum < 0 |
420 """ valid data.</p><p>Invalid line: {1}</p>""" |
435 else self.tr( |
421 ).format(filename, linenum + 1) |
436 """<p>The file <b>{0}</b> does not contain""" |
|
437 """ valid data.</p><p>Invalid line: {1}</p>""" |
|
438 ).format(filename, linenum + 1) |
422 ) |
439 ) |
423 EricMessageBox.critical(self, self.tr("Load Diagram"), msg) |
440 EricMessageBox.critical(self, self.tr("Load Diagram"), msg) |
424 |
441 |
425 ####################################################################### |
442 ####################################################################### |
426 ## Methods to read and write eric graphics files of the JSON based |
443 ## Methods to read and write eric graphics files of the JSON based |
427 ## file format. |
444 ## file format. |
428 ####################################################################### |
445 ####################################################################### |
429 |
446 |
430 def __writeJsonGraphicsFile(self, filename): |
447 def __writeJsonGraphicsFile(self, filename): |
431 """ |
448 """ |
432 Private method to write an eric graphics file using the JSON based |
449 Private method to write an eric graphics file using the JSON based |
433 file format. |
450 file format. |
434 |
451 |
435 @param filename name of the file to write to |
452 @param filename name of the file to write to |
436 @type str |
453 @type str |
437 @return flag indicating a successful write |
454 @return flag indicating a successful write |
438 @rtype bool |
455 @rtype bool |
439 """ |
456 """ |
480 EricMessageBox.critical( |
498 EricMessageBox.critical( |
481 None, |
499 None, |
482 self.tr("Load Diagram"), |
500 self.tr("Load Diagram"), |
483 self.tr( |
501 self.tr( |
484 """<p>The file <b>{0}</b> could not be read.</p>""" |
502 """<p>The file <b>{0}</b> could not be read.</p>""" |
485 """<p>Reason: {1}</p>""").format(filename, str(err)) |
503 """<p>Reason: {1}</p>""" |
|
504 ).format(filename, str(err)), |
486 ) |
505 ) |
487 return False |
506 return False |
488 |
507 |
489 try: |
508 try: |
490 # step 1: check version |
509 # step 1: check version |
491 if data["version"] in UMLDialog.JsonFileVersions: |
510 if data["version"] in UMLDialog.JsonFileVersions: |
492 version = data["version"] |
511 version = data["version"] |
493 else: |
512 else: |
494 self.__showInvalidDataMessage(filename) |
513 self.__showInvalidDataMessage(filename) |
495 return False |
514 return False |
496 |
515 |
497 # step 2: set diagram type |
516 # step 2: set diagram type |
498 try: |
517 try: |
499 self.__diagramType = UMLDialogType(data["type"]) |
518 self.__diagramType = UMLDialogType(data["type"]) |
500 except ValueError: |
519 except ValueError: |
501 self.__showInvalidDataMessage(filename) |
520 self.__showInvalidDataMessage(filename) |
502 return False |
521 return False |
503 self.scene.clear() |
522 self.scene.clear() |
504 self.builder = self.__diagramBuilder(self.__diagramType, "") |
523 self.builder = self.__diagramBuilder(self.__diagramType, "") |
505 |
524 |
506 # step 3: set scene size |
525 # step 3: set scene size |
507 self.umlView.setSceneSize(data["width"], data["height"]) |
526 self.umlView.setSceneSize(data["width"], data["height"]) |
508 |
527 |
509 # step 4: extract builder data if available |
528 # step 4: extract builder data if available |
510 ok, msg = self.builder.fromDict(version, data["builder"]) |
529 ok, msg = self.builder.fromDict(version, data["builder"]) |
511 if not ok: |
530 if not ok: |
512 if msg: |
531 if msg: |
513 res = EricMessageBox.warning( |
532 res = EricMessageBox.warning( |
514 self, |
533 self, |
515 self.tr("Load Diagram"), |
534 self.tr("Load Diagram"), |
516 msg, |
535 msg, |
517 EricMessageBox.Abort | EricMessageBox.Ignore, |
536 EricMessageBox.Abort | EricMessageBox.Ignore, |
518 EricMessageBox.Abort) |
537 EricMessageBox.Abort, |
|
538 ) |
519 if res == EricMessageBox.Abort: |
539 if res == EricMessageBox.Abort: |
520 return False |
540 return False |
521 else: |
541 else: |
522 self.umlView.setLayoutActionsEnabled(False) |
542 self.umlView.setLayoutActionsEnabled(False) |
523 else: |
543 else: |
524 self.__showInvalidDataMessage(filename) |
544 self.__showInvalidDataMessage(filename) |
525 return False |
545 return False |
526 |
546 |
527 # step 5: extract the graphics items |
547 # step 5: extract the graphics items |
528 ok = self.umlView.fromDict(version, data["view"]) |
548 ok = self.umlView.fromDict(version, data["view"]) |
529 if not ok: |
549 if not ok: |
530 self.__showInvalidDataMessage(filename) |
550 self.__showInvalidDataMessage(filename) |
531 return False |
551 return False |
532 except KeyError: |
552 except KeyError: |
533 self.__showInvalidDataMessage(filename) |
553 self.__showInvalidDataMessage(filename) |
534 return False |
554 return False |
535 |
555 |
536 # everything worked fine, so remember the file name and set the |
556 # everything worked fine, so remember the file name and set the |
537 # window title |
557 # window title |
538 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
558 self.setWindowTitle(self.__getDiagramTitel(self.__diagramType)) |
539 self.__fileName = filename |
559 self.__fileName = filename |
540 |
560 |
541 return True |
561 return True |