From fc617b0f936c1707a5e0f216de4cd884196bd61b Mon Sep 17 00:00:00 2001 From: Stefano Simonelli <16114781+s-simoncelli@users.noreply.github.com> Date: Sat, 17 Feb 2024 13:57:07 +0000 Subject: [PATCH] Reload the editor if the JSON file is changed externally --- pywr_editor/app.py | 2 -- pywr_editor/main_window.py | 35 ++++++++++++++++++++++++++++++- pywr_editor/model/model_config.py | 13 ++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/pywr_editor/app.py b/pywr_editor/app.py index d40d6b62..3d64d9a0 100644 --- a/pywr_editor/app.py +++ b/pywr_editor/app.py @@ -63,8 +63,6 @@ def app() -> None: QApplication.setHighDpiScaleFactorRoundingPolicy( Qt.HighDpiScaleFactorRoundingPolicy.PassThrough ) - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) - QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) # create new model command if create_new is not None: diff --git a/pywr_editor/main_window.py b/pywr_editor/main_window.py index 73b46269..cb7d3e3f 100644 --- a/pywr_editor/main_window.py +++ b/pywr_editor/main_window.py @@ -5,7 +5,7 @@ from typing import Literal import PySide6 -from PySide6.QtCore import Signal, Slot +from PySide6.QtCore import QTimer, Signal, Slot from PySide6.QtGui import QAction, QKeySequence, Qt, QUndoStack from PySide6.QtWidgets import QFileDialog, QMainWindow, QMessageBox, QSplitter @@ -93,6 +93,12 @@ def __init__(self, model_file: str | None = None): return self.model_config.model_changed.connect(self.on_model_change) + # listen for file changes + self.timer = QTimer(self) + # noinspection PyUnresolvedReferences + self.timer.timeout.connect(self.listen_for_changes) + self.timer.start(3000) + self.editor_settings = Settings(model_file) # store recent files if model_file is not None: @@ -1092,3 +1098,30 @@ def reload_model_file(self) -> None: self.prompt_unsaved_changes = False MainWindow(self.model_file) self.close() + + @Slot() + def listen_for_changes(self) -> None: + """ + Check whether the file is changed externally and reload the model. + :return: None + """ + # do not refresh if the window has not focus + if not self.window().isActiveWindow(): + return + + # noinspection PyBroadException + try: + with open(self.model_file, "r") as file: + # only reload the editor if there are not changes made using the editor + if ( + file.read() != self.model_config.as_string + and not self.model_config.has_changes + ): + self.logger.debug( + "Reloading model because it was changed externally" + ) + self.timer.stop() + self.close() + MainWindow(self.model_file) + except Exception: + pass diff --git a/pywr_editor/model/model_config.py b/pywr_editor/model/model_config.py index ab11e616..fc8ea0d6 100644 --- a/pywr_editor/model/model_config.py +++ b/pywr_editor/model/model_config.py @@ -452,6 +452,19 @@ def reload_file_info(self) -> None: """ self.file = ModelFileInfo(self.json_file) + @property + def as_string(self) -> str | bool: + """ + Saves the model as JSON string. + :return: A string containing the model, or False if the model cannot be + converted to a string. + """ + # noinspection PyBroadException + try: + return json.dumps(self.json, indent=2) + except Exception: + return False + def save(self) -> bool | str: """ Saves the JSON file.