author | Andrey Skvortsov <andrej.skvortzov@gmail.com> |
Thu, 19 Jan 2017 13:56:09 +0300 | |
changeset 1639 | 1953c268a194 |
parent 1571 | 486f94a8032c |
child 1696 | 8043f32de7b8 |
permissions | -rw-r--r-- |
814 | 1 |
# -*- coding: utf-8 -*- |
2 |
||
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
3 |
# This file is part of Beremiz, a Integrated Development Environment for |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
4 |
# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
5 |
# |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
6 |
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
7 |
# |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
8 |
# See COPYING file for copyrights details. |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
9 |
# |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
10 |
# This program is free software; you can redistribute it and/or |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
11 |
# modify it under the terms of the GNU General Public License |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
12 |
# as published by the Free Software Foundation; either version 2 |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
13 |
# of the License, or (at your option) any later version. |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
14 |
# |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
15 |
# This program is distributed in the hope that it will be useful, |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
16 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
17 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
18 |
# GNU General Public License for more details. |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
19 |
# |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
20 |
# You should have received a copy of the GNU General Public License |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
21 |
# along with this program; if not, write to the Free Software |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1347
diff
changeset
|
22 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
814 | 23 |
|
24 |
import wx |
|
25 |
import wx.grid |
|
26 |
import wx.lib.buttons |
|
27 |
||
28 |
from controls import CustomGrid, CustomTable |
|
29 |
from util.BitmapLibrary import GetBitmap |
|
1339 | 30 |
from PLCControler import _ActionInfos |
814 | 31 |
|
32 |
#------------------------------------------------------------------------------- |
|
33 |
# Helpers |
|
34 |
#------------------------------------------------------------------------------- |
|
35 |
||
36 |
def GetActionTableColnames(): |
|
37 |
_ = lambda x: x |
|
38 |
return [_("Qualifier"), _("Duration"), _("Type"), _("Value"), _("Indicator")] |
|
39 |
||
40 |
def GetTypeList(): |
|
41 |
_ = lambda x: x |
|
42 |
return [_("Action"), _("Variable"), _("Inline")] |
|
43 |
||
44 |
#------------------------------------------------------------------------------- |
|
45 |
# Action Table |
|
46 |
#------------------------------------------------------------------------------- |
|
47 |
||
48 |
class ActionTable(CustomTable): |
|
49 |
||
50 |
def GetValue(self, row, col): |
|
51 |
if row < self.GetNumberRows(): |
|
52 |
colname = self.GetColLabelValue(col, False) |
|
1339 | 53 |
value = getattr(self.data[row], colname.lower()) |
814 | 54 |
if colname == "Type": |
1339 | 55 |
return _(value) |
56 |
return value |
|
814 | 57 |
|
58 |
def SetValue(self, row, col, value): |
|
59 |
if col < len(self.colnames): |
|
60 |
colname = self.GetColLabelValue(col, False) |
|
61 |
if colname == "Type": |
|
62 |
value = self.Parent.TranslateType[value] |
|
1339 | 63 |
elif colname == "Qualifier" and not self.Parent.DurationList[value]: |
64 |
self.data[row].duration = "" |
|
65 |
setattr(self.data[row], colname.lower(), value) |
|
814 | 66 |
|
67 |
def _updateColAttrs(self, grid): |
|
68 |
""" |
|
69 |
wx.Grid -> update the column attributes to add the |
|
70 |
appropriate renderer given the column name. |
|
71 |
||
72 |
Otherwise default to the default renderer. |
|
73 |
""" |
|
74 |
||
75 |
for row in range(self.GetNumberRows()): |
|
76 |
for col in range(self.GetNumberCols()): |
|
77 |
editor = None |
|
78 |
renderer = None |
|
79 |
readonly = False |
|
80 |
colname = self.GetColLabelValue(col, False) |
|
81 |
if colname == "Qualifier": |
|
82 |
editor = wx.grid.GridCellChoiceEditor() |
|
83 |
editor.SetParameters(self.Parent.QualifierList) |
|
84 |
if colname == "Duration": |
|
85 |
editor = wx.grid.GridCellTextEditor() |
|
86 |
renderer = wx.grid.GridCellStringRenderer() |
|
1339 | 87 |
readonly = not self.Parent.DurationList[self.data[row].qualifier] |
814 | 88 |
elif colname == "Type": |
89 |
editor = wx.grid.GridCellChoiceEditor() |
|
90 |
editor.SetParameters(self.Parent.TypeList) |
|
91 |
elif colname == "Value": |
|
1339 | 92 |
value_type = self.data[row].type |
93 |
if value_type == "Action": |
|
814 | 94 |
editor = wx.grid.GridCellChoiceEditor() |
95 |
editor.SetParameters(self.Parent.ActionList) |
|
1339 | 96 |
elif value_type == "Variable": |
814 | 97 |
editor = wx.grid.GridCellChoiceEditor() |
98 |
editor.SetParameters(self.Parent.VariableList) |
|
1339 | 99 |
elif value_type == "Inline": |
814 | 100 |
editor = wx.grid.GridCellTextEditor() |
101 |
renderer = wx.grid.GridCellStringRenderer() |
|
102 |
elif colname == "Indicator": |
|
103 |
editor = wx.grid.GridCellChoiceEditor() |
|
104 |
editor.SetParameters(self.Parent.VariableList) |
|
105 |
||
106 |
grid.SetCellEditor(row, col, editor) |
|
107 |
grid.SetCellRenderer(row, col, renderer) |
|
108 |
grid.SetReadOnly(row, col, readonly) |
|
109 |
||
110 |
grid.SetCellBackgroundColour(row, col, wx.WHITE) |
|
111 |
self.ResizeRow(grid, row) |
|
112 |
||
113 |
#------------------------------------------------------------------------------- |
|
114 |
# Action Block Dialog |
|
115 |
#------------------------------------------------------------------------------- |
|
116 |
||
117 |
class ActionBlockDialog(wx.Dialog): |
|
118 |
||
119 |
def __init__(self, parent): |
|
120 |
wx.Dialog.__init__(self, parent, |
|
121 |
size=wx.Size(500, 300), title=_('Edit action block properties')) |
|
122 |
||
123 |
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
|
124 |
main_sizer.AddGrowableCol(0) |
|
125 |
main_sizer.AddGrowableRow(1) |
|
126 |
||
127 |
top_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0) |
|
128 |
top_sizer.AddGrowableCol(0) |
|
129 |
top_sizer.AddGrowableRow(0) |
|
130 |
main_sizer.AddSizer(top_sizer, border=20, |
|
131 |
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) |
|
132 |
||
133 |
actions_label = wx.StaticText(self, label=_('Actions:')) |
|
134 |
top_sizer.AddWindow(actions_label, flag=wx.ALIGN_BOTTOM) |
|
135 |
||
136 |
for name, bitmap, help in [ |
|
137 |
("AddButton", "add_element", _("Add action")), |
|
138 |
("DeleteButton", "remove_element", _("Remove action")), |
|
139 |
("UpButton", "up", _("Move action up")), |
|
140 |
("DownButton", "down", _("Move action down"))]: |
|
141 |
button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), |
|
142 |
size=wx.Size(28, 28), style=wx.NO_BORDER) |
|
143 |
button.SetToolTipString(help) |
|
144 |
setattr(self, name, button) |
|
145 |
top_sizer.AddWindow(button) |
|
146 |
||
147 |
self.ActionsGrid = CustomGrid(self, size=wx.Size(0, 0), style=wx.VSCROLL) |
|
148 |
self.ActionsGrid.DisableDragGridSize() |
|
149 |
self.ActionsGrid.EnableScrolling(False, True) |
|
150 |
self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, |
|
151 |
self.OnActionsGridCellChange) |
|
152 |
main_sizer.AddSizer(self.ActionsGrid, border=20, |
|
153 |
flag=wx.GROW|wx.LEFT|wx.RIGHT) |
|
154 |
||
155 |
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) |
|
156 |
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton()) |
|
157 |
main_sizer.AddSizer(button_sizer, border=20, |
|
158 |
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) |
|
159 |
||
160 |
self.SetSizer(main_sizer) |
|
161 |
||
162 |
self.Table = ActionTable(self, [], GetActionTableColnames()) |
|
163 |
typelist = GetTypeList() |
|
164 |
self.TypeList = ",".join(map(_,typelist)) |
|
165 |
self.TranslateType = dict([(_(value), value) for value in typelist]) |
|
166 |
self.ColSizes = [60, 90, 80, 110, 80] |
|
167 |
self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] |
|
168 |
||
169 |
self.ActionsGrid.SetTable(self.Table) |
|
1339 | 170 |
self.ActionsGrid.SetDefaultValue(_ActionInfos("N", "Action", "", "", "")) |
814 | 171 |
self.ActionsGrid.SetButtons({"Add": self.AddButton, |
172 |
"Delete": self.DeleteButton, |
|
173 |
"Up": self.UpButton, |
|
174 |
"Down": self.DownButton}) |
|
175 |
self.ActionsGrid.SetRowLabelSize(0) |
|
176 |
||
177 |
for col in range(self.Table.GetNumberCols()): |
|
178 |
attr = wx.grid.GridCellAttr() |
|
179 |
attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) |
|
180 |
self.ActionsGrid.SetColAttr(col, attr) |
|
181 |
self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col]) |
|
182 |
self.ActionsGrid.AutoSizeColumn(col, False) |
|
183 |
||
184 |
self.Table.ResetView(self.ActionsGrid) |
|
185 |
self.ActionsGrid.SetFocus() |
|
186 |
self.ActionsGrid.RefreshButtons() |
|
187 |
||
188 |
def OnOK(self, event): |
|
189 |
self.ActionsGrid.CloseEditControl() |
|
190 |
self.EndModal(wx.ID_OK) |
|
191 |
||
192 |
def OnActionsGridCellChange(self, event): |
|
193 |
wx.CallAfter(self.Table.ResetView, self.ActionsGrid) |
|
194 |
event.Skip() |
|
195 |
||
196 |
def SetQualifierList(self, list): |
|
1339 | 197 |
self.QualifierList = ",".join(list) |
814 | 198 |
self.DurationList = list |
199 |
||
200 |
def SetVariableList(self, list): |
|
1347
533741e5075c
Fixed pou variables information loading stylesheet
Laurent Bessard
parents:
1340
diff
changeset
|
201 |
self.VariableList = "," + ",".join([variable.Name for variable in list]) |
814 | 202 |
|
203 |
def SetActionList(self, list): |
|
204 |
self.ActionList = "," + ",".join(list) |
|
205 |
||
206 |
def SetValues(self, actions): |
|
207 |
for action in actions: |
|
1340
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
208 |
row = action.copy() |
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
209 |
if row.type == "reference" and row.value in self.ActionList: |
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
210 |
row.type = "Action" |
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
211 |
elif row.type == "reference" and row.value in self.VariableList: |
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
212 |
row.type = "Variable" |
814 | 213 |
else: |
1340
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
214 |
row.type = "Inline" |
7e5702d1f246
Fixed bug when cancelling ActionBlockDialog
Laurent Bessard
parents:
1339
diff
changeset
|
215 |
self.Table.AppendRow(row) |
814 | 216 |
self.Table.ResetView(self.ActionsGrid) |
217 |
if len(actions) > 0: |
|
218 |
self.ActionsGrid.SetGridCursor(0, 0) |
|
219 |
self.ActionsGrid.RefreshButtons() |
|
220 |
||
221 |
def GetValues(self): |
|
1339 | 222 |
actions = self.Table.GetData() |
223 |
for action in actions: |
|
224 |
if action.type in ["Action", "Variable"]: |
|
225 |
action.type = "reference" |
|
814 | 226 |
else: |
1339 | 227 |
action.type = "inline" |
228 |
return actions |