Cleanup QgsEditFormConfig

* It's now implicitly shared, meaning that changes to the config
   can be supervised and a signal is sent from QgsVectorLayer and
   there is no risk of elements suddenly being deleted.
 * Remove a bunch of methods that were in QgsVectorLayer for legacy
   reasons.
This commit is contained in:
Matthias Kuhn 2016-08-18 14:05:02 +02:00
parent 54fb32d0f5
commit 5c20f0782a
40 changed files with 1316 additions and 1020 deletions

View File

@ -216,6 +216,12 @@ attributeIndexes(), pkAttributeIndexes(), isSaveAndLoadStyleToDBSupported()</li>
</li>
</ul>
\subsection qgis_api_break_3_0_QgsEditFormConfig QgsEditFormConfig
<ul>
<li>Does no longer inherit QObject
</ul>
\subsection qgis_api_break_3_0_Qgis Qgis
<ul>
@ -867,6 +873,13 @@ displayExpression instead. For the map tip use mapTipTemplate() instead.</li>
<li>applyNamedStyle() replaced by applyNamedStyle()
<li>isReadOnly() use readOnly()
<li>Signal changeAttributeValue()
<li>Deleted GroupData (Use QgsEditFormConfig::GroupData)
<li>Deleted TabData (Use QgsEditFormConfig::TabData)
<li>Deleted EditorLayout (Use QgsEditFormConfig::EditorLayout)
<li>Deleted ValueRelationData (Use QgsEditFormConfig::editorWidgetConfig)
<li>Deleted attributeEditorElementFromDomElement
<li>editFormConfig() returns a copy instead of direct access (Use setEditFormConfig to update)
<li>Removed valueRelation(), replaced with QgsEditFormConfig::editorWidgetConfig
</ul>
\subsection qgis_api_break_3_0_QgsVectorLayerEditBuffer QgsVectorLayerEditBuffer

View File

@ -24,6 +24,7 @@
%Include qgsactionmanager.sip
%Include qgsaggregatecalculator.sip
%Include qgsattributetableconfig.sip
%Include qgsattributeeditorelement.sip
%Include qgsbrowsermodel.sip
%Include qgsclipper.sip
%Include qgscolorscheme.sip

View File

@ -0,0 +1,290 @@
/***************************************************************************
qgsattributeeditorelement.sip - QgsAttributeEditorElement
---------------------
begin : 18.8.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/** \ingroup core
* This is an abstract base class for any elements of a drag and drop form.
*
* This can either be a container which will be represented on the screen
* as a tab widget or ca collapsible group box. Or it can be a field which will
* then be represented based on the QgsEditorWidget type and configuration.
* Or it can be a relation and embed the form of several children of another
* layer.
*/
class QgsAttributeEditorElement
{
%TypeHeaderCode
#include <qgsattributeeditorelement.h>
%End
%ConvertToSubClassCode
switch( sipCpp->type() )
{
case QgsAttributeEditorElement::AeTypeContainer:
sipType = sipType_QgsAttributeEditorContainer;
break;
case QgsAttributeEditorElement::AeTypeField:
sipType = sipType_QgsAttributeEditorField;
break;
case QgsAttributeEditorElement::AeTypeRelation:
sipType = sipType_QgsAttributeEditorRelation;
break;
default:
sipType = nullptr;
break;
}
%End
public:
enum AttributeEditorType
{
AeTypeContainer, //!< A container
AeTypeField, //!< A field
AeTypeRelation, //!< A relation
AeTypeInvalid //!< Invalid
};
/**
* Constructor
*
* @param type The type of the new element. Should never
* @param name
* @param parent
*/
QgsAttributeEditorElement( AttributeEditorType type, const QString& name, QgsAttributeEditorElement* parent = nullptr );
/**
* Return the name of this element
*
* @return The name for this element
*/
QString name() const;
/**
* The type of this element
*
* @return The type
*/
AttributeEditorType type();
/**
* Get the parent of this element.
*
* @note Added in QGIS 3.0
*/
QgsAttributeEditorElement* parent() const;
/**
* Is reimplemented in classes inheriting from this to serialize it.
*
* @param doc The QDomDocument which is used to create new XML elements
*
* @return An DOM element which represents this element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const = 0;
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const = 0 /Factory/;
};
/** \ingroup core
* This is a container for attribute editors, used to group them visually in the
* attribute form if it is set to the drag and drop designer.
*/
class QgsAttributeEditorContainer : QgsAttributeEditorElement
{
%TypeHeaderCode
#include <qgsattributeeditorelement.h>
%End
%ConvertToSubClassCode
switch ( sipCpp->type() )
{
case QgsAttributeEditorElement::AeTypeContainer: sipType = sipType_QgsAttributeEditorContainer; break;
case QgsAttributeEditorElement::AeTypeField: sipType = sipType_QgsAttributeEditorField; break;
case QgsAttributeEditorElement::AeTypeRelation: sipType = sipType_QgsAttributeEditorRelation; break;
}
%End
public:
/**
* Creates a new attribute editor container
*
* @param name The name to show as title
* @param parent The parent. May be another container.
*/
QgsAttributeEditorContainer( const QString& name, QgsAttributeEditorElement* parent );
/**
* Will serialize this containers information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Add a child element to this container. This may be another container, a field or a relation.
*
* @param element The element to add as child
*/
virtual void addChildElement( QgsAttributeEditorElement* element /Transfer/ );
/**
* Determines if this container is rendered as collapsible group box or tab in a tabwidget
*
* @param isGroupBox If true, this will be a group box
*/
virtual void setIsGroupBox( bool isGroupBox );
/**
* Returns if this container is going to be rendered as a group box
*
* @return True if it will be a group box, false if it will be a tab
*/
virtual bool isGroupBox() const;
/**
* Get a list of the children elements of this container
*
* @return A list of elements
*/
QList<QgsAttributeEditorElement*> children() const;
/**
* Traverses the element tree to find any element of the specified type
*
* @param type The type which should be searched
*
* @return A list of elements of the type which has been searched for
*/
virtual QList<QgsAttributeEditorElement*> findElements( AttributeEditorType type ) const;
/**
* Clear all children from this container.
*/
void clear();
/**
* Change the name of this container
*/
void setName( const QString& name );
/**
* Get the number of columns in this group
*/
int columnCount() const;
/**
* Set the number of columns in this group
*/
void setColumnCount( int columnCount );
/**
* Creates a deep copy of this element. To be implemented by subclasses.
*
* @note Added in QGIS 3.0
*/
virtual QgsAttributeEditorElement* clone(QgsAttributeEditorElement* parent) const /Factory/;
};
/** \ingroup core
* This element will load a field's widget onto the form.
*/
class QgsAttributeEditorField : public QgsAttributeEditorElement
{
%TypeHeaderCode
#include <qgsattributeeditorelement.h>
%End
public:
/**
* Creates a new attribute editor element which represents a field
*
* @param name The name of the element
* @param idx The index of the field which should be embedded
* @param parent The parent of this widget (used as container)
*/
QgsAttributeEditorField( const QString& name, int idx, QgsAttributeEditorElement *parent );
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Return the index of the field
* @return
*/
int idx() const;
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const /Factory/;
};
/** \ingroup core
* This element will load a relation editor onto the form.
*/
class QgsAttributeEditorRelation : QgsAttributeEditorElement
{
%TypeHeaderCode
#include <qgsattributeeditorelement.h>
%End
public:
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relationId The id of the relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QString &relationId, QgsAttributeEditorElement* parent );
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relation The relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QgsRelation& relation, QgsAttributeEditorElement* parent );
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Get the id of the relation which shall be embedded
*
* @return the id
*/
const QgsRelation& relation() const;
/**
* Initializes the relation from the id
*
* @param relManager The relation manager to use for the initialization
* @return true if the relation was found in the relationmanager
*/
bool init( QgsRelationManager* relManager );
virtual QgsAttributeEditorElement* clone(QgsAttributeEditorElement* parent) const /Factory/;
};

View File

@ -15,249 +15,7 @@
* *
***************************************************************************/
class QgsAttributeEditorElement : QObject
{
%TypeHeaderCode
#include "qgsvectorlayer.h"
%End
%ConvertToSubClassCode
QgsAttributeEditorElement* e = qobject_cast<QgsAttributeEditorElement*>( sipCpp );
sipType = 0;
if ( e )
{
switch ( e->type() )
{
case QgsAttributeEditorElement::AeTypeContainer: sipType = sipType_QgsAttributeEditorContainer; break;
case QgsAttributeEditorElement::AeTypeField: sipType = sipType_QgsAttributeEditorField; break;
case QgsAttributeEditorElement::AeTypeRelation: sipType = sipType_QgsAttributeEditorRelation; break;
}
}
%End
public:
enum AttributeEditorType
{
AeTypeContainer,
AeTypeField,
AeTypeRelation,
AeTypeInvalid
};
/**
* Constructor
*
* @param type The type of the new element. Should never
* @param name
* @param parent
*/
QgsAttributeEditorElement( AttributeEditorType type, const QString& name, QObject *parent /TransferThis/ = NULL );
//! Destructor
virtual ~QgsAttributeEditorElement();
/**
* Return the name of this element
*
* @return The name for this element
*/
QString name() const;
/**
* The type of this element
*
* @return The type
*/
AttributeEditorType type() const;
/**
* Is reimplemented in classes inheriting from this to serialize it.
*
* @param doc The QDomDocument which is used to create new XML elements
*
* @return An DOM element which represents this element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const = 0;
};
class QgsAttributeEditorContainer : QgsAttributeEditorElement
{
%TypeHeaderCode
#include "qgsvectorlayer.h"
%End
public:
/**
* Creates a new attribute editor container
*
* @param name The name to show as title
* @param parent The parent. May be another container.
*/
QgsAttributeEditorContainer( const QString& name, QObject *parent /TransferThis/ );
//! Destructor
~QgsAttributeEditorContainer();
/**
* Will serialize this containers information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Add a child element to this container. This may be another container, a field or a relation.
*
* @param element The element to add as child
*/
virtual void addChildElement( QgsAttributeEditorElement *widget );
/**
* Determines if this container is rendered as collapsible group box or tab in a tabwidget
*
* @param isGroupBox If true, this will be a group box
*/
virtual void setIsGroupBox( bool isGroupBox );
/**
* Returns if this container is going to be rendered as a group box
*
* @return True if it will be a group box, false if it will be a tab
*/
virtual bool isGroupBox() const;
/**
* Get a list of the children elements of this container
*
* @return A list of elements
*/
QList<QgsAttributeEditorElement*> children() const;
/**
* Traverses the element tree to find any element of the specified type
*
* @param type The type which should be searched
*
* @return A list of elements of the type which has been searched for
*/
virtual QList<QgsAttributeEditorElement*> findElements( AttributeEditorType type ) const;
/**
* Change the name of this container
*
* @param name
*/
void setName( const QString& name );
/**
* Get the number of columns in this group
*/
int columnCount() const;
/**
* Set the number of columns in this group
*/
void setColumnCount( int columnCount );
};
/**
* This element will load a field's widget onto the form.
*/
class QgsAttributeEditorField : QgsAttributeEditorElement
{
%TypeHeaderCode
#include "qgsvectorlayer.h"
%End
public:
/**
* Creates a new attribute editor element which represents a field
*
* @param name The name of the element
* @param idx The index of the field which should be embedded
* @param parent The parent of this widget (used as container)
*/
QgsAttributeEditorField( const QString& name, int idx, QObject *parent /TransferThis/ );
//! Destructor
~QgsAttributeEditorField();
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Return the index of the field
* @return
*/
int idx() const;
};
/**
* This element will load a relation editor onto the form.
*
* @note Added in 2.1
*/
class QgsAttributeEditorRelation : QgsAttributeEditorElement
{
public:
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relationId The id of the relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QString &relationId, QObject *parent /TransferThis/ );
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relation The relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QgsRelation& relation, QObject *parent /TransferThis/);
//! Destructor
~QgsAttributeEditorRelation();
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const;
/**
* Get the id of the relation which shall be embedded
*
* @return the id
*/
const QgsRelation& relation() const;
/**
* Initializes the relation from the id
*
* @param relManager The relation manager to use for the initialization
* @return true if the relation was found in the relationmanager
*/
bool init( QgsRelationManager *relManager );
};
class QgsEditFormConfig : QObject
class QgsEditFormConfig
{
%TypeHeaderCode
#include <qgseditformconfig.h>
@ -315,7 +73,7 @@ class QgsEditFormConfig : QObject
*
* Adds a new tab to the layout. Should be a QgsAttributeEditorContainer.
*/
void addTab( QgsAttributeEditorElement* data );
void addTab( QgsAttributeEditorElement* data /Transfer/ );
/**
* Returns a list of tabs for EditorLayout::TabLayout.
@ -327,6 +85,13 @@ class QgsEditFormConfig : QObject
*/
void clearTabs();
/**
* Get the invisible root container for the drag and drop designer form (EditorLayout::TabLayout).
*
* @note Added in QGIS 3
*/
QgsAttributeEditorContainer* invisibleRootContainer();
/** Get the active layout style for the attribute editor for this layer */
EditorLayout layout();
@ -469,7 +234,7 @@ class QgsEditFormConfig : QObject
* This returns true if the field is manually set to read only or if the field
* does not support editing like joins or virtual fields.
*/
bool readOnly( int idx );
bool readOnly( int idx ) const;
/**
* If set to false, the widget at the given index will be read-only.
@ -511,7 +276,7 @@ class QgsEditFormConfig : QObject
/**
* Returns if the field at fieldidx should be treated as NOT NULL value
*/
bool notNull( int fieldidx) const;
bool notNull( int fieldidx ) const;
/**
* Set if the field at fieldidx should be treated as NOT NULL value
*/
@ -522,7 +287,7 @@ class QgsEditFormConfig : QObject
* while if it returns false, the widget will receive its label on the left hand side.
* Labeling on top leaves more horizontal space for the widget itself.
**/
bool labelOnTop( int idx );
bool labelOnTop( int idx ) const;
/**
* If this is set to true, the widget at the given index will receive its label on
@ -552,7 +317,7 @@ class QgsEditFormConfig : QObject
void setInitFunction( const QString& function );
/**
* Get python code for edit form initialization from the configuration dialog.
* Get python code for edit form initialization.
*/
QString initCode() const;
@ -581,8 +346,8 @@ class QgsEditFormConfig : QObject
*/
PythonInitCodeSource initCodeSource() const;
/** Set if python code shall be used for edit form initialization */
void setInitCodeSource( const PythonInitCodeSource initCodeSource );
/** Set if python code shall be used for edit form initialization and its origin */
void setInitCodeSource( PythonInitCodeSource initCodeSource );
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
FeatureFormSuppress suppress() const;
@ -606,5 +371,5 @@ class QgsEditFormConfig : QObject
/**
* Deserialize drag and drop designer elements.
*/
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement* parent );
};

