Skip to content

Commit 40bcb99

Browse files
committed
apply #3716: add value relation widget type
1 parent d508f56 commit 40bcb99

File tree

8 files changed

+283
-14
lines changed

8 files changed

+283
-14
lines changed

src/app/qgsattributetypedialog.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgsattributetypedialog.h"
2020
#include "qgsattributetypeloaddialog.h"
2121
#include "qgsvectordataprovider.h"
22+
#include "qgsmaplayerregistry.h"
2223

2324
#include "qgslogger.h"
2425

@@ -42,6 +43,17 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl )
4243
connect( loadFromLayerButton, SIGNAL( clicked() ), this, SLOT( loadFromLayerButtonPushed() ) );
4344
connect( loadFromCSVButton, SIGNAL( clicked() ), this, SLOT( loadFromCSVButtonPushed() ) );
4445
connect( tableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( vCellChanged( int, int ) ) );
46+
47+
valueRelationLayer->clear();
48+
foreach( QgsMapLayer *l, QgsMapLayerRegistry::instance()->mapLayers() )
49+
{
50+
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( l );
51+
if ( vl )
52+
valueRelationLayer->addItem( vl->name(), vl->id() );
53+
}
54+
55+
connect( valueRelationLayer, SIGNAL( currentIndexChanged( int ) ), this, SLOT( updateLayerColumns( int ) ) );
56+
valueRelationLayer->setCurrentIndex( -1 );
4557
}
4658

4759
QgsAttributeTypeDialog::~QgsAttributeTypeDialog()
@@ -59,6 +71,11 @@ QgsVectorLayer::RangeData QgsAttributeTypeDialog::rangeData()
5971
return mRangeData;
6072
}
6173

74+
QgsVectorLayer::ValueRelationData QgsAttributeTypeDialog::valueRelationData()
75+
{
76+
return mValueRelationData;
77+
}
78+
6279
QMap<QString, QVariant> &QgsAttributeTypeDialog::valueMap()
6380
{
6481
return mValueMap;
@@ -258,6 +275,10 @@ void QgsAttributeTypeDialog::setPageForEditType( QgsVectorLayer::EditType editTy
258275
case QgsVectorLayer::Calendar:
259276
setPage( 11 );
260277
break;
278+
279+
case QgsVectorLayer::ValueRelation:
280+
setPage( 12 );
281+
break;
261282
}
262283
}
263284

@@ -271,6 +292,11 @@ void QgsAttributeTypeDialog::setRange( QgsVectorLayer::RangeData range )
271292
mRangeData = range;
272293
}
273294

