From ec7bbcf19e4fe59437f8daee3ba3c591e25ab6d0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 29 Jul 2020 15:55:22 +0200 Subject: [PATCH] small bugfixes and added rawjson widget --- .../config_gui_schema/plugins_gui_schema.json | 24 +++ .../config_gui_schema/project_gui_schema.json | 3 +- pype/tools/config_setting/widgets/base.py | 57 ++++--- pype/tools/config_setting/widgets/inputs.py | 139 +++++++++++++++++- 4 files changed, 198 insertions(+), 25 deletions(-) create mode 100644 pype/tools/config_setting/config_gui_schema/plugins_gui_schema.json diff --git a/pype/tools/config_setting/config_gui_schema/plugins_gui_schema.json b/pype/tools/config_setting/config_gui_schema/plugins_gui_schema.json new file mode 100644 index 0000000000..79c1f85b85 --- /dev/null +++ b/pype/tools/config_setting/config_gui_schema/plugins_gui_schema.json @@ -0,0 +1,24 @@ +{ + "key": "plugins", + "type": "dict-expanding", + "label": "Plugins", + "children": [ + { + "key": "maya", + "type": "dict-expanding", + "label": "Maya", + "is_group": true, + "children": [ + { + "key": "test1", + "type": "raw-json", + "label": "Test1" + }, { + "key": "test2", + "type": "raw-json", + "label": "Test2" + } + ] + } + ] +} diff --git a/pype/tools/config_setting/config_gui_schema/project_gui_schema.json b/pype/tools/config_setting/config_gui_schema/project_gui_schema.json index 38c07ec33d..d2a6221f99 100644 --- a/pype/tools/config_setting/config_gui_schema/project_gui_schema.json +++ b/pype/tools/config_setting/config_gui_schema/project_gui_schema.json @@ -6,7 +6,8 @@ { "type": "schema", "children": [ - "ftrack_projects_gui_schema" + "ftrack_projects_gui_schema", + "plugins_gui_schema" ] } ] diff --git a/pype/tools/config_setting/widgets/base.py b/pype/tools/config_setting/widgets/base.py index e01f14aa70..52184b4c8a 100644 --- a/pype/tools/config_setting/widgets/base.py +++ b/pype/tools/config_setting/widgets/base.py @@ -177,6 +177,7 @@ class ProjectListView(QtWidgets.QListView): class ProjectListWidget(QtWidgets.QWidget): default = "< Default >" + project_changed = QtCore.Signal() def __init__(self, parent): self._parent = parent @@ -218,6 +219,10 @@ class ProjectListWidget(QtWidgets.QWidget): if self.validate_context_change(): self.select_project(new_project_name) self.current_project = new_project_name + self.project_changed.emit() + return + + self.select_project(self.current_project) def validate_context_change(self): # TODO add check if project can be changed (is modified) @@ -275,7 +280,7 @@ class ProjectWidget(QtWidgets.QWidget, PypeConfigurationWidget): def __init__(self, parent=None): super(ProjectWidget, self).__init__(parent) - self.is_overidable = True + self.is_overidable = False self.input_fields = [] scroll_widget = QtWidgets.QScrollArea(self) @@ -292,23 +297,13 @@ class ProjectWidget(QtWidgets.QWidget, PypeConfigurationWidget): project_list_widget = ProjectListWidget(self) content_layout.addWidget(project_list_widget) - self.project_list_widget = project_list_widget - self.scroll_widget = scroll_widget - self.content_layout = content_layout - self.content_widget = content_widget - - values = config.project_presets() - schema = config.gui_schema("project_gui_schema") - self.keys = schema.get("keys", []) - self.add_children_gui(schema, values) - footer_widget = QtWidgets.QWidget() footer_layout = QtWidgets.QHBoxLayout(footer_widget) - btn = QtWidgets.QPushButton("Finish") + save_btn = QtWidgets.QPushButton("Save") spacer_widget = QtWidgets.QWidget() footer_layout.addWidget(spacer_widget, 1) - footer_layout.addWidget(btn, 0) + footer_layout.addWidget(save_btn, 0) presets_widget = QtWidgets.QWidget() presets_layout = QtWidgets.QVBoxLayout(presets_widget) @@ -326,18 +321,18 @@ class ProjectWidget(QtWidgets.QWidget, PypeConfigurationWidget): layout.addWidget(project_list_widget, 0) layout.addWidget(presets_widget, 1) - btn.clicked.connect(self.___finish) + save_btn.clicked.connect(self._save) + project_list_widget.project_changed.connect(self._on_project_change) - def ___finish(self): - output = {} - for item in self.input_fields: - output.update(item.config_value()) + self.project_list_widget = project_list_widget + self.scroll_widget = scroll_widget + self.content_layout = content_layout + self.content_widget = content_widget - for key in reversed(self.keys): - _output = {key: output} - output = _output - - print(json.dumps(output, indent=4)) + values = config.global_project_presets() + schema = config.gui_schema("project_gui_schema") + self.keys = schema.get("keys", []) + self.add_children_gui(schema, values) def add_children_gui(self, child_configuration, values): item_type = child_configuration["type"] @@ -348,3 +343,19 @@ class ProjectWidget(QtWidgets.QWidget, PypeConfigurationWidget): ) self.input_fields.append(item) self.content_layout.addWidget(item) + + def _on_project_change(self): + self.is_overidable = ( + self.project_list_widget.project_name() is not None + ) + + def _save(self): + output = {} + for item in self.input_fields: + output.update(item.config_value()) + + for key in reversed(self.keys): + _output = {key: output} + output = _output + + print(json.dumps(output, indent=4)) diff --git a/pype/tools/config_setting/widgets/inputs.py b/pype/tools/config_setting/widgets/inputs.py index e5b929b7ca..58898aeccb 100644 --- a/pype/tools/config_setting/widgets/inputs.py +++ b/pype/tools/config_setting/widgets/inputs.py @@ -1,5 +1,5 @@ import json -from Qt import QtWidgets, QtCore +from Qt import QtWidgets, QtCore, QtGui from . import config from .base import PypeConfigurationWidget, TypeToKlass from .widgets import ( @@ -520,6 +520,7 @@ class TextMultiLineWidget(QtWidgets.QWidget, PypeConfigurationWidget): self, input_data, values, parent_keys, parent, label_widget=None ): self._parent = parent + self._as_widget = values is AS_WIDGET any_parent_is_group = parent.is_group if not any_parent_is_group: @@ -631,6 +632,141 @@ class TextMultiLineWidget(QtWidgets.QWidget, PypeConfigurationWidget): return {self.key: self.item_value()} +class RawJsonWidget(QtWidgets.QWidget, PypeConfigurationWidget): + value_changed = QtCore.Signal(object) + + def __init__( + self, input_data, values, parent_keys, parent, label_widget=None + ): + self._parent = parent + self._as_widget = values is AS_WIDGET + + any_parent_is_group = parent.is_group + if not any_parent_is_group: + any_parent_is_group = parent.any_parent_is_group + + is_group = input_data.get("is_group", False) + if is_group and any_parent_is_group: + raise SchemeGroupHierarchyBug() + + if not any_parent_is_group and not is_group: + is_group = True + + self.is_group = is_group + self.is_modified = False + self._is_overriden = False + + self._state = None + + super(RawJsonWidget, self).__init__(parent) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + self.text_input = QtWidgets.QPlainTextEdit() + self.text_input.setTabStopDistance( + QtGui.QFontMetricsF( + self.text_input.font() + ).horizontalAdvance(" ") * 4 + ) + if not label_widget: + label = input_data["label"] + label_widget = QtWidgets.QLabel(label) + layout.addWidget(label_widget) + layout.addWidget(self.text_input) + + self.label_widget = label_widget + + self.key = input_data["key"] + keys = list(parent_keys) + keys.append(self.key) + self.keys = keys + + value = self.value_from_values(values) + if value is not NOT_SET: + self.text_input.setPlainText(value) + + self.origin_value = self.item_value() + + self.text_input.textChanged.connect(self._on_value_change) + + @property + def child_modified(self): + return self.is_modified + + @property + def child_overriden(self): + return self._is_overriden + + @property + def is_overidable(self): + return self._parent.is_overidable + + @property + def is_overriden(self): + if self._is_overriden: + return self._is_overriden + return self._parent.is_overriden + + def validate_value(self, value): + try: + json.dumps(value) + return True + except Exception: + return False + + def set_value(self, value, origin_value=False): + is_valid = self.validate_value(value) + if is_valid: + value = json.dumps(value, indent=4) + self.text_input.setPlainText(value) + + if origin_value: + self.origin_value = self.item_value() + self._on_value_change() + + def reset_value(self): + self.set_value(self.origin_value) + + def clear_value(self): + self.set_value("{{}}") + + def _on_value_change(self, item=None): + self.is_modified = self.item_value() != self.origin_value + if self.is_overidable: + self._is_overriden = True + + self.update_style() + + self.value_changed.emit(self) + + def update_style(self, is_overriden=None): + if is_overriden is None: + is_overriden = self.is_overriden + is_modified = self.is_modified + + state = self.style_state(is_overriden, is_modified) + if self._state == state: + return + + if self._as_widget: + property_name = "input-state" + widget = self.text_input + else: + property_name = "state" + widget = self.label_widget + + widget.setProperty(property_name, state) + widget.style().polish(widget) + + def item_value(self): + return self.text_input.toPlainText() + + def config_value(self): + return {self.key: self.item_value()} + + class TextListItem(QtWidgets.QWidget, PypeConfigurationWidget): _btn_size = 20 value_changed = QtCore.Signal(object) @@ -1591,6 +1727,7 @@ class ModifiableDict(ExpandingWidget, PypeConfigurationWidget): TypeToKlass.types["boolean"] = BooleanWidget TypeToKlass.types["text-singleline"] = TextSingleLineWidget TypeToKlass.types["text-multiline"] = TextMultiLineWidget +TypeToKlass.types["raw-json"] = RawJsonWidget TypeToKlass.types["int"] = IntegerWidget TypeToKlass.types["float"] = FloatWidget TypeToKlass.types["dict-expanding"] = DictExpandWidget