Beispiel #1
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(4, rect.width() // 10)

    drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)
    try:
        angle_for_width = math.degrees(math.atan2(1.3 * disc_width, drawing_rect.width()))
    except ZeroDivisionError:
        angle_for_width = 5

    gradient = QConicalGradient(drawing_rect.center(), angle - angle_for_width)
    gradient.setColorAt(1, light)
    gradient.setColorAt(0, dark)

    painter.setPen(QPen(light, disc_width))
    painter.drawArc(drawing_rect, 0, 360 * 16)
    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - 2 * angle_for_width) * 16)
Beispiel #2
0
 def paintEvent(self, event):
     canvas_size = self.rect()
     width = self.current_pixmap_size.width()
     extrax = canvas_size.width() - width
     if extrax < 0:
         extrax = 0
     x = int(extrax/2.)
     height = self.current_pixmap_size.height()
     extray = canvas_size.height() - height
     if extray < 0:
         extray = 0
     y = int(extray/2.)
     target = QRect(x, y, width, height)
     p = QPainter(self)
     p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
     try:
         dpr = self.devicePixelRatioF()
     except AttributeError:
         dpr = self.devicePixelRatio()
     spmap = self.pixmap.scaled(target.size() * dpr, Qt.KeepAspectRatio, Qt.SmoothTransformation)
     spmap.setDevicePixelRatio(dpr)
     p.drawPixmap(target, spmap)
     if gprefs['bd_overlay_cover_size']:
         sztgt = target.adjusted(0, 0, 0, -4)
         f = p.font()
         f.setBold(True)
         p.setFont(f)
         sz = u'\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height())
         flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine
         szrect = p.boundingRect(sztgt, flags, sz)
         p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
         p.setPen(QPen(QColor(255,255,255)))
         p.drawText(sztgt, flags, sz)
     p.end()
Beispiel #3
0
def drag_icon(self, cover, multiple):
    cover = cover.scaledToHeight(120, Qt.SmoothTransformation)
    if multiple:
        base_width = cover.width()
        base_height = cover.height()
        base = QImage(base_width+21, base_height+21,
                QImage.Format_ARGB32_Premultiplied)
        base.fill(QColor(255, 255, 255, 0).rgba())
        p = QPainter(base)
        rect = QRect(20, 0, base_width, base_height)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(10)
        rect.moveTop(10)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(0)
        rect.moveTop(20)
        p.fillRect(rect, QColor('white'))
        p.save()
        p.setCompositionMode(p.CompositionMode_SourceAtop)
        p.drawImage(rect.topLeft(), cover)
        p.restore()
        p.drawRect(rect)
        p.end()
        cover = base
    return QPixmap.fromImage(cover)
Beispiel #4
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     style = QApplication.style()
     waiting = self.timer.isActive() and bool(index.data(Qt.UserRole))
     if waiting:
         rect = QRect(0, 0, self.spinner_width, self.spinner_width)
         rect.moveCenter(option.rect.center())
         draw_snake_spinner(painter, rect, self.angle, self.light_color, self.dark_color)
     else:
         # Ensure the cover is rendered over any selection rect
         style.drawItemPixmap(painter, option.rect, Qt.AlignTop|Qt.AlignHCenter,
             QPixmap(index.data(Qt.DecorationRole)))
Beispiel #5
0
 def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
     painter.fillRect(rect, self.color1)
     r = QRect(0, int(title_block.position.y), rect.width(),
               title_block.height + subtitle_block.height + subtitle_block.line_spacing // 2 + title_block.leading)
     painter.save()
     p = QPainterPath()
     p.addRoundedRect(QRectF(r), 10, 10 * r.width()/r.height(), Qt.RelativeSize)
     painter.setClipPath(p)
     painter.setRenderHint(QPainter.Antialiasing)
     painter.fillRect(r, self.color2)
     painter.restore()
     r = QRect(0, 0, int(title_block.position.x), rect.height())
     painter.fillRect(r, self.color2)
     return self.ccolor2, self.ccolor2, self.ccolor1
Beispiel #6
0
 def draw(self, painter, width, palette):
     flags = self.FLAGS | (Qt.AlignRight if self.right_align else Qt.AlignLeft)
     rect = QRect(self.rect)
     if self.right_align:
         rect.setRight(width - self.SIDE_MARGIN)
     painter.setPen(palette.color(self.color_role) if self.override_color is None else self.override_color)
     br = painter.drawText(rect, flags, self.text)
     if self.swatch is not None:
         r = QRect(br.right() + self.SIDE_MARGIN // 2, br.top() + 2, br.height() - 4, br.height() - 4)
         painter.fillRect(r, self.swatch)
         br.setRight(r.right())
     if self.is_overriden:
         painter.setPen(palette.color(QPalette.WindowText))
         painter.drawLine(br.left(), br.top() + br.height() // 2, br.right(), br.top() + br.height() // 2)
Beispiel #7
0
 def paintEvent(self, event):
     if self.pixmap.isNull():
         return
     canvas_size = self.rect()
     width = self.current_pixmap_size.width()
     extrax = canvas_size.width() - width
     if extrax < 0:
         extrax = 0
     x = int(extrax / 2.0)
     height = self.current_pixmap_size.height()
     extray = canvas_size.height() - height
     if extray < 0:
         extray = 0
     y = int(extray / 2.0)
     target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height))
     p = QPainter(self)
     p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
     p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
     p.end()
Beispiel #8
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(3, min(rect.width() // 10, 8))

    drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)

    gap = 60  # degrees
    gradient = QConicalGradient(drawing_rect.center(), angle - gap // 2)
    gradient.setColorAt((360 - gap//2)/360.0, light)
    gradient.setColorAt(0, dark)

    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - gap) * 16)
Beispiel #9
0
    def paintEvent(self, ev):
        if self.before_image is None:
            return
        canvas_size = self.rect()
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)

        p.drawPixmap(canvas_size, self.before_image, self.before_image.rect())
        if self.after_image is not None:
            width = self._current_width
            iw = self.after_image.width()
            sh = min(self.after_image.height(), canvas_size.height())

            if self.flip_forwards:
                source = QRect(max(0, iw - width), 0, width, sh)
            else:
                source = QRect(0, 0, width, sh)

            target = QRect(source)
            target.moveLeft(0)
            p.drawPixmap(target, self.after_image, source)

        p.end()
Beispiel #10
0
    def do_layout(self):
        fm = self.fontMetrics()
        bounding_rect = lambda text: fm.boundingRect(0, 0, 10000, 10000, Cell.FLAGS, text)
        line_spacing = 2
        side_margin = Cell.SIDE_MARGIN
        self.rows = []
        ypos = line_spacing + (1 if self.is_first else 0)
        if "href" in self.data:
            name = self.data["href"]
            if isinstance(name, list):
                name = self.html_name
            br1 = bounding_rect(name)
            sel = self.data["selector"] or ""
            if self.data["type"] == "inline":
                sel = 'style=""'
            br2 = bounding_rect(sel)
            self.hyperlink_rect = QRect(side_margin, ypos, br1.width(), br1.height())
            self.rows.append(
                [
                    Cell(name, self.hyperlink_rect, color_role=QPalette.Link),
                    Cell(sel, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), right_align=True),
                ]
            )
            ypos += max(br1.height(), br2.height()) + 2 * line_spacing

        for prop in self.data["properties"]:
            text = prop.name + ":\xa0"
            br1 = bounding_rect(text)
            vtext = prop.value + "\xa0" + ("!" if prop.important else "") + prop.important
            br2 = bounding_rect(vtext)
            self.rows.append(
                [
                    Cell(
                        text,
                        QRect(side_margin, ypos, br1.width(), br1.height()),
                        color_role=QPalette.LinkVisited,
                        is_overriden=prop.is_overriden,
                    ),
                    Cell(
                        vtext,
                        QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()),
                        swatch=prop.color,
                        is_overriden=prop.is_overriden,
                    ),
                ]
            )
            ypos += max(br1.height(), br2.height()) + line_spacing

        self.height_hint = ypos + line_spacing
        self.width_hint = max(row[-1].rect.right() + side_margin for row in self.rows) if self.rows else 0
Beispiel #11
0
 def paintEvent(self, event):
     QWidget.paintEvent(self, event)
     pmap = self._pixmap
     if pmap.isNull():
         return
     w, h = pmap.width(), pmap.height()
     ow, oh = w, h
     cw, ch = self.rect().width(), self.rect().height()
     scaled, nw, nh = fit_image(w, h, cw, ch)
     if scaled:
         pmap = pmap.scaled(int(nw*pmap.devicePixelRatio()), int(nh*pmap.devicePixelRatio()), Qt.IgnoreAspectRatio,
                 Qt.SmoothTransformation)
     w, h = int(pmap.width()/pmap.devicePixelRatio()), int(pmap.height()/pmap.devicePixelRatio())
     x = int(abs(cw - w)/2.)
     y = int(abs(ch - h)/2.)
     target = QRect(x, y, w, h)
     p = QPainter(self)
     p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
     p.drawPixmap(target, pmap)
     if self.draw_border:
         pen = QPen()
         pen.setWidth(self.BORDER_WIDTH)
         p.setPen(pen)
         p.drawRect(target)
     if self.show_size:
         sztgt = target.adjusted(0, 0, 0, -4)
         f = p.font()
         f.setBold(True)
         p.setFont(f)
         sz = u'\u00a0%d x %d\u00a0'%(ow, oh)
         flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine
         szrect = p.boundingRect(sztgt, flags, sz)
         p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
         p.setPen(QPen(QColor(255,255,255)))
         p.drawText(sztgt, flags, sz)
     p.end()
Beispiel #12
0
 def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
     painter.fillRect(rect, self.color1)
     y = rect.height() - rect.height() // 3
     r = QRect(rect)
     r.setBottom(y)
     painter.fillRect(rect, self.color1)
     r = QRect(rect)
     r.setTop(y)
     painter.fillRect(r, self.color2)
     return self.ccolor1, self.ccolor1, self.ccolor2
Beispiel #13
0
    def do_layout(self):
        fm = self.fontMetrics()
        bounding_rect = lambda text: fm.boundingRect(0, 0, 10000, 10000, Cell.FLAGS, text)
        line_spacing = 2
        side_margin = Cell.SIDE_MARGIN
        self.rows = []
        ypos = line_spacing + (1 if self.is_first else 0)
        if 'href' in self.data:
            name = self.data['href']
            if isinstance(name, list):
                name = self.html_name
            br1 = bounding_rect(name)
            sel = self.data['selector'] or ''
            if self.data['type'] == 'inline':
                sel = 'style=""'
            br2 = bounding_rect(sel)
            self.hyperlink_rect = QRect(side_margin, ypos, br1.width(), br1.height())
            self.rows.append([
                Cell(name, self.hyperlink_rect, color_role=QPalette.Link),
                Cell(sel, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), right_align=True)
            ])
            ypos += max(br1.height(), br2.height()) + 2 * line_spacing
            self.lines_for_copy.append(name + ' ' + sel)

        for prop in self.data['properties']:
            text = prop.name + ':\xa0'
            br1 = bounding_rect(text)
            vtext = prop.value + '\xa0' + ('!' if prop.important else '') + prop.important
            br2 = bounding_rect(vtext)
            self.rows.append([
                Cell(text, QRect(side_margin, ypos, br1.width(), br1.height()), color_role=QPalette.LinkVisited, is_overriden=prop.is_overriden),
                Cell(vtext, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), swatch=prop.color, is_overriden=prop.is_overriden)
            ])
            self.lines_for_copy.append(text + vtext)
            if prop.is_overriden:
                self.lines_for_copy[-1] += ' [overriden]'
            ypos += max(br1.height(), br2.height()) + line_spacing
        self.lines_for_copy.append('--------------------------\n')

        self.height_hint = ypos + line_spacing
        self.width_hint = max(row[-1].rect.right() + side_margin for row in self.rows) if self.rows else 0
