Skip to content

Commit

Permalink
[FEATURE] Interface for plugins to embed pages in the options dialog
Browse files Browse the repository at this point in the history
Allows plugins to embed their options into the standard options
dialog, instead of implementing their own config dialog and having
to have extra menu items just for those...
  • Loading branch information
nyalldawson committed Mar 7, 2017
1 parent cc0007c commit 2d807f5
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 61 deletions.
1 change: 1 addition & 0 deletions python/gui/gui.sip
Expand Up @@ -129,6 +129,7 @@
%Include qgsnewvectorlayerdialog.sip
%Include qgsnewgeopackagelayerdialog.sip
%Include qgsoptionsdialogbase.sip
%Include qgsoptionswidgetfactory.sip
%Include qgsorderbydialog.sip
%Include qgsowssourceselect.sip
%Include qgspanelwidget.sip
Expand Down
55 changes: 9 additions & 46 deletions python/gui/qgisinterface.sip
Expand Up @@ -296,53 +296,16 @@ class QgisInterface : QObject
* windows which are hidden rather than deleted when closed. */
virtual void removeWindow( QAction *action ) = 0;

/** Register action to the shortcuts manager so its shortcut can be changed in GUI */
virtual bool registerMainWindowAction( QAction* action, const QString& defaultShortcut ) = 0;

/** Unregister a previously registered action. (e.g. when plugin is going to be unloaded) */
virtual bool unregisterMainWindowAction( QAction* action ) = 0;

/** Register a new tab in the vector layer properties dialog.
* @note added in QGIS 2.16
* @note Ownership of the factory is not transferred, and the factory must
* be unregistered when plugin is unloaded.
* @see unregisterMapLayerPropertiesFactory() */
virtual void registerMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory* factory ) = 0;

/** Unregister a previously registered tab in the vector layer properties dialog.
* @note added in QGIS 2.16
* @see registerMapLayerPropertiesFactory()
*/
virtual void unregisterMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory* factory ) = 0;

/** Register a new custom drop handler.
* @note added in QGIS 3.0
* @note Ownership of the factory is not transferred, and the factory must
* be unregistered when plugin is unloaded.
* @see unregisterCustomDropHandler() */
virtual void registerCustomDropHandler( QgsCustomDropHandler* handler ) = 0;

/** Unregister a previously registered custom drop handler.
* @note added in QGIS 3.0
* @see registerCustomDropHandler() */
virtual void unregisterCustomDropHandler( QgsCustomDropHandler* handler ) = 0;

// @todo is this deprecated in favour of QgsContextHelp?
/** Open a url in the users browser. By default the QGIS doc directory is used
* as the base for the URL. To open a URL that is not relative to the installed
* QGIS documentation, set useQgisDocDirectory to false.
* @param url URL to open
* @param useQgisDocDirectory If true, the URL will be formed by concatenating
* url to the QGIS documentation directory path (prefix/share/doc)
* @deprecated
*/
virtual void openURL( const QString& url, bool useQgisDocDirectory = true ) = 0 /Deprecated/;

/** Accessors for inserting items into menus and toolbars.
* An item can be inserted before any existing action.
*/
virtual bool registerMainWindowAction( QAction *action, const QString &defaultShortcut ) = 0;
virtual bool unregisterMainWindowAction( QAction *action ) = 0;
virtual void registerMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory *factory ) = 0;
virtual void unregisterMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory *factory ) = 0;
virtual void registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) = 0;
virtual void unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) = 0;
virtual void registerCustomDropHandler( QgsCustomDropHandler *handler ) = 0;
virtual void unregisterCustomDropHandler( QgsCustomDropHandler *handler ) = 0;
virtual void openURL( const QString &url, bool useQgisDocDirectory = true ) = 0 /Deprecated/;

// Menus
virtual QMenu *projectMenu() = 0;
virtual QMenu *editMenu() = 0;
virtual QMenu *viewMenu() = 0;
Expand Down
39 changes: 39 additions & 0 deletions python/gui/qgsoptionswidgetfactory.sip
@@ -0,0 +1,39 @@
class QgsOptionsPageWidget : QWidget
{
%TypeHeaderCode
#include <qgsoptionswidgetfactory.h>
%End

public:

QgsOptionsPageWidget( QWidget *parent /TransferThis/ = 0 );

public slots:

virtual void apply() = 0;

};

class QgsOptionsWidgetFactory
{
%TypeHeaderCode
#include <qgsoptionswidgetfactory.h>
%End

public:

QgsOptionsWidgetFactory();

QgsOptionsWidgetFactory( const QString &title, const QIcon &icon );
virtual ~QgsOptionsWidgetFactory();

virtual QIcon icon() const;
void setIcon( const QIcon &icon );
virtual QString title() const;
void setTitle( const QString &title );

virtual QgsOptionsPageWidget *createWidget( QWidget *parent = 0 ) const = 0 /Factory/;


};

