From 192154286334b1f8991870138ec4337d109db562 Mon Sep 17 00:00:00 2001 From: mkolar Date: Thu, 20 May 2021 16:19:18 +0000 Subject: [PATCH 01/26] Create draft PR for #910 From bbb2e1562a6f59dd45aa7efe89feeaf853473cc0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:23:24 +0200 Subject: [PATCH 02/26] entity knows if should openpype requires restart --- openpype/settings/entities/base_entity.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index b2d0f8224d..f8ab871310 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -110,6 +110,8 @@ class BaseItemEntity(BaseEntity): self.file_item = None # Reference to `RootEntity` self.root_item = None + # Change of value requires restart of OpenPype + self._require_restart = False # Entity is in hierarchy of dynamically created entity self.is_in_dynamic_item = False @@ -170,6 +172,10 @@ class BaseItemEntity(BaseEntity): roles = [roles] self.roles = roles + @property + def require_restart(self): + return self._require_restart + @property def has_studio_override(self): """Says if entity or it's children has studio overrides.""" @@ -787,6 +793,12 @@ class ItemEntity(BaseItemEntity): # Root item reference self.root_item = self.parent.root_item + # Item require restart on value change + require_restart = self.schema_data.get("require_restart") + if require_restart is None: + require_restart = self.parent.require_restart + self._require_restart = require_restart + # File item reference if self.parent.is_file: self.file_item = self.parent From a18aa04bf68ae26ad81b2117cc8da8876c71bf91 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:23:37 +0200 Subject: [PATCH 03/26] added schema validation for specific values --- openpype/settings/entities/base_entity.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index f8ab871310..44431214a3 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -266,6 +266,14 @@ class BaseItemEntity(BaseEntity): self, "Dynamic entity has set `is_group` to true." ) + if ( + self._require_restart + and (self.is_dynamic_item or self.is_in_dynamic_item) + ): + raise EntitySchemaError( + self, "Dynamic entity can't require restart." + ) + @abstractmethod def set_override_state(self, state): """Set override state and trigger it on children. From 18b10d813a2364be67f13fb8d2816b968fa189fa Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:24:16 +0200 Subject: [PATCH 04/26] root entity can trigger callbacks if restart require entity changed it's state --- openpype/settings/entities/root_entities.py | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openpype/settings/entities/root_entities.py b/openpype/settings/entities/root_entities.py index b89473d9fb..b8abbe4f19 100644 --- a/openpype/settings/entities/root_entities.py +++ b/openpype/settings/entities/root_entities.py @@ -55,6 +55,8 @@ class RootEntity(BaseItemEntity): def __init__(self, schema_data, reset): super(RootEntity, self).__init__(schema_data) + self._require_restart_callbacks = [] + self._item_ids_require_restart = set() self._item_initalization() if reset: self.reset() @@ -64,6 +66,28 @@ class RootEntity(BaseItemEntity): """Current OverrideState.""" return self._override_state + @property + def require_restart(self): + return bool(self._item_ids_require_restart) + + def add_require_restart_change_callback(self, callback): + self._require_restart_callbacks.append(callback) + + def _on_require_restart_change(self): + for callback in self._require_restart_callbacks: + callback() + + def add_item_require_restart(self, item): + was_empty = len(self._item_ids_require_restart) == 0 + self._item_ids_require_restart.add(item.id) + if was_empty: + self._on_require_restart_change() + + def remove_item_require_restart(self, item): + self._item_ids_require_restart.remove(item.id) + if not self._item_ids_require_restart: + self._on_require_restart_change() + @abstractmethod def reset(self): """Reset values and entities to initial state. From e2ae21949593a022e468e2b52b15e1767671b835 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:24:38 +0200 Subject: [PATCH 05/26] endpoint entities can trigger changes on root item --- openpype/settings/entities/input_entities.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/settings/entities/input_entities.py b/openpype/settings/entities/input_entities.py index 409e6a66b4..0d675fd37d 100644 --- a/openpype/settings/entities/input_entities.py +++ b/openpype/settings/entities/input_entities.py @@ -68,6 +68,12 @@ class EndpointEntity(ItemEntity): def on_change(self): for callback in self.on_change_callbacks: callback() + + if self.require_restart: + if self.has_unsaved_changes: + self.root_item.add_item_require_restart(self) + else: + self.root_item.remove_item_require_restart(self) self.parent.on_child_change(self) def update_default_value(self, value): From 4f6b99fcd29b2bf7b1ab25cd3aa0923624601894 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:24:58 +0200 Subject: [PATCH 06/26] added require_restart on two entities in settings --- .../entities/schemas/system_schema/schema_general.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/settings/entities/schemas/system_schema/schema_general.json b/openpype/settings/entities/schemas/system_schema/schema_general.json index 568ccad5b9..fe5a8d8203 100644 --- a/openpype/settings/entities/schemas/system_schema/schema_general.json +++ b/openpype/settings/entities/schemas/system_schema/schema_general.json @@ -34,7 +34,8 @@ "key": "environment", "label": "Environment", "type": "raw-json", - "env_group_key": "global" + "env_group_key": "global", + "require_restart": true }, { "type": "splitter" @@ -44,7 +45,8 @@ "key": "openpype_path", "label": "Versions Repository", "multiplatform": true, - "multipath": true + "multipath": true, + "require_restart": true } ] } From 2e309f18ef4f74e79e7729165d7d81331f076287 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 26 May 2021 20:25:23 +0200 Subject: [PATCH 07/26] category can show a label that changes require install --- .../tools/settings/settings/categories.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index 4762aa4b6b..678aa050a9 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -181,9 +181,10 @@ class SettingsCategoryWidget(QtWidgets.QWidget): if self.user_role == "developer": self._add_developer_ui(footer_layout) - save_btn = QtWidgets.QPushButton("Save") - spacer_widget = QtWidgets.QWidget() - footer_layout.addWidget(spacer_widget, 1) + save_btn = QtWidgets.QPushButton("Save", footer_widget) + require_restart_label = QtWidgets.QLabel(footer_widget) + footer_layout.addStretch(1) + footer_layout.addWidget(require_restart_label, 0) footer_layout.addWidget(save_btn, 0) configurations_layout = QtWidgets.QVBoxLayout(configurations_widget) @@ -201,6 +202,7 @@ class SettingsCategoryWidget(QtWidgets.QWidget): save_btn.clicked.connect(self._save) self.save_btn = save_btn + self.require_restart_label = require_restart_label self.scroll_widget = scroll_widget self.content_layout = content_layout self.content_widget = content_widget @@ -319,6 +321,15 @@ class SettingsCategoryWidget(QtWidgets.QWidget): def _on_reset_start(self): return + def _on_require_restart_change(self): + value = "" + if self.entity.require_restart: + value = ( + "Your changes require restart of" + " all running OpenPype processes to take affect." + ) + self.require_restart_label.setText(value) + def reset(self): self.set_state(CategoryState.Working) @@ -335,6 +346,9 @@ class SettingsCategoryWidget(QtWidgets.QWidget): dialog = None try: self._create_root_entity() + self.entity.add_require_restart_change_callback( + self._on_require_restart_change + ) self.add_children_gui() From faa32ad8dbc4a31a7330aa5f33c4ea813ccf48ff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:41:54 +0200 Subject: [PATCH 08/26] added atexit callback to tray widget --- openpype/tools/tray/pype_tray.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 534c99bd90..23421fdbf1 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -1,5 +1,6 @@ import os import sys +import atexit import platform from avalon import style @@ -116,6 +117,8 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon): super(SystemTrayIcon, self).__init__(icon, parent) + self._exited = False + # Store parent - QtWidgets.QMainWindow() self.parent = parent @@ -134,6 +137,8 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon): # Add menu to Context of SystemTrayIcon self.setContextMenu(self.menu) + atexit.register(self.exit) + def on_systray_activated(self, reason): # show contextMenu if left click if reason == QtWidgets.QSystemTrayIcon.Trigger: @@ -145,6 +150,10 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon): - Icon won't stay in tray after exit. """ + if self._exited: + return + self._exited = True + self.hide() self.tray_man.on_exit() QtCore.QCoreApplication.exit() From abaf3237b930de5fcef8567386fb56edcffc6644 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:42:18 +0200 Subject: [PATCH 09/26] TrayManger has exit method --- openpype/tools/tray/pype_tray.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 23421fdbf1..3d7c49b38c 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -93,6 +93,9 @@ class TrayManager: self.tray_widget.menu.addAction(version_action) self.tray_widget.menu.addSeparator() + def exit(self): + self.tray_widget.exit() + def on_exit(self): self.modules_manager.on_exit() From 4fb40ac886eda1a0cd85626fcc169b58d59e1409 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:44:43 +0200 Subject: [PATCH 10/26] implemented restart method for tray tool --- openpype/tools/tray/pype_tray.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 3d7c49b38c..fa16dbf855 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -1,11 +1,13 @@ import os import sys import atexit +import subprocess import platform from avalon import style from Qt import QtCore, QtGui, QtWidgets from openpype.api import Logger, resources +from openpype.lib import get_pype_execute_args from openpype.modules import TrayModulesManager, ITrayService from openpype.settings.lib import get_system_settings import openpype.version @@ -93,6 +95,31 @@ class TrayManager: self.tray_widget.menu.addAction(version_action) self.tray_widget.menu.addSeparator() + def restart(self): + """Restart Tray tool. + + First creates new process with same argument and close current tray. + """ + args = get_pype_execute_args() + # Create a copy of sys.argv + additional_args = list(sys.argv) + # Check last argument from `get_pype_execute_args` + # - when running from code it is the same as first from sys.argv + if args[-1] == additional_args[0]: + additional_args.pop(0) + args.extend(additional_args) + + kwargs = {} + if platform.system().lower() == "windows": + flags = ( + subprocess.CREATE_NEW_PROCESS_GROUP + | subprocess.DETACHED_PROCESS + ) + kwargs["creationflags"] = flags + + subprocess.Popen(args, **kwargs) + self.exit() + def exit(self): self.tray_widget.exit() From 80132289c4434740a86e2bb2bf149377f98ea7db Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:45:12 +0200 Subject: [PATCH 11/26] added restart_tray method to TrayModulesManager so models can call it --- openpype/modules/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index b8d76aa028..50bd6411ce 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -680,6 +680,10 @@ class TrayModulesManager(ModulesManager): output.append(module) return output + def restart_tray(self): + if self.tray_manager: + self.tray_manager.restart() + def tray_init(self): report = {} time_start = time.time() From f1a2b79709d1c47cdc4cf051b11131eb6eb84aea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:45:57 +0200 Subject: [PATCH 12/26] save on categories can trigger restart_required_trigger signal if changes require restart --- openpype/tools/settings/settings/categories.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index 678aa050a9..39e831a446 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -72,6 +72,7 @@ class IgnoreInputChangesObj: class SettingsCategoryWidget(QtWidgets.QWidget): state_changed = QtCore.Signal() saved = QtCore.Signal(QtWidgets.QWidget) + restart_required_trigger = QtCore.Signal() def __init__(self, user_role, parent=None): super(SettingsCategoryWidget, self).__init__(parent) @@ -443,6 +444,15 @@ class SettingsCategoryWidget(QtWidgets.QWidget): return def _save(self): + # Don't trigger restart if defaults are modified + if ( + self.modify_defaults_checkbox + and self.modify_defaults_checkbox.isChecked() + ): + require_restart = False + else: + require_restart = self.entity.require_restart + self.set_state(CategoryState.Working) if self.items_are_valid(): @@ -452,6 +462,9 @@ class SettingsCategoryWidget(QtWidgets.QWidget): self.saved.emit(self) + if require_restart: + self.restart_required_trigger.emit() + def _on_refresh(self): self.reset() From d0bd67d675348bc0b4bb98a438c1807a31a4dcc2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:46:45 +0200 Subject: [PATCH 13/26] Settings window register slots for restart_required_trigger signal --- openpype/tools/settings/settings/window.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/tools/settings/settings/window.py b/openpype/tools/settings/settings/window.py index 9b368588c3..f369c2758c 100644 --- a/openpype/tools/settings/settings/window.py +++ b/openpype/tools/settings/settings/window.py @@ -60,6 +60,9 @@ class MainWidget(QtWidgets.QWidget): for tab_widget in tab_widgets: tab_widget.saved.connect(self._on_tab_save) tab_widget.state_changed.connect(self._on_state_change) + tab_widget.restart_required_trigger.connect( + self._on_restart_required + ) self.tab_widgets = tab_widgets @@ -132,3 +135,6 @@ class MainWidget(QtWidgets.QWidget): for tab_widget in self.tab_widgets: tab_widget.reset() + + def _on_restart_required(self): + pass From 734e503c1ff0c6b716a2299617fc17224ff3d47e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:47:05 +0200 Subject: [PATCH 14/26] created RestartDialog aasking if user want to restart current process --- openpype/tools/settings/settings/widgets.py | 44 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/openpype/tools/settings/settings/widgets.py b/openpype/tools/settings/settings/widgets.py index 249b4e305d..b20ce5ed66 100644 --- a/openpype/tools/settings/settings/widgets.py +++ b/openpype/tools/settings/settings/widgets.py @@ -275,8 +275,6 @@ class UnsavedChangesDialog(QtWidgets.QDialog): layout.addWidget(message_label) layout.addWidget(btns_widget) - self.state = None - def on_cancel_pressed(self): self.done(0) @@ -287,6 +285,48 @@ class UnsavedChangesDialog(QtWidgets.QDialog): self.done(2) +class RestartDialog(QtWidgets.QDialog): + message = ( + "Your changes require restart of process to take effect." + " Do you want to restart now?" + ) + + def __init__(self, parent=None): + super(RestartDialog, self).__init__(parent) + message_label = QtWidgets.QLabel(self.message) + + btns_widget = QtWidgets.QWidget(self) + btns_layout = QtWidgets.QHBoxLayout(btns_widget) + + btn_restart = QtWidgets.QPushButton("Restart") + btn_restart.clicked.connect(self.on_restart_pressed) + btn_cancel = QtWidgets.QPushButton("Cancel") + btn_cancel.clicked.connect(self.on_cancel_pressed) + + btns_layout.addStretch(1) + btns_layout.addWidget(btn_restart) + btns_layout.addWidget(btn_cancel) + + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(message_label) + layout.addWidget(btns_widget) + + self.btn_cancel = btn_cancel + self.btn_restart = btn_restart + + def showEvent(self, event): + super(RestartDialog, self).showEvent(event) + btns_width = max(self.btn_cancel.width(), self.btn_restart.width()) + self.btn_cancel.setFixedWidth(btns_width) + self.btn_restart.setFixedWidth(btns_width) + + def on_cancel_pressed(self): + self.done(0) + + def on_restart_pressed(self): + self.done(1) + + class SpacerWidget(QtWidgets.QWidget): def __init__(self, parent=None): super(SpacerWidget, self).__init__(parent) From 859ed6853ced5b89dd1f28e480311c45dabce02f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:47:56 +0200 Subject: [PATCH 15/26] Settings window has trigger_restart signal which meant to be triggered if saved changes require restart --- openpype/tools/settings/settings/window.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/tools/settings/settings/window.py b/openpype/tools/settings/settings/window.py index f369c2758c..fc28b61fec 100644 --- a/openpype/tools/settings/settings/window.py +++ b/openpype/tools/settings/settings/window.py @@ -14,6 +14,8 @@ from openpype.tools.settings import ( class MainWidget(QtWidgets.QWidget): + trigger_restart = QtCore.Signal() + widget_width = 1000 widget_height = 600 From 38afc53c388e7a786e617337bb7c411c8ee2c949 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:48:17 +0200 Subject: [PATCH 16/26] show restart dialog on restart require --- openpype/tools/settings/settings/window.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openpype/tools/settings/settings/window.py b/openpype/tools/settings/settings/window.py index fc28b61fec..0d54a53789 100644 --- a/openpype/tools/settings/settings/window.py +++ b/openpype/tools/settings/settings/window.py @@ -4,7 +4,7 @@ from .categories import ( SystemWidget, ProjectWidget ) -from .widgets import ShadowWidget +from .widgets import ShadowWidget, RestartDialog from . import style from openpype.tools.settings import ( @@ -139,4 +139,7 @@ class MainWidget(QtWidgets.QWidget): tab_widget.reset() def _on_restart_required(self): - pass + dialog = RestartDialog(self) + result = dialog.exec_() + if result == 1: + self.trigger_restart.emit() From 1be72669a9e66c7278c0c9a024fed650156300a3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 12:49:39 +0200 Subject: [PATCH 17/26] dont show dialog if nothing is listening to trigger_restart signal --- openpype/tools/settings/settings/window.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/tools/settings/settings/window.py b/openpype/tools/settings/settings/window.py index 0d54a53789..7a6536fd78 100644 --- a/openpype/tools/settings/settings/window.py +++ b/openpype/tools/settings/settings/window.py @@ -139,6 +139,12 @@ class MainWidget(QtWidgets.QWidget): tab_widget.reset() def _on_restart_required(self): + # Don't show dialog if there are not registered slots for + # `trigger_restart` signal. + # - For example when settings are runnin as standalone tool + if self.receivers(self.trigger_restart) < 1: + return + dialog = RestartDialog(self) result = dialog.exec_() if result == 1: From 4bdcc8fc0409447f603c340e168c2dcf55bf3327 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:01:44 +0200 Subject: [PATCH 18/26] restart label is centered in footer --- openpype/tools/settings/settings/categories.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index 39e831a446..9932ac3c2d 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -184,8 +184,8 @@ class SettingsCategoryWidget(QtWidgets.QWidget): save_btn = QtWidgets.QPushButton("Save", footer_widget) require_restart_label = QtWidgets.QLabel(footer_widget) - footer_layout.addStretch(1) - footer_layout.addWidget(require_restart_label, 0) + require_restart_label.setAlignment(QtCore.Qt.AlignCenter) + footer_layout.addWidget(require_restart_label, 1) footer_layout.addWidget(save_btn, 0) configurations_layout = QtWidgets.QVBoxLayout(configurations_widget) From 5c9d429c795a94f8aacdda5ba52744b3d34bf07f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:01:53 +0200 Subject: [PATCH 19/26] reset label text on save --- openpype/tools/settings/settings/categories.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index 9932ac3c2d..f5b15b7079 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -464,6 +464,7 @@ class SettingsCategoryWidget(QtWidgets.QWidget): if require_restart: self.restart_required_trigger.emit() + self.require_restart_label.setText("") def _on_refresh(self): self.reset() From 6bc925f54fc94ee881a5b6f41e9a19956469cb8f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:02:22 +0200 Subject: [PATCH 20/26] settings module action can trigger restart of tray --- openpype/modules/settings_action.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/modules/settings_action.py b/openpype/modules/settings_action.py index 5651868f68..f5bcb5342d 100644 --- a/openpype/modules/settings_action.py +++ b/openpype/modules/settings_action.py @@ -67,6 +67,10 @@ class SettingsAction(PypeModule, ITrayAction): return from openpype.tools.settings import MainWidget self.settings_window = MainWidget(self.user_role) + self.settings_window.trigger_restart.connect(self._on_trigger_restart) + + def _on_trigger_restart(self): + self.manager.restart_tray() def show_settings_window(self): """Show settings tool window. From 0a88d110b72f6e78dc7b1ab3ad8a35da01c03015 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:11:21 +0200 Subject: [PATCH 21/26] fixed inheritance of require_restart attribute --- openpype/settings/entities/base_entity.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index 44431214a3..a86464b433 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -803,7 +803,10 @@ class ItemEntity(BaseItemEntity): # Item require restart on value change require_restart = self.schema_data.get("require_restart") - if require_restart is None: + if ( + require_restart is None + and not (self.is_dynamic_item or self.is_in_dynamic_item) + ): require_restart = self.parent.require_restart self._require_restart = require_restart From bd40bae7aa1481903e313bfb7f661447e9202c97 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:11:59 +0200 Subject: [PATCH 22/26] added few more require_restart attributes in schemas --- .../system_schema/module_settings/schema_ftrack.json | 1 + .../entities/schemas/system_schema/schema_modules.json | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/openpype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json b/openpype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json index 50ec330a11..5f659522c3 100644 --- a/openpype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json +++ b/openpype/settings/entities/schemas/system_schema/module_settings/schema_ftrack.json @@ -3,6 +3,7 @@ "key": "ftrack", "label": "Ftrack", "collapsible": true, + "require_restart": true, "checkbox_key": "enabled", "children": [ { diff --git a/openpype/settings/entities/schemas/system_schema/schema_modules.json b/openpype/settings/entities/schemas/system_schema/schema_modules.json index b643293c87..16251b5f27 100644 --- a/openpype/settings/entities/schemas/system_schema/schema_modules.json +++ b/openpype/settings/entities/schemas/system_schema/schema_modules.json @@ -10,6 +10,7 @@ "key": "avalon", "label": "Avalon", "collapsible": true, + "require_restart": true, "children": [ { "type": "number", @@ -35,6 +36,7 @@ "key": "timers_manager", "label": "Timers Manager", "collapsible": true, + "require_restart": true, "checkbox_key": "enabled", "children": [ { @@ -66,6 +68,7 @@ "key": "clockify", "label": "Clockify", "collapsible": true, + "require_restart": true, "checkbox_key": "enabled", "children": [ { @@ -84,6 +87,7 @@ "key": "sync_server", "label": "Site Sync", "collapsible": true, + "require_restart": true, "checkbox_key": "enabled", "children": [ { @@ -114,6 +118,7 @@ "type": "dict", "key": "deadline", "label": "Deadline", + "require_restart": true, "collapsible": true, "checkbox_key": "enabled", "children": [ @@ -133,6 +138,7 @@ "type": "dict", "key": "muster", "label": "Muster", + "require_restart": true, "collapsible": true, "checkbox_key": "enabled", "children": [ From da1bd57354693583a618230bc02b3ab8377d26ce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:24:53 +0200 Subject: [PATCH 23/26] fix removing not set items yet --- openpype/settings/entities/root_entities.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/settings/entities/root_entities.py b/openpype/settings/entities/root_entities.py index b8abbe4f19..401d3980c9 100644 --- a/openpype/settings/entities/root_entities.py +++ b/openpype/settings/entities/root_entities.py @@ -84,6 +84,9 @@ class RootEntity(BaseItemEntity): self._on_require_restart_change() def remove_item_require_restart(self, item): + if item.id not in self._item_ids_require_restart: + return + self._item_ids_require_restart.remove(item.id) if not self._item_ids_require_restart: self._on_require_restart_change() From bce80e5fc8f70c9ce882bc020cf7cad2fb850205 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:25:26 +0200 Subject: [PATCH 24/26] require_restart says if entity requires restart --- openpype/settings/entities/base_entity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index a86464b433..58e63fc068 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -174,7 +174,7 @@ class BaseItemEntity(BaseEntity): @property def require_restart(self): - return self._require_restart + return False @property def has_studio_override(self): From 0508a7390243b3ec12f36ba61b5beb1197d2a730 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:26:16 +0200 Subject: [PATCH 25/26] implemented `reuire_restart` for endpoint and input entity --- openpype/settings/entities/input_entities.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/settings/entities/input_entities.py b/openpype/settings/entities/input_entities.py index 0d675fd37d..1f897d8c69 100644 --- a/openpype/settings/entities/input_entities.py +++ b/openpype/settings/entities/input_entities.py @@ -70,12 +70,16 @@ class EndpointEntity(ItemEntity): callback() if self.require_restart: - if self.has_unsaved_changes: + if self.require_restart: self.root_item.add_item_require_restart(self) else: self.root_item.remove_item_require_restart(self) self.parent.on_child_change(self) + @property + def require_restart(self): + return self.has_unsaved_changes + def update_default_value(self, value): value = self._check_update_value(value, "default") self._default_value = value @@ -121,6 +125,10 @@ class InputEntity(EndpointEntity): """Entity's value without metadata.""" return self._current_value + @property + def require_restart(self): + return self._value_is_modified + def _settings_value(self): return copy.deepcopy(self.value) From 1c6d0dd80407f183cc86e88d40996b3d7090bcba Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 27 May 2021 13:26:35 +0200 Subject: [PATCH 26/26] renamed previous require_restart to require_restart_on_change --- openpype/settings/entities/base_entity.py | 16 ++++++++++------ openpype/settings/entities/input_entities.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/openpype/settings/entities/base_entity.py b/openpype/settings/entities/base_entity.py index 58e63fc068..bd205dd4ef 100644 --- a/openpype/settings/entities/base_entity.py +++ b/openpype/settings/entities/base_entity.py @@ -111,7 +111,7 @@ class BaseItemEntity(BaseEntity): # Reference to `RootEntity` self.root_item = None # Change of value requires restart of OpenPype - self._require_restart = False + self._require_restart_on_change = False # Entity is in hierarchy of dynamically created entity self.is_in_dynamic_item = False @@ -172,6 +172,10 @@ class BaseItemEntity(BaseEntity): roles = [roles] self.roles = roles + @property + def require_restart_on_change(self): + return self._require_restart_on_change + @property def require_restart(self): return False @@ -267,7 +271,7 @@ class BaseItemEntity(BaseEntity): ) if ( - self._require_restart + self.require_restart_on_change and (self.is_dynamic_item or self.is_in_dynamic_item) ): raise EntitySchemaError( @@ -802,13 +806,13 @@ class ItemEntity(BaseItemEntity): self.root_item = self.parent.root_item # Item require restart on value change - require_restart = self.schema_data.get("require_restart") + require_restart_on_change = self.schema_data.get("require_restart") if ( - require_restart is None + require_restart_on_change is None and not (self.is_dynamic_item or self.is_in_dynamic_item) ): - require_restart = self.parent.require_restart - self._require_restart = require_restart + require_restart_on_change = self.parent.require_restart_on_change + self._require_restart_on_change = require_restart_on_change # File item reference if self.parent.is_file: diff --git a/openpype/settings/entities/input_entities.py b/openpype/settings/entities/input_entities.py index 1f897d8c69..295333eb60 100644 --- a/openpype/settings/entities/input_entities.py +++ b/openpype/settings/entities/input_entities.py @@ -69,7 +69,7 @@ class EndpointEntity(ItemEntity): for callback in self.on_change_callbacks: callback() - if self.require_restart: + if self.require_restart_on_change: if self.require_restart: self.root_item.add_item_require_restart(self) else: