Adding support for giving keyboard focus to the first control of every dialogs
authorlaurent
Fri, 14 Oct 2011 19:26:29 +0200
changeset 577 9dbb79722fbc
parent 576 3f2024f30553
child 578 73138d14d88d
Adding support for giving keyboard focus to the first control of every dialogs
Adding support for using keyboard to edit informations displayed in Grid and in EditableListBox
DataTypeEditor.py
PLCOpenEditor.py
RessourceEditor.py
VariablePanel.py
controls/CustomEditableListBox.py
controls/CustomGrid.py
controls/__init__.py
dialogs/ActionBlockDialog.py
dialogs/ArrayTypeDialog.py
dialogs/ConnectionDialog.py
dialogs/DurationEditorDialog.py
dialogs/FBDBlockDialog.py
dialogs/FBDVariableDialog.py
dialogs/LDElementDialog.py
dialogs/LDPowerRailDialog.py
dialogs/SFCDivergenceDialog.py
dialogs/SFCStepDialog.py
dialogs/SFCTransitionDialog.py
dialogs/SearchInProjectDialog.py
--- a/DataTypeEditor.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/DataTypeEditor.py	Fri Oct 14 19:26:29 2011 +0200
@@ -24,9 +24,10 @@
 
 import wx
 import wx.grid
-import wx.gizmos
+
 from plcopen.structures import IEC_KEYWORDS, TestIdentifier
 from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD
+from controls import CustomEditableListBox, CustomGrid
 
 import re
 
@@ -187,6 +188,9 @@
     def AppendRow(self, row_content):
         self.data.append(row_content)
 
+    def InsertRow(self, row_index, row_content):
+        self.data.insert(row_index, row_content)
+
     def RemoveRow(self, row_index):
         self.data.pop(row_index)
 
@@ -194,9 +198,8 @@
         new_idx = max(0, min(idx + move, len(self.data) - 1))
         if new_idx != idx:
             self.data.insert(new_idx, self.data.pop(idx))
-            return new_idx
-        return None
-    
+        return new_idx
+        
     def GetRow(self, row_index):
         return self.data[row_index]
 
@@ -460,23 +463,11 @@
               name='EnumeratedPanel', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
 
-        self.EnumeratedValues = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORENUMERATEDVALUES, 
+        self.EnumeratedValues = CustomEditableListBox(id=ID_DATATYPEEDITORENUMERATEDVALUES, 
               name='EnumeratedValues', parent=self.EnumeratedPanel, label=_("Values:"), pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE)
-        self.EnumeratedValues.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEnumeratedValueEndEdit)
-        self.EnumeratedValues.GetEditButton().SetToolTipString(_("Edit item"))
-        new_button = self.EnumeratedValues.GetNewButton()
-        new_button.SetToolTipString(_("New item"))
-        new_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
-        del_button = self.EnumeratedValues.GetDelButton()
-        del_button.SetToolTipString(_("Delete item"))
-        del_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
-        up_button = self.EnumeratedValues.GetUpButton()
-        up_button.SetToolTipString(_("Move up"))
-        up_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
-        down_button = self.EnumeratedValues.GetDownButton()
-        down_button.SetToolTipString(_("Move down"))
-        down_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged)
+        for func in ["_OnAddButton", "_OnDelButton", "_OnUpButton", "_OnDownButton"]:
+            setattr(self.EnumeratedValues, func, self.OnEnumeratedValuesChanged)
         
         self.staticText8 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT8,
               label=_('Initial Value:'), name='staticText8', parent=self.EnumeratedPanel,
@@ -502,24 +493,13 @@
               size=wx.Size(0, 28), style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, id=ID_DATATYPEEDITORARRAYBASETYPE)
 
-        self.ArrayDimensions = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORARRAYDIMENSIONS, 
+        self.ArrayDimensions = CustomEditableListBox(id=ID_DATATYPEEDITORARRAYDIMENSIONS, 
               name='ArrayDimensions', parent=self.ArrayPanel, label=_("Dimensions:"), pos=wx.Point(0, 0),
               size=wx.Size(0, 24), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE)
         self.ArrayDimensions.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnDimensionsChanged)
-        self.ArrayDimensions.GetEditButton().SetToolTipString(_("Edit item"))
-        new_button = self.ArrayDimensions.GetNewButton()
-        new_button.SetToolTipString(_("New item"))
-        new_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        del_button = self.ArrayDimensions.GetDelButton()
-        del_button.SetToolTipString(_("Delete item"))
-        del_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        up_button = self.ArrayDimensions.GetUpButton()
-        up_button.SetToolTipString(_("Move up"))
-        up_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        down_button = self.ArrayDimensions.GetDownButton()
-        down_button.SetToolTipString(_("Move down"))
-        down_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-
+        for func in ["_OnAddButton", "_OnDelButton", "_OnUpButton", "_OnDownButton"]:
+            setattr(self.EnumeratedValues, func, self.OnDimensionsChanged)
+        
         self.staticText10 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT10,
               label=_('Initial Value:'), name='staticText10', parent=self.ArrayPanel,
               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
@@ -539,7 +519,7 @@
               label=_('Elements :'), name='staticText11', parent=self.StructurePanel,
               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
 
-        self.StructureElementsGrid = wx.grid.Grid(id=ID_DATATYPEEDITORSTRUCTUREELEMENTSGRID,
+        self.StructureElementsGrid = CustomGrid(id=ID_DATATYPEEDITORSTRUCTUREELEMENTSGRID,
               name='StructureElementsGrid', parent=self.StructurePanel, pos=wx.Point(0, 0), 
               size=wx.Size(0, 150), style=wx.VSCROLL)
         self.StructureElementsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
@@ -554,27 +534,23 @@
         else:
             wx.grid.EVT_GRID_CELL_CHANGE(self.StructureElementsGrid, self.OnStructureElementsGridCellChange)
             wx.grid.EVT_GRID_EDITOR_SHOWN(self.StructureElementsGrid, self.OnStructureElementsGridEditorShown)
-
+        
         self.StructureAddButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON, label=_('Add'),
               name='StructureAddButton', parent=self.StructurePanel, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnStructureAddButton, id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON)
-
+        
         self.StructureDeleteButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON, label=_('Delete'),
               name='StructureDeleteButton', parent=self.StructurePanel, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnStructureDeleteButton, id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON)
-
+        
         self.StructureUpButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREUPBUTTON, label='^',
               name='StructureUpButton', parent=self.StructurePanel, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnStructureUpButton, id=ID_DATATYPEEDITORSTRUCTUREUPBUTTON)
-
+        
         self.StructureDownButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDOWNBUTTON, label='v',
               name='StructureDownButton', parent=self.StructurePanel, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnStructureDownButton, id=ID_DATATYPEEDITORSTRUCTUREDOWNBUTTON)
-
+        
         self._init_sizers()
 
     def __init__(self, parent, tagname, window, controler):
@@ -586,6 +562,32 @@
         self.StructureColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
         
         self.StructureElementsGrid.SetTable(self.StructureElementsTable)
+        self.StructureElementsGrid.SetButtons({"Add": self.StructureAddButton,
+                                               "Delete": self.StructureDeleteButton,
+                                               "Up": self.StructureUpButton,
+                                               "Down": self.StructureDownButton})
+        
+        def _AddStructureElement(new_row):
+            self.StructureElementsTable.InsertRow(new_row, self.StructureElementDefaultValue.copy())
+            self.RefreshTypeInfos()
+            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+            return new_row
+        setattr(self.StructureElementsGrid, "_AddRow", _AddStructureElement)
+        
+        def _DeleteStructureElement(row):
+            self.StructureElementsTable.RemoveRow(row)
+            self.RefreshTypeInfos()
+            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+        setattr(self.StructureElementsGrid, "_DeleteRow", _DeleteStructureElement)
+            
+        def _MoveStructureElement(row, move):
+            new_row = self.StructureElementsTable.MoveRow(row, move)
+            if new_row != row:
+                self.RefreshTypeInfos()
+                self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+            return new_row
+        setattr(self.StructureElementsGrid, "_MoveRow", _MoveStructureElement)
+        
         self.StructureElementsGrid.SetRowLabelSize(0)
         for col in range(self.StructureElementsTable.GetNumberCols()):
             attr = wx.grid.GridCellAttr()
