Exemple #1
0
def stamp_image(image, expression_str, position, feature):
    painter = QPainter(image)
    data = QgsExpression.replaceExpressionText(expression_str, feature, None)
    if not data:
        return image

    data = data.replace(r"\n", "<br>")
    style = """
    body {
        color: yellow;
    }
    """
    doc = QTextDocument()
    doc.setDefaultStyleSheet(style)
    data = "<body>{}</body>".format(data)
    doc.setHtml(data)
    point = QPointF(20, 20)

    # Wrap the text so we don't go crazy
    if doc.size().width() > 300:
        doc.setTextWidth(300)
    if position == "top-left":
        point = QPointF(20, 20)
    elif position == "top-right":
        x = image.width() - 20 - doc.size().width()
        point = QPointF(x, 20)
    elif position == "bottom-left":
        point = QPointF(20, image.height() - 20 - doc.size().height())
    elif position == "bottom-right":
        x = image.width() - 20 - doc.size().width()
        y = image.height() - 20 - doc.size().height()
        point = QPointF(x, y)
    painter.translate(point)
    doc.drawContents(painter)
    return image
Exemple #2
0
class FeatureShape(LabeledPolygonShape):

    def draw(self, painter, xMap, yMap, canvasRect):
        self._setup_painter(painter)

        self._set_outer_pen_and_brush(painter, xMap, yMap)
        rtmin = self.item.rtmin
        rtmax = self.item.rtmax
        mzmin = self.item.mzmin
        mzmax = self.item.mzmax
        self._draw_polygon(painter, xMap, yMap, (rtmin, rtmax, mzmin, mzmax))

        self._set_inner_pen_and_brush(painter, xMap, yMap)
        for mass_trace in self.item.mass_traces:
            self._draw_polygon(painter, xMap, yMap, mass_trace)

        if self.label is not None:
            self._draw_label(painter, xMap, yMap)

    def _draw_label(self, painter, xMap, yMap):
        self.text = QTextDocument()
        self.text.setDefaultStyleSheet("""div { color: rgb(%d, %d, %d); }""" % self.color)
        self.text.setHtml("<div>%s</div>" % (self.label, ))

        x0 = xMap.transform(self.item.rtmax)
        # y0: height between m0 and m1 masstrace if m1 exists, else at height of m0
        yi = sorted(m.mzmin for m in self.item.mass_traces)
        if len(yi) >= 2:
            y0 = yMap.transform(0.5 * yi[0] + 0.5 * yi[1])
        else:
            y0 = yMap.transform(yi[0])
        h = self.text.size().height()
        painter.translate(x0, y0 - 0.5 * h)
        self.text.drawContents(painter)
def show(cursor, pos=None, num_lines=6):
    """Displays a tooltip showing part of the cursor's Document.
    
    If the cursor has a selection, those blocks are displayed.
    Otherwise, num_lines lines are displayed.
    
    If pos is not given, the global mouse position is used.
    
    """
    block = cursor.document().findBlock(cursor.selectionStart())
    c2 = QTextCursor(block)
    if cursor.hasSelection():
        c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor)
        c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    else:
        c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines)
    
    data = textformats.formatData('editor')
    
    doc = QTextDocument()
    font = QFont(data.font)
    font.setPointSizeF(font.pointSizeF() * .8)
    doc.setDefaultFont(font)
    doc.setPlainText(c2.selection().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlighter.highlight(doc, state=tokeniter.state(block))
    size = doc.size().toSize() + QSize(8, -4)
    pix = QPixmap(size)
    pix.fill(data.baseColors['background'])
    doc.drawContents(QPainter(pix))
    label = QLabel()
    label.setPixmap(pix)
    label.setStyleSheet("QLabel { border: 1px solid #777; }")
    label.resize(size)
    widgets.customtooltip.show(label, pos)
Exemple #4
0
 def displayAnnotation(self, geom, message):
     ''' Display a specific message in the centroid of a specific geometry 
     '''
     centroid = geom.centroid()
     
     # clean previous annotations:
     for annotation in self.annotations:
         try:
             scene = annotation.scene()
             if scene:
                 scene.removeItem(annotation)
         except:
             # annotation can be erased by QGIS interface
             pass
     self.annotations = []
     
     # build annotation
     textDoc = QTextDocument(message)
     item = QgsTextAnnotationItem(self.iface.mapCanvas())
     item.setMapPosition(centroid.asPoint())
     item.setFrameSize(textDoc.size())
     item.setDocument(textDoc)
     item.update()
     
     # add to annotations
     self.annotations.append(item)
     
     # center in the centroid
     self.iface.mapCanvas().setCenter(centroid.asPoint())
     self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale))
     self.iface.mapCanvas().refresh()
