lpcmanager

Moved forgotten imports
revamp
2018-02-06, Edouard Tisserant
8aeae7fe33da
Moved forgotten imports
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import getopt
import __builtin__
import time
# On Windows install schema, we compute path to beremiz
# relative to path to python folder (sys.path[0] in that case)
# note: beware that wx import messes up sys.path[0]
_dist_folder = os.path.split(sys.path[0])[0]
_beremiz_folder = os.path.join(_dist_folder, "beremiz")
# Then we add it to sys.path, to make "import Beremiz" possible
sys.path.append(_beremiz_folder)
import wx
from util.BitmapLibrary import AddBitmapFolder
# Path of directory containing current python file
_lpcmanager_path = os.path.split(__file__)[0]
from LPCArch import PLC_module, SetLPCArch
class LPCManagerLauncher(BeremizIDELauncher):
def __init__(self):
BeremizIDELauncher.__init__(self)
self.arch = None
self.port = None
self.extensions = [os.path.join(_lpcmanager_path, "extention.py")]
self.modules.extend([
"LPCBeremiz",
"StdoutPseudoFile",
"LPCProjectController",
"LPCCommand"])
def Usage(self):
print("\nUsage of LPCManager.py :")
print("\n %s Projectpath Buildpath port arch\n" % sys.argv[0])
def ProcessCommandLineArgs(self):
# Command line arguments parsing
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
except getopt.GetoptError:
# print help information and exit:
self.Usage()
sys.exit(2)
# asking for help causes exit
for o, a in opts:
if o in ("-h", "--help"):
self.Usage()
sys.exit()
if len(args) != 4 :
self.Usage()
sys.exit()
else:
self.projectOpen = args[0]
self.buildpath = args[1]
try:
self.port = int(args[2])
except:
self.Usage()
sys.exit()
self.arch = args[3]
SetLPCArch(self.arch)
# overload with exacltly same code, but this is intended.
# we want extensions to use globals of this module, not Beremiz.py
def globals(self):
return globals()
def CreateUI(self):
CMDpipe = self.StdoutPseudoFile.StdoutPseudoFile(self.port, self.debug)
if self.projectOpen is not None:
self.projectOpen = self.BeremizIDE.DecodeFileSystemPath(self.projectOpen, False)
CTR = self.LPCProjectController.LPCProjectController(
None, CMDpipe, self.buildpath, self.arch)
if self.projectOpen is not None and os.path.isdir(self.projectOpen):
result = CTR.LoadProject(self.projectOpen)
if result:
CMDpipe.write("Error: Invalid project directory", result)
else:
CMDpipe.write("Error: No such file or directory")
lpcberemiz_cmd = LPCCommand(CTR, CMDpipe)
cmd_thread = Thread(target=lpcberemiz_cmd.cmdloop)
cmd_thread.start()
# TODO: join() when exiting
self.frame = self.LPCBeremiz.LPCBeremiz(None, ctr=CTR)
def ShowUI(self):
# the "Show" command from composer does it instead
pass
def CreateApplication(self):
# Create app usual way
BeremizIDELauncher.CreateApplication(self)
# Add LPCmanager's image folder to searched ones.
AddBitmapFolder(os.path.join(_lpcmanager_path, "images"))
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
from editors.CodeFileEditor import VariablesTable
from editors.CodeFileEditor import VariablesEditor
from editors.CodeFileEditor import CodeEditor
from controls import ProjectPropertiesPanel
from controls.SearchResultPanel import SearchResultPanel
# from controls.LogViewer import LogViewer
from WampOptionsEditor import WampOptionsEditor
from VariableExporter import VariableWriter
from PLCControler import PLCControler, ITEMS_UNEDITABLE, ITEM_POU
from wx.lib.scrolledpanel import ScrolledPanel
from types import MethodType
from IDEFrame import IDEFrame
from dialogs import SearchInProjectDialog
from controls import TextCtrlAutoComplete
from py_ext import PythonFileCTNMixin
from plcopen.structures import TestIdentifier, IDENTIFIER_MODEL
def CTNGenerate_C(self, buildpath, locations):
# location string for that CTN
location_str = "_".join(map(lambda x: str(x),
self.GetCurrentLocation()))
configname = self.GetCTRoot().GetProjectConfigNames()[0]
pyextname = self.CTNName()
varinfos = map(lambda variable: {
"name": variable.getname(),
"desc": repr(variable.getdesc()),
"onchangecode": '"' + variable.getonchange() + \
"('" + variable.getname() + "')\"" \
if variable.getonchange() else '""',
"onchange": repr(variable.getonchange()) \
if variable.getonchange() else None,
"opts": repr(variable.getopts()),
"configname": configname.upper(),
"uppername": variable.getname().upper(),
"IECtype": variable.gettype(),
"initial": repr(variable.getinitial()),
"pyextname": pyextname},
self.CodeFile.variables.variable)
# python side PLC global variables access stub
globalstubs = "\n".join(["""\
_%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\
TypeTranslator["%(IECtype)s"]
_PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s
_PySafeGetPLCGlob_%(name)s.restype = None
_PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
_PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s
_PySafeSetPLCGlob_%(name)s.restype = None
_PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
_%(pyextname)sGlobalsDesc.append((
"%(name)s",
"%(IECtype)s",
%(initial)s,
%(desc)s,
%(onchange)s,
%(opts)s))
""" % varinfo
for varinfo in varinfos])
# Runtime calls (start, stop, init, and cleanup)
rtcalls = ""
for section in self.SECTIONS_NAMES:
if section != "globals":
rtcalls += "def _runtime_%s_%s():\n" % (location_str, section)
sectiontext = self.GetSection(section).strip()
if sectiontext:
rtcalls += ' ' + \
sectiontext.replace('\n', '\n ') + "\n\n"
else:
rtcalls += " pass\n\n"
globalsection = self.GetSection("globals")
PyFileContent = """\
#!/usr/bin/env python
# -*- coding: utf-8 -*-
## Code generated by Beremiz python mixin confnode
##
## Code for PLC global variable access
from targets.typemapping import TypeTranslator
import ctypes
_%(pyextname)sGlobalsDesc = []
__ext_name__ = "%(pyextname)s"
PLCGlobalsDesc.append(( "%(pyextname)s" , _%(pyextname)sGlobalsDesc ))
%(globalstubs)s
## User code in "global" scope
%(globalsection)s
## Beremiz python runtime calls
%(rtcalls)s
del __ext_name__
""" % locals()
# write generated content to python file
runtimefile_path = os.path.join(buildpath,
"runtime_%s.py" % location_str)
runtimefile = open(runtimefile_path, 'w')
runtimefile.write(PyFileContent.encode('utf-8'))
runtimefile.close()
# C code for safe global variables access
vardecfmt = """\
extern __IEC_%(IECtype)s_t %(configname)s__%(uppername)s;
IEC_%(IECtype)s __%(name)s_rbuffer = __INIT_%(IECtype)s;
IEC_%(IECtype)s __%(name)s_wbuffer;
long __%(name)s_rlock = 0;
long __%(name)s_wlock = 0;
int __%(name)s_wbuffer_written = 0;
void __SafeGetPLCGlob_%(name)s(IEC_%(IECtype)s *pvalue){
while(AtomicCompareExchange(&__%(name)s_rlock, 0, 1));
*pvalue = __%(name)s_rbuffer;
AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
}
void __SafeSetPLCGlob_%(name)s(IEC_%(IECtype)s *value){
while(AtomicCompareExchange(&__%(name)s_wlock, 0, 1));
__%(name)s_wbuffer = *value;
__%(name)s_wbuffer_written = 1;
AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
}
"""
vardeconchangefmt = """\
PYTHON_POLL* __%(name)s_notifier;
"""
varretfmt = """\
if(!AtomicCompareExchange(&__%(name)s_wlock, 0, 1)){
if(__%(name)s_wbuffer_written == 1){
%(configname)s__%(uppername)s.value = __%(name)s_wbuffer;
__%(name)s_wbuffer_written = 0;
}
AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
}
"""
varpubfmt = """\
if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){
__%(name)s_rbuffer = __GET_VAR(%(configname)s__%(uppername)s);
AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
}
"""
varpubonchangefmt = """\
if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){
IEC_%(IECtype)s tmp = __GET_VAR(%(configname)s__%(uppername)s);
if(__%(name)s_rbuffer != tmp){
__%(name)s_rbuffer = %(configname)s__%(uppername)s.value;
PYTHON_POLL_body__(__%(name)s_notifier);
}
AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
}
"""
varinitonchangefmt = """\
__%(name)s_notifier = __GET_GLOBAL_ON%(uppername)sCHANGE();
__SET_VAR(__%(name)s_notifier->,TRIG,,__BOOL_LITERAL(TRUE));
__SET_VAR(__%(name)s_notifier->,CODE,,__STRING_LITERAL(%(onchangelen)d,%(onchangecode)s));
"""
vardec = "\n".join([(vardecfmt + vardeconchangefmt
if varinfo["onchange"] else vardecfmt) % varinfo
for varinfo in varinfos])
varret = "\n".join([varretfmt % varinfo for varinfo in varinfos])
varpub = "\n".join([(varpubonchangefmt if varinfo["onchange"] else
varpubfmt) % varinfo
for varinfo in varinfos])
varinit = "\n".join([varinitonchangefmt % dict(
onchangelen=len(varinfo["onchangecode"]), **varinfo)
for varinfo in varinfos if varinfo["onchange"]])
# TODO : use config name obtained from model instead of default
# "config.h". User cannot change config name, but project imported
# or created in older beremiz vesion could use different name.
PyCFileContent = """\
/*
* Code generated by Beremiz py_ext confnode
* for safe global variables access
*/
#include "iec_types_all.h"
#include "POUS.h"
#include "config.h"
#include "beremiz.h"
/* User variables reference */
%(vardec)s
/* Beremiz confnode functions */
int __init_%(location_str)s(int argc,char **argv){
%(varinit)s
return 0;
}
void __cleanup_%(location_str)s(void){
}
void __retrieve_%(location_str)s(void){
%(varret)s
}
void __publish_%(location_str)s(void){
%(varpub)s
}
""" % locals()
Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c" % location_str)
pycfile = open(Gen_PyCfile_path, 'w')
pycfile.write(PyCFileContent)
pycfile.close()
matiec_CFLAGS = '"-I%s"' % os.path.abspath(
self.GetCTRoot().GetIECLibPath())
return ([(Gen_PyCfile_path, matiec_CFLAGS)],
"",
True,
("runtime_%s.py" % location_str, file(runtimefile_path, "rb")))
PythonFileCTNMixin.CTNGenerate_C = CTNGenerate_C
def ResetSearchResults(self):
self.Highlights = []
self.SearchParams = None
self.SearchResults = None
self.VariableSearchResults = []
self.CurrentFindHighlight = None
self.index = 0
CodeEditor.ResetSearchResults = ResetSearchResults
from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
[STC_CODE_ERROR, STC_CODE_SEARCH_RESULT,
STC_CODE_SECTION] = range(15, 18)
HIGHLIGHT_TYPES = {
ERROR_HIGHLIGHT: STC_CODE_ERROR,
SEARCH_RESULT_HIGHLIGHT: STC_CODE_SEARCH_RESULT,
}
def FindVariable(self, direction, search_params, variables):
first = False
if self.SearchParams != search_params:
first = True
self.SearchParams = search_params
if len(self.VariableSearchResults) > 0:
(r, c) = self.VariableSearchResults[self.index]
variables.VariablesGrid.SetCellBackgroundColour(r, c, SEARCH_RESULT_HIGHLIGHT[1])
grid = variables.VariablesGrid
cols = grid.GetNumberCols()
rows = grid.GetNumberRows()
self.VariableSearchResults = []
for row in range(rows):
for col in range(cols):
value = variables.VariablesGrid.GetCellValue(row, col)
search_value = search_params['find_pattern']
if search_params['case_sensitive'] == False:
search_value = search_value.lower()
value = value.lower()
if search_value in value:
self.VariableSearchResults.append((row, col))
self.index = 0
if len(self.VariableSearchResults) > 0:
(r, c) = self.VariableSearchResults[self.index]
variables.VariablesGrid.SetCellBackgroundColour(r, c, SEARCH_RESULT_HIGHLIGHT[1])
if not first:
self.index += direction
self.index = self.index % len(self.VariableSearchResults)
(r, c) = self.VariableSearchResults[self.index]
variables.VariablesGrid.SetCellBackgroundColour(r, c, SEARCH_RESULT_HIGHLIGHT[0])
variables.VariablesGrid.MakeCellVisible(r, c)
variables.VariablesGrid.ForceRefresh()
CodeEditor.FindVariable = FindVariable
def SearchInPyfile(self, criteria):
result = []
from xml.dom import minidom
dir_list = next(os.walk(self.ProjectPath))[1]
for dir in dir_list:
if dir not in ["build", "CanOpen@CanOpen", "project_files"]:
path = os.path.join(self.ProjectPath, dir, 'pyfile.xml')
variablelist = []
if os.path.exists(path):
pyfile = minidom.parse(path)
variablelist = pyfile.getElementsByTagName('variable')
for s in variablelist:
if criteria["find_pattern"] in s.attributes['name'].value:
result.append(dir)
return result
PLCControler.SearchInPyfile = SearchInPyfile
def OnSearchInProjectMenu(self, event):
dialog = SearchInProjectDialog(self)
if dialog.ShowModal() == wx.ID_OK:
criteria = dialog.GetCriteria()
if len(criteria) > 0:
result = self.Controler.SearchInProject(criteria)
pyresult = self.Controler.SearchInPyfile(criteria)
self.ClearSearchResults()
self.SearchResultPanel.SetSearchResults(criteria, result, pyresult)
self.SearchResultPanel.AddPyFileResults(pyresult)
self.SelectTab(self.SearchResultPanel)
IDEFrame.OnSearchInProjectMenu = OnSearchInProjectMenu
def GenerateProjectTreeBranch(self, root, infos, item_alone=False):
to_delete = []
item_name = infos["name"]
if infos["type"] in ITEMS_UNEDITABLE:
if len(infos["values"]) == 1:
return self.GenerateProjectTreeBranch(root, infos["values"][0], True)
item_name = _(item_name)
self.ProjectTree.SetItemText(root, item_name)
self.ProjectTree.SetPyData(root, infos)
highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK))
self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0])
self.ProjectTree.SetItemTextColour(root, highlight_colours[1])
self.ProjectTree.SetItemExtraImage(root, None)
if infos["type"] == ITEM_POU:
self.ProjectTree.SetItemImage(root,
self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
if item_alone:
self.ProjectTree.SetItemExtraImage(root, self.Controler.GetPouType(infos["name"]))
elif infos.has_key("icon") and infos["icon"] is not None:
icon_name = infos["icon"]
if not self.TreeImageDict.has_key(icon_name):
self.TreeImageDict[icon_name] = self.TreeImageList.Add(GetBitmap(icon_name))
self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_name])
elif self.TreeImageDict.has_key(infos["type"]):
self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
item, root_cookie = self.ProjectTree.GetFirstChild(root)
for values in infos["values"]:
if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0:
if item is None or not item.IsOk():
item = self.ProjectTree.AppendItem(root, "")
item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
self.GenerateProjectTreeBranch(item, values)
item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
while item is not None and item.IsOk():
to_delete.append(item)
item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
for item in to_delete:
self.ProjectTree.Delete(item)
IDEFrame.GenerateProjectTreeBranch = GenerateProjectTreeBranch
defaultSearchResultPanelInit = SearchResultPanel.__init__
def SearchResultPanelInit(self, parent, window):
defaultSearchResultPanelInit(self, parent, window)
self.TreeImageDict["py_file"] = self.TreeImageList.Add(GetBitmap("py_file"))
self.TreeImageDict["wx_glade"] = self.TreeImageList.Add(GetBitmap("wx_glade"))
SearchResultPanel.__init__ = SearchResultPanelInit
def SetSearchResults(self, criteria, search_results, py_results):
self.Criteria = criteria
self.SearchResults = {}
self.ElementsOrder = []
self.PySearchResults = py_results
for infos, start, end, text in search_results:
if infos[0] not in self.ElementsOrder:
self.ElementsOrder.append(infos[0])
results = self.SearchResults.setdefault(infos[0], [])
results.append((infos, start, end, text))
self.RefreshView()
SearchResultPanel.SetSearchResults = SetSearchResults
def AddPyFileResults(self, search_results):
distinct_list = list(set(search_results))
for result in distinct_list:
name = result.split('@')
matches = search_results.count(result)
if name[1] == "py_ext":
root = self.SearchResultsTree.GetRootItem()
self.SearchResultsTree.AppendItem(root, name[0], image=self.TreeImageDict["py_file"])
else:
root = self.SearchResultsTree.GetRootItem()
self.SearchResultsTree.AppendItem(root, name[0], image=self.TreeImageDict["wx_glade"])
if matches > 1:
text = _("(%d matches)") % search_results.count(result)
start_idx, end_idx = 0, len(text)
style = wx.TextAttr(wx.Colour(0, 127, 174))
text_ctrl_style = wx.BORDER_NONE | wx.TE_READONLY | wx.TE_RICH2
if wx.Platform != '__WXMSW__' or len(text.splitlines()) > 1:
text_ctrl_style |= wx.TE_MULTILINE
text_ctrl = wx.TextCtrl(id=-1, parent=self.SearchResultsTree, pos=wx.Point(0, 0),
value=text, style=text_ctrl_style)
width, height = text_ctrl.GetTextExtent(text)
text_ctrl.SetClientSize(wx.Size(width + 1, height))
text_ctrl.SetBackgroundColour(self.SearchResultsTree.GetBackgroundColour())
child = self.SearchResultsTree.GetLastChild(root)
text_ctrl.SetInsertionPoint(0)
text_ctrl.SetStyle(start_idx, end_idx, style)
self.SearchResultsTree.SetItemWindow(child, text_ctrl)
SearchResultPanel.AddPyFileResults = AddPyFileResults
def ResetSearchResults(self):
self.Criteria = None
self.ElementsOrder = []
self.SearchResults = {}
self.PySearchResults = []
self.RefreshView()
SearchResultPanel.ResetSearchResults = ResetSearchResults
def GetPythonTextCtrlDClickFunction(self, item):
for type in self.ParentWindow.CTR.Children.values():
for name in type:
if name.BaseParams.attrib['Name'] == item:
name._OpenView()
selected = self.ParentWindow.TabsOpened.GetSelection()
if selected != -1:
window = self.ParentWindow.TabsOpened.GetPage(selected)
window.CodeEditor.FindVariable(1, {'find_pattern': self.Criteria['find_pattern'],
'regular_expression': self.Criteria['regular_expression'],
'pattern': self.Criteria['pattern'],
'case_sensitive': self.Criteria['case_sensitive'],
'filter': self.Criteria['filter']}, window.VariablesPanel)
for (r, c) in window.CodeEditor.VariableSearchResults:
window.VariablesPanel.VariablesGrid.SetCellBackgroundColour(r, c,
SEARCH_RESULT_HIGHLIGHT[0])
SearchResultPanel.GetPythonTextCtrlDClickFunction = GetPythonTextCtrlDClickFunction
def OnSearchResultsTreeItemActivated(self, event):
self.ShowSearchResults(event.GetItem())
if event.GetItem()._data is None:
self.GetPythonTextCtrlDClickFunction(event.GetItem()._text)
event.Skip()
SearchResultPanel.OnSearchResultsTreeItemActivated = OnSearchResultsTreeItemActivated
defaultProjectPropertiesPanelInit = ProjectPropertiesPanel.__init__
def OurProjectPropertiesPanelInit(self, parent, controller=None, window=None, enable_required=True):
REQUIRED_PARAMS = ["projectName", "productName", "productVersion", "companyName"]
[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
] = range(10)
def create_project_panel(self):
self.ProjectPanel = ScrolledPanel(self, -1, style=wx.TAB_TRAVERSAL)
self.ProjectPanel.SetAutoLayout(1)
self.ProjectPanel.SetupScrolling()
self.AddPage(self.ProjectPanel, _("Project"))
projectpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15)
projectpanel_sizer.AddGrowableCol(1)
self.ProjectPanel.SetSizer(projectpanel_sizer)
self.AddSizerParams(self.ProjectPanel, projectpanel_sizer,
[("projectName", _('Project Name (required):')),
("projectVersion", _('Project Version (optional):')),
("productName", _('Product Name (required):')),
("productVersion", _('Product Version (required):')),
("productRelease", _('Product Release (optional):'))])
self.AddPage(self.ProjectPanel, _("Project"))
def create_author_panel(self):
self.AuthorPanel = ScrolledPanel(self, -1, style=wx.TAB_TRAVERSAL)
self.AuthorPanel.SetAutoLayout(1)
self.AuthorPanel.SetupScrolling()
authorpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15)
authorpanel_sizer.AddGrowableCol(1)
self.AuthorPanel.SetSizer(authorpanel_sizer)
self.AddSizerParams(self.AuthorPanel, authorpanel_sizer,
[("companyName", _('Company Name (required):')),
("companyURL", _('Company URL (optional):')),
("authorName", _('Author Name (optional):')),
("organization", _('Organization (optional):'))])
self.AddPage(self.AuthorPanel, _("Author"))
def create_graphic_panel(self):
self.GraphicsPanel = ScrolledPanel(self, -1, style=wx.TAB_TRAVERSAL)
self.GraphicsPanel.SetAutoLayout(1)
self.GraphicsPanel.SetupScrolling()
graphicpanel_sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=4, vgap=5)
graphicpanel_sizer.AddGrowableCol(0)
graphicpanel_sizer.AddGrowableRow(3)
self.GraphicsPanel.SetSizer(graphicpanel_sizer)
pageSize_st = wx.StaticText(self.GraphicsPanel,
label=_('Page Size (optional):'))
graphicpanel_sizer.AddWindow(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,
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,
flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT)
sp = wx.SpinCtrl(self.GraphicsPanel,
min=0, max=2 ** 16, style=wx.TE_PROCESS_ENTER)
setattr(self, name, sp)
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)
scaling_st = wx.StaticText(self.GraphicsPanel,
label=_('Grid Resolution:'))
graphicpanel_sizer.AddWindow(scaling_st, border=10,
flag=wx.GROW | wx.LEFT | wx.RIGHT)
scaling_nb = wx.Notebook(self.GraphicsPanel)
graphicpanel_sizer.AddWindow(scaling_nb, border=10,
flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT)
self.Scalings = {}
for language, translation in [("FBD", _("FBD")), ("LD", _("LD")), ("SFC", _("SFC"))]:
scaling_panel = wx.Panel(scaling_nb, style=wx.TAB_TRAVERSAL)
scalingpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
scalingpanel_sizer.AddGrowableCol(1)
scaling_panel.SetSizer(scalingpanel_sizer)
scaling_controls = []
for idx, (name, label) in enumerate([('XScale', _('Horizontal:')),
('YScale', _('Vertical:'))]):
if idx == 0:
border = wx.TOP
else:
border = wx.BOTTOM
st = wx.StaticText(scaling_panel, label=label)
scalingpanel_sizer.AddWindow(st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL | border | wx.LEFT)
sp = wx.SpinCtrl(scaling_panel,
min=0, max=2 ** 16, style=wx.TE_PROCESS_ENTER)
scaling_controls.append(sp)
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,
flag=wx.GROW | border | wx.RIGHT)
self.Scalings[language] = scaling_controls
scaling_nb.AddPage(scaling_panel, translation)
self.AddPage(self.GraphicsPanel, _("Graphics"))
def create_miscellaneous_panel(self):
self.MiscellaneousPanel = ScrolledPanel(id=-1, parent=self,
name='MiscellaneousPanel', pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
self.MiscellaneousPanel.SetAutoLayout(1)
self.MiscellaneousPanel.SetupScrolling()
miscellaneouspanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
miscellaneouspanel_sizer.AddGrowableCol(1)
miscellaneouspanel_sizer.AddGrowableRow(1)
self.MiscellaneousPanel.SetSizer(miscellaneouspanel_sizer)
language_label = wx.StaticText(self.MiscellaneousPanel,
label=_('Language (optional):'))
miscellaneouspanel_sizer.AddWindow(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,
flag=wx.GROW | wx.TOP | wx.RIGHT)
description_label = wx.StaticText(self.MiscellaneousPanel,
label=_('Content Description (optional):'))
miscellaneouspanel_sizer.AddWindow(description_label, border=10,
flag=wx.BOTTOM | wx.LEFT)
self.ContentDescription = wx.TextCtrl(self.MiscellaneousPanel,
style=wx.TE_MULTILINE | wx.TE_PROCESS_ENTER)
self.Bind(wx.EVT_TEXT_ENTER, self.OnContentDescriptionChanged,
self.ContentDescription)
self.ContentDescription.Bind(wx.EVT_KILL_FOCUS,
self.OnContentDescriptionChanged)
miscellaneouspanel_sizer.AddWindow(self.ContentDescription, border=10,
flag=wx.GROW | wx.BOTTOM | wx.RIGHT)
self.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
wx.Notebook.__init__(self, parent, size=wx.Size(500, 300))
self.Controller = controller
self.ParentWindow = window
self.Values = None
create_project_panel(self)
create_author_panel(self)
create_graphic_panel(self)
create_miscellaneous_panel(self)
for param in REQUIRED_PARAMS:
getattr(self, param).Enable(enable_required)
languages = ["", "en-US", "fr-FR", "zh-CN", "ru-RU"]
for language in languages:
self.Language.Append(language)
ProjectPropertiesPanel.__init__ = OurProjectPropertiesPanelInit
def LeftClick(self, event):
if event.GetCol() == self.grid.GetNumberCols()-1:
options = [self.grid.GetCellValue(event.GetRow(), event.GetCol()), self.grid.GetCellValue(event.GetRow(), event.GetCol()-1)]
desc = self.grid.GetCellValue(event.GetRow(), event.GetCol()-2)
if hasattr(self, "dialog"):
self.dialog.SetOptions(options, desc)
answer = self.dialog.ShowModal()
#self.dialog.SetOptions(options, desc)
else:
self.dialog = WampOptionsEditor(self.Parent.Parent, options, desc)
answer = self.dialog.ShowModal()
opt,OnChange,value,description = self.dialog.GetOptions()
if answer == wx.ID_OK:
self.grid.SetCellValue(event.GetRow(), event.GetCol(), str(opt))
if OnChange:
self.grid.SetCellValue(event.GetRow(), event.GetCol()-1, value)
self.grid.SetCellValue(event.GetRow(), event.GetCol()-2, description)
self.Parent.RefreshModel()
else:
event.Skip()
VariablesTable.LeftClick = LeftClick
def VariablesEditorSetCollSize(self):
ColSizes = [20, 150] + [130] * (len(self.VariablesDefaultValue) - 2) + [300]
for col in range(self.Table.GetNumberCols()):
self.VariablesGrid.SetColSize(col, ColSizes[col])
VariablesEditor.VariablesEditorSetCollSize = VariablesEditorSetCollSize
def _updateColAttrs(self, grid):
"""
wxGrid -> update the column attributes to add the
appropriate renderer given the column name.
Otherwise default to the default renderer.
"""
typelist = None
accesslist = None
self.grid = grid
for row in range(self.GetNumberRows()):
for col in range(self.GetNumberCols()):
editor = None
renderer = None
colname = self.GetColLabelValue(col, False)
if colname in ["Name", "Initial", "Description", "OnChange"]:
editor = wx.grid.GridCellTextEditor()
elif colname == "Class":
editor = wx.grid.GridCellChoiceEditor()
editor.SetParameters("input,memory,output")
elif colname == "Type":
pass
else:
grid.SetReadOnly(row, col, True)
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
grid.SetCellBackgroundColour(row, col, wx.WHITE)
self.grid.SetRowMinimalHeight
# updated column width, with function VariablesEditorSetCollSize added in VariablesEditor class
self.Parent.VariablesEditorSetCollSize()
# added left click option on grid, with function LeftClick added in VariablesTable class
self.grid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.LeftClick)
VariablesTable._updateColAttrs = _updateColAttrs
"""Zakomentirano ker je ze v beremiz-u"""
# def OnCleanButton(self, event):
# if self.LogSource is not None:
# rez = self.LogSource.ResetLogCount()
# if not rez:
# self.GrandParent.CTR.logger.write_warning("Can not reset log messages!\n")
# self.ResetLogMessages()
# self.RefreshView()
# event.Skip()
# LogViewer.OnCleanButton = OnCleanButton
from PLCControler import PLCControler
defaultGenerateNewName = PLCControler.GenerateNewName
def newGenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False):
if tagname:
return defaultGenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False)
else:
names = exclude.copy()
i = start_idx
while name is None or names.get(name.upper(), False):
name = (format%i)
i += 1
return name
PLCControler.GenerateNewName = newGenerateNewName
if __name__ == '__main__':
lpcmanager = LPCManagerLauncher()
lpcmanager.Start()