@@ -593,6 +595,7 @@
             self.StructureElementsGrid.SetColAttr(col, attr)
             self.StructureElementsGrid.SetColMinimalWidth(col, self.StructureColSizes[col])
             self.StructureElementsGrid.AutoSizeColumn(col, False)
+        self.StructureElementsGrid.RefreshButtons()
         
         for datatype in GetDatatypeTypes():
             self.DerivationType.Append(_(datatype))
@@ -690,6 +693,7 @@
             self.RefreshDisplayedInfos()
         self.ShowHighlights()
         self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+        self.StructureElementsGrid.RefreshButtons()
         self.Initializing = False
 
     def RefreshScaling(self, refresh=True):
@@ -758,38 +762,6 @@
         wx.CallAfter(self.RefreshTypeInfos)
         event.Skip()
     
-    def OnStructureAddButton(self, event):
-        new_row = self.StructureElementDefaultValue.copy()
-        self.StructureElementsTable.AppendRow(new_row)
-        self.RefreshTypeInfos()
-        self.StructureElementsTable.ResetView(self.StructureElementsGrid)
-        event.Skip()
-    
-    def OnStructureDeleteButton(self, event):
-        row = self.StructureElementsGrid.GetGridCursorRow()
-        self.StructureElementsTable.RemoveRow(row)
-        self.RefreshTypeInfos()
-        self.StructureElementsTable.ResetView(self.StructureElementsGrid)
-        event.Skip()
-    
-    def OnStructureUpButton(self, event):
-        row = self.StructureElementsGrid.GetGridCursorRow()
-        new_index = self.StructureElementsTable.MoveRow(row, -1)
-        if new_index is not None:
-            self.RefreshTypeInfos()
-            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
-            self.StructureElementsGrid.SetGridCursor(new_index, self.StructureElementsGrid.GetGridCursorCol())
-        event.Skip()
-    
-    def OnStructureDownButton(self, event):
-        row = self.StructureElementsGrid.GetGridCursorRow()
-        new_index = self.StructureElementsTable.MoveRow(row, 1)
-        if new_index is not None:
-            self.RefreshTypeInfos()
-            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
-            self.StructureElementsGrid.SetGridCursor(new_index, self.StructureElementsGrid.GetGridCursorCol())
-        event.Skip()
-
     def OnStructureElementsGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
         colname = self.StructureElementsTable.GetColLabelValue(col)
@@ -817,7 +789,7 @@
                 event.Veto()
             else:
                 self.RefreshTypeInfos()
-                self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+                wx.CallAfter(self.StructureElementsTable.ResetView, self.StructureElementsGrid)
 ##                old_value = self.Table.GetOldValue()
 ##                if old_value != "":
 ##                    self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value)
@@ -825,9 +797,13 @@
                 event.Skip()
         else:
             self.RefreshTypeInfos()
-            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+            wx.CallAfter(self.StructureElementsTable.ResetView, self.StructureElementsGrid)
             event.Skip()
     
+    def OnStructureElementsGridSelectCell(self, event):
+        wx.CallAfter(self.RefreshStructureButtons)
+        event.Skip()
+    
     def OnStructureElementsGridEditorShown(self, event):
         row, col = event.GetRow(), event.GetCol() 
         if self.StructureElementsTable.GetColLabelValue(col) == "Type":
--- a/PLCOpenEditor.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/PLCOpenEditor.py	Fri Oct 14 19:26:29 2011 +0200
@@ -115,6 +115,7 @@
 from PLCControler import *
 from VariablePanel import VariablePanel
 from SearchResultPanel import SearchResultPanel
+from controls import CustomGrid
 
 # Define PLCOpenEditor controls id
 [ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, 
@@ -181,10 +182,10 @@
              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, 
               ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", 
               "add_connection.png", _("Create a new connection"))],
-    "LD"  : [((True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+    "LD"  : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
               ID_PLCOPENEDITORTOOLBARMOTION, "OnMotionTool",
               "move.png", _("Move the view")),
-             True, FREEDRAWING_MODE, 
+             (True, FREEDRAWING_MODE, 
               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", 
               "add_comment.png", _("Create a new comment")),
              (True, FREEDRAWING_MODE, 
@@ -4192,7 +4193,7 @@
               name='DebugVariablePanel', parent=prnt, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
 
-        self.VariablesGrid = wx.grid.Grid(id=ID_DEBUGVARIABLEPANELVARIABLESGRID,
+        self.VariablesGrid = CustomGrid(id=ID_DEBUGVARIABLEPANELVARIABLESGRID,
               name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
               size=wx.Size(0, 150), style=wx.VSCROLL)
         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
@@ -4203,26 +4204,21 @@
         self.VariablesGrid.SetSelectionForeground(wx.BLACK)
         self.VariablesGrid.SetDropTarget(DebugVariableDropTarget(self))
         if wx.VERSION >= (2, 6, 0):
-            self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridCellSelect)
             self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.OnVariablesGridCellRightClick)
         else:
-            wx.grid.EVT_GRID_SELECT_CELL(self.VariablesGrid, self.OnVariablesGridCellSelect)
             wx.grid.EVT_GRID_CELL_RIGHT_CLICK(self.VariablesGrid, self.OnVariablesGridCellRightClick)
         
         self.UpButton = wx.Button(id=ID_DEBUGVARIABLEPANELUPBUTTON, label='^',
               name='UpButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_DEBUGVARIABLEPANELUPBUTTON)
         
         self.DownButton = wx.Button(id=ID_DEBUGVARIABLEPANELDOWNBUTTON, label='v',
               name='DownButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DEBUGVARIABLEPANELDOWNBUTTON)
         
         self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label=_('Delete'),
               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DEBUGVARIABLEPANELDELETEBUTTON)
         
         self._init_sizers()
     
@@ -4233,6 +4229,29 @@
         
         self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames())
         self.VariablesGrid.SetTable(self.Table)
+        self.VariablesGrid.SetButtons({"Delete": self.DeleteButton,
+                                       "Up": self.UpButton,
+                                       "Down": self.DownButton})
+        
+        def _AddVariable(new_row):
+            return self.VariablesGrid.GetGridCursorRow()
+        setattr(self.VariablesGrid, "_AddRow", _AddVariable)
+        
+        def _DeleteVariable(row):
+            item = self.Table.GetItem(row)
+            self.RemoveDataConsumer(item)
+            self.Table.RemoveItem(row)
+            self.RefreshGrid()
+        setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
+        
+        def _MoveVariable(row, move):
+            new_row = max(0, min(row + move, self.Table.GetNumberRows() - 1))
+            if new_row != row:
+                self.Table.MoveItem(row, new_row)
+                self.RefreshGrid()
+            return new_row
+        setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
+        
         self.VariablesGrid.SetRowLabelSize(0)
         
         for col in range(self.Table.GetNumberCols()):
@@ -4242,7 +4261,7 @@
             self.VariablesGrid.SetColSize(col, 100)
         
         self.Table.ResetView(self.VariablesGrid)
-        self.RefreshButtons()
+        self.VariablesGrid.RefreshButtons()
     
     def RefreshNewData(self):
         if self.HasNewData:
@@ -4253,6 +4272,7 @@
     def RefreshGrid(self):
         self.Freeze()
         self.Table.ResetView(self.VariablesGrid)
+        self.VariablesGrid.RefreshButtons()
         self.Thaw()
     
     def ResetGrid(self):
@@ -4260,6 +4280,7 @@
         self.Table.Empty()
         self.Freeze()
         self.Table.ResetView(self.VariablesGrid)
+        self.VariablesGrid.RefreshButtons()
         self.Thaw()
     
     def GetForceVariableMenuFunction(self, iec_path, item):
@@ -4276,10 +4297,6 @@
             self.ReleaseDataValue(iec_path)
         return ReleaseVariableFunction
     
-    def OnVariablesGridCellSelect(self, event):
-        wx.CallAfter(self.RefreshButtons)
-        event.Skip()
-    
     def OnVariablesGridCellRightClick(self, event):
         row, col = event.GetRow(), event.GetCol()
         if self.Table.GetColLabelValue(col, False) == "Value":
@@ -4299,34 +4316,6 @@
             self.PopupMenu(menu)
         event.Skip()
     
-    def RefreshButtons(self):
-        if getattr(self, "Table", None):
-            table_length = len(self.Table.data)
-            row = 0
-            if table_length > 0:
-                row = self.VariablesGrid.GetGridCursorRow()
-            self.DeleteButton.Enable(table_length > 0)
-            self.UpButton.Enable(table_length > 0 and row > 0)
-            self.DownButton.Enable(table_length > 0 and row < table_length - 1)
-    
-    def OnDeleteButton(self, event):
-        idx = self.VariablesGrid.GetGridCursorRow()
-        if idx >= 0:
-            item = self.Table.GetItem(idx)
-            self.RemoveDataConsumer(item)
-            self.Table.RemoveItem(idx)
-            self.RefreshGrid()
-            self.RefreshButtons()
-        event.Skip()
-
-    def OnUpButton(self, event):
-        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
-        event.Skip()
-
-    def OnDownButton(self, event):
-        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
-        event.Skip()
-
     def InsertValue(self, iec_path, idx = None):
         if idx is None:
             idx = self.Table.GetNumberRows()
@@ -4338,16 +4327,8 @@
         if result is not None:
             self.Table.InsertItem(idx, item)
             self.RefreshGrid()
-            self.RefreshButtons()
-
-    def MoveValue(self, idx, move):
-        new_idx = max(0, min(idx + move, self.Table.GetNumberRows() - 1))
-        if new_idx != idx:
-            self.Table.MoveItem(idx, new_idx)
-            self.RefreshGrid()
-            self.VariablesGrid.SetGridCursor(new_idx, self.VariablesGrid.GetGridCursorCol())
-            self.RefreshButtons()
-            
+
+        
 #-------------------------------------------------------------------------------
 #                               Viewer Printout
 #-------------------------------------------------------------------------------
--- a/RessourceEditor.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/RessourceEditor.py	Fri Oct 14 19:26:29 2011 +0200
@@ -26,6 +26,7 @@
 import wx.grid
 
 from dialogs import DurationEditorDialog
+from controls import CustomGrid
 
 #-------------------------------------------------------------------------------
 #                          Configuration Editor class
@@ -279,27 +280,20 @@
         new_index = max(0, min(row_index + move, len(self.data) - 1))
         if new_index != row_index:
             self.data.insert(new_index, self.data.pop(row_index))
-            return new_index
-        return None
-
+        return new_index
+        
     def Empty(self):
         self.data = []
-        self.editors = []
-
+    
 #-------------------------------------------------------------------------------
 #                        Highlights showing functions
 #-------------------------------------------------------------------------------
 
-    def OnRefreshHighlightsTimer(self, event):
-        self.Table.ResetView(self.VariablesGrid)
-        event.Skip()
-
     def AddHighlight(self, infos, highlight_type):
         row_highlights = self.Highlights.setdefault(infos[0], {})
         col_highlights = row_highlights.setdefault(infos[1], [])
         col_highlights.append(highlight_type)
-        self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-
+    
     def ClearHighlights(self, highlight_type=None):
         if highlight_type is None:
             self.Highlights = {}
@@ -405,14 +399,14 @@
               label=_(u'Tasks:'), name='staticText2', parent=self, pos=wx.Point(0,
               0), size=wx.DefaultSize, style=wx.ALIGN_CENTER)
 
-        self.TasksGrid = wx.grid.Grid(id=ID_RESOURCEEDITORTASKSGRID,
+        self.TasksGrid = CustomGrid(id=ID_RESOURCEEDITORTASKSGRID,
               name='TasksGrid', parent=self, pos=wx.Point(0, 0), 
               size=wx.Size(-1, -1), style=wx.VSCROLL)
         self.TasksGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
               'Sans'))
         self.TasksGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
               False, 'Sans'))
