Skip to content

Commit

Permalink
Refactor edit form configuration out of QgsVectorLayer
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Nov 19, 2015
1 parent d315a12 commit a50f2d0
Show file tree
Hide file tree
Showing 25 changed files with 1,156 additions and 668 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -40,6 +40,7 @@
%Include qgsdatumtransformstore.sip
%Include qgsdbfilterproxymodel.sip
%Include qgsdistancearea.sip
%Include qgseditformconfig.sip
%Include qgseditorwidgetconfig.sip
%Include qgserror.sip
%Include qgsexpression.sip
Expand Down
253 changes: 253 additions & 0 deletions python/core/qgseditformconfig.sip
@@ -0,0 +1,253 @@
/***************************************************************************
qgseditformconfig.sip
-------------------
begin : Nov 18, 2015
copyright : (C) 2015 by Matthias Kuhn
email : matthias at opengis dot ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

class QgsEditFormConfig : QObject
{
%TypeHeaderCode
#include <qgseditformconfig.h>
%End

public:
/** The different types to layout the attribute editor. */
enum EditorLayout
{
GeneratedLayout = 0, //!< Autogenerate a simple tabular layout for the form
TabLayout = 1, //!< Use a layout with tabs and group boxes. Needs to be configured.
UiFileLayout = 2 //!< Load a .ui file for the layout. Needs to be configured.
};

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<QgsEditFormConfig::GroupData>& groups );
QString mName;
QList<QString> mFields;
QList<QgsEditFormConfig::GroupData> mGroups;
};

/**
* Types of feature form suppression after feature creation
*/
enum FeatureFormSuppress
{
SuppressDefault = 0, //!< Use the application-wide setting
SuppressOn = 1, //!< Suppress feature form
SuppressOff = 2 //!< Do not suppress feature form
};

explicit QgsEditFormConfig( QObject* parent = nullptr );

/**
* This is only useful in combination with EditorLayout::TabLayout.
*
* Adds a new tab to the layout. Should be a QgsAttributeEditorContainer.
*/
void addTab( QgsAttributeEditorElement* data );

/**
* Returns a list of tabs for EditorLayout::TabLayout.
*/
QList< QgsAttributeEditorElement* > tabs();

/**
* Clears all the tabs for the attribute editor form with EditorLayout::TabLayout.
*/
void clearTabs();

/** Get the active layout style for the attribute editor for this layer */
EditorLayout layout();

/** Set the active layout style for the attribute editor for this layer */
void setLayout( EditorLayout editorLayout );

/** Get path to the .ui form. Only meaningful with EditorLayout::UiFileLayout. */
QString uiForm() const;

/**
* Set path to the .ui form.
* When a string is provided, the layout style will be set to EditorLayout::UiFileLayout,
* if an empty or a null string is provided, the layout style will be set to
* EditorLayout::GeneratedLayout.
*/
void setUiForm( const QString& ui );








// Widget stuff

/**
* Set the editor widget type for a field
*
* QGIS ships the following widget types, additional types may be available depending
* on plugins.
*
* <ul>
* <li>CheckBox (QgsCheckboxWidgetWrapper)</li>
* <li>Classification (QgsClassificationWidgetWrapper)</li>
* <li>Color (QgsColorWidgetWrapper)</li>
* <li>DateTime (QgsDateTimeEditWrapper)</li>
* <li>Enumeration (QgsEnumerationWidgetWrapper)</li>
* <li>FileName (QgsFileNameWidgetWrapper)</li>
* <li>Hidden (QgsHiddenWidgetWrapper)</li>
* <li>Photo (QgsPhotoWidgetWrapper)</li>
* <li>Range (QgsRangeWidgetWrapper)</li>
* <li>RelationReference (QgsRelationReferenceWidgetWrapper)</li>
* <li>TextEdit (QgsTextEditWrapper)</li>
* <li>UniqueValues (QgsUniqueValuesWidgetWrapper)</li>
* <li>UuidGenerator (QgsUuidWidgetWrapper)</li>
* <li>ValueMap (QgsValueMapWidgetWrapper)</li>
* <li>ValueRelation (QgsValueRelationWidgetWrapper)</li>
* <li>WebView (QgsWebViewWidgetWrapper)</li>
* </ul>
*
* @param attrIdx Index of the field
* @param widgetType Type id of the editor widget to use
*/
void setWidgetType( int fieldIdx, const QString& widgetType );

/**
* Get the id for the editor widget used to represent the field at the given index
*
* @param fieldIdx The index of the field
*
* @return The id for the editor widget or a NULL string if not applicable
*/
QString widgetType( int fieldIdx ) const;

/**
* Get the id for the editor widget used to represent the field at the given index
*
* @param fieldName The name of the field
*
* @return The id for the editor widget or a NULL string if not applicable
*
* @note python method name editorWidgetV2ByName
*/
QString widgetType( const QString& fieldName ) const;

/**
* Set the editor widget config for a field.
*
* Python: Will accept a map.
*
* Example:
* \code{.py}
* layer.setEditorWidgetV2Config( 1, { 'Layer': 'otherlayerid_1234', 'Key': 'Keyfield', 'Value': 'ValueField' } )
* \endcode
*
* @param attrIdx Index of the field
* @param config The config to set for this field
*
* @see setEditorWidgetV2() for a list of widgets and choose the widget to see the available options.
*/
void setWidgetConfig( int attrIdx, const QgsEditorWidgetConfig& config );

/**
* Get the configuration for the editor widget used to represent the field at the given index
*
* @param fieldIdx The index of the field
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*/
QgsEditorWidgetConfig widgetConfig( int fieldIdx ) const;

/**
* Get the configuration for the editor widget used to represent the field with the given name
*
* @param fieldName The name of the field
*
* @return The configuration for the editor widget or an empty config if the field does not exist
*
* @note python method name is editorWidgetV2ConfigByName
*/
QgsEditorWidgetConfig widgetConfig( const QString& fieldName ) const;

/**
* If this returns false, the widget at the given index will always be read-only.
*/
bool fieldEditable( int idx );

/**
* If set to false, the widget at the given index will be read-only, regardless of the
* layer's editable state and data provider capacities.
* If it is set to true, the widget's editable state will be synchronized with the layer's
* edit state.
*/
void setFieldEditable( int idx, bool editable );

/**
* If this returns true, the widget at the given index will receive its label on the previous line
* 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 );

/**
* If this is set to true, the widget at the given index will receive its label on
* the previous line while if it is set to false, the widget will receive its label
* on the left hand side.
* Labeling on top leaves more horizontal space for the widget itself.
**/
void setLabelOnTop( int idx, bool onTop );











// Python stuff


/** Get python function for edit form initialization */
QString initFunction() const;

/** Set python function for edit form initialization */
void setInitFunction( const QString& function );

/** Get python code for edit form initialization */
QString initCode() const;

/** Set python code for edit form initialization */
void setInitCode( const QString& code );

/** Return if python code shall be loaded for edit form initialization */
bool useInitCode() const;

/** Set if python code shall be used for edit form initialization */
void setUseInitCode( const bool useCode );

FeatureFormSuppress suppress() const;
void setSuppress( FeatureFormSuppress s );
};
14 changes: 1 addition & 13 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -1097,7 +1097,7 @@ class QgsVectorLayer : QgsMapLayer
/**
* Returns a list of tabs holding groups and fields
*/
QList< QgsAttributeEditorElement* > &attributeEditorElements();
QList< QgsAttributeEditorElement* > attributeEditorElements();
/**
* Clears all the tabs for the attribute editor form
*/
Expand Down Expand Up @@ -1255,21 +1255,9 @@ class QgsVectorLayer : QgsMapLayer
/** Get python function for edit form initialization */
QString editFormInit();

/** Get python code for edit form initialization */
QString editFormInitCode();

/** Reeturn if python code has to be loaded for edit form initialization */
bool editFormInitUseCode();

/** Set python function for edit form initialization */
void setEditFormInit( const QString& function );

/** Set python code for edit form initialization */
void setEditFormInitCode( const QString& code );

/** Set python code for edit form initialization */
void setEditFormInitUseCode( const bool useCode );

/**
* Access value map
* @deprecated Use editorWidgetV2Config() instead
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -336,7 +336,7 @@ void QgsAttributeTableDialog::columnBoxInit()
if ( idx < 0 )
continue;

if ( mLayer->editorWidgetV2( idx ) != "Hidden" )
if ( mLayer->editFormConfig()->widgetType( idx ) != "Hidden" )
{
QIcon icon = QgsApplication::getThemeIcon( "/mActionNewAttribute.png" );
QString alias = mLayer->attributeDisplayName( idx );
Expand Down Expand Up @@ -460,8 +460,8 @@ void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
int fldIdx = mLayer->fieldNameIndex( fieldName );
if ( fldIdx < 0 )
return;
const QString widgetType = mLayer->editorWidgetV2( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editorWidgetV2Config( fldIdx );
const QString widgetType = mLayer->editFormConfig()->widgetType( fldIdx );
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( fldIdx );
mCurrentSearchWidgetWrapper = QgsEditorWidgetRegistry::instance()->
createSearchWidget( widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer );
if ( mCurrentSearchWidgetWrapper->applyDirectly() )
Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsfeatureaction.cpp
Expand Up @@ -168,15 +168,15 @@ 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->featureFormSuppress() )
switch ( mLayer->editFormConfig()->suppress() )
{
case QgsVectorLayer::SuppressOn:
case QgsEditFormConfig::SuppressOn:
isDisabledAttributeValuesDlg = true;
break;
case QgsVectorLayer::SuppressOff:
case QgsEditFormConfig::SuppressOff:
isDisabledAttributeValuesDlg = false;
break;
case QgsVectorLayer::SuppressDefault:
case QgsEditFormConfig::SuppressDefault:
break;
}
if ( isDisabledAttributeValuesDlg )
Expand Down

2 comments on commit a50f2d0

@nirvn
Copy link
Contributor

@nirvn nirvn commented on a50f2d0 Dec 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-kuhn I think this might have lead to a regression whereas on master builds, opening the attribute dialog sets dual view mode (even though the default view, rows & columns, is toggled on in the bottom-right set of buttons).

@m-kuhn
Copy link
Member Author

@m-kuhn m-kuhn commented on a50f2d0 Dec 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know if it was caused by this, but it's fixed now.

Please sign in to comment.