20 #include <QGraphicsLineItem>
21 #include <QGraphicsScene>
22 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsView>
26 #include <QGraphicsEffect>
46 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
49 #define M_DEG2RAD 0.0174532925
54 , QGraphicsRectItem( 0 )
55 , mRemovedFromComposition( false )
56 , mBoundingResizeRectangle( 0 )
57 , mHAlignSnapItem( 0 )
58 , mVAlignSnapItem( 0 )
61 , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
62 , mFrameJoinStyle( Qt::MiterJoin )
63 , mItemPositionLocked( false )
64 , mLastValidViewScaleFactor( -1 )
66 , mEvaluatedItemRotation( 0 )
67 , mBlendMode( QPainter::CompositionMode_SourceOver )
68 , mEffectsEnabled( true )
70 , mExcludeFromExports( false )
71 , mEvaluatedExcludeFromExports( false )
72 , mLastUsedPositionMode( UpperLeft )
73 , mIsGroupMember( false )
74 , mCurrentExportLayer( -1 )
76 , mUuid( QUuid::createUuid().toString() )
83 , QGraphicsRectItem( 0, 0, width, height, 0 )
84 , mRemovedFromComposition( false )
85 , mBoundingResizeRectangle( 0 )
86 , mHAlignSnapItem( 0 )
87 , mVAlignSnapItem( 0 )
90 , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
91 , mFrameJoinStyle( Qt::MiterJoin )
92 , mItemPositionLocked( false )
93 , mLastValidViewScaleFactor( -1 )
95 , mEvaluatedItemRotation( 0 )
96 , mBlendMode( QPainter::CompositionMode_SourceOver )
97 , mEffectsEnabled( true )
99 , mExcludeFromExports( false )
100 , mEvaluatedExcludeFromExports( false )
101 , mLastUsedPositionMode( UpperLeft )
102 , mIsGroupMember( false )
103 , mCurrentExportLayer( -1 )
105 , mUuid( QUuid::createUuid().toString() )
107 init( manageZValue );
111 void QgsComposerItem::init(
const bool manageZValue )
113 setFlag( QGraphicsItem::ItemIsSelectable,
true );
115 setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
116 QPen defaultPen( QColor( 0, 0, 0 ) );
117 defaultPen.setWidthF( 0.3 );
119 setPen( defaultPen );
123 mCompositionManagesZValue =
true;
128 mCompositionManagesZValue =
false;
174 if ( itemElem.isNull() )
179 QDomElement composerItemElem = doc.createElement(
"ComposerItem" );
184 composerItemElem.setAttribute(
"frame",
"true" );
188 composerItemElem.setAttribute(
"frame",
"false" );
194 composerItemElem.setAttribute(
"background",
"true" );
198 composerItemElem.setAttribute(
"background",
"false" );
203 composerItemElem.setAttribute(
"x", QString::number( pos().x() ) );
204 composerItemElem.setAttribute(
"y", QString::number( pos().y() ) );
205 composerItemElem.setAttribute(
"page",
page() );
206 composerItemElem.setAttribute(
"pagex", QString::number( pagepos.x() ) );
207 composerItemElem.setAttribute(
"pagey", QString::number( pagepos.y() ) );
208 composerItemElem.setAttribute(
"width", QString::number( rect().width() ) );
209 composerItemElem.setAttribute(
"height", QString::number( rect().height() ) );
211 composerItemElem.setAttribute(
"zValue", QString::number( zValue() ) );
212 composerItemElem.setAttribute(
"outlineWidth", QString::number( pen().widthF() ) );
214 composerItemElem.setAttribute(
"itemRotation", QString::number(
mItemRotation ) );
215 composerItemElem.setAttribute(
"uuid", mUuid );
216 composerItemElem.setAttribute(
"id", mId );
217 composerItemElem.setAttribute(
"visibility", isVisible() );
221 composerItemElem.setAttribute(
"positionLock",
"true" );
225 composerItemElem.setAttribute(
"positionLock",
"false" );
231 QDomElement frameColorElem = doc.createElement(
"FrameColor" );
232 QColor frameColor = pen().color();
233 frameColorElem.setAttribute(
"red", QString::number( frameColor.red() ) );
234 frameColorElem.setAttribute(
"green", QString::number( frameColor.green() ) );
235 frameColorElem.setAttribute(
"blue", QString::number( frameColor.blue() ) );
236 frameColorElem.setAttribute(
"alpha", QString::number( frameColor.alpha() ) );
237 composerItemElem.appendChild( frameColorElem );
240 QDomElement bgColorElem = doc.createElement(
"BackgroundColor" );
241 QColor bgColor = brush().color();
242 bgColorElem.setAttribute(
"red", QString::number( bgColor.red() ) );
243 bgColorElem.setAttribute(
"green", QString::number( bgColor.green() ) );
244 bgColorElem.setAttribute(
"blue", QString::number( bgColor.blue() ) );
245 bgColorElem.setAttribute(
"alpha", QString::number( bgColor.alpha() ) );
246 composerItemElem.appendChild( bgColorElem );
252 composerItemElem.setAttribute(
"transparency", QString::number(
mTransparency ) );
257 itemElem.appendChild( composerItemElem );
265 if ( itemElem.isNull() )
273 setItemRotation( itemElem.attribute(
"itemRotation",
"0" ).toDouble() );
276 mUuid = itemElem.attribute(
"uuid", QUuid::createUuid().toString() );
279 mTemplateUuid = itemElem.attribute(
"templateUuid" );
282 QString
id = itemElem.attribute(
"id",
"" );
286 QString frame = itemElem.attribute(
"frame" );
287 if ( frame.compare(
"true", Qt::CaseInsensitive ) == 0 )
297 QString background = itemElem.attribute(
"background" );
298 if ( background.compare(
"true", Qt::CaseInsensitive ) == 0 )
308 QString
positionLock = itemElem.attribute(
"positionLock" );
309 if ( positionLock.compare(
"true", Qt::CaseInsensitive ) == 0 )
319 setVisibility( itemElem.attribute(
"visibility",
"1" ) !=
"0" );
323 double x, y, pagex, pagey, width, height;
324 bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOK;
326 x = itemElem.attribute(
"x" ).toDouble( &xOk );
327 y = itemElem.attribute(
"y" ).toDouble( &yOk );
328 page = itemElem.attribute(
"page" ).toInt( &pageOk );
329 pagex = itemElem.attribute(
"pagex" ).toDouble( &pagexOk );
330 pagey = itemElem.attribute(
"pagey" ).toDouble( &pageyOk );
331 width = itemElem.attribute(
"width" ).toDouble( &widthOk );
332 height = itemElem.attribute(
"height" ).toDouble( &heightOk );
334 if ( !positionModeOK )
338 if ( pageOk && pagexOk && pageyOk )
346 if ( !xOk || !yOk || !widthOk || !heightOk )
353 setZValue( itemElem.attribute(
"zValue" ).toDouble() );
356 QDomNodeList frameColorList = itemElem.elementsByTagName(
"FrameColor" );
357 if ( frameColorList.size() > 0 )
359 QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
360 bool redOk, greenOk, blueOk, alphaOk, widthOk;
361 int penRed, penGreen, penBlue, penAlpha;
364 penWidth = itemElem.attribute(
"outlineWidth" ).toDouble( &widthOk );
365 penRed = frameColorElem.attribute(
"red" ).toDouble( &redOk );
366 penGreen = frameColorElem.attribute(
"green" ).toDouble( &greenOk );
367 penBlue = frameColorElem.attribute(
"blue" ).toDouble( &blueOk );
368 penAlpha = frameColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
371 if ( redOk && greenOk && blueOk && alphaOk && widthOk )
373 QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
374 framePen.setWidthF( penWidth );
381 QDomNodeList bgColorList = itemElem.elementsByTagName(
"BackgroundColor" );
382 if ( bgColorList.size() > 0 )
384 QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
385 bool redOk, greenOk, blueOk, alphaOk;
386 int bgRed, bgGreen, bgBlue, bgAlpha;
387 bgRed = bgColorElem.attribute(
"red" ).toDouble( &redOk );
388 bgGreen = bgColorElem.attribute(
"green" ).toDouble( &greenOk );
389 bgBlue = bgColorElem.attribute(
"blue" ).toDouble( &blueOk );
390 bgAlpha = bgColorElem.attribute(
"alpha" ).toDouble( &alphaOk );
391 if ( redOk && greenOk && blueOk && alphaOk )
393 QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
407 QRectF evaluatedRect =
evalItemRect( QRectF( x, y, width, height ) );
415 if ( drawFrame ==
mFrame )
427 QPen itemPen = pen();
428 if ( itemPen.color() == color )
433 itemPen.setColor( color );
440 QPen itemPen = pen();
446 itemPen.setWidthF( outlineWidth );
460 QPen itemPen = pen();
473 return pen().widthF() / 2.0;
479 return rect().adjusted( -frameBleed, -frameBleed, frameBleed, frameBleed );
525 p->setCompositionMode( QPainter::CompositionMode_Difference );
528 QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
529 selectedItemPen.setStyle( Qt::DotLine );
530 selectedItemPen.setWidth( 0 );
531 p->setPen( selectedItemPen );
532 p->setBrush( Qt::NoBrush );
533 p->drawPolygon( rect() );
545 p->setBrush( Qt::NoBrush );
546 p->setRenderHint( QPainter::Antialiasing,
true );
547 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
577 QRectF newSceneRect( pos().x() + dx, pos().y() + dy, rect().width(), rect().height() );
583 double y = pos().y();
586 while ( y - h >= 0. )
598 p.ry() -= (
page() - 1 ) * h;
604 Q_UNUSED( newPageWidth )
605 QPointF curPagePos =
pagePos();
606 int curPage =
page() - 1;
609 QRectF newSceneRect( pos().x(), y, rect().width(), rect().height() );
617 double width = rect().width();
618 double height = rect().height();
624 double upperLeftX = x;
625 double upperLeftY = y;
630 upperLeftY += ( page - 1 ) * h;
639 upperLeftX -= width / 2.0;
649 upperLeftY -= height / 2.0;
653 upperLeftY -= height;
656 if ( posIncludesFrame )
670 upperLeftX += lineToItemOrigin.x2();
671 upperLeftY += lineToItemOrigin.y2();
679 QRectF newRect =
evalItemRect( QRectF( upperLeftX, upperLeftY, width, height ) );
687 double newWidth = rectangle.width();
688 double newHeight = rectangle.height();
689 double xTranslation = rectangle.x();
690 double yTranslation = rectangle.y();
693 if ( rectangle.width() < 0 )
695 newWidth = - rectangle.width();
696 xTranslation -= newWidth;
699 if ( rectangle.height() < 0 )
701 newHeight = - rectangle.height();
702 yTranslation -= newHeight;
705 QGraphicsRectItem::setRect( QRectF( 0, 0, newWidth, newHeight ) );
706 setPos( QPointF( xTranslation, yTranslation ) );
713 QRectF result = newRect;
721 double width = exprVal.toDouble( &ok );
722 QgsDebugMsg( QString(
"exprVal Width:%1" ).arg( width ) );
723 if ( ok && !exprVal.isNull() )
725 result.setWidth( width );
731 double height = exprVal.toDouble( &ok );
732 QgsDebugMsg( QString(
"exprVal Height:%1" ).arg( height ) );
733 if ( ok && !exprVal.isNull() )
735 result.setHeight( height );
739 double x = result.left();
746 x += newRect.width() / 2.0;
750 x += newRect.width();
757 x += rect().width() / 2.0;
767 double positionX = exprVal.toDouble( &ok );
768 QgsDebugMsg( QString(
"exprVal Position X:%1" ).arg( positionX ) );
769 if ( ok && !exprVal.isNull() )
775 double y = result.top();
782 y += newRect.height() / 2.0;
786 y += newRect.height();
793 y += rect().height() / 2.0;
797 y += rect().height();
803 double positionY = exprVal.toDouble( &ok );
804 QgsDebugMsg( QString(
"exprVal Position Y:%1" ).arg( positionY ) );
805 if ( ok && !exprVal.isNull() )
814 x -= result.width() / 2.0;
824 y -= result.height() / 2.0;
828 y -= result.height();
831 result.moveLeft( x );
854 p->setBrush( brush() );
855 p->setPen( Qt::NoPen );
856 p->setRenderHint( QPainter::Antialiasing,
true );
857 p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
885 void QgsComposerItem::refreshBlendMode()
893 QString blendstr = exprVal.toString().trimmed();
896 QgsDebugMsg( QString(
"exprVal BlendMode:%1" ).arg( blendModeD ) );
897 blendMode = blendModeD;
907 refreshTransparency(
true );
910 void QgsComposerItem::refreshTransparency(
const bool updateItem )
919 int transparencyD = exprVal.toInt( &ok );
920 QgsDebugMsg( QString(
"exprVal Transparency:%1" ).arg( transparencyD ) );
921 if ( ok && !exprVal.isNull() )
923 transparency = transparencyD;
928 setOpacity( 1. - ( transparency / 100. ) );
940 mEffect->setEnabled( effectsEnabled );
948 void QgsComposerItem::drawText( QPainter* p,
const QRectF& rect,
const QString& text,
const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment,
int flags )
const
992 QList<QGraphicsView*> viewList = scene()->views();
993 if ( viewList.size() > 0 )
995 QGraphicsView* currentView = viewList.at( 0 );
996 if ( currentView->isVisible() )
998 result = currentView->transform().m11();
1010 double rectHandlerSize = 10.0 / viewScaleFactor;
1013 if ( rectHandlerSize > ( rect().width() / 3 ) )
1015 rectHandlerSize = rect().width() / 3;
1017 if ( rectHandlerSize > ( rect().height() / 3 ) )
1019 rectHandlerSize = rect().height() / 3;
1021 return rectHandlerSize;
1028 if ( lockSymbolSize > ( rect().width() / 3 ) )
1030 lockSymbolSize = rect().width() / 3;
1032 if ( lockSymbolSize > ( rect().height() / 3 ) )
1034 lockSymbolSize = rect().height() / 3;
1057 refreshRotation(
true, adjustPosition );
1060 void QgsComposerItem::refreshRotation(
const bool updateItem,
const bool adjustPosition )
1069 double rotD = exprVal.toDouble( &ok );
1070 QgsDebugMsg( QString(
"exprVal Rotation:%1" ).arg( rotD ) );
1071 if ( ok && !exprVal.isNull() )
1082 if ( adjustPosition )
1086 QLineF refLine = QLineF( mapToScene( QPointF( rect().width() / 2.0, rect().height() / 2.0 ) ), mapToScene( QPointF( 0, 0 ) ) );
1090 QPointF rotatedReferencePoint = refLine.p2();
1091 setPos( rotatedReferencePoint );
1095 setTransformOriginPoint( 0, 0 );
1121 if ( qAbs( rotation ) <= 0.0 )
1142 double midX = width / 2.0;
1143 double midY = height / 2.0;
1166 double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1169 if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1171 width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1172 height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1177 double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1180 width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1181 height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1201 double rotToRad = rotation *
M_PI / 180.0;
1202 QPointF midpoint( width / 2.0, height / 2.0 );
1203 double xVector = x - midpoint.x();
1204 double yVector = y - midpoint.y();
1207 double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1208 double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1211 QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1214 QList<QLineF> borders;
1215 borders << QLineF( 0, 0, width, 0 );
1216 borders << QLineF( width, 0, width, height );
1217 borders << QLineF( width, height, 0, height );
1218 borders << QLineF( 0, height, 0, 0 );
1220 QList<QLineF>::const_iterator it = borders.constBegin();
1221 QPointF intersectionPoint;
1223 for ( ; it != borders.constEnd(); ++it )
1225 if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1227 x = intersectionPoint.x();
1228 y = intersectionPoint.y();
1245 if ( rotation == 0.0 )
1251 double x1 = -width / 2.0;
1252 double y1 = -height / 2.0;
1255 double x2 = width / 2.0;
1256 double y2 = -height / 2.0;
1259 double x3 = width / 2.0;
1260 double y3 = height / 2.0;
1263 double x4 = -width / 2.0;
1264 double y4 = height / 2.0;
1268 QPointF midpoint( width / 2.0, height / 2.0 );
1270 QPolygonF rotatedRectPoly;
1271 rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1272 rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1273 rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1274 rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1275 QRectF boundingRect = rotatedRectPoly.boundingRect();
1276 width = boundingRect.width();
1277 height = boundingRect.height();
1347 QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
1349 if ( evaluatedRect != beforeRect )
1356 refreshRotation(
false,
true );
1360 refreshTransparency(
false );
1373 exclude = exprVal.toBool();
1403 setFlag( QGraphicsItem::ItemIsSelectable, !isGroupMember );
1409 if ( !
id().isEmpty() )
1419 return tr(
"<arrow>" );
1421 return tr(
"<group>" );
1423 return tr(
"<label>" );
1425 return tr(
"<legend>" );
1427 return tr(
"<map>" );
1429 return tr(
"<picture>" );
1431 return tr(
"<scale bar>" );
1433 return tr(
"<shape>" );
1435 return tr(
"<table>" );
1437 return tr(
"<attribute table>" );
1439 return tr(
"<text table>" );
1441 return tr(
"<frame>" );
1444 return tr(
"<item>" );
1449 if ( visible == isVisible() )
1455 QGraphicsItem::setVisible( visible );