-        if wx.VERSION >= (2, 5, 0):
+        if wx.VERSION >= (2, 6, 0):
             self.TasksGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnTasksGridCellChange)
         else:
             wx.grid.EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange)
@@ -420,35 +414,31 @@
         self.AddTaskButton = wx.Button(id=ID_RESOURCEEDITORADDTASKBUTTON, label=_('Add Task'),
               name='AddTaskButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnAddTaskButton, id=ID_RESOURCEEDITORADDTASKBUTTON)
-
+        
         self.DeleteTaskButton = wx.Button(id=ID_RESOURCEEDITORDELETETASKBUTTON, label=_('Delete Task'),
               name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDeleteTaskButton, id=ID_RESOURCEEDITORDELETETASKBUTTON)
-
+        
         self.UpTaskButton = wx.Button(id=ID_RESOURCEEDITORUPTASKBUTTON, label='^',
               name='UpTaskButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnUpTaskButton, id=ID_RESOURCEEDITORUPTASKBUTTON)
-
+        
         self.DownTaskButton = wx.Button(id=ID_RESOURCEEDITORDOWNTASKBUTTON, label='v',
               name='DownTaskButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDownTaskButton, id=ID_RESOURCEEDITORDOWNTASKBUTTON)
-
+        
         self.staticText2 = wx.StaticText(id=ID_RESOURCEEDITORSTATICTEXT2,
               label=_(u'Instances:'), name='staticText1', parent=self,
               pos=wx.Point(0, 0), size=wx.DefaultSize, style=wx.ALIGN_CENTER)
 
-        self.InstancesGrid = wx.grid.Grid(id=ID_RESOURCEEDITORINSTANCESGRID,
+        self.InstancesGrid = CustomGrid(id=ID_RESOURCEEDITORINSTANCESGRID,
               name='InstancesGrid', parent=self, pos=wx.Point(0, 0), 
               size=wx.Size(-1, -1), style=wx.VSCROLL)
         self.InstancesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
               'Sans'))
         self.InstancesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
               False, 'Sans'))
-        if wx.VERSION >= (2, 5, 0):
+        if wx.VERSION >= (2, 6, 0):
             self.InstancesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnInstancesGridCellChange)
         else:
             wx.grid.EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange)
@@ -456,23 +446,19 @@
         self.AddInstanceButton = wx.Button(id=ID_RESOURCEEDITORADDINSTANCEBUTTON, label=_('Add Instance'),
               name='AddInstanceButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnAddInstanceButton, id=ID_RESOURCEEDITORADDINSTANCEBUTTON)
-
+        
         self.DeleteInstanceButton = wx.Button(id=ID_RESOURCEEDITORDELETEINSTANCEBUTTON, label=_('Delete Instance'),
               name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDeleteInstanceButton, id=ID_RESOURCEEDITORDELETEINSTANCEBUTTON)
-
+        
         self.UpInstanceButton = wx.Button(id=ID_RESOURCEEDITORUPINSTANCEBUTTON, label='^',
               name='UpInstanceButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnUpInstanceButton, id=ID_RESOURCEEDITORUPINSTANCEBUTTON)
-
+        
         self.DownInstanceButton = wx.Button(id=ID_RESOURCEEDITORDOWNINSTANCEBUTTON, label='v',
               name='DownInstanceButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDownInstanceButton, id=ID_RESOURCEEDITORDOWNINSTANCEBUTTON)
-
+        
         self._init_sizers()
 
     def __init__(self, parent, tagname, window, controler):
@@ -490,17 +476,86 @@
         self.TasksTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT])
         self.TasksTable.SetColSizes([200, 100, 100, 150, 100])
         self.TasksGrid.SetTable(self.TasksTable)
+        self.TasksGrid.SetButtons({"Add": self.AddTaskButton,
+                                   "Delete": self.DeleteTaskButton,
+                                   "Up": self.UpTaskButton,
+                                   "Down": self.DownTaskButton})
+        
+        def _AddTask(new_row):
+            self.TasksTable.InsertRow(new_row, self.TasksDefaultValue.copy())
+            self.RefreshModel()
+            self.RefreshView()
+            return new_row
+        setattr(self.TasksGrid, "_AddRow", _AddTask)
+        
+        def _DeleteTask(row):
+            self.TasksTable.RemoveRow(row)
+            self.RefreshModel()
+            self.RefreshView()
+        setattr(self.TasksGrid, "_DeleteRow", _DeleteTask)
+        
+        def _MoveTask(row, move):
+            new_row = self.TasksTable.MoveRow(row, move)
+            if new_row != row:
+                self.RefreshModel()
+                self.RefreshView()
+            return new_row
+        setattr(self.TasksGrid, "_MoveRow", _MoveTask)
+        
         self.TasksGrid.SetRowLabelSize(0)
         self.TasksTable.ResetView(self.TasksGrid)
-
+        self.TasksGrid.RefreshButtons()
+        
         self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""}
         self.InstancesTable = ResourceTable(self, [], GetInstancesTableColnames())
         self.InstancesTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT])
         self.InstancesTable.SetColSizes([200, 150, 150])
         self.InstancesGrid.SetTable(self.InstancesTable)