Beispiel #14
0
    def setupUi(self):
        self.setObjectName("Dialog")
        self.resize(1024, 700)
        self.setWindowIcon(QIcon(I('convert.png')))
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.input_label = QLabel(self)
        self.input_label.setObjectName("input_label")
        self.horizontalLayout.addWidget(self.input_label)
        self.input_formats = QComboBox(self)
        self.input_formats.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.input_formats.setMinimumContentsLength(5)
        self.input_formats.setObjectName("input_formats")
        self.horizontalLayout.addWidget(self.input_formats)
        self.opt_individual_saved_settings = QCheckBox(self)
        self.opt_individual_saved_settings.setObjectName(
            "opt_individual_saved_settings")
        self.horizontalLayout.addWidget(self.opt_individual_saved_settings)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.label_2 = QLabel(self)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.output_formats = QComboBox(self)
        self.output_formats.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.output_formats.setMinimumContentsLength(5)
        self.output_formats.setObjectName("output_formats")
        self.horizontalLayout.addWidget(self.output_formats)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 2)
        self.groups = QListView(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.groups.sizePolicy().hasHeightForWidth())
        self.groups.setSizePolicy(sizePolicy)
        self.groups.setTabKeyNavigation(True)
        self.groups.setIconSize(QSize(48, 48))
        self.groups.setWordWrap(True)
        self.groups.setObjectName("groups")
        self.gridLayout.addWidget(self.groups, 1, 0, 3, 1)
        self.scrollArea = QScrollArea(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(4)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(
            self.scrollArea.sizePolicy().hasHeightForWidth())
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setLineWidth(0)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QWidget()
        self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 810, 494))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_3 = QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.stack = QStackedWidget(self.scrollAreaWidgetContents)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.stack.sizePolicy().hasHeightForWidth())
        self.stack.setSizePolicy(sizePolicy)
        self.stack.setObjectName("stack")
        self.page = QWidget()
        self.page.setObjectName("page")
        self.stack.addWidget(self.page)
        self.page_2 = QWidget()
        self.page_2.setObjectName("page_2")
        self.stack.addWidget(self.page_2)
        self.verticalLayout_3.addWidget(self.stack)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.gridLayout.addWidget(self.scrollArea, 1, 1, 1, 1)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.RestoreDefaults)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 3, 1, 1, 1)
        self.help = QTextEdit(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.help.sizePolicy().hasHeightForWidth())
        self.help.setSizePolicy(sizePolicy)
        self.help.setMaximumSize(QSize(16777215, 130))
        self.help.setObjectName("help")
        self.gridLayout.addWidget(self.help, 2, 1, 1, 1)
        self.input_label.setBuddy(self.input_formats)
        self.label_2.setBuddy(self.output_formats)
        self.input_label.setText(_("&Input format:"))
        self.opt_individual_saved_settings.setText(
            _("Use &saved conversion settings for individual books"))
        self.label_2.setText(_("&Output format:"))

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
Beispiel #15
0
 def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True):
     drect = QRect(orect)
     pw = int(pixmap.width() / pixmap.devicePixelRatio())
     ph = int(pixmap.height() / pixmap.devicePixelRatio())
     if left:
         drect.setLeft(drect.left() + right_adjust)
         drect.setRight(drect.left() + pw)
     else:
         drect.setRight(drect.right() - right_adjust)
         drect.setLeft(drect.right() - pw + 1)
     drect.setBottom(drect.bottom() - self.title_height)
     drect.setTop(drect.bottom() - ph)
     painter.drawPixmap(drect, pixmap)
Beispiel #16
0
def decoration_for_style(palette, style, icon_size, device_pixel_ratio,
                         is_dark):
    style_key = (is_dark, icon_size, device_pixel_ratio,
                 tuple((k, style[k]) for k in sorted(style)))
    sentinel = object()
    ans = decoration_cache.get(style_key, sentinel)
    if ans is not sentinel:
        return ans
    ans = None
    kind = style.get('kind')
    if kind == 'color':
        key = 'dark' if is_dark else 'light'
        val = style.get(key)
        if val is None:
            which = style.get('which')
            val = (builtin_colors_dark
                   if is_dark else builtin_colors_light).get(which)
        if val is None:
            val = style.get('background-color')
        if val is not None:
            ans = QColor(val)
    elif kind == 'decoration':
        which = style.get('which')
        if which is not None:
            q = builtin_decorations.get(which)
            if q is not None:
                style = q
        sz = int(math.ceil(icon_size * device_pixel_ratio))
        canvas = QImage(sz, sz, QImage.Format.Format_ARGB32)
        canvas.fill(Qt.GlobalColor.transparent)
        canvas.setDevicePixelRatio(device_pixel_ratio)
        p = QPainter(canvas)
        p.setRenderHint(QPainter.RenderHint.Antialiasing, True)
        p.setPen(palette.color(QPalette.ColorRole.WindowText))
        irect = QRect(0, 0, icon_size, icon_size)
        adjust = -2
        text_rect = p.drawText(
            irect.adjusted(0, adjust, 0, adjust),
            Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop, 'a')
        p.drawRect(irect)
        fm = p.fontMetrics()
        pen = p.pen()
        if 'text-decoration-color' in style:
            pen.setColor(QColor(style['text-decoration-color']))
        lstyle = style.get('text-decoration-style') or 'solid'
        q = {
            'dotted': Qt.PenStyle.DotLine,
            'dashed': Qt.PenStyle.DashLine,
        }.get(lstyle)
        if q is not None:
            pen.setStyle(q)
        lw = fm.lineWidth()
        if lstyle == 'double':
            lw * 2
        pen.setWidth(fm.lineWidth())
        q = style.get('text-decoration-line') or 'underline'
        pos = text_rect.bottom()
        height = irect.bottom() - pos
        if q == 'overline':
            pos = height
        elif q == 'line-through':
            pos = text_rect.center().y() - adjust - lw // 2
        p.setPen(pen)
        if lstyle == 'wavy':
            p.drawPath(wavy_path(icon_size, height, pos))
        else:
            p.drawLine(0, pos, irect.right(), pos)
        p.end()
        ans = QPixmap.fromImage(canvas)
    elif 'background-color' in style:
        ans = QColor(style['background-color'])
    decoration_cache[style_key] = ans
    return ans
Beispiel #17
0
    def __init__(self, plugin_action):
        self.gui = plugin_action.gui
        self.opts = plugin_action.opts

        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        # ~~~~~~~~ Create the runtime options group box ~~~~~~~~
        self.cfg_runtime_options_gb = QGroupBox(self)
        self.cfg_runtime_options_gb.setTitle(_('Runtime options'))
        self.l.addWidget(self.cfg_runtime_options_gb)
        self.cfg_runtime_options_qvl = QVBoxLayout(self.cfg_runtime_options_gb)

        # ~~~~~~~~ Disable caching checkbox ~~~~~~~~
        self.cfg_disable_caching_checkbox = QCheckBox(_('Disable caching'))
        self.cfg_disable_caching_checkbox.setObjectName('cfg_disable_caching_checkbox')
        self.cfg_disable_caching_checkbox.setToolTip(_('Force reload of reader database'))
        self.cfg_disable_caching_checkbox.setChecked(False)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_disable_caching_checkbox)

        # ~~~~~~~~ plugin logging checkbox ~~~~~~~~
        self.cfg_plugin_debug_log_checkbox = QCheckBox(_('Enable debug logging for Annotations plugin'))
        self.cfg_plugin_debug_log_checkbox.setObjectName('cfg_plugin_debug_log_checkbox')
        self.cfg_plugin_debug_log_checkbox.setToolTip(_('Print plugin diagnostic messages to console'))
        self.cfg_plugin_debug_log_checkbox.setChecked(False)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_plugin_debug_log_checkbox)

        # ~~~~~~~~ libiMobileDevice logging checkbox ~~~~~~~~
        self.cfg_libimobiledevice_debug_log_checkbox = QCheckBox(_('Enable debug logging for libiMobileDevice'))
        self.cfg_libimobiledevice_debug_log_checkbox.setObjectName('cfg_libimobiledevice_debug_log_checkbox')
        self.cfg_libimobiledevice_debug_log_checkbox.setToolTip(_('Print libiMobileDevice debug messages to console'))
        self.cfg_libimobiledevice_debug_log_checkbox.setChecked(False)
        self.cfg_libimobiledevice_debug_log_checkbox.setEnabled(LIBIMOBILEDEVICE_AVAILABLE)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_libimobiledevice_debug_log_checkbox)

        # ~~~~~~~~ Create the Annotations options group box ~~~~~~~~
        self.cfg_annotation_options_gb = QGroupBox(self)
        self.cfg_annotation_options_gb.setTitle(_('Annotation options'))
        self.l.addWidget(self.cfg_annotation_options_gb)

        self.cfg_annotation_options_qgl = QGridLayout(self.cfg_annotation_options_gb)
        current_row = 0

        # Add the label/combobox for annotations destination
        self.cfg_annotations_destination_label = QLabel(_('<b>Add fetched annotations to<b>'))
        self.cfg_annotations_destination_label.setAlignment(Qt.AlignLeft)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_label, current_row, 0)
        current_row += 1

        self.cfg_annotations_destination_comboBox = QComboBox(self.cfg_annotation_options_gb)
        self.cfg_annotations_destination_comboBox.setObjectName('cfg_annotations_destination_comboBox')
        self.cfg_annotations_destination_comboBox.setToolTip(_('Custom field to store annotations'))
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_comboBox, current_row, 0)

        # Populate annotations_field combobox
        db = self.gui.current_db
        all_custom_fields = db.custom_field_keys()
        self.custom_fields = {}
        for custom_field in all_custom_fields:
            field_md = db.metadata_for_field(custom_field)
            if field_md['datatype'] in ['comments']:
                self.custom_fields[field_md['name']] = {'field': custom_field,
                                                   'datatype': field_md['datatype']}

        all_fields = self.custom_fields.keys() + ['Comments']
        for cf in sorted(all_fields):
            self.cfg_annotations_destination_comboBox.addItem(cf)

        # Add CC Wizard
        self.cfg_annotations_wizard = QToolButton()
        self.cfg_annotations_wizard.setIcon(QIcon(I('wizard.png')))
        self.cfg_annotations_wizard.setToolTip(_("Create a custom column to store annotations"))
        self.cfg_annotations_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Annotations'))
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_wizard, current_row, 2)

        current_row += 1

        # ~~~~~~~~ Add a horizontal line ~~~~~~~~
        self.cfg_appearance_hl = QFrame(self)
        self.cfg_appearance_hl.setGeometry(QRect(0, 0, 1, 3))
        self.cfg_appearance_hl.setFrameShape(QFrame.HLine)
        self.cfg_appearance_hl.setFrameShadow(QFrame.Raised)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_appearance_hl, current_row, 0)
        current_row += 1

        # ~~~~~~~~ Add the Modify… button ~~~~~~~~
        self.cfg_annotations_appearance_pushbutton = QPushButton(_("Modify appearance…"))
        self.cfg_annotations_appearance_pushbutton.clicked.connect(self.configure_appearance)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_appearance_pushbutton, current_row, 0)
        current_row += 1

        self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.cfg_annotation_options_qgl.addItem(self.spacerItem, current_row, 0, 1, 1)

        # ~~~~~~~~ Compilations group box ~~~~~~~~
        self.cfg_compilation_options_gb = QGroupBox(self)
        self.cfg_compilation_options_gb.setTitle(_('Compilations'))
        self.l.addWidget(self.cfg_compilation_options_gb)
        self.cfg_compilation_options_qgl = QGridLayout(self.cfg_compilation_options_gb)
        current_row = 0

        #   News clippings
        self.cfg_news_clippings_checkbox = QCheckBox(_('Collect News clippings'))
        self.cfg_news_clippings_checkbox.setObjectName('cfg_news_clippings_checkbox')
        self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_checkbox,
            current_row, 0)

        self.cfg_news_clippings_lineEdit = QLineEdit()
        self.cfg_news_clippings_lineEdit.setObjectName('cfg_news_clippings_lineEdit')
        self.cfg_news_clippings_lineEdit.setToolTip(_('Title for collected news clippings'))
        self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_lineEdit,
            current_row, 1)

        # ~~~~~~~~ End of construction zone ~~~~~~~~

        self.resize(self.sizeHint())

        # Restore state of controls, populate annotations combobox
        self.controls = inventory_controls(self, dump_controls=False)
        restore_state(self)
        self.populate_annotations()

        # Hook changes to annotations_destination_combobox