Exemple #5
0
    def sizeHint(self, option, index):
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setHtml(options.text)
        doc.setTextWidth(options.rect.width())
        return QtCore.QSize(doc.idealWidth(), doc.size().height())
Exemple #6
0
	def sizeHint(self, option, index):
		options = QStyleOptionViewItemV4(option)
		self.initStyleOption(options,index)

		doc = QTextDocument()
		doc.setHtml(options.text)
		doc.setTextWidth(options.rect.width())
		return QtCore.QSize(doc.idealWidth(), doc.size().height())
Exemple #7
0
    def sizeHint(self, option, index):
        optionV4 = QStyleOptionViewItemV4(option)
        self.initStyleOption(optionV4, index)

        doc = QTextDocument()
        doc.setHtml(optionV4.text)
        doc.setTextWidth(optionV4.rect.width())

        return QSize(doc.idealWidth(), max(doc.size().height(), optionV4.decorationSize.height()))
Exemple #8
0
    def sizeHint(self, option, index):
        optionV4 = QStyleOptionViewItemV4(option)
        self.initStyleOption(optionV4, index)

        doc = QTextDocument()
        doc.setHtml(optionV4.text)
        doc.setTextWidth(optionV4.rect.width())

        return QSize(doc.idealWidth(), max(doc.size().height(), optionV4.decorationSize.height()))
Exemple #9
0
    def sizeHint(self, option, index):
        """Calculate the needed size."""
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setHtml(options.text)
        doc.setTextWidth(options.rect.width())
        return QSize(doc.idealWidth(), doc.size().height())
Exemple #10
0
    def sizeHint(self, option, index):
        """Calculate the needed size."""
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setHtml(options.text)
        doc.setTextWidth(options.rect.width())
        return QSize(doc.idealWidth(), doc.size().height())
Exemple #11
0
    def sizeHint(self, option, index):
        """QStyledItemDelegate.sizeHint implementation
        """
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setDocumentMargin(1)
        #  bad long (multiline) strings processing doc.setTextWidth(options.rect.width())
        doc.setHtml(options.text)
        return QSize(doc.idealWidth(), doc.size().height())
Exemple #12
0
    def sizeHint(self, option, index):
        """QStyledItemDelegate.sizeHint implementation
        """
        options = QStyleOptionViewItemV4(option)
        self.initStyleOption(options,index)

        doc = QTextDocument()
        doc.setDocumentMargin(1)
        #  bad long (multiline) strings processing doc.setTextWidth(options.rect.width())
        doc.setHtml(options.text)
        return QSize(doc.idealWidth(), doc.size().height())
 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))
Exemple #14
0
class PeakRangeShape(LabeledPolygonShape):

    def draw(self, painter, xMap, yMap, canvasRect):
        self._setup_painter(painter)
        self._set_inner_pen_and_brush(painter, xMap, yMap)
        self._draw_polygon(painter, xMap, yMap, self.item)

        if self.label is not None:
            self._draw_label(painter, xMap, yMap)

    def _draw_label(self, painter, xMap, yMap):
        self.text = QTextDocument()
        self.text.setDefaultStyleSheet("""div { color: rgb(%d, %d, %d); }""" % self.color)
        self.text.setHtml("<div>%s</div>" % (self.label, ))

        x0 = xMap.transform(self.item.rtmax)
        # y0: height between m0 and m1 masstrace if m1 exists, else at height of m0
        y0 = yMap.transform(0.5 * self.item.mzmin + 0.5 * self.item.mzmax)
        h = self.text.size().height()
        painter.translate(x0, y0 - 0.5 * h)
        self.text.drawContents(painter)
def show(cursor, pos=None, num_lines=6):
    """Displays a tooltip showing part of the cursor's Document.
    
    If the cursor has a selection, those blocks are displayed.
    Otherwise, num_lines lines are displayed.
    
    If pos is not given, the global mouse position is used.
    
    """
    block = cursor.document().findBlock(cursor.selectionStart())
    c2 = QTextCursor(block)
    if cursor.hasSelection():
        c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor)
        c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
    else:
        c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor,
                        num_lines)

    data = textformats.formatData('editor')

    doc = QTextDocument()
    font = QFont(data.font)
    font.setPointSizeF(font.pointSizeF() * .8)
    doc.setDefaultFont(font)
    doc.setPlainText(c2.selection().toPlainText())
    if metainfo.info(cursor.document()).highlighting:
        highlighter.highlight(doc, state=tokeniter.state(block))
    size = doc.size().toSize() + QSize(8, -4)
    pix = QPixmap(size)
    pix.fill(data.baseColors['background'])
    doc.drawContents(QPainter(pix))
    label = QLabel()
    label.setPixmap(pix)
    label.setStyleSheet("QLabel { border: 1px solid #777; }")
    label.resize(size)
    widgets.customtooltip.show(label, pos)
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))