Skip to content

Commit

Permalink
Auto enable layer editing when the move or change label tools
Browse files Browse the repository at this point in the history
require it to make changes to a label

E.g. when a layer is set to store label x/y in a real field (not
an aux field), then that layer must be editable in order to move
labels in it. Otherwise the move operation fails, but users are
left no clue as to why the label can't be shifted...

So now we automatically switch on edits and notify the user of
this via the messagebar, and if we CAN'T make the layer editable,
we also warn them of this.
  • Loading branch information
nyalldawson committed Jul 18, 2019
1 parent 781e70f commit 1d0d7d8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
27 changes: 27 additions & 0 deletions src/app/qgsmaptoolchangelabelproperties.cpp
Expand Up @@ -21,6 +21,8 @@
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgsmapmouseevent.h"
#include "qgisapp.h"
#include "qgsmessagebar.h"

QgsMapToolChangeLabelProperties::QgsMapToolChangeLabelProperties( QgsMapCanvas *canvas ): QgsMapToolLabel( canvas )
{
Expand Down Expand Up @@ -123,6 +125,31 @@ void QgsMapToolChangeLabelProperties::applyChanges( const QgsAttributeMap &chang

if ( !changes.isEmpty() )
{
if ( !vlayer->isEditable() )
{
bool needsEdit = false;
for ( auto it = changes.constBegin(); it != changes.constEnd(); ++it )
{
if ( vlayer->fields().fieldOrigin( it.key() ) != QgsFields::OriginJoin )
{
needsEdit = true;
break;
}
}
if ( needsEdit )
{
if ( vlayer->startEditing() )
{
QgisApp::instance()->messageBar()->pushInfo( tr( "Change Label" ), tr( "Layer “%1” was made editable" ).arg( vlayer->name() ) );
}
else
{
QgisApp::instance()->messageBar()->pushWarning( tr( "Change Label" ), tr( "Cannot change “%1” — the layer “%2” could not be made editable" ).arg( mCurrentLabel.pos.labelText, vlayer->name() ) );
return;
}
}
}

vlayer->beginEditCommand( tr( "Changed properties for label" ) + QStringLiteral( " '%1'" ).arg( currentLabelText( 24 ) ) );

QgsAttributeMap::const_iterator changeIt = changes.constBegin();
Expand Down
37 changes: 34 additions & 3 deletions src/app/qgsmaptoolmovelabel.cpp
Expand Up @@ -20,7 +20,8 @@
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgsmapmouseevent.h"

#include "qgisapp.h"
#include "qgsmessagebar.h"

QgsMapToolMoveLabel::QgsMapToolMoveLabel( QgsMapCanvas *canvas )
: QgsMapToolLabel( canvas )
Expand Down Expand Up @@ -106,6 +107,21 @@ void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )

if ( xCol >= 0 && yCol >= 0 )
{
const bool usesAuxFields = vlayer->fields().fieldOrigin( xCol ) == QgsFields::OriginJoin
&& vlayer->fields().fieldOrigin( yCol ) == QgsFields::OriginJoin;
if ( !usesAuxFields && !vlayer->isEditable() )
{
if ( vlayer->startEditing() )
{
QgisApp::instance()->messageBar()->pushInfo( tr( "Move Label" ), tr( "Layer “%1” was made editable" ).arg( vlayer->name() ) );
}
else
{
QgisApp::instance()->messageBar()->pushWarning( tr( "Move Label" ), tr( "Cannot move “%1” — the layer “%2” could not be made editable" ).arg( mCurrentLabel.pos.labelText, vlayer->name() ) );
return;
}
}

mStartPointMapCoords = toMapCoordinates( e->pos() );
QgsPointXY referencePoint;
if ( !currentLabelRotationPoint( referencePoint, !currentLabelPreserveRotation(), false ) )
Expand Down Expand Up @@ -180,8 +196,23 @@ void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
}

vlayer->beginEditCommand( tr( "Moved label" ) + QStringLiteral( " '%1'" ).arg( currentLabelText( 24 ) ) );
vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, xCol, xPosNew );
vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, yCol, yPosNew );
bool success = vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, xCol, xPosNew );
success = vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, yCol, yPosNew ) && success;
if ( !success )
{
// if the edit command fails, it's likely because the label x/y is being stored in a physical field (not a auxiliary one!)
// and the layer isn't in edit mode
if ( !vlayer->isEditable() )
{
QgisApp::instance()->messageBar()->pushWarning( tr( "Move Label" ), tr( "Layer “%1” must be editable in order to move labels from it" ).arg( vlayer->name() ) );
}
else
{
QgisApp::instance()->messageBar()->pushWarning( tr( "Move Label" ), tr( "Error encountered while storing new label position" ) );
}
vlayer->endEditCommand();
break;
}

// set rotation to that of label, if data-defined and no rotation set yet
// honor whether to preserve preexisting data on pin
Expand Down

0 comments on commit 1d0d7d8

Please sign in to comment.