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