def paintEvent(self, event): page_bottom = self.edit.viewport().height() font_metrics = QFontMetrics(self.edit.document().defaultFont()) current_block = self.edit.document().findBlock( self.edit.textCursor().position()) pattern = self.pat if self.edit.lang == "python" else self.patNotPython painter = QPainter(self) background = resources.CUSTOM_SCHEME.get('sidebar-background', resources.COLOR_SCHEME['sidebar-background']) foreground = resources.CUSTOM_SCHEME.get('sidebar-foreground', resources.COLOR_SCHEME['sidebar-foreground']) pep8color = resources.CUSTOM_SCHEME.get('pep8-underline', resources.COLOR_SCHEME['pep8-underline']) errorcolor = resources.CUSTOM_SCHEME.get('error-underline', resources.COLOR_SCHEME['error-underline']) painter.fillRect(self.rect(), QColor(background)) block = self.edit.firstVisibleBlock() viewport_offset = self.edit.contentOffset() line_count = block.blockNumber() painter.setFont(self.edit.document().defaultFont()) while block.isValid(): line_count += 1 # The top left position of the block in the document position = self.edit.blockBoundingGeometry(block).topLeft() + \ viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # Set the Painter Pen depending on special lines error = False if settings.CHECK_STYLE and \ ((line_count - 1) in self._pep8Lines): painter.setPen(QColor(pep8color)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.FIND_ERRORS and \ ((line_count - 1) in self._errorsLines): painter.setPen(QColor(errorcolor)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True else: painter.setPen(QColor(foreground)) # We want the line number for the selected line to be bold. bold = False if block == current_block: bold = True font = painter.font() font.setBold(True) painter.setFont(font) # Draw the line number right justified at the y position of the # line. 3 is a magic padding number. drawText(x, y, text). if block.isVisible(): painter.drawText(self.width() - self.foldArea - font_metrics.width(str(line_count)) - 3, round(position.y()) + font_metrics.ascent() + font_metrics.descent() - 1, str(line_count)) # Remove the bold style if it was set previously. if bold: font = painter.font() font.setBold(False) painter.setFont(font) if error: font = painter.font() font.setItalic(False) font.setUnderline(False) painter.setFont(font) block = block.next() self.highest_line = line_count #Code Folding xofs = self.width() - self.foldArea painter.fillRect(xofs, 0, self.foldArea, self.height(), QColor(resources.CUSTOM_SCHEME.get('fold-area', resources.COLOR_SCHEME['fold-area']))) if self.foldArea != self.rightArrowIcon.width(): polygon = QPolygonF() self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea) self.rightArrowIcon.fill(Qt.transparent) self.downArrowIcon = QPixmap(self.foldArea, self.foldArea) self.downArrowIcon.fill(Qt.transparent) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25)) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75)) polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5)) iconPainter = QPainter(self.rightArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) polygon.clear() polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8)) iconPainter = QPainter(self.downArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) block = self.edit.firstVisibleBlock() while block.isValid(): position = self.edit.blockBoundingGeometry( block).topLeft() + viewport_offset #Check if the position of the block is outside of the visible area if position.y() > page_bottom: break if pattern.match(block.text()) and block.isVisible(): if block.blockNumber() in self._foldedBlocks: painter.drawPixmap(xofs, round(position.y()), self.rightArrowIcon) else: painter.drawPixmap(xofs, round(position.y()), self.downArrowIcon) #Add Bookmarks and Breakpoint elif block.blockNumber() in self._breakpoints: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(255, 11, 11)) linear_gradient.setColorAt(1, QColor(147, 9, 9)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawEllipse( xofs + 1, round(position.y()) + 6, self.foldArea - 1, self.foldArea - 1) elif block.blockNumber() in self._bookmarks: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(13, 62, 243)) linear_gradient.setColorAt(1, QColor(5, 27, 106)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawRoundedRect( xofs + 1, round(position.y()) + 6, self.foldArea - 2, self.foldArea - 1, 3, 3) block = block.next() painter.end() QWidget.paintEvent(self, event)
def paintEvent(self, event): page_bottom = self.edit.viewport().height() font_metrics = QFontMetrics(self.edit.document().defaultFont()) current_block = self.edit.document().findBlock( self.edit.textCursor().position()) pattern = self.pat if self.edit.lang == "python" else self.patNotPython painter = QPainter(self) background = resources.CUSTOM_SCHEME.get('sidebar-background', resources.COLOR_SCHEME['sidebar-background']) foreground = resources.CUSTOM_SCHEME.get('sidebar-foreground', resources.COLOR_SCHEME['sidebar-foreground']) painter.fillRect(self.rect(), QColor(background)) block = self.edit.firstVisibleBlock() viewport_offset = self.edit.contentOffset() line_count = block.blockNumber() painter.setFont(self.edit.document().defaultFont()) while block.isValid(): line_count += 1 # The top left position of the block in the document position = self.edit.blockBoundingGeometry(block).topLeft() + \ viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # Set the Painter Pen depending on special lines painter.setPen(QColor(foreground)) error = False checkers = sorted(self._neditable.registered_checkers, key=lambda x: x[2], reverse=True) for items in checkers: checker, color, _ = items if (line_count - 1) in checker.checks: painter.setPen(QColor(color)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True break # We want the line number for the selected line to be bold. bold = False if block == current_block: bold = True font = painter.font() font.setBold(True) painter.setFont(font) # Draw the line number right justified at the y position of the # line. 3 is a magic padding number. drawText(x, y, text). if block.isVisible(): painter.drawText(self.width() - self.foldArea - font_metrics.width(str(line_count)) - 3, round(position.y()) + font_metrics.ascent() + font_metrics.descent() - 1, str(line_count)) # Remove the bold style if it was set previously. if bold: font = painter.font() font.setBold(False) painter.setFont(font) if error: font = painter.font() font.setItalic(False) font.setUnderline(False) painter.setFont(font) block = block.next() self.highest_line = line_count #Code Folding xofs = self.width() - self.foldArea painter.fillRect(xofs, 0, self.foldArea, self.height(), QColor(resources.CUSTOM_SCHEME.get('fold-area', resources.COLOR_SCHEME['fold-area']))) if self.foldArea != self.rightArrowIcon.width(): polygon = QPolygonF() self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea) self.rightArrowIcon.fill(Qt.transparent) self.downArrowIcon = QPixmap(self.foldArea, self.foldArea) self.downArrowIcon.fill(Qt.transparent) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25)) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75)) polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5)) iconPainter = QPainter(self.rightArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) polygon.clear() polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8)) iconPainter = QPainter(self.downArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) self.calculate_docstring_block_fold() block = self.edit.firstVisibleBlock() while block.isValid(): position = self.edit.blockBoundingGeometry( block).topLeft() + viewport_offset #Check if the position of the block is outside of the visible area if position.y() > page_bottom: break if pattern.match(block.text()) and block.isVisible(): can_fold = True if self.patComment.match(block.text()) and \ (block.blockNumber() in self._endDocstringBlocks): can_fold = False if can_fold: if block.blockNumber() in self.foldedBlocks: painter.drawPixmap(xofs, round(position.y()), self.rightArrowIcon) else: painter.drawPixmap(xofs, round(position.y()), self.downArrowIcon) #Add Bookmarks and Breakpoint if block.blockNumber() in self.breakpoints: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(255, 11, 11)) linear_gradient.setColorAt(1, QColor(147, 9, 9)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawEllipse( xofs + 1, round(position.y()) + 6, self.foldArea - 1, self.foldArea - 1) elif block.blockNumber() in self.bookmarks: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(13, 62, 243)) linear_gradient.setColorAt(1, QColor(5, 27, 106)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawRoundedRect( xofs + 1, round(position.y()) + 6, self.foldArea - 2, self.foldArea - 1, 3, 3) block = block.next() painter.end() QWidget.paintEvent(self, event)
class PositionMarker(QgsMapCanvasItem): ''' classdocs ''' def __init__(self, canvas, params={}): ''' Constructor :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface :param params: A dictionary defining all the properties of the position marker :type params: dictionary ''' self.canvas = canvas self.type = params.get('type', 'BOX').upper() self.size = int(params.get('size', 16)) self.bounding = 1.414213562 * self.size self.length = float(params.get('length', 98.0)) self.width = float(params.get('width', 17.0)) self.shape = params.get('shape', ((0.0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.50), (-0.5, -0.3))) s = (self.size - 1) / 2 self.paintShape = QPolygonF([QPointF(-s, -s), QPointF(s, -s), QPointF(s, s), QPointF(-s, s)]) self.color = self.getColor(params.get('color', 'black')) self.fillColor = self.getColor(params.get('fillColor', 'lime')) self.penWidth = int(params.get('penWidth', 1)) if self.type in ('CROSS', 'X'): self.penWidth = 5 self.trackLen = int(params.get('trackLength', 100)) self.trackColor = self.getColor(params.get('trackColor', self.fillColor)) self.track = deque() self.pos = None self.heading = 0 super(PositionMarker, self).__init__(canvas) self.setZValue(int(params.get('zValue', 100))) self.distArea = QgsDistanceArea() self.distArea.setEllipsoid(u'WGS84') self.distArea.setEllipsoidalMode(True) self.updateSize() def properties(self): return {'type': self.type, 'size': self.size, 'length': self.length, 'width': self.width, 'shape': self.shape, 'color': self.color.rgba(), 'fillColor': self.fillColor.rgba(), 'penWidth': self.penWidth, 'trackLength': self.trackLen, 'trackColor' : self.trackColor.rgba(), 'zValue': self.zValue()} def setMapPosition(self, pos): if self.pos != pos: self.updateTrack() self.pos = pos self.setPos(self.toCanvasCoordinates(self.pos)) self.update() def newHeading(self, heading): if self.heading != heading: self.heading = heading self.setRotation(self.canvas.rotation() + self.heading) self.update() def resetPosition(self): self.pos = None def updatePosition(self): if self.pos: self.prepareGeometryChange() self.updateSize() self.setPos(self.toCanvasCoordinates(self.pos)) self.setRotation(self.canvas.rotation() + self.heading) self.update() def updateSize(self): if self.type != 'SHAPE': return s = self.canvas.mapSettings() self.distArea.setSourceCrs(s.destinationCrs()) try: p1 = self.toMapCoordinates(QPoint(0, 0)) p2 = self.toMapCoordinates(QPoint(0, 100)) l = self.distArea.measureLine(p1, p2) f = 100 / l except: f = s.outputDpi() / 0.0254 / s.scale() paintLength = max(self.length * f, 50) paintWidth = paintLength * self.width / self.length self.paintShape.clear() for v in self.shape: self.paintShape << QPointF(v[0] * paintWidth, v[1] * paintLength) self.size = max(paintLength, paintWidth) self.bounding = sqrt(pow(paintLength, 2) + pow(paintLength, 2)) def updateTrack(self): if self.pos and self.trackLen: if len(self.track) >= self.trackLen: tpr = self.track.popleft() self.canvas.scene().removeItem(tpr) del(tpr) tp = QgsVertexMarker(self.canvas) tp.setCenter(self.pos) tp.setIconType(QgsVertexMarker.ICON_CROSS) tp.setColor(self.trackColor) tp.setZValue(self.zValue() - 0.1) tp.setIconSize(3) tp.setPenWidth(3) self.track.append(tp) def setVisible(self, visible): for tp in self.track: tp.setVisible(visible) QgsMapCanvasItem.setVisible(self, visible) def deleteTrack(self): for tp in self.track: self.canvas.scene().removeItem(tp) self.track.clear() def paint(self, painter, xxx, xxx2): if not self.pos: return s = (self.size - 1) / 2 pen = QPen(self.color) pen.setWidth(self.penWidth) painter.setPen(pen) if self.type == 'CROSS': painter.drawLine(QLineF(-s, 0, s, 0)) painter.drawLine(QLineF(0, -s, 0, s)) elif self.type == 'X': painter.drawLine(QLineF(-s, -s, s, s)) painter.drawLine(QLineF(-s, s, s, -s)) elif self.type == 'BOX': brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) elif self.type == 'SHAPE': painter.setRenderHint(QPainter.Antialiasing, True) brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) def boundingRect(self): s = self.bounding / 2 return QRectF(QPointF(-s, -s), QPointF(s, s)) def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) def removeFromCanvas(self): self.deleteTrack() self.canvas.scene().removeItem(self)
class Pointer(QGraphicsLineItem): """ QGraphicsPolygonItem to model a Pointer as an Arrow from a Pointer-Variable to its Content. """ fgcolor = QColor(0, 0, 0) bgcolor = QColor(0, 0, 0) def __init__(self, parent, fromView, toView, distributedObjects): """ Constructor @param parent parent for the QGraphicsPolygonItem-Constructor @param fromView datagraph.htmlvariableview.HtmlVariableView, starting point of the Pointer @param toView datagraph.htmlvariableview.HtmlVariableView, end point of the Pointer @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance fromView and toView are QGraphicsWebViews """ QGraphicsLineItem.__init__(self, parent) self.fromView = fromView fromView.addOutgoingPointer(self) self.toView = toView toView.addIncomingPointer(self) #self.setBrush( QBrush( self.bgcolor ) ) self.setPen(QPen(self.fgcolor, 1)) self.distributedObjects = distributedObjects QObject.connect(self.fromView, SIGNAL('geometryChanged()'), self.updatePosition) QObject.connect(self.toView, SIGNAL('geometryChanged()'), self.updatePosition) QObject.connect(self.fromView, SIGNAL('xChanged()'), self.updatePosition) QObject.connect(self.fromView, SIGNAL('yChanged()'), self.updatePosition) QObject.connect(self.toView, SIGNAL('xChanged()'), self.updatePosition) QObject.connect(self.toView, SIGNAL('yChanged()'), self.updatePosition) QObject.connect(self.fromView, SIGNAL('removing()'), self.delete) QObject.connect(self.toView, SIGNAL('removing()'), self.delete) self.arrowhead = QPolygonF() self.arrowSize = 20 self.setZValue(-1) # paint the arrows behind (lower z-value) everything else def boundingRect(self): extra = (self.pen().width() + 20) / 2 return QRectF(self.line().p1(), QSizeF(self.line().p2().x() - self.line().p1().x(), self.line().p2().y() - self.line().p1().y())).normalized().adjusted(-extra, -extra, extra, extra) def shape(self): path = QGraphicsLineItem.shape(self) path.addPolygon(self.arrowhead) return path def updatePosition(self): line = QLineF(self.mapFromItem(self.fromView, 0, 0), self.mapFromItem(self.toView, 0, 0)) self.setLine(line) def paint(self, painter, _1, _2): """ Main-Method of the Pointer-Class <br> calculates/renders/draws the Lines of the Arrow """ if self.fromView.collidesWithItem(self.toView): return # antialiasing makes things look nicer :) painter.setRenderHint(QPainter.Antialiasing) self.toView.x() pM1 = QPointF(self.fromView.x() + self.fromView.size().width() / 2, self.fromView.y() + self.fromView.size().height() / 2) pM2 = QPointF(self.toView.x() + self.toView.size().width() / 2, self.toView.y() + self.toView.size().height() / 2) deltaX = pM2.x() - pM1.x() deltaY = pM2.y() - pM1.y() if deltaX == 0: deltaX = 0.01 if deltaY == 0: deltaY = 0.01 if deltaX >= 0: if deltaY >= 0: # rechts unten if deltaX / deltaY >= self.fromView.size().width() / self.fromView.size().height(): # Start von rechter Seite pStart = QPointF(pM1.x() + self.fromView.size().width() / 2, pM1.y() + (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von unterer Seite pStart = QPointF(pM1.x() + (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() + self.fromView.size().height() / 2) if deltaX / deltaY >= self.toView.size().width() / self.toView.size().height(): # Ende bei linker Seite pEnd = QPointF(pM2.x() - self.toView.size().width() / 2, pM2.y() - (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei oberer Seite pEnd = QPointF(pM2.x() - (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() - self.toView.size().height() / 2) else: # rechts oben if deltaX / deltaY * -1 >= self.fromView.size().width() / self.fromView.size().height(): # Start von rechter Seite pStart = QPointF(pM1.x() + self.fromView.size().width() / 2, pM1.y() + (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von oberer Seite pStart = QPointF(pM1.x() - (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() - self.fromView.size().height() / 2) if deltaX / deltaY * -1 >= self.toView.size().width() / self.toView.size().height(): # Ende bei linker Seite pEnd = QPointF(pM2.x() - self.toView.size().width() / 2, pM2.y() - (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei unterer Seite pEnd = QPointF(pM2.x() + (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() + self.toView.size().height() / 2) else: if deltaY >= 0: # links unten if deltaX / deltaY * -1 >= self.fromView.size().width() / self.fromView.size().height(): # Start von linker Seite pStart = QPointF(pM1.x() - self.fromView.size().width() / 2, pM1.y() - (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von unterer Seite pStart = QPointF(pM1.x() + (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() + self.fromView.size().height() / 2) if deltaX / deltaY * -1 >= self.toView.size().width() / self.toView.size().height(): # Ende bei rechten Seite pEnd = QPointF(pM2.x() + self.toView.size().width() / 2, pM2.y() + (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei oberer Seite pEnd = QPointF(pM2.x() - (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() - self.toView.size().height() / 2) else: # links oben if deltaX / deltaY >= self.fromView.size().width() / self.fromView.size().height(): # Start von linker Seite pStart = QPointF(pM1.x() - self.fromView.size().width() / 2, pM1.y() - (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von oberer Seite pStart = QPointF(pM1.x() - (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() - self.fromView.size().height() / 2) if deltaX / deltaY >= self.toView.size().width() / self.toView.size().height(): # Ende bei rechter Seite pEnd = QPointF(pM2.x() + self.toView.size().width() / 2, pM2.y() + (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei unterer Seite pEnd = QPointF(pM2.x() + (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() + self.toView.size().height() / 2) self.setLine(QLineF(pEnd, pStart)) if self.line().length() != 0: angle = math.acos(self.line().dx() / self.line().length()) if self.line().dy() >= 0: angle = math.pi * 2 - angle arrowP1 = self.line().p1() + QPointF(math.sin(angle + math.pi / 2.5) * self.arrowSize, math.cos(angle + math.pi / 2.5) * self.arrowSize) arrowP2 = self.line().p1() + QPointF(math.sin(angle + math.pi - math.pi / 2.5) * self.arrowSize, math.cos(angle + math.pi - math.pi / 2.5) * self.arrowSize) self.arrowhead.clear() self.arrowhead.append(self.line().p1()) self.arrowhead.append(arrowP1) self.arrowhead.append(arrowP2) painter.setBrush(QBrush(self.bgcolor)) painter.drawLine(self.line()) painter.drawPolygon(self.arrowhead) def delete(self): """ removes the pointer from the DataGraph """ self.toView.incomingPointers.remove(self) self.fromView.outgoingPointers.remove(self) self.distributedObjects.datagraphController.removePointer(self) def setX(self, _): logging.error("Ignoring setting our Pointer's x position") def setY(self, _): logging.error("Ignoring setting our Pointer's y position")
def paintEvent(self, event): page_bottom = self.edit.viewport().height() font_metrics = QFontMetrics(self.edit.document().defaultFont()) current_block = self.edit.document().findBlock( self.edit.textCursor().position()) painter = QPainter(self) painter.fillRect(self.rect(), Qt.lightGray) block = self.edit.firstVisibleBlock() viewport_offset = self.edit.contentOffset() line_count = block.blockNumber() painter.setFont(self.edit.document().defaultFont()) while block.isValid(): line_count += 1 # The top left position of the block in the document position = self.edit.blockBoundingGeometry(block).topLeft() + \ viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # Set the Painter Pen depending on special lines error = False if settings.CHECK_STYLE and \ ((line_count - 1) in self._pep8Lines): painter.setPen(Qt.darkYellow) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.FIND_ERRORS and \ ((line_count - 1) in self._errorsLines): painter.setPen(Qt.red) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True else: painter.setPen(Qt.black) # We want the line number for the selected line to be bold. bold = False if block == current_block: bold = True font = painter.font() font.setBold(True) painter.setFont(font) # Draw the line number right justified at the y position of the # line. 3 is a magic padding number. drawText(x, y, text). if block.isVisible(): painter.drawText(self.width() - self.foldArea - \ font_metrics.width(str(line_count)) - 3, round(position.y()) + font_metrics.ascent() + \ font_metrics.descent() - 1, str(line_count)) # Remove the bold style if it was set previously. if bold: font = painter.font() font.setBold(False) painter.setFont(font) if error: font = painter.font() font.setItalic(False) font.setUnderline(False) painter.setFont(font) block = block.next() self.highest_line = line_count #Code Folding xofs = self.width() - self.foldArea painter.fillRect(xofs, 0, self.foldArea, self.height(), QColor(resources.CUSTOM_SCHEME.get('fold-area', resources.COLOR_SCHEME['fold-area']))) if self.foldArea != self.rightArrowIcon.width(): polygon = QPolygonF() self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea) self.rightArrowIcon.fill(Qt.transparent) self.downArrowIcon = QPixmap(self.foldArea, self.foldArea) self.downArrowIcon.fill(Qt.transparent) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25)) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75)) polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5)) iconPainter = QPainter(self.rightArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) polygon.clear() polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8)) iconPainter = QPainter(self.downArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush(QColor( resources.CUSTOM_SCHEME.get('fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) block = self.edit.firstVisibleBlock() while block.isValid(): position = self.edit.blockBoundingGeometry( block).topLeft() + viewport_offset #Check if the position of the block is outside of the visible area if position.y() > page_bottom: break if self.pat.match(unicode(block.text())) and block.isVisible(): if block.blockNumber() in self._foldedBlocks: painter.drawPixmap(xofs, round(position.y()), self.rightArrowIcon) else: painter.drawPixmap(xofs, round(position.y()), self.downArrowIcon) #Add Bookmarks and Breakpoint elif block.blockNumber() in self._breakpoints: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(255, 11, 11)) linear_gradient.setColorAt(1, QColor(147, 9, 9)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawEllipse( xofs + 1, round(position.y()) + 6, self.foldArea - 1, self.foldArea - 1) elif block.blockNumber() in self._bookmarks: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(13, 62, 243)) linear_gradient.setColorAt(1, QColor(5, 27, 106)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawRoundedRect( xofs + 1, round(position.y()) + 6, self.foldArea - 2, self.foldArea - 1, 3, 3) block = block.next() painter.end() QWidget.paintEvent(self, event)
def paintEvent(self, event): page_bottom = self.edit.viewport().height() font_metrics = QFontMetrics(self.edit.document().defaultFont()) current_block = self.edit.document().findBlock(self.edit.textCursor().position()) if self._firstPaintEvent is True: self.jumpedUP = False self.strings = self.edit.toPlainText().split("\n") self._originalTotalLine = len(self.strings) self.edit.jump_to_line(len(self.strings) - 2) elif self.jumpedUP is False: self.edit.jump_to_line(1) self.edit.verticalScrollBar().setValue(0) self.jumpedUP = True return pattern = self.pat if self.edit.lang == "python" else self.patNotPython painter = QPainter(self) background = resources.CUSTOM_SCHEME.get("sidebar-background", resources.COLOR_SCHEME["sidebar-background"]) foreground = resources.CUSTOM_SCHEME.get("sidebar-foreground", resources.COLOR_SCHEME["sidebar-foreground"]) pep8color = resources.CUSTOM_SCHEME.get("pep8-underline", resources.COLOR_SCHEME["pep8-underline"]) errorcolor = resources.CUSTOM_SCHEME.get("error-underline", resources.COLOR_SCHEME["error-underline"]) migrationcolor = resources.CUSTOM_SCHEME.get( "migration-underline", resources.COLOR_SCHEME["migration-underline"] ) painter.fillRect(self.rect(), QColor(background)) """ if self._firstPaintEvent is True: block = self.edit.document().findBlock(0) else: block = self.edit.firstVisibleBlock() """ block = self.edit.firstVisibleBlock() viewport_offset = self.edit.contentOffset() line_count = block.blockNumber() painter.setFont(self.edit.document().defaultFont()) pat = re.compile("\s*#AppObject:") patAlexaAppImage = re.compile("\s*#AppImage:") patAlexaAppText = re.compile("\s*#AppText:") patAlexaLog = re.compile("\s*#Alexa Log") while block.isValid(): line_count += 1 # The top left position of the block in the document position = self.edit.blockBoundingGeometry(block).topLeft() + viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # Set the Painter Pen depending on special lines error = False if settings.CHECK_STYLE and ((line_count - 1) in self._pep8Lines): painter.setPen(QColor(pep8color)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.FIND_ERRORS and ((line_count - 1) in self._errorsLines): painter.setPen(QColor(errorcolor)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.SHOW_MIGRATION_TIPS and ((line_count - 1) in self._migrationLines): painter.setPen(QColor(migrationcolor)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True else: painter.setPen(QColor(foreground)) # We want the line number for the selected line to be bold. bold = False if block == current_block: bold = True font = painter.font() font.setBold(True) painter.setFont(font) # Draw the line number right justified at the y position of the # line. 3 is a magic padding number. drawText(x, y, text). if block.isVisible(): painter.drawText( self.width() - self.foldArea - font_metrics.width(str(line_count)) - 3, round(position.y()) + font_metrics.ascent() + font_metrics.descent() - 1, str(line_count), ) # Remove the bold style if it was set previously. if bold: font = painter.font() font.setBold(False) painter.setFont(font) if error: font = painter.font() font.setItalic(False) font.setUnderline(False) painter.setFont(font) block = block.next() self.highest_line = line_count # Code Folding xofs = self.width() - self.foldArea painter.fillRect( xofs, 0, self.foldArea, self.height(), QColor(resources.CUSTOM_SCHEME.get("fold-area", resources.COLOR_SCHEME["fold-area"])), ) if self.foldArea != self.rightArrowIcon.width(): polygon = QPolygonF() self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea) self.rightArrowIcon.fill(Qt.transparent) self.downArrowIcon = QPixmap(self.foldArea, self.foldArea) self.downArrowIcon.fill(Qt.transparent) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25)) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75)) polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5)) iconPainter = QPainter(self.rightArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush( QColor(resources.CUSTOM_SCHEME.get("fold-arrow", resources.COLOR_SCHEME["fold-arrow"])) ) iconPainter.drawPolygon(polygon) polygon.clear() polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8)) iconPainter = QPainter(self.downArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush( QColor(resources.CUSTOM_SCHEME.get("fold-arrow", resources.COLOR_SCHEME["fold-arrow"])) ) iconPainter.drawPolygon(polygon) if self._firstPaintEvent is True: block = self.edit.document().findBlock(0) else: block = self.edit.firstVisibleBlock() # block = self.edit.firstVisibleBlock() line_count = block.blockNumber() while block.isValid(): # while line_count < 5000: line_count += 1 position = self.edit.blockBoundingGeometry(block).topLeft() + viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # block.isVisible() and if block.isVisible() and pat.match(block.text()) and block not in self._foldedAlexaObject: self._fold(line_count) self._foldedAlexaObject.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaAppImage.match(block.text()) and block not in self._foldedAlexaImage: self._fold(line_count) self._foldedAlexaImage.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaAppText.match(block.text()) and block not in self._foldedAlexaText: self._fold(line_count) self._foldedAlexaText.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaLog.match(block.text()) and block not in self._foldedAlexaLog: self._fold(line_count) self._foldedAlexaLog.append(block) self._alexaObjectsPresent = True elif pattern.match(block.text()) and block.isVisible(): if block.blockNumber() in self._foldedBlocks: painter.drawPixmap(xofs, round(position.y()), self.rightArrowIcon) else: # block.setVisible(True) painter.drawPixmap(xofs, round(position.y()), self.downArrowIcon) # Add Bookmarks and Breakpoint elif block.blockNumber() in self._breakpoints: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea ) linear_gradient.setColorAt(0, QColor(255, 11, 11)) linear_gradient.setColorAt(1, QColor(147, 9, 9)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawEllipse(xofs + 1, round(position.y()) + 6, self.foldArea - 1, self.foldArea - 1) elif block.blockNumber() in self._bookmarks: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea ) linear_gradient.setColorAt(0, QColor(13, 62, 243)) linear_gradient.setColorAt(1, QColor(5, 27, 106)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawRoundedRect(xofs + 1, round(position.y()) + 6, self.foldArea - 2, self.foldArea - 1, 3, 3) block = block.next() block = self.edit.document().findBlock(0) line_count = 0 line_hidden = 0 while block.isValid(): line_count += 1 if not block.isVisible(): line_hidden += 1 block = block.next() endScrollBar = line_count - line_hidden self.edit.verticalScrollBar().setRange(0, endScrollBar) if self._firstPaintEvent is True: self._firstPaintEvent = False # self.updateAlexaAppObjCoords() # self.updateAlexaLogCoords() painter.end() """ #self.edit.update() if self.edit.verticalScrollBar().value() != self._oldVerticalScrollbarPosition and self._alexaObjectsPresent is True: self._oldVerticalScrollbarPosition = self.edit.verticalScrollBar().value() self.updateAlexaCoords() self.edit.update() # in this way we can refresh alexa icon position if self.edit.horizontalScrollBar().value() != self._oldHorizontalScrollbarPosition and self._alexaObjectsPresent is True: self._oldHorizontalScrollbarPosition = self.edit.horizontalScrollBar().value() self.updateAlexaCoords() self.edit.update() # in this way we can refresh alexa icon position """ self.strings = self.edit.toPlainText().split("\n") self._currentTotalLine = len(self.strings) if self._currentTotalLine != self._originalTotalLine: self._originalTotalLine = self._currentTotalLine self.updateAlexaCoords() self.edit.update() """ if self._returnPressed is True: self._returnPressed = False self.updateAlexaAppObjCoords() self.updateAlexaLogCoords() self.edit.update() if self._backspacePressed is True: self._backspacePressed = False self.strings = self.edit.toPlainText().split('\n') self._currentTotalLine = len(self.strings) if self._currentTotalLine != self._originalTotalLine: self.updateAlexaAppObjCoords() self.updateAlexaLogCoords() self.edit.update() """ if self.edit._alexaAppObjIconsCoords != self._oldAlexaAppObjIconsCoords: self._oldAlexaAppObjIconsCoords = copy.deepcopy(self.edit._alexaAppObjIconsCoords) self.edit.update() if self.edit._alexaAppImgIconsCoords != self._oldAlexaAppImgIconsCoords: self._oldAlexaAppImgIconsCoords = copy.deepcopy(self.edit._alexaAppImgIconsCoords) self.edit.update() if self.edit._alexaAppTextIconsCoords != self._oldAlexaAppTextIconsCoords: self._oldAlexaAppTextIconsCoords = copy.deepcopy(self.edit._alexaAppTextIconsCoords) self.edit.update() if self.edit._alexaLogIconsCoords != self._oldAlexaLogIconsCoords: self._oldAlexaLogIconsCoords = copy.deepcopy(self.edit._alexaLogIconsCoords) self.edit.update() selectedLine = self.edit.textCursor().selectedText() textAtCursorPos = self.edit.textCursor().block().text() try: # tmp = selectedLine.index("# AppObject") if ( pat.match(selectedLine) or patAlexaLog.match(selectedLine) or pat.match(textAtCursorPos) or patAlexaLog.match(textAtCursorPos) or patAlexaAppImage.match(selectedLine) or patAlexaAppImage.match(textAtCursorPos) or patAlexaAppText.match(selectedLine) or patAlexaAppText.match(textAtCursorPos) ) and self._keypress is True: self._keypress = False self.updateAlexaCoords() except: pass QWidget.paintEvent(self, event) """
class Pointer(QGraphicsLineItem): """ QGraphicsPolygonItem to model a Pointer as an Arrow from a Pointer-Variable to its Content. """ fgcolor = QColor(0, 0, 0) bgcolor = QColor(0, 0, 0) def __init__(self, parent, fromView, toView, distributedObjects): """ Constructor @param parent parent for the QGraphicsPolygonItem-Constructor @param fromView datagraph.htmlvariableview.HtmlVariableView, starting point of the Pointer @param toView datagraph.htmlvariableview.HtmlVariableView, end point of the Pointer @param distributedObjects distributedobjects.DistributedObjects, the DistributedObjects-Instance fromView and toView are QGraphicsWebViews """ QGraphicsLineItem.__init__(self, parent) self.fromView = fromView fromView.addOutgoingPointer(self) self.toView = toView toView.addIncomingPointer(self) self.setPen(QPen(self.fgcolor, 1)) self.distributedObjects = distributedObjects self.fromView.geometryChanged.connect(self.updatePosition) self.toView.geometryChanged.connect(self.updatePosition) self.fromView.xChanged.connect(self.updatePosition) self.fromView.yChanged.connect(self.updatePosition) self.toView.xChanged.connect(self.updatePosition) self.toView.yChanged.connect(self.updatePosition) self.fromView.removing.connect(self.delete) self.toView.removing.connect(self.delete) self.arrowhead = QPolygonF() self.arrowSize = 20 self.setZValue( -1) # paint the arrows behind (lower z-value) everything else def boundingRect(self): extra = (self.pen().width() + 20) / 2 return QRectF( self.line().p1(), QSizeF(self.line().p2().x() - self.line().p1().x(), self.line().p2().y() - self.line().p1().y())).normalized().adjusted( -extra, -extra, extra, extra) def shape(self): path = QGraphicsLineItem.shape(self) path.addPolygon(self.arrowhead) return path def updatePosition(self): line = QLineF(self.mapFromItem(self.fromView, 0, 0), self.mapFromItem(self.toView, 0, 0)) self.setLine(line) def paint(self, painter, _1, _2): """ Main-Method of the Pointer-Class <br> calculates/renders/draws the Lines of the Arrow """ if self.fromView.collidesWithItem(self.toView): return # antialiasing makes things look nicer :) painter.setRenderHint(QPainter.Antialiasing) self.toView.x() pM1 = QPointF(self.fromView.x() + self.fromView.size().width() / 2, self.fromView.y() + self.fromView.size().height() / 2) pM2 = QPointF(self.toView.x() + self.toView.size().width() / 2, self.toView.y() + self.toView.size().height() / 2) deltaX = pM2.x() - pM1.x() deltaY = pM2.y() - pM1.y() if deltaX == 0: deltaX = 0.01 if deltaY == 0: deltaY = 0.01 if deltaX >= 0: if deltaY >= 0: # rechts unten if deltaX / deltaY >= self.fromView.size().width( ) / self.fromView.size().height(): # Start von rechter Seite pStart = QPointF( pM1.x() + self.fromView.size().width() / 2, pM1.y() + (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von unterer Seite pStart = QPointF( pM1.x() + (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() + self.fromView.size().height() / 2) if deltaX / deltaY >= self.toView.size().width( ) / self.toView.size().height(): # Ende bei linker Seite pEnd = QPointF( pM2.x() - self.toView.size().width() / 2, pM2.y() - (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei oberer Seite pEnd = QPointF( pM2.x() - (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() - self.toView.size().height() / 2) else: # rechts oben if deltaX / deltaY * -1 >= self.fromView.size().width( ) / self.fromView.size().height(): # Start von rechter Seite pStart = QPointF( pM1.x() + self.fromView.size().width() / 2, pM1.y() + (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von oberer Seite pStart = QPointF( pM1.x() - (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() - self.fromView.size().height() / 2) if deltaX / deltaY * -1 >= self.toView.size().width( ) / self.toView.size().height(): # Ende bei linker Seite pEnd = QPointF( pM2.x() - self.toView.size().width() / 2, pM2.y() - (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei unterer Seite pEnd = QPointF( pM2.x() + (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() + self.toView.size().height() / 2) else: if deltaY >= 0: # links unten if deltaX / deltaY * -1 >= self.fromView.size().width( ) / self.fromView.size().height(): # Start von linker Seite pStart = QPointF( pM1.x() - self.fromView.size().width() / 2, pM1.y() - (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von unterer Seite pStart = QPointF( pM1.x() + (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() + self.fromView.size().height() / 2) if deltaX / deltaY * -1 >= self.toView.size().width( ) / self.toView.size().height(): # Ende bei rechten Seite pEnd = QPointF( pM2.x() + self.toView.size().width() / 2, pM2.y() + (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei oberer Seite pEnd = QPointF( pM2.x() - (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() - self.toView.size().height() / 2) else: # links oben if deltaX / deltaY >= self.fromView.size().width( ) / self.fromView.size().height(): # Start von linker Seite pStart = QPointF( pM1.x() - self.fromView.size().width() / 2, pM1.y() - (self.fromView.size().width() / 2) * (deltaY / deltaX)) else: # Start von oberer Seite pStart = QPointF( pM1.x() - (self.fromView.size().height() / 2) * (deltaX / deltaY), pM1.y() - self.fromView.size().height() / 2) if deltaX / deltaY >= self.toView.size().width( ) / self.toView.size().height(): # Ende bei rechter Seite pEnd = QPointF( pM2.x() + self.toView.size().width() / 2, pM2.y() + (self.toView.size().width() / 2) * (deltaY / deltaX)) else: # Ende bei unterer Seite pEnd = QPointF( pM2.x() + (self.toView.size().height() / 2) * (deltaX / deltaY), pM2.y() + self.toView.size().height() / 2) self.setLine(QLineF(pEnd, pStart)) if self.line().length() != 0: angle = math.acos(self.line().dx() / self.line().length()) if self.line().dy() >= 0: angle = math.pi * 2 - angle arrowP1 = self.line().p1() + QPointF( math.sin(angle + math.pi / 2.5) * self.arrowSize, math.cos(angle + math.pi / 2.5) * self.arrowSize) arrowP2 = self.line().p1() + QPointF( math.sin(angle + math.pi - math.pi / 2.5) * self.arrowSize, math.cos(angle + math.pi - math.pi / 2.5) * self.arrowSize) self.arrowhead.clear() self.arrowhead.append(self.line().p1()) self.arrowhead.append(arrowP1) self.arrowhead.append(arrowP2) painter.setBrush(QBrush(self.bgcolor)) painter.drawLine(self.line()) painter.drawPolygon(self.arrowhead) def delete(self): """ removes the pointer from the DataGraph """ self.toView.incomingPointers.remove(self) self.fromView.outgoingPointers.remove(self) self.distributedObjects.datagraphController.removePointer(self) def setX(self, _): logging.error("Ignoring setting our Pointer's x position") def setY(self, _): logging.error("Ignoring setting our Pointer's y position")
def paintEvent(self, event): page_bottom = self.edit.viewport().height() font_metrics = QFontMetrics(self.edit.document().defaultFont()) current_block = self.edit.document().findBlock( self.edit.textCursor().position()) if self._firstPaintEvent is True: self.jumpedUP = False self.strings = self.edit.toPlainText().split('\n') self._originalTotalLine = len(self.strings) self.edit.jump_to_line(len(self.strings) - 2) elif self.jumpedUP is False: self.edit.jump_to_line(1) self.edit.verticalScrollBar().setValue(0) self.jumpedUP = True return pattern = self.pat if self.edit.lang == "python" else self.patNotPython painter = QPainter(self) background = resources.CUSTOM_SCHEME.get( 'sidebar-background', resources.COLOR_SCHEME['sidebar-background']) foreground = resources.CUSTOM_SCHEME.get( 'sidebar-foreground', resources.COLOR_SCHEME['sidebar-foreground']) pep8color = resources.CUSTOM_SCHEME.get( 'pep8-underline', resources.COLOR_SCHEME['pep8-underline']) errorcolor = resources.CUSTOM_SCHEME.get( 'error-underline', resources.COLOR_SCHEME['error-underline']) migrationcolor = resources.CUSTOM_SCHEME.get( 'migration-underline', resources.COLOR_SCHEME['migration-underline']) painter.fillRect(self.rect(), QColor(background)) ''' if self._firstPaintEvent is True: block = self.edit.document().findBlock(0) else: block = self.edit.firstVisibleBlock() ''' block = self.edit.firstVisibleBlock() viewport_offset = self.edit.contentOffset() line_count = block.blockNumber() painter.setFont(self.edit.document().defaultFont()) pat = re.compile('\s*#.*AppObject:') patAlexaAppImage = re.compile('\s*#.*AppImage:') patAlexaAppText = re.compile('\s*#.*AppText:') patAlexaLog = re.compile('\s*##.*Alexa Log') while block.isValid(): line_count += 1 # The top left position of the block in the document position = self.edit.blockBoundingGeometry(block).topLeft() + \ viewport_offset # Check if the position of the block is outside of the visible area if position.y() > page_bottom: break # Set the Painter Pen depending on special lines error = False if settings.CHECK_STYLE and \ ((line_count - 1) in self._pep8Lines): painter.setPen(QColor(pep8color)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.FIND_ERRORS and \ ((line_count - 1) in self._errorsLines): painter.setPen(QColor(errorcolor)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True elif settings.SHOW_MIGRATION_TIPS and \ ((line_count - 1) in self._migrationLines): painter.setPen(QColor(migrationcolor)) font = painter.font() font.setItalic(True) font.setUnderline(True) painter.setFont(font) error = True else: painter.setPen(QColor(foreground)) # We want the line number for the selected line to be bold. bold = False if block == current_block: bold = True font = painter.font() font.setBold(True) painter.setFont(font) # Draw the line number right justified at the y position of the # line. 3 is a magic padding number. drawText(x, y, text). if block.isVisible(): painter.drawText( self.width() - self.foldArea - font_metrics.width(str(line_count)) - 3, round(position.y()) + font_metrics.ascent() + font_metrics.descent() - 1, str(line_count)) # Remove the bold style if it was set previously. if bold: font = painter.font() font.setBold(False) painter.setFont(font) if error: font = painter.font() font.setItalic(False) font.setUnderline(False) painter.setFont(font) block = block.next() self.highest_line = line_count #Code Folding xofs = self.width() - self.foldArea painter.fillRect( xofs, 0, self.foldArea, self.height(), QColor( resources.CUSTOM_SCHEME.get( 'fold-area', resources.COLOR_SCHEME['fold-area']))) if self.foldArea != self.rightArrowIcon.width(): polygon = QPolygonF() self.rightArrowIcon = QPixmap(self.foldArea, self.foldArea) self.rightArrowIcon.fill(Qt.transparent) self.downArrowIcon = QPixmap(self.foldArea, self.foldArea) self.downArrowIcon.fill(Qt.transparent) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.25)) polygon.append(QPointF(self.foldArea * 0.4, self.foldArea * 0.75)) polygon.append(QPointF(self.foldArea * 0.8, self.foldArea * 0.5)) iconPainter = QPainter(self.rightArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush( QColor( resources.CUSTOM_SCHEME.get( 'fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) polygon.clear() polygon.append(QPointF(self.foldArea * 0.25, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.75, self.foldArea * 0.4)) polygon.append(QPointF(self.foldArea * 0.5, self.foldArea * 0.8)) iconPainter = QPainter(self.downArrowIcon) iconPainter.setRenderHint(QPainter.Antialiasing) iconPainter.setPen(Qt.NoPen) iconPainter.setBrush( QColor( resources.CUSTOM_SCHEME.get( 'fold-arrow', resources.COLOR_SCHEME['fold-arrow']))) iconPainter.drawPolygon(polygon) if self._firstPaintEvent is True: block = self.edit.document().findBlock(0) else: block = self.edit.firstVisibleBlock() #block = self.edit.firstVisibleBlock() line_count = block.blockNumber() while block.isValid(): #while line_count < 5000: line_count += 1 position = self.edit.blockBoundingGeometry( block).topLeft() + viewport_offset #Check if the position of the block is outside of the visible area if position.y() > page_bottom: break #block.isVisible() and if block.isVisible() and pat.match( block.text()) and block not in self._foldedAlexaObject: self._fold(line_count) self._foldedAlexaObject.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaAppImage.match( block.text()) and block not in self._foldedAlexaImage: self._fold(line_count) self._foldedAlexaImage.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaAppText.match( block.text()) and block not in self._foldedAlexaText: self._fold(line_count) self._foldedAlexaText.append(block) self._alexaObjectsPresent = True elif block.isVisible() and patAlexaLog.match( block.text()) and block not in self._foldedAlexaLog: self._fold(line_count) self._foldedAlexaLog.append(block) self._alexaObjectsPresent = True elif pattern.match(block.text()) and block.isVisible(): if block.blockNumber() in self._foldedBlocks: painter.drawPixmap(xofs, round(position.y()), self.rightArrowIcon) else: #block.setVisible(True) painter.drawPixmap(xofs, round(position.y()), self.downArrowIcon) #Add Bookmarks and Breakpoint elif block.blockNumber() in self._breakpoints: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(255, 11, 11)) linear_gradient.setColorAt(1, QColor(147, 9, 9)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawEllipse(xofs + 1, round(position.y()) + 6, self.foldArea - 1, self.foldArea - 1) elif block.blockNumber() in self._bookmarks: linear_gradient = QLinearGradient( xofs, round(position.y()), xofs + self.foldArea, round(position.y()) + self.foldArea) linear_gradient.setColorAt(0, QColor(13, 62, 243)) linear_gradient.setColorAt(1, QColor(5, 27, 106)) painter.setRenderHints(QPainter.Antialiasing, True) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(linear_gradient)) painter.drawRoundedRect(xofs + 1, round(position.y()) + 6, self.foldArea - 2, self.foldArea - 1, 3, 3) block = block.next() block = self.edit.document().findBlock(0) line_count = 0 line_hidden = 0 while block.isValid(): line_count += 1 if not block.isVisible(): line_hidden += 1 block = block.next() endScrollBar = line_count - line_hidden self.edit.verticalScrollBar().setRange(0, endScrollBar) if self._firstPaintEvent is True: self._firstPaintEvent = False #self.updateAlexaAppObjCoords() #self.updateAlexaLogCoords() painter.end() ''' #self.edit.update() if self.edit.verticalScrollBar().value() != self._oldVerticalScrollbarPosition and self._alexaObjectsPresent is True: self._oldVerticalScrollbarPosition = self.edit.verticalScrollBar().value() self.updateAlexaCoords() self.edit.update() # in this way we can refresh alexa icon position if self.edit.horizontalScrollBar().value() != self._oldHorizontalScrollbarPosition and self._alexaObjectsPresent is True: self._oldHorizontalScrollbarPosition = self.edit.horizontalScrollBar().value() self.updateAlexaCoords() self.edit.update() # in this way we can refresh alexa icon position ''' self.strings = self.edit.toPlainText().split('\n') self._currentTotalLine = len(self.strings) if self._currentTotalLine != self._originalTotalLine: self._originalTotalLine = self._currentTotalLine self.updateAlexaCoords() self.edit.update() ''' if self._returnPressed is True: self._returnPressed = False self.updateAlexaAppObjCoords() self.updateAlexaLogCoords() self.edit.update() if self._backspacePressed is True: self._backspacePressed = False self.strings = self.edit.toPlainText().split('\n') self._currentTotalLine = len(self.strings) if self._currentTotalLine != self._originalTotalLine: self.updateAlexaAppObjCoords() self.updateAlexaLogCoords() self.edit.update() ''' if self.edit._alexaAppObjIconsCoords != self._oldAlexaAppObjIconsCoords: self._oldAlexaAppObjIconsCoords = copy.deepcopy( self.edit._alexaAppObjIconsCoords) self.edit.update() if self.edit._alexaAppImgIconsCoords != self._oldAlexaAppImgIconsCoords: self._oldAlexaAppImgIconsCoords = copy.deepcopy( self.edit._alexaAppImgIconsCoords) self.edit.update() if self.edit._alexaAppTextIconsCoords != self._oldAlexaAppTextIconsCoords: self._oldAlexaAppTextIconsCoords = copy.deepcopy( self.edit._alexaAppTextIconsCoords) self.edit.update() if self.edit._alexaLogIconsCoords != self._oldAlexaLogIconsCoords: self._oldAlexaLogIconsCoords = copy.deepcopy( self.edit._alexaLogIconsCoords) self.edit.update() selectedLine = self.edit.textCursor().selectedText() textAtCursorPos = self.edit.textCursor().block().text() try: #tmp = selectedLine.index("# AppObject") if (pat.match(selectedLine) or patAlexaLog.match(selectedLine) or \ pat.match(textAtCursorPos) or patAlexaLog.match(textAtCursorPos) or \ patAlexaAppImage.match(selectedLine) or patAlexaAppImage.match(textAtCursorPos) or\ patAlexaAppText.match(selectedLine) or patAlexaAppText.match(textAtCursorPos)) and \ self._keypress is True: self._keypress = False self.updateAlexaCoords() except: pass QWidget.paintEvent(self, event) '''
class PositionMarker(QgsMapCanvasItem): ''' MapCanvasItem for showing the MobileItem on the MapCanvas Can have different appearences, fixed ones like corss, x or box or a userdefined shape. Can display also a label on the canvas ''' def __init__(self, canvas, params={}): ''' Constructor :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface :param params: A dictionary defining all the properties of the position marker :type params: dictionary ''' self.canvas = canvas self.type = params.get('type', 'BOX').upper() self.size = int(params.get('size', 16)) self.showLabel = bool(params.get('showLabel', True)) s = (self.size - 1) / 2 self.length = float(params.get('length', 98.0)) self.width = float(params.get('width', 17.0)) self.offsetX = float(params.get('offsetX', 0.0)) self.offsetY = float(params.get('offsetY', 0.0)) self.shape = params.get('shape', ((0.0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.50), (-0.5, -0.3))) self.paintShape = QPolygonF( [QPointF(-s, -s), QPointF(s, -s), QPointF(s, s), QPointF(-s, s)]) self.color = self.getColor(params.get('color', 'black')) self.fillColor = self.getColor(params.get('fillColor', 'lime')) self.penWidth = int(params.get('penWidth', 1)) spw = s + self.penWidth + 1 self.bounding = QRectF(-spw, -spw, spw * 2, spw * 2) if self.type in ('CROSS', 'X'): self.penWidth = 5 self.trackLen = int(params.get('trackLength', 100)) self.trackColor = self.getColor( params.get('trackColor', self.fillColor)) self.track = deque() self.position = None self.heading = 0 super(PositionMarker, self).__init__(canvas) self.setZValue(int(params.get('zValue', 100))) self.distArea = QgsDistanceArea() self.distArea.setEllipsoid(u'WGS84') self.distArea.setEllipsoidalMode(True) if self.showLabel: self.label = MarkerLabel(self.canvas, params) self.label.setZValue(self.zValue() + 0.1) self.updateSize() def properties(self): return { 'type': self.type, 'size': self.size, 'length': self.length, 'width': self.width, 'offsetX': self.offsetX, 'offsetY': self.offsetY, 'shape': self.shape, 'color': self.color.rgba(), 'fillColor': self.fillColor.rgba(), 'penWidth': self.penWidth, 'trackLength': self.trackLen, 'trackColor': self.trackColor.rgba(), 'zValue': self.zValue(), 'showLabel': self.showLabel } def setMapPosition(self, pos): if self.position != pos: self.updateTrack() self.position = pos self.setPos(self.toCanvasCoordinates(self.position)) if self.showLabel: self.label.setMapPosition(pos) self.update() def newHeading(self, heading): if self.heading != heading: self.heading = heading self.setRotation(self.canvas.rotation() + self.heading) self.update() def resetPosition(self): self.position = None if self.showLabel: self.label.resetPoition() def updatePosition(self): if self.position: self.prepareGeometryChange() self.updateSize() self.setPos(self.toCanvasCoordinates(self.position)) self.setRotation(self.canvas.rotation() + self.heading) def updateMapMagnification(self): self.updatePosition() if self.showLabel: self.label.updatePosition() for tp in self.track: tp[0].updatePosition() def updateSize(self): if self.type != 'SHAPE': return s = self.canvas.mapSettings() self.distArea.setSourceCrs(s.destinationCrs()) try: p1 = self.toMapCoordinates(QPoint(0, 0)) p2 = self.toMapCoordinates(QPoint(0, 100)) l = self.distArea.measureLine(p1, p2) f = 100 / l except: f = s.outputDpi() / 0.0254 / s.scale() paintLength = max(self.length * f, 50) paintWidth = paintLength * self.width / self.length offsY = self.offsetX / self.length * paintLength offsX = self.offsetY / self.width * paintWidth self.paintShape.clear() for v in self.shape: self.paintShape << QPointF(v[0] * paintWidth - offsX, v[1] * paintLength + offsY) self.size = max(paintLength, paintWidth) self.bounding = self.paintShape.boundingRect() def newTrackPoint(self, pos): tp = QgsVertexMarker(self.canvas) tp.setCenter(pos) tp.setIconType(QgsVertexMarker.ICON_CROSS) tp.setColor(self.trackColor) tp.setZValue(self.zValue() - 0.1) tp.setIconSize(3) tp.setPenWidth(3) return tp def updateTrack(self): if self.position and self.trackLen: if len(self.track) >= self.trackLen: tpr = self.track.popleft() self.canvas.scene().removeItem(tpr[0]) del (tpr) tp = self.newTrackPoint(self.position) self.track.append((tp, self.position)) def setVisible(self, visible): for tp in self.track: tp[0].setVisible(visible) QgsMapCanvasItem.setVisible(self, visible) if self.showLabel: self.label.setVisible(visible) def deleteTrack(self): for tp in self.track: self.canvas.scene().removeItem(tp[0]) self.track.clear() def setTrack(self, track): self.track.clear() for tp in track: tpn = self.newTrackPoint(tp) self.track.append((tpn, tp)) def paint(self, painter, xxx, xxx2): if not self.position: return s = (self.size - 1) / 2 pen = QPen(self.color) pen.setWidth(self.penWidth) painter.setPen(pen) if self.type == 'CROSS': painter.drawLine(QLineF(-s, 0, s, 0)) painter.drawLine(QLineF(0, -s, 0, s)) elif self.type == 'X': painter.drawLine(QLineF(-s, -s, s, s)) painter.drawLine(QLineF(-s, s, s, -s)) elif self.type == 'BOX': brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) elif self.type == 'SHAPE': painter.setRenderHint(QPainter.Antialiasing, True) brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) def boundingRect(self): return self.bounding def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) def removeFromCanvas(self): self.deleteTrack() if self.showLabel: self.canvas.scene().removeItem(self.label) self.canvas.scene().removeItem(self)