20 #include <QGraphicsScene>
21 #include <QGraphicsSceneMouseEvent>
22 #include <QGraphicsView>
36 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
40 , QGraphicsRectItem( 0 )
41 , mComposition( composition )
42 , mBoundingResizeRectangle( 0 )
44 , mItemPositionLocked( false )
45 , mLastValidViewScaleFactor( -1 )
48 setFlag( QGraphicsItem::ItemIsSelectable,
true );
49 setAcceptsHoverEvents(
true );
52 setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
53 QPen defaultPen( QColor( 0, 0, 0 ) );
54 defaultPen.setWidthF( 0.3 );
66 , QGraphicsRectItem( 0, 0, width, height, 0 )
67 , mComposition( composition )
68 , mBoundingResizeRectangle( 0 )
70 , mItemPositionLocked( false )
71 , mLastValidViewScaleFactor( -1 )
74 setFlag( QGraphicsItem::ItemIsSelectable,
true );
75 setAcceptsHoverEvents(
true );
82 setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
83 QPen defaultPen( QColor( 0, 0, 0 ) );
84 defaultPen.setWidthF( 0.3 );
119 if ( itemElem.isNull() )
124 QDomElement composerItemElem = doc.createElement(
"ComposerItem" );
129 composerItemElem.setAttribute(
"frame",
"true" );
133 composerItemElem.setAttribute(
"frame",
"false" );
137 composerItemElem.setAttribute(
"x", transform().dx() );
138 composerItemElem.setAttribute(
"y", transform().dy() );
139 composerItemElem.setAttribute(
"width", rect().width() );
140 composerItemElem.setAttribute(
"height", rect().height() );
141 composerItemElem.setAttribute(
"zValue", QString::number( zValue() ) );
142 composerItemElem.setAttribute(
"outlineWidth", QString::number( pen().widthF() ) );
143 composerItemElem.setAttribute(
"rotation",
mRotation );
148 composerItemElem.setAttribute(
"positionLock",
"true" );
152 composerItemElem.setAttribute(
"positionLock",
"false" );
159 QDomElement frameColorElem = doc.createElement(
"FrameColor" );
160 QColor frameColor = pen().color();
161 frameColorElem.setAttribute(
"red", QString::number( frameColor.red() ) );
162 frameColorElem.setAttribute(
"green", QString::number( frameColor.green() ) );
163 frameColorElem.setAttribute(
"blue", QString::number( frameColor.blue() ) );
164 frameColorElem.setAttribute(
"alpha", QString::number( frameColor.alpha() ) );
165 composerItemElem.appendChild( frameColorElem );
168 QDomElement bgColorElem = doc.createElement(
"BackgroundColor" );
169 QColor bgColor = brush().color();
170 bgColorElem.setAttribute(
"red", QString::number( bgColor.red() ) );
171 bgColorElem.setAttribute(
"green", QString::number( bgColor.green() ) );
172 bgColorElem.setAttribute(
"blue", QString::number( bgColor.blue() ) );
173 bgColorElem.setAttribute(
"alpha", QString::number( bgColor.alpha() ) );
174 composerItemElem.appendChild( bgColorElem );
176 itemElem.appendChild( composerItemElem );
183 if ( itemElem.isNull() )
189 mRotation = itemElem.attribute(
"rotation",
"0" ).toDouble();
192 QString
frame = itemElem.attribute(
"frame" );
193 if ( frame.compare(
"true", Qt::CaseInsensitive ) == 0 )
203 QString
positionLock = itemElem.attribute(
"positionLock" );
204 if ( positionLock.compare(
"true", Qt::CaseInsensitive ) == 0 )
214 double x, y, width, height;
215 bool xOk, yOk, widthOk, heightOk;
217 x = itemElem.attribute(
"x" ).toDouble( &xOk );
218 y = itemElem.attribute(
"y" ).toDouble( &yOk );
219 width = itemElem.attribute(
"width" ).toDouble( &widthOk );
220 height = itemElem.attribute(
"height" ).toDouble( &heightOk );
222 if ( !xOk || !yOk || !widthOk || !heightOk )
230 setZValue( itemElem.attribute(
"zValue" ).toDouble() );
233 QDomNodeList frameColorList = itemElem.elementsByTagName(
"FrameColor" );
234 if ( frameColorList.size() > 0 )
236 QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
237 bool redOk, greenOk, blueOk, alphaOk, widthOk;
238 int penRed, penGreen, penBlue, penAlpha;
241 penWidth = itemElem.attribute(
"outlineWidth" ).toDouble( &widthOk );
242 penRed = frameColorElem.attribute(
"red" ).toDouble( &redOk );
243 penGreen = frameColorElem.attribute(
"green" ).toDouble( &greenOk );
244 penBlue = frameColorElem.attribute(
"blue" ).toDouble( &blueOk );
245 penAlpha = frameColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
246 if ( redOk && greenOk && blueOk && alphaOk && widthOk )
248 QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
249 framePen.setWidthF( penWidth );
255 QDomNodeList bgColorList = itemElem.elementsByTagName(
"BackgroundColor" );
256 if ( bgColorList.size() > 0 )
258 QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
259 bool redOk, greenOk, blueOk, alphaOk;
260 int bgRed, bgGreen, bgBlue, bgAlpha;
261 bgRed = bgColorElem.attribute(
"red" ).toDouble( &redOk );
262 bgGreen = bgColorElem.attribute(
"green" ).toDouble( &greenOk );
263 bgBlue = bgColorElem.attribute(
"blue" ).toDouble( &blueOk );
264 bgAlpha = bgColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
265 if ( redOk && greenOk && blueOk && alphaOk )
267 QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
268 setBrush( QBrush( brushColor ) );
338 QTransform resizeTransform;
339 resizeTransform.translate( transform().dx(), transform().dy() );
364 QPointF mouseMoveStopPoint =
event->lastScenePos();
380 setCursor( Qt::ArrowCursor );
389 return Qt::ForbiddenCursor;
393 return Qt::ClosedHandCursor;
397 return Qt::SizeFDiagCursor;
401 return Qt::SizeBDiagCursor;
405 return Qt::SizeVerCursor;
409 return Qt::SizeHorCursor;
422 bool nearLeftBorder =
false;
423 bool nearRightBorder =
false;
424 bool nearLowerBorder =
false;
425 bool nearUpperBorder =
false;
429 if ( itemCoordPos.x() < borderTolerance )
431 nearLeftBorder =
true;
433 if ( itemCoordPos.y() < borderTolerance )
435 nearUpperBorder =
true;
437 if ( itemCoordPos.x() > ( rect().width() - borderTolerance ) )
439 nearRightBorder =
true;
441 if ( itemCoordPos.y() > ( rect().height() - borderTolerance ) )
443 nearLowerBorder =
true;
446 if ( nearLeftBorder && nearUpperBorder )
450 else if ( nearLeftBorder && nearLowerBorder )
454 else if ( nearRightBorder && nearUpperBorder )
458 else if ( nearRightBorder && nearLowerBorder )
462 else if ( nearLeftBorder )
466 else if ( nearRightBorder )
470 else if ( nearUpperBorder )
474 else if ( nearLowerBorder )
482 void QgsComposerItem::changeItemRectangle(
const QPointF& currentPosition,
const QPointF& mouseMoveStartPos,
const QGraphicsRectItem* originalItem,
double dx,
double dy, QGraphicsRectItem* changeItem )
492 double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
503 diffY = snappedPosition.y() - originalItem->transform().dy();
504 mx = 0; my = diffY; rx = 0; ry = -diffY;
508 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
509 mx = 0; my = 0; rx = 0; ry = diffY;
514 diffX = snappedPosition.x() - originalItem->transform().dx();
515 mx = diffX, my = 0; rx = -diffX; ry = 0;
519 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
520 mx = 0; my = 0; rx = diffX, ry = 0;
525 diffX = snappedPosition.x() - originalItem->transform().dx();
526 diffY = snappedPosition.y() - originalItem->transform().dy();
527 mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
531 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
532 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
533 mx = 0; my = 0; rx = diffX, ry = diffY;
537 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
538 diffY = snappedPosition.y() - originalItem->transform().dy();
539 mx = 0; my = diffY, rx = diffX, ry = -diffY;
543 diffX = snappedPosition.x() - originalItem->transform().dx();
544 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
545 mx = diffX, my = 0; rx = -diffX; ry = diffY;
551 double moveX = currentPosition.x() - mouseMoveStartPos.x();
552 double moveY = currentPosition.y() - mouseMoveStartPos.y();
554 QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY );
557 double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
558 double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();
560 if ( !changeComposerItem )
562 QTransform moveTransform;
563 moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY );
564 changeItem->setTransform( moveTransform );
568 changeComposerItem->
setSceneRect( QRectF( originalItem->transform().dx() + moveRectX,
569 originalItem->transform().dy() + moveRectY,
570 originalItem->rect().width(), originalItem->rect().height() ) );
578 if ( !changeComposerItem )
580 QTransform itemTransform;
581 itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my );
582 changeItem->setTransform( itemTransform );
583 QRectF itemRect( 0, 0, originalItem->rect().width() + rx, originalItem->rect().height() + ry );
584 changeItem->setRect( itemRect );
588 changeComposerItem->
setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my,
589 originalItem->rect().width() + rx, originalItem->rect().height() + ry ) );
610 if ( !QFile::exists( lockIconPath ) )
615 QImage lockImage( lockIconPath );
616 if ( !lockImage.isNull() )
618 p->drawImage( QRectF( 0, 0, sizeLockSymbol, sizeLockSymbol ), lockImage, QRectF( 0, 0, lockImage.width(), lockImage.height() ) );
623 p->setPen( QColor( 50, 100, 120, 200 ) );
624 p->setBrush( QColor( 200, 200, 210, 120 ) );
625 p->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
626 p->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
627 p->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
628 p->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
638 p->setBrush( Qt::NoBrush );
639 p->setRenderHint( QPainter::Antialiasing,
true );
640 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
646 QTransform t = transform();
647 QRectF newSceneRect( t.dx() + dx, t.dy() + dy, rect().width(), rect().height() );
653 double width = rect().width();
654 double height = rect().height();
660 double upperLeftX = x;
661 double upperLeftY = y;
666 upperLeftX -= width / 2.0;
676 upperLeftY -= height / 2.0;
680 upperLeftY -= height;
683 setSceneRect( QRectF( upperLeftX, upperLeftY, width, height ) );
689 double newWidth = rectangle.width();
690 double newHeight = rectangle.height();
691 double xTranslation = rectangle.x();
692 double yTranslation = rectangle.y();
695 if ( rectangle.width() < 0 )
697 newWidth = - rectangle.width();
698 xTranslation -= newWidth;
701 if ( rectangle.height() < 0 )
703 newHeight = - rectangle.height();
704 yTranslation -= newHeight;
707 QRectF newRect( 0, 0, newWidth, newHeight );
708 QGraphicsRectItem::setRect( newRect );
712 t.translate( xTranslation, yTranslation );
720 p->setBrush( brush() );
721 p->setPen( Qt::NoPen );
722 p->setRenderHint( QPainter::Antialiasing,
true );
723 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
740 p->setFont( textFont );
741 p->setPen( QColor( 0, 0, 0 ) );
743 p->scale( scaleFactor, scaleFactor );
748 void QgsComposerItem::drawText( QPainter* p,
const QRectF& rect,
const QString& text,
const QFont& font, Qt::AlignmentFlag halignement, Qt::AlignmentFlag valignment )
const
756 p->setFont( textFont );
758 p->scale( scaleFactor, scaleFactor );
759 p->drawText( scaledRect, halignement | valignment | Qt::TextWordWrap, text );
768 double angleRad = angle / 180.0 *
M_PI;
769 QPointF middlePoint( x, y );
771 QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
772 QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
774 QPointF p1Rotated, p2Rotated;
775 p1Rotated.setX( p1.x() * cos( angleRad ) + p1.y() * -sin( angleRad ) );
776 p1Rotated.setY( p1.x() * sin( angleRad ) + p1.y() * cos( angleRad ) );
777 p2Rotated.setX( p2.x() * cos( angleRad ) + p2.y() * -sin( angleRad ) );
778 p2Rotated.setY( p2.x() * sin( angleRad ) + p2.y() * cos( angleRad ) );
780 QPolygonF arrowHeadPoly;
781 arrowHeadPoly << middlePoint;
782 arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
783 arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
787 QPen arrowPen = p->pen();
788 arrowPen.setJoinStyle( Qt::RoundJoin );
789 QBrush arrowBrush = p->brush();
790 arrowBrush.setStyle( Qt::SolidPattern );
791 p->setPen( arrowPen );
792 p->setBrush( arrowBrush );
793 arrowBrush.setStyle( Qt::SolidPattern );
794 p->drawPolygon( arrowHeadPoly );
802 QFontMetrics fontMetrics( metricsFont );
809 QFontMetricsF fontMetrics( metricsFont );
816 QFontMetricsF fontMetrics( metricsFont );
822 return ( pointSize * 0.3527 );
827 QFont scaledFont = font;
829 scaledFont.setPixelSize( pixelSize );
835 double xDiff = p2.x() - p1.x();
836 double yDiff = p2.y() - p1.y();
837 double length = sqrt( xDiff * xDiff + yDiff * yDiff );
843 double angle = acos(( -yDiff * length ) / ( length * length ) ) * 180 /
M_PI;
846 return ( 360 - angle );
856 QList<QGraphicsView*> viewList = scene()->views();
857 if ( viewList.size() > 0 )
859 QGraphicsView* currentView = viewList.at( 0 );
860 if ( currentView->isVisible() )
862 result = currentView->transform().m11();
874 double rectHandlerSize = 10.0 / viewScaleFactor;
877 if ( rectHandlerSize > ( rect().width() / 3 ) )
879 rectHandlerSize = rect().width() / 3;
881 if ( rectHandlerSize > ( rect().height() / 3 ) )
883 rectHandlerSize = rect().height() / 3;
885 return rectHandlerSize;
892 if ( lockSymbolSize > ( rect().width() / 3 ) )
894 lockSymbolSize = rect().width() / 3;
896 if ( lockSymbolSize > ( rect().height() / 3 ) )
898 lockSymbolSize = rect().height() / 3;
937 double midX = width / 2.0;
938 double midY = height / 2.0;
959 double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
962 if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
964 width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
965 height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
970 double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
973 width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
974 height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
999 width = sqrt(( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
1000 height = sqrt(( x3 - x2 ) * ( x3 - x2 ) + ( y3 - y2 ) * ( y3 - y2 ) );
1009 QPointF midpoint( width / 2.0, height / 2.0 );
1010 double xVector = x - midpoint.x();
1011 double yVector = y - midpoint.y();
1014 double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1015 double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1018 QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1021 QList<QLineF> borders;
1022 borders << QLineF( 0, 0, width, 0 );
1023 borders << QLineF( width, 0, width, height );
1024 borders << QLineF( width, height, 0, height );
1025 borders << QLineF( 0, height, 0, 0 );
1027 QList<QLineF>::const_iterator it = borders.constBegin();
1028 QPointF intersectionPoint;
1030 for ( ; it != borders.constEnd(); ++it )
1032 if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1034 x = intersectionPoint.x();
1035 y = intersectionPoint.y();
1044 double dx = directionPoint.x() - startPoint.x();
1045 double dy = directionPoint.y() - startPoint.y();
1046 double length = sqrt( dx * dx + dy * dy );
1047 double scaleFactor = distance / length;
1048 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
1059 double x1 = -width / 2.0;
1060 double y1 = -height / 2.0;
1063 double x2 = width / 2.0;
1064 double y2 = -height / 2.0;
1067 double x3 = width / 2.0;
1068 double y3 = height / 2.0;
1071 double x4 = -width / 2.0;
1072 double y4 = height / 2.0;
1076 QPointF midpoint( width / 2.0, height / 2.0 );
1078 QPolygonF rotatedRectPoly;
1079 rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1080 rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1081 rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1082 rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1083 QRectF boundingRect = rotatedRectPoly.boundingRect();
1084 width = boundingRect.width();
1085 height = boundingRect.height();
1090 double rotToRad = angle *
M_PI / 180.0;
1092 xRot = x * cos( rotToRad ) - y * sin( rotToRad );
1093 yRot = x * sin( rotToRad ) + y * cos( rotToRad );