Skip to content
Permalink
Browse files

Merge pull request #4231 from nyalldawson/options

[FEATURE] Interface for plugins to embed pages in the options dialog
  • Loading branch information
nyalldawson committed Mar 8, 2017
2 parents 95040c1 + 9f23dd2 commit 94bef531f0371141e1e83ddcc5bfe2e71b2c6438
@@ -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
@@ -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;
@@ -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/;


};

@@ -32,14 +32,15 @@
import sys

from qgis.core import QgsApplication
from qgis.gui import QgsOptionsWidgetFactory
from qgis.PyQt.QtCore import Qt, QCoreApplication, QDir
from qgis.PyQt.QtWidgets import QMenu, QAction
from qgis.PyQt.QtGui import QIcon

from processing.core.Processing import Processing
from processing.gui.ProcessingToolbox import ProcessingToolbox
from processing.gui.HistoryDialog import HistoryDialog
from processing.gui.ConfigDialog import ConfigDialog
from processing.gui.ConfigDialog import ConfigOptionsPage, ConfigDialog
from processing.gui.ResultsDock import ResultsDock
from processing.gui.CommanderWindow import CommanderWindow
from processing.modeler.ModelerDialog import ModelerDialog
@@ -53,10 +54,25 @@
sys.path.insert(0, cmd_folder)


class ProcessingOptionsFactory(QgsOptionsWidgetFactory):

def __init__(self):
super(QgsOptionsWidgetFactory, self).__init__()

def icon(self):
return QgsApplication.getThemeIcon('/processingAlgorithm.svg')

def createWidget(self, parent):
return ConfigOptionsPage(parent)


class ProcessingPlugin(object):

def __init__(self, iface):
self.iface = iface
self.options_factory = ProcessingOptionsFactory()
self.options_factory.setTitle(self.tr('Processing'))
iface.registerOptionsWidgetFactory(self.options_factory)
Processing.initialize()

def initGui(self):
@@ -122,16 +138,6 @@ def initGui(self):

self.menu.addSeparator()

self.configAction = QAction(
QIcon(QgsApplication.getThemeIcon('mActionOptions.svg')),
self.tr('&Options...'), self.iface.mainWindow())
self.configAction.setObjectName('configAction')
self.configAction.setMenuRole(QAction.NoRole)

self.configAction.triggered.connect(self.openConfig)
self.iface.registerMainWindowAction(self.configAction, 'Ctrl+Alt+C')
self.menu.addAction(self.configAction)

initializeMenus()
createMenus()

@@ -152,10 +158,11 @@ def unload(self):
self.iface.unregisterMainWindowAction(self.toolboxAction)
self.iface.unregisterMainWindowAction(self.modelerAction)
self.iface.unregisterMainWindowAction(self.historyAction)
self.iface.unregisterMainWindowAction(self.configAction)
self.iface.unregisterMainWindowAction(self.resultsAction)
self.iface.unregisterMainWindowAction(self.commanderAction)

self.iface.unregisterOptionsWidgetFactory(self.options_factory)

removeMenus()

def openCommander(self):
@@ -190,9 +197,5 @@ def openHistory(self):
dlg = HistoryDialog()
dlg.exec_()

def openConfig(self):
dlg = ConfigDialog(self.toolbox)
dlg.exec_()

def tr(self, message):
return QCoreApplication.translate('ProcessingPlugin', message)
@@ -48,7 +48,9 @@
QStandardItem,
QCursor)

from qgis.gui import QgsDoubleSpinBox, QgsSpinBox
from qgis.gui import (QgsDoubleSpinBox,
QgsSpinBox,
QgsOptionsPageWidget)
from qgis.core import NULL, QgsApplication, QgsSettings

from processing.core.ProcessingConfig import (ProcessingConfig,
@@ -64,13 +66,27 @@
os.path.join(pluginPath, 'ui', 'DlgConfig.ui'))


class ConfigOptionsPage(QgsOptionsPageWidget):

def __init__(self, parent):
super(ConfigOptionsPage, self).__init__(parent)
self.config_widget = ConfigDialog()
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setMargin(0)
self.setLayout(layout)
layout.addWidget(self.config_widget)

def apply(self):
self.config_widget.accept()


class ConfigDialog(BASE, WIDGET):

def __init__(self, toolbox):
def __init__(self):
super(ConfigDialog, self).__init__(None)
self.setupUi(self)

self.toolbox = toolbox
self.groupIcon = QIcon()
self.groupIcon.addPixmap(self.style().standardPixmap(
QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off)
@@ -262,7 +278,6 @@ def resetMenusToDefaults(self):
self.saveMenus = True

def accept(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
qsettings = QgsSettings()
for setting in list(self.items.keys()):
if setting.group != menusSettingsGroup or self.saveMenus:
@@ -278,8 +293,6 @@ def accept(self):
setting.save(qsettings)
Processing.updateAlgsList()
settingsWatcher.settingsChanged.emit()
QApplication.restoreOverrideCursor()
QDialog.accept(self)

def itemExpanded(self, idx):
if idx == self.menusItem.index():
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgConfig</class>
<widget class="QDialog" name="DlgConfig">
<widget class="QWidget" name="DlgConfig">
<property name="geometry">
<rect>
<x>0</x>
@@ -17,8 +17,17 @@
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QgsFilterLineEdit" name="searchBox">
@@ -37,16 +46,6 @@
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@@ -57,38 +56,5 @@
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DlgConfig</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DlgConfig</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>
@@ -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"
@@ -9114,7 +9115,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 );
@@ -9176,8 +9177,6 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage )
mMagnifierWidget->setDefaultFactor( factor );
mMagnifierWidget->updateMagnification( factor );
}

delete optionsDialog;
}

void QgisApp::fullHistogramStretch()
@@ -9394,6 +9393,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()
{

0 comments on commit 94bef53

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