Skip to content
Permalink
Browse files
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 1, 2021
1 parent 30b1ff2 commit ad533bba39353f4dbce1c16834978461ce9db6c0
Showing with 63 additions and 2 deletions.
  1. +21 −2 src/gui/editorwidgets/qgsuuidwidgetwrapper.cpp
  2. +8 −0 src/gui/editorwidgets/qgsuuidwidgetwrapper.h
  3. +34 −0 tests/src/python/test_qgseditwidgets.py
@@ -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;
@@ -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();
}
@@ -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;

@@ -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 ad533bb

Please sign in to comment.