295+
void QgsAttributeTypeDialog::setValueRelation( QgsVectorLayer::ValueRelationData valueRelation )
296+
{
297+
mValueRelationData = valueRelation;
298+
}
299+
274300
void QgsAttributeTypeDialog::setIndex( int index, QgsVectorLayer::EditType editType )
275301
{
276302
mIndex = index;
@@ -396,6 +422,13 @@ void QgsAttributeTypeDialog::setIndex( int index, QgsVectorLayer::EditType editT
396422
editableUniqueValues->setChecked( editType == QgsVectorLayer::UniqueValuesEditable );
397423
break;
398424

425+
case QgsVectorLayer::ValueRelation:
426+
valueRelationLayer->setCurrentIndex( valueRelationLayer->findData( mValueRelationData.mLayer ) );
427+
valueRelationKeyColumn->setCurrentIndex( valueRelationKeyColumn->findText( mValueRelationData.mKey ) );
428+
valueRelationValueColumn->setCurrentIndex( valueRelationValueColumn->findText( mValueRelationData.mValue ) );
429+
valueRelationAllowNull->setChecked( mValueRelationData.mAllowNull );
430+
break;
431+
399432
case QgsVectorLayer::LineEdit:
400433
case QgsVectorLayer::UniqueValues:
401434
case QgsVectorLayer::Classification:
@@ -558,6 +591,13 @@ void QgsAttributeTypeDialog::accept()
558591
case 11:
559592
mEditType = QgsVectorLayer::Calendar;
560593
break;
594+
case 12:
595+
mEditType = QgsVectorLayer::ValueRelation;
596+
mValueRelationData.mLayer = valueRelationLayer->itemData( valueRelationLayer->currentIndex() ).toString();
597+
mValueRelationData.mKey = valueRelationKeyColumn->currentText();
598+
mValueRelationData.mValue = valueRelationValueColumn->currentText();
599+
mValueRelationData.mAllowNull = valueRelationAllowNull->isChecked();
600+
break;
561601
}
562602

563603
QDialog::accept();
@@ -567,3 +607,24 @@ QString QgsAttributeTypeDialog::defaultWindowTitle()
567607
{
568608
return tr( "Attribute Edit Dialog" );
569609
}
610+
611+
void QgsAttributeTypeDialog::updateLayerColumns( int idx )
612+
{
613+
valueRelationKeyColumn->clear();
614+
valueRelationValueColumn->clear();
615+
616+
QString id = valueRelationLayer->itemData( idx ).toString();
617+
618+
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer *>( QgsMapLayerRegistry::instance()->mapLayer( id ) );
619+
if ( !vl )
620+
return;
621+
622+
foreach( const QgsField &f, vl->pendingFields() )
623+
{
624+
valueRelationKeyColumn->addItem( f.name() );
625+
valueRelationValueColumn->addItem( f.name() );
626+
}
627+
628+
valueRelationKeyColumn->setCurrentIndex( valueRelationKeyColumn->findText( mValueRelationData.mKey ) );
629+
valueRelationValueColumn->setCurrentIndex( valueRelationValueColumn->findText( mValueRelationData.mValue ) );
630+
}

src/app/qgsattributetypedialog.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ class QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttributeTypeDialog
7777
*/
7878
void setCheckedState( QString checked, QString unchecked );
7979

80+
/**
81+
* Setter to value relation to be displayed and edited in this dialog
82+
* @param valueRelation value relation data which is to be displayed
83+
*/
84+
void setValueRelation( QgsVectorLayer::ValueRelationData valueRelationData );
85+
8086
/**
8187
* Getter for checked state after editing
8288
* @return string representing the checked
@@ -95,6 +101,11 @@ class QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttributeTypeDialog
95101
*/
96102
QgsVectorLayer::RangeData rangeData();
97103

104+
/**
105+
* Getter for value relation data
106+
*/
107+
QgsVectorLayer::ValueRelationData valueRelationData();
108+
98109
private slots:
99110
/**
100111
* Slot to handle change of index in combobox to select correct page
@@ -124,6 +135,11 @@ class QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttributeTypeDialog
124135
*/
125136
void vCellChanged( int row, int column );
126137

138+
/**
139+
* update columns list
140+
*/
141+
void updateLayerColumns( int idx );
142+
127143
private:
128144

129145
QString defaultWindowTitle();
@@ -147,6 +163,7 @@ class QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttributeTypeDialog
147163
int mIndex;
148164

149165
QgsVectorLayer::RangeData mRangeData;
166+
QgsVectorLayer::ValueRelationData mValueRelationData;
150167
QgsVectorLayer::EditType mEditType;
151168
};
152169

src/app/qgsvectorlayerproperties.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ void QgsVectorLayerProperties::attributeTypeDialog()
245245

246246
attributeTypeDialog.setValueMap( mValueMaps.value( index, layer->valueMap( index ) ) );
247247
attributeTypeDialog.setRange( mRanges.value( index, layer->range( index ) ) );
248+
attributeTypeDialog.setValueRelation( mValueRelationData.value( index, layer->valueRelation( index ) ) );
248249

