src/eric7/Graphics/ApplicationDiagramBuilder.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
24 24
25 class ApplicationDiagramBuilder(UMLDiagramBuilder): 25 class ApplicationDiagramBuilder(UMLDiagramBuilder):
26 """ 26 """
27 Class implementing a builder for imports diagrams of the application. 27 Class implementing a builder for imports diagrams of the application.
28 """ 28 """
29
29 def __init__(self, dialog, view, project, noModules=False): 30 def __init__(self, dialog, view, project, noModules=False):
30 """ 31 """
31 Constructor 32 Constructor
32 33
33 @param dialog reference to the UML dialog 34 @param dialog reference to the UML dialog
34 @type UMLDialog 35 @type UMLDialog
35 @param view reference to the view object 36 @param view reference to the view object
36 @type UMLGraphicsView 37 @type UMLGraphicsView
37 @param project reference to the project object 38 @param project reference to the project object
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, ""

eric ide

mercurial