Skip to content

Commit

Permalink
Ensure that UUID form widget doesn't try to generate UUIDs which
Browse files Browse the repository at this point in the history
are too long to fit in a string
  • Loading branch information
nyalldawson authored and github-actions[bot] committed Oct 18, 2021
1 parent dcf5cb6 commit 0a35415
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 0a35415

Please sign in to comment.