249250
QPair<QString, QString> checkStates = mCheckedStates.value( index, layer->checkedState( index ) );
250251
attributeTypeDialog.setCheckedState( checkStates.first, checkStates.second );
@@ -272,6 +273,9 @@ void QgsVectorLayerProperties::attributeTypeDialog()
272273
case QgsVectorLayer::CheckBox:
273274
mCheckedStates.insert( index, attributeTypeDialog.checkedState() );
274275
break;
276+
case QgsVectorLayer::ValueRelation:
277+
mValueRelationData.insert( index, attributeTypeDialog.valueRelationData() );
278+
break;
275279
case QgsVectorLayer::LineEdit:
276280
case QgsVectorLayer::TextEdit:
277281
case QgsVectorLayer::UniqueValues:
@@ -554,6 +558,7 @@ void QgsVectorLayerProperties::setupEditTypes()
554558
editTypeMap.insert( QgsVectorLayer::CheckBox, tr( "Checkbox" ) );
555559
editTypeMap.insert( QgsVectorLayer::TextEdit, tr( "Text edit" ) );
556560
editTypeMap.insert( QgsVectorLayer::Calendar, tr( "Calendar" ) );
561+
editTypeMap.insert( QgsVectorLayer::ValueRelation, tr( "Value relation" ) );
557562
}
558563

559564
QString QgsVectorLayerProperties::editTypeButtonText( QgsVectorLayer::EditType type )
@@ -635,6 +640,13 @@ void QgsVectorLayerProperties::apply()
635640
}
636641
break;
637642

643+
case QgsVectorLayer::ValueRelation:
644+
if ( mValueRelationData.contains( idx ) )
645+
{
646+
layer->valueRelation( idx ) = mValueRelationData[idx];
647+
}
648+
break;
649+
638650
case QgsVectorLayer::LineEdit:
639651
case QgsVectorLayer::UniqueValues:
640652
case QgsVectorLayer::UniqueValuesEditable:
@@ -945,8 +957,8 @@ QString QgsVectorLayerProperties::metadata()
945957
}
946958

947959
myMetadata += tr( "In layer spatial reference system units : " )
948-
+ tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
949-
.arg( xMin ).arg( yMin ).arg( xMax ).arg( yMax );
960+
+ tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
961+
.arg( xMin ).arg( yMin ).arg( xMax ).arg( yMax );
950962
}
951963
else
952964
{

src/app/qgsvectorlayerproperties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
173173
QMap<int, QgsVectorLayer::EditType> mEditTypeMap;
174174
QMap<int, QMap<QString, QVariant> > mValueMaps;
175175
QMap<int, QgsVectorLayer::RangeData> mRanges;
176+
QMap<int, QgsVectorLayer::ValueRelationData> mValueRelationData;
176177
QMap<int, QPair<QString, QString> > mCheckedStates;
177178

178179
QFont mDiagramFont;

src/core/qgsvectorlayer.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,6 +3020,14 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
30203020
{
30213021
mCheckedStates[ name ] = QPair<QString, QString>( editTypeElement.attribute( "checked" ), editTypeElement.attribute( "unchecked" ) );
30223022
}
3023+
else if ( editType == ValueRelation )
3024+
{
3025+
QString id = editTypeElement.attribute( "layer" );
3026+
QString key = editTypeElement.attribute( "key" );
3027+
QString value = editTypeElement.attribute( "value" );
3028+
bool allowNull = editTypeElement.attribute( "allowNull" ) == "true";
3029+
mValueRelations[ name ] = ValueRelationData( id, key, value, allowNull );
3030+
}
30233031
}
30243032
}
30253033

@@ -3215,6 +3223,17 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
32153223
}
32163224
break;
32173225

