Beispiel #1
0
    def __init__(self, parent):
        super(PythonHighlighter, self).__init__(parent)
        self.rules = []

        brush = QBrush(QtCore.Qt.darkGreen, QtCore.Qt.SolidPattern)
        builtin = QTextCharFormat()
        builtin.setForeground(brush)
        builtin.setFontWeight(QFont.Bold)
        builtins = dir(__builtin__)

        for word in builtins:
            pattern = QtCore.QRegExp("\\b{w}\\b".format(w=word))
            rule = HighlightRule(pattern, builtin)
            self.rules.append(rule)

        brush = QBrush(QtCore.Qt.darkBlue, QtCore.Qt.SolidPattern)
        keyword = QTextCharFormat()
        keyword.setForeground(brush)
        keyword.setFontWeight(QFont.Bold)
        keywords = pythonkeyword.kwlist

        for word in keywords:
            pattern = QtCore.QRegExp("\\b{w}\\b".format(w=word))
            rule = HighlightRule(pattern, keyword)
            self.rules.append(rule)

        brush = QBrush(QColor.fromRgb(255, 140, 0), QtCore.Qt.SolidPattern)
        pattern = QtCore.QRegExp("#[^\n]*")
        comment = QTextCharFormat()
        comment.setForeground(brush)
        comment.setFontWeight(QFont.Light)
        rule = HighlightRule(pattern, comment)
        self.rules.append(rule)

        self.setDocument(parent.document())
Beispiel #2
0
    def resizeEvent(self, event):
        QPlainTextEdit.resizeEvent(self, event)
        contents = self.contentsRect()
        self.line_number_widget.setGeometry(
            QtCore.QRect(contents.left(), contents.top(),
                         self.line_number_widget.digits_width(),
                         contents.height()))

        # use the viewport width to determine the right edge. This allows for
        # the propper placement w/ and w/o the scrollbar
        right_pos = self.viewport().width() + self.line_number_widget.width() + 1\
            - self.status_widget.sizeHint().width()
        self.status_widget.setGeometry(
            QtCore.QRect(right_pos, contents.top(),
                         self.status_widget.sizeHint().width(),
                         contents.height()))
Beispiel #3
0
    def resizeEvent(self, event):
        super(QtTermEntryWidget, self).resizeEvent(event)

        cr = self.contentsRect()
        nr = QtCore.QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(),
                          cr.height())
        self._lineNumber.setGeometry(nr)
 def set_position(self, center, radius, pixels_displacement):
     self.setRect(
         QtCore.QRectF(
             center[0] - radius + pixels_displacement[0],
             center[1] - radius + pixels_displacement[1],
             2. * radius,
             2. * radius))
Beispiel #5
0
 def highlightBlock(self, text):
     for rule in self.rules:
         expression = QtCore.QRegExp(rule.pattern)
         index = expression.indexIn(text)
         while index >= 0:
             length = expression.matchedLength()
             self.setFormat(index, length, rule.format)
             index = expression.indexIn(text, index + length)
     self.setCurrentBlockState(0)
    def set_position(self, center, radius, pixels_displacement):
        x = center[0] + pixels_displacement[0]
        y = center[1] + pixels_displacement[1]

        self.setRect(QtCore.QRectF(x, y, 2. * radius, 2. * radius))

        import math
        self.setTransformOriginPoint(QPointF(x, y))
        self.setRotation(math.degrees(self._rotation_in_radians))
Beispiel #7
0
    def paintEvent(self, event):
        """ Paint the line numbers.
        """
        with painter_on(self, antialias=True) as painter:
            if self.background_color is not None:
                painter.fillRect(event.rect(), self.background_color)

            cw = self.parent()

            pixels_per_block = self.height() / float(cw.blockCount())

            for line in self.info_lines:
                painter.fillRect(QtCore.QRect(0, line * pixels_per_block, self.width(), 3),
                                 QtCore.Qt.green)

            for line in self.warn_lines:
                painter.fillRect(QtCore.QRect(0, line * pixels_per_block, self.width(), 3),
                                 QtCore.Qt.yellow)

            for line in self.error_lines:
                painter.fillRect(QtCore.QRect(0, line * pixels_per_block, self.width(), 3),
                                 QtCore.Qt.red)
Beispiel #8
0
    def sizeHint(self):
        from pyvmmonitor_qt.qt.QtWidgets import QStyleOptionHeader
        from pyvmmonitor_qt.qt.QtWidgets import QStyle
        from pyvmmonitor_qt.qt.QtGui import QFontMetrics

        # Suggest a size that is 80 characters wide and 40 lines tall.
        style = self.style()
        opt = QStyleOptionHeader()
        font_metrics = QFontMetrics(self.document().defaultFont())
        width = font_metrics.width(' ') * 80
        width += self.line_number_widget.sizeHint().width()
        width += self.status_widget.sizeHint().width()
        width += style.pixelMetric(QStyle.PM_ScrollBarExtent, opt, self)
        height = font_metrics.height() * 40
        return QtCore.QSize(width, height)
