Пример #1
0
def dragFinish(self, event=None):
  """ Stops dragging """
  dragDrop(self, self.cb.getSelectionObjectSet())
    
  # If auto force transfer: apply it after dragging to push things apart
  if(self.isAutoForceTransferEnabled):
    ForceTransfer.applyLayout()
  
  modelChange(self) # Model changed, update statusbar & undo
Пример #2
0
def dragFinish(self, event=None):
    """ Stops dragging """
    dragDrop(self, self.cb.getSelectionObjectSet())

    # If auto force transfer: apply it after dragging to push things apart
    if (self.isAutoForceTransferEnabled):
        ForceTransfer.applyLayout()

    modelChange(self)  # Model changed, update statusbar & undo
Пример #3
0
def pasteObjectAttributes(self, event):
  """ Pastes attributes to the entity or link under the cursor """

  itemTuple = self.cb.getItemUnderCursor(self, event)
  if(not itemTuple): 
    return
  
  obj = itemTuple[2]    
  for nodetype in self.ASGroot.nodeTypes:		# iterate on all the node types...
    for node in self.ASGroot.listNodes[nodetype]:
      if(node.graphObject_ == obj):
        self.cb.pasteCompatibleAttributes(node, nodetype)
        modelChange(self) # Model changed, update statusbar & undo
        return
Пример #4
0
def pasteObjectAttributes(self, event):
    """ Pastes attributes to the entity or link under the cursor """

    itemTuple = self.cb.getItemUnderCursor(self, event)
    if (not itemTuple):
        return

    obj = itemTuple[2]
    for nodetype in self.ASGroot.nodeTypes:  # iterate on all the node types...
        for node in self.ASGroot.listNodes[nodetype]:
            if (node.graphObject_ == obj):
                self.cb.pasteCompatibleAttributes(node, nodetype)
                modelChange(self)  # Model changed, update statusbar & undo
                return
Пример #5
0
def scaleReset(self, textMode = False):
  """ Restores scale to 1.0 """
  
  # Re-Size the text of an Entity or Link
  if(textMode):
    
    allScalableEntityObjects = []
    for object in self.cb.getSelectionObjectSet():
        if(isEntityNode(object)):
            allScalableEntityObjects.append(object)
        elif(object.getCenterObject()):
            allScalableEntityObjects.append(object.getCenterObject())
            
            
    for object in allScalableEntityObjects:
        # Get the last scale factor
        if(not object.layConstraints.has_key('Text Scale')):
          object.layConstraints['Text Scale'] = 1.00                          
        object.ScaleText(1.00)
        object.layConstraints['Text Scale'] = 1.00  
    
  # Re-Size an entity node - NO QOCA 
  elif(isNotUsingQoca()):
    for object in self.cb.getSelectionObjectSet():
      if(isEntityNode(object)):  
        
        # Get the last scale factor
        if(not object.layConstraints.has_key('scale')):
          object.layConstraints['scale'] = [1.00, 1.00]
        sx, sy = object.layConstraints['scale']
        newSize = [1.00, 1.00]
                
        # The final scale factor
        sx, sy = [ newSize[0] / sx, newSize[1] / sy ]  
  
        # Note: moveLinks is fals only because optimizeConnectionPorts is better
        #object.Scale(sx, sy, moveLinks = False)
        x0, y0 = object.getbbox()[:2]
        object.dc.scale(object.tag, x0, y0, sx, sy) 
        object.moveTo(object.x, object.y)
        object.layConstraints['scale'] = newSize
      
    optimizeConnectionPorts(self)
    
  # Re-Size an entity node - WITH QOCA constraints
  else:
    allScalableEntityObjects = []
    for object in self.cb.getSelectionObjectSet():
        if(isEntityNode(object)):
            allScalableEntityObjects.append(object)
          
    # Make the width/height editable
    editVarList = []
    for obj in allScalableEntityObjects:
      editVarList.append(obj.qcW)
      editVarList.append(obj.qcH)
    self.qocaSolver.addEditVars(editVarList)
    
    # Suggest new width/height values
    for obj in allScalableEntityObjects:     
      self.qocaSolver.suggestVarValue([(obj.qcW, obj.sizeX), 
                                       (obj.qcH, obj.sizeY)])   
      
    # Solve to get the new width/height of the entity
    self.qocaSolver.resolve(forceSolve=True)
    self.qocaSolver.endEdit() 
    optimizeConnectionPorts(self)
    
  modelChange(self) # Model changed, update statusbar & undo
