Skip to content

Commit

Permalink
Advanced Digitizing: more common angle options
Browse files Browse the repository at this point in the history
- add 0.1, 0.5, 1.0 common angles
- add an option to show current common angle in the floater
- add 'N' 'SHIFT+N' keyboard shortcuts to cycle through the
  common angle options
  • Loading branch information
elpaso committed May 4, 2023
1 parent 61fe177 commit 5f86a40
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 68 deletions.
20 changes: 20 additions & 0 deletions python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in
Expand Up @@ -585,6 +585,13 @@ Returns the capacities

.. versionadded:: 3.26
%End
QString formatCommonAngleSnapping( double angle );
%Docstring
Returns the formatted label for common angle snapping option.

.. versionadded:: 3.32
%End

signals:

void pushWarning( const QString &message );
Expand Down Expand Up @@ -1035,6 +1042,19 @@ Could be used by widgets to capture the focus when a field is being edited.
.. versionadded:: 3.8
%End

void valueCommonAngleSnappingChanged( double angle );
%Docstring
Emitted whenever the snapping to common angle option changes, angle = 0 means that the functionality is disabled.

.. versionadded:: 3.32
%End

void commonAngleSnappingShowInFloaterChanged( bool enabled );
%Docstring
Emitted whenever the option to show common angle snapping in the floater changes.

.. versionadded:: 3.32
%End

private:
//! event filter for line edits in the dock UI (angle/distance/x/y line edits)
Expand Down
76 changes: 61 additions & 15 deletions src/gui/qgsadvanceddigitizingdockwidget.cpp
Expand Up @@ -37,7 +37,6 @@

#include <QActionGroup>


QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas *canvas, QWidget *parent )
: QgsDockWidget( parent )
, mMapCanvas( canvas )
Expand Down Expand Up @@ -117,37 +116,39 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas *
connect( mWatcher, &QgsFocusWatcher::focusOut, this, &QgsAdvancedDigitizingDockWidget::constraintFocusOut );

// config menu
QMenu *menu = new QMenu( this );
mCommonAngleActionsMenu = new QMenu( this );

QAction *showCommonAngleSnappingInFloaterAction = new QAction( tr( "Show setting in the floater" ), mCommonAngleActionsMenu );
showCommonAngleSnappingInFloaterAction->setCheckable( true );

mCommonAngleActionsMenu->addAction( showCommonAngleSnappingInFloaterAction );

// common angles
QActionGroup *angleButtonGroup = new QActionGroup( menu ); // actions are exclusive for common angles
QActionGroup *angleButtonGroup = new QActionGroup( mCommonAngleActionsMenu ); // actions are exclusive for common angles
mCommonAngleActions = QMap<QAction *, double>();
QList< QPair< double, QString > > commonAngles;
QString menuText;
const QList<double> anglesDouble( { 0.0, 5.0, 10.0, 15.0, 18.0, 22.5, 30.0, 45.0, 90.0} );
const QList<double> anglesDouble( { 0.0, 0.1, 0.5, 1.0, 5.0, 10.0, 15.0, 18.0, 22.5, 30.0, 45.0, 90.0} );
for ( QList<double>::const_iterator it = anglesDouble.constBegin(); it != anglesDouble.constEnd(); ++it )
{
if ( *it == 0 )
menuText = tr( "Do Not Snap to Common Angles" );
else
menuText = QString( tr( "%1, %2, %3, %4°…" ) ).arg( *it, 0, 'f', 1 ).arg( *it * 2, 0, 'f', 1 ).arg( *it * 3, 0, 'f', 1 ).arg( *it * 4, 0, 'f', 1 );
commonAngles << QPair<double, QString>( *it, menuText );
commonAngles << QPair<double, QString>( *it, formatCommonAngleSnapping( *it ) );
}
for ( QList< QPair<double, QString > >::const_iterator it = commonAngles.constBegin(); it != commonAngles.constEnd(); ++it )
{
QAction *action = new QAction( it->second, menu );
QAction *action = new QAction( it->second, mCommonAngleActionsMenu );
action->setCheckable( true );
action->setChecked( it->first == mCommonAngleConstraint );
menu->addAction( action );
mCommonAngleActionsMenu->addAction( action );
angleButtonGroup->addAction( action );
mCommonAngleActions.insert( action, it->first );
}

qobject_cast< QToolButton *>( mToolbar->widgetForAction( mSettingsAction ) )->setPopupMode( QToolButton::InstantPopup );
mSettingsAction->setMenu( menu );
mSettingsAction->setMenu( mCommonAngleActionsMenu );
mSettingsAction->setCheckable( true );
mSettingsAction->setToolTip( tr( "Snap to common angles" ) );
mSettingsAction->setToolTip( "<b>" + tr( "Snap to common angles" ) + "</b><br>(" + tr( "press n to cycle through the options" ) + ")" );
mSettingsAction->setChecked( mCommonAngleConstraint != 0 );
connect( menu, &QMenu::triggered, this, &QgsAdvancedDigitizingDockWidget::settingsButtonTriggered );
connect( mCommonAngleActionsMenu, &QMenu::triggered, this, &QgsAdvancedDigitizingDockWidget::settingsButtonTriggered );

