Changeset 403

Show
Ignore:
Timestamp:
Mon May 19 22:04:59 2008
Author:
Brian
Message:

Add Object API to Data. Add ORM Diagram Report.

Files:

Legend:

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

    r286 r403  
    142 142 # HIDE_RESOURCE    = 2605  
    143 143 # SHOW_HIDDEN_RESOURCE = 2606  
      144  
      145 NORMAL = 3101  
      146 DRAW = 3102  
  • ganttpv/trunk/Menu.py

    r399 r403  
    2 2 # Implement shared menu commands  
    3 3  
    4   # Copyright 2004, 2006 by Brian C. Christensen  
      4 # Copyright 2004, 2006, 2008 by Brian C. Christensen  
    4 4  
    5 5 #    This file is part of GanttPV.  
     
    56 56 # 070725 - Brian - interface changed: add code to convert GetMenuItems reply to a list  
    57 57 # 070926 - Brian - Data.FileName not set to None on New (fixed again? see 040815 in Data)  
      58 # 080519 - Brian - separate logic for DiagramFrames  
    58 59  
    59 60 import wx, os, webbrowser  
     
    904 905         # self.report_toolbar.EnableTool(ID.SCROLL_RIGHT_FAR, True)  
    905 906  
      907     elif isinstance(self, UI.DiagramFrame):  
      908         r = Data.Report[self.ReportID]  
      909         rtid = r['ReportTypeID']  
      910         rt = Data.ReportType[rtid]  
      911 ##        if rt.get('PanelType') == 'ORMDiagram': return  # IMPORTANT - fix this  
      912         ta = rt.get('TableA')  
      913         tb = rt.get('TableB')  
      914 ##        toolbar = self.report_toolbar  
      915 ##        isTask = (ta == "Task")  
      916 ##        isResource = (ta == "Resource")  
      917 ##        isAssignment = (ta == "Assignment")  
      918 ##        csel = self.Report.GetSelectedCols()  
      919 ##        rsel = self.Report.GetSelectedRows()  
      920 ##        isOneRow = bool(len(rsel) == 1)  
      921 ##        isSelCol = bool(csel)  
      922 ##        isSelRow = bool(rsel)  
      923 ##        multiRow = isSelRow and not isOneRow  
      924 ##        isEditorShown = self.Report.IsCellEditControlEnabled()  
      925 ##        noRows = not self.Report.table.rows  # no cursor if no rows  
      926  
      927         # self.report_toolbar.EnableTool(ID.INSERT_ROW, True)  
      928 ##        self.report_toolbar.EnableTool(ID.DUPLICATE_ROW, isSelRow and isTask)  
      929 ##        self.report_toolbar.EnableTool(ID.DELETE_ROW, isSelRow)  
      930 ##        self.report_toolbar.EnableTool(ID.MOVE_UP, isSelRow)  
      931 ##        self.report_toolbar.EnableTool(ID.MOVE_DOWN, isSelRow)  
      932  
      933         # check if parenting is allowed  
      934 ##        if noRows: # multiRow or noRows:  # or no rows exist  
      935 ##            canChild = False  
      936 ##        else:  
      937 ##            if isOneRow:  
      938 ##                rindex = rsel[0]  
      939 ##            else:  
      940 ##                rindex = self.Report.GetGridCursorRow()  
      941 ##            row = Data.ReportRow[self.Report.table.rows[rindex]]  
      942 ##            tsel = row.get('TableName')  
      943 ##            canChild = False  
      944 ##            if tsel == ta:  
      945 ##                dc = Data.ReportColumn  
      946 ##                dct = Data.ColumnType  
      947 ####                for col in Data.GetColumnList(self.ReportID):  
      948 ####                    ctid = dc[col].get('ColumnTypeID')  
      949 ####                    if ctid:  
      950 ####                        cTypeName = dct[ctid].get('Name')  
      951 ####                        if cTypeName == ta + 'ID':  # parent id column type is <tablename> + 'ID'  
      952 ####                            canChild = True  
      953 ####                            break  
      954 ##                # is a parent column type defined for this report's primary table?  
      955 ##                also = rt.get('Also')  
      956 ##                if also and also in Data.ReportType:  # use columns types define for primary table  
      957 ##                    search_rtid = also  
      958 ##                else:  
      959 ##                    search_rtid = rtid  
      960 ##                canChild = Data.SearchByColumn(Data.ColumnType, { 'ReportTypeID': search_rtid, 'Name': ta + 'ID' }, unique=True)  
      961 ##  
      962 ##        # self.Edit.Enable(ID.M_INSERT_CHILD, canChild)  
      963 ##        self.Edit.Enable(ID.M_SHIFT_LEFT, canChild)  
      964 ##        self.Edit.Enable(ID.M_SHIFT_RIGHT, canChild)  
      965  
      966 ##        if isSelRow:  
      967 ##            row = Data.ReportRow[self.Report.table.rows[min(rsel)]]  
      968 ##            tsel = row.get('TableName')  
      969 ##             
      970 ##            self.Edit.SetLabel(ID.M_INSERT_ROW, _("Insert New %s\tCtrl-R") % _(ta)) # should be "tsel"  
      971 ##            self.Edit.SetLabel(ID.M_INSERT_ROW_ABOVE, _("Insert New %s Above Selection\tCtrl-Shift-R") % _(ta)) # should be "tsel"  
      972 ##  
      973 ##            self.Edit.SetHelpString(ID.M_INSERT_ROW, _("Insert new %s below the selected row") % _(ta)) # should be "tsel"  
      974 ##            self.Edit.SetHelpString(ID.M_INSERT_ROW_ABOVE, _("Insert a new %s above the selected row") % _(ta)) # should be "tsel"  
      975 ##  
      976 ##            self.report_toolbar.SetToolShortHelp(ID.INSERT_ROW, _("Insert new %s") % _(ta))  
      977 ##            self.report_toolbar.SetToolShortHelp(ID.DUPLICATE_ROW, _("Duplicate %s") % _(ta))  
      978 ##  
      979 ##            self.report_toolbar.SetToolLongHelp(ID.INSERT_ROW, _("Insert new %s below selection") % _(ta))  
      980 ##            self.report_toolbar.SetToolLongHelp(ID.DUPLICATE_ROW, _("Duplicate selected %s") % _(ta))  
      981 ##  
      982 ##            canRelated = False # bool(tb and tb not in ('Assignment', 'ResourceGrouping', 'Dependency', 'MeasurementDependency', 'Report', 'ReportType', 'ColumnType', 'ReportColumn', 'ReportRow', 'ProjectWeek', 'ProjectDay', 'ProjectResourceWeek', 'ProjectResourceDay', 'TaskWeek'))  
      983 ##            self.Edit.Enable(ID.M_INSERT_RELATED, canRelated)  
      984 ##  
      985 ##            # action menu  
      986 ##            self.Action.Enable(ID.M_ASSIGN_PREREQUISITE, tsel == 'Task' and isOneRow)  
      987 ##            self.Action.Enable(ID.M_LINK_TASKS, tsel == 'Task' and not isOneRow)  # should test to make sure all are tasks  
      988 ##            self.Action.Enable(ID.M_ASSIGN_RESOURCE, tsel == 'Task' and isOneRow)  
      989 ##            oneResource = tsel == 'Resource' and isOneRow  
      990 ##            canResourceGroup = 'ResourceGrouping' in Data.Database and 'ResourceGroup' in Data.Database  
      991 ##            isResourceGroup = bool(tsel == 'Resource' and Data.Database[tsel][row.get('TableID')].get('GroupType'))  
      992 ##            self.Action.Enable(ID.M_RESOURCE_TO_GROUP, oneResource and canResourceGroup and not isResourceGroup)  
      993 ##            self.Action.Enable(ID.M_DEFINE_RESOURCE_GROUP, oneResource and canResourceGroup and isResourceGroup)  
      994 ##            self.Action.Enable(ID.M_ASSIGN_TASK, oneResource)  
      995 ##            self.View.Enable(ID.M_SCROLL_TO_TASK, tsel in ('Task', 'Assignment'))  
      996 ##            self.report_toolbar.EnableTool(ID.SCROLL_TO_TASK, tsel in ('Task', 'Assignment'))  
      997 ##  
      998 ##        else:  
      999 ##            self.Edit.SetLabel(ID.M_INSERT_ROW, _("Insert New %s\tCtrl-R") % _(ta))  
      1000 ##            self.Edit.SetLabel(ID.M_INSERT_ROW_ABOVE, _("Insert New %s Above Selection\tCtrl-Shift-R") % _(ta))  
      1001 ##  
      1002 ##            self.Edit.SetHelpString(ID.M_INSERT_ROW, _("Insert new %s below the selected row") % _(ta))  
      1003 ##            self.Edit.SetHelpString(ID.M_INSERT_ROW_ABOVE, _("Insert a new %s above the selected row") % _(ta)) # should be "tsel"  
      1004 ##  
      1005 ##            self.report_toolbar.SetToolShortHelp(ID.INSERT_ROW, _("Insert new %s") % _(ta))  
      1006 ##            self.report_toolbar.SetToolShortHelp(ID.DUPLICATE_ROW, _("Duplicate %s") % '')  
      1007 ##  
      1008 ##            self.report_toolbar.SetToolLongHelp(ID.INSERT_ROW, _("Insert new %s below selection") % _(ta))  
      1009 ##            self.report_toolbar.SetToolLongHelp(ID.DUPLICATE_ROW, _("Duplicate selected %s") % '')  
      1010 ##  
      1011 ##            # self.Edit.Enable(ID.M_INSERT_CHILD, False)  
      1012 ##            self.Edit.Enable(ID.M_INSERT_RELATED, False)  
      1013 ##  
      1014 ##            # action menu  
      1015 ##            self.Action.Enable(ID.M_ASSIGN_PREREQUISITE, False)  
      1016 ##            self.Action.Enable(ID.M_LINK_TASKS, False)  
      1017 ##            self.Action.Enable(ID.M_ASSIGN_RESOURCE, False)  
      1018 ##            self.Action.Enable(ID.M_RESOURCE_TO_GROUP, False)  
      1019 ##            self.Action.Enable(ID.M_DEFINE_RESOURCE_GROUP, False)  
      1020 ##            self.Action.Enable(ID.M_ASSIGN_TASK, False)  
      1021 ##            self.View.Enable(ID.M_SCROLL_TO_TASK, False)  
      1022 ##            self.report_toolbar.EnableTool(ID.SCROLL_TO_TASK, False)  
      1023 ##  
      1024 ##        # self.Edit.SetLabel(ID.M_INSERT_CHILD, _("Insert Child %s") % _(ta))  
      1025 ##        self.Edit.SetLabel(ID.M_INSERT_RELATED, _("Insert Related %s\tCtrl-Alt-R") % _(tb or " "))  
      1026 ##        # self.Edit.SetHelpString(ID.M_INSERT_CHILD, _("Insert a child %s") % _(ta))  
      1027 ##        self.Edit.SetHelpString(ID.M_INSERT_RELATED, _("Insert a new %s") % _(tb or " "))  
      1028 ##  
      1029 ##        # self.Edit.Enable(ID.M_INSERT_ROW_ABOVE, isSelRow)  
      1030 ##        self.Edit.Enable(ID.M_DELETE_ROW, isSelRow)  
      1031 ####        self.Edit.Enable(ID.M_MOVE_ROW_UP, isSelRow)  
      1032 ####        self.Edit.Enable(ID.M_MOVE_ROW_DOWN, isSelRow)  
      1033 ##        self.Edit.Enable(ID.M_MOVE_ROW_UP, not noRows)  # what if there are no rows??  
      1034 ##        self.Edit.Enable(ID.M_MOVE_ROW_DOWN, not noRows)  
      1035 ##  
      1036 ##        self.report_toolbar.EnableTool(ID.PREREQUISITE, isTask and isSelRow)  
      1037 ##        self.report_toolbar.EnableTool(ID.ASSIGN_RESOURCE, (isTask or isResource) and len(rsel) == 1)  
      1038 ##  
      1039 ##        self.report_toolbar.EnableTool(ID.HIDE_ROW, isSelRow)  
      1040 ##        self.report_toolbar.ToggleTool(ID.SHOW_HIDDEN, bool(r.get('ShowHidden')))  
      1041 ##  
      1042 ##        self.View.Enable(ID.M_DELETE_COLUMN, isSelCol)  
      1043 ##        self.View.Enable(ID.M_MOVE_COLUMN_LEFT, isSelCol)  
      1044 ##        self.View.Enable(ID.M_MOVE_COLUMN_RIGHT, isSelCol)  
      1045 ##  
      1046 ##        # self.report_toolbar.EnableTool(ID.INSERT_COLUMN, True)  
      1047 ##        self.report_toolbar.EnableTool(ID.DELETE_COLUMN, isSelCol)  
      1048 ##        self.report_toolbar.EnableTool(ID.MOVE_LEFT, isSelCol)  
      1049 ##        self.report_toolbar.EnableTool(ID.MOVE_RIGHT, isSelCol)  
      1050 ##        self.report_toolbar.EnableTool(ID.COLUMN_OPTIONS, False)  
      1051 ##        # self.report_toolbar.EnableTool(ID.SCROLL_LEFT_FAR, True)  
      1052 ##        # self.report_toolbar.EnableTool(ID.SCROLL_LEFT, True)  
      1053 ##        # self.report_toolbar.EnableTool(ID.SCROLL_RIGHT, True)  
      1054 ##        # self.report_toolbar.EnableTool(ID.SCROLL_RIGHT_FAR, True)  
      1055  
    906 1056  
    907 1057     # if debug: print 'Finished adjusting menus'  
  • ganttpv/trunk/GanttReport.py

    r399 r403  
    473 473             else:  
    474 474                 reportid = rr.get('ReportID')  
    475                   bars = Data.Database['Report'][reportid].get('Bars') or 'Cab'  # could be 'pab'  
      475                 bars = Data.Database['Report'][reportid].get('Bars') or 'p'  # could be 'pab'  
    475 475                  
    476 476                 if len(bars) == 3:  # 'pab'  p  
     
    502 502                                 drawbar(  
    503 503                                     es, position, completioncolor,  
    504                                       y_offset + bar_height//2, bar_height//2)  
      504                                     y_offset + bar_height//3, bar_height//3)  
    504 504                             elif 'C' in bars:  # full height completion bar  
    505 505                                 drawbar(  
  • ganttpv/trunk/Data.py

    r379 r403  
    2 2 # Data Tables - includes update logic, date routines, and gantt calculations  
    3 3  
    4   # Copyright 2004, 2005, 2006 by Brian C. Christensen  
      4 # Copyright 2004, 2005, 2006, 2007, 2008 by Brian C. Christensen  
    4 4  
    5 5 #    This file is part of GanttPV.  
     
    101 101 # 070328 - Brian - Change SetCellValue so that it will not change protected cells  
    102 102 # 070731 - Alex - hide assignment or dependency records that point to a deleted task or resource (somewhat ad hoc)  
      103 # 080517 - Brian - added object api  
    103 104  
    104 105 import datetime, calendar  
     
    579 580     return undo  
    580 581  
      582 # GanttPV Object API  
      583  
      584 class Object:  
      585     def __init__(self, db, object_type, object_id):  
      586         ''' object_type = table name; object_id = row id '''  
      587         self.__dict__['db'] = db  
      588         self.__dict__['Table'] = object_type  
      589         self.__dict__['ID'] = object_id  
      590 ##        self.Table = object_type  # avoiding use of __setattr__  
      591 ##        self.ID = object_id  
      592  
      593     def __str__(self):  
      594         if self.Table in ('ReportRow', 'GraphicObject'):  
      595             return ('Object Type %s with ID %d and target %s' %  
      596                 (self.Table, self.ID, self.TableName))  
      597         return 'Object Type %s with ID %d' % (self.Table, self.ID)  
      598          
      599     __repr__ = __str__  # is this right??  
      600          
      601     def __getattr__(self, name):  
      602 # it is impossible to return values for 'Get', 'GetList', or 'Valid'  
      603 # the program only comes here if it can't find the real attribute  
      604 #     this applies to db, Table, and ID  
      605  
      606         # edit on every access or on creation?  
      607         if not self.Table in self.db.Database:  
      608             return None  
      609         rec = self.db.Database[self.Table].get(self.ID)  
      610         if not rec:  
      611             return None  
      612  
      613         # temporary version  
      614         if name.endswith('IDX'):  # return the object  
      615             return self.Get(name[:-3])  
      616         return rec.get(name)  # any column name  
      617  
      618     def __nonzero__(self):  # if object == false if not valid  
      619         if not self.Table in self.db.Database:  
      620             return False  
      621         rec = self.db.Database[self.Table].get(self.ID)  
      622         if not rec:  
      623             return False  
      624         return True  
      625  
      626     def __setattr__(self, name, value):  
      627         # edits  
      628         if name in ('Table', 'ID', 'db', 'Valid', 'Get', 'GetList'):  
      629             return  # silently ignore attempts to change these?  
      630         if not self.Valid():  
      631             return  
      632         change = {'Table': self.Table, 'ID': self.ID, name: value }  
      633         Update(change)  # can only update the active database -- IMPORTANT  
      634         return  
      635  
      636     # ---- these are experimental ----  
      637     def _SetInShell(self, tag, value):  
      638         '''Don't update the database; save value in shell object'''  
      639         self.__dict__[tag] = value  
      640  
      641     def _SetToSubclass(self, subclass):  
      642         '''Change the class of the object to a subtype of the class'''  
      643         # self.__dict__['__class__'] = subclass  # how to make this work?  
      644         self.__class__ = subclass  # or this??  
      645         print self.__class__  
      646  
      647     # ----- end -------  
      648      
      649     def Valid(self):  
      650         try:  
      651             rec = self.db.Database[self.Table].get(self.ID)  
      652             return (rec and rec.get('zzStatus') != 'deleted')  
      653         except:  
      654             return None  
      655  
      656     def Get(self, name=None):  
      657         '''  
      658 returns an object that this one points to  
      659 returns object pointed to by name + ID  
      660         '''  
      661         if not name: return None  
      662         if not self.Valid(): return None  
      663  
      664         if self.Table in ('ReportRow', 'GraphicObject') and name == 'Target':  
      665             return self.db.GetObject(self.TableName, self.TableID)  
      666  
      667         rec = self.db.Database[self.Table].get(self.ID)  
      668         target_id = rec.get(name + 'ID')  # FK value  
      669         return self.db.GetObject(name, target_id)  # object  
      670  
      671     def GetList(self, table_name, attribute=None):  
      672         '''  
      673 returns a list of "table_name type" objects that point to this one  
      674 list_of_assignment_objects = ThisTask.Find('Assignment', 'Prerequisite')  
      675 Returns a list of all assignment objects that point to the original task object  
      676         '''  
      677         if attribute:  
      678             fk = attribute  
      679         else:  
      680             fk = self.Table  
      681         table_rows = self.db.Database.get(table_name) or {}  
      682         search = { fk + 'ID': self.ID }  
      683         result = SearchByColumn(table_rows, search)  # only works w/ current db -- IMPORTANT  
      684         # if debug: print result  
      685         return [ self.db.GetObject(table_name, x['ID']) for x in result.itervalues() if x.get('zzStatus') != 'deleted']  
      686  
      687 class DB:  
      688     def __init__(self, database):  
      689         ''' database '''  
      690         self.Database = database  
      691         self._ObjectXref = {}  # key = (table, id)  
      692  
      693     def _ConvertAlias(self, object_type):  
      694         # convert known aliases  
      695         da = self.Database['TableAlias'][1]  
      696         if object_type in da:  
      697             object_type = da[object_type]  
      698         return object_type  
      699      
      700     def GetObject(self, object_type, object_id=None):  
      701         if object_type in ('Table', 'ID'):  
      702             return None  
      703         object_type = self._ConvertAlias(object_type)  
      704         # add new objects to database  
      705         if not object_id:  
      706             update = {'Table': object_type}  
      707             object_id = Update(update)['ID']  # only works w/ current db -- IMPORTANT  
      708         # create object, save a copy for possible future use  
      709         key = (object_type, object_id)  
      710         if key in self._ObjectXref:  
      711             return self._ObjectXref[key]  
      712         else:  
      713             ob = Object(self, object_type, object_id)  
      714             self._ObjectXref[key] = ob  
      715             return ob  
      716  
      717     def GetList(self, table_name):  
      718         '''  
      719 returns a list of "table_name type"  
      720         '''  
      721         table = self.Database.get(table_name) or {}  
      722         return [ self.GetObject(table_name, x['ID']) for x in table.itervalues() if x.get('zzStatus') != 'deleted']  
      723  
      724     def RegisterType(self, type_name, constructor):  
      725         pass  
      726  
      727     def UnRegisterType(self, type_name):  
      728         pass  
      729  
      730 # end of GanttPV object API  
      731  
    581 732 ########## @@@@@@@@@@ Start Alex Date Conversion @@@@@@@@@@ ##########  
    582 733  
     
    1854 2005             continue  
    1855 2006         rt = ReportType[rtid]  
      2007         if rt.get('AdjustRowOption'): continue  
    1856 2008  
    1857 2009         ta, tb = rt.get('TableA'), rt.get('TableB')  
     
    2018 2170     global Project, Task, Dependency, Report, ReportColumn, ReportRow  
    2019 2171     global Resource, Assignment, Holiday, ReportType, ColumnType, OtherData, Other, NextID  
    2020    
      2172     global DBObject  
      2173      
    2021 2174     Project =       Database['Project']  
    2022 2175     Task =          Database['Task']  
     
    2048 2201     GanttCalculation()  
    2049 2202     AdjustReportRows()  
      2203     DBObject = DB(Database)  # will get objects from this database  
    2050 2204  
    2051 2205     UndoStack = []  
  • ganttpv/trunk/ReportAids.py

    r399 r403  
    30 30 import os, sys  
    31 31 import Data  
    32   import Menu, GanttReport  
      32 import Menu, GanttReport, ORMReport  
    32 32 # import random  
    33 33 # import StartupData  
     
    45 45     This dictionary should be passed to any scripts run with execfile.  
    46 46     """  
    47       import Data, GanttPV, GanttReport, ID, Menu, ReportAids, UI, wx  
      47     import Data, GanttPV, GanttReport, ORMReport, ID, Menu, ReportAids, UI, wx  
    47 47     return locals()  
    48 48  
     
    134 134         pos = (r.get('FramePositionX') or -1, r.get('FramePositionY') or -1)  
    135 135         size = (r.get('FrameSizeW') or 768, r.get('FrameSizeH') or 311)  
    136           Data.OpenReports[id] = GanttReport.GanttReportFrame(id, None, -1, "", pos, size)  
      136         rtid = r.get('ReportTypeID')  
      137         panel_type = Data.ReportType[rtid].get('PanelType')  
      138         print "panel type", panel_type  
      139         if panel_type == 'ORMDiagram':  
      140             Data.OpenReports[id] = ORMReport.ORMReportFrame(id, None, -1, "", pos, size)  
      141         else:  
      142             Data.OpenReports[id] = GanttReport.GanttReportFrame(id, None, -1, "", pos, size)  
    137 143         Menu.UpdateWindowMenuItem(id)  
    138 144     Data.OpenReports[id].Show(True)  
  • ganttpv/trunk/UI.py

    r399 r403  
    33 33 # 061229 - Brian - added edit project and report names to menu  
    34 34 # 070228 - Brian - add code to use smaller 'About' font on windows.  
      35 # 080519 - Brian - make diagram frame from report frame  
    35 36  
    36 37 import wx, ID, Menu, Data  
     
    405 406  
    406 407  
      408 class DiagramFrame(wx.Frame):  
      409     def __init__(self, *args, **kwds):  
      410         # begin wxGlade: ReportFrame.__init__  
      411         kwds["style"] = wx.DEFAULT_FRAME_STYLE  
      412         wx.Frame.__init__(self, *args, **kwds)  
      413         self.Report_Panel = wx.Panel(self, -1)  
      414          
      415         # Menu Bar  
      416         self.report_menubar = wx.MenuBar()  
      417         self.SetMenuBar(self.report_menubar)  
      418         self.FileMenu = wx.Menu()  
      419         self.New = wx.MenuItem(self.FileMenu, wx.ID_NEW, _("New\tCtrl-N"), _("Create a new database file; close open database (if any)"), wx.ITEM_NORMAL)  
      420         self.FileMenu.AppendItem(self.New)  
      421         self.Open = wx.MenuItem(self.FileMenu, wx.ID_OPEN, _("Open...\tCtrl-O"), _("Open existing database file"), wx.ITEM_NORMAL)  
      422         self.FileMenu.AppendItem(self.Open)  
      423         self.FileMenu.AppendSeparator()  
      424         self.CloseReport = wx.MenuItem(self.FileMenu, wx.ID_CLOSE, _("Close Report\tCtrl-W"), _("Close report window"), wx.ITEM_NORMAL)  
      425         self.FileMenu.AppendItem(self.CloseReport)  
      426         self.CloseAllReports = wx.MenuItem(self.FileMenu, wx.ID_CLOSE_ALL, _("Close All Reports\tCtrl-Alt-W"), _("Close all reports except main"), wx.ITEM_NORMAL)  
      427         self.FileMenu.AppendItem(self.CloseAllReports)  
      428         self.Save = wx.MenuItem(self.FileMenu, wx.ID_SAVE, _("Save\tCtrl-S"), _("Save project file"), wx.ITEM_NORMAL)  
      429         self.FileMenu.AppendItem(self.Save)  
      430         self.SaveAs = wx.MenuItem(self.FileMenu, wx.ID_SAVEAS, _("Save As...\tCtrl-Shift-S"), _("Save database file with new name"), wx.ITEM_NORMAL)  
      431         self.FileMenu.AppendItem(self.SaveAs)  
      432         self.AutoSave = wx.MenuItem(self.FileMenu, ID.M_AUTO_SAVE, _("Automatically Save On Quit"), _("Automatically save database when it is closed"), wx.ITEM_CHECK)  
      433         self.FileMenu.AppendItem(self.AutoSave)  
      434         self.FileMenu.AppendSeparator()  
      435         self.RevertToSaved = wx.MenuItem(self.FileMenu, wx.ID_REVERT, _("Revert to Last Saved"), _("Revert the database to the last manually saved version"), wx.ITEM_NORMAL)  
      436         self.FileMenu.AppendItem(self.RevertToSaved)  
      437         self.RevertToOpened = wx.MenuItem(self.FileMenu, ID.M_REVERT_OPEN, _("Revert to Last Opened"), _("Revert the database to the way it was when first opened"), wx.ITEM_NORMAL)  
      438         self.FileMenu.AppendItem(self.RevertToOpened)  
      439         self.FileMenu.AppendSeparator()  
      440         self.Quit = wx.MenuItem(self.FileMenu, wx.ID_EXIT, _("Quit\tCtrl-Q"), _("Quit program"), wx.ITEM_NORMAL)  
      441         self.FileMenu.AppendItem(self.Quit)  
      442         self.report_menubar.Append(self.FileMenu, _("File"))  
      443         self.Edit = wx.Menu()  
      444         self.Undo = wx.MenuItem(self.Edit, wx.ID_UNDO, _("Undo\tCtrl-Z"), _("Undo last change"), wx.ITEM_NORMAL)  
      445         self.Edit.AppendItem(self.Undo)  
      446         self.Redo = wx.MenuItem(self.Edit, wx.ID_REDO, _("Redo\tCtrl-Shift-Z"), _("Redo change"), wx.ITEM_NORMAL)  
      447         self.Edit.AppendItem(self.Redo)  
      448         self.Edit.AppendSeparator()  
      449         copy = wx.MenuItem(self.Edit, wx.ID_COPY, _("Copy\tCtrl-C"), _("Copy cells in current selection to clipboard"), wx.ITEM_NORMAL)  
      450         self.Edit.AppendItem(copy)  
      451         paste = wx.MenuItem(self.Edit, wx.ID_PASTE, _("Paste\tCtrl-V"), _("Paste cells from clipboard"), wx.ITEM_NORMAL)  
      452         self.Edit.AppendItem(paste)  
      453  
      454 ##        self.Edit.AppendSeparator()  
      455 ##        self.InsertRow = wx.MenuItem(self.Edit, ID.M_INSERT_ROW, _("Insert New %s\tCtrl-R"), _("Insert new %s below the selected row"), wx.ITEM_NORMAL)  
      456 ##        self.Edit.AppendItem(self.InsertRow)  
      457 ##        self.InsertRowAbove = wx.MenuItem(self.Edit, ID.M_INSERT_ROW_ABOVE, _("Insert New %s Above Selection\tCtrl-Shift-R"), _("Insert a new %s above the selected row"), wx.ITEM_NORMAL)  
      458 ##        self.Edit.AppendItem(self.InsertRowAbove)  
      459 ####        self.InsertChild = wx.MenuItem(self.Edit, ID.M_INSERT_CHILD, _("Insert Child %s"), _("Insert a child %s"), wx.ITEM_NORMAL)  
      460 ####        self.Edit.AppendItem(self.InsertChild)  
      461 ##        self.InsertRelated = wx.MenuItem(self.Edit, ID.M_INSERT_RELATED, _("Insert Related %s"), _("Insert a new %s"), wx.ITEM_NORMAL)  
      462 ##        self.Edit.AppendItem(self.InsertRelated)  
      463 ##        self.Edit.AppendSeparator()  
      464 ##        self.DeleteRow = wx.MenuItem(self.Edit, ID.M_DELETE_ROW, _("Delete Selected Row"), _("Delete the selected row"), wx.ITEM_NORMAL)  
      465 ##        self.Edit.AppendItem(self.DeleteRow)  
      466 ##        self.Edit.AppendSeparator()  
      467 ##        self.MoveRowUp = wx.MenuItem(self.Edit, ID.M_SHIFT_LEFT, _("Shift Left\tCtrl-Shift-9"), _("Shift left (to next higher level)"), wx.ITEM_NORMAL)  
      468 ##        self.Edit.AppendItem(self.MoveRowUp)  
      469 ##        self.MoveRowDown = wx.MenuItem(self.Edit, ID.M_SHIFT_RIGHT, _("Shift Right\tCtrl-Shift-0"), _("Shift right (to next lower level)"), wx.ITEM_NORMAL)  
      470 ##        self.Edit.AppendItem(self.MoveRowDown)  
      471 ##        self.Edit.AppendSeparator()  
      472 ##        self.MoveRowUp = wx.MenuItem(self.Edit, ID.M_MOVE_ROW_UP, _("Move Selected Row Up\tCtrl-9"), _("Move the selected row up one posiion (if possible)"), wx.ITEM_NORMAL)  
      473 ##        self.Edit.AppendItem(self.MoveRowUp)  
      474 ##        self.MoveRowDown = wx.MenuItem(self.Edit, ID.M_MOVE_ROW_DOWN, _("Move Selected Row Down\tCtrl-0"), _("Move the selected row down (if possible)"), wx.ITEM_NORMAL)  
      475 ##        self.Edit.AppendItem(self.MoveRowDown)  
      476 ##        self.Edit.AppendSeparator()  
      477 ##        editprojectname = wx.MenuItem(self.Edit, ID.M_EDIT_PROJECT_NAME, _("Edit Project Name..."), _("Edit the name of the project that owns this report"), wx.ITEM_NORMAL)  
      478 ##        self.Edit.AppendItem(editprojectname)  
      479 ##        editreportname = wx.MenuItem(self.Edit, ID.M_EDIT_REPORT_NAME, _("Edit Report Name..."), _("Edit the name of this report"), wx.ITEM_NORMAL)  
      480 ##        self.Edit.AppendItem(editreportname)  
      481  
      482         self.report_menubar.Append(self.Edit, _("Edit"))  
      483         wxglade_tmp_menu = wx.Menu()  
      484  
      485 ##        self.Action = wxglade_tmp_menu  
      486 ##        self.AssignPrerequisite = wx.MenuItem(wxglade_tmp_menu, ID.M_ASSIGN_PREREQUISITE, _("Define Prerequisite for Task..."), _("Assign prerequisite for selected task"), wx.ITEM_NORMAL)  
      487 ##        wxglade_tmp_menu.AppendItem(self.AssignPrerequisite)  
      488 ##        self.LinkTasks = wx.MenuItem(wxglade_tmp_menu, ID.M_LINK_TASKS, _("Link Selected Tasks as Dependent"), _("Link tasks as dependent in the order they appear in the report"), wx.ITEM_NORMAL)  
      489 ##        wxglade_tmp_menu.AppendItem(self.LinkTasks)  
      490 ##        self.AssignResource = wx.MenuItem(wxglade_tmp_menu, ID.M_ASSIGN_RESOURCE, _("Assign Resource to Task..."), _("Assign resources to the selected task"), wx.ITEM_NORMAL)  
      491 ##        wxglade_tmp_menu.AppendItem(self.AssignResource)  
      492 ##        wxglade_tmp_menu.AppendSeparator()  
      493 ##        self.AssignResourceToGroup = wx.MenuItem(wxglade_tmp_menu, ID.M_RESOURCE_TO_GROUP, _("Assign Resource to Resource Group..."), _("Identify the groups to which the selected resource belongs"), wx.ITEM_NORMAL)  
      494 ##        wxglade_tmp_menu.AppendItem(self.AssignResourceToGroup)  
      495 ##        self.DefineGroupMembers = wx.MenuItem(wxglade_tmp_menu, ID.M_DEFINE_RESOURCE_GROUP, _("Define Members of Resource Group..."), _("Define which resources are members of the specified resource group"), wx.ITEM_NORMAL)  
      496 ##        wxglade_tmp_menu.AppendItem(self.DefineGroupMembers)  
      497 ##        self.AssignTask = wx.MenuItem(wxglade_tmp_menu, ID.M_ASSIGN_TASK, _("Assign Task to Resource..."), _("Specify all tasks assignments for a resource"), wx.ITEM_NORMAL)  
      498 ##        wxglade_tmp_menu.AppendItem(self.AssignTask)  
      499 ##        self.report_menubar.Append(wxglade_tmp_menu, _("Action"))  
      500  
      501 ##        wxglade_tmp_menu = wx.Menu()  
      502 ##        self.View = wxglade_tmp_menu  
      503 ##        self.InsertColumn = wx.MenuItem(wxglade_tmp_menu, ID.M_INSERT_COLUMN, _("Insert Column..."), _("Insert a new column before selection"), wx.ITEM_NORMAL)  
      504 ##        wxglade_tmp_menu.AppendItem(self.InsertColumn)  
      505 ##        wxglade_tmp_menu.AppendSeparator()  
      506 ##        self.DeleteColumn = wx.MenuItem(wxglade_tmp_menu, ID.M_DELETE_COLUMN, _("Delete Selected Column"), _("Delete the selected column from the report"), wx.ITEM_NORMAL)  
      507 ##        wxglade_tmp_menu.AppendItem(self.DeleteColumn)  
      508 ##        wxglade_tmp_menu.AppendSeparator()  
      509 ##        self.MoveColumnLeft = wx.MenuItem(wxglade_tmp_menu, ID.M_MOVE_COLUMN_LEFT, _("Move Selected Column Left"), _("Move the selected column to the left"), wx.ITEM_NORMAL)  
      510 ##        wxglade_tmp_menu.AppendItem(self.MoveColumnLeft)  
      511 ##        self.MoveColumnRight = wx.MenuItem(wxglade_tmp_menu, ID.M_MOVE_COLUMN_RIGHT, _("Move Selected Column Right"), _("Move the selected column to the right"), wx.ITEM_NORMAL)  
      512 ##        wxglade_tmp_menu.AppendItem(self.MoveColumnRight)  
      513 ##        wxglade_tmp_menu.AppendSeparator()  
      514 ##        self.ScrollLeftFast = wx.MenuItem(wxglade_tmp_menu, ID.M_SCROLL_LEFT_FAST, _("Scroll Timescale Left Fast"), _("Shift the selected time scale several periods to the left"), wx.ITEM_NORMAL)  
      515 ##        wxglade_tmp_menu.AppendItem(self.ScrollLeftFast)  
      516 ##        self.ScrollLeft = wx.MenuItem(wxglade_tmp_menu, ID.M_SCROLL_LEFT, _("Scroll Timescale Left"), _("Shift the selected time scale one period to the left"), wx.ITEM_NORMAL)  
      517 ##        wxglade_tmp_menu.AppendItem(self.ScrollLeft)  
      518 ##        self.ScrollRight = wx.MenuItem(wxglade_tmp_menu, ID.M_SCROLL_RIGHT, _("Scroll Timescale Right"), _("Shift the selected time scale one period to the right"), wx.ITEM_NORMAL)  
      519 ##        wxglade_tmp_menu.AppendItem(self.ScrollRight)  
      520 ##        self.ScrollRightFast = wx.MenuItem(wxglade_tmp_menu, ID.M_SCROLL_RIGHT_FAST, _("Scroll Timescale Right Fast"), _("Shift the selected time scale several periods to the right"), wx.ITEM_NORMAL)  
      521 ##        wxglade_tmp_menu.AppendItem(self.ScrollRightFast)  
      522 ##        self.ScrollToTask = wx.MenuItem(wxglade_tmp_menu, ID.M_SCROLL_TO_TASK, _("Scroll Timescale to Task Start Date"), _("Scroll timescales to the selected task's start date"), wx.ITEM_NORMAL)  
      523 ##        wxglade_tmp_menu.AppendItem(self.ScrollToTask)  
      524 ##        self.report_menubar.Append(wxglade_tmp_menu, _("View"))  
      525  
      526         self.Script = wx.Menu()  
      527         self.FindScripts = wx.MenuItem(self.Script, ID.FIND_SCRIPTS, _("Choose Scripts Folder..."), _("Specify location of scripts folder"), wx.ITEM_NORMAL)  
      528         self.Script.AppendItem(self.FindScripts)  
      529         self.RefreshScripts = wx.MenuItem(self.Script, ID.REFRESH_SCRIPTS, _("Refresh Script Menu"), _("Update the script menu to include changes to the script folder"), wx.ITEM_NORMAL)  
      530         self.Script.AppendItem(self.RefreshScripts)  
      531         self.RepeatScript = wx.MenuItem(self.Script, ID.REPEAT_SCRIPT, _("Repeat Previous Script\tCtrl-8"), _("Re-run the previous script"), wx.ITEM_NORMAL)  
      532         self.Script.AppendItem(self.RepeatScript)  
      533         self.report_menubar.Append(self.Script, _("Script"))  
      534         wxglade_tmp_menu = wx.Menu()  
      535         self.WindowMenu = wxglade_tmp_menu  
      536         self.FirstWindow = wx.MenuItem(wxglade_tmp_menu, ID.FIRST_WINDOW, _("Main Window\tCtrl-1"), _("Bring the main window to front"), wx.ITEM_CHECK)  
      537         wxglade_tmp_menu.AppendItem(self.FirstWindow)  
      538         # self.WindowMenu.Check(ID.FIRST_WINDOW, True)  
      539         self.report_menubar.Append(wxglade_tmp_menu, _("Window"))  
      540         self.Help = wx.Menu()  
      541         self.About = wx.MenuItem(self.Help, wx.ID_ABOUT, _("About GanttPV..."), "", wx.ITEM_NORMAL)  
      542         self.Help.AppendItem(self.About)  
      543         self.QuickStart = wx.MenuItem(self.Help, ID.QUICK_START, _("Quick Start..."), _("Provide hints on how to use report"), wx.ITEM_NORMAL)  
      544         self.Help.AppendItem(self.QuickStart)  
      545         self.ShortCuts = wx.MenuItem(self.Help, ID.SHORT_CUTS, _("Shortcuts..."), _("Displays most the most useful shortcuts"), wx.ITEM_NORMAL)  
      546         self.Help.AppendItem(self.ShortCuts)  
      547         self.HomePage = wx.MenuItem(self.Help, ID.HOME_PAGE, _("GanttPV Home"), _("Open GanttPV home page in web browser"), wx.ITEM_NORMAL)  
      548         self.Help.AppendItem(self.HomePage)  
      549         self.HelpPage = wx.MenuItem(self.Help, ID.HELP_PAGE, _("Help Page and Tour"), _("Open GanttPV help page in web browser"), wx.ITEM_NORMAL)  
      550         self.Help.AppendItem(self.HelpPage)  
      551         self.Forum = wx.MenuItem(self.Help, ID.FORUM, _("Forum"), _("Open GanttPV user forum in web browser"), wx.ITEM_NORMAL)  
      552         self.Help.AppendItem(self.Forum)  
      553         self.report_menubar.Append(self.Help, _("&Help"))  
      554         # Menu Bar end  
      555         self.report_statusbar = self.CreateStatusBar(1, 0)  
      556          
      557 ##        # Tool Bar  
      558 ##        self.report_toolbar = wx.ToolBar(self, -1)  
      559 ##        self.report_toolbar.SetToolBitmapSize((16, 16))  # change  
      560 ##        self.SetToolBar(self.report_toolbar)  
      561 ##        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"))  
      562 ##        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"))  
      563 ##        self.report_toolbar.AddLabelTool(ID.DELETE_ROW, _("Delete Row"), Menu.Bitmap("icons/Delete Row.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Delete Row"), _("Delete selected rows"))  
      564 ##        self.report_toolbar.AddLabelTool(ID.MOVE_UP, _("Move Up"), Menu.Bitmap("icons/Move Up.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Move Row Up"), _("Move selected rows up"))  
      565 ##        self.report_toolbar.AddLabelTool(ID.MOVE_DOWN, _("Move Down"), Menu.Bitmap("icons/Move Down.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Move Row Down"), _("Move selected rows down"))  
      566 ##        self.report_toolbar.AddSeparator()  
      567 ##        self.report_toolbar.AddLabelTool(ID.PREREQUISITE, _("Assign Prerequisite"), Menu.Bitmap("icons/Assign Prerequisites.bmp", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, _("Assign Prerequisite"), _("Identify prerequisites for selected task"))  
      568 ##