17 #include <QGraphicsView>
18 #include <QGraphicsSceneHoverEvent>
35 , QGraphicsRectItem( 0 )
36 , mComposition( composition )
38 , mCurrentMouseMoveAction( NoAction )
39 , mBeginHandleWidth( 0 )
40 , mBeginHandleHeight( 0 )
43 , mIsDragging( false )
44 , mIsResizing( false )
45 , mHAlignSnapItem( 0 )
46 , mVAlignSnapItem( 0 )
52 setAcceptHoverEvents(
true );
60 QGraphicsView* QgsComposerMouseHandles::graphicsView()
71 QList<QGraphicsView*> viewList = scene()->views();
72 if ( viewList.size() > 0 )
74 mGraphicsView = viewList.at( 0 );
85 Q_UNUSED( itemStyle );
97 double rectHandlerSize = rectHandlerBorderTolerance();
98 drawHandles( painter, rectHandlerSize );
104 drawSelectedItemBounds( painter );
108 void QgsComposerMouseHandles::drawHandles( QPainter* painter,
double rectHandlerSize )
111 QPen handlePen = QPen( QColor( 55, 140, 195, 255 ) );
112 handlePen.setWidth( 0 );
113 painter->setPen( handlePen );
116 painter->setBrush( Qt::NoBrush );
117 painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
120 painter->setBrush( QColor( 255, 255, 255, 255 ) );
122 painter->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
124 painter->drawRect( QRectF(( rect().width() - rectHandlerSize ) / 2, 0, rectHandlerSize, rectHandlerSize ) );
126 painter->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
128 painter->drawRect( QRectF( 0, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
130 painter->drawRect( QRectF( rect().width() - rectHandlerSize, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
132 painter->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
134 painter->drawRect( QRectF(( rect().width() - rectHandlerSize ) / 2, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
136 painter->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
139 void QgsComposerMouseHandles::drawSelectedItemBounds( QPainter* painter )
143 if ( selectedItems.size() == 0 )
150 painter->setCompositionMode( QPainter::CompositionMode_Difference );
153 QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
154 selectedItemPen.setStyle( Qt::DashLine );
155 selectedItemPen.setWidth( 0 );
156 painter->setPen( selectedItemPen );
157 painter->setBrush( Qt::NoBrush );
159 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
160 for ( ; itemIter != selectedItems.end(); ++itemIter )
163 QPolygonF itemBounds;
164 if ( mIsDragging && !( *itemIter )->positionLock() )
168 QPolygonF itemSceneBounds = ( *itemIter )->mapToScene(( *itemIter )->rectWithFrame() );
171 itemSceneBounds.translate( transform().dx(), transform().dy() );
173 itemBounds = mapFromScene( itemSceneBounds );
175 else if ( mIsResizing && !( *itemIter )->positionLock() )
178 if ( selectedItems.size() > 1 )
181 QRectF itemRect = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
184 itemBounds = QPolygonF( itemRect );
195 itemBounds = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
197 painter->drawPolygon( itemBounds );
205 QList<QGraphicsItem *> itemList =
composition()->items();
206 QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
207 for ( ; itemIt != itemList.end(); ++itemIt )
221 QObject::disconnect( item, SIGNAL( sizeChanged() ),
this, 0 );
222 QObject::disconnect( item, SIGNAL( itemRotationChanged(
double ) ),
this, 0 );
223 QObject::disconnect( item, SIGNAL( frameChanged() ),
this, 0 );
224 QObject::disconnect( item, SIGNAL( lockChanged() ),
this, 0 );
235 if ( !mIsDragging && !mIsResizing )
244 if ( !mIsDragging && !mIsResizing )
251 void QgsComposerMouseHandles::updateHandles()
257 if ( selectedItems.size() > 0 )
263 if ( selectionRotation( rotation ) )
266 setRotation( rotation );
275 QRectF newHandleBounds = selectionBounds();
278 setRect( 0, 0, newHandleBounds.width(), newHandleBounds.height() );
279 setPos( mapToScene( newHandleBounds.topLeft() ) );
292 QRectF QgsComposerMouseHandles::selectionBounds()
const
296 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
299 QRectF bounds = mapFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() ).boundingRect();
302 for ( ++itemIter; itemIter != selectedItems.end(); ++itemIter )
304 bounds = bounds.united( mapFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() ).boundingRect() );
310 bool QgsComposerMouseHandles::selectionRotation(
double & rotation )
const
314 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
317 double firstItemRotation = ( *itemIter )->itemRotation();
320 for ( ++itemIter; itemIter != selectedItems.end(); ++itemIter )
322 if (( *itemIter )->itemRotation() != firstItemRotation )
330 rotation = firstItemRotation;
334 double QgsComposerMouseHandles::rectHandlerBorderTolerance()
338 double viewScaleFactor = graphicsView()->transform().m11();
341 double rectHandlerSize = 10.0 / viewScaleFactor;
344 if ( rectHandlerSize > ( rect().width() / 3 ) )
346 rectHandlerSize = rect().width() / 3;
348 if ( rectHandlerSize > ( rect().height() / 3 ) )
350 rectHandlerSize = rect().height() / 3;
352 return rectHandlerSize;
355 Qt::CursorShape QgsComposerMouseHandles::cursorForPosition(
const QPointF& itemCoordPos )
358 switch ( mouseAction )
361 return Qt::ForbiddenCursor;
363 return Qt::SizeAllCursor;
367 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
369 return Qt::SizeVerCursor;
371 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
373 return Qt::SizeBDiagCursor;
375 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
377 return Qt::SizeHorCursor;
381 return Qt::SizeFDiagCursor;
386 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
388 return Qt::SizeHorCursor;
390 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
392 return Qt::SizeFDiagCursor;
394 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
396 return Qt::SizeVerCursor;
400 return Qt::SizeBDiagCursor;
406 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
408 return Qt::SizeFDiagCursor;
410 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
412 return Qt::SizeVerCursor;
414 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
416 return Qt::SizeBDiagCursor;
420 return Qt::SizeHorCursor;
425 if (( rotation() <= 22.5 || rotation() >= 337.5 ) || ( rotation() >= 157.5 && rotation() <= 202.5 ) )
427 return Qt::SizeBDiagCursor;
429 else if (( rotation() >= 22.5 && rotation() <= 67.5 ) || ( rotation() >= 202.5 && rotation() <= 247.5 ) )
431 return Qt::SizeHorCursor;
433 else if (( rotation() >= 67.5 && rotation() <= 112.5 ) || ( rotation() >= 247.5 && rotation() <= 292.5 ) )
435 return Qt::SizeFDiagCursor;
439 return Qt::SizeVerCursor;
443 return Qt::ArrowCursor;
449 bool nearLeftBorder =
false;
450 bool nearRightBorder =
false;
451 bool nearLowerBorder =
false;
452 bool nearUpperBorder =
false;
454 bool withinWidth =
false;
455 bool withinHeight =
false;
456 if ( itemCoordPos.x() >= 0 && itemCoordPos.x() <= rect().width() )
460 if ( itemCoordPos.y() >= 0 && itemCoordPos.y() <= rect().height() )
465 double borderTolerance = rectHandlerBorderTolerance();
467 if ( itemCoordPos.x() >= 0 && itemCoordPos.x() < borderTolerance )
469 nearLeftBorder =
true;
471 if ( itemCoordPos.y() >= 0 && itemCoordPos.y() < borderTolerance )
473 nearUpperBorder =
true;
475 if ( itemCoordPos.x() <= rect().width() && itemCoordPos.x() > ( rect().width() - borderTolerance ) )
477 nearRightBorder =
true;
479 if ( itemCoordPos.y() <= rect().height() && itemCoordPos.y() > ( rect().height() - borderTolerance ) )
481 nearLowerBorder =
true;
484 if ( nearLeftBorder && nearUpperBorder )
488 else if ( nearLeftBorder && nearLowerBorder )
492 else if ( nearRightBorder && nearUpperBorder )
496 else if ( nearRightBorder && nearLowerBorder )
500 else if ( nearLeftBorder && withinHeight )
504 else if ( nearRightBorder && withinHeight )
508 else if ( nearUpperBorder && withinWidth )
512 else if ( nearLowerBorder && withinWidth )
518 QPointF scenePoint = mapToScene( itemCoordPos );
519 QList<QGraphicsItem *> itemsAtCursorPos = mComposition->items( scenePoint );
520 if ( itemsAtCursorPos.size() == 0 )
525 QList<QGraphicsItem*>::iterator itemIter = itemsAtCursorPos.begin();
526 for ( ; itemIter != itemsAtCursorPos.end(); ++itemIter )
543 QPointF itemPos = mapFromScene( sceneCoordPos );
544 return mouseActionForPosition( itemPos );
549 setViewportCursor( cursorForPosition( event->pos() ) );
555 setViewportCursor( Qt::ArrowCursor );
558 void QgsComposerMouseHandles::setViewportCursor( Qt::CursorShape cursor )
565 graphicsView()->viewport()->setCursor( cursor );
576 dragMouseMove( event->lastScenePos(),
event->modifiers() & Qt::ShiftModifier,
event->modifiers() & Qt::ControlModifier );
578 else if ( mIsResizing )
583 resizeMouseMove( event->lastScenePos(),
event->modifiers() & Qt::ShiftModifier,
event->modifiers() & Qt::AltModifier );
586 mLastMouseEventPos =
event->lastScenePos();
591 QPointF mouseMoveStopPoint =
event->lastScenePos();
592 double diffX = mouseMoveStopPoint.x() - mMouseMoveStartPos.x();
593 double diffY = mouseMoveStopPoint.y() - mMouseMoveStartPos.y();
607 QUndoCommand* parentCommand =
new QUndoCommand(
tr(
"Change item position" ) );
609 QPointF mEndHandleMovePos = scenePos();
613 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
614 for ( ; itemIter != selectedItems.end(); ++itemIter )
616 if (( *itemIter )->positionLock() || (( *itemIter )->flags() & QGraphicsItem::ItemIsSelectable ) == 0 )
623 ( *itemIter )->move( mEndHandleMovePos.x() - mBeginHandlePos.x(), mEndHandleMovePos.y() - mBeginHandlePos.y() );
626 mComposition->
undoStack()->push( parentCommand );
632 QUndoCommand* parentCommand =
new QUndoCommand(
tr(
"Change item size" ) );
636 QList<QgsComposerItem*>::iterator itemIter = selectedItems.begin();
637 for ( ; itemIter != selectedItems.end(); ++itemIter )
639 if (( *itemIter )->positionLock() || (( *itemIter )->flags() & QGraphicsItem::ItemIsSelectable ) == 0 )
648 if ( selectedItems.size() == 1 )
651 itemRect = mResizeRect;
656 itemRect = mapRectFromItem(( *itemIter ), ( *itemIter )->rectWithFrame() );
660 itemRect = itemRect.normalized();
661 QPointF newPos = mapToScene( itemRect.topLeft() );
662 ( *itemIter )->setItemPosition( newPos.x(), newPos.y(), itemRect.width(), itemRect.height(),
QgsComposerItem::UpperLeft, true );
666 mComposition->
undoStack()->push( parentCommand );
683 setViewportCursor( Qt::ArrowCursor );
691 void QgsComposerMouseHandles::resetStatusBar()
694 int selectedCount = selectedItems.size();
695 if ( selectedCount > 1 )
698 mComposition->
setStatusMessage( QString(
tr(
"%1 items selected" ) ).arg( selectedCount ) );
700 else if ( selectedCount == 1 )
715 mMouseMoveStartPos =
event->lastScenePos();
716 mLastMouseEventPos =
event->lastScenePos();
718 mBeginMouseEventPos =
event->lastScenePos();
719 mBeginHandlePos = scenePos();
720 mBeginHandleWidth = rect().width();
721 mBeginHandleHeight = rect().height();
723 mCurrentMouseMoveAction = mouseActionForPosition( event->pos() );
737 mResizeRect = QRectF( 0, 0, mBeginHandleWidth, mBeginHandleHeight );
740 mCursorOffset = calcCursorEdgeOffset( mMouseMoveStartPos );
751 QSizeF QgsComposerMouseHandles::calcCursorEdgeOffset(
const QPointF &cursorPos )
754 QPointF sceneMousePos = mapFromScene( cursorPos );
756 switch ( mCurrentMouseMoveAction )
760 return QSizeF( 0, sceneMousePos.y() );
763 return QSizeF( 0, sceneMousePos.y() - rect().height() );
767 return QSizeF( sceneMousePos.x(), 0 );
770 return QSizeF( sceneMousePos.x() - rect().width(), 0 );
774 return QSizeF( sceneMousePos.x(), sceneMousePos.y() );
777 return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() - rect().height() );
780 return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() );
783 return QSizeF( sceneMousePos.x(), sceneMousePos.y() - rect().height() );
786 return QSizeF( 0, 0 );
791 void QgsComposerMouseHandles::dragMouseMove(
const QPointF& currentPosition,
bool lockMovement,
bool preventSnap )
799 double moveX = currentPosition.x() - mBeginMouseEventPos.x();
800 double moveY = currentPosition.y() - mBeginMouseEventPos.y();
803 QPointF upperLeftPoint( mBeginHandlePos.x() + moveX, mBeginHandlePos.y() + moveY );
805 QPointF snappedLeftPoint;
807 if ( !preventSnap && rotation() == 0 )
815 snappedLeftPoint = upperLeftPoint;
820 double moveRectX = snappedLeftPoint.x() - mBeginHandlePos.x();
821 double moveRectY = snappedLeftPoint.y() - mBeginHandlePos.y();
827 if ( qAbs( moveRectX ) <= qAbs( moveRectY ) )
838 QTransform moveTransform;
839 moveTransform.translate( moveRectX, moveRectY );
840 setTransform( moveTransform );
842 mComposition->
setStatusMessage( QString(
tr(
"dx: %1 mm dy: %2 mm" ) ).arg( moveRectX ).arg( moveRectY ) );
845 void QgsComposerMouseHandles::resizeMouseMove(
const QPointF& currentPosition,
bool lockRatio,
bool fromCenter )
853 double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
855 QPointF beginMousePos;
856 QPointF finalPosition;
857 if ( rotation() == 0 )
863 beginMousePos = mapFromScene( QPointF( mBeginMouseEventPos.x() - mCursorOffset.width(), mBeginMouseEventPos.y() - mCursorOffset.height() ) );
864 QPointF snappedPosition = snapPoint( QPointF( currentPosition.x() - mCursorOffset.width(), currentPosition.y() - mCursorOffset.height() ),
QgsComposerMouseHandles::Point );
865 finalPosition = mapFromScene( snappedPosition );
870 beginMousePos = mapFromScene( mBeginMouseEventPos );
871 finalPosition = mapFromScene( currentPosition );
874 double diffX = finalPosition.x() - beginMousePos.x();
875 double diffY = finalPosition.y() - beginMousePos.y();
878 if ( lockRatio && mBeginHandleHeight != 0 )
880 ratio = mBeginHandleWidth / mBeginHandleHeight;
883 switch ( mCurrentMouseMoveAction )
890 diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
891 mx = -diffX / 2; my = diffY; rx = diffX; ry = -diffY;
895 mx = 0; my = diffY; rx = 0; ry = -diffY;
904 diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
905 mx = -diffX / 2; my = 0; rx = diffX; ry = diffY;
909 mx = 0; my = 0; rx = 0; ry = diffY;
919 diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
920 mx = diffX; my = -diffY / 2; rx = -diffX; ry = diffY;
924 mx = diffX, my = 0; rx = -diffX; ry = 0;
933 diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
934 mx = 0; my = -diffY / 2; rx = diffX; ry = diffY;
938 mx = 0; my = 0; rx = diffX, ry = 0;
949 if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
951 diffX = mBeginHandleWidth - (( mBeginHandleHeight - diffY ) * ratio );
955 diffY = mBeginHandleHeight - (( mBeginHandleWidth - diffX ) / ratio );
958 mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
967 if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
969 diffX = (( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
973 diffY = (( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
976 mx = 0; my = 0; rx = diffX, ry = diffY;
985 if (( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
987 diffX = (( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
991 diffY = mBeginHandleHeight - (( mBeginHandleWidth + diffX ) / ratio );
994 mx = 0; my = diffY, rx = diffX, ry = -diffY;
1003 if (( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
1005 diffX = mBeginHandleWidth - (( mBeginHandleHeight + diffY ) * ratio );
1009 diffY = (( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
1012 mx = diffX, my = 0; rx = -diffX; ry = diffY;
1034 mResizeMoveX = mBeginHandleWidth + rx > 0 ? mx : mx + mBeginHandleWidth + rx;
1035 mResizeMoveY = mBeginHandleHeight + ry > 0 ? my : my + mBeginHandleHeight + ry;
1038 QLineF translateLine = QLineF( 0, 0, mResizeMoveX, mResizeMoveY );
1039 translateLine.setAngle( translateLine.angle() - rotation() );
1040 QPointF sceneTranslate = translateLine.p2();
1043 QTransform itemTransform;
1044 itemTransform.translate( sceneTranslate.x(), sceneTranslate.y() );
1045 setTransform( itemTransform );
1048 if ( mBeginHandleWidth + rx >= 0 && mBeginHandleHeight + ry >= 0 )
1050 mResizeRect = QRectF( 0, 0, mBeginHandleWidth + rx, mBeginHandleHeight + ry );
1052 else if ( mBeginHandleHeight + ry >= 0 )
1054 mResizeRect = QRectF( QPointF( -( mBeginHandleWidth + rx ), 0 ), QPointF( 0, mBeginHandleHeight + ry ) );
1056 else if ( mBeginHandleWidth + rx >= 0 )
1058 mResizeRect = QRectF( QPointF( 0, -( mBeginHandleHeight + ry ) ), QPointF( mBeginHandleWidth + rx, 0 ) );
1062 mResizeRect = QRectF( QPointF( -( mBeginHandleWidth + rx ), -( mBeginHandleHeight + ry ) ), QPointF( 0, 0 ) );
1065 setRect( 0, 0, fabs( mBeginHandleWidth + rx ), fabs( mBeginHandleHeight + ry ) );
1068 mComposition->
setStatusMessage( QString(
tr(
"width: %1 mm height: %2 mm" ) ).arg( rect().width() ).arg( rect().height() ) );
1076 if ( snappedPoint != point )
1079 return snappedPoint;
1095 snappedPoint = alignItem( alignX, alignY, point.x(), point.y() );
1098 snappedPoint = alignPos( point, alignX, alignY );
1104 QGraphicsLineItem* item = hAlignSnapItem();
1105 int numPages = mComposition->
numPages();
1106 double yLineCoord = 300;
1111 item->setLine( QLineF( alignX, 0, alignX, yLineCoord ) );
1116 deleteHAlignSnapItem();
1120 QGraphicsLineItem* item = vAlignSnapItem();
1121 item->setLine( QLineF( 0, alignY, mComposition->
paperWidth(), alignY ) );
1126 deleteVAlignSnapItem();
1128 return snappedPoint;
1131 QGraphicsLineItem* QgsComposerMouseHandles::hAlignSnapItem()
1133 if ( !mHAlignSnapItem )
1135 mHAlignSnapItem =
new QGraphicsLineItem( 0 );
1136 mHAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1137 scene()->addItem( mHAlignSnapItem );
1138 mHAlignSnapItem->setZValue( 90 );
1140 return mHAlignSnapItem;
1143 QGraphicsLineItem* QgsComposerMouseHandles::vAlignSnapItem()
1145 if ( !mVAlignSnapItem )
1147 mVAlignSnapItem =
new QGraphicsLineItem( 0 );
1148 mVAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1149 scene()->addItem( mVAlignSnapItem );
1150 mVAlignSnapItem->setZValue( 90 );
1152 return mVAlignSnapItem;
1155 void QgsComposerMouseHandles::deleteHAlignSnapItem()
1157 if ( mHAlignSnapItem )
1159 scene()->removeItem( mHAlignSnapItem );
1160 delete mHAlignSnapItem;
1161 mHAlignSnapItem = 0;
1165 void QgsComposerMouseHandles::deleteVAlignSnapItem()
1167 if ( mVAlignSnapItem )
1169 scene()->removeItem( mVAlignSnapItem );
1170 delete mVAlignSnapItem;
1171 mVAlignSnapItem = 0;
1175 void QgsComposerMouseHandles::deleteAlignItems()
1177 deleteHAlignSnapItem();
1178 deleteVAlignSnapItem();
1181 QPointF QgsComposerMouseHandles::alignItem(
double& alignX,
double& alignY,
double unalignedX,
double unalignedY )
1183 double left = unalignedX;
1184 double right = left + rect().width();
1185 double midH = ( left + right ) / 2.0;
1186 double top = unalignedY;
1187 double bottom = top + rect().height();
1188 double midV = ( top + bottom ) / 2.0;
1190 QMap<double, const QgsComposerItem* > xAlignCoordinates;
1191 QMap<double, const QgsComposerItem* > yAlignCoordinates;
1192 collectAlignCoordinates( xAlignCoordinates, yAlignCoordinates );
1195 double xItemLeft = left;
1196 double xAlignCoord = 0;
1197 double smallestDiffX = DBL_MAX;
1199 checkNearestItem( left, xAlignCoordinates, smallestDiffX, 0, xItemLeft, xAlignCoord );
1200 checkNearestItem( midH, xAlignCoordinates, smallestDiffX, ( left - right ) / 2.0, xItemLeft, xAlignCoord );
1201 checkNearestItem( right, xAlignCoordinates, smallestDiffX, left - right, xItemLeft, xAlignCoord );
1204 double yItemTop = top;
1205 double yAlignCoord = 0;
1206 double smallestDiffY = DBL_MAX;
1208 checkNearestItem( top, yAlignCoordinates, smallestDiffY, 0, yItemTop, yAlignCoord );
1209 checkNearestItem( midV, yAlignCoordinates, smallestDiffY, ( top - bottom ) / 2.0, yItemTop, yAlignCoord );
1210 checkNearestItem( bottom, yAlignCoordinates, smallestDiffY, top - bottom, yItemTop, yAlignCoord );
1212 double xCoord = ( smallestDiffX < 5 ) ? xItemLeft : unalignedX;
1213 alignX = ( smallestDiffX < 5 ) ? xAlignCoord : -1;
1214 double yCoord = ( smallestDiffY < 5 ) ? yItemTop : unalignedY;
1215 alignY = ( smallestDiffY < 5 ) ? yAlignCoord : -1;
1216 return QPointF( xCoord, yCoord );
1219 QPointF QgsComposerMouseHandles::alignPos(
const QPointF& pos,
double& alignX,
double& alignY )
1221 QMap<double, const QgsComposerItem* > xAlignCoordinates;
1222 QMap<double, const QgsComposerItem* > yAlignCoordinates;
1223 collectAlignCoordinates( xAlignCoordinates, yAlignCoordinates );
1225 double nearestX = pos.x();
1226 double nearestY = pos.y();
1227 if ( !nearestItem( xAlignCoordinates, pos.x(), nearestX )
1228 || !nearestItem( yAlignCoordinates, pos.y(), nearestY ) )
1236 double viewScaleFactor = graphicsView()->transform().m11();
1237 double alignThreshold = mComposition->
snapTolerance() / viewScaleFactor;
1239 QPointF result( pos.x(), pos.y() );
1240 if ( fabs( nearestX - pos.x() ) < alignThreshold )
1242 result.setX( nearestX );
1250 if ( fabs( nearestY - pos.y() ) < alignThreshold )
1252 result.setY( nearestY );
1262 void QgsComposerMouseHandles::collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX, QMap< double, const QgsComposerItem* >& alignCoordsY )
1264 alignCoordsX.clear();
1265 alignCoordsY.clear();
1269 QList<QGraphicsItem *> itemList = mComposition->items();
1270 QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
1271 for ( ; itemIt != itemList.end(); ++itemIt )
1277 if ( !currentItem || currentItem->
selected() || currentItem->
isGroupMember() || !currentItem->isVisible() )
1282 if ( dynamic_cast<const QgsPaperItem *>( *itemIt ) )
1286 itemRect = currentItem->mapRectToScene( currentItem->rect() );
1290 itemRect = currentItem->mapRectToScene( currentItem->
rectWithFrame() );
1292 alignCoordsX.insert( itemRect.left(), currentItem );
1293 alignCoordsX.insert( itemRect.right(), currentItem );
1294 alignCoordsX.insert( itemRect.center().x(), currentItem );
1295 alignCoordsY.insert( itemRect.top(), currentItem );
1296 alignCoordsY.insert( itemRect.center().y(), currentItem );
1297 alignCoordsY.insert( itemRect.bottom(), currentItem );
1304 QList< QGraphicsLineItem* >::const_iterator sIt = mComposition->
snapLines()->constBegin();
1305 for ( ; sIt != mComposition->
snapLines()->constEnd(); ++sIt )
1307 double x = ( *sIt )->line().x1();
1308 double y = ( *sIt )->line().y1();
1311 alignCoordsX.insert( x, 0 );
1315 alignCoordsY.insert( y, 0 );
1321 void QgsComposerMouseHandles::checkNearestItem(
double checkCoord,
const QMap< double, const QgsComposerItem* >& alignCoords,
double& smallestDiff,
double itemCoordOffset,
double& itemCoord,
double& alignCoord )
1323 double currentCoord = 0;
1324 if ( !nearestItem( alignCoords, checkCoord, currentCoord ) )
1329 double currentDiff = fabs( checkCoord - currentCoord );
1331 double viewScaleFactor = graphicsView()->transform().m11();
1332 double alignThreshold = mComposition->
snapTolerance() / viewScaleFactor;
1334 if ( currentDiff < alignThreshold && currentDiff < smallestDiff )
1336 itemCoord = currentCoord + itemCoordOffset;
1337 alignCoord = currentCoord;
1338 smallestDiff = currentDiff;
1342 bool QgsComposerMouseHandles::nearestItem(
const QMap< double, const QgsComposerItem* >& coords,
double value,
double& nearestValue )
const
1344 if ( coords.size() < 1 )
1349 QMap< double, const QgsComposerItem* >::const_iterator it = coords.lowerBound( value );
1350 if ( it == coords.constBegin() )
1352 nearestValue = it.key();
1355 else if ( it == coords.constEnd() )
1358 nearestValue = it.key();
1364 double upperVal = it.key();
1366 double lowerVal = it.key();
1368 double lowerDiff = value - lowerVal;
1369 double upperDiff = upperVal - value;
1370 if ( lowerDiff < upperDiff )
1372 nearestValue = lowerVal;
1377 nearestValue = upperVal;