View File

@ -323,45 +323,6 @@ class QgsVectorLayer : QgsMapLayer
%End
public:
struct GroupData
{
GroupData();
GroupData( const QString& name, const QList<QString>& fields );
QString mName;
QList<QString> mFields;
};
struct TabData
{
TabData();
TabData( const QString& name, const QList<QString>& fields, const QList<QgsVectorLayer::GroupData>& groups );
QString mName;
QList<QString> mFields;
QList<QgsVectorLayer::GroupData> mGroups;
};
enum EditorLayout
{
GeneratedLayout,
TabLayout,
UiFileLayout
};
struct ValueRelationData
{
ValueRelationData();
ValueRelationData( const QString& layer, const QString& key, const QString& value, bool allowNull, bool orderByValue,
bool allowMulti = false,
const QString& filterExpression = QString::null );
QString mLayer;
QString mKey;
QString mValue;
QString mFilterExpression;
bool mAllowNull;
bool mOrderByValue;
bool mAllowMulti; /* allow selection of multiple keys */
};
//! Result of an edit operation
enum EditResult
@ -718,12 +679,6 @@ class QgsVectorLayer : QgsMapLayer
*/
virtual QString loadNamedStyle( const QString &theURI, bool &theResultFlag );
/** Convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
* @param elem the DOM element
* @param parent the QObject which will own this object
*/
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );
/** Read the symbology for the current layer from the Dom node supplied.
* @param node node that will contain the symbology definition for this layer.
* @param errorMessage reference to string that will be updated with any error messages
@ -1130,12 +1085,7 @@ class QgsVectorLayer : QgsMapLayer
*
* @note Added in QGIS 2.14
*/
QgsEditFormConfig* editFormConfig() const;
/**
* Clears all the tabs for the attribute editor form
*/
void clearAttributeEditorWidgets();
QgsEditFormConfig editFormConfig() const;
/**
* Returns the alias of an attribute name or a null string if there is no alias.
@ -1218,9 +1168,6 @@ class QgsVectorLayer : QgsMapLayer
/** Set annotation form for layer */
void setAnnotationForm( const QString& ui );
/** Access value relation widget data */
ValueRelationData valueRelation( int idx ) const;
/**
* Get relations, where the foreign key is on this layer
*

View File

@ -249,8 +249,8 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
bool foundFieldThatCanBeExportedAsDisplayedValue = false;
for ( int i = 0; i < mLayer->fields().size(); ++i )
{
if ( mLayer->editFormConfig()->widgetType( i ) != "TextEdit" &&
QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig()->widgetType( i ) ) )
if ( mLayer->editFormConfig().widgetType( i ) != "TextEdit" &&
QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig().widgetType( i ) ) )
{
foundFieldThatCanBeExportedAsDisplayedValue = true;
break;
@ -287,8 +287,8 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
{
QgsEditorWidgetFactory *factory = nullptr;
if ( flags == Qt::ItemIsEnabled &&
mLayer->editFormConfig()->widgetType( i ) != "TextEdit" &&
( factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig()->widgetType( i ) ) ) )
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

@ -6147,10 +6147,10 @@ QVariant QgisAppFieldValueConverter::convert( int idx, const QVariant& value )
{
return value;
}
QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig()->widgetType( idx ) );
QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig().widgetType( idx ) );
if ( factory )
{
QgsEditorWidgetConfig cfg( mLayer->editFormConfig()->widgetConfig( idx ) );
QgsEditorWidgetConfig cfg( mLayer->editFormConfig().widgetConfig( idx ) );
return QVariant( factory->representValue( mLayer, idx, cfg, QVariant(), value ) );
}
return value;

View File

@ -68,7 +68,7 @@ QgsExpressionContext QgsAttributeTableDialog::createExpressionContext() const
void QgsAttributeTableDialog::updateMultiEditButtonState()
{
if ( mLayer->editFormConfig()->layout() == QgsEditFormConfig::UiFileLayout )
if ( mLayer->editFormConfig().layout() == QgsEditFormConfig::UiFileLayout )
return;
mActionToggleMultiEdit->setEnabled( mLayer->isEditable() );
@ -298,7 +298,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
connect( mActionSearchForm, SIGNAL( toggled( bool ) ), mMainView, SLOT( toggleSearchMode( bool ) ) );
updateMultiEditButtonState();
if ( mLayer->editFormConfig()->layout() == QgsEditFormConfig::UiFileLayout )
if ( mLayer->editFormConfig().layout() == QgsEditFormConfig::UiFileLayout )
{
//not supported with custom UI
mActionToggleMultiEdit->setEnabled( false );
@ -391,7 +391,7 @@ void QgsAttributeTableDialog::columnBoxInit()
if ( idx < 0 )
continue;
if ( mLayer->editFormConfig()->widgetType( idx ) != "Hidden" )
if ( mLayer->editFormConfig().widgetType( idx ) != "Hidden" )
{
QIcon icon = mLayer->fields().iconForField( idx );
QString alias = mLayer->attributeDisplayName( idx );
@ -527,8 +527,8 @@ void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
int fldIdx = mLayer->fieldNameIndex( fieldName );
if ( fldIdx < 0 )
return;
const QString widgetType = mLayer->editFormConfig()->widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( fldIdx );
const QString widgetType = mLayer->editFormConfig().widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( fldIdx );
mCurrentSearchWidgetWrapper = QgsEditorWidgetRegistry::instance()->
createSearchWidget( widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer, mEditorContext );
if ( mCurrentSearchWidgetWrapper->applyDirectly() )

View File

@ -173,7 +173,7 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo
bool isDisabledAttributeValuesDlg = ( fields.count() == 0 ) || settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
// override application-wide setting with any layer setting
switch ( mLayer->editFormConfig()->suppress() )
switch ( mLayer->editFormConfig().suppress() )
{
case QgsEditFormConfig::SuppressOn:
isDisabledAttributeValuesDlg = true;

View File

@ -137,8 +137,8 @@ void QgsFieldsProperties::init()
{
loadRows();
mEditorLayoutComboBox->setCurrentIndex( mLayer->editFormConfig()->layout() );
mFormSuppressCmbBx->setCurrentIndex( mLayer->editFormConfig()->suppress() );
mEditorLayoutComboBox->setCurrentIndex( mLayer->editFormConfig().layout() );
mFormSuppressCmbBx->setCurrentIndex( mLayer->editFormConfig().suppress() );
loadAttributeEditorTree();
}
@ -238,7 +238,7 @@ void QgsFieldsProperties::loadAttributeEditorTree()
mDesignerTree->setAcceptDrops( true );
mDesignerTree->setDragDropMode( QAbstractItemView::DragDrop );
Q_FOREACH ( QgsAttributeEditorElement* wdg, mLayer->editFormConfig()->tabs() )
Q_FOREACH ( QgsAttributeEditorElement* wdg, mLayer->editFormConfig().tabs() )
{
loadAttributeEditorTreeItem( wdg, mDesignerTree->invisibleRootItem() );
}
@ -382,7 +382,7 @@ 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() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig()->widgetConfig( relation.id() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( relation.id() );
QVariant nmrelcfg = cfg.value( "nm-rel" );
@ -827,7 +827,7 @@ void QgsFieldsProperties::updateFieldRenamingStatus()
}
}
QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTreeWidgetItem* item, QObject *parent , bool forceGroup )
QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTreeWidgetItem* item, QgsAttributeEditorElement* parent , bool forceGroup )
{
QgsAttributeEditorElement *widgetDef = nullptr;
@ -926,14 +926,14 @@ void QgsFieldsProperties::apply()
int idx = mFieldsList->item( i, attrIdCol )->text().toInt();
FieldConfig cfg = configForRow( i );
mLayer->editFormConfig()->setReadOnly( i, !cfg.mEditable );
mLayer->editFormConfig()->setLabelOnTop( i, cfg.mLabelOnTop );
mLayer->editFormConfig()->setNotNull( i, cfg.mNotNull );
mLayer->editFormConfig()->setExpressionDescription( i, cfg.mConstraintDescription );
mLayer->editFormConfig()->setExpression( i, cfg.mConstraint );
mLayer->editFormConfig().setReadOnly( i, !cfg.mEditable );
mLayer->editFormConfig().setLabelOnTop( i, cfg.mLabelOnTop );
mLayer->editFormConfig().setNotNull( i, cfg.mNotNull );
mLayer->editFormConfig().setExpressionDescription( i, cfg.mConstraintDescription );
mLayer->editFormConfig().setExpression( i, cfg.mConstraint );
mLayer->editFormConfig()->setWidgetType( idx, cfg.mEditorWidgetType );
mLayer->editFormConfig()->setWidgetConfig( idx, cfg.mEditorWidgetConfig );
mLayer->editFormConfig().setWidgetType( idx, cfg.mEditorWidgetType );
mLayer->editFormConfig().setWidgetConfig( idx, cfg.mEditorWidgetConfig );
if ( mFieldsList->item( i, attrWMSCol )->checkState() == Qt::Unchecked )
{
@ -946,25 +946,26 @@ void QgsFieldsProperties::apply()
}
// tabs and groups
mLayer->clearAttributeEditorWidgets();
QgsEditFormConfig editFormConfig = mLayer->editFormConfig();
editFormConfig.clearTabs();
for ( int t = 0; t < mDesignerTree->invisibleRootItem()->childCount(); t++ )
{
QTreeWidgetItem* tabItem = mDesignerTree->invisibleRootItem()->child( t );
mLayer->editFormConfig()->addTab( createAttributeEditorWidget( tabItem, mLayer, false ) );
editFormConfig.addTab( createAttributeEditorWidget( tabItem, nullptr, false ) );
}
mLayer->editFormConfig()->setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
editFormConfig.setLayout(( QgsEditFormConfig::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
if ( mEditorLayoutComboBox->currentIndex() == QgsEditFormConfig::UiFileLayout )
mLayer->editFormConfig()->setUiForm( mEditFormLineEdit->text() );
editFormConfig.setUiForm( mEditFormLineEdit->text() );
// Init function configuration
mLayer->editFormConfig()->setInitFunction( mInitFunctionLineEdit->text() );
mLayer->editFormConfig()->setInitCode( mInitCodeEditorPython->text() );
mLayer->editFormConfig()->setInitFilePath( mInitFilePathLineEdit->text() );
mLayer->editFormConfig()->setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource )mInitCodeSourceComboBox->currentIndex() );
editFormConfig.setInitFunction( mInitFunctionLineEdit->text() );
editFormConfig.setInitCode( mInitCodeEditorPython->text() );
editFormConfig.setInitFilePath( mInitFilePathLineEdit->text() );
editFormConfig.setInitCodeSource(( QgsEditFormConfig::PythonInitCodeSource )mInitCodeSourceComboBox->currentIndex() );
mLayer->editFormConfig()->setSuppress(( QgsEditFormConfig::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
editFormConfig.setSuppress(( QgsEditFormConfig::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
mLayer->setExcludeAttributesWms( excludeAttributesWMS );
mLayer->setExcludeAttributesWfs( excludeAttributesWFS );
@ -986,8 +987,10 @@ void QgsFieldsProperties::apply()
QString relationName = itemData.name();
mLayer->editFormConfig()->setWidgetConfig( relationName, cfg );
editFormConfig.setWidgetConfig( relationName, cfg );
}
mLayer->setEditFormConfig( editFormConfig );
}
/*
* FieldConfig implementation
@ -1006,15 +1009,15 @@ QgsFieldsProperties::FieldConfig::FieldConfig()
QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
: mButton( nullptr )
{
mEditable = !layer->editFormConfig()->readOnly( idx );
mEditable = !layer->editFormConfig().readOnly( idx );
mEditableEnabled = layer->fields().fieldOrigin( idx ) != QgsFields::OriginJoin
&& layer->fields().fieldOrigin( idx ) != QgsFields::OriginExpression;
mLabelOnTop = layer->editFormConfig()->labelOnTop( idx );
mNotNull = layer->editFormConfig()->notNull( idx );
mConstraint = layer->editFormConfig()->expression( idx );
mConstraintDescription = layer->editFormConfig()->expressionDescription( idx );
mEditorWidgetType = layer->editFormConfig()->widgetType( idx );
mEditorWidgetConfig = layer->editFormConfig()->widgetConfig( idx );
mLabelOnTop = layer->editFormConfig().labelOnTop( idx );
mNotNull = layer->editFormConfig().notNull( idx );
mConstraint = layer->editFormConfig().expression( idx );
mConstraintDescription = layer->editFormConfig().expressionDescription( idx );
mEditorWidgetType = layer->editFormConfig().widgetType( idx );
mEditorWidgetConfig = layer->editFormConfig().widgetConfig( idx );
}
/*

View File

@ -119,7 +119,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
/** Creates the a proper item to save from the tree
* @return A widget definition. Containing another container or the final field
*/
QgsAttributeEditorElement* createAttributeEditorWidget( QTreeWidgetItem* item, QObject *parent, bool forceGroup = true );
QgsAttributeEditorElement* createAttributeEditorWidget( QTreeWidgetItem* item, QgsAttributeEditorElement* parent, bool forceGroup = true );
void init();
void apply();