#        self.connect(self.cfg_annotations_destination_comboBox,
#                     pyqtSignal('currentIndexChanged(const QString &)'),
#                     self.annotations_destination_changed)
        self.cfg_annotations_destination_comboBox.currentIndexChanged.connect(self.annotations_destination_changed)

        # Hook changes to diagnostic checkboxes
        self.cfg_disable_caching_checkbox.stateChanged.connect(self.restart_required)
        self.cfg_libimobiledevice_debug_log_checkbox.stateChanged.connect(self.restart_required)
        self.cfg_plugin_debug_log_checkbox.stateChanged.connect(self.restart_required)

        # Hook changes to News clippings, initialize
        self.cfg_news_clippings_checkbox.stateChanged.connect(self.news_clippings_toggled)
        self.news_clippings_toggled(self.cfg_news_clippings_checkbox.checkState())
        self.cfg_news_clippings_lineEdit.editingFinished.connect(self.news_clippings_destination_changed)

        # Launch the annotated_books_scanner
        field = get_cc_mapping('annotations', 'field', 'Comments')
        self.annotated_books_scanner = InventoryAnnotatedBooks(self.gui, field)
        self.annotated_books_scanner.signal.connect(self.inventory_complete)
#        self.connect(self.annotated_books_scanner, self.annotated_books_scanner.signal,
#            self.inventory_complete)
        QTimer.singleShot(1, self.start_inventory)
Beispiel #18
0
    def _paintGroupBox(self, rect, title):
        painter = QPainter(self)
        qDrawShadeRect(painter, rect, self.palette(), True)

        if len(title) > 0:
            fnt = self.font()
            fnt.setPointSize(fnt.pointSize() - 1)
            offset = 5
            asterix = ' *'
            twidth = QFontMetrics(fnt).width(title)
            awidth = QFontMetrics(fnt).width(asterix)
            width = twidth + awidth + 2 * offset
            height = QFontMetrics(fnt).height()
            rect = QRect(rect.left() + 2 * offset,
                         rect.top() - height / 2 + 1, width, height)
            painter.fillRect(rect, self.palette().color(self.backgroundRole()))
            painter.setFont(fnt)
            painter.drawText(
                QRect(rect.left() + offset, rect.top(), twidth, rect.height()),
                Qt.AlignLeft, title)
            painter.setPen(Qt.red)
            painter.drawText(
                QRect(rect.left() + offset + twidth, rect.top(), awidth,
                      rect.height()), Qt.AlignRight, asterix)
Beispiel #19
0
 def rect_at(self, frac):
     return QRect(self.point_at(frac), self.size())
Beispiel #20
0
 def add_roca(self, position):
     y, x = position
     rect = QRect(1 + SIZE_TILE * x, 1 + SIZE_TILE * y, SIZE_TILE,
                  SIZE_TILE)
     self.columns[y][x] = (rect, 'roca')
Beispiel #21
0
 def geometry(self):
     return QRect()
Beispiel #22
0
    def _setupUi(self):
        settings = Settings()
        settings.beginGroup('Browser-View-Settings')
        windowGeometry = settings.value('WindowGeometry', b'')

        keys = [
            ('LocationBarWidth', int),
            ('WebSearchBarWidth', int),
            ('SideBarWidth', int),
            ('WebViewWidth', int),
            ('SideBar', str),
        ]

        uiState = {}
        for key, typ in keys:
            if settings.contains(key):
                uiState[key] = typ(settings.value(key))

        settings.endGroup()

        widget = QWidget(self)
        widget.setCursor(Qt.ArrowCursor)
        self.setCentralWidget(widget)

        self._mainLayout = QVBoxLayout(widget)
        self._mainLayout.setContentsMargins(0, 0, 0, 0)
        self._mainLayout.setSpacing(0)
        self._mainSplitter = QSplitter(self)
        self._mainSplitter.setObjectName('sidebar-splitter')
        self._tabWidget = TabWidget(self)
        self._superMenu = QMenu(self)
        self._navigationToolbar = NavigationBar(self)
        self._bookmarksToolbar = BookmarksToolbar(self)

        self._tabModel = TabModel(self, self)
        self._tabMruModel = TabMruModel(self, self)
        self._tabMruModel.setSourceModel(self._tabModel)

        self._navigationContainer = NavigationContainer(self)
        self._navigationContainer.addWidget(self._navigationToolbar)
        self._navigationContainer.addWidget(self._bookmarksToolbar)
        self._navigationContainer.setTabBar(self._tabWidget.tabBar())

        self._mainSplitter.addWidget(self._tabWidget)
        self._mainSplitter.setCollapsible(0, False)

        self._mainLayout.addWidget(self._navigationContainer)
        self._mainLayout.addWidget(self._mainSplitter)

        self._statusBar = StatusBar(self)
        self._statusBar.setObjectName('mainwindow-statusbar')
        self._statusBar.setCursor(Qt.ArrowCursor)
        self.setStatusBar(self._statusBar)
        self._progressBar = ProgressBar(self._statusBar)
        self._ipLabel = QLabel(self)
        self._ipLabel.setObjectName('statusbar-ip-label')
        self._ipLabel.setToolTip('IP Address of current page')

        self._statusBar.addPermanentWidget(self._progressBar)
        self._statusBar.addPermanentWidget(self.ipLabel())

        downloadsButton = DownloadsButton(self)
        self._statusBar.addButton(downloadsButton)
        self._navigationToolbar.addToolButton(downloadsButton)

        desktop = gVar.app.desktop()
        windowWidth = desktop.availableGeometry().width() / 1.3
        windowHeight = desktop.availableGeometry().height() / 1.3

        # Let the WM decides where to put new browser window
        if self._windowType not in (const.BW_FirstAppWindow, const.BW_MacFirstWindow) and \
                gVar.app.getWindow():
            if const.OS_WIN:
                # Windows WM places every new window in the middle of screen .. for some reason
                p = gVar.app.getWindow().geometry().topLeft()
                p.setX(p.x() + 30)
                p.setY(p.y() + 30)
                if not desktop.availableGeometry(
                        gVar.app.getWindow()).contains(p):
                    p.setX(
                        desktop.availableGeometry(gVar.app.getWindow()).x() +
                        30)
                    p.setY(
                        desktop.availableGeometry(gVar.app.getWindow()).y() +
                        30)
                self.setGeometry(QRect(p, gVar.app.getWindow().size()))
            else:
                self.resize(gVar.app.getWindow().size())
        elif not self.restoreGeometry(windowGeometry):
            if const.OS_WIN:
                self.setGeometry(
                    QRect(
                        desktop.availableGeometry(gVar.app.getWindow()).x() +
                        30,
                        desktop.availableGeometry(gVar.app.getWindow()).y() +
                        30, windowWidth, windowHeight))
            else:
                self.resize(windowWidth, windowHeight)

        self._restoreUiState(uiState)
        # Set some sane minimum width
        self.setMinimumWidth(300)
    def paintEvent(self, event):
        """ overload of paintEvent Qt function.

        Draw every stacked images with their proprieties
        (i.e.: opacity).
        
        Stack still has the same size after operation.

        Image are scaled during the process.

        QLabel's size is equals to maximum width & height
        found while reading images.
        
        Arguments:
            ev {QPaintEvent} -- A paint event which trigger display.
        """
        if not self.images:
            return

        # new label size
        area_w = 0
        area_h = 0

        # Zoom
        zoom = self.zoom()

        # Init QPainter.
        painter = QPainter(self)

        # Draw every stacked images.
        # From the bottom of the stack to the top.
        for i in range(0, len(self.images)):
            # Opacity
            painter.setOpacity(self.opacities[i])
            
            # Scale and Draw
            image = self.images[i]
            
            _w = image.width() * zoom
            _h = image.height() * zoom

            if _w > area_w:
                area_w = _w
            
            if _h > area_h: 
                area_h = _h

            painter.drawImage(
                self.xx[i] * zoom,
                self.yy[i] * zoom, 
                image.scaled(
                    _w, _h,
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                )
            )

        if self.draw_rect is True:
            painter.setPen(QPen(self.rect_color))
            painter.drawRect(QRect(self.l_pos, self.r_pos))

        self.setFixedSize(area_w, area_h)
    def save(self, filename: str, do_crop: bool=False):
        """Save a RenderIrea as one image on disk.
        
        Arguments:
            filename {str} -- The filename of the new image.
        """
        if not self.images:
            return

        # new label size
        dst_w = 0
        dst_h = 0

        # Zoom
        zoom = self.zoom()

        # Current number of images into the stack.
        nbimg = len(self.images)

        # Find the current size of the output image.
        images = []
        for i in range(0, nbimg):
            image = self.images[i]

            _w = image.width() * zoom
            _h = image.height() * zoom

            if _w > dst_w:
                dst_w = _w
            
            if _h > dst_h: 
                dst_h = _h

            # Scale now
            images.append(
                image.scaled(
                _w, _h,
                Qt.KeepAspectRatio,
                Qt.SmoothTransformation
            ))

        # Output image
        # ARGB since we can have all types of images (colors/grayscale/alpha channel)
        dst = QImage(dst_w, dst_h, QImage.Format_ARGB32)
        dst.fill(0) # black pixels everywhere

        # Init QPainter.
        painter = QPainter()
        painter.begin(dst) # Begin to draw inside the `dst` Image

        # Draw every stacked images.
        # From the bottom of the stack to the top.
        for i in range(0, nbimg):
            # Opacity
            painter.setOpacity(self.opacities[i])
            painter.drawImage(
                self.xx[i] * zoom,
                self.yy[i] * zoom,
                images[i]
            )

        painter.end()

        # Crop or not to crop?
        if do_crop and self.draw_rect:
            rect = QRect(self.l_pos, self.r_pos)
            dst = dst.copy(rect)

        # Save image, max quality
        dst.save(filename, None, 100)