+        self.InstancesGrid.SetButtons({"Add": self.AddInstanceButton,
+                                       "Delete": self.DeleteInstanceButton,
+                                       "Up": self.UpInstanceButton,
+                                       "Down": self.DownInstanceButton})
+        
+        def _AddInstance(new_row):
+            self.InstancesTable.InsertRow(new_row, self.InstancesDefaultValue.copy())
+            self.RefreshModel()
+            self.RefreshView()
+            return new_row
+        setattr(self.InstancesGrid, "_AddRow", _AddInstance)
+        
+        def _DeleteInstance(row):
+            self.InstancesTable.RemoveRow(row)
+            self.RefreshModel()
+            self.RefreshView()
+        setattr(self.InstancesGrid, "_DeleteRow", _DeleteInstance)
+        
+        def _MoveInstance(row, move):
+            new_row = max(0, min(row + move, self.InstancesTable.GetNumberRows() - 1))
+            if new_row != row:
+                if self.InstancesTable.GetValueByName(row, "Task") != self.InstancesTable.GetValueByName(new_row, "Task"):
+                    return row 
+                self.InstancesTable.MoveRow(row, move)
+                self.RefreshModel()
+                self.RefreshView()
+            return new_row
+        setattr(self.InstancesGrid, "_MoveRow", _MoveInstance)
+        
+        def _RefreshInstanceButtons():
+            rows = self.InstancesTable.GetNumberRows()
+            row = self.InstancesGrid.GetGridCursorRow()
+            self.DeleteInstanceButton.Enable(rows > 0)
+            self.UpInstanceButton.Enable(row > 0 and 
+                self.InstancesTable.GetValueByName(row, "Task") == self.InstancesTable.GetValueByName(row - 1, "Task"))
+            self.DownInstanceButton.Enable(0 <= row < rows - 1 and 
+                self.InstancesTable.GetValueByName(row, "Task") == self.InstancesTable.GetValueByName(row + 1, "Task"))
+        setattr(self.InstancesGrid, "RefreshButtons", _RefreshInstanceButtons)
+        
         self.InstancesGrid.SetRowLabelSize(0)
         self.InstancesTable.ResetView(self.InstancesGrid)
-
+        self.InstancesGrid.RefreshButtons()
+        
+        self.TasksGrid.SetFocus()
+        
     def __del__(self):
         self.RefreshHighlightsTimer.Stop()
 
@@ -549,7 +604,7 @@
         self.ParentWindow.RefreshFileMenu()
         self.ParentWindow.RefreshEditMenu()
 
-    def RefreshView(self, task_select=None, instance_select=None):
+    def RefreshView(self):
         tasks, instances = self.Controler.GetEditedResourceInfos(self.TagName)
         self.TasksTable.SetData(tasks)
         self.InstancesTable.SetData(instances)
@@ -558,112 +613,12 @@
         self.RefreshVariableList()
         self.TasksTable.ResetView(self.TasksGrid)
         self.InstancesTable.ResetView(self.InstancesGrid)
-        if task_select is not None and len(tasks) > 0:
-            if task_select == -1:
-                task_select = len(tasks) - 1
-            else:
-                task_select = min(task_select, len(tasks) - 1)
-            col = self.TasksGrid.GetGridCursorCol()
-            self.TasksGrid.SetGridCursor(task_select, col)
-            self.TasksGrid.MakeCellVisible(task_select, col)
-            self.TasksGrid.SetFocus()
-        if instance_select is not None and len(instances) > 0:
-            if instance_select == -1:
-                instance_select = len(instances) - 1
-            else:
-                instance_select = min(instance_select, len(instances) - 1)
-            col = self.InstancesGrid.GetGridCursorCol()
-            self.InstancesGrid.SetGridCursor(instance_select, col)
-            self.InstancesGrid.MakeCellVisible(instance_select, col)
-            self.InstancesGrid.SetFocus()
+        self.TasksGrid.RefreshButtons()
+        self.InstancesGrid.RefreshButtons()
         
     def RefreshScaling(self, refresh=True):
         pass
-
-    def CloseTasksGridEditControl(self):
-        row = self.TasksGrid.GetGridCursorRow()
-        col = self.TasksGrid.GetGridCursorCol()
-        self.TasksGrid.SetGridCursor(row, col)
-
-    def OnAddTaskButton(self, event):
-        self.CloseTasksGridEditControl()
-        if len(self.TasksTable.data) > 0:
-            row = self.TasksGrid.GetGridCursorRow() + 1
-        else:
-            row = -1
-        self.TasksTable.InsertRow(row, self.TasksDefaultValue.copy())
-        self.RefreshModel()
-        self.RefreshView(task_select=row)
-        event.Skip()
-
-    def OnDeleteTaskButton(self, event):
-        self.CloseTasksGridEditControl()
-        row = self.TasksGrid.GetGridCursorRow()
-        self.TasksTable.RemoveRow(row)
-        self.RefreshModel()
-        self.RefreshView(task_select=row)
-        event.Skip()
-
-    def OnUpTaskButton(self, event):
-        self.CloseTasksGridEditControl()
-        row = self.TasksGrid.GetGridCursorRow()
-        new_row = self.TasksTable.MoveRow(row, -1)
-        self.RefreshModel()
-        self.RefreshView(task_select=new_row)
-        event.Skip()
-
-    def OnDownTaskButton(self, event):
-        self.CloseTasksGridEditControl()
-        row = self.TasksGrid.GetGridCursorRow()
-        new_row = self.TasksTable.MoveRow(row, 1)
-        self.RefreshModel()
-        self.RefreshView(task_select=new_row)
-        event.Skip()
-
-    def CloseInstancesGridEditControl(self):
-        row = self.InstancesGrid.GetGridCursorRow()
-        col = self.InstancesGrid.GetGridCursorCol()
-        self.InstancesGrid.SetGridCursor(row, col)
-
-    def OnAddInstanceButton(self, event):
-        self.CloseInstancesGridEditControl()
-        if len(self.InstancesTable.data) > 0:
-            row = self.InstancesGrid.GetGridCursorRow() + 1
-        else:
-            row = -1
-        self.InstancesTable.InsertRow(row, self.InstancesDefaultValue.copy())
-        self.RefreshModel()
-        self.RefreshView(instance_select=row)
-        self.ParentWindow.RefreshInstancesTree()
-        event.Skip()
-
-    def OnDeleteInstanceButton(self, event):
-        self.CloseInstancesGridEditControl()
-        row = self.InstancesGrid.GetGridCursorRow()
-        self.InstancesTable.RemoveRow(row)
-        self.RefreshModel()
-        self.RefreshView(instance_select=row)
-        self.ParentWindow.RefreshInstancesTree()
-        event.Skip()
-
-    def OnUpInstanceButton(self, event):
-        self.CloseInstancesGridEditControl()
-        row = self.InstancesGrid.GetGridCursorRow()
-        new_row = self.InstancesTable.MoveRow(row, -1)
-        self.RefreshModel()
-        self.RefreshView(instance_select=new_row)
-        self.ParentWindow.RefreshInstancesTree()
-        event.Skip()
-
-    def OnDownInstanceButton(self, event):
-        self.CloseInstancesGridEditControl()
-        row = self.InstancesGrid.GetGridCursorRow()
-        new_row = self.InstancesTable.MoveRow(row, 1)
-        self.RefreshModel()
-        self.RefreshView(instance_select=new_row)
-        self.ParentWindow.RefreshInstancesTree()
-        event.Skip()
-
+    
     def OnTasksGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
         if self.TasksTable.GetColLabelValue(event.GetCol()) == "Name":
@@ -688,6 +643,7 @@
     def OnInstancesGridCellChange(self, event):
         self.RefreshModel()
         self.ParentWindow.RefreshInstancesTree()
+        self.InstancesGrid.RefreshButtons()
         event.Skip()
 
 #-------------------------------------------------------------------------------
--- a/VariablePanel.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/VariablePanel.py	Fri Oct 14 19:26:29 2011 +0200
@@ -31,6 +31,7 @@
 from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
 from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD
 from dialogs import ArrayTypeDialog
