Improved the package diagram to include subpackages and their module names.

Tue, 11 Sep 2012 18:26:47 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 11 Sep 2012 18:26:47 +0200
changeset 2037
7a3470ae170e
parent 2036
3b443ed1b7d1
child 2038
72557ef75de1

Improved the package diagram to include subpackages and their module names.

Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Graphics.PackageDiagramBuilder.html file | annotate | diff | comparison | revisions
Graphics/PackageDiagramBuilder.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Mon Sep 10 18:54:30 2012 +0200
+++ b/Documentation/Help/source.qhp	Tue Sep 11 18:26:47 2012 +0200
@@ -7150,8 +7150,10 @@
       <keyword name="PackageDiagramBuilder (Module)" id="PackageDiagramBuilder (Module)" ref="eric5.Graphics.PackageDiagramBuilder.html" />
       <keyword name="PackageDiagramBuilder.__addExternalClass" id="PackageDiagramBuilder.__addExternalClass" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__addExternalClass" />
       <keyword name="PackageDiagramBuilder.__addLocalClass" id="PackageDiagramBuilder.__addLocalClass" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__addLocalClass" />
+      <keyword name="PackageDiagramBuilder.__addPackage" id="PackageDiagramBuilder.__addPackage" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__addPackage" />
       <keyword name="PackageDiagramBuilder.__arrangeClasses" id="PackageDiagramBuilder.__arrangeClasses" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__arrangeClasses" />
       <keyword name="PackageDiagramBuilder.__buildModulesDict" id="PackageDiagramBuilder.__buildModulesDict" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__buildModulesDict" />
+      <keyword name="PackageDiagramBuilder.__buildSubpackagesDict" id="PackageDiagramBuilder.__buildSubpackagesDict" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__buildSubpackagesDict" />
       <keyword name="PackageDiagramBuilder.__createAssociations" id="PackageDiagramBuilder.__createAssociations" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__createAssociations" />
       <keyword name="PackageDiagramBuilder.__getCurrentShape" id="PackageDiagramBuilder.__getCurrentShape" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__getCurrentShape" />
       <keyword name="PackageDiagramBuilder.buildDiagram" id="PackageDiagramBuilder.buildDiagram" ref="eric5.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.buildDiagram" />
--- a/Documentation/Source/eric5.Graphics.PackageDiagramBuilder.html	Mon Sep 10 18:54:30 2012 +0200
+++ b/Documentation/Source/eric5.Graphics.PackageDiagramBuilder.html	Tue Sep 11 18:26:47 2012 +0200
@@ -67,12 +67,18 @@
 <td><a href="#PackageDiagramBuilder.__addLocalClass">__addLocalClass</a></td>
 <td>Private method to add a class defined in the module.</td>
 </tr><tr>
+<td><a href="#PackageDiagramBuilder.__addPackage">__addPackage</a></td>
+<td>Private method to add a package to the diagram.</td>
+</tr><tr>
 <td><a href="#PackageDiagramBuilder.__arrangeClasses">__arrangeClasses</a></td>
 <td>Private method to arrange the shapes on the canvas.</td>
 </tr><tr>
 <td><a href="#PackageDiagramBuilder.__buildModulesDict">__buildModulesDict</a></td>
 <td>Private method to build a dictionary of modules contained in the package.</td>
 </tr><tr>
+<td><a href="#PackageDiagramBuilder.__buildSubpackagesDict">__buildSubpackagesDict</a></td>
+<td>Private method to build a dictionary of sub-packages contained in this package.</td>
+</tr><tr>
 <td><a href="#PackageDiagramBuilder.__createAssociations">__createAssociations</a></td>
 <td>Private method to generate the associations between the class shapes.</td>
 </tr><tr>
@@ -159,6 +165,26 @@
 <dd>
 flag indicating a Ruby module (boolean)
 </dd>
+</dl><a NAME="PackageDiagramBuilder.__addPackage" ID="PackageDiagramBuilder.__addPackage"></a>
+<h4>PackageDiagramBuilder.__addPackage</h4>
+<b>__addPackage</b>(<i>name, modules, x, y</i>)
+<p>
+        Private method to add a package to the diagram.
+</p><dl>
+<dt><i>name</i></dt>
+<dd>
+package name to be shown (string)
+</dd><dt><i>modules</i></dt>
+<dd>
+list of module names contained in the package
+            (list of strings)
+</dd><dt><i>x</i></dt>
+<dd>
+x-coordinate (float)
+</dd><dt><i>y</i></dt>
+<dd>
+y-coordinate (float)
+</dd>
 </dl><a NAME="PackageDiagramBuilder.__arrangeClasses" ID="PackageDiagramBuilder.__arrangeClasses"></a>
 <h4>PackageDiagramBuilder.__arrangeClasses</h4>
 <b>__arrangeClasses</b>(<i>nodes, routes, whiteSpaceFactor=1.2</i>)
@@ -176,6 +202,16 @@
 <dd>
 dictionary of modules contained in the package.
 </dd>
