示例#1
0
 def paintVerticalCell(self, painter: QPainter, hv: QHeaderView,
                       cellIndex: QModelIndex, leafIndex: QModelIndex,
                       logicalLeafIndex: int,
                       styleOptions: QStyleOptionHeader,
                       sectionRect: QRect, left: int):
     uniopt = QStyleOptionHeader(styleOptions)
     self.setForegroundBrush(uniopt, cellIndex)
     self.setBackgroundBrush(uniopt, cellIndex)
     width = self.cellSize(cellIndex, hv, uniopt).width()
     if cellIndex == leafIndex:
         width = sectionRect.width() - left
     top = self.currentCellLeft(cellIndex, leafIndex, logicalLeafIndex,
                                sectionRect.top(), hv)
     height = self.currentCellWidth(cellIndex, leafIndex,
                                    logicalLeafIndex, hv)
     r = QRect(left, top, width, height)
     uniopt.text = cellIndex.data(Qt.DisplayRole)
     painter.save()
     uniopt.rect = r
     if cellIndex.data(Qt.UserRole):
         hv.style().drawControl(QStyle.CE_HeaderSection, uniopt,
                                painter, hv)
         m = QTransform()
         m.rotate(-90)
         painter.setWorldMatrix(m, True)
         new_r = QRect(0, 0, r.height(), r.width())
         new_r.moveCenter(QPoint(-r.center().y(), r.center().x()))
         uniopt.rect = new_r
         hv.style().drawControl(QStyle.CE_HeaderLabel, uniopt, painter,
                                hv)
     else:
         hv.style().drawControl(QStyle.CE_Header, uniopt, painter, hv)
     painter.restore()
     return left + width
示例#2
0
 def paint(self, painter, rect, callback=None):
     painter.fillRect(rect, self.paperColor or QColor(Qt.white))
     page = QRect(0, 0, self.width, self.height)
     painter.translate(page.center())
     painter.rotate(self.computedRotation * 90)
     if self.computedRotation & 1:
         page.setSize(page.size().transposed())
     painter.translate(-page.center())
     self._svg_r.render(painter, QRectF(page))
示例#3
0
文件: svg.py 项目: stweil/frescobaldi
 def paint(self, painter, rect, callback=None):
     painter.fillRect(rect, self.paperColor or QColor(Qt.white))
     page = QRect(0, 0, self.width, self.height)
     painter.translate(page.center())
     painter.rotate(self.computedRotation * 90)
     if self.computedRotation & 1:
         page.setSize(page.size().transposed())
     painter.translate(-page.center())
     self._svg_r.render(painter, QRectF(page))
示例#4
0
 def paint(self, painter: QPainter, rect: QRect):
     super().paint(painter, rect)
     # edge length of a box rotated 45 degrees and within box with edge of 1
     edge = min(rect.width(), rect.height()) * 0.7
     icon_area = QRect(0, 0, edge, edge)
     painter.save()
     painter.translate(rect.center())
     rotation = self._animator.currentValue() * 360 / self._frames
     painter.rotate(rotation)
     painter.translate(-icon_area.center())
     self.icon.paint(painter, icon_area)
     painter.restore()
示例#5
0
 def render(self, page):
     """Generate an image for this Page."""
     i = QImage(page.width, page.height, QImage.Format_ARGB32_Premultiplied)
     i.fill(self.paperColor)
     painter = QPainter(i)
     rect = QRect(0, 0, page.width, page.height)
     painter.translate(rect.center())
     painter.rotate(page.computedRotation * 90)
     if page.computedRotation & 1:
         rect.setSize(rect.size().transposed())
     painter.translate(-rect.center())
     page._svg_r.render(painter, QRectF(rect))
     return i
示例#6
0
文件: svg.py 项目: stweil/frescobaldi
 def render(self, page):
     """Generate an image for this Page."""
     i = QImage(page.width, page.height, self.imageFormat)
     i.fill(page.paperColor or self.paperColor or QColor(Qt.white))
     painter = QPainter(i)
     rect = QRect(0, 0, page.width, page.height)
     painter.translate(rect.center())
     painter.rotate(page.computedRotation * 90)
     if page.computedRotation & 1:
         rect.setSize(rect.size().transposed())
     painter.translate(-rect.center())
     page._svg_r.render(painter, QRectF(rect))
     return i
示例#7
0
 def render(self, page):
     """Generate an image for this Page."""
     i = QImage(page.width, page.height, self.imageFormat)
     i.fill(page.paperColor or self.paperColor or QColor(Qt.white))
     painter = QPainter(i)
     rect = QRect(0, 0, page.width, page.height)
     painter.translate(rect.center())
     painter.rotate(page.computedRotation * 90)
     if page.computedRotation & 1:
         rect.setSize(rect.size().transposed())
     painter.translate(-rect.center())
     page._svg_r.render(painter, QRectF(rect))
     return i
示例#8
0
 def paint_date(self, date, painter, rect, num, is_past):
     font_not_large = self.settings.app_font != FONT_LARGE
     ellipse_rect = QRect(rect.x() + 3,
                          rect.y() + 3,
                          self.get_badge_width(num, self.settings.app_font),
                          20 if font_not_large else 25)
     text_rect = QRect(ellipse_rect.x() - 3.1,
                       ellipse_rect.y() + (7 if font_not_large else 10), 20,
                       20)
     if self.monthShown() == date.month():
         if is_past:
             painter.setBrush(QColor(0, 0, 0))
         else:
             painter.setBrush(QColor(BADGE_COLOR))
     else:
         painter.setBrush(QColor(196, 196, 196))
     painter.setPen(Qt.NoPen)
     painter.drawRect(ellipse_rect)
     if self.monthShown() == date.month():
         painter.setBrush(QColor(BADGE_LETTER_COLOR))
     else:
         painter.setBrush(QColor(255, 255, 255))
     painter.setPen(QPen(QColor(255, 255, 255)))
     num_repr = repr(num)
     if len(num_repr) > 1 and int(num_repr[-2]) == 1:
         text = self.tr('events')
     elif 1 < int(num_repr[-1]) < 5:
         text = self.tr('events*')
     else:
         text = self.tr(
             'event{}'.format('s' if int(num_repr[-1]) > 1 or num %
                              2 == 0 else ''))
     painter.drawText(text_rect.center(), '{} {}'.format(num, text))
示例#9
0
    def paintEvent(self, event):

        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setStyleSheet("background:transparent;")

        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        drawingRect = QRect(
            QtCore.QPoint(),
            self.rect().size() - 2 * self.width * QtCore.QSize(1, 1))
        drawingRect.moveCenter(self.rect().center())

        gradient = QtGui.QConicalGradient()
        gradient.setCenter(drawingRect.center())
        gradient.setAngle(90)
        gradient.setColorAt(1, QtGui.QColor(0, 0, 0))
        gradient.setColorAt(
            0, QtGui.QColor(self.color[0], self.color[1], self.color[2]))

        arcLengthApproximation = self.width + self.width / 3
        pen = QtGui.QPen(QtGui.QBrush(gradient), self.width)
        pen.setCapStyle(QtCore.Qt.RoundCap)
        painter.setPen(pen)
        painter.drawArc(drawingRect, 90 * 16 - arcLengthApproximation,
                        -self._loading_angle * 16)
示例#10
0
    def paint(self, painter: QPainter, rect: QRect):
        super().paint(painter, rect)
        painter.save()
        painter.translate(rect.center())

        size = rect.size() # self._size
        dot_space = min(size.width()/self._dots, size.height()) # self._max_dot_r
        max_dot_r = dot_space/2 * 0.75
        min_dot_r = max_dot_r * 0.6
        state = self._animator.currentValue() / self._frames
        len = self._dots*2-1

        painter.translate(-(size.width()/2-dot_space/2), 0)
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.black)
        painter.setRenderHint(QPainter.Antialiasing, True)
        for i in range(self._dots):
            dot_s = (state - i/len) % 1
            dot_s = dot_s * len - 0.5
            dot_s = dot_s if dot_s < 0 else min(dot_s / (len-1), 0.5)
            dot_r = min_dot_r + (max_dot_r - min_dot_r) * cos(dot_s*pi)
            painter.drawEllipse(QPoint(0, 0), dot_r, dot_r)
            painter.translate(dot_space, 0)

        painter.restore()
示例#11
0
    def mouseReleaseEvent(self, event):
        if event.button() == Qt.RightButton:
            self.rubberBand.hide()
            rb_rect = QRect(self._rb_origin, event.pos())
            rb_center = rb_rect.center()
            rb_size = rb_rect.size()

            if abs(rb_size.width()) > 3 and abs(rb_size.height()) > 3:
                viewport_size = self.viewport().geometry().size()

                zoom_factor_x = abs(viewport_size.width() / rb_size.width())
                zoom_factor_y = abs(viewport_size.height() / rb_size.height())

                new_center = self.mapToScene(rb_center)

                zoom_factor = min(zoom_factor_x, zoom_factor_y)
                self.zoom_view(zoom_factor)
                self.centerOn(new_center)

            self.update_grid()

        if event.button() == Qt.MidButton:
            self.setCursor(Qt.ArrowCursor)
            self._mousePressed = None
            self.update_grid()
示例#12
0
def decorate_welcome_icon(icon, background_color):
    """Return a `QIcon` with a circle shaped background.
    """
    welcome_icon = QIcon()
    sizes = [32, 48, 64, 80]
    background_color = NAMED_COLORS.get(background_color, background_color)
    background_color = QColor(background_color)
    grad = radial_gradient(background_color)
    for size in sizes:
        icon_pixmap = icon.pixmap(5 * size / 8, 5 * size / 8)
        icon_size = icon_pixmap.size()
        icon_rect = QRect(QPoint(0, 0), icon_size)

        pixmap = QPixmap(size, size)
        pixmap.fill(QColor(0, 0, 0, 0))
        p = QPainter(pixmap)
        p.setRenderHint(QPainter.Antialiasing, True)
        p.setBrush(QBrush(grad))
        p.setPen(Qt.NoPen)
        ellipse_rect = QRect(0, 0, size, size)
        p.drawEllipse(ellipse_rect)
        icon_rect.moveCenter(ellipse_rect.center())
        p.drawPixmap(icon_rect.topLeft(), icon_pixmap)
        p.end()

        welcome_icon.addPixmap(pixmap)

    return welcome_icon
示例#13
0
    def paintTab(self, painter: QPainter, index: int):
        if not self.isValidIndex(index):
            return
        painter.save()

        tab = self._tabs[index]
        rect = self._tabRect(index)
        selected = index == self._currentIndex
        enabled = self._enabled and tab.enabled

        if selected:
            painter.fillRect(rect, FancyToolButtonSelectedColor)

        tabText = tab.text
        tabTextRect = QRect(rect)
        drawIcon = rect.height() > 36
        tabIconRect = QRect(rect)

        tabTextRect.translate(0, -2 if drawIcon else 1)
        boldFont = QFont(painter.font())
        boldFont.setPointSizeF(SIDEBAR_FONT_SIZE)
        boldFont.setBold(True)
        painter.setFont(boldFont)
        #painter.setPen(QColor(255, 255, 255, 160) if selected else QColor(0, 0, 0, 110))
        textFlags = Qt.AlignCenter | (Qt.AlignBottom if drawIcon else
                                      Qt.AlignVCenter) | Qt.TextWordWrap

        fader = tab.fader
        if fader > 0 and not selected and enabled:
            painter.save()
            painter.setOpacity(fader)
            painter.fillRect(rect, FancyToolButtonHoverColor)
            painter.restore()

        if not enabled:
            painter.setOpacity(0.7)

        if drawIcon:
            textHeight = (painter.fontMetrics().boundingRect(
                QRect(0, 0, self.width(), self.height()), Qt.TextWordWrap,
                tabText).height())
            tabIconRect.adjust(0, 4, 0, -textHeight - 4)
            iconMode = (QIcon.Active if selected else
                        QIcon.Normal) if enabled else QIcon.Disabled
            iconRect = QRect(0, 0, MODEBAR_ICON_SIZE, MODEBAR_ICON_SIZE)
            iconRect.moveCenter(tabIconRect.center())
            iconRect = iconRect.intersected(tabIconRect)
            drawIconWithShadow(tab.icon, iconRect, painter, iconMode)

        if enabled:
            penColor = FancyTabWidgetEnabledSelectedTextColor if selected else FancyTabWidgetEnabledUnselectedTextColor
        else:
            penColor = FancyTabWidgetDisabledSelectedTextColor if selected else FancyTabWidgetDisabledUnselectedTextColor
        painter.setPen(penColor)
        painter.translate(0, -1)
        painter.drawText(tabTextRect, textFlags, tabText)

        painter.restore()
示例#14
0
 def draw_center(self, qp, event, w):
     w *= 0.2
     rect = QRect()
     rect.setSize(QSize(w, w))
     rect.moveCenter(event.rect().center())
     rad = rect.width() / 2
     cap = QRadialGradient(rect.center(), rad)
     cap.setColorAt(0, Qt.white)
     cap.setColorAt(1, Qt.gray)
     qp.setPen(QPen(Qt.black, 1))
     qp.setBrush(QBrush(cap))
     qp.drawEllipse(rect)
示例#15
0
    def paintEvent(self, event):
        painter = QPainter(self)

        painter.setBrush(Qt.darkGreen)
        painter.drawRect(self.rect())

        img_rect = self.img.rect()
        dev_rect = QRect(0, 0,
                         painter.device().width(),
                         painter.device().height())
        img_rect.moveCenter(dev_rect.center())

        painter.drawPixmap(img_rect.topLeft(), self.img)
示例#16
0
    def drawBackground(self, painter, rect):
        QGraphicsView.drawBackground(self, painter, rect)

        if not self.__backgroundIcon.isNull():
            painter.setClipRect(rect)
            vrect = QRect(QPoint(0, 0), self.viewport().size())
            vrect = self.mapToScene(vrect).boundingRect()

            pm = self.__backgroundIcon.pixmap(
                vrect.size().toSize().boundedTo(QSize(200, 200))
            )
            pmrect = QRect(QPoint(0, 0), pm.size())
            pmrect.moveCenter(vrect.center().toPoint())
            if rect.toRect().intersects(pmrect):
                painter.drawPixmap(pmrect, pm)
示例#17
0
 def draw_gauge(self, qp, event, w):
     w *= 0.6
     rect = QRect()
     rect.setSize(QSize(w, w))
     rect.moveCenter(event.rect().center())
     center = rect.center()
     qp.setPen(QPen(Qt.white, self.tick_width, cap=Qt.FlatCap))
     qp.drawArc(rect, (-45 * 16), (270 * 16))
     rad = rect.width() / 2
     inc = 270.0 / (self._num_ticks - 1)
     for i in range(self._num_ticks):
         p1 = self.qpa[i] * rad
         p1 += center
         p2 = self.qpa[i] * (rad + 10)
         p2 += center
         line = QLine(p1.toPoint(), p2.toPoint())
         qp.drawLine(line)
    def mouseMoveEvent(self, ev: QtGui.QMouseEvent) -> None:
        ev.accept()
        if self._current_item_index == -1:
            return

        current_seed_item = self._circle_seed_items[
            self._current_item_index]  # type: CircleSeedItem
        if current_seed_item.change_able:
            if self._resize_handel_pressed:
                rect = QRect(current_seed_item.rect().topLeft(),
                             QPoint(ev.pos() + self._mouse_press_offset))
                current_seed_item.radius = min(rect.width(), rect.height(), 8)
            else:
                rect = current_seed_item.rect()
                rect.moveTopLeft(ev.pos() - self._mouse_press_offset)
                rect = rect.adjusted(0, 0, 1, 1)
                current_seed_item.center_pos = rect.center()
        self.update()