+from controls import CustomGrid
 
 CWD = os.path.split(os.path.realpath(__file__))[0]
 
@@ -461,7 +462,7 @@
               name='VariableEditorPanel', parent=prnt, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
 
-        self.VariablesGrid = wx.grid.Grid(id=ID_VARIABLEEDITORPANELVARIABLESGRID,
+        self.VariablesGrid = CustomGrid(id=ID_VARIABLEEDITORPANELVARIABLESGRID,
               name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
               size=wx.Size(0, 0), style=wx.VSCROLL)
         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
@@ -472,17 +473,12 @@
         self.VariablesGrid.SetSelectionForeground(wx.BLACK)
         if wx.VERSION >= (2, 6, 0):
             self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
-            self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
             self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
             self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown)
-            #self.VariablesGrid.Bind(wx.EVT_KEY_DOWN, self.OnChar)
         else:
             wx.grid.EVT_GRID_CELL_CHANGE(self.VariablesGrid, self.OnVariablesGridCellChange)
-            wx.grid.EVT_GRID_SELECT_CELL(self.VariablesGrid, self.OnVariablesGridSelectCell)
             wx.grid.EVT_GRID_CELL_LEFT_CLICK(self.VariablesGrid, self.OnVariablesGridCellLeftClick)
             wx.grid.EVT_GRID_EDITOR_SHOWN(self.VariablesGrid, self.OnVariablesGridEditorShown)
-            #wx.EVT_KEY_DOWN(self.VariablesGrid, self.OnChar)
-        self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
         
         self.ControlPanel = wx.ScrolledWindow(id=ID_VARIABLEEDITORCONTROLPANEL,
               name='ControlPanel', parent=self, pos=wx.Point(0, 0),
@@ -510,23 +506,19 @@
         self.AddButton = wx.Button(id=ID_VARIABLEEDITORPANELADDBUTTON, label=_('Add'),
               name='AddButton', parent=self.ControlPanel, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_VARIABLEEDITORPANELADDBUTTON)
-
+        
         self.DeleteButton = wx.Button(id=ID_VARIABLEEDITORPANELDELETEBUTTON, label=_('Delete'),
               name='DeleteButton', parent=self.ControlPanel, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_VARIABLEEDITORPANELDELETEBUTTON)
-
+        
         self.UpButton = wx.Button(id=ID_VARIABLEEDITORPANELUPBUTTON, label='^',
               name='UpButton', parent=self.ControlPanel, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_VARIABLEEDITORPANELUPBUTTON)
-
+        
         self.DownButton = wx.Button(id=ID_VARIABLEEDITORPANELDOWNBUTTON, label='v',
               name='DownButton', parent=self.ControlPanel, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_VARIABLEEDITORPANELDOWNBUTTON)
-
+        
         self._init_sizers()
 
     def __init__(self, parent, window, controler, element_type):
@@ -603,91 +595,50 @@
         self.RefreshTypeList()
 
         self.VariablesGrid.SetTable(self.Table)
-        self.VariablesGrid.SetRowLabelSize(0)
-        for col in range(self.Table.GetNumberCols()):
-            attr = wx.grid.GridCellAttr()
-            attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
-            self.VariablesGrid.SetColAttr(col, attr)
-            self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col])
-            self.VariablesGrid.AutoSizeColumn(col, False)
-    
-    def __del__(self):
-        self.RefreshHighlightsTimer.Stop()
-    
-    def SetTagName(self, tagname):
-        self.TagName = tagname
-    
-    def IsFunctionBlockType(self, name):
-        bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
-        pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
-        if poutype != "function" and bodytype in ["ST", "IL"]:
-            return False
-        else:
-            return name in self.Controler.GetFunctionBlockTypes(self.TagName)
-    
-    def RefreshView(self):
-        self.PouNames = self.Controler.GetProjectPouNames()
-        
-        words = self.TagName.split("::")
-        if self.ElementType == "config":
-            self.PouIsUsed = False
-            returnType = None
-            self.Values = self.Controler.GetConfigurationGlobalVars(words[1])
-        elif self.ElementType == "resource":
-            self.PouIsUsed = False
-            returnType = None
-            self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2])
-        else:
-            if self.ElementType == "function":
-                self.ReturnType.Clear()
-                for base_type in self.Controler.GetDataTypes(self.TagName, True):
-                    self.ReturnType.Append(base_type)
-                returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
-            else:
-                returnType = None
-            self.PouIsUsed = self.Controler.PouIsUsed(words[1])
-            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName)
-        
-        if returnType is not None:
-            self.ReturnType.SetStringSelection(returnType)
-            self.ReturnType.Enable(True)
-            self.staticText1.Show()
-            self.ReturnType.Show()
-        else:
-            self.ReturnType.Enable(False)
-            self.staticText1.Hide()
-            self.ReturnType.Hide()
-        
-        self.RefreshValues()
-        self.RefreshButtons()
-    
-    def OnReturnTypeChanged(self, event):
-        words = self.TagName.split("::")
-        self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection())
-        self.Controler.BufferProject()
-        self.ParentWindow.RefreshEditor(variablepanel = False)
-        self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
-        event.Skip()
-    
-    def OnClassFilter(self, event):
-        self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]]
-        self.RefreshTypeList()
-        self.RefreshValues()
-        self.RefreshButtons()
-        event.Skip()
-
-    def RefreshTypeList(self):
-        if self.Filter == "All":
-            self.ClassList = [self.FilterChoiceTransfer[choice] for choice in self.FilterChoices if self.FilterChoiceTransfer[choice] not in ["All","Interface","Variables"]]
-        elif self.Filter == "Interface":
-            self.ClassList = ["Input","Output","InOut","External"]
-        elif self.Filter == "Variables":
-            self.ClassList = ["Local","Temp"]
-        else:
-            self.ClassList = [self.Filter]
-
-    def RefreshButtons(self):
-        if getattr(self, "Table", None):
+        self.VariablesGrid.SetButtons({"Add": self.AddButton,
+                                       "Delete": self.DeleteButton,
+                                       "Up": self.UpButton,
+                                       "Down": self.DownButton})
+        
+        def _AddVariable(new_row):
+            if not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"]:
+                row_content = self.DefaultValue.copy()
+                if self.Filter in self.DefaultTypes:
+                    row_content["Class"] = self.DefaultTypes[self.Filter]
+                else:
+                    row_content["Class"] = self.Filter
+                if self.Filter == "All" and len(self.Values) > 0:
+                    self.Values.insert(new_row, row_content)
+                else:
+                    self.Values.append(row_content)
+                    new_row = self.Table.GetNumberRows()
+                self.SaveValues()
+                self.RefreshValues()
+                return new_row
+            return self.VariablesGrid.GetGridCursorRow()
+        setattr(self.VariablesGrid, "_AddRow", _AddVariable)
+        
+        def _DeleteVariable(row):
+            if (self.Table.GetValueByName(row, "Edit") and 
+                (not self.PouIsUsed or self.Table.GetValueByName(row, "Class") not in ["Input", "Output", "InOut"])):
+                self.Values.remove(self.Table.GetRow(row))
+                self.SaveValues()
+                self.RefreshValues()
+        setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
+            
+        def _MoveVariable(row, move):
+            if (self.Filter == "All" and 
+                (not self.PouIsUsed or self.Table.GetValueByName(row, "Class") not in ["Input", "Output", "InOut"])):
+                new_row = max(0, min(row + move, len(self.Values) - 1))
+                if new_row != row:
+                    self.Values.insert(new_row, self.Values.pop(row))
+                    self.SaveValues()
+                    self.RefreshValues()
+                return new_row
+            return row
+        setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
+        
+        def _RefreshButtons():
             table_length = len(self.Table.data)
             row_class = None
             row_edit = True