View File

@ -479,7 +479,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
if ( i >= fields.count() )
break;
if ( vlayer->editFormConfig()->widgetType( i ) == "Hidden" )
if ( vlayer->editFormConfig().widgetType( i ) == "Hidden" )
{
continue;
}
@ -669,7 +669,7 @@ QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const
QVariant cache;
QMap<QString, QVariant>& layerCaches = mWidgetCaches[vlayer->id()];
QString widgetType = vlayer->editFormConfig()->widgetType( fieldName );
QString widgetType = vlayer->editFormConfig().widgetType( fieldName );
QgsEditorWidgetFactory* factory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
int idx = vlayer->fieldNameIndex( fieldName );
@ -683,11 +683,11 @@ QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const
}
else
{
cache = factory->createCache( vlayer, idx, vlayer->editFormConfig()->widgetConfig( fieldName ) );
cache = factory->createCache( vlayer, idx, vlayer->editFormConfig().widgetConfig( fieldName ) );
layerCaches.insert( fieldName, cache );
}
return factory->representValue( vlayer, idx, vlayer->editFormConfig()->widgetConfig( fieldName ), cache, value );
return factory->representValue( vlayer, idx, vlayer->editFormConfig().widgetConfig( fieldName ), cache, value );
}
void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,

View File

