add constraint description

This commit is contained in:
Blottiere Paul 2016-05-28 10:52:38 +02:00
parent bffe308aab
commit 8449e42ae0
14 changed files with 146 additions and 24 deletions

View File

@ -492,6 +492,22 @@ class QgsEditFormConfig : QObject
*/ */
void setExpression( int idx, const QString& str ); void setExpression( int idx, const QString& str );
/**
* Returns the constraint expression description of a specific filed.
* @param idx The index of the field
* @return the expression description
* @note added in QGIS 2.16
*/
QString expressionDescription( int idx ) const;
/**
* Set the constraint expression description for a specific field.
* @param idx The index of the field
* @param descr The description of the expression
* @note added in QGIS 2.16
*/
void setExpressionDescription( int idx, const QString &descr );
/** /**
* Returns if the field at fieldidx should be treated as NOT NULL value * Returns if the field at fieldidx should be treated as NOT NULL value
*/ */

View File

@ -115,6 +115,7 @@ class QgsEditorWidgetWrapper : QgsWidgetWrapper
* Emit this signal when the constraint status changed. * Emit this signal when the constraint status changed.
* @brief constraintStatusChanged * @brief constraintStatusChanged
* @param constraint represented as a string * @param constraint represented as a string
* @param desc is the constraint description
* @param err the error represented as a string. Empty if none. * @param err the error represented as a string. Empty if none.
* @param status * @param status
*/ */

View File

