kopia lustrzana https://github.com/corrscope/corrscope
[gui] When starting app, load config in GUI, not CLI (#149)
If loading invalid config via command line, show error via GUI dialog instead of CLI stacktrace/etc.pull/357/head
rodzic
80ec450dc9
commit
e058a6caa0
|
@ -115,9 +115,8 @@ def main(
|
|||
|
||||
show_gui = not any([write, play, render])
|
||||
|
||||
# Create cfg: Config object.
|
||||
cfg: Optional[Config] = None
|
||||
cfg_path: Optional[Path] = None
|
||||
# Gather data for cfg: Config object.
|
||||
cfg_or_path: Union[Config, Path, None] = None
|
||||
cfg_dir: Optional[str] = None
|
||||
|
||||
wav_list: List[Path] = []
|
||||
|
@ -144,8 +143,7 @@ def main(
|
|||
if len(files) > 1:
|
||||
raise click.ClickException(
|
||||
f'Cannot supply multiple arguments when providing config {path}')
|
||||
cfg = yaml.load(path)
|
||||
cfg_path = path
|
||||
cfg_or_path = path
|
||||
cfg_dir = str(path.parent)
|
||||
break
|
||||
|
||||
|
@ -159,11 +157,11 @@ def main(
|
|||
f'Supplied nonexistent file or wildcard: {path}')
|
||||
wav_list += matches
|
||||
|
||||
if not cfg:
|
||||
if not cfg_or_path:
|
||||
# cfg and cfg_dir are always initialized together.
|
||||
channels = [ChannelConfig(str(wav_path)) for wav_path in wav_list]
|
||||
|
||||
cfg = default_config(
|
||||
cfg_or_path = default_config(
|
||||
master_audio=audio,
|
||||
# fps=default,
|
||||
channels=channels,
|
||||
|
@ -172,10 +170,11 @@ def main(
|
|||
)
|
||||
cfg_dir = '.'
|
||||
|
||||
assert cfg_or_path is not None
|
||||
if show_gui:
|
||||
def command():
|
||||
from corrscope import gui
|
||||
return gui.gui_main(cfg, cfg_path)
|
||||
return gui.gui_main(cfg_or_path)
|
||||
|
||||
if profile:
|
||||
import cProfile
|
||||
|
@ -189,6 +188,16 @@ def main(
|
|||
else:
|
||||
if not files:
|
||||
raise click.UsageError('Must specify files or folders to play')
|
||||
|
||||
if isinstance(cfg_or_path, Config):
|
||||
cfg = cfg_or_path
|
||||
cfg_path = None
|
||||
elif isinstance(cfg_or_path, Path):
|
||||
cfg = yaml.load(cfg_or_path)
|
||||
cfg_path = cfg_or_path
|
||||
else:
|
||||
assert False, cfg_or_path
|
||||
|
||||
if write:
|
||||
write_path = get_path(audio, YAML_NAME)
|
||||
yaml.dump(cfg, write_path)
|
||||
|
|
|
@ -48,8 +48,7 @@ def res(file: str) -> str:
|
|||
return str(APP_DIR / file)
|
||||
|
||||
|
||||
def gui_main(cfg: Config, cfg_path: Optional[Path]):
|
||||
# TODO read config within MainWindow, and show popup if loading fails.
|
||||
def gui_main(cfg_or_path: Union[Config, Path]):
|
||||
# qw.QApplication.setStyle('fusion')
|
||||
QApp = qw.QApplication
|
||||
QApp.setAttribute(qc.Qt.AA_EnableHighDpiScaling)
|
||||
|
@ -63,7 +62,7 @@ def gui_main(cfg: Config, cfg_path: Optional[Path]):
|
|||
QApp.setFont(font)
|
||||
|
||||
app = qw.QApplication(sys.argv)
|
||||
window = MainWindow(cfg, cfg_path)
|
||||
window = MainWindow(cfg_or_path)
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
|
@ -72,14 +71,15 @@ class MainWindow(qw.QMainWindow):
|
|||
Main window.
|
||||
|
||||
Control flow:
|
||||
__init__
|
||||
load_cfg
|
||||
__init__: either
|
||||
- load_cfg
|
||||
- load_cfg_from_path
|
||||
|
||||
# Opening a document
|
||||
load_cfg
|
||||
Opening a document:
|
||||
- load_cfg_from_path
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, cfg_path: Optional[Path]):
|
||||
def __init__(self, cfg_or_path: Union[Config, Path]):
|
||||
super().__init__()
|
||||
|
||||
# Load UI.
|
||||
|
@ -109,7 +109,14 @@ class MainWindow(qw.QMainWindow):
|
|||
self.corr_thread: Optional[CorrThread] = None
|
||||
|
||||
# Bind config to UI.
|
||||
self.load_cfg(cfg, cfg_path)
|
||||
if isinstance(cfg_or_path, Config):
|
||||
self.load_cfg(cfg_or_path, None)
|
||||
elif isinstance(cfg_or_path, Path):
|
||||
self.load_cfg_from_path(cfg_or_path)
|
||||
else:
|
||||
raise TypeError(
|
||||
f"argument cfg={cfg_or_path} has invalid type {obj_name(cfg_or_path)}"
|
||||
)
|
||||
|
||||
self.show()
|
||||
|
||||
|
@ -133,37 +140,6 @@ class MainWindow(qw.QMainWindow):
|
|||
channel_view: "ChannelTableView"
|
||||
channelsGroup: qw.QGroupBox
|
||||
|
||||
def closeEvent(self, event: QCloseEvent) -> None:
|
||||
"""Called on closing window."""
|
||||
if self.prompt_save():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def on_action_new(self):
|
||||
if not self.prompt_save():
|
||||
return
|
||||
cfg = default_config()
|
||||
self.load_cfg(cfg, None)
|
||||
|
||||
def on_action_open(self):
|
||||
if not self.prompt_save():
|
||||
return
|
||||
name, file_type = qw.QFileDialog.getOpenFileName(
|
||||
self, "Open config", self.cfg_dir, "YAML files (*.yaml)"
|
||||
)
|
||||
if name != "":
|
||||
cfg_path = Path(name)
|
||||
try:
|
||||
# Raises YAML structural exceptions
|
||||
cfg = yaml.load(cfg_path)
|
||||
# Raises color getter exceptions
|
||||
# ISSUE: catching an exception will leave UI in undefined state?
|
||||
self.load_cfg(cfg, cfg_path)
|
||||
except Exception as e:
|
||||
qw.QMessageBox.critical(self, "Error loading file", str(e))
|
||||
return
|
||||
|
||||
def prompt_save(self) -> bool:
|
||||
"""
|
||||
Called when user is closing document
|
||||
|
@ -188,6 +164,45 @@ class MainWindow(qw.QMainWindow):
|
|||
else:
|
||||
return self.on_action_save()
|
||||
|
||||
def closeEvent(self, event: QCloseEvent) -> None:
|
||||
"""Called on closing window."""
|
||||
if self.prompt_save():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def on_action_new(self):
|
||||
if not self.prompt_save():
|
||||
return
|
||||
cfg = default_config()
|
||||
self.load_cfg(cfg, None)
|
||||
|
||||
def on_action_open(self):
|
||||
if not self.prompt_save():
|
||||
return
|
||||
name, file_type = qw.QFileDialog.getOpenFileName(
|
||||
self, "Open config", self.cfg_dir, "YAML files (*.yaml)"
|
||||
)
|
||||
if name != "":
|
||||
cfg_path = Path(name)
|
||||
self.load_cfg_from_path(cfg_path)
|
||||
|
||||
def load_cfg_from_path(self, cfg_path: Path):
|
||||
# Bind GUI to dummy config, in case loading cfg_path raises Exception.
|
||||
if self.model is None:
|
||||
self.load_cfg(default_config(), None)
|
||||
|
||||
try:
|
||||
# Raises YAML structural exceptions
|
||||
cfg = yaml.load(cfg_path)
|
||||
|
||||
# Raises color getter exceptions
|
||||
self.load_cfg(cfg, cfg_path)
|
||||
|
||||
except Exception as e:
|
||||
qw.QMessageBox.critical(self, "Error loading file", str(e))
|
||||
return
|
||||
|
||||
def load_cfg(self, cfg: Config, cfg_path: Optional[Path]):
|
||||
self._cfg_path = cfg_path
|
||||
self._any_unsaved = False
|
||||
|
|
Ładowanie…
Reference in New Issue