@ -116,8 +116,8 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
mHiddenAttributes.clear();
for ( int idx = 0; idx < mFields.count(); ++idx )
{
if ( mVectorLayer->editFormConfig()->widgetType( idx ) == "Hidden" ||
mVectorLayer->editFormConfig()->widgetType( idx ) == "Immutable" )
if ( mVectorLayer->editFormConfig().widgetType( idx ) == "Hidden" ||
mVectorLayer->editFormConfig().widgetType( idx ) == "Immutable" )
{
mHiddenAttributes.insert( idx );
continue;

View File

@ -1297,6 +1297,6 @@ void QgsVectorLayerProperties::updateVariableEditor()
void QgsVectorLayerProperties::updateFieldsPropertiesDialog()
{
QgsEditFormConfig* cfg = mLayer->editFormConfig();
mFieldsPropertiesDialog->setEditFormInit( cfg->uiForm(), cfg->initFunction(), cfg->initCode(), cfg->initFilePath(), cfg->initCodeSource() );
QgsEditFormConfig cfg = mLayer->editFormConfig();
mFieldsPropertiesDialog->setEditFormInit( cfg.uiForm(), cfg.initFunction(), cfg.initCode(), cfg.initFilePath(), cfg.initCodeSource() );
}

View File

@ -81,6 +81,7 @@ SET(QGIS_CORE_SRCS
qgsactionmanager.cpp
qgsaggregatecalculator.cpp
qgsattributetableconfig.cpp
qgsattributeeditorelement.cpp
qgsbrowsermodel.cpp
qgscachedfeatureiterator.cpp
qgscacheindex.cpp
@ -453,7 +454,6 @@ SET(QGIS_CORE_MOC_HDRS
qgsdataitem.h
qgsdataprovider.h
qgsdbfilterproxymodel.h
qgseditformconfig.h
qgsfeedback.h
qgsfield.h
qgsgeometryvalidator.h
@ -604,6 +604,7 @@ SET(QGIS_CORE_HDRS
qgsannotation.h
qgsattributetableconfig.h
qgsattributeaction.h
qgsattributeeditorelement.h
qgscachedfeatureiterator.h
qgscacheindex.h
qgscacheindexfeatureid.h
@ -632,6 +633,7 @@ SET(QGIS_CORE_HDRS
qgsdbfilterproxymodel.h
qgsdiagramrenderer.h
qgsdistancearea.h
qgseditformconfig.h
qgseditorwidgetconfig.h
qgsfeaturefilterprovider.h
qgserror.h

View File

@ -0,0 +1,106 @@
/***************************************************************************
qgsattributeeditorelement.cpp - QgsAttributeEditorElement
---------------------
begin : 18.8.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsattributeeditorelement.h"
#include "qgsrelationmanager.h"
QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorContainer" );
elem.setAttribute( "name", mName );
elem.setAttribute( "columnCount", mColumnCount );
elem.setAttribute( "groupBox", mIsGroupBox ? 1 : 0 );
Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
{
elem.appendChild( child->toDomElement( doc ) );
}
return elem;
}
void QgsAttributeEditorContainer::addChildElement( QgsAttributeEditorElement *widget )
{
mChildren.append( widget );
}
void QgsAttributeEditorContainer::setName( const QString& name )
{
mName = name;
}
QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( QgsAttributeEditorElement::AttributeEditorType type ) const
{
QList<QgsAttributeEditorElement*> results;
Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
{
if ( elem->type() == type )
{
results.append( elem );
}
if ( elem->type() == AeTypeContainer )
{
QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
if ( cont )
results += cont->findElements( type );
}
}
return results;
}
void QgsAttributeEditorContainer::clear()
{
qDeleteAll( mChildren );
mChildren.clear();
}
QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorField" );
elem.setAttribute( "name", mName );
elem.setAttribute( "index", mIdx );
return elem;
}
QgsAttributeEditorElement* QgsAttributeEditorField::clone( QgsAttributeEditorElement* parent ) const
{
QgsAttributeEditorField* element = new QgsAttributeEditorField( name(), mIdx, parent );
return element;
}
QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorRelation" );
elem.setAttribute( "name", mName );
elem.setAttribute( "relation", mRelation.id() );
return elem;
}
bool QgsAttributeEditorRelation::init( QgsRelationManager* relationManager )
{
mRelation = relationManager->relation( mRelationId );
return mRelation.isValid();
}
QgsAttributeEditorElement* QgsAttributeEditorRelation::clone( QgsAttributeEditorElement* parent ) const
{
QgsAttributeEditorRelation* element = new QgsAttributeEditorRelation( name(), mRelationId, parent );
element->mRelation = mRelation;
return element;
}

View File

@ -0,0 +1,306 @@
/***************************************************************************
qgsattributeeditorelement.h - QgsAttributeEditorElement
---------------------
begin : 18.8.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSATTRIBUTEEDITORELEMENT_H
#define QGSATTRIBUTEEDITORELEMENT_H
#include "qgsrelation.h"
class QgsRelationManager;
/** \ingroup core
* This is an abstract base class for any elements of a drag and drop form.
*
* This can either be a container which will be represented on the screen
* as a tab widget or ca collapsible group box. Or it can be a field which will
* then be represented based on the QgsEditorWidget type and configuration.
* Or it can be a relation and embed the form of several children of another
* layer.
*/
class CORE_EXPORT QgsAttributeEditorElement
{
public:
enum AttributeEditorType
{
AeTypeContainer, //!< A container
AeTypeField, //!< A field
AeTypeRelation, //!< A relation
AeTypeInvalid //!< Invalid
};
/**
* Constructor
*
* @param type The type of the new element. Should never
* @param name
* @param parent
*/
QgsAttributeEditorElement( AttributeEditorType type, const QString& name, QgsAttributeEditorElement* parent = nullptr )
: mType( type )
, mName( name )
, mParent( parent )
{}
//! Destructor
virtual ~QgsAttributeEditorElement() {}
/**
* Return the name of this element
*
* @return The name for this element
*/
QString name() const { return mName; }
/**
* The type of this element
*
* @return The type
*/
AttributeEditorType type() const { return mType; }
/**
* Get the parent of this element.
*
* @note Added in QGIS 3.0
*/
QgsAttributeEditorElement* parent() const { return mParent; }
/**
* Is reimplemented in classes inheriting from this to serialize it.
*
* @param doc The QDomDocument which is used to create new XML elements
*
* @return An DOM element which represents this element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const = 0;
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const = 0;
protected:
AttributeEditorType mType;
QString mName;
QgsAttributeEditorElement* mParent;
};
/** \ingroup core
* This is a container for attribute editors, used to group them visually in the
* attribute form if it is set to the drag and drop designer.
*/
class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement
{
public:
/**
* Creates a new attribute editor container
*
* @param name The name to show as title
* @param parent The parent. May be another container.
*/
QgsAttributeEditorContainer( const QString& name, QgsAttributeEditorElement* parent )
: QgsAttributeEditorElement( AeTypeContainer, name, parent )
, mIsGroupBox( true )
, mColumnCount( 1 )
{}
//! Destructor
virtual ~QgsAttributeEditorContainer();
/**
* Will serialize this containers information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Add a child element to this container. This may be another container, a field or a relation.
*
* @param element The element to add as child
*/
virtual void addChildElement( QgsAttributeEditorElement* element );
/**
* Determines if this container is rendered as collapsible group box or tab in a tabwidget
*
* @param isGroupBox If true, this will be a group box
*/
virtual void setIsGroupBox( bool isGroupBox ) { mIsGroupBox = isGroupBox; }
/**
* Returns if this container is going to be rendered as a group box
*
* @return True if it will be a group box, false if it will be a tab
*/
virtual bool isGroupBox() const { return mIsGroupBox; }
/**
* Get a list of the children elements of this container
*
* @return A list of elements
*/
QList<QgsAttributeEditorElement*> children() const { return mChildren; }
/**
* Traverses the element tree to find any element of the specified type
*
* @param type The type which should be searched
*
* @return A list of elements of the type which has been searched for
*/
virtual QList<QgsAttributeEditorElement*> findElements( AttributeEditorType type ) const;
/**
* Clear all children from this container.
*/
void clear();
/**
* Change the name of this container
*/
void setName( const QString& name );
/**
* Get the number of columns in this group
*/
int columnCount() const;
/**
* Set the number of columns in this group
*/
void setColumnCount( int columnCount );
/**
* Creates a deep copy of this element. To be implemented by subclasses.
*
* @note Added in QGIS 3.0
*/
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const override;
private:
bool mIsGroupBox;
QList<QgsAttributeEditorElement*> mChildren;
int mColumnCount;
};
/** \ingroup core
* This element will load a field's widget onto the form.
*/
class CORE_EXPORT QgsAttributeEditorField : public QgsAttributeEditorElement
{
public:
/**
* Creates a new attribute editor element which represents a field
*
* @param name The name of the element
* @param idx The index of the field which should be embedded
* @param parent The parent of this widget (used as container)
*/
QgsAttributeEditorField( const QString& name, int idx, QgsAttributeEditorElement *parent )
: QgsAttributeEditorElement( AeTypeField, name, parent )
, mIdx( idx )
{}
//! Destructor
virtual ~QgsAttributeEditorField() {}
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Return the index of the field
* @return
*/
int idx() const { return mIdx; }
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const override;
private:
int mIdx;
};
/** \ingroup core
* This element will load a relation editor onto the form.
*/
class CORE_EXPORT QgsAttributeEditorRelation : public QgsAttributeEditorElement
{
public:
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relationId The id of the relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QString &relationId, QgsAttributeEditorElement* parent )
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
, mRelationId( relationId ) {}
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relation The relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QgsRelation& relation, QgsAttributeEditorElement* parent )
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
, mRelationId( relation.id() )
, mRelation( relation ) {}
//! Destructor
virtual ~QgsAttributeEditorRelation() {}
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Get the id of the relation which shall be embedded
*
* @return the id
*/
const QgsRelation& relation() const { return mRelation; }
/**
* Initializes the relation from the id
*
* @param relManager The relation manager to use for the initialization
* @return true if the relation was found in the relationmanager
*/
bool init( QgsRelationManager* relManager );
virtual QgsAttributeEditorElement* clone( QgsAttributeEditorElement* parent ) const override;
private:
QString mRelationId;
QgsRelation mRelation;
};
#endif // QGSATTRIBUTEEDITORELEMENT_H

View File

@ -12,78 +12,160 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgseditformconfig_p.h"
#include "qgseditformconfig.h"
#include "qgsproject.h"
#include "qgsrelationmanager.h"
QgsEditFormConfig::QgsEditFormConfig( QObject* parent )
: QObject( parent )
, mEditorLayout( GeneratedLayout )
, mInitCodeSource( CodeSourceNone )
, mSuppressForm( SuppressDefault )
QgsAttributeEditorContainer::~QgsAttributeEditorContainer()
{
qDeleteAll( mChildren );
}
QgsEditFormConfig::QgsEditFormConfig()
: d( new QgsEditFormConfigPrivate() )
{
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
}
QString QgsEditFormConfig::widgetType( int fieldIdx ) const
{
if ( fieldIdx < 0 || fieldIdx >= mFields.count() )
if ( fieldIdx < 0 || fieldIdx >= d->mFields.count() )
return "TextEdit";
return mEditorWidgetTypes.value( mFields.at( fieldIdx ).name(), "TextEdit" );
return d->mEditorWidgetTypes.value( d->mFields.at( fieldIdx ).name(), "TextEdit" );
}
QString QgsEditFormConfig::widgetType( const QString& fieldName ) const
{
return mEditorWidgetTypes.value( fieldName, "TextEdit" );
return d->mEditorWidgetTypes.value( fieldName, "TextEdit" );
}
QgsEditorWidgetConfig QgsEditFormConfig::widgetConfig( int fieldIdx ) const
{
if ( fieldIdx < 0 || fieldIdx >= mFields.count() )
if ( fieldIdx < 0 || fieldIdx >= d->mFields.count() )
return QgsEditorWidgetConfig();
return mWidgetConfigs.value( mFields.at( fieldIdx ).name() );
return d->mWidgetConfigs.value( d->mFields.at( fieldIdx ).name() );
}
QgsEditorWidgetConfig QgsEditFormConfig::widgetConfig( const QString& widgetName ) const
{
return mWidgetConfigs.value( widgetName );
return d->mWidgetConfigs.value( widgetName );
}
void QgsEditFormConfig::setFields( const QgsFields& fields )
{
mFields = fields;
d.detach();
d->mFields = fields;
}
void QgsEditFormConfig::onRelationsLoaded()
{
QList<QgsAttributeEditorElement*> relations = d->mInvisibleRootContainer->findElements( QgsAttributeEditorElement::AeTypeRelation );
Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
{
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
if ( !rel )
continue;
rel->init( QgsProject::instance()->relationManager() );
}
}
void QgsEditFormConfig::setWidgetType( int attrIdx, const QString& widgetType )
{
if ( attrIdx >= 0 && attrIdx < mFields.count() )
mEditorWidgetTypes[ mFields.at( attrIdx ).name()] = widgetType;
if ( attrIdx >= 0 && attrIdx < d->mFields.count() )
d->mEditorWidgetTypes[ d->mFields.at( attrIdx ).name()] = widgetType;
}
void QgsEditFormConfig::setWidgetConfig( int attrIdx, const QgsEditorWidgetConfig& config )
{
if ( attrIdx >= 0 && attrIdx < mFields.count() )
mWidgetConfigs[ mFields.at( attrIdx ).name()] = config;
if ( attrIdx >= 0 && attrIdx < d->mFields.count() )
{
d.detach();
d->mWidgetConfigs[ d->mFields.at( attrIdx ).name()] = config;
}
}
void QgsEditFormConfig::setWidgetConfig( const QString& widgetName, const QgsEditorWidgetConfig& config )
{
mWidgetConfigs[widgetName] = config;
d.detach();
d->mWidgetConfigs[widgetName] = config;
}
bool QgsEditFormConfig::removeWidgetConfig( const QString &widgetName )
bool QgsEditFormConfig::removeWidgetConfig( const QString& widgetName )
{
return mWidgetConfigs.remove( widgetName ) != 0;
d.detach();
return d->mWidgetConfigs.remove( widgetName ) != 0;
}
bool QgsEditFormConfig::removeWidgetConfig( int fieldIdx )
{
if ( fieldIdx < 0 || fieldIdx >= mFields.count() )
if ( fieldIdx < 0 || fieldIdx >= d->mFields.count() )
return false;
return mWidgetConfigs.remove( mFields.at( fieldIdx ).name() );
d.detach();
return d->mWidgetConfigs.remove( d->mFields.at( fieldIdx ).name() );
}
QgsEditFormConfig::QgsEditFormConfig( const QgsEditFormConfig& o )
: d( o.d )
{
}
QgsEditFormConfig& QgsEditFormConfig::operator=( const QgsEditFormConfig & o )
{
d = o.d;
return *this;
}
bool QgsEditFormConfig::operator==( const QgsEditFormConfig& o )
{
return d == o.d;
}
QgsEditFormConfig::~QgsEditFormConfig()
{
}
void QgsEditFormConfig::addTab( QgsAttributeEditorElement* data )
{
d.detach();
d->mInvisibleRootContainer->addChildElement( data );
}
QList<QgsAttributeEditorElement*> QgsEditFormConfig::tabs() const
{
return d->mInvisibleRootContainer->children();
}
void QgsEditFormConfig::clearTabs()
{
d.detach();
d->mInvisibleRootContainer->clear();
}
QgsAttributeEditorContainer* QgsEditFormConfig::invisibleRootContainer()
{
return d->mInvisibleRootContainer;
}
QgsEditFormConfig::EditorLayout QgsEditFormConfig::layout() const
{
return d->mEditorLayout;
}
void QgsEditFormConfig::setLayout( QgsEditFormConfig::EditorLayout editorLayout )
{
d.detach();
d->mEditorLayout = editorLayout;
}
QString QgsEditFormConfig::uiForm() const
{
return d->mUiFormPath;
}
void QgsEditFormConfig::setUiForm( const QString& ui )
@ -96,17 +178,17 @@ void QgsEditFormConfig::setUiForm( const QString& ui )
{
setLayout( UiFileLayout );
}
mUiFormPath = ui;
d->mUiFormPath = ui;
}
bool QgsEditFormConfig::readOnly( int idx ) const
{
if ( idx >= 0 && idx < mFields.count() )
if ( idx >= 0 && idx < d->mFields.count() )
{
if ( mFields.fieldOrigin( idx ) == QgsFields::OriginJoin
|| mFields.fieldOrigin( idx ) == QgsFields::OriginExpression )
if ( d->mFields.fieldOrigin( idx ) == QgsFields::OriginJoin
|| d->mFields.fieldOrigin( idx ) == QgsFields::OriginExpression )
return true;
return !mFieldEditables.value( mFields.at( idx ).name(), true );
return !d->mFieldEditables.value( d->mFields.at( idx ).name(), true );
}
else
return false;
@ -114,8 +196,8 @@ bool QgsEditFormConfig::readOnly( int idx ) const
bool QgsEditFormConfig::labelOnTop( int idx ) const
{
if ( idx >= 0 && idx < mFields.count() )
return mLabelOnTop.value( mFields.at( idx ).name(), false );
if ( idx >= 0 && idx < d->mFields.count() )
return d->mLabelOnTop.value( d->mFields.at( idx ).name(), false );
else
return false;
}
@ -124,73 +206,144 @@ QString QgsEditFormConfig::expression( int idx ) const
{
QString expr;
if ( idx >= 0 && idx < mFields.count() )
expr = mConstraints.value( mFields.at( idx ).name(), QString() );
if ( idx >= 0 && idx < d->mFields.count() )
expr = d->mConstraints.value( d->mFields.at( idx ).name(), QString() );
return expr;
}
void QgsEditFormConfig::setExpression( int idx, const QString& str )
{
if ( idx >= 0 && idx < mFields.count() )
mConstraints[ mFields.at( idx ).name()] = str;
if ( idx >= 0 && idx < d->mFields.count() )
{
d.detach();
d->mConstraints[ d->mFields.at( idx ).name()] = str;
}
}
QString QgsEditFormConfig::expressionDescription( int idx ) const
{
QString description;
if ( idx >= 0 && idx < mFields.count() )
description = mConstraintsDescription[ mFields.at( idx ).name()];
if ( idx >= 0 && idx < d->mFields.count() )
description = d->mConstraintsDescription[ d->mFields.at( idx ).name()];
return description;
}
void QgsEditFormConfig::setExpressionDescription( int idx, const QString &descr )
{
if ( idx >= 0 && idx < mFields.count() )
mConstraintsDescription[ mFields.at( idx ).name()] = descr;
if ( idx >= 0 && idx < d->mFields.count() )
{
d.detach();
d->mConstraintsDescription[ d->mFields.at( idx ).name()] = descr;
}
}
bool QgsEditFormConfig::notNull( int idx ) const
{
if ( idx >= 0 && idx < mFields.count() )
return mNotNull.value( mFields.at( idx ).name(), false );
if ( idx >= 0 && idx < d->mFields.count() )
return d->mNotNull.value( d->mFields.at( idx ).name(), false );
else
return false;
}
void QgsEditFormConfig::setReadOnly( int idx, bool readOnly )
{
if ( idx >= 0 && idx < mFields.count() )
mFieldEditables[ mFields.at( idx ).name()] = !readOnly;
if ( idx >= 0 && idx < d->mFields.count() )
{
d.detach();
d->mFieldEditables[ d->mFields.at( idx ).name()] = !readOnly;
}
}
void QgsEditFormConfig::setLabelOnTop( int idx, bool onTop )
{
if ( idx >= 0 && idx < mFields.count() )
mLabelOnTop[ mFields.at( idx ).name()] = onTop;
if ( idx >= 0 && idx < d->mFields.count() )
{
d.detach();
d->mLabelOnTop[ d->mFields.at( idx ).name()] = onTop;
}
}
QString QgsEditFormConfig::initFunction() const
{
return d->mInitFunction;
}
void QgsEditFormConfig::setInitFunction( const QString& function )
{
d.detach();
d->mInitFunction = function;
}
QString QgsEditFormConfig::initCode() const
{
return d->mInitCode;
}
void QgsEditFormConfig::setInitCode( const QString& code )
{
d.detach();
d->mInitCode = code;
}
QString QgsEditFormConfig::initFilePath() const
{
return d->mInitFilePath;
}
void QgsEditFormConfig::setInitFilePath( const QString& filePath )
{
d.detach();
d->mInitFilePath = filePath;
}
QgsEditFormConfig::PythonInitCodeSource QgsEditFormConfig::initCodeSource() const
{
return d->mInitCodeSource;
}
void QgsEditFormConfig::setInitCodeSource( const QgsEditFormConfig::PythonInitCodeSource initCodeSource )
{
d.detach();
d->mInitCodeSource = initCodeSource;
}
QgsEditFormConfig::FeatureFormSuppress QgsEditFormConfig::suppress() const
{
return d->mSuppressForm;
}
void QgsEditFormConfig::setSuppress( QgsEditFormConfig::FeatureFormSuppress s )
{
d.detach();
d->mSuppressForm = s;
}
void QgsEditFormConfig::setNotNull( int idx, bool notnull )
{
if ( idx >= 0 && idx < mFields.count() )
mNotNull[ mFields.at( idx ).name()] = notnull;
if ( idx >= 0 && idx < d->mFields.count() )
{
d.detach();
d->mNotNull[ d->mFields.at( idx ).name()] = notnull;
}
}
void QgsEditFormConfig::readXml( const QDomNode& node )
{
d.detach();
QDomNode editFormNode = node.namedItem( "editform" );
if ( !editFormNode.isNull() )
{
QDomElement e = editFormNode.toElement();
mUiFormPath = QgsProject::instance()->readPath( e.text() );
d->mUiFormPath = QgsProject::instance()->readPath( e.text() );
}
QDomNode editFormInitNode = node.namedItem( "editforminit" );
if ( !editFormInitNode.isNull() )
{
mInitFunction = editFormInitNode.toElement().text();
d->mInitFunction = editFormInitNode.toElement().text();
}
QDomNode editFormInitCodeSourceNode = node.namedItem( "editforminitcodesource" );
@ -210,12 +363,12 @@ void QgsEditFormConfig::readXml( const QDomNode& node )
// For b/w compatibility, check if there's a dot in the function name
// and if yes, transform it in an import statement for the module
// and set the PythonInitCodeSource to CodeSourceDialog
int dotPos = mInitFunction.lastIndexOf( '.' );
int dotPos = d->mInitFunction.lastIndexOf( '.' );
if ( dotPos >= 0 ) // It's a module
{
setInitCodeSource( QgsEditFormConfig::CodeSourceDialog );
setInitCode( QString( "from %1 import %2\n" ).arg( mInitFunction.left( dotPos ), mInitFunction.mid( dotPos + 1 ) ) );
setInitFunction( mInitFunction.mid( dotPos + 1 ) );
setInitCode( QString( "from %1 import %2\n" ).arg( d->mInitFunction.left( dotPos ), d->mInitFunction.mid( dotPos + 1 ) ) );
setInitFunction( d->mInitFunction.mid( dotPos + 1 ) );
}
QDomNode editFormInitFilePathNode = node.namedItem( "editforminitfilepath" );
@ -227,33 +380,33 @@ void QgsEditFormConfig::readXml( const QDomNode& node )
QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
if ( fFSuppNode.isNull() )
{
mSuppressForm = QgsEditFormConfig::SuppressDefault;
d->mSuppressForm = QgsEditFormConfig::SuppressDefault;
}
else
{
QDomElement e = fFSuppNode.toElement();
mSuppressForm = static_cast< QgsEditFormConfig::FeatureFormSuppress >( e.text().toInt() );
d->mSuppressForm = static_cast< QgsEditFormConfig::FeatureFormSuppress >( e.text().toInt() );
}
// tab display
QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
if ( editorLayoutNode.isNull() )
{
mEditorLayout = QgsEditFormConfig::GeneratedLayout;
d->mEditorLayout = QgsEditFormConfig::GeneratedLayout;
}
else
{
if ( editorLayoutNode.toElement().text() == "uifilelayout" )
{
mEditorLayout = QgsEditFormConfig::UiFileLayout;
d->mEditorLayout = QgsEditFormConfig::UiFileLayout;
}
else if ( editorLayoutNode.toElement().text() == "tablayout" )
{
mEditorLayout = QgsEditFormConfig::TabLayout;
d->mEditorLayout = QgsEditFormConfig::TabLayout;
}
else
{
mEditorLayout = QgsEditFormConfig::GeneratedLayout;
d->mEditorLayout = QgsEditFormConfig::GeneratedLayout;
}
}
@ -361,10 +514,12 @@ void QgsEditFormConfig::writeXml( QDomNode& node ) const
{
QDomElement tabsElem = doc.createElement( "attributeEditorForm" );
for ( QList< QgsAttributeEditorElement* >::const_iterator it = mAttributeEditorElements.constBegin(); it != mAttributeEditorElements.constEnd(); ++it )
QDomElement rootElem = d->mInvisibleRootContainer->toDomElement( doc );
QDomNodeList elemList = rootElem.childNodes();
for ( int i = 0; i < elemList.size(); ++i )
{
QDomElement attributeEditorWidgetElem = ( *it )->toDomElement( doc );
tabsElem.appendChild( attributeEditorWidgetElem );
tabsElem.appendChild( elemList.at( i ) );
}
node.appendChild( tabsElem );
@ -375,11 +530,11 @@ void QgsEditFormConfig::writeXml( QDomNode& node ) const
QDomElement widgetsElem = doc.createElement( "widgets" );
QMap<QString, QgsEditorWidgetConfig >::ConstIterator configIt( mWidgetConfigs.constBegin() );
QMap<QString, QgsEditorWidgetConfig >::ConstIterator configIt( d->mWidgetConfigs.constBegin() );
while ( configIt != mWidgetConfigs.constEnd() )
while ( configIt != d->mWidgetConfigs.constEnd() )
{
if ( mFields.indexFromName( configIt.key() ) == -1 )
if ( d->mFields.indexFromName( configIt.key() ) == -1 )
{
QDomElement widgetElem = doc.createElement( "widget" );
widgetElem.setAttribute( "name", configIt.key() );
@ -409,7 +564,7 @@ void QgsEditFormConfig::writeXml( QDomNode& node ) const
//// END TODO
}
QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent )
QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement* parent )
{
QgsAttributeEditorElement* newElement = nullptr;
@ -426,7 +581,7 @@ QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomEleme
if ( ok )
container->setIsGroupBox( isGroupBox );
else
container->setIsGroupBox( qobject_cast<QgsAttributeEditorContainer*>( parent ) );
container->setIsGroupBox( parent );
QDomNodeList childNodeList = elem.childNodes();
@ -443,7 +598,7 @@ QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomEleme
else if ( elem.tagName() == "attributeEditorField" )
{
QString name = elem.attribute( "name" );
int idx = mFields.fieldNameIndex( name );
int idx = d->mFields.fieldNameIndex( name );
newElement = new QgsAttributeEditorField( name, idx, parent );
}
else if ( elem.tagName() == "attributeEditorRelation" )
@ -456,29 +611,6 @@ QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomEleme
return newElement;
}
void QgsEditFormConfig::onRelationsLoaded()
{
Q_FOREACH ( QgsAttributeEditorElement* elem, mAttributeEditorElements )
{
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
{
QgsAttributeEditorContainer* cont = dynamic_cast< QgsAttributeEditorContainer* >( elem );
if ( !cont )
continue;
QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
{
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
if ( !rel )
continue;
rel->init( QgsProject::instance()->relationManager() );
}
}
}
}
int QgsAttributeEditorContainer::columnCount() const
{
return mColumnCount;
@ -488,3 +620,17 @@ void QgsAttributeEditorContainer::setColumnCount( int columnCount )
{
mColumnCount = columnCount;
}
QgsAttributeEditorElement* QgsAttributeEditorContainer::clone( QgsAttributeEditorElement* parent ) const
{
QgsAttributeEditorContainer* element = new QgsAttributeEditorContainer( name(), parent );
Q_FOREACH ( QgsAttributeEditorElement* child, children() )
{
element->addChildElement( child->clone( element ) );
}
element->mIsGroupBox = mIsGroupBox;
element->mColumnCount = mColumnCount;
return element;
}

View File

@ -23,281 +23,16 @@
#include <QDomDocument>
#include "qgseditorwidgetconfig.h"
#include "qgsrelation.h"
#include "qgsattributeeditorelement.h"
class QgsRelationManager;
/** \ingroup core
* This is an abstract base class for any elements of a drag and drop form.
*
* This can either be a container which will be represented on the screen
* as a tab widget or ca collapsible group box. Or it can be a field which will
* then be represented based on the QgsEditorWidget type and configuration.
* Or it can be a relation and embed the form of several children of another
* layer.
*/
class CORE_EXPORT QgsAttributeEditorElement : public QObject
{
Q_OBJECT
public:
enum AttributeEditorType
{
AeTypeContainer, //!< A container
AeTypeField, //!< A field
AeTypeRelation, //!< A relation
AeTypeInvalid //!< Invalid
};
/**
* Constructor
*
* @param type The type of the new element. Should never
* @param name
* @param parent
*/
QgsAttributeEditorElement( AttributeEditorType type, const QString& name, QObject *parent = nullptr )
: QObject( parent )
, mType( type )
, mName( name )
{}
//! Destructor
virtual ~QgsAttributeEditorElement() {}
/**
* Return the name of this element
*
* @return The name for this element
*/
QString name() const { return mName; }
/**
* The type of this element
*
* @return The type
*/
AttributeEditorType type() const { return mType; }
/**
* Is reimplemented in classes inheriting from this to serialize it.
*
* @param doc The QDomDocument which is used to create new XML elements
*
* @return An DOM element which represents this element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const = 0;
protected:
AttributeEditorType mType;
QString mName;
};
/** \ingroup core
* This is a container for attribute editors, used to group them visually in the
* attribute form if it is set to the drag and drop designer.
*/
class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement
{
Q_OBJECT
public:
/**
* Creates a new attribute editor container
*
* @param name The name to show as title
* @param parent The parent. May be another container.
*/
QgsAttributeEditorContainer( const QString& name, QObject *parent )
: QgsAttributeEditorElement( AeTypeContainer, name, parent )
, mIsGroupBox( true )
, mColumnCount( 1 )
{}
//! Destructor
virtual ~QgsAttributeEditorContainer() {}
/**
* Will serialize this containers information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Add a child element to this container. This may be another container, a field or a relation.
*
* @param element The element to add as child
*/
virtual void addChildElement( QgsAttributeEditorElement* element );
/**
* Determines if this container is rendered as collapsible group box or tab in a tabwidget
*
* @param isGroupBox If true, this will be a group box
*/
virtual void setIsGroupBox( bool isGroupBox ) { mIsGroupBox = isGroupBox; }
/**
* Returns if this container is going to be rendered as a group box
*
* @return True if it will be a group box, false if it will be a tab
*/
virtual bool isGroupBox() const { return mIsGroupBox; }
/**
* Get a list of the children elements of this container
*
* @return A list of elements
*/
QList<QgsAttributeEditorElement*> children() const { return mChildren; }
/**
* Traverses the element tree to find any element of the specified type
*
* @param type The type which should be searched
*
* @return A list of elements of the type which has been searched for
*/
virtual QList<QgsAttributeEditorElement*> findElements( AttributeEditorType type ) const;
/**
* Change the name of this container
*/
void setName( const QString& name );
/**
* Get the number of columns in this group
*/
int columnCount() const;
/**
* Set the number of columns in this group
*/
void setColumnCount( int columnCount );
private:
bool mIsGroupBox;
QList<QgsAttributeEditorElement*> mChildren;
int mColumnCount;
};
/** \ingroup core
* This element will load a field's widget onto the form.
*/
class CORE_EXPORT QgsAttributeEditorField : public QgsAttributeEditorElement
{
Q_OBJECT
public:
/**
* Creates a new attribute editor element which represents a field
*
* @param name The name of the element
* @param idx The index of the field which should be embedded
* @param parent The parent of this widget (used as container)
*/
QgsAttributeEditorField( const QString& name, int idx, QObject *parent )
: QgsAttributeEditorElement( AeTypeField, name, parent )
, mIdx( idx )
{}
//! Destructor
virtual ~QgsAttributeEditorField() {}
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Return the index of the field
* @return
*/
int idx() const { return mIdx; }
private:
int mIdx;
};
/** \ingroup core
* This element will load a relation editor onto the form.
*/
class CORE_EXPORT QgsAttributeEditorRelation : public QgsAttributeEditorElement
{
Q_OBJECT
public:
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relationId The id of the relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QString &relationId, QObject *parent )
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
, mRelationId( relationId ) {}
/**
* Creates a new element which embeds a relation.
*
* @param name The name of this element
* @param relation The relation to embed
* @param parent The parent (used as container)
*/
QgsAttributeEditorRelation( const QString& name, const QgsRelation& relation, QObject *parent )
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
, mRelationId( relation.id() )
, mRelation( relation ) {}
//! Destructor
virtual ~QgsAttributeEditorRelation() {}
/**
* Will serialize this elements information into a QDomElement for saving it in an XML file.
*
* @param doc The QDomDocument used to generate the QDomElement
*
* @return The XML element
*/
virtual QDomElement toDomElement( QDomDocument& doc ) const override;
/**
* Get the id of the relation which shall be embedded
*
* @return the id
*/
const QgsRelation& relation() const { return mRelation; }
/**
* Initializes the relation from the id
*
* @param relManager The relation manager to use for the initialization
* @return true if the relation was found in the relationmanager
*/
bool init( QgsRelationManager *relManager );
private:
QString mRelationId;
QgsRelation mRelation;
};
class QgsEditFormConfigPrivate;
/** \ingroup core
* \class QgsEditFormConfig
*/
class CORE_EXPORT QgsEditFormConfig : public QObject
class CORE_EXPORT QgsEditFormConfig
{
Q_OBJECT
public:
/** The different types to layout the attribute editor. */
@ -353,31 +88,46 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
CodeSourceEnvironment = 3 //!< Use the python code available in the python environment
};
/**
* This is only useful in combination with EditorLayout::TabLayout.
*
* Adds a new element to the layout.
*/
void addTab( QgsAttributeEditorElement* data ) { mAttributeEditorElements.append( data ); }
QgsEditFormConfig( const QgsEditFormConfig& o );
QgsEditFormConfig& operator=( const QgsEditFormConfig& o );
bool operator==( const QgsEditFormConfig& o );
~QgsEditFormConfig();
/**
* Returns a list of tabs for EditorLayout::TabLayout.
* Adds a new element to the invisible root container in the layout.
*
* This is only useful in combination with EditorLayout::TabLayout.
*/
QList< QgsAttributeEditorElement* > tabs() const { return mAttributeEditorElements; }
void addTab( QgsAttributeEditorElement* data );
/**
* Returns a list of tabs for EditorLayout::TabLayout obtained from the invisible root container.
*/
QList< QgsAttributeEditorElement* > tabs() const;
/**
* Clears all the tabs for the attribute editor form with EditorLayout::TabLayout.
*/
void clearTabs() { mAttributeEditorElements.clear(); }
void clearTabs();
/**
* Get the invisible root container for the drag and drop designer form (EditorLayout::TabLayout).
*
* @note Added in QGIS 3
*/
QgsAttributeEditorContainer* invisibleRootContainer();
/** Get the active layout style for the attribute editor for this layer */
EditorLayout layout() const { return mEditorLayout; }
EditorLayout layout() const;
/** Set the active layout style for the attribute editor for this layer */
void setLayout( EditorLayout editorLayout ) { mEditorLayout = editorLayout; }
void setLayout( EditorLayout editorLayout );
/** Get path to the .ui form. Only meaningful with EditorLayout::UiFileLayout. */
QString uiForm() const { return mUiFormPath; }
QString uiForm() const;
/**
* Set path to the .ui form.
@ -584,7 +334,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
* includes a module name or if it's a pure function name it will searched
* in the python code set with @link setInitCode @endlink.
*/
QString initFunction() const { return mInitFunction; }
QString initFunction() const;
/**
* Set python function for edit form initialization.
@ -592,45 +342,45 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
* includes a module name or if it's a pure function name it will searched
* in the python code set with @link setInitCode @endlink.
*/
void setInitFunction( const QString& function ) { mInitFunction = function; }
void setInitFunction( const QString& function );
/**
* Get python code for edit form initialization.
*/
QString initCode() const { return mInitCode; }
QString initCode() const;
/**
* Set python code for edit form initialization.
* Make sure that you also set the appropriate function name in
* @link setInitFunction @endlink
*/
void setInitCode( const QString& code ) { mInitCode = code; }
void setInitCode( const QString& code );
/**
* Get python external file path for edit form initialization.
*/
QString initFilePath() const { return mInitFilePath; }
QString initFilePath() const;
/**
* Set python external file path for edit form initialization.
* Make sure that you also set the appropriate function name in
* @link setInitFunction @endlink
*/
void setInitFilePath( const QString& filePath ) { mInitFilePath = filePath; }
void setInitFilePath( const QString& filePath );
/** Return python code source for edit form initialization
* (if it shall be loaded from a file, read from the
* provided dialog editor or inherited from the environment)
*/
PythonInitCodeSource initCodeSource() const { return mInitCodeSource; }
PythonInitCodeSource initCodeSource() const;
/** Set if python code shall be used for edit form initialization and its origin */
void setInitCodeSource( const PythonInitCodeSource initCodeSource ) { mInitCodeSource = initCodeSource; }
void setInitCodeSource( PythonInitCodeSource initCodeSource );
/** Type of feature form pop-up suppression after feature creation (overrides app setting) */
FeatureFormSuppress suppress() const { return mSuppressForm; }
FeatureFormSuppress suppress() const;
/** Set type of feature form pop-up suppression after feature creation (overrides app setting) */
void setSuppress( FeatureFormSuppress s ) { mSuppressForm = s; }
void setSuppress( FeatureFormSuppress s );
// Serialization
@ -649,18 +399,12 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
/**
* Deserialize drag and drop designer elements.
*/
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );
private slots:
void onRelationsLoaded();
protected:
// Internal stuff
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement* parent );
/**
* Create a new edit form config. Normally invoked by QgsVectorLayer
*/
explicit QgsEditFormConfig( QObject* parent = nullptr );
explicit QgsEditFormConfig();
private:
@ -672,40 +416,13 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
*/
void setFields( const QgsFields& fields );
/**
* Will be called by friend class QgsVectorLayer
*/
void onRelationsLoaded();
private:
/** Stores a list of attribute editor elements (Each holding a tree structure for a tab in the attribute editor)*/
QList< QgsAttributeEditorElement* > mAttributeEditorElements;
/** Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
QList< TabData > mTabs;
QMap< QString, QString> mConstraints;
QMap< QString, QString> mConstraintsDescription;
QMap< QString, bool> mFieldEditables;
QMap< QString, bool> mLabelOnTop;
QMap< QString, bool> mNotNull;
QMap<QString, QString> mEditorWidgetTypes;
QMap<QString, QgsEditorWidgetConfig > mWidgetConfigs;
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
EditorLayout mEditorLayout;
/** Init form instance */
QString mUiFormPath;
/** Name of the python form init function */
QString mInitFunction;
/** Path of the python external file to be loaded */
QString mInitFilePath;
/** Choose the source of the init founction */
PythonInitCodeSource mInitCodeSource;
/** Python init code provided in the dialog */
QString mInitCode;
/** Type of feature form suppression after feature creation */
FeatureFormSuppress mSuppressForm;
QgsFields mFields;
QExplicitlySharedDataPointer<QgsEditFormConfigPrivate> d;
friend class QgsVectorLayer;
};

View File

@ -0,0 +1,90 @@
/***************************************************************************
qgseditformconfig_p - %{Cpp:License:ClassName}
---------------------
begin : 18.8.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSEDITFORMCONFIG_P_H
#define QGSEDITFORMCONFIG_P_H
#include "qgsfield.h"
#include "qgseditformconfig.h"
class QgsEditFormConfigPrivate : public QSharedData
{
public:
QgsEditFormConfigPrivate()
: mInvisibleRootContainer( new QgsAttributeEditorContainer( QString::null, nullptr ) )
, mEditorLayout( QgsEditFormConfig::GeneratedLayout )
, mInitCodeSource( QgsEditFormConfig::CodeSourceNone )
, mSuppressForm( QgsEditFormConfig::SuppressDefault )
{}
QgsEditFormConfigPrivate( const QgsEditFormConfigPrivate& o )
: QSharedData( o )
, mInvisibleRootContainer( static_cast<QgsAttributeEditorContainer*>( o.mInvisibleRootContainer->clone( nullptr ) ) )
, mConstraints( o.mConstraints )
, mConstraintsDescription( o.mConstraintsDescription )
, mFieldEditables( o.mFieldEditables )
, mLabelOnTop( o.mLabelOnTop )
, mNotNull( o.mNotNull )
, mEditorWidgetTypes( o.mEditorWidgetTypes )
, mWidgetConfigs( o.mWidgetConfigs )
, mEditorLayout( o.mEditorLayout )
, mUiFormPath( o.mUiFormPath )
, mInitFunction( o.mInitFunction )
, mInitCodeSource( o.mInitCodeSource )
, mInitCode( o.mInitCode )
, mSuppressForm( o.mSuppressForm )
, mFields( o.mFields )
{}
/** The invisible root container for attribute editors in the drag and drop designer */
QgsAttributeEditorContainer* mInvisibleRootContainer;
/** This flag is set if the root container was configured by the user */
bool mConfiguredRootContainer;
/** Map that stores the tab for attributes in the edit form. Key is the tab order and value the tab name*/
QList< QgsEditFormConfig::TabData > mTabs;
QMap< QString, QString> mConstraints;
QMap< QString, QString> mConstraintsDescription;
QMap< QString, bool> mFieldEditables;
QMap< QString, bool> mLabelOnTop;
QMap< QString, bool> mNotNull;
QMap<QString, QString> mEditorWidgetTypes;
QMap<QString, QgsEditorWidgetConfig > mWidgetConfigs;
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
QgsEditFormConfig::EditorLayout mEditorLayout;
/** Init form instance */
QString mUiFormPath;
/** Name of the python form init function */
QString mInitFunction;
/** Path of the python external file to be loaded */
QString mInitFilePath;
/** Choose the source of the init founction */
QgsEditFormConfig::PythonInitCodeSource mInitCodeSource;
/** Python init code provided in the dialog */
QString mInitCode;
/** Type of feature form suppression after feature creation */
QgsEditFormConfig::FeatureFormSuppress mSuppressForm;
QgsFields mFields;
};
#endif // QGSEDITFORMCONFIG_P_H

View File

@ -138,11 +138,11 @@ class CORE_EXPORT QgsFeature
/** Copy constructor
*/
QgsFeature( const QgsFeature & rhs );
QgsFeature( const QgsFeature& rhs );
/** Assignment operator
*/
QgsFeature & operator=( QgsFeature const & rhs );
QgsFeature& operator=( const QgsFeature& rhs );
//! Destructor
virtual ~QgsFeature();

View File

@ -283,12 +283,12 @@ QgsFields::QgsFields()
d = new QgsFieldsPrivate();
}
QgsFields::QgsFields( const QgsFields &other )
QgsFields::QgsFields( const QgsFields& other )
: d( other.d )
{
}
QgsFields &QgsFields::operator =( const QgsFields & other )
QgsFields& QgsFields::operator =( const QgsFields & other )
{
d = other.d;
return *this;

View File

@ -127,7 +127,6 @@ QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
, mDataProvider( nullptr )
, mProviderKey( providerKey )
, mReadOnly( false )
, mEditFormConfig( new QgsEditFormConfig( this ) )
, mWkbType( QgsWkbTypes::Unknown )
, mRenderer( nullptr )
, mLabeling( new QgsVectorLayerSimpleLabeling )
@ -158,6 +157,7 @@ QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( selectionChanged() ) );
connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( repaintRequested() ) );
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
// Default simplify drawing settings
QSettings settings;
@ -1656,7 +1656,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
// process the attribute actions
mActions->readXml( node );
mEditFormConfig->readXml( node );
mEditFormConfig.readXml( node );
QDomNode annotationFormNode = node.namedItem( "annotationform" );
if ( !annotationFormNode.isNull() )
@ -1716,7 +1716,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
}
}
mEditFormConfig->readXml( node );
mEditFormConfig.readXml( node );
mAttributeTableConfig.readXml( node );
@ -1886,7 +1886,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
// add attribute actions
mActions->writeXml( node, doc );
mAttributeTableConfig.writeXml( node );
mEditFormConfig->writeXml( node );
mEditFormConfig.writeXml( node );
mConditionalStyles->writeXml( node, doc );
// save expression fields
@ -2613,6 +2613,7 @@ bool QgsVectorLayer::setReadOnly( bool readonly )
return false;
mReadOnly = readonly;
emit readOnlyChanged();
return true;
}
@ -2780,7 +2781,7 @@ void QgsVectorLayer::updateFields()
if ( oldFields != mUpdatedFields )
{
emit updatedFields();
mEditFormConfig->setFields( mUpdatedFields );
mEditFormConfig.setFields( mUpdatedFields );
}
}
@ -3468,6 +3469,20 @@ void QgsVectorLayer::readSldLabeling( const QDomNode& node )
}
}
QgsEditFormConfig QgsVectorLayer::editFormConfig() const
{
return mEditFormConfig;
}
void QgsVectorLayer::setEditFormConfig( const QgsEditFormConfig& editFormConfig )
{
if ( mEditFormConfig == editFormConfig )
return;
mEditFormConfig = editFormConfig;
emit editFormConfigChanged();
}
QString QgsVectorLayer::mapTipTemplate() const
{
return mMapTipTemplate;
@ -3791,25 +3806,9 @@ void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
emit featureDeleted( fid );
}
QgsVectorLayer::ValueRelationData QgsVectorLayer::valueRelation( int idx ) const
void QgsVectorLayer::onRelationsLoaded()
{
if ( mEditFormConfig->widgetType( idx ) == "ValueRelation" )
{
QgsEditorWidgetConfig cfg = mEditFormConfig->widgetConfig( idx );
return ValueRelationData( cfg.value( "Layer" ).toString(),
cfg.value( "Key" ).toString(),
cfg.value( "Value" ).toString(),
cfg.value( "AllowNull" ).toBool(),
cfg.value( "OrderByValue" ).toBool(),
cfg.value( "AllowMulti" ).toBool(),
cfg.value( "FilterExpression" ).toString()
);
}
else
{
return ValueRelationData();
}
mEditFormConfig.onRelationsLoaded();
}
QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx ) const
@ -3817,60 +3816,6 @@ QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx ) const
return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
}
QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorContainer" );
elem.setAttribute( "name", mName );
elem.setAttribute( "columnCount", mColumnCount );
elem.setAttribute( "groupBox", mIsGroupBox ? 1 : 0 );
Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
{
elem.appendChild( child->toDomElement( doc ) );
}
return elem;
}
void QgsAttributeEditorContainer::addChildElement( QgsAttributeEditorElement *widget )
{
mChildren.append( widget );
}
void QgsAttributeEditorContainer::setName( const QString& name )
{
mName = name;
}
QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( QgsAttributeEditorElement::AttributeEditorType type ) const
{
QList<QgsAttributeEditorElement*> results;
Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
{
if ( elem->type() == type )
{
results.append( elem );
}
if ( elem->type() == AeTypeContainer )
{
QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
if ( cont )
results += cont->findElements( type );
}
}
return results;
}
QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorField" );
elem.setAttribute( "name", mName );
elem.setAttribute( "index", mIdx );
return elem;
}
int QgsVectorLayer::listStylesInDatabase( QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
@ -3989,20 +3934,6 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFl
return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
}
QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
{
QDomElement elem = doc.createElement( "attributeEditorRelation" );
elem.setAttribute( "name", mName );
elem.setAttribute( "relation", mRelation.id() );
return elem;
}
bool QgsAttributeEditorRelation::init( QgsRelationManager* relationManager )
{
mRelation = relationManager->relation( mRelationId );
return mRelation.isValid();
}
QSet<QString> QgsVectorLayer::layerDependencies() const
{
if ( mDataProvider )

View File

@ -412,47 +412,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
Q_PROPERTY( QString displayExpression READ displayExpression WRITE setDisplayExpression NOTIFY displayExpressionChanged )
Q_PROPERTY( QString mapTipTemplate READ mapTipTemplate WRITE setMapTipTemplate NOTIFY mapTipTemplateChanged )
Q_PROPERTY( QgsEditFormConfig editFormConfig READ editFormConfig WRITE setEditFormConfig NOTIFY editFormConfigChanged )
public:
typedef QgsEditFormConfig::GroupData GroupData;
typedef QgsEditFormConfig::TabData TabData;
enum EditorLayout
{
GeneratedLayout = 0,
TabLayout = 1,
UiFileLayout = 2
};
struct ValueRelationData
{
ValueRelationData()
: mAllowNull( false )
, mOrderByValue( false )
, mAllowMulti( false )
{}
ValueRelationData( const QString& layer, const QString& key, const QString& value, bool allowNull, bool orderByValue,
bool allowMulti = false,
const QString& filterExpression = QString::null )
: mLayer( layer )
, mKey( key )
, mValue( value )
, mFilterExpression( filterExpression )
, mAllowNull( allowNull )
, mOrderByValue( orderByValue )
, mAllowMulti( allowMulti )
{}
QString mLayer;
QString mKey;
QString mValue;
QString mFilterExpression;
bool mAllowNull;
bool mOrderByValue;
bool mAllowMulti; /* allow selection of multiple keys */
};
//! Result of an edit operation
enum EditResult
{
@ -808,12 +771,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
virtual QString loadNamedStyle( const QString &theURI, bool &theResultFlag ) override;
/** Convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
* @param elem the DOM element
* @param parent the QObject which will own this object
*/
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent ) { return mEditFormConfig->attributeEditorElementFromDomElement( elem, parent ); }
/** Read the symbology for the current layer from the Dom node supplied.
* @param node node that will contain the symbology definition for this layer.
* @param errorMessage reference to string that will be updated with any error messages
@ -1232,21 +1189,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
bool renameAttribute( int attIndex, const QString& newName );
/**
* Get the configuration of the form used to represent this vector layer.
* This is a writable configuration that can directly be changed in place.
*
* @return The configuration of this layers' form
*
* @note Added in QGIS 2.14
*/
QgsEditFormConfig* editFormConfig() const { return mEditFormConfig; }
/**
* Clears all the tabs for the attribute editor form
*/
void clearAttributeEditorWidgets() { mEditFormConfig->clearTabs(); }
/**
* Returns the alias of an attribute name or a null string if there is no alias.
*
@ -1328,9 +1270,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
/** Set annotation form for layer */
void setAnnotationForm( const QString& ui );
/** Access value relation widget data */
ValueRelationData valueRelation( int idx ) const;
/**
* Get relations, where the foreign key is on this layer
*
@ -1518,6 +1457,26 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
QgsExpressionContext createExpressionContext() const override;
/**
* Get the configuration of the form used to represent this vector layer.
* This is a writable configuration that can directly be changed in place.
*
* @return The configuration of this layers' form
*
* @note Added in QGIS 2.14
*/
QgsEditFormConfig editFormConfig() const;
/**
* Get the configuration of the form used to represent this vector layer.
* This is a writable configuration that can directly be changed in place.
*
* @return The configuration of this layers' form
*
* @note Added in QGIS 3.0
*/
void setEditFormConfig( const QgsEditFormConfig& editFormConfig );
public slots:
/**
* Select feature by its ID
@ -1786,14 +1745,24 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
void displayExpressionChanged();
/**
* Emitted when the read only status changes
*
* @note added in 3.0
*/
void readOnlyChanged();
/**
* Signals an error related to this vector layer.
*/
void raiseError( const QString& msg );
void editFormConfigChanged();
private slots:
void onJoinedFieldsChanged();
void onFeatureDeleted( QgsFeatureId fid );
void onRelationsLoaded();
protected:
/** Set the extent */
@ -1876,7 +1845,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
QMap< QString, QString > mAttributeAliasMap;
/** Holds the configuration for the edit form */
QgsEditFormConfig* mEditFormConfig;
QgsEditFormConfig mEditFormConfig;
/** Attributes which are not published in WMS*/
QSet<QString> mExcludeAttributesWMS;

View File

@ -125,7 +125,7 @@ bool QgsVectorLayerEditPassthrough::deleteAttribute( int attr )
if ( L->dataProvider()->deleteAttributes( QgsAttributeIds() << attr ) )
{
mModified = true;
L->editFormConfig()->removeWidgetConfig( attr );
L->editFormConfig().removeWidgetConfig( attr );
emit attributeDeleted( attr );
mModified = true;
return true;

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( mFieldIndex );
mOldEditorWidgetConfig = mBuffer->L->editFormConfig().widgetConfig( mFieldIndex );
if ( !mProviderField )
{
@ -410,7 +410,7 @@ void QgsVectorLayerUndoCommandDeleteAttribute::undo()
}
}
mBuffer->L->editFormConfig()->setWidgetConfig( mFieldIndex, mOldEditorWidgetConfig );
mBuffer->L->editFormConfig().setWidgetConfig( mFieldIndex, mOldEditorWidgetConfig );
emit mBuffer->attributeAdded( mFieldIndex );
}
@ -428,7 +428,7 @@ void QgsVectorLayerUndoCommandDeleteAttribute::redo()
mBuffer->mAddedAttributes.removeAt( mOriginIndex ); // removing temporary attribute
}
mBuffer->L->editFormConfig()->removeWidgetConfig( mFieldIndex );
mBuffer->L->editFormConfig().removeWidgetConfig( mFieldIndex );
mBuffer->handleAttributeDeleted( mFieldIndex ); // update changed attributes + new features
mBuffer->updateLayerFields();
emit mBuffer->attributeDeleted( mFieldIndex );

