Skip to content

Commit b9a4fa0

Browse files
authored
Fix custom file crash and contrast not updating custom model (RascalSoftware#197)
1 parent 5d846d3 commit b9a4fa0

File tree

7 files changed

+65
-12
lines changed

7 files changed

+65
-12
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ extend-ignore-names = ['allKeys',
6464
'setEditorData',
6565
'setModel',
6666
'setModelData',
67+
'setText',
6768
'setValue',
6869
'showEvent',
6970
'sizeHint',

rascal2/widgets/delegates.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ def commit_and_close_editor(self):
4545

4646
def setEditorData(self, _editor: QtWidgets.QWidget, index):
4747
data = index.data(QtCore.Qt.ItemDataRole.DisplayRole)
48+
extra = index.data(QtCore.Qt.ItemDataRole.UserRole)
49+
if extra:
50+
self.widget.editor.path = extra
4851
self.widget.set_data(data)
4952

5053
def setModelData(self, _editor, model, index):
@@ -60,9 +63,9 @@ def __init__(self, parent):
6063
self.widget = parent
6164

6265
def createEditor(self, parent, option, index):
63-
func_names = self.widget.model.func_names[
66+
func_names = self.widget.model.func_names.get(
6467
index.siblingAtColumn(index.column() - 1).data(QtCore.Qt.ItemDataRole.DisplayRole)
65-
]
68+
)
6669
# we define the methods set_data and get_data
6770
# so that setEditorData and setModelData don't need
6871
# to know what kind of widget the editor is

rascal2/widgets/inputs.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def __init__(self, parent):
176176

177177
self.open_on_show = False
178178
self.setAutoFillBackground(True)
179+
self.path = ""
179180

180181
def mouseDoubleClickEvent(self, event):
181182
self.open()
@@ -186,12 +187,25 @@ def showEvent(self, event):
186187
self.open()
187188
self.open_on_show = False
188189

190+
def text(self):
191+
if self.path:
192+
return (Path(self.path) / super().text()).as_posix()
193+
return super().text()
194+
195+
def setText(self, value):
196+
# if value is a path, set text to the base name only.
197+
if isinstance(value, Path):
198+
self.path = value.parent.as_posix()
199+
super().setText(value.name)
200+
else:
201+
super().setText(value)
202+
189203
def open(self):
190204
"""Open file dialog and get the selected filename."""
191205
file_dialog = QtWidgets.QFileDialog(parent=self)
192-
file = file_dialog.getOpenFileName()[0]
206+
file = file_dialog.getOpenFileName(directory=self.path)[0]
193207
if file:
194-
self.setText(file)
208+
self.setText(Path(file))
195209
self.text_changed.emit()
196210

197211

rascal2/widgets/project/project.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,15 @@ def create_edit_view(self) -> QtWidgets.QWidget:
233233
self.edit_absorption_checkbox.checkStateChanged.connect(
234234
lambda s: self.edit_tabs["Layers"].tables["layers"].set_absorption(s == QtCore.Qt.CheckState.Checked)
235235
)
236-
for tab in ["Experimental Parameters", "Layers", "Backgrounds", "Resolutions", "Data", "Domains"]:
236+
for tab in [
237+
"Experimental Parameters",
238+
"Layers",
239+
"Backgrounds",
240+
"Resolutions",
241+
"Data",
242+
"Domains",
243+
"Custom Files",
244+
]:
237245
for table in self.edit_tabs[tab].tables.values():
238246
table.edited.connect(lambda: self.edit_tabs["Contrasts"].tables["contrasts"].update_item_view())
239247

rascal2/widgets/project/tables.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,13 @@ def flags(self, index):
588588

589589
def data(self, index, role=QtCore.Qt.ItemDataRole.DisplayRole):
590590
data = super().data(index, role)
591-
if role == QtCore.Qt.ItemDataRole.DisplayRole and self.index_header(index) == "filename" and self.edit_mode:
592-
if data == "" or data == "Browse...":
591+
if self.index_header(index) == "filename":
592+
if role == QtCore.Qt.ItemDataRole.DisplayRole and self.edit_mode and (data == "" or data == "Browse..."):
593593
return "Browse..."
594-
return str(self.classlist[index.row()].path / data)
595-
594+
elif role in [QtCore.Qt.ItemDataRole.ToolTipRole, QtCore.Qt.ItemDataRole.UserRole]:
595+
display = super().data(index, QtCore.Qt.ItemDataRole.DisplayRole)
596+
if display != "" and display != "Browse...":
597+
return self.classlist[index.row()].path.as_posix()
596598
return data
597599

598600
def setData(self, index, value, role=QtCore.Qt.ItemDataRole.DisplayRole):

tests/widgets/project/test_models.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,21 @@ def test_file_model_filename_data():
420420
model = CustomFileModel(init_list, parent)
421421

422422
filename_col = model.headers.index("filename") + model.col_offset
423-
423+
working_path = Path(".").resolve().as_posix()
424424
assert model.data(model.index(0, filename_col)) == "myfile.m"
425425
assert model.data(model.index(1, filename_col)) == ""
426+
assert model.data(model.index(0, filename_col), QtCore.Qt.ItemDataRole.UserRole) == working_path
427+
assert model.data(model.index(1, filename_col), QtCore.Qt.ItemDataRole.UserRole) is None
428+
assert model.data(model.index(0, filename_col), QtCore.Qt.ItemDataRole.ToolTipRole) == working_path
429+
assert model.data(model.index(1, filename_col), QtCore.Qt.ItemDataRole.ToolTipRole) is None
426430

427431
model.edit_mode = True
428-
429-
assert Path(model.data(model.index(0, filename_col))) == (Path(".") / "myfile.m").resolve()
432+
assert model.data(model.index(0, filename_col)) == "myfile.m"
430433
assert model.data(model.index(1, filename_col)) == "Browse..."
434+
assert model.data(model.index(0, filename_col), QtCore.Qt.ItemDataRole.UserRole) == working_path
435+
assert model.data(model.index(1, filename_col), QtCore.Qt.ItemDataRole.UserRole) is None
436+
assert model.data(model.index(0, filename_col), QtCore.Qt.ItemDataRole.ToolTipRole) == working_path
437+
assert model.data(model.index(1, filename_col), QtCore.Qt.ItemDataRole.ToolTipRole) is None
431438

432439

433440
@pytest.mark.parametrize(

tests/widgets/test_inputs.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
except ImportError:
66
from strenum import StrEnum
77

8+
from pathlib import Path
9+
810
import pytest
911
from pydantic.fields import FieldInfo
1012
from PyQt6 import QtWidgets
1113

1214
from rascal2.widgets import AdaptiveDoubleSpinBox, MultiSelectComboBox, MultiSelectList, get_validated_input
15+
from rascal2.widgets.inputs import PathWidget
1316

1417

1518
class MyEnum(StrEnum):
@@ -26,6 +29,7 @@ class MyEnum(StrEnum):
2629
(FieldInfo(annotation=int), QtWidgets.QSpinBox, 15),
2730
(FieldInfo(annotation=MyEnum), QtWidgets.QComboBox, "value 2"),
2831
(FieldInfo(annotation=str), QtWidgets.QLineEdit, "Test string"),
32+
(FieldInfo(annotation=Path), PathWidget, str(Path(".").resolve())),
2933
],
3034
)
3135
def test_editor_type(field_info, expected_type, example_data):
@@ -71,3 +75,17 @@ def test_multi_select_list_update(selected):
7175
buttons = msl.findChildren(QtWidgets.QToolButton)
7276
buttons[1].click()
7377
assert msl.list.count() == 0
78+
79+
80+
def test_path_widget():
81+
widget = PathWidget(None)
82+
assert widget.path == ""
83+
assert widget.text() == ""
84+
85+
widget.setText("Browse...")
86+
assert widget.text() == "Browse..."
87+
88+
path = Path(".") / "file.m"
89+
widget.setText(path)
90+
assert widget.path == path.parent.as_posix()
91+
assert widget.text() == path.name

0 commit comments

Comments
 (0)