--- a/Beremiz.py Mon May 26 14:44:03 2014 +0100
+++ b/Beremiz.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of Beremiz, a Integrated Development Environment for
-#programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -43,7 +43,7 @@
def usage():
print "\nUsage of Beremiz.py :"
print "\n %s [Projectpath] [Buildpath]\n"%sys.argv[0]
-
+
try:
opts, args = getopt.getopt(sys.argv[1:], "hu:e:", ["help", "updatecheck=", "extend="])
except getopt.GetoptError:
@@ -52,7 +52,7 @@
sys.exit(2)
extensions=[]
-
+
for o, a in opts:
if o in ("-h", "--help"):
usage()
@@ -61,7 +61,7 @@
updateinfo_url = a
if o in ("-e", "--extend"):
extensions.append(a)
-
+
if len(args) > 2:
usage()
sys.exit()
@@ -74,7 +74,7 @@
else:
projectOpen = None
buildpath = None
-
+
if os.path.exists("BEREMIZ_DEBUG"):
__builtin__.__dict__["BMZ_DBG"] = True
else :
@@ -83,7 +83,7 @@
app = wx.PySimpleApp(redirect=BMZ_DBG)
app.SetAppName('beremiz')
wx.InitAllImageHandlers()
-
+
# popup splash
bmp = wx.Image(Bpath("images", "splash.png")).ConvertToBitmap()
#splash=AdvancedSplash(None, bitmap=bmp, style=wx.SPLASH_CENTRE_ON_SCREEN, timeout=4000)
@@ -99,8 +99,8 @@
import urllib2
updateinfo = urllib2.urlopen(updateinfo_url,None).read()
except :
- updateinfo = "update info unavailable."
-
+ updateinfo = "update info unavailable."
+
from threading import Thread
splash.SetText(text=updateinfo)
wx.Yield()
@@ -222,15 +222,15 @@
if style is None : style=self.black_white
if style != self.black_white:
self.output.StartStyling(self.output.GetLength(), 0xff)
-
+
# Temporary deactivate read only mode on StyledTextCtrl for
- # adding text. It seems that text modifications, even
+ # adding text. It seems that text modifications, even
# programmatically, are disabled in StyledTextCtrl when read
- # only is active
+ # only is active
self.output.SetReadOnly(False)
self.output.AppendText(s)
self.output.SetReadOnly(True)
-
+
if style != self.black_white:
self.output.SetStyling(len(s), style)
self.stack = []
@@ -245,7 +245,7 @@
if newtime - self.rising_timer > 1:
self.risecall(self.output)
self.rising_timer = newtime
-
+
def write_warning(self, s):
self.write(s,self.red_white)
@@ -259,11 +259,11 @@
def flush(self):
# Temporary deactivate read only mode on StyledTextCtrl for clearing
# text. It seems that text modifications, even programmatically, are
- # disabled in StyledTextCtrl when read only is active
+ # disabled in StyledTextCtrl when read only is active
self.output.SetReadOnly(False)
self.output.SetText("")
self.output.SetReadOnly(True)
-
+
def isatty(self):
return False
@@ -284,13 +284,13 @@
from util.BitmapLibrary import GetBitmap
class Beremiz(IDEFrame):
-
+
def _init_utils(self):
self.ConfNodeMenu = wx.Menu(title='')
self.RecentProjectsMenu = wx.Menu(title='')
-
+
IDEFrame._init_utils(self)
-
+
def _init_coll_FileMenu_Items(self, parent):
AppendMenu(parent, help='', id=wx.ID_NEW,
kind=wx.ITEM_NORMAL, text=_(u'New') + '\tCTRL+N')
@@ -316,7 +316,7 @@
parent.AppendSeparator()
AppendMenu(parent, help='', id=wx.ID_EXIT,
kind=wx.ITEM_NORMAL, text=_(u'Quit') + '\tCTRL+Q')
-
+
self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
@@ -327,13 +327,13 @@
self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
-
+
self.AddToMenuToolBar([(wx.ID_NEW, "new", _(u'New'), None),
(wx.ID_OPEN, "open", _(u'Open'), None),
(wx.ID_SAVE, "save", _(u'Save'), None),
(wx.ID_SAVEAS, "saveas", _(u'Save As...'), None),
(wx.ID_PRINT, "print", _(u'Print'), None)])
-
+
def _RecursiveAddMenuItems(self, menu, items):
for name, text, help, children in items:
new_id = wx.NewId()
@@ -342,20 +342,20 @@
menu.AppendMenu(new_id, text, new_menu)
self._RecursiveAddMenuItems(new_menu, children)
else:
- AppendMenu(menu, help=help, id=new_id,
+ AppendMenu(menu, help=help, id=new_id,
kind=wx.ITEM_NORMAL, text=text)
- self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name),
- id=new_id)
-
+ self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name),
+ id=new_id)
+
def _init_coll_AddMenu_Items(self, parent):
IDEFrame._init_coll_AddMenu_Items(self, parent, False)
self._RecursiveAddMenuItems(parent, GetAddMenuItems())
-
+
def _init_coll_HelpMenu_Items(self, parent):
parent.Append(help='', id=wx.ID_ABOUT,
kind=wx.ITEM_NORMAL, text=_(u'About'))
self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT)
-
+
def _init_coll_ConnectionStatusBar_Fields(self, parent):
parent.SetFieldsCount(3)
@@ -364,12 +364,12 @@
parent.SetStatusText(number=2, text='')
parent.SetStatusWidths([-1, 300, 200])
-
+
def _init_ctrls(self, prnt):
IDEFrame._init_ctrls(self, prnt)
-
+
self.EditMenuSize = self.EditMenu.GetMenuItemCount()
-
+
inspectorID = wx.NewId()
self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, id=inspectorID)
accels = [wx.AcceleratorEntry(wx.ACCEL_CTRL|wx.ACCEL_ALT, ord('I'), inspectorID)]
@@ -387,9 +387,9 @@
newid = wx.NewId()
self.Bind(wx.EVT_MENU, OnMethodGen(self,method), id=newid)
accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, shortcut,newid)]
-
+
self.SetAcceleratorTable(wx.AcceleratorTable(accels))
-
+
self.LogConsole = CustomStyledTextCtrl(
name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
size=wx.Size(0, 0))
@@ -398,32 +398,32 @@
self.LogConsole.Bind(wx.stc.EVT_STC_UPDATEUI, self.OnLogConsoleUpdateUI)
self.LogConsole.SetReadOnly(True)
self.LogConsole.SetWrapMode(wx.stc.STC_WRAP_CHAR)
-
+
# Define Log Console styles
self.LogConsole.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
self.LogConsole.StyleClearAll()
self.LogConsole.StyleSetSpec(1, "face:%(mono)s,fore:#FF0000,size:%(size)d" % faces)
self.LogConsole.StyleSetSpec(2, "face:%(mono)s,fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
-
+
# Define Log Console markers
self.LogConsole.SetMarginSensitive(1, True)
self.LogConsole.SetMarginType(1, wx.stc.STC_MARGIN_SYMBOL)
self.LogConsole.MarkerDefine(0, wx.stc.STC_MARK_CIRCLE, "BLACK", "RED")
-
+
self.LogConsole.SetModEventMask(wx.stc.STC_MOD_INSERTTEXT)
-
+
self.LogConsole.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnLogConsoleMarginClick)
self.LogConsole.Bind(wx.stc.EVT_STC_MODIFIED, self.OnLogConsoleModified)
-
+
self.MainTabs["LogConsole"] = (self.LogConsole, _("Console"))
self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
#self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
-
+
self.LogViewer = LogViewer(self.BottomNoteBook, self)
self.MainTabs["LogViewer"] = (self.LogViewer, _("PLC Log"))
self.BottomNoteBook.AddPage(*self.MainTabs["LogViewer"])
#self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogViewer), wx.RIGHT)
-
+
StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
@@ -433,27 +433,27 @@
Name("StatusToolBar").Caption(_("Status ToolBar")).
ToolbarPane().Top().Position(1).
LeftDockable(False).RightDockable(False))
-
+
self.AUIManager.Update()
-
+
self.ConnectionStatusBar = wx.StatusBar(self, style=wx.ST_SIZEGRIP)
self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar)
self.SetStatusBar(self.ConnectionStatusBar)
-
+
def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
IDEFrame.__init__(self, parent, debug)
self.Log = LogPseudoFile(self.LogConsole,self.SelectTab)
-
+
self.local_runtime = None
self.runtime_port = None
self.local_runtime_tmpdir = None
-
+
self.LastPanelSelected = None
-
+
# Define Tree item icon list
self.LocationImageList = wx.ImageList(16, 16)
self.LocationImageDict = {}
-
+
# Icons for location items
for imgname, itemtype in [
("CONFIGURATION", LOCATION_CONFNODE),
@@ -463,18 +463,18 @@
("VAR_OUTPUT", LOCATION_VAR_OUTPUT),
("VAR_LOCAL", LOCATION_VAR_MEMORY)]:
self.LocationImageDict[itemtype] = self.LocationImageList.Add(GetBitmap(imgname))
-
+
# Icons for other items
for imgname, itemtype in [
("Extension", ITEM_CONFNODE)]:
self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
-
+
# Add beremiz's icon in top left corner of the frame
self.SetIcon(wx.Icon(Bpath("images", "brz.ico"), wx.BITMAP_TYPE_ICO))
-
+
if projectOpen is not None:
projectOpen = DecodeFileSystemPath(projectOpen, False)
-
+
if projectOpen is not None and os.path.isdir(projectOpen):
self.CTR = ProjectController(self, self.Log)
self.Controler = self.CTR
@@ -498,9 +498,9 @@
self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
if self.EnableDebug:
self.DebugVariablePanel.SetDataProducer(self.CTR)
-
+
self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
-
+
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
self.RefreshAll()
self.LogConsole.SetFocus()
@@ -534,14 +534,14 @@
cwd = self.local_runtime_tmpdir)
self.local_runtime.spin()
return self.runtime_port
-
+
def KillLocalRuntime(self):
if self.local_runtime is not None:
# shutdown local runtime
self.local_runtime.kill(gently=False)
# clear temp dir
shutil.rmtree(self.local_runtime_tmpdir)
-
+
self.local_runtime = None
def OnOpenWidgetInspector(self, evt):
@@ -569,7 +569,7 @@
line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
wx.CallAfter(self.SearchLineForError, self.LogConsole.GetLine(line_idx))
event.Skip()
-
+
def OnLogConsoleModified(self, event):
line_idx = self.LogConsole.LineFromPosition(event.GetPosition())
line = self.LogConsole.GetLine(line_idx)
@@ -585,9 +585,9 @@
if result is not None:
first_line, first_column, last_line, last_column, error = result.groups()
infos = self.CTR.ShowError(self.Log,
- (int(first_line), int(first_column)),
+ (int(first_line), int(first_column)),
(int(last_line), int(last_column)))
-
+
## Function displaying an Error dialog in PLCOpenEditor.
# @return False if closing cancelled.
def CheckSaveBeforeClosing(self, title=_("Close Project")):
@@ -602,28 +602,28 @@
self.CTR.SaveProject()
elif answer == wx.ID_CANCEL:
return False
-
+
for idx in xrange(self.TabsOpened.GetPageCount()):
window = self.TabsOpened.GetPage(idx)
if not window.CheckSaveBeforeClosing():
return False
-
+
return True
-
+
def GetTabInfos(self, tab):
- if (isinstance(tab, EditorPanel) and
- not isinstance(tab, (Viewer,
- TextViewer,
- ResourceEditor,
- ConfigurationEditor,
+ if (isinstance(tab, EditorPanel) and
+ not isinstance(tab, (Viewer,
+ TextViewer,
+ ResourceEditor,
+ ConfigurationEditor,
DataTypeEditor))):
return ("confnode", tab.Controler.CTNFullName(), tab.GetTagName())
- elif (isinstance(tab, TextViewer) and
+ elif (isinstance(tab, TextViewer) and
(tab.Controler is None or isinstance(tab.Controler, MiniTextControler))):
return ("confnode", None, tab.GetInstancePath())
else:
return IDEFrame.GetTabInfos(self, tab)
-
+
def LoadTab(self, notebook, page_infos):
if page_infos[0] == "confnode":
if page_infos[1] is None:
@@ -633,26 +633,26 @@
return notebook.GetPageIndex(confnode._OpenView(*page_infos[2:]))
else:
return IDEFrame.LoadTab(self, notebook, page_infos)
-
+
def OnCloseFrame(self, event):
- for evt_type in [wx.EVT_SET_FOCUS,
- wx.EVT_KILL_FOCUS,
+ for evt_type in [wx.EVT_SET_FOCUS,
+ wx.EVT_KILL_FOCUS,
wx.stc.EVT_STC_UPDATEUI]:
self.LogConsole.Unbind(evt_type)
if self.CTR is None or self.CheckSaveBeforeClosing(_("Close Application")):
if self.CTR is not None:
self.CTR.KillDebugThread()
self.KillLocalRuntime()
-
+
self.SaveLastState()
-
+
event.Skip()
else:
event.Veto()
-
+
def RefreshFileMenu(self):
self.RefreshRecentProjectsMenu()
-
+
MenuToolBar = self.Panes["MenuToolBar"]
if self.CTR is not None:
selected = self.TabsOpened.GetSelection()
@@ -695,17 +695,17 @@
self.FileMenu.Enable(wx.ID_SAVEAS, False)
MenuToolBar.EnableTool(wx.ID_SAVEAS, False)
self.FileMenu.Enable(wx.ID_CLOSE_ALL, False)
-
+
def RefreshRecentProjectsMenu(self):
try:
- recent_projects = map(DecodeFileSystemPath,
+ recent_projects = map(DecodeFileSystemPath,
self.GetConfigEntry("RecentProjects", []))
except:
recent_projects = []
self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0)
for idx, projectpath in enumerate(recent_projects):
text = u'%d: %s' % (idx + 1, projectpath)
-
+
if idx < self.RecentProjectsMenu.GetMenuItemCount():
item = self.RecentProjectsMenu.FindItemByPosition(idx)
id = item.GetId()
@@ -713,18 +713,18 @@
self.Disconnect(id, id, wx.EVT_BUTTON._getEvtType())
else:
id = wx.NewId()
- AppendMenu(self.RecentProjectsMenu, help='', id=id,
+ AppendMenu(self.RecentProjectsMenu, help='', id=id,
kind=wx.ITEM_NORMAL, text=text)
self.Bind(wx.EVT_MENU, self.GenerateOpenRecentProjectFunction(projectpath), id=id)
-
+
def GenerateOpenRecentProjectFunction(self, projectpath):
def OpenRecentProject(event):
if self.CTR is not None and not self.CheckSaveBeforeClosing():
return
-
+
self.OpenProject(projectpath)
return OpenRecentProject
-
+
def GenerateMenuRecursive(self, items, menu):
for kind, infos in items:
if isinstance(kind, ListType):
@@ -739,27 +739,27 @@
AppendMenu(menu, help='', id=id, kind=kind, text=text)
if callback is not None:
self.Bind(wx.EVT_MENU, callback, id=id)
-
+
def RefreshEditorToolBar(self):
IDEFrame.RefreshEditorToolBar(self)
self.AUIManager.GetPane("EditorToolBar").Position(2)
self.AUIManager.GetPane("StatusToolBar").Position(1)
self.AUIManager.Update()
-
+
def RefreshStatusToolBar(self):
StatusToolBar = self.Panes["StatusToolBar"]
StatusToolBar.ClearTools()
-
+
if self.CTR is not None:
-
+
for confnode_method in self.CTR.StatusMethods:
if "method" in confnode_method and confnode_method.get("shown",True):
id = wx.NewId()
- StatusToolBar.AddSimpleTool(id,
- GetBitmap(confnode_method.get("bitmap", "Unknown")),
+ StatusToolBar.AddSimpleTool(id,
+ GetBitmap(confnode_method.get("bitmap", "Unknown")),
confnode_method["tooltip"])
self.Bind(wx.EVT_MENU, self.GetMenuCallBackFunction(confnode_method["method"]), id=id)
-
+
StatusToolBar.Realize()
self.AUIManager.GetPane("StatusToolBar").BestSize(StatusToolBar.GetBestSize()).Show()
else:
@@ -767,13 +767,13 @@
self.AUIManager.GetPane("EditorToolBar").Position(2)
self.AUIManager.GetPane("StatusToolBar").Position(1)
self.AUIManager.Update()
-
+
def RefreshEditMenu(self):
IDEFrame.RefreshEditMenu(self)
if self.FindFocus() == self.LogConsole:
self.EditMenu.Enable(wx.ID_COPY, True)
self.Panes["MenuToolBar"].EnableTool(wx.ID_COPY, True)
-
+
if self.CTR is not None:
selected = self.TabsOpened.GetSelection()
if selected >= 0:
@@ -808,28 +808,28 @@
self.EditMenu.Delete(item.GetId())
self.LastPanelSelected = None
self.MenuBar.UpdateMenus()
-
+
def RefreshAll(self):
self.RefreshStatusToolBar()
-
+
def GetMenuCallBackFunction(self, method):
""" Generate the callbackfunc for a given CTR method"""
def OnMenu(event):
- # Disable button to prevent re-entrant call
+ # Disable button to prevent re-entrant call
event.GetEventObject().Disable()
# Call
getattr(self.CTR, method)()
- # Re-enable button
+ # Re-enable button
event.GetEventObject().Enable()
return OnMenu
-
+
def GetConfigEntry(self, entry_name, default):
return cPickle.loads(str(self.Config.Read(entry_name, cPickle.dumps(default))))
-
+
def ResetConnectionStatusBar(self):
for field in xrange(self.ConnectionStatusBar.GetFieldsCount()):
self.ConnectionStatusBar.SetStatusText('', field)
-
+
def ResetView(self):
IDEFrame.ResetView(self)
self.ConfNodeInfos = {}
@@ -840,10 +840,10 @@
if self.EnableDebug:
self.DebugVariablePanel.SetDataProducer(None)
self.ResetConnectionStatusBar()
-
+
def RefreshConfigRecentProjects(self, projectpath):
try:
- recent_projects = map(DecodeFileSystemPath,
+ recent_projects = map(DecodeFileSystemPath,
self.GetConfigEntry("RecentProjects", []))
except:
recent_projects = []
@@ -853,24 +853,24 @@
self.Config.Write("RecentProjects", cPickle.dumps(
map(EncodeFileSystemPath, recent_projects[:MAX_RECENT_PROJECTS])))
self.Config.Flush()
-
+
def ResetPerspective(self):
IDEFrame.ResetPerspective(self)
self.RefreshStatusToolBar()
-
+
def OnNewProjectMenu(self, event):
if self.CTR is not None and not self.CheckSaveBeforeClosing():
return
-
+
try:
defaultpath = DecodeFileSystemPath(self.Config.Read("lastopenedfolder"))
except:
defaultpath = os.path.expanduser("~")
-
+
dialog = wx.DirDialog(self , _("Choose a project"), defaultpath)
if dialog.ShowModal() == wx.ID_OK:
projectpath = dialog.GetPath()
- self.Config.Write("lastopenedfolder",
+ self.Config.Write("lastopenedfolder",
EncodeFileSystemPath(os.path.dirname(projectpath)))
self.Config.Flush()
self.ResetView()
@@ -892,25 +892,25 @@
self.RefreshAll()
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
dialog.Destroy()
-
+
def OnOpenProjectMenu(self, event):
if self.CTR is not None and not self.CheckSaveBeforeClosing():
return
-
+
try:
defaultpath = DecodeFileSystemPath(self.Config.Read("lastopenedfolder"))
except:
defaultpath = os.path.expanduser("~")
-
+
dialog = wx.DirDialog(self , _("Choose a project"), defaultpath, style=wx.DEFAULT_DIALOG_STYLE|
wx.RESIZE_BORDER)
if dialog.ShowModal() == wx.ID_OK:
self.OpenProject(dialog.GetPath())
dialog.Destroy()
-
+
def OpenProject(self, projectpath):
if os.path.isdir(projectpath):
- self.Config.Write("lastopenedfolder",
+ self.Config.Write("lastopenedfolder",
EncodeFileSystemPath(os.path.dirname(projectpath)))
self.Config.Flush()
self.ResetView()
@@ -932,15 +932,15 @@
else:
self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath)
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
-
+
def OnCloseProjectMenu(self, event):
if self.CTR is not None and not self.CheckSaveBeforeClosing():
return
-
+
self.ResetView()
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
self.RefreshAll()
-
+
def OnSaveProjectMenu(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
@@ -950,7 +950,7 @@
self.CTR.SaveProject()
self.RefreshAll()
self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
-
+
def OnSaveProjectAsMenu(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
@@ -960,27 +960,27 @@
self.CTR.SaveProjectAs()
self.RefreshAll()
self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
-
+
def OnQuitMenu(self, event):
self.Close()
-
+
def OnAboutMenu(self, event):
OpenHtmlFrame(self,_("About Beremiz"), Bpath("doc", "about.html"), wx.Size(550, 500))
-
+
def OnProjectTreeItemBeginEdit(self, event):
selected = event.GetItem()
if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFNODE:
event.Veto()
else:
IDEFrame.OnProjectTreeItemBeginEdit(self, event)
-
+
def OnProjectTreeRightUp(self, event):
item = event.GetItem()
item_infos = self.ProjectTree.GetPyData(item)
-
+
if item_infos["type"] == ITEM_CONFNODE:
confnode_menu = wx.Menu(title='')
-
+
confnode = item_infos["confnode"]
if confnode is not None:
menu_items = confnode.GetContextualMenuItems()
@@ -998,10 +998,10 @@
new_id = wx.NewId()
AppendMenu(confnode_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
self.Bind(wx.EVT_MENU, self.GetDeleteMenuFunction(confnode), id=new_id)
-
+
self.PopupMenu(confnode_menu)
confnode_menu.Destroy()
-
+
event.Skip()
elif item_infos["type"] == ITEM_RESOURCE:
# prevent last resource to be delted
@@ -1011,7 +1011,7 @@
IDEFrame.OnProjectTreeRightUp(self, event)
else:
IDEFrame.OnProjectTreeRightUp(self, event)
-
+
def OnProjectTreeItemActivated(self, event):
selected = event.GetItem()
name = self.ProjectTree.GetItemText(selected)
@@ -1023,7 +1023,7 @@
self.CTR._OpenView()
else:
IDEFrame.OnProjectTreeItemActivated(self, event)
-
+
def ProjectTreeItemSelect(self, select_item):
if select_item is not None and select_item.IsOk():
name = self.ProjectTree.GetItemText(select_item)
@@ -1034,7 +1034,7 @@
self.CTR._OpenView(onlyopened=True)
else:
IDEFrame.ProjectTreeItemSelect(self, select_item)
-
+
def SelectProjectTreeItem(self, tagname):
if self.ProjectTree is not None:
root = self.ProjectTree.GetRootItem()
@@ -1046,31 +1046,23 @@
self.ProjectTree.SelectItem(root)
self.ResetSelectedItem()
else:
- return self.RecursiveProjectTreeItemSelection(root,
+ return self.RecursiveProjectTreeItemSelection(root,
[(word, ITEM_CONFNODE) for word in tagname.split(".")])
elif words[0] == "R":
return self.RecursiveProjectTreeItemSelection(root, [(words[2], ITEM_RESOURCE)])
elif not os.path.exists(words[0]):
IDEFrame.SelectProjectTreeItem(self, tagname)
-
+
def GetAddConfNodeFunction(self, name, confnode=None):
def AddConfNodeMenuFunction(event):
wx.CallAfter(self.AddConfNode, name, confnode)
return AddConfNodeMenuFunction
-
+
def GetDeleteMenuFunction(self, confnode):
def DeleteMenuFunction(event):
wx.CallAfter(self.DeleteConfNode, confnode)
return DeleteMenuFunction
-
- def AddResourceMenu(self, event):
- config_names = self.CTR.GetProjectConfigNames()
- if len(config_names) > 0:
- tagname = self.Controler.ProjectAddConfigurationResource(config_names[0])
- if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
- self.EditProjectElement(ITEM_RESOURCE, tagname)
-
+
def AddConfNode(self, ConfNodeType, confnode=None):
if self.CTR.CheckProjectPathPerm():
ConfNodeName = "%s_0" % ConfNodeType
@@ -1079,12 +1071,12 @@
else:
self.CTR.CTNAddChild(ConfNodeName, ConfNodeType)
self._Refresh(TITLE, FILEMENU, PROJECTTREE)
-
+
def DeleteConfNode(self, confnode):
if self.CTR.CheckProjectPathPerm():
- dialog = wx.MessageDialog(self,
- _("Really delete node '%s'?") % confnode.CTNName(),
- _("Remove %s node") % confnode.CTNType,
+ dialog = wx.MessageDialog(self,
+ _("Really delete node '%s'?") % confnode.CTNName(),
+ _("Remove %s node") % confnode.CTNType,
wx.YES_NO|wx.NO_DEFAULT)
if dialog.ShowModal() == wx.ID_YES:
confnode.CTNRemove()
@@ -1124,13 +1116,13 @@
trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
trcbck_lst.append(trcbck)
-
+
# Allow clicking....
cap = wx.Window_GetCapture()
if cap:
cap.ReleaseMouse()
- dlg = wx.SingleChoiceDialog(None,
+ dlg = wx.SingleChoiceDialog(None,
_("""
An unhandled exception (bug) occured. Bug report saved at :
(%s)
@@ -1142,7 +1134,7 @@
Traceback:
""") % bug_report_path +
- repr(e_type) + " : " + repr(e_value),
+ repr(e_type) + " : " + repr(e_value),
_("Error"),
trcbck_lst)
try:
@@ -1165,7 +1157,7 @@
ignored_exceptions = [] # a problem with a line in a module is only reported once per session
def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
-
+
def handle_exception(e_type, e_value, e_traceback):
traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
last_tb = get_last_traceback(e_traceback)
@@ -1198,7 +1190,7 @@
info['self'] = format_namespace(exception_locals['self'].__dict__)
except :
pass
-
+
output = open(bug_report_path,'w')
lst = info.keys()
lst.sort()
@@ -1225,7 +1217,7 @@
if __name__ == '__main__':
# Install a exception handle for bug reports
AddExceptHook(os.getcwd(),updateinfo_url)
-
+
frame = Beremiz(None, projectOpen, buildpath)
if splash:
splash.Close()
--- a/IDEFrame.py Mon May 26 14:44:03 2014 +0100
+++ b/IDEFrame.py Fri Jun 06 18:30:49 2014 +0100
@@ -20,27 +20,27 @@
from util.BitmapLibrary import GetBitmap
# Define PLCOpenEditor controls id
-[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK,
- ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK,
- ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER,
- ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER,
- ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL,
- ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT,
- ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED,
- ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR,
- ID_PLCOPENEDITORPROJECTPANEL,
+[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK,
+ ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK,
+ ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER,
+ ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER,
+ ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL,
+ ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT,
+ ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED,
+ ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR,
+ ID_PLCOPENEDITORPROJECTPANEL,
] = [wx.NewId() for _init_ctrls in range(17)]
# Define PLCOpenEditor EditMenu extra items id
-[ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE,
- ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
+[ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE,
+ ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
ID_PLCOPENEDITOREDITMENUFINDNEXT, ID_PLCOPENEDITOREDITMENUFINDPREVIOUS,
ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, ID_PLCOPENEDITOREDITMENUADDRESOURCE
] = [wx.NewId() for _init_coll_EditMenu_Items in range(10)]
# Define PLCOpenEditor DisplayMenu extra items id
-[ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
+[ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(1)]
#-------------------------------------------------------------------------------
@@ -56,12 +56,12 @@
ID_PLCOPENEDITOREDITORTOOLBARBRANCH, ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP,
ID_PLCOPENEDITOREDITORTOOLBARSTEP, ID_PLCOPENEDITOREDITORTOOLBARTRANSITION,
ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE,
- ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION,
+ ID_PLCOPENEDITOREDITORTOOLBARJUMP, ID_PLCOPENEDITOREDITORTOOLBARMOTION,
] = [wx.NewId() for _init_coll_DefaultEditorToolBar_Items in range(18)]
-# Define behaviour of each Toolbar item according to current POU body type
+# Define behaviour of each Toolbar item according to current POU body type
# Informations meaning are in this order:
# - Item is toggled
# - PLCOpenEditor mode where item is displayed (could be more then one)
@@ -82,77 +82,77 @@
(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
"add_block", _("Create a new block")),
- (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
+ (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
"add_connection", _("Create a new connection"))],
"LD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool",
"move", _("Move the view")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
"add_comment", _("Create a new comment")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
"add_powerrail", _("Create a new power rail")),
- (False, DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool",
+ (False, DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARRUNG, "OnRungTool",
"add_rung", _("Create a new rung")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCOIL, "OnCoilTool",
"add_coil", _("Create a new coil")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
"add_contact", _("Create a new contact")),
- (False, DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool",
+ (False, DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARBRANCH, "OnBranchTool",
"add_branch", _("Create a new branch")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
"add_variable", _("Create a new variable")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
"add_block", _("Create a new block")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
"add_connection", _("Create a new connection"))],
"SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
ID_PLCOPENEDITOREDITORTOOLBARMOTION, "OnMotionTool",
"move", _("Move the view")),
- (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
+ (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCOMMENT, "OnCommentTool",
"add_comment", _("Create a new comment")),
- (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool",
+ (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP, "OnInitialStepTool",
"add_initial_step", _("Create a new initial step")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARSTEP, "OnStepTool",
"add_step", _("Create a new step")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARTRANSITION, "OnTransitionTool",
"add_transition", _("Create a new transition")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK, "OnActionBlockTool",
"add_action", _("Create a new action block")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE, "OnDivergenceTool",
"add_divergence", _("Create a new divergence")),
- (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool",
+ (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARJUMP, "OnJumpTool",
"add_jump", _("Create a new jump")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARVARIABLE, "OnVariableTool",
"add_variable", _("Create a new variable")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARBLOCK, "OnBlockTool",
"add_block", _("Create a new block")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCONNECTION, "OnConnectionTool",
"add_connection", _("Create a new connection")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL, "OnPowerRailTool",
"add_powerrail", _("Create a new power rail")),
- (True, FREEDRAWING_MODE,
- ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
+ (True, FREEDRAWING_MODE,
+ ID_PLCOPENEDITOREDITORTOOLBARCONTACT, "OnContactTool",
"add_contact", _("Create a new contact"))],
"ST" : [],
"IL" : [],
@@ -185,7 +185,7 @@
else:
parent.Append(helpString=help, id=id, kind=kind, item=text)
-[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
+[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
] = range(10)
@@ -225,33 +225,33 @@
others = [t for t in tabs if t != tab]
others.sort(lambda x,y: cmp(x["pos"][0], y["pos"][0]))
for other in others:
- if (other["pos"][1] == tab["pos"][1] and
+ if (other["pos"][1] == tab["pos"][1] and
other["size"][1] == tab["size"][1] and
other["pos"][0] == tab["pos"][0] + tab["size"][0] + TAB_BORDER):
-
+
tab["size"] = (tab["size"][0] + other["size"][0] + TAB_BORDER, tab["size"][1])
tab["pages"].extend(other["pages"])
tabs.remove(other)
-
+
if tab["size"][0] == rect.width:
return True
-
+
elif tab["pos"][1] == rect.y:
others = [t for t in tabs if t != tab]
others.sort(lambda x,y: cmp(x["pos"][1], y["pos"][1]))
for other in others:
- if (other["pos"][0] == tab["pos"][0] and
+ if (other["pos"][0] == tab["pos"][0] and
other["size"][0] == tab["size"][0] and
other["pos"][1] == tab["pos"][1] + tab["size"][1] + TAB_BORDER):
-
+
tab["size"] = (tab["size"][0], tab["size"][1] + other["size"][1] + TAB_BORDER)
tab["pages"].extend(other["pages"])
tabs.remove(other)
-
+
if tab["size"][1] == rect.height:
return True
return False
-
+
def ComputeTabsLayout(tabs, rect):
if len(tabs) == 0:
return tabs
@@ -264,27 +264,27 @@
if tab["size"][0] == rect.width:
if tab["pos"][1] == rect.y:
split = (wx.TOP, float(tab["size"][1]) / float(rect.height))
- split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER,
+ split_rect = wx.Rect(rect.x, rect.y + tab["size"][1] + TAB_BORDER,
rect.width, rect.height - tab["size"][1] - TAB_BORDER)
elif tab["pos"][1] == rect.height + 1 - tab["size"][1]:
split = (wx.BOTTOM, 1.0 - float(tab["size"][1]) / float(rect.height))
- split_rect = wx.Rect(rect.x, rect.y,
+ split_rect = wx.Rect(rect.x, rect.y,
rect.width, rect.height - tab["size"][1] - TAB_BORDER)
break
elif tab["size"][1] == rect.height:
if tab["pos"][0] == rect.x:
split = (wx.LEFT, float(tab["size"][0]) / float(rect.width))
- split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y,
+ split_rect = wx.Rect(rect.x + tab["size"][0] + TAB_BORDER, rect.y,
rect.width - tab["size"][0] - TAB_BORDER, rect.height)
elif tab["pos"][0] == rect.width + 1 - tab["size"][0]:
split = (wx.RIGHT, 1.0 - float(tab["size"][0]) / float(rect.width))
- split_rect = wx.Rect(rect.x, rect.y,
+ split_rect = wx.Rect(rect.x, rect.y,
rect.width - tab["size"][0] - TAB_BORDER, rect.height)
break
if split != None:
split_tab = tabs.pop(idx)
return {"split": split,
- "tab": split_tab,
+ "tab": split_tab,
"others": ComputeTabsLayout(tabs, split_rect)}
else:
if SimplifyTabLayout(tabs, rect):
@@ -298,7 +298,7 @@
UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES])
class IDEFrame(wx.Frame):
-
+
# Compatibility function for wx versions < 2.6
if wx.VERSION < (2, 6, 0):
def Bind(self, event, function, id = None):
@@ -306,7 +306,7 @@
event(self, id, function)
else:
event(self, function)
-
+
def _init_coll_MenuBar_Menus(self, parent):
parent.Append(menu=self.FileMenu, title=_(u'&File'))
parent.Append(menu=self.EditMenu, title=_(u'&Edit'))
@@ -315,7 +315,7 @@
def _init_coll_FileMenu_Items(self, parent):
pass
-
+
def _init_coll_AddMenu_Items(self, parent, add_config=True):
AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
kind=wx.ITEM_NORMAL, text=_(u'&Data Type'))
@@ -330,7 +330,7 @@
if add_config:
AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
kind=wx.ITEM_NORMAL, text=_(u'&Configuration'))
-
+
def _init_coll_EditMenu_Items(self, parent):
AppendMenu(parent, help='', id=wx.ID_UNDO,
kind=wx.ITEM_NORMAL, text=_(u'Undo') + '\tCTRL+Z')
@@ -371,13 +371,13 @@
self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY)
self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE)
self.Bind(wx.EVT_MENU, self.OnFindMenu, id=wx.ID_FIND)
- self.Bind(wx.EVT_MENU, self.OnFindNextMenu,
+ self.Bind(wx.EVT_MENU, self.OnFindNextMenu,
id=ID_PLCOPENEDITOREDITMENUFINDNEXT)
- self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu,
+ self.Bind(wx.EVT_MENU, self.OnFindPreviousMenu,
id=ID_PLCOPENEDITOREDITMENUFINDPREVIOUS)
- self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
+ self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT)
- self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
+ self.Bind(wx.EVT_MENU, self.OnSearchInProjectMenu,
id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT)
self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu,
id=ID_PLCOPENEDITOREDITMENUADDDATATYPE)
@@ -387,13 +387,13 @@
id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK)
self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"),
id=ID_PLCOPENEDITOREDITMENUADDPROGRAM)
- self.Bind(wx.EVT_MENU, self.AddResourceMenu,
+ self.Bind(wx.EVT_MENU, self.AddResourceMenu,
id=ID_PLCOPENEDITOREDITMENUADDRESOURCE)
self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION)
self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL)
self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE)
-
+
self.AddToMenuToolBar([(wx.ID_UNDO, "undo", _(u'Undo'), None),
(wx.ID_REDO, "redo", _(u'Redo'), None),
None,
@@ -417,16 +417,16 @@
AppendMenu(zoommenu, help='', id=new_id,
kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%")
self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id)
-
+
parent.AppendSeparator()
AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective'))
self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE)
-
+
self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH)
if self.EnableDebug:
self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR)
-
+
def _init_coll_HelpMenu_Items(self, parent):
pass
@@ -437,7 +437,7 @@
self.EditMenu = wx.Menu(title='')
self.DisplayMenu = wx.Menu(title='')
self.HelpMenu = wx.Menu(title='')
-
+
self._init_coll_MenuBar_Menus(self.MenuBar)
self._init_coll_FileMenu_Items(self.FileMenu)
self._init_coll_EditMenu_Items(self.EditMenu)
@@ -450,49 +450,49 @@
style=wx.DEFAULT_FRAME_STYLE)
self.SetClientSize(wx.Size(1000, 600))
self.Bind(wx.EVT_ACTIVATE, self.OnActivated)
-
+
self.TabsImageList = wx.ImageList(31, 16)
self.TabsImageListIndexes = {}
-
+
#-----------------------------------------------------------------------
# Creating main structure
#-----------------------------------------------------------------------
-
+
self.AUIManager = wx.aui.AuiManager(self)
self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
self.Panes = {}
-
+
self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK,
style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.LeftNoteBook,
+ self.AUIManager.AddPane(self.LeftNoteBook,
wx.aui.AuiPaneInfo().Name("ProjectPane").
Left().Layer(1).
BestSize(wx.Size(300, 500)).CloseButton(False))
-
+
self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK,
style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.BottomNoteBook,
+ self.AUIManager.AddPane(self.BottomNoteBook,
wx.aui.AuiPaneInfo().Name("ResultPane").
Bottom().Layer(0).
BestSize(wx.Size(800, 300)).CloseButton(False))
-
+
self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK,
style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.RightNoteBook,
+ self.AUIManager.AddPane(self.RightNoteBook,
wx.aui.AuiPaneInfo().Name("LibraryPane").
Right().Layer(0).
BestSize(wx.Size(250, 400)).CloseButton(False))
-
- self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED,
+
+ self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED,
style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON)
self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING,
self.OnPouSelectedChanging)
@@ -502,21 +502,21 @@
self.OnPageClose)
self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG,
self.OnPageDragged)
- self.AUIManager.AddPane(self.TabsOpened,
+ self.AUIManager.AddPane(self.TabsOpened,
wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane"))
-
+
#-----------------------------------------------------------------------
# Creating PLCopen Project Types Tree
#-----------------------------------------------------------------------
-
+
self.MainTabs = {}
-
+
self.ProjectPanel = wx.SplitterWindow(id=ID_PLCOPENEDITORPROJECTPANEL,
name='ProjectPanel', parent=self.LeftNoteBook, point=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.SP_3D)
-
+
self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE,
- name='ProjectTree', parent=self.ProjectPanel,
+ name='ProjectTree', parent=self.ProjectPanel,
pos=wx.Point(0, 0), size=wx.Size(0, 0),
style=wx.SUNKEN_BORDER,
agwStyle=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.TR_EDIT_LABELS)
@@ -539,22 +539,22 @@
self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated,
id=ID_PLCOPENEDITORPROJECTTREE)
self.ProjectTree.Bind(wx.EVT_MOTION, self.OnProjectTreeMotion)
-
+
#-----------------------------------------------------------------------
# Creating PLCopen Project POU Instance Variables Panel
#-----------------------------------------------------------------------
-
+
self.PouInstanceVariablesPanel = PouInstanceVariablesPanel(self.ProjectPanel, self, self.Controler, self.EnableDebug)
-
+
self.MainTabs["ProjectPanel"] = (self.ProjectPanel, _("Project"))
self.LeftNoteBook.AddPage(*self.MainTabs["ProjectPanel"])
-
+
self.ProjectPanel.SplitHorizontally(self.ProjectTree, self.PouInstanceVariablesPanel, 300)
-
+
#-----------------------------------------------------------------------
# Creating Tool Bar
#-----------------------------------------------------------------------
-
+
MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
MenuToolBar.SetToolBitmapSize(wx.Size(25, 25))
@@ -564,11 +564,11 @@
Name("MenuToolBar").Caption(_("Menu ToolBar")).
ToolbarPane().Top().
LeftDockable(False).RightDockable(False))
-
+
EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
- EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
+ EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
GetBitmap("select"), wx.NullBitmap, _("Select an object"))
EditorToolBar.Realize()
self.Panes["EditorToolBar"] = EditorToolBar
@@ -576,39 +576,39 @@
Name("EditorToolBar").Caption(_("Editor ToolBar")).
ToolbarPane().Top().Position(1).
LeftDockable(False).RightDockable(False))
-
- self.Bind(wx.EVT_MENU, self.OnSelectionTool,
+
+ self.Bind(wx.EVT_MENU, self.OnSelectionTool,
id=ID_PLCOPENEDITOREDITORTOOLBARSELECTION)
-
+
#-----------------------------------------------------------------------
# Creating Search Panel
#-----------------------------------------------------------------------
-
+
self.SearchResultPanel = SearchResultPanel(self.BottomNoteBook, self)
self.MainTabs["SearchResultPanel"] = (self.SearchResultPanel, _("Search"))
self.BottomNoteBook.AddPage(*self.MainTabs["SearchResultPanel"])
-
+
#-----------------------------------------------------------------------
# Creating Library Panel
#-----------------------------------------------------------------------
-
+
self.LibraryPanel = LibraryPanel(self, True)
self.MainTabs["LibraryPanel"] = (self.LibraryPanel, _("Library"))
self.RightNoteBook.AddPage(*self.MainTabs["LibraryPanel"])
-
+
self._init_utils()
self.SetMenuBar(self.MenuBar)
-
+
if self.EnableDebug:
self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler, self)
self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger"))
self.RightNoteBook.AddPage(*self.MainTabs["DebugVariablePanel"])
-
+
self.AUIManager.Update()
-
+
self.FindDialog = FindInPouDialog(self)
self.FindDialog.Hide()
-
+
## Constructor of the PLCOpenEditor class.
# @param parent The parent window.
# @param controler The controler been used by PLCOpenEditor (default: None).
@@ -618,17 +618,17 @@
self.Controler = None
self.Config = wx.ConfigBase.Get()
self.EnableDebug = enable_debug
-
+
self._init_ctrls(parent)
-
+
# Define Tree item icon list
self.TreeImageList = wx.ImageList(16, 16)
self.TreeImageDict = {}
-
+
# Icons for languages
for language in LANGUAGES:
self.TreeImageDict[language] = self.TreeImageList.Add(GetBitmap(language))
-
+
# Icons for other items
for imgname, itemtype in [
#editables
@@ -658,11 +658,11 @@
("RESOURCES", ITEM_RESOURCES),
("PROPERTIES", ITEM_PROPERTIES)]:
self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
-
+
# Assign icon list to TreeCtrls
self.ProjectTree.SetImageList(self.TreeImageList)
self.PouInstanceVariablesPanel.SetTreeImageList(self.TreeImageList)
-
+
self.CurrentEditorToolBar = []
self.CurrentMenu = None
self.SelectedItem = None
@@ -672,7 +672,7 @@
self.DrawingMode = FREEDRAWING_MODE
#self.DrawingMode = DRIVENDRAWING_MODE
self.AuiTabCtrl = []
-
+
# Save default perspective
notebooks = {}
for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
@@ -683,8 +683,8 @@
"perspective": self.AUIManager.SavePerspective(),
"notebooks": notebooks,
}
-
-
+
+
# Initialize Printing configuring elements
self.PrintData = wx.PrintData()
self.PrintData.SetPaperId(wx.PAPER_A4)
@@ -692,17 +692,17 @@
self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
-
+
self.SetRefreshFunctions()
self.SetDeleteFunctions()
-
+
def __del__(self):
self.FindDialog.Destroy()
-
+
def Show(self):
wx.Frame.Show(self)
wx.CallAfter(self.RestoreLastState)
-
+
def OnActivated(self, event):
if event.GetActive():
wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
@@ -724,7 +724,7 @@
if page_ref == tab:
return ("main", page_name)
return None
-
+
def SaveTabLayout(self, notebook):
tabs = []
for child in notebook.GetChildren():
@@ -744,7 +744,7 @@
tabs.sort(lambda x, y: cmp(x["pos"], y["pos"]))
size = notebook.GetSize()
return ComputeTabsLayout(tabs, wx.Rect(1, 1, size[0] - NOTEBOOK_BORDER, size[1] - NOTEBOOK_BORDER))
-
+
def LoadTab(self, notebook, page_infos):
if page_infos[0] == "main":
infos = self.MainTabs.get(page_infos[1])
@@ -764,21 +764,21 @@
if instance_infos is not None:
return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"]))
return None
-
+
def LoadTabLayout(self, notebook, tabs, mode="all", first_index=None):
if isinstance(tabs, ListType):
if len(tabs) == 0:
return
raise ValueError, "Not supported"
-
+
if tabs.has_key("split"):
self.LoadTabLayout(notebook, tabs["others"])
-
+
split_dir, split_ratio = tabs["split"]
first_index = self.LoadTabLayout(notebook, tabs["tab"], mode="first")
notebook.Split(first_index, split_dir)
self.LoadTabLayout(notebook, tabs["tab"], mode="others", first_index=first_index)
-
+
elif mode == "first":
return self.LoadTab(notebook, tabs["pages"][0][0])
else:
@@ -793,39 +793,39 @@
selected = page_idx
if selected is not None:
wx.CallAfter(notebook.SetSelection, selected)
-
+
def ResetPerspective(self):
if self.DefaultPerspective is not None:
self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"])
-
+
for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]:
for idx in xrange(notebook.GetPageCount()):
notebook.RemovePage(0)
-
+
notebooks = self.DefaultPerspective["notebooks"]
for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
(self.BottomNoteBook, "bottomnotebook"),
(self.RightNoteBook, "rightnotebook")]:
self.LoadTabLayout(notebook, notebooks.get(entry_name))
-
+
self._Refresh(EDITORTOOLBAR)
-
+
def RestoreLastState(self):
frame_size = None
if self.Config.HasEntry("framesize"):
frame_size = cPickle.loads(str(self.Config.Read("framesize")))
-
+
if frame_size is None:
self.Maximize()
else:
self.SetClientSize(frame_size)
-
+
def SaveLastState(self):
if not self.IsMaximized():
self.Config.Write("framesize", cPickle.dumps(self.GetClientSize()))
elif self.Config.HasEntry("framesize"):
self.Config.DeleteEntry("framesize")
-
+
self.Config.Flush()
#-------------------------------------------------------------------------------
@@ -840,7 +840,7 @@
EDITMENU : self.RefreshEditMenu,
DISPLAYMENU : self.RefreshDisplayMenu,
PROJECTTREE : self.RefreshProjectTree,
- POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel,
+ POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel,
LIBRARYTREE : self.RefreshLibraryPanel,
SCALING : self.RefreshScaling,
PAGETITLES: self.RefreshPageTitles}
@@ -861,9 +861,9 @@
selected = self.TabsOpened.GetSelection()
if selected > -1:
window = self.TabsOpened.GetPage(selected)
-
+
if window.CheckSaveBeforeClosing():
-
+
# Refresh all window elements that have changed
wx.CallAfter(self._Refresh, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
wx.CallAfter(self.RefreshTabCtrlEvent)
@@ -871,7 +871,7 @@
event.Skip()
else:
event.Veto()
-
+
def GetCopyBuffer(self, primary_selection=False):
data = None
@@ -885,7 +885,7 @@
data = dataobj.GetText()
wx.TheClipboard.Close()
return data
-
+
def SetCopyBuffer(self, text, primary_selection=False):
if primary_selection and wx.Platform == '__WXMSW__':
return
@@ -916,14 +916,14 @@
new_values["creationDateTime"] = old_values["creationDateTime"]
if new_values != old_values:
self.Controler.SetProjectProperties(None, new_values)
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU,
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU,
PROJECTTREE, POUINSTANCEVARIABLESPANEL, SCALING)
dialog.Destroy()
#-------------------------------------------------------------------------------
# Notebook Unified Functions
#-------------------------------------------------------------------------------
-
+
## Function that add a tab in Notebook, calling refresh for tab DClick event
# for wx.aui.AUINotebook.
# @param window Panel to display in tab.
@@ -931,7 +931,7 @@
def AddPage(self, window, text):
self.TabsOpened.AddPage(window, text)
self.RefreshTabCtrlEvent()
-
+
## Function that add a tab in Notebook, calling refresh for tab DClick event
# for wx.aui.AUINotebook.
# @param window Panel to display in tab.
@@ -941,16 +941,16 @@
if self.TabsOpened.GetPage(idx) == window:
self.TabsOpened.DeletePage(idx)
self.RefreshTabCtrlEvent()
- return
-
- ## Function that fix difference in deleting all tabs between
+ return
+
+ ## Function that fix difference in deleting all tabs between
# wx.Notebook and wx.aui.AUINotebook.
def DeleteAllPages(self):
for idx in xrange(self.TabsOpened.GetPageCount()):
self.TabsOpened.DeletePage(0)
self.RefreshTabCtrlEvent()
- ## Function that fix difference in setting picture on tab between
+ ## Function that fix difference in setting picture on tab between
# wx.Notebook and wx.aui.AUINotebook.
# @param idx Tab index.
# @param bitmap wx.Bitmap to define on tab.
@@ -980,12 +980,12 @@
self.SaveProject()
elif answer == wx.ID_CANCEL:
return False
-
+
for idx in xrange(self.TabsOpened.GetPageCount()):
window = self.TabsOpened.GetPage(idx)
if not window.CheckSaveBeforeClosing():
return False
-
+
return True
#-------------------------------------------------------------------------------
@@ -1025,7 +1025,7 @@
dialog.Destroy()
def OnPreviewMenu(self, event):
- selected = self.TabsOpened.GetSelection()
+ selected = self.TabsOpened.GetSelection()
if selected != -1:
window = self.TabsOpened.GetPage(selected)
data = wx.PrintDialogData(self.PrintData)
@@ -1040,15 +1040,15 @@
preview_frame = wx.PreviewFrame(preview, self, _("Print preview"), style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT)
preview_frame.Initialize()
-
+
preview_canvas = preview.GetCanvas()
preview_canvas.SetMinSize(preview_canvas.GetVirtualSize())
preview_frame.Fit()
-
+
preview_frame.Show(True)
def OnPrintMenu(self, event):
- selected = self.TabsOpened.GetSelection()
+ selected = self.TabsOpened.GetSelection()
if selected != -1:
window = self.TabsOpened.GetPage(selected)
dialog_data = wx.PrintDialogData(self.PrintData)
@@ -1058,7 +1058,7 @@
margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
printer = wx.Printer(dialog_data)
printout = GraphicPrintout(window, page_size, margins)
-
+
if not printer.Print(self, printout, True) and printer.GetLastError() != wx.PRINTER_CANCELLED:
self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?"))
printout.Destroy()
@@ -1087,12 +1087,12 @@
self.EditMenu.Enable(wx.ID_REDO, redo)
MenuToolBar.EnableTool(wx.ID_REDO, redo)
#self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, True)
- #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO,
+ #self.EditMenu.Check(ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO,
# self.Controler.IsProjectBufferEnabled())
self.EditMenu.Enable(wx.ID_FIND, selected > -1)
- self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT,
+ self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDNEXT,
selected > -1 and self.SearchParams is not None)
- self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS,
+ self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUFINDPREVIOUS,
selected > -1 and self.SearchParams is not None)
self.EditMenu.Enable(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True)
MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, True)
@@ -1138,7 +1138,7 @@
MenuToolBar.EnableTool(ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT, False)
self.EditMenu.Enable(wx.ID_ADD, False)
self.EditMenu.Enable(wx.ID_DELETE, False)
-
+
def CloseTabsWithoutModel(self, refresh=True):
idxs = range(self.TabsOpened.GetPageCount())
idxs.reverse()
@@ -1156,9 +1156,9 @@
window.Undo()
else:
self.Controler.LoadPrevious()
- self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
- SCALING, PAGETITLES)
-
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
+ SCALING, PAGETITLES)
+
def OnRedoMenu(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
@@ -1166,9 +1166,9 @@
window.Redo()
else:
self.Controler.LoadNext()
- self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
SCALING, PAGETITLES)
-
+
def OnEnableUndoRedoMenu(self, event):
self.Controler.EnableProjectBuffer(event.IsChecked())
self.RefreshEditMenu()
@@ -1187,14 +1187,14 @@
control.SetSelection(0, control.GetLastPosition())
elif isinstance(control, wx.ComboBox):
control.SetMark(0, control.GetLastPosition() + 1)
-
+
def SetDeleteFunctions(self):
self.DeleteFunctions = {
ITEM_DATATYPE: GetDeleteElementFunction(
- PLCControler.ProjectRemoveDataType,
+ PLCControler.ProjectRemoveDataType,
check_function=self.CheckDataTypeIsUsedBeforeDeletion),
ITEM_POU: GetDeleteElementFunction(
- PLCControler.ProjectRemovePou,
+ PLCControler.ProjectRemovePou,
check_function=self.CheckPouIsUsedBeforeDeletion),
ITEM_TRANSITION: GetDeleteElementFunction(
PLCControler.ProjectRemovePouTransition, ITEM_POU),
@@ -1205,7 +1205,7 @@
ITEM_RESOURCE: GetDeleteElementFunction(
PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION)
}
-
+
def OnDeleteMenu(self, event):
window = self.FindFocus()
if window == self.ProjectTree or window is None:
@@ -1215,7 +1215,7 @@
if function is not None:
function(self, selected)
self.CloseTabsWithoutModel()
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE,
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE,
POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
elif isinstance(window, (Viewer, TextViewer)):
event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
@@ -1225,18 +1225,18 @@
def OnFindMenu(self, event):
if not self.FindDialog.IsShown():
self.FindDialog.Show()
-
+
def CloseFindInPouDialog(self):
selected = self.TabsOpened.GetSelection()
if selected == -1 and self.FindDialog.IsShown():
self.FindDialog.Hide()
-
+
def OnFindNextMenu(self, event):
self.FindInPou(1)
-
+
def OnFindPreviousMenu(self, event):
self.FindInPou(-1)
-
+
def FindInPou(self, direction, search_params=None):
if search_params is not None:
self.SearchParams = search_params
@@ -1244,7 +1244,7 @@
if selected != -1:
window = self.TabsOpened.GetPage(selected)
window.Find(direction, self.SearchParams)
-
+
def OnSearchInProjectMenu(self, event):
dialog = SearchInProjectDialog(self)
if dialog.ShowModal() == wx.ID_OK:
@@ -1253,7 +1253,7 @@
self.ClearSearchResults()
self.SearchResultPanel.SetSearchResults(criteria, result)
self.SelectTab(self.SearchResultPanel)
-
+
#-------------------------------------------------------------------------------
# Display Menu Functions
#-------------------------------------------------------------------------------
@@ -1284,7 +1284,7 @@
if self.EnableDebug:
self.DisplayMenu.Enable(wx.ID_CLEAR, False)
self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
-
+
def OnRefreshMenu(self, event):
self.RefreshEditor()
@@ -1308,14 +1308,14 @@
#-------------------------------------------------------------------------------
# Project Editor Panels Management Functions
#-------------------------------------------------------------------------------
-
+
def OnPageDragged(self, event):
wx.CallAfter(self.RefreshTabCtrlEvent)
event.Skip()
-
+
def OnAllowNotebookDnD(self, event):
event.Allow()
-
+
def RefreshTabCtrlEvent(self):
auitabctrl = []
for child in self.TabsOpened.GetChildren():
@@ -1329,11 +1329,11 @@
if pane.IsMaximized():
self.AUIManager.RestorePane(pane)
self.AUIManager.Update()
-
+
def EnsureTabVisible(self, tab):
notebook = tab.GetParent()
notebook.SetSelection(notebook.GetPageIndex(tab))
-
+
def OnPouSelectedChanging(self, event):
selected = self.TabsOpened.GetSelection()
if selected >= 0:
@@ -1341,7 +1341,7 @@
if not window.IsDebugging():
window.ResetBuffer()
event.Skip()
-
+
def OnPouSelectedChanged(self, event):
selected = self.TabsOpened.GetSelection()
if selected >= 0:
@@ -1361,7 +1361,7 @@
wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path)
wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
event.Skip()
-
+
def RefreshEditor(self):
selected = self.TabsOpened.GetSelection()
if selected >= 0:
@@ -1383,13 +1383,13 @@
window = child.GetWindowFromIdx(active_page)
window.RefreshView()
self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
-
+
def RefreshEditorNames(self, old_tagname, new_tagname):
for i in xrange(self.TabsOpened.GetPageCount()):
editor = self.TabsOpened.GetPage(i)
if editor.GetTagName() == old_tagname:
editor.SetTagName(new_tagname)
-
+
def IsOpened(self, tagname):
for idx in xrange(self.TabsOpened.GetPageCount()):
if self.TabsOpened.GetPage(idx).IsViewing(tagname):
@@ -1429,7 +1429,7 @@
tagname = item_infos.get("tagname", None)
else:
tagname = None
-
+
# Refresh treectrl items according to project infos
infos = self.Controler.GetProjectInfos()
root = self.ProjectTree.GetRootItem()
@@ -1437,7 +1437,7 @@
root = self.ProjectTree.AddRoot(infos["name"])
self.GenerateProjectTreeBranch(root, infos)
self.ProjectTree.Expand(root)
-
+
# Select new item corresponding to previous selected item
if tagname is not None:
self.SelectProjectTreeItem(tagname)
@@ -1456,7 +1456,7 @@
self.ProjectTree.SetItemTextColour(root, highlight_colours[1])
self.ProjectTree.SetItemExtraImage(root, None)
if infos["type"] == ITEM_POU:
- self.ProjectTree.SetItemImage(root,
+ self.ProjectTree.SetItemImage(root,
self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
if item_alone:
self.ProjectTree.SetItemExtraImage(root, self.Controler.GetPouType(infos["name"]))
@@ -1466,8 +1466,8 @@
self.TreeImageDict[icon_name] = self.TreeImageList.Add(GetBitmap(icon_name))
self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_name])
elif self.TreeImageDict.has_key(infos["type"]):
- self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
-
+ self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
+
item, root_cookie = self.ProjectTree.GetFirstChild(root)
for values in infos["values"]:
if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0:
@@ -1522,7 +1522,7 @@
self.SelectedItem = None
def OnProjectTreeBeginDrag(self, event):
- selected_item = (self.SelectedItem
+ selected_item = (self.SelectedItem
if self.SelectedItem is not None
else event.GetItem())
if selected_item.IsOk() and self.ProjectTree.GetPyData(selected_item)["type"] == ITEM_POU:
@@ -1563,7 +1563,7 @@
abort = True
if not abort:
self.Controler.ChangeDataTypeName(old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name),
+ self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name),
self.Controler.ComputeDataTypeName(new_name))
self.RefreshPageTitles()
elif item_infos["type"] == ITEM_POU:
@@ -1577,7 +1577,7 @@
messageDialog.Destroy()
if not abort:
self.Controler.ChangePouName(old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputePouName(old_name),
+ self.RefreshEditorNames(self.Controler.ComputePouName(old_name),
self.Controler.ComputePouName(new_name))
self.RefreshLibraryPanel()
self.RefreshPageTitles()
@@ -1589,7 +1589,7 @@
else:
words = item_infos["tagname"].split("::")
self.Controler.ChangePouTransitionName(words[1], old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name),
+ self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name),
self.Controler.ComputePouTransitionName(words[1], new_name))
self.RefreshPageTitles()
elif item_infos["type"] == ITEM_ACTION:
@@ -1600,7 +1600,7 @@
else:
words = item_infos["tagname"].split("::")
self.Controler.ChangePouActionName(words[1], old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name),
+ self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name),
self.Controler.ComputePouActionName(words[1], new_name))
self.RefreshPageTitles()
elif item_infos["type"] == ITEM_CONFIGURATION:
@@ -1619,7 +1619,7 @@
messageDialog.Destroy()
if not abort:
self.Controler.ChangeConfigurationName(old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name),
+ self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name),
self.Controler.ComputeConfigurationName(new_name))
self.RefreshPageTitles()
elif item_infos["type"] == ITEM_RESOURCE:
@@ -1639,7 +1639,7 @@
if not abort:
words = item_infos["tagname"].split("::")
self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name),
+ self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name),
self.Controler.ComputeConfigurationResourceName(words[1], new_name))
self.RefreshPageTitles()
if message or abort:
@@ -1653,7 +1653,7 @@
self.RefreshEditor()
self._Refresh(TITLE, FILEMENU, EDITMENU)
event.Skip()
-
+
def OnProjectTreeItemActivated(self, event):
selected = event.GetItem()
name = self.ProjectTree.GetItemText(selected)
@@ -1666,7 +1666,7 @@
ITEM_TRANSITION, ITEM_ACTION]:
self.EditProjectElement(item_infos["type"], item_infos["tagname"])
event.Skip()
-
+
def ProjectTreeItemSelect(self, select_item):
if select_item is not None and select_item.IsOk():
name = self.ProjectTree.GetItemText(select_item)
@@ -1676,14 +1676,14 @@
ITEM_TRANSITION, ITEM_ACTION]:
self.EditProjectElement(item_infos["type"], item_infos["tagname"], True)
self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"])
-
+
def OnProjectTreeLeftUp(self, event):
if self.SelectedItem is not None:
self.ProjectTree.SelectItem(self.SelectedItem)
self.ProjectTreeItemSelect(self.SelectedItem)
self.ResetSelectedItem()
event.Skip()
-
+
def OnProjectTreeMotion(self, event):
if not event.Dragging():
pt = wx.Point(event.GetX(), event.GetY())
@@ -1693,7 +1693,7 @@
if item != self.LastToolTipItem and self.LastToolTipItem is not None:
self.ProjectTree.SetToolTip(None)
self.LastToolTipItem = None
- if (self.LastToolTipItem != item and
+ if (self.LastToolTipItem != item and
item_infos["type"] in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]):
bodytype = self.Controler.GetEditedElementBodyType(
item_infos["tagname"])
@@ -1708,21 +1708,21 @@
else:
block_type = "Action"
self.LastToolTipItem = item
- wx.CallAfter(self.ProjectTree.SetToolTipString,
+ wx.CallAfter(self.ProjectTree.SetToolTipString,
"%s : %s : %s" % (
block_type, bodytype, item_infos["name"]))
elif self.LastToolTipItem is not None:
self.ProjectTree.SetToolTip(None)
self.LastToolTipItem = None
event.Skip()
-
+
def OnProjectTreeItemChanging(self, event):
if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None:
self.SelectedItem = event.GetItem()
event.Veto()
else:
event.Skip()
-
+
def EditProjectElement(self, element, tagname, onlyopened = False):
openedidx = self.IsOpened(tagname)
if openedidx is not None:
@@ -1790,30 +1790,30 @@
window.SetFocus()
self.RefreshPageTitles()
return new_window
-
+
def OnProjectTreeRightUp(self, event):
item = event.GetItem()
self.ProjectTree.SelectItem(item)
self.ProjectTreeItemSelect(item)
name = self.ProjectTree.GetItemText(item)
item_infos = self.ProjectTree.GetPyData(item)
-
+
menu = None
if item_infos["type"] in ITEMS_UNEDITABLE + [ITEM_PROJECT]:
if item_infos["type"] == ITEM_PROJECT:
name = "Project"
else:
name = UNEDITABLE_NAMES_DICT[name]
-
+
if name == "Data Types":
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType"))
self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id)
-
+
elif name in ["Functions", "Function Blocks", "Programs", "Project"]:
menu = wx.Menu(title='')
-
+
if name != "Project":
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add POU"))
@@ -1830,7 +1830,7 @@
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration"))
self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id)
-
+
elif name == "Transitions":
menu = wx.Menu(title='')
new_id = wx.NewId()
@@ -1841,7 +1841,7 @@
parent = self.ProjectTree.GetItemParent(parent)
parent_type = self.ProjectTree.GetPyData(parent)["type"]
self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
-
+
elif name == "Actions":
menu = wx.Menu(title='')
new_id = wx.NewId()
@@ -1852,7 +1852,7 @@
parent = self.ProjectTree.GetItemParent(parent)
parent_type = self.ProjectTree.GetPyData(parent)["type"]
self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
-
+
elif name == "Resources":
menu = wx.Menu(title='')
new_id = wx.NewId()
@@ -1871,7 +1871,7 @@
parent_name = self.ProjectTree.GetItemText(parent)
if parent_name is not None:
self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id)
-
+
else:
if item_infos["type"] == ITEM_POU:
menu = wx.Menu(title='')
@@ -1883,11 +1883,11 @@
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id)
menu.AppendSeparator()
-
+
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Copy POU"))
self.Bind(wx.EVT_MENU, self.OnCopyPou, id=new_id)
-
+
pou_type = self.Controler.GetPouType(name)
if pou_type in ["function", "functionBlock"]:
change_menu = wx.Menu(title='')
@@ -1902,27 +1902,27 @@
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename"))
self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
-
+
elif item_infos["type"] == ITEM_CONFIGURATION:
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
-
+
elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
menu = wx.Menu(title='')
-
+
if menu is not None:
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
-
+
if menu is not None:
self.PopupMenu(menu)
menu.Destroy()
-
+
self.ResetSelectedItem()
-
+
event.Skip()
@@ -1932,7 +1932,7 @@
def GetTreeImage(self, var_class):
return self.TreeImageDict[var_class]
-
+
def RefreshPouInstanceVariablesPanel(self):
self.PouInstanceVariablesPanel.RefreshView()
@@ -1945,11 +1945,11 @@
if old_selected >= 0:
self.TabsOpened.GetPage(old_selected).ResetBuffer()
self.TabsOpened.SetSelection(openedidx)
-
+
elif instance_category in ITEMS_VARIABLE:
if self.Controler.IsNumType(instance_type, True):
self.AddDebugVariable(instance_path, True)
-
+
else:
bodytype = self.Controler.GetEditedElementBodyType(instance_type, True)
if bodytype == "FBD":
@@ -1968,7 +1968,7 @@
new_window.SetKeywords(IL_KEYWORDS)
else:
new_window.SetKeywords(ST_KEYWORDS)
-
+
if new_window is not None:
if instance_category in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM]:
pou_type = self.Controler.GetEditedElementType(instance_type, True)[1].upper()
@@ -1977,7 +1977,7 @@
icon = GetBitmap("TRANSITION", bodytype)
elif instance_category == ITEM_ACTION:
icon = GetBitmap("ACTION", bodytype)
-
+
if new_window is not None:
new_window.SetIcon(icon)
self.AddPage(new_window, "")
@@ -2005,19 +2005,19 @@
elif editor.IsDebugging():
editor.SubscribeAllDataConsumers()
self.DebugVariablePanel.SubscribeAllDataConsumers()
-
+
def AddDebugVariable(self, iec_path, force=False, graph=False):
if self.EnableDebug:
self.DebugVariablePanel.InsertValue(iec_path, force=force, graph=graph)
self.EnsureTabVisible(self.DebugVariablePanel)
-
+
#-------------------------------------------------------------------------------
# Library Panel Management Function
#-------------------------------------------------------------------------------
def RefreshLibraryPanel(self):
self.LibraryPanel.RefreshTree()
-
+
#-------------------------------------------------------------------------------
# ToolBars Management Functions
#-------------------------------------------------------------------------------
@@ -2039,16 +2039,16 @@
def ResetEditorToolBar(self):
EditorToolBar = self.Panes["EditorToolBar"]
-
+
for item in self.CurrentEditorToolBar:
if wx.VERSION >= (2, 6, 0):
self.Unbind(wx.EVT_MENU, id=item)
else:
- self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED)
-
+ self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED)
+
if EditorToolBar:
EditorToolBar.DeleteTool(item)
-
+
if EditorToolBar:
EditorToolBar.Realize()
self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
@@ -2102,7 +2102,7 @@
if EditorToolBar:
EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, False)
EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, True)
-
+
def ResetToolToggle(self, id):
tool = self.Panes["EditorToolBar"].FindById(id)
tool.SetToggle(False)
@@ -2111,55 +2111,55 @@
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION)
-
+
def OnMotionTool(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_MOTION)
-
+
def OnCommentTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOMMENT)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT)
-
+
def OnVariableTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARVARIABLE)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE)
-
+
def OnBlockTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARBLOCK)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK)
-
+
def OnConnectionTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONNECTION)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION)
-
+
def OnPowerRailTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARPOWERRAIL)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_POWERRAIL)
-
+
def OnRungTool(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).AddLadderRung()
event.Skip()
-
+
def OnCoilTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCOIL)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_COIL)
event.Skip()
-
+
def OnContactTool(self, event):
if self.DrawingMode == FREEDRAWING_MODE:
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARCONTACT)
@@ -2169,18 +2169,18 @@
self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT)
else:
self.TabsOpened.GetPage(selected).AddLadderContact()
-
- def OnBranchTool(self, event):
+
+ def OnBranchTool(self, event):
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).AddLadderBranch()
-
+
def OnInitialStepTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARINITIALSTEP)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_INITIALSTEP)
-
+
def OnStepTool(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARSTEP)
@@ -2190,7 +2190,7 @@
self.TabsOpened.GetPage(selected).SetMode(MODE_STEP)
else:
self.TabsOpened.GetPage(selected).AddStep()
-
+
def OnActionBlockTool(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARACTIONBLOCK)
@@ -2200,13 +2200,13 @@
self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION)
else:
self.TabsOpened.GetPage(selected).AddStepAction()
-
+
def OnTransitionTool(self, event):
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARTRANSITION)
selected = self.TabsOpened.GetSelection()
if selected != -1:
self.TabsOpened.GetPage(selected).SetMode(MODE_TRANSITION)
-
+
def OnDivergenceTool(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARDIVERGENCE)
@@ -2216,7 +2216,7 @@
self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE)
else:
self.TabsOpened.GetPage(selected).AddDivergence()
-
+
def OnJumpTool(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
self.ResetToolToggle(ID_PLCOPENEDITOREDITORTOOLBARJUMP)
@@ -2226,7 +2226,7 @@
self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP)
else:
self.TabsOpened.GetPage(selected).AddJump()
-
+
#-------------------------------------------------------------------------------
# Add Project Elements Functions
@@ -2237,7 +2237,7 @@
if tagname is not None:
self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
self.EditProjectElement(ITEM_DATATYPE, tagname)
-
+
def GenerateAddPouFunction(self, pou_type):
def OnAddPouMenu(event):
dialog = PouDialog(self, pou_type)
@@ -2259,7 +2259,7 @@
dialog.SetPouNames(self.Controler.GetProjectPouNames())
dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name))
dialog.SetValues({"transitionName": self.Controler.GenerateNewName(None, None, "transition%d")})
- if dialog.ShowModal() == wx.ID_OK:
+ if dialog.ShowModal() == wx.ID_OK:
values = dialog.GetValues()
tagname = self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
if tagname is not None:
@@ -2289,6 +2289,14 @@
self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
self.EditProjectElement(ITEM_CONFIGURATION, tagname)
+ def AddResourceMenu(self, event):
+ config_names = self.Controler.GetProjectConfigNames()
+ if len(config_names) > 0:
+ tagname = self.Controler.ProjectAddConfigurationResource(config_names[0])
+ if tagname is not None:
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
+ self.EditProjectElement(ITEM_RESOURCE, tagname)
+
def GenerateAddResourceFunction(self, config_name):
def OnAddResourceMenu(event):
tagname = self.Controler.ProjectAddConfigurationResource(config_name)
@@ -2300,7 +2308,7 @@
def GenerateChangePouTypeFunction(self, name, new_type):
def OnChangePouTypeMenu(event):
selected = self.ProjectTree.GetSelection()
- if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
self.Controler.ProjectChangePouType(name, new_type)
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE)
return OnChangePouTypeMenu
@@ -2308,7 +2316,7 @@
def OnCopyPou(self, event):
selected = self.ProjectTree.GetSelection()
pou_name = self.ProjectTree.GetItemText(selected)
-
+
pou_xml = self.Controler.GetPouXml(pou_name)
if pou_xml is not None:
self.SetCopyBuffer(pou_xml)
@@ -2316,14 +2324,14 @@
def OnPastePou(self, event):
selected = self.ProjectTree.GetSelection()
-
- if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT:
+
+ if self.ProjectTree.GetPyData(selected)["type"] != ITEM_PROJECT:
pou_type = self.ProjectTree.GetItemText(selected)
pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs'
pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type]
else:
pou_type = None
-
+
pou_xml = self.GetCopyBuffer()
result = self.Controler.PastePou(pou_type, pou_xml)
@@ -2341,9 +2349,9 @@
def CheckElementIsUsedBeforeDeletion(self, check_function, title, name):
if not check_function(name):
return True
-
- dialog = wx.MessageDialog(self,
- _("\"%s\" is used by one or more POUs. Do you wish to continue?") % name,
+
+ dialog = wx.MessageDialog(self,
+ _("\"%s\" is used by one or more POUs. Do you wish to continue?") % name,
title, wx.YES_NO|wx.ICON_QUESTION)
answer = dialog.ShowModal()
dialog.Destroy()
@@ -2353,12 +2361,12 @@
return self.CheckElementIsUsedBeforeDeletion(
self.Controler.DataTypeIsUsed,
_("Remove Datatype"), name)
-
+
def CheckPouIsUsedBeforeDeletion(self, name):
return self.CheckElementIsUsedBeforeDeletion(
self.Controler.PouIsUsed,
_("Remove Pou"), name)
-
+
def OnRemoveDataTypeMenu(self, event):
selected = self.ProjectTree.GetSelection()
if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE:
@@ -2370,10 +2378,10 @@
if idx is not None:
self.TabsOpened.DeletePage(idx)
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE)
-
+
def OnRenamePouMenu(self, event):
selected = self.ProjectTree.GetSelection()
- if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
wx.CallAfter(self.ProjectTree.EditLabel, selected)
def OnRemovePouMenu(self, event):
@@ -2391,7 +2399,7 @@
def OnRemoveTransitionMenu(self, event):
selected = self.ProjectTree.GetSelection()
item_infos = self.ProjectTree.GetPyData(selected)
- if item_infos["type"] == ITEM_TRANSITION:
+ if item_infos["type"] == ITEM_TRANSITION:
transition = self.ProjectTree.GetItemText(selected)
pou_name = item_infos["tagname"].split("::")[1]
self.Controler.ProjectRemovePouTransition(pou_name, transition)
@@ -2404,7 +2412,7 @@
def OnRemoveActionMenu(self, event):
selected = self.ProjectTree.GetSelection()
item_infos = self.ProjectTree.GetPyData(selected)
- if item_infos["type"] == ITEM_ACTION:
+ if item_infos["type"] == ITEM_ACTION:
action = self.ProjectTree.GetItemText(selected)
pou_name = item_infos["tagname"].split("::")[1]
self.Controler.ProjectRemovePouAction(pou_name, action)
@@ -2416,7 +2424,7 @@
def OnRemoveConfigurationMenu(self, event):
selected = self.ProjectTree.GetSelection()
- if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION:
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION:
name = self.ProjectTree.GetItemText(selected)
self.Controler.ProjectRemoveConfiguration(name)
tagname = self.Controler.ComputeConfigurationName(name)
@@ -2494,17 +2502,17 @@
self.Margins = margins
self.FontSize = 5
self.TextMargin = 3
-
+
maxx, maxy = viewer.GetMaxSize()
- self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]),
+ self.PageGrid = (UPPER_DIV(maxx, self.PageSize[0]),
UPPER_DIV(maxy, self.PageSize[1]))
-
+
def GetPageNumber(self):
return self.PageGrid[0] * self.PageGrid[1]
-
+
def HasPage(self, page):
return page <= self.GetPageNumber()
-
+
def GetPageInfo(self):
page_number = self.GetPageNumber()
return (1, page_number, 1, page_number)
@@ -2520,7 +2528,7 @@
dc.SetUserScale(1.0, 1.0)
dc.SetDeviceOrigin(0, 0)
dc.printing = not self.Preview
-
+
# Get the size of the DC in pixels
ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
ppiScreenX, ppiScreenY = self.GetPPIScreen()
@@ -2528,26 +2536,26 @@
dw, dh = dc.GetSizeTuple()
Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4)
Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4)
-
+
fontsize = self.FontSize * Yscale
text_margin = self.TextMargin * Yscale
-
+
margin_left = self.Margins[0].x * Xscale
margin_top = self.Margins[0].y * Yscale
area_width = dw - self.Margins[1].x * Xscale - margin_left
area_height = dh - self.Margins[1].y * Yscale - margin_top
-
+
dc.SetPen(MiterPen(wx.BLACK))
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawRectangle(margin_left, margin_top, area_width, area_height)
-
+
dc.SetFont(wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
dc.SetTextForeground(wx.BLACK)
block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:])
text_width, text_height = dc.GetTextExtent(block_name)
dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin)
dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin)
-
+
# Calculate the position on the DC for centering the graphic
posX = area_width * ((page - 1) % self.PageGrid[0])
posY = area_height * ((page - 1) / self.PageGrid[0])
@@ -2560,10 +2568,10 @@
dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top)
dc.SetClippingRegion(posX, posY, self.PageSize[0] * scale, self.PageSize[1] * scale)
dc.SetUserScale(scale, scale)
-
+
#-------------------------------------------
-
+
self.Viewer.DoDrawing(dc, True)
-
+
return True
--- a/PLCControler.py Mon May 26 14:44:03 2014 +0100
+++ b/PLCControler.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
+#based on the plcopen standard.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -57,7 +57,7 @@
ITEM_RESOURCES,
ITEM_PROPERTIES
] = range(8, 17)
-
+
ITEMS_VARIABLE = [ITEM_VAR_LOCAL,
ITEM_VAR_GLOBAL,
ITEM_VAR_EXTERNAL,
@@ -92,12 +92,12 @@
def GetUneditableNames():
_ = lambda x:x
- return [_("User-defined POUs"), _("Functions"), _("Function Blocks"),
- _("Programs"), _("Data Types"), _("Transitions"), _("Actions"),
+ return [_("User-defined POUs"), _("Functions"), _("Function Blocks"),
+ _("Programs"), _("Data Types"), _("Transitions"), _("Actions"),
_("Configurations"), _("Resources"), _("Properties")]
UNEDITABLE_NAMES = GetUneditableNames()
-[USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS,
- DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS,
+[USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS,
+ DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS,
RESOURCES, PROPERTIES] = UNEDITABLE_NAMES
#-------------------------------------------------------------------------------
@@ -133,7 +133,7 @@
_BoolValue = lambda x: x in ["true", "0"]
def _translate_args(translations, args):
- return [translate(arg[0]) if len(arg) > 0 else None
+ return [translate(arg[0]) if len(arg) > 0 else None
for translate, arg in
zip(translations, args)]
@@ -142,7 +142,7 @@
#-------------------------------------------------------------------------------
class _VariableInfos(object):
- __slots__ = ["Name", "Class", "Option", "Location", "InitialValue",
+ __slots__ = ["Name", "Class", "Option", "Location", "InitialValue",
"Edit", "Documentation", "Type", "Tree", "Number"]
def __init__(self, *args):
for attr, value in zip(self.__slots__, args):
@@ -151,39 +151,39 @@
return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__])
class VariablesInfosFactory:
-
+
def __init__(self, variables):
self.Variables = variables
self.TreeStack = []
self.Type = None
self.Dimensions = None
-
+
def SetType(self, context, *args):
self.Type = args[0][0]
-
+
def GetType(self):
if len(self.Dimensions) > 0:
return ("array", self.Type, self.Dimensions)
return self.Type
-
+
def GetTree(self):
return (self.TreeStack.pop(-1), self.Dimensions)
-
+
def AddDimension(self, context, *args):
self.Dimensions.append(tuple(
_translate_args([_StringValue] * 2, args)))
-
+
def AddTree(self, context, *args):
self.TreeStack.append([])
self.Dimensions = []
-
+
def AddVarToTree(self, context, *args):
var = (args[0][0], self.Type, self.GetTree())
self.TreeStack[-1].append(var)
-
+
def AddVariable(self, context, *args):
self.Variables.append(_VariableInfos(*(_translate_args(
- [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) +
+ [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) +
[self.GetType(), self.GetTree()])))
#-------------------------------------------------------------------------------
@@ -199,15 +199,15 @@
"program": ITEM_PROGRAM}.get(value)
if class_type is not None:
return class_type
-
+
pou_type = POU_TYPES.get(value)
if pou_type is not None:
return pou_type
-
+
var_type = VAR_CLASS_INFOS.get(value)
if var_type is not None:
return var_type[1]
-
+
return None
class _VariablesTreeItemInfos(object):
@@ -219,24 +219,24 @@
return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__])
class VariablesTreeInfosFactory:
-
+
def __init__(self):
self.Root = None
-
+
def GetRoot(self):
return self.Root
-
+
def SetRoot(self, context, *args):
self.Root = _VariablesTreeItemInfos(
*([''] + _translate_args(
- [class_extraction, _StringValue] + [_BoolValue] * 2,
+ [class_extraction, _StringValue] + [_BoolValue] * 2,
args) + [[]]))
def AddVariable(self, context, *args):
if self.Root is not None:
self.Root.variables.append(_VariablesTreeItemInfos(
*(_translate_args(
- [_StringValue, class_extraction, _StringValue] +
+ [_StringValue, class_extraction, _StringValue] +
[_BoolValue] * 2, args) + [[]])))
#-------------------------------------------------------------------------------
@@ -244,10 +244,10 @@
#-------------------------------------------------------------------------------
class InstancesPathFactory:
-
+
def __init__(self, instances):
self.Instances = instances
-
+
def AddInstance(self, context, *args):
self.Instances.append(args[0][0])
@@ -260,13 +260,13 @@
def __init__(self, controller):
self.Controller = controller
self.TagName = None
-
+
def GetTagName(self):
return self.TagName
-
+
def ConfigTagName(self, context, *args):
self.TagName = self.Controller.ComputeConfigurationName(args[0][0])
-
+
def ResourceTagName(self, context, *args):
self.TagName = self.Controller.ComputeConfigurationResourceName(args[0][0], args[1][0])
@@ -285,15 +285,15 @@
_Point = namedtuple("Point", ["x", "y"])
-_BlockInstanceInfos = namedtuple("BlockInstanceInfos",
+_BlockInstanceInfos = namedtuple("BlockInstanceInfos",
["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
_BlockSpecificValues = (
- namedtuple("BlockSpecificValues",
+ namedtuple("BlockSpecificValues",
["name", "execution_order"]),
[_StringValue, int])
_VariableSpecificValues = (
- namedtuple("VariableSpecificValues",
+ namedtuple("VariableSpecificValues",
["name", "value_type", "execution_order"]),
[_StringValue, _StringValue, int])
_ConnectionSpecificValues = (
@@ -305,7 +305,7 @@
[int])
_LDElementSpecificValues = (
- namedtuple("LDElementSpecificValues",
+ namedtuple("LDElementSpecificValues",
["name", "negated", "edge", "storage", "execution_order"]),
[_StringValue, _BoolValue, _StringValue, _StringValue, int])
@@ -330,7 +330,7 @@
namedtuple("StepSpecificValues", ["name", "initial", "action"]),
[_StringValue, _BoolValue, lambda x: x]),
"transition": (
- namedtuple("TransitionSpecificValues",
+ namedtuple("TransitionSpecificValues",
["priority", "condition_type", "condition", "connection"]),
[int, _StringValue, _StringValue, lambda x: x]),
"selectionDivergence": _DivergenceSpecificValues,
@@ -360,24 +360,24 @@
return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
class BlockInstanceFactory:
-
+
def __init__(self, block_instances):
self.BlockInstances = block_instances
self.CurrentInstance = None
self.SpecificValues = None
self.CurrentConnection = None
self.CurrentLink = None
-
+
def SetSpecificValues(self, context, *args):
self.SpecificValues = list(args)
self.CurrentInstance = None
self.CurrentConnection = None
self.CurrentLink = None
-
+
def AddBlockInstance(self, context, *args):
specific_values_tuple, specific_values_translation = \
_SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
-
+
if (args[0][0] == "step" and len(self.SpecificValues) < 3 or
args[0][0] == "transition" and len(self.SpecificValues) < 4):
self.SpecificValues.append([None])
@@ -386,21 +386,21 @@
specific_values = specific_values_tuple(*_translate_args(
specific_values_translation, self.SpecificValues))
self.SpecificValues = None
-
+
self.CurrentInstance = _BlockInstanceInfos(
- *(_translate_args([_StringValue, int] + [float] * 4, args) +
+ *(_translate_args([_StringValue, int] + [float] * 4, args) +
[specific_values, [], []]))
-
+
self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
-
+
def AddInstanceConnection(self, context, *args):
connection_args = _translate_args(
[_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args)
-
+
self.CurrentConnection = _InstanceConnectionInfos(
*(connection_args[1:4] + [
_Point(*connection_args[4:6]), []]))
-
+
if self.CurrentInstance is not None:
if connection_args[0] == "input":
self.CurrentInstance.inputs.append(self.CurrentConnection)
@@ -408,22 +408,22 @@
self.CurrentInstance.outputs.append(self.CurrentConnection)
else:
self.SpecificValues.append([self.CurrentConnection])
-
+
def AddConnectionLink(self, context, *args):
self.CurrentLink = _ConnectionLinkInfos(
*(_translate_args([int, _StringValue], args) + [[]]))
self.CurrentConnection.links.append(self.CurrentLink)
-
+
def AddLinkPoint(self, context, *args):
self.CurrentLink.points.append(_Point(
*_translate_args([float] * 2, args)))
-
+
def AddAction(self, context, *args):
if len(self.SpecificValues) == 0:
self.SpecificValues.append([[]])
translated_args = _translate_args([_StringValue] * 5, args)
self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
-
+
pou_block_instances_xslt = etree.parse(
os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
@@ -461,7 +461,7 @@
self.LastSave = 0
else:
self.LastSave = -1
-
+
# Add a new state in buffer
def Buffering(self, currentstate):
self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
@@ -474,29 +474,29 @@
self.LastSave = -1
self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH
self.MinIndex = max(self.MinIndex, 0)
-
+
# Return current state of buffer
def Current(self):
return self.Buffer[self.CurrentIndex]
-
+
# Change current state to previous in buffer and return new current state
def Previous(self):
if self.CurrentIndex != self.MinIndex:
self.CurrentIndex = (self.CurrentIndex - 1) % UNDO_BUFFER_LENGTH
return self.Buffer[self.CurrentIndex]
return None
-
+
# Change current state to next in buffer and return new current state
def Next(self):
if self.CurrentIndex != self.MaxIndex:
self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH
return self.Buffer[self.CurrentIndex]
return None
-
+
# Return True if current state is the first in buffer
def IsFirst(self):
return self.CurrentIndex == self.MinIndex
-
+
# Return True if current state is the last in buffer
def IsLast(self):
return self.CurrentIndex == self.MaxIndex
@@ -504,7 +504,7 @@
# Note that current state is saved
def CurrentSaved(self):
self.LastSave = self.CurrentIndex
-
+
# Return True if current state is saved
def IsCurrentSaved(self):
return self.LastSave == self.CurrentIndex
@@ -518,12 +518,12 @@
Class which controls the operations made on the plcopen model and answers to view requests
"""
class PLCControler:
-
+
# Create a new PLCControler
def __init__(self):
self.LastNewIndex = 0
self.Reset()
-
+
# Reset PLCControler internal variables
def Reset(self):
self.Project = None
@@ -541,7 +541,7 @@
self.TotalTypesDict = StdBlckDct.copy()
self.TotalTypes = StdBlckLst[:]
self.ProgramFilePath = ""
-
+
def GetQualifierTypes(self):
return QualifierList
@@ -567,7 +567,7 @@
self.Project.setfileHeader(properties)
self.Project.setcontentHeader(properties)
self.SetFilePath("")
-
+
# Initialize the project buffer
self.CreateProjectBuffer(False)
self.ProgramChunks = []
@@ -575,28 +575,28 @@
self.NextCompiledProject = self.Copy(self.Project)
self.CurrentCompiledProject = None
self.Buffering = False
-
+
# Return project data type names
def GetProjectDataTypeNames(self, debug = False):
project = self.GetProject(debug)
if project is not None:
return [datatype.getname() for datatype in project.getdataTypes()]
return []
-
+
# Return project pou names
def GetProjectPouNames(self, debug = False):
project = self.GetProject(debug)
if project is not None:
return [pou.getname() for pou in project.getpous()]
return []
-
+
# Return project pou names
def GetProjectConfigNames(self, debug = False):
project = self.GetProject(debug)
if project is not None:
return [config.getname() for config in project.getconfigurations()]
return []
-
+
# Return project pou variable names
def GetProjectPouVariableNames(self, pou_name = None, debug = False):
variables = []
@@ -610,15 +610,15 @@
for action in pou.getactionList():
variables.append(action.getname())
return variables
-
+
# Return file path if project is an open file
def GetFilePath(self):
return self.FilePath
-
+
# Return file path if project is an open file
def GetProgramFilePath(self):
return self.ProgramFilePath
-
+
# Return file name and point out if file is up to date
def GetFilename(self):
if self.Project is not None:
@@ -627,7 +627,7 @@
else:
return "~%s~"%self.FileName
return ""
-
+
# Change file path and save file name or create a default one if file path not defined
def SetFilePath(self, filepath):
self.FilePath = filepath
@@ -636,7 +636,7 @@
self.FileName = _("Unnamed%d")%self.LastNewIndex
else:
self.FileName = os.path.splitext(os.path.basename(filepath))[0]
-
+
# Change project properties
def SetProjectProperties(self, name = None, properties = None, buffer = True):
if self.Project is not None:
@@ -647,14 +647,14 @@
self.Project.setcontentHeader(properties)
if buffer and (name is not None or properties is not None):
self.BufferProject()
-
+
# Return project name
def GetProjectName(self, debug=False):
project = self.GetProject(debug)
if project is not None:
return project.getname()
return None
-
+
# Return project properties
def GetProjectProperties(self, debug = False):
project = self.GetProject(debug)
@@ -663,7 +663,7 @@
properties.update(project.getcontentHeader())
return properties
return None
-
+
# Return project informations
def GetProjectInfos(self, debug = False):
project = self.GetProject(debug)
@@ -671,7 +671,7 @@
infos = {"name": project.getname(), "type": ITEM_PROJECT}
datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]}
for datatype in project.getdataTypes():
- datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE,
+ datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE,
"tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]},
"functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]},
@@ -684,14 +684,14 @@
if pou.getbodyType() == "SFC":
transitions = []
for transition in pou.gettransitionList():
- transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION,
- "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
+ transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION,
+ "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
"values": []})
pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions})
actions = []
for action in pou.getactionList():
- actions.append({"name": action.getname(), "type": ITEM_ACTION,
- "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
+ actions.append({"name": action.getname(), "type": ITEM_ACTION,
+ "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
"values": []})
pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions})
if pou_type in pou_types:
@@ -700,19 +700,19 @@
configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []}
for config in project.getconfigurations():
config_name = config.getname()
- config_infos = {"name": config_name, "type": ITEM_CONFIGURATION,
- "tagname": self.ComputeConfigurationName(config.getname()),
+ config_infos = {"name": config_name, "type": ITEM_CONFIGURATION,
+ "tagname": self.ComputeConfigurationName(config.getname()),
"values": []}
resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []}
for resource in config.getresource():
resource_name = resource.getname()
- resource_infos = {"name": resource_name, "type": ITEM_RESOURCE,
- "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
+ resource_infos = {"name": resource_name, "type": ITEM_RESOURCE,
+ "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
"values": []}
resources["values"].append(resource_infos)
config_infos["values"] = [resources]
configurations["values"].append(config_infos)
- infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"],
+ infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"],
pou_types["program"], configurations]
return infos
return None
@@ -722,17 +722,17 @@
project = self.GetProject(debug)
if project is not None:
factory = VariablesTreeInfosFactory()
-
+
parser = etree.XMLParser()
parser.resolvers.add(LibraryResolver(self, debug))
-
+
pou_variable_xslt_tree = etree.XSLT(
etree.parse(
os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"),
- parser),
+ parser),
extensions = {("pou_vars_ns", name): getattr(factory, name)
for name in ["SetRoot", "AddVariable"]})
-
+
obj = None
words = tagname.split("::")
if words[0] == "P":
@@ -742,7 +742,7 @@
if obj is not None:
pou_variable_xslt_tree(obj)
return factory.GetRoot()
-
+
return None
def GetInstanceList(self, root, name, debug = False):
@@ -750,22 +750,22 @@
project = self.GetProject(debug)
if project is not None:
factory = InstancesPathFactory(instances)
-
+
parser = etree.XMLParser()
parser.resolvers.add(LibraryResolver(self, debug))
-
+
instances_path_xslt_tree = etree.XSLT(
etree.parse(
os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
- parser),
+ parser),
extensions = {
("instances_ns", "AddInstance"): factory.AddInstance})
-
- instances_path_xslt_tree(root,
+
+ instances_path_xslt_tree(root,
instance_type=etree.XSLT.strparam(name))
-
+
return instances
-
+
def SearchPouInstances(self, tagname, debug = False):
project = self.GetProject(debug)
if project is not None:
@@ -781,28 +781,28 @@
for instance in self.SearchPouInstances(
self.ComputePouName(words[1]), debug)]
return []
-
+
def GetPouInstanceTagName(self, instance_path, debug = False):
project = self.GetProject(debug)
factory = InstanceTagName(self)
-
+
parser = etree.XMLParser()
parser.resolvers.add(LibraryResolver(self, debug))
-
+
instance_tagname_xslt_tree = etree.XSLT(
etree.parse(
os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"),
- parser),
+ parser),
extensions = {("instance_tagname_ns", name): getattr(factory, name)
for name in ["ConfigTagName", "ResourceTagName",
- "PouTagName", "ActionTagName",
+ "PouTagName", "ActionTagName",
"TransitionTagName"]})
-
- instance_tagname_xslt_tree(project,
+
+ instance_tagname_xslt_tree(project,
instance_path=etree.XSLT.strparam(instance_path))
-
+
return factory.GetTagName()
-
+
def GetInstanceInfos(self, instance_path, debug = False):
tagname = self.GetPouInstanceTagName(instance_path)
if tagname is not None:
@@ -818,7 +818,7 @@
if var_infos.name == var_name:
return var_infos
return None
-
+
# Return if data type given by name is used by another data type or pou
def DataTypeIsUsed(self, name, debug = False):
project = self.GetProject(debug)
@@ -887,11 +887,11 @@
return infos
row, col = next_row, next_col
return infos
-
+
#-------------------------------------------------------------------------------
# Project Pous management functions
#-------------------------------------------------------------------------------
-
+
# Add a Data Type to Project
def ProjectAddDataType(self, datatype_name=None):
if self.Project is not None:
@@ -902,13 +902,13 @@
self.BufferProject()
return self.ComputeDataTypeName(datatype_name)
return None
-
+
# Remove a Data Type from project
def ProjectRemoveDataType(self, datatype_name):
if self.Project is not None:
self.Project.removedataType(datatype_name)
self.BufferProject()
-
+
# Add a Pou to Project
def ProjectAddPou(self, pou_name, pou_type, body_type):
if self.Project is not None:
@@ -919,21 +919,21 @@
self.BufferProject()
return self.ComputePouName(pou_name)
return None
-
+
def ProjectChangePouType(self, name, pou_type):
if self.Project is not None:
pou = self.Project.getpou(name)
if pou is not None:
pou.setpouType(pou_type)
self.BufferProject()
-
+
def GetPouXml(self, pou_name):
if self.Project is not None:
pou = self.Project.getpou(pou_name)
if pou is not None:
return pou.tostring()
return None
-
+
def PastePou(self, pou_type, pou_xml):
'''
Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
@@ -944,21 +944,21 @@
error = ""
if error is not None:
return _("Couldn't paste non-POU object.")
-
+
name = new_pou.getname()
-
+
idx = 0
new_name = name
- while self.Project.getpou(new_name):
+ while self.Project.getpou(new_name) is not None:
# a POU with that name already exists.
# make a new name and test if a POU with that name exists.
# append an incrementing numeric suffix to the POU name.
idx += 1
new_name = "%s%d" % (name, idx)
-
+
# we've found a name that does not already exist, use it
new_pou.setname(new_name)
-
+
if pou_type is not None:
orig_type = new_pou.getpouType()
@@ -968,12 +968,12 @@
if orig_type == 'functionBlock' and pou_type == 'function' or \
orig_type == 'program' and pou_type in ['function', 'functionBlock']:
return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
-
+
new_pou.setpouType(pou_type)
- self.Project.insertpou(-1, new_pou)
+ self.Project.insertpou(0, new_pou)
self.BufferProject()
-
+
return self.ComputePouName(new_name),
# Remove a Pou from project
@@ -981,7 +981,7 @@
if self.Project is not None:
self.Project.removepou(pou_name)
self.BufferProject()
-
+
# Return the name of the configuration if only one exist
def GetProjectMainConfigurationName(self):
if self.Project is not None:
@@ -990,7 +990,7 @@
if len(configurations) == 1:
return configurations[0].getname()
return None
-
+
# Add a configuration to Project
def ProjectAddConfiguration(self, config_name=None):
if self.Project is not None:
@@ -1000,13 +1000,13 @@
self.BufferProject()
return self.ComputeConfigurationName(config_name)
return None
-
+
# Remove a configuration from project
def ProjectRemoveConfiguration(self, config_name):
if self.Project is not None:
self.Project.removeconfiguration(config_name)
self.BufferProject()
-
+
# Add a resource to a configuration of the Project
def ProjectAddConfigurationResource(self, config_name, resource_name=None):
if self.Project is not None:
@@ -1016,13 +1016,13 @@
self.BufferProject()
return self.ComputeConfigurationResourceName(config_name, resource_name)
return None
-
+
# Remove a resource from a configuration of the project
def ProjectRemoveConfigurationResource(self, config_name, resource_name):
if self.Project is not None:
self.Project.removeconfigurationResource(config_name, resource_name)
self.BufferProject()
-
+
# Add a Transition to a Project Pou
def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
if self.Project is not None:
@@ -1032,7 +1032,7 @@
self.BufferProject()
return self.ComputePouTransitionName(pou_name, transition_name)
return None
-
+
# Remove a Transition from a Project Pou
def ProjectRemovePouTransition(self, pou_name, transition_name):
# Search if the pou removed is currently opened
@@ -1041,7 +1041,7 @@
if pou is not None:
pou.removetransition(transition_name)
self.BufferProject()
-
+
# Add an Action to a Project Pou
def ProjectAddPouAction(self, pou_name, action_name, action_type):
if self.Project is not None:
@@ -1051,7 +1051,7 @@
self.BufferProject()
return self.ComputePouActionName(pou_name, action_name)
return None
-
+
# Remove an Action from a Project Pou
def ProjectRemovePouAction(self, pou_name, action_name):
# Search if the pou removed is currently opened
@@ -1060,7 +1060,7 @@
if pou is not None:
pou.removeaction(action_name)
self.BufferProject()
-
+
# Change the name of a pou
def ChangeDataTypeName(self, old_name, new_name):
if self.Project is not None:
@@ -1070,7 +1070,7 @@
datatype.setname(new_name)
self.Project.updateElementName(old_name, new_name)
self.BufferProject()
-
+
# Change the name of a pou
def ChangePouName(self, old_name, new_name):
if self.Project is not None:
@@ -1080,7 +1080,7 @@
pou.setname(new_name)
self.Project.updateElementName(old_name, new_name)
self.BufferProject()
-
+
# Change the name of a pou transition
def ChangePouTransitionName(self, pou_name, old_name, new_name):
if self.Project is not None:
@@ -1092,7 +1092,7 @@
transition.setname(new_name)
pou.updateElementName(old_name, new_name)
self.BufferProject()
-
+
# Change the name of a pou action
def ChangePouActionName(self, pou_name, old_name, new_name):
if self.Project is not None:
@@ -1104,7 +1104,7 @@
action.setname(new_name)
pou.updateElementName(old_name, new_name)
self.BufferProject()
-
+
# Change the name of a pou variable
def ChangePouVariableName(self, pou_name, old_name, new_name):
if self.Project is not None:
@@ -1116,7 +1116,7 @@
if var.getname() == old_name:
var.setname(new_name)
self.BufferProject()
-
+
# Change the name of a configuration
def ChangeConfigurationName(self, old_name, new_name):
if self.Project is not None:
@@ -1125,7 +1125,7 @@
if configuration is not None:
configuration.setname(new_name)
self.BufferProject()
-
+
# Change the name of a configuration resource
def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
if self.Project is not None:
@@ -1134,7 +1134,7 @@
if resource is not None:
resource.setname(new_name)
self.BufferProject()
-
+
# Return the description of the pou given by its name
def GetPouDescription(self, name, debug = False):
project = self.GetProject(debug)
@@ -1144,7 +1144,7 @@
if pou is not None:
return pou.getdescription()
return ""
-
+
# Return the description of the pou given by its name
def SetPouDescription(self, name, description, debug = False):
project = self.GetProject(debug)
@@ -1154,7 +1154,7 @@
if pou is not None:
pou.setdescription(description)
self.BufferProject()
-
+
# Return the type of the pou given by its name
def GetPouType(self, name, debug = False):
project = self.GetProject(debug)
@@ -1164,7 +1164,7 @@
if pou is not None:
return pou.getpouType()
return None
-
+
# Return pous with SFC language
def GetSFCPous(self, debug = False):
list = []
@@ -1174,7 +1174,7 @@
if pou.getBodyType() == "SFC":
list.append(pou.getname())
return list
-
+
# Return the body language of the pou given by its name
def GetPouBodyType(self, name, debug = False):
project = self.GetProject(debug)
@@ -1184,7 +1184,7 @@
if pou is not None:
return pou.getbodyType()
return None
-
+
# Return the actions of a pou
def GetPouTransitions(self, pou_name, debug = False):
transitions = []
@@ -1196,7 +1196,7 @@
for transition in pou.gettransitionList():
transitions.append(transition.getname())
return transitions
-
+
# Return the body language of the transition given by its name
def GetTransitionBodyType(self, pou_name, pou_transition, debug = False):
project = self.GetProject(debug)
@@ -1209,7 +1209,7 @@
if transition is not None:
return transition.getbodyType()
return None
-
+
# Return the actions of a pou
def GetPouActions(self, pou_name, debug = False):
actions = []
@@ -1221,7 +1221,7 @@
for action in pou.getactionList():
actions.append(action.getname())
return actions
-
+
# Return the body language of the pou given by its name
def GetActionBodyType(self, pou_name, pou_action, debug = False):
project = self.GetProject(debug)
@@ -1233,18 +1233,18 @@
if action is not None:
return action.getbodyType()
return None
-
+
# Extract varlists from a list of vars
def ExtractVarLists(self, vars):
varlist_list = []
current_varlist = None
current_type = None
for var in vars:
- next_type = (var.Class,
- var.Option,
- var.Location in ["", None] or
- # When declaring globals, located
- # and not located variables are
+ next_type = (var.Class,
+ var.Option,
+ var.Location in ["", None] or
+ # When declaring globals, located
+ # and not located variables are
# in the same declaration block
var.Class == "Global")
if current_type != next_type:
@@ -1264,7 +1264,7 @@
# Create variable and change its properties
tempvar = PLCOpenParser.CreateElement("variable", "varListPlain")
tempvar.setname(var.Name)
-
+
var_type = PLCOpenParser.CreateElement("type", "variable")
if isinstance(var.Type, TupleType):
if var.Type[0] == "array":
@@ -1317,28 +1317,28 @@
# Add variable to varList
current_varlist.appendvariable(tempvar)
return varlist_list
-
+
def GetVariableDictionary(self, object_with_vars, tree=False, debug=False):
variables = []
factory = VariablesInfosFactory(variables)
-
+
parser = etree.XMLParser()
parser.resolvers.add(LibraryResolver(self, debug))
-
+
variables_infos_xslt_tree = etree.XSLT(
etree.parse(
os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
- parser),
+ parser),
extensions = {("var_infos_ns", name): getattr(factory, name)
for name in ["SetType", "AddDimension", "AddTree",
"AddVarToTree", "AddVariable"]})
variables_infos_xslt_tree(object_with_vars,
tree=etree.XSLT.strparam(str(tree)))
-
+
return variables
-
+
# Add a global var to configuration to configuration
- def AddConfigurationGlobalVar(self, config_name, var_type, var_name,
+ def AddConfigurationGlobalVar(self, config_name, var_type, var_name,
location="", description=""):
if self.Project is not None:
# Found the configuration corresponding to name
@@ -1346,7 +1346,7 @@
if configuration is not None:
# Set configuration global vars
configuration.addglobalVar(
- self.GetVarTypeObject(var_type),
+ self.GetVarTypeObject(var_type),
var_name, location, description)
# Replace the configuration globalvars by those given
@@ -1359,7 +1359,7 @@
configuration.setglobalVars([
varlist for vartype, varlist
in self.ExtractVarLists(vars)])
-
+
# Return the configuration globalvars
def GetConfigurationGlobalVars(self, name, debug = False):
project = self.GetProject(debug)
@@ -1369,7 +1369,7 @@
if configuration is not None:
# Extract variables defined in configuration
return self.GetVariableDictionary(configuration, debug)
-
+
return []
# Return configuration variable names
@@ -1381,7 +1381,7 @@
if config_name is None or config_name == configuration.getname():
variables.extend(
[var.getname() for var in reduce(
- lambda x, y: x + y, [varlist.getvariable()
+ lambda x, y: x + y, [varlist.getvariable()
for varlist in configuration.globalVars],
[])])
return variables
@@ -1396,7 +1396,7 @@
resource.setglobalVars([
varlist for vartype, varlist
in self.ExtractVarLists(vars)])
-
+
# Return the resource globalvars
def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
project = self.GetProject(debug)
@@ -1406,11 +1406,11 @@
if resource is not None:
# Extract variables defined in configuration
return self.GetVariableDictionary(resource, debug)
-
+
return []
-
+
# Return resource variable names
- def GetConfigurationResourceVariableNames(self,
+ def GetConfigurationResourceVariableNames(self,
config_name = None, resource_name = None, debug = False):
variables = []
project = self.GetProject(debug)
@@ -1421,7 +1421,7 @@
if resource_name is None or resource.getname() == resource_name:
variables.extend(
[var.getname() for var in reduce(
- lambda x, y: x + y, [varlist.getvariable()
+ lambda x, y: x + y, [varlist.getvariable()
for varlist in resource.globalVars],
[])])
return variables
@@ -1445,7 +1445,7 @@
pou.interface = PLCOpenParser.CreateElement("interface", "pou")
# Set Pou interface
pou.setvars([varlist for varlist_type, varlist in self.ExtractVarLists(vars)])
-
+
# Replace the return type of the pou given by its name (only for functions)
def SetPouInterfaceReturnType(self, name, return_type):
if self.Project is not None:
@@ -1468,16 +1468,16 @@
derived_type = PLCOpenParser.CreateElement("derived", "dataType")
derived_type.setname(return_type)
return_type.setcontent(derived_type)
-
+
def UpdateProjectUsedPous(self, old_name, new_name):
if self.Project is not None:
self.Project.updateElementName(old_name, new_name)
-
+
def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name):
pou = self.GetEditedElement(tagname)
if pou is not None:
pou.updateElementName(old_name, new_name)
-
+
# Return the return type of the given pou
def GetPouInterfaceReturnType(self, pou, tree=False, debug=False):
# Verify that the pou has an interface
@@ -1486,23 +1486,23 @@
return_type = pou.interface.getreturnType()
if return_type is not None:
factory = VariablesInfosFactory([])
-
+
parser = etree.XMLParser()
parser.resolvers.add(LibraryResolver(self))
-
+
return_type_infos_xslt_tree = etree.XSLT(
etree.parse(
os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
- parser),
+ parser),
extensions = {("var_infos_ns", name): getattr(factory, name)
- for name in ["SetType", "AddDimension",
+ for name in ["SetType", "AddDimension",
"AddTree", "AddVarToTree"]})
return_type_infos_xslt_tree(return_type,
tree=etree.XSLT.strparam(str(tree)))
if tree:
return [factory.GetType(), factory.GetTree()]
return factory.GetType()
-
+
if tree:
return [None, ([], [])]
return None
@@ -1519,7 +1519,7 @@
for desc in cat["list"]:
BlkLst = self.TotalTypesDict.setdefault(desc["name"],[])
BlkLst.append((section["name"], desc))
-
+
# Function that clear the confnode list
def ClearConfNodeTypes(self):
self.ConfNodeTypes = []
@@ -1529,11 +1529,11 @@
def GetConfNodeDataTypes(self, exclude = None, only_locatables = False):
return [{"name": _("%s Data Types") % confnodetypes["name"],
"list": [
- datatype.getname()
+ datatype.getname()
for datatype in confnodetypes["types"].getdataTypes()
if not only_locatables or self.IsLocatableDataType(datatype, debug)]}
for confnodetypes in self.ConfNodeTypes]
-
+
def GetVariableLocationTree(self):
return []
@@ -1545,7 +1545,7 @@
for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
tempvar.setname(var_name)
-
+
tempvartype = PLCOpenParser.CreateElement("type", "variable")
if var_type in self.GetBaseTypes():
tempvartype.setcontent(PLCOpenParser.CreateElement(
@@ -1557,12 +1557,12 @@
tempderivedtype.setname(var_type)
tempvartype.setcontent(tempderivedtype)
tempvar.settype(tempvartype)
-
+
if var_initial != "":
value = PLCOpenParser.CreateElement("initialValue", "variable")
value.setvalue(var_initial)
tempvar.setinitialValue(value)
-
+
global_vars.append(tempvar)
return global_vars
@@ -1592,11 +1592,11 @@
blocktype_infos = blocktype.getblockInfos()
if inputs in [None, "undefined"]:
return blocktype_infos
-
- if inputs == tuple([var_type
+
+ if inputs == tuple([var_type
for name, var_type, modifier in blocktype_infos["inputs"]]):
return blocktype_infos
-
+
return None
# Return Block types checking for recursion
@@ -1610,18 +1610,18 @@
if words[0] in ["P","T","A"]:
name = words[1]
pou_type = self.GetPouType(name, debug)
- filter = (["function"]
- if pou_type == "function" or words[0] == "T"
+ filter = (["function"]
+ if pou_type == "function" or words[0] == "T"
else ["functionBlock", "function"])
blocktypes = [
{"name": category["name"],
"list": [block for block in category["list"]
if block["type"] in filter]}
for category in self.TotalTypes]
- blocktypes.append({"name" : USER_DEFINED_POUS,
+ blocktypes.append({"name" : USER_DEFINED_POUS,
"list": [pou.getblockInfos()
for pou in project.getpous(name, filter)
- if (name is None or
+ if (name is None or
len(self.GetInstanceList(pou, name, debug)) == 0)]})
return blocktypes
return self.TotalTypes
@@ -1641,7 +1641,7 @@
if project is not None:
blocktypes.extend([pou.getname()
for pou in project.getpous(name, ["functionBlock"])
- if (name is None or
+ if (name is None or
len(self.GetInstanceList(pou, name, debug)) == 0)])
return blocktypes
@@ -1672,10 +1672,10 @@
if words[0] in ["D"]:
name = words[1]
datatypes.extend([
- datatype.getname()
+ datatype.getname()
for datatype in project.getdataTypes(name)
if (not only_locatables or self.IsLocatableDataType(datatype, debug))
- and (name is None or
+ and (name is None or
len(self.GetInstanceList(datatype, name, debug)) == 0)])
if confnodetypes:
for category in self.GetConfNodeDataTypes(name, only_locatables):
@@ -1730,14 +1730,14 @@
def GetBaseType(self, typename, debug = False):
if TypeHierarchy.has_key(typename):
return typename
-
+
datatype = self.GetDataType(typename, debug)
if datatype is not None:
basetype = self.GetDataTypeBaseType(datatype)
if basetype is not None:
return self.GetBaseType(basetype, debug)
return typename
-
+
return None
def GetBaseTypes(self):
@@ -1751,19 +1751,19 @@
def IsOfType(self, typename, reference, debug = False):
if reference is None or typename == reference:
return True
-
+
basetype = TypeHierarchy.get(typename)
if basetype is not None:
return self.IsOfType(basetype, reference)
-
+
datatype = self.GetDataType(typename, debug)
if datatype is not None:
basetype = self.GetDataTypeBaseType(datatype)
if basetype is not None:
return self.IsOfType(basetype, reference, debug)
-
+
return False
-
+
def IsEndType(self, typename):
if typename is not None:
return not typename.startswith("ANY")
@@ -1781,16 +1781,16 @@
if array_base_type.getLocalTag() == "derived":
return self.IsLocatableType(array_base_type.getname(), debug)
return True
-
+
def IsLocatableType(self, typename, debug = False):
if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None:
return False
-
+
datatype = self.GetDataType(typename, debug)
if datatype is not None:
return self.IsLocatableDataType(datatype)
return True
-
+
def IsEnumeratedType(self, typename, debug = False):
if isinstance(typename, TupleType):
typename = typename[1]
@@ -1822,7 +1822,7 @@
def IsNumType(self, typename, debug = False):
return self.IsOfType(typename, "ANY_NUM", debug) or\
self.IsOfType(typename, "ANY_BIT", debug)
-
+
def GetDataTypeRange(self, typename, debug = False):
range = DataTypeRange.get(typename)
if range is not None:
@@ -1837,7 +1837,7 @@
elif basetype_content_type == "derived":
return self.GetDataTypeRange(basetype_content.getname(), debug)
return None
-
+
# Return Subrange types
def GetSubrangeBaseTypes(self, exclude, debug = False):
subrange_basetypes = DataTypeRange.keys()
@@ -1851,7 +1851,7 @@
[datatype.getname() for datatype in confnodetype["types"].getdataTypes()
if self.IsSubrangeType(datatype.getname(), exclude, debug)])
return subrange_basetypes
-
+
# Return Enumerated Values
def GetEnumeratedDataValues(self, typename = None, debug = False):
values = []
@@ -1861,7 +1861,7 @@
basetype_content = datatype_obj.baseType.getcontent()
basetype_content_type = basetype_content.getLocalTag()
if basetype_content_type == "enum":
- return [value.getname()
+ return [value.getname()
for value in basetype_content.xpath(
"ppx:values/ppx:value",
namespaces=PLCOpenParser.NSMAP)]
@@ -1878,19 +1878,19 @@
#-------------------------------------------------------------------------------
# Project Element tag name computation functions
#-------------------------------------------------------------------------------
-
+
# Compute a data type name
def ComputeDataTypeName(self, datatype):
return "D::%s" % datatype
-
+
# Compute a pou name
def ComputePouName(self, pou):
return "P::%s" % pou
-
+
# Compute a pou transition name
def ComputePouTransitionName(self, pou, transition):
return "T::%s::%s" % (pou, transition)
-
+
# Compute a pou action name
def ComputePouActionName(self, pou, action):
return "A::%s::%s" % (pou, action)
@@ -1905,7 +1905,7 @@
def GetElementType(self, tagname):
words = tagname.split("::")
- return {"D" : ITEM_DATATYPE, "P" : ITEM_POU,
+ return {"D" : ITEM_DATATYPE, "P" : ITEM_POU,
"T" : ITEM_TRANSITION, "A" : ITEM_ACTION,
"C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]]
@@ -1963,7 +1963,7 @@
dimensions.append((dimension.getlower(), dimension.getupper()))
base_type = element_type.baseType.getcontent()
base_type_type = element_type.getLocalTag()
- element_infos["Type"] = ("array",
+ element_infos["Type"] = ("array",
base_type.getname()
if base_type_type == "derived"
else base_type_type.upper(), dimensions)
@@ -1981,14 +1981,14 @@
infos["base_type"] = (basetype_content.getname()
if basetype_content_type == "derived"
else basetype_content_type.upper())
-
+
if datatype.initialValue is not None:
infos["initial"] = str(datatype.initialValue.getvalue())
else:
infos["initial"] = ""
return infos
return None
-
+
# Change the data type informations
def SetDataTypeInfos(self, tagname, infos):
words = tagname.split("::")
@@ -2006,7 +2006,7 @@
datatype.baseType.setcontent(derived_datatype)
elif infos["type"] == "Subrange":
subrange = PLCOpenParser.CreateElement(
- "subrangeUnsigned"
+ "subrangeUnsigned"
if infos["base_type"] in GetSubTypes("ANY_UINT")
else "subrangeSigned", "dataType")
datatype.baseType.setcontent(subrange)
@@ -2106,7 +2106,7 @@
else:
datatype.initialValue = None
self.BufferProject()
-
+
#-------------------------------------------------------------------------------
# Project opened Pous management functions
#-------------------------------------------------------------------------------
@@ -2132,7 +2132,7 @@
elif words[0] == 'R':
return project.getconfigurationResource(words[1], words[2])
return None
-
+
# Return edited element name
def GetEditedElementName(self, tagname):
words = tagname.split("::")
@@ -2141,7 +2141,7 @@
else:
return words[2]
return None
-
+
# Return edited element name and type
def GetEditedElementType(self, tagname, debug = False):
words = tagname.split("::")
@@ -2183,14 +2183,14 @@
elif words[0] == 'T':
return "BOOL"
return None
-
+
# Change the edited element text
def SetEditedElementText(self, tagname, text):
if self.Project is not None:
element = self.GetEditedElement(tagname)
if element is not None:
element.settext(text)
-
+
# Return the edited element text
def GetEditedElementText(self, tagname, debug = False):
element = self.GetEditedElement(tagname, debug)
@@ -2236,13 +2236,13 @@
if element is not None:
return element.tostring()
return ""
-
+
def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False):
element = self.GetEditedElement(tagname, debug)
text = ""
if element is not None:
- wires = dict([(wire, True)
- for wire in wires
+ wires = dict([(wire, True)
+ for wire in wires
if wire[0] in blocks_id and wire[1] in blocks_id])
copy_body = PLCOpenParser.CreateElement("body", "pou")
element.append(copy_body)
@@ -2257,20 +2257,20 @@
text += instance_copy.tostring()
element.remove(copy_body)
return text
-
+
def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False):
names = exclude.copy()
if tagname is not None:
- names.update(dict([(varname.upper(), True)
+ names.update(dict([(varname.upper(), True)
for varname in self.GetEditedElementVariables(tagname, debug)]))
words = tagname.split("::")
if words[0] in ["P","T","A"]:
element = self.GetEditedElement(tagname, debug)
if element is not None and element.getbodyType() not in ["ST", "IL"]:
for instance in element.getinstances():
- if isinstance(instance,
- (PLCOpenParser.GetElementClass("step", "sfcObjects"),
- PLCOpenParser.GetElementClass("connector", "commonObjects"),
+ if isinstance(instance,
+ (PLCOpenParser.GetElementClass("step", "sfcObjects"),
+ PLCOpenParser.GetElementClass("connector", "commonObjects"),
PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
names[instance.getname().upper()] = True
else:
@@ -2290,37 +2290,37 @@
names[config.getname().upper()] = True
for resource in config.getresource():
names[resource.getname().upper()] = True
-
+
i = start_idx
while name is None or names.get(name.upper(), False):
name = (format%i)
i += 1
return name
-
+
def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False):
element = self.GetEditedElement(tagname, debug)
element_name, element_type = self.GetEditedElementType(tagname, debug)
if element is not None:
bodytype = element.getbodyType()
-
+
# Get edited element type scaling
scaling = None
project = self.GetProject(debug)
if project is not None:
properties = project.getcontentHeader()
scaling = properties["scaling"][bodytype]
-
+
# Get ids already by all the instances in edited element
used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()])
new_id = {}
-
+
try:
instances, error = LoadPouInstances(text.encode("utf-8"), bodytype)
except:
instances, error = [], ""
if error is not None or len(instances) == 0:
return _("Invalid plcopen element(s)!!!")
-
+
exclude = {}
for instance in instances:
element.addinstance(instance)
@@ -2332,25 +2332,25 @@
if blocktype_infos["type"] != "function" and blockname is not None:
if element_type == "function":
return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
- blockname = self.GenerateNewName(tagname,
- blockname,
- "%s%%d"%blocktype,
+ blockname = self.GenerateNewName(tagname,
+ blockname,
+ "%s%%d"%blocktype,
debug=debug)
exclude[blockname] = True
instance.setinstanceName(blockname)
self.AddEditedElementPouVar(tagname, blocktype, blockname)
elif instance_type == "step":
- stepname = self.GenerateNewName(tagname,
- instance.getname(),
- "Step%d",
- exclude=exclude,
+ stepname = self.GenerateNewName(tagname,
+ instance.getname(),
+ "Step%d",
+ exclude=exclude,
debug=debug)
exclude[stepname] = True
instance.setname(stepname)
localid = instance.getlocalId()
if not used_id.has_key(localid):
new_id[localid] = True
-
+
idx = 1
translate_id = {}
bbox = rect()
@@ -2363,7 +2363,7 @@
new_id[idx] = True
instance.setlocalId(idx)
translate_id[localId] = idx
-
+
x, y, width, height = bbox.bounding_box()
if middle:
new_pos[0] -= width / 2
@@ -2385,43 +2385,43 @@
else:
new_pos = (max(30, new_pos[0]), max(30, new_pos[1]))
diff = (int(new_pos[0] - x), int(new_pos[1] - y))
-
+
connections = {}
for instance in instances:
connections.update(instance.updateConnectionsId(translate_id))
if getattr(instance, "setexecutionOrderId", None) is not None:
instance.setexecutionOrderId(0)
instance.translate(*diff)
-
+
return new_id, connections
-
+
def GetEditedElementInstancesInfos(self, tagname, debug = False):
element_instances = OrderedDict()
element = self.GetEditedElement(tagname, debug)
if element is not None:
factory = BlockInstanceFactory(element_instances)
-
+
pou_block_instances_xslt_tree = etree.XSLT(
- pou_block_instances_xslt,
+ pou_block_instances_xslt,
extensions = {
("pou_block_instances_ns", name): getattr(factory, name)
for name in ["AddBlockInstance", "SetSpecificValues",
"AddInstanceConnection", "AddConnectionLink",
"AddLinkPoint", "AddAction"]})
-
+
pou_block_instances_xslt_tree(element)
return element_instances
-
+
def ClearEditedElementExecutionOrder(self, tagname):
element = self.GetEditedElement(tagname)
if element is not None:
element.resetexecutionOrder()
-
+
def ResetEditedElementExecutionOrder(self, tagname):
element = self.GetEditedElement(tagname)
if element is not None:
element.compileexecutionOrder()
-
+
def SetConnectionWires(self, connection, connector):
wires = connector.GetWires()
idx = 0
@@ -2443,7 +2443,7 @@
else:
connection.setconnectionParameter(idx, None)
idx += 1
-
+
def GetVarTypeObject(self, var_type):
var_type_obj = PLCOpenParser.CreateElement("type", "variable")
if not var_type.startswith("ANY") and TypeHierarchy.get(var_type):
@@ -2455,7 +2455,7 @@
derived_type.setname(var_type)
var_type_obj.setcontent(derived_type)
return var_type_obj
-
+
def AddEditedElementPouVar(self, tagname, var_type, name,**args):
if self.Project is not None:
words = tagname.split("::")
@@ -2463,9 +2463,9 @@
pou = self.Project.getpou(words[1])
if pou is not None:
pou.addpouLocalVar(
- self.GetVarTypeObject(var_type),
+ self.GetVarTypeObject(var_type),
name, **args)
-
+
def AddEditedElementPouExternalVar(self, tagname, var_type, name):
if self.Project is not None:
words = tagname.split("::")
@@ -2474,7 +2474,7 @@
if pou is not None:
pou.addpouExternalVar(
self.GetVarTypeObject(var_type), name)
-
+
def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
if self.Project is not None:
words = tagname.split("::")
@@ -2482,7 +2482,7 @@
pou = self.Project.getpou(words[1])
if pou is not None:
pou.changepouVar(old_type, old_name, new_type, new_name)
-
+
def RemoveEditedElementPouVar(self, tagname, type, name):
if self.Project is not None:
words = tagname.split("::")
@@ -2490,7 +2490,7 @@
pou = self.Project.getpou(words[1])
if pou is not None:
pou.removepouVar(type, name)
-
+
def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2502,13 +2502,13 @@
block.setinstanceName(blockname)
self.AddEditedElementPouVar(tagname, blocktype, blockname)
element.addinstance(block)
-
+
def SetEditedElementBlockInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
block = element.getinstance(id)
if block is None:
- return
+ return
old_name = block.getinstanceName()
old_type = block.gettypeName()
new_name = infos.get("name", old_name)
@@ -2571,7 +2571,7 @@
variable.addconnectionPointOut()
variable.connectionPointOut.setrelPositionXY(position.x, position.y)
block.tostring()
-
+
def AddEditedElementVariable(self, tagname, id, var_type):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2581,13 +2581,13 @@
INOUT: "inOutVariable"}[var_type], "fbdObjects")
variable.setlocalId(id)
element.addinstance(variable)
-
+
def SetEditedElementVariableInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
variable = element.getinstance(id)
if variable is None:
- return
+ return
for param, value in infos.items():
if param == "name":
variable.setexpression(value)
@@ -2634,7 +2634,7 @@
CONTINUATION: "continuation"}[connection_type], "commonObjects")
connection.setlocalId(id)
element.addinstance(connection)
-
+
def SetEditedElementConnectionInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2643,7 +2643,7 @@
return
for param, value in infos.items():
if param == "name":
- connection.setname(value)
+ connection.setname(value)
elif param == "height":
connection.setheight(value)
elif param == "width":
@@ -2668,7 +2668,7 @@
comment = PLCOpenParser.CreateElement("comment", "commonObjects")
comment.setlocalId(id)
element.addinstance(comment)
-
+
def SetEditedElementCommentInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2693,7 +2693,7 @@
RIGHTRAIL: "rightPowerRail"}[powerrail_type], "ldObjects")
powerrail.setlocalId(id)
element.addinstance(powerrail)
-
+
def SetEditedElementPowerRailInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2725,7 +2725,7 @@
powerrail.appendconnectionPointIn(connection)
connection.setrelPositionXY(position.x, position.y)
self.SetConnectionWires(connection, connector)
-
+
def AddEditedElementContact(self, tagname, id):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2821,7 +2821,7 @@
step = PLCOpenParser.CreateElement("step", "sfcObjects")
step.setlocalId(id)
element.addinstance(step)
-
+
def SetEditedElementStepInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2864,14 +2864,14 @@
step.connectionPointOutAction.setrelPositionXY(position.x, position.y)
else:
step.deleteconnectionPointOutAction()
-
+
def AddEditedElementTransition(self, tagname, id):
element = self.GetEditedElement(tagname)
if element is not None:
transition = PLCOpenParser.CreateElement("transition", "sfcObjects")
transition.setlocalId(id)
element.addinstance(transition)
-
+
def SetEditedElementTransitionInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2907,7 +2907,7 @@
elif infos.get("type", None) == "connection" and param == "connection" and value:
transition.setconditionContent("connection", None)
self.SetConnectionWires(transition.condition.content, value)
-
+
def AddEditedElementDivergence(self, tagname, id, divergence_type):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2919,19 +2919,19 @@
divergence_type), "sfcObjects")
divergence.setlocalId(id)
element.addinstance(divergence)
-
+
DivergenceTypes = [
- (divergence_type,
+ (divergence_type,
PLCOpenParser.GetElementClass(divergence_type, "sfcObjects"))
for divergence_type in ["selectionDivergence", "simultaneousDivergence",
"selectionConvergence", "simultaneousConvergence"]]
-
+
def GetDivergenceType(self, divergence):
for divergence_type, divergence_class in self.DivergenceTypes:
if isinstance(divergence, divergence_class):
return divergence_type
return None
-
+
def SetEditedElementDivergenceInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -2975,14 +2975,14 @@
connection = PLCOpenParser.CreateElement("connectionPointOut", divergence_type)
divergence.appendconnectionPointOut(connection)
connection.setrelPositionXY(position.x, position.y)
-
+
def AddEditedElementJump(self, tagname, id):
element = self.GetEditedElement(tagname)
if element is not None:
jump = PLCOpenParser.CreateElement("jumpStep", "sfcObjects")
jump.setlocalId(id)
element.addinstance(jump)
-
+
def SetEditedElementJumpInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -3005,14 +3005,14 @@
jump.addconnectionPointIn()
jump.connectionPointIn.setrelPositionXY(position.x, position.y)
self.SetConnectionWires(jump.connectionPointIn, value)
-
+
def AddEditedElementActionBlock(self, tagname, id):
element = self.GetEditedElement(tagname)
if element is not None:
actionBlock = PLCOpenParser.CreateElement("actionBlock", "commonObjects")
actionBlock.setlocalId(id)
element.addinstance(actionBlock)
-
+
def SetEditedElementActionBlockInfos(self, tagname, id, infos):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -3035,7 +3035,7 @@
actionBlock.addconnectionPointIn()
actionBlock.connectionPointIn.setrelPositionXY(position.x, position.y)
self.SetConnectionWires(actionBlock.connectionPointIn, value)
-
+
def RemoveEditedElementInstance(self, tagname, id):
element = self.GetEditedElement(tagname)
if element is not None:
@@ -3162,19 +3162,19 @@
self.Buffering = False
self.CurrentElementEditing = None
return error
-
+
def SaveXMLFile(self, filepath = None):
if not filepath and self.FilePath == "":
return False
else:
contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])}
self.Project.setcontentHeader(contentheader)
-
+
if filepath:
SaveProject(self.Project, filepath)
else:
SaveProject(self.Project, self.FilePath)
-
+
self.MarkProjectAsSaved()
if filepath:
self.SetFilePath(filepath)
@@ -3233,7 +3233,7 @@
self.Buffering = True
else:
self.ProjectSaved = False
-
+
def EndBuffering(self):
if self.ProjectBuffer is not None and self.Buffering:
self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project))
@@ -3245,7 +3245,7 @@
self.ProjectBuffer.CurrentSaved()
else:
self.ProjectSaved = True
-
+
# Return if project is saved
def ProjectIsSaved(self):
if self.ProjectBuffer is not None:
@@ -3257,11 +3257,11 @@
self.EndBuffering()
if self.ProjectBuffer is not None:
self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Previous())
-
+
def LoadNext(self):
if self.ProjectBuffer is not None:
self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Next())
-
+
def GetBufferState(self):
if self.ProjectBuffer is not None:
first = self.ProjectBuffer.IsFirst() and not self.Buffering
--- a/ProjectController.py Mon May 26 14:44:03 2014 +0100
+++ b/ProjectController.py Fri Jun 06 18:30:49 2014 +0100
@@ -1,5 +1,5 @@
"""
-Beremiz Project Controller
+Beremiz Project Controller
"""
import os,sys,traceback
import time
@@ -63,14 +63,14 @@
class ProjectController(ConfigTreeNode, PLCControler):
"""
- This class define Root object of the confnode tree.
+ This class define Root object of the confnode tree.
It is responsible of :
- Managing project directory
- Building project
- Handling PLCOpenEditor controler and view
- Loading user confnodes and instanciante them as children
- ...
-
+
"""
# For root object, available Children Types are modules of the confnode packages.
@@ -87,15 +87,15 @@
"""+targets.GetTargetChoices()+"""
</xsd:choice>
</xsd:complexType>
- </xsd:element>
- <xsd:element name="Libraries" minOccurs="0">"""+(("""
+ </xsd:element>"""+(("""
+ <xsd:element name="Libraries" minOccurs="0">
<xsd:complexType>
"""+"\n".join(['<xsd:attribute name='+
'"Enable_'+ libname + '_Library" '+
- 'type="xsd:boolean" use="optional" default="true"/>'
+ 'type="xsd:boolean" use="optional" default="true"/>'
for libname,lib in features.libraries])+"""
- </xsd:complexType>""") if len(features.libraries)>0 else '<xsd:complexType/>') + """
- </xsd:element>
+ </xsd:complexType>
+ </xsd:element>""") if len(features.libraries)>0 else '') + """
</xsd:sequence>
<xsd:attribute name="URI_location" type="xsd:string" use="optional" default=""/>
<xsd:attribute name="Disable_Extensions" type="xsd:boolean" use="optional" default="false"/>
@@ -104,7 +104,7 @@
</xsd:schema>
"""
EditorType = ProjectNodeEditor
-
+
def __init__(self, frame, logger):
PLCControler.__init__(self)
@@ -115,10 +115,10 @@
self.DebugValuesBuffers = []
self.DebugTicks = []
self.SetAppFrame(frame, logger)
-
+
self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else ""))
self.ieclib_path = os.path.join(base_folder, "matiec", "lib")
-
+
# Setup debug information
self.IECdebug_datas = {}
self.IECdebug_lock = Lock()
@@ -147,7 +147,7 @@
if self.DebugTimer:
self.DebugTimer.cancel()
self.KillDebugThread()
-
+
def LoadLibraries(self):
self.Libraries = []
TypeStack=[]
@@ -156,7 +156,7 @@
Lib = GetClassImporter(clsname)()(self, libname, TypeStack)
TypeStack.append(Lib.GetTypes())
self.Libraries.append(Lib)
-
+
def SetAppFrame(self, frame, logger):
self.AppFrame = frame
self.logger = logger
@@ -164,23 +164,23 @@
if self.DispatchDebugValuesTimer is not None:
self.DispatchDebugValuesTimer.Stop()
self.DispatchDebugValuesTimer = None
-
+
if frame is not None:
-
+
# Timer to pull PLC status
self.StatusTimer = wx.Timer(self.AppFrame, -1)
- self.AppFrame.Bind(wx.EVT_TIMER,
+ self.AppFrame.Bind(wx.EVT_TIMER,
self.PullPLCStatusProc, self.StatusTimer)
if self._connector is not None:
frame.LogViewer.SetLogSource(self._connector)
self.StatusTimer.Start(milliseconds=500, oneShot=False)
-
+
# Timer to dispatch debug values to consumers
self.DispatchDebugValuesTimer = wx.Timer(self.AppFrame, -1)
- self.AppFrame.Bind(wx.EVT_TIMER,
+ self.AppFrame.Bind(wx.EVT_TIMER,
self.DispatchDebugValuesProc, self.DispatchDebugValuesTimer)
-
+
self.RefreshConfNodesBlockLists()
def ResetAppFrame(self, logger):
@@ -188,7 +188,7 @@
self.AppFrame.Unbind(wx.EVT_TIMER, self.StatusTimer)
self.StatusTimer = None
self.AppFrame = None
-
+
self.logger = logger
def CTNName(self):
@@ -205,16 +205,16 @@
def GetIECLibPath(self):
return self.ieclib_path
-
+
def GetIEC2cPath(self):
return self.iec2c_path
-
+
def GetCurrentLocation(self):
return ()
def GetCurrentName(self):
return ""
-
+
def _GetCurrentName(self):
return ""
@@ -223,10 +223,10 @@
def GetProjectName(self):
return os.path.split(self.ProjectPath)[1]
-
+
def GetIconName(self):
return "PROJECT"
-
+
def GetDefaultTargetName(self):
if wx.Platform == '__WXMSW__':
return "Win32"
@@ -242,15 +242,15 @@
target_name = self.GetDefaultTargetName()
target.setcontent(self.Parser.CreateElement(target_name, "TargetType"))
return target
-
+
def GetParamsAttributes(self, path = None):
params = ConfigTreeNode.GetParamsAttributes(self, path)
if params[0]["name"] == "BeremizRoot":
for child in params[0]["children"]:
if child["name"] == "TargetType" and child["value"] == '':
- child.update(self.GetTarget().getElementInfos("TargetType"))
+ child.update(self.GetTarget().getElementInfos("TargetType"))
return params
-
+
def SetParamsAttribute(self, path, value):
if path.startswith("BeremizRoot.TargetType.") and self.BeremizRoot.getTargetType().getcontent() is None:
self.BeremizRoot.setTargetType(self.GetTarget())
@@ -258,15 +258,15 @@
if path.startswith("BeremizRoot.Libraries."):
wx.CallAfter(self.RefreshConfNodesBlockLists)
return res
-
+
# helper func to check project path write permission
def CheckProjectPathPerm(self, dosave=True):
if CheckPathPerm(self.ProjectPath):
return True
if self.AppFrame is not None:
- dialog = wx.MessageDialog(self.AppFrame,
+ dialog = wx.MessageDialog(self.AppFrame,
_('You must have permission to work on the project\nWork on a project copy ?'),
- _('Error'),
+ _('Error'),
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
answer = dialog.ShowModal()
dialog.Destroy()
@@ -277,7 +277,7 @@
self.AppFrame.RefreshPageTitles()
return True
return False
-
+
def _getProjectFilesPath(self, project_path=None):
if project_path is not None:
return os.path.join(project_path, "project_files")
@@ -285,7 +285,7 @@
if not os.path.exists(projectfiles_path):
os.mkdir(projectfiles_path)
return projectfiles_path
-
+
def AddProjectDefaultConfiguration(self, config_name="config", res_name="resource1"):
self.ProjectAddConfiguration(config_name)
self.ProjectAddConfigurationResource(config_name, res_name)
@@ -299,7 +299,7 @@
# Verify that chosen folder is empty
if not os.path.isdir(ProjectPath) or len(os.listdir(ProjectPath)) > 0:
return _("Chosen folder isn't empty. You can't use it for a new project!")
-
+
# Create PLCOpen program
self.CreateNewProject(
{"projectName": _("Unnamed"),
@@ -308,7 +308,7 @@
"companyName": _("Unknown"),
"creationDateTime": datetime(*localtime()[:6])})
self.AddProjectDefaultConfiguration()
-
+
# Change XSD into class members
self._AddParamsMembers()
self.Children = {}
@@ -320,7 +320,7 @@
# this will create files base XML files
self.SaveProject()
return None
-
+
def LoadProject(self, ProjectPath, BuildPath=None):
"""
Load a project contained in a folder
@@ -357,30 +357,30 @@
#Load and init all the children
self.LoadChildren()
self.RefreshConfNodesBlockLists()
-
+
if os.path.exists(self._getBuildPath()):
self.EnableMethod("_Clean", True)
if os.path.isfile(self._getIECcodepath()):
self.ShowMethod("_showIECcode", True)
-
+
self.UpdateMethodsFromPLCStatus()
-
+
return None
-
+
def RecursiveConfNodeInfos(self, confnode):
values = []
for CTNChild in confnode.IECSortedChildren():
values.append(
{"name": "%s: %s" % (CTNChild.GetFullIEC_Channel(),
- CTNChild.CTNName()),
+ CTNChild.CTNName()),
"tagname": CTNChild.CTNFullName(),
- "type": ITEM_CONFNODE,
+ "type": ITEM_CONFNODE,
"confnode": CTNChild,
"icon": CTNChild.GetIconName(),
"values": self.RecursiveConfNodeInfos(CTNChild)})
return values
-
+
def GetProjectInfos(self):
infos = PLCControler.GetProjectInfos(self)
configurations = infos["values"].pop(-1)
@@ -394,23 +394,23 @@
infos["values"].append(resources)
infos["values"].extend(self.RecursiveConfNodeInfos(self))
return infos
-
+
def CloseProject(self):
self.ClearChildren()
self.ResetAppFrame(None)
-
+
def SaveProject(self, from_project_path=None):
if self.CheckProjectPathPerm(False):
if from_project_path is not None:
old_projectfiles_path = self._getProjectFilesPath(from_project_path)
if os.path.isdir(old_projectfiles_path):
- shutil.copytree(old_projectfiles_path,
+ shutil.copytree(old_projectfiles_path,
self._getProjectFilesPath(self.ProjectPath))
self.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml'))
result = self.CTNRequestSave(from_project_path)
if result:
self.logger.write_error(result)
-
+
def SaveProjectAs(self):
# Ask user to choose a path with write permissions
if wx.Platform == '__WXMSW__':
@@ -444,12 +444,12 @@
LocatedCCodeAndFlags=[]
Extras=[]
for lib in self.Libraries:
- res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags)
+ res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags)
LocatedCCodeAndFlags.append(res[:2])
if len(res)>2:
Extras.extend(res[2:])
return map(list,zip(*LocatedCCodeAndFlags))+[tuple(Extras)]
-
+
# Update PLCOpenEditor ConfNode Block types from loaded confnodes
def RefreshConfNodesBlockLists(self):
if getattr(self, "Children", None) is not None:
@@ -458,7 +458,7 @@
if self.AppFrame is not None:
self.AppFrame.RefreshLibraryPanel()
self.AppFrame.RefreshEditor()
-
+
# Update a PLCOpenEditor Pou variable location
def UpdateProjectVariableLocation(self, old_leading, new_leading):
self.Project.updateElementAddress(old_leading, new_leading)
@@ -469,13 +469,13 @@
self.AppFrame.RefreshFileMenu()
self.AppFrame.RefreshEditMenu()
wx.CallAfter(self.AppFrame.RefreshEditor)
-
+
def GetVariableLocationTree(self):
'''
This function is meant to be overridden by confnodes.
It should returns an list of dictionaries
-
+
- IEC_type is an IEC type like BOOL/BYTE/SINT/...
- location is a string of this variable's location, like "%IX0.0.0"
'''
@@ -483,13 +483,13 @@
for child in self.IECSortedChildren():
children.append(child.GetVariableLocationTree())
return children
-
+
def ConfNodePath(self):
return os.path.split(__file__)[0]
-
+
def CTNPath(self, CTNName=None):
return self.ProjectPath
-
+
def ConfNodeXmlFilePath(self, CTNName=None):
return os.path.join(self.CTNPath(CTNName), "beremiz.xml")
@@ -515,26 +515,26 @@
# Create a build path in temp folder
else:
self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build")
-
+
if not os.path.exists(self.DefaultBuildPath):
os.makedirs(self.DefaultBuildPath)
return self.DefaultBuildPath
-
+
def _getExtraFilesPath(self):
return os.path.join(self._getBuildPath(), "extra_files")
def _getIECcodepath(self):
# define name for IEC code file
return os.path.join(self._getBuildPath(), "plc.st")
-
+
def _getIECgeneratedcodepath(self):
# define name for IEC generated code file
return os.path.join(self._getBuildPath(), "generated_plc.st")
-
+
def _getIECrawcodepath(self):
# define name for IEC raw code file
return os.path.join(self.CTNPath(), "raw_plc.st")
-
+
def GetLocations(self):
locations = []
filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h")
@@ -546,24 +546,29 @@
# This regular expression parses the lines genereated by IEC2C
LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)")
for line in lines:
- # If line match RE,
+ # If line match RE,
result = LOCATED_MODEL.match(line)
if result:
# Get the resulting dict
resdict = result.groupdict()
# rewrite string for variadic location as a tuple of integers
resdict['LOC'] = tuple(map(int,resdict['LOC'].split(',')))
- # set located size to 'X' if not given
+ # set located size to 'X' if not given
if not resdict['SIZE']:
resdict['SIZE'] = 'X'
# finally store into located variable list
locations.append(resdict)
return locations
-
+
def GetConfNodeGlobalInstances(self):
return self._GlobalInstances()
-
+
def _Generate_SoftPLC(self):
+ if self._Generate_PLC_ST():
+ return self._Compile_ST_to_SoftPLC()
+ return False
+
+ def _Generate_PLC_ST(self):
"""
Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C
@param buildpath: path where files should be created
@@ -571,9 +576,8 @@
# Update PLCOpenEditor ConfNode Block types before generate ST code
self.RefreshConfNodesBlockLists()
-
+
self.logger.write(_("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n"))
- buildpath = self._getBuildPath()
# ask PLCOpenEditor controller to write ST/IL/SFC code file
program, errors, warnings = self.GenerateProgram(self._getIECgeneratedcodepath())
if len(warnings) > 0:
@@ -599,22 +603,25 @@
plc_file = open(self._getIECcodepath(), "a")
plc_file.write(open(self._getIECgeneratedcodepath(), "r").read())
plc_file.close()
-
+ return True
+
+ def _Compile_ST_to_SoftPLC(self):
self.logger.write(_("Compiling IEC Program into C code...\n"))
+ buildpath = self._getBuildPath()
# Now compile IEC code into many C files
- # files are listed to stdout, and errors to stderr.
+ # files are listed to stdout, and errors to stderr.
status, result, err_result = ProcessLogger(
self.logger,
"\"%s\" -f -I \"%s\" -T \"%s\" \"%s\""%(
self.iec2c_path,
- self.ieclib_path,
+ self.ieclib_path,
buildpath,
self._getIECcodepath()),
no_stdout=True, no_stderr=True).spin()
if status:
# Failed !
-
+
# parse iec2c's error message. if it contains a line number,
# then print those lines from the generated IEC file.
for err_line in err_result.split('\n'):
@@ -624,7 +631,7 @@
if m_result is not None:
first_line, first_column, last_line, last_column, error = m_result.groups()
first_line, last_line = int(first_line), int(last_line)
-
+
last_section = None
f = open(self._getIECcodepath())
@@ -640,10 +647,10 @@
self.logger.write_warning("%04d: %s" % (i, line))
f.close()
-
+
self.logger.write_error(_("Error : IEC to C compiler returned %d\n")%status)
return False
-
+
# Now extract C files of stdout
C_files = [ fname for fname in result.splitlines() if fname[-2:]==".c" or fname[-2:]==".C" ]
# remove those that are not to be compiled because included by others
@@ -679,7 +686,7 @@
targetname = self.GetTarget().getcontent().getLocalTag()
targetclass = targets.GetBuilder(targetname)
- # if target already
+ # if target already
if self._builder is None or not isinstance(self._builder,targetclass):
# Get classname instance
self._builder = targetclass(self)
@@ -703,20 +710,20 @@
# C CODE GENERATION METHODS
#
#######################################################################
-
+
def CTNGenerate_C(self, buildpath, locations):
"""
- Return C code generated by iec2c compiler
+ Return C code generated by iec2c compiler
when _generate_softPLC have been called
@param locations: ignored
@return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
"""
- return ([(C_file_name, self.plcCFLAGS)
- for C_file_name in self.PLCGeneratedCFiles ],
+ return ([(C_file_name, self.plcCFLAGS)
+ for C_file_name in self.PLCGeneratedCFiles ],
"", # no ldflags
False) # do not expose retreive/publish calls
-
+
def ResetIECProgramsAndVariables(self):
"""
Reset variable and program list that are parsed from
@@ -743,7 +750,7 @@
self._ProgramList = []
self._VariablesList = []
self._IECPathToIdx = {}
-
+
# Separate sections
ListGroup = []
for line in open(csvfile,'r').xreadlines():
@@ -754,7 +761,7 @@
elif len(strippedline) > 0 and len(ListGroup) > 0:
# append to this section
ListGroup[-1].append(strippedline)
-
+
# first section contains programs
for line in ListGroup[0]:
# Split and Maps each field to dictionnary entries
@@ -763,7 +770,7 @@
attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:])
# Push this dictionnary into result.
self._ProgramList.append(attrs)
-
+
# second section contains all variables
config_FBs = {}
for line in ListGroup[1]:
@@ -776,7 +783,7 @@
if config_FB:
parts = [config_FB] + parts[2:]
attrs["C_path"] = '.'.join(parts)
- else:
+ else:
attrs["C_path"] = '__'.join(parts[1:])
else:
attrs["C_path"] = '__'.join(parts)
@@ -788,11 +795,11 @@
IEC_path=attrs["IEC_path"]
Idx=int(attrs["num"])
self._IECPathToIdx[IEC_path]=(Idx, attrs["type"])
-
+
# third section contains ticktime
if len(ListGroup) > 2:
- self._Ticktime = int(ListGroup[2][0])
-
+ self._Ticktime = int(ListGroup[2][0])
+
except Exception,e:
self.logger.write_error(_("Cannot open/parse VARIABLES.csv!\n"))
self.logger.write_error(traceback.format_exc())
@@ -818,7 +825,7 @@
"MEM":"extern __IEC_%(type)s_p %(C_path)s;",
"OUT":"extern __IEC_%(type)s_p %(C_path)s;",
"VAR":"extern __IEC_%(type)s_t %(C_path)s;",
- "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v
+ "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v
for v in self._VariablesList if v["C_path"].find('.')<0]),
"for_each_variable_do_code":"\n".join([
{"EXT":" (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
@@ -836,9 +843,9 @@
"OUT":" return %(type)s_O_ENUM;\n",
"VAR":" return %(type)s_ENUM;\n"}[v["vartype"]]%v
for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ])}
-
+
return debug_code
-
+
def Generate_plc_main(self):
"""
Use confnodes layout given in LocationCFilesAndCFLAGS to
@@ -848,7 +855,7 @@
# in retreive, publish, init, cleanup
locstrs = map(lambda x:"_".join(map(str,x)),
[loc for loc,Cfiles,DoCalls in self.LocationCFilesAndCFLAGS if loc and DoCalls])
-
+
# Generate main, based on template
if not self.BeremizRoot.getDisable_Extensions():
plc_main_code = targets.GetCode("plc_main_head") % {
@@ -882,7 +889,7 @@
plc_main_code += targets.GetCode("plc_main_tail")
return plc_main_code
-
+
def _Build(self):
"""
Method called by user to (re)build SoftPLC and confnode tree
@@ -890,7 +897,7 @@
if self.AppFrame is not None:
self.AppFrame.ClearErrors()
self._CloseView(self._IECCodeView)
-
+
buildpath = self._getBuildPath()
# Eventually create build dir
@@ -908,21 +915,52 @@
# If IEC code gen fail, bail out.
if not IECGenRes:
- self.logger.write_error(_("IEC-61131-3 code generation failed !\n"))
+ self.logger.write_error(_("PLC code generation failed !\n"))
self.ResetBuildMD5()
return False
# Reset variable and program list that are parsed from
# CSV file generated by IEC2C compiler.
self.ResetIECProgramsAndVariables()
-
+
+ # Collect platform specific C code
+ # Code and other files from extension
+ if not self._Generate_runtime():
+ return False
+
+ # Get current or fresh builder
+ builder = self.GetBuilder()
+ if builder is None:
+ self.logger.write_error(_("Fatal : cannot get builder.\n"))
+ self.ResetBuildMD5()
+ return False
+
+ # Build
+ try:
+ if not builder.build() :
+ self.logger.write_error(_("C Build failed.\n"))
+ return False
+ except Exception, exc:
+ self.logger.write_error(_("C Build crashed !\n"))
+ self.logger.write_error(traceback.format_exc())
+ self.ResetBuildMD5()
+ return False
+
+ self.logger.write(_("Successfully built.\n"))
+ # Update GUI status about need for transfer
+ self.CompareLocalAndRemotePLC()
+ return True
+
+ def _Generate_runtime(self):
+ buildpath = self._getBuildPath()
+
# Generate C code and compilation params from confnode hierarchy
try:
CTNLocationCFilesAndCFLAGS, CTNLDFLAGS, CTNExtraFiles = self._Generate_C(
- buildpath,
+ buildpath,
self.PLCGeneratedLocatedVars)
except Exception, exc:
- self.logger.write_error(_("Runtime extensions C code generation failed !\n"))
+ self.logger.write_error(_("Runtime IO extensions C code generation failed !\n"))
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
@@ -931,7 +969,7 @@
try:
LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath)
except Exception, exc:
- self.logger.write_error(_("Runtime extensions C code generation failed !\n"))
+ self.logger.write_error(_("Runtime library extensions C code generation failed !\n"))
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
@@ -939,7 +977,7 @@
self.LocationCFilesAndCFLAGS = CTNLocationCFilesAndCFLAGS + LibCFilesAndCFLAGS
self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
ExtraFiles = CTNExtraFiles + LibExtraFiles
-
+
# Get temporary directory path
extrafilespath = self._getExtraFilesPath()
# Remove old directory
@@ -953,7 +991,7 @@
open(fpath, "wb").write(fobject.read())
# Now we can forget ExtraFiles (will close files object)
del ExtraFiles
-
+
# Header file for extensions
open(os.path.join(buildpath,"beremiz.h"), "w").write(targets.GetHeader())
@@ -978,32 +1016,9 @@
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
-
self.logger.write(_("C code generated successfully.\n"))
-
- # Get current or fresh builder
- builder = self.GetBuilder()
- if builder is None:
- self.logger.write_error(_("Fatal : cannot get builder.\n"))
- self.ResetBuildMD5()
- return False
-
- # Build
- try:
- if not builder.build() :
- self.logger.write_error(_("C Build failed.\n"))
- return False
- except Exception, exc:
- self.logger.write_error(_("C Build crashed !\n"))
- self.logger.write_error(traceback.format_exc())
- self.ResetBuildMD5()
- return False
-
- self.logger.write(_("Successfully built.\n"))
- # Update GUI status about need for transfer
- self.CompareLocalAndRemotePLC()
return True
-
+
def ShowError(self, logger, from_location, to_location):
chunk_infos = self.GetChunkInfos(from_location, to_location)
for infos, (start_row, start_col) in chunk_infos:
@@ -1011,7 +1026,7 @@
end = (to_location[0] - start_row, to_location[1] - start_col)
if self.AppFrame is not None:
self.AppFrame.ShowError(infos, start, end)
-
+
_IECCodeView = None
def _showIECcode(self):
self._OpenView("IEC code")
@@ -1019,20 +1034,20 @@
_IECRawCodeView = None
def _editIECrawcode(self):
self._OpenView("IEC raw code")
-
+
_ProjectFilesView = None
def _OpenProjectFiles(self):
self._OpenView("Project Files")
-
+
_FileEditors = {}
def _OpenFileEditor(self, filepath):
self._OpenView(filepath)
-
+
def _OpenView(self, name=None, onlyopened=False):
if name == "IEC code":
if self._IECCodeView is None:
plc_file = self._getIECcodepath()
-
+
self._IECCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name)
self._IECCodeView.SetTextSyntax("ALL")
self._IECCodeView.SetKeywords(IEC_KEYWORDS)
@@ -1043,78 +1058,78 @@
self._IECCodeView.SetText(text = text)
self._IECCodeView.SetIcon(GetBitmap("ST"))
setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor)
-
+
if self._IECCodeView is not None:
self.AppFrame.EditProjectElement(self._IECCodeView, name)
-
+
return self._IECCodeView
-
+
elif name == "IEC raw code":
if self._IECRawCodeView is None:
controler = MiniTextControler(self._getIECrawcodepath(), self)
-
+
self._IECRawCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name)
self._IECRawCodeView.SetTextSyntax("ALL")
self._IECRawCodeView.SetKeywords(IEC_KEYWORDS)
self._IECRawCodeView.RefreshView()
self._IECRawCodeView.SetIcon(GetBitmap("ST"))
setattr(self._IECRawCodeView, "_OnClose", self.OnCloseEditor)
-
+
if self._IECRawCodeView is not None:
self.AppFrame.EditProjectElement(self._IECRawCodeView, name)
-
+
return self._IECRawCodeView
-
+
elif name == "Project Files":
if self._ProjectFilesView is None:
self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True)
-
+
extensions = []
for extension, name, editor in features.file_editors:
if extension not in extensions:
extensions.append(extension)
- self._ProjectFilesView.SetEditableFileExtensions(extensions)
-
+ self._ProjectFilesView.SetEditableFileExtensions(extensions)
+
if self._ProjectFilesView is not None:
self.AppFrame.EditProjectElement(self._ProjectFilesView, name)
-
+
return self._ProjectFilesView
-
+
elif name is not None and name.find("::") != -1:
filepath, editor_name = name.split("::")
if not self._FileEditors.has_key(filepath):
if os.path.isfile(filepath):
file_extension = os.path.splitext(filepath)[1]
-
+
editors = dict([(edit_name, edit_class)
for extension, edit_name, edit_class in features.file_editors
if extension == file_extension])
-
+
if editor_name == "":
if len(editors) == 1:
editor_name = editors.keys()[0]
elif len(editors) > 0:
names = editors.keys()
- dialog = wx.SingleChoiceDialog(self.AppFrame,
- _("Select an editor:"), _("Editor selection"),
+ dialog = wx.SingleChoiceDialog(self.AppFrame,
+ _("Select an editor:"), _("Editor selection"),
names, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
editor_name = names[dialog.GetSelection()]
dialog.Destroy()
-
+
if editor_name != "":
name = "::".join([filepath, editor_name])
-
+
editor = editors[editor_name]()
self._FileEditors[filepath] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame)
self._FileEditors[filepath].SetIcon(GetBitmap("FILE"))
if isinstance(self._FileEditors[filepath], DebugViewer):
self._FileEditors[filepath].SetDataProducer(self)
-
+
if self._FileEditors.has_key(filepath):
editor = self._FileEditors[filepath]
self.AppFrame.EditProjectElement(editor, editor.GetTagName())
-
+
return self._FileEditors.get(filepath)
else:
return ConfigTreeNode._OpenView(self, self.CTNName(), onlyopened)
@@ -1147,7 +1162,7 @@
if log_count:
if self.AppFrame is not None:
self.AppFrame.LogViewer.SetLogCounters(log_count)
-
+
def UpdateMethodsFromPLCStatus(self):
status = None
if self._connector is not None:
@@ -1184,16 +1199,16 @@
self.AppFrame.ConnectionStatusBar.SetStatusText(
_("Connected to URI: %s") % self.BeremizRoot.getURI_location().strip(), 1)
self.AppFrame.ConnectionStatusBar.SetStatusText(_(status), 2)
-
+
def PullPLCStatusProc(self, event):
self.UpdateMethodsFromPLCStatus()
-
+
def SnapshotAndResetDebugValuesBuffers(self):
- buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers,
+ buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers,
[list() for iec_path in self.TracedIECPath])
ticks, self.DebugTicks = self.DebugTicks, []
return ticks, buffers
-
+
def RegisterDebugVarToConnector(self):
self.DebugTimer=None
Idxs = []
@@ -1208,10 +1223,10 @@
# This variable is not needed anymore!
IECPathsToPop.append(IECPath)
elif IECPath != "__tick__":
- # Convert
+ # Convert
Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
if Idx is not None:
- if IEC_Type in DebugTypesSize:
+ if IEC_Type in DebugTypesSize:
Idxs.append((Idx, IEC_Type, fvalue, IECPath))
else:
self.logger.write_warning(_("Debug: Unsupported type to debug '%s'\n")%IEC_Type)
@@ -1229,14 +1244,14 @@
self._connector.SetTraceVariablesList([])
self.SnapshotAndResetDebugValuesBuffers()
self.IECdebug_lock.release()
-
+
def IsPLCStarted(self):
return self.previous_plcstate == "Started"
-
+
def ReArmDebugRegisterTimer(self):
if self.DebugTimer is not None:
self.DebugTimer.cancel()
-
+
# Prevent to call RegisterDebugVarToConnector when PLC is not started
# If an output location var is forced it's leads to segmentation fault in runtime
# Links between PLC located variables and real variables are not ready
@@ -1250,16 +1265,16 @@
def GetDebugIECVariableType(self, IECPath):
Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
return IEC_Type
-
+
def SubscribeDebugIECVariable(self, IECPath, callableobj, buffer_list=False, *args, **kwargs):
"""
Dispatching use a dictionnary linking IEC variable paths
- to a WeakKeyDictionary linking
+ to a WeakKeyDictionary linking
weakly referenced callables to optionnal args
"""
if IECPath != "__tick__" and not self._IECPathToIdx.has_key(IECPath):
return None
-
+
self.IECdebug_lock.acquire()
# If no entry exist, create a new one with a fresh WeakKeyDictionary
IECdebug_data = self.IECdebug_datas.get(IECPath, None)
@@ -1273,13 +1288,13 @@
self.IECdebug_datas[IECPath] = IECdebug_data
else:
IECdebug_data[4] |= buffer_list
-
+
IECdebug_data[0][callableobj]=(buffer_list, args, kwargs)
self.IECdebug_lock.release()
-
+
self.ReArmDebugRegisterTimer()
-
+
return IECdebug_data[1]
def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
@@ -1292,7 +1307,7 @@
else:
IECdebug_data[4] = reduce(
lambda x, y: x|y,
- [buffer_list for buffer_list,args,kwargs
+ [buffer_list for buffer_list,args,kwargs
in IECdebug_data[0].itervalues()],
False)
self.IECdebug_lock.release()
@@ -1309,33 +1324,33 @@
def ForceDebugIECVariable(self, IECPath, fvalue):
if not self.IECdebug_datas.has_key(IECPath):
return
-
+
self.IECdebug_lock.acquire()
-
+
# If no entry exist, create a new one with a fresh WeakKeyDictionary
IECdebug_data = self.IECdebug_datas.get(IECPath, None)
IECdebug_data[2] = "Forced"
IECdebug_data[3] = fvalue
-
+
self.IECdebug_lock.release()
-
+
self.ReArmDebugRegisterTimer()
-
+
def ReleaseDebugIECVariable(self, IECPath):
if not self.IECdebug_datas.has_key(IECPath):
return
-
+
self.IECdebug_lock.acquire()
-
+
# If no entry exist, create a new one with a fresh WeakKeyDictionary
IECdebug_data = self.IECdebug_datas.get(IECPath, None)
IECdebug_data[2] = "Registered"
IECdebug_data[3] = None
-
+
self.IECdebug_lock.release()
-
+
self.ReArmDebugRegisterTimer()
-
+
def CallWeakcallables(self, IECPath, function_name, *cargs):
data_tuple = self.IECdebug_datas.get(IECPath, None)
if data_tuple is not None:
@@ -1415,7 +1430,7 @@
self.CallWeakcallables(IECPath, "NewValues", debug_ticks, values)
if len(debug_ticks) > 0:
self.CallWeakcallables("__tick__", "NewDataAvailable", debug_ticks)
-
+
delay = time.time() - start_time
next_refresh = max(REFRESH_PERIOD - delay, 0.2 * delay)
if self.DispatchDebugValuesTimer is not None and self.DebugThread is not None:
@@ -1437,7 +1452,7 @@
if self.DispatchDebugValuesTimer is not None:
self.DispatchDebugValuesTimer.Stop()
- def _connect_debug(self):
+ def _connect_debug(self):
self.previous_plcstate = None
if self.AppFrame:
self.AppFrame.ResetGraphicViewers()
@@ -1448,7 +1463,7 @@
if self.DebugThread is None:
self.DebugThread = Thread(target=self.DebugThreadProc)
self.DebugThread.start()
-
+
def _Run(self):
"""
Start PLC
@@ -1460,7 +1475,7 @@
else:
self.logger.write_error(_("Couldn't start PLC !\n"))
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
-
+
def _Stop(self):
"""
Stop PLC
@@ -1470,7 +1485,7 @@
# debugthread should die on his own
#self.KillDebugThread()
-
+
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
def _SetConnector(self, connector, update_status=True):
@@ -1493,7 +1508,7 @@
if self._connector is not None:
self.logger.write_error(_("Already connected. Please disconnect\n"))
return
-
+
# Get connector uri
uri = self.\
BeremizRoot.\
@@ -1512,7 +1527,7 @@
self.logger.write_error(_("Local service discovery failed!\n"))
self.logger.write_error(traceback.format_exc())
uri = None
-
+
# Nothing choosed or cancel button
if uri is None or answer == wx.ID_CANCEL:
self.logger.write_error(_("Connection canceled!\n"))
@@ -1529,7 +1544,7 @@
self.AppFrame.RefreshFileMenu()
self.AppFrame.RefreshEditMenu()
self.AppFrame.RefreshPageTitles()
-
+
# Get connector from uri
try:
self._SetConnector(connectors.ConnectorFactory(uri, self))
@@ -1547,7 +1562,7 @@
self.ShowMethod("_Transfer", True)
self.CompareLocalAndRemotePLC()
-
+
# Init with actual PLC status and print it
self.UpdateMethodsFromPLCStatus()
if self.previous_plcstate is not None:
@@ -1556,7 +1571,7 @@
status = ""
#self.logger.write(_("PLC is %s\n")%status)
-
+
if self.previous_plcstate in ["Started","Stopped"]:
if self.DebugAvailable() and self.GetIECProgramsAndVariables():
self.logger.write(_("Debugger ready\n"))
@@ -1590,12 +1605,12 @@
def _Disconnect(self):
self._SetConnector(None)
-
+
def _Transfer(self):
- # Get the last build PLC's
+ # Get the last build PLC's
MD5 = self.GetLastBuildMD5()
-
- # Check if md5 file is empty : ask user to build PLC
+
+ # Check if md5 file is empty : ask user to build PLC
if MD5 is None :
self.logger.write_error(_("Failed : Must build before transfer.\n"))
return False
@@ -1609,12 +1624,12 @@
extrafiles = []
for extrafilespath in [self._getExtraFilesPath(),
self._getProjectFilesPath()]:
-
+
extrafiles.extend(
- [(name, open(os.path.join(extrafilespath, name),
+ [(name, open(os.path.join(extrafilespath, name),
'rb').read()) \
for name in os.listdir(extrafilespath)])
-
+
# Send PLC on target
builder = self.GetBuilder()
if builder is not None:
--- a/controls/VariablePanel.py Mon May 26 14:44:03 2014 +0100
+++ b/controls/VariablePanel.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
+#based on the plcopen standard.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -30,7 +30,7 @@
import wx.grid
import wx.lib.buttons
-from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS
+from plcopen.structures import LOCATIONDATATYPES, TestIdentifier, IEC_KEYWORDS, DefaultType
from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD, ERROR_HIGHLIGHT
from dialogs.ArrayTypeDialog import ArrayTypeDialog
from CustomGrid import CustomGrid
@@ -43,13 +43,7 @@
# Helpers
#-------------------------------------------------------------------------------
-def AppendMenu(parent, help, id, kind, text):
- if wx.VERSION >= (2, 6, 0):
- parent.Append(help=help, id=id, kind=kind, text=text)
- else:
- parent.Append(helpString=help, id=id, kind=kind, item=text)
-
-[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
+[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
] = range(10)
@@ -73,8 +67,8 @@
def GetFilterChoiceTransfer():
_ = lambda x : x
- return {_("All"): _("All"), _("Interface"): _("Interface"),
- _(" Input"): _("Input"), _(" Output"): _("Output"), _(" InOut"): _("InOut"),
+ return {_("All"): _("All"), _("Interface"): _("Interface"),
+ _(" Input"): _("Input"), _(" Output"): _("Output"), _(" InOut"): _("InOut"),
_(" External"): _("External"), _("Variables"): _("Variables"), _(" Local"): _("Local"),
_(" Temp"): _("Temp"), _("Global"): _("Global")}#, _("Access") : _("Access")}
VARIABLE_CHOICES_DICT = dict([(_(_class), _class) for _class in GetFilterChoiceTransfer().iterkeys()])
@@ -97,7 +91,7 @@
#-------------------------------------------------------------------------------
class VariableTable(CustomTable):
-
+
"""
A custom wx.grid.Grid Table using user supplied data
"""
@@ -105,7 +99,7 @@
# The base class must be initialized *first*
CustomTable.__init__(self, parent, data, colnames)
self.old_value = None
-
+
def GetValueByName(self, row, colname):
if row < self.GetNumberRows():
return getattr(self.data[row], colname)
@@ -113,7 +107,7 @@
def SetValueByName(self, row, colname, value):
if row < self.GetNumberRows():
setattr(self.data[row], colname, value)
-
+
def GetValue(self, row, col):
if row < self.GetNumberRows():
if col == 0:
@@ -130,7 +124,7 @@
if colname in ["Class", "Option"]:
return _(value)
return value
-
+
def SetValue(self, row, col, value):
if col < len(self.colnames):
colname = self.GetColLabelValue(col, False)
@@ -209,10 +203,10 @@
editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded]))
elif colname != "Documentation":
grid.SetReadOnly(row, col, True)
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
-
+
if colname == "Location" and LOCATION_MODEL.match(self.GetValueByName(row, colname)) is None:
highlight_colours = ERROR_HIGHLIGHT
else:
@@ -223,23 +217,23 @@
#-------------------------------------------------------------------------------
# Variable Panel Drop Target
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class VariableDropTarget(wx.TextDropTarget):
'''
This allows dragging a variable location from somewhere to the Location
column of a variable row.
-
+
The drag source should be a TextDataObject containing a Python tuple like:
('%ID0.0.0', 'location', 'REAL')
-
+
c_ext/CFileEditor.py has an example of this (you can drag a C extension
variable to the Location column of the variable panel).
'''
def __init__(self, parent):
wx.TextDropTarget.__init__(self)
self.ParentWindow = parent
-
+
def OnDropText(self, x, y, data):
self.ParentWindow.ParentWindow.Select()
x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y)
@@ -248,7 +242,7 @@
message = None
element_type = self.ParentWindow.ElementType
try:
- values = eval(data)
+ values = eval(data)
except:
message = _("Invalid value \"%s\" for variable grid element")%data
values = None
@@ -267,12 +261,12 @@
location = values[0]
variable_type = self.ParentWindow.Table.GetValueByName(row, "Type")
base_type = self.ParentWindow.Controler.GetBaseType(variable_type)
-
+
if values[2] is not None:
base_location_type = self.ParentWindow.Controler.GetBaseType(values[2])
if values[2] != variable_type and base_type != base_location_type:
message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type)
-
+
if message is None:
if not location.startswith("%"):
if location[0].isdigit() and base_type != "BOOL":
@@ -282,9 +276,9 @@
elif base_type not in LOCATIONDATATYPES[location[0]]:
message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type)
else:
- dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
- _("Select a variable class:"), _("Variable class"),
- ["Input", "Output", "Memory"],
+ dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
+ _("Select a variable class:"), _("Variable class"),
+ ["Input", "Output", "Memory"],
wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
selected = dialog.GetSelection()
@@ -299,7 +293,7 @@
location = "%Q" + location
else:
location = "%M" + location
-
+
if message is None:
self.ParentWindow.Table.SetValue(row, col, location)
self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
@@ -311,7 +305,7 @@
self.ParentWindow.Table.SetValue(row, col, values[0])
self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
self.ParentWindow.SaveValues()
- elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and
+ elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and
self.ParentWindow.Filter in ["All", "Interface", "External"] or
element_type != "function" and values[1] == "location"):
if values[1] == "location":
@@ -319,11 +313,11 @@
else:
var_name = values[0]
tagname = self.ParentWindow.GetTagName()
- if var_name.upper() in [name.upper()
+ if var_name.upper() in [name.upper()
for name in self.ParentWindow.Controler.\
GetProjectPouNames(self.ParentWindow.Debug)]:
message = _("\"%s\" pou already exists!")%var_name
- elif not var_name.upper() in [name.upper()
+ elif not var_name.upper() in [name.upper()
for name in self.ParentWindow.Controler.\
GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
var_infos = self.ParentWindow.DefaultValue.copy()
@@ -332,9 +326,9 @@
if values[1] == "location":
location = values[0]
if not location.startswith("%"):
- dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
- _("Select a variable class:"), _("Variable class"),
- ["Input", "Output", "Memory"],
+ dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow,
+ _("Select a variable class:"), _("Variable class"),
+ ["Input", "Output", "Memory"],
wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
selected = dialog.GetSelection()
@@ -354,7 +348,7 @@
self.ParentWindow.Debug)
if len(configs) == 0:
return
- if not var_name.upper() in [name.upper()
+ if not var_name.upper() in [name.upper()
for name in self.ParentWindow.Controler.\
GetConfigurationVariableNames(configs[0])]:
self.ParentWindow.Controler.AddConfigurationGlobalVar(
@@ -372,10 +366,10 @@
self.ParentWindow.Values.append(var_infos)
self.ParentWindow.SaveValues()
self.ParentWindow.RefreshValues()
-
+
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
def ShowMessage(self, message):
message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
@@ -383,85 +377,85 @@
#-------------------------------------------------------------------------------
# Variable Panel
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
class VariablePanel(wx.Panel):
-
+
def __init__(self, parent, window, controler, element_type, debug=False):
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-
+
self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0)
self.MainSizer.AddGrowableCol(0)
self.MainSizer.AddGrowableRow(1)
-
+
controls_sizer = wx.FlexGridSizer(cols=10, hgap=5, rows=1, vgap=5)
controls_sizer.AddGrowableCol(5)
controls_sizer.AddGrowableRow(0)
self.MainSizer.AddSizer(controls_sizer, border=5, flag=wx.GROW|wx.ALL)
-
+
self.ReturnTypeLabel = wx.StaticText(self, label=_('Return Type:'))
controls_sizer.AddWindow(self.ReturnTypeLabel, flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.ReturnType = wx.ComboBox(self,
size=wx.Size(145, -1), style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnReturnTypeChanged, self.ReturnType)
controls_sizer.AddWindow(self.ReturnType)
-
+
self.DescriptionLabel = wx.StaticText(self, label=_('Description:'))
controls_sizer.AddWindow(self.DescriptionLabel, flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.Description = wx.TextCtrl(self,
size=wx.Size(250, -1), style=wx.TE_PROCESS_ENTER)
self.Bind(wx.EVT_TEXT_ENTER, self.OnDescriptionChanged, self.Description)
self.Description.Bind(wx.EVT_KILL_FOCUS, self.OnDescriptionChanged)
- controls_sizer.AddWindow(self.Description)
-
+ controls_sizer.AddWindow(self.Description)
+
class_filter_label = wx.StaticText(self, label=_('Class Filter:'))
controls_sizer.AddWindow(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL)
-
- self.ClassFilter = wx.ComboBox(self,
+
+ self.ClassFilter = wx.ComboBox(self,
size=wx.Size(145, -1), style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnClassFilter, self.ClassFilter)
controls_sizer.AddWindow(self.ClassFilter)
-
+
for name, bitmap, help in [
("AddButton", "add_element", _("Add variable")),
("DeleteButton", "remove_element", _("Remove variable")),
("UpButton", "up", _("Move variable up")),
("DownButton", "down", _("Move variable down"))]:
- button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
controls_sizer.AddWindow(button)
-
+
self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL)
self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
- self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
self.OnVariablesGridCellChange)
- self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
+ self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
self.OnVariablesGridCellLeftClick)
- self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
+ self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
self.OnVariablesGridEditorShown)
self.MainSizer.AddWindow(self.VariablesGrid, flag=wx.GROW)
-
+
self.SetSizer(self.MainSizer)
-
+
self.ParentWindow = window
self.Controler = controler
self.ElementType = element_type
self.Debug = debug
-
+
self.RefreshHighlightsTimer = wx.Timer(self, -1)
- self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer,
+ self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer,
self.RefreshHighlightsTimer)
-
+
self.Filter = "All"
self.FilterChoices = []
self.FilterChoiceTransfer = GetFilterChoiceTransfer()
-
- self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", "INT", ([], []), 0)
-
+
+ self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", DefaultType, ([], []), 0)
+
if element_type in ["config", "resource"]:
self.DefaultTypes = {"All" : "Global"}
else:
@@ -481,7 +475,7 @@
# these condense the ColAlignements list
l = wx.ALIGN_LEFT
- c = wx.ALIGN_CENTER
+ c = wx.ALIGN_CENTER
# Num Name Class Type Loc Init Option Doc
self.ColSizes = [40, 80, 70, 80, 80, 80, 100, 80]
@@ -502,15 +496,15 @@
# these condense the ColAlignements list
l = wx.ALIGN_LEFT
- c = wx.ALIGN_CENTER
+ c = wx.ALIGN_CENTER
# Num Name Class Type Init Option Doc
self.ColSizes = [40, 80, 70, 80, 80, 100, 160]
self.ColAlignements = [c, l, l, l, l, l, l]
-
+
self.ElementType = element_type
self.BodyType = None
-
+
for choice in self.FilterChoices:
self.ClassFilter.Append(_(choice))
@@ -526,11 +520,11 @@
"Up": self.UpButton,
"Down": self.DownButton})
self.VariablesGrid.SetEditable(not self.Debug)
-
+
def _AddVariable(new_row):
if new_row > 0:
row_content = self.Values[new_row - 1].copy()
-
+
result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content.Name)
if result is not None:
name = row_content.Name[:result.start(1)]
@@ -546,8 +540,8 @@
row_content = None
start_idx = 0
name = "LocalVar"
-
- if row_content is not None and row_content.Edit:
+
+ if row_content is not None and row_content.Edit:
row_content = self.Values[new_row - 1].copy()
else:
row_content = self.DefaultValue.copy()
@@ -555,10 +549,10 @@
row_content.Class = self.DefaultTypes[self.Filter]
else:
row_content.Class = self.Filter
-
+
row_content.Name = self.Controler.GenerateNewName(
self.TagName, None, name + "%d", start_idx)
-
+
if self.Filter == "All" and len(self.Values) > 0:
self.Values.insert(new_row, row_content)
else:
@@ -568,7 +562,7 @@
self.RefreshValues()
return new_row
setattr(self.VariablesGrid, "_AddRow", _AddVariable)
-
+
def _DeleteVariable(row):
if self.Table.GetValueByName(row, "Edit"):
self.Values.remove(self.Table.GetRow(row))
@@ -577,7 +571,7 @@
self.ParentWindow.RefreshView(variablepanel = False)
self.RefreshValues()
setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
-
+
def _MoveVariable(row, move):
if self.Filter == "All":
new_row = max(0, min(row + move, len(self.Values) - 1))
@@ -588,7 +582,7 @@
return new_row
return row
setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
-
+
def _RefreshButtons():
if self:
table_length = len(self.Table.data)
@@ -603,7 +597,7 @@
self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All"))
self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All"))
setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons)
-
+
self.VariablesGrid.SetRowLabelSize(0)
for col in range(self.Table.GetNumberCols()):
attr = wx.grid.GridCellAttr()
@@ -611,29 +605,29 @@
self.VariablesGrid.SetColAttr(col, attr)
self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col])
self.VariablesGrid.AutoSizeColumn(col, False)
-
+
def __del__(self):
self.RefreshHighlightsTimer.Stop()
-
+
def SetTagName(self, tagname):
self.TagName = tagname
self.BodyType = self.Controler.GetEditedElementBodyType(self.TagName)
-
+
def GetTagName(self):
return self.TagName
-
+
def IsFunctionBlockType(self, name):
- if (isinstance(name, TupleType) or
+ if (isinstance(name, TupleType) or
self.ElementType != "function" and self.BodyType in ["ST", "IL"]):
return False
else:
return self.Controler.GetBlockType(name, debug=self.Debug) is not None
-
+
def RefreshView(self):
self.PouNames = self.Controler.GetProjectPouNames(self.Debug)
returnType = None
description = None
-
+
words = self.TagName.split("::")
if self.ElementType == "config":
self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug)
@@ -647,7 +641,7 @@
returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug)
description = self.Controler.GetPouDescription(words[1])
self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
-
+
if returnType is not None:
self.ReturnType.SetStringSelection(returnType)
self.ReturnType.Enable(not self.Debug)
@@ -657,7 +651,7 @@
self.ReturnType.Enable(False)
self.ReturnTypeLabel.Hide()
self.ReturnType.Hide()
-
+
if description is not None:
self.Description.SetValue(description)
self.Description.Enable(not self.Debug)
@@ -667,11 +661,11 @@
self.Description.Enable(False)
self.DescriptionLabel.Hide()
self.Description.Hide()
-
+
self.RefreshValues()
self.VariablesGrid.RefreshButtons()
self.MainSizer.Layout()
-
+
def OnReturnTypeChanged(self, event):
words = self.TagName.split("::")
self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection())
@@ -679,7 +673,7 @@
self.ParentWindow.RefreshView(variablepanel = False)
self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
event.Skip()
-
+
def OnDescriptionChanged(self, event):
words = self.TagName.split("::")
old_description = self.Controler.GetPouDescription(words[1])
@@ -688,7 +682,7 @@
self.Controler.SetPouDescription(words[1], new_description)
self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
event.Skip()
-
+
def OnClassFilter(self, event):
self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]]
self.RefreshTypeList()
@@ -711,7 +705,7 @@
colname = self.Table.GetColLabelValue(col, False)
value = self.Table.GetValue(row, col)
message = None
-
+
if colname == "Name" and value != "":
if not TestIdentifier(value):
message = _("\"%s\" is not a valid identifier!") % value
@@ -735,7 +729,7 @@
wx.CallAfter(self.ParentWindow.RefreshView, False)
elif colname == "Location":
wx.CallAfter(self.ParentWindow.RefreshView)
-
+
if message is not None:
dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
@@ -743,64 +737,77 @@
event.Veto()
else:
event.Skip()
-
- def OnVariablesGridEditorShown(self, event):
- row, col = event.GetRow(), event.GetCol()
-
- label_value = self.Table.GetColLabelValue(col, False)
- if label_value == "Type":
- type_menu = wx.Menu(title='') # the root menu
-
+
+ def BuildStdIECTypesMenu(self,type_menu):
# build a submenu containing standard IEC types
base_menu = wx.Menu(title='')
for base_type in self.Controler.GetBaseTypes():
new_id = wx.NewId()
- AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
+ base_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id)
type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu)
+ def BuildUserTypesMenu(self,type_menu):
# build a submenu containing user-defined types
datatype_menu = wx.Menu(title='')
datatypes = self.Controler.GetDataTypes(basetypes = False, confnodetypes = False)
for datatype in datatypes:
new_id = wx.NewId()
- AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+ datatype_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
-
- for category in self.Controler.GetConfNodeDataTypes():
-
- if len(category["list"]) > 0:
- # build a submenu containing confnode types
- confnode_datatype_menu = wx.Menu(title='')
- for datatype in category["list"]:
- new_id = wx.NewId()
- AppendMenu(confnode_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
- self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
-
- type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu)
-
- # build a submenu containing function block types
- bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
- pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
+
+ def BuildLibsTypesMenu(self, type_menu):
+ for category in self.Controler.GetConfNodeDataTypes():
+ if len(category["list"]) > 0:
+ # build a submenu containing confnode types
+ confnode_datatype_menu = wx.Menu(title='')
+ for datatype in category["list"]:
+ new_id = wx.NewId()
+ confnode_datatype_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+ self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
+
+ type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu)
+
+ def BuildProjectTypesMenu(self, type_menu, classtype):
+ # build a submenu containing function block types
+ bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
+ pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
+ if classtype in ["Input", "Output", "InOut", "External", "Global"] or \
+ poutype != "function" and bodytype in ["ST", "IL"]:
+ functionblock_menu = wx.Menu(title='')
+ fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName)
+ for functionblock_type in fbtypes:
+ new_id = wx.NewId()
+ functionblock_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
+ self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
+
+ type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu)
+
+ def BuildArrayTypesMenu(self, type_menu):
+ new_id = wx.NewId()
+ type_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
+ self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id)
+
+ def OnVariablesGridEditorShown(self, event):
+ row, col = event.GetRow(), event.GetCol()
+
+ label_value = self.Table.GetColLabelValue(col, False)
+ if label_value == "Type":
classtype = self.Table.GetValueByName(row, "Class")
-
- new_id = wx.NewId()
- AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
- self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id)
-
- if classtype in ["Input", "Output", "InOut", "External", "Global"] or \
- poutype != "function" and bodytype in ["ST", "IL"]:
- functionblock_menu = wx.Menu(title='')
- fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName)
- for functionblock_type in fbtypes:
- new_id = wx.NewId()
- AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
- self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
-
- type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu)
+ type_menu = wx.Menu(title='') # the root menu
+
+ self.BuildStdIECTypesMenu(type_menu)
+
+ self.BuildUserTypesMenu(type_menu)
+
+ self.BuildLibsTypesMenu(type_menu)
+
+ self.BuildProjectTypesMenu(type_menu,classtype)
+
+ self.BuildArrayTypesMenu(type_menu)
rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col))
corner_x = rect.x + rect.width
@@ -812,7 +819,7 @@
event.Veto()
else:
event.Skip()
-
+
def GetVariableTypeFunction(self, base_type):
def VariableTypeFunction(event):
row = self.VariablesGrid.GetGridCursorRow()
@@ -823,11 +830,11 @@
self.Controler.BufferProject()
self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
return VariableTypeFunction
-
+
def VariableArrayTypeFunction(self, event):
row = self.VariablesGrid.GetGridCursorRow()
- dialog = ArrayTypeDialog(self,
- self.Controler.GetDataTypes(self.TagName),
+ dialog = ArrayTypeDialog(self,
+ self.Controler.GetDataTypes(self.TagName),
self.Table.GetValueByName(row, "Type"))
if dialog.ShowModal() == wx.ID_OK:
self.Table.SetValueByName(row, "Type", dialog.GetValue())
@@ -837,7 +844,7 @@
self.Controler.BufferProject()
self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
dialog.Destroy()
-
+
def OnVariablesGridCellLeftClick(self, event):
row = event.GetRow()
if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")):
@@ -849,7 +856,7 @@
dragSource.SetData(data)
dragSource.DoDragDrop()
event.Skip()
-
+
def RefreshValues(self):
data = []
for num, variable in enumerate(self.Values):
@@ -858,7 +865,7 @@
data.append(variable)
self.Table.SetData(data)
self.Table.ResetView(self.VariablesGrid)
-
+
def SaveValues(self, buffer = True):
words = self.TagName.split("::")
if self.ElementType == "config":
@@ -871,7 +878,7 @@
self.Controler.SetPouInterfaceVars(words[1], self.Values)
if buffer:
self.Controler.BufferProject()
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
#-------------------------------------------------------------------------------
# Highlights showing functions
--- a/editors/CodeFileEditor.py Mon May 26 14:44:03 2014 +0100
+++ b/editors/CodeFileEditor.py Fri Jun 06 18:30:49 2014 +0100
@@ -6,7 +6,7 @@
import wx.lib.buttons
from plcopen.plcopen import TestTextElement
-from plcopen.structures import TestIdentifier, IEC_KEYWORDS
+from plcopen.structures import TestIdentifier, IEC_KEYWORDS, DefaultType
from controls import CustomGrid, CustomTable
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
from util.BitmapLibrary import GetBitmap
@@ -14,7 +14,7 @@
from controls.VariablePanel import VARIABLE_NAME_SUFFIX_MODEL
from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
-[STC_CODE_ERROR, STC_CODE_SEARCH_RESULT,
+[STC_CODE_ERROR, STC_CODE_SEARCH_RESULT,
STC_CODE_SECTION] = range(15, 18)
HIGHLIGHT_TYPES = {
@@ -25,14 +25,14 @@
EDGE_COLUMN = 80
class CodeEditor(CustomStyledTextCtrl):
-
+
KEYWORDS = []
COMMENT_HEADER = ""
def __init__(self, parent, window, controler):
- CustomStyledTextCtrl.__init__(self, parent, -1, wx.DefaultPosition,
+ CustomStyledTextCtrl.__init__(self, parent, -1, wx.DefaultPosition,
wx.Size(-1, 300), 0)
-
+
self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
self.SetMarginWidth(1, 25)
@@ -41,7 +41,7 @@
self.SetMargins(0,0)
self.SetViewWhiteSpace(False)
-
+
self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
self.SetEdgeColumn(EDGE_COLUMN)
@@ -59,7 +59,7 @@
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
-
+
self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
@@ -78,33 +78,33 @@
self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
-
+
# Highlighting styles
self.StyleSetSpec(STC_CODE_ERROR, 'fore:#FF0000,back:#FFFF00,size:%(size)d' % faces)
self.StyleSetSpec(STC_CODE_SEARCH_RESULT, 'fore:#FFFFFF,back:#FFA500,size:%(size)d' % faces)
-
+
# Section style
self.StyleSetSpec(STC_CODE_SECTION, 'fore:#808080,size:%(size)d')
self.StyleSetChangeable(STC_CODE_SECTION, False)
-
+
# Indentation size
self.SetTabWidth(4)
self.SetUseTabs(0)
-
+
self.SetCodeLexer()
self.SetKeyWords(0, " ".join(self.KEYWORDS))
-
+
self.Controler = controler
self.ParentWindow = window
-
+
self.DisableEvents = True
self.CurrentAction = None
-
+
self.ResetSearchResults()
-
+
self.RefreshHighlightsTimer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-
+
self.SectionsComments = {}
for section in self.Controler.SECTIONS_NAMES:
section_comment = " %s section " % (section)
@@ -112,11 +112,11 @@
section_comment = self.COMMENT_HEADER * (len_headers / 2) + \
section_comment + \
self.COMMENT_HEADER * (len_headers - len_headers / 2)
-
+
self.SectionsComments[section] = {
"comment": section_comment,
}
-
+
for i, section in enumerate(self.Controler.SECTIONS_NAMES):
section_infos = self.SectionsComments[section]
if i + 1 < len(self.Controler.SECTIONS_NAMES):
@@ -125,24 +125,24 @@
else:
section_end = "$"
section_infos["pattern"] = re.compile(
- section_infos["comment"] + "(.*)" +
+ section_infos["comment"] + "(.*)" +
section_end, re.DOTALL)
-
+
self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop)
self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification)
-
+
def SetCodeLexer(self):
pass
-
+
def ResetSearchResults(self):
self.Highlights = []
self.SearchParams = None
self.SearchResults = None
self.CurrentFindHighlight = None
-
+
def OnModification(self, event):
if not self.DisableEvents:
mod_type = event.GetModificationType()
@@ -165,7 +165,7 @@
wx.CallAfter(self.RefreshModel)
wx.CallAfter(self.RefreshSectionStyling)
event.Skip()
-
+
def OnDoDrop(self, event):
try:
values = eval(event.GetDragText())
@@ -192,7 +192,7 @@
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
self.ParentWindow.RefreshPageTitles()
-
+
def StartBuffering(self):
self.Controler.StartBuffering()
if self.ParentWindow is not None:
@@ -200,7 +200,7 @@
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
self.ParentWindow.RefreshPageTitles()
-
+
def ResetBuffer(self):
if self.CurrentAction != None:
self.Controler.EndBuffering()
@@ -240,18 +240,18 @@
self.GotoPos(old_cursor_pos)
self.EmptyUndoBuffer()
self.DisableEvents = False
-
+
self.RefreshSectionStyling()
-
+
self.ShowHighlights()
-
+
def RefreshSectionStyling(self):
self.Colourise(0, -1)
-
+
text = self.GetText()
for line in xrange(self.GetLineCount()):
self.SetLineState(line, 0)
-
+
for section in self.Controler.SECTIONS_NAMES:
section_comments = self.SectionsComments[section]
start_pos = text.find(section_comments["comment"])
@@ -259,7 +259,7 @@
self.StartStyling(start_pos, 0xff)
self.SetStyling(end_pos - start_pos, STC_CODE_SECTION)
self.SetLineState(self.LineFromPosition(start_pos), 1)
-
+
self.StartStyling(end_pos, 0x00)
self.SetStyling(len(self.GetText()) - end_pos, stc.STC_STYLE_DEFAULT)
@@ -278,7 +278,7 @@
parts[section] = ""
self.Controler.SetTextParts(parts)
self.ResetSearchResults()
-
+
def OnKeyPressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
@@ -286,14 +286,14 @@
current_pos = self.GetCurrentPos()
selected = self.GetSelection()
text_selected = selected[0] != selected[1]
-
+
# Test if caret is before Windows like new line
text = self.GetText()
if current_pos < len(text) and ord(text[current_pos]) == 13:
newline_size = 2
else:
newline_size = 1
-
+
# Disable to type any character in section header lines
if (self.GetLineState(self.LineFromPosition(current_pos)) and
not text_selected and
@@ -301,7 +301,7 @@
wx.WXK_RETURN,
wx.WXK_NUMPAD_ENTER]):
return
-
+
# Disable to delete line between code and header lines
elif (self.GetCurLine()[0].strip() != "" and not text_selected and
(key == wx.WXK_BACK and
@@ -309,7 +309,7 @@
key in [wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE] and
self.GetLineState(self.LineFromPosition(min(len(text), current_pos + newline_size))))):
return
-
+
elif key == 32 and event.ControlDown():
pos = self.GetCurrentPos()
@@ -319,7 +319,7 @@
# Code completion
else:
self.AutoCompSetIgnoreCase(False) # so this needs to match
-
+
keywords = self.KEYWORDS + [var["Name"]
for var in self.Controler.GetVariables()]
keywords.sort()
@@ -361,11 +361,11 @@
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
-
+
selected_text = self.GetSelectedText()
if selected_text:
self.ParentWindow.SetCopyBuffer(selected_text, True)
-
+
def OnMarginClick(self, event):
# fold and unfold as needed
if evt.GetMargin() == 2:
@@ -464,11 +464,11 @@
self.DisableEvents = False
self.RefreshModel()
self.RefreshBuffer()
-
+
def Copy(self):
self.CmdKeyExecute(wx.stc.STC_CMD_COPY)
self.ParentWindow.RefreshEditMenu()
-
+
def Paste(self):
self.ResetBuffer()
self.DisableEvents = True
@@ -480,21 +480,21 @@
def Find(self, direction, search_params):
if self.SearchParams != search_params:
self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
-
+
self.SearchParams = search_params
criteria = {
- "raw_pattern": search_params["find_pattern"],
+ "raw_pattern": search_params["find_pattern"],
"pattern": re.compile(search_params["find_pattern"]),
"case_sensitive": search_params["case_sensitive"],
"regular_expression": search_params["regular_expression"],
"filter": "all"}
-
+
self.SearchResults = [
(start, end, SEARCH_RESULT_HIGHLIGHT)
- for start, end, text in
+ for start, end, text in
TestTextElement(self.GetText(), criteria)]
self.CurrentFindHighlight = None
-
+
if len(self.SearchResults) > 0:
if self.CurrentFindHighlight is not None:
old_idx = self.SearchResults.index(self.CurrentFindHighlight)
@@ -522,9 +522,9 @@
break
if self.CurrentFindHighlight is not None:
self.AddHighlight(*self.CurrentFindHighlight)
-
+
self.ScrollToLine(self.CurrentFindHighlight[0][0])
-
+
else:
if self.CurrentFindHighlight is not None:
self.RemoveHighlight(*self.CurrentFindHighlight)
@@ -557,11 +557,11 @@
def RemoveHighlight(self, start, end, highlight_type):
highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
- if (highlight_type is not None and
+ if (highlight_type is not None and
(start, end, highlight_type) in self.Highlights):
self.Highlights.remove((start, end, highlight_type))
self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-
+
def ShowHighlights(self):
for start, end, highlight_type in self.Highlights:
if start[0] == 0:
@@ -583,14 +583,14 @@
#-------------------------------------------------------------------------------
class VariablesTable(CustomTable):
-
+
def GetValue(self, row, col):
if row < self.GetNumberRows():
if col == 0:
return row + 1
else:
return str(self.data[row].get(self.GetColLabelValue(col, False), ""))
-
+
def _updateColAttrs(self, grid):
"""
wxGrid -> update the column attributes to add the
@@ -598,7 +598,7 @@
Otherwise default to the default renderer.
"""
-
+
typelist = None
accesslist = None
for row in range(self.GetNumberRows()):
@@ -606,7 +606,7 @@
editor = None
renderer = None
colname = self.GetColLabelValue(col, False)
-
+
if colname in ["Name", "Initial"]:
editor = wx.grid.GridCellTextEditor()
elif colname == "Class":
@@ -616,49 +616,49 @@
pass
else:
grid.SetReadOnly(row, col, True)
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
-
+
grid.SetCellBackgroundColour(row, col, wx.WHITE)
self.ResizeRow(grid, row)
class VariablesEditor(wx.Panel):
-
+
def __init__(self, parent, window, controler):
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-
+
main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=4)
main_sizer.AddGrowableCol(1)
main_sizer.AddGrowableRow(0)
-
+
controls_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.AddSizer(controls_sizer, border=5, flag=wx.ALL)
-
+
for name, bitmap, help in [
("AddVariableButton", "add_element", _("Add variable")),
("DeleteVariableButton", "remove_element", _("Remove variable")),
("UpVariableButton", "up", _("Move variable up")),
("DownVariableButton", "down", _("Move variable down"))]:
- button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
controls_sizer.AddWindow(button, border=5, flag=wx.BOTTOM)
-
+
self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown)
main_sizer.AddWindow(self.VariablesGrid, flag=wx.GROW)
-
+
self.SetSizer(main_sizer)
-
+
self.ParentWindow = window
self.Controler = controler
-
- self.VariablesDefaultValue = {"Name" : "", "Type" : "INT", "Initial": ""}
+
+ self.VariablesDefaultValue = {"Name" : "", "Type" : DefaultType, "Initial": ""}
self.Table = VariablesTable(self, [], ["#", "Name", "Type", "Initial"])
self.ColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
self.ColSizes = [40, 200, 150, 150]
@@ -667,7 +667,7 @@
"Delete": self.DeleteVariableButton,
"Up": self.UpVariableButton,
"Down": self.DownVariableButton})
-
+
def _AddVariable(new_row):
if new_row > 0:
row_content = self.Table.data[new_row - 1].copy()
@@ -691,13 +691,13 @@
self.RefreshView()
return new_row
setattr(self.VariablesGrid, "_AddRow", _AddVariable)
-
+
def _DeleteVariable(row):
self.Table.RemoveRow(row)
self.RefreshModel()
self.RefreshView()
setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable)
-
+
def _MoveVariable(row, move):
new_row = self.Table.MoveRow(row, move)
if new_row != row:
@@ -705,7 +705,7 @@
self.RefreshView()
return new_row
setattr(self.VariablesGrid, "_MoveRow", _MoveVariable)
-
+
self.VariablesGrid.SetRowLabelSize(0)
for col in range(self.Table.GetNumberCols()):
attr = wx.grid.GridCellAttr()
@@ -717,7 +717,7 @@
def RefreshModel(self):
self.Controler.SetVariables(self.Table.GetData())
self.RefreshBuffer()
-
+
# Buffer the last model state
def RefreshBuffer(self):
self.Controler.BufferCodeFile()
@@ -730,23 +730,23 @@
self.Table.SetData(self.Controler.GetVariables())
self.Table.ResetView(self.VariablesGrid)
self.VariablesGrid.RefreshButtons()
-
+
def DoGetBestSize(self):
return self.ParentWindow.GetPanelBestSize()
-
+
def OnVariablesGridCellChange(self, event):
row, col = event.GetRow(), event.GetCol()
colname = self.Table.GetColLabelValue(col, False)
value = self.Table.GetValue(row, col)
message = None
-
+
if colname == "Name" and value != "":
if not TestIdentifier(value):
message = _("\"%s\" is not a valid identifier!") % value
elif value.upper() in IEC_KEYWORDS:
message = _("\"%s\" is a keyword. It can't be used!") % value
- elif value.upper() in [var["Name"].upper()
- for var_row, var in enumerate(self.Table.data)
+ elif value.upper() in [var["Name"].upper()
+ for var_row, var in enumerate(self.Table.data)
if var_row != row]:
message = _("A variable with \"%s\" as name already exists!") % value
else:
@@ -755,7 +755,7 @@
else:
self.RefreshModel()
wx.CallAfter(self.RefreshView)
-
+
if message is not None:
dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
@@ -765,7 +765,7 @@
event.Skip()
def OnVariablesGridEditorShown(self, event):
- row, col = event.GetRow(), event.GetCol()
+ row, col = event.GetRow(), event.GetCol()
if self.Table.GetColLabelValue(col, False) == "Type":
type_menu = wx.Menu(title='')
base_menu = wx.Menu(title='')
@@ -781,7 +781,7 @@
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu)
rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col))
-
+
self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize())
type_menu.Destroy()
event.Veto()
@@ -803,64 +803,64 @@
row = event.GetRow()
data_type = self.Table.GetValueByName(row, "Type")
var_name = self.Table.GetValueByName(row, "Name")
- data = wx.TextDataObject(str((var_name, "Global", data_type,
+ data = wx.TextDataObject(str((var_name, "Global", data_type,
self.Controler.GetCurrentLocation())))
dragSource = wx.DropSource(self.VariablesGrid)
dragSource.SetData(data)
dragSource.DoDragDrop()
return
event.Skip()
-
+
#-------------------------------------------------------------------------------
# CodeFileEditor Main Frame Class
#-------------------------------------------------------------------------------
class CodeFileEditor(ConfTreeNodeEditor):
-
+
CONFNODEEDITOR_TABS = []
CODE_EDITOR = None
-
+
def _create_CodePanel(self, prnt):
self.CodeEditorPanel = wx.SplitterWindow(prnt)
self.CodeEditorPanel.SetMinimumPaneSize(1)
-
- self.VariablesPanel = VariablesEditor(self.CodeEditorPanel,
+
+ self.VariablesPanel = VariablesEditor(self.CodeEditorPanel,
self.ParentWindow, self.Controler)
-
+
if self.CODE_EDITOR is not None:
- self.CodeEditor = self.CODE_EDITOR(self.CodeEditorPanel,
+ self.CodeEditor = self.CODE_EDITOR(self.CodeEditorPanel,
self.ParentWindow, self.Controler)
-
- self.CodeEditorPanel.SplitHorizontally(self.VariablesPanel,
+
+ self.CodeEditorPanel.SplitHorizontally(self.VariablesPanel,
self.CodeEditor, 150)
else:
self.CodeEditorPanel.Initialize(self.VariablesPanel)
-
+
return self.CodeEditorPanel
-
+
def __init__(self, parent, controler, window):
ConfTreeNodeEditor.__init__(self, parent, controler, window)
-
+
wx.CallAfter(self.CodeEditorPanel.SetSashPosition, 150)
-
+
def GetBufferState(self):
return self.Controler.GetBufferState()
-
+
def Undo(self):
self.Controler.LoadPrevious()
self.RefreshView()
-
+
def Redo(self):
self.Controler.LoadNext()
self.RefreshView()
-
+
def RefreshView(self):
ConfTreeNodeEditor.RefreshView(self)
-
+
self.VariablesPanel.RefreshView()
self.CodeEditor.RefreshView()
-
+
def Find(self, direction, search_params):
self.CodeEditor.Find(direction, search_params)
-
\ No newline at end of file
+
--- a/editors/DataTypeEditor.py Mon May 26 14:44:03 2014 +0100
+++ b/editors/DataTypeEditor.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
+#based on the plcopen standard.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -29,7 +29,7 @@
import wx.grid
import wx.lib.buttons
-from plcopen.structures import IEC_KEYWORDS, TestIdentifier
+from plcopen.structures import IEC_KEYWORDS, TestIdentifier, DefaultType
from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD
from controls import CustomEditableListBox, CustomGrid, CustomTable
from dialogs import ArrayTypeDialog
@@ -59,7 +59,7 @@
#-------------------------------------------------------------------------------
class ElementsTable(CustomTable):
-
+
"""
A custom wx.grid.Grid Table using user supplied data
"""
@@ -67,7 +67,7 @@
# The base class must be initialized *first*
CustomTable.__init__(self, parent, data, colnames)
self.old_value = None
-
+
def GetValue(self, row, col):
if row < self.GetNumberRows():
if col == 0:
@@ -78,17 +78,17 @@
if value[0] == "array":
return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "..".join(x), value[2])), value[1])
return str(value)
-
+
def SetValue(self, row, col, value):
if col < len(self.colnames):
colname = self.GetColLabelValue(col, False)
if colname == "Name":
self.old_value = self.data[row][colname]
self.data[row][colname] = value
-
+
def GetOldValue(self):
return self.old_value
-
+
def _updateColAttrs(self, grid):
"""
wx.grid.Grid -> update the column attributes to add the
@@ -96,7 +96,7 @@
Otherwise default to the default renderer.
"""
-
+
for row in range(self.GetNumberRows()):
row_highlights = self.Highlights.get(row, {})
for col in range(self.GetNumberCols()):
@@ -115,15 +115,15 @@
editor = wx.grid.GridCellTextEditor()
else:
grid.SetReadOnly(row, col, True)
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
-
+
highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1]
grid.SetCellBackgroundColour(row, col, highlight_colours[0])
grid.SetCellTextColour(row, col, highlight_colours[1])
self.ResizeRow(grid, row)
-
+
def AddHighlight(self, infos, highlight_type):
row_highlights = self.Highlights.setdefault(infos[0], {})
if infos[1] == "initial":
@@ -137,216 +137,216 @@
#-------------------------------------------------------------------------------
class DataTypeEditor(EditorPanel):
-
+
def _init_Editor(self, parent):
self.Editor = wx.Panel(parent, style=wx.SUNKEN_BORDER)
-
+
self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
self.MainSizer.AddGrowableCol(0)
self.MainSizer.AddGrowableRow(1)
-
+
top_sizer = wx.BoxSizer(wx.HORIZONTAL)
- self.MainSizer.AddSizer(top_sizer, border=5,
+ self.MainSizer.AddSizer(top_sizer, border=5,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
derivation_type_label = wx.StaticText(self.Editor, label=_('Derivation Type:'))
- top_sizer.AddWindow(derivation_type_label, border=5,
+ top_sizer.AddWindow(derivation_type_label, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT)
-
+
self.DerivationType = wx.ComboBox(self.Editor,
size=wx.Size(200, -1), style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnDerivationTypeChanged, self.DerivationType)
top_sizer.AddWindow(self.DerivationType, border=5, flag=wx.GROW|wx.RIGHT)
-
+
typeinfos_staticbox = wx.StaticBox(self.Editor, label=_('Type infos:'))
typeinfos_sizer = wx.StaticBoxSizer(typeinfos_staticbox, wx.HORIZONTAL)
- self.MainSizer.AddSizer(typeinfos_sizer, border=5,
+ self.MainSizer.AddSizer(typeinfos_sizer, border=5,
flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
# Panel for Directly derived data types
self.DirectlyPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
typeinfos_sizer.AddWindow(self.DirectlyPanel, 1)
-
+
directly_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
-
- directly_basetype_label = wx.StaticText(self.DirectlyPanel,
+
+ directly_basetype_label = wx.StaticText(self.DirectlyPanel,
label=_('Base Type:'))
- directly_panel_sizer.AddWindow(directly_basetype_label, 1, border=5,
+ directly_panel_sizer.AddWindow(directly_basetype_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.DirectlyBaseType = wx.ComboBox(self.DirectlyPanel, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.DirectlyBaseType)
- directly_panel_sizer.AddWindow(self.DirectlyBaseType, 1, border=5,
+ directly_panel_sizer.AddWindow(self.DirectlyBaseType, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
directly_initialvalue_label = wx.StaticText(self.DirectlyPanel,
label=_('Initial Value:'))
- directly_panel_sizer.AddWindow(directly_initialvalue_label, 1, border=5,
+ directly_panel_sizer.AddWindow(directly_initialvalue_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
- self.DirectlyInitialValue = wx.TextCtrl(self.DirectlyPanel,
+
+ self.DirectlyInitialValue = wx.TextCtrl(self.DirectlyPanel,
style=wx.TE_PROCESS_ENTER|wx.TE_RICH)
self.Bind(wx.EVT_TEXT_ENTER, self.OnReturnKeyPressed, self.DirectlyInitialValue)
- directly_panel_sizer.AddWindow(self.DirectlyInitialValue, 1, border=5,
+ directly_panel_sizer.AddWindow(self.DirectlyInitialValue, 1, border=5,
flag=wx.ALL)
-
+
self.DirectlyPanel.SetSizer(directly_panel_sizer)
-
+
# Panel for Subrange data types
self.SubrangePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
typeinfos_sizer.AddWindow(self.SubrangePanel, 1)
-
+
subrange_panel_sizer = wx.GridSizer(cols=4, hgap=5, rows=3, vgap=0)
-
+
subrange_basetype_label = wx.StaticText(self.SubrangePanel,
label=_('Base Type:'))
- subrange_panel_sizer.AddWindow(subrange_basetype_label, 1, border=5,
+ subrange_panel_sizer.AddWindow(subrange_basetype_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.SubrangeBaseType = wx.ComboBox(self.SubrangePanel, style=wx.CB_READONLY)
- self.Bind(wx.EVT_COMBOBOX, self.OnSubrangeBaseTypeChanged,
+ self.Bind(wx.EVT_COMBOBOX, self.OnSubrangeBaseTypeChanged,
self.SubrangeBaseType)
- subrange_panel_sizer.AddWindow(self.SubrangeBaseType, 1, border=5,
+ subrange_panel_sizer.AddWindow(self.SubrangeBaseType, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
subrange_initialvalue_label = wx.StaticText(self.SubrangePanel,
label=_('Initial Value:'))
- subrange_panel_sizer.AddWindow(subrange_initialvalue_label, 1, border=5,
+ subrange_panel_sizer.AddWindow(subrange_initialvalue_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
- self.SubrangeInitialValue = wx.SpinCtrl(self.SubrangePanel,
+
+ self.SubrangeInitialValue = wx.SpinCtrl(self.SubrangePanel,
style=wx.TAB_TRAVERSAL)
self.Bind(wx.EVT_SPINCTRL, self.OnInfosChanged, self.SubrangeInitialValue)
- subrange_panel_sizer.AddWindow(self.SubrangeInitialValue, 1, border=5,
+ subrange_panel_sizer.AddWindow(self.SubrangeInitialValue, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
subrange_minimum_label = wx.StaticText(self.SubrangePanel, label=_('Minimum:'))
- subrange_panel_sizer.AddWindow(subrange_minimum_label, 1, border=5,
+ subrange_panel_sizer.AddWindow(subrange_minimum_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.SubrangeMinimum = wx.SpinCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMinimumChanged, self.SubrangeMinimum)
- subrange_panel_sizer.AddWindow(self.SubrangeMinimum, 1, border=5,
+ subrange_panel_sizer.AddWindow(self.SubrangeMinimum, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
for i in xrange(2):
subrange_panel_sizer.AddWindow(wx.Size(0, 0), 1)
-
+
subrange_maximum_label = wx.StaticText(self.SubrangePanel,
label=_('Maximum:'))
- subrange_panel_sizer.AddWindow(subrange_maximum_label, 1, border=5,
+ subrange_panel_sizer.AddWindow(subrange_maximum_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.SubrangeMaximum = wx.SpinCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMaximumChanged, self.SubrangeMaximum)
-
- subrange_panel_sizer.AddWindow(self.SubrangeMaximum, 1, border=5,
+
+ subrange_panel_sizer.AddWindow(self.SubrangeMaximum, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
self.SubrangePanel.SetSizer(subrange_panel_sizer)
-
+
# Panel for Enumerated data types
-
+
self.EnumeratedPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
typeinfos_sizer.AddWindow(self.EnumeratedPanel, 1)
-
+
enumerated_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
-
- self.EnumeratedValues = CustomEditableListBox(self.EnumeratedPanel,
- label=_("Values:"), style=wx.gizmos.EL_ALLOW_NEW|
- wx.gizmos.EL_ALLOW_EDIT|
+
+ self.EnumeratedValues = CustomEditableListBox(self.EnumeratedPanel,
+ label=_("Values:"), style=wx.gizmos.EL_ALLOW_NEW|
+ wx.gizmos.EL_ALLOW_EDIT|
wx.gizmos.EL_ALLOW_DELETE)
setattr(self.EnumeratedValues, "_OnLabelEndEdit", self.OnEnumeratedValueEndEdit)
for func in ["_OnAddButton", "_OnDelButton", "_OnUpButton", "_OnDownButton"]:
setattr(self.EnumeratedValues, func, self.OnEnumeratedValuesChanged)
- enumerated_panel_sizer.AddWindow(self.EnumeratedValues, 1, border=5,
+ enumerated_panel_sizer.AddWindow(self.EnumeratedValues, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
enumerated_panel_rightsizer = wx.BoxSizer(wx.HORIZONTAL)
enumerated_panel_sizer.AddSizer(enumerated_panel_rightsizer, 1)
-
+
enumerated_initialvalue_label = wx.StaticText(self.EnumeratedPanel,
label=_('Initial Value:'))
- enumerated_panel_rightsizer.AddWindow(enumerated_initialvalue_label, 1,
+ enumerated_panel_rightsizer.AddWindow(enumerated_initialvalue_label, 1,
border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
- self.EnumeratedInitialValue = wx.ComboBox(self.EnumeratedPanel,
+
+ self.EnumeratedInitialValue = wx.ComboBox(self.EnumeratedPanel,
style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.EnumeratedInitialValue)
- enumerated_panel_rightsizer.AddWindow(self.EnumeratedInitialValue, 1,
+ enumerated_panel_rightsizer.AddWindow(self.EnumeratedInitialValue, 1,
border=5, flag=wx.ALL)
-
+
self.EnumeratedPanel.SetSizer(enumerated_panel_sizer)
-
+
# Panel for Array data types
self.ArrayPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
typeinfos_sizer.AddWindow(self.ArrayPanel, 1)
-
+
array_panel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0)
array_panel_sizer.AddGrowableCol(0)
array_panel_sizer.AddGrowableCol(1)
array_panel_sizer.AddGrowableRow(1)
-
+
array_panel_leftSizer = wx.BoxSizer(wx.HORIZONTAL)
array_panel_sizer.AddSizer(array_panel_leftSizer, flag=wx.GROW)
-
+
array_basetype_label = wx.StaticText(self.ArrayPanel, label=_('Base Type:'))
- array_panel_leftSizer.AddWindow(array_basetype_label, 1, border=5,
+ array_panel_leftSizer.AddWindow(array_basetype_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.ArrayBaseType = wx.ComboBox(self.ArrayPanel, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, self.ArrayBaseType)
- array_panel_leftSizer.AddWindow(self.ArrayBaseType, 1, border=5,
+ array_panel_leftSizer.AddWindow(self.ArrayBaseType, 1, border=5,
flag=wx.GROW|wx.ALL)
-
+
array_panel_rightsizer = wx.BoxSizer(wx.HORIZONTAL)
array_panel_sizer.AddSizer(array_panel_rightsizer, flag=wx.GROW)
-
+
array_initialvalue_label = wx.StaticText(self.ArrayPanel,
label=_('Initial Value:'))
- array_panel_rightsizer.AddWindow(array_initialvalue_label, 1, border=5,
+ array_panel_rightsizer.AddWindow(array_initialvalue_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL)
-
+
self.ArrayInitialValue = wx.TextCtrl(self.ArrayPanel,
style=wx.TE_PROCESS_ENTER|wx.TE_RICH)
self.Bind(wx.EVT_TEXT_ENTER, self.OnReturnKeyPressed, self.ArrayInitialValue)
- array_panel_rightsizer.AddWindow(self.ArrayInitialValue, 1, border=5,
- flag=wx.ALL)
-
- self.ArrayDimensions = CustomEditableListBox(self.ArrayPanel,
+ array_panel_rightsizer.AddWindow(self.ArrayInitialValue, 1, border=5,
+ flag=wx.ALL)
+
+ self.ArrayDimensions = CustomEditableListBox(self.ArrayPanel,
label=_("Dimensions:"), style=wx.gizmos.EL_ALLOW_NEW|
wx.gizmos.EL_ALLOW_EDIT|
wx.gizmos.EL_ALLOW_DELETE)
- for func in ["_OnLabelEndEdit", "_OnAddButton", "_OnDelButton",
+ for func in ["_OnLabelEndEdit", "_OnAddButton", "_OnDelButton",
"_OnUpButton", "_OnDownButton"]:
setattr(self.ArrayDimensions, func, self.OnDimensionsChanged)
- array_panel_sizer.AddWindow(self.ArrayDimensions, 0, border=5,
+ array_panel_sizer.AddWindow(self.ArrayDimensions, 0, border=5,
flag=wx.GROW|wx.ALL)
-
+
self.ArrayPanel.SetSizer(array_panel_sizer)
-
+
# Panel for Structure data types
-
+
self.StructurePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
typeinfos_sizer.AddWindow(self.StructurePanel, 1)
-
+
structure_panel_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
structure_panel_sizer.AddGrowableCol(0)
structure_panel_sizer.AddGrowableRow(1)
-
+
structure_button_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
structure_button_sizer.AddGrowableCol(0)
structure_button_sizer.AddGrowableRow(0)
- structure_panel_sizer.AddSizer(structure_button_sizer, 0, border=5,
+ structure_panel_sizer.AddSizer(structure_button_sizer, 0, border=5,
flag=wx.ALL|wx.GROW)
-
+
structure_elements_label = wx.StaticText(self.StructurePanel,
label=_('Elements :'))
structure_button_sizer.AddWindow(structure_elements_label, flag=wx.ALIGN_BOTTOM)
-
+
for name, bitmap, help in [
("StructureAddButton", "add_element", _("Add element")),
("StructureDeleteButton", "remove_element", _("Remove element")),
@@ -357,46 +357,46 @@
button.SetToolTipString(help)
setattr(self, name, button)
structure_button_sizer.AddWindow(button)
-
- self.StructureElementsGrid = CustomGrid(self.StructurePanel,
+
+ self.StructureElementsGrid = CustomGrid(self.StructurePanel,
size=wx.Size(0, 150), style=wx.VSCROLL)
- self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
self.OnStructureElementsGridCellChange)
- self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
+ self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
self.OnStructureElementsGridEditorShown)
structure_panel_sizer.AddWindow(self.StructureElementsGrid, flag=wx.GROW)
-
+
self.StructurePanel.SetSizer(structure_panel_sizer)
-
+
self.Editor.SetSizer(self.MainSizer)
-
+
def __init__(self, parent, tagname, window, controler):
EditorPanel.__init__(self, parent, tagname, window, controler)
-
- self.StructureElementDefaultValue = {"Name" : "", "Type" : "INT", "Initial Value" : ""}
+
+ self.StructureElementDefaultValue = {"Name" : "", "Type" : DefaultType, "Initial Value" : ""}
self.StructureElementsTable = ElementsTable(self, [], GetElementsTableColnames())
self.StructureColSizes = [40, 150, 100, 250]
self.StructureColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
-
+
self.StructureElementsGrid.SetTable(self.StructureElementsTable)
self.StructureElementsGrid.SetButtons({"Add": self.StructureAddButton,
"Delete": self.StructureDeleteButton,
"Up": self.StructureUpButton,
"Down": self.StructureDownButton})
-
+
def _AddStructureElement(new_row):
self.StructureElementsTable.InsertRow(new_row, self.StructureElementDefaultValue.copy())
self.RefreshTypeInfos()
self.StructureElementsTable.ResetView(self.StructureElementsGrid)
return new_row
setattr(self.StructureElementsGrid, "_AddRow", _AddStructureElement)
-
+
def _DeleteStructureElement(row):
self.StructureElementsTable.RemoveRow(row)
self.RefreshTypeInfos()
self.StructureElementsTable.ResetView(self.StructureElementsGrid)
setattr(self.StructureElementsGrid, "_DeleteRow", _DeleteStructureElement)
-
+
def _MoveStructureElement(row, move):
new_row = self.StructureElementsTable.MoveRow(row, move)
if new_row != row:
@@ -404,7 +404,7 @@
self.StructureElementsTable.ResetView(self.StructureElementsGrid)
return new_row
setattr(self.StructureElementsGrid, "_MoveRow", _MoveStructureElement)
-
+
self.StructureElementsGrid.SetRowLabelSize(0)
for col in range(self.StructureElementsTable.GetNumberCols()):
attr = wx.grid.GridCellAttr()
@@ -413,7 +413,7 @@
self.StructureElementsGrid.SetColMinimalWidth(col, self.StructureColSizes[col])
self.StructureElementsGrid.AutoSizeColumn(col, False)
self.StructureElementsGrid.RefreshButtons()
-
+
for datatype in GetDatatypeTypes():
self.DerivationType.Append(_(datatype))
self.SubrangePanel.Hide()
@@ -423,7 +423,7 @@
self.CurrentPanel = "Directly"
self.Highlights = []
self.Initializing = False
-
+
self.HighlightControls = {
("Directly", "base"): self.DirectlyBaseType,
("Directly", "initial"): self.DirectlyInitialValue,
@@ -437,27 +437,27 @@
("Array", "base"): self.ArrayBaseType,
("Array", "range"): self.ArrayDimensions,
}
-
+
self.RefreshHighlightsTimer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-
+
def __del__(self):
self.RefreshHighlightsTimer.Stop()
-
+
def GetBufferState(self):
return self.Controler.GetBufferState()
-
+
def Undo(self):
self.Controler.LoadPrevious()
self.ParentWindow.CloseTabsWithoutModel()
-
+
def Redo(self):
self.Controler.LoadNext()
self.ParentWindow.CloseTabsWithoutModel()
-
+
def HasNoModel(self):
return self.Controler.GetEditedElement(self.TagName) is None
-
+
def RefreshView(self):
self.Initializing = True
self.DirectlyBaseType.Clear()
@@ -504,7 +504,7 @@
self.StructureElementsTable.ResetView(self.StructureElementsGrid)
self.StructureElementsGrid.RefreshButtons()
self.Initializing = False
-
+
def OnDerivationTypeChanged(self, event):
wx.CallAfter(self.RefreshDisplayedInfos)
wx.CallAfter(self.RefreshTypeInfos)
@@ -512,7 +512,7 @@
def OnReturnKeyPressed(self, event):
self.RefreshTypeInfos()
-
+
def OnInfosChanged(self, event):
self.RefreshTypeInfos()
event.Skip()
@@ -563,12 +563,12 @@
event.Skip()
else:
event.Skip()
-
+
def OnEnumeratedValuesChanged(self, event):
wx.CallAfter(self.RefreshEnumeratedValues)
wx.CallAfter(self.RefreshTypeInfos)
event.Skip()
-
+
def OnStructureElementsGridCellChange(self, event):
row, col = event.GetRow(), event.GetCol()
colname = self.StructureElementsTable.GetColLabelValue(col, False)
@@ -606,34 +606,34 @@
self.RefreshTypeInfos()
wx.CallAfter(self.StructureElementsTable.ResetView, self.StructureElementsGrid)
event.Skip()
-
+
def OnStructureElementsGridSelectCell(self, event):
wx.CallAfter(self.RefreshStructureButtons)
event.Skip()
-
+
def OnStructureElementsGridEditorShown(self, event):
- row, col = event.GetRow(), event.GetCol()
+ row, col = event.GetRow(), event.GetCol()
if self.StructureElementsTable.GetColLabelValue(col, False) == "Type":
type_menu = wx.Menu(title='')
-
+
base_menu = wx.Menu(title='')
for base_type in self.Controler.GetBaseTypes():
new_id = wx.NewId()
AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(base_type), id=new_id)
type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu)
-
+
datatype_menu = wx.Menu(title='')
for datatype in self.Controler.GetDataTypes(self.TagName, False):
new_id = wx.NewId()
AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(datatype), id=new_id)
type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
-
+
new_id = wx.NewId()
AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
self.Bind(wx.EVT_MENU, self.ElementArrayTypeFunction, id=new_id)
-
+
## functionblock_menu = wx.Menu(title='')
## bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
## pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
@@ -661,8 +661,8 @@
def ElementArrayTypeFunction(self, event):
row = self.StructureElementsGrid.GetGridCursorRow()
- dialog = ArrayTypeDialog(self,
- self.Controler.GetDataTypes(self.TagName),
+ dialog = ArrayTypeDialog(self,
+ self.Controler.GetDataTypes(self.TagName),
self.StructureElementsTable.GetValueByName(row, "Type"))
if dialog.ShowModal() == wx.ID_OK:
self.StructureElementsTable.SetValueByName(row, "Type", dialog.GetValue())
--- a/editors/TextViewer.py Mon May 26 14:44:03 2014 +0100
+++ b/editors/TextViewer.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
+#based on the plcopen standard.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -45,8 +45,8 @@
LETTERS.append(chr(ord('a') + i))
LETTERS.append(chr(ord('A') + i))
-[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING,
- STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP,
+[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING,
+ STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP,
STC_PLC_ERROR, STC_PLC_SEARCH_RESULT] = range(10)
[SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT, PRAGMA, DPRAGMA] = range(8)
@@ -70,35 +70,35 @@
return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False)
class TextViewer(EditorPanel):
-
+
ID = ID_TEXTVIEWER
-
+
if wx.VERSION < (2, 6, 0):
def Bind(self, event, function, id = None):
if id is not None:
event(self, id, function)
else:
event(self, function)
-
+
def _init_Editor(self, prnt):
- self.Editor = CustomStyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL,
+ self.Editor = CustomStyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL,
parent=prnt, name="TextViewer", size=wx.Size(0, 0), style=0)
self.Editor.ParentWindow = self
-
+
self.Editor.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
self.Editor.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
-
+
self.Editor.SetViewWhiteSpace(False)
-
+
self.Editor.SetLexer(wx.stc.STC_LEX_CONTAINER)
-
+
# Global default styles for all languages
self.Editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
self.Editor.StyleClearAll() # Reset all to be like the default
-
+
self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces)
self.Editor.SetSelBackground(1, "#E0E0E0")
-
+
# Highlighting styles
self.Editor.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
self.Editor.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
@@ -110,18 +110,18 @@
self.Editor.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
self.Editor.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
self.Editor.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces)
-
+
# Indicators styles
self.Editor.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
if self.ParentWindow is not None and self.Controler is not None:
self.Editor.IndicatorSetForeground(0, wx.RED)
else:
self.Editor.IndicatorSetForeground(0, wx.WHITE)
-
+
# Line numbers in the margin
self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
self.Editor.SetMarginWidth(1, 50)
-
+
# Folding
self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_BOXMINUS, "white", "#808080")
self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_BOXPLUS, "white", "#808080")
@@ -130,11 +130,11 @@
self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER, "white", "#808080")
-
+
# Indentation size
self.Editor.SetTabWidth(2)
self.Editor.SetUseTabs(0)
-
+
self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
wx.stc.STC_MOD_BEFOREDELETE|
wx.stc.STC_PERFORMED_USER)
@@ -147,13 +147,13 @@
self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWERTEXTCTRL)
self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWERTEXTCTRL)
-
+
def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
if tagname != "" and controler is not None:
self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
-
+
EditorPanel.__init__(self, parent, tagname, window, controler, debug)
-
+
self.Keywords = []
self.Variables = {}
self.Functions = {}
@@ -163,62 +163,62 @@
self.DisableEvents = True
self.TextSyntax = None
self.CurrentAction = None
-
+
self.InstancePath = instancepath
self.ContextStack = []
self.CallStack = []
-
+
self.ResetSearchResults()
-
+
self.RefreshHighlightsTimer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-
+
def __del__(self):
self.RefreshHighlightsTimer.Stop()
-
+
def GetTitle(self):
if self.Debug or self.TagName == "":
if len(self.InstancePath) > 15:
return "..." + self.InstancePath[-12:]
return self.InstancePath
return EditorPanel.GetTitle(self)
-
+
def GetInstancePath(self):
return self.InstancePath
-
+
def IsViewing(self, tagname):
if self.Debug or self.TagName == "":
return self.InstancePath == tagname
else:
return self.TagName == tagname
-
+
def GetText(self):
return self.Editor.GetText()
-
+
def SetText(self, text):
self.Editor.SetText(text)
-
+
def SelectAll(self):
self.Editor.SelectAll()
-
+
def Colourise(self, start, end):
self.Editor.Colourise(start, end)
-
+
def StartStyling(self, pos, mask):
self.Editor.StartStyling(pos, mask)
-
+
def SetStyling(self, length, style):
self.Editor.SetStyling(length, style)
-
+
def GetCurrentPos(self):
return self.Editor.GetCurrentPos()
-
+
def ResetSearchResults(self):
self.Highlights = []
self.SearchParams = None
self.SearchResults = None
self.CurrentFindHighlight = None
-
+
def OnModification(self, event):
if not self.DisableEvents:
mod_type = event.GetModificationType()
@@ -239,7 +239,7 @@
self.CurrentAction = ("Delete", event.GetPosition())
wx.CallAfter(self.RefreshModel)
event.Skip()
-
+
def OnDoDrop(self, event):
try:
values = eval(event.GetDragText())
@@ -256,7 +256,7 @@
blockinputs = values[3]
else:
blockinputs = None
- if values[1] != "function":
+ if values[1] != "function":
if blockname == "":
dialog = wx.TextEntryDialog(self.ParentWindow, "Block name", "Please enter a block name", "", wx.OK|wx.CANCEL|wx.CENTRE)
if dialog.ShowModal() == wx.ID_OK:
@@ -291,9 +291,9 @@
else:
location = values[0]
if not location.startswith("%"):
- dialog = wx.SingleChoiceDialog(self.ParentWindow,
- _("Select a variable class:"), _("Variable class"),
- ["Input", "Output", "Memory"],
+ dialog = wx.SingleChoiceDialog(self.ParentWindow,
+ _("Select a variable class:"), _("Variable class"),
+ ["Input", "Output", "Memory"],
wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
selected = dialog.GetSelection()
@@ -314,13 +314,30 @@
else:
var_type = LOCATIONDATATYPES.get(location[2], ["BOOL"])[0]
self.Controler.AddEditedElementPouVar(self.TagName,
- var_type, var_name,
+ var_type, var_name,
location=location, description=values[4])
self.RefreshVariablePanel()
self.RefreshVariableTree()
event.SetDragText(var_name)
else:
event.SetDragText("")
+ elif values[1] == "NamedConstant":
+ pou_name, pou_type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
+ if pou_type == "program":
+ initval = values[0]
+ var_name = values[3]
+ if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
+ message = _("\"%s\" pou already exists!")%var_name
+ else:
+ var_type = values[2]
+ if not var_name.upper() in [name.upper() for name in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]:
+ self.Controler.AddEditedElementPouVar(self.TagName,
+ var_type,
+ var_name,
+ description=values[4], initval=initval)
+ self.RefreshVariablePanel()
+ self.RefreshVariableTree()
+ event.SetDragText(var_name)
elif values[1] == "Global":
var_name = values[0]
if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
@@ -345,7 +362,7 @@
dialog.Destroy()
event.SetDragText("")
event.Skip()
-
+
def SetTextSyntax(self, syntax):
self.TextSyntax = syntax
if syntax in ["ST", "ALL"]:
@@ -362,16 +379,16 @@
else:
self.BlockStartKeywords = []
self.BlockEndKeywords = []
-
+
def SetKeywords(self, keywords):
self.Keywords = [keyword.upper() for keyword in keywords]
self.Colourise(0, -1)
-
+
def RefreshJumpList(self):
if self.TextSyntax != "IL":
self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
self.Colourise(0, -1)
-
+
# Buffer the last model state
def RefreshBuffer(self):
self.Controler.BufferProject()
@@ -379,42 +396,42 @@
self.ParentWindow.RefreshTitle()
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
-
+
def StartBuffering(self):
self.Controler.StartBuffering()
if self.ParentWindow:
self.ParentWindow.RefreshTitle()
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
-
+
def ResetBuffer(self):
if self.CurrentAction != None:
self.Controler.EndBuffering()
self.CurrentAction = None
-
+
def GetBufferState(self):
if not self.Debug and self.TextSyntax != "ALL":
return self.Controler.GetBufferState()
return False, False
-
+
def Undo(self):
if not self.Debug and self.TextSyntax != "ALL":
self.Controler.LoadPrevious()
self.ParentWindow.CloseTabsWithoutModel()
-
+
def Redo(self):
if not self.Debug and self.TextSyntax != "ALL":
self.Controler.LoadNext()
self.ParentWindow.CloseTabsWithoutModel()
-
+
def HasNoModel(self):
if not self.Debug and self.TextSyntax != "ALL":
return self.Controler.GetEditedElement(self.TagName) is None
return False
-
+
def RefreshView(self, variablepanel=True):
EditorPanel.RefreshView(self, variablepanel)
-
+
if self.Controler is not None:
self.ResetBuffer()
self.DisableEvents = True
@@ -434,12 +451,12 @@
self.RefreshJumpList()
self.Editor.EmptyUndoBuffer()
self.DisableEvents = False
-
+
self.RefreshVariableTree()
-
+
self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)]
self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()]
-
+
self.Functions = {}
for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
for blocktype in category["list"]:
@@ -455,13 +472,13 @@
else:
self.Functions[blockname] = {"interface": interface,
"extensible": blocktype["extensible"]}
-
+
self.Colourise(0, -1)
-
+
def RefreshVariableTree(self):
words = self.TagName.split("::")
self.Variables = self.GenerateVariableTree(
- [(variable.Name, variable.Type, variable.Tree)
+ [(variable.Name, variable.Type, variable.Tree)
for variable in self.Controler.GetEditedElementInterfaceVars(
self.TagName, True, self.Debug)])
if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
@@ -470,22 +487,22 @@
self.Variables[words[-1].upper()] = self.GenerateVariableTree(var_tree)
else:
self.Variables[words[-1].upper()] = {}
-
+
def GenerateVariableTree(self, list):
tree = {}
for var_name, var_type, (var_tree, var_dimension) in list:
tree[var_name.upper()] = self.GenerateVariableTree(var_tree)
return tree
-
+
def IsValidVariable(self, name, context):
return context is not None and context.get(name, None) is not None
def IsCallParameter(self, name, call):
if call is not None:
- return (call["interface"].get(name.upper(), None) is not None or
+ return (call["interface"].get(name.upper(), None) is not None or
call["extensible"] and EXTENSIBLE_PARAMETER.match(name.upper()) is not None)
return False
-
+
def RefreshLineFolding(self, line_number):
if self.TextSyntax in ["ST", "ALL"]:
level = wx.stc.STC_FOLDLEVELBASE + self.Editor.GetLineIndentation(line_number)
@@ -497,7 +514,7 @@
else:
level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
if level != wx.stc.STC_FOLDLEVELBASE:
- level |= wx.stc.STC_FOLDLEVELWHITEFLAG
+ level |= wx.stc.STC_FOLDLEVELWHITEFLAG
elif LineStartswith(line, self.BlockStartKeywords):
level |= wx.stc.STC_FOLDLEVELHEADERFLAG
elif LineStartswith(line, self.BlockEndKeywords):
@@ -506,7 +523,7 @@
else:
level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
self.Editor.SetFoldLevel(line_number, level)
-
+
def OnStyleNeeded(self, event):
self.TextChanged = True
line_number = self.Editor.LineFromPosition(self.Editor.GetEndStyled())
@@ -517,10 +534,10 @@
self.RefreshLineFolding(line_number)
end_pos = event.GetPosition()
self.StartStyling(start_pos, 0xff)
-
+
current_context = self.Variables
current_call = None
-
+
current_pos = last_styled_pos
state = SPACE
line = ""
@@ -642,7 +659,7 @@
elif self.IsCallParameter(word, current_call):
self.SetStyling(current_pos - last_styled_pos, STC_PLC_PARAMETER)
elif word in self.Functions:
- self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
+ self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
elif self.TextSyntax == "IL" and word in self.Jumps:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP)
elif word in self.EnumeratedValues:
@@ -670,7 +687,7 @@
if char == '[' and current_context is not None:
self.ContextStack.append(current_context.get(word, None))
current_context = self.Variables
-
+
word = ""
last_styled_pos = current_pos
state = SPACE
@@ -717,20 +734,20 @@
self.SetStyling(current_pos - start_pos, 31)
self.ShowHighlights(start_pos, end_pos)
event.Skip()
-
+
def OnMarginClick(self, event):
if event.GetMargin() == 2:
line = self.Editor.LineFromPosition(event.GetPosition())
if self.Editor.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG:
self.Editor.ToggleFold(line)
event.Skip()
-
+
def OnUpdateUI(self, event):
selected = self.Editor.GetSelectedText()
if self.ParentWindow and selected != "":
self.ParentWindow.SetCopyBuffer(selected, True)
event.Skip()
-
+
def Cut(self):
self.ResetBuffer()
self.DisableEvents = True
@@ -738,12 +755,12 @@
self.DisableEvents = False
self.RefreshModel()
self.RefreshBuffer()
-
+
def Copy(self):
self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
if self.ParentWindow:
self.ParentWindow.RefreshEditMenu()
-
+
def Paste(self):
self.ResetBuffer()
self.DisableEvents = True
@@ -751,28 +768,28 @@
self.DisableEvents = False
self.RefreshModel()
self.RefreshBuffer()
-
+
def Search(self, criteria):
return self.Controler.SearchInPou(self.TagName, criteria, self.Debug)
-
+
def Find(self, direction, search_params):
if self.SearchParams != search_params:
self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
-
+
self.SearchParams = search_params
criteria = {
- "raw_pattern": search_params["find_pattern"],
+ "raw_pattern": search_params["find_pattern"],
"pattern": re.compile(search_params["find_pattern"]),
"case_sensitive": search_params["case_sensitive"],
"regular_expression": search_params["regular_expression"],
"filter": "all"}
-
+
self.SearchResults = [
(infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)
- for infos, start, end, text in
+ for infos, start, end, text in
self.Search(criteria)]
self.CurrentFindHighlight = None
-
+
if len(self.SearchResults) > 0:
if self.CurrentFindHighlight is not None:
old_idx = self.SearchResults.index(self.CurrentFindHighlight)
@@ -787,24 +804,24 @@
else:
self.CurrentFindHighlight = self.SearchResults[0]
self.AddHighlight(*self.CurrentFindHighlight)
-
+
else:
if self.CurrentFindHighlight is not None:
self.RemoveHighlight(*self.CurrentFindHighlight)
self.CurrentFindHighlight = None
-
+
def RefreshModel(self):
self.RefreshJumpList()
self.Controler.SetEditedElementText(self.TagName, self.GetText())
self.ResetSearchResults()
-
+
def OnKeyDown(self, event):
key = event.GetKeyCode()
if self.Controler is not None:
-
+
if self.Editor.CallTipActive():
self.Editor.CallTipCancel()
-
+
key_handled = False
line = self.Editor.GetCurrentLine()
@@ -814,15 +831,15 @@
start_pos = self.Editor.GetLineEndPosition(line - 1) + 1
end_pos = self.GetCurrentPos()
lineText = self.Editor.GetTextRange(start_pos, end_pos).replace("\t", " ")
-
+
# Code completion
if key == wx.WXK_SPACE and event.ControlDown():
-
+
words = lineText.split(" ")
words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1]
-
+
kw = []
-
+
if self.TextSyntax == "IL":
if len(words) == 1:
kw = self.Keywords
@@ -875,7 +892,7 @@
def ClearHighlights(self, highlight_type=None):
EditorPanel.ClearHighlights(self, highlight_type)
-
+
if highlight_type is None:
self.Highlights = []
else:
@@ -886,7 +903,7 @@
def AddHighlight(self, infos, start, end, highlight_type):
EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
-
+
highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
if infos[0] == "body" and highlight_type is not None:
self.Highlights.append((infos[1], start, end, highlight_type))
@@ -895,13 +912,13 @@
def RemoveHighlight(self, infos, start, end, highlight_type):
EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
-
+
highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
- if (infos[0] == "body" and highlight_type is not None and
+ if (infos[0] == "body" and highlight_type is not None and
(infos[1], start, end, highlight_type) in self.Highlights):
self.Highlights.remove((infos[1], start, end, highlight_type))
self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-
+
def ShowHighlights(self, start_pos, end_pos):
for indent, start, end, highlight_type in self.Highlights:
if start[0] == 0:
@@ -917,4 +934,4 @@
self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
self.StartStyling(highlight_start_pos, 0x00)
self.SetStyling(len(self.Editor.GetText()) - highlight_end_pos, wx.stc.STC_STYLE_DEFAULT)
-
+
--- a/plcopen/definitions.py Mon May 26 14:44:03 2014 +0100
+++ b/plcopen/definitions.py Fri Jun 06 18:30:49 2014 +0100
@@ -12,7 +12,7 @@
"B" : ["SINT", "USINT", "BYTE", "STRING"],
"W" : ["INT", "UINT", "WORD", "WSTRING"],
"D" : ["DINT", "UDINT", "REAL", "DWORD"],
- "L" : ["LINT", "ULINT", "LREAL", "LWORD"]}
+ "L" : ["LINT", "ULINT", "LREAL", "LWORD"]}
#-------------------------------------------------------------------------------
# Function Block Types definitions
@@ -105,6 +105,8 @@
#("WSTRING", "ANY_STRING") # TODO
]
+DefaultType = "DINT"
+
DataTypeRange_list = [
("SINT", (-2**7, 2**7 - 1)),
("INT", (-2**15, 2**15 - 1)),
--- a/py_ext/plc_python.c Mon May 26 14:44:03 2014 +0100
+++ b/py_ext/plc_python.c Fri Jun 06 18:30:49 2014 +0100
@@ -119,7 +119,7 @@
/*printf("__PythonEvalFB pop %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/
}else if(poll){
/* when in polling, no answer == ack down */
- __SET_VAR(data__->, ACK., 0);
+ __SET_VAR(data__->, ACK,, 0);
}
/* got the order to act ?*/
if(__GET_VAR(data__->TRIGGED) == 1 &&
--- a/util/ProcessLogger.py Mon May 26 14:44:03 2014 +0100
+++ b/util/ProcessLogger.py Fri Jun 06 18:30:49 2014 +0100
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#This file is part of Beremiz, a Integrated Development Environment for
-#programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
#
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
#
@@ -31,7 +31,7 @@
if os.name == 'posix':
from signal import SIGTERM, SIGKILL
-
+
class outputThread(Thread):
"""
Thread is used to print the output of a command to the stdout
@@ -66,10 +66,10 @@
err = self.retval
self.finished = True
self.endcallback(self.Proc.pid, err)
-
+
class ProcessLogger:
- def __init__(self, logger, Command, finish_callback = None,
- no_stdout = False, no_stderr = False, no_gui = True,
+ def __init__(self, logger, Command, finish_callback = None,
+ no_stdout = False, no_stderr = False, no_gui = True,
timeout = None, outlimit = None, errlimit = None,
endlog = None, keyword = None, kill_it = False, cwd = None):
self.logger = logger
@@ -86,10 +86,10 @@
else:
self.Command = Command
self.Command_str = subprocess.list2cmdline(self.Command)
-
+
self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()),
self.Command)
-
+
self.finish_callback = finish_callback
self.no_stdout = no_stdout
self.no_stderr = no_stderr
@@ -105,27 +105,27 @@
self.kill_it = kill_it
self.finishsem = Semaphore(0)
self.endlock = Lock()
-
+
popenargs= {
"cwd":os.getcwd() if cwd is None else cwd,
- "stdin":subprocess.PIPE,
- "stdout":subprocess.PIPE,
+ "stdin":subprocess.PIPE,
+ "stdout":subprocess.PIPE,
"stderr":subprocess.PIPE}
-
+
if no_gui == True and wx.Platform == '__WXMSW__':
self.startupinfo = subprocess.STARTUPINFO()
self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
popenargs["startupinfo"] = self.startupinfo
elif wx.Platform == '__WXGTK__':
popenargs["shell"] = False
-
+
self.Proc = subprocess.Popen( self.Command, **popenargs )
self.outt = outputThread(
self.Proc,
self.Proc.stdout,
self.output,
- self.finish)
+ self.finish)
self.outt.start()
self.errt = outputThread(
@@ -147,7 +147,7 @@
self.logger.write(v)
if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit):
self.endlog()
-
+
def errors(self,v):
self.errdata.append(v)
self.errlen += 1
@@ -195,7 +195,7 @@
if not self.outt.finished and self.kill_it:
self.kill()
-
+
def spin(self):
self.finishsem.acquire()
return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]