Fixed killing app on Linux in wxPopen. Do not use shell anymore. Command line is splitted into args, taking care of double and simple cotes. To be tested on win32.
import os, shutil, sys
base_folder = os.path.split(sys.path[0])[0]
sys.path.append(os.path.join(base_folder, "wxsvg", "SVGUIEditor"))
sys.path.append(os.path.join(base_folder, "plcopeneditor", "graphics"))
import wx
from SVGUIGenerator import *
from SVGUIControler import *
from SVGUIEditor import *
from FBD_Objects import *
from wxPopen import ProcessLogger
[ID_SVGUIEDITORFBDPANEL,
] = [wx.NewId() for _init_ctrls in range(1)]
SVGUIFB_Types = {ITEM_CONTAINER : "Container",
ITEM_BUTTON : "Button",
ITEM_TEXT : "TextCtrl",
ITEM_SCROLLBAR : "ScrollBar",
ITEM_ROTATING : "RotatingCtrl",
ITEM_NOTEBOOK : "NoteBook",
ITEM_TRANSFORM : "Transform"}
class _SVGUIEditor(SVGUIEditor):
"""
This Class add IEC specific features to the SVGUIEditor :
- FDB preview
- FBD begin drag
"""
def _init_coll_EditorGridSizer_Items(self, parent):
SVGUIEditor._init_coll_EditorGridSizer_Items(self, parent)
parent.AddWindow(self.FBDPanel, 0, border=0, flag=wx.GROW)
def _init_ctrls(self, prnt):
SVGUIEditor._init_ctrls(self, prnt, False)
self.FBDPanel = wx.Panel(id=ID_SVGUIEDITORFBDPANEL,
name='FBDPanel', parent=self.EditorPanel, pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
self.FBDPanel.SetBackgroundColour(wx.WHITE)
self.FBDPanel.Bind(wx.EVT_LEFT_DOWN, self.OnFBDPanelClick)
self.FBDPanel.Bind(wx.EVT_PAINT, self.OnPaintFBDPanel)
setattr(self.FBDPanel, "GetScaling", lambda: None)
self._init_sizers()
def __init__(self, parent, controler = None, fileOpen = None):
SVGUIEditor.__init__(self, parent, controler, fileOpen)
self.FBDBlock = None
def RefreshView(self, select_id = None):
SVGUIEditor.RefreshView(self, select_id)
self.FBDPanel.Refresh()
def OnPaintFBDPanel(self,event):
dc = wx.ClientDC(self.FBDPanel)
dc.Clear()
selected = self.GetSelected()
if selected is not None:
selected_type = self.Controler.GetElementType(selected)
if selected_type is not None:
self.FBDBlock = FBD_Block(parent=self.FBDPanel,type=SVGUIFB_Types[selected_type],name=self.Controler.GetElementName(selected))
width, height = self.FBDBlock.GetMinSize()
self.FBDBlock.SetSize(width,height)
clientsize = self.FBDPanel.GetClientSize()
x = (clientsize.width - width) / 2
y = (clientsize.height - height) / 2
self.FBDBlock.SetPosition(x, y)
self.FBDBlock.Draw(dc)
else:
self.FBDBlock = None
event.Skip()
def OnFBDPanelClick(self, event):
if self.FBDBlock:
data = wx.TextDataObject(str((self.FBDBlock.GetType(), "functionBlock", self.FBDBlock.GetName())))
DropSrc = wx.DropSource(self.FBDPanel)
DropSrc.SetData(data)
DropSrc.DoDragDrop()
event.Skip()
def OnInterfaceTreeItemSelected(self, event):
self.FBDPanel.Refresh()
SVGUIEditor.OnInterfaceTreeItemSelected(self, event)
def OnGenerate(self,event):
self.SaveProject()
self.Controler.PlugGenerate_C(sys.path[0],(0,0,4,5),None)
event.Skip()
TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
"USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", "REAL" : "D", "LREAL" : "L",
"STRING" : "B", "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L", "WSTRING" : "W"}
CTYPECONVERSION = {"BOOL" : "IEC_BOOL", "UINT" : "IEC_UINT", "STRING" : "IEC_STRING", "REAL" : "IEC_REAL"}
CPRINTTYPECONVERSION = {"BOOL" : "d", "UINT" : "d", "STRING" : "s", "REAL" : "f"}
class RootClass(SVGUIControler):
def __init__(self):
SVGUIControler.__init__(self)
filepath = os.path.join(self.PlugPath(), "gui.xml")
if os.path.isfile(filepath):
svgfile = os.path.join(self.PlugPath(), "gui.svg")
if os.path.isfile(svgfile):
self.SvgFilepath = svgfile
self.OpenXMLFile(filepath)
else:
self.CreateNewInterface()
self.SetFilePath(filepath)
def GetElementIdFromName(self, name):
element = self.GetElementByName(name)
if element is not None:
return element.getid()
return None
_View = None
def _OpenView(self, logger):
if not self._View:
def _onclose():
self._View = None
def _onsave():
self.GetPlugRoot().SaveProject()
self._View = _SVGUIEditor(self.GetPlugRoot().AppFrame, self)
self._View._onclose = _onclose
self._View._onsave = _onsave
self._View.Show()
def _ImportSVG(self, logger):
if not self._View:
dialog = wx.FileDialog(self.GetPlugRoot().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, os.path.join(self.PlugPath(), "gui.svg"))
else:
logger.write_error("No such SVG file: %s\n"%svgpath)
dialog.Destroy()
def _ImportXML(self, logger):
if not self._View:
dialog = wx.FileDialog(self.GetPlugRoot().AppFrame, "Choose a XML file", os.getcwd(), "", "XML files (*.xml)|*.xml|All files|*.*", wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
xmlpath = dialog.GetPath()
if os.path.isfile(xmlpath):
shutil.copy(xmlpath, os.path.join(self.PlugPath(), "gui.xml"))
else:
logger.write_error("No such XML file: %s\n"%xmlpath)
dialog.Destroy()
PluginMethods = [
{"bitmap" : os.path.join("images","HMIEditor"),
"name" : "HMI Editor",
"tooltip" : "HMI Editor",
"method" : "_OpenView"},
{"bitmap" : os.path.join("images","ImportSVG"),
"name" : "Import SVG",
"tooltip" : "Import SVG",
"method" : "_ImportSVG"},
{"bitmap" : os.path.join("images","ImportDEF"),
"name" : "Import XML",
"tooltip" : "Import XML",
"method" : "_ImportXML"},
]
def OnPlugSave(self):
self.SaveXMLFile()
return True
def PlugGenerate_C(self, buildpath, locations, logger):
progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation()))
generator = _SVGUICGenerator(self.GetElementsByType(), self.GetSVGFilePath(), self.GetFilePath(), self.GetCurrentLocation())
generator.GenerateProgram((0, 0), buildpath, progname)
Gen_C_file = os.path.join(buildpath, progname+".cpp" )
if wx.Platform == '__WXMSW__':
cxx_flags = "-I..\\..\\wxPython-src-2.8.7.1\\bld\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\..\\wxPython-src-2.8.7.1\\include -I..\\..\\wxPython-src-2.8.7.1\\contrib\\include -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads"
libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\..\\wxPython-src-2.8.7.1\\bld\\lib -mno-cygwin -mwindows -mthreads -mno-cygwin -mwindows -Wl,--subsystem,windows -mwindows -lwx_mswu_richtext-2.8 -lwx_mswu_aui-2.8 -lwx_mswu_xrc-2.8 -lwx_mswu_qa-2.8 -lwx_mswu_html-2.8 -lwx_mswu_adv-2.8 -lwx_mswu_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8"
else:
status, result, err_result = ProcessLogger(logger, "wx-config --cxxflags", no_stdout=True).spin()
if status:
logger.write_error("Unable to get wx cxxflags\n")
cxx_flags = result.strip() + " -I../matiec/lib"
status, result, err_result = ProcessLogger(logger, "wx-config --libs", no_stdout=True).spin()
if status:
logger.write_error("Unable to get wx libs\n")
libs = result.strip() + " -lwxsvg"
return [(Gen_C_file, cxx_flags)],libs,True
def BlockTypesFactory(self):
def generate_svgui_block(generator, block, body, link, order=False):
name = block.getinstanceName()
block_id = self.GetElementIdFromName(name)
if block_id == None:
raise ValueError, "No corresponding block found"
type = block.gettypeName()
block_infos = GetBlockType(type)
current_location = ".".join(map(str, self.GetCurrentLocation()))
if not generator.ComputedBlocks.get(name, False) and not order:
generator.ComputedBlocks[block] = True
for num, variable in enumerate(block.inputVariables.getvariable()):
connections = variable.connectionPointIn.getconnections()
if connections and len(connections) == 1:
parameter = "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["inputs"][num][1]], current_location, block_id, num+1)
value = generator.ComputeFBDExpression(body, connections[0])
generator.Program += (" %s := %s;\n"%(parameter, generator.ExtractModifier(variable, value)))
if link:
connectionPoint = link.getposition()[-1]
for num, variable in enumerate(block.outputVariables.getvariable()):
blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
return "%sI%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["outputs"][num][1]], current_location, block_id, num+1)
raise ValueError, "No output variable found"
else:
return None
def initialise_block(type, name, block = None):
block_id = self.GetElementIdFromName(name)
if block_id == None:
raise ValueError, "No corresponding block found"
block_infos = GetBlockType(type)
current_location = ".".join(map(str, self.GetCurrentLocation()))
variables = []
if block is not None:
input_variables = block.inputVariables.getvariable()
output_variables = block.outputVariables.getvariable()
else:
input_variables = None
output_variables = None
for num, (input_name, input_type, input_modifier) in enumerate(block_infos["inputs"]):
if input_variables is not None and num < len(input_variables):
connections = input_variables[num].connectionPointIn.getconnections()
if input_variables is None or connections and len(connections) == 1:
variables.append((input_type, None, "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None))
for num, (output_name, output_type, output_modifier) in enumerate(block_infos["outputs"]):
variables.append((output_type, None, "%sI%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None))
return variables
return [{"name" : "SVGUI function blocks", "list" :
[{"name" : "Container", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none")],
"outputs" : [],
"comment" : "SVGUI Container",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "Button", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("Toggle","BOOL","none")],
"outputs" : [("State","BOOL","none")],
"comment" : "SVGUI Button",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "TextCtrl", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetText","STRING","none")],
"outputs" : [("Text","STRING","none")],
"comment" : "SVGUI Text Control",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "ScrollBar", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetThumb","UINT","none"),("SetRange","UINT","none"),("SetPosition","UINT","none")],
"outputs" : [("Position","UINT","none")],
"comment" : "SVGUI ScrollBar",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "NoteBook", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetSelected","BOOL","none")],
"outputs" : [("Selected","UINT","none")],
"comment" : "SVGUI Notebook",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetAngle","REAL","none")],
"outputs" : [("Angle","REAL","none")],
"comment" : "SVGUI Rotating Control",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "Transform", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetX","REAL","none"),("SetY","REAL","none"),("SetXScale","REAL","none"),("SetYScale","REAL","none"),("SetAngle","REAL","none")],
"outputs" : [("X","REAL","none"),("Y","REAL","none")],
"comment" : "SVGUI Transform",
"generate" : generate_svgui_block, "initialise" : initialise_block},
]}
]
class _SVGUICGenerator(SVGUICGenerator):
def __init__(self, elements, svgfile, xmlfile, current_location):
SVGUICGenerator.__init__(self, elements, svgfile, xmlfile)
self.CurrentLocation = current_location
def GenerateProgramHeadersPublicVars(self):
text = """ void OnPlcOutEvent(wxEvent& event);
void Retrieve();
void Publish();
void Initialize();
"""
# text += " void Print();\n"
return text
def GenerateIECVars(self):
text = ""
for element in self.Elements:
text += "STATE_TYPE out_state_%d;\n"%element.getid()
text += "STATE_TYPE in_state_%d;\n"%element.getid()
text +="\n"
current_location = "_".join(map(str, self.CurrentLocation))
#Declaration des variables
for element in self.Elements:
block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
block_id = element.getid()
for i, input in enumerate(block_infos["inputs"]):
element_c_type = CTYPECONVERSION[input[1]]
variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1)
text += "%s %s;\n"%(element_c_type, variable)
text += "%s _copy%s;\n"%(element_c_type, variable)
for i, output in enumerate(block_infos["outputs"]):
element_c_type = CTYPECONVERSION[output[1]]
variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1)
text += "%s %s;\n"%(element_c_type, variable)
text += "%s _copy%s;\n"%(element_c_type, variable)
text +="\n"
return text
def GenerateGlobalVarsAndFuncs(self, size):
text = """#include \"iec_types.h\"
#ifdef __WXMSW__
#define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) InterlockedCompareExchange(Destination, exchange, comparand)
#define THREAD_RETURN_TYPE DWORD WINAPI
#define STATE_TYPE long int
#else
#define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) __sync_val_compare_and_swap(Destination, comparand, exchange)
#define THREAD_RETURN_TYPE void*
#define STATE_TYPE volatile int
#endif
"""
text += self.GenerateIECVars()
text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp);
IMPLEMENT_WX_THEME_SUPPORT;
SVGViewApp *myapp = NULL;
#ifdef __WXMSW__
HANDLE wxMainLoop;
DWORD wxMainLoopId;
#else
pthread_t wxMainLoop;
#endif
"""
# text += "pthread_t wxMainLoop,automate;\n"
text += """int myargc = 0;
char** myargv = NULL;
#define UNCHANGED 1
#define PLC_BUSY 2
#define CHANGED 3
#define GUI_BUSY 4
#ifdef __WXMSW__
#else
#endif
bool refresh = false;
bool refreshing = false;
THREAD_RETURN_TYPE InitWxEntry(void* args)
{
wxEntry(myargc,myargv);
return 0;
}
"""
# text += """void* SimulAutomate(void* args)
#{
# while(1){
# myapp->frame->m_svgCtrl->IN_"+self.BusNumber+"();
# //printf(\"AUTOMATE\\n\");
# myapp->frame->m_svgCtrl->OUT_"+self.BusNumber+"();
# sleep(1);
# }
# return args;
#}
#
#"""
text += """bool SVGViewApp::OnInit()
{
#ifndef __WXMSW__
setlocale(LC_NUMERIC, "C");
#endif
"""
#text += " frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxSize(%d, %d));\n"%size
text += """ frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxDefaultSize);
frame->Show();
myapp = this;
"""
# text += " pthread_create(&automate, NULL, SimulAutomate, NULL);\n"
text += """ return true;
}
extern "C" {
int __init_%(location)s(int argc, char** argv)
{
myargc = argc;
myargv = argv;
#ifdef __WXMSW__
wxMainLoop = CreateThread(NULL, 0, InitWxEntry, 0, 0, &wxMainLoopId);
#else
pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL);
#endif
return 0;
}
void __cleanup_%(location)s()
{
}
void __retrieve_%(location)s()
{
if(myapp){
myapp->frame->m_svgCtrl->Retrieve();
}
}
void __publish_%(location)s()
{
if(myapp){
myapp->frame->m_svgCtrl->Publish();
}
}
}
IEC_STRING wxStringToIEC_STRING(wxString s)
{
IEC_STRING res = {0,""};
int i;
for(i = 0; i<s.Length() && i<STR_MAX_LEN; i++)
res.body[i] = s.GetChar(i);
res.len = i;
return res;
}
"""%{"location" : "_".join(map(str, self.CurrentLocation))}
return text
def GenerateProgramEventTable(self):
text = """BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE( EVT_PLC, wxNewEventType() )
END_DECLARE_EVENT_TYPES()
DEFINE_LOCAL_EVENT_TYPE( EVT_PLC )
"""
#Event Table Declaration
text += "BEGIN_EVENT_TABLE(Program, SVGUIWindow)\n"
for element in self.Elements:
element_type = GetElementType(element)
element_name = element.getname()
if element_type == ITEM_BUTTON:
text += " EVT_BUTTON (SVGUIID(\"%s\"), Program::On%sClick)\n"%(element_name, element_name)
elif element_type in [ITEM_SCROLLBAR, ITEM_ROTATING, ITEM_TRANSFORM]:
text += " EVT_COMMAND_SCROLL_THUMBTRACK (SVGUIID(\"%s\"), Program::On%sChanging)\n"%(element_name, element_name)
elif element_type == ITEM_NOTEBOOK:
text += " EVT_NOTEBOOK_PAGE_CHANGED (SVGUIID(\"%s\"), Program::On%sTabChanged)\n"%(element_name, element_name)
text += " EVT_CUSTOM(EVT_PLC, wxID_ANY, Program::OnPlcOutEvent)\n"
text += "END_EVENT_TABLE()\n\n"
return text
def GenerateProgramInitFrame(self):
text = """MainFrame::MainFrame(wxWindow *parent, const wxString& title, const wxPoint& pos,const wxSize& size, long style): wxFrame(parent, wxID_ANY, title, pos, size, style)
{
m_svgCtrl = new Program(this);
if (m_svgCtrl->LoadFiles(wxT("%s"), wxT("%s")))
{
Show(true);
m_svgCtrl->SetFocus();
m_svgCtrl->SetFitToFrame(true);
m_svgCtrl->RefreshScale();
m_svgCtrl->InitScrollBars();
m_svgCtrl->Initialize();
m_svgCtrl->Update();
}
else
{
printf("Error while opening files\\n");
exit(0);
}
}
"""%(self.SVGFilePath, self.XMLFilePath)
return text
def GenerateProgramInitProgram(self):
text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n"
for element in self.Elements:
text += " out_state_%d = UNCHANGED;\n"%element.getid()
text += " in_state_%d = UNCHANGED;\n"%element.getid()
text += "}\n\n"
return text
def GenerateProgramEventFunctions(self):
text = ""
current_location = "_".join(map(str, self.CurrentLocation))
for element in self.Elements:
element_type = GetElementType(element)
element_lock = """ if (COMPARE_AND_SWAP_VAL(&in_state_%d, CHANGED, GUI_BUSY) == CHANGED ||
COMPARE_AND_SWAP_VAL(&in_state_%d, UNCHANGED, GUI_BUSY) == UNCHANGED) {
"""%(element.getid(), element.getid())
element_unlock = """ COMPARE_AND_SWAP_VAL(&in_state_%d, GUI_BUSY, CHANGED);
}
else
ProcessEvent(event);
"""%element.getid()
element_name = element.getname()
if element_type == ITEM_BUTTON:
text += """void Program::On%sClick(wxCommandEvent& event)
{
SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name)
text += element_lock
text += " _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid())
text += element_unlock
text += " event.Skip();\n}\n\n"
elif element_type == ITEM_ROTATING:
text += """void Program::On%sChanging(wxScrollEvent& event)
{
SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid())
text += element_unlock
text += " event.Skip();\n}\n\n"
elif element_type == ITEM_NOTEBOOK:
text += """void Program::On%sTabChanged(wxNotebookEvent& event)
{
SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid())
text += element_unlock
text += " event.Skip();\n}\n\n"
elif element_type == ITEM_TRANSFORM:
text += """void Program::On%sChanging(wxScrollEvent& event)
{
SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__ID%s_%d_1 = transform->GetX();\n"%(current_location, element.getid())
text += " _copy__ID%s_%d_2 = transform->GetY();\n"%(current_location, element.getid())
text += element_unlock
text += " event.Skip();\n}\n\n"
text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n"
text += """void Program::OnPlcOutEvent(wxEvent& event)
{
SVGUIElement* element;
refreshing = true;
wxMutexGuiEnter();
"""
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
text += """ if (COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, GUI_BUSY) == CHANGED)
{
element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
if (_copy__QX%(location)s_%(id)d_1 != element->IsVisible()) {
if (_copy__QX%(location)s_%(id)d_1)
element->Show();
else
element->Hide();
}
if (_copy__QX%(location)s_%(id)d_2 != element->IsEnabled()) {
if (_copy__QX%(location)s_%(id)d_2)
element->Enable();
else
element->Disable();
}
"""%texts
if element_type == ITEM_BUTTON:
text += """ if (_copy__QX%(location)s_%(id)d_3 != ((SVGUIButton*)element)->GetToggle())
((SVGUIButton*)element)->SetToggle(_copy__QX%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_TEXT:
text += """ if (((SVGUITextCtrl*)element)->GetValue().compare(_copy__QX%(location)s_%(id)d_3))
{
wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_3);
((SVGUITextCtrl*)element)->SetText(str);
}
"""%texts
elif element_type == ITEM_SCROLLBAR:
text += """ if (_copy__QW%(location)s_%(id)d_3 != ((SVGUIScrollBar*)element)->GetThumbPosition() ||
_copy__QW%(location)s_%(id)d_4 != ((SVGUIScrollBar*)element)->GetThumbSize() ||
_copy__QW%(location)s_%(id)d_5 != ((SVGUIScrollBar*)element)->GetRange())
((SVGUIScrollBar*)element)->Init_ScrollBar(_copy__QW%(location)s_%(id)d_3, _copy__QW%(location)s_%(id)d_4, _copy__QW%(location)s_%(id)d_5);
"""%texts
elif element_type == ITEM_ROTATING:
text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUIRotatingCtrl*)element)->GetAngle())
((SVGUIRotatingCtrl*)element)->SetAngle(_copy__QD%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_NOTEBOOK:
text += """ if (_copy__QB%(location)s_%(id)d_3 != ((SVGUINoteBook*)element)->GetCurrentPage())
((SVGUINoteBook*)element)->SetCurrentPage(_copy__QB%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_TRANSFORM:
text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUITransform*)element)->GetX() ||
copy__QD%(location)s_%(id)d_4 != ((SVGUITransform*)element)->GetY())
transform->Move(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4);
if (_copy__QD%(location)s_%(id)d_5 != ((SVGUITransform*)element)->GetXScale() ||
copy__QD%(location)s_%(id)d_6 != ((SVGUITransform*)element)->GetYScale())
transform->Scale(_copy__QD%(location)s_%(id)d_5, _copy__QD%(location)s_%(id)d_6);
if (_copy__QD%(location)s_%(id)d_7 != ((SVGUITransform*)element)->GetAngle())
transform->Rotate(_copy__QD%(location)s_%(id)d_7);
"""%texts
text += " COMPARE_AND_SWAP_VAL(&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n }\n"%texts
text += """ wxMutexGuiLeave();
refreshing = false;
event.Skip();
}
"""
return text
def GenerateProgramPrivateFunctions(self):
current_location = "_".join(map(str, self.CurrentLocation))
text = "void Program::Retrieve()\n{\n"
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
if len(block_infos["outputs"]) > 0:
text += """ if (COMPARE_AND_SWAP_VAL(&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED) {
"""%texts
for i, output in enumerate(block_infos["outputs"]):
texts["type"] = TYPECONVERSION[output[1]]
texts["pin"] = i + 1
variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts
text +=" %s = _copy%s;\n"%(variable, variable)
text += """ COMPARE_AND_SWAP_VAL(&in_state_%(id)d, PLC_BUSY, UNCHANGED);
}
"""%texts
text += "}\n\n"
text += "void Program::Publish()\n{\n STATE_TYPE new_state;\n\n"
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
text += """ if ((new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, UNCHANGED, PLC_BUSY)) == UNCHANGED ||
(new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, PLC_BUSY)) == CHANGED) {
"""%texts
for i, input in enumerate(block_infos["inputs"]):
texts["type"] = TYPECONVERSION[input[1]]
texts["pin"] = i + 1
variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts
text += " if (_copy%s != %s) {\n"%(variable, variable)
text += " _copy%s = %s;\n"%(variable, variable)
text += " new_state = CHANGED;\n }\n"%texts
text += """ COMPARE_AND_SWAP_VAL(&out_state_%(id)d, PLC_BUSY, new_state);
refresh |= new_state == CHANGED;
}
"""%texts
text += """ /* Replace this with determinist signal if called from RT */
if (refresh && !refreshing) {
wxCommandEvent event( EVT_PLC );
ProcessEvent(event);
refresh = false;
}
};
"""
text += """void Program::Initialize()
{
SVGUIElement* element;
"""
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
text += """
element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
__QX%(location)s_%(id)d_1 = 1;
_copy__QX%(location)s_%(id)d_1 = 1;
__QX%(location)s_%(id)d_2 = 1;
_copy__QX%(location)s_%(id)d_2 = 1;
"""%texts
if element_type == ITEM_BUTTON:
text += " _copy__IX%(location)s_%(id)d_1 = ((SVGUIButton*)element)->GetToggle();\n"%texts
elif element_type == ITEM_TEXT:
text += " _copy__IB%(location)s_%(id)d_1 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts
elif element_type == ITEM_SCROLLBAR:
text += " _copy__IW%(location)s_%(id)d_1 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts
elif element_type == ITEM_ROTATING:
text += " _copy__ID%(location)s_%(id)d_1 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts
elif element_type == ITEM_NOTEBOOK:
text += " _copy__IB%(location)s_%(id)d_1 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts
elif element_type == ITEM_TRANSFORM:
text += " _copy__ID%(location)s_%(id)d_1 = ((SVGUITransform*)element)->GetX();\n"%texts
text += " _copy__ID%(location)s_%(id)d_2 = ((SVGUITransform*)element)->GetY();\n"%texts
text += "}\n\n"
return text