20 #include <QGraphicsLineItem>
21 #include <QGraphicsScene>
22 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsView>
26 #include <QGraphicsEffect>
43 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
47 , QGraphicsRectItem( 0 )
48 , mComposition( composition )
49 , mBoundingResizeRectangle( 0 )
50 , mHAlignSnapItem( 0 )
51 , mVAlignSnapItem( 0 )
54 , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
55 , mItemPositionLocked( false )
56 , mLastValidViewScaleFactor( -1 )
58 , mBlendMode( QPainter::CompositionMode_SourceOver )
59 , mEffectsEnabled( true )
61 , mLastUsedPositionMode( UpperLeft )
63 , mUuid( QUuid::createUuid().toString() )
70 , QGraphicsRectItem( 0, 0, width, height, 0 )
71 , mComposition( composition )
72 , mBoundingResizeRectangle( 0 )
73 , mHAlignSnapItem( 0 )
74 , mVAlignSnapItem( 0 )
77 , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
78 , mItemPositionLocked( false )
79 , mLastValidViewScaleFactor( -1 )
81 , mBlendMode( QPainter::CompositionMode_SourceOver )
82 , mEffectsEnabled( true )
84 , mLastUsedPositionMode( UpperLeft )
86 , mUuid( QUuid::createUuid().toString() )
96 setFlag( QGraphicsItem::ItemIsSelectable,
true );
97 setAcceptsHoverEvents(
true );
99 setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
100 QPen defaultPen( QColor( 0, 0, 0 ) );
101 defaultPen.setWidthF( 0.3 );
102 setPen( defaultPen );
141 if ( itemElem.isNull() )
146 QDomElement composerItemElem = doc.createElement(
"ComposerItem" );
151 composerItemElem.setAttribute(
"frame",
"true" );
155 composerItemElem.setAttribute(
"frame",
"false" );
161 composerItemElem.setAttribute(
"background",
"true" );
165 composerItemElem.setAttribute(
"background",
"false" );
169 composerItemElem.setAttribute(
"x", QString::number( transform().dx() ) );
170 composerItemElem.setAttribute(
"y", QString::number( transform().dy() ) );
171 composerItemElem.setAttribute(
"width", QString::number( rect().width() ) );
172 composerItemElem.setAttribute(
"height", QString::number( rect().height() ) );
174 composerItemElem.setAttribute(
"zValue", QString::number( zValue() ) );
175 composerItemElem.setAttribute(
"outlineWidth", QString::number( pen().widthF() ) );
176 composerItemElem.setAttribute(
"rotation", QString::number(
mRotation ) );
177 composerItemElem.setAttribute(
"uuid",
mUuid );
178 composerItemElem.setAttribute(
"id",
mId );
182 composerItemElem.setAttribute(
"positionLock",
"true" );
186 composerItemElem.setAttribute(
"positionLock",
"false" );
193 QDomElement frameColorElem = doc.createElement(
"FrameColor" );
194 QColor frameColor = pen().color();
195 frameColorElem.setAttribute(
"red", QString::number( frameColor.red() ) );
196 frameColorElem.setAttribute(
"green", QString::number( frameColor.green() ) );
197 frameColorElem.setAttribute(
"blue", QString::number( frameColor.blue() ) );
198 frameColorElem.setAttribute(
"alpha", QString::number( frameColor.alpha() ) );
199 composerItemElem.appendChild( frameColorElem );
202 QDomElement bgColorElem = doc.createElement(
"BackgroundColor" );
203 QColor bgColor = brush().color();
204 bgColorElem.setAttribute(
"red", QString::number( bgColor.red() ) );
205 bgColorElem.setAttribute(
"green", QString::number( bgColor.green() ) );
206 bgColorElem.setAttribute(
"blue", QString::number( bgColor.blue() ) );
207 bgColorElem.setAttribute(
"alpha", QString::number( bgColor.alpha() ) );
208 composerItemElem.appendChild( bgColorElem );
214 composerItemElem.setAttribute(
"transparency", QString::number(
mTransparency ) );
216 itemElem.appendChild( composerItemElem );
224 if ( itemElem.isNull() )
230 mRotation = itemElem.attribute(
"rotation",
"0" ).toDouble();
233 mUuid = itemElem.attribute(
"uuid", QUuid::createUuid().toString() );
239 QString
id = itemElem.attribute(
"id",
"" );
243 QString frame = itemElem.attribute(
"frame" );
244 if ( frame.compare(
"true", Qt::CaseInsensitive ) == 0 )
254 QString background = itemElem.attribute(
"background" );
255 if ( background.compare(
"true", Qt::CaseInsensitive ) == 0 )
265 QString
positionLock = itemElem.attribute(
"positionLock" );
266 if ( positionLock.compare(
"true", Qt::CaseInsensitive ) == 0 )
276 double x, y, width, height;
277 bool xOk, yOk, widthOk, heightOk, positionModeOK;
279 x = itemElem.attribute(
"x" ).toDouble( &xOk );
280 y = itemElem.attribute(
"y" ).toDouble( &yOk );
281 width = itemElem.attribute(
"width" ).toDouble( &widthOk );
282 height = itemElem.attribute(
"height" ).toDouble( &heightOk );
284 if ( !positionModeOK )
289 if ( !xOk || !yOk || !widthOk || !heightOk )
297 setZValue( itemElem.attribute(
"zValue" ).toDouble() );
300 QDomNodeList frameColorList = itemElem.elementsByTagName(
"FrameColor" );
301 if ( frameColorList.size() > 0 )
303 QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
304 bool redOk, greenOk, blueOk, alphaOk, widthOk;
305 int penRed, penGreen, penBlue, penAlpha;
308 penWidth = itemElem.attribute(
"outlineWidth" ).toDouble( &widthOk );
309 penRed = frameColorElem.attribute(
"red" ).toDouble( &redOk );
310 penGreen = frameColorElem.attribute(
"green" ).toDouble( &greenOk );
311 penBlue = frameColorElem.attribute(
"blue" ).toDouble( &blueOk );
312 penAlpha = frameColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
313 if ( redOk && greenOk && blueOk && alphaOk && widthOk )
315 QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
316 framePen.setWidthF( penWidth );
322 QDomNodeList bgColorList = itemElem.elementsByTagName(
"BackgroundColor" );
323 if ( bgColorList.size() > 0 )
325 QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
326 bool redOk, greenOk, blueOk, alphaOk;
327 int bgRed, bgGreen, bgBlue, bgAlpha;
328 bgRed = bgColorElem.attribute(
"red" ).toDouble( &redOk );
329 bgGreen = bgColorElem.attribute(
"green" ).toDouble( &greenOk );
330 bgBlue = bgColorElem.attribute(
"blue" ).toDouble( &blueOk );
331 bgAlpha = bgColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
332 if ( redOk && greenOk && blueOk && alphaOk )
334 QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
424 QTransform resizeTransform;
425 resizeTransform.translate( transform().dx(), transform().dy() );
455 QPointF mouseMoveStopPoint =
event->lastScenePos();
473 setCursor( Qt::ArrowCursor );
479 switch ( mouseAction )
482 return Qt::ForbiddenCursor;
484 return Qt::SizeAllCursor;
487 return Qt::SizeVerCursor;
490 return Qt::SizeHorCursor;
493 return Qt::SizeFDiagCursor;
496 return Qt::SizeBDiagCursor;
498 return Qt::ArrowCursor;
511 bool nearLeftBorder =
false;
512 bool nearRightBorder =
false;
513 bool nearLowerBorder =
false;
514 bool nearUpperBorder =
false;
518 if ( itemCoordPos.x() < borderTolerance )
520 nearLeftBorder =
true;
522 if ( itemCoordPos.y() < borderTolerance )
524 nearUpperBorder =
true;
526 if ( itemCoordPos.x() > ( rect().width() - borderTolerance ) )
528 nearRightBorder =
true;
530 if ( itemCoordPos.y() > ( rect().height() - borderTolerance ) )
532 nearLowerBorder =
true;
535 if ( nearLeftBorder && nearUpperBorder )
539 else if ( nearLeftBorder && nearLowerBorder )
543 else if ( nearRightBorder && nearUpperBorder )
547 else if ( nearRightBorder && nearLowerBorder )
551 else if ( nearLeftBorder )
555 else if ( nearRightBorder )
559 else if ( nearUpperBorder )
563 else if ( nearLowerBorder )
572 const QPointF& mouseMoveStartPos,
573 const QGraphicsRectItem* originalItem,
574 double dx,
double dy,
575 QGraphicsRectItem* changeItem )
587 double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
595 snappedPosition =
mComposition->
alignPos( snappedPosition, dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY );
626 diffY = snappedPosition.y() - originalItem->transform().dy();
627 mx = 0; my = diffY; rx = 0; ry = -diffY;
631 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
632 mx = 0; my = 0; rx = 0; ry = diffY;
637 diffX = snappedPosition.x() - originalItem->transform().dx();
638 mx = diffX, my = 0; rx = -diffX; ry = 0;
642 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
643 mx = 0; my = 0; rx = diffX, ry = 0;
648 diffX = snappedPosition.x() - originalItem->transform().dx();
649 diffY = snappedPosition.y() - originalItem->transform().dy();
650 mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
654 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
655 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
656 mx = 0; my = 0; rx = diffX, ry = diffY;
660 diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
661 diffY = snappedPosition.y() - originalItem->transform().dy();
662 mx = 0; my = diffY, rx = diffX, ry = -diffY;
666 diffX = snappedPosition.x() - originalItem->transform().dx();
667 diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
668 mx = diffX, my = 0; rx = -diffX; ry = diffY;
674 double moveX = currentPosition.x() - mouseMoveStartPos.x();
675 double moveY = currentPosition.y() - mouseMoveStartPos.y();
677 QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY );
680 if ( snappedLeftPoint != upperLeftPoint )
688 snappedLeftPoint =
mComposition->
alignItem( dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY, moveX, moveY );
693 double yLineCoord = 300;
698 item->setLine( QLineF( alignX, 0, alignX, yLineCoord ) );
716 double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
717 double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();
719 if ( !changeComposerItem )
721 QTransform moveTransform;
722 moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY );
723 changeItem->setTransform( moveTransform );
727 changeComposerItem->
setSceneRect( QRectF( originalItem->transform().dx() + moveRectX,
728 originalItem->transform().dy() + moveRectY,
729 originalItem->rect().width(), originalItem->rect().height() ) );
738 if ( !changeComposerItem )
740 QTransform itemTransform;
741 itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my );
742 changeItem->setTransform( itemTransform );
743 QRectF itemRect( 0, 0, originalItem->rect().width() + rx, originalItem->rect().height() + ry );
744 changeItem->setRect( itemRect );
748 changeComposerItem->
setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my,
749 originalItem->rect().width() + rx, originalItem->rect().height() + ry ) );
771 if ( !QFile::exists( lockIconPath ) )
776 QImage lockImage( lockIconPath );
777 if ( !lockImage.isNull() )
779 p->drawImage( QRectF( 0, 0, sizeLockSymbol, sizeLockSymbol ), lockImage, QRectF( 0, 0, lockImage.width(), lockImage.height() ) );
784 p->setPen( QColor( 50, 100, 120, 200 ) );
785 p->setBrush( QColor( 200, 200, 210, 120 ) );
786 p->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
787 p->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
788 p->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
789 p->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
799 p->setBrush( Qt::NoBrush );
800 p->setRenderHint( QPainter::Antialiasing,
true );
801 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
807 QTransform t = transform();
808 QRectF newSceneRect( t.dx() + dx, t.dy() + dy, rect().width(), rect().height() );
814 double width = rect().width();
815 double height = rect().height();
821 double upperLeftX = x;
822 double upperLeftY = y;
830 upperLeftX -= width / 2.0;
840 upperLeftY -= height / 2.0;
844 upperLeftY -= height;
847 setSceneRect( QRectF( upperLeftX, upperLeftY, width, height ) );
853 double newWidth = rectangle.width();
854 double newHeight = rectangle.height();
855 double xTranslation = rectangle.x();
856 double yTranslation = rectangle.y();
859 if ( rectangle.width() < 0 )
861 newWidth = - rectangle.width();
862 xTranslation -= newWidth;
865 if ( rectangle.height() < 0 )
867 newHeight = - rectangle.height();
868 yTranslation -= newHeight;
871 QRectF newRect( 0, 0, newWidth, newHeight );
872 QGraphicsRectItem::setRect( newRect );
876 t.translate( xTranslation, yTranslation );
886 p->setBrush( brush() );
887 p->setPen( Qt::NoPen );
888 p->setRenderHint( QPainter::Antialiasing,
true );
889 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
910 setOpacity( 1. - ( transparency / 100. ) );
917 mEffect->setEnabled( effectsEnabled );
928 setCursor( Qt::ArrowCursor );
937 p->setFont( textFont );
939 p->scale( scaleFactor, scaleFactor );
944 void QgsComposerItem::drawText( QPainter* p,
const QRectF& rect,
const QString& text,
const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment )
const
952 p->setFont( textFont );
954 p->scale( scaleFactor, scaleFactor );
955 p->drawText( scaledRect, halignment | valignment | Qt::TextWordWrap, text );
964 double angleRad = angle / 180.0 *
M_PI;
965 QPointF middlePoint( x, y );
967 QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
968 QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
970 QPointF p1Rotated, p2Rotated;
971 p1Rotated.setX( p1.x() * cos( angleRad ) + p1.y() * -sin( angleRad ) );
972 p1Rotated.setY( p1.x() * sin( angleRad ) + p1.y() * cos( angleRad ) );
973 p2Rotated.setX( p2.x() * cos( angleRad ) + p2.y() * -sin( angleRad ) );
974 p2Rotated.setY( p2.x() * sin( angleRad ) + p2.y() * cos( angleRad ) );
976 QPolygonF arrowHeadPoly;
977 arrowHeadPoly << middlePoint;
978 arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
979 arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
983 QPen arrowPen = p->pen();
984 arrowPen.setJoinStyle( Qt::RoundJoin );
985 QBrush arrowBrush = p->brush();
986 arrowBrush.setStyle( Qt::SolidPattern );
987 p->setPen( arrowPen );
988 p->setBrush( arrowBrush );
989 arrowBrush.setStyle( Qt::SolidPattern );
990 p->drawPolygon( arrowHeadPoly );
998 QFontMetricsF fontMetrics( metricsFont );
1005 QFontMetricsF fontMetrics( metricsFont );
1012 QFontMetricsF fontMetrics( metricsFont );
1019 QFontMetricsF fontMetrics( metricsFont );
1025 return ( pointSize * 0.3527 );
1030 QFont scaledFont = font;
1032 scaledFont.setPixelSize( pixelSize );
1038 double xDiff = p2.x() - p1.x();
1039 double yDiff = p2.y() - p1.y();
1040 double length = sqrt( xDiff * xDiff + yDiff * yDiff );
1046 double angle = acos(( -yDiff * length ) / ( length * length ) ) * 180 /
M_PI;
1049 return ( 360 - angle );
1059 QList<QGraphicsView*> viewList = scene()->views();
1060 if ( viewList.size() > 0 )
1062 QGraphicsView* currentView = viewList.at( 0 );
1063 if ( currentView->isVisible() )
1065 result = currentView->transform().m11();
1077 double rectHandlerSize = 10.0 / viewScaleFactor;
1080 if ( rectHandlerSize > ( rect().width() / 3 ) )
1082 rectHandlerSize = rect().width() / 3;
1084 if ( rectHandlerSize > ( rect().height() / 3 ) )
1086 rectHandlerSize = rect().height() / 3;
1088 return rectHandlerSize;
1095 if ( lockSymbolSize > ( rect().width() / 3 ) )
1097 lockSymbolSize = rect().width() / 3;
1099 if ( lockSymbolSize > ( rect().height() / 3 ) )
1101 lockSymbolSize = rect().height() / 3;
1148 double midX = width / 2.0;
1149 double midY = height / 2.0;
1170 double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1173 if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1175 width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1176 height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1181 double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1184 width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1185 height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1193 QPointF midpoint( width / 2.0, height / 2.0 );
1194 double xVector = x - midpoint.x();
1195 double yVector = y - midpoint.y();
1198 double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1199 double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1202 QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1205 QList<QLineF> borders;
1206 borders << QLineF( 0, 0, width, 0 );
1207 borders << QLineF( width, 0, width, height );
1208 borders << QLineF( width, height, 0, height );
1209 borders << QLineF( 0, height, 0, 0 );
1211 QList<QLineF>::const_iterator it = borders.constBegin();
1212 QPointF intersectionPoint;
1214 for ( ; it != borders.constEnd(); ++it )
1216 if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1218 x = intersectionPoint.x();
1219 y = intersectionPoint.y();
1234 double x1 = -width / 2.0;
1235 double y1 = -height / 2.0;
1238 double x2 = width / 2.0;
1239 double y2 = -height / 2.0;
1242 double x3 = width / 2.0;
1243 double y3 = height / 2.0;
1246 double x4 = -width / 2.0;
1247 double y4 = height / 2.0;
1251 QPointF midpoint( width / 2.0, height / 2.0 );
1253 QPolygonF rotatedRectPoly;
1254 rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1255 rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1256 rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1257 rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1258 QRectF boundingRect = rotatedRectPoly.boundingRect();
1259 width = boundingRect.width();
1260 height = boundingRect.height();
1265 double rotToRad = angle *
M_PI / 180.0;
1267 xRot = x * cos( rotToRad ) - y * sin( rotToRad );
1268 yRot = x * sin( rotToRad ) + y * cos( rotToRad );