Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Ask user to restart after changing global environments in settings #1550

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1921542
Create draft PR for #910
mkolar May 20, 2021
bbb2e15
entity knows if should openpype requires restart
iLLiCiTiT May 26, 2021
a18aa04
added schema validation for specific values
iLLiCiTiT May 26, 2021
18b10d8
root entity can trigger callbacks if restart require entity changed i…
iLLiCiTiT May 26, 2021
e2ae219
endpoint entities can trigger changes on root item
iLLiCiTiT May 26, 2021
4f6b99f
added require_restart on two entities in settings
iLLiCiTiT May 26, 2021
2e309f1
category can show a label that changes require install
iLLiCiTiT May 26, 2021
faa32ad
added atexit callback to tray widget
iLLiCiTiT May 27, 2021
abaf323
TrayManger has exit method
iLLiCiTiT May 27, 2021
4fb40ac
implemented restart method for tray tool
iLLiCiTiT May 27, 2021
8013228
added restart_tray method to TrayModulesManager so models can call it
iLLiCiTiT May 27, 2021
f1a2b79
save on categories can trigger restart_required_trigger signal if cha…
iLLiCiTiT May 27, 2021
d0bd67d
Settings window register slots for restart_required_trigger signal
iLLiCiTiT May 27, 2021
734e503
created RestartDialog aasking if user want to restart current process
iLLiCiTiT May 27, 2021
859ed68
Settings window has trigger_restart signal which meant to be triggere…
iLLiCiTiT May 27, 2021
38afc53
show restart dialog on restart require
iLLiCiTiT May 27, 2021
1be7266
dont show dialog if nothing is listening to trigger_restart signal
iLLiCiTiT May 27, 2021
4bdcc8f
restart label is centered in footer
iLLiCiTiT May 27, 2021
5c9d429
reset label text on save
iLLiCiTiT May 27, 2021
6bc925f
settings module action can trigger restart of tray
iLLiCiTiT May 27, 2021
0a88d11
fixed inheritance of require_restart attribute
iLLiCiTiT May 27, 2021
bd40bae
added few more require_restart attributes in schemas
iLLiCiTiT May 27, 2021
da1bd57
fix removing not set items yet
iLLiCiTiT May 27, 2021
bce80e5
require_restart says if entity requires restart
iLLiCiTiT May 27, 2021
0508a73
implemented `reuire_restart` for endpoint and input entity
iLLiCiTiT May 27, 2021
1c6d0dd
renamed previous require_restart to require_restart_on_change
iLLiCiTiT May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions openpype/modules/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,10 @@ def get_enabled_tray_modules(self):
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()
Expand Down
4 changes: 4 additions & 0 deletions openpype/modules/settings_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def create_settings_window(self):
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.
Expand Down
27 changes: 27 additions & 0 deletions openpype/settings/entities/base_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def __init__(self, schema_data):
self.file_item = None
# Reference to `RootEntity`
self.root_item = None
# Change of value requires restart of OpenPype
self._require_restart_on_change = False

# Entity is in hierarchy of dynamically created entity
self.is_in_dynamic_item = False
Expand Down Expand Up @@ -170,6 +172,14 @@ def __init__(self, schema_data):
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

@property
def has_studio_override(self):
"""Says if entity or it's children has studio overrides."""
Expand Down Expand Up @@ -260,6 +270,14 @@ def schema_validations(self):
self, "Dynamic entity has set `is_group` to true."
)

if (
self.require_restart_on_change
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.
Expand Down Expand Up @@ -787,6 +805,15 @@ def __init__(self, schema_data, parent, is_dynamic_item=False):
# Root item reference
self.root_item = self.parent.root_item

# Item require restart on value change
require_restart_on_change = self.schema_data.get("require_restart")
if (
require_restart_on_change is None
and not (self.is_dynamic_item or self.is_in_dynamic_item)
):
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:
self.file_item = self.parent
Expand Down
14 changes: 14 additions & 0 deletions openpype/settings/entities/input_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,18 @@ def settings_value(self):
def on_change(self):
for callback in self.on_change_callbacks:
callback()

if self.require_restart_on_change:
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
Expand Down Expand Up @@ -115,6 +125,10 @@ def value(self):
"""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)

Expand Down
27 changes: 27 additions & 0 deletions openpype/settings/entities/root_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -64,6 +66,31 @@ def override_state(self):
"""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):
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()

@abstractmethod
def reset(self):
"""Reset values and entities to initial state.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"key": "ftrack",
"label": "Ftrack",
"collapsible": true,
"require_restart": true,
"checkbox_key": "enabled",
"children": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"key": "environment",
"label": "Environment",
"type": "raw-json",
"env_group_key": "global"
"env_group_key": "global",
"require_restart": true
},
{
"type": "splitter"
Expand All @@ -44,7 +45,8 @@
"key": "openpype_path",
"label": "Versions Repository",
"multiplatform": true,
"multipath": true
"multipath": true,
"require_restart": true
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"key": "avalon",
"label": "Avalon",
"collapsible": true,
"require_restart": true,
"children": [
{
"type": "number",
Expand All @@ -35,6 +36,7 @@
"key": "timers_manager",
"label": "Timers Manager",
"collapsible": true,
"require_restart": true,
"checkbox_key": "enabled",
"children": [
{
Expand Down Expand Up @@ -66,6 +68,7 @@
"key": "clockify",
"label": "Clockify",
"collapsible": true,
"require_restart": true,
"checkbox_key": "enabled",
"children": [
{
Expand All @@ -84,6 +87,7 @@
"key": "sync_server",
"label": "Site Sync",
"collapsible": true,
"require_restart": true,
"checkbox_key": "enabled",
"children": [
{
Expand Down Expand Up @@ -114,6 +118,7 @@
"type": "dict",
"key": "deadline",
"label": "Deadline",
"require_restart": true,
"collapsible": true,
"checkbox_key": "enabled",
"children": [
Expand All @@ -133,6 +138,7 @@
"type": "dict",
"key": "muster",
"label": "Muster",
"require_restart": true,
"collapsible": true,
"checkbox_key": "enabled",
"children": [
Expand Down
34 changes: 31 additions & 3 deletions openpype/tools/settings/settings/categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def set_ignore(self, ignore_changes=True):
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)
Expand Down Expand Up @@ -181,9 +182,10 @@ def create_ui(self):
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)
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)
Expand All @@ -201,6 +203,7 @@ def create_ui(self):
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
Expand Down Expand Up @@ -319,6 +322,15 @@ def _create_root_entity(self):
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)

Expand All @@ -335,6 +347,9 @@ def reset(self):
dialog = None
try:
self._create_root_entity()
self.entity.add_require_restart_change_callback(
self._on_require_restart_change
)

self.add_children_gui()

Expand Down Expand Up @@ -429,6 +444,15 @@ def on_saved(self, saved_tab_widget):
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():
Expand All @@ -438,6 +462,10 @@ def _save(self):

self.saved.emit(self)

if require_restart:
self.restart_required_trigger.emit()
self.require_restart_label.setText("")

def _on_refresh(self):
self.reset()

Expand Down
44 changes: 42 additions & 2 deletions openpype/tools/settings/settings/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,6 @@ def __init__(self, parent=None):
layout.addWidget(message_label)
layout.addWidget(btns_widget)

self.state = None

def on_cancel_pressed(self):
self.done(0)

Expand All @@ -287,6 +285,48 @@ def on_discard_pressed(self):
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)
Expand Down
Loading