Beispiel #25
0
 def heightForWidth(self, width):
     return self.do_layout(QRect(0, 0, width, 0), apply_geometry=False)
    def paintEvent(self, event):
        '''
        @param: event QPaintEvent
        '''
        p = QPainter(self)

        # Just draw separator
        if self._bookmark.isSeparator():
            opt = QStyleOption()
            opt.initFrom(self)
            opt.state |= QStyle.State_Horizontal
            self.style().drawPrimitive(QStyle.PE_IndicatorToolBarSeparator,
                                       opt, p)
            return

        option = QStyleOptionButton()
        self.initStyleOption(option)

        # We are manually drawing the arrow
        option.features &= ~QStyleOptionButton.HasMenu

        # Draw button base (only under mouse, this is autoraise button)
        if self.isDown() or self.hitButton(self.mapFromGlobal(QCursor.pos())):
            option.state |= QStyle.State_AutoRaise | QStyle.State_Raised
            self.style().drawPrimitive(QStyle.PE_PanelButtonTool, option, p,
                                       self)

        if self.isDown():
            shiftX = self.style().pixelMetric(QStyle.PM_ButtonShiftHorizontal,
                                              option, self)
            shiftY = self.style().pixelMetric(QStyle.PM_ButtonShiftVertical,
                                              option, self)
        else:
            shiftX = 0
            shiftY = 0

        height = option.rect.height()
        center = height / 2 + option.rect.top() + shiftY

        iconSize = 16
        iconYPos = center - iconSize / 2

        leftPosition = self.PADDING + shiftX
        rightPosition = option.rect.right() - self.PADDING

        # Draw icon
        if not self._showOnlyText:
            iconRect = QRect(leftPosition, iconYPos, iconSize, iconSize)
            p.drawPixmap(
                QStyle.visualRect(option.direction, option.rect, iconRect),
                self._bookmark.icon().pixmap(iconSize))
            leftPosition = iconRect.right() + self.PADDING

        # Draw menu arrow
        if not self._showOnlyIcon and self.menu():
            arrowSize = 8
            opt = QStyleOption()
            opt.initFrom(self)
            rect = QRect(rightPosition - 8, center - arrowSize / 2, arrowSize,
                         arrowSize)
            opt.rect = QStyle.visualRect(option.direction, option.rect, rect)
            opt.state &= ~QStyle.State_MouseOver
            self.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, opt, p,
                                       self)
            rightPosition = rect.left() - self.PADDING

        # Draw text
        if not self._showOnlyIcon:
            textWidth = rightPosition - leftPosition
            textYPos = center - self.fontMetrics().height() / 2
            txt = self.fontMetrics().elidedText(self._bookmark.title(),
                                                Qt.ElideRight, textWidth)
            textRect = QRect(leftPosition, textYPos, textWidth,
                             self.fontMetrics().height())
            self.style().drawItemText(
                p, QStyle.visualRect(option.direction, option.rect, textRect),
                Qt.TextSingleLine | Qt.AlignCenter, option.palette, True, txt)
Beispiel #27
0
 def paint_embossed_emblem(self,
                           pixmap,
                           painter,
                           orect,
                           right_adjust,
                           left=True):
     drect = QRect(orect)
     if left:
         drect.setLeft(drect.left() + right_adjust)
         drect.setRight(drect.left() + pixmap.width())
     else:
         drect.setRight(drect.right() - right_adjust)
         drect.setLeft(drect.right() - pixmap.width() + 1)
     drect.setBottom(drect.bottom() - self.title_height)
     drect.setTop(drect.bottom() - pixmap.height())
     painter.drawPixmap(drect, pixmap)
Beispiel #28
0
    def dump(self, items, out_stream, pdf_metadata):
        opts = self.opts
        page_size = get_page_size(self.opts)
        xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY()

        def margin(which):
            val = getattr(opts, 'pdf_page_margin_' + which)
            if val == 0.0:
                val = getattr(opts, 'margin_' + which)
            return val
        ml, mr, mt, mb = map(margin, 'left right top bottom'.split())
        # We cannot set the side margins in the webview as there is no right
        # margin for the last page (the margins are implemented with
        # -webkit-column-gap)
        self.doc = PdfDevice(out_stream, page_size=page_size, left_margin=ml,
                             top_margin=0, right_margin=mr, bottom_margin=0,
                             xdpi=xdpi, ydpi=ydpi, errors=self.log.error,
                             debug=self.log.debug, compress=not
                             opts.uncompressed_pdf, opts=opts,
                             mark_links=opts.pdf_mark_links, page_margins=(ml, mr, mt, mb))
        self.footer = opts.pdf_footer_template
        if self.footer:
            self.footer = self.footer.strip()
        if not self.footer and opts.pdf_page_numbers:
            self.footer = '<p style="text-align:center; text-indent: 0">_PAGENUM_</p>'
        self.header = opts.pdf_header_template
        if self.header:
            self.header = self.header.strip()
        min_margin = 1.5 * opts._final_base_font_size
        if self.footer and mb < min_margin:
            self.log.warn('Bottom margin is too small for footer, increasing it to %.1fpts' % min_margin)
            mb = min_margin
        if self.header and mt < min_margin:
            self.log.warn('Top margin is too small for header, increasing it to %.1fpts' % min_margin)
            mt = min_margin

        self.page.setViewportSize(QSize(self.doc.width(), self.doc.height()))
        self.render_queue = items
        self.total_items = len(items)

        mt, mb = map(self.doc.to_px, (mt, mb))
        self.margin_top, self.margin_bottom = map(lambda x:int(floor(x)), (mt, mb))

        self.painter = QPainter(self.doc)
        try:
            self.book_language = pdf_metadata.mi.languages[0]
        except Exception:
            self.book_language = 'eng'
        self.doc.set_metadata(title=pdf_metadata.title,
                              author=pdf_metadata.author,
                              tags=pdf_metadata.tags, mi=pdf_metadata.mi)
        self.doc_title = pdf_metadata.title
        self.doc_author = pdf_metadata.author
        self.painter.save()
        try:
            if self.cover_data is not None:
                p = QPixmap()
                try:
                    p.loadFromData(self.cover_data)
                except TypeError:
                    self.log.warn('This ebook does not have a raster cover, cannot generate cover for PDF'
                                  '. Cover type: %s' % type(self.cover_data))
                if not p.isNull():
                    self.doc.init_page()
                    draw_image_page(QRect(*self.doc.full_page_rect),
                            self.painter, p,
                            preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
                    self.doc.end_page()
        finally:
            self.painter.restore()

        QTimer.singleShot(0, self.render_book)
        if self.loop.exec_() == 1:
            raise Exception('PDF Output failed, see log for details')

        if self.toc is not None and len(self.toc) > 0:
            self.doc.add_outline(self.toc)

        self.painter.end()

        if self.doc.errors_occurred:
            raise Exception('PDF Output failed, see log for details')
Beispiel #29
0
    def paintEvent(self, event):
        w = self.viewport().rect().width()
        painter = QPainter(self.viewport())
        painter.setClipRect(event.rect())
        painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
        floor = event.rect().bottom()
        ceiling = event.rect().top()
        fv = self.firstVisibleBlock().blockNumber()
        origin = self.contentOffset()
        doc = self.document()
        lines = []

        for num, text in self.headers:
            top, bot = num, num + 3
            if bot < fv:
                continue
            y_top = self.blockBoundingGeometry(
                doc.findBlockByNumber(top)).translated(origin).y()
            y_bot = self.blockBoundingGeometry(
                doc.findBlockByNumber(bot)).translated(origin).y()
            if max(y_top, y_bot) < ceiling:
                continue
            if min(y_top, y_bot) > floor:
                break
            painter.setFont(self.heading_font)
            br = painter.drawText(3, y_top, w, y_bot - y_top - 5,
                                  Qt.TextSingleLine, text)
            painter.setPen(QPen(self.palette().text(), 2))
            painter.drawLine(0, br.bottom() + 3, w, br.bottom() + 3)

        for top, bot, kind in self.changes:
            if bot < fv:
                continue
            y_top = self.blockBoundingGeometry(
                doc.findBlockByNumber(top)).translated(origin).y()
            y_bot = self.blockBoundingGeometry(
                doc.findBlockByNumber(bot)).translated(origin).y()
            if max(y_top, y_bot) < ceiling:
                continue
            if min(y_top, y_bot) > floor:
                break
            if y_top != y_bot:
                painter.fillRect(0, y_top, w, y_bot - y_top,
                                 self.diff_backgrounds[kind])
            lines.append((y_top, y_bot, kind))
            if top in self.images:
                img, maxw = self.images[top][:2]
                if bot > top + 1 and not img.isNull():
                    y_top = self.blockBoundingGeometry(
                        doc.findBlockByNumber(top +
                                              1)).translated(origin).y() + 3
                    y_bot -= 3
                    scaled, imgw, imgh = fit_image(
                        int(img.width() / img.devicePixelRatio()),
                        int(img.height() / img.devicePixelRatio()), w - 3,
                        y_bot - y_top)
                    painter.drawPixmap(QRect(3, y_top, imgw, imgh), img)

        painter.end()
        PlainTextEdit.paintEvent(self, event)
        painter = QPainter(self.viewport())
        painter.setClipRect(event.rect())
        for top, bottom, kind in sorted(
                lines, key=lambda t_b_k: {'replace': 0}.get(t_b_k[2], 1)):
            painter.setPen(QPen(self.diff_foregrounds[kind], 1))
            painter.drawLine(0, top, w, top)
            painter.drawLine(0, bottom - 1, w, bottom - 1)
Beispiel #30
0
class Declaration(QWidget):

    hyperlink_activated = pyqtSignal(object)
    context_menu_requested = pyqtSignal(object, object)

    def __init__(self, html_name, data, is_first=False, parent=None):
        QWidget.__init__(self, parent)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self.data = data
        self.is_first = is_first
        self.html_name = html_name
        self.lines_for_copy = []
        self.do_layout()
        self.setMouseTracking(True)

    def do_layout(self):
        fm = self.fontMetrics()
        bounding_rect = lambda text: fm.boundingRect(0, 0, 10000, 10000, Cell.
                                                     FLAGS, text)
        line_spacing = 2
        side_margin = Cell.SIDE_MARGIN
        self.rows = []
        ypos = line_spacing + (1 if self.is_first else 0)
        if 'href' in self.data:
            name = self.data['href']
            if isinstance(name, list):
                name = self.html_name
            br1 = bounding_rect(name)
            sel = self.data['selector'] or ''
            if self.data['type'] == 'inline':
                sel = 'style=""'
            br2 = bounding_rect(sel)
            self.hyperlink_rect = QRect(side_margin, ypos, br1.width(),
                                        br1.height())
            self.rows.append([
                Cell(name, self.hyperlink_rect, color_role=QPalette.Link),
                Cell(sel,
                     QRect(br1.right() + side_margin, ypos, br2.width(),
                           br2.height()),
                     right_align=True)
            ])
            ypos += max(br1.height(), br2.height()) + 2 * line_spacing
            self.lines_for_copy.append(name + ' ' + sel)

        for prop in self.data['properties']:
            text = prop.name + ':\xa0'
            br1 = bounding_rect(text)
            vtext = prop.value + '\xa0' + ('!' if prop.important else
                                           '') + prop.important
            br2 = bounding_rect(vtext)
            self.rows.append([
                Cell(text,
                     QRect(side_margin, ypos, br1.width(), br1.height()),
                     color_role=QPalette.LinkVisited,
                     is_overriden=prop.is_overriden),
                Cell(vtext,
                     QRect(br1.right() + side_margin, ypos, br2.width(),
                           br2.height()),
                     swatch=prop.color,
                     is_overriden=prop.is_overriden)
            ])
            self.lines_for_copy.append(text + vtext)
            ypos += max(br1.height(), br2.height()) + line_spacing

        self.height_hint = ypos + line_spacing
        self.width_hint = max(row[-1].rect.right() + side_margin
                              for row in self.rows) if self.rows else 0

    def sizeHint(self):
        return QSize(self.width_hint, self.height_hint)

    def paintEvent(self, ev):
        p = QPainter(self)
        p.setClipRect(ev.rect())
        palette = self.palette()
        p.setPen(palette.color(QPalette.WindowText))
        if not self.is_first:
            p.drawLine(0, 0, self.width(), 0)
        try:
            for row in self.rows:
                for cell in row:
                    p.save()
                    try:
                        cell.draw(p, self.width(), palette)
                    finally:
                        p.restore()

        finally:
            p.end()

    def mouseMoveEvent(self, ev):
        if hasattr(self, 'hyperlink_rect'):
            pos = ev.pos()
            hovering = self.hyperlink_rect.contains(pos)
            self.update_hover(hovering)
            cursor = Qt.ArrowCursor
            for r, row in enumerate(self.rows):
                for cell in row:
                    if cell.rect.contains(pos):
                        cursor = Qt.PointingHandCursor if cell.rect is self.hyperlink_rect else Qt.IBeamCursor
                    if r == 0:
                        break
                if cursor != Qt.ArrowCursor:
                    break
            self.setCursor(cursor)
        return QWidget.mouseMoveEvent(self, ev)

    def mousePressEvent(self, ev):
        if hasattr(self, 'hyperlink_rect') and ev.button() == Qt.LeftButton:
            pos = ev.pos()
            if self.hyperlink_rect.contains(pos):
                self.emit_hyperlink_activated()
        return QWidget.mousePressEvent(self, ev)

    def emit_hyperlink_activated(self):
        dt = self.data['type']
        data = {'type': dt, 'name': self.html_name, 'syntax': 'html'}
        if dt == 'inline':  # style attribute
            data['sourceline_address'] = self.data['href']
        elif dt == 'elem':  # <style> tag
            data['sourceline_address'] = self.data['href']
            data['rule_address'] = self.data['rule_address']
        else:  # stylesheet
            data['name'] = self.data['href']
            data['rule_address'] = self.data['rule_address']
            data['syntax'] = 'css'
        self.hyperlink_activated.emit(data)

    def leaveEvent(self, ev):
        self.update_hover(False)
        self.setCursor(Qt.ArrowCursor)
        return QWidget.leaveEvent(self, ev)

    def update_hover(self, hovering):
        cell = self.rows[0][0]
        if (hovering and cell.override_color is None) or (
                not hovering and cell.override_color is not None):
            cell.override_color = QColor(Qt.red) if hovering else None
            self.update()

    def contextMenuEvent(self, ev):
        self.context_menu_requested.emit(self, ev)
Beispiel #31
0
class Declaration(QWidget):

    hyperlink_activated = pyqtSignal(object)

    def __init__(self, html_name, data, is_first=False, parent=None):
        QWidget.__init__(self, parent)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self.data = data
        self.is_first = is_first
        self.html_name = html_name
        self.do_layout()
        self.setMouseTracking(True)

    def do_layout(self):
        fm = self.fontMetrics()
        bounding_rect = lambda text: fm.boundingRect(0, 0, 10000, 10000, Cell.FLAGS, text)
        line_spacing = 2
        side_margin = Cell.SIDE_MARGIN
        self.rows = []
        ypos = line_spacing + (1 if self.is_first else 0)
        if "href" in self.data:
            name = self.data["href"]
            if isinstance(name, list):
                name = self.html_name
            br1 = bounding_rect(name)
            sel = self.data["selector"] or ""
            if self.data["type"] == "inline":
                sel = 'style=""'
            br2 = bounding_rect(sel)
            self.hyperlink_rect = QRect(side_margin, ypos, br1.width(), br1.height())
            self.rows.append(
                [
                    Cell(name, self.hyperlink_rect, color_role=QPalette.Link),
                    Cell(sel, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), right_align=True),
                ]
            )
            ypos += max(br1.height(), br2.height()) + 2 * line_spacing

        for prop in self.data["properties"]:
            text = prop.name + ":\xa0"
            br1 = bounding_rect(text)
            vtext = prop.value + "\xa0" + ("!" if prop.important else "") + prop.important
            br2 = bounding_rect(vtext)
            self.rows.append(
                [
                    Cell(
                        text,
                        QRect(side_margin, ypos, br1.width(), br1.height()),
                        color_role=QPalette.LinkVisited,
                        is_overriden=prop.is_overriden,
                    ),
                    Cell(
                        vtext,
                        QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()),
                        swatch=prop.color,
                        is_overriden=prop.is_overriden,
                    ),
                ]
            )
            ypos += max(br1.height(), br2.height()) + line_spacing

        self.height_hint = ypos + line_spacing
        self.width_hint = max(row[-1].rect.right() + side_margin for row in self.rows) if self.rows else 0

    def sizeHint(self):
        return QSize(self.width_hint, self.height_hint)

    def paintEvent(self, ev):
        p = QPainter(self)
        p.setClipRect(ev.rect())
        palette = self.palette()
        p.setPen(palette.color(QPalette.WindowText))
        if not self.is_first:
            p.drawLine(0, 0, self.width(), 0)
        try:
            for row in self.rows:
                for cell in row:
                    p.save()
                    try:
                        cell.draw(p, self.width(), palette)
                    finally:
                        p.restore()

        finally:
            p.end()

    def mouseMoveEvent(self, ev):
        if hasattr(self, "hyperlink_rect"):
            pos = ev.pos()
            hovering = self.hyperlink_rect.contains(pos)
            self.update_hover(hovering)
            cursor = Qt.ArrowCursor
            for r, row in enumerate(self.rows):
                for cell in row:
                    if cell.rect.contains(pos):
                        cursor = Qt.PointingHandCursor if cell.rect is self.hyperlink_rect else Qt.IBeamCursor
                    if r == 0:
                        break
                if cursor != Qt.ArrowCursor:
                    break
            self.setCursor(cursor)
        return QWidget.mouseMoveEvent(self, ev)

    def mousePressEvent(self, ev):
        if hasattr(self, "hyperlink_rect"):
            pos = ev.pos()
            if self.hyperlink_rect.contains(pos):
                self.emit_hyperlink_activated()
        return QWidget.mousePressEvent(self, ev)

    def emit_hyperlink_activated(self):
        dt = self.data["type"]
        data = {"type": dt, "name": self.html_name, "syntax": "html"}
        if dt == "inline":  # style attribute
            data["sourceline_address"] = self.data["href"]
        elif dt == "elem":  # <style> tag
            data["sourceline_address"] = self.data["href"]
            data["rule_address"] = self.data["rule_address"]
        else:  # stylesheet
            data["name"] = self.data["href"]
            data["rule_address"] = self.data["rule_address"]
            data["syntax"] = "css"
        self.hyperlink_activated.emit(data)

    def leaveEvent(self, ev):
        self.update_hover(False)
        self.setCursor(Qt.ArrowCursor)
        return QWidget.leaveEvent(self, ev)

    def update_hover(self, hovering):
        cell = self.rows[0][0]
        if (hovering and cell.override_color is None) or (not hovering and cell.override_color is not None):
            cell.override_color = QColor(Qt.red) if hovering else None
            self.update()