Пример #6
0
def scaleWithMotion(self, event, textMode = False):
  """ Scales selected entities with the mouse motion """

  cb = self.cb                     

  x0, y0 = cb.getLastClickCoord() 
  x1, y1 = cb.getCanvasCoords(event)  
  
  allScalableEntityObjects = []
  for object in cb.getSelectionObjectSet():
      if(isEntityNode(object)):
          allScalableEntityObjects.append(object)
      elif(object.getCenterObject()):
          allScalableEntityObjects.append(object.getCenterObject())
  
  # Re-Size the text of an Entity or Link
  if(textMode):
    dx, dy = [ float(x1-x0) / 100.0 , float(y1-y0) / 100.0 ]
                 
    for object in allScalableEntityObjects:
        # Get the last scale factor, and add the movement delta
        if(not object.layConstraints.has_key('Text Scale')):
          object.layConstraints['Text Scale'] = 1.00
            
        newSize = object.layConstraints['Text Scale'] + dy
        
        # Bigger is better, too small is unreadable :D
        if(newSize < 0.2): 
          newSize = 0.2
          
        object.ScaleText(newSize)
        object.layConstraints['Text Scale'] = newSize  
        
        
  # Re-Size an entity node - NO QOCA 
  elif(isNotUsingQoca()):
    dx, dy = [ float(x1-x0) / 100.0 , float(y1-y0) / 100.0 ]
    for object in allScalableEntityObjects:
        
        # Get the last scale factor, and add the movement delta
        if(not object.layConstraints.has_key('scale')):
          object.layConstraints['scale'] = [1.00, 1.00]
        sx, sy = object.layConstraints['scale']
        newSize = [sx + dx, sy + dy]
        
        # Too small is not good :p
        if(newSize[0] < 0.2): 
          newSize[0] = 0.2
        if(newSize[1] < 0.2): 
          newSize[1] = 0.2
        
        # The final scale factor
        sx, sy = [ newSize[0] / sx, newSize[1] / sy ]  
  
        # Note: moveLinks is false only because optimizeConnectionPorts is better
        #object.Scale(sx, sy, moveLinks = False)
        x0, y0 = object.getbbox()[:2]
        object.dc.scale(object.tag, x0, y0, sx, sy) 
        object.moveTo(object.x, object.y)
        object.layConstraints['scale'] = newSize
      
    optimizeConnectionPorts(self)
        
  # Re-Size an entity node - WITH QOCA constraints
  else:  
    dx, dy = [float(x1-x0), float(y1-y0) ]
    
    # Make the width/height editable
    editVarList = []
    for obj in allScalableEntityObjects:
      editVarList.append(obj.qcW)
      editVarList.append(obj.qcH)      
    self.qocaSolver.addEditVars(editVarList)
    
    # Suggest new width/height values
    for obj in allScalableEntityObjects:     
      self.qocaSolver.suggestVarValue([(obj.qcW, obj.qcW.get() + dx), 
                                       (obj.qcH, obj.qcH.get() + dy)])   
      
    # Solve to get the new width/height of the entity
    self.qocaSolver.resolve(forceSolve=True)
    self.qocaSolver.endEdit() 
    object.layConstraints['scale'] = [obj.qcW.get() / obj.sizeX, 
                                      obj.qcH.get() / obj.sizeY]
    optimizeConnectionPorts(self)
    
    
  modelChange(self) # Model changed, update statusbar & undo