示例#19
0
    def paintEvent(self, event):

        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        drawingRect = QRect(
            QtCore.QPoint(),
            self.rect().size() - 2 * self.width * QtCore.QSize(1, 1))

        if drawingRect.width() == 520:
            painter.rotate(90)
            painter.translate(0, -drawingRect.height())
        elif drawingRect.width() == 470:
            painter.rotate(60)
            painter.translate(drawingRect.width() * (6 / 9),
                              -drawingRect.height() * (6 / 9))
        elif drawingRect.width() == 420:
            painter.rotate(40)
            painter.translate(drawingRect.width() * (4 / 9),
                              -drawingRect.height() * (4 / 9))
        elif drawingRect.width() == 370:
            painter.rotate(20)
            painter.translate(drawingRect.width() * (2 / 9),
                              -drawingRect.height() * (2 / 9))
        elif drawingRect.width() == 320:
            pass
        drawingRect.moveCenter(self.rect().center())

        gradient = QtGui.QConicalGradient()
        gradient.setCenter(drawingRect.center())
        gradient.setAngle(90)
        gradient.setColorAt(1, QtGui.QColor(0, 0, 0))
        gradient.setColorAt(
            0, QtGui.QColor(self.color[0], self.color[1], self.color[2]))

        arcLengthApproximation = self.width + self.width / 3
        pen = QtGui.QPen(QtGui.QBrush(gradient), self.width)
        pen.setCapStyle(QtCore.Qt.RoundCap)
        painter.setPen(pen)
        if self.side == "L":
            painter.drawLine(0, 0, self.NextStep, self.NextStep)
        else:
            painter.drawLine(drawingRect.width(), 0,
                             drawingRect.width() - self.NextStep,
                             self.NextStep)
