Esempio n. 1
0
def show(cursor, pos=None, num_lines=6):
    """Displays a tooltip showing part of the cursor's Document.
    
    If the cursor has a selection, those blocks are displayed.
    Otherwise, num_lines lines are displayed.
    
    If pos is not given, the global mouse position is used.
    
    """
    block = cursor.document().findBlock(cursor.selectionStart())
    c2 = QTextCursor(block)
    if cursor.hasSelection():
        c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor)
        c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    else:
        c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines)
    
    data = textformats.formatData('editor')
    
    doc = QTextDocument()
    font = QFont(data.font)
    font.setPointSizeF(font.pointSizeF() * .8)
    doc.setDefaultFont(font)
    doc.setPlainText(c2.selection().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlighter.highlight(doc, state=tokeniter.state(block))
    size = doc.size().toSize() + QSize(8, -4)
    pix = QPixmap(size)
    pix.fill(data.baseColors['background'])
    doc.drawContents(QPainter(pix))
    label = QLabel()
    label.setPixmap(pix)
    label.setStyleSheet("QLabel { border: 1px solid #777; }")
    label.resize(size)
    widgets.customtooltip.show(label, pos)
Esempio n. 2
0
 def loadSettings(self):
     s = QSettings()
     s.beginGroup("log")
     font = QFont(s.value("fontfamily", "monospace"))
     font.setPointSizeF(float(s.value("fontsize", 9.0)))
     with qutil.signalsBlocked(self.fontChooser, self.fontSize):
         self.fontChooser.setCurrentFont(font)
         self.fontSize.setValue(font.pointSizeF())
     self.showlog.setChecked(s.value("show_on_start", True) not in (False, "false"))
     self.rawview.setChecked(s.value("rawview", True) not in (False, "false"))
Esempio n. 3
0
 def loadSettings(self):
     s = QSettings()
     s.beginGroup("log")
     font = QFont(s.value("fontfamily", "monospace", type("")))
     font.setPointSizeF(s.value("fontsize", 9.0, float))
     with qutil.signalsBlocked(self.fontChooser, self.fontSize):
         self.fontChooser.setCurrentFont(font)
         self.fontSize.setValue(font.pointSizeF())
     self.showlog.setChecked(s.value("show_on_start", True, bool))
     self.rawview.setChecked(s.value("rawview", True, bool))
     self.hideauto.setChecked(s.value("hide_auto_engrave", False, bool))
Esempio n. 4
0
 def loadSettings(self):
     s = QSettings()
     s.beginGroup("log")
     font = QFont(s.value("fontfamily", "monospace", type("")))
     font.setPointSizeF(s.value("fontsize", 9.0, float))
     with qutil.signalsBlocked(self.fontChooser, self.fontSize):
         self.fontChooser.setCurrentFont(font)
         self.fontSize.setValue(font.pointSizeF())
     self.showlog.setChecked(s.value("show_on_start", True, bool))
     self.rawview.setChecked(s.value("rawview", True, bool))
     self.hideauto.setChecked(s.value("hide_auto_engrave", False, bool))
Esempio n. 5
0
def show(cursor, pos=None, num_lines=6):
    """Displays a tooltip showing part of the cursor's Document.
    
    If the cursor has a selection, those blocks are displayed.
    Otherwise, num_lines lines are displayed.
    
    If pos is not given, the global mouse position is used.
    
    """
    block = cursor.document().findBlock(cursor.selectionStart())
    c2 = QTextCursor(block)
    if cursor.hasSelection():
        c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor)
        c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    else:
        c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor,
                        num_lines)

    data = textformats.formatData('editor')

    doc = QTextDocument()
    font = QFont(data.font)
    font.setPointSizeF(font.pointSizeF() * .8)
    doc.setDefaultFont(font)
    doc.setPlainText(c2.selection().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlighter.highlight(doc, state=tokeniter.state(block))
    size = doc.size().toSize() + QSize(8, -4)
    pix = QPixmap(size)
    pix.fill(data.baseColors['background'])
    doc.drawContents(QPainter(pix))
    label = QLabel()
    label.setPixmap(pix)
    label.setStyleSheet("QLabel { border: 1px solid #777; }")
    label.resize(size)
    widgets.customtooltip.show(label, pos)
Esempio n. 6
0
    def draw(self, painter, size=None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport()  # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError(
                    "Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w / 5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i / nb_values))
            gr.setColorAt(i / nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [str(i) * 5 for i in range(10)]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width = max(lim_width, rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1 - length) / 2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1] - value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length * w, shift_width * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1 - shift_width - width) * w,
                                shift_length * h, width * w, length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length * w,
                                (1 - shift_width - width) * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width * w, shift_length * h, width * w,
                                length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos - start_pos) / delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
        # Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar - max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar - max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
        #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts, t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos + shift_pos * (t - value_range[0])
            if shift_left is None:
                pos.setX(pos.x() - r.width() / 2)
            else:
                pos.setX(pos.x() + shift_left)
            if shift_top is None:
                pos.setY(pos.y() - r.height() / 2)
            else:
                pos.setY(pos.y() + shift_top)
            r.moveTo(pos)
            real_rect = painter.drawText(
                r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size * exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size * exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width() + exp_r.width() + unit_r.width()
            total_height = max(r.height(),
                               unit_r.height()) + exp_r.height() / 2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w, h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else:  # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width) / 2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x() + total_width + dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(
                    r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    exp_txt)
                bounding_rect |= real_rect
                pos.setX(pos.x() + r.width())
                pos.setY(pos.y() - metric.ascent() / 2)
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(
                    exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent() / 2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(
                    unit_r,
                    Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width() * tick_size
        else:
            width = scale_rect.height() * tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos * (t - value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width,
                                               pen_width, pen_width)
        return bounding_rect
Esempio n. 7
0
class CharMap(QWidget):
    """A widget displaying a table of characters."""
    characterSelected = pyqtSignal(str)
    characterClicked = pyqtSignal(str)

    def __init__(self, parent=None):
        super(CharMap, self).__init__(parent)
        self._showToolTips = True
        self._showWhatsThis = True
        self._selected = -1
        self._column_count = 32
        self._square = 24
        self._range = (0, 0)
        self._font = QFont()

    def setRange(self, first, last):
        self._range = (first, last)
        self._selected = -1
        self.adjustSize()
        self.update()

    def range(self):
        return self._range

    def square(self):
        """Returns the width of one item (determined by font size)."""
        return self._square

    def select(self, charcode):
        """Selects the specified character (int or str)."""
        if not isinstance(charcode, int):
            charcode = ord(charcode)
        if not self._range[0] <= charcode <= self._range[1]:
            charcode = -1
        if self._selected != charcode:
            self._selected = charcode
            self.characterSelected.emit(chr(charcode))
            self.update()

    def character(self):
        """Returns the currently selected character, if any."""
        if self._selected != -1:
            return chr(self._selected)

    def setDisplayFont(self, font):
        self._font.setFamily(font.family())
        self.update()

    def displayFont(self):
        return QFont(self._font)

    def setDisplayFontSize(self, size):
        self._font.setPointSize(size)
        self._square = max(24, QFontMetrics(self._font).xHeight() * 3)
        self.adjustSize()
        self.update()

    def displayFontSize(self):
        return self._font.pointSize()

    def setDisplayFontSizeF(self, size):
        self._font.setPointSizeF(size)
        self._square = max(24, QFontMetrics(self._font).xHeight() * 3)
        self.adjustSize()
        self.update()

    def displayFontSizeF(self):
        return self._font.pointSizeF()

    def setColumnCount(self, count):
        """Sets how many columns should be used."""
        count = max(1, count)
        self._column_count = count
        self.adjustSize()
        self.update()

    def columnCount(self):
        return self._column_count

    def sizeHint(self):
        return self.sizeForColumnCount(self._column_count)

    def paintEvent(self, ev):
        rect = ev.rect()
        s = self._square
        rows = range(rect.top() // s, rect.bottom() // s + 1)
        cols = range(rect.left() // s, rect.right() // s + 1)

        painter = QPainter(self)
        painter.setPen(QPen(self.palette().color(QPalette.Window)))
        painter.setFont(self._font)
        metrics = QFontMetrics(self._font)

        # draw characters on white tiles
        tile = self.palette().color(QPalette.Base)
        selected_tile = self.palette().color(QPalette.Highlight)
        selected_tile.setAlpha(96)
        selected_box = self.palette().color(QPalette.Highlight)

        text_pen = QPen(self.palette().text())
        disabled_pen = QPen(self.palette().color(QPalette.Disabled,
                                                 QPalette.Text))
        selection_pen = QPen(selected_box)
        for row in rows:
            for col in cols:
                char = row * self._column_count + col + self._range[0]
                if char > self._range[1]:
                    break
                printable = self.isprint(char)
                painter.setClipRect(col * s, row * s, s, s)
                if char == self._selected:
                    painter.fillRect(col * s + 1, row * s + 1, s - 2, s - 2,
                                     selected_tile)
                    painter.setPen(selection_pen)
                    painter.drawRect(col * s, row * s, s - 1, s - 1)
                elif printable:
                    painter.fillRect(col * s + 1, row * s + 1, s - 2, s - 2,
                                     tile)
                painter.setPen(text_pen if printable else disabled_pen)
                t = chr(char)
                x = col * s + s // 2 - metrics.width(t) // 2
                y = row * s + 4 + metrics.ascent()
                painter.drawText(x, y, t)
            else:
                continue
            break

    def sizeForColumnCount(self, count):
        """Returns the size the widget would have in a certain column count.
        
        This can be used in e.g. a resizable scroll area.
        
        """
        first, last = self._range
        rows = ((last - first) // count) + 1
        return QSize(count, rows) * self._square

    def columnCountForWidth(self, width):
        """Returns the number of columns that would fit into the given width."""
        return width // self._square

    def mousePressEvent(self, ev):
        charcode = self.charcodeAt(ev.pos())
        if charcode != -1 and self.isprint(charcode):
            self.select(charcode)
            if ev.button() != Qt.RightButton:
                self.characterClicked.emit(chr(charcode))

    def charcodeRect(self, charcode):
        """Returns the rectangular box around the given charcode, if any."""
        if self._range[0] <= charcode <= self._range[1]:
            row, col = divmod(charcode - self._range[0], self._column_count)
            s = self._square
            return QRect(col * s, row * s, s, s)

    def charcodeAt(self, position):
        row = position.y() // self._square
        col = position.x() // self._square
        if col <= self._column_count:
            charcode = self._range[0] + row * self._column_count + col
            if charcode <= self._range[1]:
                return charcode
        return -1

    def event(self, ev):
        if ev.type() == QEvent.ToolTip:
            if self._showToolTips:
                c = self.charcodeAt(ev.pos())
                if c:
                    text = self.getToolTipText(c)
                    if text:
                        rect = self.charcodeRect(c)
                        QToolTip.showText(ev.globalPos(), text, self, rect)
                        ev.accept()
                        return True
        elif ev.type() == QEvent.QueryWhatsThis:
            if self._showWhatsThis:
                ev.accept()
                return True
        elif ev.type() == QEvent.WhatsThis:
            ev.accept()
            if self._showWhatsThis:
                c = self.charcodeAt(ev.pos())
                text = self.getWhatsThisText(c) if c else None
                if text:
                    QWhatsThis.showText(ev.globalPos(), text, self)
                else:
                    QWhatsThis.leaveWhatsThisMode()
            return True
        return super(CharMap, self).event(ev)

    def getToolTipText(self, charcode):
        try:
            return unicodedata.name(chr(charcode))
        except ValueError:
            pass

    def getWhatsThisText(self, charcode):
        try:
            name = unicodedata.name(chr(charcode))
        except ValueError:
            return
        return whatsthis_html.format(self._font.family(), chr(charcode), name,
                                     charcode)

    def setShowToolTips(self, enabled):
        self._showToolTips = bool(enabled)

    def showToolTips(self):
        return self._showToolTips

    def setShowWhatsThis(self, enabled):
        self._showWhatsThis = bool(enabled)

    def showWhatsThis(self):
        return self._showWhatsThis

    def isprint(self, charcode):
        """Returns True if the given charcode is printable."""
        return isprint(charcode)
Esempio n. 8
0
class CharMap(QWidget):
    """A widget displaying a table of characters."""
    characterSelected = pyqtSignal(str)
    characterClicked = pyqtSignal(str)
    
    def __init__(self, parent=None):
        super(CharMap, self).__init__(parent)
        self._showToolTips = True
        self._showWhatsThis = True
        self._selected = -1
        self._column_count = 32
        self._square = 24
        self._range = (0, 0)
        self._font = QFont()
        
    def setRange(self, first, last):
        self._range = (first, last)
        self._selected = -1
        self.adjustSize()
        self.update()
    
    def range(self):
        return self._range
    
    def square(self):
        """Returns the width of one item (determined by font size)."""
        return self._square
    
    def select(self, charcode):
        """Selects the specified character (int or str)."""
        if not isinstance(charcode, int):
            charcode = ord(charcode)
        if not self._range[0] <= charcode <= self._range[1]:
            charcode = -1
        if self._selected != charcode:
            self._selected = charcode
            self.characterSelected.emit(chr(charcode))
            self.update()
    
    def character(self):
        """Returns the currently selected character, if any."""
        if self._selected != -1:
            return chr(self._selected)
    
    def setDisplayFont(self, font):
        self._font.setFamily(font.family())
        self.update()
    
    def displayFont(self):
        return QFont(self._font)
    
    def setDisplayFontSize(self, size):
        self._font.setPointSize(size)
        self._square = max(24, QFontMetrics(self._font).xHeight() * 3)
        self.adjustSize()
        self.update()
    
    def displayFontSize(self):
        return self._font.pointSize()
    
    def setDisplayFontSizeF(self, size):
        self._font.setPointSizeF(size)
        self._square = max(24, QFontMetrics(self._font).xHeight() * 3)
        self.adjustSize()
        self.update()
    
    def displayFontSizeF(self):
        return self._font.pointSizeF()
    
    def setColumnCount(self, count):
        """Sets how many columns should be used."""
        count = max(1, count)
        self._column_count = count
        self.adjustSize()
        self.update()
    
    def columnCount(self):
        return self._column_count
        
    def sizeHint(self):
        return self.sizeForColumnCount(self._column_count)

    def paintEvent(self, ev):
        rect = ev.rect()
        s = self._square
        rows = range(rect.top() // s, rect.bottom() // s + 1)
        cols = range(rect.left() // s, rect.right() // s + 1)
        
        painter = QPainter(self)
        painter.setPen(QPen(self.palette().color(QPalette.Window)))
        painter.setFont(self._font)
        metrics = QFontMetrics(self._font)
        
        # draw characters on white tiles
        tile = self.palette().color(QPalette.Base)
        selected_tile = self.palette().color(QPalette.Highlight)
        selected_tile.setAlpha(96)
        selected_box = self.palette().color(QPalette.Highlight)
        
        text_pen = QPen(self.palette().text())
        disabled_pen = QPen(self.palette().color(QPalette.Disabled, QPalette.Text))
        selection_pen = QPen(selected_box)
        for row in rows:
            for col in cols:
                char = row * self._column_count + col + self._range[0]
                if char > self._range[1]:
                    break
                printable = self.isprint(char)
                painter.setClipRect(col * s, row * s, s, s)
                if char == self._selected:
                    painter.fillRect(col * s + 1, row * s + 1, s - 2, s - 2, selected_tile)
                    painter.setPen(selection_pen)
                    painter.drawRect(col * s, row * s, s - 1, s - 1)
                elif printable:
                    painter.fillRect(col * s + 1, row * s + 1, s - 2, s - 2, tile)
                painter.setPen(text_pen if printable else disabled_pen)
                t = chr(char)
                x = col * s + s // 2 - metrics.width(t) // 2
                y = row * s + 4 + metrics.ascent()
                painter.drawText(x, y, t)
            else:
                continue
            break
    
    def sizeForColumnCount(self, count):
        """Returns the size the widget would have in a certain column count.
        
        This can be used in e.g. a resizable scroll area.
        
        """
        first, last = self._range
        rows = ((last - first) // count) + 1
        return QSize(count, rows) * self._square

    def columnCountForWidth(self, width):
        """Returns the number of columns that would fit into the given width."""
        return width // self._square

    def mousePressEvent(self, ev):
        charcode = self.charcodeAt(ev.pos())
        if charcode != -1 and self.isprint(charcode):
            self.select(charcode)
            if ev.button() != Qt.RightButton:
                self.characterClicked.emit(chr(charcode))
    
    def charcodeRect(self, charcode):
        """Returns the rectangular box around the given charcode, if any."""
        if self._range[0] <= charcode <= self._range[1]:
            row, col = divmod(charcode - self._range[0], self._column_count)
            s = self._square
            return QRect(col * s, row * s, s, s)
        
    def charcodeAt(self, position):
        row = position.y() // self._square
        col = position.x() // self._square
        if col <= self._column_count:
            charcode = self._range[0] + row * self._column_count + col
            if charcode <= self._range[1]:
                return charcode
        return -1

    def event(self, ev):
        if ev.type() == QEvent.ToolTip:
            if self._showToolTips:
                c = self.charcodeAt(ev.pos())
                if c:
                    text = self.getToolTipText(c)
                    if text:
                        rect = self.charcodeRect(c)
                        QToolTip.showText(ev.globalPos(), text, self, rect)
                        ev.accept()
                        return True
        elif ev.type() == QEvent.QueryWhatsThis:
            if self._showWhatsThis:
                ev.accept()
                return True
        elif ev.type() == QEvent.WhatsThis:
            ev.accept()
            if self._showWhatsThis:
                c = self.charcodeAt(ev.pos())
                text = self.getWhatsThisText(c) if c else None
                if text:
                    QWhatsThis.showText(ev.globalPos(), text, self)
                else:
                    QWhatsThis.leaveWhatsThisMode()
            return True
        return super(CharMap, self).event(ev)
    
    def getToolTipText(self, charcode):
        try:
            return unicodedata.name(chr(charcode))
        except ValueError:
            pass
    
    def getWhatsThisText(self, charcode):
        try:
            name = unicodedata.name(chr(charcode))
        except ValueError:
            return
        return whatsthis_html.format(
            self._font.family(), chr(charcode), name, charcode)
    
    def setShowToolTips(self, enabled):
        self._showToolTips = bool(enabled)
    
    def showToolTips(self):
        return self._showToolTips

    def setShowWhatsThis(self, enabled):
        self._showWhatsThis = bool(enabled)
    
    def showWhatsThis(self):
        return self._showWhatsThis

    def isprint(self, charcode):
        """Returns True if the given charcode is printable."""
        return isprint(charcode)
Esempio n. 9
0
class TextFormatData(object):
    """Encapsulates all settings in the Fonts & Colors page for a scheme."""
    def __init__(self, scheme):
        """Loads the data from scheme."""
        self.font = None
        self.baseColors = {}
        self.defaultStyles = {}
        self.allStyles = {}
        self.load(scheme)
        
    def load(self, scheme):
        """Load the settings for the scheme. Called on init."""
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # load font
        self.font = QFont(s.value("fontfamily", "monospace"))
        self.font.setPointSizeF(float(s.value("fontsize", 10.0)))
        
        # load base colors
        s.beginGroup("basecolors")
        for name in baseColors:
            if s.contains(name):
                self.baseColors[name] = QColor(s.value(name))
            else:
                self.baseColors[name] = baseColorDefaults[name]()
        s.endGroup()
        
        # load default styles
        s.beginGroup("defaultstyles")
        for name in defaultStyles:
            self.defaultStyles[name] = f = QTextCharFormat(defaultStyleDefaults[name])
            s.beginGroup(name)
            self.loadTextFormat(f, s)
            s.endGroup()
        s.endGroup()
        
        # load specific styles
        s.beginGroup("allstyles")
        for group, styles in allStyles:
            self.allStyles[group]= {}
            s.beginGroup(group)
            for name in styles:
                default = allStyleDefaults[group].get(name)
                self.allStyles[group][name] = f = QTextCharFormat(default) if default else QTextCharFormat()
                s.beginGroup(name)
                self.loadTextFormat(f, s)
                s.endGroup()
            s.endGroup()
        s.endGroup()
        
    def save(self, scheme):
        """Save the settings to the scheme."""
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # save font
        s.setValue("fontfamily", self.font.family())
        s.setValue("fontsize", self.font.pointSizeF())
        
        # save base colors
        for name in baseColors:
            s.setValue("basecolors/"+name, self.baseColors[name].name())
        
        # save default styles
        s.beginGroup("defaultstyles")
        for name in defaultStyles:
            s.beginGroup(name)
            self.saveTextFormat(self.defaultStyles[name], s)
            s.endGroup()
        s.endGroup()
        
        # save all specific styles
        s.beginGroup("allstyles")
        for group, styles in allStyles:
            s.beginGroup(group)
            for name in styles:
                s.beginGroup(name)
                self.saveTextFormat(self.allStyles[group][name], s)
                s.endGroup()
            s.endGroup()
        s.endGroup()

    def textFormat(self, group, name):
        """Return a QTextCharFormat() for the specified group and name."""
        inherit = inherits[group].get(name)
        f = QTextCharFormat(self.defaultStyles[inherit]) if inherit else QTextCharFormat()
        f.merge(self.allStyles[group][name])
        return f
    
    def palette(self):
        """Return a basic palette with text, background, selection and selection background filled in."""
        p = QApplication.palette()
        p.setColor(QPalette.Text, self.baseColors['text'])
        p.setColor(QPalette.Base, self.baseColors['background'])
        p.setColor(QPalette.HighlightedText, self.baseColors['selectiontext'])
        p.setColor(QPalette.Highlight, self.baseColors['selectionbackground'])
        return p
        
    def saveTextFormat(self, fmt, settings):
        """(Internal) Store one QTextCharFormat in the QSettings instance."""
        if fmt.hasProperty(QTextFormat.FontWeight):
            settings.setValue('bold', fmt.fontWeight() >= 70)
        else:
            settings.remove('bold')
        if fmt.hasProperty(QTextFormat.FontItalic):
            settings.setValue('italic', fmt.fontItalic())
        else:
            settings.remove('italic')
        if fmt.hasProperty(QTextFormat.TextUnderlineStyle):
            settings.setValue('underline', fmt.fontUnderline())
        else:
            settings.remove('underline')
        if fmt.hasProperty(QTextFormat.ForegroundBrush):
            settings.setValue('textColor', fmt.foreground().color().name())
        else:
            settings.remove('textColor')
        if fmt.hasProperty(QTextFormat.BackgroundBrush):
            settings.setValue('backgroundColor', fmt.background().color().name())
        else:
            settings.remove('backgroundColor')
        if fmt.hasProperty(QTextFormat.TextUnderlineColor):
            settings.setValue('underlineColor', fmt.underlineColor().name())
        else:
            settings.remove('underlineColor')
        
    def loadTextFormat(self, fmt, settings):
        """(Internal) Merge values from the QSettings instance into the QTextCharFormat."""
        if settings.contains('bold'):
            fmt.setFontWeight(QFont.Bold if settings.value('bold') in (True, 'true') else QFont.Normal)
        if settings.contains('italic'):
            fmt.setFontItalic(settings.value('italic') in (True, 'true'))
        if settings.contains('underline'):
            fmt.setFontUnderline(settings.value('underline') in (True, 'true'))
        if settings.contains('textColor'):
            fmt.setForeground(QColor(settings.value('textColor')))
        if settings.contains('backgroundColor'):
            fmt.setBackground(QColor(settings.value('backgroundColor')))
        if settings.contains('underlineColor'):
            fmt.setUnderlineColor(QColor(settings.value('underlineColor')))
Esempio n. 10
0
class TextFormatData(object):
    """Encapsulates all settings in the Fonts & Colors page for a scheme."""
    def __init__(self, scheme):
        """Loads the data from scheme."""
        self.font = None
        self.baseColors = {}
        self.defaultStyles = {}
        self.allStyles = {}
        self.load(scheme)
        
    def load(self, scheme):
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # load font
        self.font = QFont(s.value("fontfamily", "monospace"))
        self.font.setPointSizeF(float(s.value("fontsize", 10.0)))
        
        # load base colors
        s.beginGroup("basecolors")
        for name in baseColors:
            if s.contains(name):
                self.baseColors[name] = QColor(s.value(name))
            else:
                self.baseColors[name] = baseColorDefaults[name]()
        s.endGroup()
        
        # load default styles
        s.beginGroup("defaultstyles")
        for name in defaultStyles:
            self.defaultStyles[name] = f = QTextCharFormat(defaultStyleDefaults[name])
            s.beginGroup(name)
            loadTextFormat(f, s)
            s.endGroup()
        s.endGroup()
        
        # load specific styles
        s.beginGroup("allstyles")
        for group, styles in allStyles:
            self.allStyles[group]= {}
            s.beginGroup(group)
            for name in styles:
                default = allStyleDefaults[group].get(name)
                self.allStyles[group][name] = f = QTextCharFormat(default) if default else QTextCharFormat()
                s.beginGroup(name)
                loadTextFormat(f, s)
                s.endGroup()
            s.endGroup()
        s.endGroup()
        
    def save(self, scheme):
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # save font
        s.setValue("fontfamily", self.font.family())
        s.setValue("fontsize", self.font.pointSizeF())
        
        # save base colors
        for name in baseColors:
            s.setValue("basecolors/"+name, self.baseColors[name].name())
        
        # save default styles
        s.beginGroup("defaultstyles")
        for name in defaultStyles:
            s.beginGroup(name)
            saveTextFormat(self.defaultStyles[name], s)
            s.endGroup()
        s.endGroup()
        
        # save all specific styles
        s.beginGroup("allstyles")
        for group, styles in allStyles:
            s.beginGroup(group)
            for name in styles:
                s.beginGroup(name)
                saveTextFormat(self.allStyles[group][name], s)
                s.endGroup()
            s.endGroup()
        s.endGroup()

    def textFormat(self, group, name):
        inherit = inherits[group].get(name)
        f = QTextCharFormat(self.defaultStyles[inherit]) if inherit else QTextCharFormat()
        f.merge(self.allStyles[group][name])
        return f
    
    def palette(self):
        """Returns a basic palette with text, background, selection and selection background filled in."""
        p = QApplication.palette()
        p.setColor(QPalette.Text, self.baseColors['text'])
        p.setColor(QPalette.Base, self.baseColors['background'])
        p.setColor(QPalette.HighlightedText, self.baseColors['selectiontext'])
        p.setColor(QPalette.Highlight, self.baseColors['selectionbackground'])
        return p
Esempio n. 11
0
    def draw(self, painter, size = None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport() # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError("Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w/5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i/nb_values))
            gr.setColorAt(i/nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [ str(i)*5 for i in range(10) ]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width  = max(lim_width,  rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1-length)/2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1]-value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length*w, shift_width*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1-shift_width-width)*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length*w, (1-shift_width-width)*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos-start_pos)/delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
# Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar-max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar-max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
            #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts,t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos+shift_pos*(t-value_range[0])
            if shift_left is None:
                pos.setX( pos.x() - r.width()/2 )
            else:
                pos.setX( pos.x() + shift_left )
            if shift_top is None:
                pos.setY( pos.y() - r.height()/2)
            else:
                pos.setY( pos.y() + shift_top )
            r.moveTo(pos)
            real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size*exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size*exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width()+exp_r.width()+unit_r.width()
            total_height = max(r.height(),unit_r.height())+exp_r.height()/2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w,h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else: # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width)/2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x()+total_width+dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, exp_txt)
                bounding_rect |= real_rect
                pos.setX( pos.x() + r.width() )
                pos.setY( pos.y() - metric.ascent()/2 )
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent()/2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(unit_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width()*tick_size
        else:
            width = scale_rect.height()*tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos*(t-value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width, pen_width, pen_width)
        return bounding_rect
Esempio n. 12
0
class TextFormatData(object):
    """Encapsulates all settings in the Fonts & Colors page for a scheme."""
    def __init__(self, scheme):
        """Loads the data from scheme."""
        self.font = None
        self.baseColors = {}
        self.defaultStyles = {}
        self.allStyles = {}
        self._inherits = {}
        self.load(scheme)
        
    def load(self, scheme):
        """Load the settings for the scheme. Called on init."""
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # load font
        defaultfont = "Lucida Console" if os.name == "nt" else "monospace"
        self.font = QFont(s.value("fontfamily", defaultfont, type("")))
        self.font.setPointSizeF(s.value("fontsize", 10.0, float))
        
        # load base colors
        s.beginGroup("basecolors")
        for name in baseColors:
            if s.contains(name):
                self.baseColors[name] = QColor(s.value(name, "", type("")))
            else:
                self.baseColors[name] = baseColorDefaults[name]()
        s.endGroup()
        
        # get the list of supported styles from ly.colorize
        all_styles = ly.colorize.default_mapping()
        default_styles = set()
        for group, styles in all_styles:
            d = self._inherits[group] = {}
            for style in styles:
                if style.base:
                    default_styles.add(style.base)
                    d[style.name] = style.base
        
        default_scheme = ly.colorize.default_scheme
        
        # load default styles
        s.beginGroup("defaultstyles")
        for name in default_styles:
            self.defaultStyles[name] = f = QTextCharFormat()
            css = default_scheme[None].get(name)
            if css:
                css2fmt(css, f)
            s.beginGroup(name)
            self.loadTextFormat(f, s)
            s.endGroup()
        s.endGroup()
        
        # load specific styles
        s.beginGroup("allstyles")
        for group, styles in all_styles:
            self.allStyles[group]= {}
            s.beginGroup(group)
            for style in styles:
                self.allStyles[group][style.name] = f = QTextCharFormat()
                css = default_scheme[group].get(style.name)
                if css:
                    css2fmt(css, f)
                s.beginGroup(style.name)
                self.loadTextFormat(f, s)
                s.endGroup()
            s.endGroup()
        s.endGroup()
        
    def save(self, scheme):
        """Save the settings to the scheme."""
        s = QSettings()
        s.beginGroup("fontscolors/" + scheme)
        
        # save font
        s.setValue("fontfamily", self.font.family())
        s.setValue("fontsize", self.font.pointSizeF())
        
        # save base colors
        for name in baseColors:
            s.setValue("basecolors/"+name, self.baseColors[name].name())
        
        # save default styles
        s.beginGroup("defaultstyles")
        for name in defaultStyles:
            s.beginGroup(name)
            self.saveTextFormat(self.defaultStyles[name], s)
            s.endGroup()
        s.endGroup()
        
        # save all specific styles
        s.beginGroup("allstyles")
        for group, styles in ly.colorize.default_mapping():
            s.beginGroup(group)
            for style in styles:
                s.beginGroup(style.name)
                self.saveTextFormat(self.allStyles[group][style.name], s)
                s.endGroup()
            s.endGroup()
        s.endGroup()

    def textFormat(self, group, name):
        """Return a QTextCharFormat() for the specified group and name."""
        inherit = self._inherits[group].get(name)
        f = QTextCharFormat(self.defaultStyles[inherit]) if inherit else QTextCharFormat()
        f.merge(self.allStyles[group][name])
        return f
    
    def css_scheme(self):
        """Return a dictionary of css dictionaries representing this scheme.
        
        This can be fed to the ly.colorize.format_stylesheet() function.
        
        """
        scheme = {}
        # base/default styles
        d = scheme[None] = {}
        for name, fmt in self.defaultStyles.items():
            d[name] = fmt2css(fmt)
        # mode/group styles
        for mode, styles in self.allStyles.items():
            d = scheme[mode] = {}
            for name, fmt in styles.items():
                d[name] = fmt2css(fmt)
        return scheme
    
    def palette(self):
        """Return a basic palette with text, background, selection and selection background filled in."""
        p = QApplication.palette()
        p.setColor(QPalette.Text, self.baseColors['text'])
        p.setColor(QPalette.Base, self.baseColors['background'])
        p.setColor(QPalette.HighlightedText, self.baseColors['selectiontext'])
        p.setColor(QPalette.Highlight, self.baseColors['selectionbackground'])
        return p
        
    def saveTextFormat(self, fmt, settings):
        """(Internal) Store one QTextCharFormat in the QSettings instance."""
        if fmt.hasProperty(QTextFormat.FontWeight):
            settings.setValue('bold', fmt.fontWeight() >= 70)
        else:
            settings.remove('bold')
        if fmt.hasProperty(QTextFormat.FontItalic):
            settings.setValue('italic', fmt.fontItalic())
        else:
            settings.remove('italic')
        if fmt.hasProperty(QTextFormat.TextUnderlineStyle):
            settings.setValue('underline', fmt.fontUnderline())
        else:
            settings.remove('underline')
        if fmt.hasProperty(QTextFormat.ForegroundBrush):
            settings.setValue('textColor', fmt.foreground().color().name())
        else:
            settings.remove('textColor')
        if fmt.hasProperty(QTextFormat.BackgroundBrush):
            settings.setValue('backgroundColor', fmt.background().color().name())
        else:
            settings.remove('backgroundColor')
        if fmt.hasProperty(QTextFormat.TextUnderlineColor):
            settings.setValue('underlineColor', fmt.underlineColor().name())
        else:
            settings.remove('underlineColor')
        
    def loadTextFormat(self, fmt, settings):
        """(Internal) Merge values from the QSettings instance into the QTextCharFormat."""
        if settings.contains('bold'):
            fmt.setFontWeight(QFont.Bold if settings.value('bold', False, bool) else QFont.Normal)
        if settings.contains('italic'):
            fmt.setFontItalic(settings.value('italic', False, bool))
        if settings.contains('underline'):
            fmt.setFontUnderline(settings.value('underline', False, bool))
        if settings.contains('textColor'):
            fmt.setForeground(QColor(settings.value('textColor', '' , type(""))))
        if settings.contains('backgroundColor'):
            fmt.setBackground(QColor(settings.value('backgroundColor', '' , type(""))))
        if settings.contains('underlineColor'):
            fmt.setUnderlineColor(QColor(settings.value('underlineColor', '' , type(""))))