+</dl><a NAME="PackageDiagramBuilder.__buildSubpackagesDict" ID="PackageDiagramBuilder.__buildSubpackagesDict"></a>
+<h4>PackageDiagramBuilder.__buildSubpackagesDict</h4>
+<b>__buildSubpackagesDict</b>(<i></i>)
+<p>
+        Private method to build a dictionary of sub-packages contained in this package.
+</p><dl>
+<dt>Returns:</dt>
+<dd>
+dictionary of sub-packages contained in this package
+</dd>
 </dl><a NAME="PackageDiagramBuilder.__createAssociations" ID="PackageDiagramBuilder.__createAssociations"></a>
 <h4>PackageDiagramBuilder.__createAssociations</h4>
 <b>__createAssociations</b>(<i>routes</i>)
--- a/Graphics/PackageDiagramBuilder.py	Mon Sep 10 18:54:30 2012 +0200
+++ b/Graphics/PackageDiagramBuilder.py	Tue Sep 11 18:26:47 2012 +0200
@@ -15,6 +15,7 @@
 
 from .UMLDiagramBuilder import UMLDiagramBuilder
 from .ClassItem import ClassItem, ClassModel
+from .PackageItem import PackageItem, PackageModel
 from .AssociationItem import AssociationItem, Generalisation
 from . import GraphicsUtilities
 
@@ -105,6 +106,67 @@
             progress.setValue(tot)
         return moduleDict
     
+    def __buildSubpackagesDict(self):
+        """
+        Private method to build a dictionary of sub-packages contained in this package.
+        
+        @return dictionary of sub-packages contained in this package
+        """
+        supportedExt = \
+            ['*{0}'.format(ext) for ext in Preferences.getPython("PythonExtensions")] + \
+            ['*{0}'.format(ext) for ext in Preferences.getPython("Python3Extensions")] + \
+            ['*.rb']
+        extensions = Preferences.getPython("PythonExtensions") + \
+            Preferences.getPython("Python3Extensions") + ['.rb']
+        
+        subpackagesDict = {}
+        subpackagesList = []
+        
+        for subpackage in os.listdir(self.package):
+            subpackagePath = os.path.join(self.package, subpackage)
+            if os.path.isdir(subpackagePath) and \
+               len(glob.glob(os.path.join(subpackagePath, "__init__.*"))) != 0:
+                subpackagesList.append(subpackagePath)
+        
+        tot = 0
+        for ext in supportedExt:
+            for subpackage in subpackagesList:
+                tot += len(glob.glob(Utilities.normjoinpath(subpackage, ext)))
+        try:
+            prog = 0
+            progress = QProgressDialog(self.trUtf8("Parsing modules..."),
+                None, 0, tot, self.parent())
+            progress.show()
+            QApplication.processEvents()
+            for subpackage in subpackagesList:
+                packageName = os.path.basename(subpackage)
+                subpackagesDict[packageName] = []
+                modules = []
+                for ext in supportedExt:
+                    modules.extend(glob.glob(Utilities.normjoinpath(subpackage, ext)))
+                for module in modules:
+                    progress.setValue(prog)
+                    QApplication.processEvents()
+                    prog += 1
+                    try:
+                        mod = Utilities.ModuleParser.readModule(
+                            module, extensions=extensions)
+                    except ImportError:
+                        continue
+                    else:
+                        name = mod.name
+                        if "." in name:
+                            name = name.rsplit(".", 1)[1]
+                        subpackagesDict[packageName].append(name)
+                subpackagesDict[packageName].sort()
+                # move __init__ to the front
+                if "__init__" in subpackagesDict[packageName]:
+                    subpackagesDict[packageName].remove("__init__")
+                    subpackagesDict[packageName].insert(0, "__init__")
+        finally:
+            progress.setValue(tot)
+        return subpackagesDict
+    
     def buildDiagram(self):
         """
         Public method to build the class shapes of the package diagram.
@@ -188,7 +250,13 @@
                                 routes.append((className, child))
                 
                 del todo[0]
-            
+        
+        # step 3: build the subpackages
+        subpackages = self.__buildSubpackagesDict()
+        for subpackage in sorted(subpackages.keys()):
+            self.__addPackage(subpackage, subpackages[subpackage], 0, 0)
+            nodes.append(subpackage)
+        
         self.__arrangeClasses(nodes, routes[:])
         self.__createAssociations(routes)
         self.umlView.autoAdjustSceneSize(limit=True)
@@ -299,6 +367,21 @@
         cw.setId(self.umlView.getItemId())
         self.allClasses[_class] = cw
     
+    def __addPackage(self, name, modules, x, y):
+        """
+        Private method to add a package to the diagram.
+        
+        @param name package name to be shown (string)
+        @param modules list of module names contained in the package
+            (list of strings)
+        @param x x-coordinate (float)
+        @param y y-coordinate (float)
+        """
+        pm = PackageModel(name, modules)
+        pw = PackageItem(pm, x, y, scene=self.scene)
+        pw.setId(self.umlView.getItemId())
+        self.allClasses[name] = pw
+    
     def __createAssociations(self, routes):
         """
         Private method to generate the associations between the class shapes.
--- a/changelog	Mon Sep 10 18:54:30 2012 +0200
+++ b/changelog	Tue Sep 11 18:26:47 2012 +0200
@@ -11,6 +11,9 @@
      variables viewer
 - Configuration Dialog
   -- added a filter edit to filter the configuration tree
+- Graphics Dialogs
+  -- added capability to store and load diagrams to/from disk
+  -- improved the package diagram to include subpackages and their module names
 - Version Control System Interfaces
   -- Mercurial
      --- added support for --log and --dry-run to the hg graft operation as of

eric ide

mercurial