3226+
case ValueRelation:
3227+
if ( mValueRelations.contains( it.key() ) )
3228+
{
3229+
const ValueRelationData &data = mValueRelations[ it.key()];
3230+
editTypeElement.setAttribute( "layer", data.mLayer );
3231+
editTypeElement.setAttribute( "key", data.mKey );
3232+
editTypeElement.setAttribute( "value", data.mValue );
3233+
editTypeElement.setAttribute( "allowNull", data.mAllowNull ? "true" : "false" );
3234+
}
3235+
break;
3236+
32183237
case LineEdit:
32193238
case UniqueValues:
32203239
case UniqueValuesEditable:
@@ -5263,3 +5282,21 @@ void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings& s )
52635282
mDiagramLayerSettings = new QgsDiagramLayerSettings();
52645283
*mDiagramLayerSettings = s;
52655284
}
5285+
5286+
QgsVectorLayer::ValueRelationData &QgsVectorLayer::valueRelation( int idx )
5287+
{
5288+
const QgsFieldMap &fields = pendingFields();
5289+
5290+
// FIXME: throw an exception!?
5291+
if ( fields.contains( idx ) )
5292+
{
5293+
QgsDebugMsg( QString( "field %1 not found" ).arg( idx ) );
5294+
}
5295+
5296+
if ( !mValueRelations.contains( fields[idx].name() ) )
5297+
{
5298+
mValueRelations[ fields[idx].name()] = ValueRelationData();
5299+
}
5300+
5301+
return mValueRelations[ fields[idx].name()];
5302+
}

src/core/qgsvectorlayer.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
9898
Classification,
9999
EditRange,
100100
SliderRange,
101-
CheckBox, /* added in 1.4 */
101+
CheckBox, /* added in 1.4 */
102102
FileName,
103103
Enumeration,
104-
Immutable, /* The attribute value should not be changed in the attribute form*/
105-
Hidden, /* The attribute value should not be shown in the attribute form @added in 1.4 */
106-
TextEdit, /* multiline edit @added in 1.4*/
107-
Calendar, /* calendar widget @added in 1.5 */
108-
DialRange, /* dial range @added in 1.5 */
104+
Immutable, /* The attribute value should not be changed in the attribute form*/
105+
Hidden, /* The attribute value should not be shown in the attribute form @added in 1.4 */
106+
TextEdit, /* multiline edit @added in 1.4*/
107+
Calendar, /* calendar widget @added in 1.5 */
108+
DialRange, /* dial range @added in 1.5 */
109+
ValueRelation, /* value map from an table @added in 1.8 */
109110
};
110111

111112
struct RangeData
@@ -119,6 +120,18 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
119120
QVariant mStep;
120121
};
121122

123+
struct ValueRelationData
124+
{
125+
ValueRelationData() {}
126+
ValueRelationData( QString layer, QString key, QString value, bool allowNull )
127+
: mLayer( layer ), mKey( key ), mValue( value ), mAllowNull( allowNull ) {}
128+
129+
QString mLayer;
130+
QString mKey;
131+
QString mValue;
132+
bool mAllowNull;
133+
};
134+
122135
/** Constructor */
123136
QgsVectorLayer( QString path = QString::null, QString baseName = QString::null,
124137
QString providerLib = QString::null, bool loadDefaultStyleFlag = true );
@@ -587,6 +600,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
587600
/**access range */
588601
RangeData &range( int idx );
589602

603+
/**access relations
604+
* @note added in 1.8
605+
**/
606+
ValueRelationData &valueRelation( int idx );
607+
590608
/**Adds a new overlay to this class. QgsVectorLayer takes ownership of the object
591609
@note this method was added in version 1.1
592610
*/
@@ -928,6 +946,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
928946
QMap< QString, QMap<QString, QVariant> > mValueMaps;
929947
QMap< QString, RangeData > mRanges;
930948
QMap< QString, QPair<QString, QString> > mCheckedStates;
949+
QMap< QString, ValueRelationData > mValueRelations;
931950

932951
QString mEditForm, mEditFormInit;
933952
//annotation form for this layer

0 commit comments

Comments
 (0)