示例#20
0
    def paintEvent(self, ev=None):
        drawing_rect = QRect()
        drawing_rect.setX(self._padding)
        drawing_rect.setY(self._padding)
        drawing_rect.setWidth(self._size)
        drawing_rect.setHeight(self._size)

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        gradient = QConicalGradient()
        gradient.setCenter(drawing_rect.center())
        gradient.setAngle(-self._angle - self._size / 10)
        gradient.setColorAt(0, QColor(178, 255, 246))
        gradient.setColorAt(1, QColor(5, 44, 50))

        pen = QPen(QBrush(gradient), self._size // 10)
        pen.setCapStyle(Qt.RoundCap)
        painter.setPen(pen)
        painter.drawArc(drawing_rect, -self._angle * 16, 300 * 16)
示例#21
0
文件: thumbview.py 项目: dushko/G-
    def drawThumnail(self, cellNum, pic, thumb : PhotoNode, cell : Rectangle, painter : QPainter):
        rect = QRect(cell.x, cell.y, cell.width, cell.height)
        bLeft = rect.bottomLeft()

        # draw name
        fontHeight = 20
        font = painter.font()
        font.setPixelSize(fontHeight)
        textTopRight = QPoint(bLeft.x(), bLeft.y() - fontHeight)
        textRect = QRect(textTopRight, rect.bottomRight())
        thumbName = thumb.name
        painter.drawText(textRect, Qt.AlignHCenter, thumbName)
        #painter.drawRect(rect)

        # draw thumb
        imageRect = QRect(rect.topLeft(), textRect.topRight())
        imageCenter = imageRect.center()
        imageX = int(imageCenter.x() - pic.width() / 2)
        imageY = int(imageCenter.y() - pic.height() / 2)
        imageOrigin = QPoint(imageX, imageY)
        painter.drawPixmap(imageOrigin, pic)
示例#22
0
    def _paint_tab(self, painter, index):
        if not self._is_valid_index(index):
            return

        painter.save()
        tab = self.__tabs[index]
        rect = self._tab_rect(index)
        selected = index == self.__current_index
        enabled = self._is_enabled(index)

        if selected:
            painter.fillRect(rect, QColor("#161719"))

        tab_icon_rect = QRect(rect)
        if selected:
            color = QColor(255, 255, 255, 160)
        else:
            color = QColor(0, 0, 0, 110)
        painter.setPen(color)

        fader = self.__tabs[index].fader
        if fader > 0 and not selected and enabled:
            painter.save()
            painter.setOpacity(fader)
            painter.fillRect(rect, QColor("#424242"))
            painter.restore()

        if tab.icon is not None:
            icon_rect = QRect(0, 0, 20, 20)
            icon_rect.moveCenter(tab_icon_rect.center())
            tab.icon.paint(painter, rect)

        painter.setOpacity(1.0)
        if enabled:
            painter.setPen(QColor("#ffffff"))
        else:
            painter.setPen(QColor("blue"))
        painter.translate(0, -1)

        painter.restore()
示例#23
0
    def _paint_tab(self, painter, index):
        if not self._is_valid_index(index):
            return

        painter.save()
        tab = self.__tabs[index]
        rect = self._tab_rect(index)
        selected = index == self.__current_index
        enabled = self._is_enabled(index)

        if selected:
            painter.fillRect(rect, QColor("#161719"))

        tab_icon_rect = QRect(rect)
        if selected:
            color = QColor(255, 255, 255, 160)
        else:
            color = QColor(0, 0, 0, 110)
        painter.setPen(color)

        fader = self.__tabs[index].fader
        if fader > 0 and not selected and enabled:
            painter.save()
            painter.setOpacity(fader)
            painter.fillRect(rect, QColor("#424242"))
            painter.restore()

        if tab.icon is not None:
            icon_rect = QRect(0, 0, 20, 20)
            icon_rect.moveCenter(tab_icon_rect.center())
            tab.icon.paint(painter, rect)

        painter.setOpacity(1.0)
        if enabled:
            painter.setPen(QColor("#ffffff"))
        else:
            painter.setPen(QColor("blue"))
        painter.translate(0, -1)

        painter.restore()
示例#24
0
    def drawThumnail(self, cellNum, pic, thumb: PhotoNode, cell: Rectangle,
                     painter: QPainter):
        rect = QRect(cell.x, cell.y, cell.width, cell.height)
        bLeft = rect.bottomLeft()

        # draw name
        fontHeight = 20
        font = painter.font()
        font.setPixelSize(fontHeight)
        textTopRight = QPoint(bLeft.x(), bLeft.y() - fontHeight)
        textRect = QRect(textTopRight, rect.bottomRight())
        thumbName = thumb.name
        painter.drawText(textRect, Qt.AlignHCenter, thumbName)
        #painter.drawRect(rect)

        # draw thumb
        imageRect = QRect(rect.topLeft(), textRect.topRight())
        imageCenter = imageRect.center()
        imageX = int(imageCenter.x() - pic.width() / 2)
        imageY = int(imageCenter.y() - pic.height() / 2)
        imageOrigin = QPoint(imageX, imageY)
        painter.drawPixmap(imageOrigin, pic)
示例#25
0
    def draw(self, painter: Painting.Painter, is_global: bool = False) -> None:
        """
        The center of the mower is the x and y coordinates
        The mower is rotated around the center

        :param painter:
        :param is_global: Defines if the global or the local position is taken for rendering
        """
        if is_global:
            rect = QRect(self.global_pos[0].pixel(), self.global_pos[1].pixel(), self.WIDTH.pixel(), self.LENGTH.pixel())
        else:
            rect = QRect(self.local_pos[0].pixel(), self.local_pos[1].pixel(), self.WIDTH.pixel(), self.LENGTH.pixel())

        r_x = self.global_pos[0] - self.WIDTH
        r_y = self.global_pos[1] - self.LENGTH / 2

        world_rx = r_x * math.cos(self.look_direction_rad) - math.sin(self.look_direction_rad) * r_y
        world_ry = r_x * math.sin(self.look_direction_rad) + math.cos(self.look_direction_rad) * r_y

        #logger.debug(f"{world_rx }, {world_ry}")

        transform = QtGui.QTransform()
        center_point = rect.center()

        # Sets the center as 0;0 coordinate
        transform.translate((-self.WIDTH / 2).pixel(), (-self.LENGTH).pixel())

        # Rotate around the center
        transform.translate(center_point.x(), center_point.y())
        transform.rotate(self.look_direction_deg)
        transform.translate(-center_point.x(), -center_point.y())

        painter.setTransform(transform, combine=True)

        painter.fillRect(rect, QtGui.QBrush(self.MOWER_COLOR, QtCore.Qt.SolidPattern))
        painter.drawImage(rect, self.img_mower)

        painter.resetTransform()
示例#26
0
    def __init__(self, parent):
        super().__init__(parent=parent)
        self.setWindowTitle('License')
        self.ed_info = QTextEdit()
        self.ed_GPL = QPlainTextEdit()
        self.bt_close = QPushButton('Close')

        vlay = QVBoxLayout()
        vlay.addWidget(self.ed_info)
        vlay.addWidget(self.ed_GPL)
        vlay.addWidget(self.bt_close)
        self.bt_close.clicked.connect(self.close)
        self.setLayout(vlay)

        font = QFont("Courier", 10)
        font.setStyleHint(QFont.Monospace)
        self.ed_GPL.setFont(font)

        self.ed_info.setText(info_txt)
        self.ed_GPL.setPlainText(gpl)
        my_geometry = QRect(0, 0, 640, 400)
        self.setGeometry(my_geometry)
        self.move(parent.parent_for_lic.geometry().center() -
                  my_geometry.center())
class ViewFisheye(QWidget):

    # sample selection
    SelectionType = Enum('SelectType', 'Exact Closest Rect')
    SelectionMode = Enum('SelectMode', 'Select Add Remove')
    SelectionRectMin = 10   # pixels, width and height, scales as photo scales
    SampleRadius = 10       # pixels, scales as photo scales
    SelectedPixelBox = 64   # pixels, width and height

    def __init__(self, parent):
        super().__init__()

        # members
        self.parent = parent
        self.myPhoto = QImage()
        self.myPhotoPixels = np.zeros(shape=(1, 1, 4))
        self.myPhotoPath = ""
        self.myPhotoTime = datetime(1,1,1)
        self.myPhotoSrcRect = QRect()
        self.myPhotoDestRect = QRect()
        self.myPhotoRadius = 0
        self.myPhotoRotation = 0
        self.rawAvailable = False
        self.coordsMouse = (0, 0)
        self.viewCenter = (0, 0)
        self.dragSelectRect = QRect(0, 0, 0, 0)
        self.sunPosition = (0, 0)        # (azimuth (theta), altitude (phi)(90-zenith))
        self.sunPositionVisible = (0,0)  # point (x,y) of sun location rendered on screen (scaled)
        self.sunPathPoints = []          # [(azimuth (theta), altitude (phi)(90-zenith), datetime)]
        self.compassTicks = []           # [[x1, y1, x2, y2, x1lbl, y1lbl, angle]]
        self.lensIdealRadii = []         # list of radii for ideal lens latitudes to draw
        self.lensRealRadii = []          # list of radii for real/warped lens latitudes to draw
        self.samplePoints = []           # (x,y) coords of all samples on the photo rendered on screen (scaled)
        self.sampleAreaVisible = []      # area of 4 points for each sample rendered on screen (scaled)
        self.samplePointsInFile = []     # points (x,y) of all samples in the photo on file
        self.samplesSelected = []        # indices of selected samples
        self.skyCover = common.SkyCover.UNK

        # members - preloaded graphics
        self.painter = QPainter()
        self.mask = QImage()
        self.pathSun = QPainterPath()
        self.penText = QPen(Qt.white, 1, Qt.SolidLine)
        self.penLens = QPen(Qt.magenta, 1, Qt.SolidLine)
        self.penSun = QPen(QColor(255, 165, 0), 2, Qt.SolidLine)
        self.penSelected = []  # list of pens, one for each sampling pattern location
        self.penSelectRect = QPen(Qt.white, 1, Qt.DashLine)
        self.penShadowText = QPen(Qt.black, 1, Qt.SolidLine)
        self.penShadowSun = QPen(Qt.black, 2, Qt.SolidLine)
        self.penShadowSelected = QPen(Qt.black, 3, Qt.SolidLine)
        self.brushGrid = QBrush(Qt.white, Qt.SolidPattern)
        self.fontFixed = QFont('Courier New', 8)
        self.fontScaled = QFont('Courier New', 8)
        self.fontMetrics = QFontMetrics(self.fontScaled)
        self.iconWarning = self.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(ViewFisheye.SelectedPixelBox / 2)

    def dataLoaded(self):
        # Note - this function only runs once the data directory has been loaded
        self.setMouseTracking(True)
        color = QColor(255, 255, 255)
        self.samplesSelected.clear()
        self.samplePoints.clear()
        self.sampleAreaVisible.clear()
        self.samplePointsInFile.clear()
        self.penSelected.clear()
        for t, p in common.SamplingPattern:
            self.samplePoints.append((0, 0))  # these will need to be recomputed as photo scales
            self.samplePointsInFile.append((0, 0))  # these only need to be computed once per photo
            self.sampleAreaVisible.append([])
            color.setHsv(t, int(utility.normalize(p, 0, 90) * 127 + 128), 255)
            self.penSelected.append(QPen(color, 3, Qt.SolidLine))

    def setPhoto(self, path, exif=None):
        # if photo is valid
        if path is not None and os.path.exists(path):
            self.myPhotoPath = path
            self.myPhoto = QImage(path)
            self.myPhotoSrcRect = QRect(0, 0, self.myPhoto.width(), self.myPhoto.height())
            self.myPhotoDestRect = QRect(0, 0, self.width(), self.height())
            self.rawAvailable = utility_data.isHDRRawAvailable(path)
            if exif is not None:
                self.myPhotoTime = datetime.strptime(str(exif["EXIF DateTimeOriginal"]), '%Y:%m:%d %H:%M:%S')
            else:
                self.myPhotoTime = utility_data.imageEXIFDateTime(path)

            # cache each sample's coordinate in the photo
            # note: technically doesn't need to be recalculated if all photos have same resolution!
            self.samplePointsInFile = utility_data.computePointsInImage(path, common.SamplingPattern)

            # keep a copy the image's pixels in memory (used later for exporting, etc.)
            ptr = self.myPhoto.bits()
            ptr.setsize(self.myPhoto.byteCount())
            pixbgr = np.asarray(ptr).reshape(self.myPhoto.height(), self.myPhoto.width(), 4)
            # HACKAROONIE: byte order is not the same as image format, so swapped it around :/
            # TODO: should handle this better
            self.myPhotoPixels = np.copy(pixbgr)
            red = np.copy(self.myPhotoPixels[:, :, 0])
            self.myPhotoPixels[:, :, 0] = self.myPhotoPixels[:, :, 2]
            self.myPhotoPixels[:, :, 2] = red
            # rgba = self.myPhoto.pixelColor(center[0], center[1])
            # print((rgba.red(), rgba.green(), rgba.blue()))
            # rgba = pixrgb[center[1], center[0]]
            # print(rgba)

        # photo is null or missing
        else:
            self.myPhoto = QImage()
            self.myPhotoPixels = np.zeros(shape=(1,1,4))
            self.myPhotoPath = ""
            self.myPhotoTime = datetime(1, 1, 1)
            self.myPhotoSrcRect = QRect()
            self.myPhotoDestRect = QRect()
            self.rawAvailable = False

        # precompute as much as we can before any drawing
        self.computeBounds()

    def setSunPath(self, sunpath):
        self.sunPathPoints = sunpath

    def setSunPosition(self, pos):
        self.sunPosition = pos

    def setSkycover(self, sc):
        self.skyCover = sc

    def getSamplePatternRGB(self, index):
        if index < 0 or index >= len(common.SamplingPattern):
            return (0,0,0)
        color = self.penSelected[index].color()
        return (color.red(), color.green(), color.blue())

    def resetRotation(self, angles=0):
        self.myPhotoRotation = angles

    def selectSamples(self, message="none"):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return

        # handle selection message
        if message == "none":
            self.samplesSelected.clear()
        elif message == "all":
            self.samplesSelected[:] = [i for i in range(0, len(common.SamplingPattern))]
        elif message == "inverse":
            allidx = set([i for i in range(0, len(common.SamplingPattern))])
            selidx = set(self.samplesSelected)
            self.samplesSelected[:] = list(allidx - selidx)

        # remove samples in circumsolar avoidance region if necessary
        sunAvoid = common.AppSettings["AvoidSunAngle"]
        if sunAvoid > 0:
            sunAvoidRads = math.radians(common.AppSettings["AvoidSunAngle"])
            sunPosRads = (math.radians(self.sunPosition[0]), math.radians(self.sunPosition[1]))
            self.samplesSelected[:] = [idx for idx in self.samplesSelected if utility_angles.CentralAngle(sunPosRads, common.SamplingPatternRads[idx], inRadians=True) > sunAvoidRads]

        # update
        self.repaint()
        self.parent.graphSamples(self.samplesSelected)

    def mouseMoveEvent(self, event):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return

        # detect primary mouse button drag for sample selection
        if event.buttons() == Qt.LeftButton:
            # update drag selection bounds
            self.dragSelectRect.setWidth(event.x() - self.dragSelectRect.x())
            self.dragSelectRect.setHeight(event.y() - self.dragSelectRect.y())

        # detect middle mouse button drag for image rotation
        elif (event.buttons() == Qt.MidButton):
            old = (self.coordsMouse[0] - self.viewCenter[0], self.coordsMouse[1] - self.viewCenter[1])
            new = (event.x() - self.viewCenter[0], event.y() - self.viewCenter[1])
            # clockwise drag decreases rotation
            if old[1]*new[0] < old[0]*new[1]:
                self.myPhotoRotation -= 1
            # counter-clockwise drag increases rotation
            else:
                self.myPhotoRotation += 1
            # rotation
            if self.myPhotoRotation >= 0:
                self.myPhotoRotation %= 360
            else:
                self.myPhotoRotation %= -360

        # lastly, cache mouse coordinates and update
        self.coordsMouse = (event.x(), event.y())
        self.repaint()

    def mousePressEvent(self, event):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return
        # we only care about a left click for point and drag selection
        # right click is for context menu - handled elsewhere
        # middle click is for rotation - handled elsewhere
        if event.buttons() != Qt.LeftButton:
            return

        # start logging drag selection (whether user drags or not)
        self.dragSelectRect.setX(event.x())
        self.dragSelectRect.setY(event.y())
        self.dragSelectRect.setWidth(0)
        self.dragSelectRect.setHeight(0)

    def mouseReleaseEvent(self, event):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return

        # detect primary mouse button release for stopping sample selection
        if event.button() == Qt.LeftButton:
            # read modifier keys for user desired selection mode
            mode = ViewFisheye.SelectionMode.Select
            if event.modifiers() == Qt.ControlModifier:
                mode = ViewFisheye.SelectionMode.Add
            elif event.modifiers() == Qt.ShiftModifier:
                mode = ViewFisheye.SelectionMode.Remove

            # unflip coordinates of rect so that width and height are always positive
            r = self.dragSelectRect
            r = utility.rectForwardFacing([r.x(), r.y(), r.right(), r.bottom()])
            self.dragSelectRect.setCoords(r[0], r[1], r[2], r[3])

            # select samples
            prevSelected = list(self.samplesSelected)
            if self.dragSelectRect.width() < ViewFisheye.SelectionRectMin and self.dragSelectRect.height() < ViewFisheye.SelectionRectMin:
               self.computeSelectedSamples(ViewFisheye.SelectionType.Closest, mode)
            else:
                self.computeSelectedSamples(ViewFisheye.SelectionType.Rect, mode)

            # reset drag selection
            self.dragSelectRect.setX(event.x())
            self.dragSelectRect.setY(event.y())
            self.dragSelectRect.setWidth(0)
            self.dragSelectRect.setHeight(0)

            # update
            self.repaint()
            if self.samplesSelected != prevSelected:
                self.parent.graphSamples(self.samplesSelected)

    def wheelEvent(self, event):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return

        self.parent.timeChangeWheelEvent(event)

    def leaveEvent(self, event):
        self.coordsMouse = (-1, -1)
        self.repaint()

    def resizeEvent(self, event):
        self.computeBounds()

    def contextMenuEvent(self, event):
        # nothing to do if no photo loaded
        if self.myPhoto.isNull():
            return

        self.parent.triggerContextMenu(self, event)

    def computeSelectedSamples(self, type, mode):
        px = 0
        py = 0
        x1 = 0
        y1 = 0
        x2 = 0
        y2 = 0

        # in select mode, clear current selection
        if mode == ViewFisheye.SelectionMode.Select:
            self.samplesSelected = []

        # these are the samples we will be adding or removing
        sampleAdjustments = []

        # which single sample did user select by point
        if type == ViewFisheye.SelectionType.Exact:
            px = self.coordsMouse[0]
            py = self.coordsMouse[1]
            for i in range(0, len(self.samplePoints)):
                x, y = self.samplePoints[i]
                x1 = x - ViewFisheye.SampleRadius
                y1 = y - ViewFisheye.SampleRadius
                x2 = x + ViewFisheye.SampleRadius
                y2 = y + ViewFisheye.SampleRadius
                if px >= x1 and px <= x2 and py >= y1 and py <= y2:
                    sampleAdjustments.append(i)
                    break
        # which single sample is the closest to the mouse coordinate
        elif type == ViewFisheye.SelectionType.Closest:
            px = self.coordsMouse[0]
            py = self.coordsMouse[1]
            dist = math.sqrt((py-self.viewCenter[1])*(py-self.viewCenter[1]) + (px-self.viewCenter[0])*(px-self.viewCenter[0]))
            if dist <= self.myPhotoRadius:
                close = math.inf
                closest = -1
                for i in range(0, len(self.samplePoints)):
                    x, y = self.samplePoints[i]
                    dist = math.sqrt((y-py)*(y-py) + (x-px)*(x-px))
                    if dist < close:
                        close = dist
                        closest = i
                if closest >= 0:
                    sampleAdjustments.append(closest)
        # which samples are in the drag selection rect
        elif type == ViewFisheye.SelectionType.Rect:
            x1 = self.dragSelectRect.x()
            y1 = self.dragSelectRect.y()
            x2 = self.dragSelectRect.x() + self.dragSelectRect.width()
            y2 = self.dragSelectRect.y() + self.dragSelectRect.height()
            for i in range(0, len(self.samplePoints)):
                x, y = self.samplePoints[i]
                if x >= x1 and x <= x2 and y >= y1 and y <= y2:
                    sampleAdjustments.append(i)

        # remove samples in circumsolar avoidance region
        sunAvoid = common.AppSettings["AvoidSunAngle"]
        if sunAvoid > 0:
            sunAvoidRads = math.radians(common.AppSettings["AvoidSunAngle"])
            sunPosRads = (math.radians(self.sunPosition[0]), math.radians(self.sunPosition[1]))
            sampleAdjustments[:] = [idx for idx in sampleAdjustments if utility_angles.CentralAngle(sunPosRads, common.SamplingPatternRads[idx], inRadians=True) > sunAvoidRads]

        # no changes to be made
        if len(sampleAdjustments) <= 0:
            return

        # finally modify sample selection and return difference
        if mode == ViewFisheye.SelectionMode.Select or mode == ViewFisheye.SelectionMode.Add:
            for i in range(0, len(sampleAdjustments)):
                if sampleAdjustments[i] not in self.samplesSelected:  # don't readd existing indices
                    self.samplesSelected.append(sampleAdjustments[i])
        elif mode == ViewFisheye.SelectionMode.Remove:
            for i in range(0, len(sampleAdjustments)):
                try:
                    self.samplesSelected.remove(sampleAdjustments[i])
                except:
                    pass # ignore trying to remove indices that aren't currently selected

        # sort selection for easier searching later
        self.samplesSelected.sort()

    def computeBounds(self):
        if self.myPhoto.isNull():
            self.myPhotoDestRect = QRect(0, 0, self.width(), self.height())
            self.viewCenter = (self.width() / 2, self.height() / 2)
            self.myPhotoRadius = 0
            self.myPhotoDiameter = 0
            for i in range(0, len(common.SamplingPattern)):
                self.samplePoints[i] = (0, 0)
                self.sampleAreaVisible[i] = []
            return

        # scale photo destination rect to fit photo on screen
        # scale by the scaling factor that requires the most scaling ( - 2 to fit in border )
        wRatio = self.width() / self.myPhoto.width()
        hRatio = self.height() / self.myPhoto.height()
        if wRatio <= hRatio:
            self.myPhotoDestRect.setWidth(self.myPhotoSrcRect.width() * wRatio - 2)
            self.myPhotoDestRect.setHeight(self.myPhotoSrcRect.height() * wRatio - 2)
        else:
            self.myPhotoDestRect.setWidth(self.myPhotoSrcRect.width() * hRatio - 2)
            self.myPhotoDestRect.setHeight(self.myPhotoSrcRect.height() * hRatio - 2)

        # center the photo dest rect
        self.myPhotoDestRect.moveTo(self.width() / 2 - self.myPhotoDestRect.width() / 2,
                                    self.height() / 2 - self.myPhotoDestRect.height() / 2)

        # NOTE - THESE ARE THE MOST IMPORTANT COMPUTATIONS FROM WHICH EVERYTHING ELSE IS PLOTTED
        self.viewCenter = (self.width() / 2, self.height() / 2)
        self.myPhotoRadius = self.myPhotoDestRect.height() / 2
        self.myPhotoDiameter = self.myPhotoRadius * 2
        self.myPhotoTopLeft = ((self.viewCenter[0] - self.myPhotoRadius), (self.viewCenter[1] - self.myPhotoRadius))

        # compute new scaled font size
        self.fontScaled = QFont('Courier New', self.myPhotoRadius * (1/(101-common.AppSettings["HUDTextScale"])))
        self.fontMetrics = QFontMetrics(self.fontScaled)

        # compute sampling pattern collision bounds
        ViewFisheye.SampleRadius = self.myPhotoRadius / 50
        hFOV = common.DataConfig["RadianceFOV"] / 2
        for i in range(0, len(common.SamplingPattern)):
            # compute sample bounds
            u, v = utility_angles.SkyCoord2FisheyeUV(common.SamplingPattern[i][0], common.SamplingPattern[i][1])
            x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
            y = self.myPhotoTopLeft[1] + (v * self.myPhotoDiameter)
            self.samplePoints[i] = (x, y)
            # compute sampling pattern actual sampling areas (projected differential angle area)
            p1 = utility_angles.SkyCoord2FisheyeUV(common.SamplingPattern[i][0] - hFOV, common.SamplingPattern[i][1] - hFOV)
            p2 = utility_angles.SkyCoord2FisheyeUV(common.SamplingPattern[i][0] - hFOV, common.SamplingPattern[i][1] + hFOV)
            p3 = utility_angles.SkyCoord2FisheyeUV(common.SamplingPattern[i][0] + hFOV, common.SamplingPattern[i][1] + hFOV)
            p4 = utility_angles.SkyCoord2FisheyeUV(common.SamplingPattern[i][0] + hFOV, common.SamplingPattern[i][1] - hFOV)
            p1 = QPoint(self.myPhotoTopLeft[0] + (p1[0] * self.myPhotoDiameter), self.myPhotoTopLeft[1] + (p1[1] * self.myPhotoDiameter))
            p2 = QPoint(self.myPhotoTopLeft[0] + (p2[0] * self.myPhotoDiameter), self.myPhotoTopLeft[1] + (p2[1] * self.myPhotoDiameter))
            p3 = QPoint(self.myPhotoTopLeft[0] + (p3[0] * self.myPhotoDiameter), self.myPhotoTopLeft[1] + (p3[1] * self.myPhotoDiameter))
            p4 = QPoint(self.myPhotoTopLeft[0] + (p4[0] * self.myPhotoDiameter), self.myPhotoTopLeft[1] + (p4[1] * self.myPhotoDiameter))
            self.sampleAreaVisible[i] = [p1, p2, p3, p4]

        # compute compass lines
        self.compassTicks.clear()
        tickLength = self.myPhotoRadius / 90
        for angle in range(0, 360, 10):
            theta = 360 - ((angle + 270) % 360)  # angles eastward from North, North facing down
            rads = theta * math.pi / 180.0
            cx1 = (math.cos(rads) * (self.myPhotoRadius - tickLength)) + self.viewCenter[0]
            cy1 = (math.sin(rads) * (self.myPhotoRadius - tickLength)) + self.viewCenter[1]
            cx2 = (math.cos(rads) * self.myPhotoRadius) + self.viewCenter[0]
            cy2 = (math.sin(rads) * self.myPhotoRadius) + self.viewCenter[1]
            lx1 = (math.cos(rads) * (self.myPhotoRadius - tickLength*4)) + self.viewCenter[0] - self.fontMetrics.width(str(angle))/2
            ly1 = (math.sin(rads) * (self.myPhotoRadius - tickLength*4)) + self.viewCenter[1] - self.fontMetrics.height()/2
            self.compassTicks.append([cx1, cy1, cx2, cy2, lx1, ly1, angle])  # x1, y1, x2, y2, x1lbl, y1lbl, angle

        # compute new grid for debugging coordinates
        griddivs = 5
        gridwidth = int(round(self.myPhotoDiameter / griddivs))
        self.gridpoints = []
        self.gridUVs = []
        self.gridskycoords = []
        for r in range(1, griddivs):
            for c in range(1, griddivs):
                point = (self.myPhotoTopLeft[0] + (c * gridwidth), self.myPhotoTopLeft[1] + (r * gridwidth))
                self.gridpoints.append(point)
                u = (point[0] - self.myPhotoTopLeft[0]) / self.myPhotoDiameter
                v = (point[1] - self.myPhotoTopLeft[1]) / self.myPhotoDiameter
                self.gridUVs.append((u, v))
                t, p = utility_angles.FisheyeUV2SkyCoord(u, v)
                self.gridskycoords.append((t, p))

        # compute lens (ideal and actual) radii for drawn latitude ellipses along zenith
        self.lensIdealRadii.clear()
        self.lensRealRadii.clear()
        for alt in common.SamplingPatternAlts:
            # ideal lens
            u, v = utility_angles.SkyCoord2FisheyeUV(90, alt, lenswarp=False)
            x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
            r = x - self.viewCenter[0]
            self.lensIdealRadii.append((r, alt))  # (radius, altitude)
            # warped lens
            u, v = utility_angles.SkyCoord2FisheyeUV(90, alt)
            x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
            r = x - self.viewCenter[0]
            self.lensRealRadii.append((r, alt))   # (radius, altitude)

        # compute sun path screen points
        self.pathSun = QPainterPath()
        if len(self.sunPathPoints) > 0:
            azi, alt, dt = self.sunPathPoints[0]
            u, v = utility_angles.SkyCoord2FisheyeUV(azi, alt)
            x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
            y = self.myPhotoTopLeft[1] + (v * self.myPhotoDiameter)
            self.pathSun.moveTo(x, y)
            for i in range(1, len(self.sunPathPoints)):
                azi, alt, dt = self.sunPathPoints[i]
                u, v = utility_angles.SkyCoord2FisheyeUV(azi, alt)
                x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
                y = self.myPhotoTopLeft[1] + (v * self.myPhotoDiameter)
                self.pathSun.lineTo(x, y)

        # compute sun position screen point
        u, v = utility_angles.SkyCoord2FisheyeUV(self.sunPosition[0], self.sunPosition[1])
        x = self.myPhotoTopLeft[0] + (u * self.myPhotoDiameter)
        y = self.myPhotoTopLeft[1] + (v * self.myPhotoDiameter)
        self.sunPositionVisible = (x, y)

        # compute new mask
        self.mask = QPixmap(self.width(), self.height()).toImage()

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter()
        painter.begin(self)

        # background
        brushBG = QBrush(Qt.black, Qt.SolidPattern)
        if not common.AppSettings["ShowMask"]:
            brushBG.setColor(Qt.darkGray)
            brushBG.setStyle(Qt.Dense1Pattern)
            painter.setBackground(Qt.gray)
        else:
            brushBG.setColor(Qt.black)
            brushBG.setStyle(Qt.SolidPattern)
            painter.setBackground(Qt.black)
        painter.setBackgroundMode(Qt.OpaqueMode)
        painter.setBrush(brushBG)
        painter.setPen(Qt.NoPen)
        painter.drawRect(0, 0, self.width(), self.height())

        # draw photo
        if not self.myPhoto.isNull():
            # rotate and draw photo as specified by user
            transform = QTransform()
            transform.translate(self.myPhotoDestRect.center().x(), self.myPhotoDestRect.center().y())
            transform.rotate(-self.myPhotoRotation)
            transform.translate(-self.myPhotoDestRect.center().x(), -self.myPhotoDestRect.center().y())
            painter.setTransform(transform)
            painter.drawImage(self.myPhotoDestRect, self.myPhoto, self.myPhotoSrcRect) # draw it
            painter.resetTransform()

            # useful local vars
            centerPoint = QPoint(self.viewCenter[0], self.viewCenter[1])
            destRect = QRect(0, 0, self.myPhotoDestRect.width(), self.myPhotoDestRect.height())
            fontWidth = self.fontMetrics.width("X")

            # mask
            if common.AppSettings["ShowMask"]:
                maskPainter = QPainter()
                maskPainter.begin(self.mask)
                maskPainter.setBrush(QBrush(Qt.magenta, Qt.SolidPattern))
                maskPainter.drawEllipse(self.viewCenter[0] - self.myPhotoRadius, self.viewCenter[1] - self.myPhotoRadius, self.myPhotoDiameter, self.myPhotoDiameter)
                maskPainter.end()
                painter.setCompositionMode(QPainter.CompositionMode_DestinationIn)
                painter.drawImage(0, 0, self.mask)
                painter.setCompositionMode(QPainter.CompositionMode_SourceOver)

            # HUD
            if common.AppSettings["ShowHUD"]:
                painter.setBackgroundMode(Qt.TransparentMode)
                #painter.setBackground(Qt.black)
                painter.setBrush(Qt.NoBrush)
                painter.setFont(self.fontScaled)

                # draw UV grid
                if common.AppSettings["ShowUVGrid"]:
                    painter.setPen(self.penText)
                    # box
                    tl = self.myPhotoTopLeft
                    tr = (self.viewCenter[0] + self.myPhotoRadius, self.viewCenter[1] - self.myPhotoRadius)
                    bl = (self.viewCenter[0] - self.myPhotoRadius, self.viewCenter[1] + self.myPhotoRadius)
                    br = (self.viewCenter[0] + self.myPhotoRadius, self.viewCenter[1] + self.myPhotoRadius)
                    painter.drawLine(tl[0], tl[1], tr[0], tr[1])
                    painter.drawLine(bl[0], bl[1], br[0], br[1])
                    painter.drawLine(tl[0], tl[1], bl[0], bl[1])
                    painter.drawLine(tr[0], tr[1], br[0], br[1])
                    # crosshairs
                    painter.drawLine(tl[0], self.viewCenter[1], tr[0], self.viewCenter[1])
                    painter.drawLine(self.viewCenter[0], tr[1], self.viewCenter[0], br[1])
                    # labels
                    destRect.setCoords(tl[0] + 4, tl[1] + 4, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "0")
                    destRect.setCoords(tr[0] - (fontWidth+4), tr[1] + 4, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "1")
                    destRect.setCoords(bl[0] + 3, bl[1] - (self.fontMetrics.height()+3), self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "1")
                    destRect.setCoords(br[0] - (fontWidth+3), br[1] - (self.fontMetrics.height()+3), self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "1")
                    # grid coordinates
                    gpntrad = self.myPhotoRadius * 0.005
                    painter.setPen(self.penText)
                    painter.setBrush(self.brushGrid)
                    painter.setFont(self.fontScaled)
                    for i in range(0, len(self.gridpoints)):
                        point = self.gridpoints[i]
                        u, v = self.gridUVs[i]
                        t, p = self.gridskycoords[i]
                        painter.drawEllipse(QPoint(point[0], point[1]), gpntrad, gpntrad)
                        destRect.setCoords(point[0]+fontWidth/2, point[1]-self.fontMetrics.height(), self.width(), self.height())
                        textuv = "{0:.1f}u, {1:.1f}v".format(round(u,1), round(v,1))
                        painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, textuv)
                        destRect.setCoords(point[0]+fontWidth/2, point[1], self.width(), self.height())
                        textuv = "{0:d}°, {1:d}°".format(int(round(t)), int(round(p)))
                        painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, textuv)
                    painter.setBrush(Qt.NoBrush)

                # draw lens warp
                if common.AppSettings["ShowLensWarp"]:
                    # ideal lens longitudes along azimuth
                    painter.setPen(self.penText)
                    for i in range(0, int(len(self.compassTicks)/2), 3):
                        p1 = QPoint(self.compassTicks[i][2], self.compassTicks[i][3])
                        p2 = QPoint(self.compassTicks[i+18][2], self.compassTicks[i+18][3])  # tick opposite 180 degrees
                        painter.drawLine(p1, p2)
                    # ideal lens latitudes along zenith
                    for r, alt in self.lensIdealRadii:
                        painter.drawEllipse(centerPoint, r, r)
                    # actual/warped lens latitudes along zenith
                    painter.setPen(self.penLens)
                    for r, alt in self.lensRealRadii:
                        painter.drawEllipse(centerPoint, r, r)
                        destRect.setCoords(self.viewCenter[0] + r + 3, self.viewCenter[1] - (self.fontMetrics.height() + 3), self.width(), self.height())
                        painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "{0:d}°".format(int(alt)))

                # draw compass
                if common.AppSettings["ShowCompass"]:
                    # compass ticks text shadows
                    if common.AppSettings["ShowShadows"]:
                        painter.setPen(self.penShadowText)
                        for tick in self.compassTicks:
                            destRect.setCoords(tick[4] + 1, tick[5] + 1, self.width(), self.height())
                            painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, str(tick[6])+"°")
                    # compass ticks text
                    painter.setPen(self.penText)
                    for tick in self.compassTicks:
                        painter.drawLine(tick[0], tick[1], tick[2], tick[3])
                        destRect.setCoords(tick[4], tick[5], self.width(), self.height())
                        painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, str(tick[6])+"°")
                    # photo radius
                    #painter.drawEllipse(self.viewCenter[0] - self.myPhotoRadius, self.viewCenter[1] - self.myPhotoRadius, self.myPhotoDiameter, self.myPhotoDiameter)
                    painter.drawEllipse(centerPoint, self.myPhotoRadius, self.myPhotoRadius)
                    # cardinal directions
                    destRect.setCoords(self.viewCenter[0] - self.myPhotoRadius - (fontWidth+4), self.viewCenter[1] - self.fontMetrics.height()/2, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "W")
                    destRect.setCoords(self.viewCenter[0] + self.myPhotoRadius + 4, self.viewCenter[1] - self.fontMetrics.height()/2, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "E")
                    destRect.setCoords(self.viewCenter[0] - fontWidth/2, self.viewCenter[1] - self.myPhotoRadius - (self.fontMetrics.height()+3), self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "S")
                    destRect.setCoords(self.viewCenter[0] - fontWidth/2, self.viewCenter[1] + self.myPhotoRadius + 3, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "N")

                # draw sampling pattern
                if common.AppSettings["ShowSamples"]:
                    painter.setPen(self.penText)
                    for i, points in enumerate(self.sampleAreaVisible):
                        painter.drawLine(QLine(points[0], points[1]))
                        painter.drawLine(QLine(points[1], points[2]))
                        painter.drawLine(QLine(points[2], points[3]))
                        painter.drawLine(QLine(points[3], points[0]))
                    for i in range(0, len(self.samplePoints)):
                        p = self.samplePoints[i]
                        painter.drawEllipse(QPoint(p[0],p[1]), ViewFisheye.SampleRadius, ViewFisheye.SampleRadius)
                        painter.drawText(p[0] + ViewFisheye.SampleRadius, p[1], str(i))

                # draw sun path
                if common.AppSettings["ShowSunPath"]:
                    sunradius = self.myPhotoRadius * 0.1
                    # shadows
                    painter.setPen(self.penShadowSun)
                    if common.AppSettings["ShowShadows"]:
                        painter.drawEllipse(QPoint(self.sunPositionVisible[0]+1, self.sunPositionVisible[1]+1), sunradius, sunradius)
                        self.pathSun.translate(1.0, 1.0)
                        painter.drawPath(self.pathSun)
                        self.pathSun.translate(-1.0, -1.0)
                        for i in range(0, self.pathSun.elementCount()):
                            e = self.pathSun.elementAt(i)
                            destRect.setCoords(e.x, e.y + self.fontMetrics.height()/2 + 1, self.width(), self.height())
                            painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, str(self.sunPathPoints[i][2].hour))
                    # sun, path, hours
                    painter.setPen(self.penSun)
                    painter.drawEllipse(QPoint(self.sunPositionVisible[0], self.sunPositionVisible[1]), sunradius, sunradius)
                    painter.drawPath(self.pathSun)
                    for i in range(0, self.pathSun.elementCount()):
                        e = self.pathSun.elementAt(i)
                        destRect.setCoords(e.x, e.y + self.fontMetrics.height() / 2, self.width(), self.height())
                        painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, str(self.sunPathPoints[i][2].hour))

                # draw selected samples (ALWAYS)
                r = QRect()
                # shadows
                if common.AppSettings["ShowShadows"]:
                    painter.setPen(self.penShadowSelected)
                    for i in self.samplesSelected:
                        x, y = self.samplePoints[i]
                        painter.drawEllipse(QPoint(x+1, y+1), ViewFisheye.SampleRadius, ViewFisheye.SampleRadius)
                # samples
                for i in self.samplesSelected:
                    painter.setPen(self.penSelected[i])
                    x, y = self.samplePoints[i]
                    painter.drawEllipse(QPoint(x, y), ViewFisheye.SampleRadius, ViewFisheye.SampleRadius)

                # draw user's selection bounds
                if (abs(self.dragSelectRect.right()-self.dragSelectRect.left()) >= ViewFisheye.SelectionRectMin and
                    abs(self.dragSelectRect.bottom()-self.dragSelectRect.top()) >= ViewFisheye.SelectionRectMin):
                    painter.setPen(self.penSelectRect)
                    painter.drawRect(self.dragSelectRect)

                # draw timestamp
                painter.setPen(self.penText)
                painter.setFont(self.fontFixed)
                destRect.setCoords(10, 10, self.width() / 2, 50)
                painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, str(self.myPhotoTime))
                # draw sky cover assessment
                destRect.setCoords(10, 25, self.width(), self.height())
                painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, self.skyCover.name + "/" + common.SkyCoverDesc[self.skyCover])
                # draw photo rotation
                if self.myPhotoRotation != 0:
                    destRect.setCoords(10, self.height()-25, self.width(), self.height())
                    painter.drawText(destRect, Qt.AlignTop | Qt.AlignLeft, "Rotation: " + str(self.myPhotoRotation) + "°")

                # where is the mouse relative to the center?
                # this is used as an optimization to only display information when mouse is in fisheye portion
                dx = self.coordsMouse[0] - self.viewCenter[0]
                dy = self.coordsMouse[1] - self.viewCenter[1]
                distance = math.sqrt((dx * dx) + (dy * dy))  # distance from mouse to view center

                # coordinates we are interested in
                #self.coordsMouse    # x,y of this widget
                coordsxy = (-1, -1)  # x,y over photo as scaled/rendered on this widget
                coordsXY = (-1, -1)  # x,y over actual original photo on disk
                coordsUV = (-1, -1)  # u,v coords of fisheye portion of photo w/ 0,0 top left and 1,1 bottom right
                coordsTP = (-1, -1)  # theta,phi polar coordinates
                # text
                textxy = "-1, -1 xy"
                textXY = "-1, -1 xy"
                textUV = "-1, -1 uv"
                textTP = "-1, -1 θφ"
                textPX = "0 0 0 px"

                # compute all relevant information only when mouse is within fisheye portion of photo
                if distance < self.myPhotoRadius:
                    coordsxy = (self.coordsMouse[0] - self.myPhotoDestRect.x(),
                                self.coordsMouse[1] - self.myPhotoDestRect.y())
                    coordsXY = (int(coordsxy[0] / self.myPhotoDestRect.width() * self.myPhoto.width()),
                                int(coordsxy[1] / self.myPhotoDestRect.height() * self.myPhoto.height()))
                    coordsUV = ((self.coordsMouse[0] - self.myPhotoTopLeft[0]) / self.myPhotoDiameter,
                                (self.coordsMouse[1] - self.myPhotoTopLeft[1]) / self.myPhotoDiameter)
                    coordsTP = utility_angles.FisheyeUV2SkyCoord(coordsUV[0], coordsUV[1])
                    # text
                    textxy = str(coordsxy[0]) + ", " + str(coordsxy[1]) + " xy"
                    textXY = str(coordsXY[0]) + ", " + str(coordsXY[1]) + " xy"
                    textUV = "{:.2f}".format(coordsUV[0]) + ", " + "{:.2f}".format(coordsUV[1]) + " uv"
                    textTP = "{:.2f}".format(coordsTP[0]) + ", " + "{:.2f}".format(coordsTP[1]) + " θφ"

                # pixels colors
                pixreg = common.AppSettings["PixelRegion"]
                colorsRegion = np.zeros((pixreg, pixreg, 4))
                colorFinal = colorsRegion[0,0]  # RGBA of pixel under mouse of photo on disk
                # colorFinal = self.myPhoto.pixelColor(coordsXY[0], coordsXY[1])
                if distance < self.myPhotoRadius:
                    halfdim = int(pixreg / 2)
                    rstart = coordsXY[1]-halfdim
                    rstop = coordsXY[1]+halfdim+1
                    cstart = coordsXY[0]-halfdim
                    cstop = coordsXY[0]+halfdim+1
                    if (rstart >= 0 and rstop<=self.myPhotoPixels.shape[0] and
                        cstart >= 0 and cstop<=self.myPhotoPixels.shape[1]):
                        colorsRegion = self.myPhotoPixels[rstart:rstop, cstart:cstop]
                        colorFinal = colorsRegion[halfdim, halfdim]
                        if pixreg > 1:  # with pixel weighting
                            colorFinal = utility_data.collectPixels([coordsXY], [pixreg], pixels=self.myPhotoPixels, weighting=common.PixelWeighting(common.AppSettings["PixelWeighting"]))[0]
                    textPX = str(colorFinal[0]) + " " + str(colorFinal[1]) + " " + str(colorFinal[2]) + " px"

                # draw HUD text strings
                # x,y coords
                destRect.setCoords(0, 0, self.width() - 10, self.height()- 124)
                painter.drawText(destRect, Qt.AlignBottom | Qt.AlignRight, textxy)
                # X,Y coords
                destRect.setCoords(0, 0, self.width() - 10, self.height() - 114)
                painter.drawText(destRect, Qt.AlignBottom | Qt.AlignRight, textXY)
                # u,v coords
                destRect.setCoords(0, 0, self.width() - 10, self.height() - 104)
                painter.drawText(destRect, Qt.AlignBottom | Qt.AlignRight, textUV)
                # t,p coords
                destRect.setCoords(0, 0, self.width() - 10, self.height() - 94)
                painter.drawText(destRect, Qt.AlignBottom | Qt.AlignRight, textTP)
                # pixel color
                destRect.setCoords(0, 0, self.width() - 10, self.height() - 84)
                painter.drawText(destRect, Qt.AlignBottom | Qt.AlignRight, textPX)

                # compute pixel visualization coordinates
                circleX = self.width() - 10 - ViewFisheye.SelectedPixelBox - 10 - ViewFisheye.SelectedPixelBox - 10 - ViewFisheye.SelectedPixelBox
                circleY = self.height() - 10 - ViewFisheye.SelectedPixelBox
                pixelsX = self.width() - 10 - ViewFisheye.SelectedPixelBox - 10 - ViewFisheye.SelectedPixelBox
                pixelsY = self.height() - 10 - ViewFisheye.SelectedPixelBox
                pixelsWeightedX = self.width() - ViewFisheye.SelectedPixelBox - 10
                pixelsWeightedY = self.height() - 10 - ViewFisheye.SelectedPixelBox

                # draw pixel visualization - fills
                pixreg = common.AppSettings["PixelRegion"]
                if distance < self.myPhotoRadius:
                    painter.setPen(Qt.NoPen)
                    # pixel region
                    pixdim = ViewFisheye.SelectedPixelBox / pixreg
                    for row in range(0, pixreg):
                        for col in range(0, pixreg):
                            color = colorsRegion[row, col]
                            color = QColor(color[0], color[1], color[2])
                            painter.setBrush(QBrush(color, Qt.SolidPattern))
                            painter.drawRect(pixelsX + (col * pixdim), pixelsY + (row * pixdim), math.ceil(pixdim), math.ceil(pixdim))
                    # final pixel color
                    color = QColor(colorFinal[0], colorFinal[1], colorFinal[2])
                    painter.setBrush(QBrush(color, Qt.SolidPattern))
                    cx = circleX + (coordsUV[0] * ViewFisheye.SelectedPixelBox)
                    cy = circleY + (coordsUV[1] * ViewFisheye.SelectedPixelBox)
                    painter.drawEllipse(cx - 5, cy - 5, 10, 10)
                    painter.drawRect(pixelsWeightedX, pixelsWeightedY, ViewFisheye.SelectedPixelBox, ViewFisheye.SelectedPixelBox)

                # draw pixel visualization - outlines
                painter.setPen(self.penText)
                painter.setBrush(Qt.NoBrush)
                painter.drawEllipse(circleX, circleY, ViewFisheye.SelectedPixelBox, ViewFisheye.SelectedPixelBox)
                painter.drawRect(pixelsX, pixelsY, ViewFisheye.SelectedPixelBox, ViewFisheye.SelectedPixelBox)
                painter.drawRect(pixelsWeightedX, pixelsWeightedY, ViewFisheye.SelectedPixelBox, ViewFisheye.SelectedPixelBox)

                # raw data missing indicator
                # if (not self.rawAvailable):
                #     painter.drawPixmap(pixelX + ViewFisheye.SelectedPixelBox / 2,
                #                        pixelY + ViewFisheye.SelectedPixelBox / 2,
                #                        self.iconWarning)

        # end draw
        painter.end()
