--- a/PLCControler.py Fri Oct 05 18:11:27 2007 +0200
+++ b/PLCControler.py Fri Oct 05 18:11:51 2007 +0200
@@ -383,63 +383,70 @@
# Project Pous management functions
#-------------------------------------------------------------------------------
+ def RemoveElementEditing(self, index):
+ self.ElementsOpened.pop(index)
+ if self.CurrentElementEditing > index:
+ self.CurrentElementEditing -= 1
+ if len(self.ElementsOpened) > 0:
+ self.CurrentElementEditing = max(0, min(self.CurrentElementEditing, len(self.ElementsOpened) - 1))
+ else:
+ self.CurrentElementEditing = None
+
# Add a Pou to Project
- def ProjectAddPou(self, name, pou_type, body_type):
+ def ProjectAddPou(self, pou_name, pou_type, body_type):
# Add the pou to project
- self.Project.appendPou(name, pou_type, body_type)
- self.SetPouInterfaceReturnType(name, "BOOL")
+ self.Project.appendPou(pou_name, pou_type, body_type)
+ if pou_type == "function":
+ self.SetPouInterfaceReturnType(pou_name, "BOOL")
self.RefreshPouUsingTree()
self.RefreshBlockTypes()
self.BufferProject()
# Remove a pou from project
- def ProjectRemovePou(self, name):
- removed = None
+ def ProjectRemovePou(self, pou_name):
# Search if the pou removed is currently opened
- for i, pou in enumerate(self.ElementsOpened):
- if pou == name:
- removed = i
- # If found, remove pou from list of opened pous and actualize current edited
- if removed != None:
- self.ElementsOpened.pop(removed)
- if self.CurrentElementEditing > removed:
- self.CurrentElementEditing -= 1
- if len(self.ElementsOpened) > 0:
- self.CurrentElementEditing = max(0, min(self.CurrentElementEditing, len(self.ElementsOpened) - 1))
- else:
- self.CurrentElementEditing = None
+ for i, element in enumerate(self.ElementsOpened):
+ words = element.split("::")
+ if words[0] == "P" and words[1] == pou_name:
+ self.RemoveElementEditing(i)
# Remove pou from project
- self.Project.removePou(name)
+ self.Project.removePou(pou_name)
self.RefreshPouUsingTree()
self.RefreshBlockTypes()
self.BufferProject()
# Add a configuration to Project
- def ProjectAddConfiguration(self, name):
- self.Project.addConfiguration(name)
+ def ProjectAddConfiguration(self, config_name):
+ self.Project.addConfiguration(config_name)
self.RefreshPouUsingTree()
self.RefreshBlockTypes()
self.BufferProject()
# Remove a configuration from project
- def ProjectRemoveConfiguration(self, name):
- self.Project.removeConfiguration(name)
+ def ProjectRemoveConfiguration(self, config_name):
+ # Search if the pou removed is currently opened
+ for i, element in enumerate(self.ElementsOpened):
+ words = element.split("::")
+ if words[0] == "C" and words[1] == config_name:
+ self.RemoveElementEditing(i)
+ self.Project.removeConfiguration(config_name)
+ self.BufferProject()
+
+ # Add a resource to a configuration of the Project
+ def ProjectAddConfigurationResource(self, config_name, resource_name):
+ self.Project.addConfigurationResource(config_name, resource_name)
self.RefreshPouUsingTree()
self.RefreshBlockTypes()
self.BufferProject()
- # Add a resource to a configuration of the Project
- def ProjectAddConfigurationResource(self, config, name):
- self.Project.addConfigurationResource(config, name)
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
- self.BufferProject()
-
# Remove a resource from a configuration of the project
- def ProjectRemoveConfigurationResource(self, config, name):
- self.Project.removeConfigurationResource(config, name)
- self.RefreshPouUsingTree()
- self.RefreshBlockTypes()
+ def ProjectRemoveConfigurationResource(self, config_name, resource_name):
+ # Search if the pou removed is currently opened
+ for i, element in enumerate(self.ElementsOpened):
+ words = element.split("::")
+ if words[0] == "R" and words[1] == config_name and words[2] == resource_name:
+ self.RemoveElementEditing(i)
+ self.Project.removeConfigurationResource(config_name, resource_name)
self.BufferProject()
# Add a Transition to a Project Pou
@@ -448,11 +455,33 @@
pou.addTransition(transition_name, transition_type)
self.BufferProject()
- # Add a Transition to a Project Pou
+ # Remove a Transition from a Project Pou
+ def ProjectRemovePouTransition(self, pou_name, transition_name):
+ # Search if the pou removed is currently opened
+ for i, element in enumerate(self.ElementsOpened):
+ words = element.split("::")
+ if words[0] == "T" and words[1] == pou_name and words[2] == transition_name:
+ self.RemoveElementEditing(i)
+ pou = self.Project.getPou(pou_name)
+ pou.removeTransition(transition_name)
+ self.BufferProject()
+
+ # Add an Action to a Project Pou
def ProjectAddPouAction(self, pou_name, action_name, action_type):
pou = self.Project.getPou(pou_name)
pou.addAction(action_name, action_type)
self.BufferProject()
+
+ # Remove an Action from a Project Pou
+ def ProjectRemovePouAction(self, pou_name, action_name):
+ # Search if the pou removed is currently opened
+ for i, element in enumerate(self.ElementsOpened):
+ words = element.split("::")
+ if words[0] == "A" and words[1] == pou_name and words[2] == action_name:
+ self.RemoveElementEditing(i)
+ pou = self.Project.getPou(pou_name)
+ pou.removeAction(action_name)
+ self.BufferProject()
# Change the name of a pou
def ChangePouName(self, old_name, new_name):
@@ -594,18 +623,6 @@
action = pou.getAction(pou_action)
return action.getBodyType()
- # Add a Transition to a Project Pou
- def ProjectRemovePouTransition(self, pou_name, transition_name):
- pou = self.Project.getPou(pou_name)
- pou.removeTransition(transition_name)
- self.BufferProject()
-
- # Add a Transition to a Project Pou
- def ProjectRemovePouAction(self, pou_name, action_name):
- pou = self.Project.getPou(pou_name)
- pou.removeAction(action_name)
- self.BufferProject()
-
# Extract varlists from a list of vars
def ExtractVarLists(self, vars):
varlist_list = []
@@ -901,17 +918,17 @@
# Return Function Block types checking for recursion
def GetFunctionBlockTypes(self):
if self.CurrentElementEditing != None:
+ name = ""
+ type = None
if self.Project:
current_name = self.ElementsOpened[self.CurrentElementEditing]
words = current_name.split("::")
- if len(words) == 1:
- name = current_name
- else:
- name = words[1]
- type = self.GetPouType(name)
- else:
- name = ""
- type = None
+ if words[0] in ["P","T","A"]:
+ if len(words) == 1:
+ name = current_name
+ else:
+ name = words[1]
+ type = self.GetPouType(name)
blocktypes = []
for category in BlockTypes[:-1]:
for block in category["list"]:
@@ -1032,6 +1049,12 @@
else:
self.CurrentElementEditing = None
+ # Close current element editing
+ def CloseAllElements(self):
+ # Clear the pou opened list
+ self.ElementsOpened = []
+ self.CurrentElementEditing = None
+
# Change current element editing for pou given by name
def ChangeElementEditing(self, name):
# Verify that element is opened
--- a/PLCOpenEditor.py Fri Oct 05 18:11:27 2007 +0200
+++ b/PLCOpenEditor.py Fri Oct 05 18:11:51 2007 +0200
@@ -34,6 +34,7 @@
from RessourceEditor import *
from PLCControler import *
from plcopen import OpenPDFDoc
+from plcopen.structures import LOCATIONDATATYPES
import os, re, platform, sys, time, traceback, getopt
@@ -298,7 +299,6 @@
self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=ID_PLCOPENEDITORFILEMENUITEMS5)
accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL, 83, ID_PLCOPENEDITORFILEMENUITEMS5)])
self.SetAcceleratorTable(accel)
- self.Bind(wx.EVT_ACTIVATE, self.OnFrameActivated)
self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER,
name='MainSplitter', parent=self, point=wx.Point(0, 0),
@@ -356,6 +356,7 @@
self.RefreshProjectTree()
else:
self.Controler = controler
+ self.RefreshProjectTree()
self.CurrentToolBar = []
self.CurrentLanguage = ""
@@ -443,16 +444,9 @@
self.RefreshProjectTree()
dialog.Destroy()
- def OnFrameActivated(self, event):
- if not self.ModeSolo and event.GetActive():
- self.Controler.RefreshPluginsBlockLists()
- selected = self.TabsOpened.GetSelection()
- if selected >= 0:
- self.TabsOpened.GetPage(selected).RefreshView()
- event.Skip()
-
def OnCloseFrame(self, event):
- if not self.ModeSolo and getattr(self, "_onclose", None) != None:
+ if not self.ModeSolo and getattr(self, "_onclose", None) is not None:
+ self.Controler.CloseAllElements()
self._onclose()
event.Skip()
elif not self.Controler.ProjectIsSaved():
@@ -776,6 +770,11 @@
dragSource.SetData(data)
dragSource.DoDragDrop()
+ def RefreshEditorNames(self, item_type, old_name, new_name):
+ for i in xrange(self.TabsOpened.GetPageCount()):
+ editor = self.TabsOpened.GetPage(i)
+ editor.RefreshName(item_type, old_name, new_name)
+
def OnProjectTreeItemEndEdit(self, event):
message = None
abort = False
@@ -802,11 +801,15 @@
if not abort:
old_name = self.ProjectTree.GetItemText(item)
self.Controler.ChangePouName(old_name, new_name)
+ self.RefreshEditorNames(itemtype, old_name, new_name)
self.RefreshTabsOpenedTitles()
elif itemtype == ITEM_TRANSITION:
- category = self.ProjectTree.GetItemParent(item)
- pou = self.ProjectTree.GetItemParent(category)
- pou_name = self.ProjectTree.GetItemText(pou)
+ parent = self.ProjectTree.GetItemParent(selected)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ while parent_type != ITEM_POU:
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ pou_name = self.ProjectTree.GetItemText(parent)
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
message = "A pou with \"%s\" as name exists!"%new_name
elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
@@ -814,11 +817,15 @@
else:
old_name = self.ProjectTree.GetItemText(item)
self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
+ self.RefreshEditorNames(itemtype, old_name, new_name)
self.RefreshTabsOpenedTitles()
elif itemtype == ITEM_ACTION:
- category = self.ProjectTree.GetItemParent(item)
- pou = self.ProjectTree.GetItemParent(category)
- pou_name = self.ProjectTree.GetItemText(pou)
+ parent = self.ProjectTree.GetItemParent(selected)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ while parent_type != ITEM_POU:
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ pou_name = self.ProjectTree.GetItemText(parent)
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
message = "A pou with \"%s\" as name exists!"%new_name
elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
@@ -826,6 +833,51 @@
else:
old_name = self.ProjectTree.GetItemText(item)
self.Controler.ChangePouActionName(pou_name, old_name, new_name)
+ self.RefreshEditorNames(itemtype, old_name, new_name)
+ self.RefreshTabsOpenedTitles()
+ elif itemtype == ITEM_CONFIGURATION:
+ if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+ message = "\"%s\" config already exists!"%new_name
+ abort = True
+ elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+ messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+ if messageDialog.ShowModal() == wx.ID_NO:
+ abort = True
+ messageDialog.Destroy()
+ elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+ messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+ if messageDialog.ShowModal() == wx.ID_NO:
+ abort = True
+ messageDialog.Destroy()
+ if not abort:
+ old_name = self.ProjectTree.GetItemText(item)
+ self.Controler.ChangeConfigurationName(old_name, new_name)
+ self.RefreshEditorNames(itemtype, old_name, new_name)
+ self.RefreshTabsOpenedTitles()
+ elif itemtype == ITEM_RESOURCE:
+ parent = self.ProjectTree.GetItemParent(selected)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ while parent_type != ITEM_CONFIGURATION:
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)
+ config_name = self.ProjectTree.GetItemText(parent)
+ if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+ message = "\"%s\" config already exists!"%new_name
+ abort = True
+ elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+ messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+ if messageDialog.ShowModal() == wx.ID_NO:
+ abort = True
+ messageDialog.Destroy()
+ elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+ messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+ if messageDialog.ShowModal() == wx.ID_NO:
+ abort = True
+ messageDialog.Destroy()
+ if not abort:
+ old_name = self.ProjectTree.GetItemText(item)
+ self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
+ self.RefreshEditorNames(itemtype, old_name, new_name)
self.RefreshTabsOpenedTitles()
if message or abort:
if message:
@@ -1102,8 +1154,8 @@
for i in xrange(self.TabsOpened.GetPageCount()):
if self.TabsOpened.GetPageText(i) == selected:
deleted = i
- if deleted != None:
- self.TabsOpened.DeletePage(i)
+ if deleted is not None:
+ self.TabsOpened.DeletePage(deleted)
self.RefreshTitle()
self.RefreshEditMenu()
self.RefreshProjectTree()
@@ -2067,12 +2119,6 @@
Otherwise default to the default renderer.
"""
- for col in range(self.GetNumberCols()):
- attr = wx.grid.GridCellAttr()
- attr.SetAlignment(self.Parent.ColAlignements[col], wx.ALIGN_CENTRE)
- grid.SetColAttr(col, attr)
- grid.SetColSize(col, self.Parent.ColSizes[col])
-
typelist = None
accesslist = None
for row in range(self.GetNumberRows()):
@@ -2088,9 +2134,15 @@
else:
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
- elif colname in ["Initial Value","Location"]:
+ elif colname == "Initial Value":
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
+ elif colname == "Location":
+ if self.GetValueByName(row, "Class") in ["Local", "Global"]:
+ editor = wx.grid.GridCellTextEditor()
+ renderer = wx.grid.GridCellStringRenderer()
+ else:
+ grid.SetReadOnly(row, col, True)
elif colname == "Class":
if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
grid.SetReadOnly(row, col, True)
@@ -2150,24 +2202,44 @@
if col != wx.NOT_FOUND and row != wx.NOT_FOUND:
if self.ParentWindow.Table.GetColLabelValue(col) != "Location":
return
- try:
- values = eval(data)
- except:
- values = None
- if values and values[1] == "location":
- dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL)
- if dialog.ShowModal() == wx.ID_OK:
- selected = dialog.GetSelection()
- if selected == 0:
- location = "%I" + values[0]
- elif selected == 1:
- location = "%Q" + values[0]
+ message = None
+ if not self.ParentWindow.Table.GetValueByName(row, "Edit"):
+ message = "Can't affect a location to a function block instance"
+ elif self.ParentWindow.Table.GetValueByName(row, "Class") not in ["Local", "Global"]:
+ message = "Can affect a location only to local or global variables"
+ else:
+ try:
+ values = eval(data)
+ except:
+ values = None
+ if values and values[1] == "location":
+ location = values[0]
+ variable_type = self.ParentWindow.Table.GetValueByName(row, "Type")
+ message = None
+ if location[0].isdigit() and variable_type != "BOOL":
+ message = "Incompatible size of data between \"%s\" and \"BOOL\""%location
+ elif location[0] not in LOCATIONDATATYPES:
+ message = "Unrecognized data size \"%s\""%location[0]
+ elif variable_type not in LOCATIONDATATYPES[location[0]]:
+ message = "Incompatible size of data between \"%s\" and \"%s\""%(location, variable_type)
else:
- location = "%M" + values[0]
- self.ParentWindow.Table.SetValue(row, col, location)
- self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
- self.ParentWindow.SaveValues()
- dialog.Destroy()
+ dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL)
+ if dialog.ShowModal() == wx.ID_OK:
+ selected = dialog.GetSelection()
+ if selected == 0:
+ location = "%I" + location
+ elif selected == 1:
+ location = "%Q" + location
+ else:
+ location = "%M" + location
+ self.ParentWindow.Table.SetValue(row, col, location)
+ self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
+ self.ParentWindow.SaveValues()
+ dialog.Destroy()
+ if message is not None:
+ message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
+ message.ShowModal()
+ message.Destroy()
[ID_POUEDITORPANEL, ID_POUEDITORPANELVIEWER,
ID_POUEDITORPANELVARIABLESGRID, ID_POUEDITORPANELRETURNTYPE,
@@ -2289,6 +2361,8 @@
'Sans'))
self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
False, 'Sans'))
+ self.VariablesGrid.SetSelectionBackground(wx.WHITE)
+ self.VariablesGrid.SetSelectionForeground(wx.BLACK)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
@@ -2393,6 +2467,23 @@
self.VariablesGrid.SetTable(self.Table)
self.VariablesGrid.SetRowLabelSize(0)
+ for col in range(self.Table.GetNumberCols()):
+ attr = wx.grid.GridCellAttr()
+ attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
+ self.VariablesGrid.SetColAttr(col, attr)
+ self.VariablesGrid.SetColSize(col, self.ColSizes[col])
+
+ def RefreshName(self, name_type, old_name, new_name):
+ if name_type == ITEM_POU and self.PouName == old_name:
+ self.PouName = new_name
+ elif name_type == ITEM_TRANSITION and self.TransitionName == old_name:
+ self.TransitionName = new_name
+ elif name_type == ITEM_ACTION and self.ActionName == old_name:
+ self.ActionName = new_name
+ elif name_type == ITEM_CONFIGURATION and self.ConfigName == old_name:
+ self.ConfigName = new_name
+ elif name_type == ITEM_RESOURCE and self.ResourceName == old_name:
+ self.ResourceName = new_name
def SetMode(self, mode):
if self.ElementType not in ["resource", "config"]:
@@ -2552,6 +2643,8 @@
event.Skip()
else:
self.SaveValues()
+ if colname == "Class":
+ self.Table.ResetView(self.VariablesGrid)
event.Skip()
def OnVariablesGridCellLeftClick(self, event):