@ -180,6 +180,16 @@ bool QgsAttributeTypeDialog::labelOnTop() const
return labelOnTopCheckBox->isChecked(); return labelOnTopCheckBox->isChecked();
} }
void QgsAttributeTypeDialog::setExpressionDescription( const QString &desc )
{
constraintExpressionDescription->setText( desc );
}
QString QgsAttributeTypeDialog::expressionDescription()
{
return constraintExpressionDescription->text();
}
bool QgsAttributeTypeDialog::notNull() const bool QgsAttributeTypeDialog::notNull() const
{ {
return notNullCheckBox->isChecked(); return notNullCheckBox->isChecked();

View File

@ -85,7 +85,7 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
bool fieldEditable() const; bool fieldEditable() const;
/** /**
* Getter for checkbox for not null * Setter for checkbox for not null
*/ */
void setNotNull( bool notNull ); void setNotNull( bool notNull );
@ -94,6 +94,20 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
*/ */
bool notNull() const; bool notNull() const;
/*
* Setter for constraint expression description
* @param desc the expression description
* @note added in QGIS 2.16
**/
void setExpressionDescription( const QString &desc );
/*
* Getter for constraint expression description
* @return the expression description
* @note added in QGIS 2.16
**/
QString expressionDescription();
/** /**
* Getter for the constraint expression * Getter for the constraint expression
* @note added in QGIS 2.16 * @note added in QGIS 2.16

View File

@ -529,6 +529,7 @@ void QgsFieldsProperties::attributeTypeDialog()
attributeTypeDialog.setLabelOnTop( cfg.mLabelOnTop ); attributeTypeDialog.setLabelOnTop( cfg.mLabelOnTop );
attributeTypeDialog.setNotNull( cfg.mNotNull ); attributeTypeDialog.setNotNull( cfg.mNotNull );
attributeTypeDialog.setExpression( cfg.mConstraint ); attributeTypeDialog.setExpression( cfg.mConstraint );
attributeTypeDialog.setExpressionDescription( cfg.mConstraintDescription );
attributeTypeDialog.setWidgetV2Config( cfg.mEditorWidgetV2Config ); attributeTypeDialog.setWidgetV2Config( cfg.mEditorWidgetV2Config );
attributeTypeDialog.setWidgetV2Type( cfg.mEditorWidgetV2Type ); attributeTypeDialog.setWidgetV2Type( cfg.mEditorWidgetV2Type );
@ -539,6 +540,7 @@ void QgsFieldsProperties::attributeTypeDialog()
cfg.mEditable = attributeTypeDialog.fieldEditable(); cfg.mEditable = attributeTypeDialog.fieldEditable();
cfg.mLabelOnTop = attributeTypeDialog.labelOnTop(); cfg.mLabelOnTop = attributeTypeDialog.labelOnTop();
cfg.mNotNull = attributeTypeDialog.notNull(); cfg.mNotNull = attributeTypeDialog.notNull();
cfg.mConstraintDescription = attributeTypeDialog.expressionDescription();
cfg.mConstraint = attributeTypeDialog.expression(); cfg.mConstraint = attributeTypeDialog.expression();
cfg.mEditorWidgetV2Type = attributeTypeDialog.editorWidgetV2Type(); cfg.mEditorWidgetV2Type = attributeTypeDialog.editorWidgetV2Type();
@ -913,6 +915,7 @@ void QgsFieldsProperties::apply()
mLayer->editFormConfig()->setReadOnly( i, !cfg.mEditable ); mLayer->editFormConfig()->setReadOnly( i, !cfg.mEditable );
mLayer->editFormConfig()->setLabelOnTop( i, cfg.mLabelOnTop ); mLayer->editFormConfig()->setLabelOnTop( i, cfg.mLabelOnTop );
mLayer->editFormConfig()->setNotNull( i, cfg.mNotNull ); mLayer->editFormConfig()->setNotNull( i, cfg.mNotNull );
mLayer->editFormConfig()->setExpressionDescription( i, cfg.mConstraintDescription );
mLayer->editFormConfig()->setExpression( i, cfg.mConstraint ); mLayer->editFormConfig()->setExpression( i, cfg.mConstraint );
mLayer->editFormConfig()->setWidgetType( idx, cfg.mEditorWidgetV2Type ); mLayer->editFormConfig()->setWidgetType( idx, cfg.mEditorWidgetV2Type );
@ -981,6 +984,7 @@ QgsFieldsProperties::FieldConfig::FieldConfig()
, mEditableEnabled( true ) , mEditableEnabled( true )
, mLabelOnTop( false ) , mLabelOnTop( false )
, mNotNull( false ) , mNotNull( false )
, mConstraintDescription( QString() )
, mButton( nullptr ) , mButton( nullptr )
{ {
} }
@ -994,6 +998,7 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
mLabelOnTop = layer->editFormConfig()->labelOnTop( idx ); mLabelOnTop = layer->editFormConfig()->labelOnTop( idx );
mNotNull = layer->editFormConfig()->notNull( idx ); mNotNull = layer->editFormConfig()->notNull( idx );
mConstraint = layer->editFormConfig()->expression( idx ); mConstraint = layer->editFormConfig()->expression( idx );
mConstraintDescription = layer->editFormConfig()->expressionDescription( idx );
mEditorWidgetV2Type = layer->editFormConfig()->widgetType( idx ); mEditorWidgetV2Type = layer->editFormConfig()->widgetType( idx );
mEditorWidgetV2Config = layer->editFormConfig()->widgetConfig( idx ); mEditorWidgetV2Config = layer->editFormConfig()->widgetConfig( idx );

View File

@ -94,6 +94,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
bool mLabelOnTop; bool mLabelOnTop;
bool mNotNull; bool mNotNull;
QString mConstraint; QString mConstraint;
QString mConstraintDescription;
QPushButton* mButton; QPushButton* mButton;
QString mEditorWidgetV2Type; QString mEditorWidgetV2Type;
QMap<QString, QVariant> mEditorWidgetV2Config; QMap<QString, QVariant> mEditorWidgetV2Config;

View File

@ -135,6 +135,22 @@ void QgsEditFormConfig::setExpression( int idx, const QString& str )
mConstraints[ mFields.at( idx ).name()] = str; mConstraints[ 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()];
return description;
}
void QgsEditFormConfig::setExpressionDescription( int idx, const QString &descr )
{
if ( idx >= 0 && idx < mFields.count() )
mConstraintsDescription[ mFields.at( idx ).name()] = descr;
}
bool QgsEditFormConfig::notNull( int idx ) const bool QgsEditFormConfig::notNull( int idx ) const
{ {
if ( idx >= 0 && idx < mFields.count() ) if ( idx >= 0 && idx < mFields.count() )

View File

@ -484,12 +484,12 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
QgsEditorWidgetConfig widgetConfig( const QString& widgetName ) const; QgsEditorWidgetConfig widgetConfig( const QString& widgetName ) const;
/** /**
* Remove the configuration for the editor widget used to represent the field at the given index * Remove the configuration for the editor widget used to represent the field at the given index
* *
* @param fieldIdx The index of the field * @param fieldIdx The index of the field
* *
* @return true if successful, false if the field does not exist * @return true if successful, false if the field does not exist
*/ */
bool removeWidgetConfig( int fieldIdx ); bool removeWidgetConfig( int fieldIdx );
/** /**
@ -528,6 +528,22 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
*/ */
void setExpression( int idx, const QString& str ); void setExpression( int idx, const QString& str );
/**
* Returns the constraint expression description of a specific filed.
* @param idx The index of the field
* @return the expression description
* @note added in QGIS 2.16
*/
QString expressionDescription( int idx ) const;
/**
* Set the constraint expression description for a specific field.
* @param idx The index of the field
* @param descr The description of the expression
* @note added in QGIS 2.16
*/
void setExpressionDescription( int idx, const QString &descr );
/** /**
* Returns if the field at fieldidx should be treated as NOT NULL value * Returns if the field at fieldidx should be treated as NOT NULL value
*/ */
@ -657,6 +673,7 @@ class CORE_EXPORT QgsEditFormConfig : public QObject
QList< TabData > mTabs; QList< TabData > mTabs;
QMap< QString, QString> mConstraints; QMap< QString, QString> mConstraints;
QMap< QString, QString> mConstraintsDescription;
QMap< QString, bool> mFieldEditables; QMap< QString, bool> mFieldEditables;
QMap< QString, bool> mLabelOnTop; QMap< QString, bool> mLabelOnTop;
QMap< QString, bool> mNotNull; QMap< QString, bool> mNotNull;

View File

@ -253,6 +253,7 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
vectorLayer->editFormConfig()->setLabelOnTop( idx, ewv2CfgElem.attribute( "labelOnTop", "0" ) == "1" ); vectorLayer->editFormConfig()->setLabelOnTop( idx, ewv2CfgElem.attribute( "labelOnTop", "0" ) == "1" );
vectorLayer->editFormConfig()->setNotNull( idx, ewv2CfgElem.attribute( "notNull", "0" ) == "1" ); vectorLayer->editFormConfig()->setNotNull( idx, ewv2CfgElem.attribute( "notNull", "0" ) == "1" );
vectorLayer->editFormConfig()->setExpression( idx, ewv2CfgElem.attribute( "constraint", QString() ) ); 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 );
} }
@ -312,6 +313,7 @@ void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement&
ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) ); ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) );
ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) ); ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) );
ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig()->expression( 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 );