Пример #7
0
def dropArrowPoints(self, event, snap = True, filterLinkTypeList=None):
  """ 
  Drops intermediate points in the arrow or connects the arrow to the final
  object. If connection is not possible due to the final object not having 
  connectors, the arrow will be rolled back 1 connection point, or destroyed
  """
  
  cb = self.cb                        # User-interface callback object
  dc = cb.getCanvas()
  x, y = cb.getCanvasCoords(event)   # Event coordinates     
  
  arrow = self.pilotArrow.getArrow()
  coords = dc.coords(arrow)
    
  # Find the closest item to the arrow
  itemTuple = cb.getItemUnderCursor(self, event, ignore=arrow, allTags=True)
  if(itemTuple and snap):
    itemHandler, tags, obj = itemTuple
    
    # Embedded model  ---> WARNING: Not tested, original AToM3 code
    if(len(tags) >= 2 and tags[1][:4] == 'ASG_'):
      self.toClass = tags[0]   
      # Open to select the entity inside the model
      ATOM3TypeDialog(self, obj.semanticObject, ATOM3TypeDialog.OPEN, 
                      (None, self.setConnectMode))	
      # Check if we have both sides...
      if self.sem_objFrom and self.sem_objTo:	# we have both sides...
        drawConnection(self)
      
    # Object
    elif(tags[0][:3] == 'Obj'):
    
      # Get the actual connector point that we are going to connect to
      # coords[-4],coords[-3] are the before last point, so the min distance 
      # that point to the connector yields the optimal final point.
      # Some objects may not have connectors, in this case gracefully rollback 
      # the arrow
      if(obj.hasConnectors()): 
        coords[-2], coords[-1] = obj.getMinDistance_Connectors2Fixed(obj, 
                                                         coords[-4], coords[-3])
        if(obj.hasNamedPorts() and self.showNamedPortMessage):
          name = obj.guesstimateNamedConnAtPoint(coords[-2], coords[-1])
          if(name):
            text = 'Arrow ended on named port: '  \
                    + name \
                    + '\n\nThis message is shown only when you end an arrow' \
                    + ' directly on a named port' \
                    + '\n\nIf you choose the 2nd option and want to see these '\
                    + 'messages again, restart AToM3'
            dialog = Dialog.Dialog(None, {'title': 'Lock Current Named Port', 
                        'text': text, 
                        'bitmap': '', 
                        'default': 0, 
                        'strings': (name, 'Rollback arrow', 
                                    'Never show this message')})         
            if(dialog.num == 1):
              return
            if(dialog.num == 2):
              self.showNamedPortMessage = False
      
      # Edge just happens to have a connector
      elif(obj.hasCenterObjectConnector()):
        coords[-2], coords[-1] = obj.getCenterCoord()
      
      # Hyperedge! This means that links can connect to links
      elif(isHyperEdge(obj)): 
        coords[-2], coords[-1] = obj.getCenterCoord()
        
      else:
        # Failure! The object had no connectors. Oooops.
        if(self.pilotArrow.rollbackArrow([x, y])):
#          self.UI_scope.event("Reset")
          self.UI_scope("Reset", None)
        return
      
      
      # Get the semantic object
      self.sem_objTo = obj.semanticObject	        
      self.sem_objFrom = self.pilotArrow.getFromObject().semanticObject 
      self.toClass = tags[0]
      self.fromClass = self.pilotArrow.getFromTag()
      
      # Arrow is connecting the object to itself with just 2 points! BAD
      if(self.sem_objTo == self.sem_objFrom and len(coords) <= 4):
        pass
      
      # Draw the connection, turn off simpleConnect, since using intermediate 
      # points
      else:             
        smooth = self.pilotArrow.getSmoothness()
        self.inter_connect_points = coords
        drawConnection(self, smooth, simpleConnect = False, 
                         filterLinkTypeList=filterLinkTypeList)
                
    # Unknown something...
    else:
      raise Exception, tags
      
                  
    # Empty variables
    self.fromClass   = None				
    self.toClass     = None
    self.sem_objFrom = None
    self.sem_objTo   = None

    # Model changed!
    modelChange(self)
    
    # Pilot arrow is no longer needed, GOODBYE!      
    self.pilotArrow.removeArrow(False)
    self.UI_scope("<Arrow Created>", None) # Tell UI we succeeded!
    
  # Nope, keep adding intermediate points
  else:

    # Snap Grid
    if(self.snapGridInfoTuple and self.snapGridInfoTuple[2]):
      gridSize = self.snapGridInfoTuple[0]
      coords[-2:] = [ snapIt(x, x, gridSize), snapIt(y, y, gridSize) ]
    
    # No grid snapping
    else:
      coords[-2:] = [ x, y ]
      
    # Apply coords & add a duplicate point
    dc.coords(* [arrow] + coords + coords[-2:])
