Example #1
0
void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent* e )
{
  deleteRubberBands();

  QgsLabelPosition labelPos;
  if ( !labelAtPosition( e, labelPos ) )
  {
    mCurrentLabel = LabelDetails();
    return;
  }

  mCurrentLabel = LabelDetails( labelPos );

  QgsVectorLayer* vlayer = mCurrentLabel.layer;
  if ( !vlayer || !vlayer->isEditable() )
  {
    return;
  }

  int xCol, yCol;
  if ( labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) ||
       diagramMoveable( vlayer, xCol, yCol ) )
  {
    mStartPointMapCoords = toMapCoordinates( e->pos() );
    QgsPoint referencePoint;
    if ( !currentLabelRotationPoint( referencePoint, !currentLabelPreserveRotation(), false ) )
    {
      referencePoint.setX( mCurrentLabel.pos.labelRect.xMinimum() );
      referencePoint.setY( mCurrentLabel.pos.labelRect.yMinimum() );
    }
    mClickOffsetX = mStartPointMapCoords.x() - referencePoint.x();
    mClickOffsetY = mStartPointMapCoords.y() - referencePoint.y();
    createRubberBands();
  }
}
Example #2
0
void QgsMapToolMoveLabel::canvasReleaseEvent( QgsMapMouseEvent* e )
{
  if ( !mLabelRubberBand )
  {
    return;
  }

  deleteRubberBands();

  QgsVectorLayer* vlayer = mCurrentLabel.layer;
  if ( !vlayer || !vlayer->isEditable() )
  {
    return;
  }

  QgsPoint releaseCoords = toMapCoordinates( e->pos() );
  double xdiff = releaseCoords.x() - mStartPointMapCoords.x();
  double ydiff = releaseCoords.y() - mStartPointMapCoords.y();

  int xCol, yCol;
  double xPosOrig, yPosOrig;
  bool xSuccess, ySuccess;

  if ( !currentLabelDataDefinedPosition( xPosOrig, xSuccess, yPosOrig, ySuccess, xCol, yCol ) )
  {
    return;
  }

  double xPosNew, yPosNew;

  if ( !xSuccess || !ySuccess )
  {
    xPosNew = releaseCoords.x() - mClickOffsetX;
    yPosNew = releaseCoords.y() - mClickOffsetY;
  }
  else
  {
    //transform to map crs first, because xdiff,ydiff are in map coordinates
    const QgsMapSettings& ms = mCanvas->mapSettings();
    if ( ms.hasCrsTransformEnabled() )
    {
      QgsPoint transformedPoint = ms.layerToMapCoordinates( vlayer, QgsPoint( xPosOrig, yPosOrig ) );
      xPosOrig = transformedPoint.x();
      yPosOrig = transformedPoint.y();
    }
    xPosNew = xPosOrig + xdiff;
    yPosNew = yPosOrig + ydiff;
  }

  //transform back to layer crs
  if ( mCanvas )
  {
    const QgsMapSettings& s = mCanvas->mapSettings();
    if ( s.hasCrsTransformEnabled() )
    {
      QgsPoint transformedPoint = s.mapToLayerCoordinates( vlayer, QgsPoint( xPosNew, yPosNew ) );
      xPosNew = transformedPoint.x();
      yPosNew = transformedPoint.y();
    }
  }

  vlayer->beginEditCommand( tr( "Moved label" ) + QString( " '%1'" ).arg( currentLabelText( 24 ) ) );
  vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, xCol, xPosNew );
  vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, yCol, yPosNew );

  // set rotation to that of label, if data-defined and no rotation set yet
  // honor whether to preserve preexisting data on pin
  // must come after setting x and y positions
  if ( !mCurrentLabel.pos.isDiagram
       && !mCurrentLabel.pos.isPinned
       && !currentLabelPreserveRotation() )
  {
    double defRot;
    bool rSuccess;
    int rCol;
    if ( currentLabelDataDefinedRotation( defRot, rSuccess, rCol ) )
    {
      double labelRot = mCurrentLabel.pos.rotation * 180 / M_PI;
      vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, rCol, labelRot );
    }
  }
  vlayer->endEditCommand();

  if ( mCanvas )
    mCanvas->refresh();
}
bool QgsMapToolPinLabels::pinUnpinCurrentLabel( bool pin )
{
  QgsVectorLayer *vlayer = mCurrentLabel.layer;
  const QgsLabelPosition &labelpos = mCurrentLabel.pos;

  // skip diagrams
  if ( labelpos.isDiagram )
  {
    QgsDebugMsg( QStringLiteral( "Label is diagram, skipping" ) );
    return false;
  }

  // verify attribute table has x, y fields mapped
  int xCol, yCol;
  double xPosOrig, yPosOrig;
  bool xSuccess, ySuccess;

  if ( !currentLabelDataDefinedPosition( xPosOrig, xSuccess, yPosOrig, ySuccess, xCol, yCol ) )
  {
    QgsDebugMsg( QStringLiteral( "Label X or Y column not mapped, skipping" ) );
    return false;
  }

  // rotation field is optional, but will be used if available, unless data exists
  int rCol;
  bool rSuccess = false;
  double defRot;

  bool hasRCol = currentLabelDataDefinedRotation( defRot, rSuccess, rCol, true );

  // get whether to preserve predefined rotation data during label pin/unpin operations
  bool preserveRot = currentLabelPreserveRotation();

  // edit attribute table
  int fid = labelpos.featureId;

  bool writeFailed = false;
  QString labelText = currentLabelText( 24 );

  if ( pin )
  {

//     QgsPointXY labelpoint = labelpos.cornerPoints.at( 0 );

    QgsPointXY referencePoint;
    if ( !currentLabelRotationPoint( referencePoint, !preserveRot, false ) )
    {
      referencePoint.setX( labelpos.labelRect.xMinimum() );
      referencePoint.setY( labelpos.labelRect.yMinimum() );
    }

    double labelX = referencePoint.x();
    double labelY = referencePoint.y();
    double labelR = labelpos.rotation * 180 / M_PI;

    // transform back to layer crs
    QgsPointXY transformedPoint = mCanvas->mapSettings().mapToLayerCoordinates( vlayer, referencePoint );
    labelX = transformedPoint.x();
    labelY = transformedPoint.y();

    vlayer->beginEditCommand( tr( "Pinned label" ) + QStringLiteral( " '%1'" ).arg( labelText ) );
    writeFailed = !vlayer->changeAttributeValue( fid, xCol, labelX );
    if ( !vlayer->changeAttributeValue( fid, yCol, labelY ) )
      writeFailed = true;
    if ( hasRCol && !preserveRot )
    {
      if ( !vlayer->changeAttributeValue( fid, rCol, labelR ) )
        writeFailed = true;
    }
    vlayer->endEditCommand();
  }
  else
  {
    vlayer->beginEditCommand( tr( "Unpinned label" ) + QStringLiteral( " '%1'" ).arg( labelText ) );
    writeFailed = !vlayer->changeAttributeValue( fid, xCol, QVariant( QString() ) );
    if ( !vlayer->changeAttributeValue( fid, yCol, QVariant( QString() ) ) )
      writeFailed = true;
    if ( hasRCol && !preserveRot )
    {
      if ( !vlayer->changeAttributeValue( fid, rCol, QVariant( QString() ) ) )
        writeFailed = true;
    }
    vlayer->endEditCommand();
  }

  if ( writeFailed )
  {
    QgsDebugMsg( QStringLiteral( "Write to attribute table failed" ) );

#if 0
    QgsDebugMsg( QStringLiteral( "Undoing and removing failed command from layer's undo stack" ) );
    int lastCmdIndx = vlayer->undoStack()->count();
    const QgsUndoCommand *lastCmd = qobject_cast<const QgsUndoCommand *>( vlayer->undoStack()->command( lastCmdIndx ) );
    if ( lastCmd )
    {
      vlayer->undoEditCommand( lastCmd );
      delete vlayer->undoStack()->command( lastCmdIndx );
    }
#endif

    return false;
  }

  return true;
}
void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
{
  deleteRubberBands();

  QgsLabelPosition labelPos;
  if ( !labelAtPosition( e, labelPos ) )
  {
    mCurrentLabel = LabelDetails();
    return;
  }

  mCurrentLabel = LabelDetails( labelPos );

  QgsVectorLayer *vlayer = mCurrentLabel.layer;
  if ( !vlayer )
  {
    return;
  }

  int xCol = -1, yCol = -1;

  if ( !mCurrentLabel.pos.isDiagram && !labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) )
  {
    QgsPalIndexes indexes;

    if ( createAuxiliaryFields( indexes ) )
      return;

    if ( !labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) )
      return;

    xCol = indexes[ QgsPalLayerSettings::PositionX ];
    yCol = indexes[ QgsPalLayerSettings::PositionY ];
  }
  else if ( mCurrentLabel.pos.isDiagram && !diagramMoveable( vlayer, xCol, yCol ) )
  {
    QgsDiagramIndexes indexes;

    if ( createAuxiliaryFields( indexes ) )
      return;

    if ( !diagramMoveable( vlayer, xCol, yCol ) )
      return;

    xCol = indexes[ QgsDiagramLayerSettings::PositionX ];
    yCol = indexes[ QgsDiagramLayerSettings::PositionY ];
  }

  if ( xCol >= 0 && yCol >= 0 )
  {
    mStartPointMapCoords = toMapCoordinates( e->pos() );
    QgsPointXY referencePoint;
    if ( !currentLabelRotationPoint( referencePoint, !currentLabelPreserveRotation(), false ) )
    {
      referencePoint.setX( mCurrentLabel.pos.labelRect.xMinimum() );
      referencePoint.setY( mCurrentLabel.pos.labelRect.yMinimum() );
    }
    mClickOffsetX = mStartPointMapCoords.x() - referencePoint.x();
    mClickOffsetY = mStartPointMapCoords.y() - referencePoint.y();
    createRubberBands();
  }
}