QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgseditorwidgetregistry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgseditorwidgetregistry.cpp
3  --------------------------------------
4  Date : 24.4.2013
5  Copyright : (C) 2013 Matthias Kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
19 #include "qgsmessagelog.h"
20 #include "qgsproject.h"
21 #include "qgsvectorlayer.h"
22 #include "qgseditorwidgetwrapper.h"
23 #include "qgssearchwidgetwrapper.h"
24 #include "qgsapplication.h"
25 
26 // Editors
27 #include "qgsbinarywidgetfactory.h"
30 #include "qgscolorwidgetfactory.h"
31 #include "qgsdatetimeeditfactory.h"
34 #include "qgshiddenwidgetfactory.h"
37 #include "qgslistwidgetfactory.h"
38 #include "qgsrangewidgetfactory.h"
42 #include "qgsuuidwidgetfactory.h"
45 
47 {
48  mFallbackWidgetFactory.reset( new QgsTextEditWidgetFactory( tr( "Text Edit" ) ) );
49 }
50 
52 {
53  registerWidget( QStringLiteral( "TextEdit" ), new QgsTextEditWidgetFactory( tr( "Text Edit" ) ) );
54  registerWidget( QStringLiteral( "Classification" ), new QgsClassificationWidgetWrapperFactory( tr( "Classification" ) ) );
55  registerWidget( QStringLiteral( "Range" ), new QgsRangeWidgetFactory( tr( "Range" ) ) );
56  registerWidget( QStringLiteral( "UniqueValues" ), new QgsUniqueValueWidgetFactory( tr( "Unique Values" ) ) );
57  registerWidget( QStringLiteral( "ValueMap" ), new QgsValueMapWidgetFactory( tr( "Value Map" ) ) );
58  registerWidget( QStringLiteral( "Enumeration" ), new QgsEnumerationWidgetFactory( tr( "Enumeration" ) ) );
59  registerWidget( QStringLiteral( "Hidden" ), new QgsHiddenWidgetFactory( tr( "Hidden" ) ) );
60  registerWidget( QStringLiteral( "CheckBox" ), new QgsCheckboxWidgetFactory( tr( "Checkbox" ) ) );
61  registerWidget( QStringLiteral( "ValueRelation" ), new QgsValueRelationWidgetFactory( tr( "Value Relation" ) ) );
62  registerWidget( QStringLiteral( "UuidGenerator" ), new QgsUuidWidgetFactory( tr( "Uuid Generator" ) ) );
63  registerWidget( QStringLiteral( "Color" ), new QgsColorWidgetFactory( tr( "Color" ) ) );
64  registerWidget( QStringLiteral( "RelationReference" ), new QgsRelationReferenceFactory( tr( "Relation Reference" ), mapCanvas, messageBar ) );
65  registerWidget( QStringLiteral( "DateTime" ), new QgsDateTimeEditFactory( tr( "Date/Time" ) ) );
66  registerWidget( QStringLiteral( "ExternalResource" ), new QgsExternalResourceWidgetFactory( tr( "Attachment" ), messageBar ) );
67  registerWidget( QStringLiteral( "KeyValue" ), new QgsKeyValueWidgetFactory( tr( "Key/Value" ) ) );
68  registerWidget( QStringLiteral( "List" ), new QgsListWidgetFactory( tr( "List" ) ) );
69  registerWidget( QStringLiteral( "Binary" ), new QgsBinaryWidgetFactory( tr( "Binary (BLOB)" ), messageBar ) );
70  registerWidget( QStringLiteral( "JsonEdit" ), new QgsJsonEditWidgetFactory( tr( "Json View" ) ) );
71 }
72 
74 {
75  qDeleteAll( mWidgetFactories );
76 }
77 
78 QgsEditorWidgetSetup QgsEditorWidgetRegistry::findBest( const QgsVectorLayer *vl, const QString &fieldName ) const
79 {
80  const QgsFields fields = vl->fields();
81  const int index = fields.indexOf( fieldName );
82 
83  if ( index > -1 )
84  {
85  QgsEditorWidgetSetup setup = fields.at( index ).editorWidgetSetup();
86  if ( !setup.isNull() )
87  return setup;
88  }
89  return mAutoConf.editorWidgetSetup( vl, fieldName );
90 }
91 
92 QgsEditorWidgetWrapper *QgsEditorWidgetRegistry::create( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent, const QgsAttributeEditorContext &context )
93 {
94  const QString fieldName = vl->fields().field( fieldIdx ).name();
95  const QgsEditorWidgetSetup setup = findBest( vl, fieldName );
96  return create( setup.type(), vl, fieldIdx, setup.config(), editor, parent, context );
97 }
98 
99 QgsEditorWidgetWrapper *QgsEditorWidgetRegistry::create( const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *editor, QWidget *parent, const QgsAttributeEditorContext &context )
100 {
101  if ( mWidgetFactories.contains( widgetId ) )
102  {
103  QgsEditorWidgetWrapper *ww = mWidgetFactories[widgetId]->create( vl, fieldIdx, editor, parent );
104 
105  if ( ww )
106  {
107  ww->setConfig( config );
108  ww->setContext( context );
109  // Make sure that there is a widget created at this point
110  // so setValue() et al won't crash
111  ww->widget();
112 
113  // If we tried to set a widget which is not supported by this wrapper
114  if ( !ww->valid() )
115  {
116  delete ww;
117  const QString wid = findSuitableWrapper( editor, QStringLiteral( "TextEdit" ) );
118  ww = mWidgetFactories[wid]->create( vl, fieldIdx, editor, parent );
119  ww->setConfig( config );
120  ww->setContext( context );
121  }
122 
123  return ww;
124  }
125  }
126 
127  return nullptr;
128 }
129 
130 QgsSearchWidgetWrapper *QgsEditorWidgetRegistry::createSearchWidget( const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *parent, const QgsAttributeEditorContext &context )
131 {
132  if ( mWidgetFactories.contains( widgetId ) )
133  {
134  QgsSearchWidgetWrapper *ww = mWidgetFactories[widgetId]->createSearchWidget( vl, fieldIdx, parent );
135 
136  if ( ww )
137  {
138  ww->setConfig( config );
139  ww->setContext( context );
140  // Make sure that there is a widget created at this point
141  // so setValue() et al won't crash
142  ww->widget();
143  ww->clearWidget();
144  return ww;
145  }
146  }
147  return nullptr;
148 }
149 
150 QgsEditorConfigWidget *QgsEditorWidgetRegistry::createConfigWidget( const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, QWidget *parent )
151 {
152  if ( mWidgetFactories.contains( widgetId ) )
153  {
154  return mWidgetFactories[widgetId]->configWidget( vl, fieldIdx, parent );
155  }
156  return nullptr;
157 }
158 
159 QString QgsEditorWidgetRegistry::name( const QString &widgetId )
160 {
161  if ( mWidgetFactories.contains( widgetId ) )
162  {
163  return mWidgetFactories[widgetId]->name();
164  }
165 
166  return QString();
167 }
168 
169 QMap<QString, QgsEditorWidgetFactory *> QgsEditorWidgetRegistry::factories()
170 {
171  return mWidgetFactories;
172 }
173 
175 {
176  return mWidgetFactories.value( widgetId, mFallbackWidgetFactory.get() );
177 }
178 
179 bool QgsEditorWidgetRegistry::registerWidget( const QString &widgetId, QgsEditorWidgetFactory *widgetFactory )
180 {
181  if ( !widgetFactory )
182  {
183  QgsMessageLog::logMessage( tr( "QgsEditorWidgetRegistry: Factory not valid." ) );
184  return false;
185  }
186  else if ( mWidgetFactories.contains( widgetId ) )
187  {
188  QgsMessageLog::logMessage( tr( "QgsEditorWidgetRegistry: Factory with id %1 already registered." ).arg( widgetId ) );
189  return false;
190  }
191  else
192  {
193  mWidgetFactories.insert( widgetId, widgetFactory );
194 
195  // Use this factory as default where it provides the highest priority
196  const QHash<const char *, int> types = widgetFactory->supportedWidgetTypes();
197  QHash<const char *, int>::ConstIterator it;
198  it = types.constBegin();
199 
200  for ( ; it != types.constEnd(); ++it )
201  {
202  if ( it.value() > mFactoriesByType[it.key()].first )
203  {
204  mFactoriesByType[it.key()] = qMakePair( it.value(), widgetId );
205  }
206  }
207 
208  return true;
209  }
210 }
211 
212 QString QgsEditorWidgetRegistry::findSuitableWrapper( QWidget *editor, const QString &defaultWidget )
213 {
214  QMap<const char *, QPair<int, QString> >::ConstIterator it;
215 
216  QString widgetid;
217 
218  // Editor can be null
219  if ( editor )
220  {
221  int weight = 0;
222 
223  it = mFactoriesByType.constBegin();
224  for ( ; it != mFactoriesByType.constEnd(); ++it )
225  {
226  if ( QWidget::staticMetaObject.className() == it.key() )
227  {
228  // if it's a perfect match: return it directly
229  return it.value().second;
230  }
231  else if ( editor->inherits( it.key() ) )
232  {
233  // if it's a subclass, continue evaluating, maybe we find a more-specific or one with more weight
234  if ( it.value().first > weight )
235  {
236  weight = it.value().first;
237  widgetid = it.value().second;
238  }
239  }
240  }
241  }
242 
243  if ( widgetid.isNull() )
244  widgetid = defaultWidget;
245  return widgetid;
246 }
QgsJsonEditWidgetFactory
Editor widget factory for JSON edit widgets.
Definition: qgsjsoneditwidgetfactory.h:32
QgsSearchWidgetWrapper::clearWidget
virtual void clearWidget()
Clears the widget's current value and resets it back to the default state.
Definition: qgssearchwidgetwrapper.h:223
QgsUniqueValueWidgetFactory
Definition: qgsuniquevaluewidgetfactory.h:30
QgsEditorConfigWidget
This class should be subclassed for every configurable editor widget type.
Definition: qgseditorconfigwidget.h:38
qgseditorwidgetwrapper.h
qgslistwidgetfactory.h
QgsEditorWidgetFactory
Every attribute editor widget needs a factory, which inherits this class.
Definition: qgseditorwidgetfactory.h:42
QgsWidgetWrapper::valid
virtual bool valid() const =0
Returns true if the widget has been properly initialized.
QgsEditorWidgetSetup
Holder for the widget type and its configuration for a field.
Definition: qgseditorwidgetsetup.h:28
QgsEditorWidgetRegistry::registerWidget
bool registerWidget(const QString &widgetId, QgsEditorWidgetFactory *widgetFactory)
Register a new widget factory with the given id.
Definition: qgseditorwidgetregistry.cpp:179
QgsEditorWidgetRegistry::initEditors
void initEditors(QgsMapCanvas *mapCanvas=nullptr, QgsMessageBar *messageBar=nullptr)
Registers all the default widgets.
Definition: qgseditorwidgetregistry.cpp:51
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsEditorWidgetSetup::config
QVariantMap config() const
Definition: qgseditorwidgetsetup.h:64
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsSearchWidgetWrapper
Shows a search widget on a filter form.
Definition: qgssearchwidgetwrapper.h:85
QgsExternalResourceWidgetFactory
Definition: qgsexternalresourcewidgetfactory.h:33
qgsuuidwidgetfactory.h
qgsenumerationwidgetfactory.h
QgsEditorWidgetRegistry::factories
QMap< QString, QgsEditorWidgetFactory * > factories()
Gets access to all registered factories.
Definition: qgseditorwidgetregistry.cpp:169
qgshiddenwidgetfactory.h
QgsEditorWidgetRegistry::createConfigWidget
QgsEditorConfigWidget * createConfigWidget(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, QWidget *parent)
Creates a configuration widget.
Definition: qgseditorwidgetregistry.cpp:150
QgsField::name
QString name
Definition: qgsfield.h:60
QgsWidgetWrapper::widget
QWidget * widget()
Access the widget managed by this wrapper.
Definition: qgswidgetwrapper.cpp:47
QgsEditorWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgseditorwidgetwrapper.h:47
qgsapplication.h
qgsrelationreferencefactory.h
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3436
QgsEditorWidgetSetup::type
QString type() const
Definition: qgseditorwidgetsetup.h:59
QgsEditorWidgetRegistry::name
QString name(const QString &widgetId)
Gets the human readable name for a widget type.
Definition: qgseditorwidgetregistry.cpp:159
QgsEditorWidgetRegistry::createSearchWidget
QgsSearchWidgetWrapper * createSearchWidget(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Definition: qgseditorwidgetregistry.cpp:130
qgssearchwidgetwrapper.h
QgsUuidWidgetFactory
Definition: qgsuuidwidgetfactory.h:30
QgsWidgetWrapper::setConfig
void setConfig(const QVariantMap &config)
Will set the config of this wrapper to the specified config.
Definition: qgswidgetwrapper.cpp:62
QgsMessageBar
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:60
QgsEditorWidgetRegistry::findBest
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
Definition: qgseditorwidgetregistry.cpp:78
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsRelationReferenceFactory
Definition: qgsrelationreferencefactory.h:34
QgsTextEditWidgetFactory
Definition: qgstexteditwidgetfactory.h:30
qgsattributeeditorcontext.h
qgsdatetimeeditfactory.h
QgsEditorWidgetRegistry::factory
QgsEditorWidgetFactory * factory(const QString &widgetId)
Gets a factory for the given widget type id.
Definition: qgseditorwidgetregistry.cpp:174
QgsRangeWidgetFactory
Definition: qgsrangewidgetfactory.h:30
QgsListWidgetFactory
Factory for widgets for editing a QVariantList or a QStringList.
Definition: qgslistwidgetfactory.h:30
QgsEditorWidgetFactory::supportedWidgetTypes
virtual QHash< const char *, int > supportedWidgetTypes()
Returns a list of widget types which this editor widget supports.
Definition: qgseditorwidgetfactory.h:109
QgsFields::field
QgsField field(int fieldIdx) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:168
QgsEditorWidgetSetup::isNull
bool isNull() const
Definition: qgseditorwidgetsetup.h:69
QgsColorWidgetFactory
Definition: qgscolorwidgetfactory.h:30
QgsEnumerationWidgetFactory
Definition: qgsenumerationwidgetfactory.h:30
qgsvectorlayer.h
QgsClassificationWidgetWrapperFactory
Definition: qgsclassificationwidgetwrapperfactory.h:30
QgsEditorWidgetRegistry::QgsEditorWidgetRegistry
QgsEditorWidgetRegistry()
Constructor for QgsEditorWidgetRegistry.
Definition: qgseditorwidgetregistry.cpp:46
QgsEditorWidgetRegistry::create
QgsEditorWidgetWrapper * create(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QVariantMap &config, QWidget *editor, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Create an attribute editor widget wrapper of a given type for a given field.
Definition: qgseditorwidgetregistry.cpp:99
qgscheckboxwidgetfactory.h
qgseditorwidgetregistry.h
QgsValueMapWidgetFactory
Definition: qgsvaluemapwidgetfactory.h:30
qgsclassificationwidgetwrapperfactory.h
QgsValueRelationWidgetFactory
Definition: qgsvaluerelationwidgetfactory.h:32
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsEditorWidgetRegistry::~QgsEditorWidgetRegistry
~QgsEditorWidgetRegistry() override
Destructor.
Definition: qgseditorwidgetregistry.cpp:73
QgsHiddenWidgetFactory
Definition: qgshiddenwidgetfactory.h:30
qgsvaluerelationwidgetfactory.h
qgscolorwidgetfactory.h
qgstexteditwidgetfactory.h
qgsexternalresourcewidgetfactory.h
QgsDateTimeEditFactory
Definition: qgsdatetimeeditfactory.h:30
qgskeyvaluewidgetfactory.h
qgsvaluemapwidgetfactory.h
QgsField::editorWidgetSetup
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Definition: qgsfield.cpp:602
QgsFields::at
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
QgsAttributeEditorContext
This class contains context information for attribute editor widgets. It will be passed to embedded w...
Definition: qgsattributeeditorcontext.h:40
qgsjsoneditwidgetfactory.h
QgsWidgetWrapper::setContext
void setContext(const QgsAttributeEditorContext &context)
Set the context in which this widget is shown.
Definition: qgswidgetwrapper.cpp:67
qgsuniquevaluewidgetfactory.h
qgsproject.h
qgsrangewidgetfactory.h
QgsFields::indexOf
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
qgsmessagelog.h
qgsbinarywidgetfactory.h
QgsBinaryWidgetFactory
Editor widget factory for binary (BLOB) widgets.
Definition: qgsbinarywidgetfactory.h:34
QgsCheckboxWidgetFactory
Definition: qgscheckboxwidgetfactory.h:30
QgsKeyValueWidgetFactory
Factory for widgets for editing a QVariantMap.
Definition: qgskeyvaluewidgetfactory.h:30