示例#28
0
def drawIconWithShadow(icon: QIcon,
                       rect: QRect,
                       p: QPainter,
                       iconMode: QIcon.Mode = None,
                       dipRadius: int = None,
                       color: QColor = None,
                       dipOffset: QPoint = None):
    if iconMode is None:
        iconMode = QIcon.Normal
    if color is None:
        color = QColor(0, 0, 0, 130)
    if dipRadius is None:
        dipRadius = 3
    if dipOffset is None:
        dipOffset = QPoint(1, -2)

    devicePixelRatio: int = p.device().devicePixelRatio()
    pixmapName = "icon %s %s %s %s" % (icon.cacheKey(), iconMode,
                                       rect.height(), devicePixelRatio)
    cache = QPixmapCache.find(pixmapName)
    if cache is None:
        # High-dpi support: The in parameters (rect, radius, offset) are in
        # device-independent pixels. The call to QIcon::pixmap() below might
        # return a high-dpi pixmap, which will in that case have a devicePixelRatio
        # different than 1. The shadow drawing caluculations are done in device
        # pixels.
        window = p.device().window().windowHandle()
        px = icon.pixmap(window, rect.size(), iconMode)
        radius = dipRadius * devicePixelRatio
        offset = dipOffset * devicePixelRatio
        cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
        cache.fill(Qt.transparent)
        cachePainter = QPainter(cache)

        if iconMode == QIcon.Disabled:
            hasDisabledState = len(icon.availableSizes()) == len(
                icon.availableSizes(QIcon.Disabled))
            if not hasDisabledState:
                px = disabledSideBarIcon(icon.pixmap(window, rect.size()))
        elif TOOLBAR_ICON_SHADOW:
            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1),
                         QImage.Format_ARGB32_Premultiplied)
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(
                QRect(radius, radius, px.width(), px.height()), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            #qt_blurImage(blurPainter, tmp, radius, False, True)
            # implement qt_blurImage via QLabel with QGraphicsBlurEffect
            # FIXME: alignment is broken
            scene = QGraphicsScene()
            item = QGraphicsPixmapItem(QPixmap.fromImage(tmp))
            effect = QGraphicsBlurEffect()
            effect.setBlurRadius(radius)
            item.setGraphicsEffect(effect)
            scene.addItem(item)
            scene.render(blurPainter)
            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.rect().height()), tmp)

        # Draw the actual pixmap...
        cachePainter.drawPixmap(
            QRect(
                QPoint(radius, radius) + offset, QSize(px.width(),
                                                       px.height())), px)
        cachePainter.end()
        cache.setDevicePixelRatio(devicePixelRatio)
        QPixmapCache.insert(pixmapName, cache)

    targetRect = cache.rect()
    targetRect.setSize(targetRect.size() / cache.devicePixelRatio())
    targetRect.moveCenter(rect.center() - dipOffset)
    p.drawPixmap(targetRect, cache)
    def paintEvent(self, evt):
        """
        Protected method handling paint events.
        
        @param evt paint event (QPaintEvent)
        """
        if self.__grabbing:  # grabWindow() should just get the background
            return

        painter = QPainter(self)
        pal = QPalette(QToolTip.palette())
        font = QToolTip.font()

        handleColor = pal.color(QPalette.Active, QPalette.Highlight)
        handleColor.setAlpha(160)
        overlayColor = QColor(0, 0, 0, 160)
        textColor = pal.color(QPalette.Active, QPalette.Text)
        textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
        painter.drawPixmap(0, 0, self.__pixmap)
        painter.setFont(font)

        r = QRect(self.__selection)
        if not self.__selection.isNull():
            grey = QRegion(self.rect())
            if self.__mode == SnapshotRegionGrabber.Ellipse:
                reg = QRegion(r, QRegion.Ellipse)
            else:
                reg = QRegion(r)
            grey = grey.subtracted(reg)
            painter.setClipRegion(grey)
            painter.setPen(Qt.NoPen)
            painter.setBrush(overlayColor)
            painter.drawRect(self.rect())
            painter.setClipRect(self.rect())
            drawRect(painter, r, handleColor)

        if self.__showHelp:
            painter.setPen(textColor)
            painter.setBrush(textBackgroundColor)
            self.__helpTextRect = painter.boundingRect(
                self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap,
                self.__helpText).translated(-self.__desktop.x(),
                                            -self.__desktop.y())
            self.__helpTextRect.adjust(-2, -2, 4, 2)
            drawRect(painter, self.__helpTextRect, textColor,
                     textBackgroundColor)
            painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3),
                             Qt.TextWordWrap, self.__helpText)

        if self.__selection.isNull():
            return

        # The grabbed region is everything which is covered by the drawn
        # rectangles (border included). This means that there is no 0px
        # selection, since a 0px wide rectangle will always be drawn as a line.
        txt = "{0}, {1} ({2} x {3})".format(
            self.__locale.toString(self.__selection.x()),
            self.__locale.toString(self.__selection.y()),
            self.__locale.toString(self.__selection.width()),
            self.__locale.toString(self.__selection.height()))
        textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
        boundingRect = textRect.adjusted(-4, 0, 0, 0)

        if textRect.width() < r.width() - 2 * self.__handleSize and \
           textRect.height() < r.height() - 2 * self.__handleSize and \
           r.width() > 100 and \
           r.height() > 100:
            # center, unsuitable for small selections
            boundingRect.moveCenter(r.center())
            textRect.moveCenter(r.center())
        elif r.y() - 3 > textRect.height() and \
                r.x() + textRect.width() < self.rect().width():
            # on top, left aligned
            boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
            textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
        elif r.x() - 3 > textRect.width():
            # left, top aligned
            boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
            textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
        elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
                r.right() > textRect.width():
            # at bottom, right aligned
            boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
            textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
        elif r.right() + textRect.width() + 3 < self.rect().width():
            # right, bottom aligned
            boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
            textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))

        # If the above didn't catch it, you are running on a very
        # tiny screen...
        drawRect(painter, boundingRect, textColor, textBackgroundColor)
        painter.drawText(textRect, Qt.AlignHCenter, txt)

        if (r.height() > self.__handleSize * 2 and
            r.width() > self.__handleSize * 2) or \
           not self.__mouseDown:
            self.__updateHandles()
            painter.setPen(Qt.NoPen)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.StrokeMask))
            painter.drawRect(self.rect())
            handleColor.setAlpha(60)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.FillMask))
            painter.drawRect(self.rect())
