Revert "Merge pull request #3338 from pvalsecc/editor_widgets_selection"

This reverts commit bbafbf48872eda48a2be8876cc89a0770552c6ad, reversing
changes made to 13ac0434e10fc7edd1eca665ea7c8b6cb5fd212d.
This commit is contained in:
Matthias Kuhn 2016-08-29 19:22:04 +02:00
parent b1448233e9
commit a529b448e7
61 changed files with 236 additions and 911 deletions

View File

@ -507,8 +507,6 @@ place of a null pointer.</li>
<ul>
<li>Does no longer inherit QObject
<li>widgetType() and widgetConfig() now reflect only the user configured values.
QgsEditorWidgetRegistry::instance()->findBest() must be used instead.</li>
</ul>
\subsection qgis_api_break_3_0_QgsExpression QgsExpression
@ -613,13 +611,6 @@ and the new ramp can be retrieved after executing the dialog by calling ramp().<
plugins calling this method will need to be updated.</li>
</ul>
\subsection qgis_api_break_3_0_QgsEditorWidgetRegistry QgsEditorWidgetRegistry
<ul>
<li>The signature of isFieldSupported() has been changed to return an unsigned (how good it supports the given field)
and to const-correct it.</li>
</ul>
\subsection qgis_api_break_3_0_QgsGroupWMSDataDialog QgsGroupWMSDataDialog
<ul>
@ -855,14 +846,6 @@ plugins calling this method will need to be updated.</li>
<ul>
<li>setMapRenderer() has been removed. Use setMapSettings() instead.</li>
<li>excludeAttributesWMS() and setExcludeAttributesWMS() have been renamed to excludeAttributesWms() and
setExcludeAttributesWms()</li>
<li>excludeAttributesWFS() and setExcludeAttributesWFS() have been renamed to excludeAttributesWfs() and
setExcludeAttributesWfs()</li>
<li>editorWidgetV2() and editorWidgetV2Config() have been removed and QgsEditorWidgetRegistry::instance()->findBest() must be used instead.</li>
<li>setEditorWidgetV2(), setEditorWidgetV2Config() have been removed and their equivalent in editFormConfig() must be used instead.</li>
<li>setCheckedState() is removed. Use editFormConfig()->setWidgetConfig()` instead.</li>
<li>valueMap(), valueRelation(), dateFormat(), widgetSize() have been removed. Use QgsEditorWidgetRegistry::instance()->findBest().config() instead.</li>
</ul>
\subsection qgis_api_break_3_0_QgsRenderContext QgsRenderContext

View File

@ -142,6 +142,15 @@ class QgsEditFormConfig
*/
void setWidgetType( int fieldIdx, const QString& widgetType );
/**
* Get the id for the editor widget used to represent the field at the given index
*
* @param fieldIdx The index of the field
*
* @return The id for the editor widget or a NULL string if not applicable
*/
QString widgetType( int fieldIdx ) const;
/**
* Get the id for the editor widget used to represent the field at the given index
*
@ -169,13 +178,39 @@ class QgsEditFormConfig
void setWidgetConfig( int attrIdx, const QgsEditorWidgetConfig& config );
/**
* Get the configuration for the editor widget used to represent the field with the given name
* Set the editor widget config for a widget.
*
* @param fieldName The name of the field.
* Example:
* \code{.py}
* layer.setWidgetConfig( 'relation_id', { 'nm-rel': 'other_relation' } )
* \endcode
*
* @param widgetName The name of the widget or field to configure
* @param config The config to set for this field
*
* @see setWidgetType() for a list of widgets and choose the widget to see the available options.
*
* @note not available in python bindings
*/
// void setWidgetConfig( const QString& widgetName, const QgsEditorWidgetConfig& config );
/**
* Get the configuration for the editor widget used to represent the field at the given index
*
* @param fieldIdx The index of the field
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*/
QgsEditorWidgetConfig widgetConfig( const QString& fieldName ) const;
QgsEditorWidgetConfig widgetConfig( int fieldIdx ) const;
/**
* Get the configuration for the editor widget used to represent the field with the given name
*
* @param widgetName The name of the widget. This can be a field name or the name of an additional widget.
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*/
QgsEditorWidgetConfig widgetConfig( const QString& widgetName ) const;
/**
* Remove the configuration for the editor widget used to represent the field at the given index
@ -189,11 +224,11 @@ class QgsEditFormConfig
/**
* Remove the configuration for the editor widget used to represent the field with the given name
*
* @param fieldName The name of the field.
* @param widgetName The name of the widget. This can be a field name or the name of an additional widget.
*
* @return true if successful, false if the field does not exist
*/
bool removeWidgetConfig( const QString& fieldName );
bool removeWidgetConfig( const QString& widgetName );
/**
* This returns true if the field is manually set to read only or if the field
@ -337,9 +372,4 @@ class QgsEditFormConfig
* Deserialize drag and drop designer elements.
*/
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement* parent );
/**
* Parse the XML for the config of one editor widget.
*/
static QgsEditorWidgetConfig parseEditorWidgetConfig( const QDomElement& cfgElem );
};

View File

@ -1,35 +1,3 @@
/** \ingroup core
* Holder for the widget type and its configuration for a field.
*/
class QgsEditorWidgetSetup
{
%TypeHeaderCode
#include <qgsfield.h>
%End
public:
/**
* Constructor
*/
QgsEditorWidgetSetup( const QString& type, const QgsEditorWidgetConfig& config );
QgsEditorWidgetSetup();
/**
* @return the widget type to use
*/
QString type() const;
/**
* @return the widget configuration to used
*/
QgsEditorWidgetConfig config() const;
/**
* @return true if there is no widget configured.
*/
bool isNull() const;
};
/** \class QgsField
* \ingroup core
* Encapsulate a field in an attribute table or data source.
@ -211,19 +179,6 @@ class QgsField
//! Allows direct construction of QVariants from fields.
operator QVariant() const;
/**
* Set the editor widget setup for the field.
*
* @param v The value to set
*/
void setEditorWidgetSetup( const QgsEditorWidgetSetup& v );
/**
* Get the editor widget setup for the field.
*
* @return the value
*/
const QgsEditorWidgetSetup& editorWidgetSetup() const;
}; // class QgsField

View File

@ -1,41 +0,0 @@
/***************************************************************************
qgseditorwidgetautoconf.sip
---------------------
begin : July 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick.valsecchi at camptocamp.com
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/**
* Base class for plugins allowing to pick automatically a widget type for editing fields.
*
* @note added in QGIS 3.0
*/
class QgsEditorWidgetAutoConfPlugin
{
%TypeHeaderCode
#include <qgseditorwidgetautoconf.h>
%End
public:
/**
* Typical scores are:
* * 0: no matching type found.
* * 10: a widget has been guessed from the type of field.
* * 20: a widget has been determined from an external configuration (for example a database table)
*
* @param vl The vector layer for which this widget will be created
* @param fieldName The field name on the specified layer for which this widget will be created
* @param score Where the score is returned (default to 0)
*
* @return and integer value rating how good is the setup provided by this plugin.
*/
virtual QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName, int& score /Out/ ) const = 0;
};

View File

@ -170,23 +170,17 @@ class QgsEditorWidgetFactory
*/
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
private:
/**
* This method allows disabling this editor widget type for a certain field.
* By default, it returns 5 for every fields.
* By default, it returns true for all fields.
* Reimplement this if you only support certain fields.
*
* Typical return values are:
* * 0: not supported
* * 5: maybe support (for example, Datetime support strings depending on their content)
* * 10: basic support (this is what returns TextEdit for example, since it supports everything in a crude way)
* * 20: specialised support
*
* @param vl
* @param fieldIdx
* @return 0 if the field is not supported or a bigger number if it can (the widget with the biggest number will be
* taken by default). The default implementation returns 5..
* @return True if the field is supported.
*
* @see supportsField( QgsVectorLayer* vl, fieldIdx )
*/
virtual unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const;
virtual bool isFieldSupported( QgsVectorLayer* vl, int fieldIdx );
};

View File

@ -13,7 +13,6 @@
* *
***************************************************************************/
/**
* This class manages all known edit widget factories
*/
@ -44,17 +43,6 @@ class QgsEditorWidgetRegistry : QObject
*/
static void initEditors( QgsMapCanvas* mapCanvas = 0, QgsMessageBar* messageBar = 0 );
/**
* Find the best editor widget and its configuration for a given field.
*
* @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
*
* @return The id of the widget type to use and its config
*/
QgsEditorWidgetSetup findBest( const QgsVectorLayer* vl, const QString& fieldName ) const;
/**
* 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.
@ -128,11 +116,4 @@ class QgsEditorWidgetRegistry : QObject
* @return true, if successful, false, if the widgetId is already in use or widgetFactory is NULL
*/
bool registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory /Transfer/ );
/**
* Register a new auto-conf plugin.
*
* @param plugin The plugin (ownership is transfered)
*/
void registerAutoConfPlugin( QgsEditorWidgetAutoConfPlugin* plugin );
};

View File

@ -258,7 +258,6 @@
%Include effects/qgspainteffectwidget.sip
%Include editorwidgets/core/qgseditorconfigwidget.sip
%Include editorwidgets/core/qgseditorwidgetautoconf.sip
%Include editorwidgets/core/qgseditorwidgetfactory.sip
%Include editorwidgets/core/qgseditorwidgetregistry.sip
%Include editorwidgets/core/qgseditorwidgetwrapper.sip

View File

@ -249,9 +249,8 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
bool foundFieldThatCanBeExportedAsDisplayedValue = false;
for ( int i = 0; i < mLayer->fields().size(); ++i )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, mLayer->fields()[i].name() );
if ( setup.type() != "TextEdit" &&
QgsEditorWidgetRegistry::instance()->factory( setup.type() ) )
if ( mLayer->editFormConfig().widgetType( i ) != "TextEdit" &&
QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig().widgetType( i ) ) )
{
foundFieldThatCanBeExportedAsDisplayedValue = true;
break;
@ -286,11 +285,10 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
if ( foundFieldThatCanBeExportedAsDisplayedValue )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, mLayer->fields()[i].name() );
QgsEditorWidgetFactory *factory = nullptr;
if ( flags == Qt::ItemIsEnabled &&
setup.type() != "TextEdit" &&
( factory = QgsEditorWidgetRegistry::instance()->factory( setup.type() ) ) )
mLayer->editFormConfig().widgetType( i ) != "TextEdit" &&
( factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig().widgetType( i ) ) ) )
{
item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
item->setFlags(( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );

View File

@ -6149,11 +6149,11 @@ QVariant QgisAppFieldValueConverter::convert( int idx, const QVariant& value )
{
return value;
}
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, mLayer->fields().field( idx ).name() );
QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( setup.type() );
QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig().widgetType( idx ) );
if ( factory )
{
return QVariant( factory->representValue( mLayer, idx, setup.config(), QVariant(), value ) );
QgsEditorWidgetConfig cfg( mLayer->editFormConfig().widgetConfig( idx ) );
return QVariant( factory->representValue( mLayer, idx, cfg, QVariant(), value ) );
}
return value;
}

View File

@ -391,7 +391,7 @@ void QgsAttributeTableDialog::columnBoxInit()
if ( idx < 0 )
continue;
if ( QgsEditorWidgetRegistry::instance()->findBest( mLayer, field.name() ).type() != "Hidden" )
if ( mLayer->editFormConfig().widgetType( idx ) != "Hidden" )
{
QIcon icon = mLayer->fields().iconForField( idx );
QString alias = mLayer->attributeDisplayName( idx );
@ -527,9 +527,10 @@ void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
int fldIdx = mLayer->fieldNameIndex( fieldName );
if ( fldIdx < 0 )
return;
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, fieldName );
const QString widgetType = mLayer->editFormConfig().widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( fldIdx );
mCurrentSearchWidgetWrapper = QgsEditorWidgetRegistry::instance()->
createSearchWidget( setup.type(), mLayer, fldIdx, setup.config(), mFilterContainer, mEditorContext );
createSearchWidget( widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer, mEditorContext );
if ( mCurrentSearchWidgetWrapper->applyDirectly() )
{
connect( mCurrentSearchWidgetWrapper, SIGNAL( expressionChanged( QString ) ), SLOT( filterQueryChanged( QString ) ) );

View File

@ -392,9 +392,9 @@ void QgsFieldsProperties::loadRelations()
if ( nmrel.fieldPairs().at( 0 ).referencingField() != relation.fieldPairs().at( 0 ).referencingField() )
nmCombo->addItem( QString( "%1 (%2)" ).arg( nmrel.referencedLayer()->name(), nmrel.fieldPairs().at( 0 ).referencedField() ), nmrel.id() );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, relation.id() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( relation.id() );
const QVariant nmrelcfg = setup.config().value( "nm-rel" );
QVariant nmrelcfg = cfg.value( "nm-rel" );
int idx = nmCombo->findData( nmrelcfg.toString() );
@ -1028,9 +1028,8 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
mNotNull = layer->editFormConfig().notNull( idx );
mConstraint = layer->editFormConfig().expression( idx );
mConstraintDescription = layer->editFormConfig().expressionDescription( idx );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( layer, layer->fields().field( idx ).name() );
mEditorWidgetType = setup.type();
mEditorWidgetConfig = setup.config();
mEditorWidgetType = layer->editFormConfig().widgetType( idx );
mEditorWidgetConfig = layer->editFormConfig().widgetConfig( idx );
}
/*

View File

@ -479,8 +479,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
if ( i >= fields.count() )
break;
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( vlayer, fields[i].name() );
if ( setup.type() == "Hidden" )
if ( vlayer->editFormConfig().widgetType( i ) == "Hidden" )
{
continue;
}
@ -499,7 +498,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
attrItem->setData( 1, Qt::UserRole, value );
value = representValue( vlayer, setup, fields.at( i ).name(), attrs.at( i ) );
value = representValue( vlayer, fields.at( i ).name(), attrs.at( i ) );
attrItem->setSortData( 1, value );
bool foundLinks = false;
QString links = QgsStringUtils::insertLinks( value, &foundLinks );
@ -544,8 +543,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
continue;
QString value = fields.at( i ).displayString( attrs.at( i ) );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( vlayer, fields.at( i ).name() );
QString value2 = representValue( vlayer, setup, fields.at( i ).name(), value );
QString value2 = representValue( vlayer, fields.at( i ).name(), value );
tblResults->setRowCount( j + 1 );
@ -666,12 +664,13 @@ QgsIdentifyPlotCurve::~QgsIdentifyPlotCurve()
}
}
QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const QgsEditorWidgetSetup& setup, const QString& fieldName, const QVariant& value )
QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const QString& fieldName, const QVariant& value )
{
QVariant cache;
QMap<QString, QVariant>& layerCaches = mWidgetCaches[vlayer->id()];
QgsEditorWidgetFactory* factory = QgsEditorWidgetRegistry::instance()->factory( setup.type() );
QString widgetType = vlayer->editFormConfig().widgetType( fieldName );
QgsEditorWidgetFactory* factory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
int idx = vlayer->fieldNameIndex( fieldName );
@ -684,11 +683,11 @@ QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const
}
else
{
cache = factory->createCache( vlayer, idx, setup.config() );
cache = factory->createCache( vlayer, idx, vlayer->editFormConfig().widgetConfig( fieldName ) );
layerCaches.insert( fieldName, cache );
}
return factory->representValue( vlayer, idx, setup.config(), cache, value );
return factory->representValue( vlayer, idx, vlayer->editFormConfig().widgetConfig( fieldName ), cache, value );
}
void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,
@ -1503,8 +1502,7 @@ void QgsIdentifyResultsDialog::attributeValueChanged( QgsFeatureId fid, int idx,
if ( item->data( 0, Qt::UserRole + 1 ).toInt() == idx )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( vlayer, fld.name() );
value = representValue( vlayer, setup, fld.name(), val );
value = representValue( vlayer, fld.name(), val );
QgsTreeWidgetItem* treeItem = static_cast< QgsTreeWidgetItem* >( item );
treeItem->setSortData( 1, value );

View File

@ -41,7 +41,6 @@ class QgsHighlight;
class QgsMapCanvas;
class QgsDockWidget;
class QgsMapLayerAction;
class QgsEditorWidgetSetup;
class QwtPlotCurve;
@ -218,7 +217,7 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
void mapLayerActionDestroyed();
private:
QString representValue( QgsVectorLayer* vlayer, const QgsEditorWidgetSetup& setup, const QString& fieldName, const QVariant& value );
QString representValue( QgsVectorLayer* vlayer, const QString& fieldName, const QVariant& value );
enum ItemDataRole
{

View File

@ -27,7 +27,6 @@
#include "qgsvectordataprovider.h"
#include "qgsattributeeditor.h"
#include "qgsstatisticalsummary.h"
#include "qgseditorwidgetregistry.h"
#include <limits>
#include <QComboBox>
@ -117,8 +116,8 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
mHiddenAttributes.clear();
for ( int idx = 0; idx < mFields.count(); ++idx )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mVectorLayer, mFields.at( idx ).name() );
if ( setup.type() == "Hidden" || setup.type() == "Immutable" )
if ( mVectorLayer->editFormConfig().widgetType( idx ) == "Hidden" ||
mVectorLayer->editFormConfig().widgetType( idx ) == "Immutable" )
{
mHiddenAttributes.insert( idx );
continue;
@ -126,7 +125,7 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
mTableWidget->setColumnCount( col + 1 );
QComboBox *cb = createMergeComboBox( mFields.at( idx ).type() );
QComboBox *cb = createMergeComboBox( mFields.at( idx ) .type() );
if ( pkAttrList.contains( idx ) )
{
cb->setCurrentIndex( cb->findData( "skip" ) );

View File

@ -16,7 +16,6 @@
#include "qgseditformconfig.h"
#include "qgsproject.h"
#include "qgsrelationmanager.h"
//#include "qgseditorwidgetregistry.h"
QgsAttributeEditorContainer::~QgsAttributeEditorContainer()
{
@ -28,14 +27,30 @@ QgsEditFormConfig::QgsEditFormConfig()
{
}
QString QgsEditFormConfig::widgetType( const QString& fieldName ) const
QString QgsEditFormConfig::widgetType( int fieldIdx ) const
{
return d->mEditorWidgetTypes.value( fieldName );
if ( fieldIdx < 0 || fieldIdx >= d->mFields.count() )
return "TextEdit";
return d->mEditorWidgetTypes.value( d->mFields.at( fieldIdx ).name(), "TextEdit" );
}
QgsEditorWidgetConfig QgsEditFormConfig::widgetConfig( const QString& fieldName ) const
QString QgsEditFormConfig::widgetType( const QString& fieldName ) const
{
return d->mWidgetConfigs.value( fieldName );
return d->mEditorWidgetTypes.value( fieldName, "TextEdit" );
}
QgsEditorWidgetConfig QgsEditFormConfig::widgetConfig( int fieldIdx ) const
{
if ( fieldIdx < 0 || fieldIdx >= d->mFields.count() )
return QgsEditorWidgetConfig();
return d->mWidgetConfigs.value( d->mFields.at( fieldIdx ).name() );
}
QgsEditorWidgetConfig QgsEditFormConfig::widgetConfig( const QString& widgetName ) const
{
return d->mWidgetConfigs.value( widgetName );
}
void QgsEditFormConfig::setFields( const QgsFields& fields, const QMap<QString, QString>& attributeAliasMap )
@ -428,40 +443,38 @@ void QgsEditFormConfig::readXml( const QDomNode& node )
}
//// TODO: MAKE THIS MORE GENERIC, SO INDIVIDUALL WIDGETS CAN NOT ONLY SAVE STRINGS
/// SEE QgsEditorWidgetFactory::writeConfig
QDomElement widgetsElem = node.namedItem( "widgets" ).toElement();
QDomNodeList widgetConfigsElems = widgetsElem.childNodes();
for ( int i = 0; i < widgetConfigsElems.size(); ++i )
{
const QDomElement wdgElem = widgetConfigsElems.at( i ).toElement();
const QDomElement cfgElem = wdgElem.namedItem( "config" ).toElement();
const QgsEditorWidgetConfig widgetConfig = parseEditorWidgetConfig( cfgElem );
setWidgetConfig( wdgElem.attribute( "name" ), widgetConfig );
}
}
QgsEditorWidgetConfig cfg;
QgsEditorWidgetConfig QgsEditFormConfig::parseEditorWidgetConfig( const QDomElement& cfgElem )
{
QgsEditorWidgetConfig cfg;
//// TODO: MAKE THIS MORE GENERIC, SO INDIVIDUALL WIDGETS CAN NOT ONLY SAVE STRINGS
/// SEE QgsEditorWidgetFactory::writeConfig
for ( int j = 0; j < cfgElem.attributes().size(); ++j )
{
const QDomAttr attr = cfgElem.attributes().item( j ).toAttr();
cfg.insert( attr.name(), attr.value() );
}
QDomElement wdgElem = widgetConfigsElems.at( i ).toElement();
const QDomNodeList optionElements = cfgElem.elementsByTagName( "option" );
for ( int j = 0; j < optionElements.size(); ++j )
{
const QDomElement option = optionElements.at( j ).toElement();
const QString key = option.attribute( "key" );
const QString value = option.attribute( "value" );
cfg.insert( key, value );
QDomElement cfgElem = wdgElem.namedItem( "config" ).toElement();
for ( int j = 0; j < cfgElem.attributes().size(); ++j )
{
QDomAttr attr = cfgElem.attributes().item( j ).toAttr();
cfg.insert( attr.name(), attr.value() );
}
QDomNodeList optionElements = cfgElem.elementsByTagName( "option" );
for ( int j = 0; j < optionElements.size(); ++j )
{
QString key = optionElements.at( j ).toElement().attribute( "key" );
QString value = optionElements.at( j ).toElement().attribute( "value" );
cfg.insert( key, value );
}
setWidgetConfig( wdgElem.attribute( "name" ), cfg );
}
//// END TODO
return cfg;
}
void QgsEditFormConfig::writeXml( QDomNode& node ) const

View File

@ -177,7 +177,15 @@ class CORE_EXPORT QgsEditFormConfig
/**
* Get the id for the editor widget used to represent the field at the given index
* Don't use this directly. Prefere the use of QgsEditorWidgetRegistry::instance()->findBestType.
*
* @param fieldIdx The index of the field
*
* @return The id for the editor widget or a NULL string if not applicable
*/
QString widgetType( int fieldIdx ) const;
/**
* Get the id for the editor widget used to represent the field at the given index
*
* @param fieldName The name of the field
*
@ -210,24 +218,32 @@ class CORE_EXPORT QgsEditFormConfig
* layer.setWidgetConfig( 'relation_id', { 'nm-rel': 'other_relation' } )
* \endcode
*
* @param fieldName The name of the field to configure
* @param widgetName The name of the widget or field to configure
* @param config The config to set for this field
*
* @see setWidgetType() for a list of widgets and choose the widget to see the available options.
*
* @note not available in python bindings
*/
void setWidgetConfig( const QString& fieldName, const QgsEditorWidgetConfig& config );
void setWidgetConfig( const QString& widgetName, const QgsEditorWidgetConfig& config );
/**
* Get the configuration for the editor widget used to represent the field with the given name
* Don't use this directly. Prefere the use of QgsEditorWidgetRegistry::instance()->findBestConfig.
* Get the configuration for the editor widget used to represent the field at the given index
*
* @param fieldName The name of the field.
* @param fieldIdx The index of the field
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*/
QgsEditorWidgetConfig widgetConfig( const QString& fieldName ) const;
QgsEditorWidgetConfig widgetConfig( int fieldIdx ) const;
/**
* Get the configuration for the editor widget used to represent the field with the given name
*
* @param widgetName The name of the widget. This can be a field name or the name of an additional widget.
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*/
QgsEditorWidgetConfig widgetConfig( const QString& widgetName ) const;
/**
* Remove the configuration for the editor widget used to represent the field at the given index
@ -241,11 +257,11 @@ class CORE_EXPORT QgsEditFormConfig
/**
* Remove the configuration for the editor widget used to represent the field with the given name
*
* @param fieldName The name of the widget.
* @param widgetName The name of the widget. This can be a field name or the name of an additional widget.
*
* @return true if successful, false if the field does not exist
*/
bool removeWidgetConfig( const QString& fieldName );
bool removeWidgetConfig( const QString& widgetName );
/**
* This returns true if the field is manually set to read only or if the field
@ -395,11 +411,6 @@ class CORE_EXPORT QgsEditFormConfig
*/
explicit QgsEditFormConfig();
/**
* Parse the XML for the config of one editor widget.
*/
static QgsEditorWidgetConfig parseEditorWidgetConfig( const QDomElement& cfgElem );
private:
/**

View File

@ -238,16 +238,6 @@ bool QgsField::convertCompatible( QVariant& v ) const
return true;
}
void QgsField::setEditorWidgetSetup( const QgsEditorWidgetSetup& v )
{
d->editorWidgetSetup = v;
}
const QgsEditorWidgetSetup& QgsField::editorWidgetSetup() const
{
return d->editorWidgetSetup;
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfield.cpp.

View File

@ -33,42 +33,6 @@ class QgsFieldsPrivate;
* See details in QEP #17
****************************************************************************/
#include "qgseditorwidgetconfig.h"
/** \ingroup core
* Holder for the widget type and its configuration for a field.
*
* @note added in QGIS 3.0
*/
class GUI_EXPORT QgsEditorWidgetSetup
{
public:
/**
* Constructor
*/
QgsEditorWidgetSetup( const QString& type, const QgsEditorWidgetConfig& config ) : mType( type ), mConfig( config ) {}
QgsEditorWidgetSetup() {}
/**
* @return the widget type to use
*/
QString type() const { return mType; }
/**
* @return the widget configuration to used
*/
QgsEditorWidgetConfig config() const { return mConfig; }
/**
* @return true if there is no widget configured.
*/
bool isNull() const { return mType.isEmpty(); }
private:
QString mType;
QgsEditorWidgetConfig mConfig;
};
/** \class QgsField
* \ingroup core
* Encapsulate a field in an attribute table or data source.
@ -211,20 +175,6 @@ class CORE_EXPORT QgsField
return QVariant::fromValue( *this );
}
/**
* Set the editor widget setup for the field.
*
* @param v The value to set
*/
void setEditorWidgetSetup( const QgsEditorWidgetSetup& v );
/**
* Get the editor widget setup for the field.
*
* @return the value
*/
const QgsEditorWidgetSetup& editorWidgetSetup() const;
private:
QSharedDataPointer<QgsFieldPrivate> d;

View File

@ -93,8 +93,6 @@ class QgsFieldPrivate : public QSharedData
//! Comment
QString comment;
QgsEditorWidgetSetup editorWidgetSetup;
};

View File

@ -344,7 +344,7 @@ QgsVectorLayerUndoCommandDeleteAttribute::QgsVectorLayerUndoCommandDeleteAttribu
QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex );
mOriginIndex = fields.fieldOriginIndex( mFieldIndex );
mProviderField = ( origin == QgsFields::OriginProvider );
mOldEditorWidgetConfig = mBuffer->L->editFormConfig().widgetConfig( fields.field( mFieldIndex ).name() );
mOldEditorWidgetConfig = mBuffer->L->editFormConfig().widgetConfig( mFieldIndex );
if ( !mProviderField )
{

View File

@ -84,7 +84,6 @@ SET(QGIS_GUI_SRCS
auth/qgsauthtrustedcasdialog.cpp
editorwidgets/core/qgseditorconfigwidget.cpp
editorwidgets/core/qgseditorwidgetautoconf.cpp
editorwidgets/core/qgseditorwidgetfactory.cpp
editorwidgets/core/qgseditorwidgetregistry.cpp
editorwidgets/core/qgseditorwidgetwrapper.cpp

View File

@ -67,8 +67,10 @@ QWidget* QgsAttributeTableDelegate::createEditor( QWidget *parent, const QStyleO
int fieldIdx = index.model()->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
QString widgetType = vl->editFormConfig().widgetType( fieldIdx );
QgsEditorWidgetConfig cfg = vl->editFormConfig().widgetConfig( fieldIdx );
QgsAttributeEditorContext context( masterModel( index.model() )->editorContext(), QgsAttributeEditorContext::Popup );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( vl, fieldIdx, nullptr, parent, context );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, fieldIdx, cfg, nullptr, parent, context );
QWidget* w = eww->widget();
w->setAutoFillBackground( true );

View File

@ -339,13 +339,13 @@ void QgsAttributeTableModel::loadAttributes()
for ( int idx = 0; idx < fields.count(); ++idx )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( layer(), fields[idx].name() );
QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( setup.type() );
const QString widgetType = layer()->editFormConfig().widgetType( idx );
QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
if ( widgetFactory )
{
mWidgetFactories.append( widgetFactory );
mWidgetConfigs.append( setup.config() );
mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, setup.config() ) );
mWidgetConfigs.append( layer()->editFormConfig().widgetConfig( idx ) );
mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );
attributes << idx;
}

View File

@ -26,7 +26,6 @@
#include "qgsvectordataprovider.h"
#include "qgsvectorlayercache.h"
#include "qgsorganizetablecolumnsdialog.h"
#include "qgseditorwidgetregistry.h"
#include <QClipboard>
#include <QDialog>
@ -142,7 +141,7 @@ void QgsDualView::columnBoxInit()
if ( fieldIndex == -1 )
continue;
if ( QgsEditorWidgetRegistry::instance()->findBest( mLayerCache->layer(), field.name() ).type() != "Hidden" )
if ( mLayerCache->layer()->editFormConfig().widgetType( fieldIndex ) != "Hidden" )
{
QIcon icon = mLayerCache->layer()->fields().iconForField( fieldIndex );
QString text = field.name();

View File

@ -1,112 +0,0 @@
/***************************************************************************
qgseditorwidgetautoconf.cpp
---------------------
begin : July 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick.valsecchi at camptocamp.com
***************************************************************************
* *
* 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 "qgseditorwidgetautoconf.h"
#include "qgseditorwidgetregistry.h"
/** \ingroup gui
* Widget auto conf plugin that guesses what widget type to use in function of what the widgets support.
*
* @note not available in Python bindings
* @note added in QGIS 3.0
*/
class FromFactoriesPlugin: public QgsEditorWidgetAutoConfPlugin
{
public:
virtual QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName, int& score ) const override
{
int bestScore = 0;
QString bestType;
const QMap<QString, QgsEditorWidgetFactory*> factories = QgsEditorWidgetRegistry::instance()->factories();
for ( QMap<QString, QgsEditorWidgetFactory*>::const_iterator i = factories.begin(); i != factories.end(); ++i )
{
const int index = vl->fieldNameIndex( fieldName );
if ( index >= 0 )
{
const int score = i.value()->fieldScore( vl, index );
if ( score > bestScore )
{
bestType = i.key();
bestScore = score;
}
}
}
if ( bestScore > 0 )
{
score = 10;
return QgsEditorWidgetSetup( bestType, QgsEditorWidgetConfig() );
}
return QgsEditorWidgetSetup();
}
};
/** \ingroup gui
* Widget auto conf plugin that reads the widget setup to use from what the data provider says.
*
* @note not available in Python bindings
* @note added in QGIS 3.0
*/
class FromDbTablePlugin: public QgsEditorWidgetAutoConfPlugin
{
public:
virtual QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName, int& score ) const override
{
QgsField field = vl->fields().field( fieldName );
if ( !field.editorWidgetSetup().isNull() )
{
score = 20;
return field.editorWidgetSetup();
}
else
{
return QgsEditorWidgetSetup();
}
}
};
///@cond PRIVATE
QgsEditorWidgetAutoConf::QgsEditorWidgetAutoConf()
{
registerPlugin( new FromFactoriesPlugin() );
registerPlugin( new FromDbTablePlugin() );
}
QgsEditorWidgetSetup QgsEditorWidgetAutoConf::editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName ) const
{
QgsEditorWidgetSetup result( "TextEdit", QgsEditorWidgetConfig() );
if ( vl->fields().indexFromName( fieldName ) >= 0 )
{
int bestScore = 0;
Q_FOREACH ( QSharedPointer<QgsEditorWidgetAutoConfPlugin> cur, plugins )
{
int score = 0;
const QgsEditorWidgetSetup curResult = cur->editorWidgetSetup( vl, fieldName, score );
if ( score > bestScore )
{
result = curResult;
bestScore = score;
}
}
}
return result;
}
void QgsEditorWidgetAutoConf::registerPlugin( QgsEditorWidgetAutoConfPlugin* plugin )
{
plugins.append( QSharedPointer<QgsEditorWidgetAutoConfPlugin>( plugin ) );
}
///@endcond

View File

@ -1,88 +0,0 @@
/***************************************************************************
qgseditorwidgetautoconf.h
---------------------
begin : July 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick.valsecchi at camptocamp.com
***************************************************************************
* *
* 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 QGSEDITORWIDGETAUTOCONF_H
#define QGSEDITORWIDGETAUTOCONF_H
#include <QList>
#include <QSharedPointer>
class QgsVectorLayer;
class QgsEditorWidgetSetup;
/** \ingroup gui
* Base class for plugins allowing to pick automatically a widget type for editing fields.
*
* @note added in QGIS 3.0
*/
class GUI_EXPORT QgsEditorWidgetAutoConfPlugin
{
public:
/**
* Typical scores are:
* * 0: no matching type found.
* * 10: a widget has been guessed from the type of field.
* * 20: a widget has been determined from an external configuration (for example a database table)
*
* @param vl The vector layer for which this widget will be created
* @param fieldName The field name on the specified layer for which this widget will be created
* @param score Where the score is returned (default to 0)
*
* @return and integer value rating how good is the setup provided by this plugin.
*/
virtual QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName, int& score ) const = 0;
};
///@cond PRIVATE
/** \ingroup gui
* Class that allows to register plugins to pick automatically a widget type for editing fields.
* This class has only one instance, owned by the QgsEditorWidgetRegistry singleton
*
* The plugins are instances of QgsEditorWidgetAutoConfPlugin.
* @note added in QGIS 3.0
* @note not available in Python bindings
*/
class GUI_EXPORT QgsEditorWidgetAutoConf
{
public:
/**
* Register the default plugins.
*/
QgsEditorWidgetAutoConf();
/**
* Iterate over the plugins and return the setup of the plugin returning the highest score.
*
* @param vl The vector layer for which this widget will be created
* @param fieldName The field name on the specified layer for which this widget will be created
*
* @return The best widget setup that was found
*/
QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName ) const;
/**
* Register a new plugin.
*
* @param plugin The plugin (ownership is transfered)
*/
void registerPlugin( QgsEditorWidgetAutoConfPlugin* plugin );
private:
QList<QSharedPointer<QgsEditorWidgetAutoConfPlugin> > plugins;
};
///@endcond
#endif // QGSEDITORWIDGETAUTOCONF_H

View File

@ -116,10 +116,10 @@ QgsEditorWidgetConfig QgsEditorWidgetFactory::readConfig( const QDomElement& con
return QgsEditorWidgetConfig();
}
unsigned int QgsEditorWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
bool QgsEditorWidgetFactory::isFieldSupported( QgsVectorLayer* vl, int fieldIdx )
{
Q_UNUSED( vl )
Q_UNUSED( fieldIdx )
return 5;
return true;
}

View File

@ -113,9 +113,9 @@ class GUI_EXPORT QgsEditorWidgetFactory
* @param fieldIdx The field index
* @return True if the type is supported for this field
*
* @see fieldScore( const QgsVectorLayer* vl, ind fieldIdx )
* @see isFieldSupported( QgsVectorLayer* vl, ind fieldIdx )
*/
inline bool supportsField( const QgsVectorLayer* vl, int fieldIdx ) { return fieldScore( vl, fieldIdx ) > 0; }
inline bool supportsField( QgsVectorLayer* vl, int fieldIdx ) { return isFieldSupported( vl, fieldIdx ); }
/**
* Returns a list of widget types which this editor widget supports.
@ -187,25 +187,19 @@ class GUI_EXPORT QgsEditorWidgetFactory
*/
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
private:
/**
* This method allows disabling this editor widget type for a certain field.
* By default, it returns 5 for every fields.
* By default, it returns true for all fields.
* Reimplement this if you only support certain fields.
*
* Typical return values are:
* * 0: not supported
* * 5: maybe support (for example, Datetime support strings depending on their content)
* * 10: basic support (this is what returns TextEdit for example, since it supports everything in a crude way)
* * 20: specialised support
*
* @param vl
* @param fieldIdx
* @return 0 if the field is not supported or a bigger number if it can (the widget with the biggest number will be
* taken by default). The default implementation returns 5..
* @return True if the field is supported.
*
* @see supportsField( QgsVectorLayer* vl, fieldIdx )
*/
virtual unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const;
virtual bool isFieldSupported( QgsVectorLayer* vl, int fieldIdx );
private:
QString mName;

View File

@ -54,7 +54,6 @@ QgsEditorWidgetRegistry* QgsEditorWidgetRegistry::instance()
void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBar *messageBar )
{
QgsEditorWidgetRegistry *reg = instance();
reg->registerWidget( "TextEdit", new QgsTextEditWidgetFactory( tr( "Text Edit" ) ) );
reg->registerWidget( "Classification", new QgsClassificationWidgetWrapperFactory( tr( "Classification" ) ) );
reg->registerWidget( "Range", new QgsRangeWidgetFactory( tr( "Range" ) ) );
reg->registerWidget( "UniqueValues", new QgsUniqueValueWidgetFactory( tr( "Unique Values" ) ) );
@ -63,6 +62,7 @@ void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBa
reg->registerWidget( "Enumeration", new QgsEnumerationWidgetFactory( tr( "Enumeration" ) ) );
reg->registerWidget( "Hidden", new QgsHiddenWidgetFactory( tr( "Hidden" ) ) );
reg->registerWidget( "CheckBox", new QgsCheckboxWidgetFactory( tr( "Check Box" ) ) );
reg->registerWidget( "TextEdit", new QgsTextEditWidgetFactory( tr( "Text Edit" ) ) );
reg->registerWidget( "ValueRelation", new QgsValueRelationWidgetFactory( tr( "Value Relation" ) ) );
reg->registerWidget( "UuidGenerator", new QgsUuidWidgetFactory( tr( "Uuid Generator" ) ) );
reg->registerWidget( "Photo", new QgsPhotoWidgetFactory( tr( "Photo" ) ) );
@ -89,23 +89,6 @@ QgsEditorWidgetRegistry::~QgsEditorWidgetRegistry()
qDeleteAll( mWidgetFactories );
}
QgsEditorWidgetSetup QgsEditorWidgetRegistry::findBest( const QgsVectorLayer* vl, const QString& fieldName ) const
{
const QString fromConfig = vl->editFormConfig().widgetType( fieldName );
if ( !fromConfig.isNull() )
{
return QgsEditorWidgetSetup( fromConfig, vl->editFormConfig().widgetConfig( fieldName ) );
}
return autoConf.editorWidgetSetup( vl, fieldName );
}
QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent, const QgsAttributeEditorContext &context )
{
const QString fieldName = vl->fields().field( fieldIdx ).name();
const QgsEditorWidgetSetup setup = findBest( vl, fieldName );
return create( setup.type(), vl, fieldIdx, setup.config(), editor, parent, context );
}
QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::create( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor, QWidget* parent, const QgsAttributeEditorContext &context )
{
if ( mWidgetFactories.contains( widgetId ) )
@ -288,13 +271,8 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
QgsFields fields = vectorLayer->fields();
for ( int idx = 0; idx < fields.count(); ++idx )
{
const QgsField field = fields.at( idx );
const QString& widgetType = vectorLayer->editFormConfig().widgetType( field.name() );
if ( widgetType.isNull() )
{
// Don't save widget config if it is not manually edited
continue;
}
QgsField field = fields.at( idx );
const QString& widgetType = vectorLayer->editFormConfig().widgetType( idx );
if ( !mWidgetFactories.contains( widgetType ) )
{
QgsMessageLog::logMessage( tr( "Could not save unknown editor widget type '%1'." ).arg( widgetType ) );
@ -315,7 +293,7 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig().expression( idx ) );
ewv2CfgElem.setAttribute( "constraintDescription", vectorLayer->editFormConfig().expressionDescription( idx ) );
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig().widgetConfig( field.name() ), ewv2CfgElem, doc, vectorLayer, idx );
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig().widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx );
editTypeElement.appendChild( ewv2CfgElem );
}

View File

@ -21,7 +21,6 @@
#include "qgseditorwidgetconfig.h"
#include "qgseditorwidgetfactory.h"
#include "qgsattributeeditorcontext.h"
#include "qgseditorwidgetautoconf.h"
class QgsMapLayer;
class QDomNode;
@ -68,16 +67,6 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
*/
~QgsEditorWidgetRegistry();
/**
* Find the best editor widget and its configuration for a given field.
*
* @param vl The vector layer for which this widget will be created
* @param fieldName The field name on the specified layer for which this widget will be created
*
* @return The id of the widget type to use and its config
*/
QgsEditorWidgetSetup findBest( const QgsVectorLayer* vl, const QString& fieldName ) const;
/**
* 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.
@ -100,24 +89,6 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
QWidget* parent,
const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
/**
* Create an attribute editor widget wrapper of the best type for a given field.
* The editor may be NULL if you want the widget wrapper to create a default widget.
*
* @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 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
* @param context The editor context (not available in python bindings)
*
* @return A new widget wrapper
*/
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl,
int fieldIdx,
QWidget* editor,
QWidget* parent,
const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
QgsSearchWidgetWrapper* createSearchWidget( const QString& widgetId,
QgsVectorLayer* vl,
int fieldIdx,
@ -170,13 +141,6 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
*/
bool registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory );
/**
* Register a new auto-conf plugin.
*
* @param plugin The plugin (ownership is transfered)
*/
void registerAutoConfPlugin( QgsEditorWidgetAutoConfPlugin* plugin ) { autoConf.registerPlugin( plugin ); }
protected:
QgsEditorWidgetRegistry();
@ -235,7 +199,6 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
QMap<QString, QgsEditorWidgetFactory*> mWidgetFactories;
QMap<const char*, QPair<int, QString> > mFactoriesByType;
QgsEditorWidgetAutoConf autoConf;
};
#endif // QGSEDITORWIDGETREGISTRY_H

View File

@ -68,9 +68,3 @@ QMap<const char*, int> QgsCheckboxWidgetFactory::supportedWidgetTypes()
map.insert( QGroupBox::staticMetaObject.className(), 10 );
return map;
}
unsigned int QgsCheckboxWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
const QVariant::Type type = vl->fields().field( fieldIdx ).type();
return type == QVariant::Bool ? 20 : 5;
}

View File

@ -36,7 +36,6 @@ class GUI_EXPORT QgsCheckboxWidgetFactory : public QgsEditorWidgetFactory
QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ) override;
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;
QMap<const char*, int> supportedWidgetTypes() override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
};
#endif // QGSCHECKBOXWIDGETFACTORY_H

View File

@ -33,17 +33,3 @@ QgsEditorConfigWidget* QgsColorWidgetFactory::configWidget( QgsVectorLayer* vl,
{
return new QgsDummyConfigDlg( vl, fieldIdx, parent, QObject::tr( "Field contains a color." ) );
}
unsigned int QgsColorWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
const QgsField field = vl->fields().field( fieldIdx );
const QVariant::Type type = field.type();
if ( type == QVariant::Color )
{
return 20;
}
else
{
return 5;
}
}

View File

@ -32,7 +32,6 @@ class GUI_EXPORT QgsColorWidgetFactory : public QgsEditorWidgetFactory
public:
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
};
#endif // QGSCOLORWIDGETFACTORY_H

View File

@ -114,18 +114,3 @@ QMap<const char*, int> QgsDateTimeEditFactory::supportedWidgetTypes()
map.insert( QgsDateTimeEdit::staticMetaObject.className(), 10 );
return map;
}
unsigned int QgsDateTimeEditFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
const QgsField field = vl->fields().field( fieldIdx );
const QVariant::Type type = field.type();
const QgsEditorWidgetConfig config = vl->editFormConfig().widgetConfig( field.name() );
if ( type == QVariant::DateTime || config.contains( "field_format" ) )
{
return 20;
}
else
{
return 5;
}
}

View File

@ -42,7 +42,6 @@ class GUI_EXPORT QgsDateTimeEditFactory : public QgsEditorWidgetFactory
QString representValue( QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, const QVariant& cache, const QVariant& value ) const override;
Qt::AlignmentFlag alignmentFlag( QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config ) const override;
virtual QMap<const char*, int> supportedWidgetTypes() override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
};
#endif // QGSDATETIMEEDITFACTORY_H

View File

@ -36,12 +36,12 @@ QgsEditorConfigWidget* QgsEnumerationWidgetFactory::configWidget( QgsVectorLayer
}
unsigned int QgsEnumerationWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
bool QgsEnumerationWidgetFactory::isFieldSupported( QgsVectorLayer* vl, int fieldIdx )
{
QStringList list;
vl->dataProvider()->enumValues( fieldIdx, list );
if ( !list.isEmpty() )
return 20;
return true;
else
return 0;
return false;
}

View File

@ -33,7 +33,8 @@ class GUI_EXPORT QgsEnumerationWidgetFactory : public QgsEditorWidgetFactory
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
private:
bool isFieldSupported( QgsVectorLayer* vl, int fieldIdx ) override;
};
#endif // QGSENUMERATIONWIDGETFACTORY_H

View File

@ -119,10 +119,10 @@ QgsEditorWidgetConfig QgsExternalResourceWidgetFactory::readConfig( const QDomEl
return cfg;
}
unsigned int QgsExternalResourceWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
bool QgsExternalResourceWidgetFactory::isFieldSupported( QgsVectorLayer* vl, int fieldIdx )
{
if ( vl->fields().at( fieldIdx ).type() == QVariant::String )
return 5;
return true;
return 0;
return false;
}

View File

@ -35,11 +35,13 @@ class GUI_EXPORT QgsExternalResourceWidgetFactory : public QgsEditorWidgetFactor
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
// QgsEditorWidgetFactory interface
public:
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
private:
QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ) override;
bool isFieldSupported( QgsVectorLayer* vl, int fieldIdx ) override;
};
#endif // QGSEXTERNALRESOURCEWIDGETFACTORY_H

View File

@ -71,9 +71,18 @@ void QgsRangeWidgetFactory::writeConfig( const QgsEditorWidgetConfig& config, QD
}
}
unsigned int QgsRangeWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
bool QgsRangeWidgetFactory::isFieldSupported( QgsVectorLayer* vl, int fieldIdx )
{
return vl->fields().at( fieldIdx ).isNumeric() ? 20 : 0;
switch ( vl->fields().at( fieldIdx ).type() )
{
case QVariant::LongLong:
case QVariant::Double:
case QVariant::Int:
return true;
default:
return false;
}
}
QMap<const char*, int> QgsRangeWidgetFactory::supportedWidgetTypes()

View File

@ -37,7 +37,7 @@ class GUI_EXPORT QgsRangeWidgetFactory : public QgsEditorWidgetFactory
virtual QMap<const char*, int> supportedWidgetTypes() override;
private:
virtual unsigned int fieldScore( const QgsVectorLayer *vl, int fieldIdx ) const override;
virtual bool isFieldSupported( QgsVectorLayer *vl, int fieldIdx ) override;
};
#endif // QGSRANGEWIDGETFACTORY_H

View File

@ -62,10 +62,3 @@ QgsEditorWidgetConfig QgsTextEditWidgetFactory::readConfig( const QDomElement& c
return cfg;
}
unsigned int QgsTextEditWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
Q_UNUSED( vl )
Q_UNUSED( fieldIdx )
return 10;
}

View File

@ -34,8 +34,9 @@ class GUI_EXPORT QgsTextEditWidgetFactory : public QgsEditorWidgetFactory
QgsSearchWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
// QgsEditorWidgetFactory interface
public:
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
private:
QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ) override;

View File

@ -33,9 +33,3 @@ QgsEditorConfigWidget* QgsUuidWidgetFactory::configWidget( QgsVectorLayer* vl, i
{
return new QgsDummyConfigDlg( vl, fieldIdx, parent, QObject::tr( "Read-only field that generates a UUID if empty." ) );
}
unsigned int QgsUuidWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
const QVariant::Type type = vl->fields().field( fieldIdx ).type();
return type == QVariant::String ? 5 : 0;
}

View File

@ -32,7 +32,6 @@ class GUI_EXPORT QgsUuidWidgetFactory : public QgsEditorWidgetFactory
public:
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
};
#endif // QGSUUIDWIDGETFACTORY_H

View File

@ -43,7 +43,10 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
QWidget* QgsAttributeEditor::createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant& value, QgsAttributeEditorContext& context )
{
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( vl, idx, editor, parent, context );
QString widgetType = vl->editFormConfig().widgetType( idx );
QgsEditorWidgetConfig cfg = vl->editFormConfig().widgetConfig( idx );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, idx, cfg, editor, parent, context );
if ( eww )
{

View File

@ -1216,16 +1216,17 @@ void QgsAttributeForm::init()
//show attribute alias if available
QString fieldName = mLayer->attributeDisplayName( idx );
const QgsEditorWidgetSetup widgetSetup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, field.name() );
const QString widgetType = mLayer->editFormConfig().widgetType( idx );
if ( widgetSetup.type() == "Hidden" )
if ( widgetType == "Hidden" )
continue;
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( idx );
bool labelOnTop = mLayer->editFormConfig().labelOnTop( idx );
// This will also create the widget
QLabel *l = new QLabel( fieldName );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetSetup.type(), mLayer, idx, widgetSetup.config(), nullptr, this, mContext );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, mLayer, idx, widgetConfig, nullptr, this, mContext );
QWidget* w = nullptr;
if ( eww )
@ -1233,13 +1234,13 @@ void QgsAttributeForm::init()
QgsAttributeFormEditorWidget* formWidget = new QgsAttributeFormEditorWidget( eww, this );
w = formWidget;
mFormEditorWidgets.insert( idx, formWidget );
formWidget->createSearchWidgetWrappers( widgetSetup.type(), idx, widgetSetup.config(), mContext );
formWidget->createSearchWidgetWrappers( widgetType, idx, widgetConfig, mContext );
l->setBuddy( eww->widget() );
}
else
{
w = new QLabel( QString( "<p style=\"color: red; font-style: italic;\">Failed to create widget with type '%1'</p>" ).arg( widgetSetup.type() ) );
w = new QLabel( QString( "<p style=\"color: red; font-style: italic;\">Failed to create widget with type '%1'</p>" ).arg( widgetType ) );
}
@ -1264,8 +1265,8 @@ void QgsAttributeForm::init()
Q_FOREACH ( const QgsRelation& rel, QgsProject::instance()->relationManager()->referencedRelations( mLayer ) )
{
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, rel, nullptr, this );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, rel.id() );
rww->setConfig( setup.config() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( rel.id() );
rww->setConfig( cfg );
rww->setContext( mContext );
gridLayout->addWidget( rww->widget(), row++, 0, 1, 2 );
mWidgets.append( rww );
@ -1505,13 +1506,14 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
int fldIdx = vl->fieldNameIndex( fieldDef->name() );
if ( fldIdx < vl->fields().count() && fldIdx >= 0 )
{
const QgsEditorWidgetSetup widgetSetup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, fieldDef->name() );
const QString widgetType = mLayer->editFormConfig().widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( fldIdx );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetSetup.type(), mLayer, fldIdx, widgetSetup.config(), nullptr, this, mContext );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, mLayer, fldIdx, widgetConfig, nullptr, this, mContext );
QgsAttributeFormEditorWidget* w = new QgsAttributeFormEditorWidget( eww, this );
mFormEditorWidgets.insert( fldIdx, w );
w->createSearchWidgetWrappers( widgetSetup.type(), fldIdx, widgetSetup.config(), mContext );
w->createSearchWidgetWrappers( widgetType, fldIdx, widgetConfig, mContext );
newWidgetInfo.widget = w;
addWidgetWrapper( eww );
@ -1531,8 +1533,8 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
const QgsAttributeEditorRelation* relDef = dynamic_cast<const QgsAttributeEditorRelation*>( widgetDef );
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, relDef->relation(), nullptr, this );
const QgsEditorWidgetSetup widgetSetup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, relDef->relation().id() );
rww->setConfig( widgetSetup.config() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( relDef->relation().id() );
rww->setConfig( cfg );
rww->setContext( context );
newWidgetInfo.widget = rww->widget();
rww->setShowLabel( relDef->showLabel() );
@ -1686,8 +1688,7 @@ void QgsAttributeForm::createWrappers()
if ( relation.isValid() )
{
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, relation, myWidget, this );
const QgsEditorWidgetSetup widgetSetup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, relation.id() );
rww->setConfig( widgetSetup.config() );
rww->setConfig( mLayer->editFormConfig().widgetConfig( relation.id() ) );
rww->setContext( mContext );
rww->widget(); // Will initialize the widget
mWidgets.append( rww );
@ -1699,9 +1700,11 @@ void QgsAttributeForm::createWrappers()
{
if ( field.name() == myWidget->objectName() )
{
const QString widgetType = mLayer->editFormConfig().widgetType( field.name() );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( field.name() );
int idx = mLayer->fieldNameIndex( field.name() );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( mLayer, idx, myWidget, this, mContext );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, mLayer, idx, widgetConfig, myWidget, this, mContext );
addWidgetWrapper( eww );
}
}

View File

@ -1,3 +1,4 @@
########################################################
# Files

View File

@ -1287,7 +1287,6 @@ QString QgsPostgresConn::fieldExpression( const QgsField &fld, QString expr )
}
else if ( type.startsWith( '_' ) )
{
//TODO: add native support for arrays
return QString( "array_out(%1)::text" ).arg( expr );
}
else if ( type == "bool" )
@ -1304,7 +1303,6 @@ QString QgsPostgresConn::fieldExpression( const QgsField &fld, QString expr )
{
return QString( "st_astext(%1)" ).arg( expr );
}
//TODO: add support for hstore
else
{
return expr + "::text";

View File

@ -23,7 +23,6 @@
#include <qgsmessagelog.h>
#include <qgsrectangle.h>
#include <qgscoordinatereferencesystem.h>
#include <qgseditformconfig.h>
#include <QMessageBox>
@ -39,7 +38,6 @@
const QString POSTGRES_KEY = "postgres";
const QString POSTGRES_DESCRIPTION = "PostgreSQL/PostGIS data provider";
static const QString EDITOR_WIDGET_STYLES_TABLE = "qgis_editor_widget_styles";
inline qint64 PKINT2FID( qint32 x )
{
@ -51,12 +49,6 @@ inline qint32 FID2PKINT( qint64 x )
return QgsPostgresUtils::fid_to_int32pk( x );
}
static bool tableExists( QgsPostgresConn& conn, const QString& name )
{
QgsPostgresResult res( conn.PQexec( "SELECT COUNT(*) FROM information_schema.tables WHERE table_name=" + QgsPostgresConn::quotedValue( name ) ) );
return res.PQgetvalue( 0, 0 ).toInt() > 0;
}
QgsPostgresPrimaryKeyType
QgsPostgresProvider::pkType( const QgsField& f ) const
{
@ -1061,48 +1053,9 @@ bool QgsPostgresProvider::loadFields()
mAttributeFields.append( QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment ) );
}
setEditorWidgets();
return true;
}
void QgsPostgresProvider::setEditorWidgets()
{
if ( tableExists( *connectionRO(), EDITOR_WIDGET_STYLES_TABLE ) )
{
for ( int i = 0; i < mAttributeFields.count(); ++i )
{
// CREATE TABLE qgis_editor_widget_styles (schema_name TEXT NOT NULL, table_name TEXT NOT NULL, field_name TEXT NOT NULL,
// type TEXT NOT NULL, config TEXT,
// PRIMARY KEY(schema_name, table_name, field_name));
QgsField& field = mAttributeFields[i];
const QString sql = QString( "SELECT type, config FROM %1 WHERE schema_name = %2 and table_name = %3 and field_name = %4 LIMIT 1" ).
arg( EDITOR_WIDGET_STYLES_TABLE, quotedValue( mSchemaName ), quotedValue( mTableName ), quotedValue( field.name() ) );
QgsPostgresResult result( connectionRO()->PQexec( sql ) );
for ( int i = 0; i < result.PQntuples(); ++i )
{
const QString type = result.PQgetvalue( i, 0 );
QgsEditorWidgetConfig config;
if ( !result.PQgetisnull( i, 1 ) ) // Can be null and it's OK
{
const QString configTxt = result.PQgetvalue( i, 1 );
QDomDocument doc;
if ( doc.setContent( configTxt ) )
{
config = QgsEditFormConfig::parseEditorWidgetConfig( doc.documentElement() );
}
else
{
QgsMessageLog::logMessage( tr( "Cannot parse widget configuration for field %1.%2.%3\n" ).arg( mSchemaName, mTableName, field.name() ), tr( "PostGIS" ) );
}
}
field.setEditorWidgetSetup( QgsEditorWidgetSetup( type, config ) );
}
}
}
}
bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()
{
QgsDebugMsg( "Checking for permissions on the relation" );
@ -1984,7 +1937,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
.arg( delim,
quotedValue( v.toString() ) );
}
//TODO: convert arrays and hstore to native types
else
{
values += delim + quotedValue( v );
@ -4013,23 +3965,24 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
return false;
}
if ( !tableExists( *conn, "layer_styles" ) )
QgsPostgresResult res( conn->PQexec( "SELECT COUNT(*) FROM information_schema.tables WHERE table_name='layer_styles'" ) );
if ( res.PQgetvalue( 0, 0 ).toInt() == 0 )
{
QgsPostgresResult res( conn->PQexec( "CREATE TABLE layer_styles("
"id SERIAL PRIMARY KEY"
",f_table_catalog varchar"
",f_table_schema varchar"
",f_table_name varchar"
",f_geometry_column varchar"
",styleName varchar(30)"
",styleQML xml"
",styleSLD xml"
",useAsDefault boolean"
",description text"
",owner varchar(30)"
",ui xml"
",update_time timestamp DEFAULT CURRENT_TIMESTAMP"
")" ) );
res = conn->PQexec( "CREATE TABLE layer_styles("
"id SERIAL PRIMARY KEY"
",f_table_catalog varchar"
",f_table_schema varchar"
",f_table_name varchar"
",f_geometry_column varchar"
",styleName varchar(30)"
",styleQML xml"
",styleSLD xml"
",useAsDefault boolean"
",description text"
",owner varchar(30)"
",ui xml"
",update_time timestamp DEFAULT CURRENT_TIMESTAMP"
")" );
if ( res.PQresultStatus() != PGRES_COMMAND_OK )
{
errCause = QObject::tr( "Unable to save layer style. It's not possible to create the destination table on the database. Maybe this is due to table permissions (user=%1). Please contact your database admin" ).arg( dsUri.username() );
@ -4083,7 +4036,7 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
.arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) )
.arg( QgsPostgresConn::quotedValue( styleName.isEmpty() ? dsUri.table() : styleName ) );
QgsPostgresResult res( conn->PQexec( checkQuery ) );
res = conn->PQexec( checkQuery );
if ( res.PQntuples() > 0 )
{
if ( QMessageBox::question( nullptr, QObject::tr( "Save style in database" ),
@ -4158,7 +4111,8 @@ QGISEXTERN QString loadStyle( const QString& uri, QString& errCause )
return "";
}
if ( !tableExists( *conn, "layer_styles" ) )
QgsPostgresResult result( conn->PQexec( "SELECT COUNT(*) FROM information_schema.tables WHERE table_name='layer_styles'" ) );
if ( result.PQgetvalue( 0, 0 ).toInt() == 0 )
{
return "";
}
@ -4176,7 +4130,7 @@ QGISEXTERN QString loadStyle( const QString& uri, QString& errCause )
.arg( QgsPostgresConn::quotedValue( dsUri.table() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) );
QgsPostgresResult result( conn->PQexec( selectQmlQuery ) );
result = conn->PQexec( selectQmlQuery );
QString style = result.PQntuples() == 1 ? result.PQgetvalue( 0, 0 ) : "";
conn->unref();

View File

@ -300,10 +300,6 @@ class QgsPostgresProvider : public QgsVectorDataProvider
*/
bool loadFields();
/** Set the default widget type for the fields
*/
void setEditorWidgets();
/** Convert a QgsField to work with PG */
static bool convertField( QgsField &field, const QMap<QString, QVariant> *options = nullptr );

View File

@ -811,7 +811,7 @@ void QgsServerProjectParser::addLayerProjectSettings( QDomElement& layerElem, QD
}
//edit type to text
attributeElem.setAttribute( "editType", vLayer->editFormConfig().widgetType( field.name() ) );
attributeElem.setAttribute( "editType", vLayer->editFormConfig().widgetType( idx ) );
attributeElem.setAttribute( "comment", field.comment() );
attributeElem.setAttribute( "length", field.length() );
attributeElem.setAttribute( "precision", field.precision() );
@ -1555,11 +1555,10 @@ void QgsServerProjectParser::addValueRelationLayersForLayer( const QgsVectorLaye
for ( int idx = 0; idx < vl->pendingFields().size(); idx++ )
{
const QString name = vl->pendingFields().field( idx ).name();
if ( vl->editFormConfig().widgetType( name ) != "ValueRelation" )
if ( vl->editFormConfig().widgetType( idx ) != "ValueRelation" )
continue;
QgsEditorWidgetConfig cfg( vl->editFormConfig().widgetConfig( name ) );
QgsEditorWidgetConfig cfg( vl->editFormConfig().widgetConfig( idx ) );
if ( !cfg.contains( "Layer" ) )
continue;

View File

@ -3334,11 +3334,11 @@ QDomElement QgsWmsServer::createFeatureGML(
QString QgsWmsServer::replaceValueMapAndRelation( QgsVectorLayer* vl, int idx, const QString& attributeVal )
{
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( vl, vl->fields().field( idx ).name() );
if ( QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( setup.type() ) )
if ( QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( vl->editFormConfig().widgetType( idx ) ) )
{
QString value( factory->representValue( vl, idx, setup.config(), QVariant(), attributeVal ) );
if ( setup.config().value( "AllowMulti" ).toBool() && value.startsWith( "{" ) && value.endsWith( "}" ) )
QgsEditorWidgetConfig cfg( vl->editFormConfig().widgetConfig( idx ) );
QString value( factory->representValue( vl, idx, cfg, QVariant(), attributeVal ) );
if ( cfg.value( "AllowMulti" ).toBool() && value.startsWith( "{" ) && value.endsWith( "}" ) )
{
value = value.mid( 1, value.size() - 2 );
}

View File

@ -40,7 +40,6 @@ class TestQgsField: public QObject
void displayString();
void convertCompatible();
void dataStream();
void editorWidgetSetup();
private:
};
@ -373,17 +372,5 @@ void TestQgsField::dataStream()
QCOMPARE( result.comment(), original.comment() ); //comment is NOT required for equality
}
void TestQgsField::editorWidgetSetup()
{
QgsField field;
QgsEditorWidgetConfig config;
config.insert( "a", "value_a" );
const QgsEditorWidgetSetup setup( "test", config );
field.setEditorWidgetSetup( setup );
QCOMPARE( field.editorWidgetSetup().type(), setup.type() );
QCOMPARE( field.editorWidgetSetup().config(), setup.config() );
}
QTEST_MAIN( TestQgsField )
#include "testqgsfield.moc"

View File

@ -140,5 +140,4 @@ ADD_QGIS_TEST(rubberbandtest testqgsrubberband.cpp)
ADD_QGIS_TEST(scalecombobox testqgsscalecombobox.cpp)
ADD_QGIS_TEST(spinbox testqgsspinbox.cpp)
ADD_QGIS_TEST(sqlcomposerdialog testqgssqlcomposerdialog.cpp)
ADD_QGIS_TEST(editorwidgetregistrytest testqgseditorwidgetregistry.cpp)

View File

@ -67,7 +67,6 @@ void TestQgsAttributeForm::testFieldConstraint()
// make a temporary vector layer
QString def = "Point?field=col0:integer";
QgsVectorLayer* layer = new QgsVectorLayer( def, "test", "memory" );
layer->editFormConfig().setWidgetType( 0, "TextEdit" );
// add a feature to the vector layer
QgsFeature ft( layer->dataProvider()->fields(), 1 );

View File

@ -1,119 +0,0 @@
/***************************************************************************
testqgseditorwidgetregistry.cpp
---------------------
begin : July 2016
copyright : (C) 2016 by Patrick Valsecchi
email : patrick.valsecchi at camptocamp.com
***************************************************************************
* *
* 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 <QtTest/QtTest>
#include "qgseditorwidgetregistry.h"
#include "qgseditorwidgetautoconf.h"
class TestQgsEditorWidgetRegistry: public QObject
{
Q_OBJECT
class DummyPlugin: public QgsEditorWidgetAutoConfPlugin
{
public:
QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer* vl, const QString& fieldName, int& score ) const override
{
Q_UNUSED( vl )
if ( fieldName == "special" )
{
score = 100;
return QgsEditorWidgetSetup( "Special", QgsEditorWidgetConfig() );
}
score = 0;
return QgsEditorWidgetSetup();
}
};
private slots:
void initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
QgsEditorWidgetRegistry::initEditors();
QgsEditorWidgetRegistry::instance()->registerAutoConfPlugin( new DummyPlugin() );
}
void cleanupTestCase()
{
QgsApplication::exitQgis();
}
void stringType()
{
checkSimple( "string", "TextEdit" );
}
void datetimeType()
{
checkSimple( "datetime", "DateTime" );
}
void integerType()
{
checkSimple( "integer", "Range" );
}
void doubleType()
{
checkSimple( "double", "Range" );
}
void configuredType()
{
QgsVectorLayer vl( "LineString?crs=epsg:3111&field=pk:int&field=col1:string", "vl", "memory" );
QgsEditFormConfig formConfig = vl.editFormConfig();
formConfig.setWidgetType( vl.fieldNameIndex( "col1" ), "FooEdit" );
QgsEditorWidgetConfig config;
config["a"] = QVariant( 12 );
config["b"] = QVariant( "bar" );
formConfig.setWidgetConfig( "col1", config );
vl.setEditFormConfig( formConfig );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( &vl, "col1" );
QCOMPARE( setup.type(), QString( "FooEdit" ) );
QCOMPARE( setup.config(), config );
}
void wrongFieldName()
{
const QgsVectorLayer vl( "LineString?crs=epsg:3111&field=pk:int&field=col1:string", "vl", "memory" );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( &vl, "col2" );
// an unknown fields leads to a default setup with a TextEdit
QCOMPARE( setup.type(), QString( "TextEdit" ) );
QCOMPARE( setup.config().count(), 0 );
}
void typeFromPlugin()
{
const QgsVectorLayer vl( "LineString?crs=epsg:3111&field=pk:int&field=special:string", "vl", "memory" );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( &vl, "special" );
QCOMPARE( setup.type(), QString( "Special" ) );
}
private:
static void checkSimple( const QString& dataType, const QString& widgetType )
{
const QgsVectorLayer vl( "LineString?crs=epsg:3111&field=pk:int&field=col1:" + dataType, "vl", "memory" );
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( &vl, "col1" );
QCOMPARE( setup.type(), widgetType );
QCOMPARE( setup.config().count(), 0 );
}
};
QTEST_MAIN( TestQgsEditorWidgetRegistry )
#include "testqgseditorwidgetregistry.moc"

View File

@ -24,7 +24,6 @@ from qgis.core import (
QgsTransactionGroup,
NULL
)
from qgis.gui import QgsEditorWidgetRegistry
from qgis.PyQt.QtCore import QSettings, QDate, QTime, QDateTime, QVariant
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath
@ -49,7 +48,6 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
cls.poly_vl = QgsVectorLayer(cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres')
assert cls.poly_vl.isValid()
cls.poly_provider = cls.poly_vl.dataProvider()
QgsEditorWidgetRegistry.instance().initEditors()
@classmethod
def tearDownClass(cls):
@ -314,27 +312,6 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
self.assertEqual(fet.fields()[1].name(), 'newname2')
self.assertEqual(fet.fields()[2].name(), 'another')
def testEditorWidgetTypes(self):
"""Test that editor widget types can be fetched from the qgis_editor_widget_styles table"""
vl = QgsVectorLayer('%s table="qgis_test"."widget_styles" sql=' % (self.dbconn), "widget_styles", "postgres")
self.assertTrue(vl.isValid())
fields = vl.dataProvider().fields()
setup1 = fields.field("fld1").editorWidgetSetup()
self.assertFalse(setup1.isNull())
self.assertEqual(setup1.type(), "FooEdit")
self.assertEqual(setup1.config(), {"param1": "value1", "param2": "2"})
best1 = QgsEditorWidgetRegistry.instance().findBest(vl, "fld1")
self.assertEqual(best1.type(), "FooEdit")
self.assertEqual(best1.config(), setup1.config())
self.assertTrue(fields.field("fld2").editorWidgetSetup().isNull())
best2 = QgsEditorWidgetRegistry.instance().findBest(vl, "fld2")
self.assertEqual(best2.type(), "TextEdit")
class TestPyQgsPostgresProviderCompoundKey(unittest.TestCase, ProviderTestCase):

View File

@ -6,7 +6,6 @@ SCRIPTS="
tests/testdata/provider/testdata_pg_vectorjoin.sql
"
dropdb qgis_test 2> /dev/null || true
createdb qgis_test || exit 1
for f in ${SCRIPTS}; do
psql -f $f qgis_test --set ON_ERROR_STOP=1 || exit 1

View File

@ -434,27 +434,3 @@ CREATE TABLE qgis_test.rename_table
);
INSERT INTO qgis_test.rename_table (field1,field2) VALUES ('a','b');
--------------------------------------
-- Table for editor widget types
--
CREATE TABLE qgis_editor_widget_styles
(
schema_name TEXT NOT NULL,
table_name TEXT NOT NULL,
field_name TEXT NOT NULL,
type TEXT NOT NULL,
config TEXT,
PRIMARY KEY(table_name, field_name)
);
CREATE TABLE qgis_test.widget_styles(
id int PRIMARY KEY,
fld1 TEXT,
fld2 TEXT
);
INSERT INTO qgis_editor_widget_styles VALUES
('qgis_test', 'widget_styles', 'fld1', 'FooEdit', '<config><option key="param1" value="value1"/><option key="param2" value="2"/></config>');