lpcmanager

Add MM3 definition, distinguish headless products (remote/mobile HMI) and local HMI display.
from __future__ import absolute_import
import re
import wx
import wx.grid
import controls
from collections import namedtuple
from OptionsParsing import ParseOptions, VARIABLETYPE, GenOptions, OptionsType
[ID_OPTIONSWIZARDDIALOG,ID_ONCHANGE,ID_OPTIONSTYPECHOICE,ID_SUBGROUPTEXT,ID_UNITTEXT,ID_VALUECHECKBOX,ID_MINSPIN,ID_MAXSPIN,ID_PRECISIONSPIN, ID_INITIALSPIN,ID_SCADACHECKBOX,ID_DISABLECHECKBOX,ID_OTHERTEXT,ID_DESCRIPTION,ID_STATIC] = [wx.NewId() for _init_ctrls in range(15)]
excluded_chars = [ord(i) for i in '\n"']
sanitizer = "".join([chr(i if i not in excluded_chars else ord(' ')) for i in xrange(256)])
eraser = '\r'
class WampOptionsEditor(wx.Dialog):
def _init_sizers(self):
self.MainSizer = wx.BoxSizer(wx.VERTICAL)
self.PropertySizer = wx.FlexGridSizer(cols=2, hgap=10, rows=13, vgap=10)
self.PropertySizer.AddWindow(wx.StaticText(self,wx.ID_ANY,_("Type:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.GROW | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.OptionsTypeChoice, 1, flag= wx.EXPAND)
self.PropertySizer.AddWindow(self.OnChangeCheckbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("On Change")), 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddWindow(self.ScadaCheckbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("Scada")), 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddWindow(self.StaticCheckbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("Static")), 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddWindow(wx.StaticText(self,wx.ID_ANY, _("Subgroup:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.SubgroupText, 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddWindow(wx.StaticText(self,wx.ID_ANY, _("Unit:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.UnitText, 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddWindow(self.ValueCheckbox, flag=wx.GROW | wx.LEFT, border=15)
self.PropertySizer.AddWindow(wx.StaticText(self,wx.ID_ANY, _("Enable min/max value")), flag=wx.ALIGN_CENTER_VERTICAL)
self.minValue=wx.StaticText(self, wx.ID_ANY, _("Min value:"))
self.maxValue=wx.StaticText(self, wx.ID_ANY, _("Max value:"))
self.PrecisionValue = wx.StaticText(self, wx.ID_ANY, _("Precision:"))
self.PropertySizer.AddWindow(self.minValue, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.MinSpin, flag=wx.GROW)
self.PropertySizer.AddWindow(self.maxValue, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.MaxSpin, flag=wx.GROW)
self.PropertySizer.AddWindow(self.PrecisionValue, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.PrecisionSpin, flag=wx.GROW)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("Other:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.OtherText, flag=wx.GROW)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("Tags:")), flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(self.Tags, flag=wx.GROW)
self.PropertySizer.AddWindow(self.DisableCheckbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=15)
self.PropertySizer.AddWindow(wx.StaticText(self, wx.ID_ANY, _("Disable display in xEye")), 1, flag=wx.GROW | wx.EXPAND)
self.PropertySizer.AddGrowableCol(1, 1)
self.MainSizer.AddSizer(self.PropertySizer, flag=wx.GROW | wx.UP | wx.RIGHT, border=15)
self.ButtonSizer.AddWindow(self.ClearButton)
self.MainSizer.AddSizer(self.ButtonSizer,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 10)
self.SetSizer(self.MainSizer)
self.Fit()
self.CenterOnScreen()
def _init_ctrls(self, prnt, opt):
wx.Dialog.__init__(self, id=ID_OPTIONSWIZARDDIALOG,
name='OptionsWizard', parent=prnt,
size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE,
title=_('Options'))
self.OptionsTypeChoice = wx.Choice(parent=self, id=ID_OPTIONSWIZARDDIALOG,
choices=VARIABLETYPE)
self.Bind(wx.EVT_CHOICE, self.OnTypeChoice, self.OptionsTypeChoice)
self.OnChangeCheckbox = wx.CheckBox(parent=self, id=ID_ONCHANGE)
self.SubgroupText = wx.TextCtrl(parent=self, id=ID_SUBGROUPTEXT)
self.UnitText = wx.TextCtrl(parent=self, id=ID_UNITTEXT)
self.ValueCheckbox = wx.CheckBox(parent=self, id=ID_VALUECHECKBOX)
self.MinSpin = wx.SpinCtrl(parent=self, id=ID_MINSPIN, style=wx.SP_VERTICAL)
self.MaxSpin = wx.SpinCtrl(parent=self, id=ID_MAXSPIN, style=wx.SP_VERTICAL)
self.PrecisionSpin = wx.SpinCtrl(parent=self, id=ID_PRECISIONSPIN, style=wx.SP_VERTICAL)
self.MinSpin.SetRange(-1000000, 1000000)
self.MaxSpin.SetRange(-1000000, 1000000)
self.ScadaCheckbox = wx.CheckBox(parent=self, id=ID_SCADACHECKBOX)
self.StaticCheckbox = wx.CheckBox(parent=self, id=ID_STATIC)
self.OtherText = wx.TextCtrl(parent=self, id=ID_OTHERTEXT)
self.Tags = wx.TextCtrl(parent=self, id=ID_DESCRIPTION, size=(-1, 100), style=wx.TE_MULTILINE|wx.SUNKEN_BORDER)
self.DisableCheckbox = wx.CheckBox(parent=self, id=ID_DISABLECHECKBOX)
self.ClearButton = wx.Button(self, wx.ID_CLEAR, _("Clear"))
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
self.ValueCheckbox.Bind(wx.EVT_CHECKBOX, self.EnableValue)
self.OnChangeCheckbox.Enable(False)
self.OtherText.Enable(False)
self.UnitText.Enable(False)
self.ScadaCheckbox.Enable(False)
self.DisableCheckbox.Enable(False)
self.SubgroupText.Enable(False)
self.ValueCheckbox.Enable(False)
self.MinSpin.Enable(False)
self.MaxSpin.Enable(False)
self.PrecisionSpin.Enable(False)
self.StaticCheckbox.Enable(False)
self.Bind(wx.EVT_CHOICE, self.Enabler, self.OptionsTypeChoice)
self.Bind(wx.EVT_BUTTON, self.clearOptions, self.ClearButton)
self.Bind(wx.EVT_CHECKBOX, self.Enabler, self.ScadaCheckbox)
self.Bind(wx.EVT_CHECKBOX, self.Enabler, self.DisableCheckbox)
def __init__(self, parent, opt):
self.options = opt
self.value = ""
self.OnChange = False
self._init_ctrls(parent, opt)
self._init_sizers()
self.SetOptions(opt)
self.Enabler(None)
def Enabler(self, event):
if self.OptionsTypeChoice.GetSelection() == 0:
self.clearOptions(event)
elif self.OptionsTypeChoice.GetSelection() in [1,3]:
self.ScadaCheckbox.Enable(True)
self.OtherText.Enable(True)
self.DisableCheckbox.Enable(True)
self.SubgroupText.Enable(True)
self.UnitText.Enable(True)
self.OnChangeCheckbox.Enable(True)
self.ValueCheckbox.Enable(True)
self.PrecisionSpin.Enable(True)
else:
self.ScadaCheckbox.Enable(True)
self.OtherText.Enable(True)
self.DisableCheckbox.Enable(True)
self.SubgroupText.Enable(True)
self.UnitText.Enable(True)
self.OnChangeCheckbox.SetValue(False)
self.OnChangeCheckbox.Enable(False)
self.ValueCheckbox.Enable(True)
self.PrecisionSpin.Enable(True)
if self.OptionsTypeChoice.GetSelection() == 3 and self.ScadaCheckbox.GetValue():
self.StaticCheckbox.Enable(True)
self.OnChangeCheckbox.SetValue(True)
else:
self.StaticCheckbox.SetValue(False)
self.StaticCheckbox.Enable(False)
def clearOptions(self, event):
"""Zbrisi vsebino"""
self.OptionsTypeChoice.SetSelection(0)
self.SubgroupText.SetValue("")
self.UnitText.SetValue("")
self.MinSpin.SetValue(0)
self.MaxSpin.SetValue(0)
self.ValueCheckbox.SetValue(False)
self.ScadaCheckbox.SetValue(False)
self.StaticCheckbox.SetValue(False)
self.OtherText.SetValue("")
self.DisableCheckbox.SetValue(False)
self.MinSpin.Enable(False)
self.MaxSpin.Enable(False)
self.StaticCheckbox.Enable(False)
self.PrecisionSpin.SetValue(0)
self.OnChangeCheckbox.SetValue(False)
self.Tags.SetValue("")
self.OnChangeCheckbox.Enable(False)
self.OtherText.Enable(False)
self.DisableCheckbox.Enable(False)
self.SubgroupText.Enable(False)
self.UnitText.Enable(False)
self.ScadaCheckbox.Enable(False)
self.ValueCheckbox.Enable(False)
self.MinSpin.Enable(False)
self.MaxSpin.Enable(False)
self.PrecisionSpin.Enable(False)
self.Tags.Enable(False)
self.StaticCheckbox.Enable(False)
def OnTypeChoice(self, event):
self.selected = event.GetSelection()
def EnableValue(self, event):
self.MinSpin.Enable(self.ValueCheckbox.GetValue())
self.MaxSpin.Enable(self.ValueCheckbox.GetValue())
event.Skip()
def SetOptions(self, opts):
res = ParseOptions(opts)
self.OptionsTypeChoice.SetSelection(res.variable_type_selection)
self.OnChangeCheckbox.SetValue(res.is_onchange)
self.ScadaCheckbox.SetValue(res.is_scada)
self.StaticCheckbox.SetValue(res.is_static)
self.DisableCheckbox.SetValue(res.disable)
self.StaticCheckbox.Enable(
res.is_static or (res.variable_type_selection == 3 and res.is_scada))
if res.subgroup is not None:
self.SubgroupText.SetValue(res.subgroup)
if res.unit is not None:
self.UnitText.SetValue(res.unit)
if res.min is not None or res.max is not None:
self.ValueCheckbox.SetValue(True)
self.MinSpin.Enable(True)
self.MaxSpin.Enable(True)
self.MinSpin.SetValue(res.min if res.min else 0)
self.MaxSpin.SetValue(res.max if res.max else 0)
if res.other is not None:
self.OtherText.SetValue(res.other)
if res.precision is not None:
self.PrecisionSpin.SetValue(res.precision)
if res.tags is not None:
self.Tags.SetValue(res.tags)
def GetOptions(self):
opts = OptionsType()
opts.variable_type_selection = max(self.OptionsTypeChoice.GetSelection(), 0)
opts.is_onchange = self.OnChangeCheckbox.GetValue()
opts.is_scada = self.ScadaCheckbox.GetValue()
opts.is_static = self.StaticCheckbox.GetValue()
opts.disable = self.DisableCheckbox.GetValue()
if self.MinSpin.IsEnabled():
opts.min = self.MinSpin.GetValue()
opts.max = self.MaxSpin.GetValue()
opts.precision = self.PrecisionSpin.GetValue()
for name, ctrl in [('subgroup', self.SubgroupText),
('unit', self.UnitText),
('other', self.OtherText),
('tags', self.Tags)]:
content = ctrl.GetValue().encode('ascii','ignore').translate(sanitizer,eraser)
if content:
opts[name] = content
return GenOptions(opts)
class WampOptionsCellControl(wx.PyControl):
'''
Custom cell editor control with a text box and a button that launches
the WampOptionsEditor.
'''
def __init__(self, parent, table, row):
wx.Control.__init__(self, parent, row)
main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
self.parent = parent
# create location text control
self.Options = wx.TextCtrl(self, size=wx.Size(0, -1),
style=wx.TE_PROCESS_ENTER)
self.Options.Bind(wx.EVT_KEY_DOWN, self.OnChar)
main_sizer.AddWindow(self.Options, flag=wx.GROW)
# create browse button
self.EditButton = wx.Button(self, label='...', size=wx.Size(30, -1))
self.Bind(wx.EVT_BUTTON, self.OnEditButtonClick, self.EditButton)
main_sizer.AddWindow(self.EditButton, flag=wx.GROW)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.SetSizer(main_sizer)
self.Default = None
self.table = table
self.row = row
def SetValue(self, value):
self.Default = value
self.Options.SetValue(value)
def GetValue(self):
return self.Options.GetValue()
def OnSize(self, event):
self.Layout()
def OnEditButtonClick(self, event):
# pop up the Duration Editor dialog
options = self.GetValue()
# backward compatibility
dialog = WampOptionsEditor(self.parent, options)
answer = dialog.ShowModal()
opt = dialog.GetOptions()
if answer == wx.ID_OK:
self.SetValue(opt)
dialog.Destroy()
self.Options.SetFocus()
def OnChar(self, event):
keycode = event.GetKeyCode()
if keycode in [wx.WXK_RETURN]:
self.Parent.Parent.ProcessEvent(event)
elif keycode == wx.WXK_ESCAPE:
self.Options.SetValue(self.Default)
self.Parent.Parent.CloseEditControl()
else:
event.Skip()
def SetFocus(self):
self.Options.SetFocus()
class WampOptionsCellEditor(wx.grid.PyGridCellEditor):
'''
Grid cell editor that uses WampOptionsCellControl to display an edit button.
'''
def __init__(self, table, row, col):
wx.grid.PyGridCellEditor.__init__(self)
self.table = table
self.colname = self.table.GetColLabelValue(col, False)
self.row = row
def __del__(self):
self.CellControl = None
def Create(self, parent, id, evt_handler):
self.CellControl = WampOptionsCellControl(parent, self.table, self.row)
self.SetControl(self.CellControl)
if evt_handler:
self.CellControl.PushEventHandler(evt_handler)
def BeginEdit(self, row, col, grid):
self.CellControl.Enable()
self.CellControl.SetValue(self.table.GetValueByName(self.row, self.colname))
self.CellControl.SetFocus()
def EndEdit(self, row, col, grid, oldval):
value = self.CellControl.GetValue()
changed = value != oldval
if changed:
return value
else:
return None
def ApplyEdit(self, row, col, grid):
value = self.CellControl.GetValue()
self.table.SetValueByName(row, self.colname, value)
self.CellControl.Disable()
def SetSize(self, rect):
self.CellControl.SetDimensions(rect.x + 1, rect.y,
rect.width, rect.height,
wx.SIZE_ALLOW_MINUS_ONE)