From 36ad5f9dfa55b788b0ad1448546cd23b31f46775 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sun, 28 Jul 2024 17:26:09 +0700 Subject: [PATCH] Add advanced digitizing tools registry --- .../qgsadvanceddigitizingtoolsregistry.sip.in | 113 +++++++++++++ python/PyQt6/gui/auto_generated/qgsgui.sip.in | 7 + python/PyQt6/gui/gui_auto.sip | 1 + .../qgsadvanceddigitizingtoolsregistry.sip.in | 113 +++++++++++++ python/gui/auto_generated/qgsgui.sip.in | 7 + python/gui/gui_auto.sip | 1 + src/gui/CMakeLists.txt | 2 + src/gui/qgsadvanceddigitizingdockwidget.cpp | 38 ++--- src/gui/qgsadvanceddigitizingdockwidget.h | 3 - .../qgsadvanceddigitizingtoolsregistry.cpp | 76 +++++++++ src/gui/qgsadvanceddigitizingtoolsregistry.h | 153 ++++++++++++++++++ src/gui/qgsgui.cpp | 10 ++ src/gui/qgsgui.h | 9 ++ src/ui/qgsadvanceddigitizingdockwidgetbase.ui | 4 +- 14 files changed, 514 insertions(+), 23 deletions(-) create mode 100644 python/PyQt6/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in create mode 100644 python/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in create mode 100644 src/gui/qgsadvanceddigitizingtoolsregistry.cpp create mode 100644 src/gui/qgsadvanceddigitizingtoolsregistry.h diff --git a/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in new file mode 100644 index 000000000000..fb48ea403aaa --- /dev/null +++ b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in @@ -0,0 +1,113 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgsadvanceddigitizingtoolsregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + +class QgsAdvancedDigitizingToolAbstractMetadata +{ +%Docstring(signature="appended") +Stores metadata about one advanced digitizing tool class. + +.. versionadded:: 3.40 +%End + +%TypeHeaderCode +#include "qgsadvanceddigitizingtoolsregistry.h" +%End + public: + + QgsAdvancedDigitizingToolAbstractMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon() ); +%Docstring +Constructor for QgsAdvancedDigitizingToolAbstractMetadata with the specified tool ``name``. + +``visibleName`` should be set to a translated, user visible name identifying the corresponding annotation item. + +An optional ``icon`` can be set, which will be used by the advanced digitizing dock widget. +%End + + virtual ~QgsAdvancedDigitizingToolAbstractMetadata(); + + QString name() const; +%Docstring +Returns the tool's unique name +%End + + QString visibleName() const; +%Docstring +Returns the tool's translatable user-friendly name +%End + + QIcon icon() const; +%Docstring +Returns the tool's icon +%End + + virtual QgsAdvancedDigitizingTool *createTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget ) /Factory/; +%Docstring +Returns new tool of this type. Return ``None`` on error +%End + + protected: +}; + + +class QgsAdvancedDigitizingToolsRegistry +{ +%Docstring(signature="appended") +Registry of available advanced digitizing tools. + +.. versionadded:: 3.40 +%End + +%TypeHeaderCode +#include "qgsadvanceddigitizingtoolsregistry.h" +%End + public: + + QgsAdvancedDigitizingToolsRegistry(); + ~QgsAdvancedDigitizingToolsRegistry(); + + + void addDefaultTools(); +%Docstring +Adds the default tools shipped in QGIS +%End + + bool addTool( QgsAdvancedDigitizingToolAbstractMetadata *toolMetaData /Transfer/ ); +%Docstring +Adds an advanced digitizing tool (take ownership) and return ``True`` on success +%End + + bool removeTool( const QString &name ); +%Docstring +Removes the advanced digitizing tool matching the provided ``name`` and return ``True`` on success +%End + + QgsAdvancedDigitizingToolAbstractMetadata *toolMetadata( const QString &name ); +%Docstring +Returns the advanced digitizing tool matching the provided ``name`` or ``None`` when no match available +%End + + const QStringList toolMetadataNames() const; +%Docstring +Returns the list of registered tool names +%End + + private: + QgsAdvancedDigitizingToolsRegistry( const QgsAdvancedDigitizingToolsRegistry &rh ); +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgsadvanceddigitizingtoolsregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/PyQt6/gui/auto_generated/qgsgui.sip.in b/python/PyQt6/gui/auto_generated/qgsgui.sip.in index 8f3a4bf91991..cec1874c1a49 100644 --- a/python/PyQt6/gui/auto_generated/qgsgui.sip.in +++ b/python/PyQt6/gui/auto_generated/qgsgui.sip.in @@ -77,6 +77,13 @@ Returns the global layout item GUI registry, used for registering the GUI behavi Returns the global annotation item GUI registry, used for registering the GUI behavior of annotation items. .. versionadded:: 3.22 +%End + + static QgsAdvancedDigitizingToolsRegistry *advancedDigitizingToolsRegistry() /KeepReference/; +%Docstring +Returns the global advanced digitizing tools registry, used for registering advanced digitizing tools. + +.. versionadded:: 3.40 %End static QgsProcessingGuiRegistry *processingGuiRegistry() /KeepReference/; diff --git a/python/PyQt6/gui/gui_auto.sip b/python/PyQt6/gui/gui_auto.sip index 913c0e8b2786..a69c84652cb2 100644 --- a/python/PyQt6/gui/gui_auto.sip +++ b/python/PyQt6/gui/gui_auto.sip @@ -7,6 +7,7 @@ %Include auto_generated/qgsadvanceddigitizingdockwidget.sip %Include auto_generated/qgsadvanceddigitizingfloater.sip %Include auto_generated/qgsadvanceddigitizingtools.sip +%Include auto_generated/qgsadvanceddigitizingtoolsregistry.sip %Include auto_generated/qgsaggregatetoolbutton.sip %Include auto_generated/qgsalignmentcombobox.sip %Include auto_generated/qgsapplicationexitblockerinterface.sip diff --git a/python/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in b/python/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in new file mode 100644 index 000000000000..fb48ea403aaa --- /dev/null +++ b/python/gui/auto_generated/qgsadvanceddigitizingtoolsregistry.sip.in @@ -0,0 +1,113 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgsadvanceddigitizingtoolsregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + +class QgsAdvancedDigitizingToolAbstractMetadata +{ +%Docstring(signature="appended") +Stores metadata about one advanced digitizing tool class. + +.. versionadded:: 3.40 +%End + +%TypeHeaderCode +#include "qgsadvanceddigitizingtoolsregistry.h" +%End + public: + + QgsAdvancedDigitizingToolAbstractMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon() ); +%Docstring +Constructor for QgsAdvancedDigitizingToolAbstractMetadata with the specified tool ``name``. + +``visibleName`` should be set to a translated, user visible name identifying the corresponding annotation item. + +An optional ``icon`` can be set, which will be used by the advanced digitizing dock widget. +%End + + virtual ~QgsAdvancedDigitizingToolAbstractMetadata(); + + QString name() const; +%Docstring +Returns the tool's unique name +%End + + QString visibleName() const; +%Docstring +Returns the tool's translatable user-friendly name +%End + + QIcon icon() const; +%Docstring +Returns the tool's icon +%End + + virtual QgsAdvancedDigitizingTool *createTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget ) /Factory/; +%Docstring +Returns new tool of this type. Return ``None`` on error +%End + + protected: +}; + + +class QgsAdvancedDigitizingToolsRegistry +{ +%Docstring(signature="appended") +Registry of available advanced digitizing tools. + +.. versionadded:: 3.40 +%End + +%TypeHeaderCode +#include "qgsadvanceddigitizingtoolsregistry.h" +%End + public: + + QgsAdvancedDigitizingToolsRegistry(); + ~QgsAdvancedDigitizingToolsRegistry(); + + + void addDefaultTools(); +%Docstring +Adds the default tools shipped in QGIS +%End + + bool addTool( QgsAdvancedDigitizingToolAbstractMetadata *toolMetaData /Transfer/ ); +%Docstring +Adds an advanced digitizing tool (take ownership) and return ``True`` on success +%End + + bool removeTool( const QString &name ); +%Docstring +Removes the advanced digitizing tool matching the provided ``name`` and return ``True`` on success +%End + + QgsAdvancedDigitizingToolAbstractMetadata *toolMetadata( const QString &name ); +%Docstring +Returns the advanced digitizing tool matching the provided ``name`` or ``None`` when no match available +%End + + const QStringList toolMetadataNames() const; +%Docstring +Returns the list of registered tool names +%End + + private: + QgsAdvancedDigitizingToolsRegistry( const QgsAdvancedDigitizingToolsRegistry &rh ); +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgsadvanceddigitizingtoolsregistry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/qgsgui.sip.in b/python/gui/auto_generated/qgsgui.sip.in index 3645bd698614..b911c74bc038 100644 --- a/python/gui/auto_generated/qgsgui.sip.in +++ b/python/gui/auto_generated/qgsgui.sip.in @@ -77,6 +77,13 @@ Returns the global layout item GUI registry, used for registering the GUI behavi Returns the global annotation item GUI registry, used for registering the GUI behavior of annotation items. .. versionadded:: 3.22 +%End + + static QgsAdvancedDigitizingToolsRegistry *advancedDigitizingToolsRegistry() /KeepReference/; +%Docstring +Returns the global advanced digitizing tools registry, used for registering advanced digitizing tools. + +.. versionadded:: 3.40 %End static QgsProcessingGuiRegistry *processingGuiRegistry() /KeepReference/; diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip index 913c0e8b2786..a69c84652cb2 100644 --- a/python/gui/gui_auto.sip +++ b/python/gui/gui_auto.sip @@ -7,6 +7,7 @@ %Include auto_generated/qgsadvanceddigitizingdockwidget.sip %Include auto_generated/qgsadvanceddigitizingfloater.sip %Include auto_generated/qgsadvanceddigitizingtools.sip +%Include auto_generated/qgsadvanceddigitizingtoolsregistry.sip %Include auto_generated/qgsaggregatetoolbutton.sip %Include auto_generated/qgsalignmentcombobox.sip %Include auto_generated/qgsapplicationexitblockerinterface.sip diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f346e387b0b0..021fdddbeded 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -519,6 +519,7 @@ set(QGIS_GUI_SRCS qgsadvanceddigitizingdockwidget.cpp qgsadvanceddigitizingfloater.cpp qgsadvanceddigitizingtools.cpp + qgsadvanceddigitizingtoolsregistry.cpp qgsaggregatetoolbutton.cpp qgsalignmentcombobox.cpp qgsapplicationexitblockerinterface.cpp @@ -792,6 +793,7 @@ set(QGIS_GUI_HDRS qgsadvanceddigitizingdockwidget.h qgsadvanceddigitizingfloater.h qgsadvanceddigitizingtools.h + qgsadvanceddigitizingtoolsregistry.h qgsaggregatetoolbutton.h qgsalignmentcombobox.h qgsapplicationexitblockerinterface.h diff --git a/src/gui/qgsadvanceddigitizingdockwidget.cpp b/src/gui/qgsadvanceddigitizingdockwidget.cpp index 2b3cc95005fd..52cebd0450e1 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.cpp +++ b/src/gui/qgsadvanceddigitizingdockwidget.cpp @@ -22,9 +22,11 @@ #include "qgsadvanceddigitizingdockwidget.h" #include "qgsadvanceddigitizingfloater.h" #include "qgsadvanceddigitizingcanvasitem.h" +#include "qgsadvanceddigitizingtoolsregistry.h" #include "qgsbearingnumericformat.h" #include "qgscadutils.h" #include "qgsexpression.h" +#include "qgsgui.h" #include "qgsmapcanvas.h" #include "qgsmaptooledit.h" #include "qgsmaptooladvanceddigitizing.h" @@ -98,7 +100,6 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * connect( mConstructionModeAction, &QAction::triggered, this, &QgsAdvancedDigitizingDockWidget::setConstructionMode ); connect( mParallelAction, &QAction::triggered, this, &QgsAdvancedDigitizingDockWidget::betweenLineConstraintClicked ); connect( mPerpendicularAction, &QAction::triggered, this, &QgsAdvancedDigitizingDockWidget::betweenLineConstraintClicked ); - connect( mCirclesIntersectionAction, &QAction::triggered, this, &QgsAdvancedDigitizingDockWidget::circlesIntersectionClicked ); connect( mLockAngleButton, &QAbstractButton::clicked, this, &QgsAdvancedDigitizingDockWidget::lockConstraint ); connect( mLockDistanceButton, &QAbstractButton::clicked, this, &QgsAdvancedDigitizingDockWidget::lockConstraint ); connect( mLockXButton, &QAbstractButton::clicked, this, &QgsAdvancedDigitizingDockWidget::lockConstraint ); @@ -239,6 +240,22 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * constructionModeToolButton->setMenu( constructionSettingsMenu ); constructionModeToolButton->setObjectName( QStringLiteral( "ConstructionModeButton" ) ); + // Tools + QMenu *toolsMenu = new QMenu( this ); + const QStringList toolMetadataNames = QgsGui::instance()->advancedDigitizingToolsRegistry()->toolMetadataNames(); + for ( const QString &name : toolMetadataNames ) + { + QgsAdvancedDigitizingToolAbstractMetadata *toolMetadata = QgsGui::instance()->advancedDigitizingToolsRegistry()->toolMetadata( name ); + QAction *toolAction = new QAction( toolMetadata->icon(), toolMetadata->visibleName(), this ); + connect( toolAction, &QAction::triggered, this, [ = ]() + { + setTool( toolMetadata->createTool( mMapCanvas, this ) ); + } ); + toolsMenu->addAction( toolAction ); + } + qobject_cast< QToolButton *>( mToolbar->widgetForAction( mToolsAction ) )->setPopupMode( QToolButton::InstantPopup ); + mToolsAction->setMenu( toolsMenu ); + qobject_cast< QToolButton *>( mToolbar->widgetForAction( mSettingsAction ) )->setPopupMode( QToolButton::InstantPopup ); mSettingsAction->setMenu( mCommonAngleActionsMenu ); mSettingsAction->setCheckable( true ); @@ -546,7 +563,7 @@ void QgsAdvancedDigitizingDockWidget::setCadEnabled( bool enabled ) mInputWidgets->setEnabled( enabled ); mFloaterAction->setEnabled( enabled ); mConstructionAction->setEnabled( enabled ); - mCirclesIntersectionAction->setEnabled( enabled ); + mToolsAction->setEnabled( enabled ); if ( !enabled ) { @@ -667,6 +684,7 @@ void QgsAdvancedDigitizingDockWidget::setTool( QgsAdvancedDigitizingTool *tool ) mCurrentTool = nullptr; } + qDebug() << mCurrentTool; mCurrentTool = tool; if ( mCurrentTool ) @@ -681,22 +699,6 @@ QgsAdvancedDigitizingTool *QgsAdvancedDigitizingDockWidget::tool() const return mCurrentTool.data(); } -void QgsAdvancedDigitizingDockWidget::circlesIntersectionClicked() -{ - if ( mCurrentTool && dynamic_cast( mCurrentTool.data() ) ) - { - setTool( nullptr ); - mCirclesIntersectionAction->setChecked( false ); - } - else - { - QgsAdvancedDigitizingCirclesIntersectionTool *circlesIntersectionTool = new QgsAdvancedDigitizingCirclesIntersectionTool( mMapCanvas, this ); - connect( circlesIntersectionTool, &QObject::destroyed, this, [ = ] { mCirclesIntersectionAction->setChecked( false ); } ); - setTool( circlesIntersectionTool ); - mCirclesIntersectionAction->setChecked( true ); - } -} - void QgsAdvancedDigitizingDockWidget::betweenLineConstraintClicked( bool activated ) { if ( !activated ) diff --git a/src/gui/qgsadvanceddigitizingdockwidget.h b/src/gui/qgsadvanceddigitizingdockwidget.h index acc11fc9145b..44d327fc4c8b 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.h +++ b/src/gui/qgsadvanceddigitizingdockwidget.h @@ -981,9 +981,6 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private //! Sets the between line constraint by clicking on the perpendicular/parallel buttons void betweenLineConstraintClicked( bool activated ); - //! Activate the circles intersection tool - void circlesIntersectionClicked(); - //! lock/unlock a constraint and set its value void lockConstraint( bool activate = true ); diff --git a/src/gui/qgsadvanceddigitizingtoolsregistry.cpp b/src/gui/qgsadvanceddigitizingtoolsregistry.cpp new file mode 100644 index 000000000000..77b7992b8c67 --- /dev/null +++ b/src/gui/qgsadvanceddigitizingtoolsregistry.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + qgsadvanceddigitizingtoolsregistry.cpp + ------------------- + begin : July 27 2024 + copyright : (C) 2024 by Mathieu Pellerin + email : mathieu at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsadvanceddigitizingtoolsregistry.h" +#include "qgsadvanceddigitizingtools.h" +#include "qgsapplication.h" + +QgsAdvancedDigitizingTool *QgsAdvancedDigitizingToolAbstractMetadata::createTool( QgsMapCanvas *, QgsAdvancedDigitizingDockWidget * ) +{ + return nullptr; +} + +QgsAdvancedDigitizingTool *QgsAdvancedDigitizingToolMetadata::createTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget ) +{ + return mToolFunc ? mToolFunc( canvas, cadDockWidget ) : QgsAdvancedDigitizingToolAbstractMetadata::createTool( canvas, cadDockWidget ); +} + +QgsAdvancedDigitizingToolsRegistry::~QgsAdvancedDigitizingToolsRegistry() +{ + qDeleteAll( mTools ); +} + +void QgsAdvancedDigitizingToolsRegistry::addDefaultTools() +{ + addTool( new QgsAdvancedDigitizingToolMetadata( QStringLiteral( "circlesintersection" ), + QObject::tr( "2-Circle Point Intersection" ), + QgsApplication::getThemeIcon( QStringLiteral( "/cadtools/circlesintersection.svg" ) ), + [ = ]( QgsMapCanvas * canvas, QgsAdvancedDigitizingDockWidget * cadDockWidget )->QgsAdvancedDigitizingTool * + { + return new QgsAdvancedDigitizingCirclesIntersectionTool( canvas, cadDockWidget ); + } ) ); +} + +bool QgsAdvancedDigitizingToolsRegistry::addTool( QgsAdvancedDigitizingToolAbstractMetadata *toolMetaData ) +{ + if ( mTools.contains( toolMetaData->name() ) ) + return false; + + mTools[toolMetaData->name()] = toolMetaData; + return true; +} + + +bool QgsAdvancedDigitizingToolsRegistry::removeTool( const QString &name ) +{ + if ( !mTools.contains( name ) ) + return false; + + delete mTools.take( name ); + return true; +} + +QgsAdvancedDigitizingToolAbstractMetadata *QgsAdvancedDigitizingToolsRegistry::toolMetadata( const QString &name ) +{ + if ( !mTools.contains( name ) ) + return nullptr; + + return mTools[name]; +} + +const QStringList QgsAdvancedDigitizingToolsRegistry::toolMetadataNames() const +{ + return mTools.keys(); +} diff --git a/src/gui/qgsadvanceddigitizingtoolsregistry.h b/src/gui/qgsadvanceddigitizingtoolsregistry.h new file mode 100644 index 000000000000..3793cda98a58 --- /dev/null +++ b/src/gui/qgsadvanceddigitizingtoolsregistry.h @@ -0,0 +1,153 @@ +/*************************************************************************** + qgsadvanceddigitizingtoolsregistry.cpp + ------------------- + begin : July 27 2024 + copyright : (C) 2024 by Mathieu Pellerin + email : mathieu at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSADVANCEDDIGITIZINGTOOLSREGSITRY_H +#define QGSADVANCEDDIGITIZINGTOOLSREGSITRY_H + +#include "qgis_sip.h" +#include "qgis_gui.h" + +#include +#include + +class QgsAdvancedDigitizingDockWidget; +class QgsAdvancedDigitizingTool; +class QgsMapCanvas; + +/** + * \ingroup gui + * \brief Stores metadata about one advanced digitizing tool class. + * \since QGIS 3.40 + */ +class GUI_EXPORT QgsAdvancedDigitizingToolAbstractMetadata +{ + public: + + /** + * Constructor for QgsAdvancedDigitizingToolAbstractMetadata with the specified tool \a name. + * + * \a visibleName should be set to a translated, user visible name identifying the corresponding annotation item. + * + * An optional \a icon can be set, which will be used by the advanced digitizing dock widget. + */ + QgsAdvancedDigitizingToolAbstractMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon() ) + : mName( name ) + , mVisibleName( visibleName ) + , mIcon( icon ) + {} + + virtual ~QgsAdvancedDigitizingToolAbstractMetadata() = default; + + //! Returns the tool's unique name + QString name() const { return mName; } + + //! Returns the tool's translatable user-friendly name + QString visibleName() const { return mVisibleName; } + + //! Returns the tool's icon + QIcon icon() const { return mIcon; } + + //! Returns new tool of this type. Return NULLPTR on error + virtual QgsAdvancedDigitizingTool *createTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget ) SIP_FACTORY; + + protected: + QString mName; + QString mVisibleName; + QIcon mIcon; +}; + +#ifndef SIP_RUN + +typedef std::function QgsAdvancedDigitizingToolFunc SIP_SKIP; + +/** + * \ingroup gui + * \brief Convenience metadata class that uses static functions to handle advanced digitizing tool creation + * \note not available in Python bindings + * \since QGIS 3.40 + */ +class GUI_EXPORT QgsAdvancedDigitizingToolMetadata : public QgsAdvancedDigitizingToolAbstractMetadata +{ + public: + + /** + * Constructor for QgsAdvancedDigitizingToolAbstractMetadata with the specified tool \a name. + * + * \a visibleName should be set to a translated, user visible name identifying the corresponding annotation item. + * + * An optional \a icon can be set, which will be used by the advanced digitizing dock widget. + * + * A tool creation function can be declared through the \a toolFunction parameter. + */ + QgsAdvancedDigitizingToolMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon(), + const QgsAdvancedDigitizingToolFunc &toolFunction = nullptr ) + : QgsAdvancedDigitizingToolAbstractMetadata( name, visibleName, icon ) + , mToolFunc( toolFunction ) + {} + + //! Returns the tool creation function + QgsAdvancedDigitizingToolFunc toolFunction() const { return mToolFunc; } + + //! Sets the tool creation \a function. + void setToolFunction( const QgsAdvancedDigitizingToolFunc &function ) { mToolFunc = function; } + + QgsAdvancedDigitizingTool *createTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget ) override; + + protected: + QgsAdvancedDigitizingToolFunc mToolFunc = nullptr; +}; + +#endif + +/** + * \ingroup gui + * \brief Registry of available advanced digitizing tools. + * + * \since QGIS 3.40 + */ +class GUI_EXPORT QgsAdvancedDigitizingToolsRegistry +{ + public: + + QgsAdvancedDigitizingToolsRegistry() = default; + ~QgsAdvancedDigitizingToolsRegistry(); + + QgsAdvancedDigitizingToolsRegistry( const QgsAdvancedDigitizingToolsRegistry &rh ) = delete; + QgsAdvancedDigitizingToolsRegistry &operator=( const QgsAdvancedDigitizingToolsRegistry &rh ) = delete; + + //! Adds the default tools shipped in QGIS + void addDefaultTools(); + + //! Adds an advanced digitizing tool (take ownership) and return TRUE on success + bool addTool( QgsAdvancedDigitizingToolAbstractMetadata *toolMetaData SIP_TRANSFER ); + + //! Removes the advanced digitizing tool matching the provided \a name and return TRUE on success + bool removeTool( const QString &name ); + + //! Returns the advanced digitizing tool matching the provided \a name or NULLPTR when no match available + QgsAdvancedDigitizingToolAbstractMetadata *toolMetadata( const QString &name ); + + //! Returns the list of registered tool names + const QStringList toolMetadataNames() const; + + private: +#ifdef SIP_RUN + QgsAdvancedDigitizingToolsRegistry( const QgsAdvancedDigitizingToolsRegistry &rh ); +#endif + + QMap mTools; +}; + +#endif // QGSADVANCEDDIGITIZINGTOOLSREGSITRY_H diff --git a/src/gui/qgsgui.cpp b/src/gui/qgsgui.cpp index 86404cfb4802..7daacba99b1b 100644 --- a/src/gui/qgsgui.cpp +++ b/src/gui/qgsgui.cpp @@ -26,6 +26,7 @@ #include "qgssourceselectproviderregistry.h" #include "qgslayoutitemguiregistry.h" #include "qgsannotationitemguiregistry.h" +#include "qgsadvanceddigitizingtoolsregistry.h" #include "qgscalloutsregistry.h" #include "callouts/qgscalloutwidget.h" #ifdef Q_OS_MACX @@ -144,6 +145,11 @@ QgsAnnotationItemGuiRegistry *QgsGui::annotationItemGuiRegistry() return instance()->mAnnotationItemGuiRegistry; } +QgsAdvancedDigitizingToolsRegistry *QgsGui::advancedDigitizingToolsRegistry() +{ + return instance()->mAdvancedDigitizingToolsRegistry; +} + QgsProcessingGuiRegistry *QgsGui::processingGuiRegistry() { return instance()->mProcessingGuiRegistry; @@ -243,6 +249,7 @@ QgsGui::~QgsGui() delete mProcessingRecentAlgorithmLog; delete mLayoutItemGuiRegistry; delete mAnnotationItemGuiRegistry; + delete mAdvancedDigitizingToolsRegistry; delete mLayerTreeEmbeddedWidgetRegistry; delete mEditorWidgetRegistry; delete mMapLayerActionRegistry; @@ -352,6 +359,9 @@ QgsGui::QgsGui() mAnnotationItemGuiRegistry = new QgsAnnotationItemGuiRegistry(); mAnnotationItemGuiRegistry->addDefaultItems(); + mAdvancedDigitizingToolsRegistry = new QgsAdvancedDigitizingToolsRegistry(); + mAdvancedDigitizingToolsRegistry->addDefaultTools(); + mWidgetStateHelper = new QgsWidgetStateHelper(); mProcessingFavoriteAlgorithmManager = new QgsProcessingFavoriteAlgorithmManager(); mProcessingRecentAlgorithmLog = new QgsProcessingRecentAlgorithmLog(); diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h index 8fcf8afe71ee..d45056f4736f 100644 --- a/src/gui/qgsgui.h +++ b/src/gui/qgsgui.h @@ -32,6 +32,7 @@ class QgsSourceSelectProviderRegistry; class QgsNative; class QgsLayoutItemGuiRegistry; class QgsAnnotationItemGuiRegistry; +class QgsAdvancedDigitizingToolsRegistry; class QgsWidgetStateHelper; class QgsProcessingGuiRegistry; class QgsProcessingFavoriteAlgorithmManager; @@ -131,6 +132,13 @@ class GUI_EXPORT QgsGui : public QObject */ static QgsAnnotationItemGuiRegistry *annotationItemGuiRegistry() SIP_KEEPREFERENCE; + /** + * Returns the global advanced digitizing tools registry, used for registering advanced digitizing tools. + * + * \since QGIS 3.40 + */ + static QgsAdvancedDigitizingToolsRegistry *advancedDigitizingToolsRegistry() SIP_KEEPREFERENCE; + /** * Returns the global processing gui registry, used for registering the GUI behavior of processing algorithms. * \since QGIS 3.2 @@ -334,6 +342,7 @@ class GUI_EXPORT QgsGui : public QObject QgsMapLayerActionRegistry *mMapLayerActionRegistry = nullptr; QgsLayoutItemGuiRegistry *mLayoutItemGuiRegistry = nullptr; QgsAnnotationItemGuiRegistry *mAnnotationItemGuiRegistry = nullptr; + QgsAdvancedDigitizingToolsRegistry *mAdvancedDigitizingToolsRegistry = nullptr; QgsProcessingGuiRegistry *mProcessingGuiRegistry = nullptr; QgsProcessingFavoriteAlgorithmManager *mProcessingFavoriteAlgorithmManager = nullptr; QgsProcessingRecentAlgorithmLog *mProcessingRecentAlgorithmLog = nullptr; diff --git a/src/ui/qgsadvanceddigitizingdockwidgetbase.ui b/src/ui/qgsadvanceddigitizingdockwidgetbase.ui index d97bc8ed333d..68b57cbccaa4 100644 --- a/src/ui/qgsadvanceddigitizingdockwidgetbase.ui +++ b/src/ui/qgsadvanceddigitizingdockwidgetbase.ui @@ -48,7 +48,7 @@ - + @@ -606,7 +606,7 @@ - + true