View File

@ -108,10 +108,13 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
bool toEmit( false ); bool toEmit( false );
QString errStr( tr( "predicate is True" ) ); 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 ); QVariant value = ft.attribute( mFieldIdx );
if ( ! expression.isEmpty() ) if ( ! expression.isEmpty() )
{ {
description = layer()->editFormConfig()->expressionDescription( mFieldIdx );
QgsExpressionContext context = QgsExpressionContext context =
QgsExpressionContextUtils::createFeatureBasedContext( ft, *ft.fields() ); QgsExpressionContextUtils::createFeatureBasedContext( ft, *ft.fields() );
context << QgsExpressionContextUtils::layerScope( layer() ); context << QgsExpressionContextUtils::layerScope( layer() );
@ -139,9 +142,13 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
{ {
QString fieldName = ft.fields()->field( mFieldIdx ).name(); QString fieldName = ft.fields()->field( mFieldIdx ).name();
expression = "( " + expression + " ) AND ( " + fieldName + " IS NOT NULL)"; expression = "( " + expression + " ) AND ( " + fieldName + " IS NOT NULL)";
description = "( " + description + " ) AND NotNull";
} }
else else
{
description = "NotNull";
expression = "NotNull"; expression = "NotNull";
}
mValidConstraint = mValidConstraint && !value.isNull(); mValidConstraint = mValidConstraint && !value.isNull();
@ -154,7 +161,7 @@ void QgsEditorWidgetWrapper::updateConstraint( const QgsFeature &ft )
if ( toEmit ) if ( toEmit )
{ {
updateConstraintWidgetStatus(); updateConstraintWidgetStatus();
emit constraintStatusChanged( expression, errStr, mValidConstraint ); emit constraintStatusChanged( expression, description, errStr, mValidConstraint );
} }
} }