View File

@ -67,15 +67,15 @@ 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 );
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( widgetType, vl, fieldIdx, cfg, nullptr, parent, context );
QWidget* w = eww->widget();
w->setAutoFillBackground( true );
eww->setEnabled( !vl->editFormConfig()->readOnly( fieldIdx ) );
eww->setEnabled( !vl->editFormConfig().readOnly( fieldIdx ) );
return w;
}

View File

@ -339,12 +339,12 @@ void QgsAttributeTableModel::loadAttributes()
for ( int idx = 0; idx < fields.count(); ++idx )
{
const QString widgetType = layer()->editFormConfig()->widgetType( idx );
const QString widgetType = layer()->editFormConfig().widgetType( idx );
QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
if ( widgetFactory )
{
mWidgetFactories.append( widgetFactory );
mWidgetConfigs.append( layer()->editFormConfig()->widgetConfig( idx ) );
mWidgetConfigs.append( layer()->editFormConfig().widgetConfig( idx ) );
mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );
attributes << idx;
@ -727,7 +727,7 @@ Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
if ( layer()->isEditable() &&
!layer()->editFormConfig()->readOnly( mAttributes[index.column()] ) &&
!layer()->editFormConfig().readOnly( mAttributes[index.column()] ) &&
(( layer()->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
FID_IS_NEW( rowToId( index.row() ) ) ) )
flags |= Qt::ItemIsEditable;

View File

@ -141,7 +141,7 @@ void QgsDualView::columnBoxInit()
if ( fieldIndex == -1 )
continue;
if ( mLayerCache->layer()->editFormConfig()->widgetType( fieldIndex ) != "Hidden" )
if ( mLayerCache->layer()->editFormConfig().widgetType( fieldIndex ) != "Hidden" )
{
QIcon icon = mLayerCache->layer()->fields().iconForField( fieldIndex );
QString text = field.name();

View File

@ -230,7 +230,7 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
if ( mWidgetFactories.contains( ewv2Type ) )
{
vectorLayer->editFormConfig()->setWidgetType( idx, ewv2Type );
vectorLayer->editFormConfig().setWidgetType( idx, ewv2Type );
QDomElement ewv2CfgElem = editTypeElement.namedItem( "widgetv2config" ).toElement();
if ( !ewv2CfgElem.isNull() )
@ -238,13 +238,13 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
cfg = mWidgetFactories[ewv2Type]->readEditorConfig( ewv2CfgElem, vectorLayer, idx );
}
vectorLayer->editFormConfig()->setReadOnly( idx, ewv2CfgElem.attribute( "fieldEditable", "1" ) != "1" );
vectorLayer->editFormConfig()->setLabelOnTop( idx, ewv2CfgElem.attribute( "labelOnTop", "0" ) == "1" );
vectorLayer->editFormConfig()->setNotNull( idx, ewv2CfgElem.attribute( "notNull", "0" ) == "1" );
vectorLayer->editFormConfig()->setExpression( idx, ewv2CfgElem.attribute( "constraint", QString() ) );
vectorLayer->editFormConfig()->setExpressionDescription( idx, ewv2CfgElem.attribute( "constraintDescription", QString() ) );
vectorLayer->editFormConfig().setReadOnly( idx, ewv2CfgElem.attribute( "fieldEditable", "1" ) != "1" );
vectorLayer->editFormConfig().setLabelOnTop( idx, ewv2CfgElem.attribute( "labelOnTop", "0" ) == "1" );
vectorLayer->editFormConfig().setNotNull( idx, ewv2CfgElem.attribute( "notNull", "0" ) == "1" );
vectorLayer->editFormConfig().setExpression( idx, ewv2CfgElem.attribute( "constraint", QString() ) );
vectorLayer->editFormConfig().setExpressionDescription( idx, ewv2CfgElem.attribute( "constraintDescription", QString() ) );
vectorLayer->editFormConfig()->setWidgetConfig( idx, cfg );
vectorLayer->editFormConfig().setWidgetConfig( idx, cfg );
}
else
{
@ -272,7 +272,7 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
for ( int idx = 0; idx < fields.count(); ++idx )
{
QgsField field = fields.at( idx );
const QString& widgetType = vectorLayer->editFormConfig()->widgetType( 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 ) );
@ -287,13 +287,13 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
if ( mWidgetFactories.contains( widgetType ) )
{
QDomElement ewv2CfgElem = doc.createElement( "widgetv2config" );
ewv2CfgElem.setAttribute( "fieldEditable", !vectorLayer->editFormConfig()->readOnly( idx ) );
ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) );
ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) );
ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig()->expression( idx ) );
ewv2CfgElem.setAttribute( "constraintDescription", vectorLayer->editFormConfig()->expressionDescription( idx ) );
ewv2CfgElem.setAttribute( "fieldEditable", !vectorLayer->editFormConfig().readOnly( idx ) );
ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig().labelOnTop( idx ) );
ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig().notNull( idx ) );
ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig().expression( idx ) );
ewv2CfgElem.setAttribute( "constraintDescription", vectorLayer->editFormConfig().expressionDescription( idx ) );
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig()->widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx );
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig().widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx );
editTypeElement.appendChild( ewv2CfgElem );
}

