Esempio n. 1
0
    def paint(self, painter, option, index):
        optionV4 = QStyleOptionViewItemV4(option)
        self.initStyleOption(optionV4, index)

        style = optionV4.widget.style() if optionV4.widget else QApplication.style()

        doc = QTextDocument()
        doc.setHtml(optionV4.text)

        # painting item without text
        optionV4.text = QString()
        style.drawControl(QStyle.CE_ItemViewItem, optionV4, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        # Hilight text if item is selected
        if optionV4.state & QStyle.State_Selected:
            ctx.palette.setColor(QPalette.Text, optionV4.palette.color(QPalette.Active, QPalette.HighlightedText))

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, optionV4)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Esempio n. 2
0
    def paint(self, painter, option, index):
        optionV4 = QStyleOptionViewItemV4(option)
        self.initStyleOption(optionV4, index)

        style = optionV4.widget.style() if optionV4.widget else QApplication.style()

        doc = QTextDocument()
        doc.setHtml(optionV4.text)

        # painting item without text
        optionV4.text = QString()
        style.drawControl(QStyle.CE_ItemViewItem, optionV4, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        # Hilight text if item is selected
        if optionV4.state & QStyle.State_Selected:
            ctx.palette.setColor(QPalette.Text, optionV4.palette.color(QPalette.Active, QPalette.HighlightedText))

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, optionV4)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Esempio n. 3
0
    def paint(self, painter, option, index):
        """QStyledItemDelegate.paint implementation
        """
        option.state &= ~QStyle.State_HasFocus  # never draw focus rect

        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        style = QApplication.style(
        ) if options.widget is None else options.widget.style()

        doc = QTextDocument()
        doc.setDocumentMargin(1)
        doc.setHtml(options.text)
        #  bad long (multiline) strings processing doc.setTextWidth(options.rect.width())

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        # Highlighting text if item is selected
        if option.state & QStyle.State_Selected:
            ctx.palette.setColor(
                QPalette.Text,
                option.palette.color(QPalette.Active,
                                     QPalette.HighlightedText))

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)

        painter.restore()
Esempio n. 4
0
    def paint(self, painter, option, index):
        """Render the delegate for the item."""
        if index.column() != self._html_column:
            return QStyledItemDelegate.paint(self, painter, option, index)

        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        if options.widget is None:
            style = QApplication.style()
        else:
            style = options.widget.style()

        doc = QTextDocument()
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Esempio n. 5
0
    def paint(self, painter, option, index):
        """QStyledItemDelegate.paint implementation
        """
        option.state &= ~QStyle.State_HasFocus  # never draw focus rect

        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        style = QApplication.style() if options.widget is None else options.widget.style()

        doc = QTextDocument()
        doc.setDocumentMargin(1)
        doc.setHtml(options.text)
        #  bad long (multiline) strings processing doc.setTextWidth(options.rect.width())

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        # Highlighting text if item is selected
        if option.state & QStyle.State_Selected:
            ctx.palette.setColor(QPalette.Text, option.palette.color(QPalette.Active, QPalette.HighlightedText))

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)

        painter.restore()
Esempio n. 6
0
    def paint(self, painter, option, index):
        """Render the delegate for the item."""
        if index.column() != self._html_column:
            return QStyledItemDelegate.paint(self, painter, option, index)

        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        if options.widget is None:
            style = QApplication.style()
        else:
            style = options.widget.style()

        doc = QTextDocument()
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Esempio n. 7
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        style = QApplication.style(
        ) if options.widget is None else options.widget.style()

        doc = QTextDocument()
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()
        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)

        # Highlighting text if item is selected
        if options.state & QStyle.State_Selected:
            # ctx.palette.setColor(
            # 	QPalette.Text, options.palette.color(QPalette.Active, QPalette.HighlightedText)
            # )
            # painter.setBrush( options.palette.color( QPalette.Active, QPalette.Highlight ) )
            # painter.setBrush( QColor( '#c1f48b' ) )
            painter.setBrush(QColor(0, 180, 0, 30))
            painter.setPen(Qt.NoPen)
            painter.drawRect(textRect)

        elif options.state & QStyle.State_MouseOver:
            # painter.setBrush( QColor( '#faffb8' ) )
            # painter.setPen( Qt.NoPen )
            # painter.drawRect( textRect )
            painter.setBrush(QColor(0, 255, 0, 10))
            painter.setPen(Qt.NoPen)
            painter.drawRect(textRect)

        else:
            painter.setPen(QColor(0, 0, 0, 10))
            painter.drawLine(textRect.bottomLeft(), textRect.bottomRight())

        painter.save()
        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)

        painter.restore()
