# HG changeset patch
# User Edouard Tisserant
# Date 1634713027 -7200
# Node ID 4a08728a2ea41ab8dc33b877c41b83ad3b2bce7c
# Parent a13da70a8ae4688d9c60c19e4a270b188ce2b089# Parent c6de1a6cb6554afbec63e9910cd1f7f02e8bf7f7
Merge deafult in wxPython4
diff -r c6de1a6cb655 -r 4a08728a2ea4 .hgignore
--- a/.hgignore Tue Oct 19 15:15:03 2021 +0200
+++ b/.hgignore Wed Oct 20 08:57:07 2021 +0200
@@ -9,6 +9,7 @@
syntax: regexp
^tests/.*/build$
+^exemples/.*/build$
^.idea/.*
syntax: regexp
^.*\.pyc$
diff -r c6de1a6cb655 -r 4a08728a2ea4 BeremizIDE.py
--- a/BeremizIDE.py Tue Oct 19 15:15:03 2021 +0200
+++ b/BeremizIDE.py Wed Oct 20 08:57:07 2021 +0200
@@ -92,7 +92,7 @@
return os.path.join(beremiz_dir, *args)
def AppendMenu(parent, help, id, kind, text):
- return parent.Append(help=help, id=id, kind=kind, text=text)
+ return parent.Append(wx.MenuItem(helpString=help, id=id, kind=kind, text=text))
MAX_RECENT_PROJECTS = 9
@@ -179,7 +179,7 @@
if style is None:
style = self.black_white
if style != self.black_white:
- self.output.StartStyling(self.output.GetLength(), 0xff)
+ self.output.StartStyling(self.output.GetLength())
# Temporary deactivate read only mode on StyledTextCtrl for
# adding text. It seems that text modifications, even
@@ -241,6 +241,7 @@
def _init_utils(self):
self.ConfNodeMenu = wx.Menu(title='')
self.RecentProjectsMenu = wx.Menu(title='')
+ self.TutorialsProjectsMenu = wx.Menu(title='')
IDEFrame._init_utils(self)
@@ -249,7 +250,29 @@
kind=wx.ITEM_NORMAL, text=_(u'New') + '\tCTRL+N')
AppendMenu(parent, help='', id=wx.ID_OPEN,
kind=wx.ITEM_NORMAL, text=_(u'Open') + '\tCTRL+O')
- parent.AppendMenu(ID_FILEMENURECENTPROJECTS, _("&Recent Projects"), self.RecentProjectsMenu)
+ parent.Append(ID_FILEMENURECENTPROJECTS, _("&Recent Projects"), self.RecentProjectsMenu)
+ parent.AppendSeparator()
+ parent.Append(wx.ID_ANY, _("&Tutorials and Examples"), self.TutorialsProjectsMenu)
+
+ exemples_dir = Bpath("exemples")
+ project_list = sorted(os.listdir(exemples_dir))
+
+ for idx, dirname in enumerate(project_list):
+ text = u'&%d: %s' % (idx + 1, dirname)
+
+ item = self.TutorialsProjectsMenu.Append(wx.ID_ANY, text, '')
+
+ projectpath = os.path.join(exemples_dir, dirname)
+
+ def OpenExemple(event):
+ if self.CTR is not None and not self.CheckSaveBeforeClosing():
+ return
+
+ self.OpenProject(projectpath)
+ if not self.CTR.CheckProjectPathPerm():
+ self.ResetView()
+
+ self.Bind(wx.EVT_MENU, OpenExemple, item)
parent.AppendSeparator()
AppendMenu(parent, help='', id=wx.ID_SAVE,
kind=wx.ITEM_NORMAL, text=_(u'Save') + '\tCTRL+S')
@@ -291,10 +314,10 @@
for name, text, helpstr, children in items:
if len(children) > 0:
new_menu = wx.Menu(title='')
- menu.AppendMenu(wx.ID_ANY, text, new_menu)
+ menu.AppendSubMenu(new_menu, text)
self._RecursiveAddMenuItems(new_menu, children)
else:
- item = menu.Append(wx.ID_ANY, text, helpstr)
+ item = menu.Append(wx.MenuItem(text=text, helpString=helpstr, kind=wx.ITEM_NORMAL, id=wx.ID_ANY))
self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name), item)
def _init_coll_AddMenu_Items(self, parent):
@@ -311,16 +334,16 @@
item = parent.Append(wx.ID_ANY, _(u'Community support'), '')
self.Bind(wx.EVT_MENU, handler, item)
- parent.Append(help='', id=wx.ID_ABOUT,
- kind=wx.ITEM_NORMAL, text=_(u'About'))
+ parent.Append(wx.MenuItem(helpString='', 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)
- parent.SetStatusText(number=0, text='')
- parent.SetStatusText(number=1, text='')
- parent.SetStatusText(number=2, text='')
+ parent.SetStatusText(i=0, text='')
+ parent.SetStatusText(i=1, text='')
+ parent.SetStatusText(i=2, text='')
parent.SetStatusWidths([-1, 300, 200])
@@ -397,7 +420,7 @@
self.AUIManager.Update()
- self.ConnectionStatusBar = esb.EnhancedStatusBar(self, style=wx.ST_SIZEGRIP)
+ self.ConnectionStatusBar = esb.EnhancedStatusBar(self, style=wx.STB_SIZEGRIP)
self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar)
self.ProgressStatusBar = wx.Gauge(self.ConnectionStatusBar, -1, range=100)
self.ConnectionStatusBar.AddWidget(self.ProgressStatusBar, esb.ESB_EXACT_FIT, esb.ESB_EXACT_FIT, 2)
@@ -474,8 +497,6 @@
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()
@@ -625,6 +646,7 @@
if self.CTR is None or self.CheckSaveBeforeClosing(_("Close Application")):
if self.CTR is not None:
self.CTR.KillDebugThread()
+ self.CTR._Disconnect()
self.KillLocalRuntime()
self.SaveLastState()
@@ -639,6 +661,7 @@
def OnCloseFrame(self, event):
if self.TryCloseFrame():
self.LogConsole.Disconnect(-1, -1, wx.wxEVT_KILL_FOCUS)
+ super(Beremiz, self).OnCloseFrame(event)
event.Skip()
else:
# prevent event to continue, i.e. cancel closing
@@ -699,7 +722,7 @@
while self.RecentProjectsMenu.GetMenuItemCount() > 0:
item = self.RecentProjectsMenu.FindItemByPosition(0)
- self.RecentProjectsMenu.RemoveItem(item)
+ self.RecentProjectsMenu.Remove(item)
self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0)
for idx, projectpath in enumerate(recent_projects):
@@ -746,9 +769,9 @@
for confnode_method in self.CTR.StatusMethods:
if "method" in confnode_method and confnode_method.get("shown", True):
- tool = StatusToolBar.AddSimpleTool(
- wx.ID_ANY, GetBitmap(confnode_method.get("bitmap", "Unknown")),
- confnode_method["tooltip"])
+ tool = StatusToolBar.AddTool(
+ wx.ID_ANY, confnode_method["tooltip"],
+ GetBitmap(confnode_method.get("bitmap", "Unknown")))
self.Bind(wx.EVT_MENU, self.GetMenuCallBackFunction(confnode_method["method"]), tool)
StatusToolBar.Realize()
@@ -798,7 +821,7 @@
else:
self.EditMenu.Delete(item.GetId())
self.LastPanelSelected = None
- self.MenuBar.UpdateMenus()
+ self.MenuBar.Refresh()
def RefreshAll(self):
self.RefreshStatusToolBar()
diff -r c6de1a6cb655 -r 4a08728a2ea4 Beremiz_service.py
--- a/Beremiz_service.py Tue Oct 19 15:15:03 2021 +0200
+++ b/Beremiz_service.py Wed Oct 20 08:57:07 2021 +0200
@@ -224,6 +224,7 @@
if havewx:
import re
+ import wx.adv
if wx.VERSION >= (3, 0, 0):
app = wx.App(redirect=False)
@@ -265,7 +266,7 @@
def SetTests(self, tests):
self.Tests = tests
- class BeremizTaskBarIcon(wx.TaskBarIcon):
+ class BeremizTaskBarIcon(wx.adv.TaskBarIcon):
TBMENU_START = wx.NewId()
TBMENU_STOP = wx.NewId()
TBMENU_CHANGE_NAME = wx.NewId()
@@ -277,7 +278,7 @@
TBMENU_QUIT = wx.NewId()
def __init__(self, pyroserver):
- wx.TaskBarIcon.__init__(self)
+ wx.adv.TaskBarIcon.__init__(self)
self.pyroserver = pyroserver
# Set the image
self.UpdateIcon(None)
@@ -325,7 +326,7 @@
elif "wxGTK" in wx.PlatformInfo:
img = img.Scale(22, 22)
# wxMac can be any size upto 128x128, so leave the source img alone....
- icon = wx.IconFromBitmap(img.ConvertToBitmap())
+ icon = wx.Icon(img.ConvertToBitmap())
return icon
def OnTaskBarStartPLC(self, evt):
diff -r c6de1a6cb655 -r 4a08728a2ea4 ConfigTreeNode.py
--- a/ConfigTreeNode.py Tue Oct 19 15:15:03 2021 +0200
+++ b/ConfigTreeNode.py Wed Oct 20 08:57:07 2021 +0200
@@ -194,7 +194,7 @@
os.mkdir(self.CTNPath())
def CTNRequestSave(self, from_project_path=None):
- if self.GetCTRoot().CheckProjectPathPerm(False):
+ if self.GetCTRoot().CheckProjectPathPerm():
# If confnode do not have corresponding directory
ctnpath = self.CTNPath()
if not os.path.isdir(ctnpath):
diff -r c6de1a6cb655 -r 4a08728a2ea4 IDEFrame.py
--- a/IDEFrame.py Tue Oct 19 15:15:03 2021 +0200
+++ b/IDEFrame.py Wed Oct 20 08:57:07 2021 +0200
@@ -115,7 +115,7 @@
def AppendMenu(parent, help, kind, text, id=wx.ID_ANY):
- return parent.Append(help=help, kind=kind, text=text, id=id)
+ return parent.Append(wx.MenuItem(helpString=help, kind=kind, text=text, id=id))
[
@@ -391,7 +391,7 @@
parent.AppendSeparator()
add_menu = wx.Menu(title='')
self._init_coll_AddMenu_Items(add_menu)
- parent.AppendMenu(wx.ID_ADD, _(u"&Add Element"), add_menu)
+ parent.Append(wx.ID_ADD, _(u"&Add Element"), add_menu)
AppendMenu(parent, help='', id=wx.ID_SELECTALL,
kind=wx.ITEM_NORMAL, text=_(u'Select All') + '\tCTRL+A')
AppendMenu(parent, help='', id=wx.ID_DELETE,
@@ -442,7 +442,7 @@
kind=wx.ITEM_NORMAL, text=_(u'Clear Errors') + '\tCTRL+K')
parent.AppendSeparator()
zoommenu = wx.Menu(title='')
- parent.AppendMenu(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu)
+ parent.Append(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu)
for idx, value in enumerate(ZOOM_FACTORS):
new_item = AppendMenu(zoommenu, help='',
kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%")
@@ -569,8 +569,8 @@
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)
+ name='ProjectPanel', parent=self.LeftNoteBook,
+ size=wx.Size(0, 0))
self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE,
name='ProjectTree',
@@ -631,9 +631,9 @@
wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
+ _("Select an object"),
GetBitmap("select"),
- wx.NullBitmap,
- _("Select an object"))
+ wx.NullBitmap)
EditorToolBar.Realize()
self.Panes["EditorToolBar"] = EditorToolBar
self.AUIManager.AddPane(EditorToolBar, wx.aui.AuiPaneInfo().
@@ -759,6 +759,8 @@
self.SetRefreshFunctions()
self.SetDeleteFunctions()
+ self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
+
wx.CallAfter(self.InitFindDialog)
def __del__(self):
@@ -919,12 +921,8 @@
:param elements: List of elements to refresh.
"""
- try:
- for element in elements:
- self.RefreshFunctions[element]()
- except wx.PyDeadObjectError:
- # ignore exceptions caused by refresh while quitting
- pass
+ for element in elements:
+ self.RefreshFunctions[element]()
def OnPageClose(self, event):
"""Callback function when AUINotebook Page closed with CloseButton
@@ -1154,6 +1152,9 @@
def OnQuitMenu(self, event):
self.Close()
+ def OnCloseFrame(self, event):
+ self.AUIManager.UnInit()
+
# -------------------------------------------------------------------------------
# Edit Menu Functions
# -------------------------------------------------------------------------------
@@ -1413,7 +1414,8 @@
self.AuiTabCtrl = auitabctrl
if self.TabsOpened.GetPageCount() == 0:
pane = self.AUIManager.GetPane(self.TabsOpened)
- if pane.IsMaximized():
+ # on wxPython 4.1.0, AuiPaneInfo has no "IsMaximized" attribute...
+ if (not hasattr(pane, "IsMaximized")) or pane.IsMaximized():
self.AUIManager.RestorePane(pane)
self.AUIManager.Update()
@@ -1501,7 +1503,8 @@
def SwitchPerspective(self, evt):
pane = self.AUIManager.GetPane(self.TabsOpened)
- if pane.IsMaximized():
+ # on wxPython 4.1.0, AuiPaneInfo has no "IsMaximized" attribute...
+ if (not hasattr(pane, "IsMaximized")) or pane.IsMaximized():
self.AUIManager.RestorePane(pane)
else:
self.AUIManager.MaximizePane(pane)
@@ -1803,7 +1806,7 @@
else:
block_type = "Action"
self.LastToolTipItem = item
- wx.CallAfter(self.ProjectTree.SetToolTipString,
+ wx.CallAfter(self.ProjectTree.SetToolTip,
"%s : %s : %s" % (
block_type, bodytype, item_infos["name"]))
elif self.LastToolTipItem is not None:
@@ -2113,7 +2116,7 @@
MenuToolBar.AddSeparator()
else:
id, bitmap, help, callback = toolbar_item
- MenuToolBar.AddSimpleTool(id=id, shortHelpString=help, bitmap=GetBitmap(bitmap))
+ MenuToolBar.AddTool(id, help, GetBitmap(bitmap))
if callback is not None:
self.Bind(wx.EVT_TOOL, callback, id=id)
MenuToolBar.Realize()
@@ -2153,9 +2156,9 @@
for radio, modes, id, method, picture, help in self.EditorToolBarItems[menu]:
if modes & self.DrawingMode:
if radio or self.DrawingMode == FREEDRAWING_MODE:
- EditorToolBar.AddRadioTool(id, GetBitmap(picture), wx.NullBitmap, help)
+ EditorToolBar.AddRadioTool(id, help, GetBitmap(picture), wx.NullBitmap)
else:
- EditorToolBar.AddSimpleTool(id, GetBitmap(picture), help)
+ EditorToolBar.AddTool(id, help, GetBitmap(picture))
self.Bind(wx.EVT_MENU, getattr(self, method), id=id)
self.CurrentEditorToolBar.append(id)
EditorToolBar.Realize()
diff -r c6de1a6cb655 -r 4a08728a2ea4 ProjectController.py
--- a/ProjectController.py Tue Oct 19 15:15:03 2021 +0200
+++ b/ProjectController.py Wed Oct 20 08:57:07 2021 +0200
@@ -402,7 +402,7 @@
return res
# helper func to check project path write permission
- def CheckProjectPathPerm(self, dosave=True):
+ def CheckProjectPathPerm(self):
if CheckPathPerm(self.ProjectPath):
return True
if self.AppFrame is not None:
@@ -577,7 +577,7 @@
return True
def SaveProject(self, from_project_path=None):
- if self.CheckProjectPathPerm(False):
+ if self.CheckProjectPathPerm():
if from_project_path is not None:
old_projectfiles_path = self._getProjectFilesPath(
from_project_path)
diff -r c6de1a6cb655 -r 4a08728a2ea4 bacnet/BacnetSlaveEditor.py
--- a/bacnet/BacnetSlaveEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/bacnet/BacnetSlaveEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -367,8 +367,7 @@
"Engineering Units": {"GridCellEditor": wx.grid.GridCellChoiceEditor,
# use string renderer with choice editor!
"GridCellRenderer": wx.grid.GridCellStringRenderer,
- # syntax for GridCellChoiceEditor -> comma separated values
- "GridCellEditorParam": ','.join([x[0] for x in BACnetEngineeringUnits])}
+ "GridCellEditorConstructorArgs": [x[0] for x in BACnetEngineeringUnits]}
}
# obj_properties should be a dictionary, with keys "Object Identifier",
@@ -576,7 +575,10 @@
PropertyName = self.BACnetObjectType.PropertyNames[col]
PropertyConfig = self.BACnetObjectType.PropertyConfig[PropertyName]
grid.SetReadOnly(row, col, False)
- grid.SetCellEditor(row, col, PropertyConfig["GridCellEditor"]())
+ GridCellEditorConstructorArgs = \
+ PropertyConfig["GridCellEditorConstructorArgs"]
+ if "GridCellEditorConstructorArgs" in PropertyConfig else []
+ grid.SetCellEditor(row, col, PropertyConfig["GridCellEditor"](*GridCellEditorConstructorArgs))
grid.SetCellRenderer(row, col, PropertyConfig["GridCellRenderer"]())
grid.SetCellBackgroundColour(row, col, wx.WHITE)
grid.SetCellTextColour(row, col, wx.BLACK)
@@ -816,7 +818,7 @@
self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28),
style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
controls_sizer.Add(button)
@@ -826,7 +828,7 @@
# use only to enable drag'n'drop
# self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
self.VariablesGrid.Bind(
- wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
+ wx.grid.EVT_GRID_CELL_CHANGING, 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)
self.MainSizer.Add(self.VariablesGrid, flag=wx.GROW)
diff -r c6de1a6cb655 -r 4a08728a2ea4 canfestival/NetworkEditor.py
--- a/canfestival/NetworkEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/canfestival/NetworkEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -68,7 +68,7 @@
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
- main_sizer.AddWindow(self.NetworkNodes, 0, border=5, flag=wx.GROW | wx.ALL)
+ main_sizer.Add(self.NetworkNodes, 0, border=5, flag=wx.GROW | wx.ALL)
self.NetworkEditor.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 connectors/SchemeEditor.py
--- a/connectors/SchemeEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/connectors/SchemeEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -28,19 +28,19 @@
(wx.StaticText(self, label=label),
wx.ALIGN_CENTER_VERTICAL),
(txtctrl, wx.GROW)]:
- self.fieldsizer.AddWindow(win, flag=flag)
+ self.fieldsizer.Add(win, flag=flag)
self.fieldsizer.AddSpacer(20)
if self.EnableIDSelector:
self.mainsizer = wx.FlexGridSizer(cols=2, hgap=10, vgap=10)
- self.mainsizer.AddSizer(self.fieldsizer)
+ self.mainsizer.Add(self.fieldsizer)
self.idselector = IDBrowser(
self, parent.ctr,
# use a callafter, as editor can be deleted by calling SetURI
partial(wx.CallAfter, parent.SetURI),
self.txtctrls["ID"].SetValue)
- self.mainsizer.AddWindow(self.idselector)
+ self.mainsizer.Add(self.idselector)
self.SetSizer(self.mainsizer)
else:
self.SetSizer(self.fieldsizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/CustomEditableListBox.py
--- a/controls/CustomEditableListBox.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/CustomEditableListBox.py Wed Oct 20 08:57:07 2021 +0200
@@ -25,13 +25,13 @@
from __future__ import absolute_import
import wx
-import wx.gizmos
+import wx.adv
-class CustomEditableListBox(wx.gizmos.EditableListBox):
+class CustomEditableListBox(wx.adv.EditableListBox):
def __init__(self, *args, **kwargs):
- wx.gizmos.EditableListBox.__init__(self, *args, **kwargs)
+ wx.adv.EditableListBox.__init__(self, *args, **kwargs)
listbox = self.GetListCtrl()
listbox.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
@@ -44,7 +44,7 @@
(self.GetDelButton(), _("Delete item"), "_OnDelButton"),
(self.GetUpButton(), _("Move up"), "_OnUpButton"),
(self.GetDownButton(), _("Move down"), "_OnDownButton")]:
- button.SetToolTipString(tooltip)
+ button.SetToolTip(tooltip)
button.Bind(wx.EVT_BUTTON, self.GetButtonPressedFunction(call_function))
self.Editing = False
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/CustomStyledTextCtrl.py
--- a/controls/CustomStyledTextCtrl.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/CustomStyledTextCtrl.py Wed Oct 20 08:57:07 2021 +0200
@@ -105,9 +105,9 @@
[self.GetMarginWidth(i) for i in xrange(3)],
0)
if x <= margin_width:
- self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
+ self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
else:
- self.SetCursor(wx.StockCursor(wx.CURSOR_IBEAM))
+ self.SetCursor(wx.Cursor(wx.CURSOR_IBEAM))
else:
event.Skip()
else:
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/CustomTable.py
--- a/controls/CustomTable.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/CustomTable.py Wed Oct 20 08:57:07 2021 +0200
@@ -40,7 +40,7 @@
"""
def __init__(self, parent, data, colnames):
# The base class must be initialized *first*
- wx.grid.PyGridTableBase.__init__(self)
+ wx.grid.GridTableBase.__init__(self)
self.data = data
self.colnames = colnames
self.Highlights = {}
@@ -64,7 +64,7 @@
return self.colnames[col]
def GetRowLabelValue(self, row, translate=True):
- return row
+ return str(row)
def GetValue(self, row, col):
if row < self.GetNumberRows():
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/CustomToolTip.py
--- a/controls/CustomToolTip.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/CustomToolTip.py Wed Oct 20 08:57:07 2021 +0200
@@ -137,7 +137,7 @@
max_width = max_height = 0
# Create a memory DC for calculating text extent
- dc = wx.MemoryDC(wx.EmptyBitmap(1, 1))
+ dc = wx.MemoryDC(wx.Bitmap(1, 1))
dc.SetFont(self.Font)
# Compute max tip text size
@@ -175,7 +175,6 @@
dc.SetFont(self.Font)
# Draw Tool tip
- dc.BeginDrawing()
tip_width, tip_height = self.GetToolTipSize()
# Draw background rectangle
@@ -188,6 +187,5 @@
_line_width, line_height = dc.GetTextExtent(line)
line_offset += line_height
- dc.EndDrawing()
event.Skip()
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/CustomTree.py
--- a/controls/CustomTree.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/CustomTree.py Wed Oct 20 08:57:07 2021 +0200
@@ -120,9 +120,9 @@
_item, flags = self.HitTest(pos)
bitmap_rect = self.GetBitmapRect()
- if ((bitmap_rect.InsideXY(pos.x, pos.y) or
+ if ((bitmap_rect.Contains(pos.x, pos.y) or
flags & wx.TREE_HITTEST_NOWHERE) and self.AddMenu is not None):
- wx.CallAfter(self.PopupMenuXY, self.AddMenu, pos.x, pos.y)
+ wx.CallAfter(self.PopupMenu, self.AddMenu, pos.x, pos.y)
event.Skip()
def OnEraseBackground(self, event):
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DebugVariablePanel/DebugVariableGraphicViewer.py
--- a/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Wed Oct 20 08:57:07 2021 +0200
@@ -174,7 +174,7 @@
# If mouse is dropped in graph canvas bounding box and graph is
# not 3D canvas, graphs will be merged
rect = self.ParentControl.GetAxesBoundingBox()
- if not self.ParentControl.Is3DCanvas() and rect.InsideXY(x, y):
+ if not self.ParentControl.Is3DCanvas() and rect.Contains(x, y):
# Default merge type is parallel
merge_type = GRAPH_PARALLEL
@@ -182,7 +182,7 @@
# wall be merged orthogonally
merge_rect = wx.Rect(rect.x, rect.y,
rect.width / 2., rect.height)
- if merge_rect.InsideXY(x, y):
+ if merge_rect.Contains(x, y):
merge_type = GRAPH_ORTHOGONAL
# Merge graphs
@@ -625,7 +625,7 @@
(x0, y0), (x1, y1) = t.get_window_extent().get_points()
rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0)
# Check if mouse was over label
- if rect.InsideXY(x, y):
+ if rect.Contains(x, y):
item_idx = i
break
@@ -736,7 +736,7 @@
(x0, y0), (x1, y1) = t.get_window_extent().get_points()
rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0)
# Check if mouse was over label
- if rect.InsideXY(event.x, height - event.y):
+ if rect.Contains(event.x, height - event.y):
item_idx = i
menu_direction = dir
break
@@ -756,7 +756,7 @@
# Update resize highlight
if event.y <= 5:
if self.SetHighlight(HIGHLIGHT_RESIZE):
- self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS))
+ self.SetCursor(wx.Cursor(wx.CURSOR_SIZENS))
self.ParentWindow.ForceRefresh()
else:
if self.SetHighlight(HIGHLIGHT_NONE):
@@ -832,7 +832,7 @@
# Check that double click was done inside figure
pos = event.GetPosition()
rect = self.GetAxesBoundingBox()
- if rect.InsideXY(pos.x, pos.y):
+ if rect.Contains(pos.x, pos.y):
# Reset Cursor tick to value before starting clicking
self.ParentWindow.SetCursorTick(self.StartCursorTick)
# Toggle to text Viewer(s)
@@ -926,10 +926,10 @@
# Mouse is over Viewer figure and graph is not 3D
bbox = self.GetAxesBoundingBox()
- if bbox.InsideXY(x, y) and not self.Is3DCanvas():
+ if bbox.Contains(x, y) and not self.Is3DCanvas():
rect = wx.Rect(bbox.x, bbox.y, bbox.width // 2, bbox.height)
# Mouse is over Viewer left part of figure
- if rect.InsideXY(x, y):
+ if rect.Contains(x, y):
self.SetHighlight(HIGHLIGHT_LEFT)
# Mouse is over Viewer right part of figure
@@ -1381,8 +1381,6 @@
# rendering
destGC = wx.GCDC(destDC)
- destGC.BeginDrawing()
-
# Get canvas size and figure bounding box in canvas
width, height = self.GetSize()
bbox = self.GetAxesBoundingBox()
@@ -1409,7 +1407,5 @@
# Draw other Viewer common elements
self.DrawCommonElements(destGC, self.GetButtons())
- destGC.EndDrawing()
-
self._isDrawn = True
self.gui_repaint(drawDC=drawDC)
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DebugVariablePanel/DebugVariablePanel.py
--- a/controls/DebugVariablePanel/DebugVariablePanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DebugVariablePanel/DebugVariablePanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -221,14 +221,14 @@
self.GraphicPanels = []
graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW | wx.ALL)
+ main_sizer.Add(graphics_button_sizer, border=5, flag=wx.GROW | wx.ALL)
range_label = wx.StaticText(self, label=_('Range:'))
- graphics_button_sizer.AddWindow(range_label, flag=wx.ALIGN_CENTER_VERTICAL)
+ graphics_button_sizer.Add(range_label, flag=wx.ALIGN_CENTER_VERTICAL)
self.CanvasRange = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnRangeChanged, self.CanvasRange)
- graphics_button_sizer.AddWindow(self.CanvasRange, 1,
+ graphics_button_sizer.Add(self.CanvasRange, 1,
border=5,
flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL)
@@ -246,10 +246,10 @@
button = wx.lib.buttons.GenBitmapButton(
self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
- graphics_button_sizer.AddWindow(button, border=5, flag=wx.LEFT)
+ graphics_button_sizer.Add(button, border=5, flag=wx.LEFT)
self.CanvasPosition = wx.ScrollBar(
self, size=wx.Size(0, 16), style=wx.SB_HORIZONTAL)
@@ -263,19 +263,19 @@
self.OnPositionChanging, self.CanvasPosition)
self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEDOWN,
self.OnPositionChanging, self.CanvasPosition)
- main_sizer.AddWindow(self.CanvasPosition, border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
+ main_sizer.Add(self.CanvasPosition, border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
self.TickSizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(self.TickSizer, border=5, flag=wx.ALL | wx.GROW)
+ main_sizer.Add(self.TickSizer, border=5, flag=wx.ALL | wx.GROW)
self.TickLabel = wx.StaticText(self)
- self.TickSizer.AddWindow(self.TickLabel, border=5, flag=wx.RIGHT)
+ self.TickSizer.Add(self.TickLabel, border=5, flag=wx.RIGHT)
self.MaskLabel = wx.TextCtrl(self, style=wx.TE_READONLY | wx.TE_CENTER | wx.NO_BORDER)
- self.TickSizer.AddWindow(self.MaskLabel, 1, border=5, flag=wx.RIGHT | wx.GROW)
+ self.TickSizer.Add(self.MaskLabel, 1, border=5, flag=wx.RIGHT | wx.GROW)
self.TickTimeLabel = wx.StaticText(self)
- self.TickSizer.AddWindow(self.TickTimeLabel)
+ self.TickSizer.Add(self.TickTimeLabel)
self.GraphicsWindow = wx.ScrolledWindow(self, style=wx.HSCROLL | wx.VSCROLL)
self.GraphicsWindow.SetBackgroundColour(wx.WHITE)
@@ -284,7 +284,7 @@
self.GraphicsWindow.Bind(wx.EVT_SIZE, self.OnGraphicsWindowResize)
self.GraphicsWindow.Bind(wx.EVT_MOUSEWHEEL, self.OnGraphicsWindowMouseWheel)
- main_sizer.AddWindow(self.GraphicsWindow, 1, flag=wx.GROW)
+ main_sizer.Add(self.GraphicsWindow, 1, flag=wx.GROW)
self.GraphicsSizer = wx.BoxSizer(wx.VERTICAL)
self.GraphicsWindow.SetSizer(self.GraphicsSizer)
@@ -441,7 +441,7 @@
x, y = panel.GetPosition()
width, height = panel.GetSize()
rect = wx.Rect(x, y, width, height)
- if rect.InsideXY(x_mouse, y_mouse) or \
+ if rect.Contains(x_mouse, y_mouse) or \
idx == 0 and y_mouse < 0 or \
idx == len(self.GraphicPanels) - 1 and y_mouse > panel.GetPosition()[1]:
panel.RefreshHighlight(x_mouse - x, y_mouse - y)
@@ -488,7 +488,7 @@
xw, yw = panel.GetPosition()
width, height = panel.GetSize()
bbox = wx.Rect(xw, yw, width, height)
- if bbox.InsideXY(x_mouse, y_mouse):
+ if bbox.Contains(x_mouse, y_mouse):
panel.ShowButtons(True)
merge_type = GRAPH_PARALLEL
if isinstance(panel, DebugVariableTextViewer) or panel.Is3DCanvas():
@@ -497,9 +497,9 @@
wx.CallAfter(self.MoveValue, variable, idx, True)
else:
rect = panel.GetAxesBoundingBox(True)
- if rect.InsideXY(x_mouse, y_mouse):
+ if rect.Contains(x_mouse, y_mouse):
merge_rect = wx.Rect(rect.x, rect.y, rect.width // 2, rect.height)
- if merge_rect.InsideXY(x_mouse, y_mouse):
+ if merge_rect.Contains(x_mouse, y_mouse):
merge_type = GRAPH_ORTHOGONAL
wx.CallAfter(self.MergeGraphs, variable, idx, merge_type, force=True)
else:
@@ -510,7 +510,7 @@
return
width, height = self.GraphicsWindow.GetVirtualSize()
rect = wx.Rect(0, 0, width, height)
- if rect.InsideXY(x_mouse, y_mouse):
+ if rect.Contains(x_mouse, y_mouse):
wx.CallAfter(self.MoveValue, variable, len(self.GraphicPanels), True)
self.ForceRefresh()
@@ -518,7 +518,7 @@
self.GraphicsSizer.Clear()
for panel in self.GraphicPanels:
- self.GraphicsSizer.AddWindow(panel, flag=wx.GROW)
+ self.GraphicsSizer.Add(panel, flag=wx.GROW)
self.GraphicsSizer.Layout()
self.RefreshGraphicsWindowScrollbars()
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DebugVariablePanel/DebugVariableTextViewer.py
--- a/controls/DebugVariablePanel/DebugVariableTextViewer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DebugVariablePanel/DebugVariableTextViewer.py Wed Oct 20 08:57:07 2021 +0200
@@ -195,7 +195,7 @@
# Create buffered DC for drawing in panel
width, height = self.GetSize()
- bitmap = wx.EmptyBitmap(width, height)
+ bitmap = wx.Bitmap(width, height)
dc = wx.BufferedDC(wx.PaintDC(self), bitmap)
dc.Clear()
@@ -203,8 +203,6 @@
# rendering
gc = wx.GCDC(dc)
- gc.BeginDrawing()
-
# Get first item
item = self.ItemsDict.values()[0]
@@ -232,8 +230,6 @@
# Draw other Viewer common elements
self.DrawCommonElements(gc)
- gc.EndDrawing()
-
def OnLeftDown(self, event):
"""
Function called when mouse left button is pressed
@@ -252,7 +248,7 @@
# start a move drag'n drop of item variable
x, y = event.GetPosition()
item_path_bbox = wx.Rect(20, (height - h) / 2, w, h)
- if item_path_bbox.InsideXY(x, y):
+ if item_path_bbox.Contains(x, y):
self.ShowButtons(False)
data = wx.TextDataObject(str((item.GetVariable(), "debug", "move")))
dragSource = wx.DropSource(self)
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DebugVariablePanel/GraphButton.py
--- a/controls/DebugVariablePanel/GraphButton.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DebugVariablePanel/GraphButton.py Wed Oct 20 08:57:07 2021 +0200
@@ -146,7 +146,7 @@
# Test if point is inside button
w, h = self.Bitmap.GetSize()
rect = wx.Rect(self.Position.x, self.Position.y, w, h)
- return rect.InsideXY(x, y)
+ return rect.Contains(x, y)
def ProcessCallback(self):
"""
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DiscoveryPanel.py
--- a/controls/DiscoveryPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DiscoveryPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -44,17 +44,17 @@
class DiscoveryPanel(wx.Panel, listmix.ColumnSorterMixin):
def _init_coll_MainSizer_Items(self, parent):
- parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
- parent.AddWindow(self.ServicesList, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.GROW)
- parent.AddSizer(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
+ parent.Add(self.staticText1, 0, border=20, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
+ parent.Add(self.ServicesList, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.GROW)
+ parent.Add(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
def _init_coll_MainSizer_Growables(self, parent):
parent.AddGrowableCol(0)
parent.AddGrowableRow(1)
def _init_coll_ButtonGridSizer_Items(self, parent):
- parent.AddWindow(self.RefreshButton, 0, border=0, flag=0)
- # parent.AddWindow(self.ByIPCheck, 0, border=0, flag=0)
+ parent.Add(self.RefreshButton, 0, border=0, flag=0)
+ # parent.Add(self.ByIPCheck, 0, border=0, flag=0)
def _init_coll_ButtonGridSizer_Growables(self, parent):
parent.AddGrowableCol(0)
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/DurationCellEditor.py
--- a/controls/DurationCellEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/DurationCellEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -46,12 +46,12 @@
self.Duration = wx.TextCtrl(self, size=wx.Size(0, -1),
style=wx.TE_PROCESS_ENTER)
self.Duration.Bind(wx.EVT_KEY_DOWN, self.OnDurationChar)
- main_sizer.AddWindow(self.Duration, flag=wx.GROW)
+ main_sizer.Add(self.Duration, flag=wx.GROW)
# create browse button
self.EditButton = wx.Button(self, label='...', size=wx.Size(30, -1))
self.Bind(wx.EVT_BUTTON, self.OnEditButtonClick, self.EditButton)
- main_sizer.AddWindow(self.EditButton, flag=wx.GROW)
+ main_sizer.Add(self.EditButton, flag=wx.GROW)
self.Bind(wx.EVT_SIZE, self.OnSize)
@@ -98,12 +98,12 @@
self.Duration.SetFocus()
-class DurationCellEditor(wx.grid.PyGridCellEditor):
+class DurationCellEditor(wx.grid.GridCellEditor):
'''
Grid cell editor that uses DurationCellControl to display an edit button.
'''
def __init__(self, table, colname):
- wx.grid.PyGridCellEditor.__init__(self)
+ wx.grid.GridCellEditor.__init__(self)
self.Table = table
self.Colname = colname
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/EnhancedStatusBar.py
--- a/controls/EnhancedStatusBar.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/EnhancedStatusBar.py Wed Oct 20 08:57:07 2021 +0200
@@ -85,12 +85,12 @@
class EnhancedStatusBar(wx.StatusBar):
- def __init__(self, parent, id=wx.ID_ANY, style=wx.ST_SIZEGRIP,
+ def __init__(self, parent, id=wx.ID_ANY, style=wx.STB_SIZEGRIP,
name="EnhancedStatusBar"):
"""Default Class Constructor.
EnhancedStatusBar.__init__(self, parent, id=wx.ID_ANY,
- style=wx.ST_SIZEGRIP,
+ style=wx.STB_SIZEGRIP,
name="EnhancedStatusBar")
"""
@@ -100,7 +100,7 @@
self._curPos = 0
self._parent = parent
- wx.EVT_SIZE(self, self.OnSize)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
wx.CallAfter(self.OnSize, None)
def OnSize(self, event):
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/FolderTree.py
--- a/controls/FolderTree.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/FolderTree.py Wed Oct 20 08:57:07 2021 +0200
@@ -74,12 +74,12 @@
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnTreeItemCollapsed, self.Tree)
self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeBeginLabelEdit, self.Tree)
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeEndLabelEdit, self.Tree)
- main_sizer.AddWindow(self.Tree, 1, flag=wx.GROW)
+ main_sizer.Add(self.Tree, 1, flag=wx.GROW)
if filter is not None:
self.Filter = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChanged, self.Filter)
- main_sizer.AddWindow(self.Filter, flag=wx.GROW)
+ main_sizer.Add(self.Filter, flag=wx.GROW)
else:
self.Filter = None
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/LibraryPanel.py
--- a/controls/LibraryPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/LibraryPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -77,12 +77,12 @@
search_textctrl = self.SearchCtrl.GetChildren()[0]
search_textctrl.Bind(wx.EVT_CHAR, self.OnKeyDown)
- main_sizer.AddWindow(self.SearchCtrl, flag=wx.GROW)
+ main_sizer.Add(self.SearchCtrl, flag=wx.GROW)
# Add Splitter window for tree and block comment to main sizer
splitter_window = wx.SplitterWindow(self)
splitter_window.SetSashGravity(1.0)
- main_sizer.AddWindow(splitter_window, flag=wx.GROW)
+ main_sizer.Add(splitter_window, flag=wx.GROW)
# Add TreeCtrl for functions and function blocks library in splitter
# window
@@ -216,7 +216,7 @@
# Set data associated to tree item (only save that item is a
# category)
- self.Tree.SetPyData(category_item, {"type": CATEGORY})
+ self.Tree.SetItemData(category_item, {"type": CATEGORY})
# Iterate over functions and function blocks defined in library
# category add a tree item to category tree item for each of
@@ -253,7 +253,7 @@
if blocktype["extensible"] else None),
"comment": _(comment) + blocktype.get("usage", "")
}
- self.Tree.SetPyData(blocktype_item, block_data)
+ self.Tree.SetItemData(blocktype_item, block_data)
# Select block tree item in tree if it corresponds to
# previously selected one
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/LocationCellEditor.py
--- a/controls/LocationCellEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/LocationCellEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -46,12 +46,12 @@
self.Location = wx.TextCtrl(self, size=wx.Size(0, -1),
style=wx.TE_PROCESS_ENTER)
self.Location.Bind(wx.EVT_KEY_DOWN, self.OnLocationChar)
- main_sizer.AddWindow(self.Location, flag=wx.GROW)
+ main_sizer.Add(self.Location, flag=wx.GROW)
# create browse button
self.BrowseButton = wx.Button(self, label='...', size=wx.Size(30, -1))
self.BrowseButton.Bind(wx.EVT_BUTTON, self.OnBrowseButtonClick)
- main_sizer.AddWindow(self.BrowseButton, flag=wx.GROW)
+ main_sizer.Add(self.BrowseButton, flag=wx.GROW)
self.Bind(wx.EVT_SIZE, self.OnSize)
@@ -150,12 +150,12 @@
self.Location.SetFocus()
-class LocationCellEditor(wx.grid.PyGridCellEditor):
+class LocationCellEditor(wx.grid.GridCellEditor):
'''
Grid cell editor that uses LocationCellControl to display a browse button.
'''
def __init__(self, table, controller):
- wx.grid.PyGridCellEditor.__init__(self)
+ wx.grid.GridCellEditor.__init__(self)
self.Table = table
self.Controller = controller
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/LogViewer.py
--- a/controls/LogViewer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/LogViewer.py Wed Oct 20 08:57:07 2021 +0200
@@ -99,8 +99,8 @@
width, height = self.GetClientSize()
range_rect = self.GetRangeRect()
thumb_rect = self.GetThumbRect()
- if range_rect.InsideXY(posx, posy):
- if thumb_rect.InsideXY(posx, posy):
+ if range_rect.Contains(posx, posy):
+ if thumb_rect.Contains(posx, posy):
self.ThumbScrollingStartPos = wx.Point(posx, posy)
elif posy < thumb_rect.y:
self.Parent.ScrollToLast()
@@ -139,7 +139,6 @@
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
dc.Clear()
- dc.BeginDrawing()
gc = wx.GCDC(dc)
@@ -179,7 +178,6 @@
gc.DrawRectangle(thumb_rect.x, thumb_rect.y,
thumb_rect.width, thumb_rect.height)
- dc.EndDrawing()
event.Skip()
@@ -207,7 +205,7 @@
def HitTest(self, x, y):
rect = wx.Rect(self.Position.x, self.Position.y,
self.Size.width, self.Size.height)
- if rect.InsideXY(x, y):
+ if rect.Contains(x, y):
return True
return False
@@ -303,7 +301,7 @@
main_sizer.AddGrowableRow(1)
filter_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(filter_sizer, border=5, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
+ main_sizer.Add(filter_sizer, border=5, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
self.MessageFilter = wx.ComboBox(self, style=wx.CB_READONLY)
self.MessageFilter.Append(_("All"))
@@ -312,7 +310,7 @@
for level in levels:
self.MessageFilter.Append(_(level))
self.Bind(wx.EVT_COMBOBOX, self.OnMessageFilterChanged, self.MessageFilter)
- filter_sizer.AddWindow(self.MessageFilter, 1, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
+ filter_sizer.Add(self.MessageFilter, 1, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
self.SearchMessage = wx.SearchCtrl(self, style=wx.TE_PROCESS_ENTER)
self.SearchMessage.ShowSearchButton(True)
@@ -322,18 +320,18 @@
self.OnSearchMessageSearchButtonClick, self.SearchMessage)
self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN,
self.OnSearchMessageCancelButtonClick, self.SearchMessage)
- filter_sizer.AddWindow(self.SearchMessage, 3, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
+ filter_sizer.Add(self.SearchMessage, 3, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
self.CleanButton = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap("Clean"),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- self.CleanButton.SetToolTipString(_("Clean log messages"))
+ self.CleanButton.SetToolTip(_("Clean log messages"))
self.Bind(wx.EVT_BUTTON, self.OnCleanButton, self.CleanButton)
- filter_sizer.AddWindow(self.CleanButton)
+ filter_sizer.Add(self.CleanButton)
message_panel_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
message_panel_sizer.AddGrowableCol(0)
message_panel_sizer.AddGrowableRow(0)
- main_sizer.AddSizer(message_panel_sizer, border=5, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
+ main_sizer.Add(message_panel_sizer, border=5, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
self.MessagePanel = wx.Panel(self)
if wx.Platform == '__WXMSW__':
@@ -349,10 +347,10 @@
self.MessagePanel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnMessagePanelEraseBackground)
self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint)
self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize)
- message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW)
+ message_panel_sizer.Add(self.MessagePanel, flag=wx.GROW)
self.MessageScrollBar = LogScrollBar(self, wx.Size(16, -1))
- message_panel_sizer.AddWindow(self.MessageScrollBar, flag=wx.GROW)
+ message_panel_sizer.Add(self.MessageScrollBar, flag=wx.GROW)
self.SetSizer(main_sizer)
@@ -534,10 +532,9 @@
def RefreshView(self):
width, height = self.MessagePanel.GetClientSize()
- bitmap = wx.EmptyBitmap(width, height)
+ bitmap = wx.Bitmap(width, height)
dc = wx.BufferedDC(wx.ClientDC(self.MessagePanel), bitmap)
dc.Clear()
- dc.BeginDrawing()
if self.CurrentMessage is not None:
@@ -559,8 +556,6 @@
draw_date = message.Date != previous_message.Date
message = previous_message
- dc.EndDrawing()
-
self.MessageScrollBar.RefreshThumbPosition()
def IsPLCLogEmpty(self):
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/PouInstanceVariablesPanel.py
--- a/controls/PouInstanceVariablesPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/PouInstanceVariablesPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#.!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of Beremiz, a Integrated Development Environment for
@@ -93,7 +93,7 @@
rect = wx.Rect(images_bbx.x + 4, images_bbx.y + 4,
r_image_w, r_image_h)
for r_image in rightimages:
- if rect.Inside(point):
+ if rect.Contains(point):
return r_image
rect.x += r_image_w + 4
@@ -132,7 +132,7 @@
self.ParentButton = wx.lib.buttons.GenBitmapButton(
self, bitmap=GetBitmap("top"), size=wx.Size(28, 28), style=wx.NO_BORDER)
- self.ParentButton.SetToolTipString(_("Parent instance"))
+ self.ParentButton.SetToolTip(_("Parent instance"))
self.Bind(wx.EVT_BUTTON, self.OnParentButtonClick,
self.ParentButton)
@@ -142,7 +142,7 @@
self.DebugButton = wx.lib.buttons.GenBitmapButton(
self, bitmap=GetBitmap("debug_instance"), size=wx.Size(28, 28), style=wx.NO_BORDER)
- self.DebugButton.SetToolTipString(_("Debug instance"))
+ self.DebugButton.SetToolTip(_("Debug instance"))
self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick,
self.DebugButton)
@@ -175,15 +175,15 @@
self.DebugButtonCallback, self.DebugButtonDClickCallback)}
buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
- buttons_sizer.AddWindow(self.ParentButton)
- buttons_sizer.AddWindow(self.InstanceChoice, flag=wx.GROW)
- buttons_sizer.AddWindow(self.DebugButton)
+ buttons_sizer.Add(self.ParentButton)
+ buttons_sizer.Add(self.InstanceChoice, flag=wx.GROW)
+ buttons_sizer.Add(self.DebugButton)
buttons_sizer.AddGrowableCol(1)
buttons_sizer.AddGrowableRow(0)
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
- main_sizer.AddSizer(buttons_sizer, flag=wx.GROW)
- main_sizer.AddWindow(self.VariablesList, flag=wx.GROW)
+ main_sizer.Add(buttons_sizer, flag=wx.GROW)
+ main_sizer.Add(self.VariablesList, flag=wx.GROW)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/ProjectPropertiesPanel.py
--- a/controls/ProjectPropertiesPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/ProjectPropertiesPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -57,7 +57,7 @@
border |= wx.BOTTOM
st = wx.StaticText(parent, label=label)
- sizer.AddWindow(st, border=10,
+ sizer.Add(st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL | border | wx.LEFT)
tc = wx.TextCtrl(parent, style=wx.TE_PROCESS_ENTER)
@@ -65,7 +65,7 @@
callback = self.GetTextCtrlChangedFunction(tc, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, tc)
tc.Bind(wx.EVT_KILL_FOCUS, callback)
- sizer.AddWindow(tc, border=10,
+ sizer.Add(tc, border=10,
flag=wx.GROW | border | wx.RIGHT)
def __init__(self, parent, controller=None, window=None, enable_required=True, scrolling=True):
@@ -125,19 +125,19 @@
pageSize_st = wx.StaticText(self.GraphicsPanel,
label=_('Page Size (optional):'))
- graphicpanel_sizer.AddWindow(
+ graphicpanel_sizer.Add(
pageSize_st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.LEFT | wx.RIGHT)
pageSize_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
pageSize_sizer.AddGrowableCol(1)
- graphicpanel_sizer.AddSizer(pageSize_sizer, border=10,
+ graphicpanel_sizer.Add(pageSize_sizer, border=10,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
for name, label in [('PageWidth', _('Width:')),
('PageHeight', _('Height:'))]:
st = wx.StaticText(self.GraphicsPanel, label=label)
- pageSize_sizer.AddWindow(st, border=12,
+ pageSize_sizer.Add(st, border=12,
flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT)
sp = wx.SpinCtrl(self.GraphicsPanel,
@@ -146,15 +146,15 @@
callback = self.GetPageSizeChangedFunction(sp, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, sp)
sp.Bind(wx.EVT_KILL_FOCUS, callback)
- pageSize_sizer.AddWindow(sp, flag=wx.GROW)
+ pageSize_sizer.Add(sp, flag=wx.GROW)
scaling_st = wx.StaticText(self.GraphicsPanel,
label=_('Grid Resolution:'))
- graphicpanel_sizer.AddWindow(scaling_st, border=10,
+ graphicpanel_sizer.Add(scaling_st, border=10,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
scaling_nb = wx.Notebook(self.GraphicsPanel)
- graphicpanel_sizer.AddWindow(scaling_nb, border=10,
+ graphicpanel_sizer.Add(scaling_nb, border=10,
flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.Scalings = {}
@@ -173,7 +173,7 @@
border = wx.BOTTOM
st = wx.StaticText(scaling_panel, label=label)
- scalingpanel_sizer.AddWindow(
+ scalingpanel_sizer.Add(
st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL | border | wx.LEFT)
@@ -183,7 +183,7 @@
callback = self.GetScalingChangedFunction(sp, language, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, sp)
sp.Bind(wx.EVT_KILL_FOCUS, callback)
- scalingpanel_sizer.AddWindow(sp, border=10,
+ scalingpanel_sizer.Add(sp, border=10,
flag=wx.GROW | border | wx.RIGHT)
self.Scalings[language] = scaling_controls
@@ -206,18 +206,18 @@
language_label = wx.StaticText(self.MiscellaneousPanel,
label=_('Language (optional):'))
- miscellaneouspanel_sizer.AddWindow(language_label, border=10,
+ miscellaneouspanel_sizer.Add(language_label, border=10,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.LEFT)
self.Language = wx.ComboBox(self.MiscellaneousPanel,
style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnLanguageChanged, self.Language)
- miscellaneouspanel_sizer.AddWindow(self.Language, border=10,
+ miscellaneouspanel_sizer.Add(self.Language, border=10,
flag=wx.GROW | wx.TOP | wx.RIGHT)
description_label = wx.StaticText(
self.MiscellaneousPanel, label=_('Content Description (optional):'))
- miscellaneouspanel_sizer.AddWindow(description_label, border=10,
+ miscellaneouspanel_sizer.Add(description_label, border=10,
flag=wx.BOTTOM | wx.LEFT)
self.ContentDescription = wx.TextCtrl(
@@ -227,7 +227,7 @@
self.ContentDescription)
self.ContentDescription.Bind(wx.EVT_KILL_FOCUS,
self.OnContentDescriptionChanged)
- miscellaneouspanel_sizer.AddWindow(self.ContentDescription, border=10,
+ miscellaneouspanel_sizer.Add(self.ContentDescription, border=10,
flag=wx.GROW | wx.BOTTOM | wx.RIGHT)
self.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/SearchResultPanel.py
--- a/controls/SearchResultPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/SearchResultPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -52,16 +52,16 @@
class SearchResultPanel(wx.Panel):
def _init_coll_MainSizer_Items(self, parent):
- parent.AddSizer(self.HeaderSizer, 0, border=0, flag=wx.GROW)
- parent.AddWindow(self.SearchResultsTree, 1, border=0, flag=wx.GROW)
+ parent.Add(self.HeaderSizer, 0, border=0, flag=wx.GROW)
+ parent.Add(self.SearchResultsTree, 1, border=0, flag=wx.GROW)
def _init_coll_MainSizer_Growables(self, parent):
parent.AddGrowableCol(0)
parent.AddGrowableRow(1)
def _init_coll_HeaderSizer_Items(self, parent):
- parent.AddWindow(self.HeaderLabel, 1, border=5, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
- parent.AddWindow(self.ResetButton, 0, border=0, flag=0)
+ parent.Add(self.HeaderLabel, 1, border=5, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
+ parent.Add(self.ResetButton, 0, border=0, flag=0)
def _init_coll_HeaderSizer_Growables(self, parent):
parent.AddGrowableCol(0)
@@ -90,7 +90,7 @@
self.ResetButton = wx.lib.buttons.GenBitmapButton(
self, bitmap=GetBitmap("reset"),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- self.ResetButton.SetToolTipString(_("Reset search result"))
+ self.ResetButton.SetToolTip(_("Reset search result"))
self.Bind(wx.EVT_BUTTON, self.OnResetButton, self.ResetButton)
self._init_sizers()
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/TextCtrlAutoComplete.py
--- a/controls/TextCtrlAutoComplete.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/TextCtrlAutoComplete.py Wed Oct 20 08:57:07 2021 +0200
@@ -97,7 +97,7 @@
parent_rect = wx.Rect(0, -parent_size[1], parent_size[0], parent_size[1])
if selected != wx.NOT_FOUND:
wx.CallAfter(self.Parent.SetValueFromSelected, self.ListBox.GetString(selected))
- elif parent_rect.InsideXY(event.GetX(), event.GetY()):
+ elif parent_rect.Contains(event.GetX(), event.GetY()):
result, x, y = self.Parent.HitTest(wx.Point(event.GetX(), event.GetY() + parent_size[1]))
if result != wx.TE_HT_UNKNOWN:
self.Parent.SetInsertionPoint(self.Parent.XYToPosition(x, y))
diff -r c6de1a6cb655 -r 4a08728a2ea4 controls/VariablePanel.py
--- a/controls/VariablePanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/controls/VariablePanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -200,8 +200,7 @@
retain=self.Parent.ElementType != "function" and var_class in ["Local", "Input", "Output", "Global"],
non_retain=self.Parent.ElementType != "function" and var_class in ["Local", "Input", "Output"])
if len(options) > 1:
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(",".join(map(_, options)))
+ editor = wx.grid.GridCellChoiceEditor(map(_, options))
else:
grid.SetReadOnly(row, col, True)
elif col != 0 and self._GetRowEdit(row):
@@ -212,8 +211,7 @@
elif colname == "Initial Value":
if var_class not in ["External", "InOut"]:
if self.Parent.Controler.IsEnumeratedType(var_type):
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(",".join([""] + self.Parent.Controler.GetEnumeratedDataValues(var_type)))
+ editor = wx.grid.GridCellChoiceEditor([""] + self.Parent.Controler.GetEnumeratedDataValues(var_type))
else:
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
@@ -229,11 +227,10 @@
if len(self.Parent.ClassList) == 1:
grid.SetReadOnly(row, col, True)
else:
- editor = wx.grid.GridCellChoiceEditor()
excluded = []
if self.Parent.IsFunctionBlockType(var_type):
excluded.extend(["Local", "Temp"])
- editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded]))
+ editor = wx.grid.GridCellChoiceEditor([_(choice) for choice in self.Parent.ClassList if choice not in excluded])
elif colname != "Documentation":
grid.SetReadOnly(row, col, True)
@@ -456,32 +453,32 @@
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.MainSizer.Add(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)
+ controls_sizer.Add(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)
+ controls_sizer.Add(self.ReturnType)
self.DescriptionLabel = wx.StaticText(self, label=_('Description:'))
- controls_sizer.AddWindow(self.DescriptionLabel, flag=wx.ALIGN_CENTER_VERTICAL)
+ controls_sizer.Add(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.Add(self.Description)
class_filter_label = wx.StaticText(self, label=_('Class Filter:'))
- controls_sizer.AddWindow(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL)
+ controls_sizer.Add(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL)
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)
+ controls_sizer.Add(self.ClassFilter)
for name, bitmap, help in [
("AddButton", "add_element", _("Add variable")),
@@ -490,19 +487,19 @@
("DownButton", "down", _("Move variable down"))]:
button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- controls_sizer.AddWindow(button)
+ controls_sizer.Add(button)
self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL | wx.HSCROLL)
self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
- self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING,
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)
- self.MainSizer.AddWindow(self.VariablesGrid, flag=wx.GROW)
+ self.MainSizer.Add(self.VariablesGrid, flag=wx.GROW)
self.SetSizer(self.MainSizer)
@@ -848,7 +845,7 @@
# build a submenu containing standard IEC types
base_menu = wx.Menu(title='')
for base_type in self.Controler.GetBaseTypes():
- item = base_menu.Append(wx.ID_ANY, help='', kind=wx.ITEM_NORMAL, text=base_type)
+ item = base_menu.Append(wx.ID_ANY, helpString='', kind=wx.ITEM_NORMAL, item=base_type)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), item)
type_menu.AppendMenu(wx.ID_ANY, _("Base Types"), base_menu)
@@ -858,7 +855,7 @@
datatype_menu = wx.Menu(title='')
datatypes = self.Controler.GetDataTypes(basetypes=False, confnodetypes=False)
for datatype in datatypes:
- item = datatype_menu.Append(wx.ID_ANY, help='', kind=wx.ITEM_NORMAL, text=datatype)
+ item = datatype_menu.Append(wx.ID_ANY, helpString='', kind=wx.ITEM_NORMAL, item=datatype)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), item)
type_menu.AppendMenu(wx.ID_ANY, _("User Data Types"), datatype_menu)
@@ -869,7 +866,7 @@
# build a submenu containing confnode types
confnode_datatype_menu = wx.Menu(title='')
for datatype in category["list"]:
- item = confnode_datatype_menu.Append(wx.ID_ANY, help='', kind=wx.ITEM_NORMAL, text=datatype)
+ item = confnode_datatype_menu.Append(wx.ID_ANY, helpString='', kind=wx.ITEM_NORMAL, item=datatype)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), item)
type_menu.AppendMenu(wx.ID_ANY, category["name"], confnode_datatype_menu)
@@ -883,13 +880,13 @@
functionblock_menu = wx.Menu(title='')
fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName)
for functionblock_type in fbtypes:
- item = functionblock_menu.Append(wx.ID_ANY, help='', kind=wx.ITEM_NORMAL, text=functionblock_type)
+ item = functionblock_menu.Append(wx.ID_ANY, helpString='', kind=wx.ITEM_NORMAL, item=functionblock_type)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), item)
type_menu.AppendMenu(wx.ID_ANY, _("Function Block Types"), functionblock_menu)
def BuildArrayTypesMenu(self, type_menu):
- item = type_menu.Append(wx.ID_ANY, help='', kind=wx.ITEM_NORMAL, text=_("Array"))
+ item = type_menu.Append(wx.ID_ANY, helpString='', kind=wx.ITEM_NORMAL, item=_("Array"))
self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, item)
def OnVariablesGridEditorShown(self, event):
@@ -916,7 +913,7 @@
corner_y = rect.y + self.VariablesGrid.GetColLabelSize()
# pop up this new menu
- self.VariablesGrid.PopupMenuXY(type_menu, corner_x, corner_y)
+ self.VariablesGrid.PopupMenu(type_menu, corner_x, corner_y)
type_menu.Destroy()
event.Veto()
value = self.Values[row].Type
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/ActionBlockDialog.py
--- a/dialogs/ActionBlockDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/ActionBlockDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -85,29 +85,24 @@
readonly = False
colname = self.GetColLabelValue(col, False)
if colname == "Qualifier":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.QualifierList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.QualifierList)
if colname == "Duration":
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
readonly = not self.Parent.DurationList[self.data[row].qualifier]
elif colname == "Type":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.TypeList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.TypeList)
elif colname == "Value":
value_type = self.data[row].type
if value_type == "Action":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.ActionList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.ActionList)
elif value_type == "Variable":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.VariableList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.VariableList)
elif value_type == "Inline":
editor = wx.grid.GridCellTextEditor()
renderer = wx.grid.GridCellStringRenderer()
elif colname == "Indicator":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.VariableList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.VariableList)
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
@@ -133,11 +128,11 @@
top_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
top_sizer.AddGrowableCol(0)
top_sizer.AddGrowableRow(0)
- main_sizer.AddSizer(top_sizer, border=20,
+ main_sizer.Add(top_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
actions_label = wx.StaticText(self, label=_('Actions:'))
- top_sizer.AddWindow(actions_label, flag=wx.ALIGN_BOTTOM)
+ top_sizer.Add(actions_label, flag=wx.ALIGN_BOTTOM)
for name, bitmap, help in [
("AddButton", "add_element", _("Add action")),
@@ -147,21 +142,21 @@
button = wx.lib.buttons.GenBitmapButton(
self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- top_sizer.AddWindow(button)
+ top_sizer.Add(button)
self.ActionsGrid = CustomGrid(self, size=wx.Size(-1, 250), style=wx.VSCROLL)
self.ActionsGrid.DisableDragGridSize()
self.ActionsGrid.EnableScrolling(False, True)
- self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING,
self.OnActionsGridCellChange)
- main_sizer.AddSizer(self.ActionsGrid, border=20,
+ main_sizer.Add(self.ActionsGrid, border=20,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/ArrayTypeDialog.py
--- a/dialogs/ArrayTypeDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/ArrayTypeDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -50,31 +50,31 @@
main_sizer.AddGrowableRow(1)
top_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(top_sizer, border=20,
+ main_sizer.Add(top_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
basetype_label = wx.StaticText(self, label=_('Base Type:'))
- top_sizer.AddWindow(basetype_label, 1, flag=wx.ALIGN_BOTTOM)
+ top_sizer.Add(basetype_label, 1, flag=wx.ALIGN_BOTTOM)
self.BaseType = wx.ComboBox(self, style=wx.CB_READONLY)
- top_sizer.AddWindow(self.BaseType, 1, flag=wx.GROW)
+ top_sizer.Add(self.BaseType, 1, flag=wx.GROW)
self.Dimensions = CustomEditableListBox(self, label=_("Dimensions:"),
- style=(wx.gizmos.EL_ALLOW_NEW |
- wx.gizmos.EL_ALLOW_EDIT |
- wx.gizmos.EL_ALLOW_DELETE))
+ style=(wx.adv.EL_ALLOW_NEW |
+ wx.adv.EL_ALLOW_EDIT |
+ wx.adv.EL_ALLOW_DELETE))
for func in ["_OnLabelEndEdit",
"_OnAddButton",
"_OnDelButton",
"_OnUpButton",
"_OnDownButton"]:
setattr(self.Dimensions, func, self.OnDimensionsChanged)
- main_sizer.AddSizer(self.Dimensions, border=20,
+ main_sizer.Add(self.Dimensions, border=20,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/BlockPreviewDialog.py
--- a/dialogs/BlockPreviewDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/BlockPreviewDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -75,8 +75,7 @@
# Add default dialog buttons sizer
self.ButtonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
- self.ButtonSizer.GetAffirmativeButton())
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
self.Element = None # Graphic element to display in preview
self.MinElementSize = None # Graphic element minimal size
@@ -120,7 +119,7 @@
# Create a sizer for dividing parameters in two columns
self.ColumnSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.MainSizer.AddSizer(self.ColumnSizer, border=20,
+ self.MainSizer.Add(self.ColumnSizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
# Create a sizer for left column
@@ -129,7 +128,7 @@
self.LeftGridSizer.AddGrowableCol(0)
if left_growable_row is not None:
self.LeftGridSizer.AddGrowableRow(left_growable_row)
- self.ColumnSizer.AddSizer(self.LeftGridSizer, 1, border=5,
+ self.ColumnSizer.Add(self.LeftGridSizer, 1, border=5,
flag=wx.GROW | wx.RIGHT | wx.EXPAND)
# Create a sizer for right column
@@ -138,7 +137,7 @@
self.RightGridSizer.AddGrowableCol(0)
if right_growable_row is not None:
self.RightGridSizer.AddGrowableRow(right_growable_row)
- self.ColumnSizer.AddSizer(self.RightGridSizer, 1, border=5,
+ self.ColumnSizer.Add(self.RightGridSizer, 1, border=5,
flag=wx.GROW | wx.LEFT)
self.SetSizer(self.MainSizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/BrowseLocationsDialog.py
--- a/dialogs/BrowseLocationsDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/BrowseLocationsDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -76,7 +76,7 @@
main_sizer.AddGrowableRow(1)
locations_label = wx.StaticText(self, label=_('Locations available:'))
- main_sizer.AddWindow(locations_label, border=20,
+ main_sizer.Add(locations_label, border=20,
flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
self.LocationsTree = wx.TreeCtrl(self,
@@ -88,7 +88,7 @@
self.LocationsTree.SetInitialSize(wx.Size(-1, 300))
self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnLocationsTreeItemActivated,
self.LocationsTree)
- main_sizer.AddWindow(self.LocationsTree, border=20,
+ main_sizer.Add(self.LocationsTree, border=20,
flag=wx.LEFT | wx.RIGHT | wx.GROW)
self.RenameCheckBox = wx.CheckBox(self, label=_("Rename variable to signal name"))
@@ -97,37 +97,37 @@
self.RenameCheckBox.SetValue(default_checked)
self.do_rename = default_checked
- main_sizer.AddWindow(self.RenameCheckBox, border=20,
+ main_sizer.Add(self.RenameCheckBox, border=20,
flag=wx.LEFT | wx.RIGHT | wx.GROW)
button_gridsizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
button_gridsizer.AddGrowableCol(1)
button_gridsizer.AddGrowableCol(3)
button_gridsizer.AddGrowableRow(0)
- main_sizer.AddSizer(button_gridsizer, border=20,
+ main_sizer.Add(button_gridsizer, border=20,
flag=wx.BOTTOM | wx.LEFT | wx.RIGHT | wx.GROW)
direction_label = wx.StaticText(self, label=_('Direction:'))
- button_gridsizer.AddWindow(direction_label,
+ button_gridsizer.Add(direction_label,
flag=wx.ALIGN_CENTER_VERTICAL)
self.DirFilterChoice = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChoice, self.DirFilterChoice)
- button_gridsizer.AddWindow(self.DirFilterChoice,
+ button_gridsizer.Add(self.DirFilterChoice,
flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL)
filter_label = wx.StaticText(self, label=_('Type:'))
- button_gridsizer.AddWindow(filter_label,
+ button_gridsizer.Add(filter_label,
flag=wx.ALIGN_CENTER_VERTICAL)
self.TypeFilterChoice = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChoice, self.TypeFilterChoice)
- button_gridsizer.AddWindow(self.TypeFilterChoice,
+ button_gridsizer.Add(self.TypeFilterChoice,
flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- button_gridsizer.AddSizer(button_sizer, flag=wx.ALIGN_RIGHT)
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ button_gridsizer.Add(button_sizer, flag=wx.ALIGN_RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/BrowseValuesLibraryDialog.py
--- a/dialogs/BrowseValuesLibraryDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/BrowseValuesLibraryDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -51,13 +51,13 @@
self.ButtonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
- self.flexGridSizer1.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
- self.flexGridSizer1.AddWindow(self.ValuesLibrary, 0, border=20, flag=wx.GROW | wx.LEFT | wx.RIGHT)
- self.flexGridSizer1.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
+ self.flexGridSizer1.Add(self.staticText1, 0, border=20, flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
+ self.flexGridSizer1.Add(self.ValuesLibrary, 0, border=20, flag=wx.GROW | wx.LEFT | wx.RIGHT)
+ self.flexGridSizer1.Add(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.flexGridSizer1.AddGrowableCol(0)
self.flexGridSizer1.AddGrowableRow(1)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/ConnectionDialog.py
--- a/dialogs/ConnectionDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/ConnectionDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -59,7 +59,7 @@
# Create label for connection type
type_label = wx.StaticText(self, label=_('Type:'))
- self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(type_label, flag=wx.GROW)
# Create radio buttons for selecting connection type
self.TypeRadioButtons = {}
@@ -70,27 +70,27 @@
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
- self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
+ self.LeftGridSizer.Add(radio_button, flag=wx.GROW)
self.TypeRadioButtons[type] = radio_button
first = False
# Create label for connection name
name_label = wx.StaticText(self, label=_('Name:'))
- self.LeftGridSizer.AddWindow(name_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(name_label, flag=wx.GROW)
# Create text control for defining connection name
self.ConnectionName = wx.TextCtrl(self)
self.ConnectionName.SetMinSize(wx.Size(200, -1))
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.ConnectionName)
- self.LeftGridSizer.AddWindow(self.ConnectionName, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.ConnectionName, flag=wx.GROW)
# Add preview panel and associated label to sizers
self.Preview.SetMinSize(wx.Size(-1, 100))
- self.LeftGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.LeftGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.ColumnSizer.RemoveSizer(self.RightGridSizer)
@@ -99,10 +99,10 @@
# of POU
if apply_button:
self.ApplyToAllButton = wx.Button(self, label=_("Propagate Name"))
- self.ApplyToAllButton.SetToolTipString(
+ self.ApplyToAllButton.SetToolTip(
_("Apply name modification to all continuations with the same name"))
self.Bind(wx.EVT_BUTTON, self.OnApplyToAll, self.ApplyToAllButton)
- self.ButtonSizer.AddWindow(self.ApplyToAllButton, flag=wx.LEFT)
+ self.ButtonSizer.Add(self.ApplyToAllButton, flag=wx.LEFT)
else:
self.ConnectionName.ChangeValue(
controller.GenerateNewName(
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/DurationEditorDialog.py
--- a/dialogs/DurationEditorDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/DurationEditorDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -68,7 +68,7 @@
main_sizer.AddGrowableRow(0)
controls_sizer = wx.FlexGridSizer(cols=len(CONTROLS), hgap=10, rows=2, vgap=10)
- main_sizer.AddSizer(controls_sizer, border=20,
+ main_sizer.Add(controls_sizer, border=20,
flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
controls = []
@@ -85,14 +85,14 @@
controls.append((st, txtctrl))
for st, txtctrl in controls:
- controls_sizer.AddWindow(st, flag=wx.GROW)
+ controls_sizer.Add(st, flag=wx.GROW)
for st, txtctrl in controls:
- controls_sizer.AddWindow(txtctrl, flag=wx.GROW)
+ controls_sizer.Add(txtctrl, flag=wx.GROW)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/FBDBlockDialog.py
--- a/dialogs/FBDBlockDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/FBDBlockDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -68,7 +68,7 @@
# Create static box around library panel
type_staticbox = wx.StaticBox(self, label=_('Type:'))
left_staticboxsizer = wx.StaticBoxSizer(type_staticbox, wx.VERTICAL)
- self.LeftGridSizer.AddSizer(left_staticboxsizer, border=5, flag=wx.GROW)
+ self.LeftGridSizer.Add(left_staticboxsizer, border=5, flag=wx.GROW)
# Create Library panel and add it to static box
self.LibraryPanel = LibraryPanel(self)
@@ -77,65 +77,65 @@
# Set function to call when selection in Library panel changed
setattr(self.LibraryPanel, "_OnTreeItemSelected",
self.OnLibraryTreeItemSelected)
- left_staticboxsizer.AddWindow(self.LibraryPanel, 1, border=5,
+ left_staticboxsizer.Add(self.LibraryPanel, 1, border=5,
flag=wx.GROW | wx.TOP)
# Create sizer for other block parameters
top_right_gridsizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=5)
top_right_gridsizer.AddGrowableCol(1)
- self.RightGridSizer.AddSizer(top_right_gridsizer, flag=wx.GROW)
+ self.RightGridSizer.Add(top_right_gridsizer, flag=wx.GROW)
# Create label for block name
name_label = wx.StaticText(self, label=_('Name:'))
- top_right_gridsizer.AddWindow(name_label,
+ top_right_gridsizer.Add(name_label,
flag=wx.ALIGN_CENTER_VERTICAL)
# Create text control for defining block name
self.BlockName = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.BlockName)
- top_right_gridsizer.AddWindow(self.BlockName, flag=wx.GROW)
+ top_right_gridsizer.Add(self.BlockName, flag=wx.GROW)
# Create label for extended block input number
inputs_label = wx.StaticText(self, label=_('Inputs:'))
- top_right_gridsizer.AddWindow(inputs_label,
+ top_right_gridsizer.Add(inputs_label,
flag=wx.ALIGN_CENTER_VERTICAL)
# Create spin control for defining extended block input number
self.Inputs = wx.SpinCtrl(self, min=2, max=20,
style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, self.Inputs)
- top_right_gridsizer.AddWindow(self.Inputs, flag=wx.GROW)
+ top_right_gridsizer.Add(self.Inputs, flag=wx.GROW)
# Create label for block execution order
execution_order_label = wx.StaticText(self,
label=_('Execution Order:'))
- top_right_gridsizer.AddWindow(execution_order_label,
+ top_right_gridsizer.Add(execution_order_label,
flag=wx.ALIGN_CENTER_VERTICAL)
# Create spin control for defining block execution order
self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
self.ExecutionOrder)
- top_right_gridsizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
+ top_right_gridsizer.Add(self.ExecutionOrder, flag=wx.GROW)
# Create label for block execution control
execution_control_label = wx.StaticText(self,
label=_('Execution Control:'))
- top_right_gridsizer.AddWindow(execution_control_label,
+ top_right_gridsizer.Add(execution_control_label,
flag=wx.ALIGN_CENTER_VERTICAL)
# Create check box to enable block execution control
self.ExecutionControl = wx.CheckBox(self)
self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged,
self.ExecutionControl)
- top_right_gridsizer.AddWindow(self.ExecutionControl, flag=wx.GROW)
+ top_right_gridsizer.Add(self.ExecutionControl, flag=wx.GROW)
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.Add(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
# Dictionary containing correspondence between parameter exchanged and
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/FBDVariableDialog.py
--- a/dialogs/FBDVariableDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/FBDVariableDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -73,49 +73,49 @@
# Create label for variable class
class_label = wx.StaticText(self, label=_('Class:'))
- self.LeftGridSizer.AddWindow(class_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(class_label, flag=wx.GROW)
# Create a combo box for defining variable class
self.Class = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnClassChanged, self.Class)
- self.LeftGridSizer.AddWindow(self.Class, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.Class, flag=wx.GROW)
# Create label for variable execution order
execution_order_label = wx.StaticText(self,
label=_('Execution Order:'))
- self.LeftGridSizer.AddWindow(execution_order_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(execution_order_label, flag=wx.GROW)
# Create spin control for defining variable execution order
self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
self.ExecutionOrder)
- self.LeftGridSizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.ExecutionOrder, flag=wx.GROW)
# Create label for variable expression
name_label = wx.StaticText(self, label=_('Expression:'))
- self.RightGridSizer.AddWindow(name_label, border=5,
+ self.RightGridSizer.Add(name_label, border=5,
flag=wx.GROW | wx.BOTTOM)
# Create text control for defining variable expression
self.Expression = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, self.Expression)
- self.RightGridSizer.AddWindow(self.Expression, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Expression, flag=wx.GROW)
# Create a list box to selected variable expression in the list of
# variables defined in POU
self.VariableName = wx.ListBox(self, size=wx.Size(-1, 120),
style=wx.LB_SINGLE | wx.LB_SORT)
self.Bind(wx.EVT_LISTBOX, self.OnNameChanged, self.VariableName)
- self.RightGridSizer.AddWindow(self.VariableName, border=4, flag=wx.GROW | wx.TOP)
+ self.RightGridSizer.Add(self.VariableName, border=4, flag=wx.GROW | wx.TOP)
# Add preview panel and associated label to sizers
- self.MainSizer.AddWindow(self.PreviewLabel, border=20,
+ self.MainSizer.Add(self.PreviewLabel, border=20,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
- self.MainSizer.AddWindow(self.Preview, border=20,
+ self.MainSizer.Add(self.Preview, border=20,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/FindInPouDialog.py
--- a/dialogs/FindInPouDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/FindInPouDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -48,76 +48,76 @@
main_sizer.AddGrowableRow(0)
controls_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(controls_sizer, border=20,
+ main_sizer.Add(controls_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
patterns_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5)
patterns_sizer.AddGrowableCol(1)
- controls_sizer.AddSizer(patterns_sizer, border=5, flag=wx.GROW | wx.BOTTOM)
+ controls_sizer.Add(patterns_sizer, border=5, flag=wx.GROW | wx.BOTTOM)
find_label = wx.StaticText(panel, label=_("Find:"))
- patterns_sizer.AddWindow(find_label, flag=wx.ALIGN_CENTER_VERTICAL)
+ patterns_sizer.Add(find_label, flag=wx.ALIGN_CENTER_VERTICAL)
self.FindPattern = wx.TextCtrl(panel)
self.Bind(wx.EVT_TEXT, self.OnFindPatternChanged, self.FindPattern)
self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey)
- patterns_sizer.AddWindow(self.FindPattern, flag=wx.GROW)
+ patterns_sizer.Add(self.FindPattern, flag=wx.GROW)
params_sizer = wx.BoxSizer(wx.HORIZONTAL)
- controls_sizer.AddSizer(params_sizer, border=5, flag=wx.GROW | wx.BOTTOM)
+ controls_sizer.Add(params_sizer, border=5, flag=wx.GROW | wx.BOTTOM)
direction_staticbox = wx.StaticBox(panel, label=_("Direction"))
direction_staticboxsizer = wx.StaticBoxSizer(
direction_staticbox, wx.VERTICAL)
- params_sizer.AddSizer(direction_staticboxsizer, 1, border=5,
+ params_sizer.Add(direction_staticboxsizer, 1, border=5,
flag=wx.GROW | wx.RIGHT)
self.Forward = wx.RadioButton(panel, label=_("Forward"),
style=wx.RB_GROUP)
- direction_staticboxsizer.AddWindow(self.Forward, border=5,
+ direction_staticboxsizer.Add(self.Forward, border=5,
flag=wx.ALL | wx.GROW)
self.Backward = wx.RadioButton(panel, label=_("Backward"))
- direction_staticboxsizer.AddWindow(self.Backward, border=5,
+ direction_staticboxsizer.Add(self.Backward, border=5,
flag=wx.ALL | wx.GROW)
options_staticbox = wx.StaticBox(panel, label=_("Options"))
options_staticboxsizer = wx.StaticBoxSizer(
options_staticbox, wx.VERTICAL)
- params_sizer.AddSizer(options_staticboxsizer, 1, flag=wx.GROW)
+ params_sizer.Add(options_staticboxsizer, 1, flag=wx.GROW)
self.CaseSensitive = wx.CheckBox(panel, label=_("Case sensitive"))
self.CaseSensitive.SetValue(True)
- options_staticboxsizer.AddWindow(self.CaseSensitive, border=5,
+ options_staticboxsizer.Add(self.CaseSensitive, border=5,
flag=wx.ALL | wx.GROW)
self.WrapSearch = wx.CheckBox(panel, label=_("Wrap search"))
self.WrapSearch.SetValue(True)
- options_staticboxsizer.AddWindow(self.WrapSearch, border=5,
+ options_staticboxsizer.Add(self.WrapSearch, border=5,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
self.RegularExpressions = wx.CheckBox(panel, label=_("Regular expressions"))
- options_staticboxsizer.AddWindow(self.RegularExpressions, border=5,
+ options_staticboxsizer.Add(self.RegularExpressions, border=5,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW)
buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(buttons_sizer, border=20,
+ main_sizer.Add(buttons_sizer, border=20,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT)
self.FindButton = wx.Button(panel, label=_("Find"))
self.FindButton.SetDefault()
self.Bind(wx.EVT_BUTTON, self.OnFindButton, self.FindButton)
- buttons_sizer.AddWindow(self.FindButton, border=5, flag=wx.RIGHT)
+ buttons_sizer.Add(self.FindButton, border=5, flag=wx.RIGHT)
self.CloseButton = wx.Button(panel, label=_("Close"))
self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton)
- buttons_sizer.AddWindow(self.CloseButton)
+ buttons_sizer.Add(self.CloseButton)
# set the longest message here, to use it length to calculate
# optimal size of dialog window
self.RegExpSyntaxErrMsg = _("Syntax error in regular expression of pattern to search!")
self.StatusLabel = wx.StaticText(panel, label=self.RegExpSyntaxErrMsg)
- controls_sizer.AddWindow(self.StatusLabel, flag=wx.ALIGN_CENTER_VERTICAL)
+ controls_sizer.Add(self.StatusLabel)
panel.SetSizer(main_sizer)
main_sizer.Fit(self)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/ForceVariableDialog.py
--- a/dialogs/ForceVariableDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/ForceVariableDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -189,7 +189,7 @@
info_sizer = wx.BoxSizer(wx.VERTICAL)
message_label = wx.StaticText(self, label=_("Forcing Variable Value"))
- info_sizer.AddWindow(message_label, border=10,
+ info_sizer.Add(message_label, border=10,
flag=wx.ALIGN_LEFT | wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
if GetTypeValue[self.IEC_Type] in [getinteger, getfloat]:
@@ -201,8 +201,8 @@
self.GetEnteredValue = self.GetValueDefault
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- info_sizer.AddSizer(button_sizer, border=10, flag=wx.ALIGN_RIGHT | wx.ALL)
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ info_sizer.Add(button_sizer, border=10, flag=wx.ALIGN_RIGHT | wx.ALL)
self.SetSizer(info_sizer)
self.Fit()
@@ -216,7 +216,7 @@
"""Add simple text control to change variable of any type"""
self.ValueCtrl = wx.TextCtrl(self)
self.ValueCtrl.SetValue(defaultValue)
- info_sizer.AddWindow(self.ValueCtrl, border=10, proportion=1,
+ info_sizer.Add(self.ValueCtrl, border=10, proportion=1,
flag=wx.ALIGN_LEFT | wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
def GetValueDefault(self):
@@ -235,11 +235,11 @@
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.InitCtrlDefault(sizer, defaultValue)
self.SpinButtonCtrl = wx.SpinButton(self, style=wx.HORIZONTAL | wx.SP_WRAP)
- sizer.AddWindow(self.SpinButtonCtrl, border=10,
+ sizer.Add(self.SpinButtonCtrl, border=10,
flag=wx.ALIGN_LEFT | wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND)
self.Bind(wx.EVT_SPIN_UP, self.SpinButtonChanged)
self.Bind(wx.EVT_SPIN_DOWN, self.SpinButtonChanged)
- info_sizer.AddWindow(sizer, proportion=1, flag=wx.EXPAND)
+ info_sizer.Add(sizer, proportion=1, flag=wx.EXPAND)
def SpinButtonChanged(self, evt):
"""Increment/decrement variable value"""
@@ -261,7 +261,7 @@
if value is not None:
self.ValueCtrl.SetValue(value)
- info_sizer.AddWindow(self.ValueCtrl, border=10,
+ info_sizer.Add(self.ValueCtrl, border=10,
flag=wx.ALIGN_LEFT | wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW)
def OnOK(self, event):
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/IDMergeDialog.py
--- a/dialogs/IDMergeDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/IDMergeDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -15,11 +15,11 @@
main_sizer = wx.BoxSizer(wx.VERTICAL)
message = wx.StaticText(self, label=question)
- main_sizer.AddWindow(message, border=20,
+ main_sizer.Add(message, border=20,
flag=wx.ALIGN_CENTER_HORIZONTAL | wx.TOP | wx.LEFT | wx.RIGHT)
self.check = wx.CheckBox(self, label=optiontext)
- main_sizer.AddWindow(self.check, border=20,
+ main_sizer.Add(self.check, border=20,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL)
buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -30,9 +30,9 @@
return lambda event: self.EndModal(_wxID)
self.Bind(wx.EVT_BUTTON, OnButtonFactory(wxID), Button)
- buttons_sizer.AddWindow(Button)
+ buttons_sizer.Add(Button)
- main_sizer.AddSizer(buttons_sizer, border=20,
+ main_sizer.Add(buttons_sizer, border=20,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/LDElementDialog.py
--- a/dialogs/LDElementDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/LDElementDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -63,7 +63,7 @@
# Create label for LD element modifier
modifier_label = wx.StaticText(self, label=_('Modifier:'))
- self.LeftGridSizer.AddWindow(modifier_label, border=5,
+ self.LeftGridSizer.Add(modifier_label, border=5,
flag=wx.GROW | wx.BOTTOM)
# Create radio buttons for selecting LD element modifier
@@ -84,13 +84,13 @@
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnModifierChanged, radio_button)
- self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
+ self.LeftGridSizer.Add(radio_button, flag=wx.GROW)
self.ModifierRadioButtons[modifier] = radio_button
first = False
# Create label for LD element variable
element_variable_label = wx.StaticText(self, label=_('Variable:'))
- self.LeftGridSizer.AddWindow(element_variable_label, border=5,
+ self.LeftGridSizer.Add(element_variable_label, border=5,
flag=wx.GROW | wx.TOP)
# Create a combo box for defining LD element variable
@@ -99,15 +99,15 @@
self.ElementVariable)
self.Bind(wx.EVT_TEXT, self.OnVariableChanged,
self.ElementVariable)
- self.LeftGridSizer.AddWindow(self.ElementVariable, border=5,
+ self.LeftGridSizer.Add(self.ElementVariable, border=5,
flag=wx.GROW | wx.TOP)
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.Add(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
# Save LD element class
@@ -198,8 +198,9 @@
self.GetElementModifier(),
value)
- button = self.ButtonSizer.GetAffirmativeButton()
- button.Enable(value != "")
+ # FIXME : how to disable OK button when content is not valid
+ # button = self.ButtonSizer.GetAffirmativeButton()
+ # button.Enable(value != "")
# Call BlockPreviewDialog function
BlockPreviewDialog.DrawPreview(self)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/LDPowerRailDialog.py
--- a/dialogs/LDPowerRailDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/LDPowerRailDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -56,7 +56,7 @@
# Create label for connection type
type_label = wx.StaticText(self, label=_('Type:'))
- self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(type_label, flag=wx.GROW)
# Create radio buttons for selecting power rail type
self.TypeRadioButtons = {}
@@ -67,27 +67,27 @@
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
- self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
+ self.LeftGridSizer.Add(radio_button, flag=wx.GROW)
self.TypeRadioButtons[type] = radio_button
first = False
# Create label for power rail pin number
pin_number_label = wx.StaticText(self, label=_('Pin number:'))
- self.LeftGridSizer.AddWindow(pin_number_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(pin_number_label, flag=wx.GROW)
# Create spin control for defining power rail pin number
self.PinNumber = wx.SpinCtrl(self, min=1, max=50,
style=wx.SP_ARROW_KEYS)
self.PinNumber.SetValue(1)
self.Bind(wx.EVT_SPINCTRL, self.OnPinNumberChanged, self.PinNumber)
- self.LeftGridSizer.AddWindow(self.PinNumber, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.PinNumber, flag=wx.GROW)
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.Fit()
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/PouActionDialog.py
--- a/dialogs/PouActionDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/PouActionDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -50,27 +50,26 @@
infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
infos_sizer.AddGrowableCol(1)
- main_sizer.AddSizer(infos_sizer, border=20,
+ main_sizer.Add(infos_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
actionname_label = wx.StaticText(self, label=_('Action Name:'))
- infos_sizer.AddWindow(actionname_label, border=4,
+ infos_sizer.Add(actionname_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.ActionName = wx.TextCtrl(self, size=wx.Size(180, -1))
- infos_sizer.AddWindow(self.ActionName, flag=wx.GROW)
+ infos_sizer.Add(self.ActionName, flag=wx.GROW)
language_label = wx.StaticText(self, label=_('Language:'))
- infos_sizer.AddWindow(language_label, border=4,
+ infos_sizer.Add(language_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
- infos_sizer.AddWindow(self.Language, flag=wx.GROW)
+ infos_sizer.Add(self.Language, flag=wx.GROW)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
- button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/PouDialog.py
--- a/dialogs/PouDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/PouDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -58,34 +58,34 @@
infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
infos_sizer.AddGrowableCol(1)
- main_sizer.AddSizer(infos_sizer, border=20,
+ main_sizer.Add(infos_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
pouname_label = wx.StaticText(self, label=_('POU Name:'))
- infos_sizer.AddWindow(pouname_label, border=4,
+ infos_sizer.Add(pouname_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.PouName = wx.TextCtrl(self)
- infos_sizer.AddWindow(self.PouName, flag=wx.GROW)
+ infos_sizer.Add(self.PouName, flag=wx.GROW)
poutype_label = wx.StaticText(self, label=_('POU Type:'))
- infos_sizer.AddWindow(poutype_label, border=4,
+ infos_sizer.Add(poutype_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.PouType = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, self.PouType)
- infos_sizer.AddWindow(self.PouType, flag=wx.GROW)
+ infos_sizer.Add(self.PouType, flag=wx.GROW)
language_label = wx.StaticText(self, label=_('Language:'))
- infos_sizer.AddWindow(language_label, border=4,
+ infos_sizer.Add(language_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
- infos_sizer.AddWindow(self.Language, flag=wx.GROW)
+ infos_sizer.Add(self.Language, flag=wx.GROW)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/PouNameDialog.py
--- a/dialogs/PouNameDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/PouNameDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -40,8 +40,7 @@
self.PouNames = []
- self.Bind(wx.EVT_BUTTON, self.OnOK,
- self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
def OnOK(self, event):
message = None
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/PouTransitionDialog.py
--- a/dialogs/PouTransitionDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/PouTransitionDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -53,26 +53,26 @@
infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=10)
infos_sizer.AddGrowableCol(1)
- main_sizer.AddSizer(infos_sizer, border=20,
+ main_sizer.Add(infos_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
transitionname_label = wx.StaticText(self, label=_('Transition Name:'))
- infos_sizer.AddWindow(transitionname_label, border=4,
+ infos_sizer.Add(transitionname_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.TransitionName = wx.TextCtrl(self, size=wx.Size(180, -1))
- infos_sizer.AddWindow(self.TransitionName, flag=wx.GROW)
+ infos_sizer.Add(self.TransitionName, flag=wx.GROW)
language_label = wx.StaticText(self, label=_('Language:'))
- infos_sizer.AddWindow(language_label, border=4,
+ infos_sizer.Add(language_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL | wx.TOP)
self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
- infos_sizer.AddWindow(self.Language, flag=wx.GROW)
+ infos_sizer.Add(self.Language, flag=wx.GROW)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20, flag=wx.ALIGN_RIGHT | wx.BOTTOM)
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(button_sizer, border=20, flag=wx.ALIGN_RIGHT | wx.BOTTOM)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/ProjectDialog.py
--- a/dialogs/ProjectDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/ProjectDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -42,12 +42,11 @@
self.ProjectProperties = ProjectPropertiesPanel(
self, enable_required=enable_required, scrolling=False)
- main_sizer.AddWindow(self.ProjectProperties, flag=wx.GROW)
+ main_sizer.Add(self.ProjectProperties, flag=wx.GROW)
self.ButtonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
- self.ButtonSizer.GetAffirmativeButton())
- main_sizer.AddSizer(self.ButtonSizer, border=20,
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
+ main_sizer.Add(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/SFCDivergenceDialog.py
--- a/dialogs/SFCDivergenceDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/SFCDivergenceDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -58,7 +58,7 @@
# Create label for divergence type
type_label = wx.StaticText(self, label=_('Type:'))
- self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(type_label, flag=wx.GROW)
# Create radio buttons for selecting divergence type
divergence_buttons = [
@@ -80,7 +80,7 @@
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
- self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
+ self.LeftGridSizer.Add(radio_button, flag=wx.GROW)
self.TypeRadioButtons[type] = radio_button
if first:
focusbtn = type
@@ -89,19 +89,19 @@
# Create label for number of divergence sequences
sequences_label = wx.StaticText(self,
label=_('Number of sequences:'))
- self.LeftGridSizer.AddWindow(sequences_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(sequences_label, flag=wx.GROW)
# Create spin control for defining number of divergence sequences
self.Sequences = wx.SpinCtrl(self, min=2, max=20, initial=2)
self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, self.Sequences)
- self.LeftGridSizer.AddWindow(self.Sequences, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.Sequences, flag=wx.GROW)
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/SFCStepDialog.py
--- a/dialogs/SFCStepDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/SFCStepDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -57,16 +57,16 @@
# Create label for SFC step name
name_label = wx.StaticText(self, label=_('Name:'))
- self.LeftGridSizer.AddWindow(name_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(name_label, flag=wx.GROW)
# Create text control for defining SFC step name
self.StepName = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.StepName)
- self.LeftGridSizer.AddWindow(self.StepName, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.StepName, flag=wx.GROW)
# Create label for SFC step connectors
connectors_label = wx.StaticText(self, label=_('Connectors:'))
- self.LeftGridSizer.AddWindow(connectors_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(connectors_label, flag=wx.GROW)
# Create check boxes for defining connectors available on SFC step
self.ConnectorsCheckBox = {}
@@ -77,15 +77,15 @@
if name == "output" or (name == "input" and not initial):
check_box.SetValue(True)
self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, check_box)
- self.LeftGridSizer.AddWindow(check_box, flag=wx.GROW)
+ self.LeftGridSizer.Add(check_box, flag=wx.GROW)
self.ConnectorsCheckBox[name] = check_box
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/SFCStepNameDialog.py
--- a/dialogs/SFCStepNameDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/SFCStepNameDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -42,8 +42,7 @@
self.Variables = []
self.StepNames = []
- self.Bind(wx.EVT_BUTTON, self.OnOK,
- self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
+ self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId())
def OnOK(self, event):
message = None
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/SFCTransitionDialog.py
--- a/dialogs/SFCTransitionDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/SFCTransitionDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -57,7 +57,7 @@
# Create label for transition type
type_label = wx.StaticText(self, label=_('Type:'))
- self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(type_label, flag=wx.GROW)
# Create combo box for selecting reference value
reference = wx.ComboBox(self, style=wx.CB_READONLY)
@@ -80,28 +80,28 @@
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
- self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
+ self.LeftGridSizer.Add(radio_button, flag=wx.GROW)
if control is not None:
control.Enable(first)
- self.LeftGridSizer.AddWindow(control, flag=wx.GROW)
+ self.LeftGridSizer.Add(control, flag=wx.GROW)
self.TypeRadioButtons[type] = (radio_button, control)
first = False
# Create label for transition priority
priority_label = wx.StaticText(self, label=_('Priority:'))
- self.LeftGridSizer.AddWindow(priority_label, flag=wx.GROW)
+ self.LeftGridSizer.Add(priority_label, flag=wx.GROW)
# Create spin control for defining priority value
self.Priority = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, self.Priority)
- self.LeftGridSizer.AddWindow(self.Priority, flag=wx.GROW)
+ self.LeftGridSizer.Add(self.Priority, flag=wx.GROW)
# Add preview panel and associated label to sizers
- self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
- self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
+ self.RightGridSizer.Add(self.PreviewLabel, flag=wx.GROW)
+ self.RightGridSizer.Add(self.Preview, flag=wx.GROW)
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(
+ self.MainSizer.Add(
self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
diff -r c6de1a6cb655 -r 4a08728a2ea4 dialogs/SearchInProjectDialog.py
--- a/dialogs/SearchInProjectDialog.py Tue Oct 19 15:15:03 2021 +0200
+++ b/dialogs/SearchInProjectDialog.py Wed Oct 20 08:57:07 2021 +0200
@@ -54,59 +54,59 @@
pattern_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
pattern_sizer.AddGrowableCol(0)
- main_sizer.AddSizer(pattern_sizer, border=20,
+ main_sizer.Add(pattern_sizer, border=20,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
pattern_label = wx.StaticText(self, label=_('Pattern to search:'))
- pattern_sizer.AddWindow(pattern_label, flag=wx.ALIGN_BOTTOM)
+ pattern_sizer.Add(pattern_label, flag=wx.ALIGN_BOTTOM)
self.CaseSensitive = wx.CheckBox(self, label=_('Case sensitive'))
- pattern_sizer.AddWindow(self.CaseSensitive, flag=wx.GROW)
+ pattern_sizer.Add(self.CaseSensitive, flag=wx.GROW)
self.Pattern = wx.TextCtrl(self, size=wx.Size(250, -1))
self.Bind(wx.EVT_TEXT, self.FindPatternChanged, self.Pattern)
- pattern_sizer.AddWindow(self.Pattern, flag=wx.GROW)
+ pattern_sizer.Add(self.Pattern, flag=wx.GROW)
self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey)
self.RegularExpression = wx.CheckBox(self, label=_('Regular expression'))
- pattern_sizer.AddWindow(self.RegularExpression, flag=wx.GROW)
+ pattern_sizer.Add(self.RegularExpression, flag=wx.GROW)
scope_staticbox = wx.StaticBox(self, label=_('Scope'))
scope_sizer = wx.StaticBoxSizer(scope_staticbox, wx.HORIZONTAL)
- main_sizer.AddSizer(scope_sizer, border=20,
+ main_sizer.Add(scope_sizer, border=20,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
scope_selection_sizer = wx.BoxSizer(wx.VERTICAL)
- scope_sizer.AddSizer(scope_selection_sizer, 1, border=5,
+ scope_sizer.Add(scope_selection_sizer, 1, border=5,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.BOTTOM)
self.WholeProject = wx.RadioButton(self, label=_('Whole Project'), style=wx.RB_GROUP)
self.WholeProject.SetValue(True)
self.Bind(wx.EVT_RADIOBUTTON, self.OnScopeChanged, self.WholeProject)
- scope_selection_sizer.AddWindow(self.WholeProject, border=5,
+ scope_selection_sizer.Add(self.WholeProject, border=5,
flag=wx.GROW | wx.BOTTOM)
self.OnlyElements = wx.RadioButton(self, label=_('Only Elements'))
self.Bind(wx.EVT_RADIOBUTTON, self.OnScopeChanged, self.OnlyElements)
self.OnlyElements.SetValue(False)
- scope_selection_sizer.AddWindow(self.OnlyElements, flag=wx.GROW)
+ scope_selection_sizer.Add(self.OnlyElements, flag=wx.GROW)
self.ElementsList = wx.CheckListBox(self)
self.ElementsList.Enable(False)
- scope_sizer.AddWindow(self.ElementsList, 1, border=5,
+ scope_sizer.Add(self.ElementsList, 1, border=5,
flag=wx.GROW | wx.TOP | wx.RIGHT | wx.BOTTOM)
buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(buttons_sizer, border=20,
+ main_sizer.Add(buttons_sizer, border=20,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT)
self.FindButton = wx.Button(self, label=_("Find"))
self.FindButton.SetDefault()
self.Bind(wx.EVT_BUTTON, self.OnFindButton, self.FindButton)
- buttons_sizer.AddWindow(self.FindButton, border=5, flag=wx.RIGHT)
+ buttons_sizer.Add(self.FindButton, border=5, flag=wx.RIGHT)
self.CloseButton = wx.Button(self, label=_("Close"))
self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton)
- buttons_sizer.AddWindow(self.CloseButton)
+ buttons_sizer.Add(self.CloseButton)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/CodeFileEditor.py
--- a/editors/CodeFileEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/CodeFileEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -291,17 +291,16 @@
doc_end_pos = self.GetLength()
for section in self.Controler.SECTIONS_NAMES:
section_comments = self.SectionsComments[section]
- start_pos = self.FindText(0, doc_end_pos, section_comments["comment"])
- end_pos = start_pos + len(section_comments["comment"])
- self.StartStyling(start_pos, 0xff)
+ start_pos, end_pos = self.FindText(0, doc_end_pos, section_comments["comment"])
+ self.StartStyling(start_pos)
self.SetStyling(end_pos - start_pos, STC_CODE_SECTION)
self.SetLineState(self.LineFromPosition(start_pos), 1)
- self.StartStyling(end_pos, 0x00)
+ self.StartStyling(end_pos)
self.SetStyling(doc_end_pos - end_pos, stc.STC_STYLE_DEFAULT)
def DoGetBestSize(self):
- return self.ParentWindow.GetPanelBestSize()
+ return self.ParentWindow.GetBestSize()
def RefreshModel(self):
text = self.GetText()
@@ -597,9 +596,9 @@
highlight_end_pos = end[1] + 1
else:
highlight_end_pos = self.GetLineEndPosition(end[0] - 1) + end[1] + 2
- self.StartStyling(highlight_start_pos, 0xff)
+ self.StartStyling(highlight_start_pos)
self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
- self.StartStyling(highlight_end_pos, 0x00)
+ self.StartStyling(highlight_end_pos)
self.SetStyling(len(self.GetText()) - highlight_end_pos, stc.STC_STYLE_DEFAULT)
@@ -614,8 +613,7 @@
class ClassGridCellEditor(wx.grid.GridCellChoiceEditor):
def __init__(self, table, row, col):
- wx.grid.GridCellChoiceEditor.__init__(self)
- self.SetParameters("input,memory,output")
+ wx.grid.GridCellChoiceEditor.__init__(self,["input","memory","output"])
class VariablesTable(CustomTable):
@@ -678,7 +676,7 @@
main_sizer.AddGrowableRow(0)
controls_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(controls_sizer, border=5, flag=wx.ALL)
+ main_sizer.Add(controls_sizer, border=5, flag=wx.ALL)
for name, bitmap, help in [
("AddVariableButton", "add_element", _("Add variable")),
@@ -687,15 +685,15 @@
("DownVariableButton", "down", _("Move variable down"))]:
button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- controls_sizer.AddWindow(button, border=5, flag=wx.BOTTOM)
+ controls_sizer.Add(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_CHANGING, 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)
+ main_sizer.Add(self.VariablesGrid, flag=wx.GROW)
self.SetSizer(main_sizer)
@@ -785,7 +783,7 @@
self.VariablesGrid.RefreshButtons()
def DoGetBestSize(self):
- return self.ParentWindow.GetPanelBestSize()
+ return self.ParentWindow.GetBestSize()
def ShowErrorMessage(self, message):
dialog = wx.MessageDialog(self, message, _("Error"), wx.OK | wx.ICON_ERROR)
@@ -836,7 +834,7 @@
type_menu.AppendMenu(wx.ID_ANY, "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())
+ self.VariablesGrid.PopupMenu(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize())
type_menu.Destroy()
event.Veto()
else:
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/ConfTreeNodeEditor.py
--- a/editors/ConfTreeNodeEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/ConfTreeNodeEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -120,7 +120,7 @@
bitmap = GetBitmap(bitmapname)
if bitmap is None:
- bitmap = wx.EmptyBitmap(0, 0)
+ bitmap = wx.Bitmap()
wx.StaticBitmap.__init__(self, parent, ID,
bitmap,
@@ -148,18 +148,18 @@
if self.SHOW_BASE_PARAMS:
baseparamseditor_sizer = wx.BoxSizer(wx.HORIZONTAL)
- self.MainSizer.AddSizer(baseparamseditor_sizer, border=5,
+ self.MainSizer.Add(baseparamseditor_sizer, border=5,
flag=wx.GROW | wx.ALL)
self.FullIECChannel = wx.StaticText(self.Editor, -1)
self.FullIECChannel.SetFont(
wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL,
wx.BOLD, faceName=faces["helv"]))
- baseparamseditor_sizer.AddWindow(self.FullIECChannel,
+ baseparamseditor_sizer.Add(self.FullIECChannel,
flag=wx.ALIGN_CENTER_VERTICAL)
updownsizer = wx.BoxSizer(wx.VERTICAL)
- baseparamseditor_sizer.AddSizer(updownsizer, border=5,
+ baseparamseditor_sizer.Add(updownsizer, border=5,
flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL)
self.IECCUpButton = wx.lib.buttons.GenBitmapTextButton(
@@ -169,14 +169,14 @@
style=wx.NO_BORDER)
self.IECCUpButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(1),
self.IECCUpButton)
- updownsizer.AddWindow(self.IECCUpButton, flag=wx.ALIGN_LEFT)
+ updownsizer.Add(self.IECCUpButton, flag=wx.ALIGN_LEFT)
self.IECCDownButton = wx.lib.buttons.GenBitmapButton(
self.Editor, bitmap=GetBitmap('IECCUp'),
size=wx.Size(16, 16), style=wx.NO_BORDER)
self.IECCDownButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(-1),
self.IECCDownButton)
- updownsizer.AddWindow(self.IECCDownButton, flag=wx.ALIGN_LEFT)
+ updownsizer.Add(self.IECCDownButton, flag=wx.ALIGN_LEFT)
self.ConfNodeName = wx.TextCtrl(self.Editor,
size=wx.Size(150, 25))
@@ -187,17 +187,17 @@
wx.EVT_TEXT,
self.GetTextCtrlCallBackFunction(self.ConfNodeName, "BaseParams.Name", True),
self.ConfNodeName)
- baseparamseditor_sizer.AddWindow(
+ baseparamseditor_sizer.Add(
self.ConfNodeName, border=5,
flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
buttons_sizer = self.GenerateMethodButtonSizer()
- baseparamseditor_sizer.AddSizer(buttons_sizer, flag=wx.ALIGN_CENTER)
+ baseparamseditor_sizer.Add(buttons_sizer, flag=wx.ALIGN_CENTER)
if tabs_num > 1:
self.ConfNodeNoteBook = wx.Notebook(self.Editor)
parent = self.ConfNodeNoteBook
- self.MainSizer.AddWindow(self.ConfNodeNoteBook, 1, flag=wx.GROW)
+ self.MainSizer.Add(self.ConfNodeNoteBook, 1, flag=wx.GROW)
else:
parent = self.Editor
self.ConfNodeNoteBook = None
@@ -212,7 +212,7 @@
if self.ConfNodeNoteBook is not None:
self.ConfNodeNoteBook.AddPage(editor, title)
elif self.SHOW_BASE_PARAMS:
- self.MainSizer.AddWindow(editor, 1, flag=wx.GROW)
+ self.MainSizer.Add(editor, 1, flag=wx.GROW)
else:
self.Editor = editor
@@ -232,7 +232,7 @@
self.ParamsEditor.SetSizer(self.ParamsEditorSizer)
self.ConfNodeParamsSizer = wx.BoxSizer(wx.VERTICAL)
- self.ParamsEditorSizer.AddSizer(self.ConfNodeParamsSizer, border=5,
+ self.ParamsEditorSizer.Add(self.ConfNodeParamsSizer, border=5,
flag=wx.LEFT | wx.RIGHT | wx.BOTTOM)
self.RefreshConfNodeParamsSizer()
@@ -240,7 +240,7 @@
if self.ConfNodeNoteBook is not None:
self.ConfNodeNoteBook.AddPage(self.ParamsEditor, _("Config"))
elif self.SHOW_BASE_PARAMS:
- self.MainSizer.AddWindow(self.ParamsEditor, 1, flag=wx.GROW)
+ self.MainSizer.Add(self.ParamsEditor, 1, flag=wx.GROW)
else:
self.Editor = self.ParamsEditor
else:
@@ -317,7 +317,7 @@
label=confnode_method["name"],
style=wx.NO_BORDER)
button.SetFont(normal_bt_font)
- button.SetToolTipString(confnode_method["tooltip"])
+ button.SetToolTip(confnode_method["tooltip"])
if confnode_method.get("push", False):
button.Bind(wx.EVT_LEFT_DOWN, self.GetButtonCallBackFunction(confnode_method["method"], True))
else:
@@ -335,7 +335,7 @@
# hack to force size to mini
if not confnode_method.get("enabled", True):
button.Disable()
- msizer.AddWindow(button, flag=wx.ALIGN_CENTER)
+ msizer.Add(button, flag=wx.ALIGN_CENTER)
return msizer
def UriOptions(self, event):
@@ -380,32 +380,32 @@
flags = (wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
if first:
flags |= wx.TOP
- sizer.AddSizer(staticboxsizer, border=5, flag=flags)
+ sizer.Add(staticboxsizer, border=5, flag=flags)
self.GenerateSizerElements(staticboxsizer,
element_infos["children"],
element_path)
else:
- boxsizer = wx.FlexGridSizer(cols=4, rows=1)
+ boxsizer = wx.FlexGridSizer(cols=4, rows=1, gap=wx.Size(0,0))
boxsizer.AddGrowableCol(1)
flags = (wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
if first:
flags |= wx.TOP
- sizer.AddSizer(boxsizer, border=5, flag=flags)
+ sizer.Add(boxsizer, border=5, flag=flags)
staticbitmap = GenStaticBitmap(
ID=-1, bitmapname=element_infos["name"],
name="%s_bitmap" % element_infos["name"], parent=self.ParamsEditor,
pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
- boxsizer.AddWindow(staticbitmap, border=5, flag=wx.RIGHT)
+ boxsizer.Add(staticbitmap, border=5, flag=wx.RIGHT)
statictext = wx.StaticText(self.ParamsEditor,
label="%s:" % _(element_infos["name"]))
- boxsizer.AddWindow(statictext, border=5,
+ boxsizer.Add(statictext, border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
if isinstance(element_infos["type"], list):
if isinstance(element_infos["value"], tuple):
browse_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
- boxsizer.AddSizer(browse_boxsizer)
+ boxsizer.Add(browse_boxsizer)
textctrl = wx.TextCtrl(self.ParamsEditor,
size=wx.Size(275, -1), style=wx.TE_READONLY)
@@ -414,10 +414,10 @@
value_infos = element_infos["value"][1]
else:
value_infos = None
- browse_boxsizer.AddWindow(textctrl)
+ browse_boxsizer.Add(textctrl)
button = wx.Button(self.ParamsEditor, label="...")
- browse_boxsizer.AddWindow(button)
+ browse_boxsizer.Add(button)
button.Bind(wx.EVT_BUTTON,
self.GetBrowseCallBackFunction(element_infos["name"], textctrl, element_infos["type"],
value_infos, element_path),
@@ -425,7 +425,7 @@
else:
combobox = wx.ComboBox(self.ParamsEditor,
size=wx.Size(300, -1), style=wx.CB_READONLY)
- boxsizer.AddWindow(combobox)
+ boxsizer.Add(combobox)
if element_infos["use"] == "optional":
combobox.Append("")
@@ -439,7 +439,7 @@
label="%s - %s" % (_(name), _(value)),
size=wx.Size(10, 0))
staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
- sizer.AddSizer(staticboxsizer, border=5, flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
+ sizer.Add(staticboxsizer, border=5, flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path)
callback = self.GetChoiceContentCallBackFunction(combobox, staticboxsizer, element_path)
else:
@@ -463,7 +463,7 @@
size=wx.Size(300, -1),
style=wx.SP_ARROW_KEYS | wx.ALIGN_RIGHT)
spinctrl.SetRange(scmin, scmax)
- boxsizer.AddWindow(spinctrl)
+ boxsizer.Add(spinctrl)
if element_infos["value"] is not None:
spinctrl.SetValue(element_infos["value"])
spinctrl.Bind(wx.EVT_SPINCTRL,
@@ -473,7 +473,7 @@
else:
if element_infos["type"] == "boolean":
checkbox = wx.CheckBox(self.ParamsEditor)
- boxsizer.AddWindow(checkbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
+ boxsizer.Add(checkbox, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
if element_infos["value"] is not None:
checkbox.SetValue(element_infos["value"])
checkbox.Bind(wx.EVT_CHECKBOX,
@@ -490,7 +490,7 @@
size=wx.Size(300, -1),
style=wx.SP_ARROW_KEYS | wx.ALIGN_RIGHT)
spinctrl.SetRange(scmin, scmax)
- boxsizer.AddWindow(spinctrl)
+ boxsizer.Add(spinctrl)
if element_infos["value"] is not None:
spinctrl.SetValue(element_infos["value"])
spinctrl.Bind(wx.EVT_SPINCTRL,
@@ -513,12 +513,12 @@
self.EditButton = wx.Button(self.ParamsEditor, label='...', size=wx.Size(30, -1))
self.Bind(wx.EVT_BUTTON, self.UriOptions, self.EditButton)
- uriSizer.AddWindow(textctrl, flag=wx.GROW)
- uriSizer.AddWindow(self.EditButton, flag=wx.GROW)
-
- boxsizer.AddWindow(uriSizer)
+ uriSizer.Add(textctrl, flag=wx.GROW)
+ uriSizer.Add(self.EditButton, flag=wx.GROW)
+
+ boxsizer.Add(uriSizer)
else:
- boxsizer.AddWindow(textctrl)
+ boxsizer.Add(textctrl)
if element_infos["value"] is not None:
textctrl.ChangeValue(str(element_infos["value"]))
@@ -535,7 +535,7 @@
self.GetResetFunction(element_path),
bt)
- boxsizer.AddWindow(bt, border=5, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT)
+ boxsizer.Add(bt, border=5, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT)
first = False
sizer.Layout()
self.RefreshScrollbars()
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/DataTypeEditor.py
--- a/editors/DataTypeEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/DataTypeEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -155,49 +155,49 @@
self.MainSizer.AddGrowableRow(1)
top_sizer = wx.BoxSizer(wx.HORIZONTAL)
- self.MainSizer.AddSizer(top_sizer, border=5,
+ self.MainSizer.Add(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.Add(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)
+ top_sizer.Add(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.Add(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)
+ typeinfos_sizer.Add(self.DirectlyPanel, 1)
directly_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
directly_basetype_label = wx.StaticText(self.DirectlyPanel,
label=_('Base Type:'))
- directly_panel_sizer.AddWindow(directly_basetype_label, 1, border=5,
+ directly_panel_sizer.Add(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.Add(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.Add(directly_initialvalue_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
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.Add(self.DirectlyInitialValue, 1, border=5,
flag=wx.ALL)
self.DirectlyPanel.SetSizer(directly_panel_sizer)
@@ -205,52 +205,52 @@
# Panel for Subrange data types
self.SubrangePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
- typeinfos_sizer.AddWindow(self.SubrangePanel, 1)
+ typeinfos_sizer.Add(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.Add(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.SubrangeBaseType)
- subrange_panel_sizer.AddWindow(self.SubrangeBaseType, 1, border=5,
+ subrange_panel_sizer.Add(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.Add(subrange_initialvalue_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
self.SubrangeInitialValue = CustomIntCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
self.SubrangeInitialValue.Bind(CustomIntCtrl.EVT_CUSTOM_INT, self.OnInfosChanged)
- subrange_panel_sizer.AddWindow(self.SubrangeInitialValue, 1, border=5,
+ subrange_panel_sizer.Add(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.Add(subrange_minimum_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
self.SubrangeMinimum = CustomIntCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
self.SubrangeMinimum.Bind(CustomIntCtrl.EVT_CUSTOM_INT, self.OnSubrangeMinimumChanged)
- subrange_panel_sizer.AddWindow(self.SubrangeMinimum, 1, border=5,
+ subrange_panel_sizer.Add(self.SubrangeMinimum, 1, border=5,
flag=wx.GROW | wx.ALL)
for dummy in xrange(2):
- subrange_panel_sizer.AddWindow(wx.Size(0, 0), 1)
+ subrange_panel_sizer.Add(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.Add(subrange_maximum_label, 1, border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
self.SubrangeMaximum = CustomIntCtrl(self.SubrangePanel, style=wx.TAB_TRAVERSAL)
self.SubrangeMaximum.Bind(CustomIntCtrl.EVT_CUSTOM_INT, self.OnSubrangeMaximumChanged)
- subrange_panel_sizer.AddWindow(self.SubrangeMaximum, 1, border=5,
+ subrange_panel_sizer.Add(self.SubrangeMaximum, 1, border=5,
flag=wx.GROW | wx.ALL)
self.SubrangePanel.SetSizer(subrange_panel_sizer)
@@ -258,35 +258,35 @@
# Panel for Enumerated data types
self.EnumeratedPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
- typeinfos_sizer.AddWindow(self.EnumeratedPanel, 1)
+ typeinfos_sizer.Add(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 |
- wx.gizmos.EL_ALLOW_DELETE))
+ style=(wx.adv.EL_ALLOW_NEW |
+ wx.adv.EL_ALLOW_EDIT |
+ wx.adv.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.Add(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_panel_sizer.Add(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.Add(enumerated_initialvalue_label, 1,
border=5,
flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
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.Add(self.EnumeratedInitialValue, 1,
border=5, flag=wx.ALL)
self.EnumeratedPanel.SetSizer(enumerated_panel_sizer)
@@ -294,7 +294,7 @@
# Panel for Array data types
self.ArrayPanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
- typeinfos_sizer.AddWindow(self.ArrayPanel, 1)
+ typeinfos_sizer.Add(self.ArrayPanel, 1)
array_panel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0)
array_panel_sizer.AddGrowableCol(0)
@@ -302,41 +302,41 @@
array_panel_sizer.AddGrowableRow(1)
array_panel_leftSizer = wx.BoxSizer(wx.HORIZONTAL)
- array_panel_sizer.AddSizer(array_panel_leftSizer, flag=wx.GROW)
+ array_panel_sizer.Add(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.Add(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.Add(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_panel_sizer.Add(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.Add(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,
+ array_panel_rightsizer.Add(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))
+ style=(wx.adv.EL_ALLOW_NEW |
+ wx.adv.EL_ALLOW_EDIT |
+ wx.adv.EL_ALLOW_DELETE))
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.Add(self.ArrayDimensions, 0, border=5,
flag=wx.GROW | wx.ALL)
self.ArrayPanel.SetSizer(array_panel_sizer)
@@ -344,7 +344,7 @@
# Panel for Structure data types
self.StructurePanel = wx.Panel(self.Editor, style=wx.TAB_TRAVERSAL)
- typeinfos_sizer.AddWindow(self.StructurePanel, 1)
+ typeinfos_sizer.Add(self.StructurePanel, 1)
structure_panel_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
structure_panel_sizer.AddGrowableCol(0)
@@ -353,12 +353,12 @@
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.Add(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)
+ structure_button_sizer.Add(structure_elements_label, flag=wx.ALIGN_BOTTOM)
for name, bitmap, help in [
("StructureAddButton", "add_element", _("Add element")),
@@ -369,17 +369,17 @@
bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28),
style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- structure_button_sizer.AddWindow(button)
+ structure_button_sizer.Add(button)
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_CHANGING,
self.OnStructureElementsGridCellChange)
self.StructureElementsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
self.OnStructureElementsGridEditorShown)
- structure_panel_sizer.AddWindow(self.StructureElementsGrid, flag=wx.GROW)
+ structure_panel_sizer.Add(self.StructureElementsGrid, flag=wx.GROW)
self.StructurePanel.SetSizer(structure_panel_sizer)
@@ -647,7 +647,7 @@
self.Bind(wx.EVT_MENU, self.ElementArrayTypeFunction, new_entry)
rect = self.StructureElementsGrid.BlockToDeviceRect((row, col), (row, col))
- self.StructureElementsGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.StructureElementsGrid.GetColLabelSize())
+ self.StructureElementsGrid.PopupMenu(type_menu, rect.x + rect.width, rect.y + self.StructureElementsGrid.GetColLabelSize())
type_menu.Destroy()
event.Veto()
else:
@@ -786,7 +786,7 @@
value = control.GetValueStr() if isinstance(control, CustomIntCtrl) else \
control.GetValue()
control.SetStyle(0, len(value), wx.TextAttr(wx.NullColour))
- elif isinstance(control, wx.gizmos.EditableListBox):
+ elif isinstance(control, wx.adv.EditableListBox):
listctrl = control.GetListCtrl()
for i in xrange(listctrl.GetItemCount()):
listctrl.SetItemBackgroundColour(i, wx.NullColour)
@@ -811,7 +811,7 @@
control.SetForegroundColour(highlight_type[1])
elif isinstance(control, wx.TextCtrl):
control.SetStyle(start[1], end[1] + 1, wx.TextAttr(highlight_type[1], highlight_type[0]))
- elif isinstance(control, wx.gizmos.EditableListBox):
+ elif isinstance(control, wx.adv.EditableListBox):
listctrl = control.GetListCtrl()
listctrl.SetItemBackgroundColour(infos[1], highlight_type[0])
listctrl.SetItemTextColour(infos[1], highlight_type[1])
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/FileManagementPanel.py
--- a/editors/FileManagementPanel.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/FileManagementPanel.py Wed Oct 20 08:57:07 2021 +0200
@@ -43,14 +43,14 @@
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
left_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(left_sizer, 1, border=5, flag=wx.GROW | wx.ALL)
+ main_sizer.Add(left_sizer, 1, border=5, flag=wx.GROW | wx.ALL)
managed_dir_label = wx.StaticText(self.Editor, label=_(self.TagName) + ":")
- left_sizer.AddWindow(managed_dir_label, border=5, flag=wx.GROW | wx.BOTTOM)
+ left_sizer.Add(managed_dir_label, border=5, flag=wx.GROW | wx.BOTTOM)
FILTER = _("All files (*.*)|*.*|CSV files (*.csv)|*.csv")
self.ManagedDir = FolderTree(self.Editor, self.Folder, FILTER)
- left_sizer.AddWindow(self.ManagedDir, 1, flag=wx.GROW)
+ left_sizer.Add(self.ManagedDir, 1, flag=wx.GROW)
managed_treectrl = self.ManagedDir.GetTreeCtrl()
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeItemChanged, managed_treectrl)
@@ -58,7 +58,7 @@
self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTreeBeginDrag, managed_treectrl)
button_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(button_sizer, border=5,
+ main_sizer.Add(button_sizer, border=5,
flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
for idx, (name, bitmap, help) in enumerate([
@@ -70,26 +70,26 @@
self.Editor,
bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
if idx > 0:
flag = wx.TOP
else:
flag = 0
self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
- button_sizer.AddWindow(button, border=20, flag=flag)
+ button_sizer.Add(button, border=20, flag=flag)
right_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(right_sizer, 1, border=5, flag=wx.GROW | wx.ALL)
+ main_sizer.Add(right_sizer, 1, border=5, flag=wx.GROW | wx.ALL)
if wx.Platform == '__WXMSW__':
system_dir_label = wx.StaticText(self.Editor, label=_("My Computer:"))
else:
system_dir_label = wx.StaticText(self.Editor, label=_("Home Directory:"))
- right_sizer.AddWindow(system_dir_label, border=5, flag=wx.GROW | wx.BOTTOM)
+ right_sizer.Add(system_dir_label, border=5, flag=wx.GROW | wx.BOTTOM)
self.SystemDir = FolderTree(self.Editor, self.HomeDirectory, FILTER, False)
- right_sizer.AddWindow(self.SystemDir, 1, flag=wx.GROW)
+ right_sizer.Add(self.SystemDir, 1, flag=wx.GROW)
system_treectrl = self.SystemDir.GetTreeCtrl()
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeItemChanged, system_treectrl)
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/ProjectNodeEditor.py
--- a/editors/ProjectNodeEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/ProjectNodeEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -60,7 +60,7 @@
ConfTreeNodeEditor.__init__(self, parent, controler, window, tagname)
buttons_sizer = self.GenerateMethodButtonSizer()
- self.MainSizer.InsertSizer(0, buttons_sizer, 0, border=5, flag=wx.ALL)
+ self.MainSizer.Insert(0, buttons_sizer, 0, border=5, flag=wx.ALL)
self.MainSizer.Layout()
self.VariableEditor = self.VariableEditorPanel
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/ResourceEditor.py
--- a/editors/ResourceEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/ResourceEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -76,10 +76,6 @@
return [_("Interrupt"), _("Cyclic")]
-def SingleCellEditor(*x):
- return wx.grid.GridCellChoiceEditor()
-
-
def CheckSingle(single, varlist):
return single in varlist
@@ -162,25 +158,21 @@
if interval != "" and IEC_TIME_MODEL.match(interval.upper()) is None:
error = True
elif colname == "Single":
- editor = SingleCellEditor(self, colname)
- editor.SetParameters(self.Parent.VariableList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.VariableList)
if self.GetValueByName(row, "Triggering") != "Interrupt":
grid.SetReadOnly(row, col, True)
single = self.GetValueByName(row, colname)
if single != "" and not CheckSingle(single, self.Parent.VariableList):
error = True
elif colname == "Triggering":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(",".join(map(_, GetTaskTriggeringOptions())))
+ editor = wx.grid.GridCellChoiceEditor(map(_, GetTaskTriggeringOptions()))
elif colname == "Type":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.TypeList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.TypeList)
elif colname == "Priority":
editor = wx.grid.GridCellNumberEditor()
editor.SetParameters("0,65535")
elif colname == "Task":
- editor = wx.grid.GridCellChoiceEditor()
- editor.SetParameters(self.Parent.TaskList)
+ editor = wx.grid.GridCellChoiceEditor(self.Parent.TaskList)
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
@@ -230,16 +222,16 @@
tasks_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
tasks_sizer.AddGrowableCol(0)
tasks_sizer.AddGrowableRow(1)
- main_sizer.AddSizer(tasks_sizer, border=5,
+ main_sizer.Add(tasks_sizer, border=5,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
tasks_buttons_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
tasks_buttons_sizer.AddGrowableCol(0)
tasks_buttons_sizer.AddGrowableRow(0)
- tasks_sizer.AddSizer(tasks_buttons_sizer, flag=wx.GROW)
+ tasks_sizer.Add(tasks_buttons_sizer, flag=wx.GROW)
tasks_label = wx.StaticText(self.Editor, label=_(u'Tasks:'))
- tasks_buttons_sizer.AddWindow(tasks_label, flag=wx.ALIGN_BOTTOM)
+ tasks_buttons_sizer.Add(tasks_label, flag=wx.ALIGN_BOTTOM)
for name, bitmap, help in [
("AddTaskButton", "add_element", _("Add task")),
@@ -250,27 +242,27 @@
bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28),
style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- tasks_buttons_sizer.AddWindow(button)
+ tasks_buttons_sizer.Add(button)
self.TasksGrid = CustomGrid(self.Editor, style=wx.VSCROLL)
- self.TasksGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnTasksGridCellChange)
- tasks_sizer.AddWindow(self.TasksGrid, flag=wx.GROW)
+ self.TasksGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING, self.OnTasksGridCellChange)
+ tasks_sizer.Add(self.TasksGrid, flag=wx.GROW)
instances_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
instances_sizer.AddGrowableCol(0)
instances_sizer.AddGrowableRow(1)
- main_sizer.AddSizer(instances_sizer, border=5,
+ main_sizer.Add(instances_sizer, border=5,
flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
instances_buttons_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
instances_buttons_sizer.AddGrowableCol(0)
instances_buttons_sizer.AddGrowableRow(0)
- instances_sizer.AddSizer(instances_buttons_sizer, flag=wx.GROW)
+ instances_sizer.Add(instances_buttons_sizer, flag=wx.GROW)
instances_label = wx.StaticText(self.Editor, label=_(u'Instances:'))
- instances_buttons_sizer.AddWindow(instances_label, flag=wx.ALIGN_BOTTOM)
+ instances_buttons_sizer.Add(instances_label, flag=wx.ALIGN_BOTTOM)
for name, bitmap, help in [
("AddInstanceButton", "add_element", _("Add instance")),
@@ -280,13 +272,13 @@
button = wx.lib.buttons.GenBitmapButton(
self.Editor, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- instances_buttons_sizer.AddWindow(button)
+ instances_buttons_sizer.Add(button)
self.InstancesGrid = CustomGrid(self.Editor, style=wx.VSCROLL)
- self.InstancesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnInstancesGridCellChange)
- instances_sizer.AddWindow(self.InstancesGrid, flag=wx.GROW)
+ self.InstancesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING, self.OnInstancesGridCellChange)
+ instances_sizer.Add(self.InstancesGrid, flag=wx.GROW)
self.Editor.SetSizer(main_sizer)
@@ -405,20 +397,20 @@
self.RefreshHighlightsTimer.Stop()
def RefreshTypeList(self):
- self.TypeList = ""
+ self.TypeList = []
blocktypes = self.Controler.GetBlockResource()
for blocktype in blocktypes:
- self.TypeList += ",%s" % blocktype
+ self.TypeList.append(blocktype)
def RefreshTaskList(self):
- self.TaskList = ""
+ self.TaskList = []
for row in xrange(self.TasksTable.GetNumberRows()):
- self.TaskList += ",%s" % self.TasksTable.GetValueByName(row, "Name")
+ self.TaskList.append(self.TasksTable.GetValueByName(row, "Name"))
def RefreshVariableList(self):
- self.VariableList = ""
+ self.VariableList = []
for variable in self.Controler.GetEditedResourceVariables(self.TagName):
- self.VariableList += ",%s" % variable
+ self.VariableList.append(variable)
def RefreshModel(self):
self.Controler.SetEditedResourceInfos(self.TagName, self.TasksTable.GetData(), self.InstancesTable.GetData())
@@ -481,7 +473,7 @@
wx.CallAfter(self.ShowErrorMessage, message)
return
- tasklist = [name for name in self.TaskList.split(",") if name != ""]
+ tasklist = [name for name in self.TaskList if name != ""]
for i in xrange(self.TasksTable.GetNumberRows()):
task = self.TasksTable.GetValueByName(i, "Name")
if task in tasklist:
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/TextViewer.py
--- a/editors/TextViewer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/TextViewer.py Wed Oct 20 08:57:07 2021 +0200
@@ -198,12 +198,20 @@
def Colourise(self, start, end):
self.Editor.Colourise(start, end)
- def StartStyling(self, pos, mask):
- self.Editor.StartStyling(pos, mask)
+ def StartStyling(self, pos):
+ self.Editor.StartStyling(pos)
+
+ INDIC0 = 0
+ INDIC1 = 1
+ INDIC2 = 2
def SetStyling(self, length, style):
self.Editor.SetStyling(length, style)
+ def SetIndicatorCurrentFillRange(start, length, indic):
+ self.Editor.SetIndicatorCurrent(indic)
+ self.Editor.IndicatorFillRange(start, length)
+
def GetCurrentPos(self):
return self.Editor.GetCurrentPos()
@@ -560,7 +568,7 @@
start_pos = last_styled_pos = self.Editor.GetLineEndPosition(line_number - 1) + 1
self.RefreshLineFolding(line_number)
end_pos = event.GetPosition()
- self.StartStyling(start_pos, 0xff)
+ self.StartStyling(start_pos)
current_context = self.Variables
current_call = None
@@ -595,9 +603,8 @@
else:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_EMPTY)
if word not in ["]", ")"] and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos):
- self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK)
- self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK)
- self.StartStyling(current_pos, 0xff)
+ self.SetIndicatorCurrentFillRange(last_styled_pos, current_pos - last_styled_pos, self.INDIC0)
+ self.StartStyling(current_pos)
else:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_EMPTY)
last_styled_pos = current_pos
@@ -698,9 +705,8 @@
else:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_EMPTY)
if word not in ["]", ")"] and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos):
- self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK)
- self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK)
- self.StartStyling(current_pos, 0xff)
+ self.SetIndicatorCurrentFillRange(last_styled_pos, current_pos - last_styled_pos, self.INDIC0)
+ self.StartStyling(current_pos)
if char == '.':
if word != "]":
if current_context is not None:
@@ -956,8 +962,8 @@
else:
highlight_end_pos = self.Editor.GetLineEndPosition(end[0] - 1) + end[1] - indent + 2
if highlight_start_pos < end_pos and highlight_end_pos > start_pos:
- self.StartStyling(highlight_start_pos, 0xff)
+ self.StartStyling(highlight_start_pos)
self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
- self.StartStyling(highlight_start_pos, 0x00)
+ self.StartStyling(highlight_start_pos)
until_end = max(0, len(self.Editor.GetText()) - highlight_end_pos)
self.SetStyling(until_end, wx.stc.STC_STYLE_DEFAULT)
diff -r c6de1a6cb655 -r 4a08728a2ea4 editors/Viewer.py
--- a/editors/Viewer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/editors/Viewer.py Wed Oct 20 08:57:07 2021 +0200
@@ -60,11 +60,11 @@
global CURSORS
if CURSORS is None:
CURSORS = [wx.NullCursor,
- wx.StockCursor(wx.CURSOR_HAND),
- wx.StockCursor(wx.CURSOR_SIZENWSE),
- wx.StockCursor(wx.CURSOR_SIZENESW),
- wx.StockCursor(wx.CURSOR_SIZEWE),
- wx.StockCursor(wx.CURSOR_SIZENS)]
+ wx.Cursor(wx.CURSOR_HAND),
+ wx.Cursor(wx.CURSOR_SIZENWSE),
+ wx.Cursor(wx.CURSOR_SIZENESW),
+ wx.Cursor(wx.CURSOR_SIZEWE),
+ wx.Cursor(wx.CURSOR_SIZENS)]
if wx.Platform == '__WXMSW__':
@@ -410,7 +410,7 @@
if len(tree[0]) > 0:
menu = wx.Menu(title='')
self.GenerateTreeMenu(x, y, scaling, menu, "", var_class, [(values[0], values[2], tree)])
- self.ParentWindow.PopupMenuXY(menu)
+ self.ParentWindow.PopupMenu(menu)
else:
self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, values[0], values[2])
else:
@@ -712,7 +712,7 @@
break
faces["size"] -= 1
self.Editor.SetFont(font)
- self.MiniTextDC = wx.MemoryDC(wx.EmptyBitmap(1, 1))
+ self.MiniTextDC = wx.MemoryDC(wx.Bitmap(1, 1))
self.MiniTextDC.SetFont(wx.Font(faces["size"] * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName=faces["helv"]))
self.CurrentScale = None
@@ -825,15 +825,14 @@
def GetViewScale(self):
return self.ViewScale
- def GetLogicalDC(self, buffered=False):
- if buffered:
- bitmap = wx.EmptyBitmap(*self.Editor.GetClientSize())
- dc = wx.MemoryDC(bitmap)
- else:
- dc = wx.ClientDC(self.Editor)
+ def PrepareDC(self, dc):
dc.SetFont(self.GetFont())
self.Editor.DoPrepareDC(dc)
dc.SetUserScale(self.ViewScale[0], self.ViewScale[1])
+
+ def GetLogicalDC(self):
+ dc = wx.ClientDC(self.Editor)
+ self.PrepareDC(dc)
return dc
def RefreshRect(self, rect, eraseBackground=True):
@@ -1058,7 +1057,7 @@
self.SelectedElement.SetSelected(False)
self.SelectedElement = None
if self.Mode == MODE_MOTION:
- wx.CallAfter(self.Editor.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
+ wx.CallAfter(self.Editor.SetCursor, wx.Cursor(wx.CURSOR_HAND))
self.SavedMode = True
# Return current drawing mode
@@ -1116,13 +1115,13 @@
if self.DrawGrid:
width = max(2, int(scaling[0] * self.ViewScale[0]))
height = max(2, int(scaling[1] * self.ViewScale[1]))
- bitmap = wx.EmptyBitmap(width, height)
+ bitmap = wx.Bitmap(width, height)
dc = wx.MemoryDC(bitmap)
dc.SetBackground(wx.Brush(self.Editor.GetBackgroundColour()))
dc.Clear()
dc.SetPen(MiterPen(wx.Colour(180, 180, 180)))
dc.DrawPoint(0, 0)
- self.GridBrush = wx.BrushFromBitmap(bitmap)
+ self.GridBrush = wx.Brush(bitmap)
else:
self.GridBrush = wx.TRANSPARENT_BRUSH
else:
@@ -3379,7 +3378,7 @@
element = self.ParentWindow.GetCopyBuffer()
if bbx is None:
mouse_pos = self.Editor.ScreenToClient(wx.GetMousePosition())
- middle = wx.Rect(0, 0, *self.Editor.GetClientSize()).InsideXY(mouse_pos.x, mouse_pos.y)
+ middle = wx.Rect(0, 0, *self.Editor.GetClientSize()).Contains(mouse_pos.x, mouse_pos.y)
if middle:
x, y = self.CalcUnscrolledPosition(mouse_pos.x, mouse_pos.y)
else:
@@ -3633,7 +3632,6 @@
else:
dc.SetBackground(wx.Brush(self.Editor.GetBackgroundColour()))
dc.Clear()
- dc.BeginDrawing()
if self.Scaling is not None and self.DrawGrid and not printing:
dc.SetPen(wx.TRANSPARENT_PEN)
dc.SetBrush(self.GridBrush)
@@ -3680,12 +3678,15 @@
self.InstanceName.Draw(dc)
if self.rubberBand.IsShown():
self.rubberBand.Draw(dc)
- dc.EndDrawing()
def OnPaint(self, event):
- dc = self.GetLogicalDC(True)
+ event.Skip()
+ sx,sy = self.Editor.GetClientSize()
+ if sx <= 0 or sy <= 0 :
+ return
+ dc = wx.MemoryDC(wx.Bitmap(sx,sy))
+ self.PrepareDC(dc)
self.DoDrawing(dc)
wx.BufferedPaintDC(self.Editor, dc.GetAsBitmap())
if self.Debug:
DebugViewer.RefreshNewData(self)
- event.Skip()
diff -r c6de1a6cb655 -r 4a08728a2ea4 etherlab/ConfigEditor.py
--- a/etherlab/ConfigEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/etherlab/ConfigEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -16,7 +16,7 @@
import wx
import wx.grid
-import wx.gizmos
+import wx.adv
import wx.lib.buttons
from plcopen.structures import IEC_KEYWORDS, TestIdentifier
@@ -81,9 +81,9 @@
self.VariablesFilter.Bind(wx.EVT_COMBOBOX, self.OnVariablesFilterChanged)
self.VariablesFilter.Bind(wx.EVT_TEXT_ENTER, self.OnVariablesFilterChanged)
self.VariablesFilter.Bind(wx.EVT_CHAR, self.OnVariablesFilterKeyDown)
- self.AddWindow(self.VariablesFilter, flag=wx.GROW)
-
- self.VariablesGrid = wx.gizmos.TreeListCtrl(parent,
+ self.Add(self.VariablesFilter, flag=wx.GROW)
+
+ self.VariablesGrid = wx.adv.TreeListCtrl(parent,
style=wx.TR_DEFAULT_STYLE |
wx.TR_ROW_LINES |
wx.TR_COLUMN_LINES |
@@ -91,7 +91,7 @@
wx.TR_FULL_ROW_HIGHLIGHT)
self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN,
self.OnVariablesGridLeftClick)
- self.AddWindow(self.VariablesGrid, flag=wx.GROW)
+ self.Add(self.VariablesGrid, flag=wx.GROW)
self.Filters = []
for desc, value in VARIABLES_FILTERS:
@@ -274,10 +274,10 @@
variables_label = wx.StaticText(self.EthercatNodeEditor,
label=_('Variable entries:'))
- main_sizer.AddWindow(variables_label, border=10, flag=wx.TOP | wx.LEFT | wx.RIGHT)
+ main_sizer.Add(variables_label, border=10, flag=wx.TOP | wx.LEFT | wx.RIGHT)
self.NodeVariables = NodeVariablesSizer(self.EthercatNodeEditor, self.Controler)
- main_sizer.AddSizer(self.NodeVariables, border=10,
+ main_sizer.Add(self.NodeVariables, border=10,
flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.EthercatNodeEditor.SetSizer(main_sizer)
@@ -310,7 +310,7 @@
self.EtherCATManagementTreebook = EtherCATManagementTreebook(self.EtherCATManagementEditor, self.Controler, self)
- self.EtherCATManagermentEditor_Main_Sizer.AddSizer(self.EtherCATManagementTreebook, border=10, flag=wx.GROW)
+ self.EtherCATManagermentEditor_Main_Sizer.Add(self.EtherCATManagementTreebook, border=10, flag=wx.GROW)
self.EtherCATManagementEditor.SetSizer(self.EtherCATManagermentEditor_Main_Sizer)
return self.EtherCATManagementEditor
@@ -617,7 +617,7 @@
self.MasterStateEditor_Panel = MasterStatePanelClass(self.MasterStateEditor, self.Controler)
- self.MasterStateEditor_Panel_Main_Sizer.AddSizer(self.MasterStateEditor_Panel, border=10, flag=wx.GROW)
+ self.MasterStateEditor_Panel_Main_Sizer.Add(self.MasterStateEditor_Panel, border=10, flag=wx.GROW)
self.MasterStateEditor.SetSizer(self.MasterStateEditor_Panel_Main_Sizer)
return self.MasterStateEditor
@@ -651,7 +651,7 @@
process_variables_label = wx.StaticText(self.EthercatMasterEditor,
label=_("Process variables mapped between nodes:"))
- process_variables_header.AddWindow(process_variables_label, 1,
+ process_variables_header.Add(process_variables_label, 1,
flag=wx.ALIGN_CENTER_VERTICAL)
for name, bitmap, help in [
@@ -661,14 +661,14 @@
("DownVariableButton", "down", _("Move process variable down"))]:
button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- process_variables_header.AddWindow(button, border=5, flag=wx.LEFT)
+ process_variables_header.Add(button, border=5, flag=wx.LEFT)
self.ProcessVariablesGrid = CustomGrid(self.EthercatMasterEditor, style=wx.VSCROLL)
self.ProcessVariablesGrid.SetMinSize(wx.Size(0, 150))
self.ProcessVariablesGrid.SetDropTarget(ProcessVariableDropTarget(self))
- self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING,
self.OnProcessVariablesGridCellChange)
self.ProcessVariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,
self.OnProcessVariablesGridCellLeftClick)
@@ -678,7 +678,7 @@
startup_commands_label = wx.StaticText(self.EthercatMasterEditor,
label=_("Startup service variables assignments:"))
- startup_commands_header.AddWindow(startup_commands_label, 1,
+ startup_commands_header.Add(startup_commands_label, 1,
flag=wx.ALIGN_CENTER_VERTICAL)
for name, bitmap, help in [
@@ -686,14 +686,14 @@
("DeleteCommandButton", "remove_element", _("Remove startup service variable"))]:
button = wx.lib.buttons.GenBitmapButton(self.EthercatMasterEditor, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
- startup_commands_header.AddWindow(button, border=5, flag=wx.LEFT)
+ startup_commands_header.Add(button, border=5, flag=wx.LEFT)
self.StartupCommandsGrid = CustomGrid(self.EthercatMasterEditor, style=wx.VSCROLL)
self.StartupCommandsGrid.SetDropTarget(StartupCommandDropTarget(self))
self.StartupCommandsGrid.SetMinSize(wx.Size(0, 150))
- self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGING,
self.OnStartupCommandsGridCellChange)
self.StartupCommandsGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN,
self.OnStartupCommandsGridEditorShow)
@@ -702,29 +702,29 @@
main_staticbox = wx.StaticBox(self.EthercatMasterEditor, label=_("Node filter:"))
staticbox_sizer = wx.StaticBoxSizer(main_staticbox, wx.VERTICAL)
- self.EthercatMasterEditorSizer.AddSizer(staticbox_sizer, 0, border=10, flag=wx.GROW | wx.ALL)
+ self.EthercatMasterEditorSizer.Add(staticbox_sizer, 0, border=10, flag=wx.GROW | wx.ALL)
main_staticbox_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=0)
main_staticbox_sizer.AddGrowableCol(0)
main_staticbox_sizer.AddGrowableRow(2)
main_staticbox_sizer.AddGrowableRow(4)
main_staticbox_sizer.AddGrowableRow(5)
- staticbox_sizer.AddSizer(main_staticbox_sizer, 1, flag=wx.GROW)
- main_staticbox_sizer.AddWindow(self.NodesFilter, border=5, flag=wx.GROW | wx.ALL)
- main_staticbox_sizer.AddSizer(process_variables_header, border=5,
+ staticbox_sizer.Add(main_staticbox_sizer, 1, flag=wx.GROW)
+ main_staticbox_sizer.Add(self.NodesFilter, border=5, flag=wx.GROW | wx.ALL)
+ main_staticbox_sizer.Add(process_variables_header, border=5,
flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
- main_staticbox_sizer.AddWindow(self.ProcessVariablesGrid, 1,
+ main_staticbox_sizer.Add(self.ProcessVariablesGrid, 1,
border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
- main_staticbox_sizer.AddSizer(startup_commands_header,
+ main_staticbox_sizer.Add(startup_commands_header,
border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
- main_staticbox_sizer.AddWindow(self.StartupCommandsGrid, 1,
+ main_staticbox_sizer.Add(self.StartupCommandsGrid, 1,
border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
second_staticbox = wx.StaticBox(self.EthercatMasterEditor, label=_("Nodes variables filter:"))
second_staticbox_sizer = wx.StaticBoxSizer(second_staticbox, wx.VERTICAL)
- second_staticbox_sizer.AddSizer(self.NodesVariables, 1, border=5, flag=wx.GROW | wx.ALL)
-
- main_staticbox_sizer.AddSizer(second_staticbox_sizer, 1,
+ second_staticbox_sizer.Add(self.NodesVariables, 1, border=5, flag=wx.GROW | wx.ALL)
+
+ main_staticbox_sizer.Add(second_staticbox_sizer, 1,
border=5, flag=wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM)
self.EthercatMasterEditor.SetSizer(self.EthercatMasterEditorSizer)
@@ -1113,21 +1113,21 @@
ESI_files_label = wx.StaticText(parent,
label=_("ESI Files:"))
- self.AddWindow(ESI_files_label, border=10,
+ self.Add(ESI_files_label, border=10,
flag=wx.TOP | wx.LEFT | wx.RIGHT)
folder_tree_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=0)
folder_tree_sizer.AddGrowableCol(0)
folder_tree_sizer.AddGrowableRow(0)
- self.AddSizer(folder_tree_sizer, border=10,
+ self.Add(folder_tree_sizer, border=10,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
self.ESIFiles = FolderTree(parent, self.GetPath(), editable=False)
self.ESIFiles.SetFilter(".xml")
- folder_tree_sizer.AddWindow(self.ESIFiles, flag=wx.GROW)
+ folder_tree_sizer.Add(self.ESIFiles, flag=wx.GROW)
buttons_sizer = wx.BoxSizer(wx.VERTICAL)
- folder_tree_sizer.AddSizer(buttons_sizer,
+ folder_tree_sizer.Add(buttons_sizer,
flag=wx.ALIGN_CENTER_VERTICAL)
for idx, (name, bitmap, help, callback) in enumerate(buttons):
@@ -1135,7 +1135,7 @@
bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28),
style=wx.NO_BORDER)
- button.SetToolTipString(help)
+ button.SetToolTip(help)
setattr(self, name, button)
if idx > 0:
flag = wx.TOP
@@ -1145,14 +1145,14 @@
callback = getattr(self, "On" + name, None)
if callback is not None:
parent.Bind(wx.EVT_BUTTON, callback, button)
- buttons_sizer.AddWindow(button, border=10, flag=flag)
+ buttons_sizer.Add(button, border=10, flag=flag)
modules_label = wx.StaticText(parent,
label=_("Modules library:"))
- self.AddSizer(modules_label, border=10,
+ self.Add(modules_label, border=10,
flag=wx.LEFT | wx.RIGHT)
- self.ModulesGrid = wx.gizmos.TreeListCtrl(parent,
+ self.ModulesGrid = wx.adv.TreeListCtrl(parent,
style=wx.TR_DEFAULT_STYLE |
wx.TR_ROW_LINES |
wx.TR_COLUMN_LINES |
@@ -1166,7 +1166,7 @@
self.OnModulesGridEndLabelEdit)
self.ModulesGrid.GetHeaderWindow().Bind(wx.EVT_MOTION,
self.OnModulesGridHeaderMotion)
- self.AddWindow(self.ModulesGrid, border=10,
+ self.Add(self.ModulesGrid, border=10,
flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
for colname, colsize, colalign in zip(
@@ -1335,7 +1335,7 @@
if col > 0 and self.LastToolTipCol != col:
self.LastToolTipCol = col
_param, param_infos = self.ModuleLibrary.MODULES_EXTRA_PARAMS[col - 1]
- wx.CallAfter(self.ModulesGrid.GetHeaderWindow().SetToolTipString,
+ wx.CallAfter(self.ModulesGrid.GetHeaderWindow().SetToolTip,
param_infos["description"])
event.Skip()
@@ -1359,13 +1359,14 @@
("DeleteButton", "remove_element", _("Remove file from database"), None)
])
self.DatabaseSizer.SetControlMinSize(wx.Size(0, 0))
- main_sizer.AddSizer(self.DatabaseSizer, border=10,
+ main_sizer.Add(self.DatabaseSizer, border=10,
flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
button_sizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTRE)
- button_sizer.GetAffirmativeButton().SetLabel(_("Add file to project"))
- button_sizer.GetCancelButton().SetLabel(_("Close"))
- main_sizer.AddSizer(button_sizer, border=10,
+ # FIXME: find a way to change buttons label compatible with wxPython 4.x
+ # button_sizer.GetAffirmativeButton().SetLabel(_("Add file to project"))
+ # button_sizer.GetCancelButton().SetLabel(_("Close"))
+ main_sizer.Add(button_sizer, border=10,
flag=wx.ALIGN_RIGHT | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.SetSizer(main_sizer)
diff -r c6de1a6cb655 -r 4a08728a2ea4 etherlab/EtherCATManagementEditor.py
--- a/etherlab/EtherCATManagementEditor.py Tue Oct 19 15:15:03 2021 +0200
+++ b/etherlab/EtherCATManagementEditor.py Wed Oct 20 08:57:07 2021 +0200
@@ -15,7 +15,7 @@
import wx
import wx.grid
-import wx.gizmos
+import wx.adv
import wx.lib.buttons
# --------------------------------------------------------------------
@@ -135,7 +135,7 @@
self.SizerDic["SlaveInfosDetailsInnerSizer"].AddMany([self.StaticTextDic[statictext_name],
self.TextCtrlDic[textctrl_name]])
- self.SizerDic["SlaveInfosDetailsBox"].AddSizer(self.SizerDic["SlaveInfosDetailsInnerSizer"])
+ self.SizerDic["SlaveInfosDetailsBox"].Add(self.SizerDic["SlaveInfosDetailsInnerSizer"])
self.SyncManagersGrid = CustomGrid(self, size=wx.Size(605, 155), style=wx.VSCROLL)
@@ -153,7 +153,7 @@
for button_name, button_id, button_label, button_tooltipstring, event_method, sub_item in buttons:
self.ButtonDic[button_name] = wx.Button(self, id=button_id, label=_(button_label))
self.ButtonDic[button_name].Bind(wx.EVT_BUTTON, event_method)
- self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
+ self.ButtonDic[button_name].SetToolTip(button_tooltipstring)
self.SizerDic["SlaveState_up_sizer"].Add(self.ButtonDic[button_name])
for statictext_name, statictext_label, textctrl_name in sub_item:
self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label))
@@ -166,7 +166,7 @@
("StopTimerButton", "Stop State Monitoring", "Slave State Update Stop", self.CurrentStateThreadStop)]:
self.ButtonDic[button_name] = wx.Button(self, label=_(button_label))
self.ButtonDic[button_name].Bind(wx.EVT_BUTTON, event_method)
- self.ButtonDic[button_name].SetToolTipString(button_tooltipstring)
+ self.ButtonDic[button_name].SetToolTip(button_tooltipstring)
self.SizerDic["SlaveState_down_sizer"].Add(self.ButtonDic[button_name])
self.SizerDic["SlaveState_sizer"].AddMany([self.SizerDic["SlaveState_up_sizer"],
@@ -1729,7 +1729,7 @@
wx.Panel.__init__(self, parent, -1, size=(350, 500))
- self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=(350, 500),
+ self.Tree = wx.adv.TreeListCtrl(self, -1, size=(350, 500),
style=(wx.TR_DEFAULT_STYLE |
wx.TR_FULL_ROW_HIGHLIGHT |
wx.TR_HIDE_ROOT |
@@ -2692,7 +2692,7 @@
self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]])
- self.MasterStateSizer['masterState'].AddSizer(self.MasterStateSizer['innerMasterState'])
+ self.MasterStateSizer['masterState'].Add(self.MasterStateSizer['innerMasterState'])
# ----------------------- Ethernet Network Card Information ---------------------------------------
for key, label in [
@@ -2705,7 +2705,7 @@
self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
self.MasterStateSizer['innerDeviceInfo'].AddMany([self.StaticText[key], self.TextCtrl[key]])
- self.MasterStateSizer['deviceInfo'].AddSizer(self.MasterStateSizer['innerDeviceInfo'])
+ self.MasterStateSizer['deviceInfo'].Add(self.MasterStateSizer['innerDeviceInfo'])
# ----------------------- Network Frame Information -----------------------------------------------
for key, label in [
@@ -2722,13 +2722,13 @@
self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY)
self.MasterStateSizer['innerFrameInfo'].Add(self.TextCtrl[key][index])
- self.MasterStateSizer['frameInfo'].AddSizer(self.MasterStateSizer['innerFrameInfo'])
+ self.MasterStateSizer['frameInfo'].Add(self.MasterStateSizer['innerFrameInfo'])
# ------------------------------- Slave Information -----------------------------------------------
self.SITreeListCtrl = SITreeListCtrl(self, self.Controler)
self.MasterStateSizer["innerSlaveInfo"].AddMany([self.SIUpdateButton,
self.SITreeListCtrl])
- self.MasterStateSizer["slaveInfo"].AddSizer(
+ self.MasterStateSizer["slaveInfo"].Add(
self.MasterStateSizer["innerSlaveInfo"])
# --------------------------------- Main Sizer ----------------------------------------------------
@@ -2743,7 +2743,7 @@
("main", [
"innerTop", "innerMiddle", "innerBottom"])]:
for key2 in sub:
- self.MasterStateSizer[key].AddSizer(self.MasterStateSizer[key2])
+ self.MasterStateSizer[key].Add(self.MasterStateSizer[key2])
self.SetSizer(self.MasterStateSizer["main"])
@@ -2798,7 +2798,7 @@
self.Controler=controler
- self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=wx.Size(750,350),
+ self.Tree = wx.adv.TreeListCtrl(self, -1, size=wx.Size(750,350),
style=wx.TR_HAS_BUTTONS
|wx.TR_HIDE_ROOT
|wx.TR_ROW_LINES
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/first_steps/beremiz.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/first_steps/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/first_steps/plc.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/first_steps/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,1160 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AVCnt
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt1
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt2
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt3
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt4
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+
+
+
+
+ OUT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ResetCounterValue
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Out
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cnt
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ResetCounterValue
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/beremiz.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/c_code@c_ext/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/c_code@c_ext/baseconfnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/c_code@c_ext/cfile.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/c_code@c_ext/cfile.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/c_code@c_ext/confnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/c_code@c_ext/confnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/plc.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,1644 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ '666'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pytest_var2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'sys.stdout.write("FBID :"+str(FBID)+"\n")'
+
+
+
+
+
+
+ 'PLCBinary.Simple_C_Call(5678)'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'MyPythonFunc(42)'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pytest_var1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mux1_sel
+
+
+
+
+
+
+
+
+
+
+ pytest_var3
+
+
+
+
+
+
+
+
+
+
+ FromC
+
+
+
+
+
+
+ 23
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TestInput
+
+
+
+
+
+
+
+
+
+
+ TestOutput
+
+
+
+
+
+
+
+
+
+
+ FromInput
+
+
+
+
+
+
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_BCD_RESULT
+
+
+
+
+
+
+ Test_BCD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_DT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_Date
+
+
+
+
+
+
+
+
+
+
+ Test_String
+
+
+
+
+
+
+
+
+
+
+ Test_Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'True'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Global_RS.Q1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ BOOL#TRUE
+
+
+
+
+
+
+
+
+
+
+ Global_RS.S
+
+
+
+
+
+
+
+
+
+
+ Global_RS.R1
+
+
+
+
+
+
+ Global_RS.Q1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ BOOL#FALSE
+
+
+
+
+
+
+
+
+
+
+ Test_TOD_STRING
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_TOD
+
+
+
+
+
+
+ 42
+
+
+
+
+
+
+
+
+
+
+ TOTO
+
+
+
+
+
+
+
+
+
+
+
+
+ TUTU
+
+
+
+
+
+
+ Second_Python_Var
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ fefvsd
+
+
+
+
+
+
+
+
+
+
+ fefvsd
+
+
+
+
+
+
+
+
+
+
+
+
+ mux2_sel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_BCD_WRONG
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_BCD_WRONG_RESULT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_BCD_CONVERTED
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Grumpf
+
+
+
+
+
+
+ BOOL#TRUE
+
+
+
+
+
+
+ Test_DT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test_Python_Var
+
+
+
+
+
+
+ 23
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SomeVarName
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/py_ext_0@py_ext/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/py_ext_0@py_ext/baseconfnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/py_ext_0@py_ext/pyfile.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/py_ext_0@py_ext/pyfile.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/python@py_ext/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/python@py_ext/baseconfnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/python/python@py_ext/pyfile.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/python/python@py_ext/pyfile.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/svghmi_traffic_light/beremiz.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/svghmi_traffic_light/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/svghmi_traffic_light/plc.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/svghmi_traffic_light/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,1428 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ORANGE_LIGHT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ T#500ms
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ORANGE_LIGHT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ORANGE_LIGHT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ORANGE_LIGHT
+
+
+
+
+
+
+ T#500ms
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SWITCH_BUTTON
+
+
+
+
+
+
+
+
+
+
+ STOP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PEDESTRIAN_BUTTON
+
+
+
+
+
+
+ T#2s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WARN_CARS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SWITCH_BUTTON
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SwitchButton
+
+
+
+
+
+
+ PedestrianButton
+
+
+
+
+
+
+
+
+
+
+ RedLight
+
+
+
+
+
+
+
+
+
+
+ OrangeLight
+
+
+
+
+
+
+
+
+
+
+ GreenLight
+
+
+
+
+
+
+
+
+
+
+ PedestrianRedLight
+
+
+
+
+
+
+
+
+
+
+ PedestrianGreenLight
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/svghmi_traffic_light/svghmi_0@svghmi/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/svghmi_traffic_light/svghmi_0@svghmi/baseconfnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/svghmi_traffic_light/svghmi_0@svghmi/confnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/svghmi_traffic_light/svghmi_0@svghmi/confnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 exemples/svghmi_traffic_light/svghmi_0@svghmi/svghmi.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/svghmi_traffic_light/svghmi_0@svghmi/svghmi.svg Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,1541 @@
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 features.py
--- a/features.py Tue Oct 19 15:15:03 2021 +0200
+++ b/features.py Wed Oct 20 08:57:07 2021 +0200
@@ -12,10 +12,10 @@
('Native', 'NativeLib.NativeLibrary', True),
('Python', 'py_ext.PythonLibrary', True),
('Etherlab', 'etherlab.EthercatMaster.EtherlabLibrary', False),
- ('SVGUI', 'svgui.SVGUILibrary', False),
('SVGHMI', 'svghmi.SVGHMILibrary', False)]
catalog = [
+ ('opcua', _('OPC-UA client'), _('Map OPC-UA server as located variables'), 'opc_ua.OPCUAClient'),
('canfestival', _('CANopen support'), _('Map located variables over CANopen'), 'canfestival.canfestival.RootClass'),
('bacnet', _('Bacnet support'), _('Map located variables over Bacnet'), 'bacnet.bacnet.RootClass'),
('etherlab', _('EtherCAT master'), _('Map located variables over EtherCAT'), 'etherlab.etherlab.RootClass'),
@@ -23,7 +23,6 @@
('c_ext', _('C extension'), _('Add C code accessing located variables synchronously'), 'c_ext.CFile'),
('py_ext', _('Python file'), _('Add Python code executed asynchronously'), 'py_ext.PythonFile'),
('wxglade_hmi', _('WxGlade GUI'), _('Add a simple WxGlade based GUI.'), 'wxglade_hmi.WxGladeHMI'),
- ('svgui', _('SVGUI'), _('Experimental web based HMI'), 'svgui.SVGUI'),
('svghmi', _('SVGHMI'), _('SVG based HMI'), 'svghmi.SVGHMI')]
file_editors = []
diff -r c6de1a6cb655 -r 4a08728a2ea4 graphics/FBD_Objects.py
--- a/graphics/FBD_Objects.py Tue Oct 19 15:15:03 2021 +0200
+++ b/graphics/FBD_Objects.py Wed Oct 20 08:57:07 2021 +0200
@@ -122,10 +122,10 @@
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
if self.Name != "":
- test_text = self.GetTextBoundingBox().InsideXY(pt.x, pt.y)
+ test_text = self.GetTextBoundingBox().Contains(pt.x, pt.y)
else:
test_text = False
- test_block = self.GetBlockBoundingBox(connectors).InsideXY(pt.x, pt.y)
+ test_block = self.GetBlockBoundingBox(connectors).Contains(pt.x, pt.y)
return test_text or test_block
# Returns the bounding box of the name outside the block
@@ -392,7 +392,7 @@
# pos = event.GetLogicalPosition(dc)
# for input in self.Inputs:
# rect = input.GetRedrawRect()
-# if rect.InsideXY(pos.x, pos.y):
+# if rect.Contains(pos.x, pos.y):
# print "Find input"
# tip = wx.TipWindow(self.Parent, "Test")
# tip.SetBoundingRect(rect)
diff -r c6de1a6cb655 -r 4a08728a2ea4 graphics/GraphicCommons.py
--- a/graphics/GraphicCommons.py Tue Oct 19 15:15:03 2021 +0200
+++ b/graphics/GraphicCommons.py Wed Oct 20 08:57:07 2021 +0200
@@ -388,11 +388,11 @@
rect = self.BoundingBox
else:
rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1])
- return rect.InsideXY(pt.x, pt.y)
+ return rect.Contains(pt.x, pt.y)
# Returns if the point given is in the bounding box
def IsInSelection(self, rect):
- return rect.InsideXY(self.BoundingBox.x, self.BoundingBox.y) and rect.InsideXY(self.BoundingBox.x + self.BoundingBox.width, self.BoundingBox.y + self.BoundingBox.height)
+ return rect.Contains(self.BoundingBox.x, self.BoundingBox.y) and rect.Contains(self.BoundingBox.x + self.BoundingBox.width, self.BoundingBox.y + self.BoundingBox.height)
# Override this method for refreshing the bounding box
def RefreshBoundingBox(self):
@@ -448,7 +448,7 @@
intern_rect = wx.Rect(left + HANDLE_SIZE, top + HANDLE_SIZE, right - left - HANDLE_SIZE, bottom - top - HANDLE_SIZE)
# Verify that this element is selected
- if self.Selected and extern_rect.InsideXY(pt.x, pt.y) and not intern_rect.InsideXY(pt.x, pt.y):
+ if self.Selected and extern_rect.Contains(pt.x, pt.y) and not intern_rect.Contains(pt.x, pt.y):
# Find if point is on a handle horizontally
if left <= pt.x < left + HANDLE_SIZE:
handle_x = 1
@@ -1401,7 +1401,7 @@
width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE
height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
rect = wx.Rect(x, y, width, height)
- inside = rect.InsideXY(pt.x, pt.y)
+ inside = rect.Contains(pt.x, pt.y)
return inside
@@ -1933,7 +1933,7 @@
# Calculate a rectangle around the segment
rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
- test |= rect.InsideXY(pt.x, pt.y)
+ test |= rect.Contains(pt.x, pt.y)
return test
# Returns the wire start or end point if the point given is on one of them
@@ -1941,13 +1941,13 @@
# Test the wire start point
rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE,
2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
- if rect.InsideXY(pt.x, pt.y):
+ if rect.Contains(pt.x, pt.y):
return 0
# Test the wire end point
if len(self.Points) > 1:
rect = wx.Rect(self.Points[-1].x - ANCHOR_DISTANCE, self.Points[-1].y - ANCHOR_DISTANCE,
2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
- if rect.InsideXY(pt.x, pt.y):
+ if rect.Contains(pt.x, pt.y):
return -1
return None
@@ -1961,7 +1961,7 @@
# Calculate a rectangle around the segment
rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
- if rect.InsideXY(pt.x, pt.y):
+ if rect.Contains(pt.x, pt.y):
return i, self.Segments[i]
return None
diff -r c6de1a6cb655 -r 4a08728a2ea4 graphics/RubberBand.py
--- a/graphics/RubberBand.py Tue Oct 19 15:15:03 2021 +0200
+++ b/graphics/RubberBand.py Wed Oct 20 08:57:07 2021 +0200
@@ -94,7 +94,7 @@
# Change viewer mouse cursor to reflect a rubberband bounding box is
# edited
- self.DrawingSurface.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
+ self.DrawingSurface.SetCursor(wx.Cursor(wx.CURSOR_CROSS))
self.Redraw()
@@ -195,3 +195,25 @@
"""
# Erase last bbox and draw current bbox
self.DrawBoundingBoxes([self.CurrentBBox], dc)
+
+
+def PatchRubberBandForGTK3():
+ """
+ GTK3 implementation of DC doesn't support SetLogicalFuntion(XOR)
+ Then Rubberband can't be erased by just redrawing it on the same place
+ So this is a complete refresh instead, eating a lot of CPU.
+ """
+ def Redraw(self, dc=None):
+ self.Viewer.Refresh()
+ self.Draw()
+
+ RubberBand.Redraw = Redraw
+
+ def Erase(self, dc=None):
+ self.Viewer.Refresh()
+
+ RubberBand.Erase = Erase
+
+
+if "gtk3" in wx.PlatformInfo:
+ PatchRubberBandForGTK3()
diff -r c6de1a6cb655 -r 4a08728a2ea4 graphics/SFC_Objects.py
--- a/graphics/SFC_Objects.py Tue Oct 19 15:15:03 2021 +0200
+++ b/graphics/SFC_Objects.py Wed Oct 20 08:57:07 2021 +0200
@@ -719,7 +719,7 @@
self.Pos.y + (self.Size[1] - text_height) // 2,
text_width,
text_height)
- test_text = text_bbx.InsideXY(pt.x, pt.y)
+ test_text = text_bbx.Contains(pt.x, pt.y)
else:
test_text = False
return test_text or Graphic_Element.HitTest(self, pt, connectors)
@@ -1204,7 +1204,7 @@
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
- return self.BoundingBox.InsideXY(pt.x, pt.y) or self.TestConnector(pt, exclude=False) is not None
+ return self.BoundingBox.Contains(pt.x, pt.y) or self.TestConnector(pt, exclude=False) is not None
# Refresh the divergence bounding box
def RefreshBoundingBox(self):
@@ -1592,7 +1592,7 @@
self.Pos.y + (self.Size[1] - text_height) // 2,
text_width,
text_height)
- return text_bbx.InsideXY(pt.x, pt.y) or Graphic_Element.HitTest(self, pt, connectors)
+ return text_bbx.Contains(pt.x, pt.y) or Graphic_Element.HitTest(self, pt, connectors)
# Refresh the jump bounding box
def RefreshBoundingBox(self):
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_bn_BD.po
--- a/i18n/Beremiz_bn_BD.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_bn_BD.po Wed Oct 20 08:57:07 2021 +0200
@@ -972,10 +972,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1300,10 +1296,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2084,10 +2076,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2154,10 +2142,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2706,11 +2690,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2804,10 +2783,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3400,14 +3375,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4202,12 +4169,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_de_DE.po
--- a/i18n/Beremiz_de_DE.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_de_DE.po Wed Oct 20 08:57:07 2021 +0200
@@ -980,10 +980,6 @@
msgid "Character string"
msgstr "Zeichenkette"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Wählen Sie eine SVG-Datei"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1318,10 +1314,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Konnte SPS nicht anhalten !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "HMI erstellen"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Neuer Baustein"
@@ -2109,10 +2101,6 @@
msgid "Import ESI file"
msgstr "Importiere ESI Datei"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Importiere SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "Importiere Datei zu ESI Datenbank"
@@ -2181,10 +2169,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Inline"
@@ -2741,11 +2725,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Kein SVG-File namens: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2840,10 +2819,6 @@
msgid "Open"
msgstr "Öffnen"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "öffne Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3448,14 +3423,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST Dateien (*.st)|*.st|Alle Dateien|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG Dateien (*.svg)|*.svg|Alle Dateien|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4277,14 +4244,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Sie haben keine Schreibberechtigung.\n"
-"soll Inkscape trotzdem geöffnet werden ?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_es_ES.po
--- a/i18n/Beremiz_es_ES.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_es_ES.po Wed Oct 20 08:57:07 2021 +0200
@@ -986,10 +986,6 @@
msgid "Character string"
msgstr "Cadena de caracteres"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Elegir un archivo SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1324,10 +1320,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "¡No se pudo detener el PLC!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Crear un HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Crear un nuevo POU"
@@ -2116,10 +2108,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Importar SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2188,10 +2176,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "InkScape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "En línea"
@@ -2754,11 +2738,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "No existe el archivo SVG: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2854,10 +2833,6 @@
msgid "Open"
msgstr "Abrir"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Abrir Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3464,14 +3439,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "Archivos ST (*.st)|*.st|Todos los archivos|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "Archivos SVG (*.svg)|*.svg|Todos los archivos|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4290,14 +4257,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"No tiene permisos de escritura.\n"
-"¿Desea abrir Inkscape de todos modos?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_eu.po
--- a/i18n/Beremiz_eu.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_eu.po Wed Oct 20 08:57:07 2021 +0200
@@ -960,10 +960,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1288,10 +1284,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2072,10 +2064,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2142,10 +2130,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2694,11 +2678,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2792,10 +2771,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3388,14 +3363,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4190,12 +4157,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_fr_FR.po
--- a/i18n/Beremiz_fr_FR.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_fr_FR.po Wed Oct 20 08:57:07 2021 +0200
@@ -987,10 +987,6 @@
msgid "Character string"
msgstr "Chaîne de caractères"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Choisissez un fichier SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1324,10 +1320,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Impossible d'arrêter l'automate !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Créer une IHM"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Créer un nouveau POU"
@@ -2117,10 +2109,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Importer un SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2189,10 +2177,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Inline"
@@ -2752,11 +2736,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Fichier SVG inconnu : %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2851,10 +2830,6 @@
msgid "Open"
msgstr "Ouvrir"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Ouverture de Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3461,14 +3436,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "Fichiers ST (*.st)|*.st|Tous les fichiers|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "Fichiers SVG (*.svg)|*.svg|Tous les fichiers|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4286,14 +4253,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Vous n'avez pas les permissions d'écriture.\n"
-"Ouvrir Inkscape tout de même ?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_hr.po
--- a/i18n/Beremiz_hr.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_hr.po Wed Oct 20 08:57:07 2021 +0200
@@ -956,10 +956,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1284,10 +1280,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2068,10 +2060,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2138,10 +2126,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2690,11 +2674,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2788,10 +2767,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3384,14 +3359,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4186,12 +4153,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_hu_HU.po
--- a/i18n/Beremiz_hu_HU.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_hu_HU.po Wed Oct 20 08:57:07 2021 +0200
@@ -977,10 +977,6 @@
msgid "Character string"
msgstr "Karakter sztring"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Válasszon SVG fájlt"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1305,10 +1301,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "PLC nem állt le!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "HMI létrehozása"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Új Program Szervezési Egység (POU) létrehozása"
@@ -2095,10 +2087,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "SVG importálás"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2165,10 +2153,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Inline"
@@ -2721,11 +2705,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Nincs ilyen SVG fájl: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2819,10 +2798,6 @@
msgid "Open"
msgstr "Megnyit"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Inkscape Megnyitás"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3425,14 +3400,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4236,12 +4203,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_it_IT.po
--- a/i18n/Beremiz_it_IT.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_it_IT.po Wed Oct 20 08:57:07 2021 +0200
@@ -966,10 +966,6 @@
msgid "Character string"
msgstr "Stringa di caratteri"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Scegliere un file SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1300,10 +1296,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Impossibile arrestare il PLC !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Creare HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Creare un nuovo POU"
@@ -2088,10 +2080,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2158,10 +2146,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2710,11 +2694,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2808,10 +2787,6 @@
msgid "Open"
msgstr "Apri"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Apri Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3404,14 +3379,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST files (*.st)|*.st|All files|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG files (*.svg)|*.svg|All files|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4209,14 +4176,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Non il permesso di scrittura.\n"
-"Aprire Inkscape comunque?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_ko_KR.po
--- a/i18n/Beremiz_ko_KR.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_ko_KR.po Wed Oct 20 08:57:07 2021 +0200
@@ -977,10 +977,6 @@
msgid "Character string"
msgstr "문자열"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "SVG 파일 선택"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1313,10 +1309,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "PLC 를 정지 할 수 없습니다!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "HMI 생성"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "새로운 POU 생성"
@@ -2099,10 +2091,6 @@
msgid "Import ESI file"
msgstr "ESI 파일 불러오기"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "SVG 가져오기"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "파일을 ESI 파일 데이터베이스로 불러오기"
@@ -2169,10 +2157,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr "네트워크 위치 변수의 드래그 앤 드랍 초기화"
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "인라인"
@@ -2729,11 +2713,6 @@
msgid "No slave defined at position %d!"
msgstr "위치 %d에 정의된 슬레이브가 없습니다!"
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "선택하신 %s SVG 파일은 없습니다\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2827,10 +2806,6 @@
msgid "Open"
msgstr "프로젝트 불러오기"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "잉크스케이프 열기"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3432,14 +3407,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST 파일 (*.st)|*.st|모든 파일|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG 파일 (*.svg)|*svg|모든 파일|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4247,14 +4214,6 @@
msgid "You cannot SDO download this state"
msgstr "현재 상태에서는 SDO 다운로드를 할 수 없습니다."
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"현재 쓰기 권한이 없습니다\n"
-"그래도 Inkscape를 열까요?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_nl_NL.po
--- a/i18n/Beremiz_nl_NL.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_nl_NL.po Wed Oct 20 08:57:07 2021 +0200
@@ -967,10 +967,6 @@
msgid "Character string"
msgstr "Karakterstreng"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Kies een SVG-bestand"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1303,10 +1299,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Kan PLC niet stoppen!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Maak HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Maak een nieuwe POU"
@@ -2095,10 +2087,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2165,10 +2153,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2717,11 +2701,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2815,10 +2794,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3411,14 +3386,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4213,12 +4180,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_pl.po
--- a/i18n/Beremiz_pl.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_pl.po Wed Oct 20 08:57:07 2021 +0200
@@ -974,10 +974,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1302,10 +1298,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2086,10 +2078,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2156,10 +2144,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2708,11 +2692,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2806,10 +2785,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3402,14 +3377,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4204,12 +4171,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_pt.po
--- a/i18n/Beremiz_pt.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_pt.po Wed Oct 20 08:57:07 2021 +0200
@@ -969,10 +969,6 @@
msgid "Character string"
msgstr "Cadeia de caracteres"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Escolha um ficheiro SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1304,10 +1300,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Não foi possível parar o PLC!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Criar HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Criar uma nova POU"
@@ -2090,10 +2082,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2160,10 +2148,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2712,11 +2696,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2810,10 +2789,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3406,14 +3381,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4208,12 +4175,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_pt_BR.po
--- a/i18n/Beremiz_pt_BR.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_pt_BR.po Wed Oct 20 08:57:07 2021 +0200
@@ -977,10 +977,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Escolha um arquivo SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1308,10 +1304,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Não foi possível parar o CLP!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Criar IHM"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Criar um novo POU"
@@ -2096,10 +2088,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Importar SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2166,10 +2154,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2730,11 +2714,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Nenhum arquivo SVG: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2828,10 +2807,6 @@
msgid "Open"
msgstr "Abrir"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Abrir Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3434,14 +3409,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4248,14 +4215,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Você não possui permissão de escrita.\n"
-"Abrir mesmo assim?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_ro_RO.po
--- a/i18n/Beremiz_ro_RO.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_ro_RO.po Wed Oct 20 08:57:07 2021 +0200
@@ -960,10 +960,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1288,10 +1284,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2072,10 +2064,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2142,10 +2130,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2694,11 +2678,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2792,10 +2771,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3388,14 +3363,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4190,12 +4157,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_ru_RU.po
--- a/i18n/Beremiz_ru_RU.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_ru_RU.po Wed Oct 20 08:57:07 2021 +0200
@@ -981,10 +981,6 @@
msgid "Character string"
msgstr "Строковые операции"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Выберите SVG-файл"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1318,10 +1314,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Невозможно остановить ПЛК!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Создать HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Создать новый POU"
@@ -2118,10 +2110,6 @@
msgid "Import ESI file"
msgstr "Импортировать файл ESI"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Импорт SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "Импортировать файл в базу данных файлов ESI"
@@ -2191,10 +2179,6 @@
msgstr ""
"Инициировать перетаскивание отображаемой переменной сетевого положения"
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Непосредственно"
@@ -2756,11 +2740,6 @@
msgid "No slave defined at position %d!"
msgstr "Для позиции %d не определено ведомое устройство!"
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Нет такого SVG файла: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2855,10 +2834,6 @@
msgid "Open"
msgstr "Открыть"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Открыть Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3464,14 +3439,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST файлы (*.st)|*.st|Все файлы|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG файлы (*.svg)|*.svg|Все файлы|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4293,14 +4260,6 @@
msgid "You cannot SDO download this state"
msgstr "Вы не можете загрузить это состояние через SDO"
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"У вас недостаточно прав для записи.\n"
-"Открыть Inkscape все равно?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_sl_SI.po
--- a/i18n/Beremiz_sl_SI.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_sl_SI.po Wed Oct 20 08:57:07 2021 +0200
@@ -978,10 +978,6 @@
msgid "Character string"
msgstr "Niz znakov"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Izberi SVG datoteko"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1312,10 +1308,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Ne morem ustaviti krmilnika !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Kreiraj HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Ustvari nov POU"
@@ -2101,10 +2093,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Uvoz SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2171,10 +2159,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Vstavljen"
@@ -2735,11 +2719,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Ni take SVG datoteke: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2836,10 +2815,6 @@
msgid "Open"
msgstr "Odpri"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Odpri Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3441,14 +3416,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST datoteke (*.st)|*.st|Vse datoteke|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG datoteke (*.svg)|*.svg|Vse datoteke|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4259,14 +4226,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Nimaš dovoljenja za pisanje.\n"
-"Vseeno odprem Inkscape ?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_tr_TR.po
--- a/i18n/Beremiz_tr_TR.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_tr_TR.po Wed Oct 20 08:57:07 2021 +0200
@@ -980,10 +980,6 @@
msgid "Character string"
msgstr "Karakter dizesi"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "SVG dosyası seç"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1316,10 +1312,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "PLC durduramadı!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "HMI oluştur"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Yeni bir POU oluştur"
@@ -2114,10 +2106,6 @@
msgid "Import ESI file"
msgstr "ESI dosyasını içe aktar"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "SVG'yi içe aktar"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "ESI dosya veritabanına dosya içe aktar"
@@ -2185,10 +2173,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr "Ağ konumu bulunan değişkenin Drag'n düşüşünü başlat"
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Çizgide"
@@ -2750,11 +2734,6 @@
msgid "No slave defined at position %d!"
msgstr "%d konumunda hiçbir slave tanımlanmamış!"
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Böyle bir SVG dosyası yok: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2850,10 +2829,6 @@
msgid "Open"
msgstr "Açık"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Inkscape'i aç"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3457,14 +3432,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST dosyaları (* .st) | * .st | Tüm dosyalar | *. *"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG dosyaları (* .svg) | * .svg | Tüm dosyalar | *. *"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4280,14 +4247,6 @@
msgid "You cannot SDO download this state"
msgstr "SDO bu durumu indiremezsiniz"
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Yazma yetkiniz yok.\n"
-"Yine de Inkscape'i açtın mı?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_vi_VN.po
--- a/i18n/Beremiz_vi_VN.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_vi_VN.po Wed Oct 20 08:57:07 2021 +0200
@@ -974,10 +974,6 @@
msgid "Character string"
msgstr "Chuỗi kí tự"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Chọn một tệp SVG"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1306,10 +1302,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Không thể dừng PLC !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Tạo HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Tạo một đơn vị tổ chức chương trình mới"
@@ -2092,10 +2084,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2163,10 +2151,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2721,11 +2705,6 @@
msgid "No slave defined at position %d!"
msgstr "Chưa khai báo trạm tớ tại địa chỉ %d!"
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "Không có tệp SVG: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2819,10 +2798,6 @@
msgid "Open"
msgstr "Mở"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Mở Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3424,14 +3399,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST tệp (*.st)|*.st|Tất cả tệp|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "Tệp SVG (*.svg)|*.svg|Tất cả tệp|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4240,14 +4207,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"Bạn không có quyền ghi.\n"
-"Vẫn mở Inkscape ?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/Beremiz_zh_CN.po
--- a/i18n/Beremiz_zh_CN.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/Beremiz_zh_CN.po Wed Oct 20 08:57:07 2021 +0200
@@ -980,10 +980,6 @@
msgid "Character string"
msgstr "字符串"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "选择一个SVG文件"
-
#: ../etherlab/EtherCATManagementEditor.py:911
#: ../etherlab/EtherCATManagementEditor.py:1306
msgid "Choose a binary file"
@@ -1316,10 +1312,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "无法停止PLC!\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "新建 HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "新建一个POU"
@@ -2102,10 +2094,6 @@
msgid "Import ESI file"
msgstr "导入ESI文件"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "导入 SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "导入文件到ESI文件数据库"
@@ -2172,10 +2160,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "在线"
@@ -2730,11 +2714,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "没有这样的SVG文件:%s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2828,10 +2807,6 @@
msgid "Open"
msgstr "打开"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "打开 Inkscape"
-
#: ../version.py:88
msgid ""
"Open Source framework for automation, implemented IEC 61131 IDE with "
@@ -3431,14 +3406,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST 文件 (*.st)|*.st|所有文件|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG 文件 (*.svg)|*.svg|All files|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:247 ../BeremizIDE.py:278 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4247,14 +4214,6 @@
msgid "You cannot SDO download this state"
msgstr "你不能SDO下载这个状态"
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"你没有写入的许可。\n"
-"无论如何都打开Inkscape?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/app.fil
--- a/i18n/app.fil Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/app.fil Wed Oct 20 08:57:07 2021 +0200
@@ -129,9 +129,6 @@
../util/misc.py
../util/ProcessLogger.py
../features.py
-../svgui/svgui.py
-../svgui/svgui_server.py
-../svgui/svguilib.py
../plcopen/InstancesPathCollector.py
../plcopen/types_enums.py
../plcopen/InstanceTagnameCollector.py
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/messages.po
--- a/i18n/messages.po Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/messages.po Wed Oct 20 08:57:07 2021 +0200
@@ -967,10 +967,6 @@
msgid "Character string"
msgstr "Character string"
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr "Choose a SVG file"
-
#: ../etherlab/EtherCATManagementEditor.py:912
#: ../etherlab/EtherCATManagementEditor.py:1307
msgid "Choose a binary file"
@@ -1303,10 +1299,6 @@
msgid "Couldn't stop PLC !\n"
msgstr "Couldn't stop PLC !\n"
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr "Create HMI"
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr "Create a new POU"
@@ -2079,10 +2071,6 @@
msgid "Import ESI file"
msgstr "Import ESI file"
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr "Import SVG"
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr "Import file to ESI files database"
@@ -2149,10 +2137,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr "Initiate Drag'n drop of Network position located variable"
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr "Inkscape"
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr "Inline"
@@ -2705,11 +2689,6 @@
msgid "No slave defined at position %d!"
msgstr "No slave defined at position %d!"
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr "No such SVG file: %s\n"
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2807,10 +2786,6 @@
msgid "Open"
msgstr "Open"
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr "Open Inkscape"
-
#: ../version.py:88
msgid "Open Source framework for automation, implemented IEC 61131 IDE with constantly growing set of extensions and flexible PLC runtime."
msgstr "Open Source framework for automation, implemented IEC 61131 IDE with constantly growing set of extensions and flexible PLC runtime."
@@ -3407,14 +3382,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr "ST files (*.st)|*.st|All files|*.*"
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr "SVG files (*.svg)|*.svg|All files|*.*"
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr "SVGUI"
-
#: ../BeremizIDE.py:246 ../BeremizIDE.py:277 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4215,14 +4182,6 @@
msgid "You cannot SDO download this state"
msgstr "You cannot SDO download this state"
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 i18n/messages.pot
--- a/i18n/messages.pot Tue Oct 19 15:15:03 2021 +0200
+++ b/i18n/messages.pot Wed Oct 20 08:57:07 2021 +0200
@@ -952,10 +952,6 @@
msgid "Character string"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "Choose a SVG file"
-msgstr ""
-
#: ../etherlab/EtherCATManagementEditor.py:912
#: ../etherlab/EtherCATManagementEditor.py:1307
msgid "Choose a binary file"
@@ -1280,10 +1276,6 @@
msgid "Couldn't stop PLC !\n"
msgstr ""
-#: ../svgui/svgui.py:57
-msgid "Create HMI"
-msgstr ""
-
#: ../dialogs/PouDialog.py:48
msgid "Create a new POU"
msgstr ""
@@ -2054,10 +2046,6 @@
msgid "Import ESI file"
msgstr ""
-#: ../svgui/svgui.py:50 ../svgui/svgui.py:51
-msgid "Import SVG"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1352
msgid "Import file to ESI files database"
msgstr ""
@@ -2124,10 +2112,6 @@
msgid "Initiate Drag'n drop of Network position located variable"
msgstr ""
-#: ../svgui/svgui.py:56
-msgid "Inkscape"
-msgstr ""
-
#: ../dialogs/SFCTransitionDialog.py:77 ../dialogs/ActionBlockDialog.py:47
msgid "Inline"
msgstr ""
@@ -2672,11 +2656,6 @@
msgid "No slave defined at position %d!"
msgstr ""
-#: ../svgui/svgui.py:142
-#, python-format
-msgid "No such SVG file: %s\n"
-msgstr ""
-
#: ../etherlab/ConfigEditor.py:1245
#, python-format
msgid "No such XML file: %s\n"
@@ -2774,10 +2753,6 @@
msgid "Open"
msgstr ""
-#: ../svgui/svgui.py:151
-msgid "Open Inkscape"
-msgstr ""
-
#: ../version.py:88
msgid "Open Source framework for automation, implemented IEC 61131 IDE with constantly growing set of extensions and flexible PLC runtime."
msgstr ""
@@ -3367,14 +3342,6 @@
msgid "ST files (*.st)|*.st|All files|*.*"
msgstr ""
-#: ../svgui/svgui.py:136
-msgid "SVG files (*.svg)|*.svg|All files|*.*"
-msgstr ""
-
-#: ../features.py:25
-msgid "SVGUI"
-msgstr ""
-
#: ../BeremizIDE.py:246 ../BeremizIDE.py:277 ../PLCOpenEditor.py:84
#: ../PLCOpenEditor.py:119
msgid "Save"
@@ -4161,12 +4128,6 @@
msgid "You cannot SDO download this state"
msgstr ""
-#: ../svgui/svgui.py:150
-msgid ""
-"You don't have write permissions.\n"
-"Open Inkscape anyway ?"
-msgstr ""
-
#: ../wxglade_hmi/wxglade_hmi.py:175
msgid ""
"You don't have write permissions.\n"
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/de_DE/LC_MESSAGES/Beremiz.mo
Binary file locale/de_DE/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/es_ES/LC_MESSAGES/Beremiz.mo
Binary file locale/es_ES/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/fr_FR/LC_MESSAGES/Beremiz.mo
Binary file locale/fr_FR/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/hu_HU/LC_MESSAGES/Beremiz.mo
Binary file locale/hu_HU/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/it_IT/LC_MESSAGES/Beremiz.mo
Binary file locale/it_IT/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/ko_KR/LC_MESSAGES/Beremiz.mo
Binary file locale/ko_KR/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/nl_NL/LC_MESSAGES/Beremiz.mo
Binary file locale/nl_NL/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/pt/LC_MESSAGES/Beremiz.mo
Binary file locale/pt/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/pt_BR/LC_MESSAGES/Beremiz.mo
Binary file locale/pt_BR/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/ru_RU/LC_MESSAGES/Beremiz.mo
Binary file locale/ru_RU/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/sl_SI/LC_MESSAGES/Beremiz.mo
Binary file locale/sl_SI/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/tr_TR/LC_MESSAGES/Beremiz.mo
Binary file locale/tr_TR/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/vi_VN/LC_MESSAGES/Beremiz.mo
Binary file locale/vi_VN/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 locale/zh_CN/LC_MESSAGES/Beremiz.mo
Binary file locale/zh_CN/LC_MESSAGES/Beremiz.mo has changed
diff -r c6de1a6cb655 -r 4a08728a2ea4 opc_ua/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/opc_ua/__init__.py Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,13 @@
+# opcua/__init__.py
+
+from __future__ import absolute_import
+
+from .client import OPCUAClient
+
+# class RootClass(object):
+# XSD = """
+#
+#
+# """
+# CTNChildrenTypes = [("OPCUAClient", OPCUAClient, "OPCUA Client")]
+#
diff -r c6de1a6cb655 -r 4a08728a2ea4 opc_ua/client.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/opc_ua/client.py Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,112 @@
+# opcua/client.py
+
+from __future__ import absolute_import
+
+import os
+
+from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
+from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT
+from .opcua_client_maker import OPCUAClientPanel, OPCUAClientModel, UA_IEC_types
+
+import util.paths as paths
+
+# Paths to open62541 assume that
+# - open62541 directory is aside beremiz directory
+# - open62541 was just built (not installed)
+
+Open62541Path = paths.ThirdPartyPath("open62541")
+Open62541LibraryPath = os.path.join(Open62541Path,"build","bin")
+Open62541IncludePaths = [os.path.join(Open62541Path, *dirs) for dirs in [
+ ("plugins","include"),
+ ("build","src_generated"),
+ ("include",),
+ ("arch",)]]
+
+class OPCUAClientEditor(ConfTreeNodeEditor):
+ CONFNODEEDITOR_TABS = [
+ (_("OPC-UA Client"), "CreateOPCUAClient_UI")]
+
+ def Log(self, msg):
+ self.Controler.GetCTRoot().logger.write(msg)
+
+ def UriGetter(self):
+ return self.Controler.GetServerURI()
+
+ def CreateOPCUAClient_UI(self, parent):
+ return OPCUAClientPanel(parent, self.Controler.GetModelData(), self.Log, self.UriGetter)
+
+class OPCUAClient(object):
+ XSD = """
+
+
+
+
+
+
+
+ """
+
+ EditorType = OPCUAClientEditor
+
+ def __init__(self):
+ self.modeldata = OPCUAClientModel()
+
+ filepath = self.GetFileName()
+ if os.path.isfile(filepath):
+ self.modeldata.LoadCSV(filepath)
+
+ def GetModelData(self):
+ return self.modeldata
+
+ def GetServerURI(self):
+ return self.GetParamsAttributes("OPCUAClient.Server_URI")["value"]
+
+ def GetFileName(self):
+ return os.path.join(self.CTNPath(), 'selected.csv')
+
+ def OnCTNSave(self, from_project_path=None):
+ self.modeldata.SaveCSV(self.GetFileName())
+ return True
+
+ def CTNGenerate_C(self, buildpath, locations):
+ current_location = self.GetCurrentLocation()
+ locstr = "_".join(map(str, current_location))
+ c_path = os.path.join(buildpath, "opcua_client__%s.c" % locstr)
+
+ c_code = self.modeldata.GenerateC(c_path, locstr,
+ self.GetParamsAttributes("OPCUAClient.Server_URI")["value"])
+
+ with open(c_path, 'wb') as c_file:
+ c_file.write(c_code)
+
+ LDFLAGS = [' "' + os.path.join(Open62541LibraryPath, "libopen62541.a") + '"']
+
+ CFLAGS = ' '.join(['-I"' + path + '"' for path in Open62541IncludePaths])
+
+ return [(c_path, CFLAGS)], LDFLAGS, True
+
+ def GetVariableLocationTree(self):
+ current_location = self.GetCurrentLocation()
+ locstr = "_".join(map(str, current_location))
+ name = self.BaseParams.getName()
+ entries = []
+ for direction, data in self.modeldata.iteritems():
+ iec_direction_prefix = {"input": "__I", "output": "__Q"}[direction]
+ for row in data:
+ dname, ua_nsidx, ua_nodeid_type, _ua_node_id, ua_type, iec_number = row
+ iec_type, C_type, iec_size_prefix, ua_type_enum, ua_type = UA_IEC_types[ua_type]
+ c_loc_name = iec_direction_prefix + iec_size_prefix + locstr + "_" + str(iec_number)
+ entries.append({
+ "name": dname,
+ "type": {"input": LOCATION_VAR_INPUT, "output": LOCATION_VAR_OUTPUT}[direction],
+ "size": {"X":1, "B":8, "W":16, "D":32, "L":64}[iec_size_prefix],
+ "IEC_type": iec_type,
+ "var_name": c_loc_name,
+ "location": iec_size_prefix + ".".join([str(i) for i in current_location]) + "." + str(iec_number),
+ "description": "",
+ "children": []})
+ return {"name": name,
+ "type": LOCATION_CONFNODE,
+ "location": ".".join([str(i) for i in current_location]) + ".x",
+ "children": entries}
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 opc_ua/opcua_client_maker.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/opc_ua/opcua_client_maker.py Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,694 @@
+from __future__ import print_function
+from __future__ import absolute_import
+
+import csv
+
+from opcua import Client
+from opcua import ua
+
+import wx
+import wx.lib.gizmos as gizmos # Formerly wx.gizmos in Classic
+import wx.dataview as dv
+
+
+UA_IEC_types = dict(
+# pyopcua | IEC61131| C type | sz | open62541 enum | open62541
+ Boolean = ("BOOL" , "uint8_t" , "X", "UA_TYPES_BOOLEAN", "UA_Boolean"),
+ SByte = ("SINT" , "int8_t" , "B", "UA_TYPES_SBYTE" , "UA_SByte" ),
+ Byte = ("USINT", "uint8_t" , "B", "UA_TYPES_BYTE" , "UA_Byte" ),
+ Int16 = ("INT" , "int16_t" , "W", "UA_TYPES_INT16" , "UA_Int16" ),
+ UInt16 = ("UINT" , "uint16_t", "W", "UA_TYPES_UINT16" , "UA_UInt16" ),
+ Int32 = ("DINT" , "uint32_t", "D", "UA_TYPES_INT32" , "UA_Int32" ),
+ UInt32 = ("UDINT", "int32_t" , "D", "UA_TYPES_UINT32" , "UA_UInt32" ),
+ Int64 = ("LINT" , "int64_t" , "L", "UA_TYPES_INT64" , "UA_Int64" ),
+ UInt64 = ("ULINT", "uint64_t", "L", "UA_TYPES_UINT64" , "UA_UInt64" ),
+ Float = ("REAL" , "float" , "D", "UA_TYPES_FLOAT" , "UA_Float" ),
+ Double = ("LREAL", "double" , "L", "UA_TYPES_DOUBLE" , "UA_Double" ),
+)
+
+UA_NODE_ID_types = {
+ "int" : ("UA_NODEID_NUMERIC", "{}" ),
+ "str" : ("UA_NODEID_STRING" , '"{}"'),
+ "UUIS" : ("UA_NODEID_UUID" , '"{}"'),
+}
+
+lstcolnames = [ "Name", "NSIdx", "IdType", "Id", "Type", "IEC"]
+lstcolwidths = [ 100, 50, 100, 100, 100, 50]
+lstcoltypess = [ str, int, str, str, str, int]
+
+directions = ["input", "output"]
+
+class OPCUASubListModel(dv.DataViewIndexListModel):
+ def __init__(self, data, log):
+ dv.DataViewIndexListModel.__init__(self, len(data))
+ self.data = data
+ self.log = log
+
+ def GetColumnType(self, col):
+ return "string"
+
+ def GetValueByRow(self, row, col):
+ return str(self.data[row][col])
+
+ # This method is called when the user edits a data item in the view.
+ def SetValueByRow(self, value, row, col):
+ expectedtype = lstcoltypess[col]
+
+ try:
+ v = expectedtype(value)
+ except ValueError:
+ self.log("String {} is invalid for type {}\n".format(value,expectedtype.__name__))
+ return False
+
+ if col == lstcolnames.index("IdType") and v not in UA_NODE_ID_types:
+ self.log("{} is invalid for IdType\n".format(value))
+ return False
+
+ self.data[row][col] = v
+ return True
+
+ # Report how many columns this model provides data for.
+ def GetColumnCount(self):
+ return len(lstcolnames)
+
+ # Report the number of rows in the model
+ def GetCount(self):
+ #self.log.write('GetCount')
+ return len(self.data)
+
+ # Called to check if non-standard attributes should be used in the
+ # cell at (row, col)
+ def GetAttrByRow(self, row, col, attr):
+ if col == 5:
+ attr.SetColour('blue')
+ attr.SetBold(True)
+ return True
+ return False
+
+
+ def DeleteRows(self, rows):
+ # make a copy since we'll be sorting(mutating) the list
+ # use reverse order so the indexes don't change as we remove items
+ rows = sorted(rows, reverse=True)
+
+ for row in rows:
+ # remove it from our data structure
+ del self.data[row]
+ # notify the view(s) using this model that it has been removed
+ self.RowDeleted(row)
+
+
+ def AddRow(self, value):
+ v = dict(zip(lstcolnames, value))
+
+ if type(v["IEC"]) != int:
+ if len(self.data) == 0:
+ v["IEC"] = 0
+ else:
+ iecnums = set(zip(*self.data)[lstcolnames.index("IEC")])
+ greatest = max(iecnums)
+ holes = set(range(greatest)) - iecnums
+ v["IEC"] = min(holes) if holes else greatest+1
+
+ if v["IdType"] not in UA_NODE_ID_types:
+ self.log("Unknown IdType\n".format(value))
+ return
+
+ try:
+ for t,n in zip(lstcoltypess, lstcolnames):
+ v[n] = t(v[n])
+ except ValueError:
+ self.log("Variable {} (Id={}) has invalid type\n".format(v["Name"],v["Id"]))
+ return
+
+ if len(self.data)>0 and v["Id"] in zip(*self.data)[lstcolnames.index("Id")]:
+ self.log("Variable {} (Id={}) already in list\n".format(v["Name"],v["Id"]))
+ return
+
+ self.data.append([v[n] for n in lstcolnames])
+
+ # notify views
+ self.RowAppended()
+
+ def ResetData(self):
+ self.Reset(len(self.data))
+
+OPCUAClientDndMagicWord = "text/beremiz-opcuaclient"
+
+class NodeDropTarget(wx.DropTarget):
+
+ def __init__(self, parent):
+ data = wx.CustomDataObject(OPCUAClientDndMagicWord)
+ wx.DropTarget.__init__(self, data)
+ self.ParentWindow = parent
+
+ def OnDrop(self, x, y):
+ self.ParentWindow.OnNodeDnD()
+ return True
+
+class OPCUASubListPanel(wx.Panel):
+ def __init__(self, parent, log, model, direction):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ self.dvc = dv.DataViewCtrl(self,
+ style=wx.BORDER_THEME
+ | dv.DV_ROW_LINES
+ | dv.DV_HORIZ_RULES
+ | dv.DV_VERT_RULES
+ | dv.DV_MULTIPLE
+ )
+
+ self.model = model
+
+ self.dvc.AssociateModel(self.model)
+
+ for idx,(colname,width) in enumerate(zip(lstcolnames,lstcolwidths)):
+ self.dvc.AppendTextColumn(colname, idx, width=width, mode=dv.DATAVIEW_CELL_EDITABLE)
+
+ DropTarget = NodeDropTarget(self)
+ self.dvc.SetDropTarget(DropTarget)
+
+ self.Sizer = wx.BoxSizer(wx.VERTICAL)
+
+ self.direction = direction
+ titlestr = direction + " variables"
+
+ title = wx.StaticText(self, label = titlestr)
+
+ delbt = wx.Button(self, label="Delete Row(s)")
+ self.Bind(wx.EVT_BUTTON, self.OnDeleteRows, delbt)
+
+ topsizer = wx.BoxSizer(wx.HORIZONTAL)
+ topsizer.Add(title, 1, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 5)
+ topsizer.Add(delbt, 0, wx.LEFT|wx.RIGHT, 5)
+ self.Sizer.Add(topsizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
+ self.Sizer.Add(self.dvc, 1, wx.EXPAND)
+
+
+
+ def OnDeleteRows(self, evt):
+ items = self.dvc.GetSelections()
+ rows = [self.model.GetRow(item) for item in items]
+ self.model.DeleteRows(rows)
+
+
+ def OnNodeDnD(self):
+ # Have to find OPC-UA client extension panel from here
+ # in order to avoid keeping reference (otherwise __del__ isn't called)
+ # splitter. panel. splitter
+ ClientPanel = self.GetParent().GetParent().GetParent()
+ nodes = ClientPanel.GetSelectedNodes()
+ for node in nodes:
+ cname = node.get_node_class().name
+ dname = node.get_display_name().to_string()
+ if cname != "Variable":
+ self.log("Node {} ignored (not a variable)".format(dname))
+ continue
+
+ tname = node.get_data_type_as_variant_type().name
+ if tname not in UA_IEC_types:
+ self.log("Node {} ignored (unsupported type)".format(dname))
+ continue
+
+ access = node.get_access_level()
+ if {"input":ua.AccessLevel.CurrentRead,
+ "output":ua.AccessLevel.CurrentWrite}[self.direction] not in access:
+ self.log("Node {} ignored because of insuficient access rights".format(dname))
+ continue
+
+ nsid = node.nodeid.NamespaceIndex
+ nid = node.nodeid.Identifier
+ nid_type = type(nid).__name__
+ iecid = nid
+
+ value = [dname,
+ nsid,
+ nid_type,
+ nid,
+ tname,
+ iecid]
+ self.model.AddRow(value)
+
+
+
+il = None
+fldridx = None
+fldropenidx = None
+fileidx = None
+smileidx = None
+isz = (16,16)
+
+treecolnames = [ "Name", "Class", "NSIdx", "Id"]
+treecolwidths = [ 250, 100, 50, 200]
+
+
+def prepare_image_list():
+ global il, fldridx, fldropenidx, fileidx, smileidx
+
+ if il is not None:
+ return
+
+ il = wx.ImageList(isz[0], isz[1])
+ fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
+ fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
+ fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
+ smileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_OTHER, isz))
+
+
+class OPCUAClientPanel(wx.SplitterWindow):
+ def __init__(self, parent, modeldata, log, uri_getter):
+ self.log = log
+ wx.SplitterWindow.__init__(self, parent, -1)
+
+ self.ordered_nodes = []
+
+ self.inout_panel = wx.Panel(self)
+ self.inout_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
+ self.inout_sizer.AddGrowableCol(0)
+ self.inout_sizer.AddGrowableRow(1)
+
+ self.client = None
+ self.uri_getter = uri_getter
+
+ self.connect_button = wx.ToggleButton(self.inout_panel, -1, "Browse Server")
+
+ self.selected_splitter = wx.SplitterWindow(self.inout_panel, style=wx.SUNKEN_BORDER | wx.SP_3D)
+
+ self.selected_datas = modeldata
+ self.selected_models = { direction:OPCUASubListModel(self.selected_datas[direction], log) for direction in directions }
+ self.selected_lists = { direction:OPCUASubListPanel(
+ self.selected_splitter, log,
+ self.selected_models[direction], direction)
+ for direction in directions }
+
+ self.selected_splitter.SplitHorizontally(*[self.selected_lists[direction] for direction in directions]+[300])
+
+ self.inout_sizer.Add(self.connect_button, flag=wx.GROW)
+ self.inout_sizer.Add(self.selected_splitter, flag=wx.GROW)
+ self.inout_sizer.Layout()
+ self.inout_panel.SetAutoLayout(True)
+ self.inout_panel.SetSizer(self.inout_sizer)
+
+ self.Initialize(self.inout_panel)
+
+ self.Bind(wx.EVT_TOGGLEBUTTON, self.OnConnectButton, self.connect_button)
+
+ def OnClose(self):
+ if self.client is not None:
+ self.client.disconnect()
+ self.client = None
+
+ def __del__(self):
+ self.OnClose()
+
+ def OnConnectButton(self, event):
+ if self.connect_button.GetValue():
+
+ self.tree_panel = wx.Panel(self)
+ self.tree_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
+ self.tree_sizer.AddGrowableCol(0)
+ self.tree_sizer.AddGrowableRow(0)
+
+ self.tree = gizmos.TreeListCtrl(self.tree_panel, -1, style=0, agwStyle=
+ gizmos.TR_DEFAULT_STYLE
+ | gizmos.TR_MULTIPLE
+ | gizmos.TR_FULL_ROW_HIGHLIGHT
+ )
+
+ prepare_image_list()
+ self.tree.SetImageList(il)
+
+ for idx,(colname, width) in enumerate(zip(treecolnames, treecolwidths)):
+ self.tree.AddColumn(colname)
+ self.tree.SetColumnWidth(idx, width)
+
+ self.tree.SetMainColumn(0)
+
+ self.client = Client(self.uri_getter())
+ self.client.connect()
+ self.client.load_type_definitions() # load definition of server specific structures/extension objects
+ rootnode = self.client.get_root_node()
+
+ rootitem = self.AddNodeItem(self.tree.AddRoot, rootnode)
+
+ # Populate first level so that root can be expanded
+ self.CreateSubItems(rootitem)
+
+ self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnExpand)
+
+ self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeNodeSelection)
+ self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTreeBeginDrag)
+
+ self.tree.Expand(rootitem)
+
+ hint = wx.StaticText(self, label = "Drag'n'drop desired variables from tree to Input or Output list")
+
+ self.tree_sizer.Add(self.tree, flag=wx.GROW)
+ self.tree_sizer.Add(hint, flag=wx.GROW)
+ self.tree_sizer.Layout()
+ self.tree_panel.SetAutoLayout(True)
+ self.tree_panel.SetSizer(self.tree_sizer)
+
+ self.SplitVertically(self.tree_panel, self.inout_panel, 500)
+ else:
+ self.client.disconnect()
+ self.client = None
+ self.Unsplit(self.tree_panel)
+ self.tree_panel.Destroy()
+
+
+ def CreateSubItems(self, item):
+ node, browsed = self.tree.GetPyData(item)
+ if not browsed:
+ for subnode in node.get_children():
+ self.AddNodeItem(lambda n: self.tree.AppendItem(item, n), subnode)
+ self.tree.SetPyData(item,(node, True))
+
+ def AddNodeItem(self, item_creation_func, node):
+ nsid = node.nodeid.NamespaceIndex
+ nid = node.nodeid.Identifier
+ dname = node.get_display_name().Text
+ cname = node.get_node_class().name
+
+ item = item_creation_func(dname)
+
+ if cname == "Variable":
+ access = node.get_access_level()
+ normalidx = fileidx
+ r = ua.AccessLevel.CurrentRead in access
+ w = ua.AccessLevel.CurrentWrite in access
+ if r and w:
+ ext = "RW"
+ elif r:
+ ext = "RO"
+ elif w:
+ ext = "WO" # not sure this one exist
+ else:
+ ext = "no access" # not sure this one exist
+ cname = "Var "+node.get_data_type_as_variant_type().name+" (" + ext + ")"
+ else:
+ normalidx = fldridx
+
+ self.tree.SetPyData(item,(node, False))
+ self.tree.SetItemText(item, cname, 1)
+ self.tree.SetItemText(item, str(nsid), 2)
+ self.tree.SetItemText(item, type(nid).__name__+": "+str(nid), 3)
+ self.tree.SetItemImage(item, normalidx, which = wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(item, fldropenidx, which = wx.TreeItemIcon_Expanded)
+
+ return item
+
+ def OnExpand(self, evt):
+ for item in evt.GetItem().GetChildren():
+ self.CreateSubItems(item)
+
+ # def OnActivate(self, evt):
+ # item = evt.GetItem()
+ # node, browsed = self.tree.GetPyData(item)
+
+ def OnTreeNodeSelection(self, event):
+ items = self.tree.GetSelections()
+ items_pydata = [self.tree.GetPyData(item) for item in items]
+
+ nodes = [node for node, _unused in items_pydata]
+
+ # append new nodes to ordered list
+ for node in nodes:
+ if node not in self.ordered_nodes:
+ self.ordered_nodes.append(node)
+
+ # filter out vanished items
+ self.ordered_nodes = [
+ node
+ for node in self.ordered_nodes
+ if node in nodes]
+
+ def GetSelectedNodes(self):
+ return self.ordered_nodes
+
+ def OnTreeBeginDrag(self, event):
+ """
+ Called when a drag is started in tree
+ @param event: wx.TreeEvent
+ """
+ if self.ordered_nodes:
+ # Just send a recognizable mime-type, drop destination
+ # will get python data from parent
+ data = wx.CustomDataObject(OPCUAClientDndMagicWord)
+ dragSource = wx.DropSource(self)
+ dragSource.SetData(data)
+ dragSource.DoDragDrop()
+
+ def Reset(self):
+ for direction in directions:
+ self.selected_models[direction].ResetData()
+
+
+class OPCUAClientModel(dict):
+ def __init__(self):
+ for direction in directions:
+ self[direction] = list()
+
+ def LoadCSV(self,path):
+ with open(path, 'rb') as csvfile:
+ reader = csv.reader(csvfile, delimiter=',', quotechar='"')
+ buf = {direction:[] for direction, _model in self.iteritems()}
+ for row in reader:
+ direction = row[0]
+ buf[direction].append(row[1:])
+ for direction, model in self.iteritems():
+ self[direction][:] = buf[direction]
+
+ def SaveCSV(self,path):
+ with open(path, 'wb') as csvfile:
+ for direction, data in self.iteritems():
+ writer = csv.writer(csvfile, delimiter=',',
+ quotechar='"', quoting=csv.QUOTE_MINIMAL)
+ for row in data:
+ writer.writerow([direction] + row)
+
+ def GenerateC(self, path, locstr, server_uri):
+ template = """/* code generated by beremiz OPC-UA extension */
+
+#include
+#include
+#include
+
+UA_Client *client;
+
+#define DECL_VAR(ua_type, C_type, c_loc_name) \\
+UA_Variant *c_loc_name##_variant; \\
+C_type c_loc_name##_buf = 0; \\
+C_type *c_loc_name = &c_loc_name##_buf;
+
+%(decl)s
+
+#define FREE_VARIANT(ua_type, c_loc_name) \\
+ UA_Variant_delete(c_loc_name##_variant);
+
+void __cleanup_%(locstr)s(void)
+{
+ UA_Client_disconnect(client);
+ UA_Client_delete(client);
+%(cleanup)s
+}
+
+
+#define ALLOC_VARIANT(ua_type, c_loc_name) \\
+ c_loc_name##_variant = UA_Variant_new();
+
+int __init_%(locstr)s(int argc,char **argv)
+{
+ UA_StatusCode retval;
+ client = UA_Client_new();
+ UA_ClientConfig_setDefault(UA_Client_getConfig(client));
+%(init)s
+
+ /* Connect to server */
+ retval = UA_Client_connect(client, "%(uri)s");
+ if(retval != UA_STATUSCODE_GOOD) {
+ UA_Client_delete(client);
+ return EXIT_FAILURE;
+ }
+}
+
+#define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \\
+ retval = UA_Client_readValueAttribute( \\
+ client, ua_nodeid_type(ua_nsidx, ua_node_id), c_loc_name##_variant); \\
+ if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(c_loc_name##_variant) && \\
+ c_loc_name##_variant->type == &UA_TYPES[ua_type_enum]) { \\
+ c_loc_name##_buf = *(ua_type*)c_loc_name##_variant->data; \\
+ }
+
+void __retrieve_%(locstr)s(void)
+{
+ UA_StatusCode retval;
+%(retrieve)s
+}
+
+#define WRITE_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \\
+ UA_Variant_setScalarCopy(c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]); \\
+ UA_Client_writeValueAttribute(client, ua_nodeid_type(ua_nsidx, ua_node_id), c_loc_name##_variant);
+
+void __publish_%(locstr)s(void)
+{
+%(publish)s
+}
+
+"""
+
+ formatdict = dict(
+ locstr = locstr,
+ uri = server_uri,
+ decl = "",
+ cleanup = "",
+ init = "",
+ retrieve = "",
+ publish = ""
+ )
+ for direction, data in self.iteritems():
+ iec_direction_prefix = {"input": "__I", "output": "__Q"}[direction]
+ for row in data:
+ name, ua_nsidx, ua_nodeid_type, _ua_node_id, ua_type, iec_number = row
+ iec_type, C_type, iec_size_prefix, ua_type_enum, ua_type = UA_IEC_types[ua_type]
+ c_loc_name = iec_direction_prefix + iec_size_prefix + locstr + "_" + str(iec_number)
+ ua_nodeid_type, id_formating = UA_NODE_ID_types[ua_nodeid_type]
+ ua_node_id = id_formating.format(_ua_node_id)
+
+ formatdict["decl"] += """
+DECL_VAR({ua_type}, {C_type}, {c_loc_name})""".format(**locals())
+ formatdict["cleanup"] += """
+ FREE_VARIANT({ua_type}, {c_loc_name})""".format(**locals())
+ formatdict["init"] +="""
+ ALLOC_VARIANT({ua_type}, {c_loc_name})""".format(**locals())
+ formatdict["retrieve"] += """
+ READ_VALUE({ua_type}, {ua_type_enum}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())
+ formatdict["publish"] += """
+ WRITE_VALUE({ua_type}, {ua_type_enum}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())
+
+ Ccode = template%formatdict
+
+ return Ccode
+
+if __name__ == "__main__":
+
+ import wx.lib.mixins.inspection as wit
+ import sys,os
+
+ app = wit.InspectableApp()
+
+ frame = wx.Frame(None, -1, "OPCUA Client Test App", size=(800,600))
+
+ uri = sys.argv[1] if len(sys.argv)>1 else "opc.tcp://localhost:4840"
+
+ test_panel = wx.Panel(frame)
+ test_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
+ test_sizer.AddGrowableCol(0)
+ test_sizer.AddGrowableRow(0)
+
+ modeldata = OPCUAClientModel()
+
+ opcuatestpanel = OPCUAClientPanel(test_panel, modeldata, print, lambda:uri)
+
+ def OnGenerate(evt):
+ dlg = wx.FileDialog(
+ frame, message="Generate file as ...", defaultDir=os.getcwd(),
+ defaultFile="",
+ wildcard="C (*.c)|*.c", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
+ )
+
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ Ccode = """
+/*
+In case open62541 was built just aside beremiz, you can build this test with:
+gcc %s -o %s \\
+ -I ../../open62541/plugins/include/ \\
+ -I ../../open62541/build/src_generated/ \\
+ -I ../../open62541/include/ \\
+ -I ../../open62541/arch/ ../../open62541/build/bin/libopen62541.a
+*/
+
+"""%(path, path[:-2]) + modeldata.GenerateC(path, "test", uri) + """
+
+int main(int argc, char *argv[]) {
+
+ __init_test(arc,argv);
+
+ __retrieve_test();
+
+ __publish_test();
+
+ __cleanup_test();
+
+ return EXIT_SUCCESS;
+}
+"""
+
+ with open(path, 'wb') as Cfile:
+ Cfile.write(Ccode)
+
+
+ dlg.Destroy()
+
+ def OnLoad(evt):
+ dlg = wx.FileDialog(
+ frame, message="Choose a file",
+ defaultDir=os.getcwd(),
+ defaultFile="",
+ wildcard="CSV (*.csv)|*.csv",
+ style=wx.FD_OPEN | wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST )
+
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ modeldata.LoadCSV(path)
+ opcuatestpanel.Reset()
+
+ dlg.Destroy()
+
+ def OnSave(evt):
+ dlg = wx.FileDialog(
+ frame, message="Save file as ...", defaultDir=os.getcwd(),
+ defaultFile="",
+ wildcard="CSV (*.csv)|*.csv", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
+ )
+
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ modeldata.SaveCSV(path)
+
+ dlg.Destroy()
+
+ test_sizer.Add(opcuatestpanel, flag=wx.GROW)
+
+ testbt_sizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ loadbt = wx.Button(test_panel, label="Load")
+ test_panel.Bind(wx.EVT_BUTTON, OnLoad, loadbt)
+
+ savebt = wx.Button(test_panel, label="Save")
+ test_panel.Bind(wx.EVT_BUTTON, OnSave, savebt)
+
+ genbt = wx.Button(test_panel, label="Generate")
+ test_panel.Bind(wx.EVT_BUTTON, OnGenerate, genbt)
+
+ testbt_sizer.Add(loadbt, 0, wx.LEFT|wx.RIGHT, 5)
+ testbt_sizer.Add(savebt, 0, wx.LEFT|wx.RIGHT, 5)
+ testbt_sizer.Add(genbt, 0, wx.LEFT|wx.RIGHT, 5)
+
+ test_sizer.Add(testbt_sizer, flag=wx.GROW)
+ test_sizer.Layout()
+ test_panel.SetAutoLayout(True)
+ test_panel.SetSizer(test_sizer)
+
+ def OnClose(evt):
+ opcuatestpanel.OnClose()
+ evt.Skip()
+
+ frame.Bind(wx.EVT_CLOSE, OnClose)
+
+ frame.Show()
+
+ app.MainLoop()
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 runtime/PyroServer.py
--- a/runtime/PyroServer.py Tue Oct 19 15:15:03 2021 +0200
+++ b/runtime/PyroServer.py Wed Oct 20 08:57:07 2021 +0200
@@ -62,8 +62,15 @@
self.daemon.connect(pyro_obj, "PLCObject")
when_ready()
- self.piper, self.pipew = os.pipe()
- self.daemon.requestLoop(others=[self.piper], callback=lambda x: None)
+
+ # "pipe to self" trick to to accelerate runtime shutdown
+ # instead of waiting for arbitrary pyro timeout.
+ others = []
+ if not sys.platform.startswith('win'):
+ self.piper, self.pipew = os.pipe()
+ others.append(self.piper)
+
+ self.daemon.requestLoop(others=others, callback=lambda x: None)
self.piper, self.pipew = None, None
if hasattr(self, 'sock'):
self.daemon.sock.close()
@@ -76,8 +83,9 @@
self.continueloop = False
self.daemon.shutdown(True)
self.daemon.closedown()
- if self.pipew is not None:
- os.write(self.pipew, "goodbye")
+ if not sys.platform.startswith('win'):
+ if self.pipew is not None:
+ os.write(self.pipew, "goodbye")
def Publish(self):
self.servicepublisher = ServicePublisher("PYRO")
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/analyse_widget.xslt
--- a/svghmi/analyse_widget.xslt Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/analyse_widget.xslt Wed Oct 20 08:57:07 2021 +0200
@@ -221,14 +221,16 @@
in between 0 and 100.
-
-
- If "value" labeled text is found, then its content is replaced by value.
-
Change end angle of Inkscape's arc
+
+ minimum value
+
+
+ maximum value
+
Value to display
@@ -339,9 +341,11 @@
- It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*),
-
- and "highlight" (svg:rect) labeled elements.
+ It needs "text" (svg:text or svg:use referring to svg:text),
+
+ "box" (svg:rect), "button" (svg:*), and "highlight" (svg:rect)
+
+ labeled elements.
@@ -353,11 +357,19 @@
- When only one argument is given, and argment contains "#langs" then list of
-
- texts is automatically set to the list of human-readable languages supported
-
- by this HMI.
+ When only one argument is given and argment contains "#langs" then list of
+
+ texts is automatically set to the human-readable list of supported
+
+ languages by this HMI.
+
+
+
+ If "text" labeled element is of type svg:use and refers to a svg:text
+
+ element part of a TextList widget, no argument is expected. In that case
+
+ list of texts is set to TextList content.
@@ -529,6 +541,30 @@
+
+ List widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a List, clone (svg:use) one of the items inside the widget that
+
+ expects a List.
+
+
+
+ Positions of items are relative to each other, and they must all be in the
+
+ same place. In order to make editing easier it is therefore recommanded to
+
+ make stacked clones of svg elements spread nearby the list.
+
+
+
+ A named list of named graphical elements
+
+
@@ -549,10 +585,6 @@
in between 0 and 100.
-
-
- If "value" labeled text is found, then its content is replaced by value.
-
Moves "needle" along "range"
@@ -567,12 +599,39 @@
Value to display
+
+
+
+
+
+ PathSlider -
+
+
+
+ Slide an SVG element along a path by dragging it
+
+
+ value
+
+
+ min
+
+
+ max
+
+
+ minimum value
+
+
+ maximum value
+
+
- ScrollBar - documentation to be written
+ ScrollBar - svg:rect based scrollbar
@@ -634,6 +693,58 @@
value to compare to labels
+
+
+
+
+
+ TextList widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a TextList, clone (svg:use) one of the items inside the widget
+
+ that expects a TextList.
+
+
+
+ In this list, (translated) text content is what matters. Nevertheless
+
+ text style of the cloned item will be applied in client widget.
+
+
+
+ A named list of ordered texts
+
+
+
+
+
+
+
+
+ TextStyleList widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a TextStyleList, clone (svg:use) one of the items inside the widget
+
+ that expects a TextStyleList.
+
+
+
+ In this list, only style matters. Text content is ignored.
+
+
+
+ A named list of named texts
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/detachable_pages.ysl2
--- a/svghmi/detachable_pages.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/detachable_pages.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -88,10 +88,7 @@
const "required_page_elements",
"func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*";
-const "hmi_lists_descs", "$parsed_widgets/widget[@type = 'List']";
-const "hmi_lists", "$hmi_elements[@id = $hmi_lists_descs/@id]";
-
-const "required_list_elements", "func:refered_elements($hmi_lists[@id = $required_page_elements/@id])";
+const "required_list_elements", "func:refered_elements(($hmi_lists | $hmi_textlists)[@id = $required_page_elements/@id])";
const "required_elements", "$defs | $required_list_elements | $required_page_elements";
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/gen_index_xhtml.xslt
--- a/svghmi/gen_index_xhtml.xslt Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/gen_index_xhtml.xslt Wed Oct 20 08:57:07 2021 +0200
@@ -432,6 +432,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -526,9 +549,7 @@
-
-
-
+
@@ -2381,14 +2402,16 @@
in between 0 and 100.
-
-
- If "value" labeled text is found, then its content is replaced by value.
-
Change end angle of Inkscape's arc
+
+ minimum value
+
+
+ maximum value
+
Value to display
@@ -2456,6 +2479,12 @@
init() {
+ if(this.args.length >= 2)
+
+ [this.min, this.max]=this.args;
+
+
+
let [start, end, cx, cy, rx, ry] = ["start", "end", "cx", "cy", "rx", "ry"].
map(tag=>Number(this.path_elt.getAttribute('sodipodi:'+tag)))
@@ -2504,7 +2533,7 @@
- value min max
+ min max
@@ -3227,483 +3256,6 @@
-
-
-
-
- /*
-
- */
-
-
-
- /* https://github.com/alexei/sprintf.js/blob/master/src/sprintf.js */
-
- /* global window, exports, define */
-
-
-
- !function() {
-
- 'use strict'
-
-
-
- var re = {
-
- not_string: /[^s]/,
-
- not_bool: /[^t]/,
-
- not_type: /[^T]/,
-
- not_primitive: /[^v]/,
-
- number: /[diefg]/,
-
- numeric_arg: /[bcdiefguxX]/,
-
- json: /[j]/,
-
- not_json: /[^j]/,
-
- text: /^[^%]+/,
-
- modulo: /^%{2}/,
-
- placeholder: /^%(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
-
- key: /^([a-z_][a-z_\d]*)/i,
-
- key_access: /^\.([a-z_][a-z_\d]*)/i,
-
- index_access: /^\[(\d+)\]/,
-
- sign: /^[+-]/
-
- }
-
-
-
- function sprintf(key) {
-
- // arguments is not an array, but should be fine for this call
-
- return sprintf_format(sprintf_parse(key), arguments)
-
- }
-
-
-
- function vsprintf(fmt, argv) {
-
- return sprintf.apply(null, [fmt].concat(argv || []))
-
- }
-
-
-
- function sprintf_format(parse_tree, argv) {
-
- var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
-
- for (i = 0; i < tree_length; i++) {
-
- if (typeof parse_tree[i] === 'string') {
-
- output += parse_tree[i]
-
- }
-
- else if (typeof parse_tree[i] === 'object') {
-
- ph = parse_tree[i] // convenience purposes only
-
- if (ph.keys) { // keyword argument
-
- arg = argv[cursor]
-
- for (k = 0; k < ph.keys.length; k++) {
-
- if (arg == undefined) {
-
- throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
-
- }
-
- arg = arg[ph.keys[k]]
-
- }
-
- }
-
- else if (ph.param_no) { // positional argument (explicit)
-
- arg = argv[ph.param_no]
-
- }
-
- else { // positional argument (implicit)
-
- arg = argv[cursor++]
-
- }
-
-
-
- if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
-
- arg = arg()
-
- }
-
-
-
- if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
-
- throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
-
- }
-
-
-
- if (re.number.test(ph.type)) {
-
- is_positive = arg >= 0
-
- }
-
-
-
- switch (ph.type) {
-
- case 'b':
-
- arg = parseInt(arg, 10).toString(2)
-
- break
-
- case 'c':
-
- arg = String.fromCharCode(parseInt(arg, 10))
-
- break
-
- case 'd':
-
- case 'i':
-
- arg = parseInt(arg, 10)
-
- break
-
- case 'j':
-
- arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
-
- break
-
- case 'e':
-
- arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
-
- break
-
- case 'f':
-
- arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
-
- break
-
- case 'g':
-
- arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
-
- break
-
- case 'o':
-
- arg = (parseInt(arg, 10) >>> 0).toString(8)
-
- break
-
- case 's':
-
- arg = String(arg)
-
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
-
- break
-
- case 't':
-
- arg = String(!!arg)
-
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
-
- break
-
- case 'T':
-
- arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
-
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
-
- break
-
- case 'u':
-
- arg = parseInt(arg, 10) >>> 0
-
- break
-
- case 'v':
-
- arg = arg.valueOf()
-
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
-
- break
-
- case 'x':
-
- arg = (parseInt(arg, 10) >>> 0).toString(16)
-
- break
-
- case 'X':
-
- arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
-
- break
-
- }
-
- if (re.json.test(ph.type)) {
-
- output += arg
-
- }
-
- else {
-
- if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
-
- sign = is_positive ? '+' : '-'
-
- arg = arg.toString().replace(re.sign, '')
-
- }
-
- else {
-
- sign = ''
-
- }
-
- pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
-
- pad_length = ph.width - (sign + arg).length
-
- pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
-
- output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
-
- }
-
- }
-
- }
-
- return output
-
- }
-
-
-
- var sprintf_cache = Object.create(null)
-
-
-
- function sprintf_parse(fmt) {
-
- if (sprintf_cache[fmt]) {
-
- return sprintf_cache[fmt]
-
- }
-
-
-
- var _fmt = fmt, match, parse_tree = [], arg_names = 0
-
- while (_fmt) {
-
- if ((match = re.text.exec(_fmt)) !== null) {
-
- parse_tree.push(match[0])
-
- }
-
- else if ((match = re.modulo.exec(_fmt)) !== null) {
-
- parse_tree.push('%')
-
- }
-
- else if ((match = re.placeholder.exec(_fmt)) !== null) {
-
- if (match[2]) {
-
- arg_names |= 1
-
- var field_list = [], replacement_field = match[2], field_match = []
-
- if ((field_match = re.key.exec(replacement_field)) !== null) {
-
- field_list.push(field_match[1])
-
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
-
- if ((field_match = re.key_access.exec(replacement_field)) !== null) {
-
- field_list.push(field_match[1])
-
- }
-
- else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
-
- field_list.push(field_match[1])
-
- }
-
- else {
-
- throw new SyntaxError('[sprintf] failed to parse named argument key')
-
- }
-
- }
-
- }
-
- else {
-
- throw new SyntaxError('[sprintf] failed to parse named argument key')
-
- }
-
- match[2] = field_list
-
- }
-
- else {
-
- arg_names |= 2
-
- }
-
- if (arg_names === 3) {
-
- throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
-
- }
-
-
-
- parse_tree.push(
-
- {
-
- placeholder: match[0],
-
- param_no: match[1],
-
- keys: match[2],
-
- sign: match[3],
-
- pad_char: match[4],
-
- align: match[5],
-
- width: match[6],
-
- precision: match[7],
-
- type: match[8]
-
- }
-
- )
-
- }
-
- else {
-
- throw new SyntaxError('[sprintf] unexpected placeholder')
-
- }
-
- _fmt = _fmt.substring(match[0].length)
-
- }
-
- return sprintf_cache[fmt] = parse_tree
-
- }
-
-
-
- /**
-
- * export to either browser or node.js
-
- */
-
- /* eslint-disable quote-props */
-
- if (typeof exports !== 'undefined') {
-
- exports['sprintf'] = sprintf
-
- exports['vsprintf'] = vsprintf
-
- }
-
- if (typeof window !== 'undefined') {
-
- window['sprintf'] = sprintf
-
- window['vsprintf'] = vsprintf
-
-
-
- if (typeof define === 'function' && define['amd']) {
-
- define(function() {
-
- return {
-
- 'sprintf': sprintf,
-
- 'vsprintf': vsprintf
-
- }
-
- })
-
- }
-
- }
-
- /* eslint-enable quote-props */
-
- }(); // eslint-disable-line
-
-
-
-
@@ -3715,9 +3267,11 @@
- It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*),
-
- and "highlight" (svg:rect) labeled elements.
+ It needs "text" (svg:text or svg:use referring to svg:text),
+
+ "box" (svg:rect), "button" (svg:*), and "highlight" (svg:rect)
+
+ labeled elements.
@@ -3729,11 +3283,19 @@
- When only one argument is given, and argment contains "#langs" then list of
-
- texts is automatically set to the list of human-readable languages supported
-
- by this HMI.
+ When only one argument is given and argment contains "#langs" then list of
+
+ texts is automatically set to the human-readable list of supported
+
+ languages by this HMI.
+
+
+
+ If "text" labeled element is of type svg:use and refers to a svg:text
+
+ element part of a TextList widget, no argument is expected. In that case
+
+ list of texts is set to TextList content.
@@ -3759,6 +3321,8 @@
init() {
+ this.init_specific();
+
this.button_elt.onclick = this.on_button_click.bind(this);
// Save original size of rectangle
@@ -3849,7 +3413,7 @@
// if valid selection resolve content
- display_str = this.content[value];
+ display_str = gettext(this.content[value]);
this.last_selection = value;
@@ -4061,7 +3625,7 @@
let span=spans[c];
- span.textContent = item;
+ span.textContent = gettext(item);
let sel = c;
@@ -4193,7 +3757,7 @@
}else{
- span.textContent = this.content[i];
+ span.textContent = gettext(this.content[i]);
let sel = i;
@@ -4411,16 +3975,54 @@
- text box button highlight
+ box button highlight
- content:
+
+ init_specific: function() {
+
- langs
+ this.text_elt = id("
+
+ ");
+
+ this.content = langs;
+
+
+
+
+
+ No argrument for HMI:DropDown widget id="
+
+ " and "text" labeled element is not a svg:use element
+
+
+
+ this.text_elt = id("
+
+ ");
+
+
+
+
+
+ HMI:DropDown widget id="
+
+ " "text" labeled element does not point to a svg:text owned by a HMI:List widget
+
+
+ this.content = hmi_widgets["
+
+ "].texts;
+
- [
+ this.text_elt = id("
+
+ ");
+
+ this.content = [
"
@@ -4428,10 +4030,36 @@
",
- ]
+ ];
+
- ,
+ }
+
+
+
+
+
+
+ /*
+
+ */
+
+
+
+ function gettext(o) {
+
+ if(typeof(o) == "string"){
+
+ return o;
+
+ }
+
+ return svg_text_to_multiline(o);
+
+ };
+
+
@@ -5116,25 +4744,6 @@
.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -6009,6 +5618,30 @@
+
+ List widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a List, clone (svg:use) one of the items inside the widget that
+
+ expects a List.
+
+
+
+ Positions of items are relative to each other, and they must all be in the
+
+ same place. In order to make editing easier it is therefore recommanded to
+
+ make stacked clones of svg elements spread nearby the list.
+
+
+
+ A named list of named graphical elements
+
+
@@ -6025,25 +5658,6 @@
},
-
-
-
-
-
- styles: {
-
-
-
-
-
- : "
-
- ",
-
-
- },
-
-
@@ -6063,10 +5677,6 @@
in between 0 and 100.
-
-
- If "value" labeled text is found, then its content is replaced by value.
-
Moves "needle" along "range"
@@ -6152,7 +5762,7 @@
- value min max
+ min max
@@ -6301,12 +5911,352 @@
],
+
+
+
+
+
+ PathSlider -
+
+
+
+ Slide an SVG element along a path by dragging it
+
+
+ value
+
+
+ min
+
+
+ max
+
+
+ minimum value
+
+
+ maximum value
+
+
+
+ class
+ PathSliderWidget
+ extends Widget{
+
+ frequency = 10;
+
+ position = undefined;
+
+ min = 0;
+
+ max = 100;
+
+ scannedPoints = [];
+
+ pathLength = undefined;
+
+ precision = undefined;
+
+ origPt = undefined;
+
+
+
+
+
+ scanPath() {
+
+ this.pathLength = this.path_elt.getTotalLength();
+
+ this.precision = Math.floor(this.pathLength / 10);
+
+
+
+ // save linear scan for coarse approximation
+
+ for (var scanLength = 0; scanLength <= this.pathLength; scanLength += this.precision) {
+
+ this.scannedPoints.push([this.path_elt.getPointAtLength(scanLength), scanLength]);
+
+ }
+
+ [this.origPt,] = this.scannedPoints[0];
+
+ }
+
+
+
+ closestPoint(point) {
+
+ var bestPoint,
+
+ bestLength,
+
+ bestDistance = Infinity,
+
+ scanDistance;
+
+
+
+ // use linear scan for coarse approximation
+
+ for (let [scanPoint, scanLength] of this.scannedPoints){
+
+ if ((scanDistance = distance2(scanPoint)) < bestDistance) {
+
+ bestPoint = scanPoint,
+
+ bestLength = scanLength,
+
+ bestDistance = scanDistance;
+
+ }
+
+ }
+
+
+
+ // binary search for more precise estimate
+
+ let precision = this.precision / 2;
+
+ while (precision > 0.5) {
+
+ var beforePoint,
+
+ afterPoint,
+
+ beforeLength,
+
+ afterLength,
+
+ beforeDistance,
+
+ afterDistance;
+
+ if ((beforeLength = bestLength - precision) >= 0 &&
+
+ (beforeDistance = distance2(beforePoint = this.path_elt.getPointAtLength(beforeLength))) < bestDistance) {
+
+ bestPoint = beforePoint,
+
+ bestLength = beforeLength,
+
+ bestDistance = beforeDistance;
+
+ } else if ((afterLength = bestLength + precision) <= this.pathLength &&
+
+ (afterDistance = distance2(afterPoint = this.path_elt.getPointAtLength(afterLength))) < bestDistance) {
+
+ bestPoint = afterPoint,
+
+ bestLength = afterLength,
+
+ bestDistance = afterDistance;
+
+ }
+
+ precision /= 2;
+
+ }
+
+
+
+ return [bestPoint, bestLength];
+
+
+
+ function distance2(p) {
+
+ var dx = p.x - point.x,
+
+ dy = p.y - point.y;
+
+ return dx * dx + dy * dy;
+
+ }
+
+ }
+
+
+
+ dispatch(value,oldval, index) {
+
+ switch(index) {
+
+ case 0:
+
+ this.position = value;
+
+ break;
+
+ case 1:
+
+ this.min = value;
+
+ break;
+
+ case 2:
+
+ this.max = value;
+
+ break;
+
+ }
+
+
+
+ this.request_animate();
+
+ }
+
+
+
+ get_current_point(){
+
+ let currLength = this.pathLength * (this.position - this.min) / (this.max - this.min)
+
+ return this.path_elt.getPointAtLength(currLength);
+
+ }
+
+
+
+ animate(){
+
+ if(this.position == undefined)
+
+ return;
+
+
+
+ let currPt = this.get_current_point();
+
+ this.cursor_transform.setTranslate(currPt.x - this.origPt.x, currPt.y - this.origPt.y);
+
+ }
+
+
+
+ init() {
+
+ if(this.args.length == 2)
+
+ [this.min, this.max]=this.args;
+
+
+
+ this.scanPath();
+
+
+
+ this.cursor_transform = svg_root.createSVGTransform();
+
+
+
+ this.cursor_elt.transform.baseVal.appendItem(this.cursor_transform);
+
+
+
+ this.cursor_elt.onpointerdown = (e) => this.on_cursor_down(e);
+
+
+
+ this.bound_drag = this.drag.bind(this);
+
+ this.bound_drop = this.drop.bind(this);
+
+ }
+
+
+
+ start_dragging_from_event(e){
+
+ let clientPoint = new DOMPoint(e.clientX, e.clientY);
+
+ let point = clientPoint.matrixTransform(this.invctm);
+
+ let currPt = this.get_current_point();
+
+ this.draggingOffset = new DOMPoint(point.x - currPt.x , point.y - currPt.y);
+
+ }
+
+
+
+ apply_position_from_event(e){
+
+ let clientPoint = new DOMPoint(e.clientX, e.clientY);
+
+ let rawPoint = clientPoint.matrixTransform(this.invctm);
+
+ let point = new DOMPoint(rawPoint.x - this.draggingOffset.x , rawPoint.y - this.draggingOffset.y);
+
+ let [closestPoint, closestLength] = this.closestPoint(point);
+
+ let new_position = this.min + (this.max - this.min) * closestLength / this.pathLength;
+
+ this.position = Math.round(Math.max(Math.min(new_position, this.max), this.min));
+
+ this.apply_hmi_value(0, this.position);
+
+ }
+
+
+
+ on_cursor_down(e){
+
+ // get scrollbar -> root transform
+
+ let ctm = this.path_elt.getCTM();
+
+ // root -> path transform
+
+ this.invctm = ctm.inverse();
+
+ this.start_dragging_from_event(e);
+
+ svg_root.addEventListener("pointerup", this.bound_drop, true);
+
+ svg_root.addEventListener("pointermove", this.bound_drag, true);
+
+ }
+
+
+
+ drop(e) {
+
+ svg_root.removeEventListener("pointerup", this.bound_drop, true);
+
+ svg_root.removeEventListener("pointermove", this.bound_drag, true);
+
+ }
+
+
+
+ drag(e) {
+
+ this.apply_position_from_event(e);
+
+ }
+
+ }
+
+
+
+
+
+
+
+ cursor path
+
+
+
- ScrollBar - documentation to be written
+ ScrollBar - svg:rect based scrollbar
@@ -6375,15 +6325,13 @@
let range = this.range;
- let size = Math.max(this.range * this.mincursize, Math.min(this.size, range));
+ let size = Math.max(range * this.mincursize, Math.min(this.size, range));
let maxh = this.range_elt.height.baseVal.value;
let pixels = maxh;
- let units = range;
-
- return [size, maxh, range, pixels, units];
+ return [size, maxh, range, pixels];
}
@@ -6395,11 +6343,11 @@
return;
- let [size, maxh, range, pixels, units] = this.get_ratios();
-
-
-
- let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range-size) * pixels / units);
+ let [size, maxh, range, pixels] = this.get_ratios();
+
+
+
+ let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range-size) * pixels / range);
let new_height = Math.round(maxh * size/range);
@@ -6485,7 +6433,7 @@
drag(e) {
- let [size, maxh, range, pixels, units] = this.get_ratios();
+ let [size, maxh, range, pixels] = this.get_ratios();
if(pixels == 0) return;
@@ -6493,7 +6441,7 @@
let movement = point.matrixTransform(this.invctm).y;
- this.dragpos += movement * units / pixels;
+ this.dragpos += movement * range / pixels;
this.apply_position(this.dragpos);
@@ -7332,6 +7280,87 @@
],
+
+
+
+
+
+ TextList widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a TextList, clone (svg:use) one of the items inside the widget
+
+ that expects a TextList.
+
+
+
+ In this list, (translated) text content is what matters. Nevertheless
+
+ text style of the cloned item will be applied in client widget.
+
+
+
+ A named list of ordered texts
+
+
+
+
+
+ texts: [
+
+
+ id("
+
+ "),
+
+
+ ].reverse(),
+
+
+
+
+
+
+
+ TextStyleList widget is a svg:group, list items are labeled elements
+
+ in that group.
+
+
+
+ To use a TextStyleList, clone (svg:use) one of the items inside the widget
+
+ that expects a TextStyleList.
+
+
+
+ In this list, only style matters. Text content is ignored.
+
+
+
+ A named list of named texts
+
+
+
+
+
+ styles: {
+
+
+
+
+
+ : "
+
+ ",
+
+
+ },
+
+
@@ -7488,6 +7517,470 @@
//
+ /* https://github.com/alexei/sprintf.js/blob/master/src/sprintf.js */
+
+ /* global window, exports, define */
+
+
+
+ !function() {
+
+ 'use strict'
+
+
+
+ var re = {
+
+ not_string: /[^s]/,
+
+ not_bool: /[^t]/,
+
+ not_type: /[^T]/,
+
+ not_primitive: /[^v]/,
+
+ number: /[diefg]/,
+
+ numeric_arg: /[bcdiefguxX]/,
+
+ json: /[j]/,
+
+ not_json: /[^j]/,
+
+ text: /^[^%]+/,
+
+ modulo: /^%{2}/,
+
+ placeholder: /^%(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
+
+ key: /^([a-z_][a-z_\d]*)/i,
+
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
+
+ index_access: /^\[(\d+)\]/,
+
+ sign: /^[+-]/
+
+ }
+
+
+
+ function sprintf(key) {
+
+ // arguments is not an array, but should be fine for this call
+
+ return sprintf_format(sprintf_parse(key), arguments)
+
+ }
+
+
+
+ function vsprintf(fmt, argv) {
+
+ return sprintf.apply(null, [fmt].concat(argv || []))
+
+ }
+
+
+
+ function sprintf_format(parse_tree, argv) {
+
+ var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
+
+ for (i = 0; i < tree_length; i++) {
+
+ if (typeof parse_tree[i] === 'string') {
+
+ output += parse_tree[i]
+
+ }
+
+ else if (typeof parse_tree[i] === 'object') {
+
+ ph = parse_tree[i] // convenience purposes only
+
+ if (ph.keys) { // keyword argument
+
+ arg = argv[cursor]
+
+ for (k = 0; k < ph.keys.length; k++) {
+
+ if (arg == undefined) {
+
+ throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
+
+ }
+
+ arg = arg[ph.keys[k]]
+
+ }
+
+ }
+
+ else if (ph.param_no) { // positional argument (explicit)
+
+ arg = argv[ph.param_no]
+
+ }
+
+ else { // positional argument (implicit)
+
+ arg = argv[cursor++]
+
+ }
+
+
+
+ if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
+
+ arg = arg()
+
+ }
+
+
+
+ if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
+
+ throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
+
+ }
+
+
+
+ if (re.number.test(ph.type)) {
+
+ is_positive = arg >= 0
+
+ }
+
+
+
+ switch (ph.type) {
+
+ case 'b':
+
+ arg = parseInt(arg, 10).toString(2)
+
+ break
+
+ case 'c':
+
+ arg = String.fromCharCode(parseInt(arg, 10))
+
+ break
+
+ case 'd':
+
+ case 'i':
+
+ arg = parseInt(arg, 10)
+
+ break
+
+ case 'j':
+
+ arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
+
+ break
+
+ case 'e':
+
+ arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
+
+ break
+
+ case 'f':
+
+ arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
+
+ break
+
+ case 'g':
+
+ arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
+
+ break
+
+ case 'o':
+
+ arg = (parseInt(arg, 10) >>> 0).toString(8)
+
+ break
+
+ case 's':
+
+ arg = String(arg)
+
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+
+ break
+
+ case 't':
+
+ arg = String(!!arg)
+
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+
+ break
+
+ case 'T':
+
+ arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
+
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+
+ break
+
+ case 'u':
+
+ arg = parseInt(arg, 10) >>> 0
+
+ break
+
+ case 'v':
+
+ arg = arg.valueOf()
+
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+
+ break
+
+ case 'x':
+
+ arg = (parseInt(arg, 10) >>> 0).toString(16)
+
+ break
+
+ case 'X':
+
+ arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
+
+ break
+
+ }
+
+ if (re.json.test(ph.type)) {
+
+ output += arg
+
+ }
+
+ else {
+
+ if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
+
+ sign = is_positive ? '+' : '-'
+
+ arg = arg.toString().replace(re.sign, '')
+
+ }
+
+ else {
+
+ sign = ''
+
+ }
+
+ pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
+
+ pad_length = ph.width - (sign + arg).length
+
+ pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
+
+ output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
+
+ }
+
+ }
+
+ }
+
+ return output
+
+ }
+
+
+
+ var sprintf_cache = Object.create(null)
+
+
+
+ function sprintf_parse(fmt) {
+
+ if (sprintf_cache[fmt]) {
+
+ return sprintf_cache[fmt]
+
+ }
+
+
+
+ var _fmt = fmt, match, parse_tree = [], arg_names = 0
+
+ while (_fmt) {
+
+ if ((match = re.text.exec(_fmt)) !== null) {
+
+ parse_tree.push(match[0])
+
+ }
+
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
+
+ parse_tree.push('%')
+
+ }
+
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
+
+ if (match[2]) {
+
+ arg_names |= 1
+
+ var field_list = [], replacement_field = match[2], field_match = []
+
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
+
+ field_list.push(field_match[1])
+
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
+
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
+
+ field_list.push(field_match[1])
+
+ }
+
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
+
+ field_list.push(field_match[1])
+
+ }
+
+ else {
+
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
+
+ }
+
+ }
+
+ }
+
+ else {
+
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
+
+ }
+
+ match[2] = field_list
+
+ }
+
+ else {
+
+ arg_names |= 2
+
+ }
+
+ if (arg_names === 3) {
+
+ throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
+
+ }
+
+
+
+ parse_tree.push(
+
+ {
+
+ placeholder: match[0],
+
+ param_no: match[1],
+
+ keys: match[2],
+
+ sign: match[3],
+
+ pad_char: match[4],
+
+ align: match[5],
+
+ width: match[6],
+
+ precision: match[7],
+
+ type: match[8]
+
+ }
+
+ )
+
+ }
+
+ else {
+
+ throw new SyntaxError('[sprintf] unexpected placeholder')
+
+ }
+
+ _fmt = _fmt.substring(match[0].length)
+
+ }
+
+ return sprintf_cache[fmt] = parse_tree
+
+ }
+
+
+
+ /**
+
+ * export to either browser or node.js
+
+ */
+
+ /* eslint-disable quote-props */
+
+ if (typeof exports !== 'undefined') {
+
+ exports['sprintf'] = sprintf
+
+ exports['vsprintf'] = vsprintf
+
+ }
+
+ if (typeof window !== 'undefined') {
+
+ window['sprintf'] = sprintf
+
+ window['vsprintf'] = vsprintf
+
+
+
+ if (typeof define === 'function' && define['amd']) {
+
+ define(function() {
+
+ return {
+
+ 'sprintf': sprintf,
+
+ 'vsprintf': vsprintf
+
+ }
+
+ })
+
+ }
+
+ }
+
+ /* eslint-enable quote-props */
+
+ }(); // eslint-disable-line
+
// svghmi.js
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/gen_index_xhtml.ysl2
--- a/svghmi/gen_index_xhtml.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/gen_index_xhtml.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -49,6 +49,8 @@
include geometry.ysl2
+ include lists.ysl2
+
include detachable_pages.ysl2
include inline_svg.ysl2
@@ -92,6 +94,8 @@
| \n//\n//\n// Statements that needs to be at the end \n//\n//
apply "document('')/*/epilogue:*";
+ include text sprintf.js
+
include text svghmi.js
}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/lists.ysl2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/lists.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,33 @@
+// lists.ysl2
+//
+// compute list widget related constants
+// for details, refer to :
+// widget_list.ysl2
+// widget_textlist.ysl2
+// widget_textstulelist.ysl2
+
+
+// List widgets
+
+const "hmi_lists_descs", "$parsed_widgets/widget[@type = 'List']";
+const "hmi_lists", "$hmi_elements[@id = $hmi_lists_descs/@id]";
+
+
+// TextList widget
+
+const "hmi_textlists_descs", "$parsed_widgets/widget[@type = 'TextList']";
+const "hmi_textlists", "$hmi_elements[@id = $hmi_textlists_descs/@id]";
+
+// TextStyleList widgets
+
+const "hmi_textstylelists_descs", "$parsed_widgets/widget[@type = 'TextStyleList']";
+const "hmi_textstylelists", "$hmi_elements[@id = $hmi_textstylelists_descs/@id]";
+
+const "textstylelist_related" foreach "$hmi_textstylelists" list {
+ attrib "listid" value "@id";
+ foreach "func:refered_elements(.)" elt {
+ attrib "eltid" value "@id";
+ }
+}
+const "textstylelist_related_ns", "exsl:node-set($textstylelist_related)";
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/sprintf.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/sprintf.js Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,232 @@
+/* https://github.com/alexei/sprintf.js/blob/master/src/sprintf.js */
+/* global window, exports, define */
+
+!function() {
+ 'use strict'
+
+ var re = {
+ not_string: /[^s]/,
+ not_bool: /[^t]/,
+ not_type: /[^T]/,
+ not_primitive: /[^v]/,
+ number: /[diefg]/,
+ numeric_arg: /[bcdiefguxX]/,
+ json: /[j]/,
+ not_json: /[^j]/,
+ text: /^[^\x25]+/,
+ modulo: /^\x25{2}/,
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
+ key: /^([a-z_][a-z_\d]*)/i,
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
+ index_access: /^\[(\d+)\]/,
+ sign: /^[+-]/
+ }
+
+ function sprintf(key) {
+ // arguments is not an array, but should be fine for this call
+ return sprintf_format(sprintf_parse(key), arguments)
+ }
+
+ function vsprintf(fmt, argv) {
+ return sprintf.apply(null, [fmt].concat(argv || []))
+ }
+
+ function sprintf_format(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
+ for (i = 0; i < tree_length; i++) {
+ if (typeof parse_tree[i] === 'string') {
+ output += parse_tree[i]
+ }
+ else if (typeof parse_tree[i] === 'object') {
+ ph = parse_tree[i] // convenience purposes only
+ if (ph.keys) { // keyword argument
+ arg = argv[cursor]
+ for (k = 0; k < ph.keys.length; k++) {
+ if (arg == undefined) {
+ throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
+ }
+ arg = arg[ph.keys[k]]
+ }
+ }
+ else if (ph.param_no) { // positional argument (explicit)
+ arg = argv[ph.param_no]
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++]
+ }
+
+ if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
+ arg = arg()
+ }
+
+ if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
+ throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
+ }
+
+ if (re.number.test(ph.type)) {
+ is_positive = arg >= 0
+ }
+
+ switch (ph.type) {
+ case 'b':
+ arg = parseInt(arg, 10).toString(2)
+ break
+ case 'c':
+ arg = String.fromCharCode(parseInt(arg, 10))
+ break
+ case 'd':
+ case 'i':
+ arg = parseInt(arg, 10)
+ break
+ case 'j':
+ arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
+ break
+ case 'e':
+ arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
+ break
+ case 'f':
+ arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
+ break
+ case 'g':
+ arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
+ break
+ case 'o':
+ arg = (parseInt(arg, 10) >>> 0).toString(8)
+ break
+ case 's':
+ arg = String(arg)
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+ break
+ case 't':
+ arg = String(!!arg)
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+ break
+ case 'T':
+ arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+ break
+ case 'u':
+ arg = parseInt(arg, 10) >>> 0
+ break
+ case 'v':
+ arg = arg.valueOf()
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
+ break
+ case 'x':
+ arg = (parseInt(arg, 10) >>> 0).toString(16)
+ break
+ case 'X':
+ arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
+ break
+ }
+ if (re.json.test(ph.type)) {
+ output += arg
+ }
+ else {
+ if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
+ sign = is_positive ? '+' : '-'
+ arg = arg.toString().replace(re.sign, '')
+ }
+ else {
+ sign = ''
+ }
+ pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
+ pad_length = ph.width - (sign + arg).length
+ pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
+ output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
+ }
+ }
+ }
+ return output
+ }
+
+ var sprintf_cache = Object.create(null)
+
+ function sprintf_parse(fmt) {
+ if (sprintf_cache[fmt]) {
+ return sprintf_cache[fmt]
+ }
+
+ var _fmt = fmt, match, parse_tree = [], arg_names = 0
+ while (_fmt) {
+ if ((match = re.text.exec(_fmt)) !== null) {
+ parse_tree.push(match[0])
+ }
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
+ parse_tree.push('%')
+ }
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1
+ var field_list = [], replacement_field = match[2], field_match = []
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1])
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1])
+ }
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1])
+ }
+ else {
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
+ }
+ }
+ }
+ else {
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
+ }
+ match[2] = field_list
+ }
+ else {
+ arg_names |= 2
+ }
+ if (arg_names === 3) {
+ throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
+ }
+
+ parse_tree.push(
+ {
+ placeholder: match[0],
+ param_no: match[1],
+ keys: match[2],
+ sign: match[3],
+ pad_char: match[4],
+ align: match[5],
+ width: match[6],
+ precision: match[7],
+ type: match[8]
+ }
+ )
+ }
+ else {
+ throw new SyntaxError('[sprintf] unexpected placeholder')
+ }
+ _fmt = _fmt.substring(match[0].length)
+ }
+ return sprintf_cache[fmt] = parse_tree
+ }
+
+ /**
+ * export to either browser or node.js
+ */
+ /* eslint-disable quote-props */
+ if (typeof exports !== 'undefined') {
+ exports['sprintf'] = sprintf
+ exports['vsprintf'] = vsprintf
+ }
+ if (typeof window !== 'undefined') {
+ window['sprintf'] = sprintf
+ window['vsprintf'] = vsprintf
+
+ if (typeof define === 'function' && define['amd']) {
+ define(function() {
+ return {
+ 'sprintf': sprintf,
+ 'vsprintf': vsprintf
+ }
+ })
+ }
+ }
+ /* eslint-enable quote-props */
+}(); // eslint-disable-line
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/svghmi.py
--- a/svghmi/svghmi.py Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/svghmi.py Wed Oct 20 08:57:07 2021 +0200
@@ -294,14 +294,19 @@
return ret
+if wx.Platform == '__WXMSW__':
+ browser_launch_cmd="cmd.exe /c 'start msedge {url}'"
+else:
+ browser_launch_cmd="chromium {url}"
+
class SVGHMI(object):
XSD = """
-
-
-
+
+
+
@@ -333,7 +338,7 @@
- """
+ """%browser_launch_cmd
EditorType = SVGHMIEditor
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/svghmi_server.py
--- a/svghmi/svghmi_server.py Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/svghmi_server.py Wed Oct 20 08:57:07 2021 +0200
@@ -241,6 +241,9 @@
svghmi_servers = {}
svghmi_send_thread = None
+# python's errno on windows seems to have no ENODATA
+ENODATA = errno.ENODATA if hasattr(errno,"ENODATA") else None
+
def SendThreadProc():
global svghmi_session_manager
size = ctypes.c_uint32()
@@ -255,7 +258,7 @@
if res == 0:
svghmi_session.sendMessage(
ctypes.string_at(ptr.value,size.value))
- elif res == errno.ENODATA:
+ elif res == ENODATA:
# this happens when there is no data after wakeup
# because of hmi data refresh period longer than
# PLC common ticktime
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/ui.py
--- a/svghmi/ui.py Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/ui.py Wed Oct 20 08:57:07 2021 +0200
@@ -57,13 +57,13 @@
display_name = ('{} (class={})'.format(c.name, c.hmiclass)) \
if c.hmiclass is not None else c.name
tc_child = self.AppendItem(current_tc_root, display_name)
- self.SetPyData(tc_child, c)
+ self.SetItemData(tc_child, c)
self._recurseTree(c,tc_child)
else:
display_name = '{} {}'.format(c.nodetype[4:], c.name)
tc_child = self.AppendItem(current_tc_root, display_name)
- self.SetPyData(tc_child, c)
+ self.SetItemData(tc_child, c)
def OnTreeNodeSelection(self, event):
items = self.GetSelections()
@@ -105,7 +105,7 @@
root_display_name = _("Please build to see HMI Tree") \
if hmi_tree_root is None else "HMI"
self.root = self.AddRoot(root_display_name)
- self.SetPyData(self.root, hmi_tree_root)
+ self.SetItemData(self.root, hmi_tree_root)
if hmi_tree_root is not None:
self._recurseTree(hmi_tree_root, self.root)
@@ -145,11 +145,11 @@
for d in dirlist:
current_tc_root = self.AppendItem(current_tc_root, d)
res.append(current_tc_root)
- self.SetPyData(current_tc_root, None)
+ self.SetItemData(current_tc_root, None)
dirlist = []
res.pop()
tc_child = self.AppendItem(current_tc_root, f)
- self.SetPyData(tc_child, p)
+ self.SetItemData(tc_child, p)
return res
def MakeTree(self, lib_dir = None):
@@ -162,7 +162,7 @@
root_display_name = _("Please select widget library directory") \
if lib_dir is None else os.path.basename(lib_dir)
self.root = self.AddRoot(root_display_name)
- self.SetPyData(self.root, None)
+ self.SetItemData(self.root, None)
if lib_dir is not None and os.path.exists(lib_dir):
self._recurseTree(lib_dir, self.root, [])
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_circularbar.ysl2
--- a/svghmi/widget_circularbar.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_circularbar.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -9,14 +9,12 @@
If "min" a "max" labeled texts are provided, then they are used as
respective minimum and maximum value. Otherwise, value is expected to be
in between 0 and 100.
-
- If "value" labeled text is found, then its content is replaced by value.
||
shortdesc > Change end angle of Inkscape's arc
- // TODO: add min/max arguments
- // TODO: add printf-like format
+ arg name="min" count="optional" accepts="int,real" > minimum value
+ arg name="max" count="optional" accepts="int,real" > maximum value
path name="value" accepts="HMI_INT,HMI_REAL" > Value to display
@@ -52,6 +50,9 @@
}
init() {
+ if(this.args.length >= 2)
+ [this.min, this.max]=this.args;
+
let [start, end, cx, cy, rx, ry] = ["start", "end", "cx", "cy", "rx", "ry"].
map(tag=>Number(this.path_elt.getAttribute('sodipodi:'+tag)))
@@ -74,5 +75,5 @@
widget_defs("CircularBar") {
labels("path");
- optional_labels("value min max");
+ optional_labels("min max");
}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_display.ysl2
--- a/svghmi/widget_display.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_display.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -72,239 +72,3 @@
| },
}
}
-
-emit "preamble:display"
-||
-/* https://github.com/alexei/sprintf.js/blob/master/src/sprintf.js */
-/* global window, exports, define */
-
-!function() {
- 'use strict'
-
- var re = {
- not_string: /[^s]/,
- not_bool: /[^t]/,
- not_type: /[^T]/,
- not_primitive: /[^v]/,
- number: /[diefg]/,
- numeric_arg: /[bcdiefguxX]/,
- json: /[j]/,
- not_json: /[^j]/,
- text: /^[^\x25]+/,
- modulo: /^\x25{2}/,
- placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
- key: /^([a-z_][a-z_\d]*)/i,
- key_access: /^\.([a-z_][a-z_\d]*)/i,
- index_access: /^\[(\d+)\]/,
- sign: /^[+-]/
- }
-
- function sprintf(key) {
- // arguments is not an array, but should be fine for this call
- return sprintf_format(sprintf_parse(key), arguments)
- }
-
- function vsprintf(fmt, argv) {
- return sprintf.apply(null, [fmt].concat(argv || []))
- }
-
- function sprintf_format(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
- for (i = 0; i < tree_length; i++) {
- if (typeof parse_tree[i] === 'string') {
- output += parse_tree[i]
- }
- else if (typeof parse_tree[i] === 'object') {
- ph = parse_tree[i] // convenience purposes only
- if (ph.keys) { // keyword argument
- arg = argv[cursor]
- for (k = 0; k < ph.keys.length; k++) {
- if (arg == undefined) {
- throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
- }
- arg = arg[ph.keys[k]]
- }
- }
- else if (ph.param_no) { // positional argument (explicit)
- arg = argv[ph.param_no]
- }
- else { // positional argument (implicit)
- arg = argv[cursor++]
- }
-
- if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
- arg = arg()
- }
-
- if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
- throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
- }
-
- if (re.number.test(ph.type)) {
- is_positive = arg >= 0
- }
-
- switch (ph.type) {
- case 'b':
- arg = parseInt(arg, 10).toString(2)
- break
- case 'c':
- arg = String.fromCharCode(parseInt(arg, 10))
- break
- case 'd':
- case 'i':
- arg = parseInt(arg, 10)
- break
- case 'j':
- arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
- break
- case 'e':
- arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
- break
- case 'f':
- arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
- break
- case 'g':
- arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
- break
- case 'o':
- arg = (parseInt(arg, 10) >>> 0).toString(8)
- break
- case 's':
- arg = String(arg)
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
- break
- case 't':
- arg = String(!!arg)
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
- break
- case 'T':
- arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
- break
- case 'u':
- arg = parseInt(arg, 10) >>> 0
- break
- case 'v':
- arg = arg.valueOf()
- arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
- break
- case 'x':
- arg = (parseInt(arg, 10) >>> 0).toString(16)
- break
- case 'X':
- arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
- break
- }
- if (re.json.test(ph.type)) {
- output += arg
- }
- else {
- if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
- sign = is_positive ? '+' : '-'
- arg = arg.toString().replace(re.sign, '')
- }
- else {
- sign = ''
- }
- pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
- pad_length = ph.width - (sign + arg).length
- pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
- output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
- }
- }
- }
- return output
- }
-
- var sprintf_cache = Object.create(null)
-
- function sprintf_parse(fmt) {
- if (sprintf_cache[fmt]) {
- return sprintf_cache[fmt]
- }
-
- var _fmt = fmt, match, parse_tree = [], arg_names = 0
- while (_fmt) {
- if ((match = re.text.exec(_fmt)) !== null) {
- parse_tree.push(match[0])
- }
- else if ((match = re.modulo.exec(_fmt)) !== null) {
- parse_tree.push('%')
- }
- else if ((match = re.placeholder.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1
- var field_list = [], replacement_field = match[2], field_match = []
- if ((field_match = re.key.exec(replacement_field)) !== null) {
- field_list.push(field_match[1])
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = re.key_access.exec(replacement_field)) !== null) {
- field_list.push(field_match[1])
- }
- else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
- field_list.push(field_match[1])
- }
- else {
- throw new SyntaxError('[sprintf] failed to parse named argument key')
- }
- }
- }
- else {
- throw new SyntaxError('[sprintf] failed to parse named argument key')
- }
- match[2] = field_list
- }
- else {
- arg_names |= 2
- }
- if (arg_names === 3) {
- throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
- }
-
- parse_tree.push(
- {
- placeholder: match[0],
- param_no: match[1],
- keys: match[2],
- sign: match[3],
- pad_char: match[4],
- align: match[5],
- width: match[6],
- precision: match[7],
- type: match[8]
- }
- )
- }
- else {
- throw new SyntaxError('[sprintf] unexpected placeholder')
- }
- _fmt = _fmt.substring(match[0].length)
- }
- return sprintf_cache[fmt] = parse_tree
- }
-
- /**
- * export to either browser or node.js
- */
- /* eslint-disable quote-props */
- if (typeof exports !== 'undefined') {
- exports['sprintf'] = sprintf
- exports['vsprintf'] = vsprintf
- }
- if (typeof window !== 'undefined') {
- window['sprintf'] = sprintf
- window['vsprintf'] = vsprintf
-
- if (typeof define === 'function' && define['amd']) {
- define(function() {
- return {
- 'sprintf': sprintf,
- 'vsprintf': vsprintf
- }
- })
- }
- }
- /* eslint-enable quote-props */
-}(); // eslint-disable-line
-||
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_dropdown.ysl2
--- a/svghmi/widget_dropdown.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_dropdown.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -7,16 +7,21 @@
DropDown widget let user select an entry in a list of texts, given as
arguments. Single variable path is index of selection.
- It needs "text" (svg:text), "box" (svg:rect), "button" (svg:*),
- and "highlight" (svg:rect) labeled elements.
+ It needs "text" (svg:text or svg:use referring to svg:text),
+ "box" (svg:rect), "button" (svg:*), and "highlight" (svg:rect)
+ labeled elements.
When user clicks on "button", "text" is duplicated to display enties in the
limit of available space in page, and "box" is extended to contain all
texts. "highlight" is moved over pre-selected entry.
- When only one argument is given, and argment contains "#langs" then list of
- texts is automatically set to the list of human-readable languages supported
- by this HMI.
+ When only one argument is given and argment contains "#langs" then list of
+ texts is automatically set to the human-readable list of supported
+ languages by this HMI.
+
+ If "text" labeled element is of type svg:use and refers to a svg:text
+ element part of a TextList widget, no argument is expected. In that case
+ list of texts is set to TextList content.
||
shortdesc > Let user select text entry in a drop-down menu
@@ -34,6 +39,7 @@
if(!this.opened) this.set_selection(value);
}
init() {
+ this.init_specific();
this.button_elt.onclick = this.on_button_click.bind(this);
// Save original size of rectangle
this.box_bbox = this.box_elt.getBBox()
@@ -79,7 +85,7 @@
let display_str;
if(value >= 0 && value < this.content.length){
// if valid selection resolve content
- display_str = this.content[value];
+ display_str = gettext(this.content[value]);
this.last_selection = value;
} else {
// otherwise show problem
@@ -185,7 +191,7 @@
let c = 0;
for(let item of this.content){
let span=spans[c];
- span.textContent = item;
+ span.textContent = gettext(item);
let sel = c;
this.make_clickable(span, (evt) => this.bound_on_selection_click(sel));
c++;
@@ -251,7 +257,7 @@
span.setAttribute("dx", (m.width - o.width)/2);
// otherwise normal content
}else{
- span.textContent = this.content[i];
+ span.textContent = gettext(this.content[i]);
let sel = i;
onclickfunc = (evt) => this.bound_on_selection_click(sel);
span.removeAttribute("dx");
@@ -360,19 +366,43 @@
}
widget_defs("DropDown") {
- labels("text box button highlight");
+ labels("box button highlight");
// It is assumed that list content conforms to Array interface.
- > content:
+ const "text_elt","$hmi_element//*[@inkscape:label='text'][1]";
+ | init_specific: function() {
choose{
// special case when used for language selection
when "count(arg) = 1 and arg[1]/@value = '#langs'" {
- > langs
+ | this.text_elt = id("«$text_elt/@id»");
+ | this.content = langs;
+ }
+ when "count(arg) = 0"{
+ if "not($text_elt[self::svg:use])"
+ error > No argrument for HMI:DropDown widget id="«$hmi_element/@id»" and "text" labeled element is not a svg:use element
+ const "real_text_elt","$result_widgets[@id = $hmi_element/@id]//*[@original=$text_elt/@id]/svg:text";
+ | this.text_elt = id("«$real_text_elt/@id»");
+ const "from_list_id", "substring-after($text_elt/@xlink:href,'#')";
+ const "from_list", "$hmi_textlists[(@id | */@id) = $from_list_id]";
+ if "count($from_list) = 0"
+ error > HMI:DropDown widget id="«$hmi_element/@id»" "text" labeled element does not point to a svg:text owned by a HMI:List widget
+ | this.content = hmi_widgets["«$from_list/@id»"].texts;
}
otherwise {
- > [\n
+ | this.text_elt = id("«$text_elt/@id»");
+ | this.content = [
foreach "arg" | "«@value»",
- > ]
+ | ];
}
}
- > ,\n
+ | }
}
+
+emit "declarations:DropDown"
+||
+function gettext(o) {
+ if(typeof(o) == "string"){
+ return o;
+ }
+ return svg_text_to_multiline(o);
+};
+||
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_jsontable.ysl2
--- a/svghmi/widget_jsontable.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_jsontable.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -108,17 +108,6 @@
}
-const "hmi_textstylelists_descs", "$parsed_widgets/widget[@type = 'TextStyleList']";
-const "hmi_textstylelists", "$hmi_elements[@id = $hmi_textstylelists_descs/@id]";
-
-const "textstylelist_related" foreach "$hmi_textstylelists" list {
- attrib "listid" value "@id";
- foreach "func:refered_elements(.)" elt {
- attrib "eltid" value "@id";
- }
-}
-const "textstylelist_related_ns", "exsl:node-set($textstylelist_related)";
-
def "func:json_expressions" {
param "expressions";
param "label";
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_list.ysl2
--- a/svghmi/widget_list.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_list.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -1,6 +1,22 @@
// widget_list.ysl2
+
widget_desc("List") {
- // TODO
+ longdesc
+ ||
+ List widget is a svg:group, list items are labeled elements
+ in that group.
+
+ To use a List, clone (svg:use) one of the items inside the widget that
+ expects a List.
+
+ Positions of items are relative to each other, and they must all be in the
+ same place. In order to make editing easier it is therefore recommanded to
+ make stacked clones of svg elements spread nearby the list.
+ ||
+
+ shortdesc > A named list of named graphical elements
+
+ arg name="listname"
}
widget_defs("List") {
@@ -11,15 +27,3 @@
| },
}
-widget_defs("TextStyleList") {
- // TODO
-}
-
-widget_defs("TextStyleList") {
- | styles: {
- foreach "$hmi_element/*[@inkscape:label]" {
- const "style", "func:refered_elements(.)[self::svg:text]/@style";
- | «@inkscape:label»: "«$style»",
- }
- | },
-}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_meter.ysl2
--- a/svghmi/widget_meter.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_meter.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -10,8 +10,6 @@
are provided, or if first and second argument are given, then they are used
as respective minimum and maximum value. Otherwise, value is expected to be
in between 0 and 100.
-
- If "value" labeled text is found, then its content is replaced by value.
||
shortdesc > Moves "needle" along "range"
@@ -20,8 +18,6 @@
arg name="max" count="optional" accepts="int,real" > maximum value
- // TODO: add printf-like format
-
path name="value" accepts="HMI_INT,HMI_REAL" > Value to display
}
@@ -59,7 +55,7 @@
widget_defs("Meter") {
labels("needle range");
- optional_labels("value min max");
+ optional_labels("min max");
}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_pathslider.ysl2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widget_pathslider.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,173 @@
+// widget_pathslider.ysl2
+widget_desc("PathSlider") {
+ longdesc
+ ||
+ PathSlider -
+ ||
+
+ shortdesc > Slide an SVG element along a path by dragging it
+
+ path name="value" accepts="HMI_INT,HMI_REAL" > value
+ path name="min" count="optional" accepts="HMI_INT,HMI_REAL" > min
+ path name="max" count="optional" accepts="HMI_INT,HMI_REAL" > max
+
+ arg name="min" count="optional" accepts="int,real" > minimum value
+ arg name="max" count="optional" accepts="int,real" > maximum value
+}
+
+widget_class("PathSlider") {
+ ||
+ frequency = 10;
+ position = undefined;
+ min = 0;
+ max = 100;
+ scannedPoints = [];
+ pathLength = undefined;
+ precision = undefined;
+ origPt = undefined;
+
+
+ scanPath() {
+ this.pathLength = this.path_elt.getTotalLength();
+ this.precision = Math.floor(this.pathLength / 10);
+
+ // save linear scan for coarse approximation
+ for (var scanLength = 0; scanLength <= this.pathLength; scanLength += this.precision) {
+ this.scannedPoints.push([this.path_elt.getPointAtLength(scanLength), scanLength]);
+ }
+ [this.origPt,] = this.scannedPoints[0];
+ }
+
+ closestPoint(point) {
+ var bestPoint,
+ bestLength,
+ bestDistance = Infinity,
+ scanDistance;
+
+ // use linear scan for coarse approximation
+ for (let [scanPoint, scanLength] of this.scannedPoints){
+ if ((scanDistance = distance2(scanPoint)) < bestDistance) {
+ bestPoint = scanPoint,
+ bestLength = scanLength,
+ bestDistance = scanDistance;
+ }
+ }
+
+ // binary search for more precise estimate
+ let precision = this.precision / 2;
+ while (precision > 0.5) {
+ var beforePoint,
+ afterPoint,
+ beforeLength,
+ afterLength,
+ beforeDistance,
+ afterDistance;
+ if ((beforeLength = bestLength - precision) >= 0 &&
+ (beforeDistance = distance2(beforePoint = this.path_elt.getPointAtLength(beforeLength))) < bestDistance) {
+ bestPoint = beforePoint,
+ bestLength = beforeLength,
+ bestDistance = beforeDistance;
+ } else if ((afterLength = bestLength + precision) <= this.pathLength &&
+ (afterDistance = distance2(afterPoint = this.path_elt.getPointAtLength(afterLength))) < bestDistance) {
+ bestPoint = afterPoint,
+ bestLength = afterLength,
+ bestDistance = afterDistance;
+ }
+ precision /= 2;
+ }
+
+ return [bestPoint, bestLength];
+
+ function distance2(p) {
+ var dx = p.x - point.x,
+ dy = p.y - point.y;
+ return dx * dx + dy * dy;
+ }
+ }
+
+ dispatch(value,oldval, index) {
+ switch(index) {
+ case 0:
+ this.position = value;
+ break;
+ case 1:
+ this.min = value;
+ break;
+ case 2:
+ this.max = value;
+ break;
+ }
+
+ this.request_animate();
+ }
+
+ get_current_point(){
+ let currLength = this.pathLength * (this.position - this.min) / (this.max - this.min)
+ return this.path_elt.getPointAtLength(currLength);
+ }
+
+ animate(){
+ if(this.position == undefined)
+ return;
+
+ let currPt = this.get_current_point();
+ this.cursor_transform.setTranslate(currPt.x - this.origPt.x, currPt.y - this.origPt.y);
+ }
+
+ init() {
+ if(this.args.length == 2)
+ [this.min, this.max]=this.args;
+
+ this.scanPath();
+
+ this.cursor_transform = svg_root.createSVGTransform();
+
+ this.cursor_elt.transform.baseVal.appendItem(this.cursor_transform);
+
+ this.cursor_elt.onpointerdown = (e) => this.on_cursor_down(e);
+
+ this.bound_drag = this.drag.bind(this);
+ this.bound_drop = this.drop.bind(this);
+ }
+
+ start_dragging_from_event(e){
+ let clientPoint = new DOMPoint(e.clientX, e.clientY);
+ let point = clientPoint.matrixTransform(this.invctm);
+ let currPt = this.get_current_point();
+ this.draggingOffset = new DOMPoint(point.x - currPt.x , point.y - currPt.y);
+ }
+
+ apply_position_from_event(e){
+ let clientPoint = new DOMPoint(e.clientX, e.clientY);
+ let rawPoint = clientPoint.matrixTransform(this.invctm);
+ let point = new DOMPoint(rawPoint.x - this.draggingOffset.x , rawPoint.y - this.draggingOffset.y);
+ let [closestPoint, closestLength] = this.closestPoint(point);
+ let new_position = this.min + (this.max - this.min) * closestLength / this.pathLength;
+ this.position = Math.round(Math.max(Math.min(new_position, this.max), this.min));
+ this.apply_hmi_value(0, this.position);
+ }
+
+ on_cursor_down(e){
+ // get scrollbar -> root transform
+ let ctm = this.path_elt.getCTM();
+ // root -> path transform
+ this.invctm = ctm.inverse();
+ this.start_dragging_from_event(e);
+ svg_root.addEventListener("pointerup", this.bound_drop, true);
+ svg_root.addEventListener("pointermove", this.bound_drag, true);
+ }
+
+ drop(e) {
+ svg_root.removeEventListener("pointerup", this.bound_drop, true);
+ svg_root.removeEventListener("pointermove", this.bound_drag, true);
+ }
+
+ drag(e) {
+ this.apply_position_from_event(e);
+ }
+ ||
+}
+
+widget_defs("PathSlider") {
+ labels("cursor path");
+}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_scrollbar.ysl2
--- a/svghmi/widget_scrollbar.ysl2 Tue Oct 19 15:15:03 2021 +0200
+++ b/svghmi/widget_scrollbar.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -2,7 +2,7 @@
widget_desc("ScrollBar") {
longdesc
||
- ScrollBar - documentation to be written
+ ScrollBar - svg:rect based scrollbar
||
shortdesc > ScrollBar
@@ -39,19 +39,18 @@
get_ratios() {
let range = this.range;
- let size = Math.max(this.range * this.mincursize, Math.min(this.size, range));
+ let size = Math.max(range * this.mincursize, Math.min(this.size, range));
let maxh = this.range_elt.height.baseVal.value;
let pixels = maxh;
- let units = range;
- return [size, maxh, range, pixels, units];
+ return [size, maxh, range, pixels];
}
animate(){
if(this.position == undefined || this.range == undefined || this.size == undefined)
return;
- let [size, maxh, range, pixels, units] = this.get_ratios();
+ let [size, maxh, range, pixels] = this.get_ratios();
- let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range-size) * pixels / units);
+ let new_y = this.range_elt.y.baseVal.value + Math.round(Math.min(this.position,range-size) * pixels / range);
let new_height = Math.round(maxh * size/range);
this.cursor_elt.y.baseVal.value = new_y;
@@ -94,11 +93,11 @@
}
drag(e) {
- let [size, maxh, range, pixels, units] = this.get_ratios();
+ let [size, maxh, range, pixels] = this.get_ratios();
if(pixels == 0) return;
let point = new DOMPoint(e.movementX, e.movementY);
let movement = point.matrixTransform(this.invctm).y;
- this.dragpos += movement * units / pixels;
+ this.dragpos += movement * range / pixels;
this.apply_position(this.dragpos);
}
||
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_textlist.ysl2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widget_textlist.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,28 @@
+// widget_textlist.ysl2
+
+widget_desc("TextList") {
+ longdesc
+ ||
+ TextList widget is a svg:group, list items are labeled elements
+ in that group.
+
+ To use a TextList, clone (svg:use) one of the items inside the widget
+ that expects a TextList.
+
+ In this list, (translated) text content is what matters. Nevertheless
+ text style of the cloned item will be applied in client widget.
+ ||
+
+ shortdesc > A named list of ordered texts
+
+ arg name="listname"
+}
+
+widget_defs("TextList") {
+ | texts: [
+ foreach "func:refered_elements($hmi_element/*[@inkscape:label])[self::svg:text]" {
+ | id("«@id»"),
+ }
+ // could find a proper way in xpath to reverse()
+ | ].reverse(),
+}
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widget_textstylelist.ysl2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widget_textstylelist.ysl2 Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,28 @@
+// widget_textstylelist.ysl2
+
+widget_desc("TextStyleList") {
+ longdesc
+ ||
+ TextStyleList widget is a svg:group, list items are labeled elements
+ in that group.
+
+ To use a TextStyleList, clone (svg:use) one of the items inside the widget
+ that expects a TextStyleList.
+
+ In this list, only style matters. Text content is ignored.
+ ||
+
+ shortdesc > A named list of named texts
+
+ arg name="listname"
+}
+
+widget_defs("TextStyleList") {
+ | styles: {
+ foreach "$hmi_element/*[@inkscape:label]" {
+ const "style", "func:refered_elements(.)[self::svg:text]/@style";
+ | «@inkscape:label»: "«$style»",
+ }
+ | },
+}
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 svghmi/widgetlib/dropdown.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widgetlib/dropdown.svg Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,106 @@
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/README
--- a/svgui/README Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-SVGUI HMI
\ No newline at end of file
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/__init__.py
--- a/svgui/__init__.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-from __future__ import absolute_import
-from svgui.svgui import *
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/livesvg.js
--- a/svgui/livesvg.js Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-// import Nevow.Athena
-// import Divmod.Base
-
-function updateAttr(id, param, value) {
- Nevow.Athena.Widget.fromAthenaID(1).callRemote('HMIexec', 'setattr', id, param, value);
-}
-
-var svguiWidgets = new Array();
-
-var currentObject = null;
-function setCurrentObject(obj) {
- currentObject = obj;
-}
-function isCurrentObject(obj) {
- return currentObject == obj;
-}
-
-function getSVGElementById(id) {
- return document.getElementById(id);
-}
-
-function blockSVGElementDrag(element) {
- element.addEventListener("draggesture", function(event){event.stopPropagation()}, true);
-}
-
-LiveSVGPage.LiveSVGWidget = Nevow.Athena.Widget.subclass('LiveSVGPage.LiveSVGWidget');
-LiveSVGPage.LiveSVGWidget.methods(
-
- function handleEvent(self, evt) {
- if (currentObject != null) {
- currentObject.handleEvent(evt);
- }
- },
-
- function receiveData(self, data){
- dataReceived = json_parse(data);
- gadget = svguiWidgets[dataReceived.id]
- if (gadget) {
- gadget.updateValues(json_parse(dataReceived.kwargs));
- }
- //console.log("OBJET : " + dataReceived.back_id + " STATE : " + newState);
- },
-
- function init(self, arg1){
- //console.log("Object received : " + arg1);
- for (ind in arg1) {
- gad = json_parse(arg1[ind]);
- args = json_parse(gad.kwargs);
- gadget = new svguilib[gad.__class__](self, gad.id, args);
- svguiWidgets[gadget.id]=gadget;
- //console.log('GADGET :' + gadget);
- }
- var elements = document.getElementsByTagName("svg");
- for (var i = 0; i < elements.length; i++) {
- elements[i].addEventListener("mouseup", self, false);
- }
- //console.log("SVGUIWIDGETS : " + svguiWidgets);
- }
-);
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pous.xml
--- a/svgui/pous.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1428 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'createSVGUIControl("textControl", back_id="'
-
-
-
-
-
-
- back_id
-
-
-
-
-
-
- '")'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
- set_text
-
-
-
-
-
-
- 'setAttr('
-
-
-
-
-
-
- ',"text","'
-
-
-
-
-
-
- '")'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'createSVGUIControl("button",back_id="'
-
-
-
-
-
-
- '",sele_id="'
-
-
-
-
-
-
- ',active=True)'
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
- back_id
-
-
-
-
-
-
- sele_id
-
-
-
-
-
-
- set_state
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- state_in
-
-
-
-
-
-
-
-
-
-
- state_out
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
- 'setAttr('
-
-
-
-
-
-
- ',"state",'
-
-
-
-
-
-
- ')'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
- 'int(getAttr('
-
-
-
-
-
-
- ',"state",False))'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '",toggle='
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- toggle
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'createSVGUIControl("button",back_id="'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '",sele_id="'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
- '",toggle=True,active=False)'
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
- back_id
-
-
-
-
-
-
- sele_id
-
-
-
-
-
-
- 'setAttr('
-
-
-
-
-
-
- ',"state",'
-
-
-
-
-
-
- ')'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ID
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- state_in
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/__init__.py
--- a/svgui/pyjs/__init__.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-from __future__ import absolute_import
-from svgui.pyjs.pyjs import *
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/build.py
--- a/svgui/pyjs/build.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,774 +0,0 @@
-#!/usr/bin/env python
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-import sys
-import shutil
-import re
-import os
-from os.path import join, basename, abspath, split, isfile, isdir
-from hashlib import md5
-from optparse import OptionParser
-from six.moves import cStringIO
-
-from svgui.pyjs import pyjs
-
-
-usage = """
- usage: %prog [options]
-
-This is the command line builder for the pyjamas project, which can
-be used to build Ajax applications from Python.
-For more information, see the website at http://pyjs.org/
-"""
-
-# GWT1.2 Impl | GWT1.2 Output | Pyjamas 0.2 Platform | Pyjamas 0.2 Output
-# -------------+-----------------------+----------------------+----------------------
-# IE6 | ie6 | IE6 | ie6
-# Opera | opera | Opera | opera
-# Safari | safari | Safari | safari
-# -- | gecko1_8 | Mozilla | mozilla
-# -- | gecko | OldMoz | oldmoz
-# Standard | all | (default code) | all
-# Mozilla | gecko1_8, gecko | -- | --
-# Old | safari, gecko, opera | -- | --
-
-version = "%prog pyjamas version 2006-08-19"
-
-# these names in lowercase need match the strings
-# returned by "provider$user.agent" in order to be selected corretly
-app_platforms = ['IE6', 'Opera', 'OldMoz', 'Safari', 'Mozilla']
-
-# usually defaults to e.g. /usr/share/pyjamas
-_data_dir = os.path.join(pyjs.prefix, "share/pyjamas")
-
-
-# .cache.html files produces look like this
-CACHE_HTML_PAT = re.compile(r'^[a-z]*.[0-9a-f]{32}\.cache\.html$')
-
-# ok these are the three "default" library directories, containing
-# the builtins (str, List, Dict, ord, round, len, range etc.)
-# the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.)
-# and the contributed addons
-
-for p in ["library/builtins",
- "library",
- "addons"]:
- p = os.path.join(_data_dir, p)
- if os.path.isdir(p):
- pyjs.path.append(p)
-
-
-def read_boilerplate(data_dir, filename):
- return open(join(data_dir, "builder/boilerplate", filename)).read()
-
-
-def copy_boilerplate(data_dir, filename, output_dir):
- filename = join(data_dir, "builder/boilerplate", filename)
- shutil.copy(filename, output_dir)
-
-
-# taken and modified from python2.4
-def copytree_exists(src, dst, symlinks=False):
- if not os.path.exists(src):
- return
-
- names = os.listdir(src)
- try:
- os.mkdir(dst)
- except Exception:
- pass
-
- errors = []
- for name in names:
- if name.startswith('CVS'):
- continue
- if name.startswith('.git'):
- continue
- if name.startswith('.svn'):
- continue
-
- srcname = os.path.join(src, name)
- dstname = os.path.join(dst, name)
- try:
- if symlinks and os.path.islink(srcname):
- linkto = os.readlink(srcname)
- os.symlink(linkto, dstname)
- elif isdir(srcname):
- copytree_exists(srcname, dstname, symlinks)
- else:
- shutil.copy2(srcname, dstname)
- except (IOError, os.error) as why:
- errors.append((srcname, dstname, why))
- if errors:
- print(errors)
-
-
-def check_html_file(source_file, dest_path):
- """ Checks if a base HTML-file is available in the PyJamas
- output directory.
- If the HTML-file isn't available, it will be created.
-
- If a CSS-file with the same name is available
- in the output directory, a reference to this CSS-file
- is included.
-
- If no CSS-file is found, this function will look for a special
- CSS-file in the output directory, with the name
- "pyjamas_default.css", and if found it will be referenced
- in the generated HTML-file.
-
- [thank you to stef mientki for contributing this function]
- """
-
- base_html = """\
-
-
-
-
- %(css)s
- %(title)s
-
-
-
-
-
-"""
-
- filename = os.path.split(source_file)[1]
- mod_name = os.path.splitext(filename)[0]
- file_name = os.path.join(dest_path, mod_name + '.html')
-
- # if html file in output directory exists, leave it alone.
- if os.path.exists(file_name):
- return 0
-
- if os.path.exists(os.path.join(dest_path, mod_name + '.css')):
- css = ""
- elif os.path.exists(os.path.join(dest_path, 'pyjamas_default.css')):
- css = ""
-
- else:
- css = ''
-
- title = 'PyJamas Auto-Generated HTML file ' + mod_name
-
- base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css}
-
- fh = open(file_name, 'w')
- fh.write(base_html)
- fh.close()
-
- return 1
-
-
-def build(app_name, output, js_includes=(), debug=False, dynamic=0,
- data_dir=None, cache_buster=False, optimize=False):
-
- # make sure the output directory is always created in the current working
- # directory or at the place given if it is an absolute path.
- output = os.path.abspath(output)
- msg = "Building '%(app_name)s' to output directory '%(output)s'" % locals()
- if debug:
- msg += " with debugging statements"
- print(msg)
-
- # check the output directory
- if os.path.exists(output) and not os.path.isdir(output):
- print("Output destination %s exists and is not a directory" % output, file=sys.stderr)
- return
- if not os.path.isdir(output):
- try:
- print("Creating output directory")
- os.mkdir(output)
- except OSError as e:
- print("Exception creating output directory %s: %s" % (output, e), file=sys.stderr)
-
- # public dir
- for p in pyjs.path:
- pub_dir = join(p, 'public')
- if isdir(pub_dir):
- print("Copying: public directory of library %r" % p)
- copytree_exists(pub_dir, output)
-
- # AppName.html - can be in current or public directory
- html_input_filename = app_name + ".html"
- html_output_filename = join(output, basename(html_input_filename))
- if os.path.isfile(html_input_filename):
- if not os.path.isfile(html_output_filename) or \
- os.path.getmtime(html_input_filename) > \
- os.path.getmtime(html_output_filename):
- try:
- shutil.copy(html_input_filename, html_output_filename)
- except Exception:
- print("Warning: Missing module HTML file %s" % html_input_filename, file=sys.stderr)
-
- print("Copying: %(html_input_filename)s" % locals())
-
- if check_html_file(html_input_filename, output):
- print("Warning: Module HTML file %s has been auto-generated" % html_input_filename, file=sys.stderr)
-
- # pygwt.js
-
- print("Copying: pygwt.js")
-
- pygwt_js_template = read_boilerplate(data_dir, "pygwt.js")
- pygwt_js_output = open(join(output, "pygwt.js"), "w")
-
- print(pygwt_js_template, file=pygwt_js_output)
-
- pygwt_js_output.close()
-
- # Images
-
- print("Copying: Images and History")
- copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output)
- copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output)
- copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output)
- copy_boilerplate(data_dir, "corner_dialog_bottomleft_black.png", output)
- copy_boilerplate(data_dir, "corner_dialog_edge_black.png", output)
- copy_boilerplate(data_dir, "corner_dialog_topleft.png", output)
- copy_boilerplate(data_dir, "corner_dialog_topright.png", output)
- copy_boilerplate(data_dir, "corner_dialog_bottomright.png", output)
- copy_boilerplate(data_dir, "corner_dialog_bottomleft.png", output)
- copy_boilerplate(data_dir, "corner_dialog_edge.png", output)
- copy_boilerplate(data_dir, "tree_closed.gif", output)
- copy_boilerplate(data_dir, "tree_open.gif", output)
- copy_boilerplate(data_dir, "tree_white.gif", output)
- copy_boilerplate(data_dir, "history.html", output)
-
- # all.cache.html
- app_files = generateAppFiles(data_dir, js_includes, app_name, debug,
- output, dynamic, cache_buster, optimize)
-
- # AppName.nocache.html
-
- print("Creating: %(app_name)s.nocache.html" % locals())
-
- home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html")
- home_nocache_html_output = open(join(output, app_name + ".nocache.html"),
- "w")
-
- # the selector templ is added to the selectScript function
- select_tmpl = """O(["true","%s"],"%s");"""
- script_selectors = cStringIO()
-
- for platform, file_prefix in app_files:
- print(select_tmpl % (platform, file_prefix), file=script_selectors)
-
- print(
- home_nocache_html_template % dict(
- app_name=app_name,
- script_selectors=script_selectors.getvalue(),
- ), file=home_nocache_html_output)
-
- home_nocache_html_output.close()
-
- print("Done. You can run your app by opening '%(html_output_filename)s' in a browser" % locals())
-
-
-def generateAppFiles(data_dir, js_includes, app_name, debug, output, dynamic,
- cache_buster, optimize):
-
- all_cache_html_template = read_boilerplate(data_dir, "all.cache.html")
- mod_cache_html_template = read_boilerplate(data_dir, "mod.cache.html")
-
- # clean out the old ones first
- for name in os.listdir(output):
- if CACHE_HTML_PAT.match(name):
- p = join(output, name)
- print("Deleting existing app file %s" % p)
- os.unlink(p)
-
- app_files = []
- parser = pyjs.PlatformParser("platform")
- app_headers = ''
- scripts = ['' %
- script for script in js_includes]
- app_body = '\n'.join(scripts)
-
- mod_code = {}
- mod_libs = {}
- modules = {}
- app_libs = {}
- early_app_libs = {}
- app_code = {}
- overrides = {}
- pover = {}
- app_modnames = {}
- mod_levels = {}
-
- # First, generate all the code.
- # Second, (dynamic only), post-analyse the places where modules
- # haven't changed
- # Third, write everything out.
-
- for platform in app_platforms:
-
- mod_code[platform] = {}
- mod_libs[platform] = {}
- modules[platform] = []
- pover[platform] = {}
- app_libs[platform] = ''
- early_app_libs[platform] = ''
- app_code[platform] = {}
- app_modnames[platform] = {}
-
- # Application.Platform.cache.html
-
- parser.setPlatform(platform)
- app_translator = pyjs.AppTranslator(
- parser=parser, dynamic=dynamic, optimize=optimize)
- early_app_libs[platform], appcode = \
- app_translator.translate(None, is_app=False,
- debug=debug,
- library_modules=['dynamicajax.js',
- '_pyjs.js', 'sys',
- 'pyjslib'])
- pover[platform].update(app_translator.overrides.items())
- for mname, name in app_translator.overrides.items():
- pd = overrides.setdefault(mname, {})
- pd[platform] = name
-
- print(appcode)
- # mod_code[platform][app_name] = appcode
-
- # platform.Module.cache.js
-
- modules_done = ['pyjslib', 'sys', '_pyjs.js']
- # modules_to_do = [app_name] + app_translator.library_modules
- modules_to_do = [app_name] + app_translator.library_modules
-
- dependencies = {}
-
- deps = map(pyjs.strip_py, modules_to_do)
- for d in deps:
- sublist = add_subdeps(dependencies, d)
- modules_to_do += sublist
- deps = uniquify(deps)
- # dependencies[app_name] = deps
-
- modules[platform] = modules_done + modules_to_do
-
- while modules_to_do:
-
- # print "modules to do", modules_to_do
-
- mn = modules_to_do.pop()
- mod_name = pyjs.strip_py(mn)
-
- if mod_name in modules_done:
- continue
-
- modules_done.append(mod_name)
-
- mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name)
-
- parser.setPlatform(platform)
- mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize)
- mod_libs[platform][mod_name], mod_code[platform][mod_name] = \
- mod_translator.translate(mod_name,
- is_app=False,
- debug=debug)
- pover[platform].update(mod_translator.overrides.items())
- for mname, name in mod_translator.overrides.items():
- pd = overrides.setdefault(mname, {})
- pd[platform] = name
-
- mods = mod_translator.library_modules
- modules_to_do += mods
- modules[platform] += mods
-
- deps = map(pyjs.strip_py, mods)
- sd = subdeps(mod_name)
- if len(sd) > 1:
- deps += sd[:-1]
- while mod_name in deps:
- deps.remove(mod_name)
-
- # print
- # print
- # print "modname preadd:", mod_name, deps
- # print
- # print
- for d in deps:
- sublist = add_subdeps(dependencies, d)
- modules_to_do += sublist
- modules_to_do += add_subdeps(dependencies, mod_name)
- # print "modname:", mod_name, deps
- deps = uniquify(deps)
- # print "modname:", mod_name, deps
- dependencies[mod_name] = deps
-
- # work out the dependency ordering of the modules
-
- mod_levels[platform] = make_deps(None, dependencies, modules_done)
-
- # now write everything out
-
- for platform in app_platforms:
-
- early_app_libs_ = early_app_libs[platform]
- app_libs_ = app_libs[platform]
- app_code_ = app_code[platform]
- # modules_ = filter_mods(app_name, modules[platform])
- mods = flattenlist(mod_levels[platform])
- mods.reverse()
- modules_ = filter_mods(None, mods)
-
- for mod_name in modules_:
-
- mod_code_ = mod_code[platform][mod_name]
-
- mod_name = pyjs.strip_py(mod_name)
-
- override_name = "%s.%s" % (platform.lower(), mod_name)
- if override_name in pover[platform]:
- mod_cache_name = "%s.cache.js" % (override_name)
- else:
- mod_cache_name = "%s.cache.js" % (mod_name)
-
- print("Creating: " + mod_cache_name)
-
- modlevels = make_deps(None, dependencies, dependencies[mod_name])
-
- modnames = []
-
- for md in modlevels:
- mnames = map(lambda x: "'%s'" % x, md)
- mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
- modnames.append(mnames)
-
- modnames.reverse()
- modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(modnames)
-
- # convert the overrides
-
- overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
- overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
-
- if dynamic:
- mod_cache_html_output = open(join(output, mod_cache_name), "w")
- else:
- mod_cache_html_output = cStringIO()
-
- print(mod_cache_html_template % dict(
- mod_name=mod_name,
- app_name=app_name,
- modnames=modnames,
- overrides=overnames,
- mod_libs=mod_libs[platform][mod_name],
- dynamic=dynamic,
- mod_code=mod_code_,
- ), file=mod_cache_html_output)
-
- if dynamic:
- mod_cache_html_output.close()
- else:
- mod_cache_html_output.seek(0)
- app_libs_ += mod_cache_html_output.read()
-
- # write out the dependency ordering of the modules
-
- app_modnames = []
-
- for md in mod_levels[platform]:
- mnames = map(lambda x: "'%s'" % x, md)
- mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames)
- app_modnames.append(mnames)
-
- app_modnames.reverse()
- app_modnames = "new pyjslib.List([\n\t\t%s\n\t])" % ',\n\t\t'.join(app_modnames)
-
- # convert the overrides
-
- overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items())
- overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames)
-
- # print "platform names", platform, overnames
- # print pover
-
- # now write app.allcache including dependency-ordered list of
- # library modules
-
- file_contents = all_cache_html_template % dict(
- app_name=app_name,
- early_app_libs=early_app_libs_,
- app_libs=app_libs_,
- app_code=app_code_,
- app_body=app_body,
- overrides=overnames,
- platform=platform.lower(),
- dynamic=dynamic,
- app_modnames=app_modnames,
- app_headers=app_headers
- )
- if cache_buster:
- digest = md5.new(file_contents).hexdigest()
- file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
- else:
- file_name = "%s.%s" % (platform.lower(), app_name)
- file_name += ".cache.html"
- out_path = join(output, file_name)
- out_file = open(out_path, 'w')
- out_file.write(file_contents)
- out_file.close()
- app_files.append((platform.lower(), file_name))
- print("Created app file %s:%s: %s" % (
- app_name, platform, out_path))
-
- return app_files
-
-
-def flattenlist(ll):
- res = []
- for l in ll:
- res += l
- return res
-
-
-def subdeps(m):
- """
- creates sub-dependencies e.g. pyjamas.ui.Widget
- creates pyjamas.ui.Widget, pyjamas.ui and pyjamas.
- """
- d = []
- m = m.split(".")
- for i in range(0, len(m)):
- d.append('.'.join(m[:i+1]))
- return d
-
-
-def add_subdeps(deps, mod_name):
- sd = subdeps(mod_name)
- if len(sd) == 1:
- return []
- # print "subdeps", mod_name, sd
- # print "deps", deps
- res = []
- for i in range(0, len(sd)-1):
- parent = sd[i]
- child = sd[i+1]
- k = deps.get(child, [])
- k.append(parent)
- deps[child] = k
- if parent not in res:
- res.append(parent)
- # print deps
- return res
-
-
-def uniquify(md):
- """
- makes unique and preserves list order
- """
- res = []
- for m in md:
- if m not in res:
- res.append(m)
- return res
-
-
-def filter_mods(app_name, md):
- while 'sys' in md:
- md.remove('sys')
- while 'pyjslib' in md:
- md.remove('pyjslib')
- while app_name in md:
- md.remove(app_name)
- md = filter(lambda x: not x.endswith('.js'), md)
- md = map(pyjs.strip_py, md)
-
- return uniquify(md)
-
-
-def filter_deps(app_name, deps):
-
- res = {}
- for (k, l) in deps.items():
- mods = filter_mods(k, l)
- while k in mods:
- mods.remove(k)
- res[k] = mods
- return res
-
-
-def has_nodeps(mod, deps):
- if mod not in deps or not deps[mod]:
- return True
- return False
-
-
-def nodeps_list(mod_list, deps):
- res = []
- for mod in mod_list:
- if has_nodeps(mod, deps):
- res.append(mod)
- return res
-
-# this function takes a dictionary of dependent modules and
-# creates a list of lists. the first list will be modules
-# that have no dependencies; the second list will be those
-# modules that have the first list as dependencies; the
-# third will be those modules that have the first and second...
-# etc.
-
-
-def make_deps(app_name, deps, mod_list):
- print("Calculating Dependencies ...")
- mod_list = filter_mods(app_name, mod_list)
- deps = filter_deps(app_name, deps)
-
- if not mod_list:
- return []
-
- # print mod_list
- # print deps
-
- ordered_deps = []
- last_len = -1
- while deps:
- l_deps = len(deps)
- # print l_deps
- if l_deps == last_len:
- for m, dl in deps.items():
- for d in dl:
- if m in deps.get(d, []):
- raise Exception('Circular Imports found: \n%s %s -> %s %s'
- % (m, dl, d, deps[d]))
- # raise Exception('Could not calculate dependencies: \n%s' % deps)
- break
- last_len = l_deps
- # print "modlist", mod_list
- nodeps = nodeps_list(mod_list, deps)
- # print "nodeps", nodeps
- mod_list = filter(lambda x: x not in nodeps, mod_list)
- newdeps = {}
- for k in deps.keys():
- depslist = deps[k]
- depslist = filter(lambda x: x not in nodeps, depslist)
- if depslist:
- newdeps[k] = depslist
- # print "newdeps", newdeps
- deps = newdeps
- ordered_deps.append(nodeps)
- # time.sleep(0)
-
- if mod_list:
- ordered_deps.append(mod_list) # last dependencies - usually the app(s)
-
- ordered_deps.reverse()
-
- return ordered_deps
-
-
-def main():
- global app_platforms
-
- parser = OptionParser(usage=usage, version=version)
- parser.add_option(
- "-o",
- "--output",
- dest="output",
- help="directory to which the webapp should be written"
- )
- parser.add_option(
- "-j",
- "--include-js",
- dest="js_includes",
- action="append",
- help="javascripts to load into the same frame as the rest of the script"
- )
- parser.add_option(
- "-I",
- "--library_dir",
- dest="library_dirs",
- action="append",
- help="additional paths appended to PYJSPATH"
- )
- parser.add_option(
- "-D",
- "--data_dir",
- dest="data_dir",
- help="path for data directory"
- )
- parser.add_option(
- "-m",
- "--dynamic-modules",
- action="store_true",
- dest="dynamic",
- default=False,
- help="Split output into separate dynamically-loaded modules (experimental)"
- )
- parser.add_option(
- "-P",
- "--platforms",
- dest="platforms",
- help="platforms to build for, comma-separated"
- )
- parser.add_option(
- "-d",
- "--debug",
- action="store_true",
- dest="debug"
- )
- parser.add_option(
- "-O",
- "--optimize",
- action="store_true",
- dest="optimize",
- default=False,
- help="Optimize generated code (removes all print statements)",
- )
- parser.add_option(
- "-c",
- "--cache_buster",
- action="store_true",
- dest="cache_buster",
- help="Enable browser cache-busting (MD5 hash added to output filenames)"
- )
-
- parser.set_defaults(output="output", js_includes=[], library_dirs=[],
- platforms=(','.join(app_platforms)),
- data_dir=os.path.join(sys.prefix, "share/pyjamas"),
- dynamic=False,
- cache_buster=False,
- debug=False)
- (options, args) = parser.parse_args()
- if len(args) != 1:
- parser.error("incorrect number of arguments")
-
- data_dir = abspath(options.data_dir)
-
- app_path = args[0]
- if app_path.endswith('.py'):
- app_path = abspath(app_path)
- if not isfile(app_path):
- parser.error("Application file not found %r" % app_path)
- app_path, app_name = split(app_path)
- app_name = app_name[:-3]
- pyjs.path.append(app_path)
- elif os.path.sep in app_path:
- parser.error("Not a valid module declaration %r" % app_path)
- else:
- app_name = app_path
-
- for d in options.library_dirs:
- pyjs.path.append(abspath(d))
-
- if options.platforms:
- app_platforms = options.platforms.split(',')
-
- # this is mostly for getting boilerplate stuff
- data_dir = os.path.abspath(options.data_dir)
-
- build(app_name, options.output, options.js_includes,
- options.debug, options.dynamic and 1 or 0, data_dir,
- options.cache_buster, options.optimize)
-
-
-if __name__ == "__main__":
- main()
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/jsonrpc/README.txt
--- a/svgui/pyjs/jsonrpc/README.txt Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-These classes are intended for use server-side.
-
-e.g. in a django view.py :
-
- from pyjs.jsonrpc.django import JSONService, jsonremote
-
- jsonservice = JSONRPCService()
-
- @jsonremote(jsonservice)
- def test(request, echo_param):
- return "echoing the param back: %s" % echo_param
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/jsonrpc/__init__.py
--- a/svgui/pyjs/jsonrpc/__init__.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-# module jsonrpc
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/jsonrpc/django/jsonrpc.py
--- a/svgui/pyjs/jsonrpc/django/jsonrpc.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-# jsonrpc.py
-# original code: http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas
-# also from: http://www.pimentech.fr/technologies/outils
-
-from __future__ import absolute_import
-import datetime
-from builtins import str as text
-
-from django.core.serializers import serialize
-
-
-from svgui.pyjs.jsonrpc.jsonrpc import JSONRPCServiceBase
-# JSONRPCService and jsonremote are used in combination to drastically
-# simplify the provision of JSONRPC services. use as follows:
-#
-# jsonservice = JSONRPCService()
-#
-# @jsonremote(jsonservice)
-# def test(request, echo_param):
-# return "echoing the param back: %s" % echo_param
-#
-# dump jsonservice into urlpatterns:
-# (r'^service1/$', 'djangoapp.views.jsonservice'),
-
-
-class JSONRPCService(JSONRPCServiceBase):
-
- def __call__(self, request, extra=None):
- return self.process(request.raw_post_data)
-
-
-def jsonremote(service):
- """Make JSONRPCService a decorator so that you can write :
-
- from jsonrpc import JSONRPCService
- chatservice = JSONRPCService()
-
- @jsonremote(chatservice)
- def login(request, user_name):
- (...)
- """
- def remotify(func):
- if isinstance(service, JSONRPCService):
- service.add_method(func.__name__, func)
- else:
- emsg = 'Service "%s" not found' % str(service.__name__)
- raise NotImplementedError(emsg)
- return func
- return remotify
-
-
-# FormProcessor provides a mechanism for turning Django Forms into JSONRPC
-# Services. If you have an existing Django app which makes prevalent
-# use of Django Forms it will save you rewriting the app.
-# use as follows. in djangoapp/views.py :
-#
-# class SimpleForm(forms.Form):
-# testfield = forms.CharField(max_length=100)
-#
-# class SimpleForm2(forms.Form):
-# testfield = forms.CharField(max_length=20)
-#
-# processor = FormProcessor({'processsimpleform': SimpleForm,
-# 'processsimpleform2': SimpleForm2})
-#
-# this will result in a JSONRPC service being created with two
-# RPC functions. dump "processor" into urlpatterns to make it
-# part of the app:
-# (r'^formsservice/$', 'djangoapp.views.processor'),
-
-
-def builderrors(form):
- d = {}
- for error in form.errors.keys():
- if error not in d:
- d[error] = []
- for errorval in form.errors[error]:
- d[error].append(text(errorval))
- return d
-
-
-# contains the list of arguments in each field
-field_names = {
- 'CharField': ['max_length', 'min_length'],
- 'IntegerField': ['max_value', 'min_value'],
- 'FloatField': ['max_value', 'min_value'],
- 'DecimalField': ['max_value', 'min_value', 'max_digits', 'decimal_places'],
- 'DateField': ['input_formats'],
- 'DateTimeField': ['input_formats'],
- 'TimeField': ['input_formats'],
- 'RegexField': ['max_length', 'min_length'], # sadly we can't get the expr
- 'EmailField': ['max_length', 'min_length'],
- 'URLField': ['max_length', 'min_length', 'verify_exists', 'user_agent'],
- 'ChoiceField': ['choices'],
- 'FilePathField': ['path', 'match', 'recursive', 'choices'],
- 'IPAddressField': ['max_length', 'min_length'],
-}
-
-
-def describe_field_errors(field):
- res = {}
- field_type = field.__class__.__name__
- msgs = {}
- for n, m in field.error_messages.items():
- msgs[n] = text(m)
- res['error_messages'] = msgs
- if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
- res['fields'] = map(describe_field, field.fields)
- return res
-
-
-def describe_fields_errors(fields, field_names):
- res = {}
- if not field_names:
- field_names = fields.keys()
- for name in field_names:
- field = fields[name]
- res[name] = describe_field_errors(field)
- return res
-
-
-def describe_field(field):
- res = {}
- field_type = field.__class__.__name__
- for fname in (field_names.get(field_type, []) +
- ['help_text', 'label', 'initial', 'required']):
- res[fname] = getattr(field, fname)
- if field_type in ['ComboField', 'MultiValueField', 'SplitDateTimeField']:
- res['fields'] = map(describe_field, field.fields)
- return res
-
-
-def describe_fields(fields, field_names):
- res = {}
- if not field_names:
- field_names = fields.keys()
- for name in field_names:
- field = fields[name]
- res[name] = describe_field(field)
- return res
-
-
-class FormProcessor(JSONRPCService):
- def __init__(self, forms, _formcls=None):
-
- if _formcls is None:
- JSONRPCService.__init__(self)
- for k in forms.keys():
- s = FormProcessor({}, forms[k])
- self.add_method(k, s.__process)
- else:
- JSONRPCService.__init__(self, forms)
- self.formcls = _formcls
-
- def __process(self, request, params, command=None):
-
- f = self.formcls(params)
-
- if command is None: # just validate
- if not f.is_valid():
- return {'success': False, 'errors': builderrors(f)}
- return {'success': True}
-
- elif 'describe_errors' in command:
- field_names = command['describe_errors']
- return describe_fields_errors(f.fields, field_names)
-
- elif 'describe' in command:
- field_names = command['describe']
- return describe_fields(f.fields, field_names)
-
- elif 'save' in command:
- if not f.is_valid():
- return {'success': False, 'errors': builderrors(f)}
- instance = f.save() # XXX: if you want more, over-ride save.
- return {'success': True, 'instance': json_convert(instance)}
-
- elif 'html' in command:
- return {'success': True, 'html': f.as_table()}
-
- return "unrecognised command"
-
-# The following is incredibly convenient for saving vast amounts of
-# coding, avoiding doing silly things like this:
-# jsonresult = {'field1': djangoobject.field1,
-# 'field2': djangoobject.date.strftime('%Y.%M'),
-# ..... }
-#
-# The date/time flatten function is there because JSONRPC doesn't
-# support date/time objects or formats, so conversion to a string
-# is the most logical choice. pyjamas, being python, can easily
-# be used to parse the string result at the other end.
-#
-# use as follows:
-#
-# jsonservice = JSONRPCService()
-#
-# @jsonremote(jsonservice)
-# def list_some_model(request, start=0, count=10):
-# l = SomeDjangoModelClass.objects.filter()
-# res = json_convert(l[start:end])
-#
-# @jsonremote(jsonservice)
-# def list_another_model(request, start=0, count=10):
-# l = AnotherDjangoModelClass.objects.filter()
-# res = json_convert(l[start:end])
-#
-# dump jsonservice into urlpatterns to make the two RPC functions,
-# list_some_model and list_another_model part of the django app:
-# (r'^service1/$', 'djangoapp.views.jsonservice'),
-
-
-def dict_datetimeflatten(item):
- d = {}
- for k, v in item.items():
- k = str(k)
- if isinstance(v, datetime.date):
- d[k] = str(v)
- elif isinstance(v, dict):
- d[k] = dict_datetimeflatten(v)
- else:
- d[k] = v
- return d
-
-
-def json_convert(l, fields=None):
- res = []
- for item in serialize('python', l, fields=fields):
- res.append(dict_datetimeflatten(item))
- return res
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/jsonrpc/jsonrpc.py
--- a/svgui/pyjs/jsonrpc/jsonrpc.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-from __future__ import absolute_import
-import sys
-import gluon.contrib.simplejson as simplejson
-
-
-class JSONRPCServiceBase(object):
-
- def __init__(self):
- self.methods = {}
-
- def response(self, id, result):
- return simplejson.dumps({'version': '1.1', 'id': id,
- 'result': result, 'error': None})
-
- def error(self, id, code, message):
- return simplejson.dumps({
- 'id': id,
- 'version': '1.1',
- 'error': {'name': 'JSONRPCError',
- 'code': code,
- 'message': message}
- })
-
- def add_method(self, name, method):
- self.methods[name] = method
-
- def process(self, data):
- data = simplejson.loads(data)
- id, method, params = data["id"], data["method"], data["params"]
- if method in self.methods:
- try:
- result = self.methods[method](*params)
- return self.response(id, result)
- except Exception:
- etype, eval, _etb = sys.exc_info()
- return self.error(id, 100, 'Exception %s: %s' % (etype, eval))
- except BaseException:
- etype, eval, _etb = sys.exc_info()
- return self.error(id, 100, '%s: %s' % (etype.__name__, eval))
- else:
- return self.error(id, 100, 'method "%s" does not exist' % method)
-
- def listmethods(self):
- return self.methods.keys()
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/jsonrpc/web2py/jsonrpc.py
--- a/svgui/pyjs/jsonrpc/web2py/jsonrpc.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-# pylint: disable=undefined-variable
-
-from __future__ import absolute_import
-from svgui.pyjs.jsonrpc.jsonrpc import JSONRPCServiceBase
-
-
-class JSONRPCService(JSONRPCServiceBase):
-
- def serve(self):
- return self.process(request.body.read())
-
- def __call__(self, func):
- self.methods[func.__name__] = func
- return func
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/lib/_pyjs.js
--- a/svgui/pyjs/lib/_pyjs.js Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-function pyjs_extend(klass, base) {
- function klass_object_inherit() {}
- klass_object_inherit.prototype = base.prototype;
- klass_object = new klass_object_inherit();
- for (var i in base.prototype.__class__) {
- v = base.prototype.__class__[i];
- if (typeof v == "function" && (v.class_method || v.static_method || v.unbound_method))
- {
- klass_object[i] = v;
- }
- }
-
- function klass_inherit() {}
- klass_inherit.prototype = klass_object;
- klass.prototype = new klass_inherit();
- klass_object.constructor = klass;
- klass.prototype.__class__ = klass_object;
-
- for (var i in base.prototype) {
- v = base.prototype[i];
- if (typeof v == "function" && v.instance_method)
- {
- klass.prototype[i] = v;
- }
- }
-}
-
-/* creates a class, derived from bases, with methods and variables */
-function pyjs_type(clsname, bases, methods)
-{
- var fn_cls = function() {};
- fn_cls.__name__ = clsname;
- var fn = function() {
- var instance = new fn_cls();
- if(instance.__init__) instance.__init__.apply(instance, arguments);
- return instance;
- }
- fn_cls.__initialize__ = function() {
- if (fn_cls.__was_initialized__) return;
- fn_cls.__was_initialized__ = true;
- fn_cls.__extend_baseclasses();
- fn_cls.prototype.__class__.__new__ = fn;
- fn_cls.prototype.__class__.__name__ = clsname;
- }
- fn_cls.__extend_baseclasses = function() {
- var bi;
- for (bi in fn_cls.__baseclasses)
- {
- var b = fn_cls.__baseclasses[bi];
- if (b.__was_initialized__)
- {
- continue;
- }
- b.__initialize__();
- }
- for (bi in fn_cls.__baseclasses)
- {
- var b = fn_cls.__baseclasses[bi];
- pyjs_extend(fn_cls, b);
- }
- }
- if (!bases) {
- bases = [pyjslib.__Object];
- }
- fn_cls.__baseclasses = bases;
-
- fn_cls.__initialize__();
-
- for (k in methods) {
- var mth = methods[k];
- var mtype = typeof mth;
- if (mtype == "function" ) {
- fn_cls.prototype[k] = mth;
- fn_cls.prototype.__class__[k] = function () {
- return fn_cls.prototype[k].call.apply(
- fn_cls.prototype[k], arguments);
- };
- fn_cls.prototype.__class__[k].unbound_method = true;
- fn_cls.prototype.instance_method = true;
- fn_cls.prototype.__class__[k].__name__ = k;
- fn_cls.prototype[k].__name__ = k;
- } else {
- fn_cls.prototype.__class__[k] = mth;
- }
- }
- return fn;
-}
-function pyjs_kwargs_call(obj, func, star_args, args)
-{
- var call_args;
-
- if (star_args)
- {
- if (!pyjslib.isIteratable(star_args))
- {
- throw (pyjslib.TypeError(func.__name__ + "() arguments after * must be a sequence" + pyjslib.repr(star_args)));
- }
- call_args = Array();
- var __i = star_args.__iter__();
- var i = 0;
- try {
- while (true) {
- call_args[i]=__i.next();
- i++;
- }
- } catch (e) {
- if (e != pyjslib.StopIteration) {
- throw e;
- }
- }
-
- if (args)
- {
- var n = star_args.length;
- for (var i=0; i < args.length; i++) {
- call_args[n+i]=args[i];
- }
- }
- }
- else
- {
- call_args = args;
- }
- return func.apply(obj, call_args);
-}
-
-function pyjs_kwargs_function_call(func, star_args, args)
-{
- return pyjs_kwargs_call(null, func, star_args, args);
-}
-
-function pyjs_kwargs_method_call(obj, method_name, star_args, args)
-{
- var method = obj[method_name];
- if (method.parse_kwargs)
- {
- args = method.parse_kwargs.apply(null, args);
- }
- return pyjs_kwargs_call(obj, method, star_args, args);
-}
-
-//String.prototype.__getitem__ = String.prototype.charAt;
-//String.prototype.upper = String.prototype.toUpperCase;
-//String.prototype.lower = String.prototype.toLowerCase;
-//String.prototype.find=pyjslib.String_find;
-//String.prototype.join=pyjslib.String_join;
-//String.prototype.isdigit=pyjslib.String_isdigit;
-//String.prototype.__iter__=pyjslib.String___iter__;
-//
-//String.prototype.__replace=String.prototype.replace;
-//String.prototype.replace=pyjslib.String_replace;
-//
-//String.prototype.split=pyjslib.String_split;
-//String.prototype.strip=pyjslib.String_strip;
-//String.prototype.lstrip=pyjslib.String_lstrip;
-//String.prototype.rstrip=pyjslib.String_rstrip;
-//String.prototype.startswith=pyjslib.String_startswith;
-
-var str = String;
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/lib/json.js
--- a/svgui/pyjs/lib/json.js Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-json_parse = (function () {
-
-// This is a function that can parse a JSON text, producing a JavaScript
-// data structure. It is a simple, recursive descent parser. It does not use
-// eval or regular expressions, so it can be used as a model for implementing
-// a JSON parser in other languages.
-
-// We are defining the function inside of another function to avoid creating
-// global variables.
-
- var at, // The index of the current character
- ch, // The current character
- escapee = {
- '"': '"',
- '\\': '\\',
- '/': '/',
- b: '\b',
- f: '\f',
- n: '\n',
- r: '\r',
- t: '\t'
- },
- text,
-
- error = function (m) {
-
-// Call error when something is wrong.
-
- throw {
- name: 'SyntaxError',
- message: m,
- at: at,
- text: text
- };
- },
-
- next = function (c) {
-
-// If a c parameter is provided, verify that it matches the current character.
-
- if (c && c !== ch) {
- error("Expected '" + c + "' instead of '" + ch + "'");
- }
-
-// Get the next character. When there are no more characters,
-// return the empty string.
-
- ch = text.charAt(at);
- at += 1;
- return ch;
- },
-
- number = function () {
-
-// Parse a number value.
-
- var number,
- string = '';
-
- if (ch === '-') {
- string = '-';
- next('-');
- }
- while (ch >= '0' && ch <= '9') {
- string += ch;
- next();
- }
- if (ch === '.') {
- string += '.';
- while (next() && ch >= '0' && ch <= '9') {
- string += ch;
- }
- }
- if (ch === 'e' || ch === 'E') {
- string += ch;
- next();
- if (ch === '-' || ch === '+') {
- string += ch;
- next();
- }
- while (ch >= '0' && ch <= '9') {
- string += ch;
- next();
- }
- }
- number = +string;
- if (isNaN(number)) {
- error("Bad number");
- } else {
- return number;
- }
- },
-
- string = function () {
-
-// Parse a string value.
-
- var hex,
- i,
- string = '',
- uffff;
-
-// When parsing for string values, we must look for " and \ characters.
-
- if (ch === '"') {
- while (next()) {
- if (ch === '"') {
- next();
- return string;
- } else if (ch === '\\') {
- next();
- if (ch === 'u') {
- uffff = 0;
- for (i = 0; i < 4; i += 1) {
- hex = parseInt(next(), 16);
- if (!isFinite(hex)) {
- break;
- }
- uffff = uffff * 16 + hex;
- }
- string += String.fromCharCode(uffff);
- } else if (typeof escapee[ch] === 'string') {
- string += escapee[ch];
- } else {
- break;
- }
- } else {
- string += ch;
- }
- }
- }
- error("Bad string");
- },
-
- white = function () {
-
-// Skip whitespace.
-
- while (ch && ch <= ' ') {
- next();
- }
- },
-
- word = function () {
-
-// true, false, or null.
-
- switch (ch) {
- case 't':
- next('t');
- next('r');
- next('u');
- next('e');
- return true;
- case 'f':
- next('f');
- next('a');
- next('l');
- next('s');
- next('e');
- return false;
- case 'n':
- next('n');
- next('u');
- next('l');
- next('l');
- return null;
- }
- error("Unexpected '" + ch + "'");
- },
-
- value, // Place holder for the value function.
-
- array = function () {
-
-// Parse an array value.
-
- var array = [];
-
- if (ch === '[') {
- next('[');
- white();
- if (ch === ']') {
- next(']');
- return array; // empty array
- }
- while (ch) {
- array.push(value());
- white();
- if (ch === ']') {
- next(']');
- return array;
- }
- next(',');
- white();
- }
- }
- error("Bad array");
- },
-
- object = function () {
-
-// Parse an object value.
-
- var key,
- object = {};
-
- if (ch === '{') {
- next('{');
- white();
- if (ch === '}') {
- next('}');
- return object; // empty object
- }
- while (ch) {
- key = string();
- white();
- next(':');
- if (Object.hasOwnProperty.call(object, key)) {
- error('Duplicate key "' + key + '"');
- }
- object[key] = value();
- white();
- if (ch === '}') {
- next('}');
- return object;
- }
- next(',');
- white();
- }
- }
- error("Bad object");
- };
-
- value = function () {
-
-// Parse a JSON value. It could be an object, an array, a string, a number,
-// or a word.
-
- white();
- switch (ch) {
- case '{':
- return object();
- case '[':
- return array();
- case '"':
- return string();
- case '-':
- return number();
- default:
- return ch >= '0' && ch <= '9' ? number() : word();
- }
- };
-
-// Return the json_parse function. It will have access to all of the above
-// functions and variables.
-
- return function (source, reviver) {
- var result;
-
- text = source;
- at = 0;
- ch = ' ';
- result = value();
- white();
- if (ch) {
- error("Syntax error");
- }
-
-// If there is a reviver function, we recursively walk the new structure,
-// passing each name/value pair to the reviver function for possible
-// transformation, starting with a temporary root object that holds the result
-// in an empty key. If there is not a reviver function, we simply return the
-// result.
-
- return typeof reviver === 'function' ? (function walk(holder, key) {
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }({'': result}, '')) : result;
- };
-}());
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/lib/pyjslib.py
--- a/svgui/pyjs/lib/pyjslib.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1418 +0,0 @@
-# Copyright 2006 James Tauber and contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# pylint: disable=too-many-function-args,undefined-variable,no-absolute-import,assign-to-new-keyword,nonzero-method,next-method-called,next-method-defined
-
-# iteration from Bob Ippolito's Iteration in JavaScript
-
-from __pyjamas__ import JS
-
-# must declare import _before_ importing sys
-
-
-def import_module(path, parent_module, module_name, dynamic=1, async=False):
-
- JS("""
- var cache_file;
-
- if (module_name == "sys" || module_name == 'pyjslib')
- {
- /*module_load_request[module_name] = 1;*/
- return;
- }
-
- if (path == null)
- {
- path = './';
- }
-
- var override_name = sys.platform + "." + module_name;
- if (((sys.overrides != null) &&
- (sys.overrides.has_key(override_name))))
- {
- cache_file = sys.overrides.__getitem__(override_name) ;
- }
- else
- {
- cache_file = module_name ;
- }
-
- cache_file = (path + cache_file + '.cache.js' ) ;
-
- //alert("cache " + cache_file + " " + module_name + " " + parent_module);
-
- /* already loaded? */
- if (module_load_request[module_name])
- {
- if (module_load_request[module_name] >= 3 && parent_module != null)
- {
- //onload_fn = parent_module + '.' + module_name + ' = ' + module_name + ';';
- //pyjs_eval(onload_fn); /* set up the parent-module namespace */
- }
- return;
- }
- if (typeof (module_load_request[module_name]) == 'undefined')
- {
- module_load_request[module_name] = 1;
- }
-
- /* following a load, this first executes the script
- * "preparation" function MODULENAME_loaded_fn()
- * and then sets up the loaded module in the namespace
- * of the parent.
- */
-
- onload_fn = ''; // module_name + "_loaded_fn();"
-
- if (parent_module != null)
- {
- //onload_fn += parent_module + '.' + module_name + ' = ' + module_name + ';';
- /*pmod = parent_module + '.' + module_name;
- onload_fn += 'alert("' + pmod + '"+' + pmod+');';*/
- }
-
-
- if (dynamic)
- {
- /* this one tacks the script onto the end of the DOM
- */
-
- pyjs_load_script(cache_file, onload_fn, async);
-
- /* this one actually RUNS the script (eval) into the page.
- my feeling is that this would be better for non-async
- but i can't get it to work entirely yet.
- */
- /*pyjs_ajax_eval(cache_file, onload_fn, async);*/
- }
- else
- {
- if (module_name != "pyjslib" &&
- module_name != "sys")
- pyjs_eval(onload_fn);
- }
-
- """)
-
-
-JS("""
-function import_wait(proceed_fn, parent_mod, dynamic) {
-
- var data = '';
- var element = $doc.createElement("div");
- $doc.body.appendChild(element);
- function write_dom(txt) {
- element.innerHTML = txt + '
';
- }
-
- var timeoutperiod = 1;
- if (dynamic)
- var timeoutperiod = 1;
-
- var wait = function() {
-
- var status = '';
- for (l in module_load_request)
- {
- var m = module_load_request[l];
- if (l == "sys" || l == 'pyjslib')
- continue;
- status += l + m + " ";
- }
-
- //write_dom( " import wait " + wait_count + " " + status + " parent_mod " + parent_mod);
- wait_count += 1;
-
- if (status == '')
- {
- setTimeout(wait, timeoutperiod);
- return;
- }
-
- for (l in module_load_request)
- {
- var m = module_load_request[l];
- if (l == "sys" || l == 'pyjslib')
- {
- module_load_request[l] = 4;
- continue;
- }
- if ((parent_mod != null) && (l == parent_mod))
- {
- if (m == 1)
- {
- setTimeout(wait, timeoutperiod);
- return;
- }
- if (m == 2)
- {
- /* cheat and move app on to next stage */
- module_load_request[l] = 3;
- }
- }
- if (m == 1 || m == 2)
- {
- setTimeout(wait, timeoutperiod);
- return;
- }
- if (m == 3)
- {
- //alert("waited for module " + l + ": loaded");
- module_load_request[l] = 4;
- mod_fn = modules[l];
- }
- }
- //alert("module wait done");
-
- if (proceed_fn.importDone)
- proceed_fn.importDone(proceed_fn);
- else
- proceed_fn();
- }
-
- wait();
-}
-""")
-
-
-# pylint: disable=old-style-class
-class Object:
- def __init__(self):
- pass
-
-
-object = Object
-
-
-class Modload:
-
- def __init__(self, path, app_modlist, app_imported_fn, dynamic,
- parent_mod):
- self.app_modlist = app_modlist
- self.app_imported_fn = app_imported_fn
- self.path = path
- self.idx = 0
- self.dynamic = dynamic
- self.parent_mod = parent_mod
-
- def next(self):
-
- for i in range(len(self.app_modlist[self.idx])):
- app = self.app_modlist[self.idx][i]
- import_module(self.path, self.parent_mod, app, self.dynamic, True)
- self.idx += 1
-
- if self.idx >= len(self.app_modlist):
- import_wait(self.app_imported_fn, self.parent_mod, self.dynamic)
- else:
- import_wait(getattr(self, "next"), self.parent_mod, self.dynamic)
-
-
-def get_module(module_name):
- _ev = "__mod = %s;" % module_name
- JS("pyjs_eval(_ev);")
- return __mod
-
-
-def preload_app_modules(path, app_modnames, app_imported_fn, dynamic,
- parent_mod=None):
-
- loader = Modload(path, app_modnames, app_imported_fn, dynamic, parent_mod)
- loader.next()
-
-
-# as comment on line 20 says
-# import sys should be below
-import sys # noqa # pylint: disable=wrong-import-order,unused-import,wrong-import-position
-
-
-class BaseException:
-
- name = "BaseException"
-
- def __init__(self, *args):
- self.args = args
-
- def __str__(self):
- if len(self.args) is 0:
- return ''
- elif len(self.args) is 1:
- return repr(self.args[0])
- return repr(self.args)
-
- def toString(self):
- return str(self)
-
-
-class Exception(BaseException):
- name = "Exception"
-
-
-class TypeError(BaseException):
- name = "TypeError"
-
-
-class StandardError(Exception):
- name = "StandardError"
-
-
-class LookupError(StandardError):
- name = "LookupError"
-
- def toString(self):
- return self.name + ": " + self.args[0]
-
-
-class KeyError(LookupError):
- name = "KeyError"
-
-
-class AttributeError(StandardError):
- name = "AttributeError"
-
- def toString(self):
- return "AttributeError: %s of %s" % (self.args[1], self.args[0])
-
-
-JS(r"""
-pyjslib.StopIteration = function () { };
-pyjslib.StopIteration.prototype = new Error();
-pyjslib.StopIteration.name = 'StopIteration';
-pyjslib.StopIteration.message = 'StopIteration';
-
-pyjslib.String_find = function(sub, start, end) {
- var pos=this.indexOf(sub, start);
- if (pyjslib.isUndefined(end)) return pos;
-
- if (pos + sub.length>end) return -1;
- return pos;
-}
-
-pyjslib.String_join = function(data) {
- var text="";
-
- if (pyjslib.isArray(data)) {
- return data.join(this);
- }
- else if (pyjslib.isIteratable(data)) {
- var iter=data.__iter__();
- try {
- text+=iter.next();
- while (true) {
- var item=iter.next();
- text+=this + item;
- }
- }
- catch (e) {
- if (e != pyjslib.StopIteration) throw e;
- }
- }
-
- return text;
-}
-
-pyjslib.String_isdigit = function() {
- return (this.match(/^\d+$/g) != null);
-}
-
-pyjslib.String_replace = function(old, replace, count) {
- var do_max=false;
- var start=0;
- var new_str="";
- var pos=0;
-
- if (!pyjslib.isString(old)) return this.__replace(old, replace);
- if (!pyjslib.isUndefined(count)) do_max=true;
-
- while (start= s.length) {
- throw pyjslib.StopIteration;
- }
- return s.substring(i++, i, 1);
- },
- '__iter__': function() {
- return this;
- }
- };
-}
-
-pyjslib.String_strip = function(chars) {
- return this.lstrip(chars).rstrip(chars);
-}
-
-pyjslib.String_lstrip = function(chars) {
- if (pyjslib.isUndefined(chars)) return this.replace(/^\s+/, "");
-
- return this.replace(new RegExp("^[" + chars + "]+"), "");
-}
-
-pyjslib.String_rstrip = function(chars) {
- if (pyjslib.isUndefined(chars)) return this.replace(/\s+$/, "");
-
- return this.replace(new RegExp("[" + chars + "]+$"), "");
-}
-
-pyjslib.String_startswith = function(prefix, start) {
- if (pyjslib.isUndefined(start)) start = 0;
-
- if (this.substring(start, prefix.length) == prefix) return true;
- return false;
-}
-
-pyjslib.abs = Math.abs;
-
-""")
-
-
-class Class:
- def __init__(self, name):
- self.name = name
-
- def __str___(self):
- return self.name
-
-
-def eq(a, b):
- JS("""
- if (pyjslib.hasattr(a, "__cmp__")) {
- return a.__cmp__(b) == 0;
- } else if (pyjslib.hasattr(b, "__cmp__")) {
- return b.__cmp__(a) == 0;
- }
- return a == b;
- """)
-
-
-def cmp(a, b):
- if hasattr(a, "__cmp__"):
- return a.__cmp__(b)
- elif hasattr(b, "__cmp__"):
- return -b.__cmp__(a)
- if a > b:
- return 1
- elif b > a:
- return -1
- else:
- return 0
-
-
-def bool(v):
- # this needs to stay in native code without any dependencies here,
- # because this is used by if and while, we need to prevent
- # recursion
- JS("""
- if (!v) return false;
- switch(typeof v){
- case 'boolean':
- return v;
- case 'object':
- if (v.__nonzero__){
- return v.__nonzero__();
- }else if (v.__len__){
- return v.__len__()>0;
- }
- return true;
- }
- return Boolean(v);
- """)
-
-
-class List:
- def __init__(self, data=None):
- JS("""
- this.l = [];
- this.extend(data);
- """)
-
- def append(self, item):
- JS(""" this.l[this.l.length] = item;""")
-
- def extend(self, data):
- JS("""
- if (pyjslib.isArray(data)) {
- n = this.l.length;
- for (var i=0; i < data.length; i++) {
- this.l[n+i]=data[i];
- }
- }
- else if (pyjslib.isIteratable(data)) {
- var iter=data.__iter__();
- var i=this.l.length;
- try {
- while (true) {
- var item=iter.next();
- this.l[i++]=item;
- }
- }
- catch (e) {
- if (e != pyjslib.StopIteration) throw e;
- }
- }
- """)
-
- def remove(self, value):
- JS("""
- var index=this.index(value);
- if (index<0) return false;
- this.l.splice(index, 1);
- return true;
- """)
-
- def index(self, value, start=0):
- JS("""
- var length=this.l.length;
- for (var i=start; i= 0
-
- def __iter__(self):
- JS("""
- var i = 0;
- var l = this.l;
- return {
- 'next': function() {
- if (i >= l.length) {
- throw pyjslib.StopIteration;
- }
- return l[i++];
- },
- '__iter__': function() {
- return this;
- }
- };
- """)
-
- def reverse(self):
- JS(""" this.l.reverse();""")
-
- def sort(self, compareFunc=None, keyFunc=None, reverse=False):
- if not compareFunc:
- compareFunc = cmp
- if keyFunc and reverse:
- def thisSort1(a, b):
- return -compareFunc(keyFunc(a), keyFunc(b))
- self.l.sort(thisSort1)
- elif keyFunc:
- def thisSort2(a, b):
- return compareFunc(keyFunc(a), keyFunc(b))
- self.l.sort(thisSort2)
- elif reverse:
- def thisSort3(a, b):
- return -compareFunc(a, b)
- self.l.sort(thisSort3)
- else:
- self.l.sort(compareFunc)
-
- def getArray(self):
- """
- Access the javascript Array that is used internally by this list
- """
- return self.l
-
- def __str__(self):
- return repr(self)
-
-
-list = List
-
-
-class Tuple:
- def __init__(self, data=None):
- JS("""
- this.l = [];
- this.extend(data);
- """)
-
- def append(self, item):
- JS(""" this.l[this.l.length] = item;""")
-
- def extend(self, data):
- JS("""
- if (pyjslib.isArray(data)) {
- n = this.l.length;
- for (var i=0; i < data.length; i++) {
- this.l[n+i]=data[i];
- }
- }
- else if (pyjslib.isIteratable(data)) {
- var iter=data.__iter__();
- var i=this.l.length;
- try {
- while (true) {
- var item=iter.next();
- this.l[i++]=item;
- }
- }
- catch (e) {
- if (e != pyjslib.StopIteration) throw e;
- }
- }
- """)
-
- def remove(self, value):
- JS("""
- var index=this.index(value);
- if (index<0) return false;
- this.l.splice(index, 1);
- return true;
- """)
-
- def index(self, value, start=0):
- JS("""
- var length=this.l.length;
- for (var i=start; i= 0
-
- def __iter__(self):
- JS("""
- var i = 0;
- var l = this.l;
- return {
- 'next': function() {
- if (i >= l.length) {
- throw pyjslib.StopIteration;
- }
- return l[i++];
- },
- '__iter__': function() {
- return this;
- }
- };
- """)
-
- def reverse(self):
- JS(""" this.l.reverse();""")
-
- def sort(self, compareFunc=None, keyFunc=None, reverse=False):
- if not compareFunc:
- compareFunc = cmp
- if keyFunc and reverse:
- def thisSort1(a, b):
- return -compareFunc(keyFunc(a), keyFunc(b))
- self.l.sort(thisSort1)
- elif keyFunc:
- def thisSort2(a, b):
- return compareFunc(keyFunc(a), keyFunc(b))
- self.l.sort(thisSort2)
- elif reverse:
- def thisSort3(a, b):
- return -compareFunc(a, b)
- self.l.sort(thisSort3)
- else:
- self.l.sort(compareFunc)
-
- def getArray(self):
- """
- Access the javascript Array that is used internally by this list
- """
- return self.l
-
- def __str__(self):
- return repr(self)
-
-
-tuple = Tuple
-
-
-class Dict:
- def __init__(self, data=None):
- JS("""
- this.d = {};
-
- if (pyjslib.isArray(data)) {
- for (var i in data) {
- var item=data[i];
- this.__setitem__(item[0], item[1]);
- //var sKey=pyjslib.hash(item[0]);
- //this.d[sKey]=item[1];
- }
- }
- else if (pyjslib.isIteratable(data)) {
- var iter=data.__iter__();
- try {
- while (true) {
- var item=iter.next();
- this.__setitem__(item.__getitem__(0), item.__getitem__(1));
- }
- }
- catch (e) {
- if (e != pyjslib.StopIteration) throw e;
- }
- }
- else if (pyjslib.isObject(data)) {
- for (var key in data) {
- this.__setitem__(key, data[key]);
- }
- }
- """)
-
- def __setitem__(self, key, value):
- JS("""
- var sKey = pyjslib.hash(key);
- this.d[sKey]=[key, value];
- """)
-
- def __getitem__(self, key):
- JS("""
- var sKey = pyjslib.hash(key);
- var value=this.d[sKey];
- if (pyjslib.isUndefined(value)){
- throw pyjslib.KeyError(key);
- }
- return value[1];
- """)
-
- def __nonzero__(self):
- JS("""
- for (var i in this.d){
- return true;
- }
- return false;
- """)
-
- def __len__(self):
- JS("""
- var size=0;
- for (var i in this.d) size++;
- return size;
- """)
-
- def has_key(self, key):
- return self.__contains__(key)
-
- def __delitem__(self, key):
- JS("""
- var sKey = pyjslib.hash(key);
- delete this.d[sKey];
- """)
-
- def __contains__(self, key):
- JS("""
- var sKey = pyjslib.hash(key);
- return (pyjslib.isUndefined(this.d[sKey])) ? false : true;
- """)
-
- def keys(self):
- JS("""
- var keys=new pyjslib.List();
- for (var key in this.d) {
- keys.append(this.d[key][0]);
- }
- return keys;
- """)
-
- def values(self):
- JS("""
- var values=new pyjslib.List();
- for (var key in this.d) values.append(this.d[key][1]);
- return values;
- """)
-
- def items(self):
- JS("""
- var items = new pyjslib.List();
- for (var key in this.d) {
- var kv = this.d[key];
- items.append(new pyjslib.List(kv))
- }
- return items;
- """)
-
- def __iter__(self):
- return self.keys().__iter__()
-
- def iterkeys(self):
- return self.__iter__()
-
- def itervalues(self):
- return self.values().__iter__()
-
- def iteritems(self):
- return self.items().__iter__()
-
- def setdefault(self, key, default_value):
- if key not in self:
- self[key] = default_value
-
- def get(self, key, default_=None):
- if key not in self:
- return default_
- return self[key]
-
- def update(self, d):
- for k, v in d.iteritems():
- self[k] = v
-
- def getObject(self):
- """
- Return the javascript Object which this class uses to store
- dictionary keys and values
- """
- return self.d
-
- def copy(self):
- return Dict(self.items())
-
- def __str__(self):
- return repr(self)
-
-
-dict = Dict
-
-# taken from mochikit: range( [start,] stop[, step] )
-
-
-def range():
- JS("""
- var start = 0;
- var stop = 0;
- var step = 1;
-
- if (arguments.length == 2) {
- start = arguments[0];
- stop = arguments[1];
- }
- else if (arguments.length == 3) {
- start = arguments[0];
- stop = arguments[1];
- step = arguments[2];
- }
- else if (arguments.length>0) stop = arguments[0];
-
- return {
- 'next': function() {
- if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) throw pyjslib.StopIteration;
- var rval = start;
- start += step;
- return rval;
- },
- '__iter__': function() {
- return this;
- }
- }
- """)
-
-
-def slice(object, lower, upper):
- JS("""
- if (pyjslib.isString(object)) {
- if (lower < 0) {
- lower = object.length + lower;
- }
- if (upper < 0) {
- upper = object.length + upper;
- }
- if (pyjslib.isNull(upper)) upper=object.length;
- return object.substring(lower, upper);
- }
- if (pyjslib.isObject(object) && object.slice)
- return object.slice(lower, upper);
-
- return null;
- """)
-
-
-def str(text):
- JS("""
- if (pyjslib.hasattr(text,"__str__")) {
- return text.__str__();
- }
- return String(text);
- """)
-
-
-def ord(x):
- if isString(x) and len(x) is 1:
- JS("""
- return x.charCodeAt(0);
- """)
- else:
- JS("""
- throw pyjslib.TypeError();
- """)
- return None
-
-
-def chr(x):
- JS("""
- return String.fromCharCode(x)
- """)
-
-
-def is_basetype(x):
- JS("""
- var t = typeof(x);
- return t == 'boolean' ||
- t == 'function' ||
- t == 'number' ||
- t == 'string' ||
- t == 'undefined'
- ;
- """)
-
-
-def get_pyjs_classtype(x):
- JS("""
- if (pyjslib.hasattr(x, "__class__"))
- if (pyjslib.hasattr(x.__class__, "__new__"))
- var src = x.__class__.__name__;
- return src;
- return null;
- """)
-
-
-def repr(x):
- """ Return the string representation of 'x'.
- """
- JS("""
- if (x === null)
- return "null";
-
- if (x === undefined)
- return "undefined";
-
- var t = typeof(x);
-
- //alert("repr typeof " + t + " : " + x);
-
- if (t == "boolean")
- return x.toString();
-
- if (t == "function")
- return "";
-
- if (t == "number")
- return x.toString();
-
- if (t == "string") {
- if (x.indexOf("'") == -1)
- return "'" + x + "'";
- if (x.indexOf('"') == -1)
- return '"' + x + '"';
- var s = x.replace(new RegExp('"', "g"), '\\\\"');
- return '"' + s + '"';
- };
-
- if (t == "undefined")
- return "undefined";
-
- // If we get here, x is an object. See if it's a Pyjamas class.
-
- if (!pyjslib.hasattr(x, "__init__"))
- return "<" + x.toString() + ">";
-
- // Handle the common Pyjamas data types.
-
- var constructor = "UNKNOWN";
-
- constructor = pyjslib.get_pyjs_classtype(x);
-
- //alert("repr constructor: " + constructor);
-
- if (constructor == "Tuple") {
- var contents = x.getArray();
- var s = "(";
- for (var i=0; i < contents.length; i++) {
- s += pyjslib.repr(contents[i]);
- if (i < contents.length - 1)
- s += ", ";
- };
- s += ")"
- return s;
- };
-
- if (constructor == "List") {
- var contents = x.getArray();
- var s = "[";
- for (var i=0; i < contents.length; i++) {
- s += pyjslib.repr(contents[i]);
- if (i < contents.length - 1)
- s += ", ";
- };
- s += "]"
- return s;
- };
-
- if (constructor == "Dict") {
- var keys = new Array();
- for (var key in x.d)
- keys.push(key);
-
- var s = "{";
- for (var i=0; i return the class name.
- // Note that we replace underscores with dots so that the name will
- // (hopefully!) look like the original Python name.
-
- //var s = constructor.replace(new RegExp('_', "g"), '.');
- return "<" + constructor + " object>";
- """)
-
-
-def float(text):
- JS("""
- return parseFloat(text);
- """)
-
-
-def int(text, radix=0):
- JS("""
- return parseInt(text, radix);
- """)
-
-
-def len(object):
- JS("""
- if (object==null) return 0;
- if (pyjslib.isObject(object) && object.__len__) return object.__len__();
- return object.length;
- """)
-
-
-def isinstance(object_, classinfo):
- if pyjslib.isUndefined(object_):
- return False
- if not pyjslib.isObject(object_):
-
- return False
- if _isinstance(classinfo, Tuple):
- for ci in classinfo:
- if isinstance(object_, ci):
- return True
- return False
- else:
- return _isinstance(object_, classinfo)
-
-
-def _isinstance(object_, classinfo):
- if not pyjslib.isObject(object_):
- return False
- JS("""
- if (object_.__class__){
- var res = object_ instanceof classinfo.constructor;
- return res;
- }
- return false;
- """)
-
-
-def getattr(obj, name, default_=None):
- JS("""
- if ((!pyjslib.isObject(obj))||(pyjslib.isUndefined(obj[name]))){
- if (pyjslib.isUndefined(default_)){
- throw pyjslib.AttributeError(obj, name);
- }else{
- return default_;
- }
- }
- if (!pyjslib.isFunction(obj[name])) return obj[name];
- var fnwrap = function() {
- var args = [];
- for (var i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- return obj[name].apply(obj,args);
- }
- fnwrap.__name__ = name;
- return fnwrap;
- """)
-
-
-def setattr(obj, name, value):
- JS("""
- if (!pyjslib.isObject(obj)) return null;
-
- obj[name] = value;
-
- """)
-
-
-def hasattr(obj, name):
- JS("""
- if (!pyjslib.isObject(obj)) return false;
- if (pyjslib.isUndefined(obj[name])) return false;
-
- return true;
- """)
-
-
-def dir(obj):
- JS("""
- var properties=new pyjslib.List();
- for (property in obj) properties.append(property);
- return properties;
- """)
-
-
-def filter(obj, method, sequence=None):
- # object context is LOST when a method is passed, hence object must be passed separately
- # to emulate python behaviour, should generate this code inline rather than as a function call
- items = []
- if sequence is None:
- sequence = method
- method = obj
-
- for item in sequence:
- if method(item):
- items.append(item)
- else:
- for item in sequence:
- if method.call(obj, item):
- items.append(item)
-
- return items
-
-
-def map(obj, method, sequence=None):
- items = []
-
- if sequence is None:
- sequence = method
- method = obj
-
- for item in sequence:
- items.append(method(item))
- else:
- for item in sequence:
- items.append(method.call(obj, item))
-
- return items
-
-
-def enumerate(sequence):
- enumeration = []
- nextIndex = 0
- for item in sequence:
- enumeration.append([nextIndex, item])
- nextIndex = nextIndex + 1
- return enumeration
-
-
-def min(*sequence):
- minValue = None
- for item in sequence:
- if minValue is None:
- minValue = item
- elif item < minValue:
- minValue = item
- return minValue
-
-
-def max(*sequence):
- maxValue = None
- for item in sequence:
- if maxValue is None:
- maxValue = item
- elif item > maxValue:
- maxValue = item
- return maxValue
-
-
-next_hash_id = 0
-
-
-def hash(obj):
- JS("""
- if (obj == null) return null;
-
- if (obj.$H) return obj.$H;
- if (obj.__hash__) return obj.__hash__();
- if (obj.constructor == String || obj.constructor == Number || obj.constructor == Date) return obj;
-
- obj.$H = ++pyjslib.next_hash_id;
- return obj.$H;
- """)
-
-
-# type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
-def isObject(a):
- JS("""
- return (a != null && (typeof a == 'object')) || pyjslib.isFunction(a);
- """)
-
-
-def isFunction(a):
- JS("""
- return typeof a == 'function';
- """)
-
-
-def isString(a):
- JS("""
- return typeof a == 'string';
- """)
-
-
-def isNull(a):
- JS("""
- return typeof a == 'object' && !a;
- """)
-
-
-def isArray(a):
- JS("""
- return pyjslib.isObject(a) && a.constructor == Array;
- """)
-
-
-def isUndefined(a):
- JS("""
- return typeof a == 'undefined';
- """)
-
-
-def isIteratable(a):
- JS("""
- return pyjslib.isString(a) || (pyjslib.isObject(a) && a.__iter__);
- """)
-
-
-def isNumber(a):
- JS("""
- return typeof a == 'number' && isFinite(a);
- """)
-
-
-def toJSObjects(x):
- """
- Convert the pyjs pythonic List and Dict objects into javascript Object and Array
- objects, recursively.
- """
- if isArray(x):
- JS("""
- var result = [];
- for(var k=0; k < x.length; k++) {
- var v = x[k];
- var tv = pyjslib.toJSObjects(v);
- result.push(tv);
- }
- return result;
- """)
- if isObject(x):
- if isinstance(x, Dict):
- JS("""
- var o = x.getObject();
- var result = {};
- for (var i in o) {
- result[o[i][0].toString()] = o[i][1];
- }
- return pyjslib.toJSObjects(result)
- """)
- elif isinstance(x, List):
- return toJSObjects(x.l)
- elif hasattr(x, '__class__'):
- # we do not have a special implementation for custom
- # classes, just pass it on
- return x
- if isObject(x):
- JS("""
- var result = {};
- for(var k in x) {
- var v = x[k];
- var tv = pyjslib.toJSObjects(v)
- result[k] = tv;
- }
- return result;
- """)
- return x
-
-
-def printFunc(objs):
- JS("""
- if ($wnd.console==undefined) return;
- var s = "";
- for(var i=0; i < objs.length; i++) {
- if(s != "") s += " ";
- s += objs[i];
- }
- console.debug(s)
- """)
-
-
-def type(clsname, bases=None, methods=None):
- """ creates a class, derived from bases, with methods and variables
- """
-
- JS(" var mths = {}; ")
- if methods:
- for k in methods.keys():
- _mth = methods[k]
- JS(" mths[k] = _mth; ")
-
- JS(" var bss = null; ")
- if bases:
- JS("bss = bases.l;")
- JS(" return pyjs_type(clsname, bss, mths); ")
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/lib/sys.py
--- a/svgui/pyjs/lib/sys.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-# the platform name (PyV8, smjs, Mozilla, IE6, Opera, Safari etc.)
-platform = '' # to be updated by app, on compile
-
-# a dictionary of module override names (platform-specific)
-overrides = {} # to be updated by app, on compile
-
-# the remote path for loading modules
-loadpath = None
-
-stacktrace = None
-
-appname = None
-
-
-def setloadpath(lp):
- global loadpath
- loadpath = lp
-
-
-def setappname(an):
- global appname
- appname = an
-
-
-def getloadpath():
- return loadpath
-
-
-def addoverride(module_name, path):
- overrides[module_name] = path
-
-
-def addstack(linedebug):
- JS("""
- if (pyjslib.bool((sys.stacktrace === null))) {
- sys.stacktrace = new pyjslib.List([]);
- }
- sys.stacktrace.append(linedebug);
- """)
-
-
-def popstack():
- JS("""
- sys.stacktrace.pop()
- """)
-
-
-def printstack():
- JS("""
- var res = '';
-
- var __l = sys.stacktrace.__iter__();
- try {
- while (true) {
- var l = __l.next();
- res += ( l + '\\n' ) ;
- }
- } catch (e) {
- if (e != pyjslib.StopIteration) {
- throw e;
- }
- }
-
- return res;
- """)
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/pyjs/pyjs.py
--- a/svgui/pyjs/pyjs.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1780 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2006 James Tauber and contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# pylint: disable=no-absolute-import,bad-python3-import
-
-from __future__ import print_function
-import sys
-import compiler
-from compiler import ast
-import os
-import copy
-from builtins import str as text
-from past.builtins import basestring
-from six.moves import cStringIO
-
-# the standard location for builtins (e.g. pyjslib) can be
-# over-ridden by changing this. it defaults to sys.prefix
-# so that on a system-wide install of pyjamas the builtins
-# can be found in e.g. {sys.prefix}/share/pyjamas
-#
-# over-rides can be done by either explicitly modifying
-# pyjs.prefix or by setting an environment variable, PYJSPREFIX.
-
-prefix = sys.prefix
-
-if 'PYJSPREFIX' in os.environ:
- prefix = os.environ['PYJSPREFIX']
-
-# pyjs.path is the list of paths, just like sys.path, from which
-# library modules will be searched for, for compile purposes.
-# obviously we don't want to use sys.path because that would result
-# in compiling standard python modules into javascript!
-
-path = [os.path.abspath('')]
-
-if 'PYJSPATH' in os.environ:
- for p in os.environ['PYJSPATH'].split(os.pathsep):
- p = os.path.abspath(p)
- if os.path.isdir(p):
- path.append(p)
-
-# this is the python function used to wrap native javascript
-NATIVE_JS_FUNC_NAME = "JS"
-
-UU = ""
-
-PYJSLIB_BUILTIN_FUNCTIONS = ("cmp",
- "map",
- "filter",
- "dir",
- "getattr",
- "setattr",
- "hasattr",
- "int",
- "float",
- "str",
- "repr",
- "range",
- "len",
- "hash",
- "abs",
- "ord",
- "chr",
- "enumerate",
- "min",
- "max",
- "bool",
- "type",
- "isinstance")
-
-PYJSLIB_BUILTIN_CLASSES = ("BaseException",
- "Exception",
- "StandardError",
- "StopIteration",
- "AttributeError",
- "TypeError",
- "KeyError",
- "LookupError",
- "list",
- "dict",
- "object",
- "tuple")
-
-
-def pyjs_builtin_remap(name):
- # XXX HACK!
- if name == 'list':
- name = 'List'
- if name == 'object':
- name = '__Object'
- if name == 'dict':
- name = 'Dict'
- if name == 'tuple':
- name = 'Tuple'
- return name
-
-
-# XXX: this is a hack: these should be dealt with another way
-# however, console is currently the only global name which is causing
-# problems.
-PYJS_GLOBAL_VARS = ("console")
-
-# This is taken from the django project.
-# Escape every ASCII character with a value less than 32.
-JS_ESCAPES = (
- ('\\', r'\x5C'),
- ('\'', r'\x27'),
- ('"', r'\x22'),
- ('>', r'\x3E'),
- ('<', r'\x3C'),
- ('&', r'\x26'),
- (';', r'\x3B')
- ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
-
-
-def escapejs(value):
- """Hex encodes characters for use in JavaScript strings."""
- for bad, good in JS_ESCAPES:
- value = value.replace(bad, good)
- return value
-
-
-def uuprefix(name, leave_alone=0):
- name = name.split(".")
- name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
- return '.'.join(name)
-
-
-class Klass(object):
-
- klasses = {}
-
- def __init__(self, name, name_):
- self.name = name
- self.name_ = name_
- self.klasses[name] = self
- self.functions = set()
-
- def set_base(self, base_name):
- self.base = self.klasses.get(base_name)
-
- def add_function(self, function_name):
- self.functions.add(function_name)
-
-
-class TranslationError(Exception):
- def __init__(self, message, node):
- Exception.__init__(self)
- self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
-
- def __str__(self):
- return self.message
-
-
-def strip_py(name):
- return name
-
-
-def mod_var_name_decl(raw_module_name):
- """ function to get the last component of the module e.g.
- pyjamas.ui.DOM into the "namespace". i.e. doing
- "import pyjamas.ui.DOM" actually ends up with _two_
- variables - one pyjamas.ui.DOM, the other just "DOM".
- but "DOM" is actually local, hence the "var" prefix.
-
- for PyV8, this might end up causing problems - we'll have
- to see: gen_mod_import and mod_var_name_decl might have
- to end up in a library-specific module, somewhere.
- """
- name = raw_module_name.split(".")
- if len(name) == 1:
- return ''
- child_name = name[-1]
- return "var %s = %s;\n" % (child_name, raw_module_name)
-
-
-def gen_mod_import(parentName, importName, dynamic=1):
- # pyjs_ajax_eval("%(n)s.cache.js", null, true);
- return """
- pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
- """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
- mod_var_name_decl(importName)
-
-
-class Translator(object):
-
- def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
- dynamic=0, optimize=False,
- findFile=None):
-
- if module_name:
- self.module_prefix = module_name + "."
- else:
- self.module_prefix = ""
- self.raw_module_name = raw_module_name
- src = src.replace("\r\n", "\n")
- src = src.replace("\n\r", "\n")
- src = src.replace("\r", "\n")
- self.src = src.split("\n")
- self.debug = debug
- self.imported_modules = []
- self.imported_modules_as = []
- self.imported_js = set()
- self.top_level_functions = set()
- self.top_level_classes = set()
- self.top_level_vars = set()
- self.local_arg_stack = [[]]
- self.output = output
- self.imported_classes = {}
- self.method_imported_globals = set()
- self.method_self = None
- self.nextTupleAssignID = 1
- self.dynamic = dynamic
- self.optimize = optimize
- self.findFile = findFile
-
- if module_name.find(".") >= 0:
- vdec = ''
- else:
- vdec = 'var '
- self.printo(UU+"%s%s = function (__mod_name__) {" % (vdec, module_name))
-
- self.printo(" if("+module_name+".__was_initialized__) return;")
- self.printo(" "+UU+module_name+".__was_initialized__ = true;")
- self.printo(UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn))
- self.printo(UU+"%s.__name__ = __mod_name__;" % (raw_module_name))
-
- decl = mod_var_name_decl(raw_module_name)
- if decl:
- self.printo(decl)
-
- if self.debug:
- haltException = self.module_prefix + "HaltException"
- self.printo(haltException + ' = function () {')
- self.printo(' this.message = "Program Halted";')
- self.printo(' this.name = "' + haltException + '";')
- self.printo('}')
- self.printo('')
- self.printo(haltException + ".prototype.__str__ = function()")
- self.printo('{')
- self.printo('return this.message ;')
- self.printo('}')
-
- self.printo(haltException + ".prototype.toString = function()")
- self.printo('{')
- self.printo('return this.name + ": \\"" + this.message + "\\"";')
- self.printo('}')
-
- isHaltFunction = self.module_prefix + "IsHaltException"
- self.printo(""")
- %s = function (s) {
- var suffix="HaltException";
- if (s.length < suffix.length) {
- //alert(s + " " + suffix);
- return false;
- } else {
- var ss = s.substring(s.length, (s.length - suffix.length));
- //alert(s + " " + suffix + " " + ss);
- return ss == suffix;
- }
- }
- """ % isHaltFunction)
- for child in mod.node:
- if isinstance(child, ast.Function):
- self.top_level_functions.add(child.name)
- elif isinstance(child, ast.Class):
- self.top_level_classes.add(child.name)
-
- for child in mod.node:
- if isinstance(child, ast.Function):
- self._function(child, False)
- elif isinstance(child, ast.Class):
- self._class(child)
- elif isinstance(child, ast.Import):
- importName = child.names[0][0]
- if importName == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
- pass
- elif importName.endswith('.js'):
- self.imported_js.add(importName)
- else:
- self.add_imported_module(strip_py(importName))
- elif isinstance(child, ast.From):
- if child.modname == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
- pass
- else:
- self.add_imported_module(child.modname)
- self._from(child)
- elif isinstance(child, ast.Discard):
- self._discard(child, None)
- elif isinstance(child, ast.Assign):
- self._assign(child, None, True)
- elif isinstance(child, ast.AugAssign):
- self._augassign(child, None)
- elif isinstance(child, ast.If):
- self._if(child, None)
- elif isinstance(child, ast.For):
- self._for(child, None)
- elif isinstance(child, ast.While):
- self._while(child, None)
- elif isinstance(child, ast.Subscript):
- self._subscript_stmt(child, None)
- elif isinstance(child, ast.Global):
- self._global(child, None)
- elif isinstance(child, ast.Printnl):
- self._print(child, None)
- elif isinstance(child, ast.Print):
- self._print(child, None)
- elif isinstance(child, ast.TryExcept):
- self._tryExcept(child, None)
- elif isinstance(child, ast.Raise):
- self._raise(child, None)
- elif isinstance(child, ast.Stmt):
- self._stmt(child, None)
- else:
- raise TranslationError("unsupported type (in __init__)", child)
-
- # Initialize all classes for this module
- # self.printo("__"+self.modpfx()+\
- # "classes_initialize = function() {\n")
- # for className in self.top_level_classes:
- # self.printo("\t"+UU+self.modpfx()+"__"+className+"_initialize();")
- # self.printo("};\n")
-
- self.printo("return this;\n")
- self.printo("}; /* end %s */ \n" % module_name)
-
- def printo(self, *args):
- print(*args, file=self.output)
-
- def module_imports(self):
- return self.imported_modules + self.imported_modules_as
-
- def add_local_arg(self, varname):
- local_vars = self.local_arg_stack[-1]
- if varname not in local_vars:
- local_vars.append(varname)
-
- def add_imported_module(self, importName):
-
- if importName in self.imported_modules:
- return
- self.imported_modules.append(importName)
- name = importName.split(".")
- if len(name) != 1:
- # add the name of the module to the namespace,
- # but don't add the short name to imported_modules
- # because then the short name would be attempted to be
- # added to the dependencies, and it's half way up the
- # module import directory structure!
- child_name = name[-1]
- self.imported_modules_as.append(child_name)
- self.printo(gen_mod_import(self.raw_module_name,
- strip_py(importName),
- self.dynamic))
-
- def _default_args_handler(self, node, arg_names, current_klass,
- output=None):
- if len(node.defaults):
- output = output or self.output
- default_pos = len(arg_names) - len(node.defaults)
- if arg_names and arg_names[0] == self.method_self:
- default_pos -= 1
- for default_node in node.defaults:
- if isinstance(default_node, ast.Const):
- default_value = self._const(default_node)
- elif isinstance(default_node, ast.Name):
- default_value = self._name(default_node, current_klass)
- elif isinstance(default_node, ast.UnarySub):
- default_value = self._unarysub(default_node, current_klass)
- else:
- raise TranslationError("unsupported type (in _method)", default_node)
-
- default_name = arg_names[default_pos]
- default_pos += 1
- self.printo(" if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value))
-
- def _varargs_handler(self, node, varargname, arg_names, current_klass):
- self.printo(" var", varargname, '= new pyjslib.Tuple();')
- self.printo(" for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {")
- self.printo(" var __arg = arguments[__va_arg];")
- self.printo(" "+varargname+".append(__arg);")
- self.printo(" }")
-
- def _kwargs_parser(self, node, function_name, arg_names, current_klass):
- if len(node.defaults) or node.kwargs:
- default_pos = len(arg_names) - len(node.defaults)
- if arg_names and arg_names[0] == self.method_self:
- default_pos -= 1
- self.printo(function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {")
- for _default_node in node.defaults:
- # default_value = self.expr(default_node, current_klass)
- # if isinstance(default_node, ast.Const):
- # default_value = self._const(default_node)
- # elif isinstance(default_node, ast.Name):
- # default_value = self._name(default_node)
- # elif isinstance(default_node, ast.UnarySub):
- # default_value = self._unarysub(default_node, current_klass)
- # else:
- # raise TranslationError("unsupported type (in _method)", default_node)
-
- default_name = arg_names[default_pos]
- self.printo(" if (typeof %s == 'undefined')" % (default_name))
- self.printo(" %s=__kwargs.%s;" % (default_name, default_name))
- default_pos += 1
-
- # self._default_args_handler(node, arg_names, current_klass)
- if node.kwargs:
- arg_names += ["pyjslib.Dict(__kwargs)"]
- self.printo(" var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";")
- if node.varargs:
- self._varargs_handler(node, "__args", arg_names, current_klass)
- self.printo(" __r.push.apply(__r, __args.getArray())")
- self.printo(" return __r;")
- self.printo("};")
-
- def _function(self, node, local=False):
- if local:
- function_name = node.name
- self.add_local_arg(function_name)
- else:
- function_name = UU + self.modpfx() + node.name
-
- arg_names = list(node.argnames)
- normal_arg_names = list(arg_names)
- if node.kwargs:
- kwargname = normal_arg_names.pop()
- if node.varargs:
- varargname = normal_arg_names.pop()
- declared_arg_names = list(normal_arg_names)
- if node.kwargs:
- declared_arg_names.append(kwargname)
-
- function_args = "(" + ", ".join(declared_arg_names) + ")"
- self.printo("%s = function%s {" % (function_name, function_args))
- self._default_args_handler(node, normal_arg_names, None)
-
- local_arg_names = normal_arg_names + declared_arg_names
-
- if node.varargs:
- self._varargs_handler(node, varargname, declared_arg_names, None)
- local_arg_names.append(varargname)
-
- # stack of local variable names for this function call
- self.local_arg_stack.append(local_arg_names)
-
- for child in node.code:
- self._stmt(child, None)
-
- # remove the top local arg names
- self.local_arg_stack.pop()
-
- # we need to return null always, so it is not undefined
- lastStmt = [p for p in node.code][-1]
- if not isinstance(lastStmt, ast.Return):
- if not self._isNativeFunc(lastStmt):
- self.printo(" return null;")
-
- self.printo("};")
- self.printo("%s.__name__ = '%s';\n" % (function_name, node.name))
-
- self._kwargs_parser(node, function_name, normal_arg_names, None)
-
- def _return(self, node, current_klass):
- expr = self.expr(node.value, current_klass)
- # in python a function call always returns None, so we do it
- # here too
- self.printo(" return " + expr + ";")
-
- def _break(self, node, current_klass):
- self.printo(" break;")
-
- def _continue(self, node, current_klass):
- self.printo(" continue;")
-
- def _callfunc(self, v, current_klass):
-
- if isinstance(v.node, ast.Name):
- if v.node.name in self.top_level_functions:
- call_name = self.modpfx() + v.node.name
- elif v.node.name in self.top_level_classes:
- call_name = self.modpfx() + v.node.name
- elif v.node.name in self.imported_classes:
- call_name = self.imported_classes[v.node.name] + '.' + v.node.name
- elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
- call_name = 'pyjslib.' + v.node.name
- elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
- name = pyjs_builtin_remap(v.node.name)
- call_name = 'pyjslib.' + name
- elif v.node.name == "callable":
- call_name = "pyjslib.isFunction"
- else:
- call_name = v.node.name
- call_args = []
- elif isinstance(v.node, ast.Getattr):
- attr_name = v.node.attrname
-
- if isinstance(v.node.expr, ast.Name):
- call_name = self._name2(v.node.expr, current_klass, attr_name)
- call_args = []
- elif isinstance(v.node.expr, ast.Getattr):
- call_name = self._getattr2(v.node.expr, current_klass, attr_name)
- call_args = []
- elif isinstance(v.node.expr, ast.CallFunc):
- call_name = self._callfunc(v.node.expr, current_klass) + "." + v.node.attrname
- call_args = []
- elif isinstance(v.node.expr, ast.Subscript):
- call_name = self._subscript(v.node.expr, current_klass) + "." + v.node.attrname
- call_args = []
- elif isinstance(v.node.expr, ast.Const):
- call_name = self.expr(v.node.expr, current_klass) + "." + v.node.attrname
- call_args = []
- else:
- raise TranslationError("unsupported type (in _callfunc)", v.node.expr)
- else:
- raise TranslationError("unsupported type (in _callfunc)", v.node)
-
- call_name = strip_py(call_name)
-
- kwargs = []
- star_arg_name = None
- if v.star_args:
- star_arg_name = self.expr(v.star_args, current_klass)
-
- for ch4 in v.args:
- if isinstance(ch4, ast.Keyword):
- kwarg = ch4.name + ":" + self.expr(ch4.expr, current_klass)
- kwargs.append(kwarg)
- else:
- arg = self.expr(ch4, current_klass)
- call_args.append(arg)
-
- if kwargs:
- fn_args = ", ".join(['{' + ', '.join(kwargs) + '}']+call_args)
- else:
- fn_args = ", ".join(call_args)
-
- if kwargs or star_arg_name:
- if not star_arg_name:
- star_arg_name = 'null'
- try:
- call_this, method_name = call_name.rsplit(".", 1)
- except ValueError:
- # Must be a function call ...
- return ("pyjs_kwargs_function_call("+call_name+", " +
- star_arg_name + ", ["+fn_args+"]" + ")")
- else:
- return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', " +
- star_arg_name + ", ["+fn_args+"]" + ")")
- else:
- return call_name + "(" + ", ".join(call_args) + ")"
-
- def _print(self, node, current_klass):
- if self.optimize:
- return
- call_args = []
- for ch4 in node.nodes:
- arg = self.expr(ch4, current_klass)
- call_args.append(arg)
-
- self.printo("pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");")
-
- def _tryExcept(self, node, current_klass):
- if len(node.handlers) != 1:
- raise TranslationError("except statements in this form are" +
- " not supported", node)
-
- expr = node.handlers[0][0]
- as_ = node.handlers[0][1]
- if as_:
- errName = as_.name
- else:
- errName = 'err'
-
- # XXX TODO: check that this should instead be added as a _separate_
- # local scope, temporary to the function. oh dearie me.
- self.add_local_arg(errName)
-
- self.printo(" try {")
- for stmt in node.body.nodes:
- self._stmt(stmt, current_klass)
- self.printo(" } catch(%s) {" % errName)
- if expr:
- k = []
- if isinstance(expr, ast.Tuple):
- for x in expr.nodes:
- k.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict(err=errName, expr=self.expr(x, current_klass)))
- else:
- k = [" (%(err)s.__name__ == %(expr)s.__name__) " % dict(err=errName, expr=self.expr(expr, current_klass))]
- self.printo(" if(%s) {" % '||\n\t\t'.join(k))
- for stmt in node.handlers[0][2]:
- self._stmt(stmt, current_klass)
- if expr:
- # self.printo("} else { throw(%s); } " % errName)
- self.printo("}")
- if node.else_ is not None:
- self.printo(" } finally {")
- for stmt in node.else_:
- self._stmt(stmt, current_klass)
- self.printo(" }")
-
- # XXX: change use_getattr to True to enable "strict" compilation
- # but incurring a 100% performance penalty. oops.
- def _getattr(self, v, current_klass, use_getattr=False):
- attr_name = v.attrname
- if isinstance(v.expr, ast.Name):
- obj = self._name(v.expr, current_klass, return_none_for_module=True)
- if obj is None and v.expr.name in self.module_imports():
- # XXX TODO: distinguish between module import classes
- # and variables. right now, this is a hack to get
- # the sys module working.
- # if v.expr.name == 'sys':
- return v.expr.name+'.'+attr_name
- # return v.expr.name+'.__'+attr_name+'.prototype.__class__'
- if not use_getattr or attr_name == '__class__' or \
- attr_name == '__name__':
- return obj + "." + attr_name
- return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
- elif isinstance(v.expr, ast.Getattr):
- return self._getattr(v.expr, current_klass) + "." + attr_name
- elif isinstance(v.expr, ast.Subscript):
- return self._subscript(v.expr, self.modpfx()) + "." + attr_name
- elif isinstance(v.expr, ast.CallFunc):
- return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
- else:
- raise TranslationError("unsupported type (in _getattr)", v.expr)
-
- def modpfx(self):
- return strip_py(self.module_prefix)
-
- def _name(self, v, current_klass, top_level=False,
- return_none_for_module=False):
-
- if v.name == 'ilikesillynamesfornicedebugcode':
- print(top_level, current_klass, repr(v))
- print(self.top_level_vars)
- print(self.top_level_functions)
- print(self.local_arg_stack)
- print("error...")
-
- local_var_names = None
- las = len(self.local_arg_stack)
- if las > 0:
- local_var_names = self.local_arg_stack[-1]
-
- if v.name == "True":
- return "true"
- elif v.name == "False":
- return "false"
- elif v.name == "None":
- return "null"
- elif v.name == '__name__' and current_klass is None:
- return self.modpfx() + v.name
- elif v.name == self.method_self:
- return "this"
- elif v.name in self.top_level_functions:
- return UU+self.modpfx() + v.name
- elif v.name in self.method_imported_globals:
- return UU+self.modpfx() + v.name
- elif not current_klass and las == 1 and v.name in self.top_level_vars:
- return UU+self.modpfx() + v.name
- elif v.name in local_var_names:
- return v.name
- elif v.name in self.imported_classes:
- return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
- elif v.name in self.top_level_classes:
- return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
- elif v.name in self.module_imports() and return_none_for_module:
- return None
- elif v.name in PYJSLIB_BUILTIN_CLASSES:
- return "pyjslib." + pyjs_builtin_remap(v.name)
- elif current_klass:
- if v.name not in local_var_names and \
- v.name not in self.top_level_vars and \
- v.name not in PYJS_GLOBAL_VARS and \
- v.name not in self.top_level_functions:
-
- cls_name = current_klass
- if hasattr(cls_name, "name"):
- cls_name_ = cls_name.name_
- cls_name = cls_name.name
- else:
- cls_name_ = current_klass + "_" # XXX ???
- name = UU+cls_name_ + ".prototype.__class__." + v.name
- if v.name == 'listener':
- name = 'listener+' + name
- return name
-
- return v.name
-
- def _name2(self, v, current_klass, attr_name):
- obj = v.name
-
- if obj in self.method_imported_globals:
- call_name = UU+self.modpfx() + obj + "." + attr_name
- elif obj in self.imported_classes:
- # attr_str = ""
- # if attr_name != "__init__":
- attr_str = ".prototype.__class__." + attr_name
- call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
- elif obj in self.module_imports():
- call_name = obj + "." + attr_name
- elif obj[0] == obj[0].upper(): # XXX HACK ALERT
- call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
- else:
- call_name = UU+self._name(v, current_klass) + "." + attr_name
-
- return call_name
-
- def _getattr2(self, v, current_klass, attr_name):
- if isinstance(v.expr, ast.Getattr):
- call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
- elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
- call_name = UU+v.expr.name + '.__' + v.attrname+".prototype.__class__."+attr_name
- else:
- obj = self.expr(v.expr, current_klass)
- call_name = obj + "." + v.attrname + "." + attr_name
-
- return call_name
-
- def _class(self, node):
- """
- Handle a class definition.
-
- In order to translate python semantics reasonably well, the following
- structure is used:
-
- A special object is created for the class, which inherits attributes
- from the superclass, or Object if there's no superclass. This is the
- class object; the object which you refer to when specifying the
- class by name. Static, class, and unbound methods are copied
- from the superclass object.
-
- A special constructor function is created with the same name as the
- class, which is used to create instances of that class.
-
- A javascript class (e.g. a function with a prototype attribute) is
- created which is the javascript class of created instances, and
- which inherits attributes from the class object. Bound methods are
- copied from the superclass into this class rather than inherited,
- because the class object contains unbound, class, and static methods
- that we don't necessarily want to inherit.
-
- The type of a method can now be determined by inspecting its
- static_method, unbound_method, class_method, or instance_method
- attribute; only one of these should be true.
-
- Much of this work is done in pyjs_extend, is pyjslib.py
- """
- class_name = self.modpfx() + uuprefix(node.name, 1)
- class_name_ = self.modpfx() + uuprefix(node.name)
- current_klass = Klass(class_name, class_name_)
- init_method = None
- for child in node.code:
- if isinstance(child, ast.Function):
- current_klass.add_function(child.name)
- if child.name == "__init__":
- init_method = child
-
- if len(node.bases) == 0:
- base_class = "pyjslib.__Object"
- elif len(node.bases) == 1:
- if isinstance(node.bases[0], ast.Name):
- if node.bases[0].name in self.imported_classes:
- base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
- base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
- else:
- base_class_ = self.modpfx() + "__" + node.bases[0].name
- base_class = self.modpfx() + node.bases[0].name
- elif isinstance(node.bases[0], ast.Getattr):
- # the bases are not in scope of the class so do not
- # pass our class to self._name
- base_class_ = self._name(node.bases[0].expr, None) + \
- ".__" + node.bases[0].attrname
- base_class = \
- self._name(node.bases[0].expr, None) + \
- "." + node.bases[0].attrname
- else:
- raise TranslationError("unsupported type (in _class)", node.bases[0])
-
- current_klass.set_base(base_class)
- else:
- raise TranslationError("more than one base (in _class)", node)
-
- self.printo(UU+class_name_ + " = function () {")
- # call superconstructor
- # if base_class:
- # self.printo(" __" + base_class + ".call(this);")
- self.printo("}")
-
- if not init_method:
- init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
- # self._method(init_method, current_klass, class_name)
-
- # Generate a function which constructs the object
- clsfunc = ast.Function(
- [], node.name,
- init_method.argnames[1:],
- init_method.defaults,
- init_method.flags,
- None,
- [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
- # I attempted lazy initialization, but then you can't access static class members
- # " if(!__"+base_class+".__was_initialized__)"+
- # " __" + class_name + "_initialize();\n" +
- " var instance = new " + UU + class_name_ + "();\n" +
- " if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
- " return instance;"
- )]))])
-
- self._function(clsfunc, False)
- self.printo(UU+class_name_ + ".__initialize__ = function () {")
- self.printo(" if("+UU+class_name_+".__was_initialized__) return;")
- self.printo(" "+UU+class_name_+".__was_initialized__ = true;")
- cls_obj = UU+class_name_ + '.prototype.__class__'
-
- if class_name == "pyjslib.__Object":
- self.printo(" "+cls_obj+" = {};")
- else:
- if base_class and base_class not in ("object", "pyjslib.__Object"):
- self.printo(" if(!"+UU+base_class_+".__was_initialized__)")
- self.printo(" "+UU+base_class_+".__initialize__();")
- self.printo(" pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");")
- else:
- self.printo(" pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);")
-
- self.printo(" "+cls_obj+".__new__ = "+UU+class_name+";")
- self.printo(" "+cls_obj+".__name__ = '"+UU+node.name+"';")
-
- for child in node.code:
- if isinstance(child, ast.Pass):
- pass
- elif isinstance(child, ast.Function):
- self._method(child, current_klass, class_name, class_name_)
- elif isinstance(child, ast.Assign):
- self.classattr(child, current_klass)
- elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const):
- # Probably a docstring, turf it
- pass
- else:
- raise TranslationError("unsupported type (in _class)", child)
- self.printo("}")
-
- self.printo(class_name_+".__initialize__();")
-
- def classattr(self, node, current_klass):
- self._assign(node, current_klass, True)
-
- def _raise(self, node, current_klass):
- if node.expr2:
- raise TranslationError("More than one expression unsupported",
- node)
- self.printo("throw (%s);" % self.expr(
- node.expr1, current_klass))
-
- def _method(self, node, current_klass, class_name, class_name_):
- # reset global var scope
- self.method_imported_globals = set()
-
- arg_names = list(node.argnames)
-
- classmethod = False
- staticmethod = False
- if node.decorators:
- for d in node.decorators:
- if d.name == "classmethod":
- classmethod = True
- elif d.name == "staticmethod":
- staticmethod = True
-
- if staticmethod:
- staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
- self._function(staticfunc, True)
- self.printo(" " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";")
- self.printo(" " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;")
- return
- else:
- if len(arg_names) == 0:
- raise TranslationError("methods must take an argument 'self' (in _method)", node)
- self.method_self = arg_names[0]
-
- # if not classmethod and arg_names[0] != "self":
- # raise TranslationError("first arg not 'self' (in _method)", node)
-
- normal_arg_names = arg_names[1:]
- if node.kwargs:
- kwargname = normal_arg_names.pop()
- if node.varargs:
- varargname = normal_arg_names.pop()
- declared_arg_names = list(normal_arg_names)
- if node.kwargs:
- declared_arg_names.append(kwargname)
-
- function_args = "(" + ", ".join(declared_arg_names) + ")"
-
- if classmethod:
- fexpr = UU + class_name_ + ".prototype.__class__." + node.name
- else:
- fexpr = UU + class_name_ + ".prototype." + node.name
- self.printo(" "+fexpr + " = function" + function_args + " {")
-
- # default arguments
- self._default_args_handler(node, normal_arg_names, current_klass)
-
- local_arg_names = normal_arg_names + declared_arg_names
-
- if node.varargs:
- self._varargs_handler(node, varargname, declared_arg_names, current_klass)
- local_arg_names.append(varargname)
-
- # stack of local variable names for this function call
- self.local_arg_stack.append(local_arg_names)
-
- for child in node.code:
- self._stmt(child, current_klass)
-
- # remove the top local arg names
- self.local_arg_stack.pop()
-
- self.printo(" };")
-
- self._kwargs_parser(node, fexpr, normal_arg_names, current_klass)
-
- if classmethod:
- # Have to create a version on the instances which automatically passes the
- # class as "self"
- altexpr = UU + class_name_ + ".prototype." + node.name
- self.printo(" "+altexpr + " = function() {")
- self.printo(" return " + fexpr + ".apply(this.__class__, arguments);")
- self.printo(" };")
- self.printo(" "+fexpr+".class_method = true;")
- self.printo(" "+altexpr+".instance_method = true;")
- else:
- # For instance methods, we need an unbound version in the class object
- altexpr = UU + class_name_ + ".prototype.__class__." + node.name
- self.printo(" "+altexpr + " = function() {")
- self.printo(" return " + fexpr + ".call.apply("+fexpr+", arguments);")
- self.printo(" };")
- self.printo(" "+altexpr+".unbound_method = true;")
- self.printo(" "+fexpr+".instance_method = true;")
- self.printo(" "+altexpr+".__name__ = '%s';" % node.name)
-
- self.printo(UU + class_name_ + ".prototype.%s.__name__ = '%s';" %
- (node.name, node.name))
-
- if node.kwargs or len(node.defaults):
- self.printo(" "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;")
-
- self.method_self = None
- self.method_imported_globals = set()
-
- def _isNativeFunc(self, node):
- if isinstance(node, ast.Discard):
- if isinstance(node.expr, ast.CallFunc):
- if isinstance(node.expr.node, ast.Name) and \
- node.expr.node.name == NATIVE_JS_FUNC_NAME:
- return True
- return False
-
- def _stmt(self, node, current_klass):
- debugStmt = self.debug and not self._isNativeFunc(node)
- if debugStmt:
- self.printo(' try {')
-
- if isinstance(node, ast.Return):
- self._return(node, current_klass)
- elif isinstance(node, ast.Break):
- self._break(node, current_klass)
- elif isinstance(node, ast.Continue):
- self._continue(node, current_klass)
- elif isinstance(node, ast.Assign):
- self._assign(node, current_klass)
- elif isinstance(node, ast.AugAssign):
- self._augassign(node, current_klass)
- elif isinstance(node, ast.Discard):
- self._discard(node, current_klass)
- elif isinstance(node, ast.If):
- self._if(node, current_klass)
- elif isinstance(node, ast.For):
- self._for(node, current_klass)
- elif isinstance(node, ast.While):
- self._while(node, current_klass)
- elif isinstance(node, ast.Subscript):
- self._subscript_stmt(node, current_klass)
- elif isinstance(node, ast.Global):
- self._global(node, current_klass)
- elif isinstance(node, ast.Pass):
- pass
- elif isinstance(node, ast.Function):
- self._function(node, True)
- elif isinstance(node, ast.Printnl):
- self._print(node, current_klass)
- elif isinstance(node, ast.Print):
- self._print(node, current_klass)
- elif isinstance(node, ast.TryExcept):
- self._tryExcept(node, current_klass)
- elif isinstance(node, ast.Raise):
- self._raise(node, current_klass)
- else:
- raise TranslationError("unsupported type (in _stmt)", node)
-
- if debugStmt:
-
- lt = self.get_line_trace(node)
- isHaltFunction = self.module_prefix + "IsHaltException"
-
- out = (
- ' } catch (__err) {',
- ' if (' + isHaltFunction + '(__err.name)) {',
- ' throw __err;',
- ' } else {',
- ' st = sys.printstack() + ' + '"%s"' % lt + "+ '\\n' ;"
- ' alert("' + 'Error in ' + lt + '"' +
- '+"\\n"+__err.name+": "+__err.message' +
- '+"\\n\\nStack trace:\\n"' + '+st' + ');',
- ' debugger;',
- ' throw new ' + self.module_prefix + 'HaltException();',
- ' }',
- ' }'
- )
- for s in out:
- self.printo(s)
-
- def get_line_trace(self, node):
- lineNum = "Unknown"
- srcLine = ""
- if hasattr(node, "lineno"):
- if node.lineno is not None:
- lineNum = node.lineno
- srcLine = self.src[min(lineNum, len(self.src))-1]
- srcLine = srcLine.replace('\\', '\\\\')
- srcLine = srcLine.replace('"', '\\"')
- srcLine = srcLine.replace("'", "\\'")
-
- return self.raw_module_name + ".py, line " \
- + str(lineNum) + ":"\
- + "\\n" \
- + " " + srcLine
-
- def _augassign(self, node, current_klass):
- v = node.node
- if isinstance(v, ast.Getattr):
- # XXX HACK! don't allow += on return result of getattr.
- # TODO: create a temporary variable or something.
- lhs = self._getattr(v, current_klass, False)
- else:
- lhs = self._name(node.node, current_klass)
- op = node.op
- rhs = self.expr(node.expr, current_klass)
- self.printo(" " + lhs + " " + op + " " + rhs + ";")
-
- def _assign(self, node, current_klass, top_level=False):
- if len(node.nodes) != 1:
- tempvar = '__temp'+str(node.lineno)
- tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
- self._assign(tnode, current_klass, top_level)
- for v in node.nodes:
- tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
- self._assign(tnode2, current_klass, top_level)
- return
-
- local_var_names = None
- if len(self.local_arg_stack) > 0:
- local_var_names = self.local_arg_stack[-1]
-
- def _lhsFromAttr(v, current_klass):
- attr_name = v.attrname
- if isinstance(v.expr, ast.Name):
- lhs = self._name(v.expr, current_klass) + "." + attr_name
- elif isinstance(v.expr, ast.Getattr):
- lhs = self._getattr(v, current_klass)
- elif isinstance(v.expr, ast.Subscript):
- lhs = self._subscript(v.expr, current_klass) + "." + attr_name
- else:
- raise TranslationError("unsupported type (in _assign)", v.expr)
- return lhs
-
- def _lhsFromName(v, top_level, current_klass):
- if top_level:
- if current_klass:
- lhs = UU+current_klass.name_ + ".prototype.__class__." \
- + v.name
- else:
- self.top_level_vars.add(v.name)
- vname = self.modpfx() + v.name
- if not self.modpfx() and v.name not in\
- self.method_imported_globals:
- lhs = "var " + vname
- else:
- lhs = UU + vname
- self.add_local_arg(v.name)
- else:
- if v.name in local_var_names:
- lhs = v.name
- elif v.name in self.method_imported_globals:
- lhs = self.modpfx() + v.name
- else:
- lhs = "var " + v.name
- self.add_local_arg(v.name)
- return lhs
-
- dbg = 0
- v = node.nodes[0]
- if isinstance(v, ast.AssAttr):
- lhs = _lhsFromAttr(v, current_klass)
- if v.flags == "OP_ASSIGN":
- op = "="
- else:
- raise TranslationError("unsupported flag (in _assign)", v)
-
- elif isinstance(v, ast.AssName):
- lhs = _lhsFromName(v, top_level, current_klass)
- if v.flags == "OP_ASSIGN":
- op = "="
- else:
- raise TranslationError("unsupported flag (in _assign)", v)
- elif isinstance(v, ast.Subscript):
- if v.flags == "OP_ASSIGN":
- obj = self.expr(v.expr, current_klass)
- if len(v.subs) != 1:
- raise TranslationError("must have one sub (in _assign)", v)
- idx = self.expr(v.subs[0], current_klass)
- value = self.expr(node.expr, current_klass)
- self.printo(" " + obj + ".__setitem__(" + idx + ", " + value + ");")
- return
- else:
- raise TranslationError("unsupported flag (in _assign)", v)
- elif isinstance(v, (ast.AssList, ast.AssTuple)):
- uniqueID = self.nextTupleAssignID
- self.nextTupleAssignID += 1
- tempName = "__tupleassign" + str(uniqueID) + "__"
- self.printo(" var " + tempName + " = " + self.expr(node.expr, current_klass) + ";")
- for index, child in enumerate(v.getChildNodes()):
- rhs = tempName + ".__getitem__(" + str(index) + ")"
-
- if isinstance(child, ast.AssAttr):
- lhs = _lhsFromAttr(child, current_klass)
- elif isinstance(child, ast.AssName):
- lhs = _lhsFromName(child, top_level, current_klass)
- elif isinstance(child, ast.Subscript):
- if child.flags == "OP_ASSIGN":
- obj = self.expr(child.expr, current_klass)
- if len(child.subs) != 1:
- raise TranslationError("must have one sub " +
- "(in _assign)", child)
- idx = self.expr(child.subs[0], current_klass)
- value = self.expr(node.expr, current_klass)
- self.printo(" " + obj + ".__setitem__(" + idx + ", " + rhs + ");")
- continue
- self.printo(" " + lhs + " = " + rhs + ";")
- return
- else:
- raise TranslationError("unsupported type (in _assign)", v)
-
- rhs = self.expr(node.expr, current_klass)
- if dbg:
- print("b", repr(node.expr), rhs)
- self.printo(" " + lhs + " " + op + " " + rhs + ";")
-
- def _discard(self, node, current_klass):
-
- if isinstance(node.expr, ast.CallFunc):
- debugStmt = self.debug and not self._isNativeFunc(node)
- if debugStmt and isinstance(node.expr.node, ast.Name) and \
- node.expr.node.name == 'import_wait':
- debugStmt = False
- if debugStmt:
- st = self.get_line_trace(node)
- self.printo("sys.addstack('%s');\n" % st)
- if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
- if len(node.expr.args) != 1:
- raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr)
- if not isinstance(node.expr.args[0], ast.Const):
- raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr)
- raw_js = node.expr.args[0].value
- self.printo(raw_js)
- else:
- expr = self._callfunc(node.expr, current_klass)
- self.printo(" " + expr + ";")
-
- if debugStmt:
- self.printo("sys.popstack();\n")
-
- elif isinstance(node.expr, ast.Const):
- if node.expr.value is not None: # Empty statements generate ignore None
- self.printo(self._const(node.expr))
- else:
- raise TranslationError("unsupported type (in _discard)", node.expr)
-
- def _if(self, node, current_klass):
- for i in range(len(node.tests)):
- test, consequence = node.tests[i]
- if i == 0:
- keyword = "if"
- else:
- keyword = "else if"
-
- self._if_test(keyword, test, consequence, current_klass)
-
- if node.else_:
- keyword = "else"
- test = None
- consequence = node.else_
-
- self._if_test(keyword, test, consequence, current_klass)
-
- def _if_test(self, keyword, test, consequence, current_klass):
- if test:
- expr = self.expr(test, current_klass)
-
- self.printo(" " + keyword + " (pyjslib.bool(" + expr + ")) {")
- else:
- self.printo(" " + keyword + " {")
-
- if isinstance(consequence, ast.Stmt):
- for child in consequence.nodes:
- self._stmt(child, current_klass)
- else:
- raise TranslationError("unsupported type (in _if_test)", consequence)
-
- self.printo(" }")
-
- def _from(self, node):
- for name in node.names:
- # look up "hack" in AppTranslator as to how findFile gets here
- module_name = node.modname + "." + name[0]
- try:
- ff = self.findFile(module_name + ".py")
- except Exception:
- ff = None
- if ff:
- self.add_imported_module(module_name)
- else:
- self.imported_classes[name[0]] = node.modname
-
- def _compare(self, node, current_klass):
- lhs = self.expr(node.expr, current_klass)
-
- if len(node.ops) != 1:
- raise TranslationError("only one ops supported (in _compare)", node)
-
- op = node.ops[0][0]
- rhs_node = node.ops[0][1]
- rhs = self.expr(rhs_node, current_klass)
-
- if op == "==":
- return "pyjslib.eq(%s, %s)" % (lhs, rhs)
- if op == "in":
- return rhs + ".__contains__(" + lhs + ")"
- elif op == "not in":
- return "!" + rhs + ".__contains__(" + lhs + ")"
- elif op == "is":
- op = "==="
- elif op == "is not":
- op = "!=="
-
- return "(" + lhs + " " + op + " " + rhs + ")"
-
- def _not(self, node, current_klass):
- expr = self.expr(node.expr, current_klass)
-
- return "!(" + expr + ")"
-
- def _or(self, node, current_klass):
- expr = "("+(") || (".join([self.expr(child, current_klass) for child in node.nodes]))+')'
- return expr
-
- def _and(self, node, current_klass):
- expr = "("+(") && (".join([self.expr(child, current_klass) for child in node.nodes]))+")"
- return expr
-
- def _for(self, node, current_klass):
- assign_name = ""
- assign_tuple = ""
-
- # based on Bob Ippolito's Iteration in Javascript code
- if isinstance(node.assign, ast.AssName):
- assign_name = node.assign.name
- self.add_local_arg(assign_name)
- if node.assign.flags == "OP_ASSIGN":
- op = "="
- elif isinstance(node.assign, ast.AssTuple):
- op = "="
- i = 0
- for child in node.assign:
- child_name = child.name
- if assign_name == "":
- assign_name = "temp_" + child_name
- self.add_local_arg(child_name)
- assign_tuple += """
- var %(child_name)s %(op)s %(assign_name)s.__getitem__(%(i)i);
- """ % locals()
- i += 1
- else:
- raise TranslationError("unsupported type (in _for)", node.assign)
-
- if isinstance(node.list, ast.Name):
- list_expr = self._name(node.list, current_klass)
- elif isinstance(node.list, ast.Getattr):
- list_expr = self._getattr(node.list, current_klass)
- elif isinstance(node.list, ast.CallFunc):
- list_expr = self._callfunc(node.list, current_klass)
- else:
- raise TranslationError("unsupported type (in _for)", node.list)
-
- lhs = "var " + assign_name
- iterator_name = "__" + assign_name
-
- loc_dict = {
- "iterator_name": iterator_name,
- "list_expr": list_expr,
- "lhs": lhs,
- "op": op,
- "assign_tuple": assign_tuple,
- }
-
- self.printo("""
- var %(iterator_name)s = %(list_expr)s.__iter__();
- try {
- while (true) {
- %(lhs)s %(op)s %(iterator_name)s.next();
- %(assign_tuple)s
- """ % loc_dict)
- for n in node.body.nodes:
- self._stmt(n, current_klass)
- self.printo("""
- }
- } catch (e) {
- if (e.__name__ != pyjslib.StopIteration.__name__) {
- throw e;
- }
- }
- """)
-
- def _while(self, node, current_klass):
- test = self.expr(node.test, current_klass)
- self.printo(" while (pyjslib.bool(" + test + ")) {")
- if isinstance(node.body, ast.Stmt):
- for child in node.body.nodes:
- self._stmt(child, current_klass)
- else:
- raise TranslationError("unsupported type (in _while)", node.body)
- self.printo(" }")
-
- def _const(self, node):
- if isinstance(node.value, int):
- return str(node.value)
- elif isinstance(node.value, float):
- return str(node.value)
- elif isinstance(node.value, basestring):
- v = node.value
- if isinstance(node.value, text):
- v = v.encode('utf-8')
- return "String('%s')" % escapejs(v)
- elif node.value is None:
- return "null"
- else:
- raise TranslationError("unsupported type (in _const)", node)
-
- def _unaryadd(self, node, current_klass):
- return self.expr(node.expr, current_klass)
-
- def _unarysub(self, node, current_klass):
- return "-" + self.expr(node.expr, current_klass)
-
- def _add(self, node, current_klass):
- return self.expr(node.left, current_klass) + " + " + self.expr(node.right, current_klass)
-
- def _sub(self, node, current_klass):
- return self.expr(node.left, current_klass) + " - " + self.expr(node.right, current_klass)
-
- def _div(self, node, current_klass):
- return self.expr(node.left, current_klass) + " / " + self.expr(node.right, current_klass)
-
- def _mul(self, node, current_klass):
- return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
-
- def _mod(self, node, current_klass):
- if isinstance(node.left, ast.Const) and isinstance(node.left.value, str):
- self.imported_js.add("sprintf.js") # Include the sprintf functionality if it is used
- return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
- return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
-
- def _invert(self, node, current_klass):
- return "~" + self.expr(node.expr, current_klass)
-
- def _bitand(self, node, current_klass):
- return " & ".join([self.expr(child, current_klass) for child in node.nodes])
-
- def _bitshiftleft(self, node, current_klass):
- return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
-
- def _bitshiftright(self, node, current_klass):
- return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
-
- def _bitxor(self, node, current_klass):
- return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
-
- def _bitor(self, node, current_klass):
- return " | ".join([self.expr(child, current_klass) for child in node.nodes])
-
- def _subscript(self, node, current_klass):
- if node.flags == "OP_APPLY":
- if len(node.subs) == 1:
- return self.expr(node.expr, current_klass) + ".__getitem__(" + self.expr(node.subs[0], current_klass) + ")"
- else:
- raise TranslationError("must have one sub (in _subscript)", node)
- else:
- raise TranslationError("unsupported flag (in _subscript)", node)
-
- def _subscript_stmt(self, node, current_klass):
- if node.flags == "OP_DELETE":
- self.printo(" " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");")
- else:
- raise TranslationError("unsupported flag (in _subscript)", node)
-
- def _list(self, node, current_klass):
- return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
-
- def _dict(self, node, current_klass):
- items = []
- for x in node.items:
- key = self.expr(x[0], current_klass)
- value = self.expr(x[1], current_klass)
- items.append("[" + key + ", " + value + "]")
- return "new pyjslib.Dict([" + ", ".join(items) + "])"
-
- def _tuple(self, node, current_klass):
- return "new pyjslib.Tuple([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
-
- def _lambda(self, node, current_klass):
- if node.varargs:
- raise TranslationError("varargs are not supported in Lambdas", node)
- if node.kwargs:
- raise TranslationError("kwargs are not supported in Lambdas", node)
- res = cStringIO()
- arg_names = list(node.argnames)
- function_args = ", ".join(arg_names)
- for child in node.getChildNodes():
- expr = self.expr(child, None)
- print("function (%s){" % function_args, file=res)
- self._default_args_handler(node, arg_names, None,
- output=res)
- print('return %s;}' % expr, file=res)
- return res.getvalue()
-
- def _slice(self, node, current_klass):
- if node.flags == "OP_APPLY":
- lower = "null"
- upper = "null"
- if node.lower is not None:
- lower = self.expr(node.lower, current_klass)
- if node.upper is not None:
- upper = self.expr(node.upper, current_klass)
- return "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
- else:
- raise TranslationError("unsupported flag (in _slice)", node)
-
- def _global(self, node, current_klass):
- for name in node.names:
- self.method_imported_globals.add(name)
-
- def expr(self, node, current_klass):
- if isinstance(node, ast.Const):
- return self._const(node)
- # @@@ not sure if the parentheses should be here or in individual operator functions - JKT
- elif isinstance(node, ast.Mul):
- return " ( " + self._mul(node, current_klass) + " ) "
- elif isinstance(node, ast.Add):
- return " ( " + self._add(node, current_klass) + " ) "
- elif isinstance(node, ast.Sub):
- return " ( " + self._sub(node, current_klass) + " ) "
- elif isinstance(node, ast.Div):
- return " ( " + self._div(node, current_klass) + " ) "
- elif isinstance(node, ast.Mod):
- return self._mod(node, current_klass)
- elif isinstance(node, ast.UnaryAdd):
- return self._unaryadd(node, current_klass)
- elif isinstance(node, ast.UnarySub):
- return self._unarysub(node, current_klass)
- elif isinstance(node, ast.Not):
- return self._not(node, current_klass)
- elif isinstance(node, ast.Or):
- return self._or(node, current_klass)
- elif isinstance(node, ast.And):
- return self._and(node, current_klass)
- elif isinstance(node, ast.Invert):
- return self._invert(node, current_klass)
- elif isinstance(node, ast.Bitand):
- return "("+self._bitand(node, current_klass)+")"
- elif isinstance(node, ast.LeftShift):
- return self._bitshiftleft(node, current_klass)
- elif isinstance(node, ast.RightShift):
- return self._bitshiftright(node, current_klass)
- elif isinstance(node, ast.Bitxor):
- return "("+self._bitxor(node, current_klass)+")"
- elif isinstance(node, ast.Bitor):
- return "("+self._bitor(node, current_klass)+")"
- elif isinstance(node, ast.Compare):
- return self._compare(node, current_klass)
- elif isinstance(node, ast.CallFunc):
- return self._callfunc(node, current_klass)
- elif isinstance(node, ast.Name):
- return self._name(node, current_klass)
- elif isinstance(node, ast.Subscript):
- return self._subscript(node, current_klass)
- elif isinstance(node, ast.Getattr):
- return self._getattr(node, current_klass)
- elif isinstance(node, ast.List):
- return self._list(node, current_klass)
- elif isinstance(node, ast.Dict):
- return self._dict(node, current_klass)
- elif isinstance(node, ast.Tuple):
- return self._tuple(node, current_klass)
- elif isinstance(node, ast.Slice):
- return self._slice(node, current_klass)
- elif isinstance(node, ast.Lambda):
- return self._lambda(node, current_klass)
- else:
- raise TranslationError("unsupported type (in expr)", node)
-
-
-def translate(file_name, module_name, debug=False):
- f = open(file_name, "r")
- src = f.read()
- f.close()
- output = cStringIO()
- mod = compiler.parseFile(file_name)
- Translator(module_name, module_name, module_name, src, debug, mod, output)
- return output.getvalue()
-
-
-class PlatformParser(object):
- def __init__(self, platform_dir="", verbose=True):
- self.platform_dir = platform_dir
- self.parse_cache = {}
- self.platform = ""
- self.verbose = verbose
-
- def setPlatform(self, platform):
- self.platform = platform
-
- def parseModule(self, module_name, file_name):
-
- importing = False
- if file_name not in self.parse_cache:
- importing = True
- mod = compiler.parseFile(file_name)
- self.parse_cache[file_name] = mod
- else:
- mod = self.parse_cache[file_name]
-
- override = False
- platform_file_name = self.generatePlatformFilename(file_name)
- if self.platform and os.path.isfile(platform_file_name):
- mod = copy.deepcopy(mod)
- mod_override = compiler.parseFile(platform_file_name)
- self.merge(mod, mod_override)
- override = True
-
- if self.verbose:
- if override:
- print("Importing %s (Platform %s)" % (module_name, self.platform))
- elif importing:
- print("Importing %s" % (module_name))
-
- return mod, override
-
- def generatePlatformFilename(self, file_name):
- (module_name, extension) = os.path.splitext(os.path.basename(file_name))
- platform_file_name = module_name + self.platform + extension
-
- return os.path.join(os.path.dirname(file_name), self.platform_dir, platform_file_name)
-
- def merge(self, tree1, tree2):
- for child in tree2.node:
- if isinstance(child, ast.Function):
- self.replaceFunction(tree1, child.name, child)
- elif isinstance(child, ast.Class):
- self.replaceClassMethods(tree1, child.name, child)
-
- return tree1
-
- def replaceFunction(self, tree, function_name, function_node):
- # find function to replace
- for child in tree.node:
- if isinstance(child, ast.Function) and child.name == function_name:
- self.copyFunction(child, function_node)
- return
- raise TranslationError("function not found: " + function_name, function_node)
-
- def replaceClassMethods(self, tree, class_name, class_node):
- # find class to replace
- old_class_node = None
- for child in tree.node:
- if isinstance(child, ast.Class) and child.name == class_name:
- old_class_node = child
- break
-
- if not old_class_node:
- raise TranslationError("class not found: " + class_name, class_node)
-
- # replace methods
- for function_node in class_node.code:
- if isinstance(function_node, ast.Function):
- found = False
- for child in old_class_node.code:
- if isinstance(child, ast.Function) and child.name == function_node.name:
- found = True
- self.copyFunction(child, function_node)
- break
-
- if not found:
- raise TranslationError("class method not found: " + class_name + "." + function_node.name, function_node)
-
- def copyFunction(self, target, source):
- target.code = source.code
- target.argnames = source.argnames
- target.defaults = source.defaults
- target.doc = source.doc # @@@ not sure we need to do this any more
-
-
-def dotreplace(fname):
- path, ext = os.path.splitext(fname)
- return path.replace(".", "/") + ext
-
-
-class AppTranslator(object):
-
- def __init__(self, library_dirs=None, parser=None, dynamic=False,
- optimize=False, verbose=True):
- self.extension = ".py"
- self.optimize = optimize
- self.library_modules = []
- self.overrides = {}
- library_dirs = [] if library_dirs is None else library_dirs
- self.library_dirs = path + library_dirs
- self.dynamic = dynamic
- self.verbose = verbose
-
- if not parser:
- self.parser = PlatformParser()
- else:
- self.parser = parser
-
- self.parser.dynamic = dynamic
-
- def findFile(self, file_name):
- if os.path.isfile(file_name):
- return file_name
-
- for library_dir in self.library_dirs:
- file_name = dotreplace(file_name)
- full_file_name = os.path.join(
- os.path.abspath(os.path.dirname(__file__)), library_dir, file_name)
- if os.path.isfile(full_file_name):
- return full_file_name
-
- fnameinit, _ext = os.path.splitext(file_name)
- fnameinit = fnameinit + "/__init__.py"
-
- full_file_name = os.path.join(
- os.path.abspath(os.path.dirname(__file__)), library_dir, fnameinit)
- if os.path.isfile(full_file_name):
- return full_file_name
-
- raise Exception("file not found: " + file_name)
-
- def _translate(self, module_name, is_app=True, debug=False,
- imported_js=None):
- if module_name not in self.library_modules:
- self.library_modules.append(module_name)
-
- file_name = self.findFile(module_name + self.extension)
-
- output = cStringIO()
-
- f = open(file_name, "r")
- src = f.read()
- f.close()
-
- mod, override = self.parser.parseModule(module_name, file_name)
- if override:
- override_name = "%s.%s" % (self.parser.platform.lower(),
- module_name)
- self.overrides[override_name] = override_name
- if is_app:
- mn = '__main__'
- else:
- mn = module_name
- t = Translator(mn, module_name, module_name,
- src, debug, mod, output, self.dynamic, self.optimize,
- self.findFile)
-
- module_str = output.getvalue()
- if imported_js is None:
- imported_js = set()
- imported_js.update(set(t.imported_js))
- imported_modules_str = ""
- for module in t.imported_modules:
- if module not in self.library_modules:
- self.library_modules.append(module)
- # imported_js.update(set(t.imported_js))
- # imported_modules_str += self._translate(
- # module, False, debug=debug, imported_js=imported_js)
-
- return imported_modules_str + module_str
-
- def translate(self, module_name, is_app=True, debug=False,
- library_modules=None):
- app_code = cStringIO()
- lib_code = cStringIO()
- imported_js = set()
- self.library_modules = []
- self.overrides = {}
- if library_modules is not None:
- for library in library_modules:
- if library.endswith(".js"):
- imported_js.add(library)
- continue
- self.library_modules.append(library)
- if self.verbose:
- print('Including LIB', library)
- print('\n//\n// BEGIN LIB '+library+'\n//\n', file=lib_code)
- print(self._translate(library, False, debug=debug, imported_js=imported_js),
- file=lib_code)
-
- print("/* initialize static library */", file=lib_code)
- print("%s%s();\n" % (UU, library), file=lib_code)
-
- print('\n//\n// END LIB '+library+'\n//\n', file=lib_code)
- if module_name:
- print(self._translate(module_name, is_app, debug=debug, imported_js=imported_js),
- file=app_code)
- for js in imported_js:
- path = self.findFile(js)
- if os.path.isfile(path):
- if self.verbose:
- print('Including JS', js)
- print('\n//\n// BEGIN JS '+js+'\n//\n', file=lib_code)
- print(open(path).read(), file=lib_code)
- print('\n//\n// END JS '+js+'\n//\n', file=lib_code)
- else:
- print('Warning: Unable to find imported javascript:', js, file=sys.stderr)
- return lib_code.getvalue(), app_code.getvalue()
-
-
-usage = """
- usage: %s file_name [module_name]
-"""
-
-
-def main():
- if len(sys.argv) < 2:
- print(usage % sys.argv[0], file=sys.stderr)
- sys.exit(1)
- file_name = os.path.abspath(sys.argv[1])
- if not os.path.isfile(file_name):
- print("File not found %s" % file_name, file=sys.stderr)
- sys.exit(1)
- if len(sys.argv) > 2:
- module_name = sys.argv[2]
- else:
- module_name = None
- print(translate(file_name, module_name), end="")
-
-
-if __name__ == "__main__":
- main()
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/svgui.py
--- a/svgui/svgui.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-# Copyright (C) 2017: Andrey Skvortsov
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-
-from __future__ import absolute_import
-import os
-import shutil
-
-import wx
-from svgui.pyjs import translate
-
-import util.paths as paths
-from POULibrary import POULibrary
-from docutil import open_svg
-from py_ext import PythonFileCTNMixin
-
-
-class SVGUILibrary(POULibrary):
- def GetLibraryPath(self):
- return paths.AbsNeighbourFile(__file__, "pous.xml")
-
-
-class SVGUI(PythonFileCTNMixin):
-
- ConfNodeMethods = [
- {
- "bitmap": "ImportSVG",
- "name": _("Import SVG"),
- "tooltip": _("Import SVG"),
- "method": "_ImportSVG"
- },
- {
- "bitmap": "ImportSVG", # should be something different
- "name": _("Inkscape"),
- "tooltip": _("Create HMI"),
- "method": "_StartInkscape"
- },
- ]
-
- def _getSVGpath(self, project_path=None):
- if project_path is None:
- project_path = self.CTNPath()
- # define name for SVG file containing gui layout
- return os.path.join(project_path, "gui.svg")
-
- def _getSVGUIserverpath(self):
- return paths.AbsNeighbourFile(__file__, "svgui_server.py")
-
- def OnCTNSave(self, from_project_path=None):
- if from_project_path is not None:
- shutil.copyfile(self._getSVGpath(from_project_path),
- self._getSVGpath())
- return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
-
- def CTNGenerate_C(self, buildpath, locations):
- """
- Return C code generated by iec2c compiler
- when _generate_softPLC have been called
- @param locations: ignored
- @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
- """
-
- current_location = self.GetCurrentLocation()
- # define a unique name for the generated C file
- location_str = "_".join(map(str, current_location))
-
- res = ([], "", False)
-
- svgfile = self._getSVGpath()
- if os.path.exists(svgfile):
- res += (("gui.svg", open(svgfile, "rb")),)
-
- svguiserverfile = open(self._getSVGUIserverpath(), 'r')
- svguiservercode = svguiserverfile.read()
- svguiserverfile.close()
-
- svguilibpath = os.path.join(self._getBuildPath(), "svguilib.js")
- svguilibfile = open(svguilibpath, 'w')
- fpath = paths.AbsDir(__file__)
- svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "sys.py"), "sys"))
- svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "_pyjs.js"), 'r').read())
- svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "pyjslib.py"), "pyjslib"))
- svguilibfile.write(translate(os.path.join(fpath, "svguilib.py"), "svguilib"))
- svguilibfile.write("pyjslib();\nsvguilib();\n")
- svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "json.js"), 'r').read())
- svguilibfile.write(open(os.path.join(fpath, "livesvg.js"), 'r').read())
- svguilibfile.close()
- jsmodules = {"LiveSVGPage": "svguilib.js"}
- res += (("svguilib.js", open(svguilibpath, "rb")),)
-
- runtimefile_path = os.path.join(buildpath, "runtime_%s.py" % location_str)
- runtimefile = open(runtimefile_path, 'w')
- runtimefile.write(svguiservercode % {"svgfile": "gui.svg"})
- runtimefile.write("""
-def _runtime_%(location)s_start():
- website.LoadHMI(%(svgui_class)s, %(jsmodules)s)
-
-def _runtime_%(location)s_stop():
- website.UnLoadHMI()
-
- """ % {"location": location_str,
- "svgui_class": "SVGUI_HMI",
- "jsmodules": str(jsmodules)})
- runtimefile.close()
-
- res += (("runtime_%s.py" % location_str, open(runtimefile_path, "rb")),)
-
- return res
-
- def _ImportSVG(self):
- dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "", _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
- if dialog.ShowModal() == wx.ID_OK:
- svgpath = dialog.GetPath()
- if os.path.isfile(svgpath):
- shutil.copy(svgpath, self._getSVGpath())
- else:
- self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
- dialog.Destroy()
-
- def _StartInkscape(self):
- svgfile = self._getSVGpath()
- open_inkscape = True
- if not self.GetCTRoot().CheckProjectPathPerm():
- dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
- _("You don't have write permissions.\nOpen Inkscape anyway ?"),
- _("Open Inkscape"),
- wx.YES_NO | wx.ICON_QUESTION)
- open_inkscape = dialog.ShowModal() == wx.ID_YES
- dialog.Destroy()
- if open_inkscape:
- if not os.path.isfile(svgfile):
- svgfile = None
- open_svg(svgfile)
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/svgui_server.py
--- a/svgui/svgui_server.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-
-from __future__ import absolute_import
-import os
-from builtins import str as text
-
-from nevow import tags, loaders
-import simplejson as json # pylint: disable=import-error
-import runtime.NevowServer as NS
-
-svgfile = '%(svgfile)s'
-
-svguiWidgets = {}
-
-currentId = 0
-
-
-def getNewId():
- global currentId
- currentId += 1
- return currentId
-
-
-class SvguiWidget(object):
-
- def __init__(self, classname, id, **kwargs):
- self.classname = classname
- self.id = id
- self.attrs = kwargs.copy()
- self.inputs = {}
- self.outputs = {}
- self.inhibit = False
- self.changed = False
-
- def setinput(self, attrname, value):
- self.inputs[attrname] = value
-
- def getinput(self, attrname, default=None):
- if attrname not in self.inputs:
- self.inputs[attrname] = default
- return self.inputs[attrname]
-
- def setoutput(self, attrname, value):
- if self.outputs.get(attrname) != value:
- self.outputs[attrname] = value
- self.changed = True
- self.RefreshInterface()
-
- def updateoutputs(self, **kwargs):
- for attrname, value in kwargs.iteritems():
- if self.outputs.get(attrname) != value:
- self.outputs[attrname] = value
- self.changed = True
- self.RefreshInterface()
-
- def RefreshInterface(self):
- interface = website.getHMI()
- if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
- self.changed = False
- d = interface.sendData(self)
- if d is not None:
- self.inhibit = True
- d.addCallback(self.InterfaceRefreshed)
-
- def InterfaceRefreshed(self, result):
- self.inhibit = False
- if self.changed:
- self.RefreshInterface()
-
-
-def get_object_init_state(obj):
- # Convert objects to a dictionary of their representation
- attrs = obj.attrs.copy()
- attrs.update(obj.inputs)
- d = {
- '__class__': obj.classname,
- 'id': obj.id,
- 'kwargs': json.dumps(attrs),
- }
- return d
-
-
-def get_object_current_state(obj):
- # Convert objects to a dictionary of their representation
- d = {
- '__class__': obj.classname,
- 'id': obj.id,
- 'kwargs': json.dumps(obj.outputs),
- }
- return d
-
-
-class SVGUI_HMI(website.PLCHMI):
- jsClass = u"LiveSVGPage.LiveSVGWidget"
-
- docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
- tags.xml(loaders.xmlfile(os.path.join(NS.WorkingDir, svgfile))),
- ])
-
- def HMIinitialisation(self):
- gadgets = []
- for gadget in svguiWidgets.values():
- gadgets.append(text(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
- d = self.callRemote('init', gadgets)
- d.addCallback(self.HMIinitialised)
-
- def sendData(self, data):
- if self.initialised:
- return self.callRemote('receiveData', text(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
- return None
-
- def setattr(self, id, attrname, value):
- svguiWidgets[id].setinput(attrname, value)
-
-
-def createSVGUIControl(*args, **kwargs):
- id = getNewId()
- gad = SvguiWidget(args[0], id, **kwargs)
- svguiWidgets[id] = gad
- gadget = [text(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
- interface = website.getHMI()
- if isinstance(interface, SVGUI_HMI) and interface.initialised:
- interface.callRemote('init', gadget)
- return id
-
-
-def setAttr(id, attrname, value):
- gad = svguiWidgets.get(id, None)
- if gad is not None:
- gad.setoutput(attrname, value)
-
-
-def updateAttr(id, **kwargs):
- gad = svguiWidgets.get(id, None)
- if gad is not None:
- gad.updateoutput(**kwargs)
-
-
-def getAttr(id, attrname, default=None):
- gad = svguiWidgets.get(id, None)
- if gad is not None:
- return gad.getinput(attrname, default)
- return default
diff -r c6de1a6cb655 -r 4a08728a2ea4 svgui/svguilib.py
--- a/svgui/svguilib.py Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-
-# pylint: disable=old-style-class,undefined-variable
-
-
-class button:
-
- def __init__(self, parent, id, args):
- self.parent = parent
- self.id = id
- self.back_elt = getSVGElementById(args.back_id)
- self.sele_elt = getSVGElementById(args.sele_id)
- self.toggle = args.toggle
- self.active = args.active
- if args.state != undefined:
- self.state = args.state
- else:
- self.state = False
- self.dragging = False
- if self.toggle:
- self.up = not self.state
- else:
- self.up = True
-
- # Add event on each element of the button
- if self.active:
- self.back_elt.addEventListener("mouseup", self, False)
- self.back_elt.addEventListener("mousedown", self, False)
- self.back_elt.addEventListener("mouseover", self, False)
- self.back_elt.addEventListener("mouseout", self, False)
-
- self.sele_elt.addEventListener("mouseup", self, False)
- self.sele_elt.addEventListener("mousedown", self, False)
- self.sele_elt.addEventListener("mouseover", self, False)
- self.sele_elt.addEventListener("mouseout", self, False)
-
- blockSVGElementDrag(self.back_elt)
- blockSVGElementDrag(self.sele_elt)
-
- self.updateElements()
-
- # method to display the current state of interface
- def updateElements(self):
- if self.up:
- self.sele_elt.setAttribute("display", "none")
- self.back_elt.removeAttribute("display")
- else:
- self.sele_elt.removeAttribute("display")
- self.back_elt.setAttribute("display", "none")
-
- def updateValues(self, values):
- if values.state != self.state:
- self.state = values.state
- self.up = not self.state
- if self.toggle:
- updateAttr(self.id, 'state', self.state)
- self.updateElements()
-
- def handleEvent(self, evt):
- # Quand le bouton de la souris est presse
- if evt.type == "mousedown":
- evt.stopPropagation()
- setCurrentObject(self)
-
- self.dragging = True
-
- if self.toggle:
- self.up = self.state
- else:
- self.up = False
- self.state = True
- updateAttr(self.id, 'state', self.state)
- self.updateElements()
-
- if isCurrentObject(self) and self.dragging:
- # Quand le bouton est survole
- if evt.type == "mouseover" and self.toggle:
- self.up = self.state
- self.updateElements()
-
- # Quand le curseur quitte la zone du bouton
- elif evt.type == "mouseout" and self.toggle:
- self.up = not self.state
- self.updateElements()
-
- # Quand le bouton de la souris est relache
- elif evt.type == "mouseup":
- evt.stopPropagation()
- if self.toggle and self.up == self.state:
- self.state = not self.state
- updateAttr(self.id, 'state', self.state)
- elif not self.toggle:
- self.up = True
- self.state = False
- updateAttr(self.id, 'state', self.state)
- self.updateElements()
- self.dragging = False
-
-
-class textControl:
-
- def __init__(self, parent, id, args):
- self.parent = parent
- self.id = id
- self.back_elt = getSVGElementById(args.back_id)
- if args.text != undefined:
- self.text = args.text
- else:
- self.text = ""
- self.updateElements()
-
- def updateValues(self, values):
- if values.text != self.value:
- self.text = values.text
- updateAttr(self.id, 'text', self.text)
- self.updateElements()
-
- def updateElements(self):
- self.back_elt.firstChild.firstChild.textContent = self.text
-
- def handleEvent(self, evt):
- pass
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/first_steps/beremiz.xml
--- a/tests/first_steps/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/first_steps/plc.xml
--- a/tests/first_steps/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1160 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AVCnt
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt1
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt2
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt3
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt4
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
-
-
-
-
- OUT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ResetCounterValue
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Out
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cnt
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ResetCounterValue
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/genericmake/beremiz.xml
--- a/tests/genericmake/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/genericmake/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -3,5 +3,5 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/beremiz.xml
--- a/tests/python/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/c_code@c_ext/baseconfnode.xml
--- a/tests/python/c_code@c_ext/baseconfnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/c_code@c_ext/cfile.xml
--- a/tests/python/c_code@c_ext/cfile.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/c_code@c_ext/confnode.xml
--- a/tests/python/c_code@c_ext/confnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/plc.xml
--- a/tests/python/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1644 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '666'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pytest_var2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'sys.stdout.write("FBID :"+str(FBID)+"\n")'
-
-
-
-
-
-
- 'PLCBinary.Simple_C_Call(5678)'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'MyPythonFunc(42)'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pytest_var1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mux1_sel
-
-
-
-
-
-
-
-
-
-
- pytest_var3
-
-
-
-
-
-
-
-
-
-
- FromC
-
-
-
-
-
-
- 23
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TestInput
-
-
-
-
-
-
-
-
-
-
- TestOutput
-
-
-
-
-
-
-
-
-
-
- FromInput
-
-
-
-
-
-
- 10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_BCD_RESULT
-
-
-
-
-
-
- Test_BCD
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_DT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_Date
-
-
-
-
-
-
-
-
-
-
- Test_String
-
-
-
-
-
-
-
-
-
-
- Test_Bool
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'True'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Global_RS.Q1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOL#TRUE
-
-
-
-
-
-
-
-
-
-
- Global_RS.S
-
-
-
-
-
-
-
-
-
-
- Global_RS.R1
-
-
-
-
-
-
- Global_RS.Q1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOL#FALSE
-
-
-
-
-
-
-
-
-
-
- Test_TOD_STRING
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_TOD
-
-
-
-
-
-
- 42
-
-
-
-
-
-
-
-
-
-
- TOTO
-
-
-
-
-
-
-
-
-
-
-
-
- TUTU
-
-
-
-
-
-
- Second_Python_Var
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fefvsd
-
-
-
-
-
-
-
-
-
-
- fefvsd
-
-
-
-
-
-
-
-
-
-
-
-
- mux2_sel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_BCD_WRONG
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_BCD_WRONG_RESULT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_BCD_CONVERTED
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Grumpf
-
-
-
-
-
-
- BOOL#TRUE
-
-
-
-
-
-
- Test_DT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test_Python_Var
-
-
-
-
-
-
- 23
-
-
-
-
-
-
-
-
-
-
-
-
-
- SomeVarName
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/py_ext_0@py_ext/baseconfnode.xml
--- a/tests/python/py_ext_0@py_ext/baseconfnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/py_ext_0@py_ext/pyfile.xml
--- a/tests/python/py_ext_0@py_ext/pyfile.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/python@py_ext/baseconfnode.xml
--- a/tests/python/python@py_ext/baseconfnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/python/python@py_ext/pyfile.xml
--- a/tests/python/python@py_ext/pyfile.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi/beremiz.xml
--- a/tests/svghmi/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -1,5 +1,5 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi/plc.xml
--- a/tests/svghmi/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -1,7 +1,7 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Wed Oct 20 08:57:07 2021 +0200
@@ -125,17 +125,17 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:document-units="px"
- inkscape:current-layer="g1499-7"
+ inkscape:current-layer="hmi0"
showgrid="false"
units="px"
- inkscape:zoom="0.84355633"
- inkscape:cx="1857.6296"
- inkscape:cy="687.32797"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
+ inkscape:zoom="0.42177818"
+ inkscape:cx="543.13877"
+ inkscape:cy="-467.92793"
+ inkscape:window-width="2400"
+ inkscape:window-height="2096"
+ inkscape:window-x="3200"
inkscape:window-y="27"
- inkscape:window-maximized="1"
+ inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-global="true"
@@ -406,18 +406,6 @@
y="-78.144218"
style="text-align:center;text-anchor:middle;fill:#ff6600;stroke-width:0.26458332px">10000
000
- Pressure
- 设定值
- 当前值
- 压力
- 设置
- 家
-
-
- Valeur de consigne
- Valeur courante
- Pression
- Settings
- Home
-
-
- nastavljena vrednost
- dejanska vrednost
- pritisk
- Settings
- Home
-
-
@@ -704,19 +497,6 @@
id="tspan98"
sodipodi:role="line">10000
000
- 10000
000
-
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.28600003;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#ff6600;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
10000
000
- up
+
+
+
+
+
+
+
+
+
+
+
+
+ Home
+
+
+
+
+
+
+
+ DropDown
+
+
+
+ Three
+ Two
+ One
+ Zero
+
+
+ 8
+
+
+
+
+
+ 000
+ 000
+ 000
+ 000
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/beremiz.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/plc.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ var0
+
+
+
+
+
+
+
+
+
+
+
+
+ var1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/svghmi_0@svghmi/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/svghmi_0@svghmi/baseconfnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/svghmi_0@svghmi/confnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/svghmi_0@svghmi/confnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,2 @@
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/svghmi_0@svghmi/messages.pot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/svghmi_0@svghmi/messages.pot Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,17 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR , YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2021-02-12 21:55+CET\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: SVGHMI 1.0\n"
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_pathslider/svghmi_0@svghmi/svghmi.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/svghmi_pathslider/svghmi_0@svghmi/svghmi.svg Wed Oct 20 08:57:07 2021 +0200
@@ -0,0 +1,882 @@
+
+
+
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_scrollbar/beremiz.xml
--- a/tests/svghmi_scrollbar/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi_scrollbar/beremiz.xml Wed Oct 20 08:57:07 2021 +0200
@@ -1,5 +1,5 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_scrollbar/plc.xml
--- a/tests/svghmi_scrollbar/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi_scrollbar/plc.xml Wed Oct 20 08:57:07 2021 +0200
@@ -1,7 +1,7 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_scrollbar/svghmi_0@svghmi/confnode.xml
--- a/tests/svghmi_scrollbar/svghmi_0@svghmi/confnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi_scrollbar/svghmi_0@svghmi/confnode.xml Wed Oct 20 08:57:07 2021 +0200
@@ -1,2 +1,2 @@
-
+
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svghmi_scrollbar/svghmi_0@svghmi/svghmi.svg
--- a/tests/svghmi_scrollbar/svghmi_0@svghmi/svghmi.svg Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/svghmi_scrollbar/svghmi_0@svghmi/svghmi.svg Wed Oct 20 08:57:07 2021 +0200
@@ -60,13 +60,13 @@
showgrid="false"
units="px"
inkscape:zoom="0.64"
- inkscape:cx="318.22524"
- inkscape:cy="196.09799"
- inkscape:window-width="1939"
- inkscape:window-height="1243"
- inkscape:window-x="3325"
- inkscape:window-y="162"
- inkscape:window-maximized="0"
+ inkscape:cx="-438.80601"
+ inkscape:cy="183.59799"
+ inkscape:window-width="3200"
+ inkscape:window-height="1672"
+ inkscape:window-x="0"
+ inkscape:window-y="54"
+ inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-global="true"
@@ -745,7 +745,7 @@
Size
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svgui/plc.xml
--- a/tests/svgui/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,485 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- counter
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
- 'stop_back'
-
-
-
-
-
-
- 'stop_sele'
-
-
-
-
-
-
- 'text_counter'
-
-
-
-
-
-
- 'led_stop'
-
-
-
-
-
-
- 'led_start'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BOOL#1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- counter
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svgui/svgui@svgui/baseconfnode.xml
--- a/tests/svgui/svgui@svgui/baseconfnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svgui/svgui@svgui/gui.svg
--- a/tests/svgui/svgui@svgui/gui.svg Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,723 +0,0 @@
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/svgui/svgui@svgui/pyfile.xml
--- a/tests/svgui/svgui@svgui/pyfile.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/tools/test_application.py
--- a/tests/tools/test_application.py Tue Oct 19 15:15:03 2021 +0200
+++ b/tests/tools/test_application.py Wed Oct 20 08:57:07 2021 +0200
@@ -172,7 +172,6 @@
@ddt.data(
"first_steps",
"logging",
- "svgui",
"traffic_lights",
"wxGlade",
"python",
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/traffic_lights/beremiz.xml
--- a/tests/traffic_lights/beremiz.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/traffic_lights/plc.xml
--- a/tests/traffic_lights/plc.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1732 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ORANGE_LIGHT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- T#500ms
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ORANGE_LIGHT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ORANGE_LIGHT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ORANGE_LIGHT
-
-
-
-
-
-
- T#500ms
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWITCH_BUTTON
-
-
-
-
-
-
-
-
-
-
- STOP
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PEDESTRIAN_BUTTON
-
-
-
-
-
-
- T#2s
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WARN_CARS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWITCH_BUTTON
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 'SWITCH_OFF'
-
-
-
-
-
-
- 'SWITCH_ON'
-
-
-
-
-
-
- 'PEDESTRIAN_OFF'
-
-
-
-
-
-
- 'PEDESTRIAN_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'RED_OFF'
-
-
-
-
-
-
- 'RED_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'ORANGE_OFF'
-
-
-
-
-
-
- 'ORANGE_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'GREEN_OFF'
-
-
-
-
-
-
- 'GREEN_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'PEDESTRIAN_RED_OFF'
-
-
-
-
-
-
- 'PEDESTRIAN_RED_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 'PEDESTRIAN_GREEN_OFF'
-
-
-
-
-
-
- 'PEDESTRIAN_GREEN_ON'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/traffic_lights/svgui-0@svgui/baseconfnode.xml
--- a/tests/traffic_lights/svgui-0@svgui/baseconfnode.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/traffic_lights/svgui-0@svgui/gui.svg
--- a/tests/traffic_lights/svgui-0@svgui/gui.svg Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1516 +0,0 @@
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 tests/traffic_lights/svgui-0@svgui/pyfile.xml
--- a/tests/traffic_lights/svgui-0@svgui/pyfile.xml Tue Oct 19 15:15:03 2021 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r c6de1a6cb655 -r 4a08728a2ea4 util/BitmapLibrary.py
--- a/util/BitmapLibrary.py Tue Oct 19 15:15:03 2021 +0200
+++ b/util/BitmapLibrary.py Wed Oct 20 08:57:07 2021 +0200
@@ -71,7 +71,7 @@
height = max(bmp1.GetHeight(), bmp2.GetHeight())
# Create bitmap with both icons
- bmp = wx.EmptyBitmap(width, height)
+ bmp = wx.Bitmap(width, height)
dc = wx.MemoryDC()
dc.SelectObject(bmp)
dc.Clear()
diff -r c6de1a6cb655 -r 4a08728a2ea4 util/ExceptionHandler.py
--- a/util/ExceptionHandler.py Tue Oct 19 15:15:03 2021 +0200
+++ b/util/ExceptionHandler.py Wed Oct 20 08:57:07 2021 +0200
@@ -49,7 +49,7 @@
trcbck_lst.append(trcbck)
# Allow clicking....
- cap = wx.Window_GetCapture()
+ cap = wx.Window.GetCapture()
if cap:
cap.ReleaseMouse()