示例#30
0
class corkDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        QStyledItemDelegate.__init__(self, parent)
        self.factor = settings.corkSizeFactor / 100.
        self.lastPos = None
        self.editing = None
        self.margin = 5

        self.bgColors = {}

    def newStyle(self):
        return settings.corkStyle == "new"

    def setCorkSizeFactor(self, v):
        self.factor = v / 100.

    def sizeHint(self, option, index):
        if self.newStyle():
            defaultSize = QSize(300, 210)
        else:
            defaultSize = QSize(300, 200)
        return defaultSize * self.factor

    def editorEvent(self, event, model, option, index):
        # We catch the mouse position in the widget to know which part to edit
        if type(event) == QMouseEvent:
            self.lastPos = event.pos()  # - option.rect.topLeft()
        return QStyledItemDelegate.editorEvent(self, event, model, option,
                                               index)

    def createEditor(self, parent, option, index):
        # When the user performs a global search and selects an Outline result (title or summary), the
        # associated chapter is selected in cork view, triggering a call to this method with the results
        # list widget set in self.sender(). In this case we store the searched column so we know which
        # editor should be created.
        searchedColumn = None
        if self.sender() is not None and self.sender().objectName(
        ) == 'result' and self.sender().currentItem():
            searchedColumn = self.sender().currentItem().data(
                Qt.UserRole).column()

        self.updateRects(option, index)

        bgColor = self.bgColors.get(index, "white")

        if searchedColumn == Outline.summarySentence or (
                self.lastPos is not None
                and self.mainLineRect.contains(self.lastPos)):
            # One line summary
            self.editing = Outline.summarySentence
            edt = QLineEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrame(False)
            f = QFont(option.font)
            if self.newStyle():
                f.setBold(True)
            else:
                f.setItalic(True)
                edt.setAlignment(Qt.AlignCenter)
            edt.setPlaceholderText(self.tr("One line summary"))
            edt.setFont(f)
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            return edt

        elif searchedColumn == Outline.title or (self.lastPos is not None
                                                 and self.titleRect.contains(
                                                     self.lastPos)):
            # Title
            self.editing = Outline.title
            edt = QLineEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrame(False)
            f = QFont(option.font)
            if self.newStyle():
                f.setPointSize(f.pointSize() + 4)
            else:
                edt.setAlignment(Qt.AlignCenter)
            f.setBold(True)
            edt.setFont(f)
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            # edt.setGeometry(self.titleRect)
            return edt

        else:  # self.mainTextRect.contains(self.lastPos):
            # Summary
            self.editing = Outline.summaryFull
            edt = QPlainTextEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrameShape(QFrame.NoFrame)
            try:
                # QPlainTextEdit.setPlaceholderText was introduced in Qt 5.3
                edt.setPlaceholderText(self.tr("Full summary"))
            except AttributeError:
                pass
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            return edt

    def updateEditorGeometry(self, editor, option, index):

        if self.editing == Outline.summarySentence:
            # One line summary
            editor.setGeometry(self.mainLineRect)

        elif self.editing == Outline.title:
            # Title
            editor.setGeometry(self.titleRect)

        elif self.editing == Outline.summaryFull:
            # Summary
            editor.setGeometry(self.mainTextRect)

    def setEditorData(self, editor, index):
        item = index.internalPointer()

        if self.editing == Outline.summarySentence:
            # One line summary
            editor.setText(item.data(Outline.summarySentence))

        elif self.editing == Outline.title:
            # Title
            editor.setText(index.data())

        elif self.editing == Outline.summaryFull:
            # Summary
            editor.setPlainText(item.data(Outline.summaryFull))

    def setModelData(self, editor, model, index):

        if self.editing == Outline.summarySentence:
            # One line summary
            model.setData(index.sibling(index.row(), Outline.summarySentence),
                          editor.text())

        elif self.editing == Outline.title:
            # Title
            model.setData(index, editor.text(), Outline.title)

        elif self.editing == Outline.summaryFull:
            # Summary
            model.setData(index.sibling(index.row(), Outline.summaryFull),
                          editor.toPlainText())

    def updateRects(self, option, index):
        if self.newStyle():
            self.updateRects_v2(option, index)
        else:
            self.updateRects_v1(option, index)

    def updateRects_v2(self, option, index):
        margin = self.margin * 2
        iconSize = max(24 * self.factor, 18)
        item = index.internalPointer()
        fm = QFontMetrics(option.font)
        h = fm.lineSpacing()

        self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin)

        top = 15 * self.factor
        self.topRect = QRect(self.itemRect)
        self.topRect.setHeight(top)

        self.cardRect = QRect(self.itemRect.topLeft() + QPoint(0, top),
                              self.itemRect.bottomRight())
        self.iconRect = QRect(self.cardRect.topLeft() + QPoint(margin, margin),
                              QSize(iconSize, iconSize))
        self.labelRect = QRect(
            self.cardRect.topRight() - QPoint(margin + self.factor * 18, 1),
            self.cardRect.topRight() +
            QPoint(-margin - self.factor * 4, self.factor * 24))
        self.titleRect = QRect(
            self.iconRect.topRight() + QPoint(margin, 0),
            self.labelRect.bottomLeft() - QPoint(margin, margin))
        self.titleRect.setBottom(self.iconRect.bottom())
        self.mainRect = QRect(
            self.iconRect.bottomLeft() + QPoint(0, margin),
            self.cardRect.bottomRight() - QPoint(margin, 2 * margin))
        self.mainRect.setLeft(self.titleRect.left())
        self.mainLineRect = QRect(self.mainRect.topLeft(),
                                  self.mainRect.topRight() + QPoint(0, h))
        self.mainTextRect = QRect(
            self.mainLineRect.bottomLeft() + QPoint(0, margin),
            self.mainRect.bottomRight())
        if not item.data(Outline.summarySentence):
            self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())

    def updateRects_v1(self, option, index):
        margin = self.margin
        iconSize = max(16 * self.factor, 12)
        item = index.internalPointer()
        self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin)
        self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin),
                              QSize(iconSize, iconSize))
        self.labelRect = QRect(
            self.itemRect.topRight() - QPoint(iconSize + margin, 0),
            self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin))
        self.titleRect = QRect(
            self.iconRect.topRight() + QPoint(margin, 0),
            self.labelRect.bottomLeft() - QPoint(margin, margin))
        self.bottomRect = QRect(
            QPoint(self.itemRect.x(),
                   self.iconRect.bottom() + margin),
            QPoint(self.itemRect.right(), self.itemRect.bottom()))
        self.topRect = QRect(self.itemRect.topLeft(),
                             self.bottomRect.topRight())
        self.mainRect = self.bottomRect.adjusted(margin, margin, -margin,
                                                 -margin)
        self.mainLineRect = QRect(
            self.mainRect.topLeft(),
            self.mainRect.topRight() + QPoint(0, iconSize))
        self.mainTextRect = QRect(
            self.mainLineRect.bottomLeft() + QPoint(0, margin),
            self.mainRect.bottomRight())
        if not item.data(Outline.summarySentence):
            self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())
        if item.data(Outline.label) in ["", "0", 0]:
            self.titleRect.setBottomRight(self.labelRect.bottomRight() -
                                          QPoint(self.margin, self.margin))

    def paint(self, p, option, index):
        if self.newStyle():
            self.paint_v2(p, option, index)
        else:
            self.paint_v1(p, option, index)

    def paint_v2(self, p, option, index):
        # QStyledItemDelegate.paint(self, p, option, index)
        if not index.isValid():
            return

        item = index.internalPointer()
        self.updateRects(option, index)
        colors = outlineItemColors(item)

        style = qApp.style()

        def _rotate(angle, rect=self.mainRect):
            p.translate(rect.center())
            p.rotate(angle)
            p.translate(-rect.center())

        def drawRect(r):
            p.save()
            p.setBrush(Qt.gray)
            p.drawRect(r)
            p.restore()

        # Draw background
        cg = QPalette.ColorGroup(QPalette.Normal if option.state
                                 & QStyle.State_Enabled else QPalette.Disabled)
        if cg == QPalette.Normal and not option.state & QStyle.State_Active:
            cg = QPalette.Inactive

            # Selection
        if option.state & QStyle.State_Selected:
            p.save()
            p.setBrush(option.palette.brush(cg, QPalette.Highlight))
            p.setPen(Qt.NoPen)
            #p.drawRoundedRect(option.rect, 12, 12)
            p.drawRect(option.rect)
            p.restore()

            # Background
        p.save()
        if settings.viewSettings["Cork"]["Background"] != "Nothing":
            c = colors[settings.viewSettings["Cork"]["Background"]]
            if c == QColor(Qt.transparent):
                c = QColor(Qt.white)
            col = mixColors(c, QColor(Qt.white), .2)
            backgroundColor = col
            p.setBrush(col)
        else:
            p.setBrush(Qt.white)
            backgroundColor = QColor(Qt.white)

            # Cache background color
        self.bgColors[index] = backgroundColor.name()

        p.setPen(Qt.NoPen)
        p.drawRect(self.cardRect)
        if item.isFolder():
            itemPoly = QPolygonF([
                self.topRect.topLeft(),
                self.topRect.topLeft() + QPoint(self.topRect.width() * .35, 0),
                self.cardRect.topLeft() +
                QPoint(self.topRect.width() * .45, 0),
                self.cardRect.topRight(),
                self.cardRect.bottomRight(),
                self.cardRect.bottomLeft()
            ])
            p.drawPolygon(itemPoly)
        p.restore()

        # Label color
        if settings.viewSettings["Cork"]["Corner"] != "Nothing":
            p.save()
            color = colors[settings.viewSettings["Cork"]["Corner"]]
            p.setPen(Qt.NoPen)
            p.setBrush(color)
            p.drawRect(self.labelRect)
            w = self.labelRect.width()
            poly = QPolygonF([
                self.labelRect.bottomLeft() + QPointF(0, 1),
                self.labelRect.bottomLeft() + QPointF(0, w / 2),
                self.labelRect.bottomLeft() + QPointF(w / 2, 1),
                self.labelRect.bottomRight() + QPointF(1, w / 2),
                self.labelRect.bottomRight() + QPointF(1, 1),
            ])

            p.drawPolygon(poly)
            p.restore()

        if settings.viewSettings["Cork"]["Corner"] == "Nothing" or \
           color == Qt.transparent:
            # No corner, so title can be full width
            self.titleRect.setRight(self.mainRect.right())

        # Draw the icon
        iconRect = self.iconRect
        mode = QIcon.Normal
        if not option.state & style.State_Enabled:
            mode = QIcon.Disabled
        elif option.state & style.State_Selected:
            mode = QIcon.Selected
        # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode)
        icon = index.data(Qt.DecorationRole).pixmap(iconRect.size())
        if settings.viewSettings["Cork"]["Icon"] != "Nothing":
            color = colors[settings.viewSettings["Cork"]["Icon"]]
            colorifyPixmap(icon, color)
        QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode)

        # Draw title
        p.save()
        text = index.data()

        if text:
            p.setPen(Qt.black)
            textColor = QColor(Qt.black)
            if settings.viewSettings["Cork"]["Text"] != "Nothing":
                col = colors[settings.viewSettings["Cork"]["Text"]]
                if col == Qt.transparent:
                    col = Qt.black

                # If title setting is compile, we have to hack the color
                # Or we won't see anything in some themes
                if settings.viewSettings["Cork"]["Text"] == "Compile":
                    if item.compile() in [0, "0"]:
                        col = mixColors(QColor(Qt.black), backgroundColor)
                    else:
                        col = Qt.black
                textColor = col
                p.setPen(col)
            f = QFont(option.font)
            f.setPointSize(f.pointSize() + 4)
            f.setBold(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(text, Qt.ElideRight,
                                       self.titleRect.width())
            p.drawText(self.titleRect, Qt.AlignLeft | Qt.AlignVCenter,
                       elidedText)
        p.restore()

        # One line summary background
        lineSummary = item.data(Outline.summarySentence)
        fullSummary = item.data(Outline.summaryFull)

        # Border
        if settings.viewSettings["Cork"]["Border"] != "Nothing":
            p.save()
            p.setBrush(Qt.NoBrush)
            pen = p.pen()
            pen.setWidth(2)
            col = colors[settings.viewSettings["Cork"]["Border"]]
            pen.setColor(col)
            p.setPen(pen)
            if item.isFolder():
                p.drawPolygon(itemPoly)
            else:
                p.drawRect(self.cardRect)
            p.restore()

        # Draw status
        status = item.data(Outline.status)
        if status:
            it = mainWindow().mdlStatus.item(int(status), 0)
            if it != None:
                p.save()
                p.setClipRegion(QRegion(self.cardRect))
                f = p.font()
                f.setPointSize(f.pointSize() + 12)
                f.setBold(True)
                p.setFont(f)
                p.setPen(QColor(Qt.red).lighter(170))
                _rotate(-35, rect=self.cardRect)
                p.drawText(self.cardRect, Qt.AlignCenter, it.text())
                p.restore()

                # Draw Summary
                # One line
        if lineSummary:
            p.save()
            f = QFont(option.font)
            f.setBold(True)
            p.setFont(f)
            p.setPen(textColor)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(lineSummary, Qt.ElideRight,
                                       self.mainLineRect.width())
            p.drawText(self.mainLineRect, Qt.AlignLeft | Qt.AlignVCenter,
                       elidedText)
            p.restore()

            # Full summary
        if fullSummary:
            p.save()
            p.setFont(option.font)
            p.setPen(textColor)
            p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
            p.restore()

    def paint_v1(self, p, option, index):
        # QStyledItemDelegate.paint(self, p, option, index)
        if not index.isValid():
            return

        item = index.internalPointer()
        self.updateRects(option, index)
        colors = outlineItemColors(item)

        style = qApp.style()

        def _rotate(angle):
            p.translate(self.mainRect.center())
            p.rotate(angle)
            p.translate(-self.mainRect.center())

        # Draw background
        cg = QPalette.ColorGroup(QPalette.Normal if option.state
                                 & QStyle.State_Enabled else QPalette.Disabled)
        if cg == QPalette.Normal and not option.state & QStyle.State_Active:
            cg = QPalette.Inactive

            # Selection
        if option.state & QStyle.State_Selected:
            p.save()
            p.setBrush(option.palette.brush(cg, QPalette.Highlight))
            p.setPen(Qt.NoPen)
            p.drawRoundedRect(option.rect, 12, 12)
            p.restore()

            # Stack
        if item.isFolder() and item.childCount() > 0:
            p.save()
            p.setBrush(Qt.white)
            for i in reversed(range(3)):
                p.drawRoundedRect(
                    self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10,
                    10)

            p.restore()

            # Background
        itemRect = self.itemRect
        p.save()
        if settings.viewSettings["Cork"]["Background"] != "Nothing":
            c = colors[settings.viewSettings["Cork"]["Background"]]
            col = mixColors(c, QColor(Qt.white), .2)
            p.setBrush(col)
        else:
            p.setBrush(Qt.white)
        pen = p.pen()
        pen.setWidth(2)
        p.setPen(pen)
        p.drawRoundedRect(itemRect, 10, 10)
        p.restore()

        # Title bar
        topRect = self.topRect
        p.save()
        if item.isFolder():
            color = QColor(Qt.darkGreen)
        else:
            color = QColor(Qt.blue).lighter(175)
        p.setPen(Qt.NoPen)
        p.setBrush(color)
        p.setClipRegion(QRegion(topRect))
        p.drawRoundedRect(itemRect, 10, 10)
        # p.drawRect(topRect)
        p.restore()

        # Label color
        if settings.viewSettings["Cork"]["Corner"] != "Nothing":
            p.save()
            color = colors[settings.viewSettings["Cork"]["Corner"]]
            p.setPen(Qt.NoPen)
            p.setBrush(color)
            p.setClipRegion(QRegion(self.labelRect))
            p.drawRoundedRect(itemRect, 10, 10)
            # p.drawRect(topRect)
            p.restore()
            if color != Qt.transparent:
                p.drawLine(self.labelRect.topLeft(),
                           self.labelRect.bottomLeft())

            # One line summary background
        lineSummary = item.data(Outline.summarySentence)
        fullSummary = item.data(Outline.summaryFull)
        if lineSummary or not fullSummary:
            m = self.margin
            r = self.mainLineRect.adjusted(-m, -m, m, m / 2)
            p.save()
            p.setPen(Qt.NoPen)
            p.setBrush(QColor("#EEE"))
            p.drawRect(r)
            p.restore()

            # Border
        p.save()
        p.setBrush(Qt.NoBrush)
        pen = p.pen()
        pen.setWidth(2)
        if settings.viewSettings["Cork"]["Border"] != "Nothing":
            col = colors[settings.viewSettings["Cork"]["Border"]]
            if col == Qt.transparent:
                col = Qt.black
            pen.setColor(col)
        p.setPen(pen)
        p.drawRoundedRect(itemRect, 10, 10)
        p.restore()

        # Draw the icon
        iconRect = self.iconRect
        mode = QIcon.Normal
        if not option.state & style.State_Enabled:
            mode = QIcon.Disabled
        elif option.state & style.State_Selected:
            mode = QIcon.Selected
        # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode)
        icon = index.data(Qt.DecorationRole).pixmap(iconRect.size())
        if settings.viewSettings["Cork"]["Icon"] != "Nothing":
            color = colors[settings.viewSettings["Cork"]["Icon"]]
            colorifyPixmap(icon, color)
        QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode)

        # Draw title
        p.save()
        text = index.data()
        titleRect = self.titleRect
        if text:
            if settings.viewSettings["Cork"]["Text"] != "Nothing":
                col = colors[settings.viewSettings["Cork"]["Text"]]
                if col == Qt.transparent:
                    col = Qt.black
                p.setPen(col)
            f = QFont(option.font)
            # f.setPointSize(f.pointSize() + 1)
            f.setBold(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width())
            p.drawText(titleRect, Qt.AlignCenter, elidedText)
        p.restore()

        # Draw the line
        bottomRect = self.bottomRect
        p.save()
        # p.drawLine(itemRect.x(), iconRect.bottom() + margin,
        # itemRect.right(), iconRect.bottom() + margin)
        p.drawLine(bottomRect.topLeft(), bottomRect.topRight())
        p.restore()

        # Lines
        if True:
            p.save()
            p.setPen(QColor("#EEE"))
            fm = QFontMetrics(option.font)
            h = fm.lineSpacing()
            l = self.mainTextRect.topLeft() + QPoint(0, h)
            while self.mainTextRect.contains(l):
                p.drawLine(l, QPoint(self.mainTextRect.right(), l.y()))
                l.setY(l.y() + h)
            p.restore()

        # Draw status
        mainRect = self.mainRect
        status = item.data(Outline.status)
        if status:
            it = mainWindow().mdlStatus.item(int(status), 0)
            if it != None:
                p.save()
                p.setClipRegion(QRegion(mainRect))
                f = p.font()
                f.setPointSize(f.pointSize() + 12)
                f.setBold(True)
                p.setFont(f)
                p.setPen(QColor(Qt.red).lighter(175))
                _rotate(-35)
                p.drawText(mainRect, Qt.AlignCenter, it.text())
                p.restore()

                # Draw Summary
                # One line
        if lineSummary:
            p.save()
            f = QFont(option.font)
            f.setItalic(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(lineSummary, Qt.ElideRight,
                                       self.mainLineRect.width())
            p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText)
            p.restore()

            # Full summary
        if fullSummary:
            p.setFont(option.font)
            p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
