40 shown |
41 shown |
41 @type bool |
42 @type bool |
42 """ |
43 """ |
43 super().__init__(dialog, view, project) |
44 super().__init__(dialog, view, project) |
44 self.setObjectName("ApplicationDiagram") |
45 self.setObjectName("ApplicationDiagram") |
45 |
46 |
46 self.noModules = noModules |
47 self.noModules = noModules |
47 |
48 |
48 self.umlView.setDiagramName( |
49 self.umlView.setDiagramName( |
49 self.tr("Application Diagram {0}").format( |
50 self.tr("Application Diagram {0}").format(self.project.getProjectName()) |
50 self.project.getProjectName())) |
51 ) |
51 |
52 |
52 def __buildModulesDict(self): |
53 def __buildModulesDict(self): |
53 """ |
54 """ |
54 Private method to build a dictionary of modules contained in the |
55 Private method to build a dictionary of modules contained in the |
55 application. |
56 application. |
56 |
57 |
57 @return dictionary of modules contained in the application |
58 @return dictionary of modules contained in the application |
58 @rtype dict |
59 @rtype dict |
59 """ |
60 """ |
60 import Utilities.ModuleParser |
61 import Utilities.ModuleParser |
61 extensions = ( |
62 |
62 Preferences.getPython("Python3Extensions") + |
63 extensions = Preferences.getPython("Python3Extensions") + [".rb"] |
63 ['.rb'] |
|
64 ) |
|
65 moduleDict = {} |
64 moduleDict = {} |
66 mods = self.project.pdata["SOURCES"] |
65 mods = self.project.pdata["SOURCES"] |
67 modules = [] |
66 modules = [] |
68 for module in mods: |
67 for module in mods: |
69 modules.append(Utilities.normabsjoinpath( |
68 modules.append(Utilities.normabsjoinpath(self.project.ppath, module)) |
70 self.project.ppath, module)) |
|
71 tot = len(modules) |
69 tot = len(modules) |
72 progress = EricProgressDialog( |
70 progress = EricProgressDialog( |
73 self.tr("Parsing modules..."), |
71 self.tr("Parsing modules..."), |
74 None, 0, tot, self.tr("%v/%m Modules"), self.parent()) |
72 None, |
|
73 0, |
|
74 tot, |
|
75 self.tr("%v/%m Modules"), |
|
76 self.parent(), |
|
77 ) |
75 progress.setWindowTitle(self.tr("Application Diagram")) |
78 progress.setWindowTitle(self.tr("Application Diagram")) |
76 try: |
79 try: |
77 progress.show() |
80 progress.show() |
78 QApplication.processEvents() |
81 QApplication.processEvents() |
79 |
82 |
80 now = time.monotonic() |
83 now = time.monotonic() |
81 for prog, module in enumerate(modules): |
84 for prog, module in enumerate(modules): |
82 progress.setValue(prog) |
85 progress.setValue(prog) |
83 if time.monotonic() - now > 0.01: |
86 if time.monotonic() - now > 0.01: |
84 QApplication.processEvents() |
87 QApplication.processEvents() |
85 now = time.monotonic() |
88 now = time.monotonic() |
86 if module.endswith("__init__.py"): |
89 if module.endswith("__init__.py"): |
87 continue |
90 continue |
88 try: |
91 try: |
89 mod = Utilities.ModuleParser.readModule( |
92 mod = Utilities.ModuleParser.readModule( |
90 module, extensions=extensions, caching=False) |
93 module, extensions=extensions, caching=False |
|
94 ) |
91 except ImportError: |
95 except ImportError: |
92 continue |
96 continue |
93 else: |
97 else: |
94 name = mod.name |
98 name = mod.name |
95 moduleDict[name] = mod |
99 moduleDict[name] = mod |
96 finally: |
100 finally: |
97 progress.setValue(tot) |
101 progress.setValue(tot) |
98 progress.deleteLater() |
102 progress.deleteLater() |
99 return moduleDict |
103 return moduleDict |
100 |
104 |
101 def __findApplicationRoot(self): |
105 def __findApplicationRoot(self): |
102 """ |
106 """ |
103 Private method to find the application root path. |
107 Private method to find the application root path. |
104 |
108 |
105 @return application root path |
109 @return application root path |
106 @rtype str |
110 @rtype str |
107 """ |
111 """ |
108 candidates = [] |
112 candidates = [] |
109 path = self.project.getProjectPath() |
113 path = self.project.getProjectPath() |
117 fullpath = os.path.join(path, entry) |
121 fullpath = os.path.join(path, entry) |
118 if os.path.isdir(fullpath): |
122 if os.path.isdir(fullpath): |
119 init = os.path.join(fullpath, "__init__.py") |
123 init = os.path.join(fullpath, "__init__.py") |
120 if os.path.exists(init): |
124 if os.path.exists(init): |
121 candidates.append(fullpath) |
125 candidates.append(fullpath) |
122 |
126 |
123 # check, if project uses the 'src' layout |
127 # check, if project uses the 'src' layout |
124 if os.path.exists(os.path.join(path, "src")): |
128 if os.path.exists(os.path.join(path, "src")): |
125 srcPath = os.path.join(path, "src") |
129 srcPath = os.path.join(path, "src") |
126 for entry in [e for e in os.listdir(srcPath) if not e.startswith(".")]: |
130 for entry in [e for e in os.listdir(srcPath) if not e.startswith(".")]: |
127 fullpath = os.path.join(srcPath, entry) |
131 fullpath = os.path.join(srcPath, entry) |
128 if os.path.isdir(fullpath): |
132 if os.path.isdir(fullpath): |
129 init = os.path.join(fullpath, "__init__.py") |
133 init = os.path.join(fullpath, "__init__.py") |
130 if os.path.exists(init): |
134 if os.path.exists(init): |
131 candidates.append(fullpath) |
135 candidates.append(fullpath) |
132 |
136 |
133 if len(candidates) == 1: |
137 if len(candidates) == 1: |
134 return candidates[0] |
138 return candidates[0] |
135 elif len(candidates) > 1: |
139 elif len(candidates) > 1: |
136 root, ok = QInputDialog.getItem( |
140 root, ok = QInputDialog.getItem( |
137 None, |
141 None, |
138 self.tr("Application Diagram"), |
142 self.tr("Application Diagram"), |
139 self.tr("Select the application directory:"), |
143 self.tr("Select the application directory:"), |
140 sorted(candidates), |
144 sorted(candidates), |
141 0, True) |
145 0, |
|
146 True, |
|
147 ) |
142 if ok: |
148 if ok: |
143 return root |
149 return root |
144 else: |
150 else: |
145 EricMessageBox.warning( |
151 EricMessageBox.warning( |
146 None, |
152 None, |
147 self.tr("Application Diagram"), |
153 self.tr("Application Diagram"), |
148 self.tr("""No application package could be detected.""" |
154 self.tr( |
149 """ Aborting...""")) |
155 """No application package could be detected.""" |
|
156 """ Aborting...""" |
|
157 ), |
|
158 ) |
150 return None |
159 return None |
151 |
160 |
152 def buildDiagram(self): |
161 def buildDiagram(self): |
153 """ |
162 """ |
154 Public method to build the packages shapes of the diagram. |
163 Public method to build the packages shapes of the diagram. |
155 """ |
164 """ |
156 rpath = self.__findApplicationRoot() |
165 rpath = self.__findApplicationRoot() |
157 if rpath is None: |
166 if rpath is None: |
158 # no root path detected |
167 # no root path detected |
159 return |
168 return |
160 |
169 |
161 root = os.path.splitdrive(rpath)[1].replace(os.sep, '.')[1:] |
170 root = os.path.splitdrive(rpath)[1].replace(os.sep, ".")[1:] |
162 |
171 |
163 packages = {} |
172 packages = {} |
164 self.__shapes = {} |
173 self.__shapes = {} |
165 |
174 |
166 modules = self.__buildModulesDict() |
175 modules = self.__buildModulesDict() |
167 |
176 |
168 # step 1: build a dictionary of packages |
177 # step 1: build a dictionary of packages |
169 for module in sorted(modules.keys()): |
178 for module in sorted(modules.keys()): |
170 if "." in module: |
179 if "." in module: |
171 packageName, moduleName = module.rsplit(".", 1) |
180 packageName, moduleName = module.rsplit(".", 1) |
172 else: |
181 else: |
173 packageName, moduleName = "", module |
182 packageName, moduleName = "", module |
174 if packageName in packages: |
183 if packageName in packages: |
175 packages[packageName][0].append(moduleName) |
184 packages[packageName][0].append(moduleName) |
176 else: |
185 else: |
177 packages[packageName] = ([moduleName], []) |
186 packages[packageName] = ([moduleName], []) |
178 |
187 |
179 # step 2: assign modules to dictionaries and update import relationship |
188 # step 2: assign modules to dictionaries and update import relationship |
180 for module in sorted(modules.keys()): |
189 for module in sorted(modules.keys()): |
181 package = module.rsplit(".", 1)[0] |
190 package = module.rsplit(".", 1)[0] |
182 impLst = [] |
191 impLst = [] |
183 for moduleImport in modules[module].imports: |
192 for moduleImport in modules[module].imports: |
184 if moduleImport in modules: |
193 if moduleImport in modules: |
185 impLst.append(moduleImport) |
194 impLst.append(moduleImport) |
186 else: |
195 else: |
187 if moduleImport.find('.') == -1: |
196 if moduleImport.find(".") == -1: |
188 n = "{0}.{1}".format(modules[module].package, |
197 n = "{0}.{1}".format(modules[module].package, moduleImport) |
189 moduleImport) |
|
190 if n in modules: |
198 if n in modules: |
191 impLst.append(n) |
199 impLst.append(n) |
192 else: |
200 else: |
193 n = "{0}.{1}".format(root, moduleImport) |
201 n = "{0}.{1}".format(root, moduleImport) |
194 if n in modules: |
202 if n in modules: |
199 else: |
207 else: |
200 n = "{0}.{1}".format(root, moduleImport) |
208 n = "{0}.{1}".format(root, moduleImport) |
201 if n in modules: |
209 if n in modules: |
202 impLst.append(n) |
210 impLst.append(n) |
203 for moduleImport in list(modules[module].from_imports.keys()): |
211 for moduleImport in list(modules[module].from_imports.keys()): |
204 if moduleImport.startswith('.'): |
212 if moduleImport.startswith("."): |
205 dots = len(moduleImport) - len(moduleImport.lstrip('.')) |
213 dots = len(moduleImport) - len(moduleImport.lstrip(".")) |
206 if dots == 1: |
214 if dots == 1: |
207 moduleImport = moduleImport[1:] |
215 moduleImport = moduleImport[1:] |
208 elif dots > 1: |
216 elif dots > 1: |
209 packagePath = os.path.dirname(modules[module].file) |
217 packagePath = os.path.dirname(modules[module].file) |
210 hasInit = True |
218 hasInit = True |
211 ppath = packagePath |
219 ppath = packagePath |
212 while hasInit: |
220 while hasInit: |
213 ppath = os.path.dirname(ppath) |
221 ppath = os.path.dirname(ppath) |
214 hasInit = len(glob.glob(os.path.join( |
222 hasInit = ( |
215 ppath, '__init__.*'))) > 0 |
223 len(glob.glob(os.path.join(ppath, "__init__.*"))) > 0 |
216 shortPackage = ( |
224 ) |
217 packagePath.replace(ppath, '') |
225 shortPackage = packagePath.replace(ppath, "").replace( |
218 .replace(os.sep, '.')[1:] |
226 os.sep, "." |
|
227 )[1:] |
|
228 packageList = shortPackage.split(".")[1:] |
|
229 packageListLen = len(packageList) |
|
230 moduleImport = ".".join( |
|
231 packageList[: packageListLen - dots + 1] |
|
232 + [moduleImport[dots:]] |
219 ) |
233 ) |
220 packageList = shortPackage.split('.')[1:] |
234 |
221 packageListLen = len(packageList) |
|
222 moduleImport = '.'.join( |
|
223 packageList[:packageListLen - dots + 1] + |
|
224 [moduleImport[dots:]]) |
|
225 |
|
226 if moduleImport in modules: |
235 if moduleImport in modules: |
227 impLst.append(moduleImport) |
236 impLst.append(moduleImport) |
228 else: |
237 else: |
229 if moduleImport.find('.') == -1: |
238 if moduleImport.find(".") == -1: |
230 n = "{0}.{1}".format(modules[module].package, |
239 n = "{0}.{1}".format(modules[module].package, moduleImport) |
231 moduleImport) |
|
232 if n in modules: |
240 if n in modules: |
233 impLst.append(n) |
241 impLst.append(n) |
234 else: |
242 else: |
235 n = "{0}.{1}".format(root, moduleImport) |
243 n = "{0}.{1}".format(root, moduleImport) |
236 if n in modules: |
244 if n in modules: |
243 if n in modules: |
251 if n in modules: |
244 impLst.append(n) |
252 impLst.append(n) |
245 for moduleImport in impLst: |
253 for moduleImport in impLst: |
246 impPackage = moduleImport.rsplit(".", 1)[0] |
254 impPackage = moduleImport.rsplit(".", 1)[0] |
247 try: |
255 try: |
248 if ( |
256 if impPackage not in packages[package][1] and impPackage != package: |
249 impPackage not in packages[package][1] and |
|
250 impPackage != package |
|
251 ): |
|
252 packages[package][1].append(impPackage) |
257 packages[package][1].append(impPackage) |
253 except KeyError: |
258 except KeyError: |
254 continue |
259 continue |
255 |
260 |
256 for package in sorted(packages.keys()): |
261 for package in sorted(packages.keys()): |
257 if package: |
262 if package: |
258 relPackage = package.replace(root, '') |
263 relPackage = package.replace(root, "") |
259 if relPackage and relPackage[0] == '.': |
264 if relPackage and relPackage[0] == ".": |
260 relPackage = relPackage[1:] |
265 relPackage = relPackage[1:] |
261 else: |
266 else: |
262 relPackage = self.tr("<<Application>>") |
267 relPackage = self.tr("<<Application>>") |
263 else: |
268 else: |
264 relPackage = self.tr("<<Others>>") |
269 relPackage = self.tr("<<Others>>") |
265 shape = self.__addPackage( |
270 shape = self.__addPackage(relPackage, packages[package][0], 0.0, 0.0) |
266 relPackage, packages[package][0], 0.0, 0.0) |
|
267 self.__shapes[package] = (shape, packages[package][1]) |
271 self.__shapes[package] = (shape, packages[package][1]) |
268 |
272 |
269 # build a list of routes |
273 # build a list of routes |
270 nodes = [] |
274 nodes = [] |
271 routes = [] |
275 routes = [] |
272 for module in self.__shapes: |
276 for module in self.__shapes: |
273 nodes.append(module) |
277 nodes.append(module) |
274 for rel in self.__shapes[module][1]: |
278 for rel in self.__shapes[module][1]: |
275 route = (module, rel) |
279 route = (module, rel) |
276 if route not in routes: |
280 if route not in routes: |
277 routes.append(route) |
281 routes.append(route) |
278 |
282 |
279 self.__arrangeNodes(nodes, routes[:]) |
283 self.__arrangeNodes(nodes, routes[:]) |
280 self.__createAssociations(routes) |
284 self.__createAssociations(routes) |
281 self.umlView.autoAdjustSceneSize(limit=True) |
285 self.umlView.autoAdjustSceneSize(limit=True) |
282 |
286 |
283 def __addPackage(self, name, modules, x, y): |
287 def __addPackage(self, name, modules, x, y): |
284 """ |
288 """ |
285 Private method to add a package to the diagram. |
289 Private method to add a package to the diagram. |
286 |
290 |
287 @param name package name to be shown |
291 @param name package name to be shown |
288 @type str |
292 @type str |
289 @param modules list of module names contained in the package |
293 @param modules list of module names contained in the package |
290 @type list of str |
294 @type list of str |
291 @param x x-coordinate |
295 @param x x-coordinate |
294 @type float |
298 @type float |
295 @return reference to the package item |
299 @return reference to the package item |
296 @rtype PackageItem |
300 @rtype PackageItem |
297 """ |
301 """ |
298 from .PackageItem import PackageItem, PackageModel |
302 from .PackageItem import PackageItem, PackageModel |
|
303 |
299 modules.sort() |
304 modules.sort() |
300 pm = PackageModel(name, modules) |
305 pm = PackageModel(name, modules) |
301 pw = PackageItem(pm, x, y, noModules=self.noModules, scene=self.scene, |
306 pw = PackageItem( |
302 colors=self.umlView.getDrawingColors()) |
307 pm, |
|
308 x, |
|
309 y, |
|
310 noModules=self.noModules, |
|
311 scene=self.scene, |
|
312 colors=self.umlView.getDrawingColors(), |
|
313 ) |
303 pw.setId(self.umlView.getItemId()) |
314 pw.setId(self.umlView.getItemId()) |
304 return pw |
315 return pw |
305 |
316 |
306 def __arrangeNodes(self, nodes, routes, whiteSpaceFactor=1.2): |
317 def __arrangeNodes(self, nodes, routes, whiteSpaceFactor=1.2): |
307 """ |
318 """ |
308 Private method to arrange the shapes on the canvas. |
319 Private method to arrange the shapes on the canvas. |
309 |
320 |
310 The algorithm is borrowed from Boa Constructor. |
321 The algorithm is borrowed from Boa Constructor. |
311 |
322 |
312 @param nodes list of nodes to arrange |
323 @param nodes list of nodes to arrange |
313 @type list of str |
324 @type list of str |
314 @param routes list of routes |
325 @param routes list of routes |
315 @type list of tuple of (str, str) |
326 @type list of tuple of (str, str) |
316 @param whiteSpaceFactor factor to increase whitespace between |
327 @param whiteSpaceFactor factor to increase whitespace between |
317 items |
328 items |
318 @type float |
329 @type float |
319 """ |
330 """ |
320 from . import GraphicsUtilities |
331 from . import GraphicsUtilities |
|
332 |
321 generations = GraphicsUtilities.sort(nodes, routes) |
333 generations = GraphicsUtilities.sort(nodes, routes) |
322 |
334 |
323 # calculate width and height of all elements |
335 # calculate width and height of all elements |
324 sizes = [] |
336 sizes = [] |
325 for generation in generations: |
337 for generation in generations: |
326 sizes.append([]) |
338 sizes.append([]) |
327 for child in generation: |
339 for child in generation: |
328 sizes[-1].append( |
340 sizes[-1].append(self.__shapes[child][0].sceneBoundingRect()) |
329 self.__shapes[child][0].sceneBoundingRect()) |
341 |
330 |
|
331 # calculate total width and total height |
342 # calculate total width and total height |
332 width = 0 |
343 width = 0 |
333 height = 0 |
344 height = 0 |
334 widths = [] |
345 widths = [] |
335 heights = [] |
346 heights = [] |
336 for generation in sizes: |
347 for generation in sizes: |
337 currentWidth = 0 |
348 currentWidth = 0 |
338 currentHeight = 0 |
349 currentHeight = 0 |
339 |
350 |
340 for rect in generation: |
351 for rect in generation: |
341 if rect.height() > currentHeight: |
352 if rect.height() > currentHeight: |
342 currentHeight = rect.height() |
353 currentHeight = rect.height() |
343 currentWidth += rect.width() |
354 currentWidth += rect.width() |
344 |
355 |
345 # update totals |
356 # update totals |
346 if currentWidth > width: |
357 if currentWidth > width: |
347 width = currentWidth |
358 width = currentWidth |
348 height += currentHeight |
359 height += currentHeight |
349 |
360 |
350 # store generation info |
361 # store generation info |
351 widths.append(currentWidth) |
362 widths.append(currentWidth) |
352 heights.append(currentHeight) |
363 heights.append(currentHeight) |
353 |
364 |
354 # add in some whitespace |
365 # add in some whitespace |
355 width *= whiteSpaceFactor |
366 width *= whiteSpaceFactor |
356 height = height * whiteSpaceFactor - 20 |
367 height = height * whiteSpaceFactor - 20 |
357 verticalWhiteSpace = 40.0 |
368 verticalWhiteSpace = 40.0 |
358 |
369 |
359 sceneRect = self.umlView.sceneRect() |
370 sceneRect = self.umlView.sceneRect() |
360 width += 50.0 |
371 width += 50.0 |
361 height += 50.0 |
372 height += 50.0 |
362 swidth = sceneRect.width() if width < sceneRect.width() else width |
373 swidth = sceneRect.width() if width < sceneRect.width() else width |
363 sheight = sceneRect.height() if height < sceneRect.height() else height |
374 sheight = sceneRect.height() if height < sceneRect.height() else height |
364 self.umlView.setSceneSize(swidth, sheight) |
375 self.umlView.setSceneSize(swidth, sheight) |
365 |
376 |
366 # distribute each generation across the width and the |
377 # distribute each generation across the width and the |
367 # generations across height |
378 # generations across height |
368 y = 10.0 |
379 y = 10.0 |
369 for currentWidth, currentHeight, generation in ( |
380 for currentWidth, currentHeight, generation in zip( |
370 zip(reversed(widths), reversed(heights), reversed(generations)) |
381 reversed(widths), reversed(heights), reversed(generations) |
371 ): |
382 ): |
372 x = 10.0 |
383 x = 10.0 |
373 # whiteSpace is the space between any two elements |
384 # whiteSpace is the space between any two elements |
374 whiteSpace = ( |
385 whiteSpace = (width - currentWidth - 20) / (len(generation) - 1.0 or 2.0) |
375 (width - currentWidth - 20) / |
|
376 (len(generation) - 1.0 or 2.0) |
|
377 ) |
|
378 for name in generation: |
386 for name in generation: |
379 shape = self.__shapes[name][0] |
387 shape = self.__shapes[name][0] |
380 shape.setPos(x, y) |
388 shape.setPos(x, y) |
381 rect = shape.sceneBoundingRect() |
389 rect = shape.sceneBoundingRect() |
382 x = x + rect.width() + whiteSpace |
390 x = x + rect.width() + whiteSpace |
383 y = y + currentHeight + verticalWhiteSpace |
391 y = y + currentHeight + verticalWhiteSpace |
384 |
392 |
385 def __createAssociations(self, routes): |
393 def __createAssociations(self, routes): |
386 """ |
394 """ |
387 Private method to generate the associations between the module shapes. |
395 Private method to generate the associations between the module shapes. |
388 |
396 |
389 @param routes list of associations |
397 @param routes list of associations |
390 @type list of tuple of (str, str) |
398 @type list of tuple of (str, str) |
391 """ |
399 """ |
392 from .AssociationItem import AssociationItem, AssociationType |
400 from .AssociationItem import AssociationItem, AssociationType |
|
401 |
393 for route in routes: |
402 for route in routes: |
394 assoc = AssociationItem( |
403 assoc = AssociationItem( |
395 self.__shapes[route[0]][0], |
404 self.__shapes[route[0]][0], |
396 self.__shapes[route[1]][0], |
405 self.__shapes[route[1]][0], |
397 AssociationType.IMPORTS, |
406 AssociationType.IMPORTS, |
398 colors=self.umlView.getDrawingColors()) |
407 colors=self.umlView.getDrawingColors(), |
|
408 ) |
399 self.scene.addItem(assoc) |
409 self.scene.addItem(assoc) |
400 |
410 |
401 def parsePersistenceData(self, version, data): |
411 def parsePersistenceData(self, version, data): |
402 """ |
412 """ |
403 Public method to parse persisted data. |
413 Public method to parse persisted data. |
404 |
414 |
405 @param version version of the data |
415 @param version version of the data |
406 @type str |
416 @type str |
407 @param data persisted data to be parsed |
417 @param data persisted data to be parsed |
408 @type str |
418 @type str |
409 @return flag indicating success |
419 @return flag indicating success |
410 @rtype bool |
420 @rtype bool |
411 """ |
421 """ |
412 parts = data.split(", ") |
422 parts = data.split(", ") |
413 if ( |
423 if ( |
414 len(parts) != 2 or |
424 len(parts) != 2 |
415 not parts[0].startswith("project=") or |
425 or not parts[0].startswith("project=") |
416 not parts[1].startswith("no_modules=") |
426 or not parts[1].startswith("no_modules=") |
417 ): |
427 ): |
418 return False |
428 return False |
419 |
429 |
420 projectFile = parts[0].split("=", 1)[1].strip() |
430 projectFile = parts[0].split("=", 1)[1].strip() |
421 if projectFile != self.project.getProjectFile(): |
431 if projectFile != self.project.getProjectFile(): |
422 res = EricMessageBox.yesNo( |
432 res = EricMessageBox.yesNo( |
423 None, |
433 None, |
424 self.tr("Load Diagram"), |
434 self.tr("Load Diagram"), |
425 self.tr( |
435 self.tr( |
426 """<p>The diagram belongs to the project <b>{0}</b>.""" |
436 """<p>The diagram belongs to the project <b>{0}</b>.""" |
427 """ Shall this project be opened?</p>""").format( |
437 """ Shall this project be opened?</p>""" |
428 projectFile)) |
438 ).format(projectFile), |
|
439 ) |
429 if res: |
440 if res: |
430 self.project.openProject(projectFile) |
441 self.project.openProject(projectFile) |
431 |
442 |
432 self.noModules = Utilities.toBool(parts[1].split("=", 1)[1].strip()) |
443 self.noModules = Utilities.toBool(parts[1].split("=", 1)[1].strip()) |
433 |
444 |
434 self.initialize() |
445 self.initialize() |
435 |
446 |
436 return True |
447 return True |
437 |
448 |
438 def toDict(self): |
449 def toDict(self): |
439 """ |
450 """ |
440 Public method to collect data to be persisted. |
451 Public method to collect data to be persisted. |
441 |
452 |
442 @return dictionary containing data to be persisted |
453 @return dictionary containing data to be persisted |
443 @rtype dict |
454 @rtype dict |
444 """ |
455 """ |
445 return { |
456 return { |
446 "project_name": self.project.getProjectName(), |
457 "project_name": self.project.getProjectName(), |
447 "no_modules": self.noModules, |
458 "no_modules": self.noModules, |
448 } |
459 } |
449 |
460 |
450 def fromDict(self, version, data): |
461 def fromDict(self, version, data): |
451 """ |
462 """ |
452 Public method to populate the class with data persisted by 'toDict()'. |
463 Public method to populate the class with data persisted by 'toDict()'. |
453 |
464 |
454 @param version version of the data |
465 @param version version of the data |
455 @type str |
466 @type str |
456 @param data dictionary containing the persisted data |
467 @param data dictionary containing the persisted data |
457 @type dict |
468 @type dict |
458 @return tuple containing a flag indicating success and an info |
469 @return tuple containing a flag indicating success and an info |
459 message in case the diagram belongs to a different project |
470 message in case the diagram belongs to a different project |
460 @rtype tuple of (bool, str) |
471 @rtype tuple of (bool, str) |
461 """ |
472 """ |
462 try: |
473 try: |
463 self.noModules = data["no_modules"] |
474 self.noModules = data["no_modules"] |
464 |
475 |
465 if data["project_name"] != self.project.getProjectName(): |
476 if data["project_name"] != self.project.getProjectName(): |
466 msg = self.tr( |
477 msg = self.tr( |
467 "<p>The diagram belongs to project <b>{0}</b>." |
478 "<p>The diagram belongs to project <b>{0}</b>." |
468 " Please open it and try again.</p>" |
479 " Please open it and try again.</p>" |
469 ).format(data["project_name"]) |
480 ).format(data["project_name"]) |
470 return False, msg |
481 return False, msg |
471 except KeyError: |
482 except KeyError: |
472 return False, "" |
483 return False, "" |
473 |
484 |
474 self.initialize() |
485 self.initialize() |
475 |
486 |
476 return True, "" |
487 return True, "" |