Пример #8
0
def getSelectedItemsForDelete(self, entityOnlyFlag=False):
  """ 
  Use:
    Finds all the selected nodes and links, then creates a custom event, 
    DeleteEvent, which it sends to the UI_scope that then sends the event
    to whichever scoped statechart will handle it. The DeleteEvent uses the
    x, y coordinates of the node/link to be deleted, so potentially, each
    node/link's deletion could be handled by a different scoped statechart. 
  Parameters:
    self, ATOM3 instance
    entityOnlyFlag, if this boolean flag is True, then deleting an entity will
                    NOT automatically delete arrows that connect to that entity
  """
  
  class DeleteEvent:
    """
    A special event that mimics the x, y coordinates of a Tkinter binding
    generated event, but lacks many of the normal attributes, and includes
    tag and itemHandler attributes not normally found there...
    """
    def __init__(self, obj, tag=None,
                itemHandlerTagList=None, entityOnlyFlag=False):
      self.x = obj.x
      self.y = obj.y
      self.tag = tag
      self.semanticObject = obj.semanticObject
      self.atom3i = obj.semanticObject.parent
      self.itemHandlerTagList = itemHandlerTagList
      self.entityOnlyFlag = entityOnlyFlag
      
    def destroy(self):
      """ Deletes the associated ATOM3 node or link """
      if(self.itemHandlerTagList):
        tag2objMap = self.atom3i.cb.getTag2ObjMap()
        for itemHandler, tag in self.itemHandlerTagList:
          # Deleting one segment of an arrow, can delete the other, so careful!
          if(tag2objMap.has_key(tag)):
            self.atom3i.deleteConnection(itemHandler, tag)
      else:
        self.atom3i.deleteRealEntity(self.tag, entityOnly=self.entityOnlyFlag)
    
    def getSemanticObject(self):
      """ Returns the ASGNode instance being deleted """
      return self.semanticObject
  
  selectionDict = self.cb.getSelectionDict() # Dict of selected items
  objTagDict = dict()
  
  self.fromClass = None
  self.toClass = None
  
  # This little dictionary gymnastic is being used to prevent duplicate objects
  for tag in selectionDict:
    obj = selectionDict[tag][1]
    objTagDict.update({obj:tag})

  # Now do the connections first, since if entities disappear, 
  # connections might too. And we DO NOT want that to happen... crash crash :p
  for obj in objTagDict:
    tag = objTagDict[obj]
    
    # Connection
    if(isConnectionLink(obj)):  
      #print "Now deleting connection: ", tag, obj, selectionDict[tag][0]
      # This may seem like overkill, but it's necessary for hyper-edges
      connList = []
      for connTuple in obj.in_connections_:  
        connList.append(connTuple)
      for connTuple in obj.out_connections_: 
        connList.append(connTuple)
        
      itemHandlerTagList = []
      for connTuple in connList:
        itemHandlerTagList.append(connTuple[:2])          
      event = DeleteEvent(obj, itemHandlerTagList=itemHandlerTagList)
      self.UI_scope('<serviceLinkDeleteRequest>', event)
      
    # Entity
    else:  
      event = DeleteEvent(obj, tag=tag, entityOnlyFlag=entityOnlyFlag)
      self.UI_scope('<serviceNodeDeleteRequest>', event)
      
  # Model changed!
  modelChange(self)
    
  # No more selected objects :-(
  self.cb.clearSelectionDict()