Beispiel #9
0
class OutputRedirect(QtCore.QObject):

    output = QtCore.Signal(str)

    def __init__(self, tee=True, parent=None):
        super(OutputRedirect, self).__init__(parent)
        self._handle = None
        self._tee = tee

    def __enter__(self):
        self._handle = sys.stdout
        sys.stdout = self
        return self

    def __exit__(self, type, value, traceback):
        sys.stdout = self._handle

    def write(self, msg):
        self.output.emit(msg)
        if self._tee:
            self._handle.write(msg)
Beispiel #10
0
def _set_expanded_nodes_tree(widget,
                             nodes_tree=None,
                             parent_index=None,
                             data=QtCore.Qt.DisplayRole):
    '''
    We have to find a tree subpath which matches the passed path (in nodes_tree) and expand it
    accordingly.

    :param NodesTree nodes_tree:
    '''
    if not nodes_tree.children:
        return True

    model = widget.model()
    if parent_index is None:
        parent_index = QtCore.QModelIndex()
    row_count = model.rowCount(parent_index)

    found = 0

    for row in compat.xrange(row_count):
        index = model.index(row, 0, parent_index)

        model_data = model.data(index, data)
        for node in nodes_tree.children:
            if node.data == model_data:
                # Ok, we have a match on this subtree (expand even if it means expanding
                # only partially).
                widget.setExpanded(index, True)

                # Ok, we have a possible match, let's go forward on this node
                if _set_expanded_nodes_tree(widget,
                                            nodes_tree=node,
                                            parent_index=index):
                    found += 1

    return found == len(nodes_tree.children)
Beispiel #11
0
def _get_expanded_nodes_tree(widget,
                             parent_index=None,
                             parent_node=None,
                             data=QtCore.Qt.DisplayRole):
    '''
    :return NodesTree:
        Returns a tree with the paths for the passed data.
    '''
    model = widget.model()
    if parent_index is None:
        parent_index = QtCore.QModelIndex()
    row_count = model.rowCount(parent_index)

    if parent_node is None:
        parent_node = NodesTree()

    for row in compat.xrange(row_count):
        index = model.index(row, 0, parent_index)
        if not widget.isExpanded(index):
            continue
        node = parent_node.add_child(Node(model.data(index, data)))
        _get_expanded_nodes_tree(widget, parent_index=index, parent_node=node)

    return parent_node
Beispiel #12
0
 def sizeHint(self):
     return QtCore.QSize(10, 0)
Beispiel #13
0
 def sizeHint(self):
     return QtCore.QSize(self.min_width, 0)
Beispiel #14
0
 def sizeHint(self):
     return QtCore.QSize(self.digits_width(), 0)
Beispiel #15
0
def iter_widget_captions_and_items(
        widget,
        parent_index=None,
        prefix='',
        cols=(
            0,
        ),
        only_show_expanded=False,
        add_plus_to_new_level=True):

    from pyvmmonitor_qt.custom_close_tab_widget import CustomCloseTabWidget
    from pyvmmonitor_qt.qt.QtWidgets import QMdiArea
    from pyvmmonitor_qt.qt.QtWidgets import QTabWidget
    from pyvmmonitor_qt.qt.QtWidgets import QAbstractItemView

    if isinstance(widget, QMdiArea):
        for sub in widget.subWindowList():
            yield sub.windowTitle(), sub

    elif isinstance(widget, (QTabWidget, CustomCloseTabWidget)):
        sz = widget.count()
        while sz > 0:
            sz -= 1
            txt = widget.tabText(sz)
            yield txt, widget.widget(sz)

    elif isinstance(widget, QAbstractItemView):
        model = widget.model()
        if parent_index is None:
            parent_index = QtCore.QModelIndex()
        row_count = model.rowCount(parent_index)

        for row in compat.xrange(row_count):
            index = model.index(row, 0, parent_index)
            row_items = []

            for col in cols:
                index_in_col = model.index(row, col, parent_index)
                data = model.data(index_in_col, QtCore.Qt.DisplayRole)
                if data is None:
                    data = ''
                row_items.append(
                    prefix + data)

            if len(cols) > 1:
                yield row_items, index
            else:
                yield row_items[0], index

            if only_show_expanded and hasattr(widget, 'isExpanded'):
                index = model.index(row, 0, parent_index)
                if not widget.isExpanded(index):
                    continue

            for x in iter_widget_captions_and_items(
                    widget,
                    index,
                    prefix + '+' if add_plus_to_new_level else prefix,
                    cols,
                    only_show_expanded=only_show_expanded,
                    add_plus_to_new_level=add_plus_to_new_level):
                yield x
    else:
        raise AssertionError("Don't know how to list items for: %s" % (widget,))
