21#include <QGraphicsView> 
   22#include <QGraphicsSceneHoverEvent> 
   29QgsGraphicsViewMouseHandles::QgsGraphicsViewMouseHandles( QGraphicsView *view )
 
   31  , QGraphicsRectItem( nullptr )
 
   35  setAcceptHoverEvents( 
true );
 
   38void QgsGraphicsViewMouseHandles::paintInternal( QPainter *painter, 
bool showHandles, 
bool showStaticBoundingBoxes, 
bool showTemporaryBoundingBoxes, 
const QStyleOptionGraphicsItem *, QWidget * )
 
   45  if ( showStaticBoundingBoxes )
 
   48    double rectHandlerSize = rectHandlerBorderTolerance();
 
   49    drawHandles( painter, rectHandlerSize );
 
   52  if ( showTemporaryBoundingBoxes && ( mIsResizing || mIsDragging || showStaticBoundingBoxes ) )
 
   55    drawSelectedItemBounds( painter );
 
   59QRectF QgsGraphicsViewMouseHandles::storedItemRect( QGraphicsItem *item )
 const 
   61  return itemRect( item );
 
   64void QgsGraphicsViewMouseHandles::previewItemMove( QGraphicsItem *, 
double, 
double )
 
   69QRectF QgsGraphicsViewMouseHandles::previewSetItemRect( QGraphicsItem *, QRectF )
 
   74void QgsGraphicsViewMouseHandles::startMacroCommand( 
const QString & )
 
   79void QgsGraphicsViewMouseHandles::endMacroCommand()
 
   84void QgsGraphicsViewMouseHandles::endItemCommand( QGraphicsItem * )
 
   89void QgsGraphicsViewMouseHandles::createItemCommand( QGraphicsItem * )
 
   94QPointF QgsGraphicsViewMouseHandles::snapPoint( QPointF originalPoint, QgsGraphicsViewMouseHandles::SnapGuideMode, 
bool, 
bool )
 
   99void QgsGraphicsViewMouseHandles::expandItemList( 
const QList<QGraphicsItem *> &items, QList<QGraphicsItem *> &collected )
 const 
  104void QgsGraphicsViewMouseHandles::drawHandles( QPainter *painter, 
double rectHandlerSize )
 
  107  QPen handlePen = QPen( QColor( 55, 140, 195, 255 ) );
 
  108  handlePen.setWidth( 0 );
 
  109  painter->setPen( handlePen );
 
  112  painter->setBrush( Qt::NoBrush );
 
  113  painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
 
  116  painter->setBrush( QColor( 255, 255, 255, 255 ) );
 
  118  painter->drawRect( QRectF( 0, 0, rectHandlerSize, rectHandlerSize ) );
 
  120  painter->drawRect( QRectF( ( rect().width() - rectHandlerSize ) / 2, 0, rectHandlerSize, rectHandlerSize ) );
 
  122  painter->drawRect( QRectF( rect().width() - rectHandlerSize, 0, rectHandlerSize, rectHandlerSize ) );
 
  124  painter->drawRect( QRectF( 0, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
 
  126  painter->drawRect( QRectF( rect().width() - rectHandlerSize, ( rect().height() - rectHandlerSize ) / 2, rectHandlerSize, rectHandlerSize ) );
 
  128  painter->drawRect( QRectF( 0, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
 
  130  painter->drawRect( QRectF( ( rect().width() - rectHandlerSize ) / 2, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
 
  132  painter->drawRect( QRectF( rect().width() - rectHandlerSize, rect().height() - rectHandlerSize, rectHandlerSize, rectHandlerSize ) );
 
  135void QgsGraphicsViewMouseHandles::drawSelectedItemBounds( QPainter *painter )
 
  138  const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  139  if ( selectedItems.isEmpty() )
 
  146  painter->setCompositionMode( QPainter::CompositionMode_Difference );
 
  149  QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
 
  150  selectedItemPen.setStyle( Qt::DashLine );
 
  151  selectedItemPen.setWidth( 0 );
 
  152  painter->setPen( selectedItemPen );
 
  153  painter->setBrush( Qt::NoBrush );
 
  155  QList< QGraphicsItem * > itemsToDraw;
 
  156  expandItemList( selectedItems, itemsToDraw );
 
  158  for ( QGraphicsItem *item : std::as_const( itemsToDraw ) )
 
  161    QPolygonF itemBounds;
 
  162    if ( isDragging() && !itemIsLocked( item ) )
 
  166      QPolygonF itemSceneBounds = item->mapToScene( itemRect( item ) );
 
  169      itemSceneBounds.translate( transform().dx(), transform().dy() );
 
  171      itemBounds = mapFromScene( itemSceneBounds );
 
  173    else if ( isResizing() && !itemIsLocked( item ) )
 
  176      if ( selectedItems.size() > 1 )
 
  179        QRectF thisItemRect = mapRectFromItem( item, itemRect( item ) );
 
  181        relativeResizeRect( thisItemRect, QRectF( -mResizeMoveX, -mResizeMoveY, mBeginHandleWidth, mBeginHandleHeight ), mResizeRect );
 
  182        itemBounds = QPolygonF( thisItemRect );
 
  193      itemBounds = mapRectFromItem( item, itemRect( item ) );
 
  199    path.addPolygon( itemBounds );
 
  200    painter->drawPath( path );
 
  204double QgsGraphicsViewMouseHandles::rectHandlerBorderTolerance()
 
  211  double viewScaleFactor = mView->transform().m11();
 
  214  double rectHandlerSize = mHandleSize / viewScaleFactor;
 
  217  if ( rectHandlerSize > ( rect().width() / 3 ) )
 
  219    rectHandlerSize = rect().width() / 3;
 
  221  if ( rectHandlerSize > ( rect().height() / 3 ) )
 
  223    rectHandlerSize = rect().height() / 3;
 
  225  return rectHandlerSize;
 
  228Qt::CursorShape QgsGraphicsViewMouseHandles::cursorForPosition( QPointF itemCoordPos )
 
  230  QgsGraphicsViewMouseHandles::MouseAction mouseAction = mouseActionForPosition( itemCoordPos );
 
  231  double normalizedRotation = std::fmod( rotation(), 360 );
 
  232  if ( normalizedRotation < 0 )
 
  234    normalizedRotation += 360;
 
  236  switch ( mouseAction )
 
  239      return Qt::ForbiddenCursor;
 
  241      return Qt::SizeAllCursor;
 
  245      if ( ( normalizedRotation <= 22.5 || normalizedRotation >= 337.5 ) || ( normalizedRotation >= 157.5 && normalizedRotation <= 202.5 ) )
 
  247        return Qt::SizeVerCursor;
 
  249      else if ( ( normalizedRotation >= 22.5 && normalizedRotation <= 67.5 ) || ( normalizedRotation >= 202.5 && normalizedRotation <= 247.5 ) )
 
  251        return Qt::SizeBDiagCursor;
 
  253      else if ( ( normalizedRotation >= 67.5 && normalizedRotation <= 112.5 ) || ( normalizedRotation >= 247.5 && normalizedRotation <= 292.5 ) )
 
  255        return Qt::SizeHorCursor;
 
  259        return Qt::SizeFDiagCursor;
 
  264      if ( ( normalizedRotation <= 22.5 || normalizedRotation >= 337.5 ) || ( normalizedRotation >= 157.5 && normalizedRotation <= 202.5 ) )
 
  266        return Qt::SizeHorCursor;
 
  268      else if ( ( normalizedRotation >= 22.5 && normalizedRotation <= 67.5 ) || ( normalizedRotation >= 202.5 && normalizedRotation <= 247.5 ) )
 
  270        return Qt::SizeFDiagCursor;
 
  272      else if ( ( normalizedRotation >= 67.5 && normalizedRotation <= 112.5 ) || ( normalizedRotation >= 247.5 && normalizedRotation <= 292.5 ) )
 
  274        return Qt::SizeVerCursor;
 
  278        return Qt::SizeBDiagCursor;
 
  282    case ResizeRightDown:
 
  284      if ( ( normalizedRotation <= 22.5 || normalizedRotation >= 337.5 ) || ( normalizedRotation >= 157.5 && normalizedRotation <= 202.5 ) )
 
  286        return Qt::SizeFDiagCursor;
 
  288      else if ( ( normalizedRotation >= 22.5 && normalizedRotation <= 67.5 ) || ( normalizedRotation >= 202.5 && normalizedRotation <= 247.5 ) )
 
  290        return Qt::SizeVerCursor;
 
  292      else if ( ( normalizedRotation >= 67.5 && normalizedRotation <= 112.5 ) || ( normalizedRotation >= 247.5 && normalizedRotation <= 292.5 ) )
 
  294        return Qt::SizeBDiagCursor;
 
  298        return Qt::SizeHorCursor;
 
  303      if ( ( normalizedRotation <= 22.5 || normalizedRotation >= 337.5 ) || ( normalizedRotation >= 157.5 && normalizedRotation <= 202.5 ) )
 
  305        return Qt::SizeBDiagCursor;
 
  307      else if ( ( normalizedRotation >= 22.5 && normalizedRotation <= 67.5 ) || ( normalizedRotation >= 202.5 && normalizedRotation <= 247.5 ) )
 
  309        return Qt::SizeHorCursor;
 
  311      else if ( ( normalizedRotation >= 67.5 && normalizedRotation <= 112.5 ) || ( normalizedRotation >= 247.5 && normalizedRotation <= 292.5 ) )
 
  313        return Qt::SizeFDiagCursor;
 
  317        return Qt::SizeVerCursor;
 
  320      return Qt::ArrowCursor;
 
  323  return Qt::ArrowCursor;
 
  326QgsGraphicsViewMouseHandles::MouseAction QgsGraphicsViewMouseHandles::mouseActionForPosition( QPointF itemCoordPos )
 
  328  bool nearLeftBorder = 
false;
 
  329  bool nearRightBorder = 
false;
 
  330  bool nearLowerBorder = 
false;
 
  331  bool nearUpperBorder = 
false;
 
  333  bool withinWidth = 
false;
 
  334  bool withinHeight = 
false;
 
  335  if ( itemCoordPos.x() >= 0 && itemCoordPos.x() <= rect().width() )
 
  339  if ( itemCoordPos.y() >= 0 && itemCoordPos.y() <= rect().height() )
 
  344  double borderTolerance = rectHandlerBorderTolerance();
 
  346  if ( itemCoordPos.x() >= 0 && itemCoordPos.x() < borderTolerance )
 
  348    nearLeftBorder = 
true;
 
  350  if ( itemCoordPos.y() >= 0 && itemCoordPos.y() < borderTolerance )
 
  352    nearUpperBorder = 
true;
 
  354  if ( itemCoordPos.x() <= rect().width() && itemCoordPos.x() > ( rect().width() - borderTolerance ) )
 
  356    nearRightBorder = 
true;
 
  358  if ( itemCoordPos.y() <= rect().height() && itemCoordPos.y() > ( rect().height() - borderTolerance ) )
 
  360    nearLowerBorder = 
true;
 
  363  if ( nearLeftBorder && nearUpperBorder )
 
  365    return QgsGraphicsViewMouseHandles::ResizeLeftUp;
 
  367  else if ( nearLeftBorder && nearLowerBorder )
 
  369    return QgsGraphicsViewMouseHandles::ResizeLeftDown;
 
  371  else if ( nearRightBorder && nearUpperBorder )
 
  373    return QgsGraphicsViewMouseHandles::ResizeRightUp;
 
  375  else if ( nearRightBorder && nearLowerBorder )
 
  377    return QgsGraphicsViewMouseHandles::ResizeRightDown;
 
  379  else if ( nearLeftBorder && withinHeight )
 
  381    return QgsGraphicsViewMouseHandles::ResizeLeft;
 
  383  else if ( nearRightBorder && withinHeight )
 
  385    return QgsGraphicsViewMouseHandles::ResizeRight;
 
  387  else if ( nearUpperBorder && withinWidth )
 
  389    return QgsGraphicsViewMouseHandles::ResizeUp;
 
  391  else if ( nearLowerBorder && withinWidth )
 
  393    return QgsGraphicsViewMouseHandles::ResizeDown;
 
  397  QPointF scenePoint = mapToScene( itemCoordPos );
 
  398  const QList<QGraphicsItem *> itemsAtCursorPos = sceneItemsAtPoint( scenePoint );
 
  399  if ( itemsAtCursorPos.isEmpty() )
 
  402    return QgsGraphicsViewMouseHandles::SelectItem;
 
  404  for ( QGraphicsItem *graphicsItem : itemsAtCursorPos )
 
  406    if ( graphicsItem && graphicsItem->isSelected() )
 
  409      return QgsGraphicsViewMouseHandles::MoveItem;
 
  414  return QgsGraphicsViewMouseHandles::SelectItem;
 
  417QgsGraphicsViewMouseHandles::MouseAction QgsGraphicsViewMouseHandles::mouseActionForScenePos( QPointF sceneCoordPos )
 
  420  QPointF itemPos = mapFromScene( sceneCoordPos );
 
  421  return mouseActionForPosition( itemPos );
 
  424bool QgsGraphicsViewMouseHandles::shouldBlockEvent( QInputEvent * )
 const 
  426  return mIsDragging || mIsResizing;
 
  429void QgsGraphicsViewMouseHandles::selectedItemSizeChanged()
 
  431  if ( !isDragging() && !isResizing() )
 
  438void QgsGraphicsViewMouseHandles::selectedItemRotationChanged()
 
  440  if ( !isDragging() && !isResizing() )
 
  447void QgsGraphicsViewMouseHandles::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
 
  449  setViewportCursor( cursorForPosition( event->pos() ) );
 
  452void QgsGraphicsViewMouseHandles::hoverLeaveEvent( QGraphicsSceneHoverEvent *event )
 
  455  setViewportCursor( Qt::ArrowCursor );
 
  458void QgsGraphicsViewMouseHandles::mousePressEvent( QGraphicsSceneMouseEvent *event )
 
  460  if ( event->button() != Qt::LeftButton )
 
  467  mMouseMoveStartPos = 
event->lastScenePos();
 
  468  mLastMouseEventPos = 
event->lastScenePos();
 
  470  mBeginMouseEventPos = 
event->lastScenePos();
 
  471  mBeginHandlePos = scenePos();
 
  472  mBeginHandleWidth = rect().width();
 
  473  mBeginHandleHeight = rect().height();
 
  475  mCurrentMouseMoveAction = mouseActionForPosition( event->pos() );
 
  479  if ( mCurrentMouseMoveAction == MoveItem )
 
  484  else if ( mCurrentMouseMoveAction != SelectItem &&
 
  485            mCurrentMouseMoveAction != NoAction )
 
  489    mResizeRect = QRectF( 0, 0, mBeginHandleWidth, mBeginHandleHeight );
 
  492    mCursorOffset = calcCursorEdgeOffset( mMouseMoveStartPos );
 
  497void QgsGraphicsViewMouseHandles::resetStatusBar()
 
  499  const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  500  int selectedCount = selectedItems.size();
 
  504    showStatusMessage( tr( 
"%n item(s) selected", 
nullptr, selectedCount ) );
 
  509    showStatusMessage( QString() );
 
  513void QgsGraphicsViewMouseHandles::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
 
  520    dragMouseMove( event->lastScenePos(), event->modifiers() & Qt::ShiftModifier, event->modifiers() & Qt::ControlModifier );
 
  522  else if ( isResizing() )
 
  527    resizeMouseMove( event->lastScenePos(), event->modifiers() & Qt::ShiftModifier, event->modifiers() & Qt::AltModifier );
 
  530  mLastMouseEventPos = 
event->lastScenePos();
 
  533void QgsGraphicsViewMouseHandles::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
 
  535  if ( event->button() != Qt::LeftButton )
 
  541  QPointF mouseMoveStopPoint = 
event->lastScenePos();
 
  542  double diffX = mouseMoveStopPoint.x() - mMouseMoveStartPos.x();
 
  543  double diffY = mouseMoveStopPoint.y() - mMouseMoveStartPos.y();
 
  546  if ( std::fabs( diffX ) < std::numeric_limits<double>::min() && std::fabs( diffY ) < std::numeric_limits<double>::min() )
 
  555  if ( mCurrentMouseMoveAction == MoveItem )
 
  558    startMacroCommand( tr( 
"Move Items" ) );
 
  560    QPointF mEndHandleMovePos = scenePos();
 
  562    double deltaX = mEndHandleMovePos.x() - mBeginHandlePos.x();
 
  563    double deltaY = mEndHandleMovePos.y() - mBeginHandlePos.y();
 
  566    const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  567    for ( QGraphicsItem *item : selectedItems )
 
  569      if ( itemIsLocked( item ) || ( item->flags() & QGraphicsItem::ItemIsSelectable ) == 0 || itemIsGroupMember( item ) )
 
  575      createItemCommand( item );
 
  576      moveItem( item, deltaX, deltaY );
 
  577      endItemCommand( item );
 
  581  else if ( mCurrentMouseMoveAction != NoAction )
 
  584    startMacroCommand( tr( 
"Resize Items" ) );
 
  587    const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  588    for ( QGraphicsItem *item : selectedItems )
 
  590      if ( itemIsLocked( item ) || ( item->flags() & QGraphicsItem::ItemIsSelectable ) == 0 )
 
  595      createItemCommand( item );
 
  598      if ( selectedItems.size() == 1 )
 
  601        thisItemRect = mResizeRect;
 
  606        thisItemRect = mapRectFromItem( item, itemRect( item ) );
 
  607        relativeResizeRect( thisItemRect, QRectF( -mResizeMoveX, -mResizeMoveY, mBeginHandleWidth, mBeginHandleHeight ), mResizeRect );
 
  610      thisItemRect = thisItemRect.normalized();
 
  611      QPointF newPos = mapToScene( thisItemRect.topLeft() );
 
  612      thisItemRect.moveTopLeft( newPos );
 
  613      setItemRect( item, thisItemRect );
 
  615      endItemCommand( item );
 
  631  mCurrentMouseMoveAction = MoveItem;
 
  632  setViewportCursor( Qt::ArrowCursor );
 
  640bool QgsGraphicsViewMouseHandles::selectionRotation( 
double &rotation )
 const 
  643  QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  644  auto itemIter = selectedItems.constBegin();
 
  647  double firstItemRotation = ( *itemIter )->rotation();
 
  650  for ( ++itemIter; itemIter != selectedItems.constEnd(); ++itemIter )
 
  652    if ( !
qgsDoubleNear( ( *itemIter )->rotation(), firstItemRotation ) )
 
  660  rotation = firstItemRotation;
 
  664void QgsGraphicsViewMouseHandles::updateHandles()
 
  669  QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  670  if ( !selectedItems.isEmpty() )
 
  676    if ( selectionRotation( rotation ) )
 
  679      setRotation( rotation );
 
  688    QRectF newHandleBounds = selectionBounds();
 
  691    setRect( 0, 0, newHandleBounds.width(), newHandleBounds.height() );
 
  692    setPos( mapToScene( newHandleBounds.topLeft() ) );
 
  705void QgsGraphicsViewMouseHandles::dragMouseMove( QPointF currentPosition, 
bool lockMovement, 
bool preventSnap )
 
  713  double moveX = currentPosition.x() - mBeginMouseEventPos.x();
 
  714  double moveY = currentPosition.y() - mBeginMouseEventPos.y();
 
  717  QPointF upperLeftPoint( mBeginHandlePos.x() + moveX, mBeginHandlePos.y() + moveY );
 
  719  QPointF snappedLeftPoint;
 
  725    snappedLeftPoint = snapPoint( upperLeftPoint, Item );
 
  730    snappedLeftPoint = upperLeftPoint;
 
  735  double moveRectX = snappedLeftPoint.x() - mBeginHandlePos.x();
 
  736  double moveRectY = snappedLeftPoint.y() - mBeginHandlePos.y();
 
  742    if ( std::fabs( moveRectX ) <= std::fabs( moveRectY ) )
 
  753  QTransform moveTransform;
 
  754  moveTransform.translate( moveRectX, moveRectY );
 
  755  setTransform( moveTransform );
 
  757  const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
  758  for ( QGraphicsItem *item : selectedItems )
 
  760    previewItemMove( item, moveRectX, moveRectY );
 
  763  showStatusMessage( tr( 
"dx: %1 mm dy: %2 mm" ).arg( moveRectX ).arg( moveRectY ) );
 
  766void QgsGraphicsViewMouseHandles::resizeMouseMove( QPointF currentPosition, 
bool lockRatio, 
bool fromCenter )
 
  773  double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
 
  775  QPointF beginMousePos;
 
  776  QPointF finalPosition;
 
  781    bool snapVertical = mCurrentMouseMoveAction == ResizeLeft ||
 
  782                        mCurrentMouseMoveAction == ResizeRight ||
 
  783                        mCurrentMouseMoveAction == ResizeLeftUp ||
 
  784                        mCurrentMouseMoveAction == ResizeRightUp ||
 
  785                        mCurrentMouseMoveAction == ResizeLeftDown ||
 
  786                        mCurrentMouseMoveAction == ResizeRightDown;
 
  788    bool snapHorizontal = mCurrentMouseMoveAction == ResizeUp ||
 
  789                          mCurrentMouseMoveAction == ResizeDown ||
 
  790                          mCurrentMouseMoveAction == ResizeLeftUp ||
 
  791                          mCurrentMouseMoveAction == ResizeRightUp ||
 
  792                          mCurrentMouseMoveAction == ResizeLeftDown ||
 
  793                          mCurrentMouseMoveAction == ResizeRightDown;
 
  797    beginMousePos = mapFromScene( QPointF( mBeginMouseEventPos.x() - mCursorOffset.width(), mBeginMouseEventPos.y() - mCursorOffset.height() ) );
 
  798    QPointF snappedPosition = snapPoint( QPointF( currentPosition.x() - mCursorOffset.width(), currentPosition.y() - mCursorOffset.height() ), Point, snapHorizontal, snapVertical );
 
  799    finalPosition = mapFromScene( snappedPosition );
 
  804    beginMousePos = mapFromScene( mBeginMouseEventPos );
 
  805    finalPosition = mapFromScene( currentPosition );
 
  808  double diffX = finalPosition.x() - beginMousePos.x();
 
  809  double diffY = finalPosition.y() - beginMousePos.y();
 
  812  if ( lockRatio && !
qgsDoubleNear( mBeginHandleHeight, 0.0 ) )
 
  814    ratio = mBeginHandleWidth / mBeginHandleHeight;
 
  817  switch ( mCurrentMouseMoveAction )
 
  824        diffX = ( ( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
 
  844        diffX = ( ( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
 
  865        diffY = ( ( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
 
  884        diffY = ( ( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
 
  905        if ( ( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
 
  907          diffX = mBeginHandleWidth - ( ( mBeginHandleHeight - diffY ) * ratio );
 
  911          diffY = mBeginHandleHeight - ( ( mBeginHandleWidth - diffX ) / ratio );
 
  914      mx = diffX, my = diffY;
 
  920    case ResizeRightDown:
 
  925        if ( ( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
 
  927          diffX = ( ( mBeginHandleHeight + diffY ) * ratio ) - mBeginHandleWidth;
 
  931          diffY = ( ( mBeginHandleWidth + diffX ) / ratio ) - mBeginHandleHeight;
 
  936      rx = diffX, ry = diffY;
 
  945        if ( ( mBeginHandleWidth + diffX ) / ( mBeginHandleHeight - diffY ) > ratio )
 
  947          diffX = ( ( mBeginHandleHeight - diffY ) * ratio ) - mBeginHandleWidth;
 
  951          diffY = mBeginHandleHeight - ( ( mBeginHandleWidth + diffX ) / ratio );
 
  955      my = diffY, rx = diffX, ry = -diffY;
 
  964        if ( ( mBeginHandleWidth - diffX ) / ( mBeginHandleHeight + diffY ) > ratio )
 
  966          diffX = mBeginHandleWidth - ( ( mBeginHandleHeight + diffY ) * ratio );
 
  970          diffY = ( ( mBeginHandleWidth - diffX ) / ratio ) - mBeginHandleHeight;
 
  997  mResizeMoveX = mBeginHandleWidth + rx > 0 ? mx : mx + mBeginHandleWidth + rx;
 
  998  mResizeMoveY = mBeginHandleHeight + ry > 0 ? my : my + mBeginHandleHeight + ry;
 
 1001  QLineF translateLine = QLineF( 0, 0, mResizeMoveX, mResizeMoveY );
 
 1002  translateLine.setAngle( translateLine.angle() - rotation() );
 
 1003  QPointF sceneTranslate = translateLine.p2();
 
 1006  QTransform itemTransform;
 
 1007  itemTransform.translate( sceneTranslate.x(), sceneTranslate.y() );
 
 1008  setTransform( itemTransform );
 
 1011  if ( mBeginHandleWidth + rx >= 0 && mBeginHandleHeight + ry >= 0 )
 
 1013    mResizeRect = QRectF( 0, 0, mBeginHandleWidth + rx, mBeginHandleHeight + ry );
 
 1015  else if ( mBeginHandleHeight + ry >= 0 )
 
 1017    mResizeRect = QRectF( QPointF( -( mBeginHandleWidth + rx ), 0 ), QPointF( 0, mBeginHandleHeight + ry ) );
 
 1019  else if ( mBeginHandleWidth + rx >= 0 )
 
 1021    mResizeRect = QRectF( QPointF( 0, -( mBeginHandleHeight + ry ) ), QPointF( mBeginHandleWidth + rx, 0 ) );
 
 1025    mResizeRect = QRectF( QPointF( -( mBeginHandleWidth + rx ), -( mBeginHandleHeight + ry ) ), QPointF( 0, 0 ) );
 
 1028  const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
 1029  QRectF newHandleBounds;
 
 1030  for ( QGraphicsItem *item : selectedItems )
 
 1033    QRectF thisItemRect = mapRectFromScene( storedItemRect( item ) );
 
 1035    relativeResizeRect( thisItemRect, QRectF( -mResizeMoveX, -mResizeMoveY, mBeginHandleWidth, mBeginHandleHeight ), mResizeRect );
 
 1037    thisItemRect = mapRectFromScene( previewSetItemRect( item, mapRectToScene( thisItemRect ) ) );
 
 1038    newHandleBounds = newHandleBounds.isValid() ? newHandleBounds.united( thisItemRect ) : thisItemRect;
 
 1041  setRect( newHandleBounds.isValid() ? newHandleBounds : QRectF( 0, 0, std::fabs( mBeginHandleWidth + rx ), std::fabs( mBeginHandleHeight + ry ) ) );
 
 1044  showStatusMessage( tr( 
"width: %1 mm height: %2 mm" ).arg( rect().width() ).arg( rect().height() ) );
 
 1048void QgsGraphicsViewMouseHandles::setHandleSize( 
double size )
 
 1053void QgsGraphicsViewMouseHandles::mouseDoubleClickEvent( QGraphicsSceneMouseEvent *event )
 
 1058QSizeF QgsGraphicsViewMouseHandles::calcCursorEdgeOffset( QPointF cursorPos )
 
 1061  QPointF sceneMousePos = mapFromScene( cursorPos );
 
 1063  switch ( mCurrentMouseMoveAction )
 
 1066    case QgsGraphicsViewMouseHandles::ResizeUp:
 
 1067      return QSizeF( 0, sceneMousePos.y() );
 
 1069    case QgsGraphicsViewMouseHandles::ResizeDown:
 
 1070      return QSizeF( 0, sceneMousePos.y() - rect().height() );
 
 1073    case QgsGraphicsViewMouseHandles::ResizeLeft:
 
 1074      return QSizeF( sceneMousePos.x(), 0 );
 
 1076    case QgsGraphicsViewMouseHandles::ResizeRight:
 
 1077      return QSizeF( sceneMousePos.x() - rect().width(), 0 );
 
 1080    case QgsGraphicsViewMouseHandles::ResizeLeftUp:
 
 1081      return QSizeF( sceneMousePos.x(), sceneMousePos.y() );
 
 1083    case QgsGraphicsViewMouseHandles::ResizeRightDown:
 
 1084      return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() - rect().height() );
 
 1086    case QgsGraphicsViewMouseHandles::ResizeRightUp:
 
 1087      return QSizeF( sceneMousePos.x() - rect().width(), sceneMousePos.y() );
 
 1089    case QgsGraphicsViewMouseHandles::ResizeLeftDown:
 
 1090      return QSizeF( sceneMousePos.x(), sceneMousePos.y() - rect().height() );
 
 1101QRectF QgsGraphicsViewMouseHandles::selectionBounds()
 const 
 1104  const QList<QGraphicsItem *> selectedItems = selectedSceneItems( 
false );
 
 1105  auto itemIter = selectedItems.constBegin();
 
 1108  QRectF bounds = mapFromItem( ( *itemIter ), itemRect( *itemIter ) ).boundingRect();
 
 1111  for ( ++itemIter; itemIter != selectedItems.constEnd(); ++itemIter )
 
 1113    bounds = bounds.united( mapFromItem( ( *itemIter ), itemRect( *itemIter ) ).boundingRect() );
 
 1119void QgsGraphicsViewMouseHandles::relativeResizeRect( QRectF &rectToResize, 
const QRectF &boundsBefore, 
const QRectF &boundsAfter )
 
 1122  double left = relativePosition( rectToResize.left(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
 
 1123  double right = relativePosition( rectToResize.right(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
 
 1124  double top = relativePosition( rectToResize.top(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
 
 1125  double bottom = relativePosition( rectToResize.bottom(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
 
 1127  rectToResize.setRect( left, top, right - left, bottom - top );
 
 1130double QgsGraphicsViewMouseHandles::relativePosition( 
double position, 
double beforeMin, 
double beforeMax, 
double afterMin, 
double afterMax )
 
 1133  double m = ( afterMax - afterMin ) / ( beforeMax - beforeMin );
 
 1134  double c = afterMin - ( beforeMin * m );
 
 1137  return m * position + 
c;
 
Scoped object for saving and restoring a QPainter object's state.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)