Beispiel #32
0
default_config_path = join(dirname(abspath(__file__)), "config_test.cfg")


@pytest.fixture
def init_paths():
    importExportUtils.DEFAULT_CONFIG_PATH = default_config_path
    importExportUtils.ALERT_DB_PATH = alert_db_path


sound_path = join(dirname(dirname(abspath(__file__))), 'resources', 'sounds',
                  'floop.wav')
im_path = join(dirname(dirname(abspath(__file__))), 'resources', 'images',
               'notification_clock.png')

notification = Notification("Test", "000000", "Times", 12, sound_path)
rect = QRect(0, 0, 1024, 768)

# A App is needed for the MainWindow
app = App(default_config_path, alert_db_path, [])
mw = app.main_window


@pytest.mark.test
def test_constructor(init_paths):
    """Test :class:~_clockalarm.UI.MainWindow constructor."""
    global mw

    assert mw.minimumSize() == QSize(300, 100)
    assert mw.windowTitle() == "ClockAlarm Manager"
    assert mw.size() == QSize(800, 400)
Beispiel #33
0
    def drawIconWithShadow(self,
                           icon,
                           rect,
                           painter,
                           iconMode,
                           radius=3,
                           color=QColor(0, 0, 0, 130),
                           offset=QPoint(1, -2)):
        '''
        @brief: Draw a cached pixmap with shadow
        @param: icon QIcon
        @param: rect QRect
        @param: painter QPainter
        @param: iconMode QIcon.Mode
        @param: radius int
        @param: color QColor
        @param: offset QPoint
        '''
        cache = QPixmap()
        pixmapName = 'icon %s %s %s' % (icon.cacheKey(), iconMode,
                                        rect.height())

        cache = QPixmapCache.find(pixmapName)
        if not cache:
            px = icon.pixmap(rect.size(), iconMode)
            px.setDevicePixelRatio(gVar.app.devicePixelRatio())
            cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
            cache.setDevicePixelRatio(px.devicePixelRatioF())
            cache.fill(Qt.transparent)

            cachePainter = QPainter(cache)

            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1),
                         QImage.Format_ARGB32_Premultiplied)
            tmp.setDevicePixelRatio(px.devicePixelRatioF())
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)

            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(QPoint(radius, radius), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            # TODO:
            #qt_blurImage(blurPainter, tmp, radius, False, True)
            blurPainter.end()

            tmp = blurred

            # blacken the image...
            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            # draw the blurred drop shadow...
            cachePainter.drawImage(
                QRect(0, 0,
                      cache.rect().width() / cache.devicePixelRatioF(),
                      cache.rect().height() / cache.devicePixelRatioF()), tmp)
            # Draw the actual pixmap...
            cachePainter.drawPixmap(QPoint(radius, radius) + offset, px)
            if self.usePixmapCache():
                QPixmapCache.insert(pixmapName, cache)

            sip.delete(cachePainter)
            sip.delete(tmpPainter)
            sip.delete(blurPainter)

        targetRect = QRect(cache.rect())
        targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF())
        targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF())
        targetRect.moveCenter(rect.center())
        painter.drawPixmap(targetRect.topLeft() - offset, cache)
