Started implementing the call trace functionality.

Thu, 01 Nov 2012 15:31:06 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 01 Nov 2012 15:31:06 +0100
changeset 2170
f4e0f6133ace
parent 2169
a890aab08ae4
child 2171
c7dd548d67d8

Started implementing the call trace functionality.

DebugClients/Python3/DebugBase.py file | annotate | diff | comparison | revisions
DebugClients/Python3/DebugClientBase.py file | annotate | diff | comparison | revisions
DebugClients/Python3/DebugProtocol.py file | annotate | diff | comparison | revisions
Debugger/CallTraceViewer.py file | annotate | diff | comparison | revisions
Debugger/CallTraceViewer.ui file | annotate | diff | comparison | revisions
Debugger/DebugProtocol.py file | annotate | diff | comparison | revisions
Debugger/DebugServer.py file | annotate | diff | comparison | revisions
Debugger/DebugUI.py file | annotate | diff | comparison | revisions
Debugger/DebugViewer.py file | annotate | diff | comparison | revisions
Debugger/DebuggerInterfacePython3.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
eric5.e4p file | annotate | diff | comparison | revisions
icons/default/callReturn.png file | annotate | diff | comparison | revisions
icons/default/callTrace.png file | annotate | diff | comparison | revisions
icons/default/callTraceStart.png file | annotate | diff | comparison | revisions
icons/default/callTraceStop.png file | annotate | diff | comparison | revisions
icons/default/resizeColumns.png file | annotate | diff | comparison | revisions
--- a/DebugClients/Python3/DebugBase.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/DebugClients/Python3/DebugBase.py	Thu Nov 01 15:31:06 2012 +0100
@@ -14,7 +14,7 @@
 import inspect
 
 from DebugProtocol import ResponseClearWatch, ResponseClearBreak, ResponseLine, \
-    ResponseSyntax, ResponseException
+    ResponseSyntax, ResponseException, CallTrace
 
 gRecursionLimit = 64
 
@@ -153,13 +153,39 @@
         if event == 'return':
             self.cFrame = frame.f_back
             self.__recursionDepth -= 1
+            self.__sendCallTrace(event, frame, self.cFrame)
         elif event == 'call':
+            self.__sendCallTrace(event, self.cFrame, frame)
             self.cFrame = frame
             self.__recursionDepth += 1
             if self.__recursionDepth > gRecursionLimit:
                 raise RuntimeError('maximum recursion depth exceeded\n'
                     '(offending frame is two down the stack)')
     
+    def __sendCallTrace(self, event, fromFrame, toFrame):
+        """
+        Private method to send a call/return trace.
+        
+        @param event trace event (string)
+        @param fromFrame originating frame (frame)
+        @param toFrame destination frame (frame)
+        """
+        if self._dbgClient.callTraceEnabled:
+            if not self.__skip_it(fromFrame) and not self.__skip_it(toFrame):
+                if event in ["call", "return"]:
+                    fr = fromFrame
+                    fromStr = "{0}:{1}:{2}".format(
+                        self._dbgClient.absPath(self.fix_frame_filename(fr)),
+                        fr.f_lineno,
+                        fr.f_code.co_name)
+                    fr = toFrame
+                    toStr = "{0}:{1}:{2}".format(
+                        self._dbgClient.absPath(self.fix_frame_filename(fr)),
+                        fr.f_lineno,
+                        fr.f_code.co_name)
+                    self._dbgClient.write("{0}{1}@@{2}@@{3}\n".format(
+                        CallTrace, event[0], fromStr, toStr))
+    
     def trace_dispatch(self, frame, event, arg):
         """
         Reimplemented from bdb.py to do some special things.
@@ -718,6 +744,9 @@
         @param frame the frame object
         @return flag indicating whether the debugger should skip this frame
         """
+        if frame is None:
+            return True
+        
         fn = self.fix_frame_filename(frame)
 
         # Eliminate things like <string> and <stdin>.