15 changes: 12 additions & 3 deletions src/app/qgisapp.cpp
Expand Up @@ -167,6 +167,7 @@
#include "qgsfieldformatter.h"
#include "qgsfieldformatterregistry.h"
#include "qgsformannotation.h"
#include "qgisgui.h"
#include "qgshtmlannotation.h"
#include "qgsprojectionselectiondialog.h"
#include "qgsgpsinformationwidget.h"
Expand Down Expand Up @@ -9105,7 +9106,7 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )

bool oldCapitalize = mySettings.value( QStringLiteral( "/qgis/capitalizeLayerName" ), QVariant( false ) ).toBool();

QgsOptions *optionsDialog = new QgsOptions( parent );
std::unique_ptr< QgsOptions > optionsDialog( new QgsOptions( parent, QgisGui::ModalDialogFlags, mOptionsWidgetFactories ) );
if ( !currentPage.isEmpty() )
{
optionsDialog->setCurrentPage( currentPage );
Expand Down Expand Up @@ -9167,8 +9168,6 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )
mMagnifierWidget->setDefaultFactor( factor );
mMagnifierWidget->updateMagnification( factor );
}

delete optionsDialog;
}

void QgisApp::fullHistogramStretch()
Expand Down Expand Up @@ -9385,6 +9384,16 @@ void QgisApp::unregisterMapLayerPropertiesFactory( QgsMapLayerConfigWidgetFactor
mMapStyleWidget->setPageFactories( mMapLayerPanelFactories );
}

void QgisApp::registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
{
mOptionsWidgetFactories << factory;
}

void QgisApp::unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
{
mOptionsWidgetFactories.removeAll( factory );
}

//! Get a pointer to the currently selected map layer
QgsMapLayer *QgisApp::activeLayer()
{
Expand Down
8 changes: 8 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -87,6 +87,7 @@ class QgsUserInputDockWidget;
class QgsVectorLayer;
class QgsVectorLayerTools;
class QgsWelcomePage;
class QgsOptionsWidgetFactory;

class QDomDocument;
class QNetworkReply;
Expand Down Expand Up @@ -536,6 +537,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Unregister a previously registered tab in the layer properties dialog
void unregisterMapLayerPropertiesFactory( QgsMapLayerConfigWidgetFactory *factory );

//! Register a new tab in the options dialog
void registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory );

//! Unregister a previously registered tab in the options dialog
void unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory );

//! Register a new custom drop handler.
void registerCustomDropHandler( QgsCustomDropHandler *handler );

Expand Down Expand Up @@ -1847,6 +1854,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsSnappingUtils *mSnappingUtils = nullptr;

QList<QgsMapLayerConfigWidgetFactory *> mMapLayerPanelFactories;
QList<QgsOptionsWidgetFactory *> mOptionsWidgetFactories;

QList<QgsCustomDropHandler *> mCustomDropHandlers;

Expand Down
10 changes: 10 additions & 0 deletions src/app/qgisappinterface.cpp
Expand Up @@ -503,6 +503,16 @@ void QgisAppInterface::unregisterMapLayerConfigWidgetFactory( QgsMapLayerConfigW
qgis->unregisterMapLayerPropertiesFactory( factory );
}

void QgisAppInterface::registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
{
qgis->registerOptionsWidgetFactory( factory );
}

void QgisAppInterface::unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory )
{
qgis->unregisterOptionsWidgetFactory( factory );
}

void QgisAppInterface::registerCustomDropHandler( QgsCustomDropHandler *handler )
{
qgis->registerCustomDropHandler( handler );
Expand Down
13 changes: 3 additions & 10 deletions src/app/qgisappinterface.h
Expand Up @@ -302,19 +302,12 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
//! Unregister a previously registered action. (e.g. when plugin is going to be unloaded.
virtual bool unregisterMainWindowAction( QAction *action ) override;

/** Register a new tab in the vector layer properties dialog.
* @note added in QGIS 2.16
* @note Ownership of the factory is not transferred, and the factory must
* be unregistered when plugin is unloaded.
* @see unregisterMapLayerPropertiesFactory() */
virtual void registerMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory *factory ) override;

/** Unregister a previously registered tab in the vector layer properties dialog.
* @note added in QGIS 2.16
* @see registerMapLayerPropertiesFactory()
*/
virtual void unregisterMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory *factory ) override;

virtual void registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) override;
virtual void unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) override;

