def __init__(self, breakpoint, connector, do, nr): Breakpoint.__init__(self, breakpoint, connector) self.name = "TP #%s" % nr self.variableList = VariableList(PlainVariableFactory, do) self.wave = [] self.tooltip = "Tracepoint"
class Tracepoint(Breakpoint): """This class is used as a tracepoint in tracepointmodel. Basically Tracpoints are Breakpoint but they are extended with tracedVariables (list of Variable-Value-Pairs). Every Tracepoint contains some variables that are traced. Tracepoints are breakpoints and stop program then get information of asked variables and then continue program """ def __init__(self, breakpoint, connector, do, nr): Breakpoint.__init__(self, breakpoint, connector) self.name = "TP #%s" % nr self.variableList = VariableList(PlainVariableFactory, do) self.wave = [] self.tooltip = "Tracepoint" icon = property(lambda self: Icons.tp if self.enabled else Icons.bp_dis) tracedVariables = property(lambda self: [v.exp for v in self.variableList]) def addVar(self, variableToTrace): """ add a var to trace its value @param variableToTrace: variable name of the variable that should be traced""" vw = self.variableList.addVarByName(variableToTrace) newValueList = ValueList(variableToTrace, vw.type) self.wave.append(newValueList) # FIXME: emit dataChanged to make sure the views are updated def recordData(self): """tracepoint occurred: get values of all traced variables then continue debugging """ for varList in self.wave: for v in self.variableList.items(): if v.uniqueName == varList.name: varList.addValue(v.type, v.value)
def __init__(self, distributedObjects): QObject.__init__(self) self.distributedObjects = distributedObjects self.signalProxy = distributedObjects.signalProxy self._view = DataGraphView(None) self.variableList = VariableList(DataGraphVariableFactory, self.distributedObjects) # register with session manager to save Graph self.signalProxy.registerWithSessionManager.emit(self, "Graph") # connect signals self.signalProxy.cleanupModels.connect(self.clearDataGraph) self.distributedObjects.mainwindow.insertDockWidget(self._view, "Graph", Qt.LeftDockWidgetArea, True, QIcon(":/icons/images/datagraph.png"))
class Tracepoint(ExtendedBreakpoint): """This class is used as a tracepoint in tracepointmodel. Basically Tracpoints are Breakpoint but they are extended with tracedVariables (list of Variable-Value-Pairs). Every Tracepoint contains some variables that are traced. Tracepoints are breakpoints and stop program then get information of asked variables and then continue program """ def __init__(self, distObjects, sensitiveVariable, nr): """Init Tracepoint @param sensitiveVariable: is the sensitive variable. Use extendedBreakpoints for this. If extBP occures then the variables and their values will be stored. @param nr: needed to initialize ExtendedBreakpoint class """ ExtendedBreakpoint.__init__(self, sensitiveVariable, nr, distObjects.gdb_connector) """here are the traced variables stored with their values""" self.gdb_connector = distObjects.gdb_connector self.distObjects = distObjects self.vwFactory = VarWrapperFactory() self.variableList = VariableList(self.vwFactory, distObjects) self.counter = 0 self.hitted = False self.stop = False self.distObjects.signalProxy.dataForTracepointsReady.connect(self.readDataFromVarModel) self.wave = [] self.tracedVariables = [] def addVar(self, variableToTrace): """ add a var to trace its value @param variableToTrace: variable name of the variable that should be traced""" vw = self.variableList.addVarByName(variableToTrace) newValueList = ValueList(variableToTrace, vw.type) self.wave.append(newValueList) self.tracedVariables.append(variableToTrace) def tracePointOccurred(self, stop): """ set if stop is needed or not @param stop: (bool), gdb stops after tracing if True, gdb continues after tracing if False """ self.stop = stop self.hitted = True def readDataFromVarModel(self): """tracepoint occurred: get values of all traced variables then continue debugging """ if self.hitted: self.hitted = False self.counter = self.counter + 1 for varList in self.wave: for v in self.variableList.list: if v.uniqueName == varList.name: varList.addValue(v.type, v.value) if not (self.stop): self.stop = True self.gdb_connector.cont()
def initPlugin(self, signalproxy): """Initialise the systemc block diagram plugin""" self.signalproxy = signalproxy self.do = signalproxy.distributedObjects # systemc stuff and and pointer type strings needed for casting in gdb # because systemc objects can be systemc modules, systemc ports, etc. self.ctx = None self.ctx_pointer = None self.ctx_func = "sc_get_curr_simcontext()" self.ctx_found = False self.ctx_type = "(sc_core::sc_simcontext*)" self.port_type = "(sc_core::sc_port_base*)" self.module_type = "(sc_core::sc_module*)" self.object_type = "(sc_core::sc_object*)" self.prim_channel_type = "(sc_core::sc_prim_channel*)" # dict with a string that represents the pointer as key and # a nested dict with parent, children, etc as key-values # dst_dict[ptr] = {"wrapper": vw, # "name": None, # "parent_ptr": None, # "children": {}} self.sysc_modules = {} self.sysc_objects = {} self.sysc_ports = {} self.sysc_prim_channels = {} # because of how we built the interface for the tracepoints on the # datagraph we first need to create an file obj. We choose StringIO # because it uses a string as buffer and does not acces the filesystem self._file_obj = StringIO() self.image = SVGImage("SystemC Block Diagram", self._file_obj) self.image_wrapper = SVGDataGraphVW(self.image, self.do) self.signalproxy.inferiorStoppedNormally.connect(self.update) # hook Datagraph variable wrapper into the datagraph controller # after self.action.commit is called the image will be displayed at the # datagraph self.action = self.do.actions.\ getAddSVGToDatagraphAction(self.image_wrapper, self.do. datagraphController.addVar) # pydot graph visualization library self.block_diagram = Dot(graph_type='digraph') self.block_diagram.set_graph_defaults(compound='true', splines='ortho', rankdir='LR') self.block_diagram.set_node_defaults(shape='box') # Needed for creating the right variables and variable wrappers from # the systemc pointers self.vwFactory = VarWrapperFactory() self.variableList = VariableList(self.vwFactory, self.do)
class TreeItemController(QObject): """ the Controller for the TreeView """ def __init__(self, distributedObjects, name, view, model, addDockWidget): """ Constructor <br> Create a TreeView, a TreeVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::AddTree(QString), SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) self.distributedObjects = distributedObjects self.name = name self.vwFactory = TreeVWFactory() self.model = model(self, self.distributedObjects) self.view = view self.view.controller = self self.view.setModel(self.model) self.variableList = VariableList(self.vwFactory, self.distributedObjects) self.distributedObjects.signalProxy.cleanupModels.connect(self.clear) if addDockWidget: self.distributedObjects.mainwindow.insertDockWidget(self.view, name, Qt.BottomDockWidgetArea, True) def clear(self): """ clears the TreeView and the VariableList <br> this function is connected to the signal SignalProxy::cleanupModels() """ # clear lists self.variableList.clear() self.model.clear() def add(self, vw): vw.setParent(self.model.root) # add children self.model.root.addChild(vw) self.model.addVar(vw)
class LocalsController(QObject): def __init__(self, distributed_objects): QObject.__init__(self) self.distributedObjects = distributed_objects self.vwFactory = LocalsVWFactory() self.localsModel = LocalsModel(self, self.distributedObjects) self.localsView = LocalsView() self.localsView.treeView.setModel(self.localsModel) self.localsVariableList = VariableList(self.vwFactory, self.distributedObjects) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('inferiorHasStopped(PyQt_PyObject)'), self.getLocals) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('cleanupModels()'), self.clearLocals) def insertDockWidgets(self): self.localsDock = QDockWidget("Locals") self.localsDock.setObjectName("LocalsView") self.localsDock.setWidget(self.localsView) self.distributedObjects.signal_proxy.addDockWidget(Qt.BottomDockWidgetArea, self.localsDock, True) def clearLocals(self): # clear lists del self.localsVariableList.list[:] self.localsModel.clear() def getLocals(self): self.clearLocals() self.localsVariableList.addLocals() for vw in self.localsVariableList.list: vw.setParent(self.localsModel.root) # add variable to root children self.localsModel.root.addChild(vw) self.localsModel.addVar(vw)
def __init__(self, distributed_objects): QObject.__init__(self) self.distributedObjects = distributed_objects self.vwFactory = LocalsVWFactory() self.localsModel = LocalsModel(self, self.distributedObjects) self.localsView = LocalsView() self.localsView.treeView.setModel(self.localsModel) self.localsVariableList = VariableList(self.vwFactory, self.distributedObjects) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('inferiorHasStopped(PyQt_PyObject)'), self.getLocals) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('cleanupModels()'), self.clearLocals)
def __init__(self, distributedObjects): """ Constructor <br> Creates a DataGraphView, a DataGraphVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) # controllers ## @var distributedObjects # distributedobjects.DistributedObjects, the DistributedObjects-Instance self.distributedObjects = distributedObjects ## @var signalProxy # signalproxy.SignalProxy, the SignalProxy-Instance from the DistributedObjects self.signalProxy = distributedObjects.signalProxy ## @var debugController # debugcontroller.DebugController, the DebugController-Instance from the DistributedObjects self.debugController = distributedObjects.debugController ## @var variablePool # variables.variablepool.VariablePool, the variablePool-Instance from the DistributedObjects self.variablePool = distributedObjects.variablePool # views ## @var data_graph_view # datagraph.datagraphview.DataGraphView, private, self-created DataGraphView <br> # GUI-Element that shows the DataGraphView self.data_graph_view = DataGraphView(None, self) # models ## @var vwFactory # datagraph.datagraphvwfactory.DataGraphVWFactory, private, self-created DataGraphVWFactory self.vwFactory = DataGraphVWFactory(self.distributedObjects) ## @var variableList # variables.variablelist.VariableList, private, self-created VariableList self.variableList = VariableList(self.vwFactory, self.distributedObjects) self.pointerList = [] # register with session manager to save Graph self.signalProxy.emitRegisterWithSessionManager(self, "Graph") # connect signals self.signalProxy.cleanupModels.connect(self.clearDataGraph) self.distributedObjects.mainwindow.insertDockWidget(self.data_graph_view, "Graph", Qt.LeftDockWidgetArea, True)
class VariableController(QObject): _instance = None @classmethod def CreateInstance(cls, watchview): if not cls._instance: cls._instance = cls(watchview) @classmethod def getInstance(cls): if not cls._instance: raise "VariableController has no Instance!" return cls._instance def __init__(self, watchview): QObject.__init__(self) #signalproxy self.signalProxy = SignalProxy.getInstance() QObject.connect(self.signalProxy, SIGNAL('AddWatch(QString)'), self.addWatch) # views self.watchview = watchview # controllers self.debugController = DebugController.getInstance() # factory self.vwFactory = WatchVWFactory() self.variableList = VariableList(self.vwFactory) # models self.variableModel = self.debugController.variableModel; def addWatch(self, watch): var = self.variableList.addVar(watch) QObject.connect(var, SIGNAL('changed()'), self.varChanged) for item in self.variableList: print item.getExp() + " " + item.getValue() def varChanged(self): print "variable changed" def removeSelected(self, row, parent): self.variableModel.removeRow(row, parent);
def __init__(self, distObjects, sensitiveVariable, nr): """Init Tracepoint @param sensitiveVariable: is the sensitive variable. Use extendedBreakpoints for this. If extBP occures then the variables and their values will be stored. @param nr: needed to initialize ExtendedBreakpoint class """ ExtendedBreakpoint.__init__(self, sensitiveVariable, nr, distObjects.gdb_connector) """here are the traced variables stored with their values""" self.gdb_connector = distObjects.gdb_connector self.distObjects = distObjects self.vwFactory = TraceVWFactory() self.variableList = VariableList(self.vwFactory, distObjects) self.counter = 0 self.hitted = False self.stop = False self.connect(self.distObjects.signalProxy, SIGNAL('dataForTracepointsReady()'), self.readDataFromVarModel) self.wave = []
def __init__(self, watchview): QObject.__init__(self) #signalproxy self.signalProxy = SignalProxy.getInstance() QObject.connect(self.signalProxy, SIGNAL('AddWatch(QString)'), self.addWatch) # views self.watchview = watchview # controllers self.debugController = DebugController.getInstance() # factory self.vwFactory = WatchVWFactory() self.variableList = VariableList(self.vwFactory) # models self.variableModel = self.debugController.variableModel;
def __init__(self, distributedObjects): """ Constructor <br> Create a WatchView, a WatchVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::AddWatch(QString), SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) self.distributedObjects = distributedObjects #self.root = RootVarWrapper() self.vwFactory = WatchVWFactory() self.variableModel = VariableModel(self, self.distributedObjects) self.watchView = WatchView(self) self.watchView.treeView.setModel(self.variableModel) self.watchVariableList = VariableList(self.vwFactory, self.distributedObjects) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('AddWatch(QString)'), self.addWatch) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('cleanupModels()'), self.clearVars)
def __init__(self, distributedObjects, name, view, model, addDockWidget): """ Constructor <br> Create a TreeView, a TreeVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::AddTree(QString), SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) self.distributedObjects = distributedObjects self.name = name self.vwFactory = TreeVWFactory() self.model = model(self, self.distributedObjects) self.view = view self.view.controller = self self.view.setModel(self.model) self.variableList = VariableList(self.vwFactory, self.distributedObjects) self.distributedObjects.signalProxy.cleanupModels.connect(self.clear) if addDockWidget: self.distributedObjects.mainwindow.insertDockWidget(self.view, name, Qt.BottomDockWidgetArea, True)
class VariableModel(QAbstractItemModel): def __init__(self, do, parent=None): QAbstractItemModel.__init__(self, parent) self._vars = VariableList(TreeVariableFactory, do) do.signalProxy.cleanupModels.connect(self.clear) do.signalProxy.aboutToUpdateVariables.connect(self.__unmarkAll) def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QModelIndex() parentItem = parent.internalPointer() if parent.isValid() else None if parentItem: childItem = parentItem._child(row) else: childItem = self._vars[row] return self.createIndex(row, column, childItem) def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem._parent if not parentItem: return QModelIndex() return self.createIndex(parentItem._row, 0, parentItem) def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): return len(self._vars) else: return parent.internalPointer()._childCount() def columnCount(self, _): return 3 def data(self, index, role): if not index.isValid(): return None item = index.internalPointer() ret = None if role == Qt.DisplayRole: if index.column() == 0: ret = item.exp elif index.column() == 1: ret = item.type elif index.column() == 2: ret = item.value elif role == Qt.EditRole: if index.column() == 2: ret = item.value elif role == Qt.DecorationRole: if index.column() == 0: if item.access in ['private', 'protected']: iconprefix = item.access + "_" else: iconprefix = "" icon = None if not item.inScope: return QPixmap(":/icons/images/outofscope.png") elif not isinstance(item, StdVariable): icon = QPixmap(":/icons/images/" + iconprefix + "struct.png") else: # leave item icon = QPixmap(":/icons/images/" + iconprefix + "var.png") # overlay for arguments if icon and item.arg: ol = QPixmap(":/icons/images/overlay_arg.png") p = QPainter(icon) p.drawPixmap(ol.rect(), ol) elif icon and item.exp == "Return value": ol = QPixmap(":/icons/images/overlay_ret.png") p = QPainter(icon) p.drawPixmap(ol.rect(), ol) return icon elif role == Qt.BackgroundRole: if not item.inScope: ret = QBrush(Qt.gray) elif index.column() == 2: if item.marked and item.inScope: ret = QBrush(Qt.yellow) return ret def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return ["Expression", "Type", "Value"][section] return None def addVar(self, name): self.beginInsertRows(QModelIndex(), len(self._vars), len(self._vars)) var = self._vars.addVarByName(name) var.setNodeData(len(self._vars) - 1, None, self) self.endInsertRows() return var def hasChildren(self, parent): if not parent.isValid(): return True return parent.internalPointer()._hasChildren() def emitDataChanged(self, tl, br): self.dataChanged.emit(tl, br) def mimeTypes(self): return QStringList([variable.MIME_TYPE]) def mimeData(self, indexes): if len(indexes) == 1: item = indexes[0].internalPointer() d = QMimeData() d.setData(variable.MIME_TYPE, item.uniqueName) return d else: return None def flags(self, index): if not index.isValid(): return Qt.ItemIsDropEnabled item = index.internalPointer() if not item.inScope: return Qt.ItemIsEnabled | Qt.ItemIsSelectable ret = Qt.ItemIsEnabled | Qt.ItemIsSelectable if index.column() == 2: ret |= Qt.ItemIsEditable elif index.column() == 0: ret |= Qt.ItemIsDragEnabled return ret def removeVar(self, var): pos = self._vars._vars.index(var) self.removeRows(pos, 1, QModelIndex()) def removeRows(self, position, rows, parent): """ removes the selected row in the model @param position int, starting position of selection @param rows int, number of rows to delete beginning at starting position @param parent TreeItem, parent item containing items to delete """ parentItem = parent.internalPointer() if parentItem: logging.error("Cannot remove a child variable.") return False self.beginRemoveRows(parent, position, position + rows - 1) for i in xrange(position, position + rows): self._vars.removeIdx(i) # fix the _row members of the remaining elements for offset, var in enumerate(self._vars[position:]): var._row = position + offset self.endRemoveRows() return True def clear(self): self.beginResetModel() self._vars.clear() self.endResetModel() def setData(self, index, value, role): if index.isValid() and role == Qt.EditRole: index.internalPointer().assignValue(value.toString()) return True return False def __unmarkAll(self): for i in self._vars._vars: i.unmarkAll()
class SysCDiagramPlugin(): def initPlugin(self, signalproxy): """Initialise the systemc block diagram plugin""" self.signalproxy = signalproxy self.do = signalproxy.distributedObjects # systemc stuff and and pointer type strings needed for casting in gdb # because systemc objects can be systemc modules, systemc ports, etc. self.ctx = None self.ctx_pointer = None self.ctx_func = "sc_get_curr_simcontext()" self.ctx_found = False self.ctx_type = "(sc_core::sc_simcontext*)" self.port_type = "(sc_core::sc_port_base*)" self.module_type = "(sc_core::sc_module*)" self.object_type = "(sc_core::sc_object*)" self.prim_channel_type = "(sc_core::sc_prim_channel*)" # dict with a string that represents the pointer as key and # a nested dict with parent, children, etc as key-values # dst_dict[ptr] = {"wrapper": vw, # "name": None, # "parent_ptr": None, # "children": {}} self.sysc_modules = {} self.sysc_objects = {} self.sysc_ports = {} self.sysc_prim_channels = {} # because of how we built the interface for the tracepoints on the # datagraph we first need to create an file obj. We choose StringIO # because it uses a string as buffer and does not acces the filesystem self._file_obj = StringIO() self.image = SVGImage("SystemC Block Diagram", self._file_obj) self.image_wrapper = SVGDataGraphVW(self.image, self.do) self.signalproxy.inferiorStoppedNormally.connect(self.update) # hook Datagraph variable wrapper into the datagraph controller # after self.action.commit is called the image will be displayed at the # datagraph self.action = self.do.actions.\ getAddSVGToDatagraphAction(self.image_wrapper, self.do. datagraphController.addVar) # pydot graph visualization library self.block_diagram = Dot(graph_type='digraph') self.block_diagram.set_graph_defaults(compound='true', splines='ortho', rankdir='LR') self.block_diagram.set_node_defaults(shape='box') # Needed for creating the right variables and variable wrappers from # the systemc pointers self.vwFactory = VarWrapperFactory() self.variableList = VariableList(self.vwFactory, self.do) def deInitPlugin(self): pass def evaluateExp(self, exp): return self.signalproxy.gdbEvaluateExpression(exp) def showDiagram(self): self.action.commit() def update(self): if not self.ctx_found and self.ctx is None: self.__findSimContext() if self.ctx is None: return else: # don't try to analyze if elaboration is not done if not cpp2py(self.ctx["m_elaboration_done"].value): return # prepare for easy information collection object_vec = self.ctx["m_child_objects"] # find all relevant information self.__findSysCObjects(object_vec, self.object_type, self.sysc_objects) # if there are no objects to draw than skip the drawing part # this might happen if you set the breakpoint before any objects are # created. This is actually catched above, but there might also be a # design with no objects. if len(self.sysc_objects.keys()) == 0: return clusters = {} nodes = {} # build pydot hierachy and add all subgraphs and nodes to the main # graph self.__buildHierachy(self.sysc_objects, clusters, nodes) for sptr in clusters: self.block_diagram.add_subgraph(clusters[sptr]) for sptr in nodes: self.block_diagram.add_node(nodes[sptr]) self._file_obj.write(self.block_diagram.create_svg()) self.signalproxy.inferiorStoppedNormally.disconnect(self.update) self.showDiagram() def __buildHierachy(self, obj_dict, clusters, nodes): """ Build Cluster and Node hierachy for pydot """ for ptr in obj_dict: obj = obj_dict[ptr] if ptr in (self.sysc_ports.keys()+self.sysc_prim_channels.keys()): continue if len(obj["children"].keys()) == 0: node = Node(obj["name"]) nodes[ptr] = node else: clust = Cluster(obj["name"].replace(".", "_"), color='red', label=obj["name"]) c_clusters = {} c_nodes = {} self.__buildHierachy(obj["children"], c_clusters, c_nodes) for sptr in c_clusters: clust.add_subgraph(c_clusters[sptr]) for sptr in c_nodes: clust.add_node(c_nodes[sptr]) clusters[ptr] = clust def __findSysCObjects(self, obj_vec, obj_type, dst_dict): """ Find sc_object from module, port and prim channel registry """ for i in obj_vec.childs: ptr = i.value var = "(*{}{})".format(obj_type, ptr) vw = self.variableList.addVarByName(var) dst_dict[ptr] = {"wrapper": vw, "name": None, "parent_ptr": None, "children": {}} for member in vw.childs: if member.exp == "m_name": dst_dict[ptr]["name"] = member.value.strip('"') elif member.exp == "m_child_objects": children = {} self.__findSysCObjects(vw["m_child_objects"], obj_type, children) dst_dict[ptr]["children"] = children elif member.exp == "m_parent": dst_dict[ptr]["parent_ptr"] = member.value def __findSimContext(self): """ Find systemc simulation context """ self.ctx_pointer = self.evaluateExp(self.ctx_func) if self.ctx is None: frame = 0 depth = self.signalproxy.gdbGetStackDepth() while (self.ctx_pointer is None) and frame <= depth: frame += 1 self.signalproxy.gdbSelectStackFrame(frame) self.ctx_pointer = self.evaluateExp(self.ctx_func) else: if self.ctx_pointer is None: self.ctx_found = False return else: self.ctx_found = True self.ctx = self.do.variablePool.getVar(self.ctx_func)["*"] else: self.ctx_found = True self.ctx = self.do.variablePool.getVar(self.ctx_func)["*"]
class DataGraphController(QObject): """ the Controller for the DataGraph """ def __init__(self, distributedObjects): """ Constructor <br> Creates a DataGraphView, a DataGraphVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) # controllers ## @var distributedObjects # distributedobjects.DistributedObjects, the DistributedObjects-Instance self.distributedObjects = distributedObjects ## @var signalProxy # signalproxy.SignalProxy, the SignalProxy-Instance from the DistributedObjects self.signalProxy = distributedObjects.signalProxy ## @var debugController # debugcontroller.DebugController, the DebugController-Instance from the DistributedObjects self.debugController = distributedObjects.debugController ## @var variablePool # variables.variablepool.VariablePool, the variablePool-Instance from the DistributedObjects self.variablePool = distributedObjects.variablePool # views ## @var data_graph_view # datagraph.datagraphview.DataGraphView, private, self-created DataGraphView <br> # GUI-Element that shows the DataGraphView self.data_graph_view = DataGraphView(None, self) # models ## @var vwFactory # datagraph.datagraphvwfactory.DataGraphVWFactory, private, self-created DataGraphVWFactory self.vwFactory = DataGraphVWFactory(self.distributedObjects) ## @var variableList # variables.variablelist.VariableList, private, self-created VariableList self.variableList = VariableList(self.vwFactory, self.distributedObjects) self.pointerList = [] #register with session manager to save Graph self.signalProxy.emitRegisterWithSessionManager(self, "Graph") # connect signals #QObject.connect(self.variableList, SIGNAL('reset()'), self.repaintDataGraph) QObject.connect(self.signalProxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets) QObject.connect(self.signalProxy, SIGNAL('cleanupModels()'), self.clearDataGraph) def insertDockWidgets(self): """ adds the Datagraph-DockWidget to the GUI <br> this function is connected to the signal SignalProxy::insertDockWidgets() """ self.dataGraphDock = QDockWidget("Graph") self.dataGraphDock.setObjectName("DataGraphView") self.dataGraphDock.setWidget(self.data_graph_view) self.signalProxy.addDockWidget(Qt.LeftDockWidgetArea, self.dataGraphDock, True) def addWatch(self, watch, xPos=0, yPos=0): """ adds the Variable watch to the VariableList and its wrapper to the DataGraph @param watch variables.variable.Variable, the Variable to watch to add @param xPos Integer, the X-Coordinate of the Position where to add the Variable @param yPos Integer, the Y-Coordinate of the Position where to add the Variable """ varWrapper = self.variableList.addVarByName(watch) self.addVar(varWrapper, xPos, yPos, False) return varWrapper def addVar(self, varWrapper, xPos=0, yPos=0, addVarToList=True): """ adds the given VariableWrapper varWrapper to the DataGraph and - if addVarToList is true - also to the VariableList @param varWrapper variables.variablewrapper.VariableWrapper, the VariableWrapper to add @param xPos Integer, the X-Coordinate of the Position where to add the VariableWrapper @param yPos Integer, the Y-Coordinate of the Position where to add the VariableWrapper @param addVarToList Boolean, tells if varWrapper should be added to the VariableList too """ varWrapper.createView() try: varWrapper.getView().render() except: from mako import exceptions logging.error("Caught exception while rendering template: %s", exceptions.text_error_template().render()) varWrapper.setXPos(xPos) varWrapper.setYPos(yPos) self.data_graph_view.addItem(varWrapper.getView()) if addVarToList: self.variableList.addVar(varWrapper) QObject.connect(varWrapper, SIGNAL('replace(PyQt_PyObject, PyQt_PyObject)'), self.replaceVariable) def replaceVariable(self, pendingVar, newVar): """ replaces existing variable in list with new one @param pendingVar variables.variable.Variable, the pending Variable to replace with newVar @param newVar variables.variable.Variable, the new Variable pendingVar is replaced with """ self.removeVar(pendingVar) newVW = newVar.makeWrapper(self.vwFactory) self.addVar(newVW, pendingVar.getXPos(), pendingVar.getYPos()) #for pointer in pendingVar.getView().getIncomingPointers(): # self.addPointer(pointer.getFromView(), newVW.getView()) #for pointer in pendingVar.getView().getOutgoingPointers(): # self.addPointer(newVW.getView(), pointer.getToView()) def removeVar(self, varWrapper): """ removes the given varWrapper from the DataGraphView and the PointerList @param varWrapper variables.variablewrapper.VariableWrapper, the VariableWrapper to remove """ self.variableList.removeVar(varWrapper) self.data_graph_view.removeItem(varWrapper.getView()) def addPointer(self, fromView, toView): """ fromView and toView are QGraphicsWebViews @param fromView datagraph.htmlvariableview.HtmlVariableView, starting point of the Pointer @param toView datagraph.htmlvariableview.HtmlVariableView, end point of the Pointer """ pointer = Pointer(None, fromView, toView, self.distributedObjects) self.data_graph_view.addItem(pointer) self.pointerList.append(pointer) def removePointer(self, pointer): """ removes the given pointer from the DataGraphView and the PointerList @param pointer datagraph.pointer.Pointer, pointer to remove """ self.data_graph_view.removeItem(pointer) self.pointerList.remove(pointer) def clearDataGraph(self): """ clears the DataGraphView and the VariableList <br> this function is connected to the signal SignalProxy::cleanupModels() """ self.variableList.clear() self.data_graph_view.clear() def saveSession(self, xmlHandler): """ Insert session info to xml file @param xmlHandler sessionmanager.XmlHandler, handler to write to the session-xml-file """ dgWatches = xmlHandler.createNode("GraphWatches") for vw in self.variableList: xmlHandler.createNode("Watch", dgWatches, {'expression': vw.getExp(), 'xPos': vw.getXPos(), 'yPos': vw.getYPos()}) #dgPointers = xmlHandler.createNode("Pointers") #for pointer in self.pointerList: # xmlHandler.createNode("Pointer", dgPointers, { 'expFrom': pointer.fromView.var.getExp(), 'expTo': pointer.toView.var.getExp() }) def loadSession(self, xmlHandler): """ load session info to xml file @param xmlHandler sessionmanager.XmlHandler, handler to read from the session-xml-file """ dgParent = xmlHandler.getNode("GraphWatches") if dgParent != None: childnodes = dgParent.childNodes() for i in range(childnodes.size()): attr = xmlHandler.getAttributes(childnodes.at(i)) self.addWatch(attr["expression"], int(attr["xPos"]), int(attr["yPos"]))
class Tracepoint(ExtendedBreakpoint): """This class is used as a tracepoint in tracepointmodel. Basically Tracpoints are Breakpoint but they are extended with tracedVariables (list of Variable-Value-Pairs). Every Tracepoint contains some variables that are traced. Tracepoints are breakpoints and stop program then get information of asked variables and then continue program """ def __init__(self, distObjects, sensitiveVariable, nr): """Init Tracepoint @param sensitiveVariable: is the sensitive variable. Use extendedBreakpoints for this. If extBP occures then the variables and their values will be stored. @param nr: needed to initialize ExtendedBreakpoint class """ ExtendedBreakpoint.__init__(self, sensitiveVariable, nr, distObjects.gdb_connector) """here are the traced variables stored with their values""" self.gdb_connector = distObjects.gdb_connector self.distObjects = distObjects self.vwFactory = TraceVWFactory() self.variableList = VariableList(self.vwFactory, distObjects) self.counter = 0 self.hitted = False self.stop = False self.connect(self.distObjects.signalProxy, SIGNAL('dataForTracepointsReady()'), self.readDataFromVarModel) self.wave = [] def addVar(self, variableToTrace): """ add a var to trace its value @param variableToTrace: variable name of the variable that shoudl be traced""" vw = self.variableList.addVarByName(variableToTrace) QObject.connect(vw, SIGNAL('replace(PyQt_PyObject, PyQt_PyObject)'), self.replaceVariable) newValueList = ValueList(variableToTrace, vw.getType()) self.wave.append(newValueList) def replaceVariable(self, pendingVar, newVar): """ replace existing variable in list with new one @param pendingVar: var to replace @param newVar: new var""" vwOld = self.variableList.getVariableWrapper(pendingVar) vwNew = self.variableList.replaceVar(pendingVar, newVar) QObject.connect(vwNew, SIGNAL('replace(PyQt_PyObject, PyQt_PyObject)'), self.replaceVariable) def tracePointOccurred(self, stop): """ set if stop is needed or not @param stop: (bool), gdb stops after tracing if True, gdb continues after tracing if False """ self.stop = stop self.hitted = True def readDataFromVarModel(self): """tracepoint occurred: get values of all traced variables then continue debugging """ if self.hitted: self.hitted = False self.counter = self.counter + 1 #print "\n\n------------------------ tracePoint " + self.name + " line: " + self.line + " occured " + str(self.counter) + " times:" for varList in self.wave: for v in self.variableList.list: if v.variable.uniquename == varList.name: varList.addValue(v.variable.type, v.variable.value) if not(self.stop): self.stop = True self.gdb_connector.cont()
class VariableModel(QAbstractItemModel): def __init__(self, do, parent=None): QAbstractItemModel.__init__(self, parent) self._vars = VariableList(TreeVariableFactory, do) do.signalProxy.cleanupModels.connect(self.clear) do.signalProxy.aboutToUpdateVariables.connect(self.__unmarkAll) def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QModelIndex() parentItem = parent.internalPointer() if parent.isValid() else None if parentItem: childItem = parentItem._child(row) else: childItem = self._vars[row] return self.createIndex(row, column, childItem) def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem._parent if not parentItem: return QModelIndex() return self.createIndex(parentItem._row, 0, parentItem) def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): return len(self._vars) else: return parent.internalPointer()._childCount() def columnCount(self, _): return 3 def data(self, index, role): if not index.isValid(): return None item = index.internalPointer() ret = None if role == Qt.DisplayRole: if index.column() == 0: ret = item.exp elif index.column() == 1: ret = item.type elif index.column() == 2: ret = item.value elif role == Qt.EditRole: if index.column() == 2: ret = item.value elif role == Qt.DecorationRole: if index.column() == 0: if item.access in ['private', 'protected']: iconprefix = item.access + "_" else: iconprefix = "" icon = None if not item.inScope: return QPixmap(":/icons/images/outofscope.png") elif not isinstance(item, StdVariable): icon = QPixmap(":/icons/images/" + iconprefix + "struct.png") else: # leave item icon = QPixmap(":/icons/images/" + iconprefix + "var.png") # overlay for arguments if icon and item.arg: ol = QPixmap(":/icons/images/overlay_arg.png") p = QPainter(icon) p.drawPixmap(ol.rect(), ol) elif icon and item.exp == "Return value": ol = QPixmap(":/icons/images/overlay_ret.png") p = QPainter(icon) p.drawPixmap(ol.rect(), ol) return icon elif role == Qt.BackgroundRole: if not item.inScope: ret = QBrush(Qt.gray) elif index.column() == 2: if item.marked and item.inScope: ret = QBrush(Qt.yellow) return ret def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return ["Expression", "Type", "Value"][section] return None def addVar(self, name): self.beginInsertRows(QModelIndex(), len(self._vars), len(self._vars)) var = self._vars.addVarByName(name) var.setNodeData(len(self._vars) - 1, None, self) self.endInsertRows() return var def hasChildren(self, parent): if not parent.isValid(): return True return parent.internalPointer()._hasChildren() def emitDataChanged(self, tl, br): self.dataChanged.emit(tl, br) def mimeTypes(self): return [variable.MIME_TYPE] def mimeData(self, indexes): if len(indexes) == 1: item = indexes[0].internalPointer() d = QMimeData() d.setData(variable.MIME_TYPE, item.uniqueName) return d else: return None def flags(self, index): if not index.isValid(): return Qt.ItemIsDropEnabled item = index.internalPointer() if not item.inScope: return Qt.ItemIsEnabled | Qt.ItemIsSelectable ret = Qt.ItemIsEnabled | Qt.ItemIsSelectable if index.column() == 2: ret |= Qt.ItemIsEditable elif index.column() == 0: ret |= Qt.ItemIsDragEnabled return ret def removeVar(self, var): pos = self._vars._vars.index(var) self.removeRows(pos, 1, QModelIndex()) def removeRows(self, position, rows, parent): """ removes the selected row in the model @param position int, starting position of selection @param rows int, number of rows to delete beginning at starting position @param parent TreeItem, parent item containing items to delete """ parentItem = parent.internalPointer() if parentItem: logging.error("Cannot remove a child variable.") return False self.beginRemoveRows(parent, position, position + rows - 1) for i in range(position, position + rows): self._vars.removeIdx(i) # fix the _row members of the remaining elements for offset, var in enumerate(self._vars[position:]): var._row = position + offset self.endRemoveRows() return True def clear(self): self.beginResetModel() self._vars.clear() self.endResetModel() def setData(self, index, value, role): if index.isValid() and role == Qt.EditRole: index.internalPointer().assignValue(value) return True return False def __unmarkAll(self): for i in self._vars._vars: i.unmarkAll()
def __init__(self, do, parent=None): QAbstractItemModel.__init__(self, parent) self._vars = VariableList(TreeVariableFactory, do) do.signalProxy.cleanupModels.connect(self.clear) do.signalProxy.aboutToUpdateVariables.connect(self.__unmarkAll)
class DataGraphController(QObject): """ the Controller for the DataGraph """ def __init__(self, distributedObjects): QObject.__init__(self) self.distributedObjects = distributedObjects self.signalProxy = distributedObjects.signalProxy self._view = DataGraphView(None) self.variableList = VariableList(DataGraphVariableFactory, self.distributedObjects) # register with session manager to save Graph self.signalProxy.registerWithSessionManager.emit(self, "Graph") # connect signals self.signalProxy.cleanupModels.connect(self.clearDataGraph) self.distributedObjects.mainwindow.insertDockWidget(self._view, "Graph", Qt.LeftDockWidgetArea, True, QIcon(":/icons/images/datagraph.png")) def addWatch(self, watch, xPos=0, yPos=0): """ adds `watch' to the DataGraph @param watch str, variable to add @param xPos int, x coordinate of the desired position @param yPos int, y coordinate of the desired position """ try: var = self.variableList.addVarByName(watch) var.setData(self.distributedObjects) var.createView() var.getView().render() var.setXPos(xPos) var.setYPos(yPos) self._view.addItem(var.getView()) return var except VariableNotFoundException: return None def addDereferencedPointer(self, source, name): target = self.addWatch(str(name)) self.addPointer(source.getView(), target.getView()) def removeVar(self, var): self.variableList.removeVar(var) self._view.removeItem(var.getView()) def addPointer(self, fromView, toView): """ fromView and toView are QGraphicsWebViews @param fromView datagraph.htmlvariableview.HtmlVariableView, starting point of the Pointer @param toView datagraph.htmlvariableview.HtmlVariableView, end point of the Pointer """ self._view.addItem(Pointer(None, fromView, toView, self.distributedObjects)) def removePointer(self, pointer): """ removes the given pointer from the DataGraphView and the PointerList @param pointer datagraph.pointer.Pointer, pointer to remove """ self._view.removeItem(pointer) def clearDataGraph(self): """ clears the DataGraphView and the VariableList <br> this function is connected to the signal SignalProxy::cleanupModels() """ self.variableList.clear() self._view.clear()
class WatchController(QObject): """ the Controller for the WatchView """ def __init__(self, distributedObjects): """ Constructor <br> Create a WatchView, a WatchVWFactory and a VariableList <br> Listens to the following Signals: SignalProxy::AddWatch(QString), SignalProxy::insertDockWidgets() and SignalProxy::cleanupModels() @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance """ QObject.__init__(self) self.distributedObjects = distributedObjects #self.root = RootVarWrapper() self.vwFactory = WatchVWFactory() self.variableModel = VariableModel(self, self.distributedObjects) self.watchView = WatchView(self) self.watchView.treeView.setModel(self.variableModel) self.watchVariableList = VariableList(self.vwFactory, self.distributedObjects) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('AddWatch(QString)'), self.addWatch) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets) QObject.connect(self.distributedObjects.signal_proxy, SIGNAL('cleanupModels()'), self.clearVars) def clearVars(self): """ clears the WatchView and the VariableList <br> this function is connected to the signal SignalProxy::cleanupModels() """ # clear lists del self.watchVariableList.list[:] self.variableModel.clear() def insertDockWidgets(self): """ adds the Watch-DockWidget to the GUI <br> this function is connected to the signal SignalProxy::insertDockWidgets() """ self.watchDock = QDockWidget("Watch") self.watchDock.setObjectName("WatchView") self.watchDock.setWidget(self.watchView) self.distributedObjects.signal_proxy.addDockWidget(Qt.BottomDockWidgetArea, self.watchDock, True) def removeSelected(self, row, parent): """ remove selected variable from WatchView @param row int, selected row @param parent TreeItem, parent item from selectected item """ self.variableModel.removeRow(row, parent) def addWatch(self, watch): """ adds the Variable watch to the VariableList and its wrapper to the WatchView this function is connected to the signal SignalProxy::AddWatch(QString) @param watch Variable, the Variable to add to watch """ vw = self.watchVariableList.addVarByName(watch) # connect changed and replace signal from wrapper QObject.connect(vw, SIGNAL('changed()'), vw.hasChanged) QObject.connect(vw, SIGNAL('replace(PyQt_PyObject, PyQt_PyObject)'), self.replaceVariable) # set parent for root variable vw.setParent(self.variableModel.root) # add variable to root children self.variableModel.root.addChild(vw) self.variableModel.addVar(vw) def replaceVariable(self, pendingVar, newVar): """ replaces a variable in the variablelist @param pendingVar variables.variablewrapper.VariableWrapper, VariableWrapper to replace in the list @param newVar variables.Variable, new Variable which replaces existing VariableWrapper in List """ vwOld = self.watchVariableList.getVariableWrapper(pendingVar) vwNew = self.watchVariableList.replaceVar(pendingVar, newVar) QObject.connect(vwNew, SIGNAL('changed()'), vwNew.hasChanged) QObject.connect(vwNew, SIGNAL('replace(PyQt_PyObject, PyQt_PyObject)'), self.replaceVariable) # set parent for root variable vwNew.setParent(self.variableModel.root) # add variable to root children self.variableModel.root.replaceChild(vwOld, vwNew) vwNew.setChanged(True) self.variableModel.update() def saveSession(self, xmlHandler): """ Insert session info to xml file @param xmlHandler sessionmanager.XmlHandler, handler to write to the session-xml-file """ watchParent = xmlHandler.createNode("Watches") for var in self.variableModel.getVariables(): xmlHandler.createNode("Watch", watchParent, { 'exp': var.getExp()}) def loadSession(self, xmlHandler): """ load session info to xml file @param xmlHandler sessionmanager.XmlHandler, handler to read from the session-xml-file """ watchParent = xmlHandler.getNode("Watches") if watchParent != None: childnodes = watchParent.childNodes() for i in range(childnodes.size()): attr = xmlHandler.getAttributes(childnodes.at(i)) self.addWatch(attr["exp"])