Skip to content

Commit 1566e37

Browse files
committed
Fix merge attribute dialog mangles field values when layer has hidden
fields (fix #14235)
1 parent 92e5f67 commit 1566e37

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

src/app/qgsmergeattributesdialog.cpp

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,31 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
108108
mTableWidget->setRowCount( mFeatureList.size() + 2 );
109109

110110
//create combo boxes and insert attribute names
111-
const QgsFields& fields = mVectorLayer->fields();
111+
mFields = mVectorLayer->fields();
112112
QSet<int> pkAttrList = mVectorLayer->pkAttributeList().toSet();
113113

114114
int col = 0;
115-
for ( int idx = 0; idx < fields.count(); ++idx )
115+
mHiddenAttributes.clear();
116+
for ( int idx = 0; idx < mFields.count(); ++idx )
116117
{
117118
if ( mVectorLayer->editFormConfig()->widgetType( idx ) == "Hidden" ||
118119
mVectorLayer->editFormConfig()->widgetType( idx ) == "Immutable" )
120+
{
121+
mHiddenAttributes.insert( idx );
119122
continue;
123+
}
120124

121125
mTableWidget->setColumnCount( col + 1 );
122126

123-
QComboBox *cb = createMergeComboBox( fields[idx].type() );
127+
QComboBox *cb = createMergeComboBox( mFields.at( idx ) .type() );
124128
if ( pkAttrList.contains( idx ) )
125129
{
126130
cb->setCurrentIndex( cb->findData( "skip" ) );
127131
}
128132
mTableWidget->setCellWidget( 0, col, cb );
129133

130-
QTableWidgetItem *item = new QTableWidgetItem( fields[idx].name() );
131-
item->setData( Qt::UserRole, idx );
134+
QTableWidgetItem *item = new QTableWidgetItem( mFields.at( idx ).name() );
135+
item->setData( FieldIndex, idx );
132136
mTableWidget->setHorizontalHeaderItem( col++, item );
133137
}
134138

@@ -144,12 +148,13 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
144148

145149
for ( int j = 0; j < mTableWidget->columnCount(); j++ )
146150
{
147-
int idx = mTableWidget->horizontalHeaderItem( j )->data( Qt::UserRole ).toInt();
151+
int idx = mTableWidget->horizontalHeaderItem( j )->data( FieldIndex ).toInt();
148152

149153
QTableWidgetItem* attributeValItem = new QTableWidgetItem( attrs.at( idx ).toString() );
150154
attributeValItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
151155
mTableWidget->setItem( i + 1, j, attributeValItem );
152-
mTableWidget->setCellWidget( i + 1, j, QgsAttributeEditor::createAttributeEditor( mTableWidget, nullptr, mVectorLayer, idx, attrs.at( idx ) ) );
156+
QWidget* attributeWidget = QgsAttributeEditor::createAttributeEditor( mTableWidget, nullptr, mVectorLayer, idx, attrs.at( idx ) );
157+
mTableWidget->setCellWidget( i + 1, j, attributeWidget );
153158
}
154159
}
155160

@@ -307,21 +312,21 @@ void QgsMergeAttributesDialog::refreshMergedValue( int col )
307312

308313
QVariant QgsMergeAttributesDialog::featureAttribute( QgsFeatureId featureId, int col )
309314
{
310-
int idx = mTableWidget->horizontalHeaderItem( col )->data( Qt::UserRole ).toInt();
315+
int fieldIdx = mTableWidget->horizontalHeaderItem( col )->data( FieldIndex ).toInt();
311316

312317
int i;
313318
for ( i = 0; i < mFeatureList.size() && mFeatureList.at( i ).id() != featureId; i++ )
314319
;
315320

316321
QVariant value;
317322
if ( i < mFeatureList.size() &&
318-
QgsAttributeEditor::retrieveValue( mTableWidget->cellWidget( i + 1, col ), mVectorLayer, idx, value ) )
323+
QgsAttributeEditor::retrieveValue( mTableWidget->cellWidget( i + 1, col ), mVectorLayer, fieldIdx, value ) )
319324
{
320325
return value;
321326
}
322327
else
323328
{
324-
return QVariant( mVectorLayer->fields().at( col ).type() );
329+
return QVariant( mVectorLayer->fields().at( fieldIdx ).type() );
325330
}
326331
}
327332

@@ -508,30 +513,40 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
508513
return QgsAttributes();
509514
}
510515