示例#31
0
class PFSTags(QWidget):
    removed = pyqtSignal(object)

    def __init__(self, name, use=""):
        QWidget.__init__(self)
        self._name = name
        self._use = use
        self._font = QFont("Serif", 8)
        self._rect = QRect(0, 0, 10, 10)
        self._brush = QBrush(Qt.white, Qt.SolidPattern)

    def clone(self):
        ans = PFSTags(self._name, self._use)
        ans.removed.connect(self.removed.emit)
        return ans

    def simpleUse(self):
        if len(self._use) > 16:
            return self._use[:8] + "\n" + self._use[8:13] + "..."
        if len(self._use) > 8:
            return self._use[:5] + "..."
        return self._use

    def simpleName(self):
        if len(self._name) > 30:
            return self._name[:10] + "\n" + self._name[
                10:20] + "\n" + self._name[20:27] + "..."
        if len(self._name) > 20:
            return self._name[:10] + "\n" + self._name[10:17] + "..."
        if len(self._name) > 10:
            return self._name[:7] + "..."
        return self._name

    def updateRect(self):
        fm = QFontMetrics(self._font)
        self._useRect = fm.size(Qt.TextExpandTabs, self.simpleUse())
        self._nameRect = fm.size(Qt.TextExpandTabs, self.simpleName())
        self._rect = QRect(
            0, 0,
            self._useRect.width() + self._nameRect.width() + 23,
            max(self._useRect.height(), self._nameRect.height()) + 4)
        x = self._useRect.width() + self._nameRect.width() + 12
        y = self._rect.center().y() - 3
        self._closeRect = QRect(x, y, 6, 6)

    def paintEvent(self, ev):
        self.updateRect()
        p = QPainter(self)
        p.setBrush(self._brush)
        p.drawRoundedRect(self._rect, 10, 10)
        p.drawLine(self._useRect.width() + 6, self._rect.top(),
                   self._useRect.width() + 6, self._rect.bottom())
        p.setFont(self._font)
        p.drawText(3, 0, self._useRect.width(), self._rect.height(),
                   Qt.AlignCenter, self.simpleUse())
        p.drawText(self._useRect.width() + 9, 0, self._nameRect.width(),
                   self._rect.height(), Qt.AlignCenter, self.simpleName())
        p.drawLine(self._closeRect.topLeft(), self._closeRect.bottomRight())
        p.drawLine(self._closeRect.bottomLeft(), self._closeRect.topRight())

    def mousePressEvent(self, ev: QMouseEvent):
        if self._closeRect.contains(ev.pos()):
            self.removed.emit(self)

    def __eq__(self, other):
        if not isinstance(other, PFSTags):
            return False
        return self._name == other._name and self._use == other._use