--- a/DebugClients/Python3/DebugClientBase.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/DebugClients/Python3/DebugClientBase.py	Thu Nov 01 15:31:06 2012 +0100
@@ -199,6 +199,9 @@
         self.errorstream = None
         self.pollingDisabled = False
         
+        self.callTraceEnabled = False
+        self.__newCallTraceEnabled = False
+        
         self.skipdirs = sys.path[:]
         
         self.variant = 'You should not see this'
@@ -442,6 +445,17 @@
                 self.pendingResponse = DebugProtocol.ResponseOK
                 return
 
+            if cmd == DebugProtocol.RequestCallTrace:
+                if arg.strip().lower() == "on":
+                    callTraceEnabled = True
+                else:
+                    callTraceEnabled = False
+                if self.debugging:
+                    self.callTraceEnabled = callTraceEnabled
+                else:
+                    self.__newCallTraceEnabled = callTraceEnabled   # remember for later
+                return
+            
             if cmd == DebugProtocol.RequestEnv:
                 env = eval(arg.replace("u'", "'"))
                 for key, value in env.items():
@@ -494,6 +508,7 @@
                 sys.modules['__main__'] = self.debugMod
                 code = self.__compileFileSource(self.running)
                 if code:
+                    self.callTraceEnabled = self.__newCallTraceEnabled
                     res = self.mainThread.run(code, self.debugMod.__dict__)
                     self.progTerminated(res)
                 return
--- a/DebugClients/Python3/DebugProtocol.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/DebugClients/Python3/DebugProtocol.py	Thu Nov 01 15:31:06 2012 +0100
@@ -77,4 +77,7 @@
 
 PassiveStartup = '>PassiveStartup<'
 
