UmlFrame.py :  » UML » Python-UML-Tool » pyut-1.4.0 » src » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » UML » Python UML Tool 
Python UML Tool » pyut 1.4.0 » src » UmlFrame.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

__version__ = "$Revision: 1.22 $"
__author__ = "EI5, eivd, Group Burgbacher - Waelti"
__date__ = "2001-11-14"

#from wxPython.wx.    import *
#from MiniOgl        import *
import wx
from OglLinkFactory import *
from PyutClass import *
from PyutNote import *
from PyutMethod import *
from PyutField import *
from PyutParam import *
from PyutStereotype import *
from PyutLink import *
from mediator import *
from PyutConsts import *
from PyutActor import PyutActor
from PyutUseCase import PyutUseCase
from OglActor import OglActor
from OglUseCase import OglUseCase
from OglClass import *
from OglNote import *
from OglSDMessage import OglSDMessage
from MiniOgl import *
from historyManager import *
#DEFAULT_WIDTH = 1280
DEFAULT_WIDTH = 3000
#DEFAULT_WIDTH = 5120


##############################################################################

class UmlFrame(DiagramFrame):
    """
    Represents a canvas for drawing diagrams.
    It provides all the methods to add new classes, notes, links...
    It also routes some click events to the mediator. See the `OnLeftDown`
    method.

    :version: $Revision: 1.22 $
    :author: L. Burgbacher
    :contact: lb@alawa.ch
    """
    def __init__(self, parent, frame):
        """
        constructor
        @param wx.Window parent : parent object
        @param frame : parent frame object
        @since 1.0
        @author N. hamadi (hamadi12@yahoo.fr)
        @modified L. Burgbacher <lb@alawa.ch>
            added event processing
            added mediator support
            bind with OglClass to create new classes
        """
        # initialize a canvas
        #print ">>>UmlFrame-1"
        DiagramFrame.__init__(self, parent)
        #print "---UmlFrame-2"

        # Setting charset
        #font = self.GetFont()
        #print font.GetEncoding()
        #font.SetEncoding(wx.FONTENCODING_ISO8859_2)
        #self.SetFont(font)
        #print font.GetEncoding()

        # get the mediator, and register it
        #print "---UmlFrame-3"
        self._ctrl = getMediator()
        #self._ctrl.registerUMLFrame(self)

        # initialize maxwidth, maxHeight for the canvas
        #print "---UmlFrame-4"
        self.maxWidth  = DEFAULT_WIDTH
        self.maxHeight = int(self.maxWidth / 1.41) # 1.41 is for A4 support

        # set a scrollbar
        self.SetScrollbars(20, 20, self.maxWidth/20, self.maxHeight/20)
        #print "---UmlFrame-5"

        self._frame = frame

        #added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (17.11.2005)
        #history of the frame (undo/redo)
        self._history = HistoryManager(self)
        
        # Close event
        self.Bind(wx.EVT_CLOSE, self.evtClose)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_CHAR, self._ctrl.processChar)
        #print "---UmlFrame-6"
        
        #added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (11.11.2005)
        self.SetInfinite(True)

        self._defaultCursor = self.GetCursor()

    #>------------------------------------------------------------------------

    def setCodePath(self, path):
        """
        Set the code path
        DEPRECATED
        @author C.Dutoit
        """
        project = self._ctrl.getFileHandling().getProjectFromFrame(self)
        if project is not None:
            project.setCodePath(path)
        else:
            print "Passing setCodePath in UmlFrame-setCodePath"


    #>-----------------------------------------------------------------------
    def displayDiagramProperties(self):
        """
        Display class diagram properties
        @author C.Dutoit
        """
        displayError(_("Not yet implemented !"))

    #>------------------------------------------------------------------------

    #def OnPaint(self, event):
        #self._diagram.Refresh()
        #self.Refresh()

    #>------------------------------------------------------------------------

    def cleanUp(self):
        """
        Clean up object references before quitting.

        @since 1.23
        @author Laurent Burgbacher <lb@alawa.ch>
        @modified C.Dutoit <dutoitc@hotmail.com>
            Added clean destroy code
        """
        self._ctrl = None
        self._frame = None

    #>------------------------------------------------------------------------

    def evtClose(self, event):
        """
        Clean close, event handler on EVT_CLOSE

        @since 1.35.2.8
        @author C.Dutoit <dutoitc@hotmail.com>
        """

        #added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (17.11.2005)
        #to destroy the file that contains the history
        self._history.destroy()
        
        self.cleanUp()
        self.Destroy()

    #>------------------------------------------------------------------------

    def newDiagram(self):
        """
        Remove all shapes, get a brand new empty diagram.

        @since 1.31
        @author Laurent Burgbacher <lb@alawa.ch>
        """
        self._diagram.DeleteAllShapes()
        self.Refresh()

    #>------------------------------------------------------------------------

    def getDiagram(self):
        """
        Return the diagram of this frame.

        @return wx.Diagram
        @since 1.23
        @author Laurent Burgbacher <lb@alawa.ch>
        """
        return self._diagram

    #>------------------------------------------------------------------------

    def addHierarchy(self, display):
        """
        Hardcoded example of a class diagram, for test purposes.
        Classes come from self introspection !!!
        OK, it's too big, but it's not a feature, just a toy.

        @author L. Burgbacher <lb@alawa.ch>
        @since 1.4
        """
        wx.BeginBusyCursor()
        #from pyclbr import readmodule, Class
        from inspect import getargspec
        #res = readmodule("PyutDataClasses")
        import PyutDataClasses as pdc
        import types

        #dc = wx.ClientDC(self) # to move the shapes

        # get a list of classes info for classes in the display list
        #classes = [res[name] for name in res.keys() if name in display]
        classes = [cl for cl in pdc.__dict__.values()
            if (type(cl) == ClassType or type(cl) == TypeType or 
                type(cl) == 'module')
                and cl.__name__ in display]

        objs = {}
        # create the PyutClass objects
        for cl in classes:
            # create objects
            pc = PyutClass(cl.__name__)
            po = OglClass(pc)
            methods = []
            clmethods = [me for me in cl.__dict__.values()
                if type(me) == types.FunctionType]
            # add the methods
            #for me in cl.methods.keys():
            for me in clmethods:
                meth = PyutMethod(me.func_name)
                # add the params
                if type(me) != types.FunctionType:
                    try:
                        me = mobj.__dict__.get("im_func")
                    except AttributeError:
                        me = None
                if me is not None:
                    args = getargspec(me)
                    if args[3] is None:
                        firstDefVal = len(args[0])
                    else:
                        firstDefVal = len(args[0]) - len(args[3])
                    for arg, i in zip(args[0], range(len(args[0]))):
                        # don't add self, it's implied
                        defVal = None
                        if arg != "self":
                            if i >= firstDefVal:
                                defVal = args[3][i - firstDefVal]
                                if type(defVal) == types.StringType:
                                    defVal = '"' + defVal + '"'
                                param = PyutParam(arg, "", str(defVal))
                            else:
                                param = PyutParam(arg)
                            meth.addParam(param)
                methods.append(meth)
                # set the visibility according to naming conventions
                if me.func_name[-2:] != "__":
                    if me.func_name[0:2] == "__":
                        meth.setVisibility("-")
                    elif me.func_name[0] == "_":
                        meth.setVisibility("#")
            methods.sort(lambda x, y: cmp(x.getName(), y.getName()))
            pc.setMethods(methods)
            self.addShape(po, 0, 0)
            po.autoResize()
            objs[cl.__name__] = po

        # now, search for paternity links
        for po in objs.values():
            pc = po.getPyutObject()
            # skip object, it has no parent
            if pc.getName() == "object": continue
            currentClass = pdc.__dict__.get(pc.getName())
            fatherClasses = [cl for cl in classes
                if cl.__name__ in
                    map(lambda x : x.__name__, currentClass.__bases__)]

            def getClassesNames(list):
                return [item.__name__ for item in list]

            fatherNames = getClassesNames(fatherClasses)
            for father in fatherNames:
                dest = objs.get(father)
                if dest is not None: # maybe we don't have the father loaded
                    self.createInheritanceLink(po, dest)

        def cmpHeight(a, b):
            xa, ya = a.GetSize()
            xb, yb = b.GetSize()
            return cmp(yb, ya)

        # sort by descending height
        objs = objs.values()
        objs.sort(cmpHeight)

        # organize by vertical descending sizes
        x = 20
        y = 20
        incX = 0
        incY = 0
        for po in objs:
            incX, sy = po.GetSize()
            incX += 20
            sy += 20
            incY = max(incY, sy)
            # find good coordinates
            if x + incX >= self.maxWidth:
                x = 20
                y += incY
                incY = sy
            po.SetPosition(x + incX/2, y + sy/2)
            #po.Move(dc, x + incX/2, y + sy/2, True)
            x += incX

        wx.EndBusyCursor()

    #>------------------------------------------------------------------------

    def addPyutHierarchy(self):
        """
        Calls AddHierarchy with the Pyut classes list.

        @since 1.32
        @author Philippe Waelti <pwaelti@eivd.ch>
        """
        import PyutDataClasses as pdc
        self.addHierarchy(pdc.display)

    #>------------------------------------------------------------------------

    def addOglHierarchy(self):
        """
        Calls AddHierarchy with the Ogl classes list.

        @since 1.32
        @author Philippe Waelti <pwaelti@eivd.ch>
        """
        import PyutDataClasses as pdc
        self.addHierarchy(pdc.displayOgl)

    #>------------------------------------------------------------------------

    def createNewClass(self, x, y):
        """
        Add a new class at (x, y).

        @return PyutClass : the newly created PyutClass
        @since 1.4
        @author L. Burgbacher <lb@alawa.ch>
        """
        pyutClass = PyutClass(_("NoName"))
        oglClass = OglClass(pyutClass)
        self.addShape(oglClass, x, y)
        self.Refresh()
        return pyutClass

    #>------------------------------------------------------------------------

    def createNewNote(self, x, y):
        """
        Add a new note at (x, y).

        @return PyutNote : the newly created PyutNote
        @since 1.35.2.2
        @author P. Waelti <pwaelti@eivd.ch>
        """
        pyutNote = PyutNote("")
        oglNote = OglNote(pyutNote)
        self.addShape(oglNote, x, y)
        self.Refresh()
        return pyutNote

    #>------------------------------------------------------------------------

    def createNewActor(self, x, y):
        """
        Add a new actor at (x, y).

        @return PyutActor : the newly created PyutActor
        @since 1.35.2.4
        @author P. Waelti <pwaelti@eivd.ch>
        """
        pyutActor = PyutActor()
        oglActor = OglActor(pyutActor)
        self.addShape(oglActor, x, y)
        self.Refresh()
        return pyutActor

    #>------------------------------------------------------------------------

    def createNewUseCase(self, x, y):
        """
        Add a new use case at (x, y).

        @return PyutUseCase : the newly created PyutUseCase
        @since 1.35.2.4
        @author P. Waelti <pwaelti@eivd.ch>
        """
        pyutUseCase = PyutUseCase()
        oglUseCase = OglUseCase(pyutUseCase)
        self.addShape(oglUseCase, x, y)
        self.Refresh()
        return pyutUseCase