511-
QgsAttributes results( mTableWidget->columnCount() );
512-
for ( int i = 0; i < mTableWidget->columnCount(); i++ )
516+
int widgetIndex = 0;
517+
QgsAttributes results( mFields.count() );
518+
for ( int fieldIdx = 0; fieldIdx < mFields.count(); ++fieldIdx )
513519
{
514-
int idx = mTableWidget->horizontalHeaderItem( i )->data( Qt::UserRole ).toInt();
520+
if ( mHiddenAttributes.contains( fieldIdx ) )
521+
{
522+
//hidden attribute, set to default value
523+
if ( mVectorLayer->dataProvider() )
524+
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
525+
else
526+
results[fieldIdx] = QVariant();
527+
continue;
528+
}
515529

516-
QComboBox *comboBox = qobject_cast<QComboBox *>( mTableWidget->cellWidget( 0, i ) );
530+
QComboBox *comboBox = qobject_cast<QComboBox *>( mTableWidget->cellWidget( 0, widgetIndex ) );
517531
if ( !comboBox )
518532
continue;
519533

520-
QTableWidgetItem *currentItem = mTableWidget->item( mFeatureList.size() + 1, i );
534+
QTableWidgetItem *currentItem = mTableWidget->item( mFeatureList.size() + 1, widgetIndex );
521535
if ( !currentItem )
522536
continue;
523537

524-
if ( idx >= results.count() )
525-
results.resize( idx + 1 ); // make sure the results vector is long enough (maybe not necessary)
538+
if ( fieldIdx >= results.count() )
539+
results.resize( fieldIdx + 1 ); // make sure the results vector is long enough (maybe not necessary)
526540

527541
if ( comboBox->itemData( comboBox->currentIndex() ).toString() != "skip" )
528542
{
529-
results[idx] = currentItem->data( Qt::DisplayRole );
543+
results[fieldIdx] = currentItem->data( Qt::DisplayRole );
530544
}
531545
else if ( mVectorLayer->dataProvider() )
532546
{
533-
results[idx] = mVectorLayer->dataProvider()->defaultValue( idx );
547+
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
534548
}
549+
widgetIndex++;
535550
}
536551

537552
return results;
@@ -540,9 +555,16 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
540555
QSet<int> QgsMergeAttributesDialog::skippedAttributeIndexes() const
541556
{
542557
QSet<int> skipped;
543-
for ( int i = 0; i < mTableWidget->columnCount(); ++i )
558+
int widgetIndex = 0;
559+
for ( int i = 0; i < mFields.count(); ++i )
544560
{
545-
QComboBox *comboBox = qobject_cast<QComboBox *>( mTableWidget->cellWidget( 0, i ) );
561+
if ( mHiddenAttributes.contains( i ) )
562+
{
563+
skipped << i;
564+
continue;
565+
}
566+
567+
QComboBox *comboBox = qobject_cast<QComboBox *>( mTableWidget->cellWidget( 0, widgetIndex ) );
546568
if ( !comboBox )
547569
{
548570
//something went wrong, better skip this attribute
@@ -554,6 +576,7 @@ QSet<int> QgsMergeAttributesDialog::skippedAttributeIndexes() const
554576
{
555577
skipped << i;
556578
}
579+
widgetIndex++;
557580
}
558581

559582
return skipped;

src/app/qgsmergeattributesdialog.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class APP_EXPORT QgsMergeAttributesDialog: public QDialog, private Ui::QgsMergeA
3434
{
3535
Q_OBJECT
3636
public:
37+
38+
enum ItemDataRole
39+
{
40+
FieldIndex = Qt::UserRole /*!< index of corresponding field in source table */
41+
};
42+
43+
3744
QgsMergeAttributesDialog( const QgsFeatureList& features, QgsVectorLayer* vl, QgsMapCanvas* canvas, QWidget * parent = nullptr, Qt::WindowFlags f = nullptr );
3845
~QgsMergeAttributesDialog();
3946

@@ -86,6 +93,9 @@ class APP_EXPORT QgsMergeAttributesDialog: public QDialog, private Ui::QgsMergeA
8693
/** Item that highlights the selected feature in the merge table*/
8794
QgsRubberBand* mSelectionRubberBand;
8895

96+
QgsFields mFields;
97+
QSet<int> mHiddenAttributes;
98+
8999
static QList< QgsStatisticalSummary::Statistic > mDisplayStats;
90100

91101
};

0 commit comments

Comments
 (0)