@@ -701,50 +652,90 @@
             self.DeleteButton.Enable(table_length > 0 and row_edit and row_class not in ["Input", "Output", "InOut"])
             self.UpButton.Enable(table_length > 0 and row > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
             self.DownButton.Enable(table_length > 0 and row < table_length - 1 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
-
-    def CloseVariablesGridEditControl(self):
-        row = self.VariablesGrid.GetGridCursorRow()
-        col = self.VariablesGrid.GetGridCursorCol()
-        self.VariablesGrid.SetGridCursor(row, col)
-
-    def OnAddButton(self, event):
-        self.CloseVariablesGridEditControl()
-        new_row = self.DefaultValue.copy()
-        if self.Filter in self.DefaultTypes:
-            new_row["Class"] = self.DefaultTypes[self.Filter]
-        else:
-            new_row["Class"] = self.Filter
-        if self.Filter == "All" and len(self.Values) > 0:
-            row_index = self.VariablesGrid.GetGridCursorRow() + 1
-            self.Values.insert(row_index, new_row)
-        else:
-            row_index = -1
-            self.Values.append(new_row)
-        self.SaveValues()
-        self.RefreshValues(row_index)
-        self.RefreshButtons()
+        setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons)
+        
+        self.VariablesGrid.SetRowLabelSize(0)
+        for col in range(self.Table.GetNumberCols()):
+            attr = wx.grid.GridCellAttr()
+            attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
+            self.VariablesGrid.SetColAttr(col, attr)
+            self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col])
+            self.VariablesGrid.AutoSizeColumn(col, False)
+    
+    def __del__(self):
+        self.RefreshHighlightsTimer.Stop()
+    
+    def SetTagName(self, tagname):
+        self.TagName = tagname
+    
+    def IsFunctionBlockType(self, name):
+        bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
+        pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
+        if poutype != "function" and bodytype in ["ST", "IL"]:
+            return False
+        else:
+            return name in self.Controler.GetFunctionBlockTypes(self.TagName)
+    
+    def RefreshView(self):
+        self.PouNames = self.Controler.GetProjectPouNames()
+        
+        words = self.TagName.split("::")
+        if self.ElementType == "config":
+            self.PouIsUsed = False
+            returnType = None
+            self.Values = self.Controler.GetConfigurationGlobalVars(words[1])
+        elif self.ElementType == "resource":
+            self.PouIsUsed = False
+            returnType = None
+            self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2])
+        else:
+            if self.ElementType == "function":
+                self.ReturnType.Clear()
+                for base_type in self.Controler.GetDataTypes(self.TagName, True):
+                    self.ReturnType.Append(base_type)
+                returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+            else:
+                returnType = None
+            self.PouIsUsed = self.Controler.PouIsUsed(words[1])
+            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        
+        if returnType is not None:
+            self.ReturnType.SetStringSelection(returnType)
+            self.ReturnType.Enable(True)
+            self.staticText1.Show()
+            self.ReturnType.Show()
+        else:
+            self.ReturnType.Enable(False)
+            self.staticText1.Hide()
+            self.ReturnType.Hide()
+        
+        self.RefreshValues()
+        self.VariablesGrid.RefreshButtons()
+    
+    def OnReturnTypeChanged(self, event):
+        words = self.TagName.split("::")
+        self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection())
+        self.Controler.BufferProject()
+        self.ParentWindow.RefreshEditor(variablepanel = False)
+        self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
         event.Skip()
-
-    def OnDeleteButton(self, event):
-        self.CloseVariablesGridEditControl()
-        row_index = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
-        self.Values.remove(row_index)
-        self.SaveValues()
-        self.RefreshValues(row_index)
-        self.RefreshButtons()
+    
+    def OnClassFilter(self, event):
+        self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]]
+        self.RefreshTypeList()
+        self.RefreshValues()
+        self.VariablesGrid.RefreshButtons()
         event.Skip()
 
-    def OnUpButton(self, event):
-        self.CloseVariablesGridEditControl()
-        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
-        self.RefreshButtons()
-        event.Skip()
-
-    def OnDownButton(self, event):
-        self.CloseVariablesGridEditControl()
-        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
-        self.RefreshButtons()
-        event.Skip()
+    def RefreshTypeList(self):
+        if self.Filter == "All":
+            self.ClassList = [self.FilterChoiceTransfer[choice] for choice in self.FilterChoices if self.FilterChoiceTransfer[choice] not in ["All","Interface","Variables"]]
+        elif self.Filter == "Interface":
+            self.ClassList = ["Input","Output","InOut","External"]
+        elif self.Filter == "Variables":
+            self.ClassList = ["Local","Temp"]
+        else:
+            self.ClassList = [self.Filter]
 
     def OnVariablesGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
@@ -883,29 +874,7 @@
             dragSource.DoDragDrop()
         event.Skip()
     
-    def OnVariablesGridSelectCell(self, event):
-        wx.CallAfter(self.RefreshButtons)
-        event.Skip()
-
-    def OnChar(self, event):
-        keycode = event.GetKeyCode()
-        if keycode == wx.WXK_DELETE:
-            row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
-            self.Values.remove(row)
-            self.SaveValues()
-            self.RefreshValues()
-            self.RefreshButtons()
-        event.Skip()
-
-    def MoveValue(self, value_index, move):
-        new_index = max(0, min(value_index + move, len(self.Values) - 1))
-        if new_index != value_index:
-            self.Values.insert(new_index, self.Values.pop(value_index))
-            self.SaveValues()
-            self.RefreshValues()
-            self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
-        
-    def RefreshValues(self, select=0):
+    def RefreshValues(self):
         data = []
         for num, variable in enumerate(self.Values):
             if variable["Class"] in self.ClassList:
@@ -913,16 +882,7 @@
                 data.append(variable)
         self.Table.SetData(data)
         self.Table.ResetView(self.VariablesGrid)
