Beispiel #1
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     pal = option.palette
     color = pal.color(pal.HighlightedText if option.state & QStyle.State_Selected else pal.Text).name()
     text = '<div style="color:%s">%s</div>' % (color, index.data(RENDER_ROLE))
     st = QStaticText(text)
     st.setTextWidth(option.rect.width())
     painter.drawStaticText(option.rect.left() + self.MARGIN // 2, option.rect.top() + self.MARGIN // 2, st)
Beispiel #2
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     pal = option.palette
     color = pal.color(pal.HighlightedText if option.state & QStyle.State_Selected else pal.Text).name()
     text = '<div style="color:%s">%s</div>' % (color, index.data(RENDER_ROLE))
     st = QStaticText(text)
     st.setTextWidth(option.rect.width())
     painter.drawStaticText(option.rect.left() + self.MARGIN // 2, option.rect.top() + self.MARGIN // 2, st)
Beispiel #3
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.results = ()
        self.current_result = -1
        self.max_result = -1
        self.mouse_hover_result = -1
        self.setMouseTracking(True)
        self.setFocusPolicy(Qt.NoFocus)
        self.text_option = to = QTextOption()
        to.setWrapMode(to.NoWrap)
        self.divider = QStaticText('\xa0→ \xa0')
        self.divider.setTextFormat(Qt.PlainText)
Beispiel #4
0
 def set_message(self, text, color_, bold=False, is_permanent=False):
     from vise.view import certificate_error_domains
     key = (text, color_.name(), bold, is_permanent)
     if key == self.current_key:
         return
     self.current_key = key
     self.is_permanent = is_permanent
     prefix = text.partition(':')[0]
     self.is_address = self.is_permanent and prefix.lower() in {
         'http', 'https', 'vise', 'file'
     }
     self.is_secure = prefix.lower() in {'https', 'vise', 'file'}
     color_ = color_ or self.palette().color(self.palette().WindowText)
     if self.is_address:
         qurl = QUrl(text)
         if self.is_secure and qurl.host() in certificate_error_domains:
             self.is_secure = False
         if qurl.scheme() in {'vise', 'file'}:
             host = qurl.path()
             rest = ''
             sep = ':'
         else:
             host = qurl.host()
             rest = qurl.toDisplayString(QUrl.PrettyDecoded
                                         | QUrl.RemoveScheme
                                         | QUrl.RemoveAuthority)
             sep = '://'
         self.static_text = QStaticText(
             '<span style="white-space:nowrap; color: {fg}">'
             '<span style="color:{emph}; font-weight:bold">{scheme}</span><span style="color:{dull}">{sep}</span>'
             '<span style="color:{fg}">{host}</span>'
             '<span style="color:{dull}">{rest}</span>'.format(
                 fg=color_.name(),
                 emph='green' if self.is_secure else 'red',
                 scheme=escape(qurl.scheme()),
                 host=escape(host),
                 dull=color('status bar dull foreground', 'gray'),
                 sep=sep,
                 rest=escape(rest)))
     else:
         self.static_text = QStaticText(
             '<span style="color:{}; font-weight: {}; white-space:nowrap">{}</span>'
             .format(color_.name(), ('bold' if bold else 'normal'),
                     escape(text)))
     to = QTextOption(Qt.AlignLeft | Qt.AlignTop)
     to.setWrapMode(to.NoWrap)
     self.static_text.setTextOption(to)
     self.static_text.prepare(font=self.font())
     self.update()
Beispiel #5
0
 def sizeHint(self, option, index):
     st = QStaticText(index.data(RENDER_ROLE))
     st.prepare(font=self.parent().font())
     width = max(option.rect.width(), self.parent().width() - 50)
     if width and width != st.textWidth():
         st.setTextWidth(width)
     br = st.size()
     return QSize(br.width() + self.MARGIN, br.height() + self.MARGIN)
Beispiel #6
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, QModelIndex())
     theme = index.data(Qt.UserRole)
     if not theme:
         return
     painter.save()
     pixmap = index.data(Qt.DecorationRole)
     if pixmap and not pixmap.isNull():
         rect = option.rect.adjusted(0, self.SPACING, COVER_SIZE[0] - option.rect.width(), - self.SPACING)
         painter.drawPixmap(rect, pixmap)
     if option.state & QStyle.State_Selected:
         painter.setPen(QPen(QApplication.instance().palette().highlightedText().color()))
     bottom = option.rect.bottom() - 2
     painter.drawLine(0, bottom, option.rect.right(), bottom)
     if 'static-text' not in theme:
         theme['static-text'] = QStaticText(_(
             '''
         <h1>{title}</h1>
         <p>by <i>{author}</i> with <b>{number}</b> icons [{size}]</p>
         <p>{description}</p>
         <p>Version: {version} Number of users: {usage}</p>
         '''.format(title=theme.get('title', _('Unknown')), author=theme.get('author', _('Unknown')),
                    number=theme.get('number', 0), description=theme.get('description', ''),
                    size=human_readable(theme.get('compressed-size', 0)), version=theme.get('version', 1),
                    usage=theme.get('usage', 0),
     )))
     painter.drawStaticText(COVER_SIZE[0] + self.SPACING, option.rect.top() + self.SPACING, theme['static-text'])
     painter.restore()
Beispiel #7
0
 def sizeHint(self, option, index):
     st = QStaticText(index.data(RENDER_ROLE))
     st.prepare(font=self.parent().font())
     width = max(option.rect.width(), self.parent().width() - 50)
     if width and width != st.textWidth():
         st.setTextWidth(width)
     br = st.size()
     return QSize(br.width(), br.height() + self.MARGIN)
Beispiel #8
0
 def set_message(self, text, color_, bold=False, is_permanent=False):
     from vise.view import certificate_error_domains
     key = (text, color_.name(), bold, is_permanent)
     if key == self.current_key:
         return
     self.current_key = key
     self.is_permanent = is_permanent
     prefix = text.partition(':')[0]
     self.is_address = self.is_permanent and prefix.lower() in {'http', 'https', 'vise'}
     self.is_secure = prefix.lower() in {'https', 'vise'}
     color_ = color_ or self.palette().color(self.palette().WindowText)
     if self.is_address:
         qurl = QUrl(text)
         if self.is_secure and qurl.host() in certificate_error_domains:
             self.is_secure = False
         if qurl.scheme() == 'vise':
             host = qurl.path()
             rest = ''
             sep = ':'
         else:
             host = qurl.host()
             rest = qurl.toDisplayString(QUrl.PrettyDecoded | QUrl.RemoveScheme | QUrl.RemoveAuthority)
             sep = '://'
         self.static_text = QStaticText(
             '<span style="white-space:nowrap; color: {fg}">'
             '<span style="color:{emph}; font-weight:bold">{scheme}</span><span style="color:{dull}">{sep}</span>'
             '<span style="color:{fg}">{host}</span>'
             '<span style="color:{dull}">{rest}</span>'.format(
                 fg=color_.name(), emph='green' if self.is_secure else 'red', scheme=escape(qurl.scheme()),
                 host=escape(host), dull=color('status bar dull foreground', 'gray'), sep=sep,
                 rest=escape(rest)
             ))
     else:
         self.static_text = QStaticText('<span style="color:{}; font-weight: {}; white-space:nowrap">{}</span>'.format(
             color_.name(), ('bold' if bold else 'normal'), escape(text)))
     to = QTextOption(Qt.AlignLeft | Qt.AlignTop)
     to.setWrapMode(to.NoWrap)
     self.static_text.setTextOption(to)
     self.static_text.prepare(font=self.font())
     self.update()
Beispiel #9
0
 def get_static_text(self, otext, positions):
     st = self.rendered_text_cache.get(otext)
     if st is None:
         text = (otext or '').ljust(self.max_text_length + 1, ' ')
         text = make_highlighted_text('color: magenta', text, positions)
         desc = self.descriptions.get(otext)
         if desc:
             text += ' ' + desc
         st = self.rendered_text_cache[otext] = QStaticText(text)
         st.setTextOption(self.text_option)
         st.setTextFormat(Qt.RichText)
         st.prepare(font=self.parent().font())
     return st
Beispiel #10
0
 def paintEvent(self, ev):
     painter = QPainter(self)
     painter.setClipRect(ev.rect())
     pal = self.palette()
     painter.fillRect(self.rect(), pal.color(pal.Text))
     crect = self.rect().adjusted(1, 1, -1, -1)
     painter.fillRect(crect, pal.color(pal.Base))
     painter.setClipRect(crect)
     painter.setFont(self.parent().font())
     width = self.rect().width()
     for i, st, y, height in self.iter_visible_items():
         painter.save()
         if i == self.current_index:
             painter.fillRect(1, y, width, height, pal.color(pal.Highlight))
             color = pal.color(QPalette.HighlightedText).name()
             st = QStaticText(st)
             text = st.text().partition('>')[2]
             st.setText('<span style="color: %s">%s' % (color, text))
         painter.drawStaticText(self.SIDE_MARGIN, y, st)
         painter.restore()
     painter.end()
     if self.current_size_hint is None:
         QTimer.singleShot(0, self.layout)
Beispiel #11
0
 def __call__(self, results):
     if results:
         self.current_result = 0
         prefixes = [QStaticText('<b>%s</b>' % os.path.basename(x)) for x in results]
         [(p.setTextFormat(Qt.RichText), p.setTextOption(self.text_option)) for p in prefixes]
         self.maxwidth = max([x.size().width() for x in prefixes])
         self.results = tuple((prefix, self.make_text(text, positions), text)
             for prefix, (text, positions) in izip(prefixes, results.iteritems()))
     else:
         self.results = ()
         self.current_result = -1
     self.max_result = min(10, len(self.results) - 1)
     self.mouse_hover_result = -1
     self.update()
Beispiel #12
0
 def paintEvent(self, ev):
     painter = QPainter(self)
     painter.setClipRect(ev.rect())
     pal = self.palette()
     painter.fillRect(self.rect(), pal.color(QPalette.ColorRole.Text))
     crect = self.rect().adjusted(1, 1, -1, -1)
     painter.fillRect(crect, pal.color(QPalette.ColorRole.Base))
     painter.setClipRect(crect)
     painter.setFont(self.parent().font())
     width = self.rect().width()
     for i, st, y, height in self.iter_visible_items():
         painter.save()
         if i == self.current_index:
             painter.fillRect(1, y, width, height, pal.color(pal.Highlight))
             color = pal.color(QPalette.ColorRole.HighlightedText).name()
             st = QStaticText(st)
             text = st.text().partition('>')[2]
             st.setText('<span style="color: %s">%s' % (color, text))
         painter.drawStaticText(self.SIDE_MARGIN, y, st)
         painter.restore()
     painter.end()
     if self.current_size_hint is None:
         QTimer.singleShot(0, self.layout)
Beispiel #13
0
 def get_static_text(self, otext, positions):
     st = self.rendered_text_cache.get(otext)
     if st is None:
         text = (otext or '').ljust(self.max_text_length + 1, '\xa0')
         text = make_highlighted_text('color: magenta', text, positions)
         desc = self.descriptions.get(otext)
         if desc:
             text += ' - <i>%s</i>' % prepare_string_for_xml(desc)
         color = self.palette().color(QPalette.ColorRole.Text).name()
         text = '<span style="color: %s">%s</span>' % (color, text)
         st = self.rendered_text_cache[otext] = QStaticText(text)
         st.setTextOption(self.text_option)
         st.setTextFormat(Qt.TextFormat.RichText)
         st.prepare(font=self.parent().font())
     return st
Beispiel #14
0
 def static_text(self):
     if self._static_text is None:
         before_words = self.before.split()
         before = ' '.join(before_words[-3:])
         before_extra = len(before) - 15
         if before_extra > 0:
             before = before[before_extra:]
         before = '…' + before
         before_space = '' if self.before.rstrip() == self.before else ' '
         after_words = self.after.split()
         after = ' '.join(after_words[:3])[:15] + '…'
         after_space = '' if self.after.lstrip() == self.after else ' '
         self._static_text = st = QStaticText('<p>{}{}<b>{}</b>{}{}'.format(before, before_space, self.text, after_space, after))
         st.setTextFormat(Qt.RichText)
         st.setTextWidth(10000)
     return self._static_text
Beispiel #15
0
def make_highlighted_text(text, positions, emph='color:magenta', wrapper=None):
    positions = sorted(set(positions) - {-1})
    if positions:
        parts = []
        pos = 0
        for p in positions:
            ch = text[p]
            parts.append(escape(text[pos:p]))
            parts.append('<span style="%s">%s</span>' % (emph, escape(ch)))
            pos = p + len(ch)
        parts.append(escape(text[pos:]))
        text = ''.join(parts)
    if wrapper:
        text = '<span style="%s">%s</span>' % (wrapper, text)
    ans = QStaticText(text)
    to = ans.textOption()
    to.setWrapMode(to.NoWrap)
    ans.setTextOption(to)
    ans.setTextFormat(Qt.RichText)
    return ans
Beispiel #16
0
def make_highlighted_text(text, positions, emph='color:magenta', wrapper=None):
    positions = sorted(set(positions) - {-1})
    if positions:
        parts = []
        pos = 0
        for p in positions:
            ch = text[p]
            parts.append(escape(text[pos:p]))
            parts.append('<span style="%s">%s</span>' % (emph, escape(ch)))
            pos = p + len(ch)
        parts.append(escape(text[pos:]))
        text = ''.join(parts)
    if wrapper:
        text = '<span style="%s">%s</span>' % (wrapper, text)
    ans = QStaticText(text)
    to = ans.textOption()
    to.setWrapMode(to.NoWrap)
    ans.setTextOption(to)
    ans.setTextFormat(Qt.RichText)
    return ans
Beispiel #17
0
 def make_text(self, text, positions):
     text = QStaticText(make_highlighted_text(self.EMPH, text, positions))
     text.setTextOption(self.text_option)
     text.setTextFormat(Qt.RichText)
     return text
Beispiel #18
0
class Message(QWidget):

    def __init__(self, parent, sb_background):
        QWidget.__init__(self, parent)
        self.is_permanent = False
        self.is_address = False
        self.is_secure = False
        self.static_text = None
        self.current_key = None
        self.setFocusPolicy(Qt.NoFocus)
        self.sb_background = QColor(color(sb_background, self.palette().color(QPalette.Window)))

    def set_message(self, text, color_, bold=False, is_permanent=False):
        from vise.view import certificate_error_domains
        key = (text, color_.name(), bold, is_permanent)
        if key == self.current_key:
            return
        self.current_key = key
        self.is_permanent = is_permanent
        prefix = text.partition(':')[0]
        self.is_address = self.is_permanent and prefix.lower() in {'http', 'https', 'vise'}
        self.is_secure = prefix.lower() in {'https', 'vise'}
        color_ = color_ or self.palette().color(self.palette().WindowText)
        if self.is_address:
            qurl = QUrl(text)
            if self.is_secure and qurl.host() in certificate_error_domains:
                self.is_secure = False
            if qurl.scheme() == 'vise':
                host = qurl.path()
                rest = ''
                sep = ':'
            else:
                host = qurl.host()
                rest = qurl.toDisplayString(QUrl.PrettyDecoded | QUrl.RemoveScheme | QUrl.RemoveAuthority)
                sep = '://'
            self.static_text = QStaticText(
                '<span style="white-space:nowrap; color: {fg}">'
                '<span style="color:{emph}; font-weight:bold">{scheme}</span><span style="color:{dull}">{sep}</span>'
                '<span style="color:{fg}">{host}</span>'
                '<span style="color:{dull}">{rest}</span>'.format(
                    fg=color_.name(), emph='green' if self.is_secure else 'red', scheme=escape(qurl.scheme()),
                    host=escape(host), dull=color('status bar dull foreground', 'gray'), sep=sep,
                    rest=escape(rest)
                ))
        else:
            self.static_text = QStaticText('<span style="color:{}; font-weight: {}; white-space:nowrap">{}</span>'.format(
                color_.name(), ('bold' if bold else 'normal'), escape(text)))
        to = QTextOption(Qt.AlignLeft | Qt.AlignTop)
        to.setWrapMode(to.NoWrap)
        self.static_text.setTextOption(to)
        self.static_text.prepare(font=self.font())
        self.update()

    def paintEvent(self, ev):
        if not self.static_text or not self.static_text.text():
            return
        p = QPainter(self)
        p.setRenderHint(p.TextAntialiasing)
        # If text is too long too fit, fade it out at the end
        self.static_text.setTextWidth(self.rect().width())
        sz = self.static_text.size()
        r = self.rect()
        p.drawStaticText(0, (r.height() - sz.height()) // 2, self.static_text)
        if sz.width() > r.width():
            g = QLinearGradient(self.rect().topLeft(), self.rect().topRight())
            c = QColor(self.sb_background)
            c.setAlpha(0)
            g.setColorAt(0, c)
            g.setColorAt(0.8, c)
            g.setColorAt(1.0, self.sb_background)
            p.fillRect(self.rect(), QBrush(g))
        p.end()
Beispiel #19
0
class Results(QWidget):

    EMPH = "color:magenta; font-weight:bold"
    MARGIN = 4

    item_selected = pyqtSignal()

    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.results = ()
        self.current_result = -1
        self.max_result = -1
        self.mouse_hover_result = -1
        self.setMouseTracking(True)
        self.setFocusPolicy(Qt.NoFocus)
        self.text_option = to = QTextOption()
        to.setWrapMode(to.NoWrap)
        self.divider = QStaticText('\xa0→ \xa0')
        self.divider.setTextFormat(Qt.PlainText)

    def item_from_y(self, y):
        if not self.results:
            return
        delta = self.results[0][0].size().height() + self.MARGIN
        maxy = self.height()
        pos = 0
        for i, r in enumerate(self.results):
            bottom = pos + delta
            if pos <= y < bottom:
                return i
                break
            pos = bottom
            if pos > min(y, maxy):
                break
        return -1

    def mouseMoveEvent(self, ev):
        y = ev.pos().y()
        prev = self.mouse_hover_result
        self.mouse_hover_result = self.item_from_y(y)
        if prev != self.mouse_hover_result:
            self.update()

    def mousePressEvent(self, ev):
        if ev.button() == 1:
            i = self.item_from_y(ev.pos().y())
            if i != -1:
                ev.accept()
                self.current_result = i
                self.update()
                self.item_selected.emit()
                return
        return QWidget.mousePressEvent(self, ev)

    def change_current(self, delta=1):
        if not self.results:
            return
        nc = self.current_result + delta
        if 0 <= nc <= self.max_result:
            self.current_result = nc
            self.update()

    def __call__(self, results):
        if results:
            self.current_result = 0
            prefixes = [QStaticText('<b>%s</b>' % os.path.basename(x)) for x in results]
            [(p.setTextFormat(Qt.RichText), p.setTextOption(self.text_option)) for p in prefixes]
            self.maxwidth = max([x.size().width() for x in prefixes])
            self.results = tuple((prefix, self.make_text(text, positions), text)
                for prefix, (text, positions) in izip(prefixes, results.iteritems()))
        else:
            self.results = ()
            self.current_result = -1
        self.max_result = min(10, len(self.results) - 1)
        self.mouse_hover_result = -1
        self.update()

    def make_text(self, text, positions):
        text = QStaticText(make_highlighted_text(self.EMPH, text, positions))
        text.setTextOption(self.text_option)
        text.setTextFormat(Qt.RichText)
        return text

    def paintEvent(self, ev):
        offset = QPoint(0, 0)
        p = QPainter(self)
        p.setClipRect(ev.rect())
        bottom = self.rect().bottom()

        if self.results:
            for i, (prefix, full, text) in enumerate(self.results):
                size = prefix.size()
                if offset.y() + size.height() > bottom:
                    break
                self.max_result = i
                offset.setX(0)
                if i in (self.current_result, self.mouse_hover_result):
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
                offset.setY(offset.y() + self.MARGIN // 2)
                p.drawStaticText(offset, prefix)
                offset.setX(self.maxwidth + 5)
                p.drawStaticText(offset, self.divider)
                offset.setX(offset.x() + self.divider.size().width())
                p.drawStaticText(offset, full)
                offset.setY(offset.y() + size.height() + self.MARGIN // 2)
                if i in (self.current_result, self.mouse_hover_result):
                    offset.setX(0)
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
        else:
            p.drawText(self.rect(), Qt.AlignCenter, _('No results found'))

        p.end()

    @property
    def selected_result(self):
        try:
            return self.results[self.current_result][-1]
        except IndexError:
            pass
Beispiel #20
0
class Message(QWidget):
    def __init__(self, parent, sb_background):
        QWidget.__init__(self, parent)
        self.is_permanent = False
        self.is_address = False
        self.is_secure = False
        self.static_text = None
        self.current_key = None
        self.setFocusPolicy(Qt.NoFocus)
        self.sb_background = QColor(
            color(sb_background,
                  self.palette().color(QPalette.Window)))

    def set_message(self, text, color_, bold=False, is_permanent=False):
        from vise.view import certificate_error_domains
        key = (text, color_.name(), bold, is_permanent)
        if key == self.current_key:
            return
        self.current_key = key
        self.is_permanent = is_permanent
        prefix = text.partition(':')[0]
        self.is_address = self.is_permanent and prefix.lower() in {
            'http', 'https', 'vise', 'file'
        }
        self.is_secure = prefix.lower() in {'https', 'vise', 'file'}
        color_ = color_ or self.palette().color(self.palette().WindowText)
        if self.is_address:
            qurl = QUrl(text)
            if self.is_secure and qurl.host() in certificate_error_domains:
                self.is_secure = False
            if qurl.scheme() in {'vise', 'file'}:
                host = qurl.path()
                rest = ''
                sep = ':'
            else:
                host = qurl.host()
                rest = qurl.toDisplayString(QUrl.PrettyDecoded
                                            | QUrl.RemoveScheme
                                            | QUrl.RemoveAuthority)
                sep = '://'
            self.static_text = QStaticText(
                '<span style="white-space:nowrap; color: {fg}">'
                '<span style="color:{emph}; font-weight:bold">{scheme}</span><span style="color:{dull}">{sep}</span>'
                '<span style="color:{fg}">{host}</span>'
                '<span style="color:{dull}">{rest}</span>'.format(
                    fg=color_.name(),
                    emph='green' if self.is_secure else 'red',
                    scheme=escape(qurl.scheme()),
                    host=escape(host),
                    dull=color('status bar dull foreground', 'gray'),
                    sep=sep,
                    rest=escape(rest)))
        else:
            self.static_text = QStaticText(
                '<span style="color:{}; font-weight: {}; white-space:nowrap">{}</span>'
                .format(color_.name(), ('bold' if bold else 'normal'),
                        escape(text)))
        to = QTextOption(Qt.AlignLeft | Qt.AlignTop)
        to.setWrapMode(to.NoWrap)
        self.static_text.setTextOption(to)
        self.static_text.prepare(font=self.font())
        self.update()

    def paintEvent(self, ev):
        if not self.static_text or not self.static_text.text():
            return
        p = QPainter(self)
        p.setRenderHint(p.TextAntialiasing)
        # If text is too long too fit, fade it out at the end
        self.static_text.setTextWidth(self.rect().width())
        sz = self.static_text.size()
        r = self.rect()
        p.drawStaticText(0, (r.height() - sz.height()) // 2, self.static_text)
        if sz.width() > r.width():
            g = QLinearGradient(self.rect().topLeft(), self.rect().topRight())
            c = QColor(self.sb_background)
            c.setAlpha(0)
            g.setColorAt(0, c)
            g.setColorAt(0.8, c)
            g.setColorAt(1.0, self.sb_background)
            p.fillRect(self.rect(), QBrush(g))
        p.end()
Beispiel #21
0
 def make_text(self, text, positions):
     text = QStaticText(
         make_highlighted_text(emphasis_style(), text, positions))
     text.setTextOption(self.text_option)
     text.setTextFormat(Qt.TextFormat.RichText)
     return text