-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP Correct array string display in table and form #9610
Conversation
src/core/qgsfield.cpp
Outdated
@@ -268,6 +268,11 @@ QString QgsField::displayString( const QVariant &v ) const | |||
{ | |||
return QObject::tr( "BLOB" ); | |||
} | |||
else if ( d->type == QVariant::StringList ) | |||
{ | |||
return "{" + v.toStringList().join( "," ) + "}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return "{" + v.toStringList().join( "," ) + "}"; | |
return '{' + v.toStringList().join( ',' ) + '}'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about json format [x,y,z]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not, but If the data comes from postgres and there is more than two dimensions then, you will have something displayed like this : [{"test", "titi"}, {"tutu", "tata"}], because only the first level of array is parsed.
But if the data comes from JSON (is it possible?), it will be the opposite problem.
Not sure what the ideal solution is here, support of multidimensionnal array is quite partial in QGIS (like I said before, integer or float array won't work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if the data comes from JSON (is it possible?), it will be the opposite problem.
Yes https://qgis.org/en/site/forusers/visualchangelog34/#feature-json-jsonb-type-support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, displayString
treats the specific case of json and jsonb and return the json text as is.
My modifications will only occurs when we encounter an array which is not a json array.
So :
- In case of postgres array we would have : {{"test", "titi"}, {"tutu", "tata"}}
- In case of postgres json array we would have : [["test", "titi"], ["tutu", "tata"]]
Don't you think it's OK because each one respect the original text description?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand your point, but I can't find an elegant way of fixing this.
Best I can propose is to add a method on QgsField to setup the way we have to format array. To set the default to [
and ]
and call this method from postgres provider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the underlying problem that the postgres provider is only able to parse non-nested arrays?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can parse nested array, so 2 dimension string array would result in a QVariantList where each element is QStringList. I try it at first but I get other problems (I don't remember exactly why).
Some users seems to expect the original string when displaying PostGres array https://issues.qgis.org/issues/20872.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the silence, let's see if we can define some basic requirements
- internally in QGIS the data should be passed around as QVariantList (of QVariantLists) to allow for generic implementation for data aggregation and the like
- the "default" representation should be as generic as it gets (and my gut feeling is that json is more in this area than hstore formatting) but having this configurable (or autoconfigured) sounds good
... so re-reading your proposal #9610 (comment) sounds quite good, I must have misread that before, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the modifications described above 24fd6ce
Best I can propose is to add a method on QgsField to setup the way we have to format array. To set the default to [ and ] and call this method from postgres provider.
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
@m-kuhn Are you OK with the last modifications? |
Ping @m-kuhn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me the way it is.
Just some minor adjustments to be made before it's good to merge.
src/core/qgsfield_p.h
Outdated
@@ -60,6 +60,7 @@ class QgsFieldPrivate : public QSharedData | |||
, length( len ) | |||
, precision( prec ) | |||
, comment( comment ) | |||
, arrayFormatString( "[%1]" ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
, arrayFormatString( "[%1]" ) | |
, arrayFormatString( QStringLiteral( "[%1]" ) ) |
@@ -1046,6 +1046,7 @@ bool QgsPostgresProvider::loadFields() | |||
mDefaultValues.insert( mAttributeFields.size(), defValMap[tableoid][attnum] ); | |||
|
|||
QgsField newField = QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType ); | |||
newField.setArrayFormatString( "{%1}" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't that be conditional for hstore fields?
And don't forget QStringLiteral
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array field has to be formatted this way too, so it works for all postgres field, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forget about my previous comment, I forget about the json fields
@troopa81 what's your opinion about the current formatting possibilities? I am kind of undecided, because on the one hand they pretend to be very flexible with the replacement pattern, on the other hand, they only go half the way because the delimiter is hardcoded to |
I ask myself pretty much the same thing. Do you really think that one day, we will need to specify the delimeter, or quotes around the array values? It should be several enum (one for {} or [], one for delimeter, one for quote around value) or maybe a flags combination. I'm not sure but il seems a little bit complicated just to overcome this issue, no? Or maybe we can just start with an enum CURLY_BRACKETS and SQUARE_BRACKETS and see what comes next. |
I was more thinking of a |
formatting arrays (postgres for instance)
0ccbf2d
to
1dc486f
Compare
Looks fine to me indeed. I made the modifications 1dc486f I'm choose to define the enum as an integer in QgsField private class and convert it then https://github.com/qgis/QGIS/pull/9610/files#diff-b2de5811b366da6fc58a391b307efd38R207. Indeed private class cannot include public one or forward declare the enum. It's not so pretty but I don't see a better way. |
else if ( d->type == QVariant::StringList ) | ||
{ | ||
QString formatString = arrayFormatString() == QgsField::FormatHstore ? "{%1}" : "[%1]"; | ||
return formatString.arg( v.toStringList().join( "," ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if an element of the string list contains commas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a test to check it works
|
||
// string list field | ||
QgsField stringListField( QStringLiteral( "stringlist" ), QVariant::StringList, QStringLiteral( "_text" ) ); | ||
QCOMPARE( stringListField.displayString( QStringList() << "test1" << "test2" << "test3" ), QString( "[test1,test2,test3]" ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to test strings containing commas and []
Co-Authored-By: Alessandro Pasotti <elpaso@itopen.it>
Just now :)
I'm not sure this could be independent from the provider storage. For instance, when QGIS deals with multidimensionnal array (let say 2 dimension), it parses the first dimension and let the second dimension in raw format. For instance, if you have this kind of table
You will have a QVariantList containing 2 string :
So, for now, if you have a PG provider and you display your value with plain text widget, you will display If you want to force the representation, you will have to parse and store internally all array dimension. Futhermore, it seems that user wants to keep the original provider format https://issues.qgis.org/issues/20872#note-14 |
There is a big issue with edition, I have to think again about this. |
When we use It's not as simple as splitting upon commas because of possible espaced character (,") or because we have multidimensionnal array. Best option I think is to reuse the array parsing method developed in qgspostgresprovider (and move them to QgsArrayParser file). I made an (ugly) POC, it works. We could even add a method to format list to string in order to add quote and protect special character. |
Does it work if you make the enum an enum class? |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
Description
This is the following of PR #9048.
The previous PR fixes the read from postgres and it works with list widget but not with plain text widget.
This PR fixes the display with plain text widget for string array.
Be aware that there is still a problem to deal with integer and float array in plain text.
Checklist
fixes #11111
in the commit message next to the description[FEATURE]
in the commit message[needs-docs]
in the commit message and contain sufficient information in the commit message to be documentedscripts/prepare-commit.sh
script before each commit