// Construction modes
QMenu *constructionMenu = new QMenu( this );
Expand All @@ -167,7 +168,7 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas *
constructionToolBar->setMenu( constructionMenu );
constructionToolBar->setObjectName( QStringLiteral( "ConstructionButton" ) );

mConstructionAction->setMenu( menu );
mConstructionAction->setMenu( mCommonAngleActionsMenu );
mConstructionAction->setCheckable( true );
mConstructionAction->setToolTip( tr( "Construction Tools" ) );
// connect( constructionMenu, &QMenu::triggered, this, &QgsAdvancedDigitizingDockWidget::settingsButtonTriggered );
Expand Down Expand Up @@ -216,12 +217,29 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas *
connect( mToggleFloaterAction, &QAction::triggered, mFloater, &QgsAdvancedDigitizingFloater::setActive );
mToggleFloaterAction->setChecked( mFloater->active() );

mShowCommonAngleInFloater = QgsSettings().value( QStringLiteral( "/Cad/CommonAngleShowInFloater" ), false ).toBool();
connect( showCommonAngleSnappingInFloaterAction, &QAction::triggered, this, &QgsAdvancedDigitizingDockWidget::commonAngleSnappingShowInFloaterChanged );
showCommonAngleSnappingInFloaterAction->setChecked( mShowCommonAngleInFloater );
connect( showCommonAngleSnappingInFloaterAction, &QAction::triggered, this, [ = ]( bool checked )
{
mShowCommonAngleInFloater = checked;
QgsSettings().setValue( QStringLiteral( "/Cad/CommonAngleShowInFloater" ), checked );
} );

updateCapacity( true );
connect( QgsProject::instance(), &QgsProject::snappingConfigChanged, this, [ = ] { updateCapacity( true ); } );

disable();
}

QString QgsAdvancedDigitizingDockWidget::formatCommonAngleSnapping( double angle )
{
if ( angle == 0 )
return tr( "Do Not Snap to Common Angles" );
else
return QString( tr( "%1, %2, %3, %4°…" ) ).arg( angle, 0, 'f', 1 ).arg( angle * 2, 0, 'f', 1 ).arg( angle * 3, 0, 'f', 1 ).arg( angle * 4, 0, 'f', 1 );
}

void QgsAdvancedDigitizingDockWidget::setX( const QString &value, WidgetSetMode mode )
{
mXLineEdit->setText( value );
Expand Down Expand Up @@ -349,6 +367,12 @@ void QgsAdvancedDigitizingDockWidget::setCadEnabled( bool enabled )
switchZM();
emit cadEnabledChanged( enabled );

if ( enabled )
{
emit commonAngleSnappingShowInFloaterChanged( mShowCommonAngleInFloater );
emit valueCommonAngleSnappingChanged( mCommonAngleConstraint );
}

mLastSnapMatch = QgsPointLocator::Match();
}

