Skip to content

Commit

Permalink
Merge pull request #57690 from elpaso/bugfix-gh57634-value-map-length
Browse files Browse the repository at this point in the history
[forms] Validate value length for value maps
  • Loading branch information
elpaso authored Jun 7, 2024
2 parents 998744e + d4cf6b0 commit 8aff964
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 51 deletions.
81 changes: 77 additions & 4 deletions src/gui/editorwidgets/qgsvaluemapconfigdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ QgsValueMapConfigDlg::QgsValueMapConfigDlg( QgsVectorLayer *vl, int fieldIdx, QW
{
setupUi( this );

mValueMapErrorsLabel->setVisible( false );
mValueMapErrorsLabel->setStyleSheet( QStringLiteral( "QLabel { color : red; }" ) );

tableWidget->insertRow( 0 );

tableWidget->horizontalHeader()->setSectionsClickable( true );
Expand Down Expand Up @@ -90,12 +93,13 @@ void QgsValueMapConfigDlg::setConfig( const QVariantMap &config )
}

QList<QVariant> valueList = config.value( QStringLiteral( "map" ) ).toList();
QList<QPair<QString, QVariant>> orderedList;

if ( valueList.count() > 0 )
{
for ( int i = 0, row = 0; i < valueList.count(); i++, row++ )
{
setRow( row, valueList[i].toMap().constBegin().value().toString(), valueList[i].toMap().constBegin().key() );
orderedList.append( qMakePair( valueList[i].toMap().constBegin().value().toString(), valueList[i].toMap().constBegin().key() ) );
}
}
else
Expand All @@ -105,11 +109,14 @@ void QgsValueMapConfigDlg::setConfig( const QVariantMap &config )
for ( QVariantMap::ConstIterator mit = values.constBegin(); mit != values.constEnd(); mit++, row++ )
{
if ( QgsVariantUtils::isNull( mit.value() ) )
setRow( row, mit.key(), QString() );
orderedList.append( qMakePair( mit.key(), QVariant() ) );
else
setRow( row, mit.value().toString(), mit.key() );
orderedList.append( qMakePair( mit.value().toString(), mit.key() ) );
}
}

updateMap( orderedList, false );

}

void QgsValueMapConfigDlg::vCellChanged( int row, int column )
Expand All @@ -120,6 +127,24 @@ void QgsValueMapConfigDlg::vCellChanged( int row, int column )
tableWidget->insertRow( row + 1 );
} //else check type

if ( layer()->fields().exists( field() ) )
{
// check cell value
QTableWidgetItem *item = tableWidget->item( row, 0 );
if ( item )
{
const QString validValue = checkValueLength( item->text() );
if ( validValue.length() != item->text().length() )
{
const QString errorMessage = tr( "Value '%1' has been trimmed (maximum field length: %2)" )
.arg( item->text(), QString::number( layer()->fields().field( field() ).length() ) );
item->setText( validValue );
mValueMapErrorsLabel->setVisible( true );
mValueMapErrorsLabel->setText( QStringLiteral( "%1<br>%2" ).arg( errorMessage, mValueMapErrorsLabel->text() ) );
}
}
}

emit changed();
}

