30 QGraphicsRectItem( 0 ),
31 mComposition( composition ),
33 mBeginHandleWidth( 0 ),
34 mBeginHandleHeight( 0 ),
46 setAcceptsHoverEvents(
true );
65 QList<QGraphicsView*> viewList = scene()->views();
66 if ( viewList.size() > 0 )
79 Q_UNUSED( itemStyle );
99 QPen handlePen = QPen( QColor( 55, 140, 195, 255 ) );
100 handlePen.setWidth( 0 );
101 painter->setPen( handlePen );
104 painter->setBrush( Qt::NoBrush );
105 painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
108 painter->setBrush( QColor( 255, 255, 255, 255 ) );
110 painter->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
112 painter->drawRect( QRectF(( rect().width() - rectHandlerSize ) / 2, 0, rectHandlerSize, rectHandlerSize ) );
114 painter->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
116 painter->drawRect( QRectF( 0, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
118 painter->drawRect( QRectF( rect().width() - rectHandlerSize, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
120 painter->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
122 painter->drawRect( QRectF(( rect().width() - rectHandlerSize ) / 2, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
124 painter->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
131 if ( selectedItems.size() == 0 )
138 painter->setCompositionMode( QPainter::CompositionMode_Difference );
141 QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
142 selectedItemPen.setStyle( Qt::DashLine );
143 selectedItemPen.setWidth( 0 );
144 painter->setPen( selectedItemPen );
145 painter->setBrush( Qt::NoBrush );
147 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
148 for ( ; itemIter != selectedItems.end(); ++itemIter )
151 QPolygonF itemBounds;
152 if (
mIsDragging && !( *itemIter )->positionLock() )
156 QPolygonF itemSceneBounds = ( *itemIter )->mapToScene(( *itemIter )->rectWithFrame() );
159 itemSceneBounds.translate( transform().dx(), transform().dy() );
161 itemBounds = mapFromScene( itemSceneBounds );
163 else if (
mIsResizing && !( *itemIter )->positionLock() )
166 if ( selectedItems.size() > 1 )
169 QRectF itemRect = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
172 itemBounds = QPolygonF( itemRect );
183 itemBounds = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
185 painter->drawPolygon( itemBounds );
193 QList<QGraphicsItem *> itemList =
composition()->items();
194 QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
195 for ( ; itemIt != itemList.end(); ++itemIt )
208 QObject::disconnect( item, SIGNAL( sizeChanged() ),
this, 0 );
209 QObject::disconnect( item, SIGNAL( itemRotationChanged(
double ) ),
this, 0 );
210 QObject::disconnect( item, SIGNAL( frameChanged( ) ),
this, 0 );
243 if ( selectedItems.size() > 0 )
252 setRotation( rotation );
264 setRect( 0, 0, newHandleBounds.width(), newHandleBounds.height() );
265 setPos( mapToScene( newHandleBounds.topLeft() ) );
282 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
285 QRectF bounds = mapFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() ).boundingRect();
288 for ( ++itemIter; itemIter != selectedItems.end(); ++itemIter )
290 bounds = bounds.united( mapFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() ).boundingRect() );
300 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
303 double firstItemRotation = ( *itemIter )->itemRotation();
306 for ( ++itemIter; itemIter != selectedItems.end(); ++itemIter )
308 if (( *itemIter )->itemRotation() != firstItemRotation )
316 rotation = firstItemRotation;
324 double viewScaleFactor =
graphicsView()->transform().m11();
327 double rectHandlerSize = 10.0 / viewScaleFactor;
330 if ( rectHandlerSize > ( rect().width() / 3 ) )
332 rectHandlerSize = rect().width() / 3;
334 if ( rectHandlerSize > ( rect().height() / 3 ) )
336 rectHandlerSize = rect().height() / 3;
338 return rectHandlerSize;
344 switch ( mouseAction )
347 return Qt::ForbiddenCursor;
349 return Qt::SizeAllCursor;
353 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
355 return Qt::SizeVerCursor;
357 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
359 return Qt::SizeBDiagCursor;
361 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
363 return Qt::SizeHorCursor;
367 return Qt::SizeFDiagCursor;
372 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
374 return Qt::SizeHorCursor;
376 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
378 return Qt::SizeFDiagCursor;
380 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
382 return Qt::SizeVerCursor;
386 return Qt::SizeBDiagCursor;
392 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
394 return Qt::SizeFDiagCursor;
396 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
398 return Qt::SizeVerCursor;
400 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
402 return Qt::SizeBDiagCursor;
406 return Qt::SizeHorCursor;
411 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
413 return Qt::SizeBDiagCursor;
415 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
417 return Qt::SizeHorCursor;
419 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
421 return Qt::SizeFDiagCursor;
425 return Qt::SizeVerCursor;
429 return Qt::ArrowCursor;
435 bool nearLeftBorder =
false;
436 bool nearRightBorder =
false;
437 bool nearLowerBorder =
false;
438 bool nearUpperBorder =
false;
442 if ( itemCoordPos.x() >= 0 && itemCoordPos.x() < borderTolerance )
444 nearLeftBorder =
true;
446 if ( itemCoordPos.y() >= 0 && itemCoordPos.y() < borderTolerance )
448 nearUpperBorder =
true;
450 if ( itemCoordPos.x() <= rect().width() && itemCoordPos.x() > ( rect().width() - borderTolerance ) )
452 nearRightBorder =
true;
454 if ( itemCoordPos.y() <= rect().height() && itemCoordPos.y() > ( rect().height() - borderTolerance ) )
456 nearLowerBorder =
true;
459 if ( nearLeftBorder && nearUpperBorder )
463 else if ( nearLeftBorder && nearLowerBorder )
467 else if ( nearRightBorder && nearUpperBorder )
471 else if ( nearRightBorder && nearLowerBorder )
475 else if ( nearLeftBorder )
479 else if ( nearRightBorder )
483 else if ( nearUpperBorder )
487 else if ( nearLowerBorder )
493 QPointF scenePoint = mapToScene( itemCoordPos );
494 QList<QGraphicsItem *> itemsAtCursorPos =
mComposition->items( scenePoint );
495 if ( itemsAtCursorPos.size() == 0 )
500 QList<QGraphicsItem*>::iterator itemIter = itemsAtCursorPos.begin();
501 for ( ; itemIter != itemsAtCursorPos.end(); ++itemIter )
518 QPointF itemPos = mapFromScene( sceneCoordPos );
546 bool shiftModifier =
false;
547 bool controlModifier =
false;
548 if ( event->modifiers() & Qt::ShiftModifier )
551 shiftModifier =
true;
553 if ( event->modifiers() & Qt::ControlModifier )
556 controlModifier =
true;
562 dragMouseMove( event->lastScenePos(), shiftModifier, controlModifier );
567 resizeMouseMove( event->lastScenePos(), shiftModifier, controlModifier );
575 QPointF mouseMoveStopPoint =
event->lastScenePos();
590 QUndoCommand* parentCommand =
new QUndoCommand(
tr(
"Change item position" ) );
592 QPointF mEndHandleMovePos = scenePos();
596 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
597 for ( ; itemIter != selectedItems.end(); ++itemIter )
599 if (( *itemIter )->positionLock() || (( *itemIter )->flags() & QGraphicsItem::ItemIsSelectable ) == 0 )
615 QUndoCommand* parentCommand =
new QUndoCommand(
tr(
"Change item size" ) );
619 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
620 for ( ; itemIter != selectedItems.end(); ++itemIter )
622 if (( *itemIter )->positionLock() || (( *itemIter )->flags() & QGraphicsItem::ItemIsSelectable ) == 0 )
631 if ( selectedItems.size() == 1 )
639 itemRect = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
643 itemRect = itemRect.normalized();
644 QPointF newPos = mapToScene( itemRect.topLeft() );
645 ( *itemIter )->setItemPosition( newPos.x(), newPos.y(), itemRect.width(), itemRect.height(),
QgsComposerItem::UpperLeft, true );
676 int selectedCount = selectedItems.size();
677 if ( selectedCount > 1 )
682 else if ( selectedCount == 1 )
731 QPointF sceneMousePos = mapFromScene( cursorPos );
737 return QSizeF( 0, sceneMousePos.y() );
740 return QSizeF( 0, sceneMousePos.y() - rect().height() );
744 return QSizeF( sceneMousePos.x(), 0 );
747 return QSizeF( sceneMousePos.x() - rect().width(), 0 );
751 return QSizeF( sceneMousePos.x(), sceneMousePos.y() );
754 return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() - rect().height() );
757 return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() );
760 return QSizeF( sceneMousePos.x(), sceneMousePos.y() - rect().height() );
763 return QSizeF( 0, 0 );
782 QPointF snappedLeftPoint;
784 if ( !preventSnap && rotation() == 0 )
792 snappedLeftPoint = upperLeftPoint;
804 if ( abs( moveRectX ) <= abs( moveRectY ) )
815 QTransform moveTransform;
816 moveTransform.translate( moveRectX, moveRectY );
817 setTransform( moveTransform );
830 double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
832 QPointF beginMousePos;
833 QPointF finalPosition;
834 if ( rotation() == 0 )
842 finalPosition = mapFromScene( snappedPosition );
848 finalPosition = mapFromScene( currentPosition );
851 double diffX = finalPosition.x() - beginMousePos.x();
852 double diffY = finalPosition.y() - beginMousePos.y();
868 mx = -diffX / 2; my = diffY; rx = diffX; ry = -diffY;
872 mx = 0; my = diffY; rx = 0; ry = -diffY;
882 mx = -diffX / 2; my = 0; rx = diffX; ry = diffY;
886 mx = 0; my = 0; rx = 0; ry = diffY;
897 mx = diffX; my = -diffY / 2; rx = -diffX; ry = diffY;
901 mx = diffX, my = 0; rx = -diffX; ry = 0;
911 mx = 0; my = -diffY / 2; rx = diffX; ry = diffY;
915 mx = 0; my = 0; rx = diffX, ry = 0;
935 mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
953 mx = 0; my = 0; rx = diffX, ry = diffY;
971 mx = 0; my = diffY, rx = diffX, ry = -diffY;
989 mx = diffX, my = 0; rx = -diffX; ry = diffY;
1016 translateLine.setAngle( translateLine.angle() - rotation() );
1017 QPointF sceneTranslate = translateLine.p2();
1020 QTransform itemTransform;
1021 itemTransform.translate( sceneTranslate.x(), sceneTranslate.y() );
1022 setTransform( itemTransform );
1053 if ( snappedPoint != point )
1056 return snappedPoint;
1072 snappedPoint =
alignItem( alignX, alignY, point.x(), point.y() );
1075 snappedPoint =
alignPos( point, alignX, alignY );
1083 double yLineCoord = 300;
1088 item->setLine( QLineF( alignX, 0, alignX, yLineCoord ) );
1105 return snappedPoint;
1160 double left = unalignedX;
1161 double right = left + rect().width();
1162 double midH = ( left + right ) / 2.0;
1163 double top = unalignedY;
1164 double bottom = top + rect().height();
1165 double midV = ( top + bottom ) / 2.0;
1167 QMap<double, const QgsComposerItem* > xAlignCoordinates;
1168 QMap<double, const QgsComposerItem* > yAlignCoordinates;
1172 double xItemLeft = left;
1173 double xAlignCoord = 0;
1174 double smallestDiffX = DBL_MAX;
1176 checkNearestItem( left, xAlignCoordinates, smallestDiffX, 0, xItemLeft, xAlignCoord );
1177 checkNearestItem( midH, xAlignCoordinates, smallestDiffX, ( left - right ) / 2.0, xItemLeft, xAlignCoord );
1178 checkNearestItem( right, xAlignCoordinates, smallestDiffX, left - right, xItemLeft, xAlignCoord );
1181 double yItemTop = top;
1182 double yAlignCoord = 0;
1183 double smallestDiffY = DBL_MAX;
1185 checkNearestItem( top, yAlignCoordinates, smallestDiffY, 0, yItemTop, yAlignCoord );
1186 checkNearestItem( midV, yAlignCoordinates, smallestDiffY, ( top - bottom ) / 2.0, yItemTop, yAlignCoord );
1187 checkNearestItem( bottom, yAlignCoordinates, smallestDiffY, top - bottom, yItemTop, yAlignCoord );
1189 double xCoord = ( smallestDiffX < 5 ) ? xItemLeft : unalignedX;
1190 alignX = ( smallestDiffX < 5 ) ? xAlignCoord : -1;
1191 double yCoord = ( smallestDiffY < 5 ) ? yItemTop : unalignedY;
1192 alignY = ( smallestDiffY < 5 ) ? yAlignCoord : -1;
1193 return QPointF( xCoord, yCoord );
1198 QMap<double, const QgsComposerItem* > xAlignCoordinates;
1199 QMap<double, const QgsComposerItem* > yAlignCoordinates;
1202 double nearestX = pos.x();
1203 double nearestY = pos.y();
1204 if ( !
nearestItem( xAlignCoordinates, pos.x(), nearestX )
1205 || !
nearestItem( yAlignCoordinates, pos.y(), nearestY ) )
1212 QPointF result( pos.x(), pos.y() );
1215 result.setX( nearestX );
1225 result.setY( nearestY );
1237 alignCoordsX.clear();
1238 alignCoordsY.clear();
1242 QList<QGraphicsItem *> itemList =
mComposition->items();
1243 QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
1244 for ( ; itemIt != itemList.end(); ++itemIt )
1248 if ( !currentItem || currentItem->
selected() )
1253 if ( dynamic_cast<const QgsPaperItem *>( *itemIt ) )
1257 itemRect = currentItem->rect();
1261 itemRect = currentItem->mapRectToScene( currentItem->
rectWithFrame() );
1263 alignCoordsX.insert( itemRect.left(), currentItem );
1264 alignCoordsX.insert( itemRect.right(), currentItem );
1265 alignCoordsX.insert( itemRect.center().x(), currentItem );
1266 alignCoordsY.insert( itemRect.top(), currentItem );
1267 alignCoordsY.insert( itemRect.center().y(), currentItem );
1268 alignCoordsY.insert( itemRect.bottom(), currentItem );
1278 double x = ( *sIt )->line().x1();
1279 double y = ( *sIt )->line().y1();
1282 alignCoordsX.insert( x, 0 );
1286 alignCoordsY.insert( y, 0 );
1294 double currentCoord = 0;
1295 if ( !
nearestItem( alignCoords, checkCoord, currentCoord ) )
1300 double currentDiff = abs( checkCoord - currentCoord );
1301 if ( currentDiff < mComposition->alignmentSnapTolerance() )
1303 itemCoord = currentCoord + itemCoordOffset;
1304 alignCoord = currentCoord;
1305 smallestDiff = currentDiff;
1311 if ( coords.size() < 1 )
1316 QMap< double, const QgsComposerItem* >::const_iterator it = coords.lowerBound( value );
1317 if ( it == coords.constBegin() )
1319 nearestValue = it.key();
1322 else if ( it == coords.constEnd() )
1325 nearestValue = it.key();
1331 double upperVal = it.key();
1333 double lowerVal = it.key();
1335 double lowerDiff = value - lowerVal;
1336 double upperDiff = upperVal - value;
1337 if ( lowerDiff < upperDiff )
1339 nearestValue = lowerVal;
1344 nearestValue = upperVal;
QGraphicsLineItem * hAlignSnapItem()
Return horizontal align snap item.
QUndoStack * undoStack()
Returns pointer to undo/redo command storage.
double alignmentSnapTolerance() const
QgsComposition * mComposition
double paperWidth() const
Returns width of paper item.
bool mIsDragging
True if user is currently dragging items.
void drawHandles(QPainter *painter, double rectHandlerSize)
Draws the handles.
QPointF mLastMouseEventPos
Position of the last mouse move event (in scene coordinates)
QPointF alignPos(const QPointF &pos, double &alignX, double &alignY)
Snaps a point to to the grid or align rulers.
void updateHandles()
Redraws or hides the handles based on the current selection.
Qt::CursorShape cursorForPosition(const QPointF &itemCoordPos)
Finds out the appropriate cursor for the current mouse position in the widget (e.g.
void selectedItemRotationChanged()
Redraws handles when selected item rotation changes.
virtual bool selected() const
Is selected.
QGraphicsView * graphicsView()
bool smartGuidesEnabled() const
A item that forms part of a map composition.
bool preventCursorChange()
QGraphicsLineItem * mVAlignSnapItem
QPointF snapPointToGrid(const QPointF &scenePoint) const
Snaps a scene coordinate point to grid.
void savePreviousState()
Saves current item state as previous state.
MouseAction
Describes the action (move or resize in different directon) to be done during mouse move...
double mBeginHandleWidth
Width and height of composer handles at beginning of resize.
void selectedItemSizeChanged()
Redraws handles when selected item size changes.
virtual ~QgsComposerMouseHandles()
double spaceBetweenPages() const
bool alignmentSnap() const
void setStatusMessage(const QString &message)
Sets the status bar message for the composer window.
int numPages() const
Note: added in version 1.9.
QPointF mMouseMoveStartPos
Start point of the last mouse move action (in scene coordinates)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
void setViewportCursor(Qt::CursorShape cursor)
double rectHandlerBorderTolerance()
Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to t...
void mousePressEvent(QGraphicsSceneMouseEvent *event)
QgsComposerMouseHandles::MouseAction mouseActionForPosition(const QPointF &itemCoordPos)
Finds out which mouse move action to choose depending on the cursor position inside the widget...
QRectF selectionBounds() const
Returns the mouse handle bounds of current selection.
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
void resizeMouseMove(const QPointF ¤tPosition, bool lockAspect, bool fromCenter)
Handles resizing of items during mouse move.
bool nearestItem(const QMap< double, const QgsComposerItem * > &coords, double value, double &nearestValue) const
void drawSelectedItemBounds(QPainter *painter)
Draw outlines for selected items.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget)
void selectionChanged()
Sets up listeners to sizeChanged signal for all selected items.
Graphics scene for map printing.
double mBeginHandleHeight
void collectAlignCoordinates(QMap< double, const QgsComposerItem * > &alignCoordsX, QMap< double, const QgsComposerItem * > &alignCoordsY)
QGraphicsLineItem * vAlignSnapItem()
Return vertical align snap item.
virtual QRectF rectWithFrame() const
Returns the item's rectangular bounds, including any bleed caused by the item's frame.
void saveAfterState()
Saves current item state as after state.
void hoverMoveEvent(QGraphicsSceneHoverEvent *event)
QGraphicsLineItem * mHAlignSnapItem
Align snap lines.
void deleteVAlignSnapItem()
QPointF snapPoint(const QPointF &originalPoint, QgsComposerMouseHandles::SnapGuideMode mode)
Snaps an item or point (depending on mode) originating at originalPoint to the grid or align rulers...
QgsComposition * composition()
Undo command to undo/redo all composer item related changes.
QPointF mBeginMouseEventPos
Position of the mouse at beginning of move/resize (in scene coordinates)
QgsComposerMouseHandles::MouseAction mCurrentMouseMoveAction
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void dragMouseMove(const QPointF ¤tPosition, bool lockMovement, bool preventSnap)
Handles dragging of items during mouse move.
QPointF mBeginHandlePos
Position of composer handles at beginning of move/resize (in scene coordinates)
double paperHeight() const
Returns height of paper item.
QSizeF calcCursorEdgeOffset(const QPointF &cursorPos)
Calculates the distance of the mouse cursor from thed edge of the mouse handles.
static void relativeResizeRect(QRectF &rectToResize, const QRectF &boundsBefore, const QRectF &boundsAfter)
Resizes a QRectF relative to the change from boundsBefore to boundsAfter.
void deleteHAlignSnapItem()
double ANALYSIS_EXPORT min(double x, double y)
returns the minimum of two doubles or the first argument if both are equal
QGraphicsView * mGraphicsView
QgsComposerMouseHandles(QgsComposition *composition)
QgsComposition::PlotStyle plotStyle() const
QList< QgsComposerItem * > selectedComposerItems()
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
QgsComposerMouseHandles::MouseAction mouseActionForScenePos(const QPointF &sceneCoordPos)
Finds out which mouse move action to choose depending on the scene cursor position.
QPointF alignItem(double &alignX, double &alignY, double unalignedX, double unalignedY)
Snaps an item originating at unalignedX, unalignedY to the grid or align rulers.
bool selectionRotation(double &rotation) const
Returns true if all selected items have same rotation, and if so, updates passed rotation variable...
void checkNearestItem(double checkCoord, const QMap< double, const QgsComposerItem * > &alignCoords, double &smallestDiff, double itemCoordOffset, double &itemCoord, double &alignCoord) const
bool mIsResizing
True is user is currently resizing items.
QList< QGraphicsLineItem * > * snapLines()
Returns pointer to snap lines collection.