Changeset 328

Show
Ignore:
Timestamp:
Thu Sep 13 20:49:59 2007
Author:
Brian
Message:

More work to get the ORM window working.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • scripts/trunk/ORM/Install ORM Tables.py

    r326 r328  
    21 21 #       Included draft of tables and objects  
    22 22 # 070807 - added object and report_object  
      23 # 070907 - more corrections and additions  
    23 24  
    24 25 # These design notes are intended to explore the problem. They include more than will be  
     
    30 31  
    31 32 #       Report  
    32   #           set it so that data.py won't manage the rows  
      33 #           set it so that data.py won't manage the rows - done  
    32 33  
    33   #       Row  
    34   #       - PosX  
      34 #       ReportRow - all diagram objects are represented as a report row  
      35 #       - ID  
      36 #       - ReportID  
      37 #       - PosX      # these refer to the center of the object (the target of arrows pointing to the object)  
    35 38 #       - PosY  
    36   #       - Moveable # can this object be moved with the mouse  
    37   #       - FollowID  # if this ID is moved, follow it  
    38   #       - EndAID    # this line connects these two objects, follow each end if it is moved  
    39   #       - EndBID  
      39 #                   # this line connects these two objects, follow each end if it is moved  
      40 #       - NodeAID   # these are pointers to other ReportRow objects that are the ends of a connector  
      41 #       - NodeBID  
      42 #       - OffsetX   # Text that is displayed offset from the main object (that text is separately moveable)  
      43 #       - OffsetY   # needed for role, probably not for reading  
      44 #       - Moveable  # can this object be moved with the mouse - is this needed????  
      45 #       - FollowID  # if this ID is moved, follow it - is this needed? - maybe - for reading?  
    40 46  
    41 47 #       ORMObject  
     
    51 57  
    52 58     rt = { 'Name': 'ORM Diagram', 'TableA': 'ORMObject', 'TableB': None, 'Also': None, 'AllOrEach': 'each',  
    53              'SuggestedColumns': ',ID;,Name' }  
      59            'SuggestedColumns': ',ID;,Name', 'AdjustRowOption': 'ORMDiagram' }  
    53 59     ct = [  
    54 60     { 'Name': 'ID',           'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': False, 'Width': 35  },  
     
    78 84 #       - ID  
    79 85 #       - ProjectID (Schema)  
    80   #       - Nary (2 ..)  
    81   #       - ReadingID  
    82   #       - ReadingAlternateID  
      86 #       - Nary (1 ..)  
      87 #       - ORMReadingID         # prefered reading  
      88 #       - ORMReadingAltID            # do I need this????  
    83 89 #       - Derived [None, '*', '+']  
    84 90 #       - DerivationRule  
     
    100 106     Data.AddReportType(rt, ct)  
    101 107  
    102   #       ORMReading  (follows the fact, but has it's own X&Y  
      108 #       ORMReading  (follows the fact, but has it's own X&Y)  
    102 108 #       - ID  
    103 109 #       - ProjectID (Schema)  
    104 110 #       - ORMFactID  
    105   #       - Reading  
      111 #       - Reading (reading text refers to role ids??)  
    105 111  
    106 112     rt = { 'Name': 'ORM Reading', 'TableA': 'ORMReading', 'TableB': None, 'Also': None, 'AllOrEach': 'each',  
     
    121 127 #       - ID  
    122 128 #       - ProjectID (Schema)  
      129 #       - ORMFactID - NodeA in the report row  
      130 #       - ORMObjectID - NodeB in the report row  
      131 #       - Seq = sequence number - this identifies the position of the role in the fact  
    123 132 #       - Name  
    124 133 #       - Mandatory ['a', 'd']  
     
    131 140     { 'Name': 'Project/Name',  'Label': 'Project\nName',  'DataType': 't', 'AccessType': 'i', 'T': 'A', 'Edit': False, 'Width': 100  },  
    132 141     { 'Name': 'ID',            'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': False, 'Width': 35  },  
    133       { 'Name': 'ORMObjectID',   'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 100  },  
    134 142     { 'Name': 'ORMFactID',     'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 100  },  
      143     { 'Name': 'ORMObjectID',   'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 100  },  
    135 144     { 'Name': 'Seq',           'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 100  },  
    136 145     { 'Name': 'Name',          'Label': None,             'DataType': 't', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 35  },  
      146     { 'Name': 'Mandatory',     'Label': None,             'DataType': 't', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 35  },  
      147     { 'Name': 'Unique',        'Label': None,             'DataType': 't', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 35  },  
    137 148     { 'Name': 'DateAdded',     'Label': 'Date\nAdded',    'DataType': 'd', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 80  },  
    138 149         ]  
     
    187 198 #       - ID  
    188 199 #       - ProjectID (Schema)  
    189   #       - Note  # notes are always at one end of the note connector  
    190   #       - TableName - this is the what ganttpv points to any object  
      200 #       - ORMNoteID  # notes are always at one end of the note connector  
      201 #       - TableName - this is the way ganttpv points to any object  
    191 202 #       - TableID  
    192 203  
      204     rt = { 'Name': 'ORM Note Connectors', 'TableA': 'ORMNoteConnector', 'TableB': None, 'Also': None, 'AllOrEach': 'each',  
      205            'SuggestedColumns': ',ID;,ORMNoteID;,TableName;,TableID' }  
      206     ct = [  
      207     { 'Name': 'ID',           'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': False, 'Width': 35  },  
      208     { 'Name': 'ORMNoteID',    'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True, 'Width': 55  },  
      209     { 'Name': 'TableName',    'Label': None,             'DataType': 't', 'AccessType': 'd', 'T': 'A', 'Edit': True,  'Width': 100  },  
      210     { 'Name': 'TableID',      'Label': None,             'DataType': 'i', 'AccessType': 'd', 'T': 'A', 'Edit': True, 'Width': 55  },  
      211         ]  
      212     Data.AddReportType(rt, ct)  
      213  
    193 214 # --------------------------  
    194   #       ReportORMObject  
    195   #       - ORMObjectID  # many may point to same  
    196   #       - ReportID  
    197   #       - PosX  
    198   #       - PosY  
    199 215  
    200 216 ### instead of a report object, it might be better just to use the good old report row?  
  • scripts/trunk/ORM/Open ORM Window.py

    r326 r328  
    2038 2038     object_id = Data.Update(model)['ID']  
    2039 2039  
    2040       graphic = {'Table': 'ReportRow', 'ProjectID': projectid, 'ReportID': self.ReportID,  
      2040     graphic = {'Table': 'ReportRow', 'ProjectID': projectid, 'ReportID': report_object.ID,  
    2040 2040                'TableName': object_type, 'TableID': object_id,  
    2041 2041                'PosX': x, 'PosY': y,  
     
    2055 2055 def AddConnectorToDiagram(report_object, object_type, nodea, nodeb):  
    2056 2056     ''' Add report row, add target object, connect to end objects'''  
    2057       if debug: print report_object  
      2057     if debug: print 'adding %s to %s' % (object_type, report_object)  
    2057 2057     project = report_object.Get('Project')  
    2058 2058     projectid = project.ID  
     
    2062 2062     # I think that subtype is the only example of linking the same types to each other  
    2063 2063     model = {'Table': object_type, 'ProjectID': projectid, 'DateAdded': today}  
    2064       model[nodea.Target.Table + 'ID'] = nodea.Target.ID  
      2064     model[nodea.TableName + 'ID'] = nodea.TableID  
    2064 2064     if object_type == 'ORMSubtypeArrow':  # what should this be called?  
    2065           model['ORMSubtypeID'] = nodeb.Target.ID  
      2065         model['ORMSubtypeID'] = nodeb.TableID  
      2066     elif object_type == 'ORMNoteConnector':  # may connect to anything  
      2067         model['TableName'] = nodeb.TableName  
      2068         model['TableID'] = nodeb.TableID  
    2066 2069     else:  
    2067           model[nodeb.Target.Table + 'ID'] = nodeb.Target.ID  
      2070         model[nodeb.TableName + 'ID'] = nodeb.TableID  
    2067 2070     object_id = Data.Update(model)['ID']  
    2068 2071  
    2069       graphic = {'Table': 'ReportRow', 'ProjectID': projectid, 'ReportID': self.ReportID,  
      2072     graphic = {'Table': 'ReportRow', 'ProjectID': projectid, 'ReportID': report_object.ID,  
    2069 2072                'TableName': object_type, 'TableID': object_id,  
    2070 2073                'NodeAID': nodea.ID, 'NodeBID': nodeb.ID,  # objects pointed to  
    2071   #               'PosX': x, 'PosY': y,  
      2074                'PosX': -1, 'PosY': -1,  
    2071 2074                'DateAdded': today}  
    2072 2075     newrowid = Data.Update(graphic)['ID']  
     
    2621 2624         wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)  
    2622 2625  
    2623           self.leftClickType = 'ORMObject'  
      2626         self.leftClickType = 'ORMObject'  # where to specify behaviors?  
    2623 2626  
    2624 2627         self.Report = report  # report object  
    2625           self.ReportID = report.ID  
      2628         self.ReportID = report.ID  # redundant - may remove  
    2625 2628  
    2626 2629         self.lines = []  
     
    2663 2666         # wxCURSOR_PENCIL  
    2664 2667         # wxCURSOR_PAINT_BRUSH  
    2665           self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))  
      2668         # self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))  
    2665 2668      
    2666 2669 # -- code for popup menu on canvas??? -- This isn't working  
     
    2709 2712         # add some other items  
    2710 2713         menu.Append(self.popupID2, "Fact")  
    2711           menu.Append(self.popupID3, "Three")  
      2714         menu.Append(self.popupID3, "Constraint - not implemented")  
    2711 2714         menu.Append(self.popupID4, "Four")  
    2712           menu.Append(self.popupID5, "Five")  
    2713           menu.Append(self.popupID6, "Six")  
      2715         menu.Append(self.popupID5, "Undo - not implemented")  
      2716         menu.Append(self.popupID6, "Redo - not implemented")  
    2714 2717         # make a submenu  
    2715 2718         sm = wx.Menu()  
     
    2727 2730  
    2728 2731     def OnPopupOne(self, event):  
    2729           self.AddNode('ORMNote', self.popupx, self.popupy)  
      2732         new_shape = self.AddNode('ORMNote', self.popupx, self.popupy)  
    2729 2732         Data.SetUndo('Add Note')  
      2733         id = self.shapexref[new_shape.ID]  
      2734         self.RedisplayID(id)  
    2730 2735  
    2731 2736     def OnPopupTwo(self, event):  
    2732           self.AddNode('ORMFact', self.popupx, self.popupy)  
      2737         new_shape = self.AddNode('ORMFact', self.popupx, self.popupy)  
    2732 2737         Data.SetUndo('Add Fact')  
      2738         id = self.shapexref[new_shape.ID]  
      2739         self.RedisplayID(id)  
    2733 2740  
    2734 2741     def OnPopupThree(self, event):  
     
    2774 2781         self.CreateNode(dc, shape)  
    2775 2782         dc.EndDrawing()  
      2783         return shape  
      2784  
      2785     def AddConnector(self, node_type, source, target):  # create model and graphic objects  
      2786         shape = AddConnectorToDiagram(self.Report, node_type, source, target)  
      2787         dc = self.pdc  
      2788         dc.BeginDrawing()  
      2789         self.CreateNode(dc, shape)  
      2790         dc.EndDrawing()  
      2791         return shape  
    2776 2792  
    2777 2793     def CreateNode(self, dc, shape):  # create graphics node for existing model object  
     
    2785 2801         # can't store in object, must be in the graphics window  
    2786 2802         self.shapexref[shape.ID] = id  
      2803         self.idxref[id] = shape  
    2787 2804  
    2788 2805         orm_object = shape.Get('Target')  
    2789           x = shape.PosX  
      2806         x = shape.PosX  # treat this as the center of the shape  
    2789 2806         y = shape.PosY  
    2790 2807  
     
    2796 2813             return  
    2797 2814         if orm_object.Table in ('ORMObject'):  
      2815 ##            word = orm_object.Name or 'default name'  
      2816 ##            name_w,name_h = self.GetFullTextExtent(word)[0:2]  # pull out only w and h  
      2817 ##            box_w = name_w + 6  
      2818 ##            box_h = name_h + 6  
      2819  
      2820             # text = orm_object.Text or 'empty note'  
      2821             lines = []  
    2798 2822             word = orm_object.Name or 'default name'  
    2799               name_w,name_h = self.GetFullTextExtent(word)[0:2]  # pull out only w and h  
    2800               box_w = name_w + 6  
    2801               box_h = name_h + 6  
      2823             if orm_object.Independent:  
      2824                 work += "!"  
      2825             if orm_object.Derived:  
      2826                 work += orm_object.Derived  
      2827             lines.append(word)  
      2828             word = orm_object.RefMode or ''  
      2829             if word:  
      2830                 word = '(' + word + ')'  
      2831             lines.append(word)  
      2832              
      2833             sizes = [ self.GetFullTextExtent(line)[0:2] for line in lines ]  # pull out only w and h  
      2834             w = 5  
      2835             h = 0  
      2836             for line_w,line_h in sizes:  
      2837                 w = max(w, line_w)  
      2838                 h += line_h  
      2839             box_w = w + 8  
      2840             box_h = h + 6  
    2802 2841  
    2803 2842             if orm_object.Type == 'Entity':  
     
    2809 2848             dc.SetBrush(self.CachedBrush('White'))  
    2810 2849             if debug: print 'round rectangle dimensions',x, y, box_w, box_h  
    2811               dc.DrawRoundedRectangle(x,y,box_w,box_h,8)  
      2850             box_x = x - box_w/2  
      2851             box_y = y - box_h/2  
      2852 #            dc.DrawRoundedRectangle(box_x,box_y,box_w,box_h,8)  
      2853             dc.DrawRoundedRectangle(box_x,box_y,box_w,box_h,6)  
    2812 2854  
    2813 2855             dc.SetFont(self.GetFont())  
     
    2816 2858             dc.SetTextForeground('Black')  
    2817 2859             dc.SetTextBackground('White')  
    2818               dc.DrawText(word, x+3, y+3)  
      2860             dc.DrawText(lines[0], x - sizes[0][0]/2, box_y+3)  # center text in box  
      2861             dc.DrawText(lines[1], x - sizes[1][0]/2, box_y+box_h/2+1)  
    2819 2862  
    2820               r = wx.Rect(x,y,box_w,box_h)  
      2863             r = wx.Rect(box_x,box_y,box_w,box_h)  
    2820 2863             r.Inflate(pen.GetWidth(),pen.GetWidth())  
    2821 2864             dc.SetIdBounds(id,r)  
     
    2886 2929             dc.SetIdBounds(id,r)  
    2887 2930              
      2931         elif orm_object.Table in ('ORMRole'):  
      2932             nodea = shape.Get('NodeA')  
      2933             nodeb = shape.Get('NodeB')  
      2934  
      2935             minx = min(nodea.PosX, nodeb.PosX)  
      2936             maxx = max(nodea.PosX, nodeb.PosX)  
      2937             miny = min(nodea.PosY, nodeb.PosY)  
      2938             maxy = max(nodea.PosY, nodeb.PosY)  
      2939              
      2940             box_w = maxx - minx + 6  
      2941             box_h = maxy - miny + 6  
      2942  
      2943             pen = self.CachedPen(1, 1, wx.SOLID)  
      2944             dc.SetPen(pen)  
      2945             dc.DrawLine(nodea.PosX,nodea.PosY,nodeb.PosX, nodeb.PosY)  
      2946  
      2947             # need to add logic to draw the role name  
      2948  
      2949             r = wx.Rect(minx,miny,box_w,box_h)  
      2950             r.Inflate(pen.GetWidth(),pen.GetWidth())  
      2951             dc.SetIdBounds(id,r)  
      2952              
      2953         elif orm_object.Table in ('ORMNoteConnector'):  
      2954             nodea = shape.Get('NodeA')  
      2955             nodeb = shape.Get('NodeB')  
      2956  
      2957             minx = min(nodea.PosX, nodeb.PosX)  
      2958             maxx = max(nodea.PosX, nodeb.PosX)  
      2959             miny = min(nodea.PosY, nodeb.PosY)  
      2960             maxy = max(nodea.PosY, nodeb.PosY)  
      2961              
      2962             box_w = maxx - minx + 6  
      2963             box_h = maxy - miny + 6  
      2964  
      2965             pen = self.CachedPen(1, 1, wx.DOT)  
      2966             dc.SetPen(pen)  
      2967             dc.DrawLine(nodea.PosX,nodea.PosY,nodeb.PosX, nodeb.PosY)  
      2968  
      2969             r = wx.Rect(minx,miny,box_w,box_h)  
      2970             r.Inflate(pen.GetWidth(),pen.GetWidth())  
      2971             dc.SetIdBounds(id,r)  
      2972              
    2888 2973         self.objids.append(id)  
    2889 2974  
      2975     def RedisplayID(self, id):  
      2976         r = self.pdc.GetIdBounds(id)  
      2977         r.Inflate(4,4)  
      2978         self.OffsetRect(r)  
      2979         self.RefreshRect(r, False)  
      2980  
      2981     def ConnectEm(self, source, target):  
      2982         if debug: print 'connecting', source.TableName, target.TableName  
      2983         if (source.TableName == 'ORMNote'  
      2984             and target.TableName in ('ORMObject', 'ORMFact')):  
      2985             new_shape = self.AddConnector('ORMNoteConnector', source, target)  
      2986             Data.SetUndo('Add Note Connector')  
      2987         elif (target.TableName == 'ORMNote'  
      2988             and source.TableName in ('ORMObject', 'ORMFact')):  
      2989             new_shape = self.AddConnector('ORMNoteConnector', target, source)  
      2990             Data.SetUndo('Add Note Connector')  
      2991         elif source.TableName == 'ORMObject' and target.TableName == 'ORMFact':  
      2992             new_shape = self.AddConnector('ORMRole', target, source)  
      2993             Data.SetUndo('Add Role Connector')  
      2994         elif source.TableName == 'ORMFact' and target.TableName == 'ORMObject':  
      2995             new_shape = self.AddConnector('ORMRole', source, target)  
      2996             Data.SetUndo('Add Role Connector')  
      2997         id = self.shapexref[new_shape.ID]  
      2998         self.RedisplayID(id)  
      2999  
      3000  
    2890 3001     def OnMouse(self, event):  
    2891 3002         global hitradius  
    2892           if 1:  # if self.draw_mode:  
      3003         if self.demo.draw_mode:  # "demo" is a poor name, this is where the window global data is  
    2892 3003             if event.LeftDown():  # select object -> object potentially source of arrow  
    2893 3004                 x,y = self.ConvertEventCoords(event)  
     
    2900 3011                             self.dragid = id  
    2901 3012                             self.lastpos = (event.GetX(),event.GetY())  
      3013                             if debug: print 'left clicked on', self.idxref.get(id)  
    2902 3014                             break  
    2903 3015                 else: # didn't click on any object  
    2904                       self.AddNode(self.leftClickType, x, y)  
      3016                     # add new object  
      3017                     new_shape = self.AddNode(self.leftClickType, x, y)  
      3018                     Data.SetUndo('Add %s' % self.leftClickType)  
      3019                     # redisplay object??  
      3020                     id = self.shapexref[new_shape.ID]  
      3021                     self.RedisplayID(id)  
      3022                     # make object current selection  
      3023                     self.dragid = id  # remember start of drag  
      3024                     self.lastpos = (event.GetX(),event.GetY())  # needed?  
    2905 3025             elif event.RightDown():  
    2906 3026                 x,y = self.ConvertEventCoords(event)  
     
    2919 3039             elif event.Dragging() or event.LeftUp():  
    2920 3040                 if self.dragid != -1:  
    2921                       x,y = self.lastpos  
    2922                       dx = event.GetX() - x  
    2923                       dy = event.GetY() - y  
    2924                       r = self.pdc.GetIdBounds(self.dragid)  
    2925                       self.pdc.TranslateId(self.dragid, dx, dy)  
    2926                       r2 = self.pdc.GetIdBounds(self.dragid)  
    2927                       r = r.Union(r2)  
    2928                       r.Inflate(4,4)  
    2929                       self.OffsetRect(r)  
    2930                       self.RefreshRect(r, False)  
    2931                       self.lastpos = (event.GetX(),event.GetY())  
      3041                     pass  
      3042 ##                    x,y = self.lastpos  
      3043 ##                    dx = event.GetX() - x  
      3044 ##                    dy = event.GetY() - y  
      3045 ##                    r = self.pdc.GetIdBounds(self.dragid)  
      3046 ##                    self.pdc.TranslateId(self.dragid, dx, dy)  
      3047 ##                    r2 = self.pdc.GetIdBounds(self.dragid)  
      3048 ##                    r = r.Union(r2)  
      3049 ##                    r.Inflate(4,4)  
      3050 ##                    self.OffsetRect(r)  
      3051 ##                    self.RefreshRect(r, False)  
      3052 ##                    self.lastpos = (event.GetX(),event.GetY())  
    2932 3053                 if event.LeftUp():  
    2933                       self.dragid = -1  
      3054                     # self.dragid = -1  
    2933 3054                     # what did we release on?  
    2934 3055                     x,y = self.ConvertEventCoords(event)  
    2935 3056                     #l = self.pdc.FindObjectsByBBox(x, y)  
    2936 3057                     l = self.pdc.FindObjects(x, y, hitradius)  
    2937                       if l:  # connect to this object (if legal)  
    2938                           pass  
    2939                       else:  # create target object (if legal)  
      3058                     if l:  # connect to this object and maybe connection (if legal)  
      3059                         target = self.idxref.get(l[0])  
      3060                         source = self.idxref.get(self.dragid)  
      3061                         self.ConnectEm(source, target)  
      3062                     else:  # create target object and connection (if legal)  
    2940 3063                         pass  
      3064 ##                        # add new object  
      3065 ##                        ll = self.AddNode(self.leftClickType, x, y)  
      3066 ##                        Data.SetUndo('Add %s' % self.leftClickType)  
      3067 ##                        # redisplay object??  
      3068 ##                        r = self.pdc.GetIdBounds(self.shapexref[ll])  
      3069 ##                        r.Inflate(4,4)  
      3070 ##                        self.OffsetRect(r)  
      3071 ##                        self.RefreshRect(r, False)  
      3072 ##                        # make object current selection  
      3073 ##                        self.dragid = id  # remember start of draf  
      3074 ##                        self.lastpos = (event.GetX(),event.GetY())  
    2941 3075         else:  
    2942 3076             if event.LeftDown():  
     
    3045 3179         random.seed()  
    3046 3180         self.objids = []  
    3047           self.shapexref = {}  # xref between shapes and dc_ids  
      3181         self.shapexref = {}  # xrefs between shapes and dc_ids  
      3182         self.idxref = {}     # inverse of shapexref  
    3048 3183         self.boundsdict = {}  
    3049 3184         dc.BeginDrawing()  
     
    3189 3324         self.report_toolbar.SetToolBitmapSize((16, 16))  # change  
    3190 3325         # self.SetToolBar(self.report_toolbar)  
    3191           self.report_toolbar.AddLabelTool(ID.INSERT_ROW, _("Insert %s"), Menu.Bitmap("icons/Insert Row.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Insert new %s"), _("Insert new %s below selection"))  
    3192           self.report_toolbar.AddLabelTool(ID.DUPLICATE_ROW, _("Duplicate %s"), Menu.Bitmap("icons/Duplicate.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Duplicate %s"), _("Duplicate selected %s"))  
      3326         self.report_toolbar.AddLabelTool(ID.NORMAL, _("Normal Mode"), Menu.Bitmap("icons/Insert Row.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Normal Mode"), _("Draging will move objects"))  
      3327         self.report_toolbar.AddLabelTool(ID.DRAW, _("Drawing Mode"), Menu.Bitmap("icons/Duplicate.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Drawing Mode"), _("Draging will connect objects"))  
    3193 3328         self.report_toolbar.Realize()  
    3194 3329    
     
    3209 3344         sc.Bind(wx.EVT_SPINCTRL,self.OnChange)  
    3210 3345         sc.Bind(wx.EVT_TEXT,self.OnChange)  
      3346          
      3347         wx.EVT_TOOL(self, ID.NORMAL,self.OnNormal)  
      3348         wx.EVT_TOOL(self, ID.DRAW,self.OnDraw)  
    3211 3349  
    3212 3350     def OnChange(self, event):  
     
    3214 3352         hitradius = self.sc.GetValue()  
    3215 3353      
      3354     def OnNormal(self, event):  
      3355         self.demo.draw_mode = False  
      3356      
      3357     def OnDraw(self, event):  
      3358         self.demo.draw_mode = True  
      3359  
    3216 3360 #---------------------------------------------------------------------------  
    3217 3361 # BELOW HERE IT IS NOTEBOOK  
     
    3291 3435         wx.Frame.__init__(self, parent, title="FlatNotebook Demo", size=(800,600))  
    3292 3436         self.log = log  
    3293            
      3437         self.draw_mode = False  # used by canvas  
      3438  
    3294 3439         self._bShowImages = False  
    3295 3440         self._bVCStyle = False  
     
    3799 3944             pnl = wx.Panel(nb, wx.ID_ANY,size=(200,30))  
    3800 3945             pnl2 = ControlPanel(pnl,wx.ID_ANY)  
      3946             pnl2.demo = self  # so control panel can save data at application level  
    3801 3947             win = MyCanvas(pnl, wx.ID_ANY, log, report=report)  
      3948             win.demo = self  # so canvas can save data at application level  
    3802 3949             sz = wx.BoxSizer(wx.VERTICAL)  
    3803 3950             sz.Add(pnl2,0,wx.EXPAND|wx.ALL,5)  
     
    3835 3982             pnl = wx.Panel(nb, wx.ID_ANY,size=(200,30))  
    3836 3983             pnl2 = ControlPanel(pnl,wx.ID_ANY)  
      3984             pnl2.demo = self  # so control panel can save data at application level  
    3837 3985             win = MyCanvas(pnl, wx.ID_ANY, log, report=report)  
      3986             win.demo = self  # so canvas can save data at application level  
    3838 3987             sz = wx.BoxSizer(wx.VERTICAL)  
    3839 3988             sz.Add(pnl2,0,wx.EXPAND|wx.ALL,5)