+RequestCallTrace = '>CallTrace<'
+CallTrace = '>CallTrace<'
+
 EOT = '>EOT<\n'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debugger/CallTraceViewer.py	Thu Nov 01 15:31:06 2012 +0100
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Call Trace viewer widget.
+"""
+
+from PyQt4.QtCore import pyqtSlot, pyqtSignal
+from PyQt4.QtGui import QWidget,  QTreeWidgetItem
+
+from .Ui_CallTraceViewer import Ui_CallTraceViewer
+
+import UI.PixmapCache
+import Preferences
+
+
+class CallTraceViewer(QWidget, Ui_CallTraceViewer):
+    """
+    Class implementing the Call Trace viewer widget.
+    
+    @signal sourceFile(str, int) emitted to show the source of a call/return point
+    """
+    sourceFile = pyqtSignal(str, int)
+    
+    def __init__(self, debugServer, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+        
+        self.__dbs = debugServer
+        
+        self.startTraceButton.setIcon(UI.PixmapCache.getIcon("callTraceStart.png"))
+        self.stopTraceButton.setIcon(UI.PixmapCache.getIcon("callTraceStop.png"))
+        self.resizeButton.setIcon(UI.PixmapCache.getIcon("resizeColumns.png"))
+        self.clearButton.setIcon(UI.PixmapCache.getIcon("editDelete.png"))
+        self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSave.png"))
+        
+        self.__headerItem = QTreeWidgetItem(["", self.trUtf8("From"), self.trUtf8("To")])
+        self.__headerItem.setIcon(0, UI.PixmapCache.getIcon("callReturn.png"))
+        self.callTrace.setHeaderItem(self.__headerItem)
+        
+        self.__callStack = []
+        
+        self.__entryFormat = "{0}:{1} ({2})"
+        
+        self.__callTraceEnabled = Preferences.toBool(
+            Preferences.Prefs.settings.value("CallTrace/Enabled", False))
+        
+        if self.__callTraceEnabled:
+            self.stopTraceButton.setEnabled(False)
+        else:
+            self.startTraceButton.setEnabled(False)
+        
+        self.__dbs.callTraceInfo.connect(self.__addCallTraceInfo)
+    
+    @pyqtSlot()
+    def on_startTraceButton_clicked(self):
+        """
+        Private slot to start call tracing.
+        """
+        self.__dbs.setCallTraceEnabled(True)
+        self.stopTraceButton.setEnabled(True)
+        self.startTraceButton.setEnabled(False)
+        Preferences.Prefs.settings.setValue("CallTrace/Enabled", True)
+    
+    @pyqtSlot()
+    def on_stopTraceButton_clicked(self):
+        """
+        Private slot to start call tracing.
+        """
+        self.__dbs.setCallTraceEnabled(False)
+        self.stopTraceButton.setEnabled(False)
+        self.startTraceButton.setEnabled(True)
+        Preferences.Prefs.settings.setValue("CallTrace/Enabled", False)
+    
+    @pyqtSlot()
+    def on_resizeButton_clicked(self):
+        """
+        Private slot to resize the columns of the call trace to their contents.
+        """
+        for column in range(self.callTrace.columnCount()):
+            self.callTrace.resizeColumnToContents(column)
+    
+    @pyqtSlot()
+    def on_clearButton_clicked(self):
+        """
+        Private slot to clear the call trace.
+        """
+        self.clear()
+    
+    @pyqtSlot()
+    def on_saveButton_clicked(self):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    @pyqtSlot(QTreeWidgetItem, int)
+    def on_callTrace_itemDoubleClicked(self, item, column):
+        """
+        Slot documentation goes here.
+        """
+        # TODO: not implemented yet
+        raise NotImplementedError
+    
+    def clear(self):
+        """
+        Public slot to clear the call trace info.
+        """
+        self.callTrace.clear()
+        self.__callStack = []
+    
+    def __addCallTraceInfo(self, isCall, fromFile, fromLine, fromFunction,
+                           toFile, toLine, toFunction):
+        """
+        Private method to add an entry to the call trace viewer.
+        
+        @param isCall flag indicating a 'call' (boolean)
+        @param fromFile name of the originating file (string)
+        @param fromLine line number in the originating file (string)
+        @param fromFunction name of the originating function (string)
+        @param toFile name of the target file (string)
+        @param toLine line number in the target file (string)
+        @param toFunction name of the target function (string)
+        """
+        if isCall:
+            icon = UI.PixmapCache.getIcon("forward.png")
+        else:
+            icon = UI.PixmapCache.getIcon("back.png")
+        parentItem = self.__callStack[-1] if self.__callStack else self.callTrace
+        
+        itm = QTreeWidgetItem(parentItem, ["",
+            self.__entryFormat.format(fromFile, fromLine, fromFunction),
+            self.__entryFormat.format(toFile, toLine, toFunction)])
+        itm.setIcon(0, icon)
+        itm.setExpanded(True)
+        
+        if isCall:
+            self.__callStack.append(itm)
+        else:
+            self.__callStack.pop(-1)
+    
+    def isCallTraceEnabled(self):
+        """
+        Public method to get the state of the call trace function.
+        
+        @return flag indicating the state of the call trace function (boolean)
+        """
+        return self.__callTraceEnabled
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debugger/CallTraceViewer.ui	Thu Nov 01 15:31:06 2012 +0100
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CallTraceViewer</class>
+ <widget class="QWidget" name="CallTraceViewer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>528</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Call Trace</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QToolButton" name="startTraceButton">
+       <property name="toolTip">
+        <string>Press to start tracing calls and returns</string>
+       </property>
+       <property name="text">
+        <string notr="true">Start</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="stopTraceButton">
+       <property name="toolTip">
+        <string>Press to stop tracing calls and returns</string>
+       </property>
+       <property name="text">
+        <string notr="true">Stop</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QToolButton" name="resizeButton">
+       <property name="toolTip">
+        <string>Press to resize the columns to their contents</string>
+       </property>
+       <property name="text">
+        <string notr="true">Resize</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="clearButton">
+       <property name="toolTip">
+        <string>Press to clear the call trace</string>
+       </property>
+       <property name="text">
+        <string notr="true">Clear</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="saveButton">
+       <property name="toolTip">
+        <string>Press to save the call trace as a text file</string>
+       </property>
+       <property name="text">
+        <string notr="true">Save</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QTreeWidget" name="callTrace">
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string> </string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>From</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>To</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>startTraceButton</tabstop>
+  <tabstop>stopTraceButton</tabstop>
+  <tabstop>resizeButton</tabstop>
+  <tabstop>clearButton</tabstop>
+  <tabstop>saveButton</tabstop>
+  <tabstop>callTrace</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- a/Debugger/DebugProtocol.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/Debugger/DebugProtocol.py	Thu Nov 01 15:31:06 2012 +0100
@@ -74,4 +74,7 @@
 
 PassiveStartup = '>PassiveStartup<'
 
+RequestCallTrace = '>CallTrace<'
+CallTrace = '>CallTrace<'
+
 EOT = '>EOT<\n'
--- a/Debugger/DebugServer.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/Debugger/DebugServer.py	Thu Nov 01 15:31:06 2012 +0100
@@ -95,6 +95,8 @@
             an expected test failure
     @signal utTestSucceededUnexpected(testname, id) emitted after the client reported
             an unexpected test success
+    @signal callTraceInfo(isCall, fromFile, fromLine, fromFunction, toFile, toLine,
+            toFunction) emitted after the client reported the call trace data
     """
     clientClearBreak = pyqtSignal(str, int)
     clientClearWatch = pyqtSignal(str)