Esempio n. 8
0
	def paint(self, painter, option, index):
		options = QStyleOptionViewItemV4(option)
		self.initStyleOption(options,index)

		style = QApplication.style() if options.widget is None else options.widget.style()

		doc = QTextDocument()
		doc.setHtml(options.text)

		options.text = ""
		style.drawControl( QStyle.CE_ItemViewItem, options, painter)

		ctx = QAbstractTextDocumentLayout.PaintContext()
		textRect = style.subElementRect( QStyle.SE_ItemViewItemText, options )

		# Highlighting text if item is selected
		if options.state & QStyle.State_Selected :
			# ctx.palette.setColor(
			# 	QPalette.Text, options.palette.color(QPalette.Active, QPalette.HighlightedText)
			# )
			# painter.setBrush( options.palette.color( QPalette.Active, QPalette.Highlight ) )
			# painter.setBrush( QColor( '#c1f48b' ) )
			painter.setBrush( QColor( 0,180,0,30 ) )
			painter.setPen( Qt.NoPen )
			painter.drawRect( textRect )
			

		elif options.state & QStyle.State_MouseOver :
			# painter.setBrush( QColor( '#faffb8' ) )
			# painter.setPen( Qt.NoPen )
			# painter.drawRect( textRect )
			painter.setBrush( QColor( 0,255,0,10 ) )
			painter.setPen( Qt.NoPen )
			painter.drawRect( textRect )

		else:
			painter.setPen( QColor( 0,0,0,10 ) )
			painter.drawLine( textRect.bottomLeft(), textRect.bottomRight() )

		painter.save()
		painter.translate(textRect.topLeft())
		painter.setClipRect(textRect.translated(-textRect.topLeft()))
		doc.documentLayout().draw(painter, ctx)

		painter.restore()
Esempio n. 9
0
    def renderLabel(self, painter):
        """Render the current timestamp on the map canvas"""
        if not self.showLabel or not self.model.hasLayers() or not self.dock.pushButtonToggleTime.isChecked():
            return

        dt = self.model.getCurrentTimePosition()
        if dt is None:
            return

        labelString = self.labelOptions.getLabel(dt)

        # Determine placement of label given cardinal directions
        flags = 0
        for direction, flag in ('N', Qt.AlignTop), ('S', Qt.AlignBottom), ('E', Qt.AlignRight), ('W', Qt.AlignLeft):
            if direction in self.labelOptions.placement:
                flags |= flag

        # Get canvas dimensions
        width = painter.device().width()
        height = painter.device().height()

        painter.setRenderHint(painter.Antialiasing, True)
        txt = QTextDocument()
        html = """<span style="background-color:%s; padding: 5px; font-size: %spx;">
                    <font face="%s" color="%s">%s</font>
                  </span> """\
               % (self.labelOptions.bgcolor, self.labelOptions.size, self.labelOptions.font,  
                  self.labelOptions.color, labelString)
        txt.setHtml(html)
        layout = txt.documentLayout()
        size = layout.documentSize()

        if flags & Qt.AlignRight:
            x = width - 5 - size.width()
        elif flags & Qt.AlignLeft:
            x = 5
        else:
            x = width / 2 - size.width() / 2

        if flags & Qt.AlignBottom:
            y = height - 5 - size.height()
        elif flags & Qt.AlignTop:
            y = 5
        else:
            y = height / 2 - size.height() / 2

        painter.translate(x, y)
        layout.draw(painter, QAbstractTextDocumentLayout.PaintContext())
        painter.translate(-x, -y)  # translate back