Expand Down Expand Up @@ -163,6 +188,8 @@ void QgsValueMapConfigDlg::updateMap( const QMap<QString, QVariant> &map, bool i
void QgsValueMapConfigDlg::updateMap( const QList<QPair<QString, QVariant>> &list, bool insertNull )
{
tableWidget->clearContents();
mValueMapErrorsLabel->setVisible( false );

for ( int i = tableWidget->rowCount() - 1; i > 0; i-- )
{
tableWidget->removeRow( i );
Expand All @@ -175,16 +202,62 @@ void QgsValueMapConfigDlg::updateMap( const QList<QPair<QString, QVariant>> &lis
++row;
}

constexpr int maxOverflowErrors { 5 };
QStringList reportedErrors;
const bool hasField { layer()->fields().exists( field() ) };
const QgsField mappedField { hasField ? layer()->fields().field( field() ) : QgsField() };

for ( const auto &pair : list )
{
if ( QgsVariantUtils::isNull( pair.second ) )
setRow( row, pair.first, QString() );
else
setRow( row, pair.first, pair.second.toString() );
{
const QString value { pair.first };
// Check value
const QString validValue = checkValueLength( value ) ;

if ( validValue.length() != value.length() )
{

if ( reportedErrors.length() < maxOverflowErrors )
{
reportedErrors.push_back( tr( "Value '%1' has been trimmed (maximum field length: %2)" )
.arg( value, QString::number( mappedField.length() ) ) );
}
else if ( reportedErrors.length() == maxOverflowErrors )
{
reportedErrors.push_back( tr( "Only first %1 errors have been reported." )
.arg( maxOverflowErrors ) );
}
}

setRow( row, validValue, pair.second.toString() );

// Show errors if any
if ( !reportedErrors.isEmpty() )
{
mValueMapErrorsLabel->setVisible( true );
mValueMapErrorsLabel->setText( reportedErrors.join( QStringLiteral( "<br>" ) ) );
}
}
++row;
}
}

QString QgsValueMapConfigDlg::checkValueLength( const QString &value )
{
if ( layer()->fields().exists( field() ) )
{
const QgsField mappedField { layer()->fields().field( field() ) };
if ( mappedField.length() > 0 && value.length() > mappedField.length() )
{
return value.mid( 0, mappedField.length() );
}
}
return value;
}

void QgsValueMapConfigDlg::populateComboBox( QComboBox *comboBox, const QVariantMap &config, bool skipNull )
{
const QList<QVariant> valueList = config.value( QStringLiteral( "map" ) ).toList();
Expand Down
8 changes: 8 additions & 0 deletions src/gui/editorwidgets/qgsvaluemapconfigdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ class GUI_EXPORT QgsValueMapConfigDlg : public QgsEditorConfigWidget, private Ui
private:
void setRow( int row, const QString &value, const QString &description );

/**
* Validates a value against the maximum allowed field length and trims it is necessary.
* \param value
* \return the validated field value trimmed if necessary
*/
QString checkValueLength( const QString &value );


private slots:
void copySelectionToClipboard();
void vCellChanged( int row, int column );
Expand Down
121 changes: 74 additions & 47 deletions src/ui/editorwidgets/qgsvaluemapconfigdlgbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<string notr="true">Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="5">
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="valueMapLabel">
<property name="text">
<string>Combo box with predefined items. Value is stored in the attribute, description is shown in the combo box.</string>
Expand All @@ -31,66 +31,93 @@
</property>
</widget>
</item>
<item row="1" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>339</width>
<height>20</height>
</size>
<item row="1" column="1">
<widget class="QPushButton" name="loadFromCSVButton">
<property name="text">
<string>Load Data from CSV File</string>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="5">
<widget class="QTableWidget" name="tableWidget">
<column>
<property name="text">
<string>Value</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
<item row="3" column="3" colspan="2">
<spacer name="horizontalSpacer_2">
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<width>339</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="addNullButton">
<property name="text">
<string>Add &quot;NULL&quot; value</string>
</property>
</widget>
<item row="2" column="0" colspan="3">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableWidget" name="tableWidget">
<column>
<property name="text">
<string>Value</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QLabel" name="mValueMapErrorsLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>No errors</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="removeSelectedButton">
<property name="text">
<string>Remove Selected</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="loadFromCSVButton">
<property name="text">
<string>Load Data from CSV File</string>
</property>
</widget>
<item row="3" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="addNullButton">
<property name="text">
<string>Add &quot;NULL&quot; value</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeSelectedButton">
<property name="text">
<string>Remove Selected</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
Expand Down

0 comments on commit 8aff964

Please sign in to comment.