View File

@ -137,10 +137,11 @@ class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
* Emit this signal when the constraint status changed. * Emit this signal when the constraint status changed.
* @brief constraintStatusChanged * @brief constraintStatusChanged
* @param constraint represented as a string * @param constraint represented as a string
* @param desc is the constraint description
* @param err the error represented as a string. Empty if none. * @param err the error represented as a string. Empty if none.
* @param status * @param status
*/ */
void constraintStatusChanged( const QString& constraint, const QString& err, bool status ); void constraintStatusChanged( const QString& constraint, const QString &desc, const QString& err, bool status );
public slots: public slots:
/** /**

View File

@ -795,17 +795,26 @@ void QgsAttributeForm::clearInvalidConstraintsMessage()
} }
} }
void QgsAttributeForm::displayInvalidConstraintMessage( const QStringList &f ) void QgsAttributeForm::displayInvalidConstraintMessage( const QStringList &f,
const QStringList &d )
{ {
clearInvalidConstraintsMessage(); clearInvalidConstraintsMessage();
// show only the third first error
int max = 3;
int size = f.size() > max ? max : f.size();
QString descriptions;
for ( int i = 0; i < size; i++ )
descriptions += "<br />- " + f[i] + ": " + d[i];
mInvalidConstraintMessageBarItem = mInvalidConstraintMessageBarItem =
new QgsMessageBarItem( tr( "Invalid fields:" ), new QgsMessageBarItem( tr( "Invalid fields: " ),
f.join( ", " ), QgsMessageBar::WARNING ); descriptions, QgsMessageBar::WARNING );
mMessageBar->pushItem( mInvalidConstraintMessageBarItem ); mMessageBar->pushItem( mInvalidConstraintMessageBarItem );
} }
bool QgsAttributeForm::currentFormValidConstraints( QStringList &invalidFields ) bool QgsAttributeForm::currentFormValidConstraints( QStringList &invalidFields,
QStringList &descriptions )
{ {
bool valid( true ); bool valid( true );
@ -817,6 +826,10 @@ bool QgsAttributeForm::currentFormValidConstraints( QStringList &invalidFields )
if ( ! eww->isValidConstraint() ) if ( ! eww->isValidConstraint() )
{ {
invalidFields.append( eww->field().name() ); invalidFields.append( eww->field().name() );
QString desc = eww->layer()->editFormConfig()->expressionDescription( eww->fieldIdx() );
descriptions.append( desc );
valid = false; // continue to get all invalif fields valid = false; // continue to get all invalif fields
} }
} }
@ -883,7 +896,7 @@ void QgsAttributeForm::onUpdatedFields()
} }
void QgsAttributeForm::onConstraintStatusChanged( const QString& constraint, void QgsAttributeForm::onConstraintStatusChanged( const QString& constraint,
const QString& err, bool ok ) const QString &description, const QString& err, bool ok )
{ {
QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( sender() ); QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( sender() );
Q_ASSERT( eww ); Q_ASSERT( eww );
@ -892,7 +905,8 @@ void QgsAttributeForm::onConstraintStatusChanged( const QString& constraint,
if ( buddy ) if ( buddy )
{ {
QString tooltip = tr( "Expression: " ) + constraint + "\n" + tr( "Constraint: " ) + err; QString tooltip = tr( "Description: " ) + description + "\n" +
tr( "Raw expression: " ) + constraint + "\n" + tr( "Constraint: " ) + err;
buddy->setToolTip( tooltip ); buddy->setToolTip( tooltip );
if ( !buddy->property( "originalText" ).isValid() ) if ( !buddy->property( "originalText" ).isValid() )
@ -986,11 +1000,11 @@ void QgsAttributeForm::synchronizeEnabledState()
// push a message and disable the OK button if constraints are invalid // push a message and disable the OK button if constraints are invalid
clearInvalidConstraintsMessage(); clearInvalidConstraintsMessage();
QStringList invalidFields; QStringList invalidFields, descriptions;
bool validConstraint = currentFormValidConstraints( invalidFields ); bool validConstraint = currentFormValidConstraints( invalidFields, descriptions );
if ( ! validConstraint ) if ( ! validConstraint )
displayInvalidConstraintMessage( invalidFields ); displayInvalidConstraintMessage( invalidFields, descriptions );
isEditable = isEditable & validConstraint; isEditable = isEditable & validConstraint;
@ -1205,7 +1219,6 @@ void QgsAttributeForm::init()
} }
mButtonBox->setVisible( buttonBoxVisible ); mButtonBox->setVisible( buttonBoxVisible );
<<<<<<< HEAD
if ( !mSearchButtonBox ) if ( !mSearchButtonBox )
{ {
mSearchButtonBox = new QWidget(); mSearchButtonBox = new QWidget();
@ -1618,7 +1631,8 @@ void QgsAttributeForm::afterWidgetInit()
} }
connect( eww, SIGNAL( valueChanged( const QVariant& ) ), this, SLOT( onAttributeChanged( const QVariant& ) ) ); connect( eww, SIGNAL( valueChanged( const QVariant& ) ), this, SLOT( onAttributeChanged( const QVariant& ) ) );
connect( eww, SIGNAL( constraintStatusChanged( QString, QString, bool ) ), this, SLOT( onConstraintStatusChanged( QString, QString, bool ) ) ); connect( eww, SIGNAL( constraintStatusChanged( QString, QString, QString, bool ) ),
this, SLOT( onConstraintStatusChanged( QString, QString, QString, bool ) ) );
} }
} }

View File

@ -234,8 +234,8 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
void onAttributeAdded( int idx ); void onAttributeAdded( int idx );
void onAttributeDeleted( int idx ); void onAttributeDeleted( int idx );
void onUpdatedFields(); void onUpdatedFields();
void onConstraintStatusChanged( const QString& constraint, const QString& err, bool ok ); void onConstraintStatusChanged( const QString& constraint,
const QString &description, const QString& err, bool ok );
void preventFeatureRefresh(); void preventFeatureRefresh();
void synchronizeEnabledState(); void synchronizeEnabledState();
void layerSelectionChanged(); void layerSelectionChanged();
@ -302,10 +302,11 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
void updateAllConstaints(); void updateAllConstaints();
void updateConstraints( QgsEditorWidgetWrapper *w ); void updateConstraints( QgsEditorWidgetWrapper *w );
bool currentFormFeature( QgsFeature &feature ); bool currentFormFeature( QgsFeature &feature );
bool currentFormValidConstraints( QStringList &invalidFields ); bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions );
void constraintDependencies( QgsEditorWidgetWrapper *w, QList<QgsEditorWidgetWrapper*> &wDeps ); void constraintDependencies( QgsEditorWidgetWrapper *w, QList<QgsEditorWidgetWrapper*> &wDeps );
void clearInvalidConstraintsMessage(); void clearInvalidConstraintsMessage();
void displayInvalidConstraintMessage( const QStringList &invalidFields ); void displayInvalidConstraintMessage( const QStringList &invalidFields,
const QStringList &description );
void displayNullFieldsMessage(); void displayNullFieldsMessage();
QgsMessageBarItem *mInvalidConstraintMessageBarItem; QgsMessageBarItem *mInvalidConstraintMessageBarItem;
QgsMessageBarItem *mFieldNotInitializedMessageBarItem; QgsMessageBarItem *mFieldNotInitializedMessageBarItem;

View File

@ -74,6 +74,23 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Constraint description</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="constraintExpressionDescription"/>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>