-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Add null handling to value map edit widget (fixes #15215) #3274
Conversation
@@ -24,10 +26,13 @@ QgsValueMapWidgetWrapper::QgsValueMapWidgetWrapper( QgsVectorLayer* vl, int fiel | |||
|
|||
QVariant QgsValueMapWidgetWrapper::value() const | |||
{ | |||
QVariant v; | |||
QString v; |
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.
Better to make that a QVariant
and only have a single return in the end
@m-kuhn Is this what you meant by "single return in the end"? |
Yes, thanks. I also wondered if the Right now, the widget setting for NULL and the application representation setting for NULL have to match, is this correct? |
The added toString() isn't required anymore, that's true. I'll fix that. The idea of this PR is that you should be able to do something like this: (assuming that 'NULL' is the application-wide representation for null values.) Currently, this would just try to write the literal string value 'NULL' into the attribute when selecting the first option. |
I really like the functionality. I'm just a bit worried about the portability of the project, mixing representation and data seems to be a bit brittle. What would be great it to make the whole configuration for the Value Map a bit more advanced. At the moment it's just a key-value pair which is saved. This leads to ugly side-effects like leftovers from configurations from other widgets when you start configuring it. The proper way to go would be to move the configuration to a QVariantMap in a dedicated key in the configuration. (See e.g. relationreferencefactory that does a similar thing for a stringlist). Sorry, getting a bit off-topic here :) If the above is implemented, there could also be a dedicated boolean key "AddNull" which would be semantically safe. Would you be able to implement that for merging for QGIS 3 (I guess it's a bit late for QGIS 2 now). To fix the current behavior, what do you think about this: We make a hardcoded string |
I agree that the value map widget could use some improvements. In addition to a widget-specific null configuration it should perhaps also try to actually use the data type which the attribute actually has. Currently all configuration is done with strings, so that the result after choosing is always a string, which leads to queries like As for a quick fix, my thought has been that the application-wide null setting is there for a reason, namely that some people apparently really want to write the string 'NULL' into a field. So I think that the value map should also allow to enter that value, if QGis is configured accordingly. |
But this string is nowhere to be written by the user (apart from the configuration). Normally it's written by the user into a text field and the converted to a null value which is appropriate for the backend. If you think about it in an MVC concept way.
And the result is that if you like to write 'NULL' for NULL and your colleague likes to write empty string '' for NULL values and you give him your project it will be broken. |
That is true. And perhaps that is a more common problem than that someone really wants to enter the string 'NULL' by using a value map. Ok, I'll see if I can change it to a hard-coded value and add a button, like you suggested. :) |
So how about this? Internally the null value is represented as one particular hard-coded GUID. A bit of a hack, but I think it prevents both kinds of problem. If doing it like this, perhaps the GUID should be stored somewhere as a constant, but at the moment the widget itself and the configuration dialog don't seem to share a common header file. |
Wow, this is exactly how I thought it should be! Can you convince me? ;) |
{ | ||
tableWidget->setItem( row, 0, new QTableWidgetItem( mit.key() ) ); | ||
} | ||
setRow( row, mit.key(), QString( "" ) ); |
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.
FYI, there's also a NULL string
@@ -48,13 +49,17 @@ QgsEditorWidgetConfig QgsValueMapConfigDlg::config() | |||
if ( !ki ) | |||
continue; | |||
|
|||
QString ks = ki->text(); | |||
if (( ks == QString( "NULL" ) ) && !( ki->flags() & Qt::ItemIsEditable ) ) | |||
ks = "{2839923C-8B7D-419E-B84B-CA2FE9B80EC7}"; |
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.
can you make this a #define somewhere to avoid the multiple places it's manually reused?
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.e. just include the config in the widget
Yes, it has turned out a bit bigger than I first expected! I've done some more testing with a colleague just now. The functionality seems to be ok, but he complained that the value is displayed as "NULL" even if the global null representation setting is different. I think he is right, so I'll fix that. |
Cool, if it's for displaying only it's the right thing to do I think. Did you consider to expand the editwidget test? https://github.com/qgis/QGIS/blob/master/tests/src/python/test_qgseditwidgets.py |
@m-kuhn Thanks for the suggestion! I've added a few unit tests and they did indeed catch a minor issue with my code. |
Thanks a lot! |
Great!
I've been thinking about this a bit more, and I cannot think of a really suitable solution here. It is probably desired not to break things when you open a project saved by a previous QGIS version. So, then, a value map saved in the current format needs to be converted on-the-fly to the new format. But such a function would also 'upgrade' those left-overs from other widgets into a value map of the new type, right? So then, not much is solved after all. |
There is the possibility to upgrade on project load. Then it would only affect old configurations and no left-overs. There is a "projectupgrader" class (can't remember the name right now). How does that sound? Smooth upgrade to 3.0 is not a strict requirement - but from my side appreciated. |
) * Add null handling to value map edit widget (fixes qgis#15215) * Return QVariant type * Use hardcoded value for 'null' representation * Detect "null" value when loading value map from csv; use null QString constructor * Use configured "null" representation for display in value map * Use single definition for value map null representation guid * Added unit test for value map widget and fixed value displaying bug (cherry picked from commit d2c9863)
) * Add null handling to value map edit widget (fixes qgis#15215) * Return QVariant type * Use hardcoded value for 'null' representation * Detect "null" value when loading value map from csv; use null QString constructor * Use configured "null" representation for display in value map * Use single definition for value map null representation guid * Added unit test for value map widget and fixed value displaying bug (cherry picked from commit d2c9863)
* Add null handling to value map edit widget (fixes #15215) * Return QVariant type * Use hardcoded value for 'null' representation * Detect "null" value when loading value map from csv; use null QString constructor * Use configured "null" representation for display in value map * Use single definition for value map null representation guid * Added unit test for value map widget and fixed value displaying bug (cherry picked from commit d2c9863)
See title. :)
This makes it possible to use the NULL placeholder value in the value map widget, just like in the other editing widgets, so that NULL values can be displayed with an appropriate description, and so that values can be reset to NULL.
I hope this can also be applied to the LTR release 2.14.