View File

@ -109,13 +109,13 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
{
bool toEmit( false );
QString errStr( tr( "predicate is True" ) );
QString expression = layer()->editFormConfig()->expression( mFieldIdx );
QString expression = layer()->editFormConfig().expression( mFieldIdx );
QString description;
QVariant value = ft.attribute( mFieldIdx );
if ( ! expression.isEmpty() )
{
description = layer()->editFormConfig()->expressionDescription( mFieldIdx );
description = layer()->editFormConfig().expressionDescription( mFieldIdx );
QgsExpressionContext context =
QgsExpressionContextUtils::createFeatureBasedContext( ft, ft.fields() );
@ -138,7 +138,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
else
mValidConstraint = true;
if ( layer()->editFormConfig()->notNull( mFieldIdx ) )
if ( layer()->editFormConfig().notNull( mFieldIdx ) )
{
if ( !expression.isEmpty() )
{

View File

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

View File

@ -302,7 +302,7 @@ bool QgsAttributeForm::saveEdits()
bool changed = ( dstVar != srcVar && !dstVar.isNull() && !srcVar.isNull() )
|| ( dstVar.isNull() != srcVar.isNull() );
if ( changed && srcVar.isValid()
&& !mLayer->editFormConfig()->readOnly( eww->fieldIdx() ) )
&& !mLayer->editFormConfig().readOnly( eww->fieldIdx() ) )
{
dst[eww->fieldIdx()] = srcVar;
@ -347,7 +347,7 @@ bool QgsAttributeForm::saveEdits()
{
if (( dst.at( i ) == src.at( i ) && dst.at( i ).isNull() == src.at( i ).isNull() ) // If field is not changed...
|| !dst.at( i ).isValid() // or the widget returns invalid (== do not change)
|| mLayer->editFormConfig()->readOnly( i ) ) // or the field cannot be edited ...
|| mLayer->editFormConfig().readOnly( i ) ) // or the field cannot be edited ...
{
continue;
}
@ -498,7 +498,7 @@ bool QgsAttributeForm::saveMultiEdits()
continue;
if ( !w->currentValue().isValid() // if the widget returns invalid (== do not change)
|| mLayer->editFormConfig()->readOnly( wIt.key() ) ) // or the field cannot be edited ...
|| mLayer->editFormConfig().readOnly( wIt.key() ) ) // or the field cannot be edited ...
{
continue;
}
@ -681,7 +681,7 @@ void QgsAttributeForm::onAttributeChanged( const QVariant& value )
break;
}
if ( eww->layer()->editFormConfig()->notNull( eww->fieldIdx() ) )
if ( eww->layer()->editFormConfig().notNull( eww->fieldIdx() ) )
{
QLabel* buddy = mBuddyMap.value( eww->widget() );
@ -766,7 +766,7 @@ bool QgsAttributeForm::currentFormFeature( QgsFeature &feature )
QVariant srcVar = eww->value();
// need to check dstVar.isNull() != srcVar.isNull()
// otherwise if dstVar=NULL and scrVar=0, then dstVar = srcVar
if (( dstVar != srcVar || dstVar.isNull() != srcVar.isNull() ) && srcVar.isValid() && !mLayer->editFormConfig()->readOnly( eww->fieldIdx() ) )
if (( dstVar != srcVar || dstVar.isNull() != srcVar.isNull() ) && srcVar.isValid() && !mLayer->editFormConfig().readOnly( eww->fieldIdx() ) )
dst[eww->fieldIdx()] = srcVar;
}
else
@ -822,7 +822,7 @@ bool QgsAttributeForm::currentFormValidConstraints( QStringList &invalidFields,
{
invalidFields.append( eww->field().name() );
QString desc = eww->layer()->editFormConfig()->expressionDescription( eww->fieldIdx() );
QString desc = eww->layer()->editFormConfig().expressionDescription( eww->fieldIdx() );
descriptions.append( desc );
valid = false; // continue to get all invalif fields
@ -939,7 +939,7 @@ void QgsAttributeForm::constraintDependencies( QgsEditorWidgetWrapper *w,
if ( name != ewwName )
{
// get expression and referencedColumns
QgsExpression expr = eww->layer()->editFormConfig()->expression( eww->fieldIdx() );
QgsExpression expr = eww->layer()->editFormConfig().expression( eww->fieldIdx() );
Q_FOREACH ( const QString& colName, expr.referencedColumns() )
{
@ -985,7 +985,7 @@ void QgsAttributeForm::synchronizeEnabledState()
QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
if ( eww )
{
fieldEditable = !mLayer->editFormConfig()->readOnly( eww->fieldIdx() ) &&
fieldEditable = !mLayer->editFormConfig().readOnly( eww->fieldIdx() ) &&
(( mLayer->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
FID_IS_NEW( mFeature.id() ) );
}
@ -1067,16 +1067,16 @@ void QgsAttributeForm::init()
setContentsMargins( 0, 0, 0, 0 );
// Try to load Ui-File for layout
if ( mContext.allowCustomUi() && mLayer->editFormConfig()->layout() == QgsEditFormConfig::UiFileLayout &&
!mLayer->editFormConfig()->uiForm().isEmpty() )
if ( mContext.allowCustomUi() && mLayer->editFormConfig().layout() == QgsEditFormConfig::UiFileLayout &&
!mLayer->editFormConfig().uiForm().isEmpty() )
{
QFile file( mLayer->editFormConfig()->uiForm() );
QFile file( mLayer->editFormConfig().uiForm() );
if ( file.open( QFile::ReadOnly ) )
{
QUiLoader loader;
QFileInfo fi( mLayer->editFormConfig()->uiForm() );
QFileInfo fi( mLayer->editFormConfig().uiForm() );
loader.setWorkingDirectory( fi.dir() );
formWidget = loader.load( &file, this );
formWidget->setWindowFlags( Qt::Widget );
@ -1093,13 +1093,13 @@ void QgsAttributeForm::init()
QTabWidget* tabWidget = nullptr;
// Tab layout
if ( !formWidget && mLayer->editFormConfig()->layout() == QgsEditFormConfig::TabLayout )
if ( !formWidget && mLayer->editFormConfig().layout() == QgsEditFormConfig::TabLayout )
{
int row = 0;
int column = 0;
int columnCount = 1;
Q_FOREACH ( QgsAttributeEditorElement* widgDef, mLayer->editFormConfig()->tabs() )
Q_FOREACH ( QgsAttributeEditorElement* widgDef, mLayer->editFormConfig().tabs() )
{
if ( widgDef->type() == QgsAttributeEditorElement::AeTypeContainer )
{
@ -1204,13 +1204,13 @@ void QgsAttributeForm::init()
//show attribute alias if available
QString fieldName = mLayer->attributeDisplayName( idx );
const QString widgetType = mLayer->editFormConfig()->widgetType( idx );
const QString widgetType = mLayer->editFormConfig().widgetType( idx );
if ( widgetType == "Hidden" )
continue;
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( idx );
bool labelOnTop = mLayer->editFormConfig()->labelOnTop( idx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( idx );
bool labelOnTop = mLayer->editFormConfig().labelOnTop( idx );
// This will also create the widget
QLabel *l = new QLabel( fieldName );
@ -1253,7 +1253,7 @@ void QgsAttributeForm::init()
Q_FOREACH ( const QgsRelation& rel, QgsProject::instance()->relationManager()->referencedRelations( mLayer ) )
{
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, rel, nullptr, this );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig()->widgetConfig( rel.id() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( rel.id() );
rww->setConfig( cfg );
rww->setContext( mContext );
gridLayout->addWidget( rww->widget(), row++, 0, 1, 2 );
@ -1377,15 +1377,15 @@ void QgsAttributeForm::initPython()
// Init Python, if init function is not empty and the combo indicates
// the source for the function code
if ( !mLayer->editFormConfig()->initFunction().isEmpty()
&& mLayer->editFormConfig()->initCodeSource() != QgsEditFormConfig::CodeSourceNone )
if ( !mLayer->editFormConfig().initFunction().isEmpty()
&& mLayer->editFormConfig().initCodeSource() != QgsEditFormConfig::CodeSourceNone )
{
QString initFunction = mLayer->editFormConfig()->initFunction();
QString initFilePath = mLayer->editFormConfig()->initFilePath();
QString initFunction = mLayer->editFormConfig().initFunction();
QString initFilePath = mLayer->editFormConfig().initFilePath();
QString initCode;
switch ( mLayer->editFormConfig()->initCodeSource() )
switch ( mLayer->editFormConfig().initCodeSource() )
{
case QgsEditFormConfig::CodeSourceFile:
if ( ! initFilePath.isEmpty() )
@ -1411,7 +1411,7 @@ void QgsAttributeForm::initPython()
break;
case QgsEditFormConfig::CodeSourceDialog:
initCode = mLayer->editFormConfig()->initCode();
initCode = mLayer->editFormConfig().initCode();
if ( initCode.isEmpty() )
{
QgsLogger::warning( QString( "The python code provided in the dialog is empty!" ) );
@ -1494,8 +1494,8 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
int fldIdx = vl->fieldNameIndex( fieldDef->name() );
if ( fldIdx < vl->fields().count() && fldIdx >= 0 )
{
const QString widgetType = mLayer->editFormConfig()->widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( fldIdx );
const QString widgetType = mLayer->editFormConfig().widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig().widgetConfig( fldIdx );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, mLayer, fldIdx, widgetConfig, nullptr, this, mContext );
QgsAttributeFormEditorWidget* w = new QgsAttributeFormEditorWidget( eww, this );
@ -1509,7 +1509,7 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
newWidgetInfo.widget->setObjectName( mLayer->fields().at( fldIdx ).name() );
}
newWidgetInfo.labelOnTop = mLayer->editFormConfig()->labelOnTop( fieldDef->idx() );
newWidgetInfo.labelOnTop = mLayer->editFormConfig().labelOnTop( fieldDef->idx() );
newWidgetInfo.labelText = mLayer->attributeDisplayName( fieldDef->idx() );
break;
@ -1520,7 +1520,7 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
const QgsAttributeEditorRelation* relDef = dynamic_cast<const QgsAttributeEditorRelation*>( widgetDef );
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, relDef->relation(), nullptr, this );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig()->widgetConfig( relDef->relation().id() );
QgsEditorWidgetConfig cfg = mLayer->editFormConfig().widgetConfig( relDef->relation().id() );
rww->setConfig( cfg );
rww->setContext( context );
newWidgetInfo.widget = rww->widget();
@ -1671,7 +1671,7 @@ void QgsAttributeForm::createWrappers()
if ( relation.isValid() )
{
QgsRelationWidgetWrapper* rww = new QgsRelationWidgetWrapper( mLayer, relation, myWidget, this );
rww->setConfig( mLayer->editFormConfig()->widgetConfig( relation.id() ) );
rww->setConfig( mLayer->editFormConfig().widgetConfig( relation.id() ) );
rww->setContext( mContext );
rww->widget(); // Will initialize the widget
mWidgets.append( rww );
@ -1683,8 +1683,8 @@ void QgsAttributeForm::createWrappers()
{
if ( field.name() == myWidget->objectName() )
{
const QString widgetType = mLayer->editFormConfig()->widgetType( field.name() );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( field.name() );
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( widgetType, mLayer, idx, widgetConfig, myWidget, this, mContext );

View File

@ -292,7 +292,7 @@ void QgsAttributeFormEditorWidget::updateWidgets()
{
//first update the tool buttons
bool hasMultiEditButton = ( mEditPage->layout()->indexOf( mMultiEditButton ) >= 0 );
bool fieldReadOnly = layer()->editFormConfig()->readOnly( mWidget->fieldIdx() );
bool fieldReadOnly = layer()->editFormConfig().readOnly( mWidget->fieldIdx() );
if ( hasMultiEditButton )
{

View File

@ -397,7 +397,7 @@ void QgsGrassPlugin::onEditingStarted()
return;
mOldStyles[vectorLayer] = vectorLayer->styleManager()->currentStyle();
mFormSuppress[vectorLayer] = vectorLayer->editFormConfig()->suppress();
mFormSuppress[vectorLayer] = vectorLayer->editFormConfig().suppress();
// Because the edit style may be stored to project:
// - do not translate because it may be loaded in QGIS running with different language
@ -515,7 +515,7 @@ void QgsGrassPlugin::addFeature()
grassProvider->setNewFeatureType( GV_AREA );
formSuppress = QgsEditFormConfig::SuppressOn;
}
vectorLayer->editFormConfig()->setSuppress( formSuppress );
vectorLayer->editFormConfig().setSuppress( formSuppress );
}
void QgsGrassPlugin::onSplitFeaturesTriggered( bool checked )

View File

@ -1128,8 +1128,8 @@ void QgsGrassProvider::startEditing( QgsVectorLayer *vectorLayer )
// TODO: enable cats editing once all consequences are implemented
// disable cat and topo symbol editing
vectorLayer->editFormConfig()->setReadOnly( mLayer->keyColumn(), true );
vectorLayer->editFormConfig()->setReadOnly( mLayer->fields().size() - 1, true );
vectorLayer->editFormConfig().setReadOnly( mLayer->keyColumn(), true );
vectorLayer->editFormConfig().setReadOnly( mLayer->fields().size() - 1, true );
mEditedCount++;

View File

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

View File

@ -3319,9 +3319,9 @@ QDomElement QgsWmsServer::createFeatureGML(
QString QgsWmsServer::replaceValueMapAndRelation( QgsVectorLayer* vl, int idx, const QString& attributeVal )
{
if ( QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( vl->editFormConfig()->widgetType( idx ) ) )
if ( QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( vl->editFormConfig().widgetType( idx ) ) )
{
QgsEditorWidgetConfig cfg( vl->editFormConfig()->widgetConfig( idx ) );
QgsEditorWidgetConfig cfg( vl->editFormConfig().widgetConfig( idx ) );
QString value( factory->representValue( vl, idx, cfg, QVariant(), attributeVal ) );
if ( cfg.value( "AllowMulti" ).toBool() && value.startsWith( "{" ) && value.endsWith( "}" ) )
{

View File

@ -75,7 +75,7 @@ void TestQgsVectorLayerSaveAsDialog::testAttributesAsDisplayedValues()
QVERIFY( tempLayer->isValid() );
// Set a widget
tempLayer->editFormConfig()->setWidgetType( 0, "ValueRelation" );
tempLayer->editFormConfig().setWidgetType( 0, "ValueRelation" );
QgsVectorLayerSaveAsDialog d( tempLayer.data() );

View File

@ -82,7 +82,9 @@ void TestQgsAttributeForm::testFieldConstraint()
QString invalidLabel = "col0<font color=\"red\">*</font>";
// set constraint
layer->editFormConfig()->setExpression( 0, QString() );
QgsEditFormConfig config = layer->editFormConfig();
config.setExpression( 0, QString() );
layer->setEditFormConfig( config );
// get wrapper
QgsEditorWidgetWrapper *ww;
@ -93,7 +95,8 @@ void TestQgsAttributeForm::testFieldConstraint()
QCOMPARE( label->text(), QString( "col0" ) );
// set a not null constraint
layer->editFormConfig()->setExpression( 0, "col0 is not null" );
config.setExpression( 0, "col0 is not null" );
layer->setEditFormConfig( config );
// set value to 1
ww->setValue( 1 );
@ -127,10 +130,12 @@ void TestQgsAttributeForm::testFieldMultiConstraints()
ft.setAttribute( "col3", 3 );
// set constraints for each field
layer->editFormConfig()->setExpression( 0, QString() );
layer->editFormConfig()->setExpression( 1, QString() );
layer->editFormConfig()->setExpression( 2, QString() );
layer->editFormConfig()->setExpression( 3, QString() );
QgsEditFormConfig config = layer->editFormConfig();
config.setExpression( 0, QString() );
config.setExpression( 1, QString() );
config.setExpression( 2, QString() );
config.setExpression( 3, QString() );
layer->setEditFormConfig( config );
// build a form for this feature
QgsAttributeForm form( layer );
@ -161,10 +166,11 @@ void TestQgsAttributeForm::testFieldMultiConstraints()
QCOMPARE( label3->text(), QString( "col3" ) );
// update constraint
layer->editFormConfig()->setExpression( 0, "col0 < (col1 * col2)" );
layer->editFormConfig()->setExpression( 1, QString() );
layer->editFormConfig()->setExpression( 2, QString() );
layer->editFormConfig()->setExpression( 3, "col0 = 2" );
config.setExpression( 0, "col0 < (col1 * col2)" );
config.setExpression( 1, QString() );
config.setExpression( 2, QString() );
config.setExpression( 3, "col0 = 2" );
layer->setEditFormConfig( config );
// change value
ww0->setValue( 2 ); // update col0
@ -197,6 +203,11 @@ void TestQgsAttributeForm::testOKButtonStatus()
ft.setAttribute( "col0", 0 );
ft.setValid( true );
// set constraint
QgsEditFormConfig config = layer->editFormConfig();
config.setExpression( 0, QString() );
layer->setEditFormConfig( config );
// build a form for this feature
QgsAttributeForm form( layer );
form.setFeature( ft );
@ -212,9 +223,6 @@ void TestQgsAttributeForm::testOKButtonStatus()
QSignalSpy spy2( layer, SIGNAL( editingStarted() ) );
QSignalSpy spy3( layer, SIGNAL( editingStopped() ) );
// set constraint
layer->editFormConfig()->setExpression( 0, QString() );
// no constraint but layer not editable : OK button disabled
QCOMPARE( layer->isEditable(), false );
QCOMPARE( okButton->isEnabled(), false );
@ -226,12 +234,14 @@ void TestQgsAttributeForm::testOKButtonStatus()
QCOMPARE( okButton->isEnabled(), true );
// invalid constraint and editable layer : OK button disabled
layer->editFormConfig()->setExpression( 0, "col0 = 0" );
config.setExpression( 0, "col0 = 0" );
layer->setEditFormConfig( config );
ww->setValue( 1 );
QCOMPARE( okButton->isEnabled(), false );
// valid constraint and editable layer : OK button enabled
layer->editFormConfig()->setExpression( 0, "col0 = 2" );
config.setExpression( 0, "col0 = 2" );
layer->setEditFormConfig( config );
ww->setValue( 2 );
QCOMPARE( okButton->isEnabled(), true );