--- a/Beremiz.py Wed Feb 27 14:36:05 2008 +0100
+++ b/Beremiz.py Wed Feb 27 18:40:39 2008 +0100
@@ -68,6 +68,8 @@
WINDOW_COLOUR = wx.Colour(240,240,240)
TITLE_COLOUR = wx.Colour(200,200,220)
+CHANGED_TITLE_COLOUR = wx.Colour(220,200,220) +CHANGED_WINDOW_COLOUR = wx.Colour(255,240,240) if wx.Platform == '__WXMSW__':
faces = { 'times': 'Times New Roman',
@@ -322,6 +324,7 @@
self.SetClientSize(wx.Size(1000, 600))
self.SetMenuBar(self.menuBar1)
self.Bind(wx.EVT_ACTIVATE, self.OnFrameActivated)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) if wx.VERSION < (2, 8, 0):
self.MainSplitter = wx.SplitterWindow(id=ID_BEREMIZMAINSPLITTER,
@@ -384,6 +387,17 @@
+ def OnCloseFrame(self, event): + if self.PluginRoot.HasProjectOpened(): + if self.PluginRoot.runningPLC is not None: + wx.MessageBox("Please stop any running PLC before closing") + if self.PluginRoot.ProjectTestModified(): + self.PluginRoot.SaveProject() + wx.MessageBox("Project saved") def OnMoveWindow(self, event):
@@ -422,8 +436,12 @@
self.ClearSizer(self.PLCParamsSizer)
- if self.PluginRoot.HasProjectOpened():
+ if self.PluginRoot.HasProjectOpened(): plcwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
+ if self.PluginRoot.PlugTestModified(): + bkgdclr = CHANGED_TITLE_COLOUR plcwindow.SetBackgroundColour(TITLE_COLOUR)
self.PLCParamsSizer.AddWindow(plcwindow, 0, border=0, flag=wx.GROW)
@@ -494,6 +512,8 @@
minimizebutton.Bind(wx.EVT_BUTTON, togglewindow, id=minimizebutton_id)
+ self.PluginInfos[self.PluginRoot] = {"main" : plcwindow, "params" : paramswindow} self.PLCConfigMainSizer.Layout()
@@ -541,19 +561,34 @@
self.ClearSizer(self.PluginTreeSizer)
if self.PluginRoot.HasProjectOpened():
for child in self.PluginRoot.IECSortedChilds():
- self.GenerateTreeBranch(child, index)
+ self.GenerateTreeBranch(child) if not self.PluginInfos[child]["expanded"]:
self.CollapsePlugin(child)
self.PLCConfigMainSizer.Layout()
+ def SetPluginParamsAttribute(self, plugin, *args, **kwargs): + res, StructChanged = plugin.SetParamsAttribute(*args, **kwargs) + wx.CallAfter(self.RefreshPluginTree) + if plugin == self.PluginRoot: + bkgdclr = CHANGED_TITLE_COLOUR + items = ["main", "params"] + bkgdclr = CHANGED_WINDOW_COLOUR + items = ["left", "middle", "params"] + self.PluginInfos[plugin][i].SetBackgroundColour(bkgdclr) + self.PluginInfos[plugin][i].Refresh() def ExpandPlugin(self, plugin, force = False):
for child in self.PluginInfos[plugin]["children"]:
- self.PluginTreeSizer.Show(self.PluginInfos[child]["left"])
- self.PluginTreeSizer.Show(self.PluginInfos[child]["middle"])
+ self.PluginInfos[child]["left"].Show() + self.PluginInfos[child]["middle"].Show() # self.PluginTreeSizer.Show(self.PluginInfos[child]["right"])
if force or not self.PluginInfos[child]["expanded"]:
self.ExpandPlugin(child, force)
@@ -562,17 +597,22 @@
def CollapsePlugin(self, plugin, force = False):
for child in self.PluginInfos[plugin]["children"]:
- self.PluginTreeSizer.Hide(self.PluginInfos[child]["left"])
- self.PluginTreeSizer.Hide(self.PluginInfos[child]["middle"])
+ self.PluginInfos[child]["left"].Hide() + self.PluginInfos[child]["middle"].Hide() # self.PluginTreeSizer.Hide(self.PluginInfos[child]["right"])
if force or self.PluginInfos[child]["expanded"]:
self.CollapsePlugin(child, force)
self.PluginInfos[child]["expanded"] = False
- def GenerateTreeBranch(self, plugin, index):
+ def GenerateTreeBranch(self, plugin): leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
- leftwindow.SetBackgroundColour(WINDOW_COLOUR)
+ if plugin.PlugTestModified(): + bkgdclr=CHANGED_WINDOW_COLOUR + leftwindow.SetBackgroundColour(bkgdclr) if plugin not in self.PluginInfos:
self.PluginInfos[plugin] = {"expanded" : False, "left_visible" : False, "middle_visible" : False}
@@ -607,8 +647,7 @@
enablebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Enabled.png')))
enablebutton.SetToggle(plugin.MandatoryParams[1].getEnabled())
def toggleenablebutton(event):
- res, StructChanged = plugin.SetParamsAttribute("BaseParams.Enabled", enablebutton.GetToggle(), self.Log)
- if StructChanged: wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, "BaseParams.Enabled", enablebutton.GetToggle(), self.Log) enablebutton.SetToggle(res)
enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
@@ -690,10 +729,10 @@
leftbuttonsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
- tc = wx.TextCtrl(leftwindow, tc_id, size=wx.Size(150, 35), style=wx.TE_PROCESS_ENTER|wx.NO_BORDER)
+ tc = wx.TextCtrl(leftwindow, tc_id, size=wx.Size(150, 35), style=wx.NO_BORDER) tc.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
tc.SetValue(plugin.MandatoryParams[1].getName())
- tc.Bind(wx.EVT_TEXT_ENTER, self.GetTextCtrlCallBackFunction(tc, plugin, "BaseParams.Name"), id=tc_id)
+ tc.Bind(wx.EVT_KILL_FOCUS, self.GetTextCtrlCallBackFunction(tc, plugin, "BaseParams.Name"), id=tc_id) leftbuttonsizer.AddWindow(tc, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
@@ -726,7 +765,7 @@
leftwindowsizer.AddWindow(lb, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
middlewindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
- middlewindow.SetBackgroundColour(wx.Colour(240,240,240))
+ middlewindow.SetBackgroundColour(bkgdclr) self.PluginTreeSizer.AddWindow(middlewindow, 0, border=0, flag=wx.GROW)
@@ -745,10 +784,11 @@
middlewindowsizer.AddSizer(middleparamssizer, 0, border=0, flag=wx.ALIGN_RIGHT)
paramswindow = wx.Panel(middlewindow, -1, size=wx.Size(-1, -1))
- paramswindow.SetBackgroundColour(WINDOW_COLOUR)
+ paramswindow.SetBackgroundColour(bkgdclr) psizer = wx.BoxSizer(wx.HORIZONTAL)
paramswindow.SetSizer(psizer)
+ self.PluginInfos[plugin]["params"] = paramswindow middleparamssizer.AddWindow(paramswindow, 0, border=5, flag=wx.ALL)
@@ -801,13 +841,11 @@
middleminimizebutton.Bind(wx.EVT_BUTTON, togglemiddlerightwindow, id=middleminimizebutton_id)
- self.PluginInfos[plugin]["left"] = index[0]
- self.PluginInfos[plugin]["middle"] = index[0] + 1
-# self.PluginInfos[plugin]["right"] = index[0] + 2
+ self.PluginInfos[plugin]["left"] = leftwindow + self.PluginInfos[plugin]["middle"] = middlewindow +# self.PluginInfos[plugin]["right"] = rightwindow for child in self.PluginInfos[plugin]["children"]:
- self.GenerateTreeBranch(child, index)
+ self.GenerateTreeBranch(child) if not self.PluginInfos[child]["expanded"]:
self.CollapsePlugin(child)
@@ -827,8 +865,7 @@
def GetItemChannelChangedFunction(self, plugin, value):
def OnPluginTreeItemChannelChanged(event):
- res, StructChanged = plugin.SetParamsAttribute("BaseParams.IEC_Channel", value, self.Log)
- wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, "BaseParams.IEC_Channel", value, self.Log) return OnPluginTreeItemChannelChanged
@@ -866,16 +903,14 @@
def GetChoiceCallBackFunction(self, choicectrl, plugin, path):
def OnChoiceChanged(event):
- res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
- if StructChanged: wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection(), self.Log) choicectrl.SetStringSelection(res)
def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, plugin, path):
def OnChoiceContentChanged(event):
- res, StructChanged = plugin.SetParamsAttribute(path, choicectrl.GetStringSelection(), self.Log)
- if StructChanged: wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection(), self.Log) choicectrl.SetStringSelection(res)
infos = self.PluginRoot.GetParamsAttributes(path)
staticbox = staticboxsizer.GetStaticBox()
@@ -893,16 +928,14 @@
def GetTextCtrlCallBackFunction(self, textctrl, plugin, path):
def OnTextCtrlChanged(event):
- res, StructChanged = plugin.SetParamsAttribute(path, textctrl.GetValue(), self.Log)
- if StructChanged: wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, path, textctrl.GetValue(), self.Log) def GetCheckBoxCallBackFunction(self, chkbx, plugin, path):
def OnCheckBoxChanged(event):
- res, StructChanged = plugin.SetParamsAttribute(path, chkbx.IsChecked(), self.Log)
- if StructChanged: wx.CallAfter(self.RefreshPluginTree)
+ res = self.SetPluginParamsAttribute(plugin, path, chkbx.IsChecked(), self.Log) @@ -1040,10 +1073,9 @@
spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, plugin, element_path), id=id)
textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=parent,
- pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.TE_PROCESS_ENTER)
+ pos=wx.Point(0, 0), size=wx.Size(150, 25), style=0)#wx.TE_PROCESS_ENTER) boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
textctrl.SetValue(str(element_infos["value"]))
- textctrl.Bind(wx.EVT_TEXT_ENTER, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path), id=id)
textctrl.Bind(wx.EVT_KILL_FOCUS, self.GetTextCtrlCallBackFunction(textctrl, plugin, element_path))
@@ -1100,6 +1132,7 @@
def OnSaveProjectMenu(self, event):
if self.PluginRoot.HasProjectOpened():
self.PluginRoot.SaveProject()
def OnPropertiesMenu(self, event):
--- a/plugger.py Wed Feb 27 14:36:05 2008 +0100
+++ b/plugger.py Wed Feb 27 18:40:39 2008 +0100
@@ -110,6 +110,19 @@
return os.path.join(self.PlugParent.PlugPath(), PlugName + NameTypeSeparator + self.PlugType)
def PlugTestModified(self):
+ return self.ChangesToSave + def ProjectTestModified(self): + recursively check modified status + if self.PlugTestModified(): + for PlugChild in self.IterChilds(): + if PlugChild.ProjectTestModified(): @@ -132,13 +145,14 @@
def SetParamsAttribute(self, path, value, logger):
+ self.ChangesToSave = True # Filter IEC_Channel and Name, that have specific behavior
if path == "BaseParams.IEC_Channel":
return self.FindNewIEC_Channel(value,logger), True
elif path == "BaseParams.Name":
res = self.FindNewName(value,logger)
parts = path.split(".", 1)
if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
@@ -172,7 +186,9 @@
result = self.OnPlugSave()
return "Error while saving \"%s\""%self.PlugPath()
+ self.ChangesToSave = False # go through all childs and do the same
for PlugChild in self.IterChilds():
result = PlugChild.PlugRequestSave()
@@ -473,6 +489,8 @@
PlugClass.__init__(_self)
#Load and init all the childs
+ #just loaded, nothing to saved + _self.ChangesToSave = False # If plugin do not have corresponding file/dirs - they will be created on Save
os.mkdir(_self.PlugPath())
@@ -482,6 +500,8 @@
if getattr(PlugClass, "__init__", None):
PlugClass.__init__(_self)
+ #just created, must be saved + _self.ChangesToSave = True def _getBuildPath(_self):
return self._getBuildPath()
@@ -658,22 +678,23 @@
+ # In both new or load scenario, no need to save + self.ChangesToSave = False # Keep track of the plugin type name
self.PlugType = "Beremiz"
# After __init__ root plugin is not valid
# copy PluginMethods so that it can be later customized
self.PluginMethods = [dic.copy() for dic in self.PluginMethods]
+ # special root member for handlig PLC execution
+ def PlugTestModified(self): + return self.ChangesToSave or not self.ProjectIsSaved() def HasProjectOpened(self):
Return if a project is actually opened