--- a/Graphics/ImportsDiagram.py Sun Sep 09 14:46:59 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,252 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2007 - 2012 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog showing an imports diagram of a package. -""" - -import glob -import os - -from PyQt4.QtGui import QProgressDialog, QApplication, QGraphicsTextItem - -from .UMLDialog import UMLDialog -from .ModuleItem import ModuleItem, ModuleModel -from .AssociationItem import AssociationItem, Imports - -import Utilities.ModuleParser -import Utilities -import Preferences - - -class ImportsDiagram(UMLDialog): - """ - Class implementing a dialog showing an imports diagram of a package. - - Note: Only package internal imports are show in order to maintain - some readability. - """ - def __init__(self, project, package, parent=None, name=None, - showExternalImports=False): - """ - Constructor - - @param project reference to the project object - @param package name of a python package to show the import - relationships (string) - @param parent parent widget of the view (QWidget) - @param name name of the view widget (string) - @keyparam showExternalImports flag indicating to show exports from outside - the package (boolean) - """ - UMLDialog.__init__(self, "ImportsDiagram", buildFunction=self.__buildImports, - parent=parent) - - self.showExternalImports = showExternalImports - self.packagePath = Utilities.normabspath(package) - self.package = os.path.splitdrive(self.packagePath)[1].replace(os.sep, '.')[1:] - hasInit = True - ppath = self.packagePath - while hasInit: - ppath = os.path.dirname(ppath) - hasInit = len(glob.glob(os.path.join(ppath, '__init__.*'))) > 0 - self.shortPackage = self.packagePath.replace(ppath, '').replace(os.sep, '.')[1:] - - self.umlView.setPersistenceData("package={0}".format(self.packagePath)) - - pname = project.getProjectName() - if pname: - name = self.trUtf8("Imports Diagramm {0}: {1}").format( - pname, project.getRelativePath(self.packagePath)) - else: - name = self.trUtf8("Imports Diagramm: {0}").format(self.packagePath) - self.setDiagramName(name) - - if not name: - self.setObjectName("ImportsDiagram") - else: - self.setObjectName(name) - - self.umlView.relayout.connect(self.relayout) - - def __buildModulesDict(self): - """ - Private method to build a dictionary of modules contained in the package. - - @return dictionary of modules contained in the package. - """ - extensions = Preferences.getPython("PythonExtensions") + \ - Preferences.getPython("Python3Extensions") - moduleDict = {} - modules = [] - for ext in Preferences.getPython("PythonExtensions") + \ - Preferences.getPython("Python3Extensions"): - modules.extend( - glob.glob(Utilities.normjoinpath(self.packagePath, '*{0}'.format(ext)))) - - tot = len(modules) - try: - prog = 0 - progress = QProgressDialog(self.trUtf8("Parsing modules..."), - None, 0, tot, self) - progress.show() - QApplication.processEvents() - for module in modules: - progress.setValue(prog) - QApplication.processEvents() - prog = prog + 1 - try: - mod = Utilities.ModuleParser.readModule(module, extensions=extensions, - caching=False) - except ImportError: - continue - else: - name = mod.name - if name.startswith(self.package): - name = name[len(self.package) + 1:] - moduleDict[name] = mod - finally: - progress.setValue(tot) - return moduleDict - - def __buildImports(self): - """ - Private method to build the modules shapes of the diagram. - """ - initlist = glob.glob(os.path.join(self.packagePath, '__init__.*')) - if len(initlist) == 0: - ct = QGraphicsTextItem(None, self.scene) - ct.setHtml( - self.trUtf8("The directory <b>'{0}'</b> is not a Python package.")\ - .format(self.package)) - return - - shapes = {} - p = 10 - y = 10 - maxHeight = 0 - sceneRect = self.umlView.sceneRect() - - modules = self.__buildModulesDict() - sortedkeys = sorted(modules.keys()) - externalMods = [] - packageList = self.shortPackage.split('.') - packageListLen = len(packageList) - for module in sortedkeys: - impLst = [] - for i in modules[module].imports: - if i.startswith(self.package): - n = i[len(self.package) + 1:] - else: - n = i - if i in modules: - impLst.append(n) - elif self.showExternalImports: - impLst.append(n) - if not n in externalMods: - externalMods.append(n) - for i in list(modules[module].from_imports.keys()): - if i.startswith('.'): - dots = len(i) - len(i.lstrip('.')) - if dots == 1: - n = i[1:] - i = n - else: - if self.showExternalImports: - n = '.'.join( - packageList[:packageListLen - dots + 1] + [i[dots:]]) - else: - n = i - elif i.startswith(self.package): - n = i[len(self.package) + 1:] - else: - n = i - if i in modules: - impLst.append(n) - elif self.showExternalImports: - impLst.append(n) - if not n in externalMods: - externalMods.append(n) - classNames = [] - for cls in list(modules[module].classes.keys()): - className = modules[module].classes[cls].name - if className not in classNames: - classNames.append(className) - shape = self.__addModule(module, classNames, 0.0, 0.0) - shapeRect = shape.sceneBoundingRect() - shapes[module] = (shape, impLst) - pn = p + shapeRect.width() + 10 - maxHeight = max(maxHeight, shapeRect.height()) - if pn > sceneRect.width(): - p = 10 - y += maxHeight + 10 - maxHeight = shapeRect.height() - shape.setPos(p, y) - p += shapeRect.width() + 10 - else: - shape.setPos(p, y) - p = pn - - for module in externalMods: - shape = self.__addModule(module, [], 0.0, 0.0) - shapeRect = shape.sceneBoundingRect() - shapes[module] = (shape, []) - pn = p + shapeRect.width() + 10 - maxHeight = max(maxHeight, shapeRect.height()) - if pn > sceneRect.width(): - p = 10 - y += maxHeight + 10 - maxHeight = shapeRect.height() - shape.setPos(p, y) - p += shapeRect.width() + 10 - else: - shape.setPos(p, y) - p = pn - - rect = self.umlView._getDiagramRect(10) - sceneRect = self.umlView.sceneRect() - if rect.width() > sceneRect.width(): - sceneRect.setWidth(rect.width()) - if rect.height() > sceneRect.height(): - sceneRect.setHeight(rect.height()) - self.umlView.setSceneSize(sceneRect.width(), sceneRect.height()) - - self.__createAssociations(shapes) - self.umlView.autoAdjustSceneSize(limit=True) - - def __addModule(self, name, classes, x, y): - """ - Private method to add a module to the diagram. - - @param name module name to be shown (string) - @param classes list of class names contained in the module - (list of strings) - @param x x-coordinate (float) - @param y y-coordinate (float) - """ - classes.sort() - impM = ModuleModel(name, classes) - impW = ModuleItem(impM, x, y, scene=self.scene) - impW.setId(self.umlView.getItemId()) - return impW - - def __createAssociations(self, shapes): - """ - Private method to generate the associations between the module shapes. - - @param shapes list of shapes - """ - for module in list(shapes.keys()): - for rel in shapes[module][1]: - assoc = AssociationItem( - shapes[module][0], shapes[rel][0], - Imports) - self.scene.addItem(assoc) - - def relayout(self): - """ - Method to relayout the diagram. - """ - self.__buildImports()