@@ -129,6 +131,7 @@
     utTestSucceededUnexpected = pyqtSignal(str, str)
     utFinished = pyqtSignal()
     passiveDebugStarted = pyqtSignal(str, bool)
+    callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str)
     
     def __init__(self):
         """
@@ -665,7 +668,7 @@
     def remoteLoad(self, fn, argv, wd, env, autoClearShell=True,
                    tracePython=False, autoContinue=True, forProject=False,
                    runInConsole=False, autoFork=False, forkChild=False,
-                   clientType=""):
+                   clientType="", enableCallTrace=False):
         """
         Public method to load a new program to debug.
         
@@ -685,6 +688,8 @@
         @keyparam autoFork flag indicating the automatic fork mode (boolean)
         @keyparam forkChild flag indicating to debug the child after forking (boolean)
         @keyparam clientType client type to be used (string)
+        @keyparam enableCallTrace flag indicating to enable the call trace
+            function (boolean)
         """
         self.__autoClearShell = autoClearShell
         self.__autoContinue = autoContinue
@@ -699,6 +704,7 @@
             self.__setClientType('Python3')    # assume it is a Python3 file
         self.startClient(False, forProject=forProject, runInConsole=runInConsole)
         
+        self.setCallTraceEnabled(enableCallTrace)
         self.remoteEnvironment(env)
         
         self.debuggerInterface.remoteLoad(fn, argv, wd, tracePython, autoContinue,
@@ -977,6 +983,18 @@
         """
         self.debuggerInterface.remoteClientSetFilter(scope, filter)
         
+    def setCallTraceEnabled(self, on):
+        """
+        Public method to set the call trace state.
+        
+        @param on flag indicating to enable the call trace function (boolean)
+        """
+        # TODO: remove the try/except once all interface have been adjusted
+        try:
+            self.debuggerInterface.setCallTraceEnabled(on)
+        except AttributeError:
+            pass
+        
     def remoteEval(self, arg):
         """
         Public method to evaluate arg in the current context of the debugged program.
@@ -1238,6 +1256,22 @@
         """
         self.clientCompletionList.emit(completionList, text)
         
