Changeset 430

Show
Ignore:
Timestamp:
Fri Jun 6 22:52:25 2008
Author:
Alexander
Message:

deontic constraints; three-way role constraints; shift-click on constraint to add role sequence; new icons

Files:

Legend:

Unmodified
Added
Removed
Modified
  • ganttpv/trunk/ORMReport.py

    r403 r430  
    63 63     sz.Add(win,1,wx.EXPAND)  
    64 64     pnl.SetSizerAndFit(sz)  
      65  
      66     wx.EVT_KEY_DOWN(win, pnl2.OnShiftKey)  
      67     wx.EVT_KEY_UP(win, pnl2.OnShiftKey)  
    65 68     return pnl  
    66 69  
  • ganttpv/trunk/ORM.py

    r427 r430  
    61 61 # 080605 - Alex - workaround for bug in GetPixel on MacOSX; moved rolebox connector logic into the fact shape; replaced ctrl-click with cmd-click on Mac  
    62 62 # 080606 - Brian - display constraint symbols, connect correctly to adjacent pairs of roles  
      63 # 080606 - Alex - deontic constraints; three-way role constraints; shift-click on constraint to add role sequence; new icons  
    63 64  
    64 65 import wx  
     
    133 134  
    134 135  
    135   # ---------------- Main.opj replacement -----------  
    136   def opj(path):  
    137       """Convert paths to the platform-specific separator"""  
    138       str = apply(os.path.join, tuple(path.split('/')))  
    139       # HACK: on Linux, a leading / gets lost...  
    140       if path.startswith('/'):  
    141           str = '/' + str  
    142       str = r'C:\Program Files\wxPython2.8 Docs and Demos\demo' + '\\' + str  
    143       return str  
    144    
    145 136 #---------------------------------------------------------------------------  
    146 137  
     
    1297 1288     elif shape_type == 'ORMSubtypeConnectorShape':  # what should this be called?  
    1298 1289         model['ORMSubtypeID'] = nodeb.TableID  
    1299       elif shape_type in ('ORMNoteConnectorShape', 'ORMConstraintConnectorShape'):  # may connect to anything  
      1290     elif shape_type == 'ORMNoteConnectorShape':  # may connect to anything  
    1299 1290         model['TableName'] = nodeb.TableName  
    1300 1291         model['TableID'] = nodeb.TableID  
    1301 1292     else:  
    1302 1293         model[nodeb.TableName + 'ID'] = nodeb.TableID  
    1303       model['Table'] = object_type   
      1294     model['Table'] = object_type  
    1303 1294     object_id = Data.Update(model)['ID']  
    1304 1295  
     
    2052 2043     def Draw(self, dc):  
    2053 2044         orm_object = self.Get('Target')  
    2054           x, y = self.GetPos()  
    2055    
    2056 2045         dc.ClearId(self.dcid)  
    2057 2046         if not orm_object: return  # object has probably been undone  
    2058 2047         dc.SetId(self.dcid)  
    2059 2048  
      2049         x, y = self.GetPos()  
      2050  
    2060 2051         left_margin = 6  
    2061 2052         right_margin = 5  
     
    2206 2197         bx, by = other_end  
    2207 2198         midway = ay + role_box_height / 2  
    2208           rightend = ax + role_box_width * seq  
      2199         right = ax + role_box_width * seq  
    2208 2199  
    2209 2200         if seq == 1 and bx < ax and abs(bx - ax) > abs(by - midway):  
    2210 2201             ay = midway  
    2211           elif seq == nary and ax < bx and abs(bx - rightend) > abs(by - midway):  
    2212               ax = rightend  
      2202         elif seq == nary and right < bx and abs(bx - right) > abs(by - midway):  
      2203             ax = right  
    2213 2204             ay = midway  
    2214 2205         else:  
     
    2227 2218     def Draw(self, dc):  
    2228 2219         orm_object = self.Get('Target')  
      2220         dc.ClearId(self.dcid)  
      2221         if not orm_object: return  # object has probably been undone  
      2222         dc.SetId(self.dcid)  
      2223  
    2229 2224         x, y = self.GetPos()  
    2230 2225 ##        x = self.PosX  # treat this as the center of the shape  
     
    2233 2228         prior_r = self.canvas.pdc.GetIdBounds(self.dcid)  
    2234 2229         if debug: print "prior rectangle", prior_r  
    2235           dc.ClearId(self.dcid)  
    2236           if not orm_object: return  # object has probably been undone  
    2237           dc.SetId(self.dcid)  
    2238    
    2239 2230         nary = orm_object.Nary or 1  
    2240 2231 ##        role_box_height = 8 # 12  
     
    2386 2377         x, y = self.canvas.clickx, self.canvas.clicky  
    2387 2378         role = self.GetRole(x, y)  
    2388           if role: self.canvas.AddRole(role)  
      2379         if role and (role not in self.canvas.rolelist):  
      2380             for r in self.Target.GetList('ORMRole'):  
      2381                 self.canvas.RemoveRole(r)  
      2382             self.canvas.AddRole(role)  
    2389 2383         self._SetInShell('IsSelected', True)  
    2390 2384         self._SetInShell('CharMode', '')  
     
    2436 2430     def Draw(self, dc):  
    2437 2431         orm_object = self.Get('Target')  
    2438   #        orm_object = self.Get('ORMReading')  # make sure this is there  
    2439           x, y = self.GetPos()  
    2440    
    2441 2432         dc.ClearId(self.dcid)  
    2442 2433         if not orm_object: return  # object has probably been undone  
    2443 2434         dc.SetId(self.dcid)  
    2444 2435  
      2436         x, y = self.GetPos()  
      2437  
    2445 2438         text = orm_object.Reading or ''  
    2446 2439         lines = text.splitlines()  
     
    2503 2496 class ORMRoleNameShape(ORMFollowText):  
    2504 2497     def Draw(self, dc):  
    2505   ##        orm_object = self.Get('Target')  
    2506   ##        if not orm_object: return  # object has probably been undone  
    2507 2498         orm_object = self.Get('ORMRole')  # make sure this is there?  
    2508           if not orm_object:  
    2509               if debug: print 'RoleNameShape not attached to role'  
    2510               return  # object has probably been undone  
    2511           x, y = self.GetPos()  
    2512    
    2513 2499         dc.ClearId(self.dcid)  
    2514 2500         if not orm_object: return  # object has probably been undone  
    2515 2501 ##        dc.SetId(self.dcid)  
    2516 2502 ##  
      2503 ##        x, y = self.GetPos()  
      2504 ##  
    2517 2505 ##        text = (orm_object.Name or '')  
    2518 2506 ##        if text: text = '[' + text + ']'  
     
    2580 2568     def Draw(self, dc):  
    2581 2569         orm_object = self.Get('Target')  
    2582           x, y = self.GetPos()  
    2583   ##        x = self.PosX  # treat this as the center of the shape  
    2584   ##        y = self.PosY  
    2585    
    2586 2570         dc.ClearId(self.dcid)  
    2587 2571         if not orm_object: return  # object has probably been undone  
    2588 2572         dc.SetId(self.dcid)  
    2589 2573  
      2574         x, y = self.GetPos()  
      2575 ##        x = self.PosX  # treat this as the center of the shape  
      2576 ##        y = self.PosY  
      2577  
    2590 2578         text = orm_object.Text or 'empty note'  
    2591 2579         lines = text.splitlines()  
     
    2646 2634     def Draw(self, dc):  
    2647 2635         orm_object = self.Get('Target')  
    2648           x, y = self.GetPos()  
    2649   ##        x = self.PosX  # treat this as the center of the shape  
    2650   ##        y = self.PosY  
    2651    
    2652 2636         dc.ClearId(self.dcid)  
    2653 2637         if not orm_object: return  # object has probably been undone  
    2654 2638         dc.SetId(self.dcid)  
    2655 2639  
      2640         x, y = self.GetPos()  
      2641 ##        x = self.PosX  # treat this as the center of the shape  
      2642 ##        y = self.PosY  
      2643  
    2656 2644         box_w = 14  # 20  
    2657 2645         box_h = box_w  
     
    2659 2647         box_y = y - box_h/2  
    2660 2648  
    2661           pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
      2649         if orm_object.Deontic:  
      2650             pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
      2651         else:  # Alethic  
      2652             pen = self.canvas.CachedPen(3, 1, wx.SOLID)  
    2662 2653         dc.SetPen(pen)  
    2663 2654         if self.GetSelected():  
     
    2726 2717     def Draw(self, dc):  
    2727 2718         orm_object = self.Get('Target')  
    2728           x, y = self.GetPos()  
    2729   ##        x = self.PosX  # treat this as the center of the shape  
    2730   ##        y = self.PosY  
    2731    
    2732 2719         dc.ClearId(self.dcid)  
    2733 2720         if not orm_object: return  # object has probably been undone  
    2734 2721         dc.SetId(self.dcid)  
    2735 2722  
      2723         x, y = self.GetPos()  
      2724 ##        x = self.PosX  # treat this as the center of the shape  
      2725 ##        y = self.PosY  
      2726  
    2736 2727         box_w = 14  # 20  
    2737 2728         box_h = box_w  
     
    2739 2730         box_y = y - box_h/2  
    2740 2731  
    2741           pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
      2732         if orm_object.Deontic:  
      2733             pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
      2734         else:  # Alethic  
      2735             pen = self.canvas.CachedPen(3, 1, wx.SOLID)  
    2742 2736         dc.SetPen(pen)  
    2743 2737         if self.GetSelected():  
     
    2777 2771     def Draw(self, dc):  
    2778 2772         orm_object = self.Get('Target')  
    2779           x, y = self.GetPos()  
    2780           nodea = self.Get('NodeA')  # these objects might not already be in the diagram  
    2781           nodeb = self.Get('NodeB')  
    2782    
    2783 2773         dc.ClearId(self.dcid)  
    2784 2774         if not orm_object: return  # object has probably been undone  
    2785 2775         dc.SetId(self.dcid)  
    2786 2776          
      2777         x, y = self.GetPos()  
      2778         nodea = self.Get('NodeA')  # these objects might not already be in the diagram  
      2779         nodeb = self.Get('NodeB')  
      2780  
    2787 2781         seq = orm_object.Seq or 1  
    2788 2782         endb = nodeb.GetPos()  
    2789           enda = nodea.AdjustEnd(endb, seq)  
      2783         enda = nodea.AdjustEnd(endb, seq)  # nodeA should be a fact shape  
    2789 2783         endb = nodeb.AdjustEnd(enda)  
    2790 2784  
     
    2844 2838     def Draw(self, dc):  
    2845 2839         orm_object = self.Get('Target')  
      2840         dc.ClearId(self.dcid)  
      2841         if not orm_object: return  # object has probably been undone  
      2842         dc.SetId(self.dcid)  
      2843  
    2846 2844         x, y = self.GetPos()  # treat this as the center of the shape  
    2847 2845         nodea = self.Get('NodeA')  # these objects might not already be in the diagram  
     
    2851 2849         endb = nodeb.GetPos()  
    2852 2850         enda, endb = nodea.AdjustEnd(endb), nodeb.AdjustEnd(enda)  
    2853    
    2854           dc.ClearId(self.dcid)  
    2855           if not orm_object: return  # object has probably been undone  
    2856           dc.SetId(self.dcid)  
    2857 2851          
    2858 2852         minx = min(enda[0], endb[0])  
     
    2892 2886     def Draw(self, dc):  
    2893 2887         orm_object = self.Get('Target')  
    2894           x, y = self.GetPos()  
    2895           nodea = self.Get('NodeA')  
    2896           nodeb = self.Get('NodeB')  
    2897    
    2898 2888         dc.ClearId(self.dcid)  
    2899 2889         if not orm_object: return  # object has probably been undone  
    2900 2890         dc.SetId(self.dcid)  
    2901 2891  
      2892         x, y = self.GetPos()  
      2893         nodea = self.Get('NodeA')  
      2894         nodeb = self.Get('NodeB')  
      2895  
    2902 2896         enda = nodea.GetPos()  
    2903 2897         endb = nodeb.GetPos()  
     
    2925 2919     def Draw(self, dc):  
    2926 2920         orm_object = self.Get('Target')  
    2927           x, y = self.GetPos()  
    2928           nodea = self.Get('NodeA')  # these objects might not already be in the diagram  
    2929           nodeb = self.Get('NodeB')  
    2930    
    2931 2921         dc.ClearId(self.dcid)  
    2932 2922         if not orm_object: return  # object has probably been undone  
    2933 2923         dc.SetId(self.dcid)  
    2934 2924          
      2925         x, y = self.GetPos()  
      2926         nodea = self.Get('NodeA')  # these objects might not already be in the diagram  
      2927         nodeb = self.Get('NodeB')  
      2928  
    2935 2929         constraintlist = self.Get('Target')  
    2936 2930         cr_list = constraintlist.GetList('ORMConstraintRole')  
    2937 2931         # remove constraint roles that aren't for this fact  
    2938           fact_roles = [ cr for cr in cr_list if cr.ORMRole.ORMFactTypeID == nodea.Target.ID ]         
    2939           if len(fact_roles) == 0:  
    2940               seq = 1  
    2941           elif len(fact_roles) == 1:  
    2942               role = fact_roles[0].ORMRole  
    2943               seq = role.Seq or 1  
    2944           elif (len(fact_roles) == 2  
    2945               and abs(fact_roles[0].ORMRole.Seq - fact_roles[1].ORMRole.Seq) == 1):  
    2946               seq = float(fact_roles[0].ORMRole.Seq + fact_roles[1].ORMRole.Seq)/2  
    2947           else:  # much more complicated (but do it later)  
    2948               role = fact_roles[0].ORMRole  
    2949               seq = role.Seq or 1  
      2932         fact_roles = [cr.ORMRole for cr in cr_list if cr.ORMRole.ORMFactTypeID == nodea.Target.ID]  
      2933         seq_numbers = [role.Seq for role in fact_roles]  
      2934         if not seq_numbers: return  
      2935  
      2936         if orm_object.ORMConstraint.Deontic:  
      2937             c = 1  
      2938         else:  # Alethic  
      2939             c = 3  
      2940  
      2941         min_seq = min(seq_numbers)  
      2942         max_seq = max(seq_numbers)  
      2943         seq = (min_seq + max_seq) / 2.0  
    2950 2944  
    2951 2945         endb = nodeb.GetPos()  
    2952           enda = nodea.AdjustEnd(endb, seq)  
      2946         enda = nodea.AdjustEnd(endb, seq)  # nodeA should be a fact shape  
    2952 2946         endb = nodeb.AdjustEnd(enda)  
    2953 2947  
     
    2957 2951         miny = min(enda[1], endb[1])  
    2958 2952         maxy = max(enda[1], endb[1])  
      2953  
      2954         if max_seq - min_seq > 1:  
      2955             # make room for the horizontal bar  
      2956             factX, factY = enda  
      2957             if factY < nodea.GetCenter()[1]:  
      2958                 barY = factY - 4  
      2959             else:  
      2960                 barY = factY + 4  
      2961             enda = factX, barY  
      2962  
      2963             leftX = nodea.AdjustEnd(enda, min_seq)[0]  
      2964             rightX = nodea.AdjustEnd(enda, max_seq)[0]  
      2965             pen = self.canvas.CachedPen(c, 1, wx.SOLID)  
      2966             dc.SetPen(pen)  
      2967             dc.DrawLine(leftX, barY, rightX, barY)  
      2968  
      2969             for s in seq_numbers:  
      2970                 roleX = nodea.AdjustEnd(enda, s)[0]  
      2971                 dc.DrawLine(roleX, factY, roleX, barY)  
      2972  
      2973             minx = min(minx, leftX)  
      2974             maxx = max(maxx, rightX)  
      2975             miny = min(miny, barY, factY)  
      2976             maxy = max(maxy, barY, factY)  
    2959 2977          
    2960 2978         box_w = maxx - minx + 6  
    2961 2979         box_h = maxy - miny + 6  
    2962 2980  
    2963           pen = self.canvas.CachedPen(0, 1, wx.SOLID)  
      2981         pen = self.canvas.CachedPen(c, 1, wx.DOT)  
    2963 2981         dc.SetPen(pen)  
    2964 2982         dc.DrawLine(enda[0], enda[1], endb[0], endb[1])  
     
    2974 2992     def Draw(self, dc):  
    2975 2993         orm_object = self.Get('Target')  
    2976           x, y = self.GetPos()  
    2977           nodea = self.Get('NodeA')  
    2978           nodeb = self.Get('NodeB')  
    2979    
    2980 2994         dc.ClearId(self.dcid)  
    2981 2995         if not orm_object: return  # object has probably been undone  
    2982 2996         dc.SetId(self.dcid)  
    2983 2997  
      2998         x, y = self.GetPos()  
      2999         nodea = self.Get('NodeA')  
      3000         nodeb = self.Get('NodeB')  
      3001  
    2984 3002         enda = nodea.GetPos()  
    2985 3003         endb = nodeb.GetPos()  
     
    2994 3012         box_h = maxy - miny + 6  
    2995 3013  
    2996           pen = self.canvas.CachedPen(1, 1, wx.SOLID)  
      3014         if orm_object.ORMSubtypeConstraint.Deontic:  
      3015             pen = self.canvas.CachedPen(1, 1, wx.DOT)  
      3016         else:  # Alethic  
      3017             pen = self.canvas.CachedPen(3, 1, wx.DOT)  
    2997 3018         dc.SetPen(pen)  
    2998 3019         dc.DrawLine(enda[0], enda[1], endb[0], endb[1])  
     
    3087 3108         self.Bind(wx.EVT_CHAR, self.OnChar)  # edit orm object text  
    3088 3109         self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)  
    3089            
      3110  
    3089 3110         # vars for handling mouse clicks  
    3090 3111         self.dragid = -1  
     
    3191 3212     def OnPopupFour(self, event):  
    3192 3213         new_shape = self.AddNode('ORMConstraintShape', self.popupx, self.popupy)  
      3214         Data.SetUndo('Add Constraint')  
      3215         if len(self.rolelist) >= 2:  
      3216             self.AddRoleSequence(new_shape)  
    3193 3217         self.ClearSelection()  
    3194 3218         self.SelectObject(new_shape.dcid)  
    3195           Data.SetUndo('Add Constraint')  
    3196 3219 #        id = self.shapeid_to_dcid_xref[new_shape.ID]  
    3197 3220         self.RedisplayID(new_shape.dcid)  
     
    3239 3262     def ConstraintMenu(self, constraint, menu):  
    3240 3263         if self.rolelist:  
    3241               menu.Append(self.popsID20, "Add Role List")  
      3264             menu.Append(self.popsID20, "Add Role Sequence")  
      3265             menu.AppendSeparator()  
      3266         count = len(constraint.GetList('ORMConstraintList'))  
      3267         if count > 0:  
      3268             for x in range(count):  
      3269                 menu.Append(self.popsID41, "Delete Role List %d" % (x + 1))  
      3270                 # we should use EVT_MENU_RANGE (like the Script menu)  
    3242 3271             menu.AppendSeparator()  
    3243 3272         menu.AppendRadioItem(self.popsID21, "Set as Unique")  
     
    3259 3288         menu.AppendRadioItem(self.popsID29, "Set as Ring (not implemented)")  
    3260 3289         menu.Check(self.popsID29, (constraint.Operator == 'Ring'))  
    3261           count = len(constraint.GetList('ORMConstraintList'))  
    3262           if count > 0:  
    3263               menu.AppendSeparator()  
    3264               menu.Append(self.popsID41, "Delete Role List 1")  
    3265           if count > 1:  
    3266               menu.Append(self.popsID42, "Delete Role List 2")  
    3267           if count > 2:  
    3268               menu.Append(self.popsID43, "Delete Role List 3")  
    3269           if count > 3:  
    3270               menu.Append(self.popsID44, "Delete Role List 4")  
    3271           if count > 4:  
    3272               menu.Append(self.popsID44, "Delete Role List 4")  
      3290         menu.AppendSeparator()  
      3291         menu.AppendCheckItem(self.ID_SetAsDeontic, "Set as Deontic")  
      3292         menu.Check(self.ID_SetAsDeontic, bool(constraint.Deontic))  
    3273 3293  
    3274 3294     def SubtypeConstraintMenu(self, constraint, menu):  
     
    3279 3299         menu.AppendRadioItem(self.popsID53, "Set as Partition")  
    3280 3300         menu.Check(self.popsID53, (constraint.Operator == 'Partition'))  
      3301         menu.AppendSeparator()  
      3302         menu.AppendCheckItem(self.ID_SetAsDeontic, "Set as Deontic")  
      3303         menu.Check(self.ID_SetAsDeontic, bool(constraint.Deontic))  
    3281 3304  
    3282 3305     def OnContextMenuShape(self, event):  
     
    3290 3313         # avoid clutter, some prefer them close to the object of interest  
    3291 3314         # for clarity.  
    3292           if not hasattr(self, "popsID1"):  
      3315         if not hasattr(self, "popsID01"):  
    3292 3315             self.popsID01 = wx.NewId()  
    3293 3316             self.popsID02 = wx.NewId()  
     
    3325 3348             self.popsID52 = wx.NewId()  
    3326 3349             self.popsID53 = wx.NewId()  
      3350             self.ID_SetAsDeontic = wx.NewId()  
    3327 3351  
    3328 3352             self.Bind(wx.EVT_MENU, self.OnPops01, id=self.popsID01)  
     
    3360 3384             self.Bind(wx.EVT_MENU, self.OnPops52, id=self.popsID52)  
    3361 3385             self.Bind(wx.EVT_MENU, self.OnPops53, id=self.popsID53)  
      3386             wx.EVT_MENU(self, self.ID_SetAsDeontic, self.SetAsDeontic)  
    3362 3387  
    3363 3388         # make a menu  
     
    3626 3651             self.RoleUniqueOther(event, None, 'Set Other Roles as Not Unique')  
    3627 3652  
      3653     def AddRoleSequence(self, shape):  
      3654         target = shape.Get('Target')  
      3655         # create new constraint list  
      3656         priorlists = target.GetList('ORMConstraintList')  
      3657         clist = shape.db.GetObject('ORMConstraintList')  # new constraint object  
      3658         clist.ORMConstraintID = target.ID  
      3659         clist.Seq = len(priorlists)+1  # next number  
      3660         fact_type_ids = {}  
      3661         for i, role in enumerate(self.rolelist):  
      3662             crole = shape.db.GetObject('ORMConstraintRole')  
      3663             crole.ORMConstraintListID = clist.ID  
      3664             crole.ORMRoleID = role.ID  
      3665             crole.Seq = i + 1  
      3666             fact_type_ids[role.ORMFactTypeID] = None  
      3667  
      3668         print 'fact type ids', fact_type_ids  
      3669         self.rolelist = []  
      3670         facts = [ x for x in self.Report.GetList('GraphicObject') if x.Subtype == 'ORMFactTypeShape' ]  
      3671         for factshape in facts:  
      3672             if factshape.Target.ID in fact_type_ids:  
      3673                 new_shape = self.AddConnector('ORMConstraintConnectorShape', factshape, shape)  
      3674                 new_shape.TableName = clist.Table  # so 'Target' will work  
      3675                 new_shape.TableID = clist.ID  
      3676                 self.RedrawID(factshape.dcid)  
      3677                 self.RedrawID(new_shape.dcid)  
      3678         Data.SetUndo("Add Role Sequence to Constraint")  
      3679  
    3628 3680     def OnPops20(self, event):  
    3629           if not self.rolelist: return  # ignore command of not roles have been selected  
      3681         if not self.rolelist: return  # ignore command if no roles have been selected  
    3629 3681         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
    3630 3682         if l:  
    3631 3683             shape = self.dcid_to_shape_xref.get(l[0])  
    3632               target = shape.Get('Target')  
    3633               # create new constraint list  
    3634               priorlists = target.GetList('ORMConstraintList')  
    3635               clist = shape.db.GetObject('ORMConstraintList')  # new constraint object  
    3636               clist.ORMConstraintID = target.ID  
    3637               clist.Seq = len(priorlists)+1  # next number  
    3638               fact_type_ids = {}  
    3639               for i, role in enumerate(self.rolelist):  
    3640                   crole = shape.db.GetObject('ORMConstraintRole')  
    3641                   crole.ORMConstraintListID = clist.ID  
    3642                   crole.ORMRoleID = role.ID  
    3643                   crole.Seq = i + 1  
    3644                   fact_type_ids[role.ORMFactTypeID] = None  
    3645    
    3646               print 'fact type ids', fact_type_ids  
    3647               self.rolelist = []  
    3648               facts = [ x for x in self.Report.GetList('GraphicObject') if x.Subtype == 'ORMFactTypeShape' ]  
    3649               for factshape in facts:  
    3650                   print factshape.Target.ID, factshape.Target.ID in fact_type_ids  
    3651                   if factshape.Target.ID in fact_type_ids:  
    3652                       new_shape = self.AddConnector('ORMConstraintConnectorShape', factshape, shape)  
    3653                       new_shape.TableName = clist.Table  # so 'Target' will work  
    3654                       new_shape.TableID = clist.ID  
    3655                       new_shape.ORMConstraintListID = clist.ID  
    3656                       self.RedrawID(factshape.dcid)  
    3657                       self.RedrawID(new_shape.dcid)  
    3658    
    3659   ##            self.ClearSelection()  
    3660   ##            self.SelectObject(new_shape.dcid)  
    3661               Data.SetUndo("Add Constraint List")  
    3662   ##            self.RedisplayID(new_shape.dcid)  
    3663   ##            self.RedrawID(shape.dcid)  
    3664   ##            for x in shape.GetFollowers():  
    3665   ##                self.RedrawID(x.dcid)  
      3684             self.AddRoleSequence(shape)  
    3666 3685  
    3667 3686     def SetRoleConstraint(self, event, new_value, undo_msg):  
     
    3731 3750         self.SubtypeConstraintOperator(event, 'Partition', 'Set Partition')  
    3732 3751  
      3752     def SetAsDeontic(self, event):  
      3753         l = self.pdc.FindObjects(self.popupx, self.popupy, hitradius)  
      3754         if l:  
      3755             shape = self.dcid_to_shape_xref.get(l[0])  
      3756             target = shape.Get('Target')  
      3757             if event.IsChecked():  
      3758                 target.Deontic = True  
      3759                 Data.SetUndo("Set as Deontic")  
      3760             else:  
      3761                 target.Deontic = False  
      3762                 Data.SetUndo("Set as Alethic")  
      3763             self.RedrawID(shape.dcid)  
      3764             for follow in shape.GetFollowers():  # when typing into fact  
      3765                 self.RedrawID(follow.dcid)  
      3766  
    3733 3767 # -- end code for popup menu on shape --  
    3734 3768  
     
    3872 3906         self.SetGraphic(dc, shape)  
    3873 3907  
    3874       def RedisplayID(self, id):  # object has moved, not changed  
      3908     def RedisplayID(self, id):  # object has moved but not changed  
    3874 3908         r = self.pdc.GetIdBounds(id)  
    3875 3909         r.Inflate(4,4)  
     
    3878 3912         self.RefreshRect(r, False)  
    3879 3913  
    3880       def RedrawID(self, id):  # object has moved and changed  
      3914     def RedrawID(self, id):  # object has changed  
    3880 3914         r = self.pdc.GetIdBounds(id)  
    3881 3915         shape = self.dcid_to_shape_xref.get(id)  
     
    3896 3930             self.RedrawID(dcid)  
    3897 3931  
    3898       def ConnectEm(self, source, target):  
    3899           if debug: print 'connecting', source.TableName, target.TableName  
      3932     def _ConnectEm(self, source, target):  
    3900 3933         if source.ID == target.ID:  
    3901 3934             return False  
     
    3903 3936             and target.TableName in ('ORMObjectType', 'ORMFactType')):  
    3904 3937             new_shape = self.AddConnector('ORMNoteConnectorShape', source, target)  
    3905           elif (target.TableName == 'ORMNote'  
    3906               and source.TableName in ('ORMObjectType', 'ORMFactType')):  
    3907               new_shape = self.AddConnector('ORMNoteConnectorShape', target, source)  
    3908           elif source.TableName == 'ORMObjectType' and target.TableName == 'ORMFactType':  
    3909               new_shape = self.AddConnector('ORMRoleConnectorShape', target, source)  
    3910               new_rolelabel = self.AddFollower('ORMRoleNameShape', new_shape)  
    3911 3938         elif source.TableName == 'ORMFactType' and target.TableName == 'ORMObjectType':  
    3912 3939             new_shape = self.AddConnector('ORMRoleConnectorShape', source, target)  
    3913 3940             new_rolelabel = self.AddFollower('ORMRoleNameShape', new_shape)  
    3914           elif source.TableName == 'ORMConstraint' and target.TableName == 'ORMFactType':  
    3915               new_shape = self.AddConnector('ORMConstraintConnectorShape', source, target)  
    3916 3941         elif source.TableName == 'ORMSubtypeConstraint' and target.TableName == 'ORMSubtypeConnector':  
    3917 3942             new_shape = self.AddConnector('ORMSubtypeConstraintConnectorShape', source, target)  
     
    3923 3948         return new_shape.__class__  
    3924 3949  
      3950     def ConnectEm(self, source, target):  
      3951         if debug: print 'connecting', source.TableName, target.TableName  
      3952         return (self._ConnectEm(source, target) or  
      3953                 self._ConnectEm(target, source))  
      3954  
    3925 3955 # ---- selection ----  
    3926 3956     def DrawSelectionRectangle(self, flag):  
     
    3931 3961     def AddToSelection(self, id):  
    3932 3962         self.keyboard_target_dcid = id  # for char input  
    3933    
    3934           if not self.InSelection(id):  
    3935   ##            a = self.dcid_to_shape_xref.keys()  
    3936   ##            a.sort()  
    3937   ##            print a  
    3938    
    3939               shape = self.dcid_to_shape_xref.get(id)  
    3940               if not shape:  
    3941                   print "invalid dcid %s, can't add to selection" % id  
    3942                   return  
    3943               self.selection[id] = shape  # only the key is used at present  
    3944               shape.SetSelected()  
    3945               shape.Draw(self.pdc)  
    3946               self.RedisplayID(id)                     
      3963         shape = self.dcid_to_shape_xref.get(id)  
      3964         if not shape:  
      3965             print "invalid dcid %s, can't add to selection" % id  
      3966             return  
      3967         self.selection[id] = shape  
      3968         shape.SetSelected()  
      3969         self.RedrawID(id)                     
    3947 3970  
    3948 3971     def DropFromSelection(self, id):  
     
    3987 4010         if not self.InSelection(id):  
    3988 4011             self.ClearSelection()  
    3989               self.AddToSelection(id)  
      4012         self.AddToSelection(id)  # role may not be selected even if fact is  
    3989 4012  
    3990 4013     def ToggleObjectSelect(self, id):  
     
    4168 4191         elif isinstance(source, ORMFactTypeShape):  
    4169 4192             target = self.AddNode('ORMObjectTypeShape', x, y)  
    4170           if not target is None:  
      4193         if target is not None:  
    4170 4193             Data.SetUndo('Add %s' % target.__class__)  
    4171 4194             self.RedisplayID(target.dcid)  
     
    4230 4253                 if source:  
    4231 4254       &nbs