Skip to content
Permalink
Browse files

[cad] update constraint when user changes values in widgets while

constraint is locked

The previous behaviour was that the constraint had to be "relocked"
if the user manually altered the constraint value in the text
widgets. Now users can edit the constraint value after already
locking the constraint.
  • Loading branch information
nyalldawson committed May 2, 2016
1 parent 5654886 commit bd305885c271ceb3e6dfe1525dde0fc444f6cdca
@@ -104,8 +104,10 @@ class QgsAdvancedDigitizingDockWidget : QDockWidget

/**
* Set the value of the constraint
* @param value new value for constraint
* @param updateWidget set to false to prevent automatically updating the associated widget's value
*/
void setValue( double value );
void setValue( double value, bool updateWidget = true );

/**
* Toggle lock mode
@@ -29,6 +29,7 @@
#include "qgsmessagebaritem.h"
#include "qgspoint.h"
#include "qgslinestringv2.h"
#include "qgsfocuswatcher.h"

struct EdgesOnlyFilter : public QgsPointLocator::MatchFilter
{
@@ -138,6 +139,19 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas*
connect( mDistanceLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
connect( mXLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
connect( mYLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
connect( mAngleLineEdit, SIGNAL( textEdited( QString ) ), this, SLOT( constraintTextEdited( QString ) ) );
connect( mDistanceLineEdit, SIGNAL( textEdited( QString ) ), this, SLOT( constraintTextEdited( QString ) ) );
connect( mXLineEdit, SIGNAL( textEdited( QString ) ), this, SLOT( constraintTextEdited( QString ) ) );
connect( mYLineEdit, SIGNAL( textEdited( QString ) ), this, SLOT( constraintTextEdited( QString ) ) );
//also watch for focus out events on these widgets
QgsFocusWatcher* angleWatcher = new QgsFocusWatcher( mAngleLineEdit );
connect( angleWatcher, SIGNAL( focusOut() ), this, SLOT( constraintFocusOut() ) );
QgsFocusWatcher* distanceWatcher = new QgsFocusWatcher( mDistanceLineEdit );
connect( distanceWatcher, SIGNAL( focusOut() ), this, SLOT( constraintFocusOut() ) );
QgsFocusWatcher* xWatcher = new QgsFocusWatcher( mXLineEdit );
connect( xWatcher, SIGNAL( focusOut() ), this, SLOT( constraintFocusOut() ) );
QgsFocusWatcher* yWatcher = new QgsFocusWatcher( mYLineEdit );
connect( yWatcher, SIGNAL( focusOut() ), this, SLOT( constraintFocusOut() ) );

// config menu
QMenu *menu = new QMenu( this );
@@ -300,9 +314,8 @@ void QgsAdvancedDigitizingDockWidget::emit pointChanged()
}
#endif

void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default true */ )
QgsAdvancedDigitizingDockWidget::CadConstraint* QgsAdvancedDigitizingDockWidget::objectToConstraint( const QObject* obj ) const
{
QObject* obj = sender();
CadConstraint* constraint = nullptr;
if ( obj == mAngleLineEdit || obj == mLockAngleButton )
{
@@ -320,6 +333,53 @@ void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default t
{
constraint = mYConstraint;
}
return constraint;
}

double QgsAdvancedDigitizingDockWidget::parseUserInput( const QString& inputValue, bool& ok ) const
{
ok = false;
double value = inputValue.toDouble( &ok );
if ( ok )
{
return value;
}
else
{
// try to evalute expression
QgsExpression expr( inputValue );
QVariant result = expr.evaluate();
if ( expr.hasEvalError() )
ok = false;
else
value = result.toDouble( &ok );
return value;
}
}

void QgsAdvancedDigitizingDockWidget::updateConstraintValue( CadConstraint* constraint, const QString& textValue, bool convertExpression )
{
if ( !constraint || textValue.isEmpty() )
{
return;
}

if ( constraint->lockMode() == CadConstraint::NoLock )
return;

bool ok;
double value = parseUserInput( textValue, ok );
if ( !ok )
return;

constraint->setValue( value, convertExpression );
// run a fake map mouse event to update the paint item
emit pointChanged( mCadPointList.value( 0 ) );
}

void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default true */ )
{
CadConstraint* constraint = objectToConstraint( sender() );
if ( !constraint )
{
return;
@@ -328,28 +388,17 @@ void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default t
if ( activate )
{
QString textValue = constraint->lineEdit()->text();
bool ok;
double value = textValue.toDouble( &ok );
if ( !textValue.isEmpty() )
{
bool ok;
double value = parseUserInput( textValue, ok );
if ( ok )
{
constraint->setValue( value );
}
else
{
// try to evalute expression
QgsExpression expr( textValue );
QVariant result = expr.evaluate();
value = result.toDouble( &ok );
if ( expr.hasEvalError() || !ok )
{
activate = false;
}
else
{
constraint->setValue( value );
}
activate = false;
}
}
else
@@ -372,6 +421,32 @@ void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default t
}
}

void QgsAdvancedDigitizingDockWidget::constraintTextEdited( const QString& textValue )
{
CadConstraint* constraint = objectToConstraint( sender() );
if ( !constraint )
{
return;
}

updateConstraintValue( constraint, textValue, false );
}

void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
{
QLineEdit* lineEdit = qobject_cast< QLineEdit* >( sender()->parent() );
if ( !lineEdit )
return;

CadConstraint* constraint = objectToConstraint( lineEdit );
if ( !constraint )
{
return;
}

updateConstraintValue( constraint, lineEdit->text(), true );
}

void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint( AdditionalConstraint constraint )
{
mAdditionalConstraint = constraint;
@@ -1169,10 +1244,11 @@ void QgsAdvancedDigitizingDockWidget::CadConstraint::setRelative( bool relative
}
}

void QgsAdvancedDigitizingDockWidget::CadConstraint::setValue( double value )
void QgsAdvancedDigitizingDockWidget::CadConstraint::setValue( double value, bool updateWidget )
{
mValue = value;
mLineEdit->setText( QString::number( value, 'f' ) );
if ( updateWidget )
mLineEdit->setText( QString::number( value, 'f' ) );
}

void QgsAdvancedDigitizingDockWidget::CadConstraint::toggleLocked()
@@ -133,8 +133,10 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U

/**
* Set the value of the constraint
* @param value new value for constraint
* @param updateWidget set to false to prevent automatically updating the associated widget's value
*/
void setValue( double value );
void setValue( double value, bool updateWidget = true );

/**
* Toggle lock mode
@@ -312,12 +314,20 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
void pointChanged( const QgsPoint& point );

private slots:
//! set the additiona constraint by clicking on the perpendicular/parallel buttons
//! set the additional constraint by clicking on the perpendicular/parallel buttons
void addtionalConstraintClicked( bool activated );

//! lock/unlock a constraint and set its value
void lockConstraint( bool activate = true );

//! Called when user has manually altered a constraint value. Any entered expressions will
//! be left intact
void constraintTextEdited( const QString& textValue );

//! Called when a constraint input widget has lost focus. Any entered expressions
//! will be converted to their calculated value
void constraintFocusOut();

//! unlock all constraints
void releaseLocks();

@@ -372,7 +382,17 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
//! trigger fake mouse move event to update map tool rubber band and/or show new constraints
void triggerMouseMoveEvent();

//! Returns the constraint associated with an object
CadConstraint* objectToConstraint( const QObject* obj ) const;

//! Attempts to convert a user input value to double, either directly or via expression
double parseUserInput( const QString& inputValue, bool& ok ) const;

/** Updates a constraint value based on a text input.
* @param textValue user entered text value, may be an expression
* @param convertExpression set to true to update widget contents to calculated expression value
*/
void updateConstraintValue( CadConstraint* constraint, const QString& textValue, bool convertExpression = false );

QgsMapCanvas* mMapCanvas;
QgsAdvancedDigitizingCanvasItem* mCadPaintItem;
@@ -409,6 +429,7 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
QAction* mEnableAction;
QMap< QAction*, int > mCommonAngleActions; // map the common angle actions with their angle values
QMap< QAction*, QgsMapMouseEvent::SnappingMode > mSnappingActions; // map the snapping mode actions with their values

};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAdvancedDigitizingDockWidget::CadCapacities )

0 comments on commit bd30588

Please sign in to comment.
You can’t perform that action at this time.