--- a/Beremiz.py Wed Mar 13 12:34:25 2013 +0900
+++ b/Beremiz.py Wed Mar 13 23:17:30 2013 +0100
@@ -146,6 +146,7 @@
from editors.DataTypeEditor import DataTypeEditor
from util.MiniTextControler import MiniTextControler
from util.ProcessLogger import ProcessLogger
+from controls.LogViewer import LogViewer from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE
from ProjectController import ProjectController, MATIEC_ERROR_MODEL, ITEM_CONFNODE
@@ -287,7 +288,7 @@
CONFNODEMENU_POSITION = 3
self.ConfNodeMenu = wx.Menu(title='')
self.RecentProjectsMenu = wx.Menu(title='')
@@ -385,7 +386,12 @@
self.MainTabs["LogConsole"] = (self.LogConsole, _("Log Console"))
self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
#self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
+ self.LogViewer = LogViewer(self.BottomNoteBook, self) + self.MainTabs["LogViewer"] = (self.LogViewer, _("Log Viewer")) + self.BottomNoteBook.AddPage(*self.MainTabs["LogViewer"]) + self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogViewer), wx.RIGHT) StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
@@ -541,7 +547,7 @@
infos = self.CTR.ShowError(self.Log,
(int(first_line), int(first_column)),
(int(last_line), int(last_column)))
## Function displaying an Error dialog in PLCOpenEditor.
# @return False if closing cancelled.
def CheckSaveBeforeClosing(self, title=_("Close Project")):
--- a/ProjectController.py Wed Mar 13 12:34:25 2013 +0900
+++ b/ProjectController.py Wed Mar 13 23:17:30 2013 +0100
@@ -85,9 +85,9 @@
PLCControler.__init__(self)
self.MandatoryParams = None
- self.SetAppFrame(frame, logger)
+ self.SetAppFrame(frame, logger) self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else ""))
self.ieclib_path = os.path.join(base_folder, "matiec", "lib")
@@ -113,7 +113,6 @@
self.previous_plcstate = None
- self.previous_log_count = [None]*LogLevelsCount
# copy ConfNodeMethods so that it can be later customized
self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
@@ -137,6 +136,8 @@
+ frame.LogViewer.SetLogSource(self._connector) # Timer to pull PLC status
ID_STATUSTIMER = wx.NewId()
self.StatusTimer = wx.Timer(self.AppFrame, ID_STATUSTIMER)
@@ -281,7 +282,7 @@
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 _("Chosen folder doesn't contain a program. It's not a valid project!")
@@ -1077,36 +1078,10 @@
self.CompareLocalAndRemotePLC()
def UpdatePLCLog(self, log_count):
- for level, count, prev in zip(xrange(LogLevelsCount), log_count,self.previous_log_count):
- if count is not None and prev != count:
- # XXX replace dump to console with dedicated log panel.
- dump_end = max( # request message sent after the last one we already got
- prev - 1 if prev is not None else -1,
- count - 100) # 100 is purely arbitrary number
- # dedicated panel should only ask for a small range,
- # depending on how user navigate in the panel
- # and only ask for last one in follow mode
- for msgidx in xrange(count-1, dump_end,-1):
- answer = self._connector.GetLogMessage(level, msgidx)
- if answer is not None :
- msg, tick, tv_sec, tv_nsec = answer
- str(datetime.fromtimestamp(tv_sec)),
- self.previous_log_count[level] = count
- self.logger.write("\n".join(zip(*to_console)[1]+('',)))
+ if self.AppFrame is not None: + self.AppFrame.LogViewer.SetLogCounters(log_count) def UpdateMethodsFromPLCStatus(self):
if self._connector is not None:
@@ -1115,7 +1090,7 @@
status, log_count = PLCstatus
self.UpdatePLCLog(log_count)
+ self._SetConnector(None) if(self.previous_plcstate != status):
@@ -1303,6 +1278,7 @@
+ #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] if plc_status == "Started":
self.IECdebug_lock.acquire()
if len(debug_vars) == len(self.TracedIECPath):
@@ -1341,7 +1317,6 @@
def _connect_debug(self):
self.previous_plcstate = None
- self.previous_log_count = [None]*LogLevelsCount
self.AppFrame.ResetGraphicViewers()
self.RegisterDebugVarToConnector()
@@ -1373,6 +1348,11 @@
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
+ def _SetConnector(self, connector): + self._connector = connector + if self.AppFrame is not None: + self.AppFrame.LogViewer.SetLogSource(connector) # don't accept re-connetion if already connected
if self._connector is not None:
@@ -1417,7 +1397,7 @@
- self._connector = connectors.ConnectorFactory(uri, self)
+ self._SetConnector(connectors.ConnectorFactory(uri, self)) self.logger.write_error(_("Exception while connecting %s!\n")%uri)
self.logger.write_error(traceback.format_exc())
@@ -1477,7 +1457,7 @@
+ self._SetConnector(None) wx.CallAfter(self.UpdateMethodsFromPLCStatus)
@@ -1522,8 +1502,6 @@
self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n"))
- self.previous_log_count = [None]*LogLevelsCount
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
--- a/controls/__init__.py Wed Mar 13 12:34:25 2013 +0900
+++ b/controls/__init__.py Wed Mar 13 23:17:30 2013 +0100
@@ -38,3 +38,4 @@
from SearchResultPanel import SearchResultPanel
from TextCtrlAutoComplete import TextCtrlAutoComplete
from FolderTree import FolderTree
+from LogViewer import LogViewer --- a/images/icons.svg Wed Mar 13 12:34:25 2013 +0900
+++ b/images/icons.svg Wed Mar 13 23:17:30 2013 +0100
@@ -16,7 +16,7 @@
inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="icons.svg.2013_02_08_17_20_04.0.svg"
+ sodipodi:docname="icons.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape">
@@ -26,7 +26,7 @@
<dc:format>image/svg+xml</dc:format>
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
@@ -44,9 +44,9 @@
- inkscape:cx="590.30324"
- inkscape:cy="563.15477"
- inkscape:window-x="1920"
+ inkscape:cx="301.65135" + inkscape:cy="426.18259" inkscape:current-layer="svg2"
@@ -93515,4 +93515,132 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccccccccccc" />
+ style="font-size:20px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + x="170.02246">Log levels icons</tspan></text> + sodipodi:linespacing="125%" + 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;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + sodipodi:role="line">%% CRITICAL WARNING INFO DEBUG %%</tspan></text> + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + sodipodi:cy="379.61218" + d="m 426.5,379.61218 a 6.25,6.25 0 1 1 -12.5,0 6.25,6.25 0 1 1 12.5,0 z" + transform="matrix(1.8061017,0,0,1.8061017,-338.01425,-305.25604)" /> + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 417.26562,373.92467 -2.78125,2.875 3.65625,3.5625 -3.65625,3.5625 2.78125,2.875 3.71875,-3.65625 3.75,3.65625 2.78125,-2.875 -3.65625,-3.5625 3.65625,-3.5625 -2.78125,-2.875 -3.75,3.65625 -3.71875,-3.65625 z" + inkscape:connector-curvature="0" /> + style="color:#000000;fill:#ffcc00;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + sodipodi:cy="371.94867" + sodipodi:r1="12.432317" + sodipodi:r2="6.3169394" + sodipodi:arg1="0.52090978" + sodipodi:arg2="1.568032" + inkscape:flatsided="false" + inkscape:randomized="0" + d="m 496.21218,378.13585 -10.76592,0.12973 -10.76741,-0.0718 5.27061,-9.38843 5.44591,-9.28893 5.49531,9.25869 z" + inkscape:transform-center-x="-0.016715197" + inkscape:transform-center-y="-2.9692899" + transform="translate(-0.44552723,10.971182)" /> + style="font-size:18.60616684px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + sodipodi:linespacing="125%" + transform="scale(1.191303,0.839417)"><tspan + y="461.09991">!</tspan></text> + style="color:#000000;fill:#0000ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + sodipodi:cy="379.61218" + d="m 426.5,379.61218 a 6.25,6.25 0 1 1 -12.5,0 6.25,6.25 0 1 1 12.5,0 z" + transform="matrix(1.8061017,0,0,1.8061017,-222.01425,-306.25604)" /> + style="font-size:23.34662056px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans" + sodipodi:linespacing="125%" + transform="scale(1.2919212,0.77404101)"><tspan + y="498.97501">i</tspan></text> + style="color:#000000;fill:#008000;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 569.81323,379.69702 6.40816,0 2.17016,-3.75883 3.95368,6.84797 2.08109,-3.60455 5.76043,0" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" />