#P. Dabrowski 20051202 : These two methods have been deplaced to the
#                        createOglLinkCommand module in order to be
#                        undone/redone.
##    #>------------------------------------------------------------------------
##
##    def createInheritanceLink(self, child, father):
##        """
##        Add a paternity link between child and father.
##
##        @param OglClass child : child
##        @param OglClass father : father
##        @since 1.4
##        @author L. Burgbacher <lb@alawa.ch>
##        """
##
##        pyutLink = PyutLink("", linkType=OGL_INHERITANCE,
##            source=child.getPyutObject(),
##            destination=father.getPyutObject())
##        oglLink = getOglLinkFactory().getOglLink(child, pyutLink, father,
##            OGL_INHERITANCE)
##        self._diagram.AddShape(oglLink)
##
##        # Added by ND
##        child.addLink(oglLink)
##        father.addLink(oglLink)
##
##        # add it to the PyutClass
##        child.getPyutObject().addFather(father.getPyutObject())
##
##        return oglLink
##
##    #>------------------------------------------------------------------------
##
##    def createNewLink(self, src, dst, linkType=OGL_INHERITANCE, 
##                      srcPos = None, dstPos = None):
##        """
##        Add a link between src and dst.
##
##        @param OglClass src  : source of the link
##        @param OglClass dst  : destination of the link
##        @param int type : type of the link
##        @param srcPos, dstPos : position on source and destination
##        @return OglLink : the link created
##        @author L. Burgbacher
##        @modified C.Dutoit 20021125 : added srcPos and dstPos to be compatible
##                                with Sequence diagram
##        """
##        
##        #print "Create new link"
##        if linkType == OGL_INHERITANCE:
##            return self.createInheritanceLink(src, dst)
##
##        pyutLink = PyutLink("", linkType=linkType,
##                            source=src.getPyutObject(),
##                            destination=dst.getPyutObject())
##        
##        # Call the factory to create OGL Link
##        oglLinkFactory = getOglLinkFactory()
##        oglLink = oglLinkFactory.getOglLink(src, pyutLink, dst, linkType)
##        
##        
##        self._diagram.AddShape(oglLink, withModelUpdate = False) # add it to the diagram
##        
##        src.addLink(oglLink)  # add it to the source OglShape
##        dst.addLink(oglLink)  # add it to the destination OglShape
##
##        src.getPyutObject().addLink(pyutLink) # add it to the PyutClass
##        
##        return oglLink
##
##    #>------------------------------------------------------------------------

    def OnLeftDown(self, event):
        """
        Manage a left down mouse event.
        If there's an action pending in the mediator, give it the event, else
        let it go to the next handler.

        @param wx.Event event
        @since 1.4
        @author L. Burgbacher <lb@alawa.ch>
        """
        #print "-" * 76
        #print "UmlFrame.OnLeftDown"
        if self._ctrl.actionWaiting():
            x, y = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
            skip = self._ctrl.doAction(x, y)

            #added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (11.11.2005)
            #if we use the zoom tool...
            if self._ctrl.getCurrentAction() == ACTION_ZOOM_IN:
                DiagramFrame._BeginSelect(self, event)
            
            if skip == SKIP_EVENT:
                DiagramFrame.OnLeftDown(self, event)
        
        else:
            DiagramFrame.OnLeftDown(self, event)

    #>------------------------------------------------------------------------
    
    def OnLeftUp(self, event):
        """
        Added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (11.11.2005)
        to make the right action if it is a selection or a zoom.
        """
        if self._ctrl.getCurrentAction() == ACTION_ZOOM_IN:
            width, height = self._selector.GetSize()
            x, y = self._selector.GetPosition()
            self._selector.Detach()
            self._selector = None
            self.DoZoomIn(x, y, width, height)
            self.Refresh()
            self._ctrl.updateTitle()
        else:
            
            DiagramFrame.OnLeftUp(self, event)
            
    #>------------------------------------------------------------------------

    def OnLeftDClick(self, event):
        """
        Manage a left double click mouse event.

        @param wx.Event event
        @since 1.22
        @author L. Burgbacher <lb@alawa.ch>
        """
        x, y = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
        self._ctrl.editObject(x, y)
        DiagramFrame.OnLeftDClick(self, event)

    #>------------------------------------------------------------------------

    def addShape(self, shape, x, y, pen=None, brush=None, withModelUpdate = True):
        """
        Add a shape to the UmlFrame.

        @param wx.Shape shape : the shape to add
        @param int x y : coords of the center of the shape
        @param wx.Pen pen : pen to use
        @param wx.Brush brush : brush to use
        @param withModelUpdate boolean  :   if true the model of the shape will
                                            update from the shape (view) when
                                            added to the diagram. Added by
                                            P. Dabrowski (29.11.05)
        @since 1.4
        @author L. Burgbacher <lb@alawa.ch>
        """
        #print ">UMLFrame-AddShape-1"
        shape.SetDraggable(True)
        #print "UMLFrame-AddShape-1"
        shape.SetPosition(x, y)
        #print "UMLFrame-AddShape-1"
        if pen:
            shape.SetPen(pen)
        if brush:
            shape.SetBrush(brush)
        #print "UMLFrame-AddShape-1"
        self._diagram.AddShape(shape, withModelUpdate)
        #print "<<UMLFrame-AddShape-1"
        #self._umlObjects.append(shape)

    #>------------------------------------------------------------------------

    def getUmlObjects(self):
        """
        To know all OglObject. 

        @since 1.19
        @author L. Burgbacher <lb@alawa.ch>
        """
        return [s for s in self._diagram.GetShapes()
            if isinstance(s, (OglObject, OglLink, OglSDMessage))]

    #>------------------------------------------------------------------------

    def getWidth(self):
        """
        Knowing Width.

        @since 1.19
        @author Deve Roux <droux@eivd.ch>
        """
        return self.maxWidth

    #>------------------------------------------------------------------------

    def getHeight(self) :
        """
        Knowing Height.

        @since 1.19
        @author Deve Roux <droux@eivd.ch>
        """
        return self.maxHeight


    #>------------------------------------------------------------------------

    def getObjectsBoundaries(self) :
        """
        Return object boundaries (coordinates)

        @since 1.35.2.25
        @author C.Dutoit <dutoitc@hotmail.com>
        """
        # Init
        infinite = 1e9
        minx = infinite
        maxx = -infinite
        miny = infinite
        maxy = -infinite

        # Get boundaries
        for object in self._diagram.GetShapes():
            # Get object limits
            ox1, oy1 = object.GetPosition()
            ox2, oy2 = object.GetSize()
            ox2+=ox1
            oy2+=oy1

            # Update min-max
            minx = min(minx, ox1)
            maxx = max(maxx, ox2)
            miny = min(miny, oy1)
            maxy = max(maxy, oy2)

        # Return values
        return (minx, miny, maxx, maxy)

    #>------------------------------------------------------------------------
    
    def getUmlObjectById(self, objectId):
        """
        Added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (20.11.2005)
        @param objectId (Integer)   :   id for which we want to get an object
        @return the uml object that has the specified id. If there is no
        matching object, None is returned.
        """

        for shape in self.GetDiagram().GetShapes():
            if isinstance(shape, (OglObject, OglLink)):
                if shape.getPyutObject().getId() == objectId:
                    return shape
        return None

    #>------------------------------------------------------------------------
     
    def getHistory(self):
        """
        Added by P. Dabrowski <przemek.dabrowski@destroy-display.com> (20.11.2005)
        @return the history associated to this frame
        """
        return self._history

    #>------------------------------------------------------------------------


        
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.