示例#32
0
 def paintEvent(self, evt):
     """
     Protected method handling paint events.
     
     @param evt paint event (QPaintEvent)
     """
     if self.__grabbing:     # grabWindow() should just get the background
         return
     
     painter = QPainter(self)
     pal = QPalette(QToolTip.palette())
     font = QToolTip.font()
     
     handleColor = pal.color(QPalette.Active, QPalette.Highlight)
     handleColor.setAlpha(160)
     overlayColor = QColor(0, 0, 0, 160)
     textColor = pal.color(QPalette.Active, QPalette.Text)
     textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
     painter.drawPixmap(0, 0, self.__pixmap)
     painter.setFont(font)
     
     r = QRect(self.__selection)
     if not self.__selection.isNull():
         grey = QRegion(self.rect())
         if self.__mode == SnapshotRegionGrabber.Ellipse:
             reg = QRegion(r, QRegion.Ellipse)
         else:
             reg = QRegion(r)
         grey = grey.subtracted(reg)
         painter.setClipRegion(grey)
         painter.setPen(Qt.NoPen)
         painter.setBrush(overlayColor)
         painter.drawRect(self.rect())
         painter.setClipRect(self.rect())
         drawRect(painter, r, handleColor)
     
     if self.__showHelp:
         painter.setPen(textColor)
         painter.setBrush(textBackgroundColor)
         self.__helpTextRect = painter.boundingRect(
             self.rect().adjusted(2, 2, -2, -2),
             Qt.TextWordWrap, self.__helpText).translated(
             -self.__desktop.x(), -self.__desktop.y())
         self.__helpTextRect.adjust(-2, -2, 4, 2)
         drawRect(painter, self.__helpTextRect, textColor,
                  textBackgroundColor)
         painter.drawText(
             self.__helpTextRect.adjusted(3, 3, -3, -3),
             Qt.TextWordWrap, self.__helpText)
     
     if self.__selection.isNull():
         return
     
     # The grabbed region is everything which is covered by the drawn
     # rectangles (border included). This means that there is no 0px
     # selection, since a 0px wide rectangle will always be drawn as a line.
     txt = "{0:n}, {1:n} ({2:n} x {3:n})".format(
         self.__selection.x(), self.__selection.y(),
         self.__selection.width(), self.__selection.height())
     textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
     boundingRect = textRect.adjusted(-4, 0, 0, 0)
     
     if textRect.width() < r.width() - 2 * self.__handleSize and \
        textRect.height() < r.height() - 2 * self.__handleSize and \
        r.width() > 100 and \
        r.height() > 100:
         # center, unsuitable for small selections
         boundingRect.moveCenter(r.center())
         textRect.moveCenter(r.center())
     elif r.y() - 3 > textRect.height() and \
             r.x() + textRect.width() < self.rect().width():
         # on top, left aligned
         boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
         textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
     elif r.x() - 3 > textRect.width():
         # left, top aligned
         boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
         textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
     elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
             r.right() > textRect.width():
         # at bottom, right aligned
         boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
         textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
     elif r.right() + textRect.width() + 3 < self.rect().width():
         # right, bottom aligned
         boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
         textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))
     
     # If the above didn't catch it, you are running on a very
     # tiny screen...
     drawRect(painter, boundingRect, textColor, textBackgroundColor)
     painter.drawText(textRect, Qt.AlignHCenter, txt)
     
     if (r.height() > self.__handleSize * 2 and
         r.width() > self.__handleSize * 2) or \
        not self.__mouseDown:
         self.__updateHandles()
         painter.setPen(Qt.NoPen)
         painter.setBrush(handleColor)
         painter.setClipRegion(
             self.__handleMask(SnapshotRegionGrabber.StrokeMask))
         painter.drawRect(self.rect())
         handleColor.setAlpha(60)
         painter.setBrush(handleColor)
         painter.setClipRegion(
             self.__handleMask(SnapshotRegionGrabber.FillMask))
         painter.drawRect(self.rect())
示例#33
0
    def draw_tracker_pixmap(self, cursor_pos):
        tracker_pixmap = QPixmap(self.parent.size())
        tracker_pixmap.fill(QColor(255, 255, 255, 0))
        qpainter = QPainter()
        qpainter.begin(tracker_pixmap)

        origin = self.calc_gui_point([0, 0])
        axis_origin = [
            max(min(origin[0],
                    self.parent.width() - self.axis_margin[0]),
                self.axis_margin[0]),
            max(min(origin[1],
                    self.parent.height() - self.axis_margin[1]),
                self.axis_margin[1])
        ]

        qpainter.setPen(self.axis_pen)
        pnt = self.calc_val_point([cursor_pos.x(), cursor_pos.y()])
        x_label = str(round(pnt[0], 2))
        y_label = str(round(pnt[1], 2))
        str_rect = QRect(cursor_pos.x() + 5, axis_origin[1],
                         qpainter.fontMetrics().width(x_label), 25)

        g_rect = QRect(str_rect.x() - 30, str_rect.y(), 30, str_rect.height())
        gradient = QLinearGradient(QPoint(g_rect.right(),
                                          g_rect.center().y()),
                                   QPoint(g_rect.left(),
                                          g_rect.center().y()))
        gradient.setColorAt(0, QColor(255, 255, 255))
        gradient.setColorAt(1, QColor(255, 255, 255, 0))
        qpainter.fillRect(g_rect, gradient)

        g_rect = QRect(str_rect.right(), str_rect.y(), 30, str_rect.height())
        gradient = QLinearGradient(QPoint(g_rect.left(),
                                          g_rect.center().y()),
                                   QPoint(g_rect.right(),
                                          g_rect.center().y()))
        gradient.setColorAt(0, QColor(255, 255, 255))
        gradient.setColorAt(1, QColor(255, 255, 255, 0))
        qpainter.fillRect(g_rect, gradient)

        qpainter.fillRect(str_rect, QColor(255, 255, 255))
        qpainter.drawText(str_rect, Qt.AlignLeft | Qt.AlignCenter, x_label)
        qpainter.drawLine(cursor_pos.x(), axis_origin[1], cursor_pos.x(),
                          axis_origin[1] + 10)

        label_width = qpainter.fontMetrics().width(y_label)
        str_rect = QRect(axis_origin[0] - label_width - 1,
                         cursor_pos.y() + 1, label_width, 15)

        g_rect = QRect(str_rect.x(), str_rect.y() - 10, str_rect.width(), 10)
        gradient = QLinearGradient(
            QPoint(g_rect.center().x(), g_rect.bottom()),
            QPoint(g_rect.center().x(), g_rect.top()))
        gradient.setColorAt(0, QColor(255, 255, 255))
        gradient.setColorAt(1, QColor(255, 255, 255, 0))
        qpainter.fillRect(g_rect, gradient)

        g_rect = QRect(str_rect.x(), str_rect.bottom(), str_rect.width(), 10)
        gradient = QLinearGradient(
            QPoint(g_rect.center().x(), g_rect.top()),
            QPoint(g_rect.center().x(), g_rect.bottom()))
        gradient.setColorAt(0, QColor(255, 255, 255))
        gradient.setColorAt(1, QColor(255, 255, 255, 0))
        qpainter.fillRect(g_rect, gradient)

        qpainter.fillRect(str_rect, QColor(255, 255, 255))
        qpainter.drawText(str_rect, Qt.AlignRight | Qt.AlignCenter, y_label)
        qpainter.drawLine(axis_origin[0], cursor_pos.y(), axis_origin[0] - 10,
                          cursor_pos.y())

        qpainter.end()
        return tracker_pixmap
示例#34
0
    def __paintEventNoStyle(self):
        p = QPainter(self)
        opt = QStyleOptionToolButton()
        self.initStyleOption(opt)

        fm = QFontMetrics(opt.font)
        palette = opt.palette

        # highlight brush is used as the background for the icon and background
        # when the tab is expanded and as mouse hover color (lighter).
        brush_highlight = palette.highlight()
        foregroundrole = QPalette.ButtonText
        if opt.state & QStyle.State_Sunken:
            # State 'down' pressed during a mouse press (slightly darker).
            background_brush = brush_darker(brush_highlight, 110)
            foregroundrole = QPalette.HighlightedText
        elif opt.state & QStyle.State_MouseOver:
            background_brush = brush_darker(brush_highlight, 95)
            foregroundrole = QPalette.HighlightedText
        elif opt.state & QStyle.State_On:
            background_brush = brush_highlight
            foregroundrole = QPalette.HighlightedText
        else:
            # The default button brush.
            background_brush = palette.button()

        rect = opt.rect

        icon_area_rect = QRect(rect)
        icon_area_rect.setRight(int(icon_area_rect.height() * 1.26))

        text_rect = QRect(rect)
        text_rect.setLeft(icon_area_rect.right() + 10)

        # Background  (TODO: Should the tab button have native
        # toolbutton shape, drawn using PE_PanelButtonTool or even
        # QToolBox tab shape)

        # Default outline pen
        pen = QPen(palette.color(QPalette.Mid))

        p.save()
        p.setPen(Qt.NoPen)
        p.setBrush(QBrush(background_brush))
        p.drawRect(rect)

        # Draw the background behind the icon if the background_brush
        # is different.
        if not opt.state & QStyle.State_On:
            p.setBrush(brush_highlight)
            p.drawRect(icon_area_rect)
            # Line between the icon and text
            p.setPen(pen)
            p.drawLine(icon_area_rect.topRight(), icon_area_rect.bottomRight())

        if opt.state & QStyle.State_HasFocus:
            # Set the focus frame pen and draw the border
            pen = QPen(QColor(FOCUS_OUTLINE_COLOR))
            p.setPen(pen)
            p.setBrush(Qt.NoBrush)
            # Adjust for pen
            rect = rect.adjusted(0, 0, -1, -1)
            p.drawRect(rect)

        else:
            p.setPen(pen)
            # Draw the top/bottom border
            if self.position == QStyleOptionToolBox.OnlyOneTab or \
                    self.position == QStyleOptionToolBox.Beginning or \
                    self.selected & \
                        QStyleOptionToolBox.PreviousIsSelected:

                p.drawLine(rect.topLeft(), rect.topRight())

            p.drawLine(rect.bottomLeft(), rect.bottomRight())

        p.restore()

        p.save()
        text = fm.elidedText(opt.text, Qt.ElideRight, text_rect.width())
        p.setPen(QPen(palette.color(foregroundrole)))
        p.setFont(opt.font)

        p.drawText(text_rect,
                   int(Qt.AlignVCenter | Qt.AlignLeft) | \
                   int(Qt.TextSingleLine),
                   text)

        if not opt.icon.isNull():
            if opt.state & QStyle.State_Enabled:
                mode = QIcon.Normal
            else:
                mode = QIcon.Disabled
            if opt.state & QStyle.State_On:
                state = QIcon.On
            else:
                state = QIcon.Off
            icon_area_rect = icon_area_rect
            icon_rect = QRect(QPoint(0, 0), opt.iconSize)
            icon_rect.moveCenter(icon_area_rect.center())
            opt.icon.paint(p, icon_rect, Qt.AlignCenter, mode, state)
        p.restore()
