Beispiel #1
0
 def __init__(self, lint, args, editor, results_iter, message):
     AbstractProcess.__init__(self, lint, args, editor)
     # self.lint = lint
     # self.args = args
     # self.editor = editor
     self.results_iter = results_iter
     self.message = message  # Must be callable.
     # Set up styling for annotations.
     self.console.setAnnotationDisplay(2)
     self.font = Qt.QFont('Courier', 9, Qt.QFont.Normal, True)
     self.info = QsciStyle(-1, 'Hilite style for lint info',
                           Qt.QColor('#222222'), Qt.QColor('#FFFFFF'),
                           self.font)
     self.warning = QsciStyle(-1, 'Hilite style for lint warnings',
                              Qt.QColor('#222222'), Qt.QColor('#FFFF44'),
                              self.font)
     self.error = QsciStyle(-1, 'Hilite style for lint errors',
                            Qt.QColor('#FFFFFF'), Qt.QColor('#EE0000'),
                            self.font)
     self.severities = {
         'I': self.info,
         'C': self.info,
         'W': self.warning,
         'R': self.warning,
         'E': self.error,
         'F': self.error
     }
     self.connect(self, Qt.SIGNAL('results()'), self.apply_results)
     return
Beispiel #2
0
    def __setRevisionText(self):
        " Sets the revision margin text "
        for revNumber in self.__revisionInfo:
            author = self.__revisionInfo[revNumber]['author']
            if '@' in author:
                # Most probably this is an e-mail address. Leave just name.
                self.__revisionInfo[revNumber]['shortAuthor'] = author.split(
                    '@')[0]
            else:
                self.__revisionInfo[revNumber]['shortAuthor'] = author

        skin = GlobalData().skin
        revisionMarginFont = QFont(skin.lineNumFont)
        revisionMarginFont.setItalic(True)
        style = QsciStyle(-1, "Revision margin style",
                          skin.revisionMarginColor, skin.revisionMarginPaper,
                          revisionMarginFont)

        lineNumber = 0
        self.__maxLength = -1

        # Altering line background support
        currentRevision = -1
        needMarker = True

        for lineRevision in self.__lineRevisions:
            if lineRevision in self.__revisionInfo:
                marginText = " " + ":".join([
                    str(lineRevision),
                    self.__revisionInfo[lineRevision]['shortAuthor']
                ])
            else:
                marginText = " " + str(lineRevision)
            textLength = len(marginText)
            if textLength > self.__maxLength:
                self.__maxLength = textLength
            self.setMarginText(lineNumber, marginText, style)

            # Set the line background if needed
            if lineRevision != currentRevision:
                currentRevision = lineRevision
                needMarker = not needMarker
            if needMarker:
                self.markerAdd(lineNumber, self.__alterMarker)

            lineNumber += 1

        self.setRevisionMarginWidth()
        return
    def __init__(self, distributedObjects, filename, parent):
        ScintillaWrapper.__init__(self, parent)
        self.breakpointOverlays = {}

        filename = str(filename)
        self.distributedObjects = distributedObjects
        self.debugController = self.distributedObjects.debugController
        self.__bpModel = self.distributedObjects.breakpointModel
        self.tracepointController = self.distributedObjects.tracepointController
        self.signalProxy = self.distributedObjects.signalProxy
        self.filename = filename
        self.lastContextMenuLine = 0
        self.markerBp = QPixmap(":/markers/bp.png")
        self.markerBpDisabled = QPixmap(":/markers/bp_dis.png")
        self.markerTp = QPixmap(":/markers/tp.png")
        self.markerExec = QPixmap(":/markers/exec_pos.png")
        self.markerStack = QPixmap(":/markers/stack_pos.png")
        self.markerExecSignal = QPixmap(":/markers/exec_pos_signal.png")
        self.shown = False

        self.setToolTip("")
        self.setWhatsThis("")
        self.setMarginLineNumbers(self.MARGIN_NUMBERS, True)
        # set sensitivity
        self.setMarginSensitivity(self.MARGIN_NUMBERS, True)
        self.setMarginSensitivity(self.MARGIN_MARKER_BP, True)
        self.setMarginSensitivity(self.MARGIN_MARKER_TP, True)
        # define symbol
        self.markerDefine(self.markerBp, self.MARGIN_MARKER_BP)
        self.markerDefine(self.markerBpDisabled, self.MARGIN_MARKER_BP_DIS)
        self.markerDefine(self.markerTp, self.MARGIN_MARKER_TP)
        self.markerDefine(self.markerExec, self.MARGIN_MARKER_EXEC)
        self.markerDefine(self.markerStack, self.MARGIN_MARKER_STACK)
        self.markerDefine(self.markerExecSignal, self.MARGIN_MARKER_EXEC_SIGNAL)
        self.markerDefine(QsciScintilla.Background, self.MARKER_HIGHLIGHTED_LINE)

        # define width and mask to show margin
        self.setMarginWidth(self.MARGIN_MARKER_BP, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_BP, 1 << self.MARGIN_MARKER_BP | 1 << self.MARGIN_MARKER_BP_DIS)
        self.setMarginWidth(self.MARGIN_MARKER_TP, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_TP, 1 << self.MARGIN_MARKER_TP)
        self.setMarginWidth(self.MARGIN_MARKER_EXEC, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_EXEC,
                1 << self.MARGIN_MARKER_EXEC |
                1 << self.MARGIN_MARKER_EXEC_SIGNAL |
                1 << self.MARGIN_MARKER_STACK)
        self.setMarginWidth(self.MARKER_HIGHLIGHTED_LINE, 0)
        self.setMarginMarkerMask(self.MARKER_HIGHLIGHTED_LINE, 1 << self.MARKER_HIGHLIGHTED_LINE)

        self.INDICATOR_TOOLTIP = self.indicatorDefine(self.BoxIndicator)
        self.setIndicatorDrawUnder(True, self.INDICATOR_TOOLTIP)

        self.setReadOnly(False)
        self.modificationChanged.connect(self.__setFileModified)

        self.SendScintilla(QsciScintilla.SCI_SETMOUSEDWELLTIME, 500)

        # override scintillas context menu with our own
        self.SendScintilla(QsciScintilla.SCI_USEPOPUP, 0)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        self.marginClicked.connect(self.onMarginClicked)
        self.SCN_DOUBLECLICK.connect(self.editDoubleClicked)
        self.dwellStart.connect(self.onDwellStart)
        self.dwellEnd.connect(self.onDwellEnd)

        self.__bpModel.rowsInserted.connect(self.breakpointsInserted)
        # don't connect to rowsRemoved here since the breakpoint is already gone
        # from the model when it's emitted
        self.__bpModel.rowsAboutToBeRemoved.connect(self.breakpointsRemoved)
        self.__bpModel.dataChanged.connect(self.breakpointsModified)
        _model = self.tracepointController.model()
        _model.rowsInserted.connect(self.getTracepointsFromModel)
        _model.rowsRemoved.connect(self.getTracepointsFromModel)

        act = self.distributedObjects.actions
        act.ToggleTrace.triggered.connect(self.toggleTracepoint)

        self.__allowToolTip = True
        self.__enableToolTip(True)

        self.__popupMenu = None

        self.__disAsmStyle = QsciStyle()

        self.__fileWatcher = QFileSystemWatcher([self.filename])
        self.__fileWatcher.fileChanged.connect(self.__fileChanged)

        # this timer is used for a workaround: QFileSystemWatcher will sometimes
        # report a change multiple times; therefore, in self.__fileChanged, we
        # simply start the timer on a notification and discard all notifications
        # while the timer is running
        self.__fileChangedTimer = QTimer()
        self.__fileChangedTimer.setSingleShot(True)
        self.__fileChangedTimer.setInterval(100)

        ScintillaWrapper.init(self, distributedObjects)
        self.setLexer(QsciLexerCPP())

        self.openFile()
