Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Ensure that UUID form widget doesn't try to generate UUIDs which
are too long to fit in a string
  • Loading branch information
nyalldawson committed Nov 2, 2021
1 parent a3472f4 commit ec467dd
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/gui/editorwidgets/qgsuuidwidgetwrapper.cpp
Expand Up @@ -23,6 +23,19 @@ QgsUuidWidgetWrapper::QgsUuidWidgetWrapper( QgsVectorLayer *layer, int fieldIdx,
{
}

QString QgsUuidWidgetWrapper::createUiid( int maxLength )
{
if ( maxLength <= 0 )
{
return QUuid::createUuid().toString();
}
else
{
// trim left "{" and remove -'s... they are wasted characters given that we have a limited length!
return QUuid::createUuid().toString().replace( '-', QString() ).mid( 1, maxLength );
}
}

QVariant QgsUuidWidgetWrapper::value() const
{
QVariant v;
Expand Down Expand Up @@ -57,10 +70,16 @@ void QgsUuidWidgetWrapper::updateValues( const QVariant &value, const QVariantLi
{
if ( value.isNull() )
{
int maxLength = 0;
if ( field().type() == QVariant::String && field().length() > 0 )
{
maxLength = field().length();
}
const QString uuid = createUiid( maxLength );
if ( mLineEdit )
mLineEdit->setText( QUuid::createUuid().toString() );
mLineEdit->setText( uuid );
if ( mLabel )
mLabel->setText( QUuid::createUuid().toString() );
mLabel->setText( uuid );

emitValueChanged();
}
Expand Down
8 changes: 8 additions & 0 deletions src/gui/editorwidgets/qgsuuidwidgetwrapper.h
Expand Up @@ -48,7 +48,15 @@ class GUI_EXPORT QgsUuidWidgetWrapper : public QgsEditorWidgetWrapper
*/
explicit QgsUuidWidgetWrapper( QgsVectorLayer *layer, int fieldIdx, QWidget *editor = nullptr, QWidget *parent = nullptr );

/**
* Creates a UUID value, respecting the specified maximum length.
*
* \since QGIS 3.22
*/
static QString createUiid( int maxLength = 0 );

// QgsEditorWidgetWrapper interface

public:
QVariant value() const override;

Expand Down
34 changes: 34 additions & 0 deletions tests/src/python/test_qgseditwidgets.py
Expand Up @@ -164,5 +164,39 @@ def test_ValueMap_set_get(self):
QgsProject.instance().removeAllMapLayers()


class TestQgsUuidWidget(unittest.TestCase):

def test_create_uuid(self):
layer = QgsVectorLayer("none?field=text_no_limit:text(0)&field=text_limit:text(10)", "layer", "memory")
self.assertTrue(layer.isValid())
QgsProject.instance().addMapLayer(layer)

# unlimited length text field
wrapper = QgsGui.editorWidgetRegistry().create('UuidGenerator', layer, 0, {}, None, None)
_ = wrapper.widget()
feature = QgsFeature(layer.fields())
wrapper.setFeature(feature)
val = wrapper.value()
# we can't directly check the result, as it will be random, so just check it's general properties
self.assertEqual(len(val), 38)
self.assertEqual(val[0], '{')
self.assertEqual(val[-1], '}')

# limited length text field, value must be truncated
wrapper = QgsGui.editorWidgetRegistry().create('UuidGenerator', layer, 1, {}, None, None)
_ = wrapper.widget()
feature = QgsFeature(layer.fields())
wrapper.setFeature(feature)
val = wrapper.value()
# we can't directly check the result, as it will be random, so just check it's general properties
self.assertEqual(len(val), 10)
self.assertNotEqual(val[0], '{')
self.assertNotEqual(val[-1], '}')
with self.assertRaises(ValueError):
val.index('-')

QgsProject.instance().removeAllMapLayers()


if __name__ == "__main__":
unittest.main()

0 comments on commit ec467dd

Please sign in to comment.