Пример #9
0
def scaleReset(self, textMode=False):
    """ Restores scale to 1.0 """

    # Re-Size the text of an Entity or Link
    if (textMode):

        allScalableEntityObjects = []
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):
                allScalableEntityObjects.append(object)
            elif (object.getCenterObject()):
                allScalableEntityObjects.append(object.getCenterObject())

        for object in allScalableEntityObjects:
            # Get the last scale factor
            if (not object.layConstraints.has_key('Text Scale')):
                object.layConstraints['Text Scale'] = 1.00
            object.ScaleText(1.00)
            object.layConstraints['Text Scale'] = 1.00

    # Re-Size an entity node - NO QOCA
    elif (isNotUsingQoca()):
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):

                # Get the last scale factor
                if (not object.layConstraints.has_key('scale')):
                    object.layConstraints['scale'] = [1.00, 1.00]
                sx, sy = object.layConstraints['scale']
                newSize = [1.00, 1.00]

                # The final scale factor
                sx, sy = [newSize[0] / sx, newSize[1] / sy]

                # Note: moveLinks is fals only because optimizeConnectionPorts is better
                #object.Scale(sx, sy, moveLinks = False)
                x0, y0 = object.getbbox()[:2]
                object.dc.scale(object.tag, x0, y0, sx, sy)
                object.moveTo(object.x, object.y)
                object.layConstraints['scale'] = newSize

        optimizeConnectionPorts(self)

    # Re-Size an entity node - WITH QOCA constraints
    else:
        allScalableEntityObjects = []
        for object in self.cb.getSelectionObjectSet():
            if (isEntityNode(object)):
                allScalableEntityObjects.append(object)

        # Make the width/height editable
        editVarList = []
        for obj in allScalableEntityObjects:
            editVarList.append(obj.qcW)
            editVarList.append(obj.qcH)
        self.qocaSolver.addEditVars(editVarList)

        # Suggest new width/height values
        for obj in allScalableEntityObjects:
            self.qocaSolver.suggestVarValue([(obj.qcW, obj.sizeX),
                                             (obj.qcH, obj.sizeY)])

        # Solve to get the new width/height of the entity
        self.qocaSolver.resolve(forceSolve=True)
        self.qocaSolver.endEdit()
        optimizeConnectionPorts(self)

    modelChange(self)  # Model changed, update statusbar & undo
Пример #10
0
def scaleWithMotion(self, event, textMode=False):
    """ Scales selected entities with the mouse motion """

    cb = self.cb

    x0, y0 = cb.getLastClickCoord()
    x1, y1 = cb.getCanvasCoords(event)

    allScalableEntityObjects = []
    for object in cb.getSelectionObjectSet():
        if (isEntityNode(object)):
            allScalableEntityObjects.append(object)
        elif (object.getCenterObject()):
            allScalableEntityObjects.append(object.getCenterObject())

    # Re-Size the text of an Entity or Link
    if (textMode):
        dx, dy = [float(x1 - x0) / 100.0, float(y1 - y0) / 100.0]

        for object in allScalableEntityObjects:
            # Get the last scale factor, and add the movement delta
            if (not object.layConstraints.has_key('Text Scale')):
                object.layConstraints['Text Scale'] = 1.00

            newSize = object.layConstraints['Text Scale'] + dy

            # Bigger is better, too small is unreadable :D
            if (newSize < 0.2):
                newSize = 0.2

            object.ScaleText(newSize)
            object.layConstraints['Text Scale'] = newSize

    # Re-Size an entity node - NO QOCA
    elif (isNotUsingQoca()):
        dx, dy = [float(x1 - x0) / 100.0, float(y1 - y0) / 100.0]
        for object in allScalableEntityObjects:

            # Get the last scale factor, and add the movement delta
            if (not object.layConstraints.has_key('scale')):
                object.layConstraints['scale'] = [1.00, 1.00]
            sx, sy = object.layConstraints['scale']
            newSize = [sx + dx, sy + dy]

            # Too small is not good :p
            if (newSize[0] < 0.2):
                newSize[0] = 0.2
            if (newSize[1] < 0.2):
                newSize[1] = 0.2

            # The final scale factor
            sx, sy = [newSize[0] / sx, newSize[1] / sy]

            # Note: moveLinks is false only because optimizeConnectionPorts is better
            #object.Scale(sx, sy, moveLinks = False)
            x0, y0 = object.getbbox()[:2]
            object.dc.scale(object.tag, x0, y0, sx, sy)
            object.moveTo(object.x, object.y)
            object.layConstraints['scale'] = newSize

        optimizeConnectionPorts(self)

    # Re-Size an entity node - WITH QOCA constraints
    else:
        dx, dy = [float(x1 - x0), float(y1 - y0)]

        # Make the width/height editable
        editVarList = []
        for obj in allScalableEntityObjects:
            editVarList.append(obj.qcW)
            editVarList.append(obj.qcH)
        self.qocaSolver.addEditVars(editVarList)

        # Suggest new width/height values
        for obj in allScalableEntityObjects:
            self.qocaSolver.suggestVarValue([(obj.qcW, obj.qcW.get() + dx),
                                             (obj.qcH, obj.qcH.get() + dy)])

        # Solve to get the new width/height of the entity
        self.qocaSolver.resolve(forceSolve=True)
        self.qocaSolver.endEdit()
        object.layConstraints['scale'] = [
            obj.qcW.get() / obj.sizeX,
            obj.qcH.get() / obj.sizeY
        ]
        optimizeConnectionPorts(self)

    modelChange(self)  # Model changed, update statusbar & undo
