|
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) 2007: 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 #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 import wx |
|
26 import wx.grid |
|
27 |
|
28 class CustomGrid(wx.grid.Grid): |
|
29 |
|
30 def __init__(self, *args, **kwargs): |
|
31 wx.grid.Grid.__init__(self, *args, **kwargs) |
|
32 |
|
33 self.Editable = True |
|
34 |
|
35 self.AddButton = None |
|
36 self.DeleteButton = None |
|
37 self.UpButton = None |
|
38 self.DownButton = None |
|
39 |
|
40 self.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, 'Sans')) |
|
41 self.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, False, 'Sans')) |
|
42 self.SetSelectionBackground(wx.WHITE) |
|
43 self.SetSelectionForeground(wx.BLACK) |
|
44 self.DisableDragRowSize() |
|
45 |
|
46 self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelectCell) |
|
47 self.Bind(wx.grid.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden) |
|
48 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) |
|
49 |
|
50 def SetDefaultValue(self, default_value): |
|
51 self.DefaultValue = default_value |
|
52 |
|
53 def SetEditable(self, editable=True): |
|
54 self.Editable = editable |
|
55 self.RefreshButtons() |
|
56 |
|
57 def SetButtons(self, buttons): |
|
58 for name in ["Add", "Delete", "Up", "Down"]: |
|
59 button = buttons.get(name, None) |
|
60 setattr(self, "%sButton" % name, button) |
|
61 if button is not None: |
|
62 button.Bind(wx.EVT_BUTTON, getattr(self, "On%sButton" % name)) |
|
63 |
|
64 def RefreshButtons(self): |
|
65 if self: |
|
66 rows = self.Table.GetNumberRows() |
|
67 row = self.GetGridCursorRow() |
|
68 if self.AddButton is not None: |
|
69 self.AddButton.Enable(self.Editable) |
|
70 if self.DeleteButton is not None: |
|
71 self.DeleteButton.Enable(self.Editable and rows > 0) |
|
72 if self.UpButton is not None: |
|
73 self.UpButton.Enable(self.Editable and row > 0) |
|
74 if self.DownButton is not None: |
|
75 self.DownButton.Enable(self.Editable and 0 <= row < rows - 1) |
|
76 |
|
77 def CloseEditControl(self): |
|
78 row, col = self.GetGridCursorRow(), self.GetGridCursorCol() |
|
79 if row != -1 and col != -1: |
|
80 self.SetGridCursor(row, col) |
|
81 |
|
82 def AddRow(self): |
|
83 self.CloseEditControl() |
|
84 new_row = self.GetGridCursorRow() + 1 |
|
85 col = max(self.GetGridCursorCol(), 0) |
|
86 if getattr(self, "_AddRow", None) is not None: |
|
87 new_row = self._AddRow(new_row) |
|
88 else: |
|
89 self.Table.InsertRow(new_row, self.DefaultValue.copy()) |
|
90 self.Table.ResetView(self) |
|
91 self.SetGridCursor(new_row, col) |
|
92 self.MakeCellVisible(new_row, col) |
|
93 self.RefreshButtons() |
|
94 |
|
95 def DeleteRow(self): |
|
96 self.CloseEditControl() |
|
97 row = self.GetGridCursorRow() |
|
98 if row >= 0: |
|
99 col = self.GetGridCursorCol() |
|
100 if getattr(self, "_DeleteRow", None) is not None: |
|
101 self._DeleteRow(row) |
|
102 else: |
|
103 self.Table.RemoveRow(row) |
|
104 self.Table.ResetView(self) |
|
105 new_row = min(row, self.Table.GetNumberRows() - 1) |
|
106 self.SetGridCursor(new_row, col) |
|
107 self.MakeCellVisible(new_row, col) |
|
108 self.RefreshButtons() |
|
109 |
|
110 def MoveRow(self, row, move): |
|
111 self.CloseEditControl() |
|
112 col = self.GetGridCursorCol() |
|
113 if getattr(self, "_MoveRow", None) is not None: |
|
114 new_row = self._MoveRow(row, move) |
|
115 else: |
|
116 new_row = self.Table.MoveRow(row, move) |
|
117 if new_row != row: |
|
118 self.Table.ResetView(self) |
|
119 if new_row != row: |
|
120 self.SetGridCursor(new_row, col) |
|
121 self.MakeCellVisible(new_row, col) |
|
122 self.RefreshButtons() |
|
123 |
|
124 def OnAddButton(self, event): |
|
125 self.AddRow() |
|
126 self.SetFocus() |
|
127 event.Skip() |
|
128 |
|
129 def OnDeleteButton(self, event): |
|
130 self.DeleteRow() |
|
131 self.SetFocus() |
|
132 event.Skip() |
|
133 |
|
134 def OnUpButton(self, event): |
|
135 self.MoveRow(self.GetGridCursorRow(), -1) |
|
136 self.SetFocus() |
|
137 event.Skip() |
|
138 |
|
139 def OnDownButton(self, event): |
|
140 self.MoveRow(self.GetGridCursorRow(), 1) |
|
141 self.SetFocus() |
|
142 event.Skip() |
|
143 |
|
144 def OnSelectCell(self, event): |
|
145 wx.CallAfter(self.RefreshButtons) |
|
146 event.Skip() |
|
147 |
|
148 def OnEditorHidden(self, event): |
|
149 wx.CallAfter(self.SetFocus) |
|
150 event.Skip() |
|
151 |
|
152 def OnKeyDown(self, event): |
|
153 key_handled = False |
|
154 keycode = event.GetKeyCode() |
|
155 if keycode == wx.WXK_TAB: |
|
156 row = self.GetGridCursorRow() |
|
157 col = self.GetGridCursorCol() |
|
158 if event.ShiftDown(): |
|
159 if row < 0 or col == 0: |
|
160 self.Navigate(wx.NavigationKeyEvent.IsBackward) |
|
161 key_handled = True |
|
162 elif row < 0 or col == self.Table.GetNumberCols() - 1: |
|
163 self.Navigate(wx.NavigationKeyEvent.IsForward) |
|
164 key_handled = True |
|
165 elif keycode in (wx.WXK_ADD, wx.WXK_NUMPAD_ADD) and self.Editable: |
|
166 self.AddRow() |
|
167 key_handled = True |
|
168 elif keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE) and self.Editable: |
|
169 self.DeleteRow() |
|
170 key_handled = True |
|
171 elif keycode == wx.WXK_UP and event.ShiftDown() and self.Editable: |
|
172 self.MoveRow(self.GetGridCursorRow(), -1) |
|
173 key_handled = True |
|
174 elif keycode == wx.WXK_DOWN and event.ShiftDown() and self.Editable: |
|
175 self.MoveRow(self.GetGridCursorRow(), 1) |
|
176 key_handled = True |
|
177 if not key_handled: |
|
178 event.Skip() |