/** Register a new custom drop handler.
* @note added in QGIS 3.0
* @note Ownership of the factory is not transferred, and the factory must
Expand Down
25 changes: 24 additions & 1 deletion src/app/qgsoptions.cpp
Expand Up @@ -46,6 +46,7 @@
#include "qgsunittypes.h"
#include "qgsclipboard.h"
#include "qgssettings.h"
#include "qgsoptionswidgetfactory.h"

#include <QInputDialog>
#include <QFileDialog>
Expand Down Expand Up @@ -74,7 +75,7 @@
* \class QgsOptions - Set user options and preferences
* Constructor
*/
QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOptionsWidgetFactory *> &optionsFactories )
: QgsOptionsDialogBase( QStringLiteral( "Options" ), parent, fl )
, mSettings( nullptr )
{
Expand Down Expand Up @@ -926,6 +927,23 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )

mAdvancedSettingsEditor->setSettingsObject( mSettings );

Q_FOREACH ( QgsOptionsWidgetFactory *factory, optionsFactories )
{
QListWidgetItem *item = new QListWidgetItem();
item->setIcon( factory->icon() );
item->setText( factory->title() );
item->setToolTip( factory->title() );

mOptionsListWidget->addItem( item );

QgsOptionsPageWidget *page = factory->createWidget( this );
if ( !page )
continue;

mAdditionalOptionWidgets << page;
mOptionsStackedWidget->addWidget( page );
}

// restore window and widget geometry/state
restoreOptionsBaseUi();
}
Expand Down Expand Up @@ -1473,6 +1491,11 @@ void QgsOptions::saveOptions()
}

saveDefaultDatumTransformations();

Q_FOREACH ( QgsOptionsPageWidget *widget, mAdditionalOptionWidgets )
{
widget->apply();
}
}

void QgsOptions::rejectOptions()
Expand Down
9 changes: 8 additions & 1 deletion src/app/qgsoptions.h
Expand Up @@ -30,6 +30,7 @@
#include "qgis_app.h"

class QgsExpressionContext;
class QgsOptionsPageWidget;

/**
* \class QgsOptions
Expand All @@ -45,8 +46,10 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
* @param parent Parent widget (usually a QgisApp)
* @param name name for the widget
* @param modal true for modal dialog
* @param optionsFactories factories for additional option pages
*/
QgsOptions( QWidget *parent = nullptr, Qt::WindowFlags fl = QgisGui::ModalDialogFlags );
QgsOptions( QWidget *parent = nullptr, Qt::WindowFlags fl = QgisGui::ModalDialogFlags,
const QList<QgsOptionsWidgetFactory *> &optionsFactories = QList<QgsOptionsWidgetFactory *>() );

~QgsOptions();

Expand Down Expand Up @@ -245,6 +248,10 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
static const int PALETTE_COLOR_ROLE = Qt::UserRole + 1;
static const int PALETTE_LABEL_ROLE = Qt::UserRole + 2;

private:

QList< QgsOptionsPageWidget * > mAdditionalOptionWidgets;

};

#endif // #ifndef QGSOPTIONS_H
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -416,6 +416,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsnewvectorlayerdialog.h
qgsnewgeopackagelayerdialog.h
qgsoptionsdialogbase.h
qgsoptionswidgetfactory.h
qgsorderbydialog.h
qgsowssourceselect.h
qgssourceselectdialog.h
Expand Down
14 changes: 14 additions & 0 deletions src/gui/qgisinterface.h
Expand Up @@ -41,6 +41,7 @@ class QgsRasterLayer;
class QgsSnappingUtils;
class QgsVectorLayer;
class QgsVectorLayerTools;
class QgsOptionsWidgetFactory;

#include <QObject>
#include <QFont>
Expand Down Expand Up @@ -364,6 +365,19 @@ class GUI_EXPORT QgisInterface : public QObject
*/
virtual void unregisterMapLayerConfigWidgetFactory( QgsMapLayerConfigWidgetFactory *factory ) = 0;

/** Register a new tab in the options dialog.
* @note added in QGIS 3.0
* @note Ownership of the factory is not transferred, and the factory must
* be unregistered when plugin is unloaded.
* @see unregisterOptionsWidgetFactory() */
virtual void registerOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) = 0;

/** Unregister a previously registered tab in the options dialog.
* @note added in QGIS 3.0
* @see registerOptionsWidgetFactory()
*/
virtual void unregisterOptionsWidgetFactory( QgsOptionsWidgetFactory *factory ) = 0;

/** Register a new custom drop handler.
* @note added in QGIS 3.0
* @note Ownership of the factory is not transferred, and the factory must
Expand Down

0 comments on commit 2d807f5

Please sign in to comment.