class OpenedFileView(ScintillaWrapper):
    MARGIN_NUMBERS, MARGIN_MARKER_FOLD, MARGIN_MARKER_BP, MARGIN_MARKER_TP, MARGIN_MARKER_EXEC, \
    MARGIN_MARKER_EXEC_SIGNAL, MARKER_HIGHLIGHTED_LINE, MARGIN_MARKER_STACK, MARGIN_MARKER_BP_DIS = range(9)

    def __init__(self, distributedObjects, filename, parent):
        ScintillaWrapper.__init__(self, parent)
        self.breakpointOverlays = {}

        filename = str(filename)
        self.distributedObjects = distributedObjects
        self.debugController = self.distributedObjects.debugController
        self.__bpModel = self.distributedObjects.breakpointModel
        self.tracepointController = self.distributedObjects.tracepointController
        self.signalProxy = self.distributedObjects.signalProxy
        self.filename = filename
        self.lastContextMenuLine = 0
        self.markerBp = QPixmap(":/markers/bp.png")
        self.markerBpDisabled = QPixmap(":/markers/bp_dis.png")
        self.markerTp = QPixmap(":/markers/tp.png")
        self.markerExec = QPixmap(":/markers/exec_pos.png")
        self.markerStack = QPixmap(":/markers/stack_pos.png")
        self.markerExecSignal = QPixmap(":/markers/exec_pos_signal.png")
        self.shown = False

        self.setToolTip("")
        self.setWhatsThis("")
        self.setMarginLineNumbers(self.MARGIN_NUMBERS, True)
        # set sensitivity
        self.setMarginSensitivity(self.MARGIN_NUMBERS, True)
        self.setMarginSensitivity(self.MARGIN_MARKER_BP, True)
        self.setMarginSensitivity(self.MARGIN_MARKER_TP, True)
        # define symbol
        self.markerDefine(self.markerBp, self.MARGIN_MARKER_BP)
        self.markerDefine(self.markerBpDisabled, self.MARGIN_MARKER_BP_DIS)
        self.markerDefine(self.markerTp, self.MARGIN_MARKER_TP)
        self.markerDefine(self.markerExec, self.MARGIN_MARKER_EXEC)
        self.markerDefine(self.markerStack, self.MARGIN_MARKER_STACK)
        self.markerDefine(self.markerExecSignal, self.MARGIN_MARKER_EXEC_SIGNAL)
        self.markerDefine(QsciScintilla.Background, self.MARKER_HIGHLIGHTED_LINE)

        # define width and mask to show margin
        self.setMarginWidth(self.MARGIN_MARKER_BP, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_BP, 1 << self.MARGIN_MARKER_BP | 1 << self.MARGIN_MARKER_BP_DIS)
        self.setMarginWidth(self.MARGIN_MARKER_TP, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_TP, 1 << self.MARGIN_MARKER_TP)
        self.setMarginWidth(self.MARGIN_MARKER_EXEC, 10)
        self.setMarginMarkerMask(self.MARGIN_MARKER_EXEC,
                1 << self.MARGIN_MARKER_EXEC |
                1 << self.MARGIN_MARKER_EXEC_SIGNAL |
                1 << self.MARGIN_MARKER_STACK)
        self.setMarginWidth(self.MARKER_HIGHLIGHTED_LINE, 0)
        self.setMarginMarkerMask(self.MARKER_HIGHLIGHTED_LINE, 1 << self.MARKER_HIGHLIGHTED_LINE)

        self.INDICATOR_TOOLTIP = self.indicatorDefine(self.BoxIndicator)
        self.setIndicatorDrawUnder(True, self.INDICATOR_TOOLTIP)

        self.setReadOnly(False)
        self.modificationChanged.connect(self.__setFileModified)

        self.SendScintilla(QsciScintilla.SCI_SETMOUSEDWELLTIME, 500)

        # override scintillas context menu with our own
        self.SendScintilla(QsciScintilla.SCI_USEPOPUP, 0)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        self.marginClicked.connect(self.onMarginClicked)
        self.SCN_DOUBLECLICK.connect(self.editDoubleClicked)
        self.dwellStart.connect(self.onDwellStart)
        self.dwellEnd.connect(self.onDwellEnd)

        self.__bpModel.rowsInserted.connect(self.breakpointsInserted)
        # don't connect to rowsRemoved here since the breakpoint is already gone
        # from the model when it's emitted
        self.__bpModel.rowsAboutToBeRemoved.connect(self.breakpointsRemoved)
        self.__bpModel.dataChanged.connect(self.breakpointsModified)
        _model = self.tracepointController.model()
        _model.rowsInserted.connect(self.getTracepointsFromModel)
        _model.rowsRemoved.connect(self.getTracepointsFromModel)

        act = self.distributedObjects.actions
        act.ToggleTrace.triggered.connect(self.toggleTracepoint)

        self.__allowToolTip = True
        self.__enableToolTip(True)

        self.__popupMenu = None

        self.__disAsmStyle = QsciStyle()

        self.__fileWatcher = QFileSystemWatcher([self.filename])
        self.__fileWatcher.fileChanged.connect(self.__fileChanged)

        # this timer is used for a workaround: QFileSystemWatcher will sometimes
        # report a change multiple times; therefore, in self.__fileChanged, we
        # simply start the timer on a notification and discard all notifications
        # while the timer is running
        self.__fileChangedTimer = QTimer()
        self.__fileChangedTimer.setSingleShot(True)
        self.__fileChangedTimer.setInterval(100)

        ScintillaWrapper.init(self, distributedObjects)
        self.setLexer(QsciLexerCPP())

        self.openFile()

    def updateConfig(self):
        if not ScintillaWrapper.updateConfig(self):
            return False
        # check whether we're supposed to use overlays and reload everything
        # that uses them
        qs = QsciScintilla
        c = self.distributedObjects.editorController.config
        l = self.lexer()
        self.setFolding(qs.BoxedTreeFoldStyle if c.folding.value else qs.NoFoldStyle, self.MARGIN_MARKER_FOLD)
        self.setMarkerBackgroundColor(QColor(c.highlightColor.value), self.MARKER_HIGHLIGHTED_LINE)
        l.setColor(QColor(c.preprocessorColor.value), l.PreProcessor)
        l.setColor(QColor(c.commentColor.value), l.CommentLine)
        l.setColor(QColor(c.commentColor.value), l.CommentDoc)

        self.__disAsmStyle.setFont(formlayout.tuple_to_qfont(self.distributedObjects.editorController.config.font.value))
        # make the annotation's background slightly shaded with the identifier color
        bg = QColor(self.distributedObjects.editorController.config.backgroundColor.value)
        fg = QColor(self.distributedObjects.editorController.config.identifierColor.value)
        self.__disAsmStyle.setPaper(mixColor(bg, .8, fg))
        self.__disAsmStyle.setColor(fg)

        self.__useBreakpointOverlays = c.useBreakpointOverlays.value
        self.getBreakpointsFromModel()
        self.setDisassemble(self.distributedObjects.editorController.config.showDisassemble.value)

        return True

    def __fileChanged(self):
        if not self.__fileChangedTimer.isActive():
            logging.warning("Source file %s modified. Recompile executable for correct debugging.", self.filename)
            self.__fileChangedTimer.start()

    def saveFile(self):
        ''' Save source file '''
        if (QFile.exists(self.filename)):
            f = open(self.filename, 'w')
            f.write(self.text())
            f.close()
            self.openFile()

    def openFile(self):
        if not (QFile.exists(self.filename)):
            logging.error("Could not open file %s", self.filename)

        self.file_ = QFile(self.filename)
        self.file_.open(QIODevice.ReadOnly | QIODevice.Text)
        self.read(self.file_)
        self.file_.close()
        self.setMarginWidthByLineNumbers()
        self.__setFileModified(False)

        # read all breakpoints and tracepoints from the model
        self.getTracepointsFromModel()
        self.getBreakpointsFromModel()

    def __setFileModified(self, modified):
        ''' Method called whenever current file is marked as modified '''
        self.distributedObjects.signalProxy.fileModified.emit(self.filename, modified)

    def onDwellStart(self, pos, x, y):
        if self.__allowToolTip:
            exp, (line, start, _) = self.getWordOrSelectionAndRangeFromPosition(pos)

            # try evaluating the expression before doing anything else: this will return None if the
            # expression is not valid (ie. something that is not a variable)
            if self.debugController.evaluateExpression(exp.strip()) is not None:
                startPos = self.positionFromLineIndex(line, start)
                x = self.SendScintilla(QsciScintilla.SCI_POINTXFROMPOSITION, 0, startPos)
                y = self.SendScintilla(QsciScintilla.SCI_POINTYFROMPOSITION, 0, startPos)
                self.distributedObjects.toolTipController.showToolTip(exp, QPoint(x + 3, y + 3 + self.textHeight(line)), self)

    def onDwellEnd(self, _1, _2, _3):
        self.distributedObjects.toolTipController.hideToolTip()

    def showContextMenu(self, point):
        scipos = self.SendScintilla(
                QsciScintilla.SCI_POSITIONFROMPOINT, point.x(), point.y())
        point = self.mapToGlobal(point)
        exp, _ = self.getWordOrSelectionAndRangeFromPosition(scipos)

        # self.lineIndexFromPosition(..) returns tuple. first element is line
        self.lastContextMenuLine = int(self.lineIndexFromPosition(scipos)[0])

        self.__popupMenu = QMenu(self)
        self.__popupMenu.addAction(self.distributedObjects.actions.ToggleTrace)

        if exp:
            self.__popupMenu.addAction(self.distributedObjects.actions.getAddToWatchAction(exp, self.signalProxy.addWatch))
            self.__popupMenu.addAction(self.distributedObjects.actions.getAddToDatagraphAction(exp, self.distributedObjects.datagraphController.addWatch))
            self.__popupMenu.addAction(self.distributedObjects.actions.getAddWatchpointAction(exp, self.distributedObjects.breakpointModel.insertWatchpoint))

            listOfTracepoints = self.tracepointController.getTracepointsFromModel()
            if listOfTracepoints:
                subPopupMenu = QMenu(self)
                subPopupMenu.setTitle("Add variable " + exp + " to tracepoint...")

                for tp in listOfTracepoints:
                    subPopupMenu.addAction(self.distributedObjects.actions.getAddToTracepointAction(exp, tp.name, tp.addVar))

                self.__popupMenu.addSeparator()
                self.__popupMenu.addMenu(subPopupMenu)

        self.__popupMenu.popup(point)

        # disable the tooltips while the menu is shown
        self.__enableToolTip(False)
        self.__popupMenu.aboutToHide.connect(lambda: self.__enableToolTip(True))

    def __enableToolTip(self, enable):
        self.__allowToolTip = enable

    def isPositionInsideSelection(self, position):
        lf, cf, lt, ct = self.getSelection()
        pl, pc = self.lineIndexFromPosition(position)

        if lf < pl and pl < lt:
            return True
        elif lf == pl and pl < lt:
            return True if cf <= pc else False
        elif lf < pl and pl == lt:
            return True if pc <= ct else False
        elif lf == pl and pl == lt:
            return True if (cf <= pc and pc <= ct) else False
        else:
            return False

    def getWordOrSelectionAndRangeFromPosition(self, position):
        if self.isPositionInsideSelection(position):
            line, start, lineTo, end = self.getSelection()
            if line != lineTo:
                return "", (None, None, None)
        else:
            line, start, end = self.getWordRangeFromPosition(position)
        return self.getWordFromRange(line, start, end), (line, start, end)

    def getWordRangeFromPosition(self, position):
        line, col = self.lineIndexFromPosition(position)
        start, end = self.getWordRangeFromLineCol(line, col)
        return line, start, end

    def getWordRangeFromLineCol(self, line, col):
        s = str(self.text(line))
        start = col - 1
        end = col

        a = 0

        while start >= 0:
            if s[start].isalnum() or s[start] in [".", "_"]:
                pass
            elif s[start] == ">" and start >= 1 and s[start - 1] == "-":
                start -= 1
            elif s[start] == "]":
                a -= 1
            elif s[start] == "[":
                a += 1
            else:
                break
            start -= 1
        start += 1

        while end < len(s):
            if a >= 0:
                pass
            if s[end].isalnum() or s[end] == "_":
                pass
            elif s[end] == "]":
                a -= 1
            else:
                break
            end += 1

        if a == 0:
            return start, end
        else:
            return 0, 0

    def getWordFromLineCol(self, line, col):
        self.clearIndicatorRange(0, 0, self.lines(), 1, self.INDICATOR_TOOLTIP)

        start, end = self.getWordRangeFromLineCol(line, col)
        word = self.getWordFromRange(line, start, end)
        if word:
            for i, line in enumerate(self.text().split('\n')):
                for match in re.finditer(r"\b%s\b" % word, line):
                    self.fillIndicatorRange(i, match.start(), i, match.end(), self.INDICATOR_TOOLTIP)


    def getWordFromRange(self, line, start, end):
        return str(self.text(line))[start:end]

    def editDoubleClicked(self, position, line, modifiers):
        line, start, end = self.getWordRangeFromPosition(position)
        w = str(self.text(line))[start:end]
        if w:
            self.signalProxy.addWatch(w)

    def showExecutionPosition(self, line):
        self.markerAdd(line, self.MARGIN_MARKER_EXEC)
        self.showLine(line)

    def showSignalPosition(self, line):
        self.markerAdd(line, self.MARGIN_MARKER_EXEC_SIGNAL)
        self.showLine(line)

    def showLine(self, line):
        self.setCursorPosition(line, 1)
        self.ensureLineVisible(line)

    def clearExecutionPositionMarkers(self):
        self.markerDeleteAll(self.MARGIN_MARKER_EXEC)

    def setMarginWidthByLineNumbers(self):
        self.setMarginWidth(0, ceil(log(self.lines(), 10)) * 10 + 5)

    def onMarginClicked(self, margin, line, _):
        # if breakpoint should be toggled
        if margin == self.MARGIN_NUMBERS or margin == self.MARGIN_MARKER_BP:
            self.toggleBreakpointWithLine(line)
        elif margin == self.MARGIN_MARKER_TP:
            self.toggleTracepointWithLine(line)

    def toggleBreakpointWithLine(self, line):
        self.__bpModel.toggleBreakpoint(self.filename, line + 1)

    def toggleTracepointWithLine(self, line):
        self.tracepointController.toggleTracepoint(self.filename, line + 1)

    def toggleTracepoint(self):
        self.toggleTracepointWithLine(self.lastContextMenuLine)

    def getBreakpointsFromModel(self):
        self.markerDeleteAll(self.MARGIN_MARKER_BP)
        self.markerDeleteAll(self.MARGIN_MARKER_BP_DIS)

        self.removeAllOverlayWidgets()
        self.breakpointOverlays = {}

        for bp in self.__bpModel.breakpoints:
            if bp.fullname == self.filename:
                self.markerAdd(bp.line - 1, self.MARGIN_MARKER_BP if bp.enabled else self.MARGIN_MARKER_BP_DIS)
                self.__addBreakpointOverlay(bp)

    def __addBreakpointOverlay(self, bp):
        if not self.__useBreakpointOverlays:
            return

        l = BreakpointOverlayWidget(self.viewport(), self.distributedObjects, bp, self.__bpModel)
        self.breakpointOverlays[bp.number] = l
        self.__updateBreakpointOverlay(bp)
        l.show()
        self.addOverlayWidget(l, int(bp.line), None, 50, 400)

    def __updateBreakpointOverlay(self, bp):
        if not self.__useBreakpointOverlays:
            return

        w = self.breakpointOverlays[bp.number]
        w.update()

    def __removeBreakpointOverlay(self, bp):
        if not self.__useBreakpointOverlays:
            return

        self.removeOverlayWidget(self.breakpointOverlays[bp.number], bp.line)

    def __validBreakpoints(self, startRow, endRow):
        for i in range(startRow, endRow + 1):
            # the column has no meaning here, all columns will return the
            # breakpoint object for role InternalDataRole
            bp = self.__bpModel.data(self.__bpModel.index(i, 0), self.__bpModel.InternalDataRole)
            if not bp.fullname == self.filename:
                continue
            yield bp

    def breakpointsInserted(self, _, start, end):
        for bp in self.__validBreakpoints(start, end):
            self.markerAdd(bp.line - 1, self.MARGIN_MARKER_BP if bp.enabled else self.MARGIN_MARKER_BP_DIS)
            self.__addBreakpointOverlay(bp)

    def breakpointsRemoved(self, _, start, end):
        for bp in self.__validBreakpoints(start, end):
            self.markerDelete(bp.line - 1, self.MARGIN_MARKER_BP)
            self.markerDelete(bp.line - 1, self.MARGIN_MARKER_BP_DIS)
            self.__removeBreakpointOverlay(bp)

    def breakpointsModified(self, topLeft, bottomRight):
        for bp in self.__validBreakpoints(topLeft.row(), bottomRight.row()):
            self.markerDelete(bp.line - 1, self.MARGIN_MARKER_BP)
            self.markerDelete(bp.line - 1, self.MARGIN_MARKER_BP_DIS)
            self.markerAdd(bp.line - 1, self.MARGIN_MARKER_BP if bp.enabled else self.MARGIN_MARKER_BP_DIS)
            self.__updateBreakpointOverlay(bp)

    def getTracepointsFromModel(self):
        """Get tracepoints from model."""
        self.markerDeleteAll(self.MARGIN_MARKER_TP)
        for tp in self.tracepointController.getTracepointsFromModel():
            if tp.fullname == self.filename:
                self.markerAdd(int(tp.line) - 1, self.MARGIN_MARKER_TP)

    def highlightLine(self, line):
        self.removeHighlightedLines()
        self.markerAdd(line, self.MARKER_HIGHLIGHTED_LINE)
        QTimer.singleShot(int(self.distributedObjects.editorController.config.highlightingDuration.value), self.removeHighlightedLines)

    def removeHighlightedLines(self):
        self.markerDeleteAll(self.MARKER_HIGHLIGHTED_LINE)

    def setDisassemble(self, enable):
        self.clearAnnotations()

        if not enable:
            return

        ret = self.distributedObjects.gdb_connector.disassemble(self.filename)

        for i in ret.asm_insns:
            assert i.dest=="src_and_asm_line"
            insns = "\n".join((j.address + " "*4 + j.inst for j in i.src.line_asm_insn))
            if insns:
                self.annotate(int(i.src.line)-1, insns, self.__disAsmStyle)