Expand Down Expand Up @@ -521,6 +545,7 @@ void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction *action )
mCommonAngleConstraint = ica.value();
QgsSettings().setValue( QStringLiteral( "/Cad/CommonAngle" ), ica.value() );
mSettingsAction->setChecked( mCommonAngleConstraint != 0 );
emit valueCommonAngleSnappingChanged( mCommonAngleConstraint );
return;
}
}
Expand Down Expand Up @@ -1611,6 +1636,27 @@ bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
}
break;
}
case Qt::Key_N:
{
if ( type == QEvent::ShortcutOverride )
{
const QList<double> constActionValues { mCommonAngleActions.values() };
const int currentAngleActionIndex { constActionValues.indexOf( mCommonAngleConstraint ) };
const QList<QAction *> constActions { mCommonAngleActions.keys( ) };
QAction *nextAngleAction;
if ( e->modifiers() == Qt::ShiftModifier )
{
nextAngleAction = currentAngleActionIndex == 0 ? constActions.last() : constActions.at( currentAngleActionIndex - 1 );
}
else
{
nextAngleAction = currentAngleActionIndex == constActions.count() - 1 ? constActions.first() : constActions.at( currentAngleActionIndex + 1 );
}
nextAngleAction->trigger();
e->accept();
}
break;
}
default:
{
return false; // continues
Expand Down
20 changes: 20 additions & 0 deletions src/gui/qgsadvanceddigitizingdockwidget.h
Expand Up @@ -545,6 +545,12 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private
*/
CadCapacities capacities() const { return mCapacities; };

/**
* Returns the formatted label for common angle snapping option.
* \since QGIS 3.32
*/
QString formatCommonAngleSnapping( double angle );

signals:

/**
Expand Down Expand Up @@ -866,6 +872,17 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private
*/
void focusOnDistanceRequested();

/**
* Emitted whenever the snapping to common angle option changes, angle = 0 means that the functionality is disabled.
* \since QGIS 3.32
*/
void valueCommonAngleSnappingChanged( double angle );

/**
* Emitted whenever the option to show common angle snapping in the floater changes.
* \since QGIS 3.32
*/
void commonAngleSnappingShowInFloaterChanged( bool enabled );

private slots:
//! Sets the between line constraint by clicking on the perpendicular/parallel buttons
Expand Down Expand Up @@ -1033,6 +1050,9 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private
//! Convenient method to convert a 2D Point to a QgsPoint
QgsPoint pointXYToPoint( const QgsPointXY &point ) const;

QMenu *mCommonAngleActionsMenu = nullptr;
bool mShowCommonAngleInFloater = false;

friend class TestQgsAdvancedDigitizing;
friend class TestQgsAdvancedDigitizingDockWidget;
};
Expand Down
17 changes: 17 additions & 0 deletions src/gui/qgsadvanceddigitizingfloater.cpp
Expand Up @@ -37,6 +37,8 @@ QgsAdvancedDigitizingFloater::QgsAdvancedDigitizingFloater( QgsMapCanvas *canvas

hideIfDisabled();

enabledCommonAngleSnapping( cadDockWidget->commonAngleConstraint() );

// This is required to be able to track mouse move events
mMapCanvas->viewport()->installEventFilter( this );
mMapCanvas->viewport()->setMouseTracking( true );
Expand All @@ -57,6 +59,8 @@ QgsAdvancedDigitizingFloater::QgsAdvancedDigitizingFloater( QgsMapCanvas *canvas
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueZChanged, this, &QgsAdvancedDigitizingFloater::changeZ );
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueMChanged, this, &QgsAdvancedDigitizingFloater::changeM );
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueAngleChanged, this, &QgsAdvancedDigitizingFloater::changeAngle );
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueCommonAngleSnappingChanged, this, &QgsAdvancedDigitizingFloater::changeCommonAngleSnapping );
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::commonAngleSnappingShowInFloaterChanged, this, &QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping );
connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::valueDistanceChanged, this, &QgsAdvancedDigitizingFloater::changeDistance );

connect( cadDockWidget, &QgsAdvancedDigitizingDockWidget::lockXChanged, this, &QgsAdvancedDigitizingFloater::changeLockX );
Expand Down Expand Up @@ -114,6 +118,7 @@ QgsAdvancedDigitizingFloater::QgsAdvancedDigitizingFloater( QgsMapCanvas *canvas
connect( angleWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [ = ]() { cadDockWidget->setAngle( mAngleLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
QgsFocusWatcher *distanceWatcher = new QgsFocusWatcher( mDistanceLineEdit );
connect( distanceWatcher, &QgsFocusWatcher::focusOut, cadDockWidget, [ = ]() { cadDockWidget->setDistance( mDistanceLineEdit->text(), QgsAdvancedDigitizingDockWidget::WidgetSetMode::FocusOut ); } );
changeCommonAngleSnapping( mCadDockWidget->commonAngleConstraint() );

}

Expand Down Expand Up @@ -191,6 +196,11 @@ void QgsAdvancedDigitizingFloater::changeM( const QString &text )
mMLineEdit->setText( text );
}

void QgsAdvancedDigitizingFloater::changeCommonAngleSnapping( double angle )
{
mCommonAngleSnappingLineEdit->setText( qgsDoubleNear( angle, 0.0 ) ? tr( "disabled" ) : QLocale().toString( angle ).append( QStringLiteral( "°" ) ) );
}

void QgsAdvancedDigitizingFloater::changeDistance( const QString &text )
{
mDistanceLineEdit->setText( text );
Expand Down Expand Up @@ -443,6 +453,13 @@ void QgsAdvancedDigitizingFloater::enabledChangedDistance( bool enabled )
adjustSize();
}

void QgsAdvancedDigitizingFloater::enabledCommonAngleSnapping( bool enabled )
{
mCommonAngleSnappingLineEdit->setVisible( enabled );
mCommonAngleSnappingLabel->setVisible( enabled );
adjustSize();
}

void QgsAdvancedDigitizingFloater::enabledChangedAngle( bool enabled )
{
mAngleLineEdit->setVisible( enabled );
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsadvanceddigitizingfloater.h
Expand Up @@ -75,6 +75,7 @@ class GUI_EXPORT QgsAdvancedDigitizingFloater : public QWidget, private Ui::QgsA
void changeY( const QString &text );
void changeZ( const QString &text );
void changeM( const QString &text );
void changeCommonAngleSnapping( double angle );
void changeDistance( const QString &text );
void changeAngle( const QString &text );
void changeLockX( bool locked );
Expand All @@ -101,6 +102,7 @@ class GUI_EXPORT QgsAdvancedDigitizingFloater : public QWidget, private Ui::QgsA
void enabledChangedM( bool enabled );
void enabledChangedAngle( bool enabled );
void enabledChangedDistance( bool enabled );
void enabledCommonAngleSnapping( bool enabled );

private:

Expand Down

0 comments on commit 5f86a40

Please sign in to comment.