gui: save explorer state

This commit is contained in:
Sebastien Bourdeauducq 2015-08-05 13:35:28 +08:00
parent c8db83b11f
commit cddb5b9ae4
3 changed files with 81 additions and 33 deletions

View File

@ -81,6 +81,7 @@ def main():
win.setStatusBar(status_bar) win.setStatusBar(status_bar)
d_explorer = ExplorerDock(win, status_bar, schedule_ctl) d_explorer = ExplorerDock(win, status_bar, schedule_ctl)
smgr.register(d_explorer)
loop.run_until_complete(d_explorer.sub_connect( loop.run_until_complete(d_explorer.sub_connect(
args.server, args.port_notify)) args.server, args.port_notify))
atexit.register(lambda: loop.run_until_complete(d_explorer.sub_close())) atexit.register(lambda: loop.run_until_complete(d_explorer.sub_close()))

View File

@ -28,21 +28,27 @@ class _FreeValueEntry(QtGui.QLineEdit):
def __init__(self, procdesc): def __init__(self, procdesc):
QtGui.QLineEdit.__init__(self) QtGui.QLineEdit.__init__(self)
if "default" in procdesc: if "default" in procdesc:
self.insert(pyon.encode(procdesc["default"])) self.set_argument_value(procdesc["default"])
def get_argument_value(self): def get_argument_value(self):
return pyon.decode(self.text()) return pyon.decode(self.text())
def set_argument_value(self, value):
self.setText(pyon.encode(value))
class _BooleanEntry(QtGui.QCheckBox): class _BooleanEntry(QtGui.QCheckBox):
def __init__(self, procdesc): def __init__(self, procdesc):
QtGui.QCheckBox.__init__(self) QtGui.QCheckBox.__init__(self)
if "default" in procdesc: if "default" in procdesc:
self.setChecked(procdesc["default"]) self.set_argument_value(procdesc["default"])
def get_argument_value(self): def get_argument_value(self):
return self.isChecked() return self.isChecked()
def set_argument_value(self, value):
self.setChecked(value)
class _EnumerationEntry(QtGui.QComboBox): class _EnumerationEntry(QtGui.QComboBox):
def __init__(self, procdesc): def __init__(self, procdesc):
@ -50,16 +56,15 @@ class _EnumerationEntry(QtGui.QComboBox):
self.choices = procdesc["choices"] self.choices = procdesc["choices"]
self.addItems(self.choices) self.addItems(self.choices)
if "default" in procdesc: if "default" in procdesc:
try: self.set_argument_value(procdesc["default"])
idx = self.choices.index(procdesc["default"])
except:
pass
else:
self.setCurrentIndex(idx)
def get_argument_value(self): def get_argument_value(self):
return self.choices[self.currentIndex()] return self.choices[self.currentIndex()]
def set_argument_value(self, value):
idx = self.choices.index(value)
self.setCurrentIndex(idx)
class _NumberEntry(QtGui.QDoubleSpinBox): class _NumberEntry(QtGui.QDoubleSpinBox):
def __init__(self, procdesc): def __init__(self, procdesc):
@ -73,21 +78,27 @@ class _NumberEntry(QtGui.QDoubleSpinBox):
if procdesc["unit"]: if procdesc["unit"]:
self.setSuffix(" " + procdesc["unit"]) self.setSuffix(" " + procdesc["unit"])
if "default" in procdesc: if "default" in procdesc:
force_spinbox_value(self, procdesc["default"]) self.set_argument_value(procdesc["default"])
def get_argument_value(self): def get_argument_value(self):
return self.value() return self.value()
def set_argument_value(self, value):
force_spinbox_value(self, value)
class _StringEntry(QtGui.QLineEdit): class _StringEntry(QtGui.QLineEdit):
def __init__(self, procdesc): def __init__(self, procdesc):
QtGui.QLineEdit.__init__(self) QtGui.QLineEdit.__init__(self)
if "default" in procdesc: if "default" in procdesc:
self.insert(procdesc["default"]) self.set_argument_value(procdesc["default"])
def get_argument_value(self): def get_argument_value(self):
return self.text() return self.text()
def set_argument_value(self, value):
self.setText(value)
_procty_to_entry = { _procty_to_entry = {
"FreeValue": _FreeValueEntry, "FreeValue": _FreeValueEntry,
@ -114,21 +125,31 @@ class _ArgumentSetter(LayoutWidget):
self.addWidget(entry, n, 1) self.addWidget(entry, n, 1)
self._args_to_entries[name] = entry self._args_to_entries[name] = entry
def get_argument_values(self): def get_argument_values(self, show_error_message):
r = dict() r = dict()
for arg, entry in self._args_to_entries.items(): for arg, entry in self._args_to_entries.items():
try: try:
r[arg] = entry.get_argument_value() r[arg] = entry.get_argument_value()
except: except:
msgbox = QtGui.QMessageBox(self.dialog_parent) if show_error_message:
msgbox.setWindowTitle("Error") msgbox = QtGui.QMessageBox(self.dialog_parent)
msgbox.setText("Failed to obtain value for argument '{}'.\n{}" msgbox.setWindowTitle("Error")
.format(arg, traceback.format_exc())) msgbox.setText("Failed to obtain value for argument '{}'.\n{}"
msgbox.setStandardButtons(QtGui.QMessageBox.Ok) .format(arg, traceback.format_exc()))
msgbox.show() msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
msgbox.show()
return None return None
return r return r
def set_argument_values(self, arguments, ignore_errors):
for arg, value in arguments.items():
try:
entry = self._args_to_entries[arg]
entry.set_argument_value(value)
except:
if not ignore_errors:
raise
class ExplorerDock(dockarea.Dock): class ExplorerDock(dockarea.Dock):
def __init__(self, dialog_parent, status_bar, schedule_ctl): def __init__(self, dialog_parent, status_bar, schedule_ctl):
@ -163,7 +184,7 @@ class ExplorerDock(dockarea.Dock):
grid.addWidget(self.priority, 1, 3) grid.addWidget(self.priority, 1, 3)
self.pipeline = QtGui.QLineEdit() self.pipeline = QtGui.QLineEdit()
self.pipeline.insert("main") self.pipeline.setText("main")
grid.addWidget(QtGui.QLabel("Pipeline:"), 2, 0) grid.addWidget(QtGui.QLabel("Pipeline:"), 2, 0)
grid.addWidget(self.pipeline, 2, 1) grid.addWidget(self.pipeline, 2, 1)
@ -177,8 +198,15 @@ class ExplorerDock(dockarea.Dock):
self.argsetter = _ArgumentSetter(self.dialog_parent, []) self.argsetter = _ArgumentSetter(self.dialog_parent, [])
self.splitter.addWidget(self.argsetter) self.splitter.addWidget(self.argsetter)
self.splitter.setSizes([grid.minimumSizeHint().width(), 1000]) self.splitter.setSizes([grid.minimumSizeHint().width(), 1000])
self.state = dict()
def update_argsetter(self, selected, deselected): def update_argsetter(self, selected, deselected):
deselected = deselected.indexes()
if deselected:
row = deselected[0].row()
key = self.explist_model.row_to_key[row]
self.state[key] = self.argsetter.get_argument_values(False)
selected = selected.indexes() selected = selected.indexes()
if selected: if selected:
row = selected[0].row() row = selected[0].row()
@ -188,9 +216,24 @@ class ExplorerDock(dockarea.Dock):
sizes = self.splitter.sizes() sizes = self.splitter.sizes()
self.argsetter.deleteLater() self.argsetter.deleteLater()
self.argsetter = _ArgumentSetter(self.dialog_parent, arguments) self.argsetter = _ArgumentSetter(self.dialog_parent, arguments)
if key in self.state:
arguments = self.state[key]
if arguments is not None:
self.argsetter.set_argument_values(arguments, True)
self.splitter.insertWidget(1, self.argsetter) self.splitter.insertWidget(1, self.argsetter)
self.splitter.setSizes(sizes) self.splitter.setSizes(sizes)
def save_state(self):
idx = self.el.selectedIndexes()
if idx:
row = idx[0].row()
key = self.explist_model.row_to_key[row]
self.state[key] = self.argsetter.get_argument_values(False)
return self.state
def restore_state(self, state):
self.state = state
def enable_duedate(self): def enable_duedate(self):
self.datetime_en.setChecked(True) self.datetime_en.setChecked(True)
@ -231,7 +274,7 @@ class ExplorerDock(dockarea.Dock):
due_date = self.datetime.dateTime().toMSecsSinceEpoch()/1000 due_date = self.datetime.dateTime().toMSecsSinceEpoch()/1000
else: else:
due_date = None due_date = None
arguments = self.argsetter.get_argument_values() arguments = self.argsetter.get_argument_values(True)
if arguments is None: if arguments is None:
return return
asyncio.async(self.submit(self.pipeline.text(), asyncio.async(self.submit(self.pipeline.text(),

View File

@ -96,20 +96,7 @@ class ScanController(LayoutWidget):
b.toggled.connect(self.select_page) b.toggled.connect(self.select_page)
if "default" in procdesc: if "default" in procdesc:
d = procdesc["default"] self.set_argument_value(procdesc["default"])
if d["ty"] == "NoScan":
self.noscan.setChecked(True)
force_spinbox_value(self.v_noscan, d["value"])
elif d["ty"] == "LinearScan":
self.linear.setChecked(True)
self.v_linear.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "RandomScan":
self.random.setChecked(True)
self.v_random.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "ExplicitScan":
self.explicit.setChecked(True)
self.v_explicit.insert(" ".join(
[str(x) for x in d["sequence"]]))
else: else:
self.noscan.setChecked(True) self.noscan.setChecked(True)
@ -137,3 +124,20 @@ class ScanController(LayoutWidget):
elif self.explicit.isChecked(): elif self.explicit.isChecked():
sequence = [float(x) for x in self.v_explicit.text().split()] sequence = [float(x) for x in self.v_explicit.text().split()]
return {"ty": "ExplicitScan", "sequence": sequence} return {"ty": "ExplicitScan", "sequence": sequence}
def set_argument_value(self, d):
if d["ty"] == "NoScan":
self.noscan.setChecked(True)
force_spinbox_value(self.v_noscan, d["value"])
elif d["ty"] == "LinearScan":
self.linear.setChecked(True)
self.v_linear.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "RandomScan":
self.random.setChecked(True)
self.v_random.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "ExplicitScan":
self.explicit.setChecked(True)
self.v_explicit.insert(" ".join(
[str(x) for x in d["sequence"]]))
else:
raise ValueError("Unknown scan type '{}'".format(d["ty"]))