-
-
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
[needs-docs][feature] Deferred handling of bad layers #8359
Conversation
Beautiful to see this happening. IMHO, this should not be optional, but rather our new behavior when handling missing layer source. It'd just be dragging weight to keep the current dialog on project load. |
@nirvn I'm slightly doubtful on this, if we drop the initial dialog, we should still notify the user that there are some "bad" layers, they might be buried inside nested groups and I think that the user should immediately know about "bad" layers. |
@elpaso , yep, beyond the indicator itself (which btw should break away from our standard dark gray outline in favor of a red outline icon) I suggest we through in an error message bar. I think we can insure that we end up with a superior experience focusing on one handling of bad layers. |
some questions:
|
That's the idea, and this is the (initial and too-basic-to-be-safe) test: https://github.com/qgis/QGIS/pull/8359/files#diff-d83688aa49188d5d74b506975e654145 Note that
Yes, maybe, the thing is that even now without this patch a layer can become invalid at any time in its lifecycle, so I think it's better to never assume layer validity. But I started to add some API methods to retrieve only valid layers: 5402505
I didn't test that yet, but I hope we do have checks in place or it will just crash (I'll make sure this part is tested).
I agree with you that it should not become active. |
Great to see work towards this feature - much needed!
Are you sure about this? I think at this point QgsProject::mapLayers() always gives you valid layers. What are the cases a layer suddenly becomes invalid? It may happen that a layer gets suddenly deleted, but then mapLayers() would not return such layer anymore... Also I am not sure if I understand the need for "invalidLayerProperties" - why not just save the invalid layers as they were before? This extra packaging of XML into a custom property to be stored inside XML again seems a bit strange. |
@wonder-sk about |
In PyQGIS we should raise an exception. |
[...]
Yes, that's exactly the case, the geometry type is stored in the project but it gets set to unknown when a "bad" layer is loaded, so we currently have that information available only in the original XML layer properties. |
Just a heads up -- there's actually two types of invalid layers we need to handle. One is layers which exist and where layer.isValid() returns false. The other is layer nodes in the layer tree which could not be resolved to a valid layer. These return a nullptr when calling QgsLayerTreeLayer::layer(), and result from operations like importing a QLR file with a broken data source. Just something to be aware of here. |
Another thing we need to consider -- the current (bad) bad layers dialog does allow repathing multiple items at once. If we drop the dialog we'd need to add a way for users to set the correct data source for multiple selected layers from the layer tree at once, or it'd be very annoying for fixing projects with many layers... |
@elpaso , @nyalldawson , I gave this some more thoughts overnight. While I'm a big -1 to have any kind of options with regard to how we load a project (i.e. missing data source popup etc.), it's indeed the case that the current (yes, bad) bad layers dialog makes it easier to repath multiple items at once. Here's my proposal: when loading a project, if layers with missing/inaccessible data sources are found, throw an error message bar which includes a button to open the (again, bad) bad layers dialog. It'd look like:
IMHO, that creates a much, much better UX overall, and we keep the option for mass repathing. |
Correct, basically a |
@3nids I've added relations to the mix, see ffde3ae#diff-d83688aa49188d5d74b506975e654145R121 |
9fdd888
to
d886da7
Compare
tests/src/python/test_qgsrelation.py
Outdated
for t in tab.children(): | ||
if (t.type() == QgsAttributeEditorElement.AeTypeRelation): | ||
valid = t.relation().isValid() | ||
if tab.type() == QgsAttributeEditorElement.AeTypeRelation: |
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.
@pblottiere would you please have a look here? This test was failing on travis with:
Traceback (most recent call last):
File "/root/QGIS/tests/src/python/test_qgsrelation.py", line 187, in testValidRelationAfterChangingStyle
for t in tab.children():
AttributeError: 'QgsAttributeEditorRelation' object has no attribute 'children'
I cannot reproduce the issue locally, it looks like the QgsAttributeEditorContainer
is not added and the QgsAttributeEditorRelation
is added directly.
I patched the test here but maybe there is something else I can check.
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.
@elpaso I'm glad to see that you've fixed your issue :)
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.
@pblottiere I can't say I fixed it, I still cannot reproduce it locally so I had to bisect using a docker (that took hours!!!) and found the guilty commit, which contained an apparently harmless change (storing the style as QDomDocument instead of and XML string), I just reverted that commit. So far so good.
cf87203
to
c63bc0a
Compare
Ready for merge. There might be some remaining corner cases to catch, and the UI can of course be polished, but I think we should merge and and start playing with it. |
This can be used to restore initial layer status or to apply styles and other layer properties if the data source is changed. The idea is that the user can fix bad layers at any time, and by setting a new datasource she probably wants to keep the original layer properties.
- do not add them to the manager dialog - do not add relations to not existent layers (but keep relations to invalid layers)
ecd8d43
to
64bd7a7
Compare
Wonderful, I've been hoping for this for years. Kudos |
@elpaso , I've just tested this. Few comments:
Beyond that, I'm just left with a big thanks for tackling this, it's been on many people's wishlist for a looong time. |
@nirvn thanks for testing! I'll check the other issues.
That button has a discard role with a "Discard" label, and a nice trashbin icon on linux. What it does is really a discard (destructive action, with a confirmation dialog), but you are right that "Close without saving" is confusing. We should add an explicit label, do you have any recommendation for the button text? I've added tooltips btw.
Sure, I was going to ask @SrNetoChan (he's my icon master!) to polish that icon, but perhaps you would like to help with that? |
@elpaso , I usually think tooltips aren't the greatest UX to begin with. If a label requires to get the tooltip to understand its meaning, IMHO we need to change the label :) The screenshot I took is on linux, ubuntu 18.10 (ubuntu has terrrible qt5 action button icons). I'd suggest using a custom icon, our trash icon. [ Browser ] [ ✔️ Apply ] [ 🗑️ Remove broken layers ] [ Defer broken layer source change ] Something like that :) |
How about: |
Created a pull request #8426 with a new icon: If possible I would also change the color of the layer name on the layers panel. Either a soft gray (like the one used when the layer is not visible, or a soft red. I also find the image icon on the left side a bit confusing, would prefer a de-activate check box. |
@SrNetoChan the standard generic layer image sucks, it's one of the few that are still in png format https://github.com/qgis/QGIS/blob/master/images/themes/default/mIconLayer.png |
Description
This is an implementation of the (optional) deferred bad layers handling, it also offers a "Change data source..." contextual menu for raster and vector layers.
This feature was funded by ARPA Piemonte (regional environment protection agency).
Use cases
User has a project set up to work on an intranet that has access to some internal resources like, for example:
User wants to be able to open the project when is not connected to the intranet, skip the bad layers dialog by choosing "Ignore all bad layers" and have the bad layers in the TOC marked as bad layers.
By clicking on the bad layer indicator (or right clicking in the contextual menu over the layer entry in the TOC), the user should be able to "fix" the bad layer by selecting another data source through either a data source select dialog filtered by layer type (vector or raster, or maybe also by provider key) or a browser dialog.
When the user makes any modifications to the project and save the project, the bad layers (if not "fixed" as described above) should be stored back in the project file unchanged (so that they are still available when back into the intranet network).
Open issues
setDataSource
reset the style to default, we want to restore original layer properties (not only style!), for doing that, I've come up with hack of storing the original XML layer properties to be able to use to restore the layer properties whensetDataSource
is called. The very same information could be useful if the user wanted to reset the original layer properties after having changed them, but this is not a priority for now. Needless to say that this is just a hack and we should probably store that information in the layer directly and not as a custom layer property as I did in this POC.TODO
setDataSource
for raster layerssetDataSource
to be able to preserve layer properties (if possible) when a new dataSource is set