| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #include <QMap> | ||
| #include <QString> | ||
| #include <QVariant> | ||
|
|
||
|
|
||
| /** | ||
| * Holds a set of configuration parameters for a editor widget wrapper. | ||
| * It's basically a set of key => value pairs. | ||
| * | ||
| * If you need more advanced structures than a simple key => value pair, | ||
| * you can use a value to hold any structure a QVariant can handle (and that's | ||
| * about anything you get through your compiler) | ||
| * | ||
| * These are the user configurable options in the field properties tab of the | ||
| * vector layer properties. They are saved in the project file per layer and field. | ||
| * You get these passed, for every new widget wrapper. | ||
| */ | ||
|
|
||
| typedef QMap<QString, QVariant> QgsEditorWidgetConfig; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /*************************************************************************** | ||
| qgseditorconfigwidget.cpp | ||
| -------------------------------------- | ||
| Date : 24.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 "qgseditorconfigwidget.h" | ||
|
|
||
|
|
||
| QgsEditorConfigWidget::QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) | ||
| : QWidget( parent ) | ||
| , mLayer( vl ) | ||
| , mField( fieldIdx ) | ||
|
|
||
| { | ||
| } | ||
|
|
||
| int QgsEditorConfigWidget::field() | ||
| { | ||
| return mField; | ||
| } | ||
|
|
||
| QgsVectorLayer*QgsEditorConfigWidget::layer() | ||
| { | ||
| return mLayer; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| /*************************************************************************** | ||
| qgseditorconfigwidget.h | ||
| -------------------------------------- | ||
| Date : 24.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 QGSEDITORCONFIGWIDGET_H | ||
| #define QGSEDITORCONFIGWIDGET_H | ||
|
|
||
| #include <QWidget> | ||
|
|
||
| #include "qgseditorwidgetwrapper.h" | ||
|
|
||
| class QgsVectorLayer; | ||
|
|
||
| /** | ||
| * This class should be subclassed for every configurable editor widget type. | ||
| * | ||
| * It implements the GUI configuration widget and transforms this to/from a configuration. | ||
| * | ||
| * It will only be instantiated by {@see QgsEditorWidgetFactory} | ||
| */ | ||
|
|
||
| class GUI_EXPORT QgsEditorConfigWidget : public QWidget | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| /** | ||
| * Create a new configuration widget | ||
| * | ||
| * @param vl The layer for which the configuration dialog will be created | ||
| * @param fieldIdx The index of the field on the layer for which this dialog will be created | ||
| * @param parent A parent widget | ||
| */ | ||
| explicit QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ); | ||
|
|
||
| /** | ||
| * @brief Create a configuration from the current GUI state | ||
| * | ||
| * @return A widget configuration | ||
| */ | ||
| virtual QgsEditorWidgetConfig config() = 0; | ||
|
|
||
| /** | ||
| * @brief Update the configuration widget to represent the given configuration. | ||
| * | ||
| * @param config The configuration which should be represented by this widget | ||
| */ | ||
| virtual void setConfig( const QgsEditorWidgetConfig& config ) = 0; | ||
|
|
||
| /** | ||
| * Returns the field for which this configuration widget applies | ||
| * | ||
| * @return The field index | ||
| */ | ||
| int field(); | ||
|
|
||
| /** | ||
| * Returns the layer for which this configuration widget applies | ||
| * | ||
| * @return The layer | ||
| */ | ||
| QgsVectorLayer* layer(); | ||
|
|
||
| /** | ||
| * Destructor | ||
| */ | ||
| virtual ~QgsEditorConfigWidget() {} | ||
|
|
||
| private: | ||
| QgsVectorLayer* mLayer; | ||
| int mField; | ||
| }; | ||
|
|
||
| #endif // QGSEDITORCONFIGWIDGET_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetfactory.cpp | ||
| -------------------------------------- | ||
| Date : 21.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 "qgseditorwidgetfactory.h" | ||
|
|
||
| QgsEditorWidgetFactory::QgsEditorWidgetFactory( const QString& name ) | ||
| : mName( name ) | ||
| { | ||
| } | ||
|
|
||
| QgsEditorWidgetFactory::~QgsEditorWidgetFactory() | ||
| { | ||
| } | ||
|
|
||
| QString QgsEditorWidgetFactory::name() | ||
| { | ||
| return mName; | ||
| } | ||
|
|
||
| QgsEditorWidgetConfig QgsEditorWidgetFactory::readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ) | ||
| { | ||
| Q_UNUSED( configElement ); | ||
| Q_UNUSED( layer ); | ||
| Q_UNUSED( fieldIdx ); | ||
|
|
||
| return QgsEditorWidgetConfig(); | ||
| } | ||
|
|
||
| void QgsEditorWidgetFactory::writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) | ||
| { | ||
| Q_UNUSED( config ); | ||
| Q_UNUSED( configElement ); | ||
| Q_UNUSED( doc ); | ||
| Q_UNUSED( layer ); | ||
| Q_UNUSED( fieldIdx ); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetfactory.h | ||
| -------------------------------------- | ||
| Date : 21.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 QGSEDITORWIDGETFACTORY_H | ||
| #define QGSEDITORWIDGETFACTORY_H | ||
|
|
||
| #include "qgseditorwidgetwrapper.h" | ||
| #include "qgsapplication.h" | ||
|
|
||
| #include <QDomNode> | ||
| #include <QMap> | ||
| #include <QString> | ||
|
|
||
| class QgsEditorConfigWidget; | ||
|
|
||
| /** | ||
| * Every attribute editor widget needs a factory, which inherits this class | ||
| * | ||
| * It provides metadata for the widgets such as the name (human readable), it serializes | ||
| * the configuration to an xml structure and loads the configuration from there. | ||
| * | ||
| * It also has factory methods to create a widget wrapper for the attribute editor itself | ||
| * and another factory method to create a configuration dialog. | ||
| */ | ||
| class GUI_EXPORT QgsEditorWidgetFactory | ||
| { | ||
| public: | ||
| /** | ||
| * Constructor | ||
| * | ||
| * @param name A human readable name for this widget type | ||
| */ | ||
| QgsEditorWidgetFactory( const QString& name ); | ||
|
|
||
| virtual ~QgsEditorWidgetFactory(); | ||
|
|
||
| /** | ||
| * Override this in your implementation. | ||
| * Create a new editor widget wrapper. Call {@link QgsEditorWidgetRegistry::create()} | ||
| * instead of calling this method directly. | ||
| * | ||
| * @param vl The vector layer on which this widget will act | ||
| * @param fieldIdx The field index on which this widget will act | ||
| * @param editor An editor widget if already existent. If NULL is provided, a new widget will be created. | ||
| * @param parent The parent for the wrapper class and any created widget. | ||
| * | ||
| * @return A new widget wrapper | ||
| */ | ||
| virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const = 0; | ||
|
|
||
| /** | ||
| * Return The human readable name of this widget type | ||
| * | ||
| * By default returns the name specified when constructing and does not need to be overwritten | ||
| * | ||
| * @return a name | ||
| */ | ||
| virtual QString name(); | ||
|
|
||
| /** | ||
| * Override this in your implementation. | ||
| * Create a new configuration widget for this widget type. | ||
| * | ||
| * @param vl The layer for which the widget will be created | ||
| * @param fieldIdx The field index for which the widget will be created | ||
| * @param parent The parent widget of the created config widget | ||
| * | ||
| * @return A configuration widget | ||
| */ | ||
| virtual QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const = 0; | ||
|
|
||
| /** | ||
| * Read the config from an XML file and map it to a proper {@link QgsEditorWidgetConfig}. | ||
| * | ||
| * @param configElement The configuration element from the project file | ||
| * @param layer The layer for which this configuration applies | ||
| * @param fieldIdx The field on the layer for which this configuration applies | ||
| * | ||
| * @return A configuration object. This will be passed to your widget wrapper later on | ||
| */ | ||
| virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ); | ||
|
|
||
| /** | ||
| * Serialize your configuration and save it in a xml doc. | ||
| * | ||
| * @param config The configuration to serialize | ||
| * @param configElement The element, where you can write your configuration into | ||
| * @param doc The document. You can use this to create new nodes | ||
| * @param layer The layer for which this configuration applies | ||
| * @param fieldIdx The field on the layer for which this configuration applies | ||
| */ | ||
| virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ); | ||
|
|
||
| private: | ||
| QString mName; | ||
| }; | ||
|
|
||
| /** | ||
| * This is a templated wrapper class, which inherits QgsEditWidgetFactory and does the boring work for you. | ||
| * C++ only | ||
| */ | ||
| template<typename F, typename G> | ||
| class GUI_EXPORT QgsEditWidgetFactoryHelper : public QgsEditorWidgetFactory | ||
| { | ||
| public: | ||
| QgsEditWidgetFactoryHelper( QString name ) | ||
| : QgsEditorWidgetFactory( name ) {} | ||
|
|
||
| QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const | ||
| { | ||
| return new F( vl, fieldIdx, editor, parent ); | ||
| } | ||
|
|
||
| QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) | ||
| { | ||
| return new G( vl, fieldIdx, parent ); | ||
| } | ||
|
|
||
| /** | ||
| * Read the config from an XML file and map it to a proper {@link QgsEditorWidgetConfig}. | ||
| * | ||
| * Implement this method yourself somewhere with the class template parameters | ||
| * specified. To keep things clean, every implementation of this class should be placed | ||
| * next to the associated widget factory implementation. | ||
| * | ||
| * @param configElement The configuration element from the project file | ||
| * @param layer The layer for which this configuration applies | ||
| * @param fieldIdx The field on the layer for which this configuration applies | ||
| * | ||
| * @return A configuration object. This will be passed to your widget wrapper later on | ||
| */ | ||
|
|
||
| virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ); | ||
|
|
||
| /** | ||
| * Serialize your configuration and save it in a xml doc. | ||
| * | ||
| * Implement this method yourself somewhere with the class template parameters | ||
| * specified. To keep things clean, every implementation of this class should be placed | ||
| * next to the associated widget factory implementation. | ||
| * | ||
| * @param config The configuration to serialize | ||
| * @param configElement The element, where you can write your configuration into | ||
| * @param doc The document. You can use this to create new nodes | ||
| * @param layer The layer for which this configuration applies | ||
| * @param fieldIdx The field on the layer for which this configuration applies | ||
| */ | ||
| virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ); | ||
| }; | ||
|
|
||
| #endif // QGSEDITORWIDGETFACTORY_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,218 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetregistry.cpp | ||
| -------------------------------------- | ||
| Date : 24.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 "qgseditorwidgetregistry.h" | ||
|
|
||
| #include "qgseditorwidgetfactory.h" | ||
| #include "qgsproject.h" | ||
| #include "qgsvectorlayer.h" | ||
| #include "qgsmessagelog.h" | ||
|
|
||
|
|
||
| QgsEditorWidgetRegistry QgsEditorWidgetRegistry::sInstance; | ||
|
|
||
| QgsEditorWidgetRegistry* QgsEditorWidgetRegistry::instance() | ||
| { | ||
| return &sInstance; | ||
| } | ||
|
|
||
| QgsEditorWidgetRegistry::QgsEditorWidgetRegistry() | ||
| { | ||
| connect( QgsProject::instance(), SIGNAL( readMapLayer( QgsMapLayer*, const QDomElement& ) ), this, SLOT( readMapLayer( QgsMapLayer*, const QDomElement& ) ) ); | ||
| connect( QgsProject::instance(), SIGNAL( writeMapLayer( QgsMapLayer*, QDomElement&, QDomDocument& ) ), this, SLOT( writeMapLayer( QgsMapLayer*, QDomElement&, QDomDocument& ) ) ); | ||
| } | ||
|
|
||
| QgsEditorWidgetRegistry::~QgsEditorWidgetRegistry() | ||
| { | ||
| qDeleteAll( mWidgetFactories.values() ); | ||
| } | ||
|
|
||
| QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::create( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor, QWidget* parent ) | ||
| { | ||
| if ( mWidgetFactories.contains( widgetId ) ) | ||
| { | ||
| QgsEditorWidgetWrapper* ww = mWidgetFactories[widgetId]->create( vl, fieldIdx, editor, parent ); | ||
| if ( ww ) | ||
| { | ||
| ww->setConfig( config ); | ||
| return ww; | ||
| } | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| QgsEditorConfigWidget* QgsEditorWidgetRegistry::createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) | ||
| { | ||
| if ( mWidgetFactories.contains( widgetId ) ) | ||
| { | ||
| return mWidgetFactories[widgetId]->configWidget( vl, fieldIdx, parent ); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| QString QgsEditorWidgetRegistry::name( const QString& widgetId ) | ||
| { | ||
| if ( mWidgetFactories.contains( widgetId ) ) | ||
| { | ||
| return mWidgetFactories[widgetId]->name(); | ||
| } | ||
|
|
||
| return QString(); | ||
| } | ||
|
|
||
| const QMap<QString, QgsEditorWidgetFactory*> QgsEditorWidgetRegistry::factories() | ||
| { | ||
| return mWidgetFactories; | ||
| } | ||
|
|
||
| bool QgsEditorWidgetRegistry::registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory ) | ||
| { | ||
| if ( !widgetFactory ) | ||
| { | ||
| QgsMessageLog::instance()->logMessage( "QgsEditorWidgetRegistry: Factory not valid." ); | ||
| return false; | ||
| } | ||
| else if ( mWidgetFactories.contains( widgetId ) ) | ||
| { | ||
| QgsMessageLog::instance()->logMessage( QString( "QgsEditorWidgetRegistry: Factory with id %1 already registered." ).arg( widgetId ) ); | ||
| return false; | ||
| } | ||
| else | ||
| { | ||
| mWidgetFactories.insert( widgetId, widgetFactory ); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomElement& layerElem ) | ||
| { | ||
| if ( mapLayer->type() != QgsMapLayer::VectorLayer ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer ); | ||
| if ( !vectorLayer ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| for ( int idx = 0; idx < vectorLayer->pendingFields().count(); ++idx ) | ||
| { | ||
| if ( vectorLayer->editType( idx ) != QgsVectorLayer::EditorWidgetV2 ) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| QDomNodeList editTypeNodes = layerElem.namedItem( "edittypes" ).childNodes(); | ||
|
|
||
| for ( int i = 0; i < editTypeNodes.size(); i++ ) | ||
| { | ||
| QDomNode editTypeNode = editTypeNodes.at( i ); | ||
| QDomElement editTypeElement = editTypeNode.toElement(); | ||
|
|
||
| QString name = editTypeElement.attribute( "name" ); | ||
|
|
||
| if ( vectorLayer->fieldNameIndex( name ) != idx ) | ||
| continue; | ||
|
|
||
| QgsVectorLayer::EditType editType = | ||
| ( QgsVectorLayer::EditType ) editTypeElement.attribute( "type" ).toInt(); | ||
|
|
||
| if ( editType != QgsVectorLayer::EditorWidgetV2 ) | ||
| continue; | ||
|
|
||
| QString ewv2Type = editTypeElement.attribute( "widgetv2type" ); | ||
|
|
||
| if ( mWidgetFactories.contains( ewv2Type ) ) | ||
| { | ||
| vectorLayer->setEditorWidgetV2( idx, ewv2Type ); | ||
| QDomElement ewv2CfgElem = editTypeElement.namedItem( "widgetv2config" ).toElement(); | ||
|
|
||
| if ( !ewv2CfgElem.isNull() ) | ||
| { | ||
| QMap<QString, QVariant> cfg = mWidgetFactories[ewv2Type]->readConfig( ewv2CfgElem, vectorLayer, idx ); | ||
| vectorLayer->setEditorWidgetV2Config( idx, cfg ); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| QgsMessageLog::logMessage( tr( "Unknown attribute editor widget '%1'" ).arg( ewv2Type ) ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc ) | ||
| { | ||
| if ( mapLayer->type() != QgsMapLayer::VectorLayer ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer ); | ||
| if ( !vectorLayer ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| for ( int idx = 0; idx < vectorLayer->pendingFields().count(); ++idx ) | ||
| { | ||
| if ( vectorLayer->editType( idx ) != QgsVectorLayer::EditorWidgetV2 ) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| const QString& widgetType = vectorLayer->editorWidgetV2( idx ); | ||
| if ( !mWidgetFactories.contains( widgetType ) ) | ||
| { | ||
| QgsMessageLog::logMessage( tr( "Could not save unknown editor widget type '%1'." ).arg( widgetType ) ); | ||
| continue; | ||
| } | ||
|
|
||
| QDomNodeList editTypeNodes = layerElem.namedItem( "edittypes" ).childNodes(); | ||
|
|
||
| for ( int i = 0; i < editTypeNodes.size(); i++ ) | ||
| { | ||
| QDomElement editTypeElement = editTypeNodes.at( i ).toElement(); | ||
|
|
||
| QString name = editTypeElement.attribute( "name" ); | ||
|
|
||
| if ( vectorLayer->fieldNameIndex( name ) != idx ) | ||
| continue; | ||
|
|
||
| QgsVectorLayer::EditType editType = | ||
| ( QgsVectorLayer::EditType ) editTypeElement.attribute( "type" ).toInt(); | ||
|
|
||
| if ( editType != QgsVectorLayer::EditorWidgetV2 ) | ||
| continue; | ||
|
|
||
| editTypeElement.setAttribute( "widgetv2type", widgetType ); | ||
|
|
||
| if ( mWidgetFactories.contains( widgetType ) ) | ||
| { | ||
| QDomElement ewv2CfgElem = doc.createElement( "widgetv2config" ); | ||
|
|
||
| mWidgetFactories[widgetType]->writeConfig( vectorLayer->editorWidgetV2Config( idx ), ewv2CfgElem, doc, vectorLayer, idx ); | ||
|
|
||
| editTypeElement.appendChild( ewv2CfgElem ); | ||
| } | ||
| else | ||
| { | ||
| QgsMessageLog::logMessage( tr( "Unknown attribute editor widget '%1'" ).arg( widgetType ) ); | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetregistry.h | ||
| -------------------------------------- | ||
| Date : 24.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 QGSEDITORWIDGETREGISTRY_H | ||
| #define QGSEDITORWIDGETREGISTRY_H | ||
|
|
||
| #include <QObject> | ||
| #include <QMap> | ||
|
|
||
| #include "qgseditorwidgetfactory.h" | ||
|
|
||
| class QgsMapLayer; | ||
| class QDomNode; | ||
|
|
||
| /** | ||
| * This class manages all known edit widget factories | ||
| */ | ||
| class GUI_EXPORT QgsEditorWidgetRegistry : public QObject | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| /** | ||
| * This class is a singleton and has therefore to be accessed with this method instead | ||
| * of a constructor. | ||
| * | ||
| * @return | ||
| */ | ||
| static QgsEditorWidgetRegistry* instance(); | ||
| ~QgsEditorWidgetRegistry(); | ||
|
|
||
| /** | ||
| * Create an attribute editor widget wrapper of a given type for a given field. | ||
| * The editor may be NULL if you want the widget wrapper to create a default widget. | ||
| * | ||
| * @param widgetId The id of the widget type to create an attribute editor for | ||
| * @param vl The vector layer for which this widget will be created | ||
| * @param fieldIdx The field index on the specified layer for which this widget will be created | ||
| * @param config A configuration which should be used for the widget creation | ||
| * @param editor An editor widget which will be used instead of an autocreated widget | ||
| * @param parent The parent which will be used for the created wrapper and the created widget | ||
| * | ||
| * @return A new widget wrapper | ||
| */ | ||
| QgsEditorWidgetWrapper* create( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor, QWidget* parent ); | ||
|
|
||
| /** | ||
| * Creates a configuration widget | ||
| * | ||
| * @param widgetId The id of the widget type to create a configuration widget for | ||
| * @param vl The vector layer for which this widget will be created | ||
| * @param fieldIdx The field index on the specified layer for which this widget will be created | ||
| * @param parent The parent widget for the created widget | ||
| * | ||
| * @return A new configuration widget | ||
| */ | ||
| QgsEditorConfigWidget* createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent ); | ||
|
|
||
| /** | ||
| * Get the human readable name for a widget type | ||
| * | ||
| * @param widgetId The widget type to get the name for | ||
| * | ||
| * @return A human readable name | ||
| */ | ||
| QString name( const QString& widgetId ); | ||
|
|
||
| /** | ||
| * Get access to all registered factories | ||
| * | ||
| * @return All ids and factories | ||
| */ | ||
| const QMap<QString, QgsEditorWidgetFactory*> factories(); | ||
|
|
||
| /** | ||
| * The other part which does the boring work for you | ||
| */ | ||
| template <class W, class C> | ||
| void registerWidget( const QString& widgetType, const QString& name ) | ||
| { | ||
| mWidgetFactories.insert( widgetType, new QgsEditWidgetFactoryHelper<W, C>( name ) ); | ||
| } | ||
|
|
||
| /** | ||
| * Register a new widget factory with the given id | ||
| * | ||
| * @param widgetId The id which will be used later to refer to this widget type | ||
| * @param widgetFactory The factory which will create this widget type | ||
| * | ||
| * @return true, if successful, false, if the widgetId is already in use or widgetFactory is NULL | ||
| */ | ||
| bool registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory ); | ||
|
|
||
| protected: | ||
| QgsEditorWidgetRegistry(); | ||
|
|
||
| private slots: | ||
| void readMapLayer( QgsMapLayer* mapLayer , const QDomElement& layerElem ); | ||
| void writeMapLayer( QgsMapLayer* mapLayer , QDomElement& layerElem, QDomDocument& doc ); | ||
|
|
||
| private: | ||
| QMap<QString, QgsEditorWidgetFactory*> mWidgetFactories; | ||
| static QgsEditorWidgetRegistry sInstance; | ||
| }; | ||
|
|
||
|
|
||
| #endif // QGSEDITORWIDGETREGISTRY_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetwrapper.cpp | ||
| -------------------------------------- | ||
| Date : 20.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 "qgseditorwidgetwrapper.h" | ||
|
|
||
| #include <QWidget> | ||
|
|
||
| QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) | ||
| : QObject( parent ) | ||
| , mWidget( editor ) | ||
| , mParent( parent ) | ||
| , mLayer( vl ) | ||
| { | ||
| mField = fieldIdx; | ||
| } | ||
|
|
||
| QWidget* QgsEditorWidgetWrapper::widget() | ||
| { | ||
| if ( !mWidget ) | ||
| { | ||
| mWidget = createWidget( mParent ); | ||
| mWidget->setProperty( "EWV2Wrapper", QVariant::fromValue( this ) ); | ||
| initWidget( mWidget ); | ||
| } | ||
|
|
||
| return mWidget; | ||
| } | ||
|
|
||
| void QgsEditorWidgetWrapper::setConfig( const QgsEditorWidgetConfig& config ) | ||
| { | ||
| mConfig = config; | ||
| // If an editor widget was supplied, we can initialize this now | ||
| if ( mWidget ) | ||
| { | ||
| mWidget->setProperty( "EWV2Wrapper", QVariant::fromValue( this ) ); | ||
| initWidget( mWidget ); | ||
| } | ||
| } | ||
|
|
||
| QVariant QgsEditorWidgetWrapper::config( QString key, QVariant defaultVal ) | ||
| { | ||
| if ( mConfig.contains( key ) ) | ||
| { | ||
| return mConfig[key]; | ||
| } | ||
| return defaultVal; | ||
| } | ||
|
|
||
| QgsVectorLayer* QgsEditorWidgetWrapper::layer() | ||
| { | ||
| return mLayer; | ||
| } | ||
|
|
||
| int QgsEditorWidgetWrapper::field() | ||
| { | ||
| return mField; | ||
| } | ||
|
|
||
| QgsEditorWidgetWrapper* QgsEditorWidgetWrapper::fromWidget( QWidget* widget ) | ||
| { | ||
| QVariant w = widget->property( "EWV2Wrapper" ); | ||
|
|
||
| if ( w.isNull() ) | ||
| { | ||
| return NULL; | ||
| } | ||
|
|
||
| return w.value<QgsEditorWidgetWrapper*>(); | ||
| } | ||
|
|
||
| void QgsEditorWidgetWrapper::initWidget( QWidget* editor ) | ||
| { | ||
| Q_UNUSED( editor ) | ||
| } | ||
|
|
||
| void QgsEditorWidgetWrapper::setEnabled( bool enabled ) | ||
| { | ||
| if ( mWidget ) | ||
| { | ||
| mWidget->setEnabled( enabled ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| /*************************************************************************** | ||
| qgseditorwidgetwrapper.h | ||
| -------------------------------------- | ||
| Date : 20.4.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 QGSEDITORWIDGETWRAPPER_H | ||
| #define QGSEDITORWIDGETWRAPPER_H | ||
|
|
||
| #include <QObject> | ||
| #include <QMap> | ||
| #include <QVariant> | ||
|
|
||
| class QgsVectorLayer; | ||
|
|
||
| #include "qgseditorwidgetconfig.h" | ||
|
|
||
| /** | ||
| * Manages an editor widget | ||
| * Widget and wrapper share the same parent | ||
| * | ||
| * A wrapper controls one attribute editor widget and is able to create a default | ||
| * widget or use a pre-existent widget. It is able to set the widget to the value implied | ||
| * by a field of a vector layer, or return the value it currently holds. Every time it is changed | ||
| * it has to emit a valueChanged signal (this does not yet mean, that the value is accepted). | ||
| * | ||
| */ | ||
| class GUI_EXPORT QgsEditorWidgetWrapper : public QObject | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| /** | ||
| * Create a new widget wrapper | ||
| * | ||
| * @param vl The layer on which the field is | ||
| * @param fieldIdx The field which will be controlled | ||
| * @param editor An editor widget. Can be NULL if one should be autogenerated. | ||
| * @param parent A parent widget for this widget wrapper and the created widget. | ||
| */ | ||
| explicit QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor = 0, QWidget* parent = 0 ); | ||
|
|
||
| /** | ||
| * Will be used to access the widget's value. Read the value from the widget and | ||
| * return it properly formatted to be saved in the attribute. | ||
| * | ||
| * @return The current value the widget represents | ||
| */ | ||
| virtual QVariant value() = 0; | ||
|
|
||
| /** | ||
| * @brief Access the widget managed by this wrapper | ||
| * | ||
| * @return The widget | ||
| */ | ||
| QWidget* widget(); | ||
|
|
||
| /** | ||
| * @brief Access the widget managed by this wrapper and cast it to a given type | ||
| * Example: QPushButton* pb = wrapper->widget<QPushButton*>(); | ||
| * | ||
| * @return The widget as template type or NULL, if it cannot be cast to this type. | ||
| */ | ||
| template <class T> | ||
| T* widget() { return dynamic_cast<T>( mWidget ); } | ||
|
|
||
| /** | ||
| * Will set the config of this wrapper to the specified config. | ||
| * | ||
| * @param config The config for this wrapper | ||
| */ | ||
| void setConfig( const QgsEditorWidgetConfig& config ); | ||
|
|
||
| /** | ||
| * Use this inside your overriden classes to access the configuration. | ||
| * | ||
| * @param key The configuration option you want to load | ||
| * @param defaultVal Default value | ||
| * | ||
| * @return the value assigned to this configuration option | ||
| */ | ||
| QVariant config( QString key, QVariant defaultVal = QVariant() ); | ||
|
|
||
| /** | ||
| * Returns the whole config | ||
| * | ||
| * @return The configuration | ||
| */ | ||
| const QgsEditorWidgetConfig config(); | ||
|
|
||
| /** | ||
| * Access the QgsVectorLayer, you are working on | ||
| * | ||
| * @return The layer | ||
| * | ||
| * @see field() | ||
| */ | ||
| QgsVectorLayer* layer(); | ||
|
|
||
| /** | ||
| * Access the field index. | ||
| * | ||
| * @return The index of the field you are working on | ||
| * | ||
| * @see layer() | ||
| */ | ||
| int field(); | ||
|
|
||
| /** | ||
| * Will return a wrapper for a given widget | ||
| * @param widget The widget which was created by a wrapper | ||
| * @return The wrapper for the widget or NULL | ||
| */ | ||
| static QgsEditorWidgetWrapper* fromWidget( QWidget* widget ); | ||
|
|
||
| protected: | ||
| /** | ||
| * This method should create a new widget with the provided parent. This will only be called | ||
| * if the form did not already provide a widget, so it is not guaranteed to be called! | ||
| * You should not do initialisation stuff, which also has to be done for custom editor | ||
| * widgets inside this method. Things like filling comboboxes and assigning other data which | ||
| * will also be used to make widgets on forms created in the QtDesigner usable should be assigned | ||
| * in {@link initWidget(QWidget*)}. | ||
| * | ||
| * @param parent You should set this parent on the created widget. | ||
| * @return A new widget | ||
| */ | ||
| virtual QWidget* createWidget( QWidget* parent ) = 0; | ||
|
|
||
| /** | ||
| * This method should initialize the editor widget with runtime data. Fill your comboboxes here. | ||
| * | ||
| * @param editor The widget which will represent this attribute editor in a form. | ||
| */ | ||
| virtual void initWidget( QWidget* editor ); | ||
|
|
||
| signals: | ||
| /** | ||
| * Emit this signal, whenever the value changed. | ||
| * | ||
| * @param value The new value | ||
| */ | ||
| void valueChanged( const QVariant& value ); | ||
|
|
||
| public slots: | ||
| /** | ||
| * Is called, when the value of the widget needs to be changed. Update the widget representation | ||
| * to reflect the new value. | ||
| * | ||
| * @param value The new value of the attribute | ||
| */ | ||
| virtual void setValue( const QVariant& value ) = 0; | ||
|
|
||
| /** | ||
| * Is used to enable or disable the edit functionality of the managed widget. | ||
| * By default this will enable or disable the whole widget | ||
| * | ||
| * @param enabled Enable or Disable? | ||
| */ | ||
| virtual void setEnabled( bool enabled ); | ||
|
|
||
| private: | ||
| QgsEditorWidgetConfig mConfig; | ||
| QWidget* mWidget; | ||
| QWidget* mParent; | ||
| QgsVectorLayer* mLayer; | ||
| int mField; | ||
| }; | ||
|
|
||
| // We'll use this class inside a QVariant in the widgets properties | ||
| Q_DECLARE_METATYPE( QgsEditorWidgetWrapper* ) | ||
|
|
||
| #endif // QGSEDITORWIDGETWRAPPER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /*************************************************************************** | ||
| qgsattributeeditorcontext.cpp | ||
| -------------------------------------- | ||
| Date : 30.7.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 "qgsattributeeditorcontext.h" | ||
|
|
||
| QgsAttributeEditorContext::QgsAttributeEditorContext() | ||
| { | ||
|
|
||
| } | ||
|
|
||
| QWidget*QgsAttributeEditorContext::proxyWidget( QgsVectorLayer* vl, int fieldIdx ) | ||
| { | ||
| return mProxyWidgets.value( vl ).value( fieldIdx ); | ||
| } | ||
|
|
||
| void QgsAttributeEditorContext::addProxyWidgets( QgsVectorLayer* vl, QMap<int, QWidget*> proxyWidgets ) | ||
| { | ||
| mProxyWidgets[ vl ].unite( proxyWidgets ); | ||
| } | ||
|
|
||
| void QgsAttributeEditorContext::addProxyWidget( QgsVectorLayer* vl, int idx, QWidget* widget ) | ||
| { | ||
| mProxyWidgets[ vl ].insert( idx, widget ); | ||
| } | ||
|
|
||
|
|
||
| void QgsAttributeEditorContext::adjustForLayer( QgsVectorLayer* layer ) | ||
| { | ||
| mDistanceArea.setSourceCrs( layer->crs() ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /*************************************************************************** | ||
| qgsattributeeditorcontext.h | ||
| -------------------------------------- | ||
| Date : 30.7.2013 | ||
| Copyright : (C) 2013 Matthias Kuhn | ||
| Email : matthias dot kuhn at gmx 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 QGSATTRIBUTEEDITORCONTEXT_H | ||
| #define QGSATTRIBUTEEDITORCONTEXT_H | ||
|
|
||
| #include <QMap> | ||
| #include <QWidget> | ||
|
|
||
| #include <qgsdistancearea.h> | ||
| #include <qgsvectorlayer.h> | ||
|
|
||
|
|
||
| /** | ||
| * This class contains context information for attribute editor widgets. | ||
| * It will be passed to embedded widgets whenever this occurs (e.g. when | ||
| * showing an embedded form due to relations) | ||
| */ | ||
|
|
||
| class GUI_EXPORT QgsAttributeEditorContext | ||
| { | ||
| public: | ||
| QgsAttributeEditorContext(); | ||
|
|
||
| QWidget* proxyWidget( QgsVectorLayer* vl, int fieldIdx ); | ||
| void addProxyWidgets( QgsVectorLayer* vl, QMap<int, QWidget*> proxyWidgets ); | ||
| void addProxyWidget( QgsVectorLayer* vl, int idx, QWidget* widget ); | ||
|
|
||
| void setDistanceArea( const QgsDistanceArea& distanceArea ) { mDistanceArea = distanceArea; } | ||
| inline const QgsDistanceArea& distanceArea() { return mDistanceArea; } | ||
|
|
||
| /** | ||
| * When copying the context for another layer, call this. | ||
| * Will adjast the distance area for this layer | ||
| * | ||
| * @param layer The layer to adjust for. | ||
| */ | ||
| void adjustForLayer( QgsVectorLayer* layer ); | ||
|
|
||
| private: | ||
| //! vectorlayer => ( fieldIdx, proxyWidget ) | ||
| QMap<QgsVectorLayer*, QMap<int, QWidget*> > mProxyWidgets; | ||
|
|
||
| QgsDistanceArea mDistanceArea; | ||
| }; | ||
|
|
||
| #endif // QGSATTRIBUTEEDITORCONTEXT_H |