Beispiel #34
0
 def draw_text(self, style, painter, option, widget, index, item):
     tr = style.subElementRect(style.SE_ItemViewItemText, option, widget)
     text = index.data(Qt.DisplayRole)
     hover = option.state & style.State_MouseOver
     if hover or gprefs['tag_browser_show_counts']:
         count = unicode_type(index.data(COUNT_ROLE))
         width = painter.fontMetrics().boundingRect(count).width()
         r = QRect(tr)
         r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
         painter.drawText(r, Qt.AlignCenter | Qt.TextSingleLine, count)
         tr.setRight(r.left() - 1)
     else:
         tr.setRight(tr.right() - 1)
     is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text)
     if is_rating:
         painter.setFont(self.rating_font)
     flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine
     lr = QRect(tr)
     lr.setRight(lr.right() * 2)
     br = painter.boundingRect(lr, flags, text)
     if br.width() > tr.width():
         g = QLinearGradient(tr.topLeft(), tr.topRight())
         c = option.palette.color(QPalette.WindowText)
         g.setColorAt(0, c), g.setColorAt(0.8, c)
         c = QColor(c)
         c.setAlpha(0)
         g.setColorAt(1, c)
         pen = QPen()
         pen.setBrush(QBrush(g))
         painter.setPen(pen)
     painter.drawText(tr, flags, text)
    def __init__(self, opts):
        self.matched_ids = set()
        self.opts = opts
        self.prefs = opts.prefs
        super(FindAnnotationsDialog, self).__init__(self.opts.gui,
                                                    'find_annotations_dialog')
        self.setWindowTitle(_('Find Annotations'))
        self.setWindowIcon(self.opts.icon)
        self.l = QVBoxLayout(self)
        self.setLayout(self.l)

        self.search_criteria_gb = QGroupBox(self)
        self.search_criteria_gb.setTitle(_("Search criteria"))
        self.scgl = QGridLayout(self.search_criteria_gb)
        self.l.addWidget(self.search_criteria_gb)
        # addWidget(widget, row, col, rowspan, colspan)

        row = 0
        # ~~~~~~~~ Create the Readers comboBox ~~~~~~~~
        self.reader_label = QLabel(_('Reader'))
        self.reader_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.scgl.addWidget(self.reader_label, row, 0, 1, 1)

        self.find_annotations_reader_comboBox = QComboBox()
        self.find_annotations_reader_comboBox.setObjectName(
            'find_annotations_reader_comboBox')
        self.find_annotations_reader_comboBox.setToolTip(
            _('Reader annotations to search for'))

        self.find_annotations_reader_comboBox.addItem(self.GENERIC_READER)
        racs = ReaderApp.get_reader_app_classes()
        for ra in sorted(list(racs.keys())):
            self.find_annotations_reader_comboBox.addItem(ra)
        self.scgl.addWidget(self.find_annotations_reader_comboBox, row, 1, 1,
                            4)
        row += 1

        # ~~~~~~~~ Create the Styles comboBox ~~~~~~~~
        self.style_label = QLabel(_('Style'))
        self.style_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.scgl.addWidget(self.style_label, row, 0, 1, 1)

        self.find_annotations_color_comboBox = QComboBox()
        self.find_annotations_color_comboBox.setObjectName(
            'find_annotations_color_comboBox')
        self.find_annotations_color_comboBox.setToolTip(
            _('Annotation style to search for'))

        self.find_annotations_color_comboBox.addItem(self.GENERIC_STYLE)
        all_colors = list(COLOR_MAP.keys())
        all_colors.remove('Default')
        for color in sorted(all_colors):
            self.find_annotations_color_comboBox.addItem(color)
        self.scgl.addWidget(self.find_annotations_color_comboBox, row, 1, 1, 4)
        row += 1

        # ~~~~~~~~ Create the Text LineEdit control ~~~~~~~~
        self.text_label = QLabel(_('Text'))
        self.text_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.scgl.addWidget(self.text_label, row, 0, 1, 1)
        self.find_annotations_text_lineEdit = MyLineEdit()
        self.find_annotations_text_lineEdit.setObjectName(
            'find_annotations_text_lineEdit')
        self.scgl.addWidget(self.find_annotations_text_lineEdit, row, 1, 1, 3)
        self.reset_text_tb = QToolButton()
        self.reset_text_tb.setObjectName('reset_text_tb')
        self.reset_text_tb.setToolTip(_('Clear search criteria'))
        self.reset_text_tb.setIcon(QIcon(I('trash.png')))
        self.reset_text_tb.clicked.connect(self.clear_text_field)
        self.scgl.addWidget(self.reset_text_tb, row, 4, 1, 1)
        row += 1

        # ~~~~~~~~ Create the Note LineEdit control ~~~~~~~~
        self.note_label = QLabel(_('Note'))
        self.note_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.scgl.addWidget(self.note_label, row, 0, 1, 1)
        self.find_annotations_note_lineEdit = MyLineEdit()
        self.find_annotations_note_lineEdit.setObjectName(
            'find_annotations_note_lineEdit')
        self.scgl.addWidget(self.find_annotations_note_lineEdit, row, 1, 1, 3)
        self.reset_note_tb = QToolButton()
        self.reset_note_tb.setObjectName('reset_note_tb')
        self.reset_note_tb.setToolTip(_('Clear search criteria'))
        self.reset_note_tb.setIcon(QIcon(I('trash.png')))
        self.reset_note_tb.clicked.connect(self.clear_note_field)
        self.scgl.addWidget(self.reset_note_tb, row, 4, 1, 1)
        row += 1

        # ~~~~~~~~ Create the Date range controls ~~~~~~~~
        self.date_range_label = QLabel(_('Date range'))
        self.date_range_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.scgl.addWidget(self.date_range_label, row, 0, 1, 1)

        # Date 'From'
        self.find_annotations_date_from_dateEdit = MyDateEdit(
            self, datetime(1970, 1, 1))
        self.find_annotations_date_from_dateEdit.setObjectName(
            'find_annotations_date_from_dateEdit')
        #self.find_annotations_date_from_dateEdit.current_val = datetime(1970,1,1)
        self.find_annotations_date_from_dateEdit.clear_button.clicked.connect(
            self.find_annotations_date_from_dateEdit.reset_from_date)
        self.scgl.addWidget(self.find_annotations_date_from_dateEdit, row, 1,
                            1, 1)
        self.scgl.addWidget(
            self.find_annotations_date_from_dateEdit.clear_button, row, 2, 1,
            1)

        # Date 'To'
        self.find_annotations_date_to_dateEdit = MyDateEdit(
            self, datetime.today())
        self.find_annotations_date_to_dateEdit.setObjectName(
            'find_annotations_date_to_dateEdit')
        #self.find_annotations_date_to_dateEdit.current_val = datetime.today()
        self.find_annotations_date_to_dateEdit.clear_button.clicked.connect(
            self.find_annotations_date_to_dateEdit.reset_to_date)
        self.scgl.addWidget(self.find_annotations_date_to_dateEdit, row, 3, 1,
                            1)
        self.scgl.addWidget(
            self.find_annotations_date_to_dateEdit.clear_button, row, 4, 1, 1)
        row += 1

        # ~~~~~~~~ Create a horizontal line ~~~~~~~~
        self.hl = QFrame(self)
        self.hl.setGeometry(QRect(0, 0, 1, 3))
        self.hl.setFrameShape(QFrame.HLine)
        self.hl.setFrameShadow(QFrame.Raised)
        self.scgl.addWidget(self.hl, row, 0, 1, 5)
        row += 1

        # ~~~~~~~~ Create the results label field ~~~~~~~~
        self.result_label = QLabel('<p style="color:red">{0}</p>'.format(
            _('scanning…')))
        self.result_label.setAlignment(Qt.AlignCenter)
        self.result_label.setWordWrap(False)

        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum,
                                       QtGui.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.result_label.sizePolicy().hasHeightForWidth())
        self.result_label.setSizePolicy(sizePolicy)
        self.result_label.setMinimumSize(QtCore.QSize(250, 0))
        self.scgl.addWidget(self.result_label, row, 0, 1, 5)
        row += 1

        # ~~~~~~~~ Create the ButtonBox ~~~~~~~~
        self.dialogButtonBox = QDialogButtonBox(self)
        self.dialogButtonBox.setOrientation(Qt.Horizontal)
        if False:
            self.update_button = QPushButton(_('Update results'))
            self.update_button.setDefault(True)
            self.update_button.setVisible(False)
            self.dialogButtonBox.addButton(self.update_button,
                                           QDialogButtonBox.ActionRole)

        self.cancel_button = self.dialogButtonBox.addButton(
            self.dialogButtonBox.Cancel)
        self.find_button = self.dialogButtonBox.addButton(
            self.dialogButtonBox.Ok)
        self.find_button.setText(_('Find Matching Books'))

        self.l.addWidget(self.dialogButtonBox)
        self.dialogButtonBox.clicked.connect(
            self.find_annotations_dialog_clicked)

        # ~~~~~~~~ Add a spacer ~~~~~~~~
        self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
                                            QtGui.QSizePolicy.Expanding)
        self.l.addItem(self.spacerItem)

        # ~~~~~~~~ Restore previously saved settings ~~~~~~~~
        self.restore_settings()

        # ~~~~~~~~ Declare sizing ~~~~~~~~
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred,
                                       QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.resize_dialog()

        # ~~~~~~~~ Connect all signals ~~~~~~~~
        self.find_annotations_reader_comboBox.currentIndexChanged.connect(
            partial(self.update_results, 'reader'))
        self.find_annotations_color_comboBox.currentIndexChanged.connect(
            partial(self.update_results, 'color'))
        self.find_annotations_text_lineEdit.editingFinished.connect(
            partial(self.update_results, 'text'))
        self.find_annotations_note_lineEdit.editingFinished.connect(
            partial(self.update_results, 'note'))
        #        self.connect(self.find_annotations_text_lineEdit, pyqtSignal("return_pressed"), self.return_pressed)
        self.find_annotations_text_lineEdit.return_pressed.connect(
            self.return_pressed)
        #        self.connect(self.find_annotations_note_lineEdit, pyqtSignal("return_pressed"), self.return_pressed)
        self.find_annotations_note_lineEdit.return_pressed.connect(
            self.return_pressed)

        # Date range signals connected in inventory_available()

        # ~~~~~~~~ Allow dialog to render before doing inventory ~~~~~~~~
        #field = self.prefs.get('cfg_annotations_destination_field', None)
        field = get_cc_mapping('annotations', 'field', None)
        self.annotated_books_scanner = InventoryAnnotatedBooks(
            self.opts.gui, field, get_date_range=True)
        self.annotated_books_scanner.signal.connect(self.inventory_available)
        QTimer.singleShot(1, self.start_inventory_scan)
Beispiel #36
0
 def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True):
     drect = QRect(orect)
     if left:
         drect.setLeft(drect.left() + right_adjust)
         drect.setRight(drect.left() + pixmap.width())
     else:
         drect.setRight(drect.right() - right_adjust)
         drect.setLeft(drect.right() - pixmap.width() + 1)
     drect.setBottom(drect.bottom() - self.title_height)
     drect.setTop(drect.bottom() - pixmap.height())
     painter.drawPixmap(drect, pixmap)
Beispiel #37
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     hovering = index.data(HOVER_ROLE) is True
     painter.save()
     rect = option.rect
     is_current = index.data(Qt.FontRole) is not None
     if not hovering and is_current:
         qpp = QPainterPath()
         qpp.addRoundedRect(QRectF(rect), 6, 6)
         painter.fillPath(qpp, self.current_background)
     icon_rect = QRect(rect.left() + self.MARGIN, rect.top() + self.MARGIN, ICON_SIZE, ICON_SIZE)
     left = icon_rect.right() + 2 * self.MARGIN
     text_rect = QRect(left, icon_rect.top(), rect.width() - left + rect.left(), icon_rect.height())
     mark = index.data(MARK_ROLE)
     if hovering or mark:
         text_rect.adjust(0, 0, -text_rect.height(), 0)
     text = index.data(DISPLAY_ROLE) or ''
     font = index.data(Qt.FontRole)
     if font:
         painter.setFont(font)
     text_flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine
     text = elided_text(text, font, text_rect.width(), 'right')
     if option.state & QStyle.State_Selected:
         painter.setPen(QPen(self.highlighted_text))
     painter.drawText(text_rect, text_flags, text)
     if mark:
         hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height())
         painter.fillRect(hrect, QColor('#ffffaa'))
         painter.drawText(hrect, Qt.AlignCenter, mark)
     elif hovering:
         hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height())
         close_hover = index.data(CLOSE_HOVER_ROLE) is True
         if close_hover:
             pen = painter.pen()
             pen.setColor(QColor('red'))
             painter.setPen(pen)
         painter.drawText(hrect, Qt.AlignCenter, '✖ ')
     if index.data(LOADING_ROLE):
         if not self.errored_out:
             angle = index.data(ANGLE_ROLE)
             try:
                 draw_snake_spinner(painter, icon_rect, angle, self.light, self.dark)
             except Exception:
                 import traceback
                 traceback.print_exc()
                 self.errored_out = True
     else:
         icurl = index.data(URL_ROLE)
         if icurl == WELCOME_URL:
             icon = welcome_icon()
         elif icurl == DOWNLOADS_URL:
             icon = downloads_icon()
         else:
             icon = index.data(DECORATION_ROLE)
         icon.paint(painter, icon_rect)
     painter.restore()
Beispiel #38
0
 def paint_emblems(self, painter, rect, emblems):
     gutter = self.emblem_size + self.MARGIN
     grect = QRect(rect)
     gpos = self.gutter_position
     if gpos is self.TOP:
         grect.setBottom(grect.top() + gutter)
         rect.setTop(rect.top() + gutter)
     elif gpos is self.BOTTOM:
         grect.setTop(grect.bottom() - gutter + self.MARGIN)
         rect.setBottom(rect.bottom() - gutter)
     elif gpos is self.LEFT:
         grect.setRight(grect.left() + gutter)
         rect.setLeft(rect.left() + gutter)
     else:
         grect.setLeft(grect.right() - gutter + self.MARGIN)
         rect.setRight(rect.right() - gutter)
     horizontal = gpos in (self.TOP, self.BOTTOM)
     painter.save()
     painter.setClipRect(grect)
     try:
         for i, emblem in enumerate(emblems):
             delta = 0 if i == 0 else self.emblem_size + self.MARGIN
             grect.moveLeft(grect.left() + delta) if horizontal else grect.moveTop(grect.top() + delta)
             rect = QRect(grect)
             rect.setWidth(int(emblem.width() / emblem.devicePixelRatio())), rect.setHeight(int(emblem.height() / emblem.devicePixelRatio()))
             painter.drawPixmap(rect, emblem)
     finally:
         painter.restore()