class MessageItemDelegate(QStyledItemDelegate):
    def __init__(self, parentView, logger, column=None, margin=50):
        super(MessageItemDelegate, self).__init__(parentView)

        self.logger = logger
        # We need that to receive mouse move events in editorEvent
        parentView.setMouseTracking(True)

        # Revert the mouse cursor when the mouse isn't over 
        # an item but still on the view widget
        parentView.viewportEntered.connect(self.unsetParentCursor)

        self.document = QTextDocument()
        self.mouseOverDocument = self.document
        self.mouseOverDocumentRow = -1
        self.mouseOverOption = None
        self.lastTextPos = QPoint(0, 0)
        self._editIndex = None
        self._editor = None
        self._column = column
        self._margin = margin
        
        ownGradient = QLinearGradient(0, 0, 0, 10)
        ownGradient.setColorAt(0, QColor(229, 239, 254))
        ownGradient.setColorAt(1, QColor(182, 208, 251))
        self._ownBrush = QBrush(ownGradient)
        self._ownPenColor = QColor(104, 126, 164)
        
        otherGradient = QLinearGradient(0, 0, 0, 10)
        otherGradient.setColorAt(0, QColor(248, 248, 248))
        otherGradient.setColorAt(1, QColor(200, 200, 200))
        self._otherBrush = QBrush(otherGradient)
        self._otherPenColor = QColor(153, 153, 153)
        
        self._timeFont = QFont("default", 12, QFont.Bold)
        
        self.closeEditor.connect(self.editorClosing)
        
        self._rowHeights = {}
        
    @loggingSlot()
    def unsetParentCursor(self):
        self.parent().unsetCursor()
        
    def setEditIndex(self, modelIndex):
        self._editIndex = modelIndex
        
    def getEditIndex(self):
        return self._editIndex
        
    @loggingSlot(QWidget, QAbstractItemDelegate.EndEditHint)
    def editorClosing(self, _editor, _hint):
        self._editor = None
        self.setEditIndex(None)
        
    def getEditor(self):
        return self._editor
    
    def createEditor(self, parent, option_, modelIndex):
        self.setEditIndex(modelIndex)
        
        option = QStyleOptionViewItemV4(option_)
        self.initStyleOption(option, modelIndex)
        
        text = QString(option.text)
    
        editorWidget = EditorWidget(parent)
        editor = ItemEditor(text, self._preferredMessageWidth(option.rect.width()), editorWidget)
        editorWidget.setItemEditor(editor)

        messageRect = self._getMessageRect(option, editor.document(), modelIndex, relativeToItem=True)
        pos = messageRect.topLeft()
        editor.move(pos)
        editor.resize(messageRect.size())
        
        self._editor = editorWidget
        return editorWidget
    
    def setModelData(self, *_args, **_kwargs):
        pass
    
    def _preferredMessageWidth(self, textRectWidth):
        return textRectWidth - self._margin
    
    def _getMessageRect(self, option, doc, modelIndex, relativeToItem=False):
        rightAligned = modelIndex.data(ChatMessagesModel.OWN_MESSAGE_ROLE).toBool()
        statusIcon = modelIndex.data(ChatMessagesModel.STATUS_ICON_ROLE)
        hasStatusIcon = statusIcon != None and not statusIcon.isNull()
        textRect = option.rect
        
        documentWidth = doc.idealWidth()
        if rightAligned:
            xOffset = textRect.width() - documentWidth - 3
            if hasStatusIcon:
                xOffset -= 20
        else:
            xOffset = 3
            if hasStatusIcon:
                xOffset += 20
        
        height = doc.size().height()
        if modelIndex.row() not in self._rowHeights:
            self._rowHeights[modelIndex.row()] = height
        elif self._rowHeights[modelIndex.row()] != height:
            self._rowHeights[modelIndex.row()] = height
            self.sizeHintChanged.emit(modelIndex)
            
        if height < 32:
            # vertically center
            yOffset = (32. - height) / 2 + 1
        else:
            yOffset = 0
        
        textPos = QPoint(0,0) if relativeToItem else textRect.topLeft()
        textPos += QPoint(xOffset, yOffset)
        return QRect(textPos, QSize(documentWidth, height))
    
    def _paintTime(self, painter, option, modelIndex):
        if modelIndex.column() != 1:
            return
        # total rect for us to paint in
        textRect = option.rect
        
        rtime, _ok = modelIndex.data(Qt.DisplayRole).toDouble()
        timeString = formatTime(localtime(rtime))
        
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(textRect.topLeft())
        painter.setFont(self._timeFont)
        textWidth = painter.fontMetrics().width(timeString)
        painter.drawText((textRect.size().width() - textWidth) / 2, 13, timeString)
        painter.restore()
    
    def paint(self, painter, option1, modelIndex):
        if self._column is not None and modelIndex.column() != self._column:
            return super(MessageItemDelegate, self).paint(painter, option1, modelIndex)
        
        option = QStyleOptionViewItemV4(option1)
        self.initStyleOption(option, modelIndex)
        
        if modelIndex.data(Qt.DisplayRole).type() == QMetaType.Double:
            # this is a time item
            self._paintTime(painter, option, modelIndex)
            return

        text = QString(option.text)
        if not text:
            option1.decorationAlignment = Qt.AlignLeft
            return super(MessageItemDelegate, self).paint(painter, option1, modelIndex)
        
        rightAligned = modelIndex.data(ChatMessagesModel.OWN_MESSAGE_ROLE).toBool()
        selected = (int(option.state) & int(QStyle.State_Selected)) != 0
        editing = self._editIndex == modelIndex
    
        self.document.setHtml(text)
        self.document.setTextWidth(self._preferredMessageWidth(option.rect.width()))
        
        ctx = QAbstractTextDocumentLayout.PaintContext()
    
        # Highlighting text if item is selected
        if selected:
            ctx.palette.setColor(QPalette.Text, option.palette.color(QPalette.Active, QPalette.HighlightedText))
    
        # total rect for us to paint in
        textRect = option.rect
        # final rect to paint message in
        messageRect = self._getMessageRect(option, self.document, modelIndex)
        
        painter.save()
        
        mouseOver = (int(option.state) & int(QStyle.State_MouseOver)) != 0
        if mouseOver:
            self.mouseOverDocument = QTextDocument()
            self.mouseOverDocument.setHtml(text)
            self.mouseOverDocument.setTextWidth(self._preferredMessageWidth(option.rect.width()))
            self.mouseOverDocumentRow = modelIndex.row()
            self.lastTextPos = textRect.topLeft()
            self.mouseOverOption = option
        
        # draw decoration
        painter.translate(textRect.topLeft())
        statusIcon = modelIndex.data(ChatMessagesModel.STATUS_ICON_ROLE)
        if statusIcon != None and not statusIcon.isNull():
            statusIcon = QIcon(statusIcon)
            if rightAligned:
                statusIcon.paint(painter, textRect.size().width() - 19, 8, 16, 16, Qt.AlignCenter)
            else:
                statusIcon.paint(painter, 3, 8, 16, 16, Qt.AlignCenter)
                
        # draw message
        painter.restore()
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(messageRect.topLeft())
        if not editing:
            painter.setBrush(self._ownBrush if rightAligned else self._otherBrush)
        painter.setPen(self._ownPenColor if rightAligned else self._otherPenColor)
        painter.drawRoundedRect(QRectF(QPointF(0, 0.5),
                                       QSizeF(self.document.idealWidth(),
                                              self.document.size().height() - 1.)),
                                7, 7)
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        if not editing:
            self.document.documentLayout().draw(painter, ctx)
        painter.restore()

    startEditing = pyqtSignal(QModelIndex)

    def shouldStartEditAt(self, eventPos, modelIndex):
        option = QStyleOptionViewItemV4()
        option.initFrom(self.parent())
        option.rect.setHeight(32)
        self.initStyleOption(option, modelIndex)
        
        if modelIndex.row() != self.mouseOverDocumentRow:
            # TODO reset document
            self.logger.warning("shouldStartEditAt(): wrong mouse over document")
            return False
        messageRect = self._getMessageRect(self.mouseOverOption, self.mouseOverDocument, modelIndex)
        anchorPos = QPointF(eventPos) - QPointF(messageRect.topLeft())
        anchor = self.mouseOverDocument.documentLayout().anchorAt(anchorPos)
        if anchor != "":
            return False
        
        return messageRect.contains(eventPos)

    def editorEvent(self, event, _model, option_, modelIndex):
        if self._column and modelIndex.column() != self._column:
            return False
        option = QStyleOptionViewItemV4(option_)
        self.initStyleOption(option, modelIndex)
        text = QString(option.text)
        if not text:
            self.parent().unsetCursor()
            return False
        
        if event.type() not in (QEvent.MouseMove, QEvent.MouseButtonRelease, QEvent.MouseButtonPress) \
            or not (option.state & QStyle.State_Enabled):
            return False
        
        if modelIndex.row() != self.mouseOverDocumentRow:
            return False
        
        # Get the link at the mouse position
        pos = event.pos()
        messageRect = self._getMessageRect(option, self.mouseOverDocument, modelIndex)
        anchor = convert_string(self.mouseOverDocument.documentLayout().anchorAt(QPointF(pos) - QPointF(messageRect.topLeft())))
        if anchor == "":
            if messageRect.contains(pos):
                self.parent().setCursor(Qt.IBeamCursor)
            else:
                self.parent().unsetCursor()
        else:
            self.parent().setCursor(Qt.PointingHandCursor)               
            if event.type() == QEvent.MouseButtonRelease:
                if anchor.startswith(u"www."):
                    anchor = u"http://" + anchor
                webbrowser.open(anchor)
                return True 
        return False

    def sizeHint(self, option1, index):
        # option.rect is a zero rect
        width = self.parent().columnWidth(index.column())
        
        if index.data(Qt.DisplayRole).type() == QMetaType.Double:
            return QSize(width, 18)
        
        option = QStyleOptionViewItemV4(option1)
        self.initStyleOption(option, index)
        
        if not option.text:
            iconSize = option.icon.actualSize(QSize(32, 32))
            return QSize(32, max(32, iconSize.height() + 4))
        
        doc = QTextDocument()
        doc.setHtml(option.text)
        doc.setTextWidth(self._preferredMessageWidth(width))
        
        return QSize(doc.idealWidth(), max(32, doc.size().height() + 4))