Пример #11
0
def dropArrowPoints(self, event, snap=True, filterLinkTypeList=None):
    """ 
  Drops intermediate points in the arrow or connects the arrow to the final
  object. If connection is not possible due to the final object not having 
  connectors, the arrow will be rolled back 1 connection point, or destroyed
  """

    cb = self.cb  # User-interface callback object
    dc = cb.getCanvas()
    x, y = cb.getCanvasCoords(event)  # Event coordinates

    arrow = self.pilotArrow.getArrow()
    coords = dc.coords(arrow)

    # Find the closest item to the arrow
    itemTuple = cb.getItemUnderCursor(self, event, ignore=arrow, allTags=True)
    if (itemTuple and snap):
        itemHandler, tags, obj = itemTuple

        # Embedded model  ---> WARNING: Not tested, original AToM3 code
        if (len(tags) >= 2 and tags[1][:4] == 'ASG_'):
            self.toClass = tags[0]
            # Open to select the entity inside the model
            ATOM3TypeDialog(self, obj.semanticObject, ATOM3TypeDialog.OPEN,
                            (None, self.setConnectMode))
            # Check if we have both sides...
            if self.sem_objFrom and self.sem_objTo:  # we have both sides...
                drawConnection(self)

        # Object
        elif (tags[0][:3] == 'Obj'):

            # Get the actual connector point that we are going to connect to
            # coords[-4],coords[-3] are the before last point, so the min distance
            # that point to the connector yields the optimal final point.
            # Some objects may not have connectors, in this case gracefully rollback
            # the arrow
            if (obj.hasConnectors()):
                coords[-2], coords[-1] = obj.getMinDistance_Connectors2Fixed(
                    obj, coords[-4], coords[-3])
                if (obj.hasNamedPorts() and self.showNamedPortMessage):
                    name = obj.guesstimateNamedConnAtPoint(
                        coords[-2], coords[-1])
                    if (name):
                        text = 'Arrow ended on named port: '  \
                                + name \
                                + '\n\nThis message is shown only when you end an arrow' \
                                + ' directly on a named port' \
                                + '\n\nIf you choose the 2nd option and want to see these '\
                                + 'messages again, restart AToM3'
                        dialog = Dialog.Dialog(
                            None, {
                                'title':
                                'Lock Current Named Port',
                                'text':
                                text,
                                'bitmap':
                                '',
                                'default':
                                0,
                                'strings': (name, 'Rollback arrow',
                                            'Never show this message')
                            })
                        if (dialog.num == 1):
                            return
                        if (dialog.num == 2):
                            self.showNamedPortMessage = False

            # Edge just happens to have a connector
            elif (obj.hasCenterObjectConnector()):
                coords[-2], coords[-1] = obj.getCenterCoord()

            # Hyperedge! This means that links can connect to links
            elif (isHyperEdge(obj)):
                coords[-2], coords[-1] = obj.getCenterCoord()

            else:
                # Failure! The object had no connectors. Oooops.
                if (self.pilotArrow.rollbackArrow([x, y])):
                    #          self.UI_scope.event("Reset")
                    self.UI_scope("Reset", None)
                return

            # Get the semantic object
            self.sem_objTo = obj.semanticObject
            self.sem_objFrom = self.pilotArrow.getFromObject().semanticObject
            self.toClass = tags[0]
            self.fromClass = self.pilotArrow.getFromTag()

            # Arrow is connecting the object to itself with just 2 points! BAD
            if (self.sem_objTo == self.sem_objFrom and len(coords) <= 4):
                pass

            # Draw the connection, turn off simpleConnect, since using intermediate
            # points
            else:
                smooth = self.pilotArrow.getSmoothness()
                self.inter_connect_points = coords
                drawConnection(self,
                               smooth,
                               simpleConnect=False,
                               filterLinkTypeList=filterLinkTypeList)

        # Unknown something...
        else:
            raise Exception, tags

        # Empty variables
        self.fromClass = None
        self.toClass = None
        self.sem_objFrom = None
        self.sem_objTo = None

        # Model changed!
        modelChange(self)

        # Pilot arrow is no longer needed, GOODBYE!
        self.pilotArrow.removeArrow(False)
        self.UI_scope("<Arrow Created>", None)  # Tell UI we succeeded!

    # Nope, keep adding intermediate points
    else:

        # Snap Grid
        if (self.snapGridInfoTuple and self.snapGridInfoTuple[2]):
            gridSize = self.snapGridInfoTuple[0]
            coords[-2:] = [snapIt(x, x, gridSize), snapIt(y, y, gridSize)]

        # No grid snapping
        else:
            coords[-2:] = [x, y]

        # Apply coords & add a duplicate point
        dc.coords(*[arrow] + coords + coords[-2:])