示例#35
0
class corkDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        QStyledItemDelegate.__init__(self, parent)
        self.factor = settings.corkSizeFactor / 100.
        self.lastPos = None
        self.editing = None
        self.margin = 5

        self.bgColors = {}

    def newStyle(self):
        return settings.corkStyle == "new"

    def setCorkSizeFactor(self, v):
        self.factor = v / 100.

    def sizeHint(self, option, index):
        if self.newStyle():
            defaultSize = QSize(300, 210)
        else:
            defaultSize = QSize(300, 200)
        return defaultSize * self.factor

    def editorEvent(self, event, model, option, index):
        # We catch the mouse position in the widget to know which part to edit
        if type(event) == QMouseEvent:
            self.lastPos = event.pos()  # - option.rect.topLeft()
        return QStyledItemDelegate.editorEvent(self, event, model, option, index)

    def createEditor(self, parent, option, index):
        self.updateRects(option, index)

        bgColor = self.bgColors.get(index, "white")

        if self.mainLineRect.contains(self.lastPos):
            # One line summary
            self.editing = Outline.summarySentence
            edt = QLineEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrame(False)
            f = QFont(option.font)
            if self.newStyle():
                f.setBold(True)
            else:
                f.setItalic(True)
                edt.setAlignment(Qt.AlignCenter)
            edt.setPlaceholderText(self.tr("One line summary"))
            edt.setFont(f)
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            return edt

        elif self.titleRect.contains(self.lastPos):
            # Title
            self.editing = Outline.title
            edt = QLineEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrame(False)
            f = QFont(option.font)
            if self.newStyle():
                f.setPointSize(f.pointSize() + 4)
            else:
                edt.setAlignment(Qt.AlignCenter)
            f.setBold(True)
            edt.setFont(f)
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            # edt.setGeometry(self.titleRect)
            return edt

        else:  # self.mainTextRect.contains(self.lastPos):
            # Summary
            self.editing = Outline.summaryFull
            edt = QPlainTextEdit(parent)
            edt.setFocusPolicy(Qt.StrongFocus)
            edt.setFrameShape(QFrame.NoFrame)
            try:
                # QPlainTextEdit.setPlaceholderText was introduced in Qt 5.3
                edt.setPlaceholderText(self.tr("Full summary"))
            except AttributeError:
                pass
            edt.setStyleSheet("background: {}; color: black;".format(bgColor))
            return edt

    def updateEditorGeometry(self, editor, option, index):

        if self.editing == Outline.summarySentence:
            # One line summary
            editor.setGeometry(self.mainLineRect)

        elif self.editing == Outline.title:
            # Title
            editor.setGeometry(self.titleRect)

        elif self.editing == Outline.summaryFull:
            # Summary
            editor.setGeometry(self.mainTextRect)

    def setEditorData(self, editor, index):
        item = index.internalPointer()

        if self.editing == Outline.summarySentence:
            # One line summary
            editor.setText(item.data(Outline.summarySentence))

        elif self.editing == Outline.title:
            # Title
            editor.setText(index.data())

        elif self.editing == Outline.summaryFull:
            # Summary
            editor.setPlainText(item.data(Outline.summaryFull))

    def setModelData(self, editor, model, index):

        if self.editing == Outline.summarySentence:
            # One line summary
            model.setData(index.sibling(index.row(), Outline.summarySentence), editor.text())

        elif self.editing == Outline.title:
            # Title
            model.setData(index, editor.text(), Outline.title)

        elif self.editing == Outline.summaryFull:
            # Summary
            model.setData(index.sibling(index.row(), Outline.summaryFull), editor.toPlainText())

    def updateRects(self, option, index):
        if self.newStyle():
            self.updateRects_v2(option, index)
        else:
            self.updateRects_v1(option, index)

    def updateRects_v2(self, option, index):
        margin = self.margin * 2
        iconSize = max(24 * self.factor, 18)
        item = index.internalPointer()
        fm = QFontMetrics(option.font)
        h = fm.lineSpacing()

        self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin)

        top = 15 * self.factor
        self.topRect = QRect(self.itemRect)
        self.topRect.setHeight(top)

        self.cardRect = QRect(self.itemRect.topLeft() + QPoint(0, top),
                         self.itemRect.bottomRight())
        self.iconRect = QRect(self.cardRect.topLeft() + QPoint(margin, margin),
                              QSize(iconSize, iconSize))
        self.labelRect = QRect(self.cardRect.topRight() - QPoint(margin + self.factor * 18, 1),
                               self.cardRect.topRight() + QPoint(- margin - self.factor * 4, self.factor * 24))
        self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0),
                               self.labelRect.bottomLeft() - QPoint(margin, margin))
        self.titleRect.setBottom(self.iconRect.bottom())
        self.mainRect = QRect(self.iconRect.bottomLeft() + QPoint(0, margin),
                              self.cardRect.bottomRight() - QPoint(margin, 2*margin))
        self.mainRect.setLeft(self.titleRect.left())
        self.mainLineRect = QRect(self.mainRect.topLeft(),
                                  self.mainRect.topRight() + QPoint(0, h))
        self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin),
                                  self.mainRect.bottomRight())
        if not item.data(Outline.summarySentence):
            self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())

    def updateRects_v1(self, option, index):
        margin = self.margin
        iconSize = max(16 * self.factor, 12)
        item = index.internalPointer()
        self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin)
        self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize))
        self.labelRect = QRect(self.itemRect.topRight() - QPoint(iconSize + margin, 0),
                               self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin))
        self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0),
                               self.labelRect.bottomLeft() - QPoint(margin, margin))
        self.bottomRect = QRect(QPoint(self.itemRect.x(), self.iconRect.bottom() + margin),
                                QPoint(self.itemRect.right(), self.itemRect.bottom()))
        self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight())
        self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin)
        self.mainLineRect = QRect(self.mainRect.topLeft(),
                                  self.mainRect.topRight() + QPoint(0, iconSize))
        self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin),
                                  self.mainRect.bottomRight())
        if not item.data(Outline.summarySentence):
            self.mainTextRect.setTopLeft(self.mainLineRect.topLeft())
        if item.data(Outline.label) in ["", "0", 0]:
            self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin))

    def paint(self, p, option, index):
        if self.newStyle():
            self.paint_v2(p, option, index)
        else:
            self.paint_v1(p, option, index)

    def paint_v2(self, p, option, index):
        # QStyledItemDelegate.paint(self, p, option, index)
        if not index.isValid():
            return

        item = index.internalPointer()
        self.updateRects(option, index)
        colors = outlineItemColors(item)

        style = qApp.style()

        def _rotate(angle, rect=self.mainRect):
            p.translate(rect.center())
            p.rotate(angle)
            p.translate(-rect.center())

        def drawRect(r):
            p.save()
            p.setBrush(Qt.gray)
            p.drawRect(r)
            p.restore()

        # Draw background
        cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled)
        if cg == QPalette.Normal and not option.state & QStyle.State_Active:
            cg = QPalette.Inactive

            # Selection
        if option.state & QStyle.State_Selected:
            p.save()
            p.setBrush(option.palette.brush(cg, QPalette.Highlight))
            p.setPen(Qt.NoPen)
            #p.drawRoundedRect(option.rect, 12, 12)
            p.drawRect(option.rect)
            p.restore()

            # Background
        p.save()
        if settings.viewSettings["Cork"]["Background"] != "Nothing":
            c = colors[settings.viewSettings["Cork"]["Background"]]
            if c == QColor(Qt.transparent):
                c = QColor(Qt.white)
            col = mixColors(c, QColor(Qt.white), .2)
            backgroundColor = col
            p.setBrush(col)
        else:
            p.setBrush(Qt.white)
            backgroundColor = QColor(Qt.white)

            # Cache background color
        self.bgColors[index] = backgroundColor.name()

        p.setPen(Qt.NoPen)
        p.drawRect(self.cardRect)
        if item.isFolder():
            itemPoly = QPolygonF([
                self.topRect.topLeft(),
                self.topRect.topLeft() + QPoint(self.topRect.width() * .35, 0),
                self.cardRect.topLeft() + QPoint(self.topRect.width() * .45, 0),
                self.cardRect.topRight(),
                self.cardRect.bottomRight(),
                self.cardRect.bottomLeft()
            ])
            p.drawPolygon(itemPoly)
        p.restore()

        # Label color
        if settings.viewSettings["Cork"]["Corner"] != "Nothing":
            p.save()
            color = colors[settings.viewSettings["Cork"]["Corner"]]
            p.setPen(Qt.NoPen)
            p.setBrush(color)
            p.drawRect(self.labelRect)
            w = self.labelRect.width()
            poly = QPolygonF([
                self.labelRect.bottomLeft() + QPointF(0, 1),
                self.labelRect.bottomLeft() + QPointF(0, w / 2),
                self.labelRect.bottomLeft() + QPointF(w / 2, 1),
                self.labelRect.bottomRight() + QPointF(1, w / 2),
                self.labelRect.bottomRight() + QPointF(1, 1),
            ])

            p.drawPolygon(poly)
            p.restore()

        if settings.viewSettings["Cork"]["Corner"] == "Nothing" or \
           color == Qt.transparent:
            # No corner, so title can be full width
            self.titleRect.setRight(self.mainRect.right())

        # Draw the icon
        iconRect = self.iconRect
        mode = QIcon.Normal
        if not option.state & style.State_Enabled:
            mode = QIcon.Disabled
        elif option.state & style.State_Selected:
            mode = QIcon.Selected
        # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode)
        icon = index.data(Qt.DecorationRole).pixmap(iconRect.size())
        if settings.viewSettings["Cork"]["Icon"] != "Nothing":
            color = colors[settings.viewSettings["Cork"]["Icon"]]
            colorifyPixmap(icon, color)
        QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode)

        # Draw title
        p.save()
        text = index.data()

        if text:
            p.setPen(Qt.black)
            textColor = QColor(Qt.black)
            if settings.viewSettings["Cork"]["Text"] != "Nothing":
                col = colors[settings.viewSettings["Cork"]["Text"]]
                if col == Qt.transparent:
                    col = Qt.black

                # If title setting is compile, we have to hack the color
                # Or we won't see anything in some themes
                if settings.viewSettings["Cork"]["Text"] == "Compile":
                    if item.compile() in [0, "0"]:
                        col = mixColors(QColor(Qt.black), backgroundColor)
                    else:
                        col = Qt.black
                textColor = col
                p.setPen(col)
            f = QFont(option.font)
            f.setPointSize(f.pointSize() + 4)
            f.setBold(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(text, Qt.ElideRight, self.titleRect.width())
            p.drawText(self.titleRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText)
        p.restore()

            # One line summary background
        lineSummary = item.data(Outline.summarySentence)
        fullSummary = item.data(Outline.summaryFull)

            # Border
        if settings.viewSettings["Cork"]["Border"] != "Nothing":
            p.save()
            p.setBrush(Qt.NoBrush)
            pen = p.pen()
            pen.setWidth(2)
            col = colors[settings.viewSettings["Cork"]["Border"]]
            pen.setColor(col)
            p.setPen(pen)
            if item.isFolder():
                p.drawPolygon(itemPoly)
            else:
                p.drawRect(self.cardRect)
            p.restore()

        # Draw status
        status = item.data(Outline.status)
        if status:
            it = mainWindow().mdlStatus.item(int(status), 0)
            if it != None:
                p.save()
                p.setClipRegion(QRegion(self.cardRect))
                f = p.font()
                f.setPointSize(f.pointSize() + 12)
                f.setBold(True)
                p.setFont(f)
                p.setPen(QColor(Qt.red).lighter(170))
                _rotate(-35, rect=self.cardRect)
                p.drawText(self.cardRect, Qt.AlignCenter, it.text())
                p.restore()

                # Draw Summary
                # One line
        if lineSummary:
            p.save()
            f = QFont(option.font)
            f.setBold(True)
            p.setFont(f)
            p.setPen(textColor)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width())
            p.drawText(self.mainLineRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText)
            p.restore()

            # Full summary
        if fullSummary:
            p.save()
            p.setFont(option.font)
            p.setPen(textColor)
            p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
            p.restore()

    def paint_v1(self, p, option, index):
        # QStyledItemDelegate.paint(self, p, option, index)
        if not index.isValid():
            return

        item = index.internalPointer()
        self.updateRects(option, index)
        colors = outlineItemColors(item)

        style = qApp.style()

        def _rotate(angle):
            p.translate(self.mainRect.center())
            p.rotate(angle)
            p.translate(-self.mainRect.center())

        # Draw background
        cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled)
        if cg == QPalette.Normal and not option.state & QStyle.State_Active:
            cg = QPalette.Inactive

            # Selection
        if option.state & QStyle.State_Selected:
            p.save()
            p.setBrush(option.palette.brush(cg, QPalette.Highlight))
            p.setPen(Qt.NoPen)
            p.drawRoundedRect(option.rect, 12, 12)
            p.restore()

            # Stack
        if item.isFolder() and item.childCount() > 0:
            p.save()
            p.setBrush(Qt.white)
            for i in reversed(range(3)):
                p.drawRoundedRect(self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10, 10)

            p.restore()

            # Background
        itemRect = self.itemRect
        p.save()
        if settings.viewSettings["Cork"]["Background"] != "Nothing":
            c = colors[settings.viewSettings["Cork"]["Background"]]
            col = mixColors(c, QColor(Qt.white), .2)
            p.setBrush(col)
        else:
            p.setBrush(Qt.white)
        pen = p.pen()
        pen.setWidth(2)
        p.setPen(pen)
        p.drawRoundedRect(itemRect, 10, 10)
        p.restore()

        # Title bar
        topRect = self.topRect
        p.save()
        if item.isFolder():
            color = QColor(Qt.darkGreen)
        else:
            color = QColor(Qt.blue).lighter(175)
        p.setPen(Qt.NoPen)
        p.setBrush(color)
        p.setClipRegion(QRegion(topRect))
        p.drawRoundedRect(itemRect, 10, 10)
        # p.drawRect(topRect)
        p.restore()

        # Label color
        if settings.viewSettings["Cork"]["Corner"] != "Nothing":
            p.save()
            color = colors[settings.viewSettings["Cork"]["Corner"]]
            p.setPen(Qt.NoPen)
            p.setBrush(color)
            p.setClipRegion(QRegion(self.labelRect))
            p.drawRoundedRect(itemRect, 10, 10)
            # p.drawRect(topRect)
            p.restore()
            if color != Qt.transparent:
                p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft())

            # One line summary background
        lineSummary = item.data(Outline.summarySentence)
        fullSummary = item.data(Outline.summaryFull)
        if lineSummary or not fullSummary:
            m = self.margin
            r = self.mainLineRect.adjusted(-m, -m, m, m / 2)
            p.save()
            p.setPen(Qt.NoPen)
            p.setBrush(QColor("#EEE"))
            p.drawRect(r)
            p.restore()

            # Border
        p.save()
        p.setBrush(Qt.NoBrush)
        pen = p.pen()
        pen.setWidth(2)
        if settings.viewSettings["Cork"]["Border"] != "Nothing":
            col = colors[settings.viewSettings["Cork"]["Border"]]
            if col == Qt.transparent:
                col = Qt.black
            pen.setColor(col)
        p.setPen(pen)
        p.drawRoundedRect(itemRect, 10, 10)
        p.restore()

        # Draw the icon
        iconRect = self.iconRect
        mode = QIcon.Normal
        if not option.state & style.State_Enabled:
            mode = QIcon.Disabled
        elif option.state & style.State_Selected:
            mode = QIcon.Selected
        # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode)
        icon = index.data(Qt.DecorationRole).pixmap(iconRect.size())
        if settings.viewSettings["Cork"]["Icon"] != "Nothing":
            color = colors[settings.viewSettings["Cork"]["Icon"]]
            colorifyPixmap(icon, color)
        QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode)

        # Draw title
        p.save()
        text = index.data()
        titleRect = self.titleRect
        if text:
            if settings.viewSettings["Cork"]["Text"] != "Nothing":
                col = colors[settings.viewSettings["Cork"]["Text"]]
                if col == Qt.transparent:
                    col = Qt.black
                p.setPen(col)
            f = QFont(option.font)
            # f.setPointSize(f.pointSize() + 1)
            f.setBold(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width())
            p.drawText(titleRect, Qt.AlignCenter, elidedText)
        p.restore()

        # Draw the line
        bottomRect = self.bottomRect
        p.save()
        # p.drawLine(itemRect.x(), iconRect.bottom() + margin,
        # itemRect.right(), iconRect.bottom() + margin)
        p.drawLine(bottomRect.topLeft(), bottomRect.topRight())
        p.restore()

        # Lines
        if True:
            p.save()
            p.setPen(QColor("#EEE"))
            fm = QFontMetrics(option.font)
            h = fm.lineSpacing()
            l = self.mainTextRect.topLeft() + QPoint(0, h)
            while self.mainTextRect.contains(l):
                p.drawLine(l, QPoint(self.mainTextRect.right(), l.y()))
                l.setY(l.y() + h)
            p.restore()

        # Draw status
        mainRect = self.mainRect
        status = item.data(Outline.status)
        if status:
            it = mainWindow().mdlStatus.item(int(status), 0)
            if it != None:
                p.save()
                p.setClipRegion(QRegion(mainRect))
                f = p.font()
                f.setPointSize(f.pointSize() + 12)
                f.setBold(True)
                p.setFont(f)
                p.setPen(QColor(Qt.red).lighter(175))
                _rotate(-35)
                p.drawText(mainRect, Qt.AlignCenter, it.text())
                p.restore()

                # Draw Summary
                # One line
        if lineSummary:
            p.save()
            f = QFont(option.font)
            f.setItalic(True)
            p.setFont(f)
            fm = QFontMetrics(f)
            elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width())
            p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText)
            p.restore()

            # Full summary
        if fullSummary:
            p.setFont(option.font)
            p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)