Changeset 370

Show
Ignore:
Timestamp:
Wed Jan 30 02:55:14 2008
Author:
Brian
Message:

Some old bug fixes that I hadn't committed. Plus some clean up for the demo. Added context menu for shapes.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • scripts/trunk/ORM/Auto Layout of ORM Model.py

    r357 r370  
    87 87 # constants from "graph"  
    88 88 # DEFINITION OF OBJECT WINDOW PARAMETERS  
    89   OVERWINDOW_X = 1000.0  
    90   OVERWINDOW_Y = 1000.0  
    91   WALL_MARGIN = (OVERWINDOW_X / 10.0)  
      89 OVERWINDOW_X = 1200.0  
      90 # OVERWINDOW_Y = 1400.0  
      91 OVERWINDOW_Y = 1800.0  
      92 WALL_MARGIN = 100 # (OVERWINDOW_X / 10.0)  # push all 100 away from walls  
    92 93  
    93 94 # MAXIMAL ALLOWABLE RELATION OF TWO NODES  
     
    121 122 # CONSTANTS  
    122 123 TIME_STEP = 0.1  # time step of diff equ  
    123   MAX_TIME_SCALE = 10.0  # scale of max time of solution  
      124 MAX_TIME_SCALE = 5.0  # 10.0  # scale of max time of solution  
    123 124  
    124 125 MAX_FORCE = 500.0  # force shows instability  
     
    132 133 ZERO_DIST = 10.0  # distance considered as 0  
    133 134 WALL_OUT_DRIVE = 80.0  # forces of the wall  
    134   WALL_MARGIN_DRIVE = 1.0  
      135 WALL_MARGIN_DRIVE = 40.0  
    134 135 ROLE_SEQ_DRIVE = 10.0  # force to put role connectors in sequence-order  
    135 136  
     
    174 175     moveable_nodes = [ x for x in all_shapes if (  
    175 176         not x.NodeAID  # not lines  
    176           and True  # moveable test?  
      177         and x.Moveable()  
    176 177         )]  
    177 178         # what about constraints (can a relation also be a node??  
     
    208 209     if debug: print 'nmovnode %s nfixnode %s' % (nmovnode, nfixnode)  
    209 210      
    210       MAX_TIME = MAX_TIME_SCALE * 2 # (nmovnode + nfixnode + 1)  
      211     MAX_TIME = MAX_TIME_SCALE * 1 # (nmovnode + nfixnode + 1)  
    210 211  
    211 212     # INIT SPEED OF MOVEABLE NODES TO 0  
     
    227 228          
    228 229         # INITIALIZE FORCE IN NODES TO 0  
      230 #        for node in moveable_nodes:  
    229 231         for node in moveable_nodes:  
    230 232             node.SetForce(vector( 0.0, 0.0 ))  
     
    244 246             for n2 in range(n1+1, len(nodes)):                 
    245 247                 nodeb = nodes[n2]  
    246    
    247 248                 # I should only do this if one of the nodes is moveable???  
      249                 if not nodea.Moveable() and not nodeb.Moveable(): continue  
      250  
    248 251 #                if debug: print nodea.__class__, nodeb.__class__  
    249 252 #                if debug: print 'nodea %s, nodeb %s' % (nodea.Position, nodeb.Position)  
     
    283 286  
    284 287                     drive /= 3  # float(maxsernum + nfixnode);  # I don't know about this yet  
    285                       nodea.AddForceR(drive);  
    286                       nodeb.AddForceR(-drive);  
      288                     if nodea.Moveable(): nodea.AddForceR(drive)  
      289                     if nodeb.Moveable(): nodeb.AddForceR(-drive)  
    287 290                 else:  # unrelated nodes  
    288 291                     constraint = MINCONSTRAINT + MAXRELATION * SCALECONSTRAINT  
     
    293 296 #                if debug: print 'constraint %s, pre-drive %s' % (constraint, drive)  
    294 297 #                if debug: print 'adjusted drive %s' % drive  
    295                       nodea.AddForceNR(drive);  
    296                       nodeb.AddForceNR(-drive);  
      298                     if nodea.Moveable():  nodea.AddForceNR(drive)  
      299                     if nodeb.Moveable():  nodeb.AddForceNR(-drive)  
    297 300  
    298 301 ##        return  
     
    348 351                 node.SetForce(node.Force * 20 / node.Force.Size())  
    349 352             # sum of wall, relational, and non-relational forces  
    350               if debug: print 'Node %s, wall %s, relational %s, non-rel %s' % (node, node.Force, node.ForceR, node.ForceNR)  
      353             #if debug: print 'Node %s, wall %s, relational %s, non-rel %s' % (node, node.Force, node.ForceR, node.ForceNR)  
    350 353             node.SetForce(node.Force + node.ForceR + node.ForceNR)  
    351 354  
     
    359 362                 # I reversed the order of the multiply because the vector has to be first  
    360 363                 # in this implementation  
    361               if debug: print 'Node %s, old speed %s, new speed %s, position %s' % (node, old_speed, node.Speed, node.Position)  
      364             #if debug: print 'Node %s, old speed %s, new speed %s, position %s' % (node, old_speed, node.Speed, node.Position)  
    361 364  
    362 365             # update the display and pause So I can see the effect it has  
     
    370 373             canvas.Update()  
    371 374  
    372    
    373 375             # CALCULATE MAXIMUM FORCE  
    374 376             abs_force = node.Force.Size()  
  • scripts/trunk/ORM/Open ORM Window.py

    r354 r370  
    54 54 #           Revise window layout within frame. Implement a draft of auto layout.  
    55 55 #           Implement multiple selection.  
      56 # 080129 - Some clean up before the demo  
    56 57  
    57 58 import wx  
     
    443 444 # CustomTreeCtrl Demo Implementation  
    444 445 #---------------------------------------------------------------------------  
      446  
    445 447 class CustomTreeCtrl(CT.CustomTreeCtrl):  
    446 448  
     
    557 559         self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnItemCheck)  
    558 560  
    559           self.eventdict = {'EVT_TREE_BEGIN_DRAG': self.OnBeginDrag, 'EVT_TREE_BEGIN_LABEL_EDIT': self.OnBeginEdit,  
    560                             'EVT_TREE_BEGIN_RDRAG': self.OnBeginRDrag, 'EVT_TREE_DELETE_ITEM': self.OnDeleteItem,  
    561                             'EVT_TREE_END_DRAG': self.OnEndDrag, 'EVT_TREE_END_LABEL_EDIT': self.OnEndEdit,  
    562                             'EVT_TREE_ITEM_ACTIVATED': self.OnActivate, 'EVT_TREE_ITEM_CHECKED': self.OnItemCheck,  
    563                             'EVT_TREE_ITEM_CHECKING': self.OnItemChecking, 'EVT_TREE_ITEM_COLLAPSED': self.OnItemCollapsed,  
    564                             'EVT_TREE_ITEM_COLLAPSING': self.OnItemCollapsing, 'EVT_TREE_ITEM_EXPANDED': self.OnItemExpanded,  
    565                             'EVT_TREE_ITEM_EXPANDING': self.OnItemExpanding, 'EVT_TREE_ITEM_GETTOOLTIP': self.OnToolTip,  
    566                             'EVT_TREE_ITEM_MENU': self.OnItemMenu, 'EVT_TREE_ITEM_RIGHT_CLICK': self.OnRightDown,  
    567                             'EVT_TREE_KEY_DOWN': self.OnKey, 'EVT_TREE_SEL_CHANGED': self.OnSelChanged,  
    568                             'EVT_TREE_SEL_CHANGING': self.OnSelChanging, "EVT_TREE_ITEM_HYPERLINK": self.OnHyperLink}  
      561         self.eventdict = {  
      562             'EVT_TREE_BEGIN_DRAG': self.OnBeginDrag,  
      563             'EVT_TREE_BEGIN_LABEL_EDIT': self.OnBeginEdit,  
      564             'EVT_TREE_BEGIN_RDRAG': self.OnBeginRDrag,  
      565             'EVT_TREE_DELETE_ITEM': self.OnDeleteItem,  
      566             'EVT_TREE_END_DRAG': self.OnEndDrag,  
      567             'EVT_TREE_END_LABEL_EDIT': self.OnEndEdit,  
      568             'EVT_TREE_ITEM_ACTIVATED': self.OnActivate,  
      569             'EVT_TREE_ITEM_CHECKED': self.OnItemCheck,  
      570             'EVT_TREE_ITEM_CHECKING': self.OnItemChecking,  
      571             'EVT_TREE_ITEM_COLLAPSED': self.OnItemCollapsed,  
      572             'EVT_TREE_ITEM_COLLAPSING': self.OnItemCollapsing,  
      573             'EVT_TREE_ITEM_EXPANDED': self.OnItemExpanded,  
      574             'EVT_TREE_ITEM_EXPANDING': self.OnItemExpanding,  
      575             'EVT_TREE_ITEM_GETTOOLTIP': self.OnToolTip,  
      576             'EVT_TREE_ITEM_MENU': self.OnItemMenu,  
      577             'EVT_TREE_ITEM_RIGHT_CLICK': self.OnRightDown,  
      578             'EVT_TREE_KEY_DOWN': self.OnKey,  
      579             'EVT_TREE_SEL_CHANGED': self.OnSelChanged,  
      580             'EVT_TREE_SEL_CHANGING': self.OnSelChanging,  
      581             "EVT_TREE_ITEM_HYPERLINK": self.OnHyperLink}  
    569 582  
    570 583         mainframe = wx.GetTopLevelParent(self)  
     
    634 647         return 1  
    635 648  
    636        
      649  
    636 649 ##    def OnIdle(self, event):  
    637 650 ##  
     
    881 894         dlg.ShowModal()  
    882 895         dlg.Destroy()  
    883                    
    884 896          
    885 897  
     
    897 909         self.DeleteChildren(self.current)  
    898 910         self.Delete(self.current)  
    899           self.current = None  
    900            
      911         self.current = None         
    901 912  
    902 913  
     
    1715 1726 SH = 150  
    1716 1727 SHAPE_COUNT = 2500  
    1717   hitradius = 5  
      1728 hitradius = 2  
    1717 1728  
    1718 1729 #---------------------------------------------------------------------------  
     
    1781 1792         # add methods to shape object  
    1782 1793  
      1794 ##    def ClearFollowers(self):  # objects don't have this method soon enough  
      1795 ##        self._SetInShell('followers', [])  
    1783 1796     def Follow(self):  # identify which objects you follow  
    1784 1797         pass  # overriden in subtypes  
    1785 1798     def AddFollower(self, follower_shape):  
    1786 1799         self.followers.append(follower_shape)  
    1787       def GetFollowers(self):  # I should use this instead of accessing followers directly  
    1788           return self.followers  
      1800     def GetFollowers(self):  # use this instead of accessing followers directly  
      1801         return self.followers  # returned value can be iterated over  
    1789 1802     def RemoveFollower(self, follower_shape):  
    1790 1803         pass  
     
    1809 1822     def SetSelected(self):  
    1810 1823         self._SetInShell('IsSelected', True)  
    1811           if debug: print "Select %s" % str(self)  
    1812 1824     def ClearSelected(self):  
    1813 1825         self._SetInShell('IsSelected', False)  
    1814 1826     def GetSelected(self):  
    1815           if debug: print "Getting select on %s" % str(self)  
    1816 1827         return self.IsSelected  
      1828     def NoneSelected(self):  
      1829         return not self.canvas.selection  
      1830     def Moveable(self):  
      1831         ''' if any nodes are selected, then only selected nodes are moveable'''  
      1832         return self.NoneSelected() or self.GetSelected()  
    1817 1833  
    1818 1834     # these are for the autolayout algorithm  
     
    2123 2139         dc.SetPen(pen)  
    2124 2140 #            dc.SetBrush(self.RandomBrush())  
    2125           dc.SetBrush(self.canvas.CachedBrush('White'))  
      2141         if self.GetSelected():  
      2142             dc.SetBrush(self.canvas.CachedBrush((210,210,210)))  
      2143         else:  
      2144             dc.SetBrush(self.canvas.CachedBrush((254,254,254,128)))  
      2145             # dc.SetBrush(self.canvas.CachedBrush('White'))  
    2126 2146         dc.DrawRectangle(box_x,box_y,box_w,box_h)  
    2127 2147  
     
    2175 2195         pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
    2176 2196         dc.SetPen(pen)  
    2177           dc.SetBrush(self.canvas.CachedBrush('White'))  
      2197         if self.GetSelected():  
      2198             dc.SetBrush(self.canvas.CachedBrush((210,210,210)))  
      2199         else:  
      2200             dc.SetBrush(self.canvas.CachedBrush((254,254,254,128)))  
      2201             # dc.SetBrush(self.canvas.CachedBrush('White'))  
    2178 2202         dc.DrawCircle(x,y,box_w/2)  
    2179 2203  
     
    2470 2494         # self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))  
    2471 2495      
    2472   # -- code for popup menu on canvas??? -- This isn't working  
    2473           self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)  
      2496 # -- code for popup menus -- This isn't working  
      2497         self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenuCanvas)  
      2498         self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenuShape)  
    2474 2499  
    2475       def OnContextMenu(self, event):  
      2500 # -- code for popup menu on canvas  
      2501     def OnContextMenuCanvas(self, event):  
    2476 2502         self.popupx, self.popupy = self.ConvertEventCoords(event)  
    2477 2503         #self.log = sys.stdout  
     
    2507 2533         menu = wx.Menu()  
    2508 2534         # Show how to put an icon in the menu  
    2509           item = wx.MenuItem(menu, self.popupID1,"Note")  
    2510   #        bmp = images.getSmilesBitmap()  
    2511           bmp = Menu.Bitmap("icons/New Project.bmp", wx.BITMAP_TYPE_ANY)  
    2512           item.SetBitmap(bmp)  
    2513           menu.AppendItem(item)  
      2535 ##        item = wx.MenuItem(menu, self.popupID1,"Note")  
      2536 ###        bmp = images.getSmilesBitmap()  
      2537 ##        bmp = Menu.Bitmap("icons/New Project.bmp", wx.BITMAP_TYPE_ANY)  
      2538 ##        item.SetBitmap(bmp)  
      2539 ##        menu.AppendItem(item)  
    2514 2540         # add some other items  
      2541         menu.Append(self.popupID1, "Object")  
    2515 2542         menu.Append(self.popupID2, "Fact")  
    2516           menu.Append(self.popupID3, "Constraint")  
    2517           menu.Append(self.popupID4, "Four")  
    2518           menu.Append(self.popupID5, "Undo - not implemented")  
    2519           menu.Append(self.popupID6, "Redo - not implemented")  
      2543         menu.Append(self.popupID3, "Note")  
      2544         menu.Append(self.popupID4, "Constraint")  
      2545 #        menu.Append(self.popupID4, "Four")  
      2546 #        menu.Append(self.popupID5, "Undo - not implemented")  
      2547 #        menu.Append(self.popupID6, "Redo - not implemented")  
    2520 2548         # make a submenu  
    2521           sm = wx.Menu()  
    2522           sm.Append(self.popupID8, "sub item 1")  
    2523           sm.Append(self.popupID9, "sub item 1")  
    2524           menu.AppendMenu(self.popupID7, "Test Submenu", sm)  
      2549 #        sm = wx.Menu()  
      2550 #        sm.Append(self.popupID8, "sub item 1")  
      2551 #        sm.Append(self.popupID9, "sub item 1")  
      2552 #        menu.AppendMenu(self.popupID7, "Test Submenu", sm)  
    2525 2553  
    2526 2554  
     
    2532 2560  
    2533 2561     def OnPopupOne(self, event):  
    2534           new_shape = self.AddNode('ORMNote', self.popupx, self.popupy)  
    2535           Data.SetUndo('Add Note')  
      2562         new_shape = self.AddNode('ORMObjectType', self.popupx, self.popupy)  
      2563         self.ClearSelection()  
      2564         self.SelectObject(new_shape.dcid)  
      2565         Data.SetUndo('Add Object Type')  
    2536 2566         # id = self.shapeid_to_dcid_xref[new_shape.ID]  
    2537 2567         self.RedisplayID(new_shape.dcid)  
     
    2539 2569     def OnPopupTwo(self, event):  
    2540 2570         new_shape = self.AddNode('ORMFactType', self.popupx, self.popupy)  
      2571         self.ClearSelection()  
      2572         self.SelectObject(new_shape.dcid)  
    2541 2573         Data.SetUndo('Add Fact')  
    2542 2574         # id = self.shapeid_to_dcid_xref[new_shape.ID]  
     
    2544 2576  
    2545 2577     def OnPopupThree(self, event):  
      2578         new_shape = self.AddNode('ORMNote', self.popupx, self.popupy)  
      2579         self.ClearSelection()  
      2580         self.SelectObject(new_shape.dcid)  
      2581         Data.SetUndo('Add Note')  
      2582         # id = self.shapeid_to_dcid_xref[new_shape.ID]  
      2583         self.RedisplayID(new_shape.dcid)  
      2584  
      2585     def OnPopupFour(self, event):  
    2546 2586         new_shape = self.AddNode('ORMConstraint', self.popupx, self.popupy)  
      2587         self.ClearSelection()  
      2588         self.SelectObject(new_shape.dcid)  
    2547 2589         Data.SetUndo('Add Constraint')  
    2548 2590 #        id = self.shapeid_to_dcid_xref[new_shape.ID]  
    2549 2591         self.RedisplayID(new_shape.dcid)  
    2550 2592  
    2551       def OnPopupFour(self, event):  
    2552           self.log.WriteText("Popup four\n")  
    2553    
    2554 2593     def OnPopupFive(self, event):  
    2555 2594         self.log.WriteText("Popup five\n")  
     
    2568 2607 # -- end code for popup menu on canvas??? --  
    2569 2608  
      2609 # -- code for popup menu on shape  
      2610     def OnContextMenuShape(self, event):  
      2611         self.popupx, self.popupy = self.ConvertEventCoords(event)  
      2612         #self.log = sys.stdout  
      2613         #self.log.WriteText("OnContextMenu\n")  
      2614  
      2615         # only do this part the first time so the events are only bound once  
      2616         #  
      2617         # Yet another anternate way to do IDs. Some prefer them up top to  
      2618         # avoid clutter, some prefer them close to the object of interest  
      2619         # for clarity.  
      2620         if not hasattr(self, "popsID1"):  
      2621             self.popsID1 = wx.NewId()  
      2622             self.popsID2 = wx.NewId()  
      2623             self.popsID3 = wx.NewId()  
      2624             self.popsID4 = wx.NewId()  
      2625             self.popsID5 = wx.NewId()  
      2626             self.popsID6 = wx.NewId()  
      2627             self.popsID7 = wx.NewId()  
      2628             self.popsID8 = wx.NewId()  
      2629             self.popsID9 = wx.NewId()  
      2630  
      2631             self.Bind(wx.EVT_MENU, self.OnPopsOne, id=self.popsID1)  
      2632             self.Bind(wx.EVT_MENU, self.OnPopsTwo, id=self.popsID2)  
      2633             self.Bind(wx.EVT_MENU, self.OnPopsThree, id=self.popsID3)  
      2634             self.Bind(wx.EVT_MENU, self.OnPopsFour, id=self.popsID4)  
      2635             self.Bind(wx.EVT_MENU, self.OnPopsFive, id=self.popsID5)  
      2636             self.Bind(wx.EVT_MENU, self.OnPopsSix, id=self.popsID6)  
      2637             self.Bind(wx.EVT_MENU, self.OnPopsSeven, id=self.popsID7)  
      2638             self.Bind(wx.EVT_MENU, self.OnPopsEight, id=self.popsID8)  
      2639             self.Bind(wx.EVT_MENU, self.OnPopsNine, id=self.popsID9)  
      2640  
      2641         # make a menu  
      2642         menu = wx.Menu()  
      2643         # Show how to put an icon in the menu  
      2644 #        item = wx.MenuItem(menu, self.popupID1,"Note")  
      2645 #        bmp = images.getSmilesBitmap()  
      2646 #        bmp = Menu.Bitmap("icons/New Project.bmp", wx.BITMAP_TYPE_ANY)  
      2647 #        item.SetBitmap(bmp)  
      2648 #        menu.AppendItem(item)  
      2649         # add some other items  
      2650         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
      2651         if l:  
      2652             shape = self.dcid_to_shape_xref.get(l[0])  
      2653             if shape.TableName == 'ORMObjectType':  
      2654                 target = shape.Get('Target')  
      2655                 if target.Type == 'Entity':  
      2656                     change = 'Value'  
      2657                 else:  
      2658                     change = 'Entity'  
      2659                 menu.Append(self.popsID1, "Change to %s Type" % change)  
      2660 #        menu.Append(self.popsID3, "Constraint")  
      2661 #        menu.Append(self.popsID4, "Four")  
      2662 #        menu.Append(self.popsID5, "Undo - not implemented")  
      2663         menu.Append(self.popsID6, "Dependent Layout Right")  
      2664         # make a submenu  
      2665         sm = wx.Menu()  
      2666         sm.Append(self.popsID8, "Dependent Layout Left")  
      2667 #        sm.Append(self.popsID9, "sub item 1")  
      2668         menu.AppendMenu(self.popsID7, "Dependent Layout", sm)  
      2669  
      2670  
      2671         # Popup the menu.  If an item is selected then its handler  
      2672         # will be called before PopupMenu returns.  
      2673         self.PopupMenu(menu)  
      2674         menu.Destroy()  
      2675  
      2676  
      2677     def OnPopsOne(self, event):  
      2678         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
      2679         if l:  
      2680             shape = self.dcid_to_shape_xref.get(l[0])  
      2681             target = shape.Get('Target')  
      2682             if target.Type == 'Entity':  
      2683                 target.Type = 'Value'  
      2684             else:  
      2685                 target.Type = 'Entity'  
      2686             Data.SetUndo('Set %s Type' % target.Type)  
      2687             self.RedrawID(shape.dcid)  
      2688  
      2689     def OnPopsTwo(self, event):  
      2690         self.log.WriteText("Popup six\n")  
      2691  
      2692     def OnPopsThree(self, event):  
      2693         new_shape = self.AddNode('ORMConstraint', self.popupx, self.popupy)  
      2694         Data.SetUndo('Add Constraint')  
      2695 #        id = self.shapeid_to_dcid_xref[new_shape.ID]  
      2696         self.RedisplayID(new_shape.dcid)  
      2697  
      2698     def OnPopsFour(self, event):  
      2699         self.log.WriteText("Popup four\n")  
      2700  
      2701     def OnPopsFive(self, event):  
      2702         self.log.WriteText("Popup five\n")  
      2703  
      2704     def OnPopsSix(self, event):  
      2705         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
      2706         if l:  
      2707             self.MoveDependents(l[0], 'Name', 'Right')  
      2708         Data.SetUndo('Dependent Layout Right')  
      2709  
      2710     def OnPopsSeven(self, event):  
      2711         self.log.WriteText("Popup seven\n")  
      2712  
      2713     def OnPopsEight(self, event):  
      2714         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
      2715         if l:  
      2716             self.MoveDependents(l[0], 'Name', 'Left')  
      2717         Data.SetUndo('Dependent Layout Left')  
      2718  
      2719     def OnPopsNine(self, event):  
      2720         self.log.WriteText("Popup nine\n")  
      2721 # -- end code for popup menu on shape --  
      2722  
    2570 2723     def ConvertEventCoords(self, event):  
    2571 2724         xView, yView = self.GetViewStart()  
     
    2621 2774 ##        shape._SetInShell('RemoveFollower', RemoveFollower)  
    2622 2775         shape._SetInShell('followers', [])  
      2776 ##        shape.ClearFollowers()  # objects don't have this method yet  
    2623 2777  
    2624 2778         orm_object = shape.Get('Target')  
     
    2775 2929  
    2776 2930     def AddDependentsToSelection(self, id):  
      2931         '''  
      2932 If entity type:  
      2933   Add all children with no other parents  
      2934 If fact type:  
      2935   Add all participating entities  
      2936   '''  
    2777 2937         if debug: print 'AddDependentsToSelection'  
    2778 2938         shape = self.dcid_to_shape_xref.get(id)  
     
    2781 2941             self.AddToSelection(shape.Get('NodeA').dcid)  
    2782 2942             self.AddToSelection(shape.Get('NodeB').dcid)  
    2783           elif shape.Get('Target').Nary:  # fact  
      2943         elif shape.Get('Target').Nary:  # fact type  
    2783 2943             # fact -> roles -> objects (all of them?)  
    2784 2944             print shape.GetFollowers()  
     
    2809 2969                     if debug: print 'nary = 1'  
    2810 2970                     self.AddToSelection(role.dcid)  
    2811                       self.AddToSelection(fact.dcid)                             
      2971                     self.AddToSelection(fact.dcid)  
    2811 2971                 elif len(out_roles) == 2:  # should filter out notes -- TODO!  
    2812 2972                     out_role = out_roles[0]  # should be the fact  
     
    2824 2984                     elif len(shape.GetFollowers()) == 1:  
    2825 2985                         self.AddToSelection(role.dcid)  
    2826                           self.AddToSelection(fact.dcid)                             
      2986                         self.AddToSelection(fact.dcid)  
    2826 2986  
    2827 2987         self.AddToSelection(id)  # last to make sure it is target of keyboard  
      2988                  
      2989     def MoveDependents(self, id, reformat='', direction=''):  
      2990         '''reformat = name of field to sort on'''  
      2991         if debug: print 'AddDependentsToSelection'  
      2992         shape = self.dcid_to_shape_xref.get(id)  
      2993         if shape.NodeAID:  # relation  
      2994             self.AddToSelection(shape.dcid)  
      2995             self.AddToSelection(shape.Get('NodeA').dcid)  
      2996             self.AddToSelection(shape.Get('NodeB').dcid)  
      2997         elif shape.Get('Target').Nary:  # fact type  
      2998             # fact -> roles -> objects (all of them?)  
      2999             print shape.GetFollowers()  
      3000             for role in shape.GetFollowers():  
      3001                 if role.NodeAID:  # relation (role)  
      3002                     if debug: print 'follower id %s' % role.NodeAID  
      3003                     leaf = role.Get('NodeA')  # should be the fact  
      3004                     if leaf.ID == shape.ID:  
      3005                         leaf = role.Get('NodeB')  
      3006                     if debug: print 'leaf followers %s' % leaf.GetFollowers()  
      3007                     # if len(leaf.GetFollowers()) == 1:  # should filter out notes -- TODO!  
      3008                     self.AddToSelection(role.dcid)  
      3009                     self.AddToSelection(leaf.dcid)  
      3010                 else:  # -- are they always relations?  
      3011                     pass  
      3012         elif shape.Get('Target').Name:  # object type -- better test?  
      3013             # object type -> role -> fact -> out_role -> leaf_object  
      3014             grid = []  
      3015             for role in shape.GetFollowers():  
      3016                 if not role.NodeAID: continue  # relation (role)  
      3017                 if debug: print 'role id %s' % role.NodeAID  
      3018                 fact = role.Get('NodeA')  # find the other end  
      3019                 if fact.ID == shape.ID:  
      3020                     fact = role.Get('NodeB')  
      3021                 if debug: print 'fact followers %s' % fact.GetFollowers()  
      3022                 out_roles = fact.GetFollowers()  
      3023                 if len(out_roles) == 1:  # nary = 1  
      3024                     if debug: print 'nary = 1'  
      3025                     self.AddToSelection(role.dcid)  
      3026                     self.AddToSelection(fact.dcid)  
      3027                     grid.append([role, fact])  
      3028                 elif len(out_roles) == 2:  # should filter out notes -- TODO!  
      3029                     out_role = out_roles[0]  # should be the fact  
      3030                     if out_role.ID == role.ID:  
      3031                         out_role = out_roles[1]  
      3032                     leaf = out_role.Get('NodeA')  # should be the fact  
      3033                     if leaf.ID == fact.ID:  
      3034                         leaf = out_role.Get('NodeB')  
      3035                     if len(leaf.GetFollowers()) == 1:  # should filter out notes -- TODO!  
      3036                         self.AddToSelection(role.dcid)  
      3037                         self.AddToSelection(fact.dcid)  
      3038                         self.AddToSelection(out_role.dcid)  
      3039                         self.AddToSelection(leaf.dcid)  
      3040                         grid.append([role, fact, out_role, leaf])  
      3041                     elif len(shape.GetFollowers()) == 1:  
      3042                         self.AddToSelection(role.dcid)  
      3043                         self.AddToSelection(fact.dcid)  
      3044                         grid.append([role, fact])  
    2828 3045  
      3046         self.AddToSelection(id)  # last to make sure it is target of keyboard  
      3047  
      3048         if reformat in ('Name', 'ID') and grid and direction in ('Right', 'Left'):  
      3049             sorter = []  
      3050             if reformat == 'Name':  
      3051                 for i, branch in enumerate(grid):  
      3052                     if len(branch) == 2:  
      3053                         sort_name = ('A', (branch[0].Get('Target').Name  
      3054                                            or branch[1].Get('Target').Name or ''))  
      3055                     else:  # == 4  
      3056                         sort_name = ('B', (branch[2].Get('Target').Name  
      3057                                            or branch[3].Get('Target').Name or ''))  
      3058                     sorter.append((sort_name, i))  
      3059             else:  # 'ID'  
      3060                 for i, branch in enumerate(grid):  
      3061                     if len(branch) == 2:  
      3062                         sort_name = ('A', str(branch[1].ID))  
      3063                     else:  # == 4  
      3064                         sort_name = ('B', str(branch[3].ID))  
      3065                     sorter.append((sort_name, i))  
      3066             y = shape.PosY  
      3067             offsetY = 50  
      3068             offsetX = 80  
      3069             if direction == 'Right':  
      3070                 direction = +1  
      3071             else:  
      3072                 direction = -1  
      3073             if len(grid) % 2:  # odd number  
      3074                 y -= (len(grid) - 1) / 2 * offsetY  
      3075             else:  
      3076                 y -= (len(grid) / 2) * offsetY - offsetY / 2  
      3077             sorter.sort()  
      3078             for x, i in sorter:  
      3079                 branch = grid[i]  
      3080                 x = shape.PosX  
      3081  
      3082                 node = branch[1]  
      3083                 x += offsetX * direction  
      3084                 self.MoveID(node.dcid, x-node.PosX, y-node.PosY-4)  # -4 = half height  
      3085                 self.CommitPositionID(node.dcid)  
      3086                 if len(branch) == 4:  
      3087                     node = branch[3]  
      3088                     x += offsetX * direction  
      3089                     self.MoveID(node.dcid, x-node.PosX, y-node.PosY)  
      3090                     self.CommitPositionID(node.dcid)  
      3091                 y += offsetY  
      3092                  
    2829 3093 ##    def AddNeighborsToSelection(self, id):  
    2830 3094 ##        if debug: print 'AddNeighborsToSelection'  
     
    2943 3207             l = self.pdc.FindObjects(x, y, hitradius)  
    2944 3208             if l:  
    2945                   self.pdc.SetIdGreyedOut(l[0], not self.pdc.GetIdGreyedOut(l[0]))  
    2946                   r = self.pdc.GetIdBounds(l[0])  
    2947                   r.Inflate(4,4)  
    2948                   self.OffsetRect(r)  
    2949                   self.RefreshRect(r, False)  
      3209                 self.OnContextMenuShape(event)  
      3210 ##                self.pdc.SetIdGreyedOut(l[0], not self.pdc.GetIdGreyedOut(l[0]))  
      3211 ##                r = self.pdc.GetIdBounds(l[0])  
      3212 ##                r.Inflate(4,4)  
      3213 ##                self.OffsetRect(r)  
      3214 ##                self.RefreshRect(r, False)  
    2950 3215 # -- code for popup menu on canvas??? --  
    2951 3216             else: # didn't click on any object  
    2952                   self.OnContextMenu(event)  
      3217                 self.OnContextMenuCanvas(event)  
    2952 3217 # -- end code for popup menu on canvas??? --  
    2953 3218         elif event.Dragging() or event.LeftUp():  
     
    3012 3277                         if source.ID != target.ID:  
    3013 3278                             connected = self.ConnectEm(source, target)  # return value if connected?  
    3014                               if connected: Data.SetUndo('Add %s' % 'Connector')  
      3279                             if connected:  
      3280                                 self.ClearSelection()  
      3281                                 self.SelectObject(target.dcid)  
      3282                                 Data.SetUndo('Add %s' % 'Connector')