Пример #12
0
def getSelectedItemsForDelete(self, entityOnlyFlag=False):
    """ 
  Use:
    Finds all the selected nodes and links, then creates a custom event, 
    DeleteEvent, which it sends to the UI_scope that then sends the event
    to whichever scoped statechart will handle it. The DeleteEvent uses the
    x, y coordinates of the node/link to be deleted, so potentially, each
    node/link's deletion could be handled by a different scoped statechart. 
  Parameters:
    self, ATOM3 instance
    entityOnlyFlag, if this boolean flag is True, then deleting an entity will
                    NOT automatically delete arrows that connect to that entity
  """
    class DeleteEvent:
        """
    A special event that mimics the x, y coordinates of a Tkinter binding
    generated event, but lacks many of the normal attributes, and includes
    tag and itemHandler attributes not normally found there...
    """
        def __init__(self,
                     obj,
                     tag=None,
                     itemHandlerTagList=None,
                     entityOnlyFlag=False):
            self.x = obj.x
            self.y = obj.y
            self.tag = tag
            self.semanticObject = obj.semanticObject
            self.atom3i = obj.semanticObject.parent
            self.itemHandlerTagList = itemHandlerTagList
            self.entityOnlyFlag = entityOnlyFlag

        def destroy(self):
            """ Deletes the associated ATOM3 node or link """
            if (self.itemHandlerTagList):
                tag2objMap = self.atom3i.cb.getTag2ObjMap()
                for itemHandler, tag in self.itemHandlerTagList:
                    # Deleting one segment of an arrow, can delete the other, so careful!
                    if (tag2objMap.has_key(tag)):
                        self.atom3i.deleteConnection(itemHandler, tag)
            else:
                self.atom3i.deleteRealEntity(self.tag,
                                             entityOnly=self.entityOnlyFlag)

        def getSemanticObject(self):
            """ Returns the ASGNode instance being deleted """
            return self.semanticObject

    selectionDict = self.cb.getSelectionDict()  # Dict of selected items
    objTagDict = dict()

    self.fromClass = None
    self.toClass = None

    # This little dictionary gymnastic is being used to prevent duplicate objects
    for tag in selectionDict:
        obj = selectionDict[tag][1]
        objTagDict.update({obj: tag})

    # Now do the connections first, since if entities disappear,
    # connections might too. And we DO NOT want that to happen... crash crash :p
    for obj in objTagDict:
        tag = objTagDict[obj]

        # Connection
        if (isConnectionLink(obj)):
            #print "Now deleting connection: ", tag, obj, selectionDict[tag][0]
            # This may seem like overkill, but it's necessary for hyper-edges
            connList = []
            for connTuple in obj.in_connections_:
                connList.append(connTuple)
            for connTuple in obj.out_connections_:
                connList.append(connTuple)

            itemHandlerTagList = []
            for connTuple in connList:
                itemHandlerTagList.append(connTuple[:2])
            event = DeleteEvent(obj, itemHandlerTagList=itemHandlerTagList)
            self.UI_scope('<serviceLinkDeleteRequest>', event)

        # Entity
        else:
            event = DeleteEvent(obj, tag=tag, entityOnlyFlag=entityOnlyFlag)
            self.UI_scope('<serviceNodeDeleteRequest>', event)

    # Model changed!
    modelChange(self)

    # No more selected objects :-(
    self.cb.clearSelectionDict()