-        if len(self.Table.data) > 0:
-            if select == -1:
-                select = len(self.Table.data) - 1
-            else:
-                select = min(select, len(self.Table.data) - 1)
-            col = max(1, self.VariablesGrid.GetGridCursorCol())
-            self.VariablesGrid.SetGridCursor(select, col)
-            self.VariablesGrid.MakeCellVisible(select, col)
-            self.VariablesGrid.SetFocus()
-        
+            
     def SaveValues(self, buffer = True):
         words = self.TagName.split("::")
         if self.ElementType == "config":
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/CustomEditableListBox.py	Fri Oct 14 19:26:29 2011 +0200
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard. 
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+import wx
+import wx.gizmos
+
+class CustomEditableListBox(wx.gizmos.EditableListBox):
+    
+    def __init__(self, *args, **kwargs):
+        wx.gizmos.EditableListBox.__init__(self, *args, **kwargs)
+        
+        self.GetListCtrl().Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        
+        for button, tooltip, call_function in [(self.GetEditButton(), _("Edit item"), "_OnEditButton"),
+                                               (self.GetNewButton(), _("New item"), "_OnNewButton"),
+                                               (self.GetDelButton(), _("Delete item"), "_OnDelButton"),
+                                               (self.GetUpButton(), _("Move up"), "_OnUpButton"),
+                                               (self.GetDownButton(), _("Move down"), "_OnDownButton")]:
+            button.SetToolTipString(tooltip)
+            button.Bind(wx.EVT_BUTTON, self.GetButtonPressedFunction(call_function))
+    
+    def EnsureCurrentItemVisible(self):
+        listctrl = self.GetListCtrl()
+        listctrl.EnsureVisible(listctrl.GetFocusedItem())
+    
+    def GetButtonPressedFunction(self, call_function):
+        def OnButtonPressed(event):
+            func = getattr(self, call_function, None)
+            if func is not None:
+                wx.CallAfter(func, event)
+            wx.CallAfter(self.EnsureCurrentItemVisible)
+            event.Skip()
+        return OnButtonPressed
+    
+    def OnKeyDown(self, event):
+        button = None
+        keycode = event.GetKeyCode()
+        if keycode in (wx.WXK_ADD, wx.WXK_NUMPAD_ADD):
+            button = self.GetNewButton()
+        elif keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE):
+            button = self.GetDelButton()
+        elif keycode == wx.WXK_UP and event.ShiftDown():
+            button = self.GetUpButton()
+        elif keycode == wx.WXK_DOWN and event.ShiftDown():
+            button = self.GetDownButton()
+        elif keycode == wx.WXK_SPACE:
+            button = self.GetEditButton()
+        if button is not None and button.IsEnabled():
+            button.ProcessEvent(wx.CommandEvent(wx.EVT_BUTTON.typeId, button.GetId()))
+        else:
+            event.Skip()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/CustomGrid.py	Fri Oct 14 19:26:29 2011 +0200
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard. 
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+import wx
+import wx.grid
+
+class CustomGrid(wx.grid.Grid):
+    
+    if wx.VERSION < (2, 6, 0):
+        def Bind(self, event, function, id = None):
+            if id is not None:
+                event(self, id, function)
+            else:
+                event(self, function)
+    
+    def __init__(self, *args, **kwargs):
+        wx.grid.Grid.__init__(self, *args, **kwargs)
+        
+        if wx.VERSION >= (2, 6, 0):
+            self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelectCell)
+        else:
+            wx.grid.EVT_GRID_SELECT_CELL(self, self.OnSelectCell)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+    
+    def SetDefaultValue(self, default_value):
+        self.DefaultValue = default_value
+    
+    def SetButtons(self, buttons):
+        for name in ["Add", "Delete", "Up", "Down"]:
+            button = buttons.get(name, None)
+            setattr(self, "%sButton" % name, button)
+            if button is not None:
+                button.Bind(wx.EVT_BUTTON, getattr(self, "On%sButton" % name))
+    
+    def RefreshButtons(self):
+        rows = self.Table.GetNumberRows()
+        row = self.GetGridCursorRow()
+        if self.DeleteButton is not None:
+            self.DeleteButton.Enable(rows > 0)
+        if self.UpButton is not None:
+            self.UpButton.Enable(row > 0)
+        if self.DownButton is not None:
+            self.DownButton.Enable(0 <= row < rows - 1)
+    
+    def CloseEditControl(self):
+        self.SetGridCursor(self.GetGridCursorRow(), self.GetGridCursorCol())
+
+    def AddRow(self):
+        self.CloseEditControl()
+        new_row = self.GetGridCursorRow() + 1
+        col = max(self.GetGridCursorCol(), 0)
+        if getattr(self, "_AddRow", None) is not None:
+            new_row = self._AddRow(new_row)
+        else:
+            self.Table.InsertRow(new_row, self.DefaultValue.copy())
+            self.Table.ResetView(self)
+        self.SetGridCursor(new_row, col)
+        self.MakeCellVisible(new_row, col)
+        self.RefreshButtons()
+
+    def DeleteRow(self):
+        self.CloseEditControl()
+        row = self.GetGridCursorRow()
+        if row >= 0:
+            col = self.GetGridCursorCol()
+            if getattr(self, "_DeleteRow", None) is not None:
+                self._DeleteRow(row)
+            else:
+                self.Table.RemoveRow(row)
+                self.Table.ResetView(self)
+            new_row = min(row, self.Table.GetNumberRows() - 1)
+            self.SetGridCursor(new_row, col)
+            self.MakeCellVisible(new_row, col)
+            self.RefreshButtons()
+
+    def MoveRow(self, row, move):
+        self.CloseEditControl()
+        col = self.GetGridCursorCol()
+        if getattr(self, "_MoveRow", None) is not None:
+            new_row = self._MoveRow(row, move)
+        else:
+            new_row = self.Table.MoveRow(row, move)
+            if new_row != row:
+                self.Table.ResetView(self)
+        if new_row != row:
+            self.SetGridCursor(new_row, col)
+            self.MakeCellVisible(new_row, col)
+            self.RefreshButtons()
+
+    def OnAddButton(self, event):
+        self.AddRow()
+        self.SetFocus()
+        event.Skip()
+        
+    def OnDeleteButton(self, event):
+        self.DeleteRow()
+        self.SetFocus()
+        event.Skip()
+        
+    def OnUpButton(self, event):
+        self.MoveRow(self.GetGridCursorRow(), -1)
+        self.SetFocus()
+        event.Skip()
+        
+    def OnDownButton(self, event):
+        self.MoveRow(self.GetGridCursorRow(), 1)
+        self.SetFocus()
+        event.Skip()
+
+    def OnSelectCell(self, event):
+        wx.CallAfter(self.RefreshButtons)
+        event.Skip()
+
+    def OnKeyDown(self, event):
+        key_handled = False
+        keycode = event.GetKeyCode()
+        if keycode == wx.WXK_TAB:
+            row = self.GetGridCursorRow()
+            col = self.GetGridCursorCol()
+            if event.ShiftDown():
+                if row < 0 or col == 0:
+                    self.Navigate(wx.NavigationKeyEvent.IsBackward)
+                    key_handled = True
+            elif row < 0 or col == self.Table.GetNumberCols() - 1:
+                self.Navigate(wx.NavigationKeyEvent.IsForward)
+                key_handled = True
+        elif keycode in (wx.WXK_ADD, wx.WXK_NUMPAD_ADD):
+            self.AddRow()
+            key_handled = True
+        elif keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE):
+            self.DeleteRow()
+            key_handled = True
+        elif keycode == wx.WXK_UP and event.ShiftDown():
+            self.MoveRow(self.GetGridCursorRow(), -1)
+            key_handled = True
+        elif keycode == wx.WXK_DOWN and event.ShiftDown():
+            self.MoveRow(self.GetGridCursorRow(), 1)
+            key_handled = True
+        if not key_handled:
+            event.Skip()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/__init__.py	Fri Oct 14 19:26:29 2011 +0200
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard. 
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# Package initialization
+
+from CustomEditableListBox import CustomEditableListBox
+from CustomGrid import CustomGrid
\ No newline at end of file
--- a/dialogs/ActionBlockDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/ActionBlockDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -24,6 +24,8 @@
 import wx
 import wx.grid
 
+from controls import CustomGrid
+
 #-------------------------------------------------------------------------------
 #                            Action Block Dialog
 #-------------------------------------------------------------------------------
@@ -169,6 +171,11 @@
                 grid.SetReadOnly(row, col, readonly)
                 
                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
+            if wx.Platform == '__WXMSW__':
+                grid.SetRowMinimalHeight(row, 20)
+            else:
+                grid.SetRowMinimalHeight(row, 28)
+            grid.AutoSizeRow(row, False)
     
     def SetData(self, data):
         self.data = data
@@ -184,19 +191,21 @@
     
     def AppendRow(self, row_content):
         self.data.append(row_content)
+    
+    def InsertRow(self, row_index, row_content):
+        self.data.insert(row_index, row_content)
 
     def RemoveRow(self, row_index):
         self.data.pop(row_index)
         
-    def MoveRow(self, row_index, move, grid):
+    def MoveRow(self, row_index, move):
         new_index = max(0, min(row_index + move, len(self.data) - 1))
         if new_index != row_index:
             self.data.insert(new_index, self.data.pop(row_index))
-            grid.SetGridCursor(new_index, grid.GetGridCursorCol())
+        return new_index
 
     def Empty(self):
         self.data = []
-        self.editors = []
 
 [ID_ACTIONBLOCKDIALOG, ID_ACTIONBLOCKDIALOGVARIABLESGRID, 
  ID_ACTIONBLOCKDIALOGSTATICTEXT1, ID_ACTIONBLOCKDIALOGADDBUTTON,
@@ -260,7 +269,7 @@
               label=_('Actions:'), name='staticText1', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
-        self.ActionsGrid = wx.grid.Grid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID,
+        self.ActionsGrid = CustomGrid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID,
               name='ActionsGrid', parent=self, pos=wx.Point(0, 0), 
               size=wx.Size(0, 0), style=wx.VSCROLL)
         self.ActionsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
@@ -269,28 +278,27 @@
               False, 'Sans'))
         self.ActionsGrid.DisableDragGridSize()
         self.ActionsGrid.EnableScrolling(False, True)
-        self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange)
-
+        if wx.VERSION >= (2, 6, 0):
+            self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange)
+        else:
+            wx.grid.EVT_GRID_CELL_CHANGE(self.ActionsGrid, self.OnActionsGridCellChange)
+        
         self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label=_('Add'),
               name='AddButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_ACTIONBLOCKDIALOGADDBUTTON)
-
+        
         self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label=_('Delete'),
               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
               size=wx.DefaultSize, style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_ACTIONBLOCKDIALOGDELETEBUTTON)
-
+        
         self.UpButton = wx.Button(id=ID_ACTIONBLOCKDIALOGUPBUTTON, label='^',
               name='UpButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_ACTIONBLOCKDIALOGUPBUTTON)
-
+        
         self.DownButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDOWNBUTTON, label='v',
               name='DownButton', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(32, 32), style=0)
-        self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_ACTIONBLOCKDIALOGDOWNBUTTON)
-
+        
         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
         if wx.VERSION >= (2, 5, 0):
             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
@@ -302,7 +310,6 @@
     def __init__(self, parent):
         self._init_ctrls(parent)
         
-        self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""}
         self.Table = ActionTable(self, [], GetActionTableColnames())
         typelist = GetTypeList()       
         self.TypeList = ",".join(map(_,typelist))