Beispiel #39
0
class CameraImage(QWidget):
    _aspect_ratio = (setting.camera_resolution[1] /
                     setting.camera_resolution[0])

    def __init__(self, resize_leader):
        super().__init__()
        self._pixmap = None
        self._paint_rect = QRect(0, 0, self.width(), self.height())

        self._hover = False
        self._inspect = False
        self._resize_leader = resize_leader

        self._setup_ui()

    def set_map(self, pixmap):
        if isinstance(pixmap, QPixmap):
            self._pixmap = pixmap
            self.update()

    def _setup_ui(self):
        self.setAttribute(Qt.WA_Hover, True)
        self.setContentsMargins(0, 0, 0, 0)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._inspect_map = icons.get('inspect')
        self._pixmap = icons.get('connect_none')

    def set_inspect(self, inspect):
        if self._inspect != inspect:
            self._inspect = inspect
            self.update()

    def resizeEvent(self, event):
        if self.width() * setting.camera_resolution[1] >\
                self.height() * setting.camera_resolution[0]:
            width = self.height() / self._aspect_ratio
            width_margin = (self.width() - width) / 2
            self._paint_rect = QRect(width_margin, 0, width, self.height())
        else:
            height = self.width() * self._aspect_ratio
            height_margin = (self.height() - height) / 2
            self._paint_rect = QRect(0, height_margin, self.width(), height)

        if (self._resize_leader and self.isVisible()):
            value = self._paint_rect.width()
            if value > 0:
                state.set('live_view_size', value)

    def enterEvent(self, event):
        if not self._inspect:
            self._hover = True
            self.setCursor(Qt.PointingHandCursor)

    def leaveEvent(self, event):
        self._hover = False
        self.unsetCursor()

    def paintEvent(self, event):
        painter = QPainter(self)

        if self._inspect:
            painter.drawPixmap(
                (self.width() - self._inspect_map.width()) / 2,
                (self.height() - self._inspect_map.height()) / 2,
                self._inspect_map)
            return

        if self._pixmap.width() > 50:
            painter.setRenderHint(QPainter.SmoothPixmapTransform)
            painter.drawPixmap(self._paint_rect, self._pixmap)
        else:
            painter.drawPixmap((self.width() - self._pixmap.width()) / 2,
                               (self.height() - self._pixmap.height()) / 2,
                               self._pixmap)

        if self._hover:
            painter.setPen(QPen(self.palette().highlight().color(), 2))
            painter.drawRect(self._paint_rect)
Beispiel #40
0
    def resizeEvent(self, event):
        QPlainTextEdit.resizeEvent(self, event)

        contents_rect = self.contentsRect()
        self._line_number_area.setGeometry(QRect(contents_rect.left(), contents_rect.top(), self.lineNumberAreaWidth(), contents_rect.height()))
Beispiel #41
0
 def paint_emblems(self, painter, rect, emblems):
     gutter = self.emblem_size + self.MARGIN
     grect = QRect(rect)
     gpos = self.gutter_position
     if gpos is self.TOP:
         grect.setBottom(grect.top() + gutter)
         rect.setTop(rect.top() + gutter)
     elif gpos is self.BOTTOM:
         grect.setTop(grect.bottom() - gutter + self.MARGIN)
         rect.setBottom(rect.bottom() - gutter)
     elif gpos is self.LEFT:
         grect.setRight(grect.left() + gutter)
         rect.setLeft(rect.left() + gutter)
     else:
         grect.setLeft(grect.right() - gutter + self.MARGIN)
         rect.setRight(rect.right() - gutter)
     horizontal = gpos in (self.TOP, self.BOTTOM)
     painter.save()
     painter.setClipRect(grect)
     try:
         for i, emblem in enumerate(emblems):
             delta = 0 if i == 0 else self.emblem_size + self.MARGIN
             grect.moveLeft(grect.left() + delta) if horizontal else grect.moveTop(grect.top() + delta)
             rect = QRect(grect)
             rect.setWidth(int(emblem.width() / emblem.devicePixelRatio())), rect.setHeight(int(emblem.height() / emblem.devicePixelRatio()))
             painter.drawPixmap(rect, emblem)
     finally:
         painter.restore()
Beispiel #42
0
 def draw_text(self, style, painter, option, widget, index, item):
     tr = style.subElementRect(style.SE_ItemViewItemText, option, widget)
     text = index.data(Qt.DisplayRole)
     hover = option.state & style.State_MouseOver
     if hover or gprefs['tag_browser_show_counts']:
         count = unicode_type(index.data(COUNT_ROLE))
         width = painter.fontMetrics().boundingRect(count).width()
         r = QRect(tr)
         r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
         painter.drawText(r, Qt.AlignCenter | Qt.TextSingleLine, count)
         tr.setRight(r.left() - 1)
     else:
         tr.setRight(tr.right() - 1)
     is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub(
         '', text)
     if is_rating:
         painter.setFont(self.rating_font)
     flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine
     lr = QRect(tr)
     lr.setRight(lr.right() * 2)
     br = painter.boundingRect(lr, flags, text)
     if br.width() > tr.width():
         g = QLinearGradient(tr.topLeft(), tr.topRight())
         c = option.palette.color(QPalette.WindowText)
         g.setColorAt(0, c), g.setColorAt(0.8, c)
         c = QColor(c)
         c.setAlpha(0)
         g.setColorAt(1, c)
         pen = QPen()
         pen.setBrush(QBrush(g))
         painter.setPen(pen)
     painter.drawText(tr, flags, text)
Beispiel #43
0
 def mouseMoveInLabel(self, event):
     if not self.pt1.isNull():
         pt = self.img_lbl.mapTo(self,event.pos())
         self.rubberBand.setGeometry(QRect(self.pt1_rect, pt).normalized())
Beispiel #44
0
class Declaration(QWidget):

    hyperlink_activated = pyqtSignal(object)
    context_menu_requested = pyqtSignal(object, object)

    def __init__(self, html_name, data, is_first=False, parent=None):
        QWidget.__init__(self, parent)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        self.data = data
        self.is_first = is_first
        self.html_name = html_name
        self.lines_for_copy = []
        self.do_layout()
        self.setMouseTracking(True)

    def do_layout(self):
        fm = self.fontMetrics()
        bounding_rect = lambda text: fm.boundingRect(0, 0, 10000, 10000, Cell.FLAGS, text)
        line_spacing = 2
        side_margin = Cell.SIDE_MARGIN
        self.rows = []
        ypos = line_spacing + (1 if self.is_first else 0)
        if 'href' in self.data:
            name = self.data['href']
            if isinstance(name, list):
                name = self.html_name
            br1 = bounding_rect(name)
            sel = self.data['selector'] or ''
            if self.data['type'] == 'inline':
                sel = 'style=""'
            br2 = bounding_rect(sel)
            self.hyperlink_rect = QRect(side_margin, ypos, br1.width(), br1.height())
            self.rows.append([
                Cell(name, self.hyperlink_rect, color_role=QPalette.Link),
                Cell(sel, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), right_align=True)
            ])
            ypos += max(br1.height(), br2.height()) + 2 * line_spacing
            self.lines_for_copy.append(name + ' ' + sel)

        for prop in self.data['properties']:
            text = prop.name + ':\xa0'
            br1 = bounding_rect(text)
            vtext = prop.value + '\xa0' + ('!' if prop.important else '') + prop.important
            br2 = bounding_rect(vtext)
            self.rows.append([
                Cell(text, QRect(side_margin, ypos, br1.width(), br1.height()), color_role=QPalette.LinkVisited, is_overriden=prop.is_overriden),
                Cell(vtext, QRect(br1.right() + side_margin, ypos, br2.width(), br2.height()), swatch=prop.color, is_overriden=prop.is_overriden)
            ])
            self.lines_for_copy.append(text + vtext)
            if prop.is_overriden:
                self.lines_for_copy[-1] += ' [overriden]'
            ypos += max(br1.height(), br2.height()) + line_spacing
        self.lines_for_copy.append('--------------------------\n')

        self.height_hint = ypos + line_spacing
        self.width_hint = max(row[-1].rect.right() + side_margin for row in self.rows) if self.rows else 0

    def sizeHint(self):
        return QSize(self.width_hint, self.height_hint)

    def paintEvent(self, ev):
        p = QPainter(self)
        p.setClipRect(ev.rect())
        palette = self.palette()
        p.setPen(palette.color(QPalette.WindowText))
        if not self.is_first:
            p.drawLine(0, 0, self.width(), 0)
        try:
            for row in self.rows:
                for cell in row:
                    p.save()
                    try:
                        cell.draw(p, self.width(), palette)
                    finally:
                        p.restore()

        finally:
            p.end()

    def mouseMoveEvent(self, ev):
        if hasattr(self, 'hyperlink_rect'):
            pos = ev.pos()
            hovering = self.hyperlink_rect.contains(pos)
            self.update_hover(hovering)
            cursor = Qt.ArrowCursor
            for r, row in enumerate(self.rows):
                for cell in row:
                    if cell.rect.contains(pos):
                        cursor = Qt.PointingHandCursor if cell.rect is self.hyperlink_rect else Qt.IBeamCursor
                    if r == 0:
                        break
                if cursor != Qt.ArrowCursor:
                    break
            self.setCursor(cursor)
        return QWidget.mouseMoveEvent(self, ev)

    def mousePressEvent(self, ev):
        if hasattr(self, 'hyperlink_rect') and ev.button() == Qt.LeftButton:
            pos = ev.pos()
            if self.hyperlink_rect.contains(pos):
                self.emit_hyperlink_activated()
        return QWidget.mousePressEvent(self, ev)

    def emit_hyperlink_activated(self):
        dt = self.data['type']
        data = {'type':dt, 'name':self.html_name, 'syntax':'html'}
        if dt == 'inline':  # style attribute
            data['sourceline_address'] = self.data['href']
        elif dt == 'elem':  # <style> tag
            data['sourceline_address'] = self.data['href']
            data['rule_address'] = self.data['rule_address']
        else:  # stylesheet
            data['name'] = self.data['href']
            data['rule_address'] = self.data['rule_address']
            data['syntax'] = 'css'
        self.hyperlink_activated.emit(data)

    def leaveEvent(self, ev):
        self.update_hover(False)
        self.setCursor(Qt.ArrowCursor)
        return QWidget.leaveEvent(self, ev)

    def update_hover(self, hovering):
        cell = self.rows[0][0]
        if (hovering and cell.override_color is None) or (
                not hovering and cell.override_color is not None):
            cell.override_color = QColor(Qt.red) if hovering else None
            self.update()

    def contextMenuEvent(self, ev):
        self.context_menu_requested.emit(self, ev)
Beispiel #45
0
 def resizeEvent(self, ev):
     QPlainTextEdit.resizeEvent(self, ev)
     cr = self.contentsRect()
     self.line_number_area.setGeometry(QRect(cr.left(), cr.top(), self.line_number_area_width(), cr.height()))
Beispiel #46
0
def drag_icon(self, cover, multiple):
    cover = cover.scaledToHeight(120, Qt.SmoothTransformation)
    if multiple:
        base_width = cover.width()
        base_height = cover.height()
        base = QImage(base_width+21, base_height+21,
                QImage.Format_ARGB32_Premultiplied)
        base.fill(QColor(255, 255, 255, 0).rgba())
        p = QPainter(base)
        rect = QRect(20, 0, base_width, base_height)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(10)
        rect.moveTop(10)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(0)
        rect.moveTop(20)
        p.fillRect(rect, QColor('white'))
        p.save()
        p.setCompositionMode(p.CompositionMode_SourceAtop)
        p.drawImage(rect.topLeft(), cover)
        p.restore()
        p.drawRect(rect)
        p.end()
        cover = base
    return QPixmap.fromImage(cover)
