--- a/Beremiz.py Tue Aug 12 16:27:07 2008 +0200
+++ b/Beremiz.py Wed Aug 20 00:11:40 2008 +0200
@@ -357,13 +357,13 @@
# Add beremiz's icon in top left corner of the frame
self.SetIcon(wx.Icon(os.path.join(CWD, "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
- self.PluginRoot = PluginsRoot(self)
+ self.PluginRoot = PluginsRoot(self, self.Log) self.DisableEvents = False
- self.PluginRoot.LoadProject(projectOpen, self.Log)
+ self.PluginRoot.LoadProject(projectOpen) @@ -572,7 +572,7 @@
msizer = wx.FlexGridSizer(cols=1)
for plugin_method in plugin.PluginMethods:
- if "method" in plugin_method:
+ if "method" in plugin_method and plugin_method.get("shown",True): button = GenBitmapTextButton(id=id, parent=parent,
bitmap=wx.Bitmap(os.path.join(CWD, "%s.png"%plugin_method.get("bitmap", os.path.join("images", "Unknown")))), label=plugin_method["name"],
@@ -675,7 +675,7 @@
enablebutton.SetBitmapSelected(wx.Bitmap(os.path.join(CWD, 'images', 'Enabled.png')))
enablebutton.SetToggle(plugin.MandatoryParams[1].getEnabled())
def toggleenablebutton(event):
- res = self.SetPluginParamsAttribute(plugin, "BaseParams.Enabled", enablebutton.GetToggle(), self.Log)
+ res = self.SetPluginParamsAttribute(plugin, "BaseParams.Enabled", enablebutton.GetToggle()) enablebutton.SetToggle(res)
enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
@@ -895,7 +895,7 @@
def GetItemChannelChangedFunction(self, plugin, value):
def OnPluginTreeItemChannelChanged(event):
- res = self.SetPluginParamsAttribute(plugin, "BaseParams.IEC_Channel", value, self.Log)
+ res = self.SetPluginParamsAttribute(plugin, "BaseParams.IEC_Channel", value) return OnPluginTreeItemChannelChanged
@@ -923,7 +923,7 @@
# Disable button to prevent re-entrant call
event.GetEventObject().Disable()
- getattr(plugin,method)(self.Log)
+ getattr(plugin,method)() event.GetEventObject().Enable()
# Trigger refresh on Idle
@@ -933,14 +933,14 @@
def GetChoiceCallBackFunction(self, choicectrl, plugin, path):
def OnChoiceChanged(event):
- res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection(), self.Log)
+ res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection()) choicectrl.SetStringSelection(res)
def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, plugin, path):
def OnChoiceContentChanged(event):
- res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection(), self.Log)
+ res = self.SetPluginParamsAttribute(plugin, path, choicectrl.GetStringSelection()) if wx.VERSION < (2, 8, 0):
self.ParamsPanel.Freeze()
choicectrl.SetStringSelection(res)
@@ -958,14 +958,14 @@
def GetTextCtrlCallBackFunction(self, textctrl, plugin, path):
def OnTextCtrlChanged(event):
- res = self.SetPluginParamsAttribute(plugin, path, textctrl.GetValue(), self.Log)
+ res = self.SetPluginParamsAttribute(plugin, path, textctrl.GetValue()) def GetCheckBoxCallBackFunction(self, chkbx, plugin, path):
def OnCheckBoxChanged(event):
- res = self.SetPluginParamsAttribute(plugin, path, chkbx.IsChecked(), self.Log)
+ res = self.SetPluginParamsAttribute(plugin, path, chkbx.IsChecked()) @@ -1112,7 +1112,7 @@
if dialog.ShowModal() == wx.ID_OK:
projectpath = dialog.GetPath()
if os.path.isdir(projectpath):
- result = self.PluginRoot.LoadProject(projectpath, self.Log)
+ result = self.PluginRoot.LoadProject(projectpath) @@ -1216,7 +1216,7 @@
dialog = wx.TextEntryDialog(self, "Please enter a name for plugin:", "Add Plugin", "", wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
PluginName = dialog.GetValue()
- plugin.PlugAddChild(PluginName, PluginType, self.Log)
+ plugin.PlugAddChild(PluginName, PluginType) --- a/images/icons.svg Tue Aug 12 16:27:07 2008 +0200
+++ b/images/icons.svg Wed Aug 20 00:11:40 2008 +0200
@@ -30,7 +30,7 @@
inkscape:window-height="994"
- inkscape:window-width="1625"
+ inkscape:window-width="1623" inkscape:pageopacity="0.0"
@@ -40,12 +40,12 @@
- inkscape:cx="440.43263"
- inkscape:cy="865.35999"
+ inkscape:cx="514.46278" inkscape:current-layer="svg2"
inkscape:guide-bbox="true">
@@ -56,6 +56,30 @@
+ inkscape:collect="always" + id="linearGradient17546"> + style="stop-color:#ff0000;stop-opacity:1;" + style="stop-color:#ffff00;stop-opacity:1" + inkscape:collect="always" + id="linearGradient17526"> + style="stop-color:#469837;stop-opacity:1;" + style="stop-color:#469837;stop-opacity:0;" style="stop-color:#ffffff;stop-opacity:1.0000000;"
@@ -82531,10 +82555,116 @@
+ inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16478" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16480" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16596" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16598" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16715" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient34137" + id="linearGradient16717" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient17526" + id="linearGradient17532" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(60,0)" /> + inkscape:collect="always" + xlink:href="#linearGradient17526" + id="linearGradient17534" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(60,0)" /> + inkscape:collect="always" + xlink:href="#linearGradient17526" + id="linearGradient17536" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(60,0)" /> + inkscape:collect="always" + xlink:href="#linearGradient17526" + id="linearGradient17540" + gradientUnits="userSpaceOnUse" + inkscape:collect="always" + xlink:href="#linearGradient17546" + id="linearGradient17552" + gradientUnits="userSpaceOnUse" /> - transform="matrix(0.9968636,0,0,0.9968648,-6.725278,-12.08626)">
+ transform="matrix(0.9968636,0,0,0.9968648,-6.725278,-192.08626)"> @@ -82637,7 +82767,7 @@
- transform="matrix(1.2234367,0,0,1.2234367,1268.4713,-201.46094)"
+ transform="matrix(1.2234367,0,0,1.2234367,1268.4713,-281.46094)" @@ -82695,21 +82825,21 @@
style="font-size:12.76095104px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
sodipodi:role="line">%% Build Clean editPLC HMIEditor ImportDEF ImportSVG NetworkEdit Run ShowIECcode Stop Unknown %%</tspan></text>
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="translate(1181,-139.4776)"
+ transform="translate(1181,-219.4776)" @@ -82773,7 +82903,7 @@
- transform="translate(1240.7988,-169.49646)"
+ transform="translate(1240.7988,-249.49646)" @@ -82869,7 +82999,7 @@
d="M -1045.6271,459.85458 L -1044.4626,460.28154 L -1044.4534,460.25632 L -1045.6179,459.82936 L -1045.6271,459.85458 z M -1045.483,459.46147 L -1044.8985,459.67576 L -1044.8893,459.65054 L -1045.4737,459.43625 L -1045.483,459.46147 z M -1045.3394,459.06983 L -1044.7549,459.28413 L -1044.7451,459.25743 L -1045.3296,459.04313 L -1045.3394,459.06983 z M -1045.1953,458.67671 L -1044.6108,458.89101 L -1044.6015,458.86579 L -1045.186,458.6515 L -1045.1953,458.67671 z M -1045.0511,458.2836 L -1044.4666,458.49789 L -1044.4574,458.47267 L -1045.0419,458.25838 L -1045.0511,458.2836 z M -1044.907,457.89048 L -1043.7425,458.31744 L -1043.7332,458.29222 L -1044.8977,457.86526 L -1044.907,457.89048 z M -1044.7629,457.49736 L -1044.1784,457.71166 L -1044.1691,457.68644 L -1044.7536,457.47214 L -1044.7629,457.49736 z M -1044.6193,457.10573 L -1044.0348,457.32003 L -1044.025,457.29332 L -1044.6095,457.07903 L -1044.6193,457.10573 z M -1044.4751,456.71261 L -1043.8907,456.92691 L -1043.8814,456.90169 L -1044.4659,456.68739 L -1044.4751,456.71261 z M -1044.331,456.3195 L -1043.7465,456.53379 L -1043.7373,456.50857 L -1044.3218,456.29428 L -1044.331,456.3195 z M -1044.1869,455.92638 L -1043.0224,456.35334 L -1043.0131,456.32812 L -1044.1776,455.90116 L -1044.1869,455.92638 z M -1044.0427,455.53326 L -1043.4583,455.74756 L -1043.449,455.72234 L -1044.0335,455.50804 L -1044.0427,455.53326 z M -1043.8986,455.14014 L -1043.3141,455.35444 L -1043.3049,455.32922 L -1043.8894,455.11493 L -1043.8986,455.14014 z M -1043.755,454.74851 L -1043.1705,454.96281 L -1043.1607,454.9361 L -1043.7452,454.72181 L -1043.755,454.74851 z M -1043.6109,454.35539 L -1043.0264,454.56969 L -1043.0172,454.54447 L -1043.6016,454.33017 L -1043.6109,454.35539 z M -1043.4667,453.96228 L -1042.3022,454.38924 L -1042.293,454.36402 L -1043.4575,453.93706 L -1043.4667,453.96228 z M -1043.3226,453.56916 L -1042.7381,453.78346 L -1042.7289,453.75824 L -1043.3134,453.54394 L -1043.3226,453.56916 z M -1043.1785,453.17604 L -1042.594,453.39034 L -1042.5848,453.36512 L -1043.1692,453.15082 L -1043.1785,453.17604 z M -1043.0349,452.78441 L -1042.4504,452.9987 L -1042.4406,452.972 L -1043.0251,452.75771 L -1043.0349,452.78441 z M -1042.8908,452.39129 L -1042.3063,452.60559 L -1042.297,452.58037 L -1042.8815,452.36607 L -1042.8908,452.39129 z M -1042.7466,451.99817 L -1041.5821,452.42513 L -1041.5729,452.39992 L -1042.7374,451.97295 L -1042.7466,451.99817 z M -1042.6025,451.60506 L -1042.018,451.81935 L -1042.0088,451.79413 L -1042.5932,451.57984 L -1042.6025,451.60506 z M -1042.4584,451.21194 L -1041.8739,451.42624 L -1041.8646,451.40102 L -1042.4491,451.18672 L -1042.4584,451.21194 z M -1042.3148,450.82031 L -1041.7303,451.0346 L -1041.7205,451.0079 L -1042.305,450.7936 L -1042.3148,450.82031 z M -1042.1706,450.42719 L -1041.5862,450.64148 L -1041.5769,450.61627 L -1042.1614,450.40197 L -1042.1706,450.42719 z M -1042.0265,450.03407 L -1040.862,450.46103 L -1040.8527,450.43581 L -1042.0173,450.00885 L -1042.0265,450.03407 z M -1041.8824,449.64095 L -1041.2979,449.85525 L -1041.2886,449.83003 L -1041.8731,449.61573 L -1041.8824,449.64095 z M -1041.7382,449.24784 L -1041.1538,449.46213 L -1041.1445,449.43692 L -1041.729,449.22262 L -1041.7382,449.24784 z M -1041.5946,448.8562 L -1041.0102,449.0705 L -1041.0004,449.0438 L -1041.5849,448.8295 L -1041.5946,448.8562 z M -1041.4505,448.46309 L -1040.866,448.67738 L -1040.8568,448.65216 L -1041.4413,448.43787 L -1041.4505,448.46309 z M -1041.3064,448.06997 L -1040.1419,448.49693 L -1040.1326,448.47171 L -1041.2971,448.04475 L -1041.3064,448.06997 z" />
- transform="translate(1541.0897,-320.03854)"
+ transform="translate(1541.0897,-400.03854)" @@ -82887,7 +83017,7 @@
d="M -1043.3148,591.51852 C -1042.1671,591.51852 -1041.2381,592.51591 -1041.2381,593.74961 C -1041.2381,594.98052 -1042.1671,595.97828 -1043.3148,595.97828 C -1044.4596,595.97828 -1045.3867,594.98052 -1045.3867,593.74961 C -1045.3867,592.51591 -1044.4596,591.51852 -1043.3148,591.51852 z M -1048.4282,594.44426 C -1047.4919,594.46171 -1046.5801,594.73882 -1046.0331,595.02798 C -1045.4412,595.33917 -1045.4725,595.99227 -1045.1141,596.27013 C -1044.75,596.52298 -1044.2166,596.30364 -1043.8888,596.59817 C -1043.5554,596.88714 -1043.3383,597.38735 -1043.1411,598.02366 C -1042.941,598.65718 -1043.2194,599.51581 -1042.6997,600.36329 C -1042.1579,601.20798 -1041.1693,601.98435 -1039.9838,603.03094 C -1039.7383,603.24774 -1039.4784,603.67038 -1039.5738,603.94508 C -1039.7674,604.50302 -1040.1089,604.66757 -1040.459,604.7121 C -1040.8091,604.74545 -1041.1452,604.49515 -1041.6481,604.16458 C -1042.14,603.81725 -1042.8525,603.29754 -1043.4137,602.70291 C -1043.9722,602.10273 -1044.4846,601.4192 -1044.979,600.61895 L -1046.3032,602.37247 C -1045.4751,603.03656 -1044.7728,603.68364 -1044.1614,604.34789 C -1043.5363,605.00904 -1042.891,605.58171 -1042.6659,606.32089 C -1042.4436,607.04889 -1042.5963,607.49919 -1042.8686,608.73288 C -1043.1436,609.97493 -1043.8931,612.61785 -1044.2989,613.70159 C -1044.6934,614.763 -1044.8709,614.98822 -1045.2516,615.12708 C -1045.6323,615.25775 -1046.3979,615.17954 -1046.5758,614.50719 C -1046.7396,613.82374 -1046.4196,612.25651 -1046.2695,611.07011 C -1046.1167,609.87237 -1045.929,608.683 -1045.693,607.41594 L -1048.4475,605.33439 C -1050.0729,607.62951 -1051.3606,609.44427 -1052.3887,610.85301 C -1053.4056,612.24789 -1053.9336,613.01256 -1054.5281,613.70159 C -1055.1089,614.38782 -1055.4351,614.80205 -1055.8909,614.94375 C -1056.3466,615.06872 -1057.1123,614.96846 -1057.2151,614.47102 C -1057.2957,613.96539 -1057.1611,613.44582 -1056.3998,611.94807 C -1055.6162,610.42825 -1054.0144,607.99671 -1052.6251,605.47911 C -1051.2276,602.95351 -1049.7723,600.14902 -1048.1412,596.92861 C -1048.9386,596.61185 -1049.7389,596.5703 -1050.5532,596.78147 C -1051.3756,596.99266 -1052.3594,597.95412 -1053.0013,598.20696 C -1053.6348,598.44592 -1054.0888,598.45432 -1054.2917,598.24314 C -1054.4806,598.02363 -1054.5035,597.44543 -1054.1229,596.92861 C -1053.7201,596.40067 -1052.9063,595.5533 -1051.9811,595.1365 C -1051.0501,594.71693 -1049.6111,594.46093 -1048.6163,594.44426 C -1048.5538,594.44305 -1048.4906,594.44309 -1048.4282,594.44426 z" />
- transform="translate(1480.1847,-289.94418)"
+ transform="translate(1480.1847,-369.94418)" @@ -83140,7 +83270,7 @@
- transform="translate(1600.9892,-350.1329)">
+ transform="translate(1600.9892,-430.1329)"> @@ -83150,7 +83280,7 @@
style="opacity:1;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- transform="matrix(1.6473499,0,0,1.6473499,680.92343,263.57576)"
+ transform="matrix(1.6473499,0,0,1.6473499,680.92343,183.57576)" style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient19976);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Andale Mono"><flowRegion
@@ -83164,7 +83294,7 @@
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient34167);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Andale Mono" /></flowRegion><flowPara
style="fill:url(#linearGradient19974);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">ST</flowPara></flowRoot> <g
- transform="matrix(7.1599763e-2,0,0,7.1599763e-2,543.18029,275.95335)"
+ transform="matrix(7.1599763e-2,0,0,7.1599763e-2,543.18029,195.95335)" d="M 144.80549,88.557517 C 144.80549,127.69251 113.04391,159.45419 73.909089,159.45419 C 34.773922,159.45419 3.0123414,127.69251 3.0123414,88.557517 C 3.0123414,49.42256 34.773922,17.660874 73.909089,17.660874 C 113.04391,17.660874 144.80549,49.42256 144.80549,88.557517 z"
@@ -83237,7 +83367,7 @@
style="opacity:0.84418604;fill:#6d9d37;fill-opacity:1;stroke:none" />
- transform="translate(1660.8886,-380.22727)"
+ transform="translate(1660.8886,-460.22727)" @@ -83332,7 +83462,7 @@
transform="matrix(0.5724346,-0.3079575,0.3079575,0.5724346,131.42904,887.47867)" />
- transform="translate(1360.788,-229.831)"
+ transform="translate(1360.788,-309.831)" @@ -83408,7 +83538,7 @@
- transform="translate(1420.788,-259.84989)"
+ transform="translate(1420.788,-339.84989)" @@ -83464,7 +83594,7 @@
- transform="translate(1121,-109.38324)"
+ transform="translate(1121,-189.38324)" @@ -83522,7 +83652,7 @@
style="fill:none;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83531,9 +83661,9 @@
style="font-size:12.76000023px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
sodipodi:role="line">%% Add Delete Disabled Enabled HideVars IECCDown IECCUp Maximize Minimize minus plus ShowVars %%</tspan></text>
@@ -83561,7 +83691,7 @@
transform="matrix(4.5011397,0,0,4.5011397,2971.834,-119.97324)" />
- transform="translate(25.999952,123.97794)">
+ transform="translate(25.999952,-56.02206)"> @@ -83604,7 +83734,7 @@
transform="matrix(3.9071406,0,0,3.9071406,2402.8076,-50.595777)" />
- transform="translate(19.498009,119.61597)">
+ transform="translate(19.498009,-60.38403)"> @@ -83630,7 +83760,7 @@
transform="matrix(1.0031449,0,0,1.0031449,685.39009,256.82525)" />
- transform="matrix(0.9968618,0,0,0.996865,-396.72428,99.913609)">
+ transform="matrix(0.9968618,0,0,0.996865,-396.72428,-80.086391)"> @@ -83648,7 +83778,7 @@
transform="matrix(1.0031449,0,0,1.0031449,660.09588,272.46095)" />
- transform="matrix(0.9968618,0,0,0.9968618,-339.72428,79.915124)">
+ transform="matrix(0.9968618,0,0,0.9968618,-339.72428,-100.08488)"> @@ -83663,7 +83793,7 @@
- transform="matrix(0.965737,0,0,0.965737,-233.99669,79.166717)">
+ transform="matrix(0.965737,0,0,0.965737,-233.99669,-100.83328)"> @@ -83938,14 +84068,14 @@
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
style="fill:url(#linearGradient16279);fill-opacity:1;stroke:url(#linearGradient16281)"
- transform="matrix(1,0,0,-1,-6.571463,804.20104)">
+ transform="matrix(1,0,0,-1,-6.571463,624.20104)"> style="fill:url(#linearGradient16274);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16276);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.43299961;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83954,14 +84084,14 @@
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
style="fill:url(#linearGradient16270);fill-opacity:1;stroke:url(#linearGradient16272)"
- transform="translate(39.428537,314.5234)">
+ transform="translate(39.428537,134.5234)"> style="fill:url(#linearGradient16266);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16268);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.43299961;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83969,7 +84099,7 @@
- transform="matrix(0.9968629,0,0,0.9968629,-119.72484,1.91483)">
+ transform="matrix(0.9968629,0,0,0.9968629,-119.72484,-178.08517)"> @@ -84175,7 +84305,7 @@
- transform="translate(20,119.91553)">
+ transform="translate(20,-60.08447)"> @@ -84307,7 +84437,7 @@
- transform="matrix(0.996861,0,0,0.996861,17.276127,-43.08392)">
+ transform="matrix(0.996861,0,0,0.996861,17.276127,-223.08392)"> @@ -84336,7 +84466,7 @@
- transform="matrix(0.996861,0,0,0.996861,58.276127,-63.08387)">
+ transform="matrix(0.996861,0,0,0.996861,58.276127,-243.08387)"> @@ -84375,29 +84505,29 @@
style="font-size:12.76000023px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
sodipodi:role="line">%% Compiler TargetType %%</tspan></text>
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(9.6211589e-2,0,0,9.6211589e-2,359.72267,486.8136)">
+ transform="matrix(9.6211589e-2,0,0,9.6211589e-2,219.72267,266.8136)"> transform="translate(48.379983,78.100302)" />
@@ -84440,7 +84570,7 @@
- transform="matrix(5.3097304e-2,0,0,5.3097304e-2,387.38564,480.36282)">
+ transform="matrix(5.3097304e-2,0,0,5.3097304e-2,247.38564,260.36282)"> @@ -84501,44 +84631,44 @@
style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="42.860386">Plugin</tspan><tspan
x="42.860386">Methods</tspan></text>
style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="283.48929">Plugin</tspan><tspan
+ x="43.489288">Plugin</tspan><tspan
- x="283.48929">Params</tspan></text>
+ x="43.489288">Params</tspan></text> style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="504.30698">Buttons</tspan></text>
+ x="37.5">Buttons</tspan></text> style="font-size:40.12579727px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
style="text-align:center;text-anchor:middle"
x="371.85562">Beremiz icons</tspan></text>
@@ -84630,19 +84760,19 @@
x="-988.61249">Pre-Alpha Release. Copyright © LOLITECH 2008</tspan></text>
- style="font-size:12.76000023px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ style="font-size:51.04000092px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- style="font-size:12.76000023px">%% splash %%</tspan></text>
+ style="font-size:51.04000092px">%% splash %%</tspan></text> - transform="matrix(0.2686638,0,0,0.2686638,754.93573,100.70118)">
+ transform="matrix(0.2686638,0,0,0.2686638,514.93573,-19.29882)"> @@ -84748,13 +84878,13 @@
style="font-size:13.88476658px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="266.00839">%% ico48 ico24 ico16 %%</tspan></text>
+ x="26.008392">%% ico48 ico24 ico16 %%</tspan></text> - transform="translate(1084.009,-113.72536)"
+ transform="translate(1084.009,-193.72536)" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.43299961;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -84835,7 +84965,7 @@
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.43299961;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- transform="translate(1083.788,-113.94633)"
+ transform="translate(1083.788,-193.94633)" style="fill:#4fadf7;fill-opacity:1"
@@ -84917,7 +85047,7 @@
- transform="translate(-0.212,-7.035e-2)"
+ transform="translate(-0.212,-80.07035)" d="M 263.65515,289.22899 L 258.6897,286.36218 L 263.65515,283.49538 L 263.65515,289.22899 z"
@@ -84947,9 +85077,9 @@
d="M 263.65515,289.22899 L 258.6897,286.36218 L 263.65515,283.49538 L 263.65515,289.22899 z"
- transform="translate(-0.5214,-0.3797)" />
+ transform="translate(-0.5214,-80.3797)" /> - transform="matrix(8.8340245e-2,0,0,8.8340245e-2,320.46956,254.13123)"
+ transform="matrix(8.8340245e-2,0,0,8.8340245e-2,320.46956,174.13123)" @@ -85051,27 +85181,27 @@
transform="matrix(0.5324675,0,0,0.5324675,-889.75288,329.57107)" />
style="font-size:12.76095104px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
sodipodi:linespacing="125%"><tspan
- y="341.52582">%% editIECrawcode EditCfile %%</tspan></text>
+ y="121.52582">%% editIECrawcode EditCfile Transfer Connect Disconnect Debug %%</tspan></text>
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:label="#rect16270" />
- transform="translate(-600.13257,100)">
+ transform="translate(-520.13257,-140)"> transform="matrix(1.6473499,0,0,1.6473499,800.92342,263.57576)"
@@ -85283,12 +85413,12 @@
inkscape:label="#rect16270"
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="translate(-480.13257,100)"
+ transform="translate(-400.13257,-140)" style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20956);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Andale Mono"
@@ -85497,4 +85627,81 @@
d="M 683.74504,273.49232 C 682.52118,272.4238 682.05427,273.42101 681.27718,274.09784 C 681.11122,273.95433 680.94525,273.81082 680.77929,273.66732 C 681.36055,272.97034 681.65306,272.60698 682.5725,272.17027 C 682.75266,272.27845 683.47211,273.29694 683.74504,273.49232 z"
style="fill:url(#linearGradient20979);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"><tspan + id="tspan16384">Icons</tspan></text> + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:label="#rect16270" /> + inkscape:label="#rect16270" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:label="#rect16270" /> + style="opacity:1;fill:url(#linearGradient17534);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:8.59499931;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="M 392,137.40625 C 388.95578,137.61016 386.40951,139.60837 385.4375,142.375 L 380,142.375 L 380,147.375 L 385.4375,147.375 C 386.41696,150.12787 388.96436,152.1385 392,152.34375 L 392,137.40625 z M 393,137.40625 L 393,152.34375 C 396.03564,152.1385 398.58304,150.12787 399.5625,147.375 L 404,147.375 L 404,142.375 L 399.5625,142.375 C 398.59049,139.60837 396.04422,137.61016 393,137.40625 z" + style="opacity:1;fill:url(#linearGradient17532);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:8.59499931;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="M 448,137.40625 C 444.95578,137.61016 442.40951,139.60837 441.4375,142.375 L 436,142.375 L 436,147.375 L 441.4375,147.375 C 442.41696,150.12787 444.96436,152.1385 448,152.34375 L 448,137.40625 z" + style="opacity:1;fill:url(#linearGradient17536);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:8.59499931;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="M 456,137.42468 L 456,152.36218 C 459.03564,152.15693 461.58304,150.1463 462.5625,147.39343 L 467,147.39343 L 467,142.39343 L 462.5625,142.39343 C 461.59049,139.6268 459.04422,137.62859 456,137.42468 z" + d="M 332,137.40625 C 328.95578,137.61016 326.40951,139.60837 325.4375,142.375 L 320,142.375 L 320,147.375 L 325.4375,147.375 C 326.41696,150.12787 328.96436,152.1385 332,152.34375 L 332,137.40625 z M 333,137.40625 L 333,152.34375 C 336.03564,152.1385 338.58304,150.12787 339.5625,147.375 L 344,147.375 L 344,142.375 L 339.5625,142.375 C 338.59049,139.60837 336.04422,137.61016 333,137.40625 z" + style="opacity:1;fill:url(#linearGradient17540);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:8.59499931;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + style="opacity:1;fill:url(#linearGradient17552);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:8.59499931;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + sodipodi:cy="144.36218" + sodipodi:r1="5.6378174" + sodipodi:r2="2.8189087" + sodipodi:arg1="1.5707963" + sodipodi:arg2="2.6179939" + inkscape:flatsided="true" + inkscape:randomized="0" + d="M 332,150 L 327.11751,141.54327 L 336.88249,141.54327 L 332,150 z" + transform="matrix(1.1031299,0.6368924,-0.6368924,1.1031299,58.022874,-226.14748)" /> + inkscape:label="#rect16270" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="opacity:1;fill:#160379;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="M 514.14211,134.18201 L 513.44846,134.37119 L 514.09481,136.75167 C 513.55664,136.88976 513.034,137.15037 512.61293,137.57144 C 512.58031,137.60404 512.56503,137.64813 512.53409,137.68179 C 511.78169,137.61864 511.00589,137.70771 510.24821,137.94979 L 509.60186,135.53777 L 508.90819,135.72696 L 509.5861,138.20203 C 508.90904,138.50465 508.25523,138.92751 507.67856,139.47899 L 505.51876,138.13898 L 505.15618,138.7538 L 507.18983,139.99922 C 506.46851,140.85118 505.98679,141.84216 505.771,142.83687 L 503.56394,142.23781 L 503.37475,142.93146 L 505.67641,143.56206 C 505.54986,144.9582 505.92466,146.33767 506.82724,147.39291 L 514.37857,139.84157 L 514.88305,140.34605 L 507.33172,147.89738 C 508.2984,148.72357 509.54404,149.1165 510.81574,149.07974 L 511.28869,150.84539 L 511.98234,150.65621 L 511.54092,149.01668 C 512.59832,148.85042 513.66579,148.38127 514.58351,147.64515 L 515.46634,149.06397 L 516.08117,148.70138 L 515.13529,147.15642 C 515.82639,146.46532 516.32697,145.65819 516.64871,144.82323 L 518.49319,145.31195 L 518.68237,144.6183 L 516.86941,144.1296 C 517.03506,143.48333 517.09629,142.82751 517.04282,142.19052 C 517.07648,142.15959 517.12057,142.14431 517.15319,142.11171 C 517.57426,141.69063 517.83486,141.16798 517.97296,140.6298 L 520.35344,141.27617 L 520.54262,140.58251 L 518.08331,139.92038 C 518.10481,139.07152 517.80055,138.21881 517.15319,137.57144 C 516.50581,136.92407 515.6531,136.61982 514.80424,136.64131 L 514.14211,134.18201 z" --- a/plugger.py Tue Aug 12 16:27:07 2008 +0200
+++ b/plugger.py Wed Aug 20 00:11:40 2008 +0200
@@ -70,6 +70,10 @@
+# helper func to get path to images + return os.path.join("images",imgname) This class is the one that define plugins.
@@ -100,9 +104,6 @@
# copy PluginMethods so that it can be later customized
self.PluginMethods = [dic.copy() for dic in self.PluginMethods]
def PluginBaseXmlFilePath(self, PlugName=None):
return os.path.join(self.PlugPath(PlugName), "baseplugin.xml")
@@ -112,7 +113,8 @@
def PlugPath(self,PlugName=None):
PlugName = self.BaseParams.getName()
- return os.path.join(self.PlugParent.PlugPath(), PlugName + NameTypeSeparator + self.PlugType)
+ return os.path.join(self.PlugParent.PlugPath(), + PlugName + NameTypeSeparator + self.PlugType) def PlugTestModified(self):
return self.ChangesToSave
@@ -149,13 +151,13 @@
params.append(self.PlugParams[1].getElementInfos(self.PlugParams[0]))
- def SetParamsAttribute(self, path, value, logger):
+ def SetParamsAttribute(self, path, value): self.ChangesToSave = True
# Filter IEC_Channel and Name, that have specific behavior
if path == "BaseParams.IEC_Channel":
- return self.FindNewIEC_Channel(value,logger), True
+ return self.FindNewIEC_Channel(value), True elif path == "BaseParams.Name":
- res = self.FindNewName(value,logger)
+ res = self.FindNewName(value) @@ -205,7 +207,7 @@
shutil.copytree(src_PlugPath, self.PlugPath)
- def PlugGenerate_C(self, buildpath, locations, logger):
+ def PlugGenerate_C(self, buildpath, locations): @param locations: List of complete variables locations \
@@ -217,12 +219,15 @@
@return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
- logger.write_warning(".".join(map(lambda x:str(x), self.GetCurrentLocation())) + " -> Nothing to do\n")
+ self.logger.write_warning(".".join(map(lambda x:str(x), self.GetCurrentLocation())) + " -> Nothing to do\n") - def _Generate_C(self, buildpath, locations, logger):
- # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS
- PlugCFilesAndCFLAGS, PlugLDFLAGS, DoCalls = self.PlugGenerate_C(buildpath, locations, logger)
+ def _Generate_C(self, buildpath, locations): + # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS, DoCalls, extra_files + # extra_files = [(fname,fobject), ...] + gen_result = self.PlugGenerate_C(buildpath, locations) + PlugCFilesAndCFLAGS, PlugLDFLAGS, DoCalls = gen_result[:3] + extra_files = gen_result[3:] # if some files heve been generated put them in the list with their location
LocationCFilesAndCFLAGS = [(self.GetCurrentLocation(), PlugCFilesAndCFLAGS, DoCalls)]
@@ -245,19 +250,18 @@
new_location = PlugChild.GetCurrentLocation()
# How deep are we in the tree ?
- _LocationCFilesAndCFLAGS, _LDFLAGS = \
+ _LocationCFilesAndCFLAGS, _LDFLAGS, _extra_files = \ # filter locations that start with current IEC location
- [loc for loc in locations if loc["LOC"][0:depth] == new_location ],
+ [loc for loc in locations if loc["LOC"][0:depth] == new_location ]) LocationCFilesAndCFLAGS += _LocationCFilesAndCFLAGS
+ extra_files += _extra_files - return LocationCFilesAndCFLAGS,LDFLAGS
+ return LocationCFilesAndCFLAGS, LDFLAGS, extra_files def BlockTypesFactory(self):
@@ -343,7 +347,7 @@
return {"name" : self.BaseParams.getName(), "channel" : self.BaseParams.getIEC_Channel(), "enabled" : self.BaseParams.getEnabled(), "parent" : len(self.PlugChildsTypes) > 0, "type" : self.BaseParams.getName(), "values" : childs}
- def FindNewName(self, DesiredName, logger):
+ def FindNewName(self, DesiredName): Changes Name to DesiredName if available, Name-N if not.
@param DesiredName: The desired Name (string)
@@ -376,10 +380,10 @@
shutil.move(oldname, self.PlugPath())
# warn user he has two left hands
- logger.write_warning("A child names \"%s\" already exist -> \"%s\"\n"%(DesiredName,res))
+ self.logger.write_warning("A child names \"%s\" already exist -> \"%s\"\n"%(DesiredName,res)) - def FindNewIEC_Channel(self, DesiredChannel, logger):
+ def FindNewIEC_Channel(self, DesiredChannel): Changes IEC Channel number to DesiredChannel if available, nearest available if not.
@param DesiredChannel: The desired IEC channel (int)
@@ -401,15 +405,14 @@
if res < CurrentChannel: # Want to go down ?
- logger.write_warning("Cannot find lower free IEC channel than %d\n"%CurrentChannel)
+ self.logger.write_warning("Cannot find lower free IEC channel than %d\n"%CurrentChannel) return CurrentChannel # Can't go bellow 0, do nothing
# Finally set IEC Channel
self.BaseParams.setIEC_Channel(res)
- if logger and DesiredChannel != res:
- logger.write_warning("A child with IEC channel %d already exist -> %d\n"%(DesiredChannel,res))
+ if DesiredChannel != res: + self.logger.write_warning("A child with IEC channel %d already exist -> %d\n"%(DesiredChannel,res)) @@ -433,7 +436,7 @@
# Ask to his parent to remove it
self.PlugParent._doRemoveChild(self)
- def PlugAddChild(self, PlugName, PlugType, logger):
+ def PlugAddChild(self, PlugName, PlugType): Create the plugins that may be added as child to this node self
@param PlugType: string desining the plugin class name (get name from PlugChildsTypes)
@@ -469,6 +472,8 @@
+ _self.logger = self.logger # Keep track of the plugin type name
_self.PlugType = PlugType
# remind the help string, for more fancy display
@@ -476,11 +481,11 @@
# Call the base plugin template init - change XSD into class members
PlugTemplate.__init__(_self)
- NewPlugName = _self.FindNewName(PlugName, logger)
+ NewPlugName = _self.FindNewName(PlugName) # If dir have already be made, and file exist
if os.path.isdir(_self.PlugPath(NewPlugName)): #and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
#Load the plugin.xml file into parameters members
- _self.LoadXMLParams(logger, NewPlugName)
+ _self.LoadXMLParams(NewPlugName) # Basic check. Better to fail immediately.
if (_self.BaseParams.getName() != NewPlugName):
raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(NewPlugName, _self.BaseParams.getName())
@@ -488,12 +493,12 @@
# Now, self.PlugPath() should be OK
# Check that IEC_Channel is not already in use.
- _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel(),logger)
+ _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel()) # Call the plugin real __init__
if getattr(PlugClass, "__init__", None):
PlugClass.__init__(_self)
#Load and init all the childs
- _self.LoadChilds(logger)
#just loaded, nothing to saved
_self.ChangesToSave = False
@@ -519,42 +524,44 @@
- def LoadXMLParams(self, logger, PlugName = None):
+ def LoadXMLParams(self, PlugName = None): methode_name = os.path.join(self.PlugPath(PlugName), "methods.py")
if os.path.isfile(methode_name):
basexmlfile = open(self.PluginBaseXmlFilePath(PlugName), 'r')
basetree = minidom.parse(basexmlfile)
self.MandatoryParams[1].loadXMLTree(basetree.childNodes[0])
- # logger.write_error("Couldn't load plugin base parameters %s :\n %s" % (PlugName, str(e)))
+ self.logger.write_error("Couldn't load plugin base parameters %s :\n %s" % (PlugName, str(exc))) + self.logger.write_error(traceback.format_exc())
xmlfile = open(self.PluginXmlFilePath(PlugName), 'r')
tree = minidom.parse(xmlfile)
self.PlugParams[1].loadXMLTree(tree.childNodes[0])
- # logger.write_error("Couldn't load plugin parameters %s :\n %s" % (PlugName, str(e)))
+ self.logger.write_error("Couldn't load plugin parameters %s :\n %s" % (PlugName, str(exc))) + self.logger.write_error(traceback.format_exc()) - def LoadChilds(self, logger):
# Iterate over all PlugName@PlugType in plugin directory, and try to open them
for PlugDir in os.listdir(self.PlugPath()):
if os.path.isdir(os.path.join(self.PlugPath(), PlugDir)) and \
PlugDir.count(NameTypeSeparator) == 1:
pname, ptype = PlugDir.split(NameTypeSeparator)
- self.PlugAddChild(pname, ptype, logger)
- # logger.write_error("Could not add child \"%s\", type %s :\n%s\n"%(pname, ptype, str(e)))
+ self.PlugAddChild(pname, ptype) + self.logger.write_error("Could not add child \"%s\", type %s :\n%s\n"%(pname, ptype, str(exc))) + self.logger.write_error(traceback.format_exc()) def EnableMethod(self, method, value):
for d in self.PluginMethods:
@@ -563,6 +570,13 @@
+ def ShowMethod(self, method, value): + for d in self.PluginMethods: + if d["method"]==method: def _GetClassFunction(name):
return getattr(__import__("plugins." + name), name).RootClass
@@ -586,15 +600,24 @@
ieclib_path = os.path.join(base_folder, "matiec", "lib")
# import for project creation timestamping
+from threading import Timer from time import localtime
from datetime import datetime
# import necessary stuff from PLCOpenEditor
from PLCControler import PLCControler
from PLCOpenEditor import PLCOpenEditor, ProjectDialog
from TextViewer import TextViewer
-from plcopen.structures import IEC_KEYWORDS
+from plcopen.structures import IEC_KEYWORDS, TypeHierarchy_list +# Construct debugger natively supported types +DebugTypes = [t for t in zip(*TypeHierarchy_list)[0] if not t.startswith("ANY")] + \ + ["STEP","TRANSITION","ACTION"] +from discovery import DiscoveryDialog class PluginsRoot(PlugTemplate, PLCControler):
@@ -619,77 +642,36 @@
<xsd:element name="TargetType">
- <xsd:element name="Win32">
- <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
- <xsd:element name="Linux">
- <xsd:attribute name="Nice" type="xsd:integer" use="required"/>
- <xsd:element name="Xenomai">
- <xsd:attribute name="xeno_config" type="xsd:string" use="optional" default="/usr/xenomai/"/>
- <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
- <xsd:element name="RTAI">
- <xsd:attribute name="rtai_config" type="xsd:string" use="required"/>
- <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
- <xsd:element name="Library">
- <xsd:attribute name="Dynamic" type="xsd:boolean" use="optional" default="true"/>
- <xsd:element name="Connection">
- <xsd:element name="Local"/>
- <xsd:element name="TCP_IP">
- <xsd:attribute name="Host" type="xsd:string" use="required"/>
+ """+targets.targetchoices+""" - <xsd:attribute name="Compiler" type="xsd:string" use="optional" default="gcc"/>
- <xsd:attribute name="CFLAGS" type="xsd:string" use="required"/>
- <xsd:attribute name="Linker" type="xsd:string" use="optional" default="ld"/>
- <xsd:attribute name="LDFLAGS" type="xsd:string" use="required"/>
- <xsd:attribute name="Sync_Align_Ratio" use="optional" default="50">
- <xsd:restriction base="xsd:integer">
- <xsd:minInclusive value="1"/>
- <xsd:maxInclusive value="99"/>
- def __init__(self, frame):
+ def __init__(self, frame, logger): PLCControler.__init__(self)
self.MandatoryParams = None
- This method are not called here... but in NewProject and OpenProject
- self._AddParamsMembers()
- self.PluggedChilds = {}
+ # Setup debug information + self.IECdebug_callables = {} + # Timer to prevent rapid-fire when registering many variables + self.DebugTimer=Timer(0.5,self.RegisterDebugVarToConnector) + self.ResetIECProgramsAndVariables() + #This method are not called here... but in NewProject and OpenProject + #self._AddParamsMembers() + #self.PluggedChilds = {} # In both new or load scenario, no need to save
self.ChangesToSave = False
@@ -769,14 +751,14 @@
- def LoadProject(self, ProjectPath, logger):
+ def LoadProject(self, ProjectPath): Load a project contained in a folder
@param ProjectPath: path of the project folder
if os.path.basename(ProjectPath) == "":
ProjectPath = os.path.dirname(ProjectPath)
- # Verify that project contains a PLCOpen program
+ # Verify that project contains a PLCOpen program plc_file = os.path.join(ProjectPath, "plc.xml")
if not os.path.isfile(plc_file):
return "Folder choosen doesn't contain a program. It's not a valid project!"
@@ -792,12 +774,19 @@
# If dir have already be made, and file exist
if os.path.isdir(self.PlugPath()) and os.path.isfile(self.PluginXmlFilePath()):
#Load the plugin.xml file into parameters members
- result = self.LoadXMLParams(logger)
+ result = self.LoadXMLParams() #Load and init all the childs
- self.LoadChilds(logger)
self.RefreshPluginsBlockLists()
+ if os.path.exists(self._getBuildPath()): + self.EnableMethod("_Clean", True) + if os.path.isfile(self._getIECrawcodepath()): + self.ShowMethod("_showIECcode", True) @@ -827,19 +816,12 @@
def PluginXmlFilePath(self, PlugName=None):
return os.path.join(self.PlugPath(PlugName), "beremiz.xml")
- def PlugGenerate_C(self, buildpath, locations, logger):
- @param locations: List of complete variables locations \
- [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
- ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
- @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
- return [(C_file_name, self.CFLAGS) for C_file_name in self.PLCGeneratedCFiles ] , "", False
return os.path.join(self.ProjectPath, "build")
+ def _getExtraFilesPath(self): + return os.path.join(self._getBuildPath(), "extra_files") def _getIECcodepath(self):
# define name for IEC code file
return os.path.join(self._getBuildPath(), "plc.st")
@@ -850,7 +832,7 @@
def _getIECrawcodepath(self):
# define name for IEC raw code file
- return os.path.join(self._getBuildPath(), "raw_plc.st")
+ return os.path.join(self.PlugPath(), "raw_plc.st") @@ -877,23 +859,22 @@
locations.append(resdict)
- def _Generate_SoftPLC(self, logger):
+ def _Generate_SoftPLC(self): Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C
@param buildpath: path where files should be created
- @param logger: the log pseudo file
# Update PLCOpenEditor Plugin Block types before generate ST code
self.RefreshPluginsBlockLists()
- logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n")
+ self.logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") buildpath = self._getBuildPath()
# ask PLCOpenEditor controller to write ST/IL/SFC code file
result = self.GenerateProgram(self._getIECgeneratedcodepath())
- logger.write_error("Error in ST/IL/SFC code generator :\n%s\n"%result)
+ self.logger.write_error("Error in ST/IL/SFC code generator :\n%s\n"%result) plc_file = open(self._getIECcodepath(), "w")
if os.path.isfile(self._getIECrawcodepath()):
@@ -901,11 +882,11 @@
plc_file.write(open(self._getIECgeneratedcodepath(), "r").read())
- logger.write("Compiling IEC Program in to C code...\n")
+ self.logger.write("Compiling IEC Program in to C code...\n") # Now compile IEC code into many C files
# files are listed to stdout, and errors to stderr.
status, result, err_result = ProcessLogger(
"\"%s\" -f \"%s\" -I \"%s\" \"%s\""%(
@@ -913,27 +894,238 @@
- logger.write_error("Error : IEC to C compiler returned %d\n"%status)
+ self.logger.write_error("Error : IEC to C compiler returned %d\n"%status) # Now extract C files of stdout
C_files = [ fname for fname in result.splitlines() if fname[-2:]==".c" or fname[-2:]==".C" ]
# remove those that are not to be compiled because included by others
- logger.write_error("Error : At least one configuration and one ressource must be declared in PLC !\n")
+ self.logger.write_error("Error : At least one configuration and one ressource must be declared in PLC !\n") # transform those base names to full names with path
C_files = map(lambda filename:os.path.join(buildpath, filename), C_files)
- logger.write("Extracting Located Variables...\n")
+ self.logger.write("Extracting Located Variables...\n") # Keep track of generated located variables for later use by self._Generate_C
self.PLCGeneratedLocatedVars = self.GetLocations()
# Keep track of generated C files for later use by self.PlugGenerate_C
self.PLCGeneratedCFiles = C_files
- self.CFLAGS = "\"-I"+ieclib_path+"\""
+ self.plcCFLAGS = "\"-I"+ieclib_path+"\"" - def _build(self, logger):
+ Return a Builder (compile C code into machine code) + # Get target, module and class name + targetname = self.BeremizRoot.getTargetType().getcontent()["name"] + modulename = "targets." + targetname + classname = targetname + "_target" + targetmodule = getattr(__import__(modulename), targetname) + self.logger.write_error("Can't find module for target %s!\n"%targetname) + self.logger.write_error(str(msg)) + targetclass = getattr(targetmodule, classname) + if self._builder is None or not isinstance(self._builder,targetclass): + # Get classname instance + self._builder = targetclass(self) + def GetLastBuildMD5(self): + builder=self.GetBuilder() + if builder is not None: + return builder.GetBinaryCodeMD5() + ####################################################################### + # C CODE GENERATION METHODS + ####################################################################### + def PlugGenerate_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 + return [(C_file_name, self.plcCFLAGS) for C_file_name in self.PLCGeneratedCFiles ] , "-lrt", False + def ResetIECProgramsAndVariables(self): + Reset variable and program list that are parsed from + CSV file generated by IEC2C compiler. + self._ProgramList = None + self._VariablesList = None + self._IECPathToIdx = None + self._IdxToIECPath = None + def GetIECProgramsAndVariables(self): + Parse CSV-like file VARIABLES.csv resulting from IEC2C compiler. + Each section is marked with a line staring with '//' + list of all variables used in various POUs + if self._ProgramList is None or self._VariablesList is None: + csvfile = os.path.join(self._getBuildPath(),"VARIABLES.csv") + # describes CSV columns + ProgramsListAttributeName = ["num", "C_path", "type"] + VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"] + self._VariablesList = [] + self._IECPathToIdx = {} + self._IdxToIECPath = {} + for line in open(csvfile,'r').xreadlines(): + strippedline = line.strip() + if strippedline.startswith("//"): + elif len(strippedline) > 0 and len(ListGroup) > 0: + # append to this section + ListGroup[-1].append(strippedline) + # first section contains programs + for line in ListGroup[0]: + # Split and Maps each field to dictionnary entries + attrs = dict(zip(ProgramsListAttributeName,line.strip().split(';'))) + # Truncate "C_path" to remove conf an ressources names + attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:]) + # Push this dictionnary into result. + self._ProgramList.append(attrs) + # second section contains all variables + for line in ListGroup[1]: + # Split and Maps each field to dictionnary entries + attrs = dict(zip(VariablesListAttributeName,line.strip().split(';'))) + # Truncate "C_path" to remove conf an ressources names + attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:]) + # Push this dictionnary into result. + self._VariablesList.append(attrs) + # Fill in IEC<->C translation dicts + IEC_path=attrs["IEC_path"] + self._IECPathToIdx[IEC_path]=Idx + self._IdxToIECPath[Idx]=IEC_path + self.logger.write_error("Cannot open/parse VARIABLES.csv!\n") + self.logger.write_error(traceback.format_exc()) + self.ResetIECProgramsAndVariables() + def Generate_plc_debugger(self): + Generate trace/debug code out of PLC variable list + self.GetIECProgramsAndVariables() + debug_code = runtime.code("plc_debug") % { + "programs_declarations": + "\n".join(["extern %(type)s %(C_path)s;"%p for p in self._ProgramList]), + "extern_variables_declarations":"\n".join([ + {"PT":"extern %(type)s *%(C_path)s;", + "VAR":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v + for v in self._VariablesList if v["C_path"].find('.')<0]), + "subscription_table_count": + len(self._VariablesList), + "variables_pointer_type_table_count": + len(self._VariablesList), + "variables_pointer_type_table_initializer":"\n".join([ + {"PT":" variable_table[%(num)s].ptrvalue = (void*)(%(C_path)s);\n", + "VAR":" variable_table[%(num)s].ptrvalue = (void*)(&%(C_path)s);\n"}[v["vartype"]]%v + + " variable_table[%(num)s].type = %(type)s_ENUM;\n"%v + for v in self._VariablesList if v["type"] in DebugTypes ])} + def RegisterDebugVarToConnector(self): + if self._connector is not None: + for IECPath,WeakCallableDict in self.IECdebug_callables: + if len(WeakCallableDict) == 0: + # Callable Dict is empty. + # This variable is not needed anymore! + self.IECdebug_callables.pop(IECPath) + Idx = self._IECPathToIdx.get(IECPath,None) + self.logger.write_warning("Debug : Unknown variable %s\n"%IECPath) + self._connector.TraceVariables(Idxs) + def SubscribeDebugIECVariable(self, IECPath, callable, *args, **kwargs): + Dispatching use a dictionnary linking IEC variable paths + to a WeakKeyDictionary linking + weakly referenced callables to optionnal args + # If no entry exist, create a new one with a fresh WeakKeyDictionary + self.IECdebug_callables.setdefault( + WeakKeyDictionary())[callable]=(args, kwargs) + # Rearm anti-rapid-fire timer + self.DebugTimer.cancel() + self.DebugTimer.start() + def Generate_plc_common_main(self): + Use plugins layout given in LocationCFilesAndCFLAGS to + generate glue code that dispatch calls to all plugins + # filter location that are related to code that will be called + # in retreive, publish, init, cleanup + locstrs = map(lambda x:"_".join(map(str,x)), + [loc for loc,Cfiles,DoCalls in self.LocationCFilesAndCFLAGS if loc and DoCalls]) + # Generate main, based on template + plc_main_code = runtime.code("plc_common_main") % { + "calls_prototypes":"\n".join([( + "int __init_%(s)s(int argc,char **argv);\n"+ + "void __cleanup_%(s)s();\n"+ + "void __retrieve_%(s)s();\n"+ + "void __publish_%(s)s();")%{'s':locstr} for locstr in locstrs]), + "retrieve_calls":"\n ".join([ + "__retrieve_%s();"%locstr for locstr in locstrs]), + "publish_calls":"\n ".join([ #Call publish in reverse order + "__publish_%s();"%locstrs[i-1] for i in xrange(len(locstrs), 0, -1)]), + "init_calls":"\n ".join([ + "if(res = __init_%s(argc,argv)){"%locstr + + #"printf(\"%s\"); "%locstr + #for debug + "return res;}" for i,locstr in enumerate(locstrs)]), + "cleanup_calls":"\n ".join([ + "if(init_level >= %d) "%i+ + "__cleanup_%s();"%locstrs[i-1] for i in xrange(len(locstrs), 0, -1)]) + target_name = self.BeremizRoot.getTargetType().getcontent()["name"] + plc_main_code += runtime.code("plc_%s_main"%target_name) Method called by user to (re)build SoftPLC and plugin tree
@@ -945,113 +1137,90 @@
# Eventually create build dir
if not os.path.exists(buildpath):
- logger.write("Start build in %s\n" % buildpath)
+ # There is something to clean self.EnableMethod("_Clean", True)
- self.EnableMethod("_showIECcode", True)
- # Generate SoftPLC code
- if not self._Generate_SoftPLC(logger):
- logger.write_error("SoftPLC code generation failed !\n")
+ self.logger.write("Start build in %s\n" % buildpath) + # Generate SoftPLC IEC code + IECGenRes = self._Generate_SoftPLC() + self.ShowMethod("_showIECcode", True) + # If IEC code gen fail, bail out. + self.logger.write_error("IEC-61131-3 code generation failed !\n")
- #logger.write("SoftPLC code generation successfull\n")
- logger.write("Generating plugins code ...\n")
+ # Reset variable and program list that are parsed from + # CSV file generated by IEC2C compiler. + self.ResetIECProgramsAndVariables() # Generate C code and compilation params from plugin hierarchy
+ self.logger.write("Generating plugins C code\n") - LocationCFilesAndCFLAGS,LDFLAGS = self._Generate_C(
+ self.LocationCFilesAndCFLAGS, self.LDFLAGS, ExtraFiles = self._Generate_C( - self.PLCGeneratedLocatedVars,
+ self.PLCGeneratedLocatedVars) - logger.write_error("Plugins code generation Failed !\n")
- logger.write_error(traceback.format_exc())
+ self.logger.write_error("Plugins code generation failed !\n") + self.logger.write_error(traceback.format_exc())
- #pp = pprint.PrettyPrinter(indent=4)
- #logger.write("LocationCFilesAndCFLAGS :\n"+pp.pformat(LocationCFilesAndCFLAGS)+"\n")
- #logger.write("LDFLAGS :\n"+pp.pformat(LDFLAGS)+"\n")
- locstrs = map(lambda x:"_".join(map(str,x)), [loc for loc,Cfiles,DoCalls in LocationCFilesAndCFLAGS if loc and DoCalls])
- plc_main = runtime.code("plc_common_main") % {
- "calls_prototypes":"\n".join(
- ["int __init_%(s)s(int argc,char **argv);\nvoid __cleanup_%(s)s();\nvoid __retrieve_%(s)s();\nvoid __publish_%(s)s();"%
- {'s':locstr} for locstr in locstrs]),
- "retrieve_calls":"\n ".join(["__retrieve_%(s)s();"%{'s':locstr} for locstr in locstrs]),
- "publish_calls":"\n ".join(["__publish_%(s)s();"%{'s':locstr} for locstr in locstrs]),
- "init_calls":"\n ".join(["init_level++; if(res = __init_%(s)s(argc,argv)) return res;"%{'s':locstr} for locstr in locstrs]),
- "cleanup_calls":"\n ".join(["if(init_level-- > 0) __cleanup_%(s)s();"%{'s':locstr} for locstr in locstrs]),
- "sync_align_ratio":self.BeremizRoot.getSync_Align_Ratio()}
- target_name = self.BeremizRoot.TargetType.content["name"]
- plc_main += runtime.code("plc_%s_main"%target_name)
+ # Get temprary directory path + extrafilespath = self._getExtraFilesPath() + if os.path.exists(extrafilespath): + shutil.rmtree(extrafilespath) + os.mkdir(extrafilespath) + for fname,fobject in ExtraFiles: + fpath = os.path.join(extrafilespath,fname) + open(fpath, "wb").write(fobject.read()) + # Now we can forget ExtraFiles (will close files object) - main_path = os.path.join(buildpath, "main.c" )
- f = open(main_path,'w')
- # First element is necessarely root
- LocationCFilesAndCFLAGS[0][1].insert(0,(main_path, self.CFLAGS))
- # Compile the resulting code into object files.
- compiler = self.BeremizRoot.getCompiler()
- _CFLAGS = self.BeremizRoot.getCFLAGS()
- linker = self.BeremizRoot.getLinker()
- _LDFLAGS = self.BeremizRoot.getLDFLAGS()
- for Location, CFilesAndCFLAGS, DoCalls in LocationCFilesAndCFLAGS:
- logger.write("Plugin : " + self.GetChildByIECLocation(Location).GetCurrentName() + " " + str(Location)+"\n")
- logger.write("PLC :\n")
- for CFile, CFLAGS in CFilesAndCFLAGS:
- bn = os.path.basename(CFile)
- obn = os.path.splitext(bn)[0]+".o"
- logger.write(" [CC] "+bn+" -> "+obn+"\n")
- objectfilename = os.path.splitext(CFile)[0]+".o"
+ # Template based part of C code generation + # files are stacked at the beginning, as files of plugin tree root + for generator, filename, name in [ + (self.Generate_plc_debugger, "plc_debugger.c", "Debugger"), + # init/cleanup/retrieve/publish, run and align code + (self.Generate_plc_common_main,"plc_common_main.c","Common runtime")]: + code_path = os.path.join(buildpath,filename) + open(code_path, "w").write(code) + # Insert this file as first file to be compiled at root plugin + self.LocationCFilesAndCFLAGS[0][1].insert(0,(code_path, self.plcCFLAGS)) + self.logger.write_error(name+" generation failed !\n") + self.logger.write_error(traceback.format_exc()) - status, result, err_result = ProcessLogger(
- "\"%s\" -c \"%s\" -o \"%s\" %s %s"%
- (compiler, CFile, objectfilename, _CFLAGS, CFLAGS)
+ self.logger.write("C code generated successfully.\n") + # Get current or fresh builder + builder = self.GetBuilder() + self.logger.write_error("Fatal : cannot get builder.\n")
- logger.write_error("Build failed\n")
- objs.append(objectfilename)
- # Link all the object files into one executable
- logger.write("Linking :\n")
- exe = self.GetProjectName()
- if target_name == "Win32":
- exe_path = os.path.join(buildpath, exe)
- logger.write(" [CC] " + ' '.join(obns)+" -> " + exe + "\n")
- status, result, err_result = ProcessLogger(
- "\"%s\" \"%s\" -o \"%s\" %s"%
- ' '.join(LDFLAGS+[_LDFLAGS]))
- logger.write_error("Build failed\n")
- self.EnableMethod("_Run", False)
+ if not builder.build() : + self.logger.write_error("C Build failed.\n") + self.logger.write_error("C Build crashed !\n") + self.logger.write_error(traceback.format_exc())
- self.EnableMethod("_Run", True)
+ # Update GUI status about need for transfer + self.CompareLocalAndRemotePLC() def ShowError(self, logger, from_location, to_location):
@@ -1061,8 +1230,8 @@
start = (from_location[0] - start_row, from_location[1] - start_col)
end = (to_location[0] - start_row, to_location[1] - start_col)
self.PLCEditor.ShowError(infos, start, end)
- def _showIECcode(self, logger):
+ def _showIECcode(self): plc_file = self._getIECcodepath()
new_dialog = wx.Frame(self.AppFrame)
ST_viewer = TextViewer(new_dialog, "", None, None)
@@ -1076,14 +1245,9 @@
- def _editIECrawcode(self, logger):
+ def _editIECrawcode(self): new_dialog = wx.Frame(self.AppFrame)
- buildpath = self._getBuildPath()
- # Eventually create build dir
- if not os.path.exists(buildpath):
controler = MiniTextControler(self._getIECrawcodepath())
ST_viewer = TextViewer(new_dialog, "", None, controler)
@@ -1092,7 +1256,7 @@
- def _EditPLC(self, logger):
if self.PLCEditor is None:
self.RefreshPluginsBlockLists()
@@ -1108,83 +1272,245 @@
self.PLCEditor._onsave = _onsave
- def _Clean(self, logger):
if os.path.isdir(os.path.join(self._getBuildPath())):
- logger.write("Cleaning the build directory\n")
+ self.logger.write("Cleaning the build directory\n") shutil.rmtree(os.path.join(self._getBuildPath()))
- logger.write_error("Build directory already clean\n")
- self.EnableMethod("_showIECcode", False)
+ self.logger.write_error("Build directory already clean\n") + self.ShowMethod("_showIECcode", False) self.EnableMethod("_Clean", False)
- self.EnableMethod("_Run", False)
- def _Run(self, logger):
- command_start_plc = os.path.join(self._getBuildPath(),self.GetProjectName() + exe_ext)
- if os.path.isfile(command_start_plc):
- for PlugChild in self.IterChilds():
- has_gui_plugin |= PlugChild.IsGUIPlugin()
- logger.write("Starting PLC\n")
- def this_plc_finish_callback(*args):
- if self.runningPLC is not None:
- self.runningPLC = ProcessLogger(
- finish_callback = this_plc_finish_callback,
- no_gui=wx.Platform != '__WXMSW__' or not has_gui_plugin)
- self.EnableMethod("_Clean", False)
- self.EnableMethod("_Run", False)
- self.EnableMethod("_Stop", True)
- self.EnableMethod("_build", False)
+ self.CompareLocalAndRemotePLC() + ############# Real PLC object access ############# + def UpdateMethodsFromPLCStatus(self): + # Get PLC state : Running or Stopped + # TODO : use explicit status instead of boolean + if self._connector is not None: + status = self._connector.GetPLCstatus() + self.logger.write("PLC is %s\n"%status) + status = "Disconnected" + "Started":[("_Run", False), + "Stopped":[("_Run", True), + "Empty": [("_Run", False), + "Dirty": [("_Run", True), + "Disconnected": [("_Run", False), + if self._connector.StartPLC(): + self.logger.write("Starting PLC\n") + self.logger.write_error("Couldn't start PLC !\n") + self.UpdateMethodsFromPLCStatus() + if self.GetIECProgramsAndVariables() and self._connector.StartPLC(): + self.logger.write("Starting PLC (debug mode)\n") + # TODO : laucnch PLCOpenEditor in Debug Mode + self.logger.write_warning("Debug mode for PLCopenEditor not implemented\n") + self.logger.write_warning("Starting alternative test GUI\n") + # TODO : laucnch PLCOpenEditor in Debug Mode + self.logger.write_error("Couldn't start PLC debug !\n") + self.UpdateMethodsFromPLCStatus() + if self._connector.StopPLC(): + self.logger.write("Stopping PLC\n") - logger.write_error("%s doesn't exist\n" %command_start_plc)
+ self.logger.write_error("Couldn't stop PLC !\n") + self.UpdateMethodsFromPLCStatus() + # don't accept re-connetion is already connected + if self._connector is not None: + self.logger.write_error("Already connected. Please disconnect\n") + getcontent()["value"].\ - def reset_finished(self):
- self.EnableMethod("_Clean", True)
- self.EnableMethod("_Run", True)
- self.EnableMethod("_Stop", False)
- self.EnableMethod("_build", True)
+ # if uri is empty launch discovery dialog + # Launch Service Discovery dialog + dia = DiscoveryDialog(self.AppFrame) + # Nothing choosed or cancel button + getcontent()["value"].\ + # Get connector from uri + self._connector = connectors.ConnectorFactory(uri, self) + self.logger.write_error("Exception while connecting %s!\n"%uri) + self.logger.write_error(traceback.format_exc()) + # Did connection success ? + if self._connector is None: + self.logger.write_error("Connection failed to %s!\n"%uri) + self.ShowMethod("_Connect", False) + self.ShowMethod("_Disconnect", True) + self.ShowMethod("_Transfer", True) + self.CompareLocalAndRemotePLC() + self.UpdateMethodsFromPLCStatus() - def _Stop(self, logger):
- if self.runningPLC is not None:
- logger.write("Stopping PLC\n")
- was_runningPLC = self.runningPLC
+ def CompareLocalAndRemotePLC(self): + if self._connector is None: + # We are now connected. Update button status + MD5 = self.GetLastBuildMD5() + # Check remote target PLC correspondance to that md5 + if not self._connector.MatchMD5(MD5): + self.logger.write_warning( + "Latest build do not match with target, please transfer.\n") + self.EnableMethod("_Transfer", True) + "Latest build match target, no transfer needed.\n") + self.EnableMethod("_Transfer", True) + #self.EnableMethod("_Transfer", False) + self.logger.write_warning( + "Cannot compare latest build to target. Please build.\n") + self.EnableMethod("_Transfer", False) + self.ShowMethod("_Transfer", False) + self.ShowMethod("_Connect", True) + self.ShowMethod("_Disconnect", False) + self.UpdateMethodsFromPLCStatus() + # Get the last build PLC's + MD5 = self.GetLastBuildMD5() + # Check if md5 file is empty : ask user to build PLC + self.logger.write_error("Failed : Must build before transfer.\n") + # Compare PLC project with PLC on target + if self._connector.MatchMD5(MD5): + "Latest build already match current target. Transfering anyway...\n") + # Get temprary directory path + extrafilespath = self._getExtraFilesPath() + extrafiles = [(name, open(os.path.join(extrafilespath, name), + for name in os.listdir(extrafilespath) \ + for filename, unused in extrafiles: + builder = self.GetBuilder() + if builder is not None: + data = builder.GetBinaryCode() + if self._connector.NewPLC(MD5, data, extrafiles): + self.logger.write("Transfer completed successfully.\n") + self.logger.write_error("Transfer failed\n") + self.logger.write_error("No PLC to transfer (did build success ?)\n") + self.UpdateMethodsFromPLCStatus() - {"bitmap" : os.path.join("images", "editPLC"),
+ {"bitmap" : opjimg("editPLC"), "tooltip" : "Edit PLC program with PLCOpenEditor",
- {"bitmap" : os.path.join("images", "Build"),
+ {"bitmap" : opjimg("Build"), "tooltip" : "Build project into build folder",
- {"bitmap" : os.path.join("images", "Clean"),
+ {"bitmap" : opjimg("Clean"), "tooltip" : "Clean project build folder",
- {"bitmap" : os.path.join("images", "Run"),
+ {"bitmap" : opjimg("Run"),
- "tooltip" : "Run PLC from build folder",
+ "tooltip" : "Start PLC", - {"bitmap" : os.path.join("images", "Stop"),
+ {"bitmap" : opjimg("Debug"), + "tooltip" : "Start PLC (debug mode)", + {"bitmap" : opjimg("Stop"),
"tooltip" : "Stop Running PLC",
- {"bitmap" : os.path.join("images", "ShowIECcode"),
+ {"bitmap" : opjimg("Connect"), + "tooltip" : "Connect to the target PLC", + "method" : "_Connect"}, + {"bitmap" : opjimg("Transfer"), + "tooltip" : "Transfer PLC", + "method" : "_Transfer"}, + {"bitmap" : opjimg("Disconnect"), + "tooltip" : "Disconnect from PLC", + "method" : "_Disconnect"}, + {"bitmap" : opjimg("ShowIECcode"),
"tooltip" : "Show IEC code generated by PLCGenerator",
"method" : "_showIECcode"},
- {"bitmap" : os.path.join("images", "editIECrawcode"),
+ {"bitmap" : opjimg("editIECrawcode"), "tooltip" : "Edit raw IEC code added to code generated by PLCGenerator",
- "method" : "_editIECrawcode"}
+ "method" : "_editIECrawcode"}, --- a/plugins/svgui/svgui.py Tue Aug 12 16:27:07 2008 +0200
+++ b/plugins/svgui/svgui.py Wed Aug 20 00:11:40 2008 +0200
@@ -116,9 +116,6 @@
self.CreateNewInterface()
self.SetFilePath(filepath)
def GetElementIdFromName(self, name):
element = self.GetElementByName(name)
@@ -126,7 +123,7 @@
- def _OpenView(self, logger):
@@ -137,7 +134,7 @@
self._View._onsave = _onsave
- def _ImportSVG(self, logger):
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:
@@ -145,10 +142,10 @@
if os.path.isfile(svgpath):
shutil.copy(svgpath, os.path.join(self.PlugPath(), "gui.svg"))
- logger.write_error("No such SVG file: %s\n"%svgpath)
+ self.logger.write_error("No such SVG file: %s\n"%svgpath) - def _ImportXML(self, logger):
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:
@@ -156,7 +153,7 @@
if os.path.isfile(xmlpath):
shutil.copy(xmlpath, os.path.join(self.PlugPath(), "gui.xml"))
- logger.write_error("No such XML file: %s\n"%xmlpath)
+ self.logger.write_error("No such XML file: %s\n"%xmlpath) @@ -178,7 +175,7 @@
self.SaveXMLFile(os.path.join(self.PlugPath(), "gui.xml"))
- def PlugGenerate_C(self, buildpath, locations, logger):
+ def PlugGenerate_C(self, buildpath, locations): progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation()))
doc = SVGDocument(self.GetSVGFilePath())
@@ -186,10 +183,15 @@
window_size = (int(float(root_element.GetAttribute("width"))),
int(float(root_element.GetAttribute("height"))))
- svgfilepath = self.GetSVGFilePath()
- xmlfilepath = self.GetFilePath()
- shutil.copy(svgfilepath, buildpath)
- shutil.copy(xmlfilepath, buildpath)
+# svgfilepath = self.GetSVGFilePath() +# xmlfilepath = self.GetFilePath() +# shutil.copy(svgfilepath, buildpath) +# shutil.copy(xmlfilepath, buildpath) + SVGFilePath = self.GetSVGFilePath() + SVGFileBaseName = os.path.split(SVGFilePath)[1] + FilePath = self.GetFilePath() + FileBaseName = os.path.split(FilePath)[1] generator = _SVGUICGenerator(self, self.GetElementsByType(),
os.path.split(self.GetSVGFilePath())[1],
@@ -202,17 +204,17 @@
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"
- status, result, err_result = ProcessLogger(logger, "wx-config --cxxflags", no_stdout=True).spin()
+ status, result, err_result = ProcessLogger(self.logger, "wx-config --cxxflags", no_stdout=True).spin() - logger.write_error("Unable to get wx cxxflags\n")
+ self.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()
+ status, result, err_result = ProcessLogger(self.logger, "wx-config --libs", no_stdout=True).spin() - logger.write_error("Unable to get wx libs\n")
+ self.logger.write_error("Unable to get wx libs\n") libs = result.strip() + " -lwxsvg"
- return [(Gen_C_file, cxx_flags)],libs,True
+ return [(Gen_C_file, cxx_flags)],libs,True,(SVGFileBaseName, file(SVGFilePath, "rb")), (FileBaseName, file(FilePath, "rb")) def BlockTypesFactory(self):
@@ -330,7 +332,8 @@
self.Controler = controler
def GenerateProgramHeadersPublicVars(self):
- text = """ void OnPlcOutEvent(wxEvent& event);
+ void OnPlcOutEvent(wxEvent& event); @@ -382,7 +385,6 @@
text += self.GenerateIECVars()
text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp);
-IMPLEMENT_WX_THEME_SUPPORT;
SVGViewApp *myapp = NULL;
@@ -412,12 +414,14 @@
THREAD_RETURN_TYPE InitWxEntry(void* args)
- text += """bool SVGViewApp::OnInit()
+bool SVGViewApp::OnInit() setlocale(LC_NUMERIC, "C");
@@ -448,6 +452,12 @@
void __cleanup_%(location)s()
+ wxCloseEvent event(wxEVT_CLOSE_WINDOW); + myapp->frame->AddPendingEvent(event); void __retrieve_%(location)s()
@@ -506,9 +516,8 @@
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)
- wxFileName apppath(wxTheApp->argv[0]);
- wxFileName svgfilepath(apppath.GetPath(), wxT("%s"));
- wxFileName xmlfilepath(apppath.GetPath(), wxT("%s"));
+ wxFileName svgfilepath(wxTheApp->argv[1], wxT("%s")); + wxFileName xmlfilepath(wxTheApp->argv[1], wxT("%s")); m_svgCtrl = new Program(this);
if (m_svgCtrl->LoadFiles(svgfilepath.GetFullPath(), xmlfilepath.GetFullPath()))
@@ -522,8 +531,7 @@
- printf("Error while opening files\\n");
+ printf("Error while opening SVGUI files\\n"); @@ -545,13 +553,19 @@
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 ||
+ 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);
+ COMPARE_AND_SWAP_VAL(&in_state_%d, GUI_BUSY, CHANGED); + /* re post event for idle */ + AddPendingEvent(event);
element_name = element.getname()
@@ -562,7 +576,6 @@
text += " _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid())
- text += " event.Skip();\n}\n\n"
elif element_type == ITEM_ROTATING:
text += """void Program::On%sChanging(wxScrollEvent& event)
@@ -571,7 +584,6 @@
text += " _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid())
- text += " event.Skip();\n}\n\n"
elif element_type == ITEM_NOTEBOOK:
text += """void Program::On%sTabChanged(wxNotebookEvent& event)
@@ -580,7 +592,6 @@
text += " _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid())
- text += " event.Skip();\n}\n\n"
elif element_type == ITEM_TRANSFORM:
text += """void Program::On%sChanging(wxScrollEvent& event)
@@ -590,7 +601,6 @@
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 += " event.Skip();\n}\n\n"
text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n"
text += """void Program::OnPlcOutEvent(wxEvent& event)
@@ -599,7 +609,7 @@
for element in self.Elements:
element_type = GetElementType(element)
@@ -659,7 +669,7 @@
text += " COMPARE_AND_SWAP_VAL(&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n }\n"%texts
- text += """ wxMutexGuiLeave();
@@ -716,7 +726,7 @@
text += """ /* Replace this with determinist signal if called from RT */
if (refresh && !refreshing) {
wxCommandEvent event( EVT_PLC );
+ AddPendingEvent(event);