Skip to content

Commit 583eeac

Browse files
committed
fix: save the guessed contacts layer and show one geology picker
The guessed contacts layer was set while _loading was set, so the guards of the pickers did not save it. Save it after _loading is cleared. Set the layer of the unit name picker before its field. On step 2, hide the geology picker of the column tab when the contacts come from the geology polygons. The source layers tab has that picker.
1 parent 0ab938f commit 583eeac

4 files changed

Lines changed: 96 additions & 1 deletion

File tree

‎loopstructural/gui/modelling/model_definition/stratigraphic_layers.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def _apply_contacts_source(self, source):
7171
source has another (the `basal_contacts` role). Each one is kept.
7272
"""
7373
from_geology = source == layer_roles.CONTACTS_FROM_GEOLOGY
74+
guessed = False
7475
self._loading = True
7576
try:
7677
if from_geology:
@@ -100,6 +101,7 @@ def _apply_contacts_source(self, source):
100101
self._guess_basal_contacts()
101102
layer = self.basalContactsLayer.currentLayer()
102103
field = self.unitNameField.currentField() or field
104+
guessed = layer is not None
103105
self.basalContactsLayer.setLayer(layer)
104106
self.unitNameField.setLayer(layer)
105107
if field:
@@ -108,6 +110,11 @@ def _apply_contacts_source(self, source):
108110
self.useZCoordinateLabel.setVisible(not from_geology)
109111
finally:
110112
self._loading = False
113+
if guessed:
114+
# The guards of the pickers skip a change while `_loading` is set,
115+
# so save the guessed layer here
116+
self._write_first_picker(layer, field)
117+
self._persist_selection()
111118

112119
def _add_contacts_source_combo(self):
113120
"""Add the choice of where the basal contacts come from."""
@@ -287,6 +294,8 @@ def _guess_basal_contacts(self):
287294
layer = self.data_manager.find_layer_by_name(basal_match)
288295
if layer:
289296
self.basalContactsLayer.setLayer(layer)
297+
# setField does nothing for a field that is not in the layer of the picker
298+
self.unitNameField.setLayer(layer)
290299
fields = [f.name() for f in layer.fields()]
291300
fmatcher = ColumnMatcher(fields)
292301
if unit_match := fmatcher.find_match('UNITNAME'):

‎loopstructural/gui/modelling/steps/pages.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
StratigraphicLayersWidget,
3232
)
3333

34+
from loopstructural.main import layer_roles
3435
from loopstructural.main.workflow_mode import WORKFLOW_MODE_LABELS, WORKFLOW_MODES
3536

3637
from . import checks
@@ -168,6 +169,25 @@ def __init__(self, parent=None, **kwargs):
168169
self.tabs.setCurrentWidget(self.tab)
169170
layout.addWidget(self.tabs, 1)
170171

172+
# With contacts from the geology polygons, the "Source layers" tab has
173+
# the geology picker, so do not show a second one on the column tab
174+
roles = self.data_manager.layer_roles
175+
roles.attach(self._on_layer_role_changed)
176+
self._show_column_geology_picker(roles.contacts_source)
177+
178+
def _show_column_geology_picker(self, source):
179+
self.tab.stratigraphic_column_widget.geologyGroup.setVisible(
180+
source != layer_roles.CONTACTS_FROM_GEOLOGY
181+
)
182+
183+
def _on_layer_role_changed(self, role, value):
184+
if role == 'contacts_source':
185+
try:
186+
self._show_column_geology_picker(value)
187+
except RuntimeError:
188+
# the page was deleted
189+
pass
190+
171191

172192
class FaultsStep(StepPage):
173193
"""Step 3: the fault layer, the fault topology and the adjacency tables."""

‎loopstructural/gui/modelling/stratigraphic_column/stratigraphic_column.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def _set_update_buttons_enabled(self, enabled):
289289
def _build_geology_group(self):
290290
"""Build the group with the geology layer, the unit name field and a
291291
summary of the unit names that have no match in the layer."""
292-
group = QGroupBox("Geology layer", self)
292+
group = self.geologyGroup = QGroupBox("Geology layer", self)
293293
form = QFormLayout(group)
294294
self.unitsLayerComboBox = QgsMapLayerComboBox()
295295
configure_layer_combo(
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""Pytest tests for the source layers of step 2 (`StratigraphicLayersWidget`)."""
2+
3+
import pytest
4+
from qgis.core import QgsProject, QgsVectorLayer
5+
from qgis.testing import start_app
6+
7+
from loopstructural.main import layer_roles
8+
from loopstructural.main.layer_roles import LayerRoles
9+
10+
11+
class _DataManager:
12+
"""The parts of the data manager that the widget uses."""
13+
14+
def __init__(self):
15+
self.layer_roles = LayerRoles()
16+
self.layer_roles.contacts_source = layer_roles.CONTACTS_FROM_LAYER
17+
self._basal_contacts = None
18+
self.basal_contacts_calls = []
19+
self.settings = {}
20+
21+
def set_basal_contacts_callback(self, callback):
22+
pass
23+
24+
def set_structural_orientations_callback(self, callback):
25+
pass
26+
27+
def find_layer_by_name(self, name):
28+
layers = QgsProject.instance().mapLayersByName(name)
29+
return layers[0] if layers else None
30+
31+
def get_widget_settings(self, key, default=None):
32+
return self.settings.get(key, default)
33+
34+
def set_widget_settings(self, key, value):
35+
self.settings[key] = value
36+
37+
def set_basal_contacts(self, layer, unitname_field=None, use_z_coordinate=False):
38+
self.basal_contacts_calls.append((layer, unitname_field))
39+
40+
def set_structural_orientations(self, *args, **kwargs):
41+
pass
42+
43+
def logger(self, *args, **kwargs):
44+
pass
45+
46+
47+
@pytest.fixture
48+
def contacts_layer():
49+
start_app()
50+
layer = QgsVectorLayer("LineString?field=unitname:string", "basal_contacts", "memory")
51+
QgsProject.instance().addMapLayer(layer)
52+
yield layer
53+
QgsProject.instance().removeMapLayer(layer.id())
54+
55+
56+
def test_the_guessed_contacts_layer_is_saved(contacts_layer):
57+
from loopstructural.gui.modelling.model_definition.stratigraphic_layers import (
58+
StratigraphicLayersWidget,
59+
)
60+
61+
data_manager = _DataManager()
62+
StratigraphicLayersWidget(data_manager=data_manager)
63+
64+
assert data_manager.basal_contacts_calls[-1] == (contacts_layer, 'unitname')
65+
settings = data_manager.settings['stratigraphic_layers_widget']
66+
assert settings['basal_layer'] == 'basal_contacts'

0 commit comments

Comments
 (0)