RessourceEditor.py
changeset 27 dae55dd9ee14
child 56 7187e1c00975
equal deleted inserted replaced
26:36d378bd852e 27:dae55dd9ee14
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C): Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #Lesser General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from wxPython.wx import *
       
    26 from wxPython.grid import *
       
    27 import wx
       
    28 
       
    29 #-------------------------------------------------------------------------------
       
    30 #                            Resource Editor class
       
    31 #-------------------------------------------------------------------------------
       
    32 
       
    33 class ResourceTable(wxPyGridTableBase):
       
    34     
       
    35     """
       
    36     A custom wxGrid Table using user supplied data
       
    37     """
       
    38     def __init__(self, parent, data, colnames):
       
    39         # The base class must be initialized *first*
       
    40         wxPyGridTableBase.__init__(self)
       
    41         self.data = data
       
    42         self.colnames = colnames
       
    43         self.Parent = parent
       
    44         
       
    45         self.ColAlignements = []
       
    46         self.ColSizes = []
       
    47         # XXX
       
    48         # we need to store the row length and collength to
       
    49         # see if the table has changed size
       
    50         self._rows = self.GetNumberRows()
       
    51         self._cols = self.GetNumberCols()
       
    52     
       
    53     def GetColAlignements(self):
       
    54         return self.ColAlignements
       
    55     
       
    56     def SetColAlignements(self, list):
       
    57         self.ColAlignements = list
       
    58 
       
    59     def GetColSizes(self):
       
    60         return self.ColSizes
       
    61     
       
    62     def SetColSizes(self, list):
       
    63         self.ColSizes = list
       
    64 
       
    65     def GetNumberCols(self):
       
    66         return len(self.colnames)
       
    67         
       
    68     def GetNumberRows(self):
       
    69         return len(self.data)
       
    70 
       
    71     def GetColLabelValue(self, col):
       
    72         if col < len(self.colnames):
       
    73             return self.colnames[col]
       
    74 
       
    75     def GetRowLabelValues(self, row):
       
    76         return row
       
    77 
       
    78     def GetValue(self, row, col):
       
    79         if row < self.GetNumberRows():
       
    80             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
       
    81             return name
       
    82     
       
    83     def GetValueByName(self, row, colname):
       
    84         return self.data[row].get(colname)
       
    85 
       
    86     def SetValue(self, row, col, value):
       
    87         if col < len(self.colnames):
       
    88             self.data[row][self.GetColLabelValue(col)] = value
       
    89     
       
    90     def SetValueByName(self, row, colname, value):
       
    91         if colname in self.colnames:
       
    92             self.data[row][colname] = value
       
    93     
       
    94     def ResetView(self, grid):
       
    95         """
       
    96         (wxGrid) -> Reset the grid view.   Call this to
       
    97         update the grid if rows and columns have been added or deleted
       
    98         """
       
    99         grid.BeginBatch()
       
   100         for current, new, delmsg, addmsg in [
       
   101             (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
       
   102             (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
       
   103         ]:
       
   104             if new < current:
       
   105                 msg = wxGridTableMessage(self,delmsg,new,current-new)
       
   106                 grid.ProcessTableMessage(msg)
       
   107             elif new > current:
       
   108                 msg = wxGridTableMessage(self,addmsg,new-current)
       
   109                 grid.ProcessTableMessage(msg)
       
   110                 self.UpdateValues(grid)
       
   111         grid.EndBatch()
       
   112 
       
   113         self._rows = self.GetNumberRows()
       
   114         self._cols = self.GetNumberCols()
       
   115         # update the column rendering scheme
       
   116         self._updateColAttrs(grid)
       
   117 
       
   118         # update the scrollbars and the displayed part of the grid
       
   119         grid.AdjustScrollbars()
       
   120         grid.ForceRefresh()
       
   121 
       
   122     def UpdateValues(self, grid):
       
   123         """Update all displayed values"""
       
   124         # This sends an event to the grid table to update all of the values
       
   125         msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
   126         grid.ProcessTableMessage(msg)
       
   127 
       
   128     def _updateColAttrs(self, grid):
       
   129         """
       
   130         wxGrid -> update the column attributes to add the
       
   131         appropriate renderer given the column name.
       
   132 
       
   133         Otherwise default to the default renderer.
       
   134         """
       
   135         
       
   136         for col in range(self.GetNumberCols()):
       
   137             attr = wxGridCellAttr()
       
   138             attr.SetAlignment(self.ColAlignements[col], wxALIGN_CENTRE)
       
   139             grid.SetColAttr(col, attr)
       
   140             grid.SetColSize(col, self.ColSizes[col])
       
   141         
       
   142         for row in range(self.GetNumberRows()):
       
   143             for col in range(self.GetNumberCols()):
       
   144                 editor = None
       
   145                 renderer = None
       
   146                 colname = self.GetColLabelValue(col)
       
   147                 grid.SetReadOnly(row, col, False)
       
   148                 if colname in ["Name","Interval"]:
       
   149                     editor = wxGridCellTextEditor()
       
   150                     renderer = wxGridCellStringRenderer()
       
   151                     if colname == "Interval" and self.GetValueByName(row, "Single") != "":
       
   152                         grid.SetReadOnly(row, col, True)
       
   153                 elif colname == "Single":
       
   154                     editor = wxGridCellChoiceEditor()
       
   155                     editor.SetParameters(self.Parent.VariableList)
       
   156                     if self.GetValueByName(row, "Interval") != "":
       
   157                         grid.SetReadOnly(row, col, True)
       
   158                 elif colname == "Type":
       
   159                     editor = wxGridCellChoiceEditor()
       
   160                     editor.SetParameters(self.Parent.TypeList)
       
   161                 elif colname == "Priority":
       
   162                     editor = wxGridCellNumberEditor()
       
   163                     editor.SetParameters("0,65535")
       
   164                 elif colname == "Task":
       
   165                     editor = wxGridCellChoiceEditor()
       
   166                     editor.SetParameters(self.Parent.TaskList)
       
   167                     
       
   168                 grid.SetCellEditor(row, col, editor)
       
   169                 grid.SetCellRenderer(row, col, renderer)
       
   170                 
       
   171                 grid.SetCellBackgroundColour(row, col, wxWHITE)
       
   172     
       
   173     def SetData(self, data):
       
   174         self.data = data
       
   175     
       
   176     def GetData(self):
       
   177         return self.data
       
   178     
       
   179     def GetCurrentIndex(self):
       
   180         return self.CurrentIndex
       
   181     
       
   182     def SetCurrentIndex(self, index):
       
   183         self.CurrentIndex = index
       
   184     
       
   185     def AppendRow(self, row_content):
       
   186         self.data.append(row_content)
       
   187 
       
   188     def RemoveRow(self, row_index):
       
   189         self.data.pop(row_index)
       
   190         
       
   191     def MoveRow(self, row_index, move, grid):
       
   192         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
   193         if new_index != row_index:
       
   194             self.data.insert(new_index, self.data.pop(row_index))
       
   195             grid.SetGridCursor(new_index, grid.GetGridCursorCol())
       
   196 
       
   197     def Empty(self):
       
   198         self.data = []
       
   199         self.editors = []
       
   200 
       
   201 
       
   202 [wxID_RESOURCEEDITOR, wxID_RESOURCEEDITORSTATICTEXT1,
       
   203  wxID_RESOURCEEDITORSTATICTEXT2, wxID_RESOURCEEDITORINSTANCESGRID,
       
   204  wxID_RESOURCEEDITORTASKSGRID, wxID_RESOURCEEDITORADDINSTANCEBUTTON,
       
   205  wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, wxID_RESOURCEEDITORUPINSTANCEBUTTON,
       
   206  wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, wxID_RESOURCEEDITORADDTASKBUTTON,
       
   207  wxID_RESOURCEEDITORDELETETASKBUTTON, wxID_RESOURCEEDITORUPTASKBUTTON,
       
   208  wxID_RESOURCEEDITORDOWNTASKBUTTON,
       
   209 ] = [wx.NewId() for _init_ctrls in range(13)]
       
   210 
       
   211 class ResourceEditor(wx.Panel):
       
   212     
       
   213     def _init_coll_InstancesSizer_Growables(self, parent):
       
   214         # generated method, don't edit
       
   215 
       
   216         parent.AddGrowableCol(0)
       
   217         parent.AddGrowableRow(1)
       
   218 
       
   219     def _init_coll_InstancesSizer_Items(self, parent):
       
   220         # generated method, don't edit
       
   221 
       
   222         parent.AddSizer(self.InstancesButtonsSizer, 0, border=0, flag=wxGROW)
       
   223         parent.AddWindow(self.InstancesGrid, 0, border=0, flag=wxGROW)
       
   224 
       
   225     def _init_coll_InstancesButtonsSizer_Growables(self, parent):
       
   226         # generated method, don't edit
       
   227 
       
   228         parent.AddGrowableCol(0)
       
   229         parent.AddGrowableRow(0)
       
   230 
       
   231     def _init_coll_InstancesButtonsSizer_Items(self, parent):
       
   232         # generated method, don't edit
       
   233 
       
   234         parent.AddWindow(self.staticText2, 0, border=0, flag=wxALIGN_BOTTOM)
       
   235         parent.AddWindow(self.AddInstanceButton, 0, border=0, flag=0)
       
   236         parent.AddWindow(self.DeleteInstanceButton, 0, border=0, flag=0)
       
   237         parent.AddWindow(self.UpInstanceButton, 0, border=0, flag=0)
       
   238         parent.AddWindow(self.DownInstanceButton, 0, border=0, flag=0)
       
   239 
       
   240     def _init_coll_TasksSizer_Growables(self, parent):
       
   241         # generated method, don't edit
       
   242 
       
   243         parent.AddGrowableCol(0)
       
   244         parent.AddGrowableRow(1)
       
   245 
       
   246     def _init_coll_TasksSizer_Items(self, parent):
       
   247         # generated method, don't edit
       
   248 
       
   249         parent.AddSizer(self.TasksButtonsSizer, 0, border=0, flag=wxGROW)
       
   250         parent.AddWindow(self.TasksGrid, 0, border=0, flag=wxGROW)
       
   251 
       
   252     def _init_coll_TasksButtonsSizer_Growables(self, parent):
       
   253         # generated method, don't edit
       
   254 
       
   255         parent.AddGrowableCol(0)
       
   256         parent.AddGrowableRow(0)
       
   257 
       
   258     def _init_coll_TasksButtonsSizer_Items(self, parent):
       
   259         # generated method, don't edit
       
   260 
       
   261         parent.AddWindow(self.staticText1, 0, border=0, flag=wxALIGN_BOTTOM)
       
   262         parent.AddWindow(self.AddTaskButton, 0, border=0, flag=0)
       
   263         parent.AddWindow(self.DeleteTaskButton, 0, border=0, flag=0)
       
   264         parent.AddWindow(self.UpTaskButton, 0, border=0, flag=0)
       
   265         parent.AddWindow(self.DownTaskButton, 0, border=0, flag=0)
       
   266 
       
   267     def _init_coll_MainGridSizer_Items(self, parent):
       
   268         # generated method, don't edit
       
   269 
       
   270         parent.AddSizer(self.TasksSizer, 0, border=0, flag=wxGROW)
       
   271         parent.AddSizer(self.InstancesSizer, 0, border=0, flag=wxGROW)
       
   272 
       
   273     def _init_coll_MainGridSizer_Growables(self, parent):
       
   274         # generated method, don't edit
       
   275 
       
   276         parent.AddGrowableCol(0)
       
   277         parent.AddGrowableRow(0)
       
   278         parent.AddGrowableRow(1)
       
   279 
       
   280     def _init_sizers(self):
       
   281         # generated method, don't edit
       
   282         self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   283 
       
   284         self.InstancesSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   285 
       
   286         self.InstancesButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
       
   287 
       
   288         self.TasksSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   289 
       
   290         self.TasksButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
       
   291 
       
   292         self._init_coll_MainGridSizer_Growables(self.MainGridSizer)
       
   293         self._init_coll_MainGridSizer_Items(self.MainGridSizer)
       
   294         self._init_coll_InstancesSizer_Growables(self.InstancesSizer)
       
   295         self._init_coll_InstancesSizer_Items(self.InstancesSizer)
       
   296         self._init_coll_InstancesButtonsSizer_Growables(self.InstancesButtonsSizer)
       
   297         self._init_coll_InstancesButtonsSizer_Items(self.InstancesButtonsSizer)
       
   298         self._init_coll_TasksSizer_Growables(self.TasksSizer)
       
   299         self._init_coll_TasksSizer_Items(self.TasksSizer)
       
   300         self._init_coll_TasksButtonsSizer_Growables(self.TasksButtonsSizer)
       
   301         self._init_coll_TasksButtonsSizer_Items(self.TasksButtonsSizer)
       
   302 
       
   303         self.SetSizer(self.MainGridSizer)
       
   304 
       
   305     def _init_ctrls(self, prnt):
       
   306         # generated method, don't edit
       
   307         wx.Panel.__init__(self, id=wxID_RESOURCEEDITOR, name='', parent=prnt,
       
   308               pos=wx.Point(0, 0), size=wx.Size(-1, -1),
       
   309               style=wx.SUNKEN_BORDER)
       
   310         
       
   311         self.staticText1 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT1,
       
   312               label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0,
       
   313               0), size=wx.Size(60, 17), style=wxALIGN_CENTER)
       
   314 
       
   315         self.TasksGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORTASKSGRID,
       
   316               name='TasksGrid', parent=self, pos=wx.Point(0, 0), 
       
   317               size=wx.Size(-1, -1), style=wxVSCROLL)
       
   318         self.TasksGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
   319               'Sans'))
       
   320         self.TasksGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
   321               False, 'Sans'))
       
   322         EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange)
       
   323 
       
   324         self.AddTaskButton = wx.Button(id=wxID_RESOURCEEDITORADDTASKBUTTON, label='Add Task',
       
   325               name='AddTaskButton', parent=self, pos=wx.Point(0, 0),
       
   326               size=wx.Size(102, 32), style=0)
       
   327         EVT_BUTTON(self, wxID_RESOURCEEDITORADDTASKBUTTON, self.OnAddTaskButton)
       
   328 
       
   329         self.DeleteTaskButton = wx.Button(id=wxID_RESOURCEEDITORDELETETASKBUTTON, label='Delete Task',
       
   330               name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0),
       
   331               size=wx.Size(102, 32), style=0)
       
   332         EVT_BUTTON(self, wxID_RESOURCEEDITORDELETETASKBUTTON, self.OnDeleteTaskButton)
       
   333 
       
   334         self.UpTaskButton = wx.Button(id=wxID_RESOURCEEDITORUPTASKBUTTON, label='^',
       
   335               name='UpTaskButton', parent=self, pos=wx.Point(0, 0),
       
   336               size=wx.Size(32, 32), style=0)
       
   337         EVT_BUTTON(self, wxID_RESOURCEEDITORUPTASKBUTTON, self.OnUpTaskButton)
       
   338 
       
   339         self.DownTaskButton = wx.Button(id=wxID_RESOURCEEDITORDOWNTASKBUTTON, label='v',
       
   340               name='DownTaskButton', parent=self, pos=wx.Point(0, 0),
       
   341               size=wx.Size(32, 32), style=0)
       
   342         EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNTASKBUTTON, self.OnDownTaskButton)
       
   343 
       
   344         self.staticText2 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT2,
       
   345               label=u'Instances:', name='staticText1', parent=self,
       
   346               pos=wx.Point(0, 0), size=wx.Size(85, 17), style=wxALIGN_CENTER)
       
   347 
       
   348         self.InstancesGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORINSTANCESGRID,
       
   349               name='InstancesGrid', parent=self, pos=wx.Point(0, 0), 
       
   350               size=wx.Size(-1, -1), style=wxVSCROLL)
       
   351         self.InstancesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
   352               'Sans'))
       
   353         self.InstancesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
   354               False, 'Sans'))
       
   355         EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange)
       
   356 
       
   357         self.AddInstanceButton = wx.Button(id=wxID_RESOURCEEDITORADDINSTANCEBUTTON, label='Add Instance',
       
   358               name='AddInstanceButton', parent=self, pos=wx.Point(0, 0),
       
   359               size=wx.Size(122, 32), style=0)
       
   360         EVT_BUTTON(self, wxID_RESOURCEEDITORADDINSTANCEBUTTON, self.OnAddInstanceButton)
       
   361 
       
   362         self.DeleteInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, label='Delete Instance',
       
   363               name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0),
       
   364               size=wx.Size(122, 32), style=0)
       
   365         EVT_BUTTON(self, wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, self.OnDeleteInstanceButton)
       
   366 
       
   367         self.UpInstanceButton = wx.Button(id=wxID_RESOURCEEDITORUPINSTANCEBUTTON, label='^',
       
   368               name='UpInstanceButton', parent=self, pos=wx.Point(0, 0),
       
   369               size=wx.Size(32, 32), style=0)
       
   370         EVT_BUTTON(self, wxID_RESOURCEEDITORUPINSTANCEBUTTON, self.OnUpInstanceButton)
       
   371 
       
   372         self.DownInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, label='v',
       
   373               name='DownInstanceButton', parent=self, pos=wx.Point(0, 0),
       
   374               size=wx.Size(32, 32), style=0)
       
   375         EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, self.OnDownInstanceButton)
       
   376 
       
   377         self._init_sizers()
       
   378 
       
   379     def __init__(self, parent, window, controler):
       
   380         self._init_ctrls(parent)
       
   381         
       
   382         self.Parent = window
       
   383         self.Controler = controler
       
   384         
       
   385         self.TasksDefaultValue = {"Name" : "", "Single" : "", "Interval" : "", "Priority" : 0}
       
   386         self.TasksTable = ResourceTable(self, [], ["Name", "Single", "Interval", "Priority"])
       
   387         self.TasksTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_RIGHT, wxALIGN_RIGHT])
       
   388         self.TasksTable.SetColSizes([200, 100, 100, 100])
       
   389         self.TasksGrid.SetTable(self.TasksTable)
       
   390         self.TasksGrid.SetRowLabelSize(0)
       
   391         self.TasksTable.ResetView(self.TasksGrid)
       
   392 
       
   393         self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""}
       
   394         self.InstancesTable = ResourceTable(self, [], ["Name", "Type", "Task"])
       
   395         self.InstancesTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT])
       
   396         self.InstancesTable.SetColSizes([200, 150, 150])
       
   397         self.InstancesGrid.SetTable(self.InstancesTable)
       
   398         self.InstancesGrid.SetRowLabelSize(0)
       
   399         self.InstancesTable.ResetView(self.InstancesGrid)
       
   400 
       
   401     def SetMode(self, mode):
       
   402         pass
       
   403 
       
   404     def RefreshTypeList(self):
       
   405         self.TypeList = ""
       
   406         blocktypes = self.Controler.GetBlockResource()
       
   407         for blocktype in blocktypes:
       
   408             self.TypeList += ",%s"%blocktype
       
   409 
       
   410     def RefreshTaskList(self):
       
   411         self.TaskList = ""
       
   412         for row in xrange(self.TasksTable.GetNumberRows()):
       
   413             self.TaskList += ",%s"%self.TasksTable.GetValueByName(row, "Name")
       
   414 
       
   415     def RefreshVariableList(self):
       
   416         self.VariableList = ""
       
   417         for variable in self.Controler.GetCurrentResourceEditingVariables():
       
   418             self.VariableList += ",%s"%variable
       
   419         
       
   420     def RefreshModel(self):
       
   421         self.Controler.SetCurrentResourceEditingInfos(self.TasksTable.GetData(), self.InstancesTable.GetData())
       
   422 
       
   423     def RefreshView(self):
       
   424         tasks, instances = self.Controler.GetCurrentResourceEditingInfos()
       
   425         self.TasksTable.SetData(tasks)
       
   426         self.InstancesTable.SetData(instances)
       
   427         self.RefreshTypeList()
       
   428         self.RefreshTaskList()
       
   429         self.RefreshVariableList()
       
   430         self.InstancesTable.ResetView(self.InstancesGrid)
       
   431         self.TasksTable.ResetView(self.TasksGrid)
       
   432 
       
   433     def OnAddTaskButton(self, event):
       
   434         self.TasksTable.AppendRow(self.TasksDefaultValue.copy())
       
   435         self.RefreshModel()
       
   436         self.RefreshView()
       
   437         event.Skip()
       
   438 
       
   439     def OnDeleteTaskButton(self, event):
       
   440         row = self.TasksGrid.GetGridCursorRow()
       
   441         self.TasksTable.RemoveRow(row)
       
   442         self.RefreshModel()
       
   443         self.RefreshView()
       
   444         event.Skip()
       
   445 
       
   446     def OnUpTaskButton(self, event):
       
   447         row = self.TasksGrid.GetGridCursorRow()
       
   448         self.TasksTable.MoveRow(row, -1, self.TasksGrid)
       
   449         self.RefreshModel()
       
   450         self.RefreshView()
       
   451         event.Skip()
       
   452 
       
   453     def OnDownTaskButton(self, event):
       
   454         row = self.TasksGrid.GetGridCursorRow()
       
   455         self.TasksTable.MoveRow(row, 1, self.TasksGrid)
       
   456         self.RefreshModel()
       
   457         self.RefreshView()
       
   458         event.Skip()
       
   459 
       
   460     def OnAddInstanceButton(self, event):
       
   461         self.InstancesTable.AppendRow(self.InstancesDefaultValue.copy())
       
   462         self.RefreshModel()
       
   463         self.RefreshView()
       
   464         event.Skip()
       
   465 
       
   466     def OnDeleteInstanceButton(self, event):
       
   467         row = self.InstancesGrid.GetGridCursorRow()
       
   468         self.InstancesTable.RemoveRow(row)
       
   469         self.RefreshModel()
       
   470         self.RefreshView()
       
   471         event.Skip()
       
   472 
       
   473     def OnUpInstanceButton(self, event):
       
   474         row = self.InstancesGrid.GetGridCursorRow()
       
   475         self.InstancesTable.MoveRow(row, -1, self.InstancesGrid)
       
   476         self.RefreshModel()
       
   477         self.RefreshView()
       
   478         event.Skip()
       
   479 
       
   480     def OnDownInstanceButton(self, event):
       
   481         row = self.InstancesGrid.GetGridCursorRow()
       
   482         self.InstancesTable.MoveRow(row, 1, self.InstancesGrid)
       
   483         self.RefreshModel()
       
   484         self.RefreshView()
       
   485         event.Skip()
       
   486 
       
   487     def OnTasksGridCellChange(self, event):
       
   488         row, col = event.GetRow(), event.GetCol()
       
   489         if self.TasksTable.GetColLabelValue(event.GetCol()) == "Name":
       
   490             tasklist = self.TaskList.split(",")
       
   491             for i in xrange(self.TasksTable.GetNumberRows()):
       
   492                 task = self.TasksTable.GetValueByName(i, "Name")
       
   493                 if task in tasklist:
       
   494                     tasklist.remove(task)
       
   495             tasklist.remove("")
       
   496             if len(tasklist) > 0:
       
   497                 old_name = tasklist[0]
       
   498                 new_name = self.TasksTable.GetValue(row, col)
       
   499                 for i in xrange(self.InstancesTable.GetNumberRows()):
       
   500                     if self.InstancesTable.GetValueByName(i, "Task") == old_name:
       
   501                         self.InstancesTable.SetValueByName(i, "Task", new_name)
       
   502         self.RefreshModel()
       
   503         self.RefreshView()
       
   504         event.Skip()
       
   505 
       
   506     def OnInstancesGridCellChange(self, event):
       
   507         self.RefreshModel()
       
   508         self.RefreshView()
       
   509         event.Skip()