Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions EasyReflectometryApp/Backends/Py/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ def setCurrentModelIndex(self, new_value: int) -> None:
if self._project_lib.current_model_index != new_value:
self._project_lib.current_model_index = new_value
self.modelsIndexChanged.emit()
# A model switch starts from the first assembly and layer of the new model
# (the lib does the same). The layer table is cached, so the assembly/layer
# side has to be refreshed too, or the layer editor keeps showing the
# previous model's layers (#407).
self._project_lib.current_assembly_index = 0
self._project_lib.current_layer_index = 0
self._refreshCurrentAssemblySelectionState()
self.assembliesTableChanged.emit()
self.externalRefreshPlot.emit()
self.externalSampleChanged.emit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,21 @@ EaElements.GroupColumn {

EaComponents.TableViewComboBox{
readonly property int rowIndex: index
property string currentAssemblyName: Globals.BackendWrapper.sampleCurrentAssemblyName
// Track the row's own material so the combo re-syncs whenever the layer
// list is refreshed (e.g. a model switch), even if the assembly name and
// the materials list are unchanged.
readonly property string layerMaterial: {
const layer = Globals.BackendWrapper.sampleLayers[index]
return layer ? String(layer.material) : ""
}
horizontalAlignment: Text.AlignLeft
model: Globals.BackendWrapper.sampleMaterialNames
onActivated: function(comboIndex) {
Globals.BackendWrapper.sampleSetLayerMaterialAtIndex(rowIndex, comboIndex)
}
onModelChanged: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].material)
}
onCurrentAssemblyNameChanged: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].material)
}
Component.onCompleted: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].material)
}
onModelChanged: currentIndex = indexOfValue(layerMaterial)
onLayerMaterialChanged: currentIndex = indexOfValue(layerMaterial)
Component.onCompleted: currentIndex = indexOfValue(layerMaterial)
}

EaComponents.TableViewTextInput {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,21 @@ EaElements.GroupColumn {

EaComponents.TableViewComboBox{
readonly property int rowIndex: index
property string currentAssemblyName: Globals.BackendWrapper.sampleCurrentAssemblyName
// Track the row's own solvent so the combo re-syncs whenever the layer
// list is refreshed (e.g. a model switch), even if the assembly name and
// the materials list are unchanged.
readonly property string layerSolvent: {
const layer = Globals.BackendWrapper.sampleLayers[index]
return layer ? String(layer.solvent) : ""
}
horizontalAlignment: Text.AlignLeft
model: Globals.BackendWrapper.sampleMaterialNames
onActivated: function(comboIndex) {
Globals.BackendWrapper.sampleSetLayerSolventAtIndex(rowIndex, comboIndex)
}
onModelChanged: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].solvent)
}
onCurrentAssemblyNameChanged: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].solvent)
}
Component.onCompleted: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleLayers[index].solvent)
}
onModelChanged: currentIndex = indexOfValue(layerSolvent)
onLayerSolventChanged: currentIndex = indexOfValue(layerSolvent)
Component.onCompleted: currentIndex = indexOfValue(layerSolvent)
}
mouseArea.onPressed: {
if (Globals.BackendWrapper.sampleCurrentLayerIndex !== index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,18 @@ EaElements.GroupBox {
property var fullModel: ["Multi-layer", "Repeating Multi-layer", "Surfactant Layer"]
property var limitedModel: ["Multi-layer", "Repeating Multi-layer"]
model: index === 0 || index === assembliesView.model - 1 ? limitedModel : fullModel
// Track the row's own type so the combo re-syncs when the assemblies
// list is refreshed (e.g. a model switch reusing the same rows).
readonly property string assemblyType: {
const assembly = Globals.BackendWrapper.sampleAssemblies[index]
return assembly ? String(assembly.type) : ""
}
onActivated: function(comboIndex) {
Globals.BackendWrapper.sampleSetAssemblyTypeAtIndex(rowIndex, model[comboIndex])
}
Component.onCompleted: {
currentIndex = indexOfValue(Globals.BackendWrapper.sampleAssemblies[index].type)
}
onModelChanged: currentIndex = indexOfValue(assemblyType)
onAssemblyTypeChanged: currentIndex = indexOfValue(assemblyType)
Component.onCompleted: currentIndex = indexOfValue(assemblyType)
}

EaComponents.TableViewButton {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ EaElements.GroupBox {
EaComponents.TableViewTextInput {
horizontalAlignment: Text.AlignLeft
text: Globals.BackendWrapper.sampleModels[index].label
// Commit while typing so "Model editor: <name>" follows the edit
// instead of waiting for Enter or focus loss (#407).
onTextEdited: Globals.BackendWrapper.sampleSetModelNameAtIndex(index, text)
onEditingFinished: Globals.BackendWrapper.sampleSetModelNameAtIndex(index, text)
}

Expand Down
33 changes: 33 additions & 0 deletions tests/test_py_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,36 @@ def test_structure_cache_cleared_and_signal_emitted_on_invalidation(qcore_applic
assert emitted == [True]
assert len(backend.structure) == 4
assert backend.structureTotalThickness == 40.0


def test_set_current_model_index_refreshes_layers_and_selection(qcore_application):
materials = make_material_collection(make_material('Air'), make_material('D2O'), make_material('Si'))
first = make_sample(
make_assembly(name='Superphase', layers=[make_layer(name='Air Layer', material=materials[0])]),
make_assembly(name='Substrate', layers=[make_layer(name='Si Layer', material=materials[2])]),
)
second = make_sample(
make_assembly(name='Superphase', layers=[make_layer(name='D2O Layer', material=materials[1])]),
make_assembly(name='Substrate', layers=[make_layer(name='Si Layer', material=materials[2])]),
)
project = make_project(
materials=materials,
models=make_model_collection(make_model(name='M1', sample=first), make_model(name='M2', sample=second)),
)
project.current_model_index = 0
project.current_assembly_index = 1

backend = Sample(project)
assert [layer['material'] for layer in backend.layers] == ['Si']

fired = []
for name in ('assembliesIndexChanged', 'layersIndexChanged', 'layersChange'):
getattr(backend, name).connect(lambda name=name: fired.append(name))

backend.setCurrentModelIndex(1)

assert backend.currentModelName == 'M2'
assert backend.currentAssemblyIndex == 0
assert backend.currentLayerIndex == 0
assert [layer['material'] for layer in backend.layers] == ['D2O']
assert set(fired) == {'assembliesIndexChanged', 'layersIndexChanged', 'layersChange'}
Loading