@@ -311,6 +318,15 @@
         self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
         
         self.ActionsGrid.SetTable(self.Table)
+        self.ActionsGrid.SetDefaultValue({"Qualifier" : "N", 
+                                          "Duration" : "", 
+                                          "Type" : "Action", 
+                                          "Value" : "", 
+                                          "Indicator" : ""})
+        self.ActionsGrid.SetButtons({"Add": self.AddButton,
+                                     "Delete": self.DeleteButton,
+                                     "Up": self.UpButton,
+                                     "Down": self.DownButton})
         self.ActionsGrid.SetRowLabelSize(0)
         
         for col in range(self.Table.GetNumberCols()):
@@ -321,38 +337,17 @@
             self.ActionsGrid.AutoSizeColumn(col, False)
         
         self.Table.ResetView(self.ActionsGrid)
-
+        self.ActionsGrid.SetFocus()
+        self.ActionsGrid.RefreshButtons()
+    
     def OnOK(self, event):
-        self.ActionsGrid.SetGridCursor(0, 0)
+        self.ActionsGrid.CloseEditControl()
         self.EndModal(wx.ID_OK)
 
-    def OnAddButton(self, event):
-        self.Table.AppendRow(self.DefaultValue.copy())
-        self.Table.ResetView(self.ActionsGrid)
+    def OnActionsGridCellChange(self, event):
+        wx.CallAfter(self.Table.ResetView, self.ActionsGrid)
         event.Skip()
-
-    def OnDeleteButton(self, event):
-        row = self.ActionsGrid.GetGridCursorRow()
-        self.Table.RemoveRow(row)
-        self.Table.ResetView(self.ActionsGrid)
-        event.Skip()
-
-    def OnUpButton(self, event):
-        row = self.ActionsGrid.GetGridCursorRow()
-        self.Table.MoveRow(row, -1, self.ActionsGrid)
-        self.Table.ResetView(self.ActionsGrid)
-        event.Skip()
-
-    def OnDownButton(self, event):
-        row = self.ActionsGrid.GetGridCursorRow()
-        self.Table.MoveRow(row, 1, self.ActionsGrid)
-        self.Table.ResetView(self.ActionsGrid)
-        event.Skip()
-
-    def OnActionsGridCellChange(self, event):
-        self.Table.ResetView(self.ActionsGrid)
-        event.Skip()
-
+    
     def SetQualifierList(self, list):
         self.QualifierList = "," + ",".join(list)
         self.DurationList = list
@@ -385,6 +380,9 @@
                 row["Indicator"] = ""
             self.Table.AppendRow(row)
         self.Table.ResetView(self.ActionsGrid)
+        if len(actions) > 0:
+            self.ActionsGrid.SetGridCursor(0, 0)
+        self.ActionsGrid.RefreshButtons()
     
     def GetValues(self):
         values = []
--- a/dialogs/ArrayTypeDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/ArrayTypeDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -25,7 +25,8 @@
 from types import TupleType
 
 import wx
-import wx.gizmos
+
+from controls import CustomEditableListBox
 
 DIMENSION_MODEL = re.compile("([0-9]+)\.\.([0-9]+)$")
 
@@ -80,22 +81,13 @@
               name='BaseType', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 28), style=wx.CB_READONLY)
         
-        self.Dimensions = wx.gizmos.EditableListBox(id=ID_ARRAYTYPEDIALOGDIMENSIONS, 
+        self.Dimensions = CustomEditableListBox(id=ID_ARRAYTYPEDIALOGDIMENSIONS, 
               name='ArrayDimensions', parent=self, label=_("Dimensions:"), pos=wx.Point(0, 0),
               size=wx.Size(0, 24), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE)
-        self.Dimensions.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnDimensionsChanged)
-        new_button = self.Dimensions.GetNewButton()
-        new_button.SetToolTipString(_("New item"))
-        new_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        del_button = self.Dimensions.GetDelButton()
-        del_button.SetToolTipString(_("Delete item"))
-        del_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        up_button = self.Dimensions.GetUpButton()
-        up_button.SetToolTipString(_("Move up"))
-        up_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
-        down_button = self.Dimensions.GetDownButton()
-        down_button.SetToolTipString(_("Move down"))
-        down_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged)
+        list_ctrl = self.Dimensions.GetListCtrl()
+        list_ctrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnDimensionsChanged)
+        for func in ["_OnAddButton", "_OnDelButton", "_OnUpButton", "_OnDownButton"]:
+            setattr(self.Dimensions, func, self.OnDimensionsChanged)
         
         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
         if wx.VERSION >= (2, 5, 0):
@@ -117,6 +109,8 @@
         elif infos in datatypes:
             self.BaseType.SetStringSelection(infos)
         
+        self.BaseType.SetFocus()
+        
     def GetDimensions(self):
         dimensions_list = []
         for dimensions in self.Dimensions.GetStrings():
@@ -144,4 +138,4 @@
             self.EndModal(wx.ID_OK)
             
     def GetValue(self):
-        return "array", self.BaseType.GetStringSelection(), self.GetDimensions()
\ No newline at end of file
+        return "array", self.BaseType.GetStringSelection(), self.GetDimensions()
--- a/dialogs/ConnectionDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/ConnectionDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -137,11 +137,11 @@
         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
         setattr(self.Preview, "GetScaling", lambda:None)
         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
-
+        
         self.Spacer = wx.Panel(id=ID_CONNECTIONDIALOGSPACER,
               name='Spacer', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
-
+        
         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
         if wx.VERSION >= (2, 5, 0):
             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
@@ -159,6 +159,8 @@
         
         self.PouNames = []
         self.PouElementNames = []
+        
+        self.radioButton1.SetFocus()
     
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
@@ -192,7 +194,7 @@
         
     def SetPouElementNames(self, element_names):
         self.PouElementNames = [element_name.upper() for element_name in element_names]
-
+    
     def OnOK(self, event):
         connection_name = self.ConnectionName.GetValue()
         if connection_name == "":
--- a/dialogs/DurationEditorDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/DurationEditorDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -154,6 +154,8 @@
     def __init__(self, parent):
         self._init_ctrls(parent)
         
+        self.Days.SetFocus()
+        
     def SetDuration(self, value):
         result = IEC_TIME_MODEL.match(value.upper())
         if result is not None:
--- a/dialogs/FBDBlockDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/FBDBlockDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -203,6 +203,8 @@
         self.PouNames = []
         self.PouElementNames = []
     
+        self.TypeTree.SetFocus()
+    
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
     
--- a/dialogs/FBDVariableDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/FBDVariableDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -194,6 +194,7 @@
         self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[INPUT])
 
         self.RefreshNameList()
+        self.Class.SetFocus()
 
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/LDElementDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/LDElementDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -192,7 +192,8 @@
         elif type == "coil":
             self._init_ctrls(parent, controler, _("Edit Coil Values"), 50)
             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
-            
+        
+        self.radioButton1.SetFocus()
     
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/LDPowerRailDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/LDPowerRailDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -162,6 +162,8 @@
         
         self.PowerRailMinSize = (0, 0)
         self.PowerRail = None
+        
+        self.radioButton1.SetFocus()
 
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/SFCDivergenceDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/SFCDivergenceDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -169,6 +169,8 @@
         
         self.Divergence = None
         self.MinSize = (0, 0)
+        
+        self.radioButton1.SetFocus()
     
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/SFCStepDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/SFCStepDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -165,6 +165,8 @@
         self.PouNames = []
         self.Variables = []
         self.StepNames = []
+        
+        self.StepName.SetFocus()
     
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/SFCTransitionDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/SFCTransitionDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -182,6 +182,8 @@
         self.MinTransitionSize = None
         
         self.Element = SFC_Transition(self.Preview)
+        
+        self.radioButton1.SetFocus()
     
     def SetPreviewFont(self, font):
         self.Preview.SetFont(font)
--- a/dialogs/SearchInProjectDialog.py	Wed Oct 12 23:47:48 2011 +0200
+++ b/dialogs/SearchInProjectDialog.py	Fri Oct 14 19:26:29 2011 +0200
@@ -161,6 +161,8 @@
 
         for name, label in GetElementsChoices():
             self.ElementsList.Append(_(label))
+        
+        self.Pattern.SetFocus()
 
     def GetCriteria(self):
         raw_pattern = pattern = self.Pattern.GetValue()