Skip to content

Commit 47a56c2

Browse files
committed
Allow opening statepoint files when one is already open
1 parent 86050ce commit 47a56c2

2 files changed

Lines changed: 151 additions & 7 deletions

File tree

openmc_plotter/main_window.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -582,15 +582,18 @@ def openView(self):
582582
self.loadViewFile(filename)
583583

584584
def openStatePoint(self):
585-
# check for an alread-open statepoint
585+
# confirm replacement when a statepoint is already open
586586
if self.model.statepoint:
587-
msg_box = QMessageBox()
588-
msg_box.setText("Please close the current statepoint file before "
589-
"opening a new one.")
587+
msg_box = QMessageBox(self)
588+
msg_box.setText("A statepoint file is currently open. Continue to "
589+
"close it and open a new one?")
590590
msg_box.setIcon(QMessageBox.Information)
591-
msg_box.setStandardButtons(QMessageBox.Ok)
592-
msg_box.exec()
593-
return
591+
msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel)
592+
msg_box.setDefaultButton(QMessageBox.Cancel)
593+
msg_box.button(QMessageBox.Yes).setText("Continue")
594+
if msg_box.exec() != QMessageBox.Yes:
595+
return
596+
self.closeStatePoint()
594597
filename, ext = QFileDialog.getOpenFileName(self, "Open StatePoint",
595598
".", "*.h5")
596599
if filename:
@@ -635,6 +638,7 @@ def importProperties(self):
635638
def closeStatePoint(self):
636639
# remove the statepoint object and update the data menu
637640
filename = self.model.statepoint.filename
641+
self.model.statepoint.close()
638642
self.model.statepoint = None
639643
self.model.currentView.selectedTally = None
640644
self.model.activeView.selectedTally = None
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
from types import SimpleNamespace
2+
3+
from openmc_plotter import main_window
4+
5+
6+
class FakeButton:
7+
def __init__(self):
8+
self.text = None
9+
10+
def setText(self, text):
11+
self.text = text
12+
13+
14+
class FakeMessageBox:
15+
Yes = 1
16+
Cancel = 2
17+
Ok = 4
18+
Information = 8
19+
Warning = 16
20+
next_result = Cancel
21+
instances = []
22+
23+
def __init__(self, *args, **kwargs):
24+
self.text = None
25+
self.icon = None
26+
self.standard_buttons = None
27+
self.default_button = None
28+
self.buttons = {}
29+
type(self).instances.append(self)
30+
31+
def setText(self, text):
32+
self.text = text
33+
34+
def setIcon(self, icon):
35+
self.icon = icon
36+
37+
def setStandardButtons(self, buttons):
38+
self.standard_buttons = buttons
39+
40+
def setDefaultButton(self, button):
41+
self.default_button = button
42+
43+
def button(self, button):
44+
return self.buttons.setdefault(button, FakeButton())
45+
46+
def exec(self):
47+
return type(self).next_result
48+
49+
50+
def make_window(events):
51+
status_bar = SimpleNamespace(
52+
showMessage=lambda message, timeout=None: events.append(
53+
("status", message, timeout)
54+
)
55+
)
56+
statepoint = SimpleNamespace(
57+
filename="current.h5",
58+
close=lambda: events.append("close-current-statepoint"),
59+
)
60+
model = SimpleNamespace(
61+
statepoint=statepoint,
62+
currentView=SimpleNamespace(selectedTally=17),
63+
activeView=SimpleNamespace(selectedTally=17),
64+
)
65+
66+
def open_statepoint(filename):
67+
events.append(("open-statepoint", filename))
68+
model.statepoint = SimpleNamespace(
69+
filename=filename,
70+
close=lambda: events.append(("close-statepoint", filename)),
71+
)
72+
73+
model.openStatePoint = open_statepoint
74+
75+
window = SimpleNamespace(
76+
model=model,
77+
statusBar=lambda: status_bar,
78+
updateDataMenu=lambda: events.append("update-data-menu"),
79+
tallyPanel=SimpleNamespace(
80+
selectTally=lambda: events.append("select-tally"),
81+
update=lambda: events.append("update-tally-panel"),
82+
),
83+
plotIm=SimpleNamespace(updatePixmap=lambda: events.append("update-pixmap")),
84+
)
85+
window.closeStatePoint = lambda: main_window.MainWindow.closeStatePoint(window)
86+
return window
87+
88+
89+
def test_open_statepoint_cancel_keeps_current_file(monkeypatch):
90+
events = []
91+
FakeMessageBox.instances = []
92+
FakeMessageBox.next_result = FakeMessageBox.Cancel
93+
window = make_window(events)
94+
95+
def fake_get_open_file_name(*args, **kwargs):
96+
events.append("show-open-dialog")
97+
return ("replacement.h5", "*.h5")
98+
99+
monkeypatch.setattr(main_window, "QMessageBox", FakeMessageBox)
100+
monkeypatch.setattr(
101+
main_window.QFileDialog, "getOpenFileName", fake_get_open_file_name
102+
)
103+
104+
main_window.MainWindow.openStatePoint(window)
105+
106+
assert events == []
107+
assert window.model.statepoint.filename == "current.h5"
108+
assert len(FakeMessageBox.instances) == 1
109+
assert FakeMessageBox.instances[0].text == (
110+
"A statepoint file is currently open. Continue to close it and open "
111+
"a new one?"
112+
)
113+
assert FakeMessageBox.instances[0].button(FakeMessageBox.Yes).text == "Continue"
114+
115+
116+
def test_open_statepoint_continue_closes_current_file_before_reopening(
117+
monkeypatch,
118+
):
119+
events = []
120+
FakeMessageBox.instances = []
121+
FakeMessageBox.next_result = FakeMessageBox.Yes
122+
window = make_window(events)
123+
124+
def fake_get_open_file_name(*args, **kwargs):
125+
events.append("show-open-dialog")
126+
return ("replacement.h5", "*.h5")
127+
128+
monkeypatch.setattr(main_window, "QMessageBox", FakeMessageBox)
129+
monkeypatch.setattr(
130+
main_window.QFileDialog, "getOpenFileName", fake_get_open_file_name
131+
)
132+
133+
main_window.MainWindow.openStatePoint(window)
134+
135+
assert events.index("close-current-statepoint") < events.index("show-open-dialog")
136+
assert ("open-statepoint", "replacement.h5") in events
137+
assert ("status", "Opened statepoint file: replacement.h5", 5000) in events
138+
assert window.model.currentView.selectedTally is None
139+
assert window.model.activeView.selectedTally is None
140+
assert window.model.statepoint.filename == "replacement.h5"

0 commit comments

Comments
 (0)