Beispiel #47
0
    def paint(self, painter, option, index):
        QStyledItemDelegate.paint(self, painter, option, empty_index)  # draw the hover and selection highlights
        m = index.model()
        db = m.db
        try:
            book_id = db.id(index.row())
        except (ValueError, IndexError, KeyError):
            return
        if book_id in m.ids_to_highlight_set:
            painter.save()
            try:
                painter.setPen(self.highlight_color)
                painter.setRenderHint(QPainter.Antialiasing, True)
                painter.drawRoundedRect(option.rect, 10, 10, Qt.RelativeSize)
            finally:
                painter.restore()
        marked = db.data.get_marked(book_id)
        db = db.new_api
        cdata = self.cover_cache[book_id]
        device_connected = self.parent().gui.device_connected is not None
        on_device = device_connected and db.field_for('ondevice', book_id)

        emblem_rules = db.pref('cover_grid_icon_rules', default=())
        emblems = []
        if self.emblem_size > 0:
            mi = None
            for i, (kind, column, rule) in enumerate(emblem_rules):
                icon_name, mi = self.render_emblem(book_id, rule, i, m.cover_grid_emblem_cache, mi, db, m.formatter, m.cover_grid_template_cache)
                if icon_name is not None:
                    pixmap = self.cached_emblem(m.cover_grid_bitmap_cache, icon_name)
                    if pixmap is not None:
                        emblems.append(pixmap)
            if marked:
                emblems.insert(0, self.cached_emblem(m.cover_grid_bitmap_cache, ':marked', m.marked_icon))
            if on_device:
                emblems.insert(0, self.cached_emblem(m.cover_grid_bitmap_cache, ':ondevice'))

        painter.save()
        right_adjust = 0
        try:
            rect = option.rect
            rect.adjust(self.MARGIN, self.MARGIN, -self.MARGIN, -self.MARGIN)
            if self.emblem_size > 0:
                self.paint_emblems(painter, rect, emblems)
            orect = QRect(rect)
            trect = QRect(rect)
            if self.title_height != 0:
                rect.setBottom(rect.bottom() - self.title_height)
                trect.setTop(trect.bottom() - self.title_height + 5)
            if cdata is None or cdata is False:
                title = db.field_for('title', book_id, default_value='')
                authors = ' & '.join(db.field_for('authors', book_id, default_value=()))
                painter.setRenderHint(QPainter.TextAntialiasing, True)
                painter.drawText(rect, Qt.AlignCenter|Qt.TextWordWrap, '%s\n\n%s' % (title, authors))
                if cdata is False:
                    self.render_queue.put(book_id)
                if self.title_height != 0:
                    self.paint_title(painter, trect, db, book_id)
            else:
                if self.animating is not None and self.animating.row() == index.row():
                    cdata = cdata.scaled(cdata.size() * self._animated_size)
                dpr = cdata.devicePixelRatio()
                cw, ch = int(cdata.width() / dpr), int(cdata.height() / dpr)
                dx = max(0, int((rect.width() - cw)/2.0))
                dy = max(0, int((rect.height() - ch)/2.0))
                right_adjust = dx
                rect.adjust(dx, dy, -dx, -dy)
                painter.drawPixmap(rect, cdata)
                if self.title_height != 0:
                    self.paint_title(painter, trect, db, book_id)
            if self.emblem_size > 0:
                return  # We dont draw embossed emblems as the ondevice/marked emblems are drawn in the gutter
            if marked:
                try:
                    p = self.marked_emblem
                except AttributeError:
                    p = self.marked_emblem = m.marked_icon.pixmap(48, 48)
                self.paint_embossed_emblem(p, painter, orect, right_adjust)

            if on_device:
                try:
                    p = self.on_device_emblem
                except AttributeError:
                    p = self.on_device_emblem = QIcon(I('ok.png')).pixmap(48, 48)
                self.paint_embossed_emblem(p, painter, orect, right_adjust, left=False)
        finally:
            painter.restore()
Beispiel #48
0
 def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True):
     drect = QRect(orect)
     pw = int(pixmap.width() / pixmap.devicePixelRatio())
     ph = int(pixmap.height() / pixmap.devicePixelRatio())
     if left:
         drect.setLeft(drect.left() + right_adjust)
         drect.setRight(drect.left() + pw)
     else:
         drect.setRight(drect.right() - right_adjust)
         drect.setLeft(drect.right() - pw + 1)
     drect.setBottom(drect.bottom() - self.title_height)
     drect.setTop(drect.bottom() - ph)
     painter.drawPixmap(drect, pixmap)
    def paint(self, painter, option, index):  # noqa C901
        '''
        @param painter QPainter
        @param option index QStyleOptionViewItem
        @param option index QModelIndex
        '''
        from ..LocationBar import LocationBar
        opt = QStyleOptionViewItem(option)
        self.initStyleOption(opt, index)

        w = opt.widget
        if w:
            style = w.style()
        else:
            style = QApplication.style()

        height = opt.rect.height()
        center = height / 2 + opt.rect.top()

        # Prepare link font
        # QFont
        linkFont = opt.font
        linkFont.setPointSize(linkFont.pointSize() - 1)

        linkMetrics = QFontMetrics(linkFont)

        leftPosition = self._padding * 2
        rightPosition = opt.rect.right() - self._padding

        opt.state |= QStyle.State_Active

        if opt.state & QStyle.State_Selected:
            iconMode = QIcon.Selected
            colorRole = QPalette.HighlightedText
            colorLinkRole = QPalette.HighlightedText
        else:
            iconMode = QIcon.Normal
            colorRole = QPalette.Text
            colorLinkRole = QPalette.Link

        if const.OS_WIN:
            opt.palette.setColor(QPalette.All, QPalette.HighlightedText,
                opt.palette.color(QPalette.Active, QPalette.Text))
            opt.palette.setColor(QPalette.All, QPalette.Highlight,
                opt.palette.base().color().darker(108))

        textPalette = QPalette(opt.palette)
        if opt.state & QStyle.State_Enabled:
            textPalette.setCurrentColorGroup(QPalette.Normal)
        else:
            textPalette.setCurrentColorGroup(QPalette.Disabled)

        # Draw background
        style.drawPrimitive(QStyle.PE_PanelItemViewItem, opt, painter, w)

        isVisitSearchItem = index.data(LocationCompleterModel.VisitSearchItemRole)
        isSearchSuggestion = index.data(LocationCompleterModel.SearchSuggestionRole)

        loadAction = LocationBar.LoadAction()
        isWebSearch = isSearchSuggestion

        # BookmarkItem
        bookmark = index.data(LocationCompleterModel.BookmarkItemRole)

        if isVisitSearchItem:
            text = index.data(LocationCompleterModel.SearchStringRole)
            loadAction = LocationBar.loadAction(text)
            isWebSearch = loadAction.type == LocationBar.LoadAction.Search
            if not self._forceVisitItem:
                bookmark = loadAction.bookmark

        # Draw icon
        iconSize = 16
        iconYPos = center - iconSize / 2
        iconRect = QRect(leftPosition, iconYPos, iconSize, iconSize)
        icon = index.data(Qt.DecorationRole)
        if not icon:
            icon = QIcon()
        pixmap = icon.pixmap(iconSize)
        if isSearchSuggestion or (isVisitSearchItem and isWebSearch):
            pixmap = QIcon.fromTheme('edit-find', QIcon(':/icons/menu/search-icon.svg')).pixmap(iconSize, iconMode)
        if isVisitSearchItem and bookmark:
            pixmap = bookmark.icon().pixmap(iconSize)
        elif loadAction.type == LocationBar.LoadAction.Search:
            if loadAction.searchEngine.name != LocationBar.searchEngine().name:
                pixmap = loadAction.searchEngine.icon.pixmap(iconSize)

        painter.drawPixmap(iconRect, pixmap)
        leftPosition = iconRect.right() + self._padding * 2

        # Draw star to bookmark items
        starPixmapWidth = 0
        if bookmark:
            icon = IconProvider.instance().bookmarkIcon
            starSize = QSize(16, 16)
            starPixmapWidth = starSize.width()
            pos = QPoint(rightPosition - starPixmapWidth, center - starSize.height() / 2)
            starRect = QRect(pos, starSize)
            painter.drawPixmap(starRect, icon.pixmap(starSize, iconMode))

        searchText = index.data(LocationCompleterModel.SearchStringRole)

        # Draw title
        leftPosition += 2
        titleRect = QRect(leftPosition, center - opt.fontMetrics.height() / 2,
                opt.rect.width() * 0.6, opt.fontMetrics.height())
        title = index.data(LocationCompleterModel.TitleRole)
        painter.setFont(opt.font)

        if isVisitSearchItem:
            if bookmark:
                title = bookmark.title()
            else:
                title = index.data(LocationCompleterModel.SearchStringRole)
                searchText = ''

        leftPosition += self.viewItemDrawText(painter, opt, titleRect, title,
                textPalette.color(colorRole), searchText)
        leftPosition += self._padding * 2

        # Trim link to maximum number characters that can be visible,
        # otherwise there may be perf issue with huge URLs
        maxChars = int((opt.rect.width() - leftPosition) / opt.fontMetrics.width('i'))
        link = index.data(Qt.DisplayRole)
        if not link.startswith('data') and not link.startswith('javascript'):
            link = unquote(link)[:maxChars]
        else:
            link = link[:maxChars]

        if isVisitSearchItem or isSearchSuggestion:
            if not (opt.state & QStyle.State_Selected) and not (opt.state & QStyle.State_MouseOver):
                link = ''
            elif isVisitSearchItem and (not isWebSearch or self._forceVisitItem):
                link = _('Visit')
            else:
                searchEngineName = loadAction.searchEngine.name
                if not searchEngineName:
                    searchEngineName = LocationBar.searchEngine().name
                link = _('Search with %s') % searchEngineName

        if bookmark:
            link = bookmark.url().toString()

        # Draw separator
        if link:
            separator = '-'
            separatorRect = QRect(leftPosition, center - linkMetrics.height() / 2,
                    linkMetrics.width(separator), linkMetrics.height())
            style.drawItemText(painter, separatorRect, Qt.AlignCenter, textPalette,
                    True, separator, colorRole)
            leftPosition += separatorRect.width() + self._padding * 2

        # Draw link
        leftLinkEdge = leftPosition
        rightLinkEdge = rightPosition - self._padding - starPixmapWidth
        linkRect = QRect(leftLinkEdge, center - linkMetrics.height() / 2,
                rightLinkEdge - leftLinkEdge, linkMetrics.height())
        painter.setFont(linkFont)

        # Darw url (or switch to tab)
        tabPos = index.data(LocationCompleterModel.TabPositionTabRole)

        if gVar.appSettings.showSwitchTab and not self._forceVisitItem and tabPos != -1:
            tabIcon = QIcon(':/icons/menu/tab.svg')
            iconRect = QRect(linkRect)
            iconRect.setX(iconRect.x())
            iconRect.setWidth(16)
            painter.drawPixmap(iconRect, tabIcon.pixmap(iconRect.size(), iconMode))

            textRect = QRect(linkRect)
            textRect.setX(textRect.x() + self._padding + 16 + self._padding)
            self.viewItemDrawText(painter, opt, textRect, _('Switch to tab'),
                    textPalette.color(colorLinkRole))
        elif isVisitSearchItem or isSearchSuggestion:
            self.viewItemDrawText(painter, opt, linkRect, link, textPalette.color(colorLinkRole))
        else:
            self.viewItemDrawText(painter, opt, linkRect, link, textPalette.color(colorLinkRole),
                    searchText)