Beispiel #16
0
class QtTermEntryWidget(QPlainTextEdit):

    traceback = QtCore.Signal(int)
    syntaxError = QtCore.Signal(int)

    def __init__(self, parent=None):
        super(QtTermEntryWidget, self).__init__(parent)

        self._termWidget = parent
        font = QFont("Monaco")
        font.setStyleHint(font.TypeWriter, font.PreferDefault)
        self.setFont(font)

        self._lineNumber = QtTermEntryLineNumberWidget(self)
        self._highlighter = PythonHighlighter(self)

        self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
        self.updateRequest.connect(self.updateLineNumberArea)
        self.cursorPositionChanged.connect(self.highlightCurrentLine)

        self.updateLineNumberAreaWidth(0)
        self.highlightCurrentLine()

        self.executeAction = QAction('Execute Python', self)
        self.executeAction.setShortcut(QKeySequence("Ctrl+Return"))
        self.executeAction.triggered.connect(self.execute)
        self.addAction(self.executeAction)

        self.syntaxError.connect(self.displaySyntaxError)

        self.stdoutRedirect = OutputRedirect()

        self._locals = {}

    def displaySyntaxError(self, line):

        sel = QTextEdit.ExtraSelection()
        lineColor = QColor(QtCore.Qt.red).lighter(150)
        sel.format.setBackground(QBrush(lineColor, QtCore.Qt.SolidPattern))
        sel.format.setProperty(QTextFormat.FullWidthSelection, True)
        sel.cursor = QTextCursor(self.document())
        sel.cursor.movePosition(sel.cursor.NextBlock, QTextCursor.MoveAnchor,
                                line - 1)
        sel.cursor.clearSelection()
        extraSelections = [sel]

        self.setExtraSelections(extraSelections)

    def execute(self):
        script = self.toPlainText()

        try:
            script_code = compile(script, '<interactive interpreter>', 'exec')
        except (SyntaxError) as e:
            self.syntaxError.emit(e.lineno)
            return
        with self.stdoutRedirect:
            try:
                exec(script_code, globals(), self._locals)
            except (StandardError) as e:  # Which error should this be?
                type_, value_, traceback_ = sys.exc_info()
                tb = traceback.extract_tb(traceback_)

                index = self._termWidget.storeTraceback(tb)
                self.traceback.emit(index)

    def lineNumberAreaPaintEvent(self, event):
        painter = QPainter(self._lineNumber)
        painter.fillRect(event.rect(), QColor.fromRgb(200, 200, 200))
        block = self.firstVisibleBlock()
        blockNumber = block.blockNumber()
        top = int(
            self.blockBoundingGeometry(block).translated(
                self.contentOffset()).top())
        bottom = top + int(self.blockBoundingRect(block).height())

        while block.isValid() and top <= event.rect().bottom():
            if block.isVisible() and bottom >= event.rect().top():
                number = str(blockNumber + 1)
                painter.setPen(QtCore.Qt.black)
                painter.drawText(0, top, self._lineNumber.width(),
                                 self.fontMetrics().height(),
                                 QtCore.Qt.AlignRight, number)

            block = block.next()
            top = bottom
            bottom = top + int(self.blockBoundingRect(block).height())
            blockNumber += 1

    def highlightCurrentLine(self):

        sel = QTextEdit.ExtraSelection()
        lineColor = QColor(QtCore.Qt.gray).lighter(150)
        sel.format.setBackground(QBrush(lineColor, QtCore.Qt.DiagCrossPattern))
        sel.format.setProperty(QTextFormat.FullWidthSelection, True)
        sel.cursor = self.textCursor()
        sel.cursor.clearSelection()
        extraSelections = [sel]

        self.setExtraSelections(extraSelections)

    def updateLineNumberArea(self, area, num):
        if (num):
            self._lineNumber.scroll(0, num)
        else:
            self._lineNumber.update(0, area.y(), self._lineNumber.width(),
                                    area.height())

        if area.contains(self.viewport().rect()):
            self.updateLineNumberAreaWidth(0)

    def updateLineNumberAreaWidth(self, num):
        self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)

    def lineNumberAreaWidth(self):
        digits = math.floor(math.log10(self.blockCount())) + 1
        space = 3 + self.fontMetrics().width('9') * digits
        return space

    def resizeEvent(self, event):
        super(QtTermEntryWidget, self).resizeEvent(event)

        cr = self.contentsRect()
        nr = QtCore.QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(),
                          cr.height())
        self._lineNumber.setGeometry(nr)