+    def signalClientCallTrace(self, isCall, fromFile, fromLine, fromFunction,
+                              toFile, toLine, toFunction):
+        """
+        Public method to process the client call trace data.
+        
+        @param isCall flag indicating a 'call' (boolean)
+        @param fromFile name of the originating file (string)
+        @param fromLine line number in the originating file (string)
+        @param fromFunction name of the originating function (string)
+        @param toFile name of the target file (string)
+        @param toLine line number in the target file (string)
+        @param toFunction name of the target function (string)
+        """
+        self.callTraceInfo.emit(isCall, fromFile, fromLine, fromFunction,
+            toFile, toLine, toFunction)
+        
     def clientUtPrepared(self, result, exceptionType, exceptionValue):
         """
         Public method to process the client unittest prepared info.
--- a/Debugger/DebugUI.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/Debugger/DebugUI.py	Thu Nov 01 15:31:06 2012 +0100
@@ -1776,12 +1776,18 @@
                     fn = os.path.join(getConfig('ericDir'), "eric5.py")
                     tracePython = True  # override flag because it must be true
                 
+                # Ask the client to send call trace info
+                enableCallTrace = self.debugViewer.isCallTraceEnabled()
+                if enableCallTrace:
+                    self.debugViewer.clearCallTrace()
+                
                 # Ask the client to open the new program.
                 self.debugServer.remoteLoad(fn, argv, wd, env,
                     autoClearShell=self.autoClearShell, tracePython=tracePython,
                     autoContinue=autoContinue, forProject=debugProject,
                     runInConsole=console, autoFork=forkAutomatically,
-                    forkChild=forkIntoChild, clientType=self.clientType)
+                    forkChild=forkIntoChild, clientType=self.clientType,
+                    enableCallTrace=enableCallTrace)
                 
                 # Signal that we have started a debugging session
                 self.debuggingStarted.emit(fn)
@@ -1827,12 +1833,18 @@
                 fn = os.path.join(getConfig('ericDir'), "eric5.py")
             
             if self.lastStartAction in [1, 2]:
+                # Ask the client to send call trace info
+                enableCallTrace = self.debugViewer.isCallTraceEnabled()
+                if enableCallTrace:
+                    self.debugViewer.clearCallTrace()
+                
                 # Ask the client to debug the new program.
                 self.debugServer.remoteLoad(fn, argv, wd, env,
                     autoClearShell=self.autoClearShell, tracePython=self.tracePython,
                     autoContinue=self.autoContinue, forProject=forProject,
                     runInConsole=self.runInConsole, autoFork=self.forkAutomatically,
-                    forkChild=self.forkIntoChild, clientType=self.clientType)
+                    forkChild=self.forkIntoChild, clientType=self.clientType,
+                    enableCallTrace=enableCallTrace)
                 
                 # Signal that we have started a debugging session
                 self.debuggingStarted.emit(fn)
--- a/Debugger/DebugViewer.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/Debugger/DebugViewer.py	Thu Nov 01 15:31:06 2012 +0100
@@ -10,6 +10,7 @@
 <ul>
   <li>variables viewer for global variables</li>
   <li>variables viewer for local variables</li>
+  <li>call trace viewer</li>
   <li>viewer for breakpoints</li>
   <li>viewer for watch expressions</li>
   <li>viewer for exceptions</li>
@@ -30,6 +31,7 @@
 from .ExceptionLogger import ExceptionLogger
 from .BreakPointViewer import BreakPointViewer
 from .WatchPointViewer import WatchPointViewer
+from .CallTraceViewer import CallTraceViewer
 
 import UI.PixmapCache
 import Preferences
@@ -183,6 +185,12 @@
         self.setLocalsFilterButton.clicked[()].connect(self.__setLocalsFilter)
         self.localsFilterEdit.returnPressed.connect(self.__setLocalsFilter)
         
+        # add the call trace viewer
+        self.callTraceViewer = CallTraceViewer(self.debugServer)
+        index = self.__tabWidget.addTab(self.callTraceViewer,
+            UI.PixmapCache.getIcon("callTrace.png"), "")
+        self.__tabWidget.setTabToolTip(index, self.callTraceViewer.windowTitle())
+        
         # add the breakpoint viewer
         self.breakpointViewer = BreakPointViewer()
         self.breakpointViewer.setModel(self.debugServer.getBreakPointModel())
@@ -278,7 +286,21 @@
         if self.embeddedShell:
             self.saveCurrentPage()
             self.__tabWidget.setCurrentWidget(self.shellAssembly)
-            
+        
+    def isCallTraceEnabled(self):
+        """
+        Public method to get the state of the call trace function.
+        
+        @return flag indicating the state of the call trace function (boolean)
+        """
+        return self.callTraceViewer.isCallTraceEnabled()
+        
+    def clearCallTrace(self):
+        """
+        Public method to clear the recorded call trace.
+        """
+        self.callTraceViewer.clear()
+        
     def showVariables(self, vlist, globals):
         """
         Public method to show the variables in the respective window.
--- a/Debugger/DebuggerInterfacePython3.py	Thu Nov 01 10:15:08 2012 +0100
+++ b/Debugger/DebuggerInterfacePython3.py	Thu Nov 01 15:31:06 2012 +0100
@@ -666,6 +666,18 @@
         self.__sendCommand('{0}{1:d}, "{2}"\n'.format(
             DebugProtocol.RequestSetFilter, scope, filter))
     
+    def setCallTraceEnabled(self, on):
+        """
+        Public method to set the call trace state.
+        
+        @param on flag indicating to enable the call trace function (boolean)
+        """
+        if on:
+            cmd = "on"
+        else:
+            cmd = "off"
+        self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestCallTrace, cmd))
+    
     def remoteEval(self, arg):
         """
         Public method to evaluate arg in the current context of the debugged program.
@@ -800,6 +812,16 @@
                         self.debugServer.signalClientStack(stack)
                     continue
                 
+                if resp == DebugProtocol.CallTrace:
+                    event, fromStr, toStr = line[eoc:-1].split("@@")
+                    isCall = event.lower() == "c"
+                    fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2)
+                    toFile, toLineno, toFunc = toStr.rsplit(":", 2)
+                    self.debugServer.signalClientCallTrace(isCall,
+                        fromFile, fromLineno, fromFunc,
+                        toFile, toLineno, toFunc)
+                    continue
+                
                 if resp == DebugProtocol.ResponseThreadList:
                     currentId, threadList = eval(line[eoc:-1])
                     self.debugServer.signalClientThreadList(currentId, threadList)
--- a/changelog	Thu Nov 01 10:15:08 2012 +0100
+++ b/changelog	Thu Nov 01 15:31:06 2012 +0100
@@ -1,5 +1,8 @@
 Change Log
 ----------
+Version 5.3-snapshot-2012mmdd:
+- bug fixes
+
 Version 5.3-snapshot-20121101:
 - bug fixes
 - General
--- a/eric5.e4p	Thu Nov 01 10:15:08 2012 +0100
+++ b/eric5.e4p	Thu Nov 01 15:31:06 2012 +0100
@@ -1049,6 +1049,7 @@
     <Source>Toolbox/Startup.py</Source>
     <Source>Preferences/ConfigurationPages/HelpInterfacePage.py</Source>
     <Source>E5Gui/E5MainWindow.py</Source>
+    <Source>Debugger/CallTraceViewer.py</Source>
   </Sources>
   <Forms>
     <Form>PyUnit/UnittestDialog.ui</Form>
@@ -1349,6 +1350,7 @@
     <Form>Helpviewer/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationScriptInfoDialog.ui</Form>
     <Form>Helpviewer/AdBlock/AdBlockExceptionsDialog.ui</Form>
     <Form>Preferences/ConfigurationPages/HelpInterfacePage.ui</Form>
+    <Form>Debugger/CallTraceViewer.ui</Form>
   </Forms>
   <Translations>
     <Translation>i18n/eric5_cs.qm</Translation>
Binary file icons/default/callReturn.png has changed
Binary file icons/default/callTrace.png has changed
Binary file icons/default/callTraceStart.png has changed
Binary file icons/default/callTraceStop.png has changed
Binary file icons/default/resizeColumns.png has changed

eric ide

mercurial