From 625eebea25dd93c127c47d394fdfc3e3d02e5c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Fri, 18 Sep 2020 17:32:56 +0200 Subject: [PATCH 001/176] maya plugins and capture settings --- .../plugins/maya/maya/maya_capture.json | 108 +++++ .../plugins/maya/maya/publish.json | 21 + .../plugins/maya/maya/workfile_build.json | 1 + .../projects_schema/1_plugins_gui_schema.json | 101 +--- .../projects_schema/2_maya_capture.json | 433 ++++++++++++++++++ .../projects_schema/2_maya_plugins.json | 90 ++++ .../projects_schema/2_maya_workfiles.json | 6 + pype/tools/settings/settings/widgets/lib.py | 6 +- 8 files changed, 681 insertions(+), 85 deletions(-) create mode 100644 pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json create mode 100644 pype/settings/defaults/project_settings/plugins/maya/maya/publish.json create mode 100644 pype/settings/defaults/project_settings/plugins/maya/maya/workfile_build.json create mode 100644 pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json create mode 100644 pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_plugins.json create mode 100644 pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_workfiles.json diff --git a/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json b/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json new file mode 100644 index 0000000000..b6c4893034 --- /dev/null +++ b/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json @@ -0,0 +1,108 @@ +{ + "Codec": { + "compression": "jpg", + "format": "image", + "quality": 95 + }, + "Display Options": { + "background": [ + 0.7137254901960784, + 0.7137254901960784, + 0.7137254901960784 + ], + "backgroundBottom": [ + 0.7137254901960784, + 0.7137254901960784, + 0.7137254901960784 + ], + "backgroundTop": [ + 0.7137254901960784, + 0.7137254901960784, + 0.7137254901960784 + ], + "override_display": true + }, + "Generic": { + "isolate_view": true, + "off_screen": true + }, + "IO": { + "name": "", + "open_finished": false, + "raw_frame_numbers": false, + "recent_playblasts": [], + "save_file": false + }, + "PanZoom": { + "pan_zoom": true + }, + "Renderer": { + "rendererName": "vp2Renderer" + }, + "Resolution": { + "height": 1080, + "mode": "Custom", + "percent": 1.0, + "width": 1920 + }, + "Time Range": { + "end_frame": 25, + "frame": "", + "start_frame": 0, + "time": "Time Slider" + }, + "Viewport Options": { + "cameras": false, + "clipGhosts": false, + "controlVertices": false, + "deformers": false, + "dimensions": false, + "displayLights": 0, + "dynamicConstraints": false, + "dynamics": false, + "fluids": false, + "follicles": false, + "gpuCacheDisplayFilter": false, + "greasePencils": false, + "grid": false, + "hairSystems": false, + "handles": false, + "high_quality": true, + "hud": false, + "hulls": false, + "ikHandles": false, + "imagePlane": false, + "joints": false, + "lights": false, + "locators": false, + "manipulators": false, + "motionTrails": false, + "nCloths": false, + "nParticles": false, + "nRigids": false, + "nurbsCurves": false, + "nurbsSurfaces": false, + "override_viewport_options": true, + "particleInstancers": false, + "pivots": false, + "planes": false, + "pluginShapes": false, + "polymeshes": true, + "shadows": false, + "strokes": false, + "subdivSurfaces": false, + "textures": false, + "twoSidedLighting": true + }, + "Camera Options": { + "displayGateMask": false, + "displayResolution": false, + "displayFilmGate": false, + "displayFieldChart": false, + "displaySafeAction": false, + "displaySafeTitle": false, + "displayFilmPivot": false, + "displayFilmOrigin": false, + "overscan": 1.0 + } +} diff --git a/pype/settings/defaults/project_settings/plugins/maya/maya/publish.json b/pype/settings/defaults/project_settings/plugins/maya/maya/publish.json new file mode 100644 index 0000000000..486f0917e2 --- /dev/null +++ b/pype/settings/defaults/project_settings/plugins/maya/maya/publish.json @@ -0,0 +1,21 @@ +{ + "ValidateModelName": { + "enabled": true, + "material_file": { + "windows": "", + "darwin": "", + "linux": "" + }, + "regex": "" + }, + "ValidateAssemblyName": { + "enabled": true + }, + "ValidateShaderName": { + "enabled": true, + "regex": "(?P.*)_(.*)_SHD" + }, + "ValidateMeshHasOverlappingUVs": { + "enabled": true + } +} \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/plugins/maya/maya/workfile_build.json b/pype/settings/defaults/project_settings/plugins/maya/maya/workfile_build.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/pype/settings/defaults/project_settings/plugins/maya/maya/workfile_build.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json index f70495017e..560d214877 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json @@ -353,94 +353,27 @@ } ] }, { - "type": "dict", + "type": "dict-invisible", "collapsable": true, "key": "maya", "label": "Maya", "children": [ - { - "type": "dict", - "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "key": "ValidateModelName", - "label": "Validate Model Name", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "text", - "key": "material_file", - "label": "Material File" - }, { - "type": "text", - "key": "regex", - "label": "Validation regex" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ValidateAssemblyName", - "label": "Validate Assembly Name", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ValidateShaderName", - "label": "ValidateShaderName", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "text", - "key": "regex", - "label": "Validation regex" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ValidateMeshHasOverlappingUVs", - "label": "ValidateMeshHasOverlappingUVs", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - } - ] - }, { - "type": "raw-json", - "key": "workfile_build", - "label": "Workfile Build logic", - "is_file": true - } + { + "type": "dict", + "collapsable": true, + "key": "maya", + "label": "Maya", + "children": [ + { + "type": "schema", + "children": [ + "2_maya_capture", + "2_maya_plugins", + "2_maya_workfiles" + ] + } + ] + } ] }, { "type": "dict", diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json new file mode 100644 index 0000000000..a7b44323d2 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json @@ -0,0 +1,433 @@ +{ + "type": "dict", + "collapsable": true, + "key": "maya_capture", + "label": "Maya Capture settings", + "is_file": true, + "children": [ + { + "type": "dict", + "collapsable": true, + "key": "Codec", + "label": "Codec", + "children": [ + { + "type": "text", + "key": "compression", + "label": "Compression type" + }, { + "type": "text", + "key": "format", + "label": "Data format" + }, { + "type": "number", + "key": "quality", + "label": "Quality", + "decimal": 0, + "minimum": 0, + "maximum": 100 + } + ] + }, { + "type": "dict", + "collapsable": true, + "key": "Display Options", + "label": "Display Options", + "children": [ + { + "type": "list", + "key": "background", + "label": "Background Color", + "object_type": "number", + "input_modifiers": { + "decimal": 3, + "minimum": 0, + "maximum": 1 + } + }, { + "type": "list", + "key": "backgroundBottom", + "label": "Bottom Background Color", + "object_type": "number", + "input_modifiers": { + "decimal": 3, + "minimum": 0, + "maximum": 1 + } + }, { + "type": "list", + "key": "backgroundTop", + "label": "Top Background Color", + "object_type": "number", + "input_modifiers": { + "decimal": 3, + "minimum": 0, + "maximum": 1 + } + }, { + "type": "boolean", + "key": "override_display", + "label": "Override display options" + } + ] + }, { + "type": "dict", + "collapsable": true, + "key": "Generic", + "label": "Generic", + "children": [ + { + "type": "boolean", + "key": "isolate_view", + "label": "Isolate view" + },{ + "type": "boolean", + "key": "off_screen", + "label": "Off Screen" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "IO", + "label": "IO", + "children": [ + { + "type": "text", + "key": "name", + "label": "Name" + },{ + "type": "boolean", + "key": "open_finished", + "label": "Open finished" + },{ + "type": "boolean", + "key": "raw_frame_numbers", + "label": "Raw frame numbers" + },{ + "type": "list", + "key": "recent_playblasts", + "label": "Recent playbacks", + "object_type": "text" + },{ + "type": "boolean", + "key": "save_file", + "label": "Save file" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "PanZoom", + "label": "Pan Zoom", + "children": [ + { + "type": "boolean", + "key": "pan_zoom", + "label": "Pan Zoom" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "Renderer", + "label": "Renderer", + "children": [ + { + "type": "text", + "key": "rendererName", + "label": "Renderer name" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "Resolution", + "label": "Resolution", + "children": [ + { + "type": "number", + "key": "width", + "label": "Width", + "decimal": 0, + "minimum": 0, + "maximum": 99999 + },{ + "type": "number", + "key": "height", + "label": "Height", + "decimal": 0, + "minimum": 0, + "maximum": 99999 + },{ + "type": "number", + "key": "percent", + "label": "percent", + "decimal": 1, + "minimum": 0, + "maximum": 200 + },{ + "type": "text", + "key": "mode", + "label": "Mode" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "Time Range", + "label": "Time Range", + "children": [ + { + "type": "number", + "key": "start_frame", + "label": "Start frame", + "decimal": 0, + "minimum": 0, + "maximum": 999999 + },{ + "type": "number", + "key": "end_frame", + "label": "End frame", + "decimal": 0, + "minimum": 0, + "maximum": 999999 + },{ + "type": "text", + "key": "mode", + "label": "Mode" + },{ + "type": "text", + "key": "frame", + "label": "Frame" + },{ + "type": "text", + "key": "time", + "label": "Time" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "Viewport Options", + "label": "Viewport Options", + "children": [ + { + "type": "boolean", + "key": "cameras", + "label": "cameras" + },{ + "type": "boolean", + "key": "clipGhosts", + "label": "clipGhosts" + },{ + "type": "boolean", + "key": "controlVertices", + "label": "controlVertices" + },{ + "type": "boolean", + "key": "deformers", + "label": "deformers" + },{ + "type": "boolean", + "key": "dimensions", + "label": "dimensions" + },{ + "type": "number", + "key": "displayLights", + "label": "displayLights", + "decimal": 0, + "minimum": 0, + "maximum": 10 + },{ + "type": "boolean", + "key": "dynamicConstraints", + "label": "dynamicConstraints" + },{ + "type": "boolean", + "key": "dynamics", + "label": "dynamics" + },{ + "type": "boolean", + "key": "fluids", + "label": "fluids" + },{ + "type": "boolean", + "key": "follicles", + "label": "follicles" + },{ + "type": "boolean", + "key": "gpuCacheDisplayFilter", + "label": "gpuCacheDisplayFilter" + },{ + "type": "boolean", + "key": "greasePencils", + "label": "greasePencils" + },{ + "type": "boolean", + "key": "grid", + "label": "grid" + },{ + "type": "boolean", + "key": "hairSystems", + "label": "hairSystems" + },{ + "type": "boolean", + "key": "handles", + "label": "handles" + },{ + "type": "boolean", + "key": "high_quality", + "label": "high_quality" + },{ + "type": "boolean", + "key": "hud", + "label": "hud" + },{ + "type": "boolean", + "key": "hulls", + "label": "hulls" + },{ + "type": "boolean", + "key": "ikHandles", + "label": "ikHandles" + },{ + "type": "boolean", + "key": "imagePlane", + "label": "imagePlane" + },{ + "type": "boolean", + "key": "joints", + "label": "joints" + },{ + "type": "boolean", + "key": "lights", + "label": "lights" + },{ + "type": "boolean", + "key": "locators", + "label": "locators" + },{ + "type": "boolean", + "key": "manipulators", + "label": "manipulators" + },{ + "type": "boolean", + "key": "motionTrails", + "label": "motionTrails" + },{ + "type": "boolean", + "key": "nCloths", + "label": "nCloths" + },{ + "type": "boolean", + "key": "nParticles", + "label": "nParticles" + },{ + "type": "boolean", + "key": "nRigids", + "label": "nRigids" + },{ + "type": "boolean", + "key": "nurbsCurves", + "label": "nurbsCurves" + },{ + "type": "boolean", + "key": "nurbsSurfaces", + "label": "nurbsSurfaces" + },{ + "type": "boolean", + "key": "override_viewport_options", + "label": "override_viewport_options" + },{ + "type": "boolean", + "key": "particleInstancers", + "label": "particleInstancers" + },{ + "type": "boolean", + "key": "pivots", + "label": "pivots" + },{ + "type": "boolean", + "key": "planes", + "label": "planes" + },{ + "type": "boolean", + "key": "pluginShapes", + "label": "pluginShapes" + },{ + "type": "boolean", + "key": "polymeshes", + "label": "polymeshes" + },{ + "type": "boolean", + "key": "shadows", + "label": "shadows" + },{ + "type": "boolean", + "key": "strokes", + "label": "strokes" + },{ + "type": "boolean", + "key": "subdivSurfaces", + "label": "subdivSurfaces" + },{ + "type": "boolean", + "key": "textures", + "label": "textures" + },{ + "type": "boolean", + "key": "twoSidedLighting", + "label": "twoSidedLighting" + } + ] + },{ + "type": "dict", + "collapsable": true, + "key": "Camera Options", + "label": "Camera Options", + "children": [ + { + "type": "boolean", + "key": "displayGateMask", + "label": "displayGateMask" + },{ + "type": "boolean", + "key": "displayResolution", + "label": "displayResolution" + },{ + "type": "boolean", + "key": "displayFilmGate", + "label": "displayFilmGate" + },{ + "type": "boolean", + "key": "displayFieldChart", + "label": "displayFieldChart" + },{ + "type": "boolean", + "key": "displaySafeAction", + "label": "displaySafeAction" + },{ + "type": "boolean", + "key": "displaySafeTitle", + "label": "displaySafeTitle" + },{ + "type": "boolean", + "key": "displayFilmPivot", + "label": "displayFilmPivot" + },{ + "type": "boolean", + "key": "displayFilmOrigin", + "label": "displayFilmOrigin" + },{ + "type": "number", + "key": "overscan", + "label": "overscan", + "decimal": 1, + "minimum": 0, + "maximum": 10 + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_plugins.json b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_plugins.json new file mode 100644 index 0000000000..7ba9608610 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_plugins.json @@ -0,0 +1,90 @@ +{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [ + { + "type": "dict", + "collapsable": true, + "key": "ValidateModelName", + "label": "Validate Model Name", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "label", + "label": "Path to material file defining list of material names to check. This is material name per line simple text file.
It will be checked against named group shader in your Validation regex.

For example:
^.*(?P=<shader>.+)_GEO

" + }, + { + "type": "path-widget", + "key": "material_file", + "label": "Material File", + "multiplatform": true, + "multipath": false + }, + { + "type": "text", + "key": "regex", + "label": "Validation regex" + } + ] + }, { + "type": "dict", + "collapsable": true, + "key": "ValidateAssemblyName", + "label": "Validate Assembly Name", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + } + ] + }, { + "type": "dict", + "collapsable": true, + "key": "ValidateShaderName", + "label": "ValidateShaderName", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "label", + "label": "Shader name regex can use named capture group asset to validate against current asset name.

Example:
^.*(?P=<asset>.+)_SHD

" + + }, { + "type": "text", + "key": "regex", + "label": "Validation regex" + } + ] + }, { + "type": "dict", + "collapsable": true, + "key": "ValidateMeshHasOverlappingUVs", + "label": "ValidateMeshHasOverlappingUVs", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + } + ] + } + ] + } diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_workfiles.json b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_workfiles.json new file mode 100644 index 0000000000..bae4d32abd --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_workfiles.json @@ -0,0 +1,6 @@ +{ + "type": "raw-json", + "key": "workfile_build", + "label": "Workfile Build logic", + "is_file": true +} diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index e225d65417..24dc4b552c 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -300,7 +300,11 @@ def gui_schema(subfolder, main_schema_name): filepath = os.path.join(dirpath, filename) with open(filepath, "r") as json_stream: - schema_data = json.load(json_stream) + try: + schema_data = json.load(json_stream) + except Exception as e: + raise Exception((f"Unable to parse JSON file {json_stream}\n " + f" - {e}")) from e loaded_schemas[basename] = schema_data main_schema = _fill_inner_schemas( From b7301a37346cc315739b6f25d94e25219cfc22c1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 10:33:58 +0200 Subject: [PATCH 002/176] items are stretched in settings gui --- pype/tools/settings/settings/widgets/base.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index 423380d54c..ee4762de14 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -268,6 +268,10 @@ class SystemWidget(QtWidgets.QWidget): self.input_fields.append(item) self.content_layout.addWidget(item) + # Add spacer to stretch children guis + spacer = QtWidgets.QWidget(self.content_widget) + self.content_layout.addWidget(spacer, 1) + class ProjectListView(QtWidgets.QListView): left_mouse_released_at = QtCore.Signal(QtCore.QModelIndex) @@ -530,6 +534,10 @@ class ProjectWidget(QtWidgets.QWidget): self.input_fields.append(item) self.content_layout.addWidget(item) + # Add spacer to stretch children guis + spacer = QtWidgets.QWidget(self.content_widget) + self.content_layout.addWidget(spacer, 1) + def _on_project_change(self): project_name = self.project_list_widget.project_name() if project_name is None: From 066349a3cb4424c4a0317002cdb5918c16614491 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 12:02:39 +0200 Subject: [PATCH 003/176] implemented base pype module class in modules --- pype/modules/__init__.py | 5 +++++ pype/modules/base.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 pype/modules/base.py diff --git a/pype/modules/__init__.py b/pype/modules/__init__.py index e69de29bb2..32b7426ba5 100644 --- a/pype/modules/__init__.py +++ b/pype/modules/__init__.py @@ -0,0 +1,5 @@ +from .base import PypeModule + +__all__ = ( + "PypeModule", +) diff --git a/pype/modules/base.py b/pype/modules/base.py new file mode 100644 index 0000000000..2d97bc5e14 --- /dev/null +++ b/pype/modules/base.py @@ -0,0 +1,26 @@ +from uuid import uuid4 +from pype.api import Logger + + +class PypeModule: + """Base class of pype module.""" + enabled = False + name = None + _id = None + + def __init__(self, settings): + if self.name is None: + self.name = self.__class__.__name__ + + self.log = Logger().get_logger(self.name) + + self.settings = settings.get(self.name) + self.enabled = settings.get("enabled", False) + self._id = uuid4() + + @property + def id(self): + return self._id + + def startup_environments(self): + return {} From b50438a66cebbbb1dc7767a6973ff781c5b429b4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 12:03:35 +0200 Subject: [PATCH 004/176] implemented basic pype modules manager which does not much do at this time --- pype/modules_manager.py | 104 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 pype/modules_manager.py diff --git a/pype/modules_manager.py b/pype/modules_manager.py new file mode 100644 index 0000000000..073b153f08 --- /dev/null +++ b/pype/modules_manager.py @@ -0,0 +1,104 @@ +import os +import sys +import inspect + +import pype.modules +from pype.modules import PypeModule +from pype.settings import system_settings +from pype.api import Logger + + +class PypeModuleManager: + skip_module_names = ("__pycache__", ) + + def __init__(self): + self.log = Logger().get_logger( + "{}.{}".format(__name__, self.__class__.__name__) + ) + + self.pype_modules = self.find_pype_modules() + + def modules_environments(self): + environments = {} + for pype_module in self.pype_modules.values(): + environments.update(pype_module.startup_environments()) + return environments + + def find_pype_modules(self): + settings = system_settings() + modules = [] + dirpath = os.path.dirname(pype.modules.__file__) + for module_name in os.listdir(dirpath): + # Check if path lead to a folder + full_path = os.path.join(dirpath, module_name) + if not os.path.isdir(full_path): + continue + + # Skip known invalid names + if module_name in self.skip_module_names: + continue + + import_name = "pype.modules.{}".format(module_name) + try: + modules.append( + __import__(import_name, fromlist=[""]) + ) + print(import_name, sys.modules.get("PyQt5")) + + except Exception: + self.log.warning( + "Couldn't import {}".format(import_name), exc_info=True + ) + + pype_module_classes = [] + for module in modules: + try: + pype_module_classes.extend( + self._classes_from_module(PypeModule, module) + ) + except Exception: + self.log.warning( + "Couldn't import {}".format(import_name), exc_info=True + ) + + pype_modules = {} + for pype_module_class in pype_module_classes: + try: + pype_module = pype_module_class(settings) + if pype_module.enabled: + pype_modules[pype_module.id] = pype_module + except Exception: + self.log.warning( + "Couldn't create instance of {}".format( + pype_module_class.__class__.__name__ + ), + exc_info=True + ) + return pype_modules + + def _classes_from_module(self, superclass, module): + classes = list() + + def recursive_bases(klass): + output = [] + output.extend(klass.__bases__) + for base in klass.__bases__: + output.extend(recursive_bases(base)) + return output + + for name in dir(module): + # It could be anything at this point + obj = getattr(module, name) + + if not inspect.isclass(obj) or not len(obj.__bases__) > 0: + continue + + # Use string comparison rather than `issubclass` + # in order to support reloading of this module. + bases = recursive_bases(obj) + if not any(base.__name__ == superclass.__name__ for base in bases): + continue + + classes.append(obj) + + return classes From 04fd74587804006c7d3df0fede102b9735692dc9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 12:37:38 +0200 Subject: [PATCH 005/176] implemented multiselection combobox --- .../widgets/multiselection_combobox.py | 335 ++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 pype/tools/settings/settings/widgets/multiselection_combobox.py diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py new file mode 100644 index 0000000000..d77de9f0e3 --- /dev/null +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -0,0 +1,335 @@ +from Qt import QtCore, QtGui, QtWidgets + + +class ComboItemDelegate(QtWidgets.QStyledItemDelegate): + """ + Helper styled delegate (mostly based on existing private Qt's + delegate used by the QtWidgets.QComboBox). Used to style the popup like a + list view (e.g windows style). + """ + + def paint(self, painter, option, index): + option = QtWidgets.QStyleOptionViewItem(option) + option.showDecorationSelected = True + + # option.state &= ( + # ~QtWidgets.QStyle.State_HasFocus + # & ~QtWidgets.QStyle.State_MouseOver + # ) + super(ComboItemDelegate, self).paint(painter, option, index) + + +class ComboMenuDelegate(QtWidgets.QAbstractItemDelegate): + """ + Helper styled delegate (mostly based on existing private Qt's + delegate used by the QtWidgets.QComboBox). Used to style the popup like a + menu. (e.g osx aqua style). + """ + + def paint(self, painter, option, index): + menuopt = self._menu_style_option(option, index) + if option.widget is not None: + style = option.widget.style() + else: + style = QtWidgets.QApplication.style() + style.drawControl(QtWidgets.QStyle.CE_MenuItem, menuopt, painter, + option.widget) + + def sizeHint(self, option, index): + menuopt = self._menu_style_option(option, index) + if option.widget is not None: + style = option.widget.style() + else: + style = QtWidgets.QApplication.style() + return style.sizeFromContents( + QtWidgets.QStyle.CT_MenuItem, menuopt, menuopt.rect.size(), + option.widget + ) + + def _menu_style_option(self, option, index): + menuoption = QtWidgets.QStyleOptionMenuItem() + if option.widget: + palette_source = option.widget.palette("QMenu") + else: + palette_source = QtWidgets.QApplication.palette("QMenu") + + palette = option.palette.resolve(palette_source) + foreground = index.data(QtCore.Qt.ForegroundRole) + if isinstance(foreground, (QtGui.QBrush, QtGui.QColor, QtGui.QPixmap)): + foreground = QtGui.QBrush(foreground) + palette.setBrush(QtGui.QPalette.Text, foreground) + palette.setBrush(QtGui.QPalette.ButtonText, foreground) + palette.setBrush(QtGui.QPalette.WindowText, foreground) + + background = index.data(QtCore.Qt.BackgroundRole) + if isinstance(background, (QtGui.QBrush, QtGui.QColor, QtGui.QPixmap)): + background = QtGui.QBrush(background) + palette.setBrush(QtGui.QPalette.Background, background) + + menuoption.palette = palette + + decoration = index.data(QtCore.Qt.DecorationRole) + if isinstance(decoration, QtGui.QIcon): + menuoption.icon = decoration + + menuoption.menuItemType = QtWidgets.QStyleOptionMenuItem.Normal + + if index.flags() & QtCore.Qt.ItemIsUserCheckable: + menuoption.checkType = QtWidgets.QStyleOptionMenuItem.NonExclusive + else: + menuoption.checkType = QtWidgets.QStyleOptionMenuItem.NotCheckable + + check = index.data(QtCore.Qt.CheckStateRole) + menuoption.checked = check == QtCore.Qt.Checked + + if option.widget is not None: + menuoption.font = option.widget.font() + else: + menuoption.font = QtWidgets.QApplication.font("QMenu") + + menuoption.maxIconWidth = option.decorationSize.width() + 4 + menuoption.rect = option.rect + menuoption.menuRect = option.rect + + # menuoption.menuHasCheckableItems = True + menuoption.tabWidth = 0 + # TODO: self.displayText(QVariant, QLocale) + # TODO: Why is this not a QtWidgets.QStyledItemDelegate? + menuoption.text = str(index.data(QtCore.Qt.DisplayRole)) + + menuoption.fontMetrics = QtGui.QFontMetrics(menuoption.font) + state = option.state & ( + QtWidgets.QStyle.State_MouseOver + | QtWidgets.QStyle.State_Selected + | QtWidgets.QStyle.State_Active + ) + + if index.flags() & QtCore.Qt.ItemIsEnabled: + state = state | QtWidgets.QStyle.State_Enabled + menuoption.palette.setCurrentColorGroup(QtGui.QPalette.Active) + else: + state = state & ~QtWidgets.QStyle.State_Enabled + menuoption.palette.setCurrentColorGroup(QtGui.QPalette.Disabled) + + if menuoption.checked: + state = state | QtWidgets.QStyle.State_On + else: + state = state | QtWidgets.QStyle.State_Off + + menuoption.state = state + return menuoption + + +class CheckComboBox(QtWidgets.QComboBox): + ignored_keys = { + QtCore.Qt.Key_Up, + QtCore.Qt.Key_Down, + QtCore.Qt.Key_PageDown, + QtCore.Qt.Key_PageUp, + QtCore.Qt.Key_Home, + QtCore.Qt.Key_End + } + + def __init__( + self, parent=None, placeholder_text="", separator=", ", **kwargs + ): + super(CheckComboBox, self).__init__(parent=parent, **kwargs) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + self._popup_is_shown = False + # self.__supressPopupHide = False + self._block_mouse_release_timer = QtCore.QTimer(self, singleShot=True) + self._initial_mouse_pos = None + self._separator = separator + self._placeholder_text = placeholder_text + self._update_item_delegate() + + def mousePressEvent(self, event): + """Reimplemented.""" + self._popup_is_shown = False + super(CheckComboBox, self).mousePressEvent(event) + if self._popup_is_shown: + self._initial_mouse_pos = self.mapToGlobal(event.pos()) + self._block_mouse_release_timer.start( + QtWidgets.QApplication.doubleClickInterval() + ) + + def changeEvent(self, event): + """Reimplemented.""" + if event.type() == QtCore.QEvent.StyleChange: + self._update_item_delegate() + super(CheckComboBox, self).changeEvent(event) + + def showPopup(self): + """Reimplemented.""" + super(CheckComboBox, self).showPopup() + view = self.view() + view.installEventFilter(self) + view.viewport().installEventFilter(self) + self._popup_is_shown = True + + def hidePopup(self): + """Reimplemented.""" + self.view().removeEventFilter(self) + self.view().viewport().removeEventFilter(self) + self._popup_is_shown = False + self._initial_mouse_pos = None + super(CheckComboBox, self).hidePopup() + self.view().clearFocus() + + def eventFilter(self, obj, event): + """Reimplemented.""" + if ( + self._popup_is_shown + and event.type() == QtCore.QEvent.MouseMove + and self.view().isVisible() + and self._initial_mouse_pos is not None + ): + diff = obj.mapToGlobal(event.pos()) - self._initial_mouse_pos + if ( + diff.manhattanLength() > 9 + and self._block_mouse_release_timer.isActive() + ): + self._block_mouse_release_timer.stop() + + current_index = self.view().currentIndex() + if ( + self._popup_is_shown + and event.type() == QtCore.QEvent.MouseButtonRelease + and self.view().isVisible() + and self.view().rect().contains(event.pos()) + and current_index.isValid() + and current_index.flags() & QtCore.Qt.ItemIsSelectable + and current_index.flags() & QtCore.Qt.ItemIsEnabled + and current_index.flags() & QtCore.Qt.ItemIsUserCheckable + and self.view().visualRect(current_index).contains(event.pos()) + and not self._block_mouse_release_timer.isActive() + ): + model = self.model() + index = self.view().currentIndex() + state = model.data(index, QtCore.Qt.CheckStateRole) + if state == QtCore.Qt.Unchecked: + check_state = QtCore.Qt.Checked + else: + check_state = QtCore.Qt.Unchecked + + model.setData(index, check_state, QtCore.Qt.CheckStateRole) + self.view().update(index) + self.update() + return True + + if self._popup_is_shown and event.type() == QtCore.QEvent.KeyPress: + if event.key() == QtCore.Qt.Key_Space: + # toogle the current items check state + model = self.model() + index = self.view().currentIndex() + flags = model.flags(index) + state = model.data(index, QtCore.Qt.CheckStateRole) + if flags & QtCore.Qt.ItemIsUserCheckable and \ + flags & QtCore.Qt.ItemIsTristate: + state = QtCore.Qt.CheckState((int(state) + 1) % 3) + elif flags & QtCore.Qt.ItemIsUserCheckable: + state = ( + QtCore.Qt.Checked + if state != QtCore.Qt.Checked + else QtCore.Qt.Unchecked + ) + model.setData(index, state, QtCore.Qt.CheckStateRole) + self.view().update(index) + self.update() + return True + # TODO: handle QtCore.Qt.Key_Enter, Key_Return? + + return super(CheckComboBox, self).eventFilter(obj, event) + + def paintEvent(self, event): + """Reimplemented.""" + painter = QtWidgets.QStylePainter(self) + option = QtWidgets.QStyleOptionComboBox() + self.initStyleOption(option) + painter.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, option) + # draw the icon and text + items = self.checked_items_text() + if not items: + option.currentText = self._placeholder_text + option.palette.setCurrentColorGroup(QtGui.QPalette.Disabled) + painter.drawControl(QtWidgets.QStyle.CE_ComboBoxLabel, option) + return + + # body_rect = QtCore.QRectF(option.rect) + + side_padding = 3 + item_spacing = 5 + font_metricts = self.fontMetrics() + left_x = option.rect.left() + 2 + for item in items: + rect = font_metricts.boundingRect(item) + rect.moveTop(option.rect.y()) + + label_height = rect.height() + + rect.moveLeft(left_x) + rect.setHeight(option.rect.height()) + + bg_rect = QtCore.QRect(rect) + bg_rect.setWidth(rect.width() + (2 * side_padding)) + left_x = bg_rect.right() + item_spacing + + rect.moveLeft(rect.x() + side_padding) + + remainder_half = (option.rect.height() - label_height) / 2 + remainder_quarter = int(remainder_half / 2) + 1 + bg_rect.setHeight(label_height + remainder_half) + bg_rect.moveTop(bg_rect.top() + remainder_quarter) + + path = QtGui.QPainterPath() + path.addRoundedRect(bg_rect, 5, 5) + + painter.fillPath(path, QtGui.QColor("#38d39f")) + + painter.drawText( + rect, + QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, + item + ) + option.currentText = self._separator.join(items) + # option.currentIcon = QtGui.QIcon() + + def setItemCheckState(self, index, state): + self.setItemData(index, state, QtCore.Qt.CheckStateRole) + + def checked_items_text(self): + items = list() + for idx in range(self.count()): + state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + if state == QtCore.Qt.Checked: + items.append(self.itemText(idx)) + return items + + def wheelEvent(self, event): + event.ignore() + + def keyPressEvent(self, event): + if ( + event.key() == QtCore.Qt.Key_Down + and event.modifiers() & QtCore.Qt.AltModifier + ): + self.showPopup() + return + + if event.key() in self.ignored_keys: + event.ignore() + return + + return super(CheckComboBox, self).keyPressEvent(event) + + def _update_item_delegate(self): + opt = QtWidgets.QStyleOptionComboBox() + opt.initFrom(self) + if self.style().styleHint( + QtWidgets.QStyle.SH_ComboBox_Popup, opt, self + ): + delegate = ComboMenuDelegate(self) + else: + delegate = ComboItemDelegate(self) + self.setItemDelegate(delegate) From 0ce16680044b8f17f6c3229ed95cd6a69e72d979 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 13:10:09 +0200 Subject: [PATCH 006/176] implemented basic combobox with custom modifications --- .../settings/settings/widgets/widgets.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 2a1f5fe804..616e605a35 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -25,6 +25,28 @@ class NumberSpinBox(QtWidgets.QDoubleSpinBox): return output +class ComboBox(QtWidgets.QComboBox): + value_changed = QtCore.Signal() + + def __init__(self, *args, **kwargs): + super(ComboBox, self).__init__(*args, **kwargs) + + self.currentIndexChanged.connect(self._on_change) + + def _on_change(self, *args, **kwargs): + self.value_changed.emit() + + def set_value(self, value): + for idx in range(self.count()): + _value = self.itemData(idx, role=QtCore.Qt.UserRole) + if _value == value: + self.setCurrentIndex(idx) + break + + def value(self): + return self.itemData(self.currentIndex(), role=QtCore.Qt.UserRole) + + class PathInput(QtWidgets.QLineEdit): def clear_end_path(self): value = self.text().strip() From 8aefe456ae4c97d543d11d77c4680ddacfd0716c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 13:10:30 +0200 Subject: [PATCH 007/176] multiselectio ncheckbox has methods for getting and setting value --- .../widgets/multiselection_combobox.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index d77de9f0e3..98e6048cce 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -121,6 +121,7 @@ class ComboMenuDelegate(QtWidgets.QAbstractItemDelegate): class CheckComboBox(QtWidgets.QComboBox): + value_changed = QtCore.Signal() ignored_keys = { QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, @@ -131,7 +132,7 @@ class CheckComboBox(QtWidgets.QComboBox): } def __init__( - self, parent=None, placeholder_text="", separator=", ", **kwargs + self, parent=None, placeholder="", separator=", ", **kwargs ): super(CheckComboBox, self).__init__(parent=parent, **kwargs) self.setFocusPolicy(QtCore.Qt.StrongFocus) @@ -141,7 +142,7 @@ class CheckComboBox(QtWidgets.QComboBox): self._block_mouse_release_timer = QtCore.QTimer(self, singleShot=True) self._initial_mouse_pos = None self._separator = separator - self._placeholder_text = placeholder_text + self._placeholder_text = placeholder self._update_item_delegate() def mousePressEvent(self, event): @@ -216,6 +217,7 @@ class CheckComboBox(QtWidgets.QComboBox): model.setData(index, check_state, QtCore.Qt.CheckStateRole) self.view().update(index) self.update() + self.value_changed.emit() return True if self._popup_is_shown and event.type() == QtCore.QEvent.KeyPress: @@ -298,6 +300,26 @@ class CheckComboBox(QtWidgets.QComboBox): def setItemCheckState(self, index, state): self.setItemData(index, state, QtCore.Qt.CheckStateRole) + def set_value(self, values): + for idx in range(self.count()): + value = self.itemData(idx, role=QtCore.Qt.UserRole) + state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + if value in values: + check_state = QtCore.Qt.Checked + else: + check_state = QtCore.Qt.Unchecked + self.setItemData(idx, check_state, QtCore.Qt.CheckStateRole) + + def value(self): + items = list() + for idx in range(self.count()): + state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) + if state == QtCore.Qt.Checked: + items.append( + self.itemData(idx, role=QtCore.Qt.UserRole) + ) + return items + def checked_items_text(self): items = list() for idx in range(self.count()): From b700de57ddb5993ae91cc920ff09559b9f776ba3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 13:10:49 +0200 Subject: [PATCH 008/176] implemented enumerator item --- .../settings/settings/widgets/item_types.py | 106 +++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e589b89c0f..634b14ab0e 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -6,8 +6,10 @@ from .widgets import ( ExpandingWidget, NumberSpinBox, PathInput, - GridLabelWidget + GridLabelWidget, + ComboBox ) +from .multiselection_combobox import CheckComboBox from .lib import NOT_SET, METADATA_KEY, TypeToKlass, CHILD_OFFSET from avalon.vendor import qtawesome @@ -827,6 +829,107 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): return self.checkbox.isChecked() +class EnumeratorWidget(QtWidgets.QWidget, InputObject): + default_input_value = True + value_changed = QtCore.Signal(object) + + def __init__( + self, input_data, parent, + as_widget=False, label_widget=None, parent_widget=None + ): + if parent_widget is None: + parent_widget = parent + super(EnumeratorWidget, self).__init__(parent_widget) + + self.initial_attributes(input_data, parent, as_widget) + self.multiselection = input_data.get("multiselection") + self.enum_items = input_data["enum_items"] + if not self.enum_items: + raise ValueError( + "Attribute `enum_items` is not defined." + ) + + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(5) + + if not self._as_widget: + self.key = input_data["key"] + if not label_widget: + label = input_data["label"] + label_widget = QtWidgets.QLabel(label) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(label_widget, 0) + self.label_widget = label_widget + + if self.multiselection: + placeholder = input_data.get("placeholder") + self.input_field = CheckComboBox( + placeholder=placeholder, parent=self + ) + else: + self.input_field = ComboBox(self) + + first_value = None + for enum_item in self.enum_items: + for value, label in enum_item.items(): + if first_value is None: + first_value = value + self.input_field.addItem(label, value) + + self._first_value = first_value + + layout.addWidget(self.input_field, 0) + + self.setFocusProxy(self.input_field) + + self.input_field.value_changed.connect(self._on_value_change) + + @property + def default_input_value(self): + if self.multiselection: + return [] + return self._first_value + + def set_value(self, value): + # Ignore value change because if `self.isChecked()` has same + # value as `value` the `_on_value_change` is not triggered + self.input_field.set_value(value) + + def update_style(self): + if self._as_widget: + if not self.isEnabled(): + state = self.style_state(False, False, False, False) + else: + state = self.style_state( + False, + self._is_invalid, + False, + self._is_modified + ) + else: + state = self.style_state( + self.has_studio_override, + self.is_invalid, + self.is_overriden, + self.is_modified + ) + if self._state == state: + return + + if self._as_widget: + property_name = "input-state" + else: + property_name = "state" + + self.label_widget.setProperty(property_name, state) + self.label_widget.style().polish(self.label_widget) + self._state = state + + def item_value(self): + return self.input_field.value() + + class NumberWidget(QtWidgets.QWidget, InputObject): default_input_value = 0 value_changed = QtCore.Signal(object) @@ -3494,6 +3597,7 @@ TypeToKlass.types["path-input"] = PathInputWidget TypeToKlass.types["raw-json"] = RawJsonWidget TypeToKlass.types["list"] = ListWidget TypeToKlass.types["list-strict"] = ListStrictWidget +TypeToKlass.types["enum"] = EnumeratorWidget TypeToKlass.types["dict-modifiable"] = ModifiableDict # DEPRECATED - remove when removed from schemas TypeToKlass.types["dict-item"] = DictWidget From 4954a3dba0f9d793f5fb319e84aa39894da6147e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:04:15 +0200 Subject: [PATCH 009/176] fix checkables in multiselection --- pype/tools/settings/settings/widgets/item_types.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 634b14ab0e..274aeff86a 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -877,6 +877,11 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): first_value = value self.input_field.addItem(label, value) + if self.multiselection: + model = self.input_field.model() + for idx in range(self.input_field.count()): + model.item(idx).setCheckable(True) + self._first_value = first_value layout.addWidget(self.input_field, 0) From 918ff9eefa91b814d4f0312010738568e7745653 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:04:36 +0200 Subject: [PATCH 010/176] changed bg_rect to QRectF --- .../settings/settings/widgets/multiselection_combobox.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 98e6048cce..029f577032 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -273,7 +273,7 @@ class CheckComboBox(QtWidgets.QComboBox): rect.moveLeft(left_x) rect.setHeight(option.rect.height()) - bg_rect = QtCore.QRect(rect) + bg_rect = QtCore.QRectF(rect) bg_rect.setWidth(rect.width() + (2 * side_padding)) left_x = bg_rect.right() + item_spacing @@ -287,7 +287,7 @@ class CheckComboBox(QtWidgets.QComboBox): path = QtGui.QPainterPath() path.addRoundedRect(bg_rect, 5, 5) - painter.fillPath(path, QtGui.QColor("#38d39f")) + painter.fillPath(path, QtGui.QColor("#555555")) painter.drawText( rect, From f6f75c6fb33a6880a5e6b68b171f4d86ad4cf42f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:04:49 +0200 Subject: [PATCH 011/176] added enum to examples --- .../gui_schemas/system_schema/1_examples.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json index 0578968508..00aef304a9 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json @@ -9,6 +9,25 @@ "type": "dict-invisible", "children": [ { + "type": "enum", + "key": "test_enum_singleselection", + "label": "Enum Single Selection", + "enum_items": [ + {"value_1": "Label 1"}, + {"value_2": "Label 2"}, + {"value_3": "Label 3"} + ] + }, { + "type": "enum", + "key": "test_enum_multiselection", + "label": "Enum Multi Selection", + "multiselection": true, + "enum_items": [ + {"value_1": "Label 1"}, + {"value_2": "Label 2"}, + {"value_3": "Label 3"} + ] + }, { "type": "boolean", "key": "bool", "label": "Boolean checkbox" From d5c0fa464ae7b0fdc61367e8b14719aa972a589a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:05:36 +0200 Subject: [PATCH 012/176] removed debug prints --- pype/modules_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/modules_manager.py b/pype/modules_manager.py index 073b153f08..4b337c075b 100644 --- a/pype/modules_manager.py +++ b/pype/modules_manager.py @@ -43,7 +43,6 @@ class PypeModuleManager: modules.append( __import__(import_name, fromlist=[""]) ) - print(import_name, sys.modules.get("PyQt5")) except Exception: self.log.warning( From 4db75b45e5c26dac46ddbf75a11676adee5d9c44 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:06:43 +0200 Subject: [PATCH 013/176] PypeModule inherit from abstract class --- pype/modules/base.py | 3 ++- pype/modules_manager.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/modules/base.py b/pype/modules/base.py index 2d97bc5e14..ede2f41bd5 100644 --- a/pype/modules/base.py +++ b/pype/modules/base.py @@ -1,8 +1,9 @@ from uuid import uuid4 +from abc import ABC from pype.api import Logger -class PypeModule: +class PypeModule(ABC): """Base class of pype module.""" enabled = False name = None diff --git a/pype/modules_manager.py b/pype/modules_manager.py index 4b337c075b..6538187ea9 100644 --- a/pype/modules_manager.py +++ b/pype/modules_manager.py @@ -1,5 +1,4 @@ import os -import sys import inspect import pype.modules From 6e49beb9c38e5e20d81333c4f8d62339935b2853 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 14:56:44 +0200 Subject: [PATCH 014/176] added style for combobox --- pype/tools/settings/settings/style/style.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pype/tools/settings/settings/style/style.css b/pype/tools/settings/settings/style/style.css index 3f648abef8..c4fce7aa90 100644 --- a/pype/tools/settings/settings/style/style.css +++ b/pype/tools/settings/settings/style/style.css @@ -38,6 +38,14 @@ QLineEdit:disabled, QSpinBox:disabled, QDoubleSpinBox:disabled, QPlainTextEdit:d QLineEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QPlainTextEdit:focus, QTextEdit:focus { border: 1px solid #ffffff; } + +QComboBox { + border: 1px solid #aaaaaa; + border-radius: 3px; + padding: 2px 2px 4px 4px; + background: #1d272f; +} + QToolButton { background: transparent; } From b4080ebbe23855a943f3b61ba9ae24deabe307bc Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 22 Sep 2020 16:12:25 +0200 Subject: [PATCH 015/176] docstrings and abstract method --- pype/modules/__init__.py | 1 + pype/modules/base.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pype/modules/__init__.py b/pype/modules/__init__.py index 32b7426ba5..aacd541e18 100644 --- a/pype/modules/__init__.py +++ b/pype/modules/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from .base import PypeModule __all__ = ( diff --git a/pype/modules/base.py b/pype/modules/base.py index ede2f41bd5..ee90aa4cbb 100644 --- a/pype/modules/base.py +++ b/pype/modules/base.py @@ -1,10 +1,19 @@ +# -*- coding: utf-8 -*- +"""Base class for Pype Modules.""" from uuid import uuid4 -from abc import ABC +from abc import ABC, abstractmethod from pype.api import Logger class PypeModule(ABC): - """Base class of pype module.""" + """Base class of pype module. + + Attributes: + id (UUID): Module id. + enabled (bool): Is module enabled. + name (str): Module name. + """ + enabled = False name = None _id = None @@ -23,5 +32,7 @@ class PypeModule(ABC): def id(self): return self._id + @abstractmethod def startup_environments(self): + """Get startup environments for module.""" return {} From 4b70f708566bc1a06ef6295ced0e3e4783266fff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 16:35:48 +0200 Subject: [PATCH 016/176] multiselection combobox expand size by its items --- .../widgets/multiselection_combobox.py | 140 +++++++++++++----- 1 file changed, 104 insertions(+), 36 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 029f577032..30b0c89d28 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -131,6 +131,13 @@ class CheckComboBox(QtWidgets.QComboBox): QtCore.Qt.Key_End } + padding = 2 + left_offset = 2 + h_margins = 2 + item_spacing = 5 + + item_bg_color = QtGui.QColor("#555555") + def __init__( self, parent=None, placeholder="", separator=", ", **kwargs ): @@ -142,9 +149,16 @@ class CheckComboBox(QtWidgets.QComboBox): self._block_mouse_release_timer = QtCore.QTimer(self, singleShot=True) self._initial_mouse_pos = None self._separator = separator - self._placeholder_text = placeholder + self.placeholder_text = placeholder self._update_item_delegate() + self.lines = {} + self.item_height = ( + self.fontMetrics().height() + + (2 * self.padding) + + (2 * self.h_margins) + ) + def mousePressEvent(self, event): """Reimplemented.""" self._popup_is_shown = False @@ -216,7 +230,7 @@ class CheckComboBox(QtWidgets.QComboBox): model.setData(index, check_state, QtCore.Qt.CheckStateRole) self.view().update(index) - self.update() + self.update_size_hint() self.value_changed.emit() return True @@ -250,52 +264,106 @@ class CheckComboBox(QtWidgets.QComboBox): option = QtWidgets.QStyleOptionComboBox() self.initStyleOption(option) painter.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, option) + # draw the icon and text items = self.checked_items_text() if not items: - option.currentText = self._placeholder_text + option.currentText = self.placeholder_text option.palette.setCurrentColorGroup(QtGui.QPalette.Disabled) painter.drawControl(QtWidgets.QStyle.CE_ComboBoxLabel, option) return - # body_rect = QtCore.QRectF(option.rect) - - side_padding = 3 - item_spacing = 5 font_metricts = self.fontMetrics() - left_x = option.rect.left() + 2 + for line, items in self.lines.items(): + top_y = option.rect.top() + (line * self.item_height) + left_x = option.rect.left() + self.left_offset + for item in items: + label_rect = font_metricts.boundingRect(item) + label_height = label_rect.height() + + label_rect.moveTop(top_y) + label_rect.moveLeft(left_x) + label_rect.setHeight(self.item_height) + + bg_rect = QtCore.QRectF(label_rect) + bg_rect.setWidth(label_rect.width() + (2 * self.padding)) + left_x = bg_rect.right() + self.item_spacing + + label_rect.moveLeft(label_rect.x() + self.padding) + + bg_rect.setHeight(label_height + (2 * self.padding)) + bg_rect.moveTop(bg_rect.top() + self.h_margins) + + path = QtGui.QPainterPath() + path.addRoundedRect(bg_rect, 5, 5) + + painter.fillPath(path, self.item_bg_color) + + painter.drawText( + label_rect, + QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, + item + ) + + def resizeEvent(self, *args, **kwargs): + super(CheckComboBox, self).resizeEvent(*args, **kwargs) + self.update_size_hint() + + def update_size_hint(self): + previous_lines = len(self.lines) + + self.lines = {} + + items = self.checked_items_text() + if not items: + self.update() + return + + option = QtWidgets.QStyleOptionComboBox() + self.initStyleOption(option) + btn_rect = self.style().subControlRect( + QtWidgets.QStyle.CC_ComboBox, + option, + QtWidgets.QStyle.SC_ComboBoxArrow + ) + total_width = self.width() - btn_rect.width() + font_metricts = self.fontMetrics() + + line = 0 + self.lines = {line: []} + + font_metricts = self.fontMetrics() + left_x = None for item in items: + if left_x is None: + left_x = 0 + self.left_offset rect = font_metricts.boundingRect(item) - rect.moveTop(option.rect.y()) + width = rect.width() + (2 * self.padding) + right_x = left_x + width + if right_x > total_width: + if self.lines.get(line): + line += 1 + left_x = None + self.lines[line] = [item] + else: + self.lines[line] = [item] + line += 1 + left_x = None + else: + self.lines[line].append(item) + left_x = left_x + width + self.item_spacing - label_height = rect.height() + self.update() + if len(self.lines) != previous_lines: + self.updateGeometry() - rect.moveLeft(left_x) - rect.setHeight(option.rect.height()) - - bg_rect = QtCore.QRectF(rect) - bg_rect.setWidth(rect.width() + (2 * side_padding)) - left_x = bg_rect.right() + item_spacing - - rect.moveLeft(rect.x() + side_padding) - - remainder_half = (option.rect.height() - label_height) / 2 - remainder_quarter = int(remainder_half / 2) + 1 - bg_rect.setHeight(label_height + remainder_half) - bg_rect.moveTop(bg_rect.top() + remainder_quarter) - - path = QtGui.QPainterPath() - path.addRoundedRect(bg_rect, 5, 5) - - painter.fillPath(path, QtGui.QColor("#555555")) - - painter.drawText( - rect, - QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, - item - ) - option.currentText = self._separator.join(items) - # option.currentIcon = QtGui.QIcon() + def sizeHint(self): + value = super(CheckComboBox, self).sizeHint() + lines = len(self.lines) + if lines == 0: + lines = 1 + value.setHeight(lines * self.item_height) + return value def setItemCheckState(self, index, state): self.setItemData(index, state, QtCore.Qt.CheckStateRole) From e779375b9b3e61d5d9e1810cdb7ca6f67d1d7f8b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 16:55:31 +0200 Subject: [PATCH 017/176] renamed CheckComboBox to MultiSelectionComboBox --- .../settings/settings/widgets/item_types.py | 4 ++-- .../widgets/multiselection_combobox.py | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 274aeff86a..33585773f9 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -9,7 +9,7 @@ from .widgets import ( GridLabelWidget, ComboBox ) -from .multiselection_combobox import CheckComboBox +from .multiselection_combobox import MultiSelectionComboBox from .lib import NOT_SET, METADATA_KEY, TypeToKlass, CHILD_OFFSET from avalon.vendor import qtawesome @@ -864,7 +864,7 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): if self.multiselection: placeholder = input_data.get("placeholder") - self.input_field = CheckComboBox( + self.input_field = MultiSelectionComboBox( placeholder=placeholder, parent=self ) else: diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 30b0c89d28..d49ebeb45a 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -120,7 +120,7 @@ class ComboMenuDelegate(QtWidgets.QAbstractItemDelegate): return menuoption -class CheckComboBox(QtWidgets.QComboBox): +class MultiSelectionComboBox(QtWidgets.QComboBox): value_changed = QtCore.Signal() ignored_keys = { QtCore.Qt.Key_Up, @@ -141,7 +141,7 @@ class CheckComboBox(QtWidgets.QComboBox): def __init__( self, parent=None, placeholder="", separator=", ", **kwargs ): - super(CheckComboBox, self).__init__(parent=parent, **kwargs) + super(MultiSelectionComboBox, self).__init__(parent=parent, **kwargs) self.setFocusPolicy(QtCore.Qt.StrongFocus) self._popup_is_shown = False @@ -162,7 +162,7 @@ class CheckComboBox(QtWidgets.QComboBox): def mousePressEvent(self, event): """Reimplemented.""" self._popup_is_shown = False - super(CheckComboBox, self).mousePressEvent(event) + super(MultiSelectionComboBox, self).mousePressEvent(event) if self._popup_is_shown: self._initial_mouse_pos = self.mapToGlobal(event.pos()) self._block_mouse_release_timer.start( @@ -173,11 +173,11 @@ class CheckComboBox(QtWidgets.QComboBox): """Reimplemented.""" if event.type() == QtCore.QEvent.StyleChange: self._update_item_delegate() - super(CheckComboBox, self).changeEvent(event) + super(MultiSelectionComboBox, self).changeEvent(event) def showPopup(self): """Reimplemented.""" - super(CheckComboBox, self).showPopup() + super(MultiSelectionComboBox, self).showPopup() view = self.view() view.installEventFilter(self) view.viewport().installEventFilter(self) @@ -189,7 +189,7 @@ class CheckComboBox(QtWidgets.QComboBox): self.view().viewport().removeEventFilter(self) self._popup_is_shown = False self._initial_mouse_pos = None - super(CheckComboBox, self).hidePopup() + super(MultiSelectionComboBox, self).hidePopup() self.view().clearFocus() def eventFilter(self, obj, event): @@ -256,7 +256,7 @@ class CheckComboBox(QtWidgets.QComboBox): return True # TODO: handle QtCore.Qt.Key_Enter, Key_Return? - return super(CheckComboBox, self).eventFilter(obj, event) + return super(MultiSelectionComboBox, self).eventFilter(obj, event) def paintEvent(self, event): """Reimplemented.""" @@ -306,7 +306,7 @@ class CheckComboBox(QtWidgets.QComboBox): ) def resizeEvent(self, *args, **kwargs): - super(CheckComboBox, self).resizeEvent(*args, **kwargs) + super(MultiSelectionComboBox, self).resizeEvent(*args, **kwargs) self.update_size_hint() def update_size_hint(self): @@ -358,7 +358,7 @@ class CheckComboBox(QtWidgets.QComboBox): self.updateGeometry() def sizeHint(self): - value = super(CheckComboBox, self).sizeHint() + value = super(MultiSelectionComboBox, self).sizeHint() lines = len(self.lines) if lines == 0: lines = 1 @@ -411,7 +411,7 @@ class CheckComboBox(QtWidgets.QComboBox): event.ignore() return - return super(CheckComboBox, self).keyPressEvent(event) + return super(MultiSelectionComboBox, self).keyPressEvent(event) def _update_item_delegate(self): opt = QtWidgets.QStyleOptionComboBox() From 13576aeedcf07646b72294cb9adcb75d73ca54f5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 16:58:52 +0200 Subject: [PATCH 018/176] added a little bit more atomicity to padding and margins --- .../widgets/multiselection_combobox.py | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index d49ebeb45a..d7179f07f0 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -131,9 +131,10 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): QtCore.Qt.Key_End } - padding = 2 + top_bottom_padding = 2 + left_right_padding = 3 left_offset = 2 - h_margins = 2 + top_bottom_margins = 2 item_spacing = 5 item_bg_color = QtGui.QColor("#555555") @@ -155,8 +156,8 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): self.lines = {} self.item_height = ( self.fontMetrics().height() - + (2 * self.padding) - + (2 * self.h_margins) + + (2 * self.top_bottom_padding) + + (2 * self.top_bottom_margins) ) def mousePressEvent(self, event): @@ -275,7 +276,11 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): font_metricts = self.fontMetrics() for line, items in self.lines.items(): - top_y = option.rect.top() + (line * self.item_height) + top_y = ( + option.rect.top() + + (line * self.item_height) + + self.top_bottom_margins + ) left_x = option.rect.left() + self.left_offset for item in items: label_rect = font_metricts.boundingRect(item) @@ -286,13 +291,16 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): label_rect.setHeight(self.item_height) bg_rect = QtCore.QRectF(label_rect) - bg_rect.setWidth(label_rect.width() + (2 * self.padding)) + bg_rect.setWidth( + label_rect.width() + + (2 * self.left_right_padding) + ) left_x = bg_rect.right() + self.item_spacing - label_rect.moveLeft(label_rect.x() + self.padding) + label_rect.moveLeft(label_rect.x() + self.left_right_padding) - bg_rect.setHeight(label_height + (2 * self.padding)) - bg_rect.moveTop(bg_rect.top() + self.h_margins) + bg_rect.setHeight(label_height + (2 * self.top_bottom_padding)) + bg_rect.moveTop(bg_rect.top() + self.top_bottom_margins) path = QtGui.QPainterPath() path.addRoundedRect(bg_rect, 5, 5) @@ -338,7 +346,7 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): if left_x is None: left_x = 0 + self.left_offset rect = font_metricts.boundingRect(item) - width = rect.width() + (2 * self.padding) + width = rect.width() + (2 * self.left_right_padding) right_x = left_x + width if right_x > total_width: if self.lines.get(line): @@ -362,7 +370,10 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): lines = len(self.lines) if lines == 0: lines = 1 - value.setHeight(lines * self.item_height) + value.setHeight( + (lines * self.item_height) + + (2 * self.top_bottom_margins) + ) return value def setItemCheckState(self, index, state): From 016ea3146bd55f2809173731371121fd5fc8aa5c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 16:59:08 +0200 Subject: [PATCH 019/176] added style for multiselection combobox --- pype/tools/settings/settings/style/style.css | 4 ++++ .../settings/settings/widgets/multiselection_combobox.py | 1 + 2 files changed, 5 insertions(+) diff --git a/pype/tools/settings/settings/style/style.css b/pype/tools/settings/settings/style/style.css index c4fce7aa90..796efa22a6 100644 --- a/pype/tools/settings/settings/style/style.css +++ b/pype/tools/settings/settings/style/style.css @@ -110,6 +110,10 @@ QPushButton[btn-type="expand-toggle"] { font-weight: bold; } +#MultiSelectionComboBox { + font-size: 12px; +} + #DictKey[state="studio"] {border-color: #bfccd6;} #DictKey[state="modified"] {border-color: #137cbd;} #DictKey[state="overriden"] {border-color: #00f;} diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index d7179f07f0..ddd4f65e65 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -143,6 +143,7 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): self, parent=None, placeholder="", separator=", ", **kwargs ): super(MultiSelectionComboBox, self).__init__(parent=parent, **kwargs) + self.setObjectName("MultiSelectionComboBox") self.setFocusPolicy(QtCore.Qt.StrongFocus) self._popup_is_shown = False From 1c1676f6f8924dcd826d2832ef0fdb41c446d7a7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 17:06:54 +0200 Subject: [PATCH 020/176] final touches --- .../settings/settings/widgets/multiselection_combobox.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index ddd4f65e65..b02d19f9c4 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -133,11 +133,11 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): top_bottom_padding = 2 left_right_padding = 3 - left_offset = 2 + left_offset = 4 top_bottom_margins = 2 item_spacing = 5 - item_bg_color = QtGui.QColor("#555555") + item_bg_color = QtGui.QColor("#31424e") def __init__( self, parent=None, placeholder="", separator=", ", **kwargs From 49ac226f30a6c99ad8dce87f5ac19190af6695c9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 17:32:21 +0200 Subject: [PATCH 021/176] line width is calculated right --- .../widgets/multiselection_combobox.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index b02d19f9c4..85dd538cd0 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -32,8 +32,9 @@ class ComboMenuDelegate(QtWidgets.QAbstractItemDelegate): style = option.widget.style() else: style = QtWidgets.QApplication.style() - style.drawControl(QtWidgets.QStyle.CE_MenuItem, menuopt, painter, - option.widget) + style.drawControl( + QtWidgets.QStyle.CE_MenuItem, menuopt, painter, option.widget + ) def sizeHint(self, option, index): menuopt = self._menu_style_option(option, index) @@ -335,36 +336,34 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): option, QtWidgets.QStyle.SC_ComboBoxArrow ) - total_width = self.width() - btn_rect.width() + total_width = option.rect.width() - btn_rect.width() font_metricts = self.fontMetrics() line = 0 self.lines = {line: []} font_metricts = self.fontMetrics() - left_x = None + default_left_x = 0 + self.left_offset + left_x = int(default_left_x) for item in items: - if left_x is None: - left_x = 0 + self.left_offset rect = font_metricts.boundingRect(item) width = rect.width() + (2 * self.left_right_padding) right_x = left_x + width if right_x > total_width: + left_x = int(default_left_x) if self.lines.get(line): line += 1 - left_x = None self.lines[line] = [item] + left_x += width else: self.lines[line] = [item] line += 1 - left_x = None else: self.lines[line].append(item) left_x = left_x + width + self.item_spacing self.update() - if len(self.lines) != previous_lines: - self.updateGeometry() + self.updateGeometry() def sizeHint(self): value = super(MultiSelectionComboBox, self).sizeHint() From 85e67b6ce25da02919ebc16b56323489fd6fef1d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 17:35:23 +0200 Subject: [PATCH 022/176] fix stretch --- pype/tools/settings/settings/widgets/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index ee4762de14..404d7b700b 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -266,7 +266,7 @@ class SystemWidget(QtWidgets.QWidget): klass = lib.TypeToKlass.types.get(item_type) item = klass(child_configuration, self) self.input_fields.append(item) - self.content_layout.addWidget(item) + self.content_layout.addWidget(item, 0) # Add spacer to stretch children guis spacer = QtWidgets.QWidget(self.content_widget) @@ -532,7 +532,7 @@ class ProjectWidget(QtWidgets.QWidget): klass = lib.TypeToKlass.types.get(item_type) item = klass(child_configuration, self) self.input_fields.append(item) - self.content_layout.addWidget(item) + self.content_layout.addWidget(item, 0) # Add spacer to stretch children guis spacer = QtWidgets.QWidget(self.content_widget) From 34d16bb0960789b4a3e994e25c490a698f04b8a6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:21:26 +0200 Subject: [PATCH 023/176] small cleanup --- pype/tools/settings/settings/style/style.css | 4 ++++ .../settings/settings/widgets/multiselection_combobox.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/style/style.css b/pype/tools/settings/settings/style/style.css index 796efa22a6..ebea87203d 100644 --- a/pype/tools/settings/settings/style/style.css +++ b/pype/tools/settings/settings/style/style.css @@ -46,6 +46,10 @@ QComboBox { background: #1d272f; } +QComboBox QAbstractItemView::item { + padding: 3px; +} + QToolButton { background: transparent; } diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 85dd538cd0..0c2d57aed8 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -148,7 +148,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): self.setFocusPolicy(QtCore.Qt.StrongFocus) self._popup_is_shown = False - # self.__supressPopupHide = False self._block_mouse_release_timer = QtCore.QTimer(self, singleShot=True) self._initial_mouse_pos = None self._separator = separator From 102a8ead4c0ddf95844cffce37d610d355947ec9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:30:55 +0200 Subject: [PATCH 024/176] added enumerator to ExtractReview --- .../projects_schema/1_plugins_gui_schema.json | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json index f357b51dc5..2fefe8df2d 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json @@ -202,8 +202,15 @@ }, { "key": "tags", "label": "Tags", - "type": "list", - "object_type": "text" + "type": "enum", + "multiselection": true, + "enum_items": [ + {"burnin": "Add burnins"}, + {"ftrackreview": "Add to Ftrack"}, + {"delete": "Delete output"}, + {"slate-frame": "Add slate frame"}, + {"no-hnadles": "Skip handle frames"} + ] }, { "key": "ffmpeg_args", "label": "FFmpeg arguments", From 223ed557520c3938162fe719f87abb88b41b15c2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:34:55 +0200 Subject: [PATCH 025/176] project override values are not propagated in right way if dict is used as widget --- pype/tools/settings/settings/widgets/item_types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e589b89c0f..c477a7986a 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2442,7 +2442,9 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self._state = None self._child_state = None - if not self.as_widget: + if self.as_widget: + override_values = parent_values + else: metadata = {} groups = tuple() override_values = NOT_SET From 5410bab315df471f5f68b161b8e3d1f9fcd77bd6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:40:32 +0200 Subject: [PATCH 026/176] added readme --- pype/tools/settings/settings/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pype/tools/settings/settings/README.md b/pype/tools/settings/settings/README.md index 47bbf28ba5..9492d8bc7b 100644 --- a/pype/tools/settings/settings/README.md +++ b/pype/tools/settings/settings/README.md @@ -168,6 +168,29 @@ } ``` +### enum +- returns value of single on multiple items from predefined values +- multiselection can be allowed with setting key `"multiselection"` to `True` (Default: `False`) +- values are defined under value of key `"enum_items"` as list + - each item in list is simple dictionary where value is label and key is value which will be stored + - should be possible to enter single dictionary if order of items doesn't matter + +``` +{ + "key": "tags", + "label": "Tags", + "type": "enum", + "multiselection": true, + "enum_items": [ + {"burnin": "Add burnins"}, + {"ftrackreview": "Add to Ftrack"}, + {"delete": "Delete output"}, + {"slate-frame": "Add slate frame"}, + {"no-hnadles": "Skip handle frames"} + ] +} +``` + ## Inputs for setting value using Pure inputs - these inputs also have required `"key"` and `"label"` - they use Pure inputs "as widgets" From 9ed5778b51e6df049a9c6d29213576244b695b0f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:46:13 +0200 Subject: [PATCH 027/176] removed unused variables --- .../tools/settings/settings/widgets/multiselection_combobox.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 0c2d57aed8..0106051cc4 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -319,8 +319,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): self.update_size_hint() def update_size_hint(self): - previous_lines = len(self.lines) - self.lines = {} items = self.checked_items_text() @@ -381,7 +379,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): def set_value(self, values): for idx in range(self.count()): value = self.itemData(idx, role=QtCore.Qt.UserRole) - state = self.itemData(idx, role=QtCore.Qt.CheckStateRole) if value in values: check_state = QtCore.Qt.Checked else: From 06dba918f7de483b710eeaab4e295bcf21c55c84 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:50:19 +0200 Subject: [PATCH 028/176] label is offset by two pixels down to fake nice view --- pype/tools/settings/settings/widgets/widgets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 2a1f5fe804..522f606baa 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -243,10 +243,11 @@ class GridLabelWidget(QtWidgets.QWidget): self.properties = {} layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) + layout.setContentsMargins(0, 2, 0, 0) layout.setSpacing(0) label_proxy = QtWidgets.QWidget(self) + label_proxy_layout = QtWidgets.QHBoxLayout(label_proxy) label_proxy_layout.setContentsMargins(0, 0, 0, 0) label_proxy_layout.setSpacing(0) From cc3d5bcc4165402d9c75c3bda6da8ef254b1aaa2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 22 Sep 2020 18:50:29 +0200 Subject: [PATCH 029/176] label and proxy widget are transparent now --- pype/tools/settings/settings/widgets/widgets.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 522f606baa..d6d28b3e43 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -266,6 +266,9 @@ class GridLabelWidget(QtWidgets.QWidget): layout.addWidget(label_proxy, 0) layout.addWidget(spacer_widget_v, 1) + label_proxy.setAttribute(QtCore.Qt.WA_TranslucentBackground) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + self.label_widget = label_widget def setProperty(self, name, value): From 3aaf4433274fd322aac1656feaec17620443b034 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:04:56 +0200 Subject: [PATCH 030/176] moved enumerator --- .../settings/settings/widgets/item_types.py | 212 +++++++++--------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 33585773f9..6e169b07b1 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -829,112 +829,6 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): return self.checkbox.isChecked() -class EnumeratorWidget(QtWidgets.QWidget, InputObject): - default_input_value = True - value_changed = QtCore.Signal(object) - - def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None - ): - if parent_widget is None: - parent_widget = parent - super(EnumeratorWidget, self).__init__(parent_widget) - - self.initial_attributes(input_data, parent, as_widget) - self.multiselection = input_data.get("multiselection") - self.enum_items = input_data["enum_items"] - if not self.enum_items: - raise ValueError( - "Attribute `enum_items` is not defined." - ) - - layout = QtWidgets.QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.setSpacing(5) - - if not self._as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - layout.addWidget(label_widget, 0) - self.label_widget = label_widget - - if self.multiselection: - placeholder = input_data.get("placeholder") - self.input_field = MultiSelectionComboBox( - placeholder=placeholder, parent=self - ) - else: - self.input_field = ComboBox(self) - - first_value = None - for enum_item in self.enum_items: - for value, label in enum_item.items(): - if first_value is None: - first_value = value - self.input_field.addItem(label, value) - - if self.multiselection: - model = self.input_field.model() - for idx in range(self.input_field.count()): - model.item(idx).setCheckable(True) - - self._first_value = first_value - - layout.addWidget(self.input_field, 0) - - self.setFocusProxy(self.input_field) - - self.input_field.value_changed.connect(self._on_value_change) - - @property - def default_input_value(self): - if self.multiselection: - return [] - return self._first_value - - def set_value(self, value): - # Ignore value change because if `self.isChecked()` has same - # value as `value` the `_on_value_change` is not triggered - self.input_field.set_value(value) - - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) - if self._state == state: - return - - if self._as_widget: - property_name = "input-state" - else: - property_name = "state" - - self.label_widget.setProperty(property_name, state) - self.label_widget.style().polish(self.label_widget) - self._state = state - - def item_value(self): - return self.input_field.value() - - class NumberWidget(QtWidgets.QWidget, InputObject): default_input_value = 0 value_changed = QtCore.Signal(object) @@ -1180,6 +1074,112 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): return self.path_input.text() +class EnumeratorWidget(QtWidgets.QWidget, InputObject): + default_input_value = True + value_changed = QtCore.Signal(object) + + def __init__( + self, input_data, parent, + as_widget=False, label_widget=None, parent_widget=None + ): + if parent_widget is None: + parent_widget = parent + super(EnumeratorWidget, self).__init__(parent_widget) + + self.initial_attributes(input_data, parent, as_widget) + self.multiselection = input_data.get("multiselection") + self.enum_items = input_data["enum_items"] + if not self.enum_items: + raise ValueError( + "Attribute `enum_items` is not defined." + ) + + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(5) + + if not self._as_widget: + self.key = input_data["key"] + if not label_widget: + label = input_data["label"] + label_widget = QtWidgets.QLabel(label) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(label_widget, 0) + self.label_widget = label_widget + + if self.multiselection: + placeholder = input_data.get("placeholder") + self.input_field = MultiSelectionComboBox( + placeholder=placeholder, parent=self + ) + else: + self.input_field = ComboBox(self) + + first_value = None + for enum_item in self.enum_items: + for value, label in enum_item.items(): + if first_value is None: + first_value = value + self.input_field.addItem(label, value) + + if self.multiselection: + model = self.input_field.model() + for idx in range(self.input_field.count()): + model.item(idx).setCheckable(True) + + self._first_value = first_value + + layout.addWidget(self.input_field, 0) + + self.setFocusProxy(self.input_field) + + self.input_field.value_changed.connect(self._on_value_change) + + @property + def default_input_value(self): + if self.multiselection: + return [] + return self._first_value + + def set_value(self, value): + # Ignore value change because if `self.isChecked()` has same + # value as `value` the `_on_value_change` is not triggered + self.input_field.set_value(value) + + def update_style(self): + if self._as_widget: + if not self.isEnabled(): + state = self.style_state(False, False, False, False) + else: + state = self.style_state( + False, + self._is_invalid, + False, + self._is_modified + ) + else: + state = self.style_state( + self.has_studio_override, + self.is_invalid, + self.is_overriden, + self.is_modified + ) + if self._state == state: + return + + if self._as_widget: + property_name = "input-state" + else: + property_name = "state" + + self.label_widget.setProperty(property_name, state) + self.label_widget.style().polish(self.label_widget) + self._state = state + + def item_value(self): + return self.input_field.value() + + class RawJsonInput(QtWidgets.QPlainTextEdit): tab_length = 4 From dfaa62ef952758d51076fec4ff142bf8d9018bd2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:19:35 +0200 Subject: [PATCH 031/176] enum has better style changes --- .../settings/settings/widgets/item_types.py | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 6e169b07b1..647ec96c58 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1090,9 +1090,7 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): self.multiselection = input_data.get("multiselection") self.enum_items = input_data["enum_items"] if not self.enum_items: - raise ValueError( - "Attribute `enum_items` is not defined." - ) + raise ValueError("Attribute `enum_items` is not defined.") layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) @@ -1105,7 +1103,7 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): label_widget = QtWidgets.QLabel(label) label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) layout.addWidget(label_widget, 0) - self.label_widget = label_widget + self.label_widget = label_widget if self.multiselection: placeholder = input_data.get("placeholder") @@ -1121,14 +1119,13 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): if first_value is None: first_value = value self.input_field.addItem(label, value) + self._first_value = first_value if self.multiselection: model = self.input_field.model() for idx in range(self.input_field.count()): model.item(idx).setCheckable(True) - self._first_value = first_value - layout.addWidget(self.input_field, 0) self.setFocusProxy(self.input_field) @@ -1147,16 +1144,13 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): self.input_field.set_value(value) def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) + if self.as_widget: + state = self.style_state( + False, + self._is_invalid, + False, + self._is_modified + ) else: state = self.style_state( self.has_studio_override, @@ -1164,17 +1158,16 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): self.is_overriden, self.is_modified ) + if self._state == state: return - if self._as_widget: - property_name = "input-state" - else: - property_name = "state" - - self.label_widget.setProperty(property_name, state) - self.label_widget.style().polish(self.label_widget) self._state = state + self.input_field.setProperty("input-state", state) + self.input_field.style().polish(self.input_field) + if self.label_widget: + self.label_widget.setProperty("state", state) + self.label_widget.style().polish(self.label_widget) def item_value(self): return self.input_field.value() From 83c0010320c63045f5129d34cc6ce871e3786f71 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:22:26 +0200 Subject: [PATCH 032/176] removed ComboMenuDelegate as not used --- .../widgets/multiselection_combobox.py | 122 +----------------- 1 file changed, 2 insertions(+), 120 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 0106051cc4..9e5bc815b4 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -19,108 +19,6 @@ class ComboItemDelegate(QtWidgets.QStyledItemDelegate): super(ComboItemDelegate, self).paint(painter, option, index) -class ComboMenuDelegate(QtWidgets.QAbstractItemDelegate): - """ - Helper styled delegate (mostly based on existing private Qt's - delegate used by the QtWidgets.QComboBox). Used to style the popup like a - menu. (e.g osx aqua style). - """ - - def paint(self, painter, option, index): - menuopt = self._menu_style_option(option, index) - if option.widget is not None: - style = option.widget.style() - else: - style = QtWidgets.QApplication.style() - style.drawControl( - QtWidgets.QStyle.CE_MenuItem, menuopt, painter, option.widget - ) - - def sizeHint(self, option, index): - menuopt = self._menu_style_option(option, index) - if option.widget is not None: - style = option.widget.style() - else: - style = QtWidgets.QApplication.style() - return style.sizeFromContents( - QtWidgets.QStyle.CT_MenuItem, menuopt, menuopt.rect.size(), - option.widget - ) - - def _menu_style_option(self, option, index): - menuoption = QtWidgets.QStyleOptionMenuItem() - if option.widget: - palette_source = option.widget.palette("QMenu") - else: - palette_source = QtWidgets.QApplication.palette("QMenu") - - palette = option.palette.resolve(palette_source) - foreground = index.data(QtCore.Qt.ForegroundRole) - if isinstance(foreground, (QtGui.QBrush, QtGui.QColor, QtGui.QPixmap)): - foreground = QtGui.QBrush(foreground) - palette.setBrush(QtGui.QPalette.Text, foreground) - palette.setBrush(QtGui.QPalette.ButtonText, foreground) - palette.setBrush(QtGui.QPalette.WindowText, foreground) - - background = index.data(QtCore.Qt.BackgroundRole) - if isinstance(background, (QtGui.QBrush, QtGui.QColor, QtGui.QPixmap)): - background = QtGui.QBrush(background) - palette.setBrush(QtGui.QPalette.Background, background) - - menuoption.palette = palette - - decoration = index.data(QtCore.Qt.DecorationRole) - if isinstance(decoration, QtGui.QIcon): - menuoption.icon = decoration - - menuoption.menuItemType = QtWidgets.QStyleOptionMenuItem.Normal - - if index.flags() & QtCore.Qt.ItemIsUserCheckable: - menuoption.checkType = QtWidgets.QStyleOptionMenuItem.NonExclusive - else: - menuoption.checkType = QtWidgets.QStyleOptionMenuItem.NotCheckable - - check = index.data(QtCore.Qt.CheckStateRole) - menuoption.checked = check == QtCore.Qt.Checked - - if option.widget is not None: - menuoption.font = option.widget.font() - else: - menuoption.font = QtWidgets.QApplication.font("QMenu") - - menuoption.maxIconWidth = option.decorationSize.width() + 4 - menuoption.rect = option.rect - menuoption.menuRect = option.rect - - # menuoption.menuHasCheckableItems = True - menuoption.tabWidth = 0 - # TODO: self.displayText(QVariant, QLocale) - # TODO: Why is this not a QtWidgets.QStyledItemDelegate? - menuoption.text = str(index.data(QtCore.Qt.DisplayRole)) - - menuoption.fontMetrics = QtGui.QFontMetrics(menuoption.font) - state = option.state & ( - QtWidgets.QStyle.State_MouseOver - | QtWidgets.QStyle.State_Selected - | QtWidgets.QStyle.State_Active - ) - - if index.flags() & QtCore.Qt.ItemIsEnabled: - state = state | QtWidgets.QStyle.State_Enabled - menuoption.palette.setCurrentColorGroup(QtGui.QPalette.Active) - else: - state = state & ~QtWidgets.QStyle.State_Enabled - menuoption.palette.setCurrentColorGroup(QtGui.QPalette.Disabled) - - if menuoption.checked: - state = state | QtWidgets.QStyle.State_On - else: - state = state | QtWidgets.QStyle.State_Off - - menuoption.state = state - return menuoption - - class MultiSelectionComboBox(QtWidgets.QComboBox): value_changed = QtCore.Signal() ignored_keys = { @@ -152,7 +50,8 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): self._initial_mouse_pos = None self._separator = separator self.placeholder_text = placeholder - self._update_item_delegate() + self.delegate = ComboItemDelegate(self) + self.setItemDelegate(self.delegate) self.lines = {} self.item_height = ( @@ -171,12 +70,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): QtWidgets.QApplication.doubleClickInterval() ) - def changeEvent(self, event): - """Reimplemented.""" - if event.type() == QtCore.QEvent.StyleChange: - self._update_item_delegate() - super(MultiSelectionComboBox, self).changeEvent(event) - def showPopup(self): """Reimplemented.""" super(MultiSelectionComboBox, self).showPopup() @@ -419,14 +312,3 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): return return super(MultiSelectionComboBox, self).keyPressEvent(event) - - def _update_item_delegate(self): - opt = QtWidgets.QStyleOptionComboBox() - opt.initFrom(self) - if self.style().styleHint( - QtWidgets.QStyle.SH_ComboBox_Popup, opt, self - ): - delegate = ComboMenuDelegate(self) - else: - delegate = ComboItemDelegate(self) - self.setItemDelegate(delegate) From ddd1637bd345f0135b6781a27d0c690b9a65689e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:46:35 +0200 Subject: [PATCH 033/176] reorganized eventFilter --- .../widgets/multiselection_combobox.py | 116 +++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 9e5bc815b4..2c4c910770 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -87,69 +87,73 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): super(MultiSelectionComboBox, self).hidePopup() self.view().clearFocus() - def eventFilter(self, obj, event): - """Reimplemented.""" - if ( - self._popup_is_shown - and event.type() == QtCore.QEvent.MouseMove - and self.view().isVisible() - and self._initial_mouse_pos is not None - ): - diff = obj.mapToGlobal(event.pos()) - self._initial_mouse_pos - if ( - diff.manhattanLength() > 9 - and self._block_mouse_release_timer.isActive() - ): - self._block_mouse_release_timer.stop() + def _event_popup_shown(self, obj, event): + if not self._popup_is_shown: + return current_index = self.view().currentIndex() - if ( - self._popup_is_shown - and event.type() == QtCore.QEvent.MouseButtonRelease - and self.view().isVisible() - and self.view().rect().contains(event.pos()) - and current_index.isValid() - and current_index.flags() & QtCore.Qt.ItemIsSelectable - and current_index.flags() & QtCore.Qt.ItemIsEnabled - and current_index.flags() & QtCore.Qt.ItemIsUserCheckable - and self.view().visualRect(current_index).contains(event.pos()) - and not self._block_mouse_release_timer.isActive() - ): - model = self.model() - index = self.view().currentIndex() - state = model.data(index, QtCore.Qt.CheckStateRole) - if state == QtCore.Qt.Unchecked: - check_state = QtCore.Qt.Checked - else: - check_state = QtCore.Qt.Unchecked + model = self.model() - model.setData(index, check_state, QtCore.Qt.CheckStateRole) - self.view().update(index) + if event.type() == QtCore.QEvent.MouseMove: + if ( + self.view().isVisible() + and self._initial_mouse_pos is not None + and self._block_mouse_release_timer.isActive() + ): + diff = obj.mapToGlobal(event.pos()) - self._initial_mouse_pos + if diff.manhattanLength() > 9: + self._block_mouse_release_timer.stop() + return + + index_flags = current_index.flags() + state = current_index.data(QtCore.Qt.CheckStateRole) + new_state = None + + if event.type() == QtCore.QEvent.MouseButtonRelease: + if ( + self._block_mouse_release_timer.isActive() + or not current_index.isValid() + or not self.view().isVisible() + or not self.view().rect().contains(event.pos()) + or not index_flags & QtCore.Qt.ItemIsSelectable + or not index_flags & QtCore.Qt.ItemIsEnabled + or not index_flags & QtCore.Qt.ItemIsUserCheckable + ): + return + + if state == QtCore.Qt.Unchecked: + new_state = QtCore.Qt.Checked + else: + new_state = QtCore.Qt.Unchecked + + elif event.type() == QtCore.QEvent.KeyPress: + # TODO: handle QtCore.Qt.Key_Enter, Key_Return? + if event.key() == QtCore.Qt.Key_Space: + # toogle the current items check state + if ( + index_flags & QtCore.Qt.ItemIsUserCheckable + and index_flags & QtCore.Qt.ItemIsTristate + ): + new_state = QtCore.Qt.CheckState((int(state) + 1) % 3) + + elif index_flags & QtCore.Qt.ItemIsUserCheckable: + if state != QtCore.Qt.Checked: + new_state = QtCore.Qt.Checked + else: + new_state = QtCore.Qt.Unchecked + + if new_state is not None: + model.setData(current_index, new_state, QtCore.Qt.CheckStateRole) + self.view().update(current_index) self.update_size_hint() self.value_changed.emit() return True - if self._popup_is_shown and event.type() == QtCore.QEvent.KeyPress: - if event.key() == QtCore.Qt.Key_Space: - # toogle the current items check state - model = self.model() - index = self.view().currentIndex() - flags = model.flags(index) - state = model.data(index, QtCore.Qt.CheckStateRole) - if flags & QtCore.Qt.ItemIsUserCheckable and \ - flags & QtCore.Qt.ItemIsTristate: - state = QtCore.Qt.CheckState((int(state) + 1) % 3) - elif flags & QtCore.Qt.ItemIsUserCheckable: - state = ( - QtCore.Qt.Checked - if state != QtCore.Qt.Checked - else QtCore.Qt.Unchecked - ) - model.setData(index, state, QtCore.Qt.CheckStateRole) - self.view().update(index) - self.update() - return True - # TODO: handle QtCore.Qt.Key_Enter, Key_Return? + def eventFilter(self, obj, event): + """Reimplemented.""" + result = self._event_popup_shown(obj, event) + if result is not None: + return result return super(MultiSelectionComboBox, self).eventFilter(obj, event) From 028b754f59bd5c2175153f74a7b6a1427b920e3b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:47:49 +0200 Subject: [PATCH 034/176] fixed set_value method for discard changes etc. --- pype/tools/settings/settings/widgets/multiselection_combobox.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 2c4c910770..159b2d16dc 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -281,6 +281,7 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): else: check_state = QtCore.Qt.Unchecked self.setItemData(idx, check_state, QtCore.Qt.CheckStateRole) + self.update_size_hint() def value(self): items = list() From b2cd99cbcca73fb926983b3f6f333c2cd9bb517e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:50:46 +0200 Subject: [PATCH 035/176] skip setting item as checkable for multiselection input --- pype/tools/settings/settings/widgets/item_types.py | 5 ----- .../settings/settings/widgets/multiselection_combobox.py | 7 ++----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 647ec96c58..e495cfc8aa 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1121,11 +1121,6 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): self.input_field.addItem(label, value) self._first_value = first_value - if self.multiselection: - model = self.input_field.model() - for idx in range(self.input_field.count()): - model.item(idx).setCheckable(True) - layout.addWidget(self.input_field, 0) self.setFocusProxy(self.input_field) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 159b2d16dc..17750f909e 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -117,7 +117,6 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): or not self.view().rect().contains(event.pos()) or not index_flags & QtCore.Qt.ItemIsSelectable or not index_flags & QtCore.Qt.ItemIsEnabled - or not index_flags & QtCore.Qt.ItemIsUserCheckable ): return @@ -309,11 +308,9 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): event.key() == QtCore.Qt.Key_Down and event.modifiers() & QtCore.Qt.AltModifier ): - self.showPopup() - return + return self.showPopup() if event.key() in self.ignored_keys: - event.ignore() - return + return event.ignore() return super(MultiSelectionComboBox, self).keyPressEvent(event) From ba785f748bfa580a5cd44343b589e8c3b62bdbde Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 10:53:18 +0200 Subject: [PATCH 036/176] made None as valid value --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e495cfc8aa..9ddfa5acab 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1113,10 +1113,10 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): else: self.input_field = ComboBox(self) - first_value = None + first_value = NOT_SET for enum_item in self.enum_items: for value, label in enum_item.items(): - if first_value is None: + if first_value is NOT_SET: first_value = value self.input_field.addItem(label, value) self._first_value = first_value From 614234f2f6a0bad9682fb08a65d4af67e42579ae Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 11:33:17 +0200 Subject: [PATCH 037/176] all items has attribute `label_widget` which may be set to None --- .../settings/settings/widgets/item_types.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e589b89c0f..468ef6e1b0 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -775,7 +775,7 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): label_widget = QtWidgets.QLabel(label) label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) layout.addWidget(label_widget, 0) - self.label_widget = label_widget + self.label_widget = label_widget self.checkbox = QtWidgets.QCheckBox(self) spacer = QtWidgets.QWidget(self) @@ -861,7 +861,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): label = input_data["label"] label_widget = QtWidgets.QLabel(label) layout.addWidget(label_widget, 0) - self.label_widget = label_widget + self.label_widget = label_widget layout.addWidget(self.input_field, 1) @@ -946,7 +946,7 @@ class TextWidget(QtWidgets.QWidget, InputObject): label = input_data["label"] label_widget = QtWidgets.QLabel(label) layout.addWidget(label_widget, 0, **layout_kwargs) - self.label_widget = label_widget + self.label_widget = label_widget layout.addWidget(self.text_input, 1, **layout_kwargs) @@ -1021,7 +1021,7 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): label = input_data["label"] label_widget = QtWidgets.QLabel(label) layout.addWidget(label_widget, 0) - self.label_widget = label_widget + self.label_widget = label_widget self.path_input = PathInput(self) self.setFocusProxy(self.path_input) @@ -1156,8 +1156,9 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): label = input_data["label"] label_widget = QtWidgets.QLabel(label) layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) - self.label_widget = label_widget - layout.addWidget(self.text_input, 1, alignment=QtCore.Qt.AlignTop) + self.label_widget = label_widget + + layout.addWidget(self.input_field, 1, alignment=QtCore.Qt.AlignTop) self.text_input.textChanged.connect(self._on_value_change) @@ -2014,6 +2015,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): if as_widget: body_widget = None + self.label_widget = label_widget else: body_widget = ExpandingWidget(input_data["label"], self) main_layout.addWidget(body_widget) @@ -2903,7 +2905,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): label_widget = QtWidgets.QLabel(label) label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) - self.label_widget = label_widget + self.label_widget = label_widget self.content_widget = QtWidgets.QWidget(self) self.content_layout = QtWidgets.QVBoxLayout(self.content_widget) From 733c64831743d01fa94ae595b8385f238a241784 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 11:33:54 +0200 Subject: [PATCH 038/176] implemented `update_style` for all input objects the same --- .../settings/settings/widgets/item_types.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 468ef6e1b0..40b2035e25 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -681,6 +681,36 @@ class InputObject(SettingObject): def hierarchical_style_update(self): self.update_style() + def _style_state(self): + if self.as_widget: + state = self.style_state( + False, + self._is_invalid, + False, + self._is_modified + ) + else: + state = self.style_state( + self.has_studio_override, + self.is_invalid, + self.is_overriden, + self.is_modified + ) + return state + + def update_style(self): + state = self._style_state() + if self._state == state: + return + + self._state = state + + self.input_field.setProperty("input-state", state) + self.input_field.style().polish(self.input_field) + if self.label_widget: + self.label_widget.setProperty("state", state) + self.label_widget.style().polish(self.label_widget) + def remove_overrides(self): self._is_overriden = False self._is_modified = False From a3b6c5c027a9fdadcdf9e4bde5ba3907d3d354f5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 11:35:37 +0200 Subject: [PATCH 039/176] removed `update_style` from most of inputs --- .../settings/settings/widgets/item_types.py | 155 ------------------ 1 file changed, 155 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 40b2035e25..308c2ef65c 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -823,35 +823,6 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): # value as `value` the `_on_value_change` is not triggered self.checkbox.setChecked(value) - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) - if self._state == state: - return - - if self._as_widget: - property_name = "input-state" - else: - property_name = "state" - - self.label_widget.setProperty(property_name, state) - self.label_widget.style().polish(self.label_widget) - self._state = state def item_value(self): return self.checkbox.isChecked() @@ -900,37 +871,6 @@ class NumberWidget(QtWidgets.QWidget, InputObject): def set_value(self, value): self.input_field.setValue(value) - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) - if self._state == state: - return - - if self._as_widget: - property_name = "input-state" - widget = self.input_field - else: - property_name = "state" - widget = self.label_widget - - widget.setProperty(property_name, state) - widget.style().polish(widget) - def item_value(self): return self.input_field.value() @@ -988,37 +928,6 @@ class TextWidget(QtWidgets.QWidget, InputObject): else: self.text_input.setText(value) - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.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): if self.multiline: @@ -1066,38 +975,6 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): self.path_input.clear_end_path() super(PathInput, self).focusOutEvent(event) - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) - - if self._state == state: - return - - if self._as_widget: - property_name = "input-state" - widget = self.path_input - else: - property_name = "state" - widget = self.label_widget - - widget.setProperty(property_name, state) - widget.style().polish(widget) - def item_value(self): return self.path_input.text() @@ -1203,38 +1080,6 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): self._is_invalid = self.text_input.has_invalid_value() return super(RawJsonWidget, self)._on_value_change(*args, **kwargs) - def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.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): if self.is_invalid: return NOT_SET From 19138839428d4bb929fff45237df342596314782 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 11:36:27 +0200 Subject: [PATCH 040/176] all inputs object has attribute `input_field` --- .../settings/settings/widgets/item_types.py | 70 +++++++++---------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 308c2ef65c..289690250f 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -798,7 +798,7 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self._as_widget: + if not self.as_widget: self.key = input_data["key"] if not label_widget: label = input_data["label"] @@ -807,25 +807,24 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): layout.addWidget(label_widget, 0) self.label_widget = label_widget - self.checkbox = QtWidgets.QCheckBox(self) + self.input_field = QtWidgets.QCheckBox(self) spacer = QtWidgets.QWidget(self) - layout.addWidget(self.checkbox, 0) - layout.addWidget(spacer, 1) - spacer.setAttribute(QtCore.Qt.WA_TranslucentBackground) - self.setFocusProxy(self.checkbox) + layout.addWidget(self.input_field, 0) + layout.addWidget(spacer, 1) - self.checkbox.stateChanged.connect(self._on_value_change) + self.setFocusProxy(self.input_field) + + self.input_field.stateChanged.connect(self._on_value_change) def set_value(self, value): # Ignore value change because if `self.isChecked()` has same # value as `value` the `_on_value_change` is not triggered - self.checkbox.setChecked(value) - + self.input_field.setChecked(value) def item_value(self): - return self.checkbox.isChecked() + return self.input_field.isChecked() class NumberWidget(QtWidgets.QWidget, InputObject): @@ -897,14 +896,14 @@ class TextWidget(QtWidgets.QWidget, InputObject): layout.setSpacing(5) if self.multiline: - self.text_input = QtWidgets.QPlainTextEdit(self) + self.input_field = QtWidgets.QPlainTextEdit(self) else: - self.text_input = QtWidgets.QLineEdit(self) + self.input_field = QtWidgets.QLineEdit(self) if placeholder: - self.text_input.setPlaceholderText(placeholder) + self.input_field.setPlaceholderText(placeholder) - self.setFocusProxy(self.text_input) + self.setFocusProxy(self.input_field) layout_kwargs = {} if self.multiline: @@ -918,22 +917,21 @@ class TextWidget(QtWidgets.QWidget, InputObject): layout.addWidget(label_widget, 0, **layout_kwargs) self.label_widget = label_widget - layout.addWidget(self.text_input, 1, **layout_kwargs) + layout.addWidget(self.input_field, 1, **layout_kwargs) - self.text_input.textChanged.connect(self._on_value_change) + self.input_field.textChanged.connect(self._on_value_change) def set_value(self, value): if self.multiline: - self.text_input.setPlainText(value) + self.input_field.setPlainText(value) else: - self.text_input.setText(value) - + self.input_field.setText(value) def item_value(self): if self.multiline: - return self.text_input.toPlainText() + return self.input_field.toPlainText() else: - return self.text_input.text() + return self.input_field.text() class PathInputWidget(QtWidgets.QWidget, InputObject): @@ -962,21 +960,21 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): layout.addWidget(label_widget, 0) self.label_widget = label_widget - self.path_input = PathInput(self) - self.setFocusProxy(self.path_input) - layout.addWidget(self.path_input, 1) + self.input_field = PathInput(self) + self.setFocusProxy(self.input_field) + layout.addWidget(self.input_field, 1) - self.path_input.textChanged.connect(self._on_value_change) + self.input_field.textChanged.connect(self._on_value_change) def set_value(self, value): - self.path_input.setText(value) + self.input_field.setText(value) def focusOutEvent(self, event): - self.path_input.clear_end_path() + self.input_field.clear_end_path() super(PathInput, self).focusOutEvent(event) def item_value(self): - return self.path_input.text() + return self.input_field.text() class RawJsonInput(QtWidgets.QPlainTextEdit): @@ -1049,15 +1047,15 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - self.text_input = RawJsonInput(self) - self.text_input.setSizePolicy( + self.input_field = RawJsonInput(self) + self.input_field.setSizePolicy( QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding ) - self.setFocusProxy(self.text_input) + self.setFocusProxy(self.input_field) - if not self._as_widget: + if not self.as_widget: self.key = input_data["key"] if not label_widget: label = input_data["label"] @@ -1067,17 +1065,17 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): layout.addWidget(self.input_field, 1, alignment=QtCore.Qt.AlignTop) - self.text_input.textChanged.connect(self._on_value_change) + self.input_field.textChanged.connect(self._on_value_change) def update_studio_values(self, parent_values): - self._is_invalid = self.text_input.has_invalid_value() + self._is_invalid = self.input_field.has_invalid_value() return super(RawJsonWidget, self).update_studio_values(parent_values) def set_value(self, value): - self.text_input.set_value(value) + self.input_field.set_value(value) def _on_value_change(self, *args, **kwargs): - self._is_invalid = self.text_input.has_invalid_value() + self._is_invalid = self.input_field.has_invalid_value() return super(RawJsonWidget, self)._on_value_change(*args, **kwargs) def item_value(self): From eadf08f0bbcd6981877d2afa203a80d151039a0d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 11:36:59 +0200 Subject: [PATCH 041/176] updated methed `update_style` for inputs where it is more complex --- .../settings/settings/widgets/item_types.py | 97 ++++++------------- 1 file changed, 29 insertions(+), 68 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 289690250f..e262960655 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1469,29 +1469,16 @@ class ListWidget(QtWidgets.QWidget, InputObject): self.update_style() def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) + if not self.label_widget: + return + + state = self._style_state() if self._state == state: return - if self.label_widget: - self.label_widget.setProperty("state", state) - self.label_widget.style().polish(self.label_widget) + self._state = state + self.label_widget.setProperty("state", state) + self.label_widget.style().polish(self.label_widget) def item_value(self): output = [] @@ -1648,30 +1635,17 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): self.update_style() def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self._is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) + if not self.label_widget: + return + + state = self._style_state() if self._state == state: return - if self.label_widget: - self.label_widget.setProperty("state", state) - self.label_widget.style().polish(self.label_widget) + self._state = state + self.label_widget.setProperty("state", state) + self.label_widget.style().polish(self.label_widget) def item_value(self): output = [] @@ -1990,42 +1964,29 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.update_style() def update_style(self): - if self._as_widget: - if not self.isEnabled(): - state = self.style_state(False, False, False, False) - else: - state = self.style_state( - False, - self.is_invalid, - False, - self._is_modified - ) - else: - state = self.style_state( - self.has_studio_override, - self.is_invalid, - self.is_overriden, - self.is_modified - ) + state = self._style_state() + if self._state == state: return + self._state = state + + if self.label_widget: + self.label_widget.setProperty("state", state) + self.label_widget.style().polish(self.label_widget) + + if not self.body_widget: + return + if state: child_state = "child-{}".format(state) else: child_state = "" - if self.body_widget: - self.body_widget.side_line_widget.setProperty("state", child_state) - self.body_widget.side_line_widget.style().polish( - self.body_widget.side_line_widget - ) - - if not self._as_widget: - self.label_widget.setProperty("state", state) - self.label_widget.style().polish(self.label_widget) - - self._state = state + self.body_widget.side_line_widget.setProperty("state", child_state) + self.body_widget.side_line_widget.style().polish( + self.body_widget.side_line_widget + ) def all_item_values(self): output = {} From 1c8709b07559fb8d7da45863d4c2d4ce2892a200 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:30:53 +0200 Subject: [PATCH 042/176] implemented basic value type validations to not crash gui when different type is loaded from settings --- .../settings/settings/widgets/item_types.py | 117 ++++++++++++++++-- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e589b89c0f..58263175cc 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1,5 +1,4 @@ import json -import logging import collections from Qt import QtWidgets, QtCore, QtGui from .widgets import ( @@ -9,9 +8,28 @@ from .widgets import ( GridLabelWidget ) from .lib import NOT_SET, METADATA_KEY, TypeToKlass, CHILD_OFFSET +from pype.api import Logger from avalon.vendor import qtawesome +class InvalidValueType(Exception): + msg_template = "{}" + + def __init__(self, valid_types, invalid_type, key): + msg = "" + if key: + msg += "Key \"{}\". ".format(key) + + joined_types = ", ".join( + [str(valid_type) for valid_type in valid_types] + ) + msg += "Got invalid type \"{}\". Expected: {}".format( + invalid_type, joined_types + ) + self.msg = msg + super(InvalidValueType, self).__init__(msg) + + class SettingObject: """Partially abstract class for Setting's item type workflow.""" # `is_input_type` attribute says if has implemented item type methods @@ -27,6 +45,19 @@ class SettingObject: value_changed = None # Item will expand to full width in grid layout expand_in_grid = False + # types that are valid for `set_value` method + valid_value_types = tuple() + + def validate_value(self, value): + if not self.valid_value_types: + return + + for valid_type in self.valid_value_types: + if isinstance(value, valid_type): + return + + key = getattr(self, "key", None) + raise InvalidValueType(self.valid_value_types, type(value), key) def _set_default_attributes(self): """Create and reset attributes required for all item types. @@ -109,7 +140,7 @@ class SettingObject: def log(self): """Auto created logger for debugging.""" if self._log is None: - self._log = logging.getLogger(self.__class__.__name__) + self._log = Logger().get_logger(self.__class__.__name__) return self._log @property @@ -564,7 +595,7 @@ class InputObject(SettingObject): self._is_modified = False value = NOT_SET - if self._as_widget: + if self.as_widget: value = parent_values elif parent_values is not NOT_SET: value = parent_values.get(self.key, NOT_SET) @@ -589,7 +620,10 @@ class InputObject(SettingObject): self.default_value = value self._has_studio_override = False self._had_studio_override = False - self.set_value(value) + try: + self.set_value(value) + except InvalidValueType as exc: + self.log.warning(exc.msg) def update_studio_values(self, parent_values): self._state = None @@ -605,12 +639,17 @@ class InputObject(SettingObject): if value is not NOT_SET: self._has_studio_override = True self._had_studio_override = True - self.set_value(value) else: self._has_studio_override = False self._had_studio_override = False - self.set_value(self.default_value) + value = self.default_value + + try: + self.set_value(value) + except InvalidValueType as exc: + self.studio_value = NOT_SET + self.log.warning(exc.msg) def apply_overrides(self, parent_values): self._is_modified = False @@ -637,7 +676,11 @@ class InputObject(SettingObject): self._was_overriden = True value = override_value - self.set_value(value) + try: + self.set_value(value) + except InvalidValueType as exc: + self.override_value = NOT_SET + self.log.warning(exc.msg) def _on_value_change(self, item=None): if self.ignore_value_changes: @@ -753,6 +796,7 @@ class InputObject(SettingObject): class BooleanWidget(QtWidgets.QWidget, InputObject): default_input_value = True value_changed = QtCore.Signal(object) + valid_value_types = (bool, ) def __init__( self, input_data, parent, @@ -791,6 +835,7 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): def set_value(self, value): # Ignore value change because if `self.isChecked()` has same # value as `value` the `_on_value_change` is not triggered + self.validate_value(value) self.checkbox.setChecked(value) def update_style(self): @@ -831,6 +876,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): default_input_value = 0 value_changed = QtCore.Signal(object) input_modifiers = ("minimum", "maximum", "decimal") + valid_value_types = (int, float) def __init__( self, input_data, parent, @@ -868,6 +914,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): self.input_field.valueChanged.connect(self._on_value_change) def set_value(self, value): + self.validate_value(value) self.input_field.setValue(value) def update_style(self): @@ -908,6 +955,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): class TextWidget(QtWidgets.QWidget, InputObject): default_input_value = "" value_changed = QtCore.Signal(object) + valid_value_types = (int, str) def __init__( self, input_data, parent, @@ -953,6 +1001,7 @@ class TextWidget(QtWidgets.QWidget, InputObject): self.text_input.textChanged.connect(self._on_value_change) def set_value(self, value): + self.validate_value(value) if self.multiline: self.text_input.setPlainText(value) else: @@ -1000,6 +1049,7 @@ class TextWidget(QtWidgets.QWidget, InputObject): class PathInputWidget(QtWidgets.QWidget, InputObject): default_input_value = "" value_changed = QtCore.Signal(object) + valid_value_types = (str, ) def __init__( self, input_data, parent, @@ -1030,6 +1080,7 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): self.path_input.textChanged.connect(self._on_value_change) def set_value(self, value): + self.validate_value(value) self.path_input.setText(value) def focusOutEvent(self, event): @@ -1102,6 +1153,7 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): def set_value(self, value): if value is NOT_SET: value = "" + elif not isinstance(value, str): try: value = json.dumps(value, indent=4) @@ -1127,6 +1179,7 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): class RawJsonWidget(QtWidgets.QWidget, InputObject): default_input_value = "{}" value_changed = QtCore.Signal(object) + valid_value_types = (str, dict, list, type(NOT_SET)) def __init__( self, input_data, parent, @@ -1166,6 +1219,7 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): return super(RawJsonWidget, self).update_studio_values(parent_values) def set_value(self, value): + self.validate_value(value) self.text_input.set_value(value) def _on_value_change(self, *args, **kwargs): @@ -1395,6 +1449,7 @@ class ListItem(QtWidgets.QWidget, SettingObject): class ListWidget(QtWidgets.QWidget, InputObject): default_input_value = [] value_changed = QtCore.Signal(object) + valid_value_types = (list, ) def __init__( self, input_data, parent, @@ -1446,6 +1501,8 @@ class ListWidget(QtWidgets.QWidget, InputObject): self.hierarchical_style_update() def set_value(self, value): + self.validate_value(value) + previous_inputs = tuple(self.input_fields) for item_value in value: self.add_row(value=item_value) @@ -1631,6 +1688,7 @@ class ListWidget(QtWidgets.QWidget, InputObject): class ListStrictWidget(QtWidgets.QWidget, InputObject): value_changed = QtCore.Signal(object) _default_input_value = None + valid_value_types = (list, ) def __init__( self, input_data, parent, @@ -1750,6 +1808,8 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): return self._default_input_value def set_value(self, value): + self.validate_value(value) + if self._is_overriden: method_name = "apply_overrides" elif not self._has_studio_override: @@ -1985,6 +2045,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): # TODO this is actually input field (do not care if is group or not) value_changed = QtCore.Signal(object) expand_in_grid = True + valid_value_types = (dict, ) def __init__( self, input_data, parent, @@ -2061,6 +2122,8 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): return len(self.input_fields) def set_value(self, value): + self.validate_value(value) + previous_inputs = tuple(self.input_fields) for item_key, item_value in value.items(): self.add_row(key=item_key, value=item_value) @@ -2236,6 +2299,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): class DictWidget(QtWidgets.QWidget, SettingObject): value_changed = QtCore.Signal(object) expand_in_grid = True + valid_value_types = (dict, type(NOT_SET)) def __init__( self, input_data, parent, @@ -2414,6 +2478,12 @@ class DictWidget(QtWidgets.QWidget, SettingObject): elif parent_values is not NOT_SET: value = parent_values.get(self.key, NOT_SET) + try: + self.validate_value(value) + except InvalidValueType as exc: + value = NOT_SET + self.log.warning(exc.msg) + for item in self.input_fields: item.update_default_values(value) @@ -2434,6 +2504,14 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self._had_studio_override = bool(self._has_studio_override) + try: + self.validate_value(value) + except InvalidValueType as exc: + value = NOT_SET + self._has_studio_override = False + self._had_studio_override = False + self.log.warning(exc.msg) + for item in self.input_fields: item.update_studio_values(value) @@ -2453,6 +2531,12 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self._is_overriden = self.key in groups + try: + self.validate_value(override_values) + except InvalidValueType as exc: + override_values = NOT_SET + self.log.warning(exc.msg) + for item in self.input_fields: item.apply_overrides(override_values) @@ -2618,6 +2702,7 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): value_changed = QtCore.Signal(object) allow_actions = False expand_in_grid = True + valid_value_types = (dict, type(NOT_SET)) def __init__( self, input_data, parent, @@ -2788,6 +2873,12 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): elif parent_values is not NOT_SET: value = parent_values.get(self.key, NOT_SET) + try: + self.validate_value(value) + except InvalidValueType as exc: + value = NOT_SET + self.log.warning(exc.msg) + for item in self.input_fields: item.update_default_values(value) @@ -2796,6 +2887,12 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): if parent_values is not NOT_SET: value = parent_values.get(self.key, NOT_SET) + try: + self.validate_value(value) + except InvalidValueType as exc: + value = NOT_SET + self.log.warning(exc.msg) + for item in self.input_fields: item.update_studio_values(value) @@ -2814,6 +2911,12 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): self._is_overriden = self.key in groups + try: + self.validate_value(override_values) + except InvalidValueType as exc: + override_values = NOT_SET + self.log.warning(exc.msg) + for item in self.input_fields: item.apply_overrides(override_values) From 8f959eb73844e54e8a9a1eb470a97b21adaa4722 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:45:14 +0200 Subject: [PATCH 043/176] expandable widget can have widget before and after label now --- .../settings/settings/widgets/widgets.py | 68 +++++++------------ 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 2a1f5fe804..355c297e5e 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -71,33 +71,51 @@ class ExpandingWidget(QtWidgets.QWidget): top_part = ClickableWidget(parent=self) + side_line_widget = QtWidgets.QWidget(top_part) + side_line_widget.setObjectName("SideLineWidget") + button_size = QtCore.QSize(5, 5) - button_toggle = QtWidgets.QToolButton(parent=top_part) + button_toggle = QtWidgets.QToolButton(parent=side_line_widget) button_toggle.setProperty("btn-type", "expand-toggle") button_toggle.setIconSize(button_size) button_toggle.setArrowType(QtCore.Qt.RightArrow) button_toggle.setCheckable(True) button_toggle.setChecked(False) - label_widget = QtWidgets.QLabel(label, parent=top_part) + label_widget = QtWidgets.QLabel(label, parent=side_line_widget) label_widget.setObjectName("DictLabel") - side_line_widget = QtWidgets.QWidget(top_part) - side_line_widget.setObjectName("SideLineWidget") + before_label_widget = QtWidgets.QWidget(side_line_widget) + before_label_layout = QtWidgets.QVBoxLayout(before_label_widget) + before_label_layout.setContentsMargins(0, 0, 0, 0) + + after_label_widget = QtWidgets.QWidget(side_line_widget) + after_label_layout = QtWidgets.QVBoxLayout(after_label_widget) + after_label_layout.setContentsMargins(0, 0, 0, 0) + + spacer_widget = QtWidgets.QWidget(side_line_widget) + side_line_layout = QtWidgets.QHBoxLayout(side_line_widget) side_line_layout.setContentsMargins(5, 10, 0, 10) side_line_layout.addWidget(button_toggle) + side_line_layout.addWidget(before_label_widget) side_line_layout.addWidget(label_widget) + side_line_layout.addWidget(after_label_widget) + side_line_layout.addWidget(spacer_widget, 1) top_part_layout = QtWidgets.QHBoxLayout(top_part) top_part_layout.setContentsMargins(0, 0, 0, 0) top_part_layout.addWidget(side_line_widget) + before_label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + after_label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + spacer_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.top_part_ending = None - self.after_label_layout = None - self.end_of_layout = None + self.after_label_layout = after_label_layout + self.before_label_layout = before_label_layout self.side_line_widget = side_line_widget self.side_line_layout = side_line_layout @@ -146,45 +164,11 @@ class ExpandingWidget(QtWidgets.QWidget): self.parent().updateGeometry() def add_widget_after_label(self, widget): - self._add_side_widget_subwidgets() self.after_label_layout.addWidget(widget) - def _add_side_widget_subwidgets(self): - if self.top_part_ending is not None: - return + def add_widget_before_label(self, widget): + self.before_label_layout.addWidget(widget) - top_part_ending = QtWidgets.QWidget(self.side_line_widget) - top_part_ending.setAttribute(QtCore.Qt.WA_TranslucentBackground) - - top_part_ending_layout = QtWidgets.QHBoxLayout(top_part_ending) - top_part_ending_layout.setContentsMargins(0, 0, 0, 0) - top_part_ending_layout.setSpacing(0) - top_part_ending_layout.setAlignment(QtCore.Qt.AlignVCenter) - - after_label_widget = QtWidgets.QWidget(top_part_ending) - spacer_item = QtWidgets.QWidget(top_part_ending) - end_of_widget = QtWidgets.QWidget(top_part_ending) - - self.after_label_layout = QtWidgets.QVBoxLayout(after_label_widget) - self.after_label_layout.setContentsMargins(0, 0, 0, 0) - - self.end_of_layout = QtWidgets.QVBoxLayout(end_of_widget) - self.end_of_layout.setContentsMargins(0, 0, 0, 0) - - spacer_layout = QtWidgets.QVBoxLayout(spacer_item) - spacer_layout.setContentsMargins(0, 0, 0, 0) - - top_part_ending_layout.addWidget(after_label_widget, 0) - top_part_ending_layout.addWidget(spacer_item, 1) - top_part_ending_layout.addWidget(end_of_widget, 0) - - top_part_ending.setAttribute(QtCore.Qt.WA_TranslucentBackground) - after_label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - spacer_item.setAttribute(QtCore.Qt.WA_TranslucentBackground) - end_of_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - - self.top_part_ending = top_part_ending - self.side_line_layout.addWidget(top_part_ending) def resizeEvent(self, event): super(ExpandingWidget, self).resizeEvent(event) From 86ed514b5a34451c39eb80eaf07cbf0a2a476a31 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:45:26 +0200 Subject: [PATCH 044/176] dict item adds checkbox before label instead of after --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e589b89c0f..60208cedaf 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2360,7 +2360,7 @@ class DictWidget(QtWidgets.QWidget, SettingObject): ) item.value_changed.connect(self._on_value_change) - self.body_widget.add_widget_after_label(item) + self.body_widget.add_widget_before_label(item) self.checkbox_widget = item self.input_fields.append(item) return item From 89b99479afbe35b7a644cf66de08c46f19e3fd68 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:46:29 +0200 Subject: [PATCH 045/176] formatting fix --- pype/tools/settings/settings/widgets/widgets.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 355c297e5e..cab50bc7b9 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -169,7 +169,6 @@ class ExpandingWidget(QtWidgets.QWidget): def add_widget_before_label(self, widget): self.before_label_layout.addWidget(widget) - def resizeEvent(self, event): super(ExpandingWidget, self).resizeEvent(event) self.content_widget.updateGeometry() From 145b34425581758649dfa7fa0ab1f6e2e0d1e373 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:49:34 +0200 Subject: [PATCH 046/176] added validation of type for checkbox_key --- pype/tools/settings/settings/widgets/item_types.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 60208cedaf..58520d9d24 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2333,7 +2333,13 @@ class DictWidget(QtWidgets.QWidget, SettingObject): if self.checkbox_key and not self.checkbox_widget: key = child_configuration.get("key") if key == self.checkbox_key: - return self._add_checkbox_child(child_configuration) + if child_configuration["type"] != "boolean": + self.log.warning(( + "SCHEMA BUG: Dictionary item has set as checkbox" + " item invalid type \"{}\". Expected \"boolean\"." + ).format(child_configuration["type"])) + else: + return self._add_checkbox_child(child_configuration) label_widget = None if not klass.expand_in_grid: From c2d9a66b8cff8321a1de68a36e560f2db636d4f0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 12:59:06 +0200 Subject: [PATCH 047/176] fix default checkboxes in multiselection --- pype/tools/settings/settings/widgets/item_types.py | 5 +++++ .../settings/settings/widgets/multiselection_combobox.py | 1 + 2 files changed, 6 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 9ddfa5acab..dc6cde2407 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1121,6 +1121,11 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): self.input_field.addItem(label, value) self._first_value = first_value + if self.multiselection: + model = self.input_field.model() + for idx in range(self.input_field.count()): + model.item(idx).setCheckable(True) + layout.addWidget(self.input_field, 0) self.setFocusProxy(self.input_field) diff --git a/pype/tools/settings/settings/widgets/multiselection_combobox.py b/pype/tools/settings/settings/widgets/multiselection_combobox.py index 17750f909e..9a99561ea8 100644 --- a/pype/tools/settings/settings/widgets/multiselection_combobox.py +++ b/pype/tools/settings/settings/widgets/multiselection_combobox.py @@ -117,6 +117,7 @@ class MultiSelectionComboBox(QtWidgets.QComboBox): or not self.view().rect().contains(event.pos()) or not index_flags & QtCore.Qt.ItemIsSelectable or not index_flags & QtCore.Qt.ItemIsEnabled + or not index_flags & QtCore.Qt.ItemIsUserCheckable ): return From 2c360a99c7642376ce95551c29f8bd8427157f64 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 15:18:00 +0200 Subject: [PATCH 048/176] invalid default value is also marked as bad and modified --- pype/tools/settings/settings/widgets/item_types.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 58263175cc..2ad18001b7 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -623,6 +623,8 @@ class InputObject(SettingObject): try: self.set_value(value) except InvalidValueType as exc: + self.default_value = NOT_SET + self.defaults_not_set = True self.log.warning(exc.msg) def update_studio_values(self, parent_values): @@ -2530,6 +2532,8 @@ class DictWidget(QtWidgets.QWidget, SettingObject): override_values = parent_values.get(self.key, override_values) self._is_overriden = self.key in groups + else: + override_values = parent_values try: self.validate_value(override_values) @@ -2868,7 +2872,7 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): def update_default_values(self, parent_values): value = NOT_SET - if self._as_widget: + if self.as_widget: value = parent_values elif parent_values is not NOT_SET: value = parent_values.get(self.key, NOT_SET) From d91f67a799a4faf8a8251047242d37aafa19e414 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:47:57 +0200 Subject: [PATCH 049/176] ListItem and ModifiableDictItem expect one argument less --- pype/tools/settings/settings/widgets/item_types.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 0419c48c5c..406565c950 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1190,8 +1190,7 @@ class ListItem(QtWidgets.QWidget, SettingObject): value_changed = QtCore.Signal(object) def __init__( - self, object_type, input_modifiers, config_parent, parent, - is_strict=False + self, item_schema, config_parent, parent, is_strict=False ): super(ListItem, self).__init__(parent) @@ -1243,9 +1242,9 @@ class ListItem(QtWidgets.QWidget, SettingObject): layout.addWidget(self.add_btn, 0) layout.addWidget(self.remove_btn, 0) - ItemKlass = TypeToKlass.types[object_type] + ItemKlass = TypeToKlass.types[item_schema["type"]] self.value_input = ItemKlass( - input_modifiers, + item_schema, self, as_widget=True, label_widget=None @@ -1759,7 +1758,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): _btn_size = 20 value_changed = QtCore.Signal(object) - def __init__(self, object_type, input_modifiers, config_parent, parent): + def __init__(self, item_schema, config_parent, parent): super(ModifiableDictItem, self).__init__(parent) self._set_default_attributes() @@ -1779,13 +1778,13 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(3) - ItemKlass = TypeToKlass.types[object_type] + ItemKlass = TypeToKlass.types[item_schema["type"]] self.key_input = QtWidgets.QLineEdit(self) self.key_input.setObjectName("DictKey") self.value_input = ItemKlass( - input_modifiers, + item_schema, self, as_widget=True, label_widget=None From ddc1042d6cf3d1f33a923f67167212b23d5c3a07 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:48:09 +0200 Subject: [PATCH 050/176] use pype logger inside --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 406565c950..6f092b4bd8 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1,5 +1,4 @@ import json -import logging import collections from Qt import QtWidgets, QtCore, QtGui from .widgets import ( @@ -11,6 +10,7 @@ from .widgets import ( ) from .multiselection_combobox import MultiSelectionComboBox from .lib import NOT_SET, METADATA_KEY, TypeToKlass, CHILD_OFFSET +from pype.api import Logger from avalon.vendor import qtawesome @@ -111,7 +111,7 @@ class SettingObject: def log(self): """Auto created logger for debugging.""" if self._log is None: - self._log = logging.getLogger(self.__class__.__name__) + self._log = Logger().get_logger(self.__class__.__name__) return self._log @property From 83eab6b2ca5f5776d630b1b6f1f12cd93e55dfc2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:49:14 +0200 Subject: [PATCH 051/176] ModifiableDict and List are able to handle new way of their item definition with backwards compatibility --- .../settings/settings/widgets/item_types.py | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 6f092b4bd8..ba343b3979 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1381,8 +1381,21 @@ class ListWidget(QtWidgets.QWidget, InputObject): self.initial_attributes(input_data, parent, as_widget) - self.object_type = input_data["object_type"] - self.input_modifiers = input_data.get("input_modifiers") or {} + object_type = input_data["object_type"] + if isinstance(object_type, dict): + self.item_schema = object_type + else: + self.item_schema = { + "type": object_type + } + # Backwards compatibility + input_modifiers = input_data.get("input_modifiers") or {} + if input_modifiers: + self.log.info(( + "Used deprecated key `input_modifiers` to define item." + " Rather use `object_type` as dictionary with modifiers." + )) + self.item_schema.update(input_modifiers) self.input_fields = [] @@ -1949,6 +1962,22 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.key = input_data["key"] + object_type = input_data["object_type"] + if isinstance(object_type, dict): + self.item_schema = object_type + else: + # Backwards compatibility + self.item_schema = { + "type": object_type + } + input_modifiers = input_data.get("input_modifiers") or {} + if input_modifiers: + self.log.info(( + "Used deprecated key `input_modifiers` to define item." + " Rather use `object_type` as dictionary with modifiers." + )) + self.item_schema.update(input_modifiers) + if input_data.get("highlight_content", False): content_state = "hightlighted" bottom_margin = 5 From a1715355a35b1874b3ebda32f08ba27d150fb492 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:50:22 +0200 Subject: [PATCH 052/176] List and ModifiableDict are creating new items in right way --- pype/tools/settings/settings/widgets/item_types.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index ba343b3979..d6858d390b 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1464,9 +1464,7 @@ class ListWidget(QtWidgets.QWidget, InputObject): def add_row(self, row=None, value=None, is_empty=False): # Create new item - item_widget = ListItem( - self.object_type, self.input_modifiers, self, self.inputs_widget - ) + item_widget = ListItem(self.item_schema, self, self.inputs_widget) previous_field = None next_field = None @@ -1652,11 +1650,8 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): children_item_mapping = [] for child_configuration in input_data["object_types"]: - object_type = child_configuration["type"] - item_widget = ListItem( - object_type, child_configuration, self, self.inputs_widget, - is_strict=True + child_configuration, self, self.inputs_widget, is_strict=True ) self.input_fields.append(item_widget) @@ -2030,9 +2025,6 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.setAttribute(QtCore.Qt.WA_TranslucentBackground) - self.object_type = input_data["object_type"] - self.input_modifiers = input_data.get("input_modifiers") or {} - self.add_row(is_empty=True) def count(self): @@ -2132,7 +2124,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): def add_row(self, row=None, key=None, value=None, is_empty=False): # Create new item item_widget = ModifiableDictItem( - self.object_type, self.input_modifiers, self, self.content_widget + self.item_schema, self, self.content_widget ) if is_empty: item_widget.set_as_empty() From d241a450375f6fd0ce45885777d214e78035e0b5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:51:59 +0200 Subject: [PATCH 053/176] info changed to warning --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index d6858d390b..ed8a5d6305 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1391,7 +1391,7 @@ class ListWidget(QtWidgets.QWidget, InputObject): # Backwards compatibility input_modifiers = input_data.get("input_modifiers") or {} if input_modifiers: - self.log.info(( + self.log.warning(( "Used deprecated key `input_modifiers` to define item." " Rather use `object_type` as dictionary with modifiers." )) @@ -1967,7 +1967,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): } input_modifiers = input_data.get("input_modifiers") or {} if input_modifiers: - self.log.info(( + self.log.warning(( "Used deprecated key `input_modifiers` to define item." " Rather use `object_type` as dictionary with modifiers." )) From 069f25f1cbf8ab570878b148adf805f50dee742a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:56:34 +0200 Subject: [PATCH 054/176] skip input modifiers in anatomy --- pype/tools/settings/settings/widgets/anatomy_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/anatomy_types.py b/pype/tools/settings/settings/widgets/anatomy_types.py index 6d7b3292ce..e1a726187c 100644 --- a/pype/tools/settings/settings/widgets/anatomy_types.py +++ b/pype/tools/settings/settings/widgets/anatomy_types.py @@ -271,9 +271,9 @@ class RootsWidget(QtWidgets.QWidget, SettingObject): ) multiroot_data = { "key": self.key, - "object_type": "path-widget", "expandable": False, - "input_modifiers": { + "object_type": { + "type": "path-widget", "multiplatform": True } } From 8cc5a906ffdca51f1fcdbda8468732e06be07902 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:57:07 +0200 Subject: [PATCH 055/176] modified schema to use new object_type definition --- .../projects_schema/1_plugins_gui_schema.json | 8 ++++---- .../gui_schemas/system_schema/1_examples.json | 16 ++++++++-------- .../system_schema/1_modules_gui_schema.json | 18 +++++++++--------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json index 2fefe8df2d..f70d9345e5 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json @@ -172,8 +172,8 @@ "type": "list", "key": "profiles", "label": "Profiles", - "object_type": "dict", - "input_modifiers": { + "object_type": { + "type": "dict", "children": [ { "key": "families", @@ -192,8 +192,8 @@ "label": "Output Definitions", "type": "dict-modifiable", "highlight_content": true, - "object_type": "dict", - "input_modifiers": { + "object_type": { + "type": "dict", "children": [ { "key": "ext", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json index 00aef304a9..dd0f7f20d1 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json @@ -67,16 +67,16 @@ "type": "list", "key": "list_item_of_multiline_texts", "label": "List of multiline texts", - "object_type": "text", - "input_modifiers": { + "object_type": { + "type": "text", "multiline": true } }, { "type": "list", "key": "list_item_of_floats", "label": "List of floats", - "object_type": "number", - "input_modifiers": { + "object_type": { + "type": "number", "decimal": 3, "minimum": 1000, "maximum": 2000 @@ -85,8 +85,8 @@ "type": "dict-modifiable", "key": "modifiable_dict_of_integers", "label": "Modifiable dict of integers", - "object_type": "number", - "input_modifiers": { + "object_type": { + "type": "number", "decimal": 0, "minimum": 10, "maximum": 100 @@ -213,8 +213,8 @@ "type": "list", "key": "dict_item", "label": "DictItem in List", - "object_type": "dict-item", - "input_modifiers": { + "object_type": { + "type": "dict-item", "children": [ { "key": "families", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json index 7b3d8cdd13..d78c11838a 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json @@ -80,8 +80,8 @@ "type": "list", "key": "statuses_name_change", "label": "Status name change", - "object_type": "text", - "input_modifiers": { + "object_type": { + "type": "text", "multiline": false } }] @@ -96,9 +96,9 @@ "type": "dict-modifiable", "key": "status_update", "label": "Status Updates", - "object_type": "list", - "input_modifiers": { - "object_type": "text" + "object_type": { + "type": "list", + "object_type": "text" } }, { @@ -133,10 +133,10 @@ }, { "type": "list", - "object_type": "number", "key": "exclude_ports", "label": "Exclude ports", - "input_modifiers": { + "object_type": { + "type": "number", "minimum": 1, "maximum": 65535 } @@ -213,8 +213,8 @@ "label": "Muster Resl URL" },{ "type": "dict-modifiable", - "object_type": "number", - "input_modifiers": { + "object_type": { + "type": "number", "minimum": 0, "maximum": 300 }, From 7c80946cef55ea803fed79d76286b482cf3117b3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 17:57:15 +0200 Subject: [PATCH 056/176] modified readme --- pype/tools/settings/settings/README.md | 52 ++++++++++++++++++++------ 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/pype/tools/settings/settings/README.md b/pype/tools/settings/settings/README.md index 9492d8bc7b..e8b7fcdb57 100644 --- a/pype/tools/settings/settings/README.md +++ b/pype/tools/settings/settings/README.md @@ -84,8 +84,8 @@ "type": "list", "key": "profiles", "label": "Profiles", - "object_type": "dict-item", - "input_modifiers": { + "object_type": { + "type": "dict-item", "children": [ { "key": "families", @@ -199,37 +199,53 @@ - output is list - items can be added and removed - items in list must be the same type - - type of items is defined with key `"object_type"` where Pure input name is entered (e.g. `number`) - - because Pure inputs may have modifiers (`number` input has `minimum`, `maximum` and `decimals`) you can set these in key `"input_modifiers"` +- type of items is defined with key `"object_type"` +- there are 2 possible ways how to set the type: + 1.) dictionary with item modifiers (`number` input has `minimum`, `maximum` and `decimals`) in that case item type must be set as value of `"type"` (example below) + 2.) item type name as string without modifiers (e.g. `text`) +1.) with item modifiers ``` { "type": "list", - "object_type": "number", "key": "exclude_ports", "label": "Exclude ports", - "input_modifiers": { - "minimum": 1, - "maximum": 65535 + "object_type": { + "type": "number", # number item type + "minimum": 1, # minimum modifier + "maximum": 65535 # maximum modifier } } ``` +2.) without modifiers +``` +{ + "type": "list", + "key": "exclude_ports", + "label": "Exclude ports", + "object_type": "text" +} +``` + ### dict-modifiable - one of dictionary inputs, this is only used as value input - items in this input can be removed and added same way as in `list` input - value items in dictionary must be the same type - - type of items is defined with key `"object_type"` where Pure input name is entered (e.g. `number`) - - because Pure inputs may have modifiers (`number` input has `minimum`, `maximum` and `decimals`) you can set these in key `"input_modifiers"` +- type of items is defined with key `"object_type"` +- there are 2 possible ways how to set the type: + 1.) dictionary with item modifiers (`number` input has `minimum`, `maximum` and `decimals`) in that case item type must be set as value of `"type"` (example below) + 2.) item type name as string without modifiers (e.g. `text`) - this input can be expandable - that can be set with key `"expandable"` as `True`/`False` (Default: `True`) - with key `"expanded"` as `True`/`False` can be set that is expanded when GUI is opened (Default: `False`) +1.) with item modifiers ``` { "type": "dict-modifiable", - "object_type": "number", - "input_modifiers": { + "object_type": { + "type": "number", "minimum": 0, "maximum": 300 }, @@ -240,6 +256,18 @@ } ``` +2.) without modifiers +``` +{ + "type": "dict-modifiable", + "object_type": "text", + "is_group": true, + "key": "templates_mapping", + "label": "Muster - Templates mapping", + "is_file": true +} +``` + ### path-widget - input for paths, use `path-input` internally - has 2 input modifiers `"multiplatform"` and `"multipath"` From 0f05901ac7979b84d2b6f624dd8bf23163d07b48 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 19:11:03 +0200 Subject: [PATCH 057/176] simplified PathWidget with usage of dict as widget --- .../settings/settings/widgets/item_types.py | 146 +++++++----------- 1 file changed, 56 insertions(+), 90 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 0419c48c5c..9512680a39 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2835,13 +2835,13 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self.multiplatform = input_data.get("multiplatform", False) self.multipath = input_data.get("multipath", False) - self.input_fields = [] + self.input_field = None layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self._as_widget: + if not self.as_widget: self.key = input_data["key"] if not label_widget: label = input_data["label"] @@ -2882,45 +2882,49 @@ class PathWidget(QtWidgets.QWidget, SettingObject): ) self.setFocusProxy(path_input) self.content_layout.addWidget(path_input) - self.input_fields.append(path_input) + self.input_field = path_input path_input.value_changed.connect(self._on_value_change) return - input_data_for_list = { - "object_type": "path-input" - } if not self.multiplatform: - input_data_for_list["key"] = self.key + item_schema = { + "key": self.key, + "object_type": "path-input" + } input_widget = ListWidget( - input_data_for_list, self, label_widget=self.label_widget + item_schema, self, label_widget=self.label_widget ) self.setFocusProxy(input_widget) self.content_layout.addWidget(input_widget) - self.input_fields.append(input_widget) + self.input_field = input_widget input_widget.value_changed.connect(self._on_value_change) return - proxy_widget = QtWidgets.QWidget(self.content_widget) - proxy_layout = QtWidgets.QFormLayout(proxy_widget) + item_schema = { + "type": "dict", + "show_borders": False, + "children": [] + } for platform_key in self.platforms: platform_label = self.platform_labels_mapping[platform_key] - label_widget = QtWidgets.QLabel(platform_label, proxy_widget) + child_item = { + "key": platform_key, + "label": platform_label + } if self.multipath: - input_data_for_list["key"] = platform_key - input_widget = ListWidget( - input_data_for_list, self, label_widget=label_widget - ) + child_item["type"] = "list" + child_item["object_type"] = "path-input" else: - input_data = {"key": platform_key} - input_widget = PathInputWidget( - input_data, self, label_widget=label_widget - ) - proxy_layout.addRow(label_widget, input_widget) - self.input_fields.append(input_widget) - input_widget.value_changed.connect(self._on_value_change) + child_item["type"] = "path-input" - self.setFocusProxy(self.input_fields[0]) - self.content_layout.addWidget(proxy_widget) + item_schema["children"].append(child_item) + + input_widget = DictWidget( + item_schema, self, as_widget=True, label_widget=self.label_widget + ) + self.content_layout.addWidget(input_widget) + self.input_field = input_widget + input_widget.value_changed.connect(self._on_value_change) def update_default_values(self, parent_values): self._state = None @@ -2960,11 +2964,8 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._has_studio_override = False self._had_studio_override = False - if not self.multiplatform: - self.input_fields[0].update_default_values(value) - else: - for input_field in self.input_fields: - input_field.update_default_values(value) + # TODO handle invalid value type + self.input_field.update_default_values(value) def update_studio_values(self, parent_values): self._state = None @@ -2989,11 +2990,8 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._had_studio_override = False value = self.default_value - if not self.multiplatform: - self.input_fields[0].update_studio_values(value) - else: - for input_field in self.input_fields: - input_field.update_studio_values(value) + # TODO handle invalid value type + self.input_field.update_studio_values(value) def apply_overrides(self, parent_values): self._is_modified = False @@ -3012,11 +3010,8 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._is_overriden = override_values is not NOT_SET self._was_overriden = bool(self._is_overriden) - if not self.multiplatform: - self.input_fields[0].apply_overrides(parent_values) - else: - for input_field in self.input_fields: - input_field.apply_overrides(override_values) + # TODO handle invalid value type + self.input_field.update_studio_values(override_values) if not self._is_overriden: self._is_overriden = ( @@ -3029,12 +3024,13 @@ class PathWidget(QtWidgets.QWidget, SettingObject): def set_value(self, value): if not self.multiplatform: - self.input_fields[0].set_value(value) + return self.input_field.set_value(value) - else: - for input_field in self.input_fields: - _value = value[input_field.key] - input_field.set_value(_value) + for _input_field in self.input_field.input_fields: + _value = value.get(_input_field.key, NOT_SET) + if _value is NOT_SET: + continue + _input_field.set_value(_value) def _on_value_change(self, item=None): if self.ignore_value_changes: @@ -3095,17 +3091,14 @@ class PathWidget(QtWidgets.QWidget, SettingObject): def remove_overrides(self): self._is_overriden = False self._is_modified = False - for input_field in self.input_fields: - input_field.remove_overrides() + self.input_field.remove_overrides() def reset_to_pype_default(self): - for input_field in self.input_fields: - input_field.reset_to_pype_default() + self.input_field.reset_to_pype_default() self._has_studio_override = False def set_studio_default(self): - for input_field in self.input_fields: - input_field.set_studio_default() + self.input_field.set_studio_default() if self.is_group: self._has_studio_override = True @@ -3114,8 +3107,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._is_modified = False self._is_overriden = self._was_overriden - for input_field in self.input_fields: - input_field.discard_changes() + self.input_field.discard_changes() self._is_modified = self.child_modified @@ -3124,51 +3116,29 @@ class PathWidget(QtWidgets.QWidget, SettingObject): @property def child_has_studio_override(self): - for input_field in self.input_fields: - if ( - input_field.has_studio_override - or input_field.child_has_studio_override - ): - return True - return False + return ( + self.input_field.has_studio_override + or self.input_field.child_has_studio_override + ) @property def child_modified(self): - for input_field in self.input_fields: - if input_field.child_modified: - return True - return False + return self.input_field.child_modified @property def child_overriden(self): - for input_field in self.input_fields: - if input_field.child_overriden: - return True - return False + return self.input_field.child_overriden @property def child_invalid(self): - for input_field in self.input_fields: - if input_field.child_invalid: - return True - return False + return self.input_field.child_invalid def hierarchical_style_update(self): - for input_field in self.input_fields: - input_field.hierarchical_style_update() + self.input_field.hierarchical_style_update() self.update_style() def item_value(self): - if not self.multiplatform and not self.multipath: - return self.input_fields[0].item_value() - - if not self.multiplatform: - return self.input_fields[0].item_value() - - output = {} - for input_field in self.input_fields: - output.update(input_field.config_value()) - return output + return self.input_field.item_value() def studio_overrides(self): if ( @@ -3178,18 +3148,14 @@ class PathWidget(QtWidgets.QWidget, SettingObject): ): return NOT_SET, False - value = self.item_value() - if not self.multiplatform: - value = {self.key: value} + value = {self.key: self.item_value()} return value, self.is_group def overrides(self): if not self.is_overriden and not self.child_overriden: return NOT_SET, False - value = self.item_value() - if not self.multiplatform: - value = {self.key: value} + value = {self.key: self.item_value()} return value, self.is_group From 3a6c8e32eb518b74e1b56ebb0217b5641155eeb1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 19:14:20 +0200 Subject: [PATCH 058/176] DictWidget used as widget has ability to not add borders around the widget --- pype/tools/settings/settings/widgets/item_types.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 9512680a39..fd284bb339 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2244,6 +2244,8 @@ class DictWidget(QtWidgets.QWidget, SettingObject): def _ui_as_widget(self, input_data): body = QtWidgets.QWidget(self) body.setObjectName("DictAsWidgetBody") + show_borders = str(int(input_data.get("show_borders", True))) + body.setProperty("show_borders", show_borders) content_layout = QtWidgets.QGridLayout(body) content_layout.setContentsMargins(5, 5, 5, 5) From 36a2edf2fbae8636c0684ffba7517cfbec279929 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 19:14:39 +0200 Subject: [PATCH 059/176] modified styles for dict widget --- pype/tools/settings/settings/style/style.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/style/style.css b/pype/tools/settings/settings/style/style.css index ebea87203d..dcc7a5effe 100644 --- a/pype/tools/settings/settings/style/style.css +++ b/pype/tools/settings/settings/style/style.css @@ -168,8 +168,10 @@ QPushButton[btn-type="expand-toggle"] { background: #141a1f; } -#DictAsWidgetBody{ +#DictAsWidgetBody { background: transparent; +} +#DictAsWidgetBody[show_borders="1"] { border: 2px solid #cccccc; border-radius: 5px; } From c51daf918b706416cdb2bbb65cbce0e0af295bce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 19:40:29 +0200 Subject: [PATCH 060/176] fixed a lot of in path widget --- .../settings/settings/widgets/item_types.py | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index fd284bb339..379f058fab 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2873,14 +2873,14 @@ class PathWidget(QtWidgets.QWidget, SettingObject): platform: value_type() for platform in self.platforms } - else: - return value_type() + return value_type() def create_gui(self): if not self.multiplatform and not self.multipath: input_data = {"key": self.key} path_input = PathInputWidget( - input_data, self, label_widget=self.label_widget + input_data, self, + as_widget=True, label_widget=self.label_widget ) self.setFocusProxy(path_input) self.content_layout.addWidget(path_input) @@ -2894,7 +2894,8 @@ class PathWidget(QtWidgets.QWidget, SettingObject): "object_type": "path-input" } input_widget = ListWidget( - item_schema, self, label_widget=self.label_widget + item_schema, self, + as_widget=True, label_widget=self.label_widget ) self.setFocusProxy(input_widget) self.content_layout.addWidget(input_widget) @@ -2934,21 +2935,15 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._is_modified = False value = NOT_SET - if self._as_widget: + if self.as_widget: value = parent_values elif parent_values is not NOT_SET: - if not self.multiplatform: - value = parent_values - else: - value = parent_values.get(self.key, NOT_SET) + value = parent_values.get(self.key, NOT_SET) if value is NOT_SET: if self.develop_mode: - if self._as_widget or not self.multiplatform: - value = {self.key: self.default_input_value} - else: - value = self.default_input_value self.defaults_not_set = True + value = self.default_input_value if value is NOT_SET: raise NotImplementedError(( "{} Does not have implemented" @@ -2975,13 +2970,10 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._is_modified = False value = NOT_SET - if self._as_widget: + if self.as_widget: value = parent_values elif parent_values is not NOT_SET: - if not self.multiplatform: - value = parent_values - else: - value = parent_values.get(self.key, NOT_SET) + value = parent_values.get(self.key, NOT_SET) self.studio_value = value if value is not NOT_SET: @@ -2990,7 +2982,6 @@ class PathWidget(QtWidgets.QWidget, SettingObject): else: self._has_studio_override = False self._had_studio_override = False - value = self.default_value # TODO handle invalid value type self.input_field.update_studio_values(value) @@ -3004,10 +2995,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): if self._as_widget: override_values = parent_values elif parent_values is not NOT_SET: - if not self.multiplatform: - override_values = parent_values - else: - override_values = parent_values.get(self.key, NOT_SET) + override_values = parent_values.get(self.key, NOT_SET) self._is_overriden = override_values is not NOT_SET self._was_overriden = bool(self._is_overriden) @@ -3075,7 +3063,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self.style().polish(self) self._child_state = child_state - if not self._as_widget: + if self.label_widget: state = self.style_state( child_has_studio_override, child_invalid, @@ -3106,30 +3094,36 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._has_studio_override = True def discard_changes(self): - self._is_modified = False self._is_overriden = self._was_overriden + self._has_studio_override = self._had_studio_override self.input_field.discard_changes() - self._is_modified = self.child_modified + if not self.is_overidable: + if self.has_studio_override: + self._is_modified = self.studio_value != self.item_value() + else: + self._is_modified = self.default_value != self.item_value() + self._is_overriden = False + return + + self._is_modified = False + self._is_overriden = self._was_overriden def set_as_overriden(self): self._is_overriden = True @property def child_has_studio_override(self): - return ( - self.input_field.has_studio_override - or self.input_field.child_has_studio_override - ) + return self.has_studio_override @property def child_modified(self): - return self.input_field.child_modified + return self.is_modified @property def child_overriden(self): - return self.input_field.child_overriden + return self.is_overriden @property def child_invalid(self): From 4f61d84612bbcb1c3705611b6657fa6e7c3015a7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 23 Sep 2020 19:41:34 +0200 Subject: [PATCH 061/176] fix raw json item_value method --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 0419c48c5c..ec315acaf5 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1182,7 +1182,7 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): def item_value(self): if self.is_invalid: return NOT_SET - return self.text_input.json_value() + return self.input_field.json_value() class ListItem(QtWidgets.QWidget, SettingObject): From 53dc5e20dd8953726f0ee6ed0f679cde8093430d Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 24 Sep 2020 14:55:54 +0200 Subject: [PATCH 062/176] switch maya capture to invidible dictionary --- .../plugins/maya/maya/maya_capture.json | 26 +- .../projects_schema/1_plugins_gui_schema.json | 1149 ++++++++--------- .../projects_schema/2_maya_capture.json | 193 ++- 3 files changed, 693 insertions(+), 675 deletions(-) diff --git a/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json b/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json index b6c4893034..02e6a9b95d 100644 --- a/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json +++ b/pype/settings/defaults/project_settings/plugins/maya/maya/maya_capture.json @@ -6,19 +6,19 @@ }, "Display Options": { "background": [ - 0.7137254901960784, - 0.7137254901960784, - 0.7137254901960784 + 0.714, + 0.714, + 0.714 ], "backgroundBottom": [ - 0.7137254901960784, - 0.7137254901960784, - 0.7137254901960784 + 0.714, + 0.714, + 0.714 ], "backgroundTop": [ - 0.7137254901960784, - 0.7137254901960784, - 0.7137254901960784 + 0.714, + 0.714, + 0.714 ], "override_display": true }, @@ -40,15 +40,15 @@ "rendererName": "vp2Renderer" }, "Resolution": { + "width": 1920, "height": 1080, - "mode": "Custom", "percent": 1.0, - "width": 1920 + "mode": "Custom" }, "Time Range": { + "start_frame": 0, "end_frame": 25, "frame": "", - "start_frame": 0, "time": "Time Slider" }, "Viewport Options": { @@ -105,4 +105,4 @@ "displayFilmOrigin": false, "overscan": 1.0 } -} +} \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json index ea015edfc5..87912cfdc0 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/1_plugins_gui_schema.json @@ -3,683 +3,612 @@ "collapsable": true, "key": "plugins", "label": "Plugins", - "children": [ - { + "children": [{ "type": "dict", "collapsable": true, "key": "celaction", "label": "CelAction", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractCelactionDeadline", - "label": "ExtractCelactionDeadline", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "text", - "key": "deadline_department", - "label": "Deadline apartment" - }, { - "type": "number", - "key": "deadline_priority", - "label": "Deadline priority" - }, { - "type": "text", - "key": "deadline_pool", - "label": "Deadline pool" - }, { - "type": "text", - "key": "deadline_pool_secondary", - "label": "Deadline pool (secondary)" - }, { - "type": "text", - "key": "deadline_group", - "label": "Deadline Group" - }, { - "type": "number", - "key": "deadline_chunk_size", - "label": "Deadline Chunk size" - } - ] - } - ] - } - ] + "checkbox_key": "enabled", + "key": "ExtractCelactionDeadline", + "label": "ExtractCelactionDeadline", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "text", + "key": "deadline_department", + "label": "Deadline apartment" + }, { + "type": "number", + "key": "deadline_priority", + "label": "Deadline priority" + }, { + "type": "text", + "key": "deadline_pool", + "label": "Deadline pool" + }, { + "type": "text", + "key": "deadline_pool_secondary", + "label": "Deadline pool (secondary)" + }, { + "type": "text", + "key": "deadline_group", + "label": "Deadline Group" + }, { + "type": "number", + "key": "deadline_chunk_size", + "label": "Deadline Chunk size" + }] + }] + }] }, { "type": "dict", "collapsable": true, "key": "ftrack", "label": "Ftrack", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "IntegrateFtrackNote", - "label": "IntegrateFtrackNote", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "text", - "key": "note_with_intent_template", - "label": "Note with intent template" - }, { - "type": "list", - "object_type": "text", - "key": "note_labels", - "label": "Note labels" - } - ] - } - ] - } - ] + "checkbox_key": "enabled", + "key": "IntegrateFtrackNote", + "label": "IntegrateFtrackNote", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "text", + "key": "note_with_intent_template", + "label": "Note with intent template" + }, { + "type": "list", + "object_type": "text", + "key": "note_labels", + "label": "Note labels" + }] + }] + }] }, { "type": "dict", "collapsable": true, "key": "global", "label": "Global", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "IntegrateMasterVersion", - "label": "IntegrateMasterVersion", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] + "checkbox_key": "enabled", + "key": "IntegrateMasterVersion", + "label": "IntegrateMasterVersion", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }] + }, { + "type": "dict", + "collapsable": true, + "checkbox_key": "enabled", + "key": "ExtractJpegEXR", + "label": "ExtractJpegEXR", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "dict-invisible", + "key": "ffmpeg_args", + "children": [{ + "type": "list", + "object_type": "text", + "key": "input", + "label": "FFmpeg input arguments" }, { + "type": "list", + "object_type": "text", + "key": "output", + "label": "FFmpeg output arguments" + }] + }] + }, { + "type": "dict", + "collapsable": true, + "key": "ExtractReview", + "label": "ExtractReview", + "checkbox_key": "enabled", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "list", + "key": "profiles", + "label": "Profiles", + "object_type": { "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractJpegEXR", - "label": "ExtractJpegEXR", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "dict-invisible", - "key": "ffmpeg_args", - "children": [ - { - "type": "list", - "object_type": "text", - "key": "input", - "label": "FFmpeg input arguments" - }, { - "type": "list", - "object_type": "text", - "key": "output", - "label": "FFmpeg output arguments" - } - ] - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ExtractReview", - "label": "ExtractReview", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "list", - "key": "profiles", - "label": "Profiles", - "object_type": { - "type": "dict", - "children": [ + "children": [{ + "key": "families", + "label": "Families", + "type": "list", + "object_type": "text" + }, { + "key": "hosts", + "label": "Hosts", + "type": "list", + "object_type": "text" + }, { + "type": "splitter" + }, { + "key": "outputs", + "label": "Output Definitions", + "type": "dict-modifiable", + "highlight_content": true, + "object_type": { + "type": "dict", + "children": [{ + "key": "ext", + "label": "Output extension", + "type": "text" + }, { + "key": "tags", + "label": "Tags", + "type": "enum", + "multiselection": true, + "enum_items": [{ + "burnin": "Add burnins" + }, { - "key": "families", - "label": "Families", - "type": "list", - "object_type": "text" - }, { - "key": "hosts", - "label": "Hosts", - "type": "list", - "object_type": "text" - }, { - "type": "splitter" - }, { - "key": "outputs", - "label": "Output Definitions", - "type": "dict-modifiable", - "highlight_content": true, - "object_type": { - "type": "dict", - "children": [ - { - "key": "ext", - "label": "Output extension", - "type": "text" - }, { - "key": "tags", - "label": "Tags", - "type": "enum", - "multiselection": true, - "enum_items": [ - {"burnin": "Add burnins"}, - {"ftrackreview": "Add to Ftrack"}, - {"delete": "Delete output"}, - {"slate-frame": "Add slate frame"}, - {"no-hnadles": "Skip handle frames"} - ] - }, { - "key": "ffmpeg_args", - "label": "FFmpeg arguments", - "type": "dict", - "highlight_content": true, - "children": [ - { - "key": "video_filters", - "label": "Video filters", - "type": "list", - "object_type": "text" - }, { - "type": "splitter" - }, { - "key": "audio_filters", - "label": "Audio filters", - "type": "list", - "object_type": "text" - }, { - "type": "splitter" - }, { - "key": "input", - "label": "Input arguments", - "type": "list", - "object_type": "text" - }, { - "type": "splitter" - }, { - "key": "output", - "label": "Output arguments", - "type": "list", - "object_type": "text" - } - ] - }, { - "key": "filter", - "label": "Additional output filtering", - "type": "dict", - "highlight_content": true, - "children": [ - { - "key": "families", - "label": "Families", - "type": "list", - "object_type": "text" - } - ] - } - ] - } + "ftrackreview": "Add to Ftrack" + }, + { + "delete": "Delete output" + }, + { + "slate-frame": "Add slate frame" + }, + { + "no-hnadles": "Skip handle frames" } ] - } + }, { + "key": "ffmpeg_args", + "label": "FFmpeg arguments", + "type": "dict", + "highlight_content": true, + "children": [{ + "key": "video_filters", + "label": "Video filters", + "type": "list", + "object_type": "text" + }, { + "type": "splitter" + }, { + "key": "audio_filters", + "label": "Audio filters", + "type": "list", + "object_type": "text" + }, { + "type": "splitter" + }, { + "key": "input", + "label": "Input arguments", + "type": "list", + "object_type": "text" + }, { + "type": "splitter" + }, { + "key": "output", + "label": "Output arguments", + "type": "list", + "object_type": "text" + }] + }, { + "key": "filter", + "label": "Additional output filtering", + "type": "dict", + "highlight_content": true, + "children": [{ + "key": "families", + "label": "Families", + "type": "list", + "object_type": "text" + }] + }] } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ExtractBurnin", - "label": "ExtractBurnin", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "dict", - "collapsable": true, - "key": "options", - "label": "Burnin formating options", - "children": [ - { - "type": "number", - "key": "font_size", - "label": "Font size" - }, { - "type": "number", - "key": "opacity", - "label": "Font opacity" - }, { - "type": "number", - "key": "bg_opacity", - "label": "Background opacity" - }, { - "type": "number", - "key": "x_offset", - "label": "X Offset" - }, { - "type": "number", - "key": "y_offset", - "label": "Y Offset" - }, { - "type": "number", - "key": "bg_padding", - "label": "Padding aroung text" - } - ] - }, { - "type": "raw-json", - "key": "profiles", - "label": "Burnin profiles" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "IntegrateAssetNew", - "label": "IntegrateAssetNew", - "is_group": true, - "children": [ - { - "type": "raw-json", - "key": "template_name_profiles", - "label": "template_name_profiles" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ProcessSubmittedJobOnFarm", - "label": "ProcessSubmittedJobOnFarm", - "checkbox_key": "enabled", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "text", - "key": "deadline_department", - "label": "Deadline department" - }, { - "type": "text", - "key": "deadline_pool", - "label": "Deadline Pool" - }, { - "type": "text", - "key": "deadline_group", - "label": "Deadline Group" - } - ] + }] } - ] - } - ] + }] + }, { + "type": "dict", + "collapsable": true, + "key": "ExtractBurnin", + "label": "ExtractBurnin", + "checkbox_key": "enabled", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "dict", + "collapsable": true, + "key": "options", + "label": "Burnin formating options", + "children": [{ + "type": "number", + "key": "font_size", + "label": "Font size" + }, { + "type": "number", + "key": "opacity", + "label": "Font opacity" + }, { + "type": "number", + "key": "bg_opacity", + "label": "Background opacity" + }, { + "type": "number", + "key": "x_offset", + "label": "X Offset" + }, { + "type": "number", + "key": "y_offset", + "label": "Y Offset" + }, { + "type": "number", + "key": "bg_padding", + "label": "Padding aroung text" + }] + }, { + "type": "raw-json", + "key": "profiles", + "label": "Burnin profiles" + }] + }, { + "type": "dict", + "collapsable": true, + "key": "IntegrateAssetNew", + "label": "IntegrateAssetNew", + "is_group": true, + "children": [{ + "type": "raw-json", + "key": "template_name_profiles", + "label": "template_name_profiles" + }] + }, { + "type": "dict", + "collapsable": true, + "key": "ProcessSubmittedJobOnFarm", + "label": "ProcessSubmittedJobOnFarm", + "checkbox_key": "enabled", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "text", + "key": "deadline_department", + "label": "Deadline department" + }, { + "type": "text", + "key": "deadline_pool", + "label": "Deadline Pool" + }, { + "type": "text", + "key": "deadline_group", + "label": "Deadline Group" + }] + }] + }] }, { "type": "dict-invisible", "collapsable": true, "key": "maya", "label": "Maya", - "children": [ - { - "type": "dict", - "collapsable": true, - "key": "maya", - "label": "Maya", - "children": [ + "children": [{ + "type": "dict", + "collapsable": true, + "key": "maya", + "label": "Maya", + "children": [ + { - "type": "schema", - "children": [ - "2_maya_capture", - "2_maya_plugins", - "2_maya_workfiles" - ] + "type": "schema", + "name": "2_maya_capture" + }, + { + "type": "schema", + "name": "2_maya_plugins" + }, + { + "type": "schema", + "name": "2_maya_workfiles" } ] - } - ] + }] }, { "type": "dict", "collapsable": true, "key": "nuke", "label": "Nuke", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "create", + "label": "Create plugins", + "is_file": true, + "children": [{ + "type": "dict", + "collapsable": false, + "key": "CreateWriteRender", + "label": "CreateWriteRender", + "is_group": true, + "children": [{ + "type": "text", + "key": "fpath_template", + "label": "Path template" + }] + }, { + "type": "dict", + "collapsable": false, + "key": "CreateWritePrerender", + "label": "CreateWritePrerender", + "is_group": true, + "children": [{ + "type": "text", + "key": "fpath_template", + "label": "Path template" + }] + }] + }, { + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "create", - "label": "Create plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": false, - "key": "CreateWriteRender", - "label": "CreateWriteRender", - "is_group": true, - "children": [ - { - "type": "text", - "key": "fpath_template", - "label": "Path template" - } - ] - }, { - "type": "dict", - "collapsable": false, - "key": "CreateWritePrerender", - "label": "CreateWritePrerender", - "is_group": true, - "children": [ - { - "type": "text", - "key": "fpath_template", - "label": "Path template" - } - ] - } - ] + "checkbox_key": "enabled", + "key": "ExtractThumbnail", + "label": "ExtractThumbnail", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "raw-json", + "key": "nodes", + "label": "Nodes" + }] }, { "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractThumbnail", - "label": "ExtractThumbnail", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "raw-json", - "key": "nodes", - "label": "Nodes" - } - ] - }, { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ValidateNukeWriteKnobs", - "label": "ValidateNukeWriteKnobs", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "raw-json", - "key": "knobs", - "label": "Knobs" - } - ] - }, { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractReviewDataLut", - "label": "ExtractReviewDataLut", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - }, { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractReviewDataMov", - "label": "ExtractReviewDataMov", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "boolean", - "key": "viewer_lut_raw", - "label": "Viewer LUT raw" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "ExtractSlateFrame", - "label": "ExtractSlateFrame", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "viewer_lut_raw", - "label": "Viewer LUT raw" - } - ] - }, { - "type": "dict", - "collapsable": true, - "key": "NukeSubmitDeadline", - "label": "NukeSubmitDeadline", - "is_group": true, - "children": [ - { - "type": "number", - "key": "deadline_priority", - "label": "deadline_priority" - }, { - "type": "text", - "key": "deadline_pool", - "label": "deadline_pool" - }, { - "type": "text", - "key": "deadline_pool_secondary", - "label": "deadline_pool_secondary" - }, { - "type": "number", - "key": "deadline_chunk_size", - "label": "deadline_chunk_size" - } - ] - } - ] + "checkbox_key": "enabled", + "key": "ValidateNukeWriteKnobs", + "label": "ValidateNukeWriteKnobs", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "raw-json", + "key": "knobs", + "label": "Knobs" + }] }, { - "type": "raw-json", - "key": "workfile_build", - "label": "Workfile Build logic", - "is_file": true - } - ] + "type": "dict", + "collapsable": true, + "checkbox_key": "enabled", + "key": "ExtractReviewDataLut", + "label": "ExtractReviewDataLut", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }] + }, { + "type": "dict", + "collapsable": true, + "checkbox_key": "enabled", + "key": "ExtractReviewDataMov", + "label": "ExtractReviewDataMov", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "boolean", + "key": "viewer_lut_raw", + "label": "Viewer LUT raw" + }] + }, { + "type": "dict", + "collapsable": true, + "key": "ExtractSlateFrame", + "label": "ExtractSlateFrame", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "viewer_lut_raw", + "label": "Viewer LUT raw" + }] + }, { + "type": "dict", + "collapsable": true, + "key": "NukeSubmitDeadline", + "label": "NukeSubmitDeadline", + "is_group": true, + "children": [{ + "type": "number", + "key": "deadline_priority", + "label": "deadline_priority" + }, { + "type": "text", + "key": "deadline_pool", + "label": "deadline_pool" + }, { + "type": "text", + "key": "deadline_pool_secondary", + "label": "deadline_pool_secondary" + }, { + "type": "number", + "key": "deadline_chunk_size", + "label": "deadline_chunk_size" + }] + }] + }, { + "type": "raw-json", + "key": "workfile_build", + "label": "Workfile Build logic", + "is_file": true + }] }, { "type": "dict", "collapsable": true, "key": "nukestudio", "label": "NukeStudio", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "CollectInstanceVersion", - "label": "Collect Instance Version", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - }, { - "type": "dict", - "collapsable": true, - "checkbox_key": "enabled", - "key": "ExtractReviewCutUpVideo", - "label": "Extract Review Cut Up Video", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, { - "type": "list", - "object_type": "text", - "key": "tags_addition", - "label": "Tags addition" - } - ] - } - ] - } - ] + "checkbox_key": "enabled", + "key": "CollectInstanceVersion", + "label": "Collect Instance Version", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }] + }, { + "type": "dict", + "collapsable": true, + "checkbox_key": "enabled", + "key": "ExtractReviewCutUpVideo", + "label": "Extract Review Cut Up Video", + "is_group": true, + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "list", + "object_type": "text", + "key": "tags_addition", + "label": "Tags addition" + }] + }] + }] }, { "type": "dict", "collapsable": true, "key": "resolve", "label": "DaVinci Resolve", - "children": [ - { - "type": "dict", - "collapsable": true, - "key": "create", - "label": "Creator plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "key": "CreateShotClip", - "label": "Create Shot Clip", - "is_group": true, - "children": [ - { - "type": "text", - "key": "clipName", - "label": "Clip name template" - }, { - "type": "text", - "key": "folder", - "label": "Folder" - }, { - "type": "number", - "key": "steps", - "label": "Steps" - } - ] - } + "children": [{ + "type": "dict", + "collapsable": true, + "key": "create", + "label": "Creator plugins", + "is_file": true, + "children": [{ + "type": "dict", + "collapsable": true, + "key": "CreateShotClip", + "label": "Create Shot Clip", + "is_group": true, + "children": [{ + "type": "text", + "key": "clipName", + "label": "Clip name template" + }, { + "type": "text", + "key": "folder", + "label": "Folder" + }, { + "type": "number", + "key": "steps", + "label": "Steps" + }] + } - ] - } - ] + ] + }] }, { "type": "dict", "collapsable": true, "key": "standalonepublisher", "label": "Standalone Publisher", - "children": [ - { + "children": [{ + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [{ "type": "dict", "collapsable": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsable": true, - "key": "ExtractThumbnailSP", - "label": "ExtractThumbnailSP", - "is_group": true, - "children": [ - { - "type": "dict", - "collapsable": false, - "key": "ffmpeg_args", - "label": "ffmpeg_args", - "children": [ - { - "type": "list", - "object_type": "text", - "key": "input", - "label": "input" - }, - { - "type": "list", - "object_type": "text", - "key": "output", - "label": "output" - } - ] - } - ] - } - ] - } - ] + "key": "ExtractThumbnailSP", + "label": "ExtractThumbnailSP", + "is_group": true, + "children": [{ + "type": "dict", + "collapsable": false, + "key": "ffmpeg_args", + "label": "ffmpeg_args", + "children": [{ + "type": "list", + "object_type": "text", + "key": "input", + "label": "input" + }, + { + "type": "list", + "object_type": "text", + "key": "output", + "label": "output" + } + ] + }] + }] + }] } ] } diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json index a7b44323d2..836ad90404 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/2_maya_capture.json @@ -6,11 +6,15 @@ "is_file": true, "children": [ { - "type": "dict", - "collapsable": true, + "type": "dict-invisible", "key": "Codec", "label": "Codec", + "collapsable": false, "children": [ + { + "type": "label", + "label": "Codec" + }, { "type": "text", "key": "compression", @@ -26,72 +30,137 @@ "decimal": 0, "minimum": 0, "maximum": 100 + }, + + { + "type": "splitter" } ] }, { - "type": "dict", - "collapsable": true, + "type": "dict-invisible", "key": "Display Options", "label": "Display Options", + "collapsable": false, "children": [ { - "type": "list", + "type": "label", + "label": "Display Options" + }, + { + "type": "list-strict", "key": "background", - "label": "Background Color", - "object_type": "number", - "input_modifiers": { - "decimal": 3, - "minimum": 0, - "maximum": 1 - } - }, { - "type": "list", - "key": "backgroundBottom", - "label": "Bottom Background Color", - "object_type": "number", - "input_modifiers": { - "decimal": 3, - "minimum": 0, - "maximum": 1 - } - }, { - "type": "list", - "key": "backgroundTop", - "label": "Top Background Color", - "object_type": "number", - "input_modifiers": { - "decimal": 3, - "minimum": 0, - "maximum": 1 - } - }, { + "label": "Background Color: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, { + "type": "list-strict", + "key": "backgroundBottom", + "label": "Background Bottom: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, { + "type": "list-strict", + "key": "backgroundTop", + "label": "Background Top: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, { "type": "boolean", "key": "override_display", "label": "Override display options" } ] - }, { - "type": "dict", + }, + { + "type": "splitter" + } , + { + "type": "dict-invisible", "collapsable": true, "key": "Generic", "label": "Generic", "children": [ + { + "type": "label", + "label": "Generic" + }, { "type": "boolean", "key": "isolate_view", - "label": "Isolate view" + "label": " Isolate view" },{ "type": "boolean", "key": "off_screen", - "label": "Off Screen" + "label": " Off Screen" } ] },{ - "type": "dict", + "type": "dict-invisible", "collapsable": true, "key": "IO", "label": "IO", "children": [ + { + "type": "label", + "label": "IO" + }, { "type": "text", "key": "name", @@ -107,7 +176,7 @@ },{ "type": "list", "key": "recent_playblasts", - "label": "Recent playbacks", + "label": "Recent Playblasts", "object_type": "text" },{ "type": "boolean", @@ -116,7 +185,7 @@ } ] },{ - "type": "dict", + "type": "dict-invisible", "collapsable": true, "key": "PanZoom", "label": "Pan Zoom", @@ -124,31 +193,47 @@ { "type": "boolean", "key": "pan_zoom", - "label": "Pan Zoom" + "label": " Pan Zoom" } ] + }, + { + "type": "splitter" },{ - "type": "dict", + "type": "dict-invisible", "collapsable": true, "key": "Renderer", "label": "Renderer", "children": [ + + { + "type": "label", + "label": "Renderer" + }, { "type": "text", "key": "rendererName", - "label": "Renderer name" + "label": " Renderer name" } ] },{ - "type": "dict", + "type": "dict-invisible", "collapsable": true, "key": "Resolution", "label": "Resolution", "children": [ + + { + "type": "splitter" + }, + { + "type": "label", + "label": "Resolution" + }, { "type": "number", "key": "width", - "label": "Width", + "label": " Width", "decimal": 0, "minimum": 0, "maximum": 99999 @@ -172,16 +257,24 @@ "label": "Mode" } ] - },{ - "type": "dict", + }, + { + "type": "splitter" + }, + { + "type": "dict-invisible", "collapsable": true, "key": "Time Range", "label": "Time Range", "children": [ + { + "type": "label", + "label": "Time Range" + }, { "type": "number", "key": "start_frame", - "label": "Start frame", + "label": " Start frame", "decimal": 0, "minimum": 0, "maximum": 999999 @@ -192,10 +285,6 @@ "decimal": 0, "minimum": 0, "maximum": 999999 - },{ - "type": "text", - "key": "mode", - "label": "Mode" },{ "type": "text", "key": "frame", From 3830e347d4722ec7850dff01341acad5606baead Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 24 Sep 2020 16:07:49 +0200 Subject: [PATCH 063/176] remove all widgets in content_layout on refresh --- pype/tools/settings/settings/widgets/base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index 404d7b700b..243a8448e5 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -133,11 +133,11 @@ class SystemWidget(QtWidgets.QWidget): def reset(self): reset_default_settings() - if self.content_layout.count() != 0: - for widget in self.input_fields: - self.content_layout.removeWidget(widget) - widget.deleteLater() - self.input_fields.clear() + self.input_fields.clear() + while self.content_layout.count() != 0: + widget = self.content_layout.itemAt(0).widget() + self.content_layout.removeWidget(widget) + widget.deleteLater() self.schema = lib.gui_schema("system_schema", "0_system_gui_schema") self.keys = self.schema.get("keys", []) From b0d1b9575177852d4bb14c819b52f031f0317647 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 24 Sep 2020 16:48:16 +0200 Subject: [PATCH 064/176] fix merge bug --- pype/tools/settings/settings/widgets/item_types.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 71516a1efc..addce2b6b5 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2499,8 +2499,6 @@ class DictWidget(QtWidgets.QWidget, SettingObject): override_values = parent_values.get(self.key, override_values) self._is_overriden = self.key in groups - else: - override_values = parent_values try: self.validate_value(override_values) From 7b93174d920d3f7f4dc582bdae75b155b19c64a7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 30 Sep 2020 14:39:30 +0200 Subject: [PATCH 065/176] moved environments folder one level higher --- .../{system_settings => }/environments/avalon.json | 0 .../{system_settings => }/environments/blender.json | 3 ++- .../{system_settings => }/environments/celaction.json | 0 .../{system_settings => }/environments/deadline.json | 0 .../{system_settings => }/environments/ftrack.json | 0 .../{system_settings => }/environments/global.json | 6 +++--- .../{system_settings => }/environments/harmony.json | 0 .../{system_settings => }/environments/houdini.json | 0 .../defaults/{system_settings => }/environments/maya.json | 0 .../{system_settings => }/environments/maya_2018.json | 0 .../{system_settings => }/environments/maya_2020.json | 0 .../{system_settings => }/environments/mayabatch.json | 0 .../{system_settings => }/environments/mayabatch_2019.json | 0 .../{system_settings => }/environments/mtoa_3.1.1.json | 0 .../{system_settings => }/environments/muster.json | 0 .../defaults/{system_settings => }/environments/nuke.json | 0 .../{system_settings => }/environments/nukestudio.json | 0 .../environments/nukestudio_10.0.json | 0 .../defaults/{system_settings => }/environments/nukex.json | 0 .../{system_settings => }/environments/nukex_10.0.json | 0 pype/settings/defaults/environments/photoshop.json | 7 +++++++ .../{system_settings => }/environments/premiere.json | 0 .../{system_settings => }/environments/resolve.json | 0 .../{system_settings => }/environments/storyboardpro.json | 0 .../{system_settings => }/environments/unreal_4.24.json | 0 .../{system_settings => }/environments/vray_4300.json | 0 .../defaults/system_settings/environments/photoshop.json | 4 ---- 27 files changed, 12 insertions(+), 8 deletions(-) rename pype/settings/defaults/{system_settings => }/environments/avalon.json (100%) rename pype/settings/defaults/{system_settings => }/environments/blender.json (82%) rename pype/settings/defaults/{system_settings => }/environments/celaction.json (100%) rename pype/settings/defaults/{system_settings => }/environments/deadline.json (100%) rename pype/settings/defaults/{system_settings => }/environments/ftrack.json (100%) rename pype/settings/defaults/{system_settings => }/environments/global.json (91%) rename pype/settings/defaults/{system_settings => }/environments/harmony.json (100%) rename pype/settings/defaults/{system_settings => }/environments/houdini.json (100%) rename pype/settings/defaults/{system_settings => }/environments/maya.json (100%) rename pype/settings/defaults/{system_settings => }/environments/maya_2018.json (100%) rename pype/settings/defaults/{system_settings => }/environments/maya_2020.json (100%) rename pype/settings/defaults/{system_settings => }/environments/mayabatch.json (100%) rename pype/settings/defaults/{system_settings => }/environments/mayabatch_2019.json (100%) rename pype/settings/defaults/{system_settings => }/environments/mtoa_3.1.1.json (100%) rename pype/settings/defaults/{system_settings => }/environments/muster.json (100%) rename pype/settings/defaults/{system_settings => }/environments/nuke.json (100%) rename pype/settings/defaults/{system_settings => }/environments/nukestudio.json (100%) rename pype/settings/defaults/{system_settings => }/environments/nukestudio_10.0.json (100%) rename pype/settings/defaults/{system_settings => }/environments/nukex.json (100%) rename pype/settings/defaults/{system_settings => }/environments/nukex_10.0.json (100%) create mode 100644 pype/settings/defaults/environments/photoshop.json rename pype/settings/defaults/{system_settings => }/environments/premiere.json (100%) rename pype/settings/defaults/{system_settings => }/environments/resolve.json (100%) rename pype/settings/defaults/{system_settings => }/environments/storyboardpro.json (100%) rename pype/settings/defaults/{system_settings => }/environments/unreal_4.24.json (100%) rename pype/settings/defaults/{system_settings => }/environments/vray_4300.json (100%) delete mode 100644 pype/settings/defaults/system_settings/environments/photoshop.json diff --git a/pype/settings/defaults/system_settings/environments/avalon.json b/pype/settings/defaults/environments/avalon.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/avalon.json rename to pype/settings/defaults/environments/avalon.json diff --git a/pype/settings/defaults/system_settings/environments/blender.json b/pype/settings/defaults/environments/blender.json similarity index 82% rename from pype/settings/defaults/system_settings/environments/blender.json rename to pype/settings/defaults/environments/blender.json index 6f4f6a012d..00a4070b8e 100644 --- a/pype/settings/defaults/system_settings/environments/blender.json +++ b/pype/settings/defaults/environments/blender.json @@ -3,5 +3,6 @@ "PYTHONPATH": [ "{PYPE_SETUP_PATH}/repos/avalon-core/setup/blender", "{PYTHONPATH}" - ] + ], + "CREATE_NEW_CONSOLE": "yes" } diff --git a/pype/settings/defaults/system_settings/environments/celaction.json b/pype/settings/defaults/environments/celaction.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/celaction.json rename to pype/settings/defaults/environments/celaction.json diff --git a/pype/settings/defaults/system_settings/environments/deadline.json b/pype/settings/defaults/environments/deadline.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/deadline.json rename to pype/settings/defaults/environments/deadline.json diff --git a/pype/settings/defaults/system_settings/environments/ftrack.json b/pype/settings/defaults/environments/ftrack.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/ftrack.json rename to pype/settings/defaults/environments/ftrack.json diff --git a/pype/settings/defaults/system_settings/environments/global.json b/pype/settings/defaults/environments/global.json similarity index 91% rename from pype/settings/defaults/system_settings/environments/global.json rename to pype/settings/defaults/environments/global.json index ef528e6857..ba467d2f5d 100644 --- a/pype/settings/defaults/system_settings/environments/global.json +++ b/pype/settings/defaults/environments/global.json @@ -6,9 +6,9 @@ "PYPE_PROJECT_PLUGINS": "", "STUDIO_SOFT": "{PYP_SETUP_ROOT}/soft", "FFMPEG_PATH": { - "windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/ffmpeg_exec/windows/bin", - "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/ffmpeg_exec/darwin/bin", - "linux": "{VIRTUAL_ENV}/localized/ffmpeg_exec/linux:{PYPE_SETUP_PATH}/vendor/ffmpeg_exec/linux" + "windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/windows/bin", + "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin", + "linux": "{VIRTUAL_ENV}/localized/ffmpeg_exec/linux:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/linux" }, "DJV_PATH": { "windows": [ diff --git a/pype/settings/defaults/system_settings/environments/harmony.json b/pype/settings/defaults/environments/harmony.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/harmony.json rename to pype/settings/defaults/environments/harmony.json diff --git a/pype/settings/defaults/system_settings/environments/houdini.json b/pype/settings/defaults/environments/houdini.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/houdini.json rename to pype/settings/defaults/environments/houdini.json diff --git a/pype/settings/defaults/system_settings/environments/maya.json b/pype/settings/defaults/environments/maya.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/maya.json rename to pype/settings/defaults/environments/maya.json diff --git a/pype/settings/defaults/system_settings/environments/maya_2018.json b/pype/settings/defaults/environments/maya_2018.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/maya_2018.json rename to pype/settings/defaults/environments/maya_2018.json diff --git a/pype/settings/defaults/system_settings/environments/maya_2020.json b/pype/settings/defaults/environments/maya_2020.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/maya_2020.json rename to pype/settings/defaults/environments/maya_2020.json diff --git a/pype/settings/defaults/system_settings/environments/mayabatch.json b/pype/settings/defaults/environments/mayabatch.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/mayabatch.json rename to pype/settings/defaults/environments/mayabatch.json diff --git a/pype/settings/defaults/system_settings/environments/mayabatch_2019.json b/pype/settings/defaults/environments/mayabatch_2019.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/mayabatch_2019.json rename to pype/settings/defaults/environments/mayabatch_2019.json diff --git a/pype/settings/defaults/system_settings/environments/mtoa_3.1.1.json b/pype/settings/defaults/environments/mtoa_3.1.1.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/mtoa_3.1.1.json rename to pype/settings/defaults/environments/mtoa_3.1.1.json diff --git a/pype/settings/defaults/system_settings/environments/muster.json b/pype/settings/defaults/environments/muster.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/muster.json rename to pype/settings/defaults/environments/muster.json diff --git a/pype/settings/defaults/system_settings/environments/nuke.json b/pype/settings/defaults/environments/nuke.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/nuke.json rename to pype/settings/defaults/environments/nuke.json diff --git a/pype/settings/defaults/system_settings/environments/nukestudio.json b/pype/settings/defaults/environments/nukestudio.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/nukestudio.json rename to pype/settings/defaults/environments/nukestudio.json diff --git a/pype/settings/defaults/system_settings/environments/nukestudio_10.0.json b/pype/settings/defaults/environments/nukestudio_10.0.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/nukestudio_10.0.json rename to pype/settings/defaults/environments/nukestudio_10.0.json diff --git a/pype/settings/defaults/system_settings/environments/nukex.json b/pype/settings/defaults/environments/nukex.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/nukex.json rename to pype/settings/defaults/environments/nukex.json diff --git a/pype/settings/defaults/system_settings/environments/nukex_10.0.json b/pype/settings/defaults/environments/nukex_10.0.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/nukex_10.0.json rename to pype/settings/defaults/environments/nukex_10.0.json diff --git a/pype/settings/defaults/environments/photoshop.json b/pype/settings/defaults/environments/photoshop.json new file mode 100644 index 0000000000..d39634ce20 --- /dev/null +++ b/pype/settings/defaults/environments/photoshop.json @@ -0,0 +1,7 @@ +{ + "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH": "1", + "PYTHONPATH": "{PYTHONPATH}", + "PYPE_LOG_NO_COLORS": "Yes", + "WEBSOCKET_URL": "ws://localhost:8099/ws/", + "WORKFILES_SAVE_AS": "Yes" +} diff --git a/pype/settings/defaults/system_settings/environments/premiere.json b/pype/settings/defaults/environments/premiere.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/premiere.json rename to pype/settings/defaults/environments/premiere.json diff --git a/pype/settings/defaults/system_settings/environments/resolve.json b/pype/settings/defaults/environments/resolve.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/resolve.json rename to pype/settings/defaults/environments/resolve.json diff --git a/pype/settings/defaults/system_settings/environments/storyboardpro.json b/pype/settings/defaults/environments/storyboardpro.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/storyboardpro.json rename to pype/settings/defaults/environments/storyboardpro.json diff --git a/pype/settings/defaults/system_settings/environments/unreal_4.24.json b/pype/settings/defaults/environments/unreal_4.24.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/unreal_4.24.json rename to pype/settings/defaults/environments/unreal_4.24.json diff --git a/pype/settings/defaults/system_settings/environments/vray_4300.json b/pype/settings/defaults/environments/vray_4300.json similarity index 100% rename from pype/settings/defaults/system_settings/environments/vray_4300.json rename to pype/settings/defaults/environments/vray_4300.json diff --git a/pype/settings/defaults/system_settings/environments/photoshop.json b/pype/settings/defaults/system_settings/environments/photoshop.json deleted file mode 100644 index 2208a88665..0000000000 --- a/pype/settings/defaults/system_settings/environments/photoshop.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH": "1", - "PYTHONPATH": "{PYTHONPATH}" -} From 68c10ab1ee47e9ddc408d7006c2562941f282963 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 30 Sep 2020 14:39:44 +0200 Subject: [PATCH 066/176] added launchers to pype --- .../defaults/launchers/blender_2.80.toml | 8 +++++ .../defaults/launchers/blender_2.81.toml | 9 ++++++ .../defaults/launchers/blender_2.82.toml | 9 ++++++ .../defaults/launchers/blender_2.83.toml | 9 ++++++ .../defaults/launchers/celaction_local.toml | 9 ++++++ .../defaults/launchers/celaction_publish.toml | 8 +++++ .../defaults/launchers/darwin/blender_2.82 | 2 ++ .../defaults/launchers/darwin/harmony_17 | 9 ++++++ .../launchers/darwin/harmony_17_launch | 5 ++++ .../defaults/launchers/darwin/python3 | 2 ++ .../defaults/launchers/harmony_17.toml | 9 ++++++ .../defaults/launchers/houdini_16.toml | 8 +++++ .../defaults/launchers/houdini_17.toml | 8 +++++ .../defaults/launchers/houdini_18.toml | 8 +++++ .../defaults/launchers/linux/maya2016 | 8 +++++ .../defaults/launchers/linux/maya2017 | 8 +++++ .../defaults/launchers/linux/maya2018 | 8 +++++ .../defaults/launchers/linux/maya2019 | 8 +++++ .../defaults/launchers/linux/maya2020 | 8 +++++ .../defaults/launchers/linux/nuke11.3 | 2 ++ .../defaults/launchers/linux/nuke12.0 | 2 ++ .../defaults/launchers/linux/nukestudio11.3 | 2 ++ .../defaults/launchers/linux/nukestudio12.0 | 2 ++ .../defaults/launchers/linux/nukex11.3 | 2 ++ .../defaults/launchers/linux/nukex12.0 | 2 ++ .../defaults/launchers/maya_2016.toml | 27 +++++++++++++++++ .../defaults/launchers/maya_2017.toml | 29 +++++++++++++++++++ .../defaults/launchers/maya_2018.toml | 15 ++++++++++ .../defaults/launchers/maya_2019.toml | 15 ++++++++++ .../defaults/launchers/maya_2020.toml | 15 ++++++++++ .../defaults/launchers/mayabatch_2019.toml | 17 +++++++++++ .../defaults/launchers/mayabatch_2020.toml | 17 +++++++++++ .../defaults/launchers/mayapy2016.toml | 17 +++++++++++ .../defaults/launchers/mayapy2017.toml | 17 +++++++++++ .../defaults/launchers/mayapy2018.toml | 17 +++++++++++ .../defaults/launchers/mayapy2019.toml | 17 +++++++++++ .../defaults/launchers/mayapy2020.toml | 17 +++++++++++ pype/settings/defaults/launchers/myapp.toml | 5 ++++ .../defaults/launchers/nuke_10.0.toml | 8 +++++ .../defaults/launchers/nuke_11.0.toml | 8 +++++ .../defaults/launchers/nuke_11.2.toml | 8 +++++ .../defaults/launchers/nuke_11.3.toml | 8 +++++ .../defaults/launchers/nuke_12.0.toml | 8 +++++ .../defaults/launchers/nukestudio_10.0.toml | 8 +++++ .../defaults/launchers/nukestudio_11.0.toml | 8 +++++ .../defaults/launchers/nukestudio_11.2.toml | 8 +++++ .../defaults/launchers/nukestudio_11.3.toml | 8 +++++ .../defaults/launchers/nukestudio_12.0.toml | 8 +++++ .../defaults/launchers/nukex_10.0.toml | 8 +++++ .../defaults/launchers/nukex_11.0.toml | 8 +++++ .../defaults/launchers/nukex_11.2.toml | 8 +++++ .../defaults/launchers/nukex_11.3.toml | 8 +++++ .../defaults/launchers/nukex_12.0.toml | 8 +++++ .../defaults/launchers/photoshop_2020.toml | 9 ++++++ .../defaults/launchers/premiere_2019.toml | 9 ++++++ .../defaults/launchers/premiere_2020.toml | 10 +++++++ .../settings/defaults/launchers/python_2.toml | 12 ++++++++ .../settings/defaults/launchers/python_3.toml | 12 ++++++++ .../defaults/launchers/resolve_16.toml | 10 +++++++ pype/settings/defaults/launchers/shell.toml | 7 +++++ .../defaults/launchers/storyboardpro_7.toml | 9 ++++++ .../defaults/launchers/unreal_4.24.toml | 10 +++++++ .../launchers/windows/blender_2.80.bat | 11 +++++++ .../launchers/windows/blender_2.81.bat | 11 +++++++ .../launchers/windows/blender_2.82.bat | 11 +++++++ .../launchers/windows/blender_2.83.bat | 11 +++++++ .../launchers/windows/celaction_local.bat | 19 ++++++++++++ .../launchers/windows/celaction_publish.bat | 3 ++ .../defaults/launchers/windows/harmony_17.bat | 13 +++++++++ .../defaults/launchers/windows/houdini_16.bat | 13 +++++++++ .../defaults/launchers/windows/houdini_17.bat | 13 +++++++++ .../defaults/launchers/windows/houdini_18.bat | 13 +++++++++ .../defaults/launchers/windows/maya2016.bat | 17 +++++++++++ .../defaults/launchers/windows/maya2017.bat | 17 +++++++++++ .../defaults/launchers/windows/maya2018.bat | 17 +++++++++++ .../defaults/launchers/windows/maya2019.bat | 17 +++++++++++ .../defaults/launchers/windows/maya2020.bat | 17 +++++++++++ .../launchers/windows/mayabatch2019.bat | 14 +++++++++ .../launchers/windows/mayabatch2020.bat | 14 +++++++++ .../defaults/launchers/windows/mayapy2016.bat | 13 +++++++++ .../defaults/launchers/windows/mayapy2017.bat | 13 +++++++++ .../defaults/launchers/windows/mayapy2018.bat | 13 +++++++++ .../defaults/launchers/windows/mayapy2019.bat | 13 +++++++++ .../defaults/launchers/windows/mayapy2020.bat | 13 +++++++++ .../defaults/launchers/windows/nuke10.0.bat | 13 +++++++++ .../defaults/launchers/windows/nuke11.0.bat | 13 +++++++++ .../defaults/launchers/windows/nuke11.2.bat | 13 +++++++++ .../defaults/launchers/windows/nuke11.3.bat | 13 +++++++++ .../defaults/launchers/windows/nuke12.0.bat | 13 +++++++++ .../launchers/windows/nukestudio10.0.bat | 13 +++++++++ .../launchers/windows/nukestudio11.0.bat | 13 +++++++++ .../launchers/windows/nukestudio11.2.bat | 13 +++++++++ .../launchers/windows/nukestudio11.3.bat | 13 +++++++++ .../launchers/windows/nukestudio12.0.bat | 13 +++++++++ .../defaults/launchers/windows/nukex10.0.bat | 13 +++++++++ .../defaults/launchers/windows/nukex11.0.bat | 13 +++++++++ .../defaults/launchers/windows/nukex11.2.bat | 13 +++++++++ .../defaults/launchers/windows/nukex11.3.bat | 13 +++++++++ .../defaults/launchers/windows/nukex12.0.bat | 13 +++++++++ .../launchers/windows/photoshop_2020.bat | 15 ++++++++++ .../launchers/windows/premiere_pro_2019.bat | 14 +++++++++ .../launchers/windows/premiere_pro_2020.bat | 13 +++++++++ .../defaults/launchers/windows/python3.bat | 13 +++++++++ .../defaults/launchers/windows/resolve_16.bat | 17 +++++++++++ .../defaults/launchers/windows/shell.bat | 2 ++ .../launchers/windows/storyboardpro_7.bat | 13 +++++++++ .../defaults/launchers/windows/unreal.bat | 11 +++++++ 107 files changed, 1177 insertions(+) create mode 100644 pype/settings/defaults/launchers/blender_2.80.toml create mode 100644 pype/settings/defaults/launchers/blender_2.81.toml create mode 100644 pype/settings/defaults/launchers/blender_2.82.toml create mode 100644 pype/settings/defaults/launchers/blender_2.83.toml create mode 100644 pype/settings/defaults/launchers/celaction_local.toml create mode 100644 pype/settings/defaults/launchers/celaction_publish.toml create mode 100644 pype/settings/defaults/launchers/darwin/blender_2.82 create mode 100644 pype/settings/defaults/launchers/darwin/harmony_17 create mode 100644 pype/settings/defaults/launchers/darwin/harmony_17_launch create mode 100644 pype/settings/defaults/launchers/darwin/python3 create mode 100644 pype/settings/defaults/launchers/harmony_17.toml create mode 100644 pype/settings/defaults/launchers/houdini_16.toml create mode 100644 pype/settings/defaults/launchers/houdini_17.toml create mode 100644 pype/settings/defaults/launchers/houdini_18.toml create mode 100644 pype/settings/defaults/launchers/linux/maya2016 create mode 100644 pype/settings/defaults/launchers/linux/maya2017 create mode 100644 pype/settings/defaults/launchers/linux/maya2018 create mode 100644 pype/settings/defaults/launchers/linux/maya2019 create mode 100644 pype/settings/defaults/launchers/linux/maya2020 create mode 100644 pype/settings/defaults/launchers/linux/nuke11.3 create mode 100644 pype/settings/defaults/launchers/linux/nuke12.0 create mode 100644 pype/settings/defaults/launchers/linux/nukestudio11.3 create mode 100644 pype/settings/defaults/launchers/linux/nukestudio12.0 create mode 100644 pype/settings/defaults/launchers/linux/nukex11.3 create mode 100644 pype/settings/defaults/launchers/linux/nukex12.0 create mode 100644 pype/settings/defaults/launchers/maya_2016.toml create mode 100644 pype/settings/defaults/launchers/maya_2017.toml create mode 100644 pype/settings/defaults/launchers/maya_2018.toml create mode 100644 pype/settings/defaults/launchers/maya_2019.toml create mode 100644 pype/settings/defaults/launchers/maya_2020.toml create mode 100644 pype/settings/defaults/launchers/mayabatch_2019.toml create mode 100644 pype/settings/defaults/launchers/mayabatch_2020.toml create mode 100644 pype/settings/defaults/launchers/mayapy2016.toml create mode 100644 pype/settings/defaults/launchers/mayapy2017.toml create mode 100644 pype/settings/defaults/launchers/mayapy2018.toml create mode 100644 pype/settings/defaults/launchers/mayapy2019.toml create mode 100644 pype/settings/defaults/launchers/mayapy2020.toml create mode 100644 pype/settings/defaults/launchers/myapp.toml create mode 100644 pype/settings/defaults/launchers/nuke_10.0.toml create mode 100644 pype/settings/defaults/launchers/nuke_11.0.toml create mode 100644 pype/settings/defaults/launchers/nuke_11.2.toml create mode 100644 pype/settings/defaults/launchers/nuke_11.3.toml create mode 100644 pype/settings/defaults/launchers/nuke_12.0.toml create mode 100644 pype/settings/defaults/launchers/nukestudio_10.0.toml create mode 100644 pype/settings/defaults/launchers/nukestudio_11.0.toml create mode 100644 pype/settings/defaults/launchers/nukestudio_11.2.toml create mode 100644 pype/settings/defaults/launchers/nukestudio_11.3.toml create mode 100644 pype/settings/defaults/launchers/nukestudio_12.0.toml create mode 100644 pype/settings/defaults/launchers/nukex_10.0.toml create mode 100644 pype/settings/defaults/launchers/nukex_11.0.toml create mode 100644 pype/settings/defaults/launchers/nukex_11.2.toml create mode 100644 pype/settings/defaults/launchers/nukex_11.3.toml create mode 100644 pype/settings/defaults/launchers/nukex_12.0.toml create mode 100644 pype/settings/defaults/launchers/photoshop_2020.toml create mode 100644 pype/settings/defaults/launchers/premiere_2019.toml create mode 100644 pype/settings/defaults/launchers/premiere_2020.toml create mode 100644 pype/settings/defaults/launchers/python_2.toml create mode 100644 pype/settings/defaults/launchers/python_3.toml create mode 100644 pype/settings/defaults/launchers/resolve_16.toml create mode 100644 pype/settings/defaults/launchers/shell.toml create mode 100644 pype/settings/defaults/launchers/storyboardpro_7.toml create mode 100644 pype/settings/defaults/launchers/unreal_4.24.toml create mode 100644 pype/settings/defaults/launchers/windows/blender_2.80.bat create mode 100644 pype/settings/defaults/launchers/windows/blender_2.81.bat create mode 100644 pype/settings/defaults/launchers/windows/blender_2.82.bat create mode 100644 pype/settings/defaults/launchers/windows/blender_2.83.bat create mode 100644 pype/settings/defaults/launchers/windows/celaction_local.bat create mode 100644 pype/settings/defaults/launchers/windows/celaction_publish.bat create mode 100644 pype/settings/defaults/launchers/windows/harmony_17.bat create mode 100644 pype/settings/defaults/launchers/windows/houdini_16.bat create mode 100644 pype/settings/defaults/launchers/windows/houdini_17.bat create mode 100644 pype/settings/defaults/launchers/windows/houdini_18.bat create mode 100644 pype/settings/defaults/launchers/windows/maya2016.bat create mode 100644 pype/settings/defaults/launchers/windows/maya2017.bat create mode 100644 pype/settings/defaults/launchers/windows/maya2018.bat create mode 100644 pype/settings/defaults/launchers/windows/maya2019.bat create mode 100644 pype/settings/defaults/launchers/windows/maya2020.bat create mode 100644 pype/settings/defaults/launchers/windows/mayabatch2019.bat create mode 100644 pype/settings/defaults/launchers/windows/mayabatch2020.bat create mode 100644 pype/settings/defaults/launchers/windows/mayapy2016.bat create mode 100644 pype/settings/defaults/launchers/windows/mayapy2017.bat create mode 100644 pype/settings/defaults/launchers/windows/mayapy2018.bat create mode 100644 pype/settings/defaults/launchers/windows/mayapy2019.bat create mode 100644 pype/settings/defaults/launchers/windows/mayapy2020.bat create mode 100644 pype/settings/defaults/launchers/windows/nuke10.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nuke11.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nuke11.2.bat create mode 100644 pype/settings/defaults/launchers/windows/nuke11.3.bat create mode 100644 pype/settings/defaults/launchers/windows/nuke12.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukestudio10.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukestudio11.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukestudio11.2.bat create mode 100644 pype/settings/defaults/launchers/windows/nukestudio11.3.bat create mode 100644 pype/settings/defaults/launchers/windows/nukestudio12.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukex10.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukex11.0.bat create mode 100644 pype/settings/defaults/launchers/windows/nukex11.2.bat create mode 100644 pype/settings/defaults/launchers/windows/nukex11.3.bat create mode 100644 pype/settings/defaults/launchers/windows/nukex12.0.bat create mode 100644 pype/settings/defaults/launchers/windows/photoshop_2020.bat create mode 100644 pype/settings/defaults/launchers/windows/premiere_pro_2019.bat create mode 100644 pype/settings/defaults/launchers/windows/premiere_pro_2020.bat create mode 100644 pype/settings/defaults/launchers/windows/python3.bat create mode 100644 pype/settings/defaults/launchers/windows/resolve_16.bat create mode 100644 pype/settings/defaults/launchers/windows/shell.bat create mode 100644 pype/settings/defaults/launchers/windows/storyboardpro_7.bat create mode 100644 pype/settings/defaults/launchers/windows/unreal.bat diff --git a/pype/settings/defaults/launchers/blender_2.80.toml b/pype/settings/defaults/launchers/blender_2.80.toml new file mode 100644 index 0000000000..88b5ea0c11 --- /dev/null +++ b/pype/settings/defaults/launchers/blender_2.80.toml @@ -0,0 +1,8 @@ +application_dir = "blender" +executable = "blender_2.80" +schema = "avalon-core:application-1.0" +label = "Blender" +label_variant = "2.80" +ftrack_label = "Blender" +icon = "app_icons/blender.png" +ftrack_icon = "{}/app_icons/blender.png" diff --git a/pype/settings/defaults/launchers/blender_2.81.toml b/pype/settings/defaults/launchers/blender_2.81.toml new file mode 100644 index 0000000000..072eaa8141 --- /dev/null +++ b/pype/settings/defaults/launchers/blender_2.81.toml @@ -0,0 +1,9 @@ +application_dir = "blender" +executable = "blender_2.81" +schema = "avalon-core:application-1.0" +label = "Blender" +label_variant = "2.81" +icon = "app_icons/blender.png" + +ftrack_label = "Blender" +ftrack_icon = '{}/app_icons/blender.png' diff --git a/pype/settings/defaults/launchers/blender_2.82.toml b/pype/settings/defaults/launchers/blender_2.82.toml new file mode 100644 index 0000000000..a485f790f1 --- /dev/null +++ b/pype/settings/defaults/launchers/blender_2.82.toml @@ -0,0 +1,9 @@ +application_dir = "blender" +executable = "blender_2.82" +schema = "avalon-core:application-1.0" +label = "Blender" +label_variant = "2.82" +icon = "app_icons/blender.png" + +ftrack_label = "Blender" +ftrack_icon = '{}/app_icons/blender.png' diff --git a/pype/settings/defaults/launchers/blender_2.83.toml b/pype/settings/defaults/launchers/blender_2.83.toml new file mode 100644 index 0000000000..0f98151d01 --- /dev/null +++ b/pype/settings/defaults/launchers/blender_2.83.toml @@ -0,0 +1,9 @@ +application_dir = "blender" +executable = "blender_2.83" +schema = "avalon-core:application-1.0" +label = "Blender" +label_variant = "2.83" +icon = "app_icons/blender.png" + +ftrack_label = "Blender" +ftrack_icon = '{}/app_icons/blender.png' diff --git a/pype/settings/defaults/launchers/celaction_local.toml b/pype/settings/defaults/launchers/celaction_local.toml new file mode 100644 index 0000000000..6cc5d4fa0e --- /dev/null +++ b/pype/settings/defaults/launchers/celaction_local.toml @@ -0,0 +1,9 @@ +executable = "celaction_local" +schema = "avalon-core:application-1.0" +application_dir = "celaction" +label = "CelAction2D" +icon = "app_icons/celaction_local.png" +launch_hook = "pype/hooks/celaction/prelaunch.py/CelactionPrelaunchHook" + +ftrack_label = "CelAction2D" +ftrack_icon = '{}/app_icons/celaction_local.png' diff --git a/pype/settings/defaults/launchers/celaction_publish.toml b/pype/settings/defaults/launchers/celaction_publish.toml new file mode 100644 index 0000000000..dc7ac82673 --- /dev/null +++ b/pype/settings/defaults/launchers/celaction_publish.toml @@ -0,0 +1,8 @@ +schema = "avalon-core:application-1.0" +application_dir = "shell" +executable = "celaction_publish" +label = "Celaction Shell" +icon = "app_icons/celaction.png" + +[environment] +CREATE_NEW_CONSOLE = "Yes" diff --git a/pype/settings/defaults/launchers/darwin/blender_2.82 b/pype/settings/defaults/launchers/darwin/blender_2.82 new file mode 100644 index 0000000000..8254411ea2 --- /dev/null +++ b/pype/settings/defaults/launchers/darwin/blender_2.82 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +open -a blender $@ diff --git a/pype/settings/defaults/launchers/darwin/harmony_17 b/pype/settings/defaults/launchers/darwin/harmony_17 new file mode 100644 index 0000000000..b7eba2c2d0 --- /dev/null +++ b/pype/settings/defaults/launchers/darwin/harmony_17 @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +DIRNAME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +set >~/environment.tmp +if [ $? -ne -0 ] ; then + echo "ERROR: cannot write to '~/environment.tmp'!" + read -n 1 -s -r -p "Press any key to exit" + return +fi +open -a Terminal.app "$DIRNAME/harmony_17_launch" diff --git a/pype/settings/defaults/launchers/darwin/harmony_17_launch b/pype/settings/defaults/launchers/darwin/harmony_17_launch new file mode 100644 index 0000000000..5dcf5db57e --- /dev/null +++ b/pype/settings/defaults/launchers/darwin/harmony_17_launch @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +source ~/environment.tmp +export $(cut -d= -f1 ~/environment.tmp) +exe="/Applications/Toon Boom Harmony 17 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" +$PYPE_PYTHON_EXE -c "import avalon.harmony;avalon.harmony.launch('$exe')" diff --git a/pype/settings/defaults/launchers/darwin/python3 b/pype/settings/defaults/launchers/darwin/python3 new file mode 100644 index 0000000000..c2b82c7638 --- /dev/null +++ b/pype/settings/defaults/launchers/darwin/python3 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +open /usr/bin/python3 --args $@ diff --git a/pype/settings/defaults/launchers/harmony_17.toml b/pype/settings/defaults/launchers/harmony_17.toml new file mode 100644 index 0000000000..dd1c929b1b --- /dev/null +++ b/pype/settings/defaults/launchers/harmony_17.toml @@ -0,0 +1,9 @@ +application_dir = "harmony" +label = "Harmony" +label_variant = "17" +ftrack_label = "Harmony" +schema = "avalon-core:application-1.0" +executable = "harmony_17" +description = "" +icon = "app_icons/harmony.png" +ftrack_icon = '{}/app_icons/harmony.png' diff --git a/pype/settings/defaults/launchers/houdini_16.toml b/pype/settings/defaults/launchers/houdini_16.toml new file mode 100644 index 0000000000..0a0876a264 --- /dev/null +++ b/pype/settings/defaults/launchers/houdini_16.toml @@ -0,0 +1,8 @@ +executable = "houdini_16" +schema = "avalon-core:application-1.0" +application_dir = "houdini" +label = "Houdini" +label_variant = "16" +ftrack_label = "Houdini" +icon = "app_icons/houdini.png" +ftrack_icon = '{}/app_icons/houdini.png' diff --git a/pype/settings/defaults/launchers/houdini_17.toml b/pype/settings/defaults/launchers/houdini_17.toml new file mode 100644 index 0000000000..203f5cdb9b --- /dev/null +++ b/pype/settings/defaults/launchers/houdini_17.toml @@ -0,0 +1,8 @@ +executable = "houdini_17" +schema = "avalon-core:application-1.0" +application_dir = "houdini" +label = "Houdini" +label_variant = "17" +ftrack_label = "Houdini" +icon = "app_icons/houdini.png" +ftrack_icon = '{}/app_icons/houdini.png' diff --git a/pype/settings/defaults/launchers/houdini_18.toml b/pype/settings/defaults/launchers/houdini_18.toml new file mode 100644 index 0000000000..40f530c291 --- /dev/null +++ b/pype/settings/defaults/launchers/houdini_18.toml @@ -0,0 +1,8 @@ +executable = "houdini_18" +schema = "avalon-core:application-1.0" +application_dir = "houdini" +label = "Houdini" +label_variant = "18" +ftrack_label = "Houdini" +icon = "app_icons/houdini.png" +ftrack_icon = '{}/app_icons/houdini.png' diff --git a/pype/settings/defaults/launchers/linux/maya2016 b/pype/settings/defaults/launchers/linux/maya2016 new file mode 100644 index 0000000000..98424304b1 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/maya2016 @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +maya_path = "/usr/autodesk/maya2016/bin/maya" + +if [[ -z $PYPE_LOG_NO_COLORS ]]; then + $maya_path -file "$AVALON_LAST_WORKFILE" $@ +else + $maya_path $@ diff --git a/pype/settings/defaults/launchers/linux/maya2017 b/pype/settings/defaults/launchers/linux/maya2017 new file mode 100644 index 0000000000..7a2662a55e --- /dev/null +++ b/pype/settings/defaults/launchers/linux/maya2017 @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +maya_path = "/usr/autodesk/maya2017/bin/maya" + +if [[ -z $AVALON_LAST_WORKFILE ]]; then + $maya_path -file "$AVALON_LAST_WORKFILE" $@ +else + $maya_path $@ diff --git a/pype/settings/defaults/launchers/linux/maya2018 b/pype/settings/defaults/launchers/linux/maya2018 new file mode 100644 index 0000000000..db832b3fe7 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/maya2018 @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +maya_path = "/usr/autodesk/maya2018/bin/maya" + +if [[ -z $AVALON_LAST_WORKFILE ]]; then + $maya_path -file "$AVALON_LAST_WORKFILE" $@ +else + $maya_path $@ diff --git a/pype/settings/defaults/launchers/linux/maya2019 b/pype/settings/defaults/launchers/linux/maya2019 new file mode 100644 index 0000000000..8398734ab9 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/maya2019 @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +maya_path = "/usr/autodesk/maya2019/bin/maya" + +if [[ -z $AVALON_LAST_WORKFILE ]]; then + $maya_path -file "$AVALON_LAST_WORKFILE" $@ +else + $maya_path $@ diff --git a/pype/settings/defaults/launchers/linux/maya2020 b/pype/settings/defaults/launchers/linux/maya2020 new file mode 100644 index 0000000000..18a1edd598 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/maya2020 @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +maya_path = "/usr/autodesk/maya2020/bin/maya" + +if [[ -z $AVALON_LAST_WORKFILE ]]; then + $maya_path -file "$AVALON_LAST_WORKFILE" $@ +else + $maya_path $@ diff --git a/pype/settings/defaults/launchers/linux/nuke11.3 b/pype/settings/defaults/launchers/linux/nuke11.3 new file mode 100644 index 0000000000..b1c9a90d74 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nuke11.3 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke11.3v5/Nuke11.3' diff --git a/pype/settings/defaults/launchers/linux/nuke12.0 b/pype/settings/defaults/launchers/linux/nuke12.0 new file mode 100644 index 0000000000..99ea1a6b0c --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nuke12.0 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke12.0v1/Nuke12.0' diff --git a/pype/settings/defaults/launchers/linux/nukestudio11.3 b/pype/settings/defaults/launchers/linux/nukestudio11.3 new file mode 100644 index 0000000000..750d54a7d5 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nukestudio11.3 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke11.3v5/Nuke11.3 --studio' diff --git a/pype/settings/defaults/launchers/linux/nukestudio12.0 b/pype/settings/defaults/launchers/linux/nukestudio12.0 new file mode 100644 index 0000000000..ba5cf654a8 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nukestudio12.0 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke12.0v1/Nuke12.0 --studio' diff --git a/pype/settings/defaults/launchers/linux/nukex11.3 b/pype/settings/defaults/launchers/linux/nukex11.3 new file mode 100644 index 0000000000..d913e4b961 --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nukex11.3 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke11.3v5/Nuke11.3 -nukex' diff --git a/pype/settings/defaults/launchers/linux/nukex12.0 b/pype/settings/defaults/launchers/linux/nukex12.0 new file mode 100644 index 0000000000..da2721c48b --- /dev/null +++ b/pype/settings/defaults/launchers/linux/nukex12.0 @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +gnome-terminal -e '/usr/local/Nuke12.0v1/Nuke12.0 -nukex' diff --git a/pype/settings/defaults/launchers/maya_2016.toml b/pype/settings/defaults/launchers/maya_2016.toml new file mode 100644 index 0000000000..24a463d9c6 --- /dev/null +++ b/pype/settings/defaults/launchers/maya_2016.toml @@ -0,0 +1,27 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya" +label_variant = "2016" +ftrack_label = "Maya" +schema = "avalon-core:application-1.0" +executable = "maya2016" +description = "" +icon = "app_icons/maya.png" +ftrack_icon = '{}/app_icons/maya.png' + +[copy] +"{PYPE_MODULE_ROOT}/pype/resources/maya/workspace.mel" = "workspace.mel" + +[environment] +MAYA_DISABLE_CLIC_IPM = "Yes" # Disable the AdSSO process +MAYA_DISABLE_CIP = "Yes" # Shorten time to boot +MAYA_DISABLE_CER = "Yes" +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/maya_2017.toml b/pype/settings/defaults/launchers/maya_2017.toml new file mode 100644 index 0000000000..5295862e87 --- /dev/null +++ b/pype/settings/defaults/launchers/maya_2017.toml @@ -0,0 +1,29 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya" +label_variant = "2017" +ftrack_label = "Maya" +schema = "avalon-core:application-1.0" +executable = "maya2017" +description = "" +icon = "app_icons/maya.png" +ftrack_icon = '{}/app_icons/maya.png' + +[copy] +"{PYPE_MODULE_ROOT}/pype/resources/maya/workspace.mel" = "workspace.mel" + +[environment] +MAYA_DISABLE_CLIC_IPM = "Yes" # Disable the AdSSO process +MAYA_DISABLE_CIP = "Yes" # Shorten time to boot +MAYA_DISABLE_CER = "Yes" +PYMEL_SKIP_MEL_INIT = "Yes" +LC_ALL= "C" # Mute color management warnings +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/maya_2018.toml b/pype/settings/defaults/launchers/maya_2018.toml new file mode 100644 index 0000000000..2bdff2094d --- /dev/null +++ b/pype/settings/defaults/launchers/maya_2018.toml @@ -0,0 +1,15 @@ +application_dir = "maya" +default_dirs = [ + "renders" +] +label = "Autodesk Maya" +label_variant = "2018" +ftrack_label = "Maya" +schema = "avalon-core:application-1.0" +executable = "maya2018" +description = "" +icon = "app_icons/maya.png" +ftrack_icon = '{}/app_icons/maya.png' + +[copy] +"{PYPE_MODULE_ROOT}/pype/resources/maya/workspace.mel" = "workspace.mel" diff --git a/pype/settings/defaults/launchers/maya_2019.toml b/pype/settings/defaults/launchers/maya_2019.toml new file mode 100644 index 0000000000..8eb88179f9 --- /dev/null +++ b/pype/settings/defaults/launchers/maya_2019.toml @@ -0,0 +1,15 @@ +application_dir = "maya" +default_dirs = [ + "renders" +] +label = "Autodesk Maya" +label_variant = "2019" +ftrack_label = "Maya" +schema = "avalon-core:application-1.0" +executable = "maya2019" +description = "" +icon = "app_icons/maya.png" +ftrack_icon = '{}/app_icons/maya.png' + +[copy] +"{PYPE_MODULE_ROOT}/pype/resources/maya/workspace.mel" = "workspace.mel" diff --git a/pype/settings/defaults/launchers/maya_2020.toml b/pype/settings/defaults/launchers/maya_2020.toml new file mode 100644 index 0000000000..693de0cf9e --- /dev/null +++ b/pype/settings/defaults/launchers/maya_2020.toml @@ -0,0 +1,15 @@ +application_dir = "maya" +default_dirs = [ + "renders" +] +label = "Autodesk Maya" +label_variant = "2020" +ftrack_label = "Maya" +schema = "avalon-core:application-1.0" +executable = "maya2020" +description = "" +icon = "app_icons/maya.png" +ftrack_icon = '{}/app_icons/maya.png' + +[copy] +"{PYPE_MODULE_ROOT}/pype/resources/maya/workspace.mel" = "workspace.mel" diff --git a/pype/settings/defaults/launchers/mayabatch_2019.toml b/pype/settings/defaults/launchers/mayabatch_2019.toml new file mode 100644 index 0000000000..a928618d2b --- /dev/null +++ b/pype/settings/defaults/launchers/mayabatch_2019.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2019x64" +schema = "avalon-core:application-1.0" +executable = "mayabatch2019" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayabatch_2020.toml b/pype/settings/defaults/launchers/mayabatch_2020.toml new file mode 100644 index 0000000000..cd1e1e4474 --- /dev/null +++ b/pype/settings/defaults/launchers/mayabatch_2020.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2020x64" +schema = "avalon-core:application-1.0" +executable = "mayabatch2020" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayapy2016.toml b/pype/settings/defaults/launchers/mayapy2016.toml new file mode 100644 index 0000000000..ad1e3dee86 --- /dev/null +++ b/pype/settings/defaults/launchers/mayapy2016.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2016x64" +schema = "avalon-core:application-1.0" +executable = "mayapy2016" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayapy2017.toml b/pype/settings/defaults/launchers/mayapy2017.toml new file mode 100644 index 0000000000..8d2095ff47 --- /dev/null +++ b/pype/settings/defaults/launchers/mayapy2017.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2017x64" +schema = "avalon-core:application-1.0" +executable = "mayapy2017" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayapy2018.toml b/pype/settings/defaults/launchers/mayapy2018.toml new file mode 100644 index 0000000000..597744fd85 --- /dev/null +++ b/pype/settings/defaults/launchers/mayapy2018.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2018x64" +schema = "avalon-core:application-1.0" +executable = "mayapy2017" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayapy2019.toml b/pype/settings/defaults/launchers/mayapy2019.toml new file mode 100644 index 0000000000..3c8a9860f9 --- /dev/null +++ b/pype/settings/defaults/launchers/mayapy2019.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2019x64" +schema = "avalon-core:application-1.0" +executable = "mayapy2019" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/mayapy2020.toml b/pype/settings/defaults/launchers/mayapy2020.toml new file mode 100644 index 0000000000..8f2d2e4a67 --- /dev/null +++ b/pype/settings/defaults/launchers/mayapy2020.toml @@ -0,0 +1,17 @@ +application_dir = "maya" +default_dirs = [ + "scenes", + "data", + "renderData/shaders", + "images" +] +label = "Autodesk Maya 2020x64" +schema = "avalon-core:application-1.0" +executable = "mayapy2020" +description = "" + +[environment] +PYTHONPATH = [ + "{AVALON_CORE}/setup/maya", + "{PYTHONPATH}" +] diff --git a/pype/settings/defaults/launchers/myapp.toml b/pype/settings/defaults/launchers/myapp.toml new file mode 100644 index 0000000000..21da0d52b2 --- /dev/null +++ b/pype/settings/defaults/launchers/myapp.toml @@ -0,0 +1,5 @@ +executable = "python" +schema = "avalon-core:application-1.0" +application_dir = "myapp" +label = "My App" +arguments = [ "-c", "import sys; from Qt import QtWidgets; if __name__ == '__main__':;\n app = QtWidgets.QApplication(sys.argv);\n window = QtWidgets.QWidget();\n window.setWindowTitle(\"My App\");\n window.resize(400, 300);\n window.show();\n app.exec_();\n",] \ No newline at end of file diff --git a/pype/settings/defaults/launchers/nuke_10.0.toml b/pype/settings/defaults/launchers/nuke_10.0.toml new file mode 100644 index 0000000000..d4dd028942 --- /dev/null +++ b/pype/settings/defaults/launchers/nuke_10.0.toml @@ -0,0 +1,8 @@ +executable = "nuke10.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "Nuke" +label_variant = "10.0v4" +ftrack_label = "Nuke" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nuke_11.0.toml b/pype/settings/defaults/launchers/nuke_11.0.toml new file mode 100644 index 0000000000..10ff6aca37 --- /dev/null +++ b/pype/settings/defaults/launchers/nuke_11.0.toml @@ -0,0 +1,8 @@ +executable = "nuke11.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "Nuke" +label_variant = "11.0" +ftrack_label = "Nuke" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nuke_11.2.toml b/pype/settings/defaults/launchers/nuke_11.2.toml new file mode 100644 index 0000000000..530c7f610e --- /dev/null +++ b/pype/settings/defaults/launchers/nuke_11.2.toml @@ -0,0 +1,8 @@ +executable = "nuke11.2" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "Nuke" +label_variant = "11.2" +ftrack_label = "Nuke" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nuke_11.3.toml b/pype/settings/defaults/launchers/nuke_11.3.toml new file mode 100644 index 0000000000..c9ff005feb --- /dev/null +++ b/pype/settings/defaults/launchers/nuke_11.3.toml @@ -0,0 +1,8 @@ +executable = "nuke11.3" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "Nuke" +label_variant = "11.3" +ftrack_label = "Nuke" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nuke_12.0.toml b/pype/settings/defaults/launchers/nuke_12.0.toml new file mode 100644 index 0000000000..9ac1084fbf --- /dev/null +++ b/pype/settings/defaults/launchers/nuke_12.0.toml @@ -0,0 +1,8 @@ +executable = "nuke12.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "Nuke" +label_variant = "12.0" +ftrack_label = "Nuke" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukestudio_10.0.toml b/pype/settings/defaults/launchers/nukestudio_10.0.toml new file mode 100644 index 0000000000..6c554aff62 --- /dev/null +++ b/pype/settings/defaults/launchers/nukestudio_10.0.toml @@ -0,0 +1,8 @@ +executable = "nukestudio10.0" +schema = "avalon-core:application-1.0" +application_dir = "nukestudio" +label = "NukeStudio" +label_variant = "10.0" +ftrack_label = "NukeStudio" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukestudio_11.0.toml b/pype/settings/defaults/launchers/nukestudio_11.0.toml new file mode 100644 index 0000000000..482aa6587e --- /dev/null +++ b/pype/settings/defaults/launchers/nukestudio_11.0.toml @@ -0,0 +1,8 @@ +executable = "nukestudio11.0" +schema = "avalon-core:application-1.0" +application_dir = "nukestudio" +label = "NukeStudio" +label_variant = "11.0" +ftrack_label = "NukeStudio" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukestudio_11.2.toml b/pype/settings/defaults/launchers/nukestudio_11.2.toml new file mode 100644 index 0000000000..78d1de3d8b --- /dev/null +++ b/pype/settings/defaults/launchers/nukestudio_11.2.toml @@ -0,0 +1,8 @@ +executable = "nukestudio11.2" +schema = "avalon-core:application-1.0" +application_dir = "nukestudio" +label = "NukeStudio" +label_variant = "11.2" +ftrack_label = "NukeStudio" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukestudio_11.3.toml b/pype/settings/defaults/launchers/nukestudio_11.3.toml new file mode 100644 index 0000000000..35c6a08b2f --- /dev/null +++ b/pype/settings/defaults/launchers/nukestudio_11.3.toml @@ -0,0 +1,8 @@ +executable = "nukestudio11.3" +schema = "avalon-core:application-1.0" +application_dir = "nukestudio" +label = "NukeStudio" +label_variant = "11.3" +ftrack_label = "NukeStudio" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukestudio_12.0.toml b/pype/settings/defaults/launchers/nukestudio_12.0.toml new file mode 100644 index 0000000000..2754116aef --- /dev/null +++ b/pype/settings/defaults/launchers/nukestudio_12.0.toml @@ -0,0 +1,8 @@ +executable = "nukestudio12.0" +schema = "avalon-core:application-1.0" +application_dir = "nukestudio" +label = "NukeStudio" +label_variant = "12.0" +ftrack_label = "NukeStudio" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nuke.png' diff --git a/pype/settings/defaults/launchers/nukex_10.0.toml b/pype/settings/defaults/launchers/nukex_10.0.toml new file mode 100644 index 0000000000..48da30fe16 --- /dev/null +++ b/pype/settings/defaults/launchers/nukex_10.0.toml @@ -0,0 +1,8 @@ +executable = "nukex10.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "NukeX" +label_variant = "10.0" +ftrack_label = "NukeX" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nukex.png' diff --git a/pype/settings/defaults/launchers/nukex_11.0.toml b/pype/settings/defaults/launchers/nukex_11.0.toml new file mode 100644 index 0000000000..8f353e9e00 --- /dev/null +++ b/pype/settings/defaults/launchers/nukex_11.0.toml @@ -0,0 +1,8 @@ +executable = "nukex11.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "NukeX" +label_variant = "11.0" +ftrack_label = "NukeX" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nukex.png' diff --git a/pype/settings/defaults/launchers/nukex_11.2.toml b/pype/settings/defaults/launchers/nukex_11.2.toml new file mode 100644 index 0000000000..38e37fa4c9 --- /dev/null +++ b/pype/settings/defaults/launchers/nukex_11.2.toml @@ -0,0 +1,8 @@ +executable = "nukex11.2" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "NukeX" +label_variant = "11.2" +ftrack_label = "NukeX" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nukex.png' diff --git a/pype/settings/defaults/launchers/nukex_11.3.toml b/pype/settings/defaults/launchers/nukex_11.3.toml new file mode 100644 index 0000000000..42969c5e69 --- /dev/null +++ b/pype/settings/defaults/launchers/nukex_11.3.toml @@ -0,0 +1,8 @@ +executable = "nukex11.3" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "NukeX" +label_variant = "11.3" +ftrack_label = "NukeX" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nukex.png' diff --git a/pype/settings/defaults/launchers/nukex_12.0.toml b/pype/settings/defaults/launchers/nukex_12.0.toml new file mode 100644 index 0000000000..19d27a12d7 --- /dev/null +++ b/pype/settings/defaults/launchers/nukex_12.0.toml @@ -0,0 +1,8 @@ +executable = "nukex12.0" +schema = "avalon-core:application-1.0" +application_dir = "nuke" +label = "NukeX" +label_variant = "12.0" +ftrack_label = "NukeX" +icon = "app_icons/nuke.png" +ftrack_icon = '{}/app_icons/nukex.png' diff --git a/pype/settings/defaults/launchers/photoshop_2020.toml b/pype/settings/defaults/launchers/photoshop_2020.toml new file mode 100644 index 0000000000..8164af929f --- /dev/null +++ b/pype/settings/defaults/launchers/photoshop_2020.toml @@ -0,0 +1,9 @@ +executable = "photoshop_2020" +schema = "avalon-core:application-1.0" +application_dir = "photoshop" +label = "Adobe Photoshop" +label_variant = "2020" +icon = "app_icons/photoshop.png" +ftrack_label = "Photoshop" +ftrack_icon = '{}/app_icons/photoshop.png' +launch_hook = "pype/hooks/photoshop/prelaunch.py/PhotoshopPrelaunch" diff --git a/pype/settings/defaults/launchers/premiere_2019.toml b/pype/settings/defaults/launchers/premiere_2019.toml new file mode 100644 index 0000000000..d03395e022 --- /dev/null +++ b/pype/settings/defaults/launchers/premiere_2019.toml @@ -0,0 +1,9 @@ +executable = "premiere_pro_2019" +schema = "avalon-core:application-1.0" +application_dir = "premiere" +label = "Adobe Premiere Pro CC" +label_variant = "2019" +icon = "app_icons/premiere.png" + +ftrack_label = "Premiere" +ftrack_icon = '{}/app_icons/premiere.png' diff --git a/pype/settings/defaults/launchers/premiere_2020.toml b/pype/settings/defaults/launchers/premiere_2020.toml new file mode 100644 index 0000000000..01c7b5b745 --- /dev/null +++ b/pype/settings/defaults/launchers/premiere_2020.toml @@ -0,0 +1,10 @@ +executable = "premiere_pro_2020" +schema = "avalon-core:application-1.0" +application_dir = "premiere" +label = "Adobe Premiere Pro CC" +label_variant = "2020" +launch_hook = "pype/hooks/premiere/prelaunch.py/PremierePrelaunch" +icon = "app_icons/premiere.png" + +ftrack_label = "Premiere" +ftrack_icon = '{}/app_icons/premiere.png' diff --git a/pype/settings/defaults/launchers/python_2.toml b/pype/settings/defaults/launchers/python_2.toml new file mode 100644 index 0000000000..f1c1ca7e68 --- /dev/null +++ b/pype/settings/defaults/launchers/python_2.toml @@ -0,0 +1,12 @@ +schema = "avalon-core:application-1.0" +application_dir = "python" +executable = "python" +label = "Python" +label_variant = "2" +icon = "app_icons/python.png" + +ftrack_label = "Python" +ftrack_icon = '{}/app_icons/python.png' + +[environment] +CREATE_NEW_CONSOLE = "Yes" diff --git a/pype/settings/defaults/launchers/python_3.toml b/pype/settings/defaults/launchers/python_3.toml new file mode 100644 index 0000000000..90fb10eaeb --- /dev/null +++ b/pype/settings/defaults/launchers/python_3.toml @@ -0,0 +1,12 @@ +schema = "avalon-core:application-1.0" +application_dir = "python" +executable = "python3" +label = "Python" +label_variant = "3" +icon = "app_icons/python.png" + +ftrack_label = "Python" +ftrack_icon = '{}/app_icons/python.png' + +[environment] +CREATE_NEW_CONSOLE = "Yes" diff --git a/pype/settings/defaults/launchers/resolve_16.toml b/pype/settings/defaults/launchers/resolve_16.toml new file mode 100644 index 0000000000..47918a22a6 --- /dev/null +++ b/pype/settings/defaults/launchers/resolve_16.toml @@ -0,0 +1,10 @@ +executable = "resolve_16" +schema = "avalon-core:application-1.0" +application_dir = "resolve" +label = "BM DaVinci Resolve" +label_variant = "16" +launch_hook = "pype/hooks/resolve/prelaunch.py/ResolvePrelaunch" +icon = "app_icons/resolve.png" + +ftrack_label = "BM DaVinci Resolve" +ftrack_icon = '{}/app_icons/resolve.png' diff --git a/pype/settings/defaults/launchers/shell.toml b/pype/settings/defaults/launchers/shell.toml new file mode 100644 index 0000000000..959ad392ea --- /dev/null +++ b/pype/settings/defaults/launchers/shell.toml @@ -0,0 +1,7 @@ +schema = "avalon-core:application-1.0" +application_dir = "shell" +executable = "shell" +label = "Shell" + +[environment] +CREATE_NEW_CONSOLE = "Yes" \ No newline at end of file diff --git a/pype/settings/defaults/launchers/storyboardpro_7.toml b/pype/settings/defaults/launchers/storyboardpro_7.toml new file mode 100644 index 0000000000..067f10a23a --- /dev/null +++ b/pype/settings/defaults/launchers/storyboardpro_7.toml @@ -0,0 +1,9 @@ +application_dir = "storyboardpro" +label = "Storyboard Pro" +label_variant = "7" +ftrack_label = "Storyboard Pro" +schema = "avalon-core:application-1.0" +executable = "storyboardpro_7" +description = "" +icon = "app_icons/storyboardpro.png" +ftrack_icon = '{}/app_icons/storyboardpro.png' diff --git a/pype/settings/defaults/launchers/unreal_4.24.toml b/pype/settings/defaults/launchers/unreal_4.24.toml new file mode 100644 index 0000000000..10b14e7f59 --- /dev/null +++ b/pype/settings/defaults/launchers/unreal_4.24.toml @@ -0,0 +1,10 @@ +executable = "unreal" +schema = "avalon-core:application-1.0" +application_dir = "unreal" +label = "Unreal Editor" +label_variant = "4.24" +icon = "app_icons/ue4.png" +launch_hook = "pype/hooks/unreal/unreal_prelaunch.py/UnrealPrelaunch" + +ftrack_label = "UnrealEditor" +ftrack_icon = '{}/app_icons/ue4.png' diff --git a/pype/settings/defaults/launchers/windows/blender_2.80.bat b/pype/settings/defaults/launchers/windows/blender_2.80.bat new file mode 100644 index 0000000000..5b8a37356b --- /dev/null +++ b/pype/settings/defaults/launchers/windows/blender_2.80.bat @@ -0,0 +1,11 @@ +set __app__="Blender" +set __exe__="C:\Program Files\Blender Foundation\Blender 2.80\blender.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/blender_2.81.bat b/pype/settings/defaults/launchers/windows/blender_2.81.bat new file mode 100644 index 0000000000..a900b18eda --- /dev/null +++ b/pype/settings/defaults/launchers/windows/blender_2.81.bat @@ -0,0 +1,11 @@ +set __app__="Blender" +set __exe__="C:\Program Files\Blender Foundation\Blender 2.81\blender.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/blender_2.82.bat b/pype/settings/defaults/launchers/windows/blender_2.82.bat new file mode 100644 index 0000000000..7105c1efe1 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/blender_2.82.bat @@ -0,0 +1,11 @@ +set __app__="Blender" +set __exe__="C:\Program Files\Blender Foundation\Blender 2.82\blender.exe" --python-use-system-env +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/blender_2.83.bat b/pype/settings/defaults/launchers/windows/blender_2.83.bat new file mode 100644 index 0000000000..671952f0d7 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/blender_2.83.bat @@ -0,0 +1,11 @@ +set __app__="Blender" +set __exe__="C:\Program Files\Blender Foundation\Blender 2.83\blender.exe" --python-use-system-env +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/celaction_local.bat b/pype/settings/defaults/launchers/windows/celaction_local.bat new file mode 100644 index 0000000000..8f2171617e --- /dev/null +++ b/pype/settings/defaults/launchers/windows/celaction_local.bat @@ -0,0 +1,19 @@ +set __app__="CelAction2D" +set __app_dir__="C:\Program Files (x86)\CelAction\" +set __exe__="C:\Program Files (x86)\CelAction\CelAction2D.exe" + +if not exist %__exe__% goto :missing_app + +pushd %__app_dir__% + +if "%PYPE_CELACTION_PROJECT_FILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% "%PYPE_CELACTION_PROJECT_FILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/celaction_publish.bat b/pype/settings/defaults/launchers/windows/celaction_publish.bat new file mode 100644 index 0000000000..77ec2ac24e --- /dev/null +++ b/pype/settings/defaults/launchers/windows/celaction_publish.bat @@ -0,0 +1,3 @@ +echo %* + +%PYPE_PYTHON_EXE% "%PYPE_MODULE_ROOT%\pype\hosts\celaction\cli.py" %* diff --git a/pype/settings/defaults/launchers/windows/harmony_17.bat b/pype/settings/defaults/launchers/windows/harmony_17.bat new file mode 100644 index 0000000000..0822650875 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/harmony_17.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Harmony 17" +set __exe__="C:/Program Files (x86)/Toon Boom Animation/Toon Boom Harmony 17 Premium/win64/bin/HarmonyPremium.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% cmd.exe /k "python -c ^"import avalon.harmony;avalon.harmony.launch("%__exe__%")^"" + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/houdini_16.bat b/pype/settings/defaults/launchers/windows/houdini_16.bat new file mode 100644 index 0000000000..018ba08b4c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/houdini_16.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Houdini 16.0" +set __exe__="C:\Program Files\Side Effects Software\Houdini 16.0.621\bin\houdini.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/houdini_17.bat b/pype/settings/defaults/launchers/windows/houdini_17.bat new file mode 100644 index 0000000000..950a599623 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/houdini_17.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Houdini 17.0" +set __exe__="C:\Program Files\Side Effects Software\Houdini 17.0.459\bin\houdini.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/houdini_18.bat b/pype/settings/defaults/launchers/windows/houdini_18.bat new file mode 100644 index 0000000000..3d6b1ae258 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/houdini_18.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Houdini 18.0" +set __exe__="C:\Program Files\Side Effects Software\Houdini 18.0.287\bin\houdini.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/maya2016.bat b/pype/settings/defaults/launchers/windows/maya2016.bat new file mode 100644 index 0000000000..54f15cf269 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/maya2016.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Maya 2016" +set __exe__="C:\Program Files\Autodesk\Maya2016\bin\maya.exe" +if not exist %__exe__% goto :missing_app + +if "%AVALON_LAST_WORKFILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% -file "%AVALON_LAST_WORKFILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/maya2017.bat b/pype/settings/defaults/launchers/windows/maya2017.bat new file mode 100644 index 0000000000..5c2aeb495c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/maya2017.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Maya 2017" +set __exe__="C:\Program Files\Autodesk\Maya2017\bin\maya.exe" +if not exist %__exe__% goto :missing_app + +if "%AVALON_LAST_WORKFILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% -file "%AVALON_LAST_WORKFILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/maya2018.bat b/pype/settings/defaults/launchers/windows/maya2018.bat new file mode 100644 index 0000000000..28cf776c77 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/maya2018.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Maya 2018" +set __exe__="C:\Program Files\Autodesk\Maya2018\bin\maya.exe" +if not exist %__exe__% goto :missing_app + +if "%AVALON_LAST_WORKFILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% -file "%AVALON_LAST_WORKFILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/maya2019.bat b/pype/settings/defaults/launchers/windows/maya2019.bat new file mode 100644 index 0000000000..7e80dd2557 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/maya2019.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Maya 2019" +set __exe__="C:\Program Files\Autodesk\Maya2019\bin\maya.exe" +if not exist %__exe__% goto :missing_app + +if "%AVALON_LAST_WORKFILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% -file "%AVALON_LAST_WORKFILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/maya2020.bat b/pype/settings/defaults/launchers/windows/maya2020.bat new file mode 100644 index 0000000000..b2acb5df5a --- /dev/null +++ b/pype/settings/defaults/launchers/windows/maya2020.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Maya 2020" +set __exe__="C:\Program Files\Autodesk\maya2020\bin\maya.exe" +if not exist %__exe__% goto :missing_app + +if "%AVALON_LAST_WORKFILE%"=="" ( + start %__app__% %__exe__% %* +) else ( + start %__app__% %__exe__% -file "%AVALON_LAST_WORKFILE%" %* +) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayabatch2019.bat b/pype/settings/defaults/launchers/windows/mayabatch2019.bat new file mode 100644 index 0000000000..ddd9b9b956 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayabatch2019.bat @@ -0,0 +1,14 @@ +@echo off + +set __app__="Maya Batch 2019" +set __exe__="C:\Program Files\Autodesk\Maya2019\bin\mayabatch.exe" +if not exist %__exe__% goto :missing_app + +echo "running maya : %*" +%__exe__% %* +echo "done." +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayabatch2020.bat b/pype/settings/defaults/launchers/windows/mayabatch2020.bat new file mode 100644 index 0000000000..b1cbc6dbb6 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayabatch2020.bat @@ -0,0 +1,14 @@ +@echo off + +set __app__="Maya Batch 2020" +set __exe__="C:\Program Files\Autodesk\Maya2020\bin\mayabatch.exe" +if not exist %__exe__% goto :missing_app + +echo "running maya : %*" +%__exe__% %* +echo "done." +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayapy2016.bat b/pype/settings/defaults/launchers/windows/mayapy2016.bat new file mode 100644 index 0000000000..205991fd3d --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayapy2016.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Mayapy 2016" +set __exe__="C:\Program Files\Autodesk\Maya2016\bin\mayapy.exe" +if not exist %__exe__% goto :missing_app + +call %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found at %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayapy2017.bat b/pype/settings/defaults/launchers/windows/mayapy2017.bat new file mode 100644 index 0000000000..14aacc5a7f --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayapy2017.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Mayapy 2017" +set __exe__="C:\Program Files\Autodesk\Maya2017\bin\mayapy.exe" +if not exist %__exe__% goto :missing_app + +call %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found at %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayapy2018.bat b/pype/settings/defaults/launchers/windows/mayapy2018.bat new file mode 100644 index 0000000000..c47c472f46 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayapy2018.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Mayapy 2018" +set __exe__="C:\Program Files\Autodesk\Maya2018\bin\mayapy.exe" +if not exist %__exe__% goto :missing_app + +call %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found at %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayapy2019.bat b/pype/settings/defaults/launchers/windows/mayapy2019.bat new file mode 100644 index 0000000000..73ca5b2d40 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayapy2019.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Mayapy 2019" +set __exe__="C:\Program Files\Autodesk\Maya2019\bin\mayapy.exe" +if not exist %__exe__% goto :missing_app + +call %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found at %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/mayapy2020.bat b/pype/settings/defaults/launchers/windows/mayapy2020.bat new file mode 100644 index 0000000000..770a03dcf5 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/mayapy2020.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Mayapy 2020" +set __exe__="C:\Program Files\Autodesk\Maya2020\bin\mayapy.exe" +if not exist %__exe__% goto :missing_app + +call %__exe__% %* + +goto :eofS + +:missing_app + echo ERROR: %__app__% not found at %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nuke10.0.bat b/pype/settings/defaults/launchers/windows/nuke10.0.bat new file mode 100644 index 0000000000..a47cbdfb20 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nuke10.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Nuke10.0v4" +set __exe__="C:\Program Files\Nuke10.0v4\Nuke10.0.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nuke11.0.bat b/pype/settings/defaults/launchers/windows/nuke11.0.bat new file mode 100644 index 0000000000..a374c5cf5b --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nuke11.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Nuke11.0v4" +set __exe__="C:\Program Files\Nuke11.0v4\Nuke11.0.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nuke11.2.bat b/pype/settings/defaults/launchers/windows/nuke11.2.bat new file mode 100644 index 0000000000..4c777ac28c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nuke11.2.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Nuke11.2v3" +set __exe__="C:\Program Files\Nuke11.2v3\Nuke11.2.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nuke11.3.bat b/pype/settings/defaults/launchers/windows/nuke11.3.bat new file mode 100644 index 0000000000..a023f5f46f --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nuke11.3.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Nuke11.3v1" +set __exe__="C:\Program Files\Nuke11.3v1\Nuke11.3.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nuke12.0.bat b/pype/settings/defaults/launchers/windows/nuke12.0.bat new file mode 100644 index 0000000000..d8fb5772bb --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nuke12.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Nuke12.0v1" +set __exe__="C:\Program Files\Nuke12.0v1\Nuke12.0.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukestudio10.0.bat b/pype/settings/defaults/launchers/windows/nukestudio10.0.bat new file mode 100644 index 0000000000..82f833667c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukestudio10.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeStudio10.0v4" +set __exe__="C:\Program Files\Nuke10.0v4\Nuke10.0.exe" --studio +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukestudio11.0.bat b/pype/settings/defaults/launchers/windows/nukestudio11.0.bat new file mode 100644 index 0000000000..b66797727e --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukestudio11.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeStudio11.0v4" +set __exe__="C:\Program Files\Nuke11.0v4\Nuke11.0.exe" -studio +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukestudio11.2.bat b/pype/settings/defaults/launchers/windows/nukestudio11.2.bat new file mode 100644 index 0000000000..a653d816b4 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukestudio11.2.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeStudio11.2v3" +set __exe__="C:\Program Files\Nuke11.2v3\Nuke11.2.exe" -studio +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukestudio11.3.bat b/pype/settings/defaults/launchers/windows/nukestudio11.3.bat new file mode 100644 index 0000000000..62c8718873 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukestudio11.3.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeStudio11.3v1" +set __exe__="C:\Program Files\Nuke11.3v1\Nuke11.3.exe" --studio +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukestudio12.0.bat b/pype/settings/defaults/launchers/windows/nukestudio12.0.bat new file mode 100644 index 0000000000..488232bcbf --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukestudio12.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeStudio12.0v1" +set __exe__="C:\Program Files\Nuke12.0v1\Nuke12.0.exe" --studio +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukex10.0.bat b/pype/settings/defaults/launchers/windows/nukex10.0.bat new file mode 100644 index 0000000000..1759706a7b --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukex10.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeX10.0v4" +set __exe__="C:\Program Files\Nuke10.0v4\Nuke10.0.exe" -nukex +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukex11.0.bat b/pype/settings/defaults/launchers/windows/nukex11.0.bat new file mode 100644 index 0000000000..b554a7b6fa --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukex11.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeX11.0v4" +set __exe__="C:\Program Files\Nuke11.0v4\Nuke11.0.exe" --nukex +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukex11.2.bat b/pype/settings/defaults/launchers/windows/nukex11.2.bat new file mode 100644 index 0000000000..a4cb5dec5c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukex11.2.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeX11.2v3" +set __exe__="C:\Program Files\Nuke11.2v3\Nuke11.2.exe" --nukex +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukex11.3.bat b/pype/settings/defaults/launchers/windows/nukex11.3.bat new file mode 100644 index 0000000000..490b55cf4c --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukex11.3.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeX11.3v1" +set __exe__="C:\Program Files\Nuke11.3v1\Nuke11.3.exe" --nukex +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/nukex12.0.bat b/pype/settings/defaults/launchers/windows/nukex12.0.bat new file mode 100644 index 0000000000..26adf0d3f1 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/nukex12.0.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="NukeX12.0v1" +set __exe__="C:\Program Files\Nuke12.0v1\Nuke12.0.exe" --nukex +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/photoshop_2020.bat b/pype/settings/defaults/launchers/windows/photoshop_2020.bat new file mode 100644 index 0000000000..6b90922ef6 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/photoshop_2020.bat @@ -0,0 +1,15 @@ +@echo off + +set __app__="Photoshop 2020" +set __exe__="C:\Program Files\Adobe\Adobe Photoshop 2020\Photoshop.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% cmd.exe /k "%PYPE_PYTHON_EXE% -c ^"import avalon.photoshop;avalon.photoshop.launch("%__exe__%")^"" + +goto :eof + +pause + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/premiere_pro_2019.bat b/pype/settings/defaults/launchers/windows/premiere_pro_2019.bat new file mode 100644 index 0000000000..4886737d2f --- /dev/null +++ b/pype/settings/defaults/launchers/windows/premiere_pro_2019.bat @@ -0,0 +1,14 @@ +@echo off + +set __app__="Adobe Premiere Pro" +set __exe__="C:\Program Files\Adobe\Adobe Premiere Pro CC 2019\Adobe Premiere Pro.exe" +if not exist %__exe__% goto :missing_app + +python -u %PREMIERA_PATH%\init.py +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/premiere_pro_2020.bat b/pype/settings/defaults/launchers/windows/premiere_pro_2020.bat new file mode 100644 index 0000000000..14662d3be3 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/premiere_pro_2020.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Adobe Premiere Pro" +set __exe__="C:\Program Files\Adobe\Adobe Premiere Pro 2020\Adobe Premiere Pro.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/python3.bat b/pype/settings/defaults/launchers/windows/python3.bat new file mode 100644 index 0000000000..c7c116fe72 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/python3.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Python36" +set __exe__="C:\Python36\python.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/resolve_16.bat b/pype/settings/defaults/launchers/windows/resolve_16.bat new file mode 100644 index 0000000000..1a5d964e6b --- /dev/null +++ b/pype/settings/defaults/launchers/windows/resolve_16.bat @@ -0,0 +1,17 @@ +@echo off + +set __app__="Resolve" +set __appy__="Resolve Python Console" +set __exe__="C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe" +set __py__="%PYTHON36_RESOLVE%/python.exe" + +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %* +IF "%RESOLVE_DEV%"=="True" (start %__appy__% %__py__% -i %PRE_PYTHON_SCRIPT%) + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/shell.bat b/pype/settings/defaults/launchers/windows/shell.bat new file mode 100644 index 0000000000..eb0895364f --- /dev/null +++ b/pype/settings/defaults/launchers/windows/shell.bat @@ -0,0 +1,2 @@ +@echo off +start cmd diff --git a/pype/settings/defaults/launchers/windows/storyboardpro_7.bat b/pype/settings/defaults/launchers/windows/storyboardpro_7.bat new file mode 100644 index 0000000000..122edac572 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/storyboardpro_7.bat @@ -0,0 +1,13 @@ +@echo off + +set __app__="Storyboard Pro 7" +set __exe__="C:/Program Files (x86)/Toon Boom Animation/Toon Boom Storyboard Pro 7/win64/bin/StoryboardPro.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% cmd.exe /k "python -c ^"import avalon.storyboardpro;avalon.storyboardpro.launch("%__exe__%")^"" + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 diff --git a/pype/settings/defaults/launchers/windows/unreal.bat b/pype/settings/defaults/launchers/windows/unreal.bat new file mode 100644 index 0000000000..7771aaa5a5 --- /dev/null +++ b/pype/settings/defaults/launchers/windows/unreal.bat @@ -0,0 +1,11 @@ +set __app__="Unreal Editor" +set __exe__="%AVALON_CURRENT_UNREAL_ENGINE%\Engine\Binaries\Win64\UE4Editor.exe" +if not exist %__exe__% goto :missing_app + +start %__app__% %__exe__% %PYPE_UNREAL_PROJECT_FILE% %* + +goto :eof + +:missing_app + echo ERROR: %__app__% not found in %__exe__% + exit /B 1 From 9e40f3c9fd719bc39ce2a2efa26c2c4979272199 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 30 Sep 2020 14:50:33 +0200 Subject: [PATCH 067/176] implemented function which returns environments --- pype/settings/lib.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 388557ca9b..848bdeea92 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -19,6 +19,12 @@ SYSTEM_SETTINGS_PATH = os.path.join( STUDIO_OVERRIDES_PATH, SYSTEM_SETTINGS_KEY + ".json" ) +# File where studio's environment overrides are stored +ENVIRONMENTS_KEY = "environments" +ENVIRONMENTS_PATH = os.path.join( + STUDIO_OVERRIDES_PATH, ENVIRONMENTS_KEY + ".json" +) + # File where studio's default project overrides are stored PROJECT_SETTINGS_KEY = "project_settings" PROJECT_SETTINGS_FILENAME = PROJECT_SETTINGS_KEY + ".json" @@ -162,6 +168,12 @@ def studio_system_settings(): return {} +def studio_environments(): + if os.path.exists(ENVIRONMENTS_PATH): + return load_json(ENVIRONMENTS_PATH) + return {} + + def studio_project_settings(): if os.path.exists(PROJECT_SETTINGS_PATH): return load_json(PROJECT_SETTINGS_PATH) @@ -256,3 +268,9 @@ def project_settings(project_name): project_overrides = project_settings_overrides(project_name) return apply_overrides(studio_overrides, project_overrides) + + +def environments(): + default_values = default_settings()[ENVIRONMENTS_KEY] + studio_values = studio_system_settings() + return apply_overrides(default_values, studio_values) From def129501420aa644d8304f6a6c719ac12a97c55 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 30 Sep 2020 14:50:48 +0200 Subject: [PATCH 068/176] added environemnts function to pype.api --- pype/api.py | 4 +++- pype/settings/__init__.py | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pype/api.py b/pype/api.py index 021080b4d5..c1bf84b4ef 100644 --- a/pype/api.py +++ b/pype/api.py @@ -1,6 +1,7 @@ from .settings import ( system_settings, - project_settings + project_settings, + environments ) from pypeapp import ( Logger, @@ -55,6 +56,7 @@ from .lib import _subprocess as subprocess __all__ = [ "system_settings", "project_settings", + "environments", "Logger", "Anatomy", diff --git a/pype/settings/__init__.py b/pype/settings/__init__.py index 7e73d541a4..7a99ba0b2f 100644 --- a/pype/settings/__init__.py +++ b/pype/settings/__init__.py @@ -1,9 +1,11 @@ from .lib import ( system_settings, - project_settings + project_settings, + environments ) __all__ = ( "system_settings", - "project_settings" + "project_settings", + "environments" ) From 15bb321b1f25cac721a10fc357f612c5d5d9ad46 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 15:44:17 +0200 Subject: [PATCH 069/176] system widget can store environment fields --- pype/tools/settings/settings/widgets/base.py | 5 +++++ pype/tools/settings/settings/widgets/item_types.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index 243a8448e5..9cff07ea90 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -47,6 +47,7 @@ class SystemWidget(QtWidgets.QWidget): self._ignore_value_changes = False self.input_fields = [] + self.environ_fields = [] scroll_widget = QtWidgets.QScrollArea(self) scroll_widget.setObjectName("GroupWidget") @@ -130,10 +131,14 @@ class SystemWidget(QtWidgets.QWidget): for input_field in self.input_fields: input_field.hierarchical_style_update() + def add_environ_field(self, input_field): + self.environ_fields.append(input_field) + def reset(self): reset_default_settings() self.input_fields.clear() + self.environ_fields.clear() while self.content_layout.count() != 0: widget = self.content_layout.itemAt(0).widget() self.content_layout.removeWidget(widget) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 4124c32ba8..9c55f5dc05 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -140,6 +140,9 @@ class SettingObject: """ return self._has_studio_override or self._parent.has_studio_override + def add_environ_field(self, input_field): + self._parent.add_environ_field(input_field) + @property def as_widget(self): """Item is used as widget in parent item. From 226ddab164af10a6c3447eca7dcf912a617e1748 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 16:15:38 +0200 Subject: [PATCH 070/176] preparation for storing to separated environments settings --- .../settings/settings/widgets/item_types.py | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 9c55f5dc05..d1c29b6ae1 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -24,6 +24,8 @@ class SettingObject: # Will allow to show actions for the item type (disabled for proxies) else # item is skipped and try to trigger actions on it's parent. allow_actions = True + # If item can store environment values + allow_to_environment = False # All item types must have implemented Qt signal which is emitted when # it's or it's children value has changed, value_changed = None @@ -49,6 +51,9 @@ class SettingObject: self._as_widget = False self._is_group = False + # If value should be stored to environments + self._env_group_key = None + self._any_parent_as_widget = None self._any_parent_is_group = None @@ -84,6 +89,20 @@ class SettingObject: self._is_group = input_data.get("is_group", False) # TODO not implemented yet self._is_nullable = input_data.get("is_nullable", False) + self._env_group_key = input_data.get("env_group_key") + + if self.is_environ: + if not self.allow_to_environment: + raise TypeError(( + "Item {} does not allow to store environment values" + ).format(input_data["type"])) + + if self.as_widget: + raise TypeError(( + "Item is used as widget and" + " marked to store environments at the same time." + )) + self.add_environ_field(self) any_parent_as_widget = parent.as_widget if not any_parent_as_widget: @@ -140,9 +159,25 @@ class SettingObject: """ return self._has_studio_override or self._parent.has_studio_override + @property + def is_environ(self): + return self._env_group_key is not None + + @property + def env_group_key(self): + return self._env_group_key + def add_environ_field(self, input_field): self._parent.add_environ_field(input_field) + @property + def has_only_environ_children(self): + raise NotImplementedError( + "{} does not have implemented `has_only_environ_children`".format( + self + ) + ) + @property def as_widget(self): """Item is used as widget in parent item. @@ -270,8 +305,17 @@ class SettingObject: def config_value(self): """Output for saving changes or overrides.""" + if self.has_only_environ_children: + return {} return {self.key: self.item_value()} + def environment_value(self): + raise NotImplementedError( + "{} Method `set_studio_default` not implemented!".format( + repr(self) + ) + ) + @classmethod def style_state( cls, has_studio_override, is_invalid, is_overriden, is_modified @@ -667,6 +711,10 @@ class InputObject(SettingObject): self.value_changed.emit(self) + @property + def has_only_environ_children(self): + return self.is_environ + def studio_overrides(self): if ( not (self.as_widget or self.any_parent_as_widget) @@ -882,6 +930,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): class TextWidget(QtWidgets.QWidget, InputObject): default_input_value = "" value_changed = QtCore.Signal(object) + # allow_to_environment = True def __init__( self, input_data, parent, @@ -985,6 +1034,7 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): class EnumeratorWidget(QtWidgets.QWidget, InputObject): default_input_value = True value_changed = QtCore.Signal(object) + # allow_to_environment = True def __init__( self, input_data, parent, @@ -1136,6 +1186,7 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): class RawJsonWidget(QtWidgets.QWidget, InputObject): default_input_value = "{}" value_changed = QtCore.Signal(object) + allow_to_environment = True def __init__( self, input_data, parent, @@ -1182,6 +1233,12 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): self._is_invalid = self.input_field.has_invalid_value() return super(RawJsonWidget, self)._on_value_change(*args, **kwargs) + def environment_value(self): + output = {} + for key, value in self.item_value().items(): + output[key.upper()] = value + return output + def item_value(self): if self.is_invalid: return NOT_SET @@ -1372,6 +1429,7 @@ class ListItem(QtWidgets.QWidget, SettingObject): class ListWidget(QtWidgets.QWidget, InputObject): default_input_value = [] value_changed = QtCore.Signal(object) + # allow_to_environment = True def __init__( self, input_data, parent, @@ -1944,6 +2002,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): # TODO this is actually input field (do not care if is group or not) value_changed = QtCore.Signal(object) expand_in_grid = True + # allow_to_environment = True def __init__( self, input_data, parent, @@ -2209,6 +2268,8 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self.input_fields = [] + self._has_only_environ_children = None + self.checkbox_widget = None self.checkbox_key = input_data.get("checkbox_key") @@ -2532,6 +2593,19 @@ class DictWidget(QtWidgets.QWidget, SettingObject): return True return False + @property + def has_only_environ_children(self): + if self._has_only_environ_children is None: + has_only_environ_children = True + if not self.is_environ: + for input_field in self.input_fields: + if not input_field.has_only_environ_children: + has_only_environ_children = False + break + + self._has_only_environ_children = has_only_environ_children + return self._has_only_environ_children + def get_invalid(self): output = [] for input_field in self.input_fields: @@ -2600,6 +2674,8 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): self.initial_attributes(input_data, parent, as_widget) + self._has_only_environ_children = None + if self._is_group: raise TypeError("DictInvisible can't be marked as group input.") @@ -2660,6 +2736,19 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): return True return False + @property + def has_only_environ_children(self): + if self._has_only_environ_children is None: + has_only_environ_children = True + if not self.is_environ: + for input_field in self.input_fields: + if not input_field.has_only_environ_children: + has_only_environ_children = False + break + + self._has_only_environ_children = has_only_environ_children + return self._has_only_environ_children + @property def child_modified(self): for input_field in self.input_fields: @@ -2840,6 +2929,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): "darwin": "MacOS", "linux": "Linux" } + # allow_to_environment = True def __init__( self, input_data, parent, @@ -3136,6 +3226,10 @@ class PathWidget(QtWidgets.QWidget, SettingObject): def set_as_overriden(self): self._is_overriden = True + @property + def has_only_environ_children(self): + return self.is_environ + @property def child_has_studio_override(self): return self.has_studio_override @@ -3200,6 +3294,8 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): self.initial_attributes(input_data, parent, as_widget) + self._has_only_environ_children = None + self._as_widget = False self._is_group = False @@ -3307,6 +3403,19 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): return True return False + @property + def has_only_environ_children(self): + if self._has_only_environ_children is None: + has_only_environ_children = True + if not self.is_environ: + for input_field in self.input_fields: + if not input_field.has_only_environ_children: + has_only_environ_children = False + break + + self._has_only_environ_children = has_only_environ_children + return self._has_only_environ_children + @property def child_modified(self): for input_field in self.input_fields: From 227755669f444f903e6cf73d50d3944250c617e2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 17:57:21 +0200 Subject: [PATCH 071/176] METATADATA_KEY is object not type --- pype/tools/settings/settings/widgets/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index cf2bd7f8af..f9c0532a97 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -11,7 +11,7 @@ class TypeToKlass: NOT_SET = type("NOT_SET", (), {"__bool__": lambda obj: False})() -METADATA_KEY = type("METADATA_KEY", (), {}) +METADATA_KEY = type("METADATA_KEY", (), {})() OVERRIDE_VERSION = 1 CHILD_OFFSET = 15 From 8a8aa0422db964e2ed1162699e1f5ad33badb917 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 17:57:51 +0200 Subject: [PATCH 072/176] raise KeyError exception not just create --- pype/tools/settings/settings/widgets/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index f9c0532a97..88e4015198 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -30,7 +30,7 @@ def convert_gui_data_to_overrides(data, first=True): if key == "groups": output[OVERRIDEN_KEY] = value else: - KeyError("Unknown metadata key \"{}\"".format(key)) + raise KeyError("Unknown metadata key \"{}\"".format(key)) for key, value in data.items(): output[key] = convert_gui_data_to_overrides(value, False) From 9afcdd3546b79ad25c81b223f94410fb37250ddc Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 17:59:04 +0200 Subject: [PATCH 073/176] renamed variable OVERRIDEN_KEY to M_OVERRIDEN_KEY --- pype/settings/lib.py | 6 +++--- pype/tools/settings/settings/widgets/lib.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 848bdeea92..f8b483cae9 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -6,7 +6,7 @@ import copy log = logging.getLogger(__name__) # Metadata keys for work with studio and project overrides -OVERRIDEN_KEY = "__overriden_keys__" +M_OVERRIDEN_KEY = "__overriden_keys__" # NOTE key popping not implemented yet POP_KEY = "__pop_key__" @@ -223,8 +223,8 @@ def project_anatomy_overrides(project_name): def merge_overrides(global_dict, override_dict): - if OVERRIDEN_KEY in override_dict: - overriden_keys = set(override_dict.pop(OVERRIDEN_KEY)) + if M_OVERRIDEN_KEY in override_dict: + overriden_keys = set(override_dict.pop(M_OVERRIDEN_KEY)) else: overriden_keys = set() diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 88e4015198..479653e4d4 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -1,7 +1,7 @@ import os import json import copy -from pype.settings.lib import OVERRIDEN_KEY +from pype.settings.lib import M_OVERRIDEN_KEY, M_ENVIRONMENT_KEY from queue import Queue @@ -28,7 +28,7 @@ def convert_gui_data_to_overrides(data, first=True): metadata = data.pop(METADATA_KEY) for key, value in metadata.items(): if key == "groups": - output[OVERRIDEN_KEY] = value + output[M_OVERRIDEN_KEY] = value else: raise KeyError("Unknown metadata key \"{}\"".format(key)) @@ -42,8 +42,8 @@ def convert_overrides_to_gui_data(data, first=True): return data output = {} - if OVERRIDEN_KEY in data: - groups = data.pop(OVERRIDEN_KEY) + if M_OVERRIDEN_KEY in data: + groups = data.pop(M_OVERRIDEN_KEY) if METADATA_KEY not in output: output[METADATA_KEY] = {} output[METADATA_KEY]["groups"] = groups From 4903c09f40a870c802f84f0c070d70c1e8d7052f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 17:59:20 +0200 Subject: [PATCH 074/176] variable POP_KEY renamed to M_POP_KEY --- pype/settings/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index f8b483cae9..4faf757198 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -8,7 +8,7 @@ log = logging.getLogger(__name__) # Metadata keys for work with studio and project overrides M_OVERRIDEN_KEY = "__overriden_keys__" # NOTE key popping not implemented yet -POP_KEY = "__pop_key__" +M_POP_KEY = "__pop_key__" # Folder where studio overrides are stored STUDIO_OVERRIDES_PATH = os.environ["PYPE_PROJECT_CONFIGS"] @@ -229,7 +229,7 @@ def merge_overrides(global_dict, override_dict): overriden_keys = set() for key, value in override_dict.items(): - if value == POP_KEY: + if value == M_POP_KEY: global_dict.pop(key) elif ( From ec445fcc2d28ea775c63227b265c3c03127aeabc Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 17:59:32 +0200 Subject: [PATCH 075/176] added new M_ENVIRONMENT_KEY for storing environments --- pype/settings/lib.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 4faf757198..b01c80038f 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -7,6 +7,8 @@ log = logging.getLogger(__name__) # Metadata keys for work with studio and project overrides M_OVERRIDEN_KEY = "__overriden_keys__" +# Metadata key for storing information about environments +M_ENVIRONMENT_KEY = "__environment_keys__" # NOTE key popping not implemented yet M_POP_KEY = "__pop_key__" From e6749a53f7f0285ab2b5ec767d9c6b1f463ec715 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:00:11 +0200 Subject: [PATCH 076/176] added 2 functions for converting gui data for storing and oposite --- pype/tools/settings/settings/widgets/lib.py | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 479653e4d4..e7ab00d7bd 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -16,6 +16,44 @@ OVERRIDE_VERSION = 1 CHILD_OFFSET = 15 +def convert_gui_data_with_metadata(data, ignored_keys=None): + if not data or not isinstance(data, dict): + return data + + if ignored_keys is None: + ignored_keys = tuple() + + output = {} + if METADATA_KEY in data: + metadata = data.pop(METADATA_KEY) + for key, value in metadata.items(): + if key in ignored_keys or key == "groups": + continue + + if key == "environments": + output[M_ENVIRONMENT_KEY] = value + else: + raise KeyError("Unknown metadata key \"{}\"".format(key)) + + for key, value in data.items(): + output[key] = convert_gui_data_with_metadata(value, ignored_keys) + return output + + +def convert_data_to_gui_data(data, first=True): + if not data or not isinstance(data, dict): + return data + + output = {} + if M_ENVIRONMENT_KEY in data: + data.pop(M_ENVIRONMENT_KEY) + + for key, value in data.items(): + output[key] = convert_data_to_gui_data(value, False) + + return output + + def convert_gui_data_to_overrides(data, first=True): if not data or not isinstance(data, dict): return data From 116c9469c8394ea55b03b2e1d56755c00bad1963 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:01:04 +0200 Subject: [PATCH 077/176] fix not implemented message --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index d1c29b6ae1..bad1ce08fe 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -311,7 +311,7 @@ class SettingObject: def environment_value(self): raise NotImplementedError( - "{} Method `set_studio_default` not implemented!".format( + "{} Method `environment_value` not implemented!".format( repr(self) ) ) From 08554af5fdea03b76bf2a02bdb239848231f70bb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:01:38 +0200 Subject: [PATCH 078/176] bases use converting in and out data --- pype/tools/settings/settings/widgets/base.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index 9cff07ea90..7cbe7c2f6f 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -219,7 +219,7 @@ class SystemWidget(QtWidgets.QWidget): all_values = _all_values # Skip first key - all_values = all_values["system"] + all_values = lib.convert_gui_data_with_metadata(all_values["system"]) prject_defaults_dir = os.path.join( DEFAULTS_DIR, SYSTEM_SETTINGS_KEY @@ -251,16 +251,19 @@ class SystemWidget(QtWidgets.QWidget): def _update_values(self): self.ignore_value_changes = True - default_values = { + default_values = lib.convert_data_to_gui_data({ "system": default_settings()[SYSTEM_SETTINGS_KEY] - } + }) for input_field in self.input_fields: input_field.update_default_values(default_values) if self._hide_studio_overrides: system_values = lib.NOT_SET else: - system_values = {"system": studio_system_settings()} + system_values = lib.convert_overrides_to_gui_data( + {"system": studio_system_settings()} + ) + for input_field in self.input_fields: input_field.update_studio_values(system_values) @@ -735,17 +738,20 @@ class ProjectWidget(QtWidgets.QWidget): def _update_values(self): self.ignore_value_changes = True - default_values = {"project": default_settings()} + default_values = default_values = lib.convert_data_to_gui_data( + {"project": default_settings()} + ) for input_field in self.input_fields: input_field.update_default_values(default_values) if self._hide_studio_overrides: studio_values = lib.NOT_SET else: - studio_values = {"project": { + studio_values = lib.convert_overrides_to_gui_data({"project": { PROJECT_SETTINGS_KEY: studio_project_settings(), PROJECT_ANATOMY_KEY: studio_project_anatomy() - }} + }}) + for input_field in self.input_fields: input_field.update_studio_values(studio_values) From e804c47214fb451f02fd988c1a5d0c74f59d17e8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:02:05 +0200 Subject: [PATCH 079/176] converting functions for overrides use new implemented conversions --- pype/tools/settings/settings/widgets/lib.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index e7ab00d7bd..31e4401ab0 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -61,6 +61,7 @@ def convert_gui_data_to_overrides(data, first=True): output = {} if first: output["__override_version__"] = OVERRIDE_VERSION + data = convert_gui_data_with_metadata(data, ("environments",)) if METADATA_KEY in data: metadata = data.pop(METADATA_KEY) @@ -79,6 +80,9 @@ def convert_overrides_to_gui_data(data, first=True): if not data or not isinstance(data, dict): return data + if first: + data = convert_data_to_gui_data(data) + output = {} if M_OVERRIDEN_KEY in data: groups = data.pop(M_OVERRIDEN_KEY) From d33de6856674304ba6008690c2906e7cf13e4b06 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:02:48 +0200 Subject: [PATCH 080/176] removed `has_only_environ_children` --- .../settings/settings/widgets/item_types.py | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index bad1ce08fe..76b8504685 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -170,14 +170,6 @@ class SettingObject: def add_environ_field(self, input_field): self._parent.add_environ_field(input_field) - @property - def has_only_environ_children(self): - raise NotImplementedError( - "{} does not have implemented `has_only_environ_children`".format( - self - ) - ) - @property def as_widget(self): """Item is used as widget in parent item. @@ -305,8 +297,6 @@ class SettingObject: def config_value(self): """Output for saving changes or overrides.""" - if self.has_only_environ_children: - return {} return {self.key: self.item_value()} def environment_value(self): @@ -711,10 +701,6 @@ class InputObject(SettingObject): self.value_changed.emit(self) - @property - def has_only_environ_children(self): - return self.is_environ - def studio_overrides(self): if ( not (self.as_widget or self.any_parent_as_widget) @@ -2268,8 +2254,6 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self.input_fields = [] - self._has_only_environ_children = None - self.checkbox_widget = None self.checkbox_key = input_data.get("checkbox_key") @@ -2593,19 +2577,6 @@ class DictWidget(QtWidgets.QWidget, SettingObject): return True return False - @property - def has_only_environ_children(self): - if self._has_only_environ_children is None: - has_only_environ_children = True - if not self.is_environ: - for input_field in self.input_fields: - if not input_field.has_only_environ_children: - has_only_environ_children = False - break - - self._has_only_environ_children = has_only_environ_children - return self._has_only_environ_children - def get_invalid(self): output = [] for input_field in self.input_fields: @@ -2674,8 +2645,6 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): self.initial_attributes(input_data, parent, as_widget) - self._has_only_environ_children = None - if self._is_group: raise TypeError("DictInvisible can't be marked as group input.") @@ -2736,19 +2705,6 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): return True return False - @property - def has_only_environ_children(self): - if self._has_only_environ_children is None: - has_only_environ_children = True - if not self.is_environ: - for input_field in self.input_fields: - if not input_field.has_only_environ_children: - has_only_environ_children = False - break - - self._has_only_environ_children = has_only_environ_children - return self._has_only_environ_children - @property def child_modified(self): for input_field in self.input_fields: @@ -3226,10 +3182,6 @@ class PathWidget(QtWidgets.QWidget, SettingObject): def set_as_overriden(self): self._is_overriden = True - @property - def has_only_environ_children(self): - return self.is_environ - @property def child_has_studio_override(self): return self.has_studio_override @@ -3294,8 +3246,6 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): self.initial_attributes(input_data, parent, as_widget) - self._has_only_environ_children = None - self._as_widget = False self._is_group = False @@ -3403,19 +3353,6 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): return True return False - @property - def has_only_environ_children(self): - if self._has_only_environ_children is None: - has_only_environ_children = True - if not self.is_environ: - for input_field in self.input_fields: - if not input_field.has_only_environ_children: - has_only_environ_children = False - break - - self._has_only_environ_children = has_only_environ_children - return self._has_only_environ_children - @property def child_modified(self): for input_field in self.input_fields: From 9de4efc7c35fcd91557d865810db2e4585abfabc Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:50:10 +0200 Subject: [PATCH 081/176] prepared method for merging metadata under same key --- .../settings/settings/widgets/item_types.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 76b8504685..6b35246db9 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -32,6 +32,24 @@ class SettingObject: # Item will expand to full width in grid layout expand_in_grid = False + def merge_metadata(self, current_metadata, new_metadata): + for key, value in new_metadata.items(): + if key not in current_metadata: + current_metadata[key] = value + + elif key == "groups": + current_metadata[key].extend(value) + + elif key == "environments": + for group_key, subvalue in value.items(): + if group_key not in current_metadata[key]: + current_metadata[key][group_key] = [] + current_metadata[key][group_key].extend(subvalue) + + else: + raise KeyError("Unknown metadata key: \"{}\"".format(key)) + return current_metadata + def _set_default_attributes(self): """Create and reset attributes required for all item types. From 2933eab903716e43ea4c44b0d5395dd2dd46ac02 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:51:20 +0200 Subject: [PATCH 082/176] dicitonaries can merge metadata keys --- .../settings/settings/widgets/item_types.py | 106 ++++++++++-------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 6b35246db9..74eab078e1 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2609,6 +2609,33 @@ class DictWidget(QtWidgets.QWidget, SettingObject): output.update(input_field.config_value()) return output + def _override_values(self, project_overrides): + values = {} + groups = [] + for input_field in self.input_fields: + if project_overrides: + value, is_group = input_field.overrides() + else: + value, is_group = input_field.studio_overrides() + if value is NOT_SET: + continue + + if METADATA_KEY in value and METADATA_KEY in values: + new_metadata = value.pop(METADATA_KEY) + values[METADATA_KEY] = self.merge_metadata( + values[METADATA_KEY], new_metadata + ) + + values.update(value) + if is_group: + groups.extend(value.keys()) + + if groups: + if METADATA_KEY not in values: + values[METADATA_KEY] = {} + values[METADATA_KEY]["groups"] = groups + return {self.key: values}, self.is_group + def studio_overrides(self): if ( not (self.as_widget or self.any_parent_as_widget) @@ -2616,34 +2643,12 @@ class DictWidget(QtWidgets.QWidget, SettingObject): and not self.child_has_studio_override ): return NOT_SET, False - - values = {} - groups = [] - for input_field in self.input_fields: - value, is_group = input_field.studio_overrides() - if value is not NOT_SET: - values.update(value) - if is_group: - groups.extend(value.keys()) - if groups: - values[METADATA_KEY] = {"groups": groups} - return {self.key: values}, self.is_group + return self._override_values(False) def overrides(self): if not self.is_overriden and not self.child_overriden: return NOT_SET, False - - values = {} - groups = [] - for input_field in self.input_fields: - value, is_group = input_field.overrides() - if value is not NOT_SET: - values.update(value) - if is_group: - groups.extend(value.keys()) - if groups: - values[METADATA_KEY] = {"groups": groups} - return {self.key: values}, self.is_group + return self._override_values(True) class DictInvisible(QtWidgets.QWidget, SettingObject): @@ -2858,6 +2863,33 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): ) self._was_overriden = bool(self._is_overriden) + def _override_values(self, project_overrides): + values = {} + groups = [] + for input_field in self.input_fields: + if project_overrides: + value, is_group = input_field.overrides() + else: + value, is_group = input_field.studio_overrides() + if value is NOT_SET: + continue + + if METADATA_KEY in value and METADATA_KEY in values: + new_metadata = value.pop(METADATA_KEY) + values[METADATA_KEY] = self.merge_metadata( + values[METADATA_KEY], new_metadata + ) + + values.update(value) + if is_group: + groups.extend(value.keys()) + + if groups: + if METADATA_KEY not in values: + values[METADATA_KEY] = {} + values[METADATA_KEY]["groups"] = groups + return {self.key: values}, self.is_group + def studio_overrides(self): if ( not (self.as_widget or self.any_parent_as_widget) @@ -2865,34 +2897,12 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): and not self.child_has_studio_override ): return NOT_SET, False - - values = {} - groups = [] - for input_field in self.input_fields: - value, is_group = input_field.studio_overrides() - if value is not NOT_SET: - values.update(value) - if is_group: - groups.extend(value.keys()) - if groups: - values[METADATA_KEY] = {"groups": groups} - return {self.key: values}, self.is_group + return self._override_values(False) def overrides(self): if not self.is_overriden and not self.child_overriden: return NOT_SET, False - - values = {} - groups = [] - for input_field in self.input_fields: - value, is_group = input_field.overrides() - if value is not NOT_SET: - values.update(value) - if is_group: - groups.extend(value.keys()) - if groups: - values[METADATA_KEY] = {"groups": groups} - return {self.key: values}, self.is_group + return self._override_values(True) class PathWidget(QtWidgets.QWidget, SettingObject): From 65d51d56a80638c5e0a6c79d6a1bbc67dd42093b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 18:51:42 +0200 Subject: [PATCH 083/176] raw-json can store environments --- pype/tools/settings/settings/widgets/item_types.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 74eab078e1..70f0506a2b 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1246,7 +1246,15 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): def item_value(self): if self.is_invalid: return NOT_SET - return self.input_field.json_value() + + value = self.input_field.json_value() + if self.is_environ: + value[METADATA_KEY] = { + "environments": { + self.env_group_key: list(value.keys()) + } + } + return value class ListItem(QtWidgets.QWidget, SettingObject): From 03bbc6e839eb8f71df7dab7d5701a0916bc6b777 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:01:16 +0200 Subject: [PATCH 084/176] raw json can return env value/keys --- .../settings/settings/widgets/item_types.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 70f0506a2b..1adebddff7 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1237,24 +1237,24 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): self._is_invalid = self.input_field.has_invalid_value() return super(RawJsonWidget, self)._on_value_change(*args, **kwargs) - def environment_value(self): - output = {} - for key, value in self.item_value().items(): - output[key.upper()] = value - return output - def item_value(self): if self.is_invalid: return NOT_SET value = self.input_field.json_value() - if self.is_environ: - value[METADATA_KEY] = { - "environments": { - self.env_group_key: list(value.keys()) - } + if not self.is_environ: + return value + + output = {} + for key, value in value.items(): + output[key.upper()] = value + + output[METADATA_KEY] = { + "environments": { + self.env_group_key: list(output.keys()) } - return value + } + return output class ListItem(QtWidgets.QWidget, SettingObject): From 484a35ae528dbf6e79610cc343591316098e5fad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:15:23 +0200 Subject: [PATCH 085/176] modified way how environments are loaded --- pype/settings/lib.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index b01c80038f..7c1adcd8a7 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -113,6 +113,32 @@ def load_json(fpath): return {} +def find_environments(data): + if not data or not isinstance(data, dict): + return + + output = {} + if M_ENVIRONMENT_KEY in data: + metadata = data.pop(M_ENVIRONMENT_KEY) + for env_group_key, env_keys in metadata.items(): + output[env_group_key] = {} + for key in env_keys: + output[env_group_key][key] = data[key] + + for value in data.values(): + result = find_environments(value) + if not result: + continue + + for env_group_key, env_values in result.items(): + if env_group_key not in output: + output[env_group_key] = {} + + for env_key, env_value in env_values.items(): + output[env_group_key][env_key] = env_value + return output + + def subkey_merge(_dict, value, keys): key = keys.pop(0) if not keys: @@ -274,5 +300,5 @@ def project_settings(project_name): def environments(): default_values = default_settings()[ENVIRONMENTS_KEY] - studio_values = studio_system_settings() + studio_values = find_environments(system_settings()) return apply_overrides(default_values, studio_values) From 87df2ea1019505911e908ac862afc3761719af52 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:30:18 +0200 Subject: [PATCH 086/176] added validation for env group keys --- pype/tools/settings/settings/widgets/lib.py | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 31e4401ab0..6d8694dc7a 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -162,6 +162,21 @@ class SchemaDuplicatedKeys(Exception): super(SchemaDuplicatedKeys, self).__init__(msg) +class SchemaDuplicatedEnvGroupKeys(Exception): + def __init__(self, invalid): + items = [] + for key_path, keys in invalid.items(): + joined_keys = ", ".join([ + "\"{}\"".format(key) for key in keys + ]) + items.append("\"{}\" ({})".format(key_path, joined_keys)) + + msg = ( + "Schema items contain duplicated environment group keys. {}" + ).format(" || ".join(items)) + super(SchemaDuplicatedEnvGroupKeys, self).__init__(msg) + + def file_keys_from_schema(schema_data): output = [] item_type = schema_data["type"] @@ -319,10 +334,50 @@ def validate_keys_are_unique(schema_data, keys=None): raise SchemaDuplicatedKeys(invalid) +def validate_environment_groups_uniquenes( + schema_data, env_groups=None, keys=None +): + is_first = False + if env_groups is None: + is_first = True + env_groups = {} + keys = [] + + my_keys = copy.deepcopy(keys) + key = schema_data.get("key") + if key: + my_keys.append(key) + + env_group_key = schema_data.get("env_group_key") + if env_group_key: + if env_group_key not in env_groups: + env_groups[env_group_key] = [] + env_groups[env_group_key].append("/".join(my_keys)) + + children = schema_data.get("children") + if not children: + return + + for child in children: + validate_environment_groups_uniquenes( + child, env_groups, copy.deepcopy(my_keys) + ) + + if is_first: + invalid = {} + for env_group_key, key_paths in env_groups.items(): + if len(key_paths) > 1: + invalid[env_group_key] = key_paths + + if invalid: + raise SchemaDuplicatedEnvGroupKeys(invalid) + + def validate_schema(schema_data): validate_all_has_ending_file(schema_data) validate_is_group_is_unique_in_hierarchy(schema_data) validate_keys_are_unique(schema_data) + validate_environment_groups_uniquenes(schema_data) def gui_schema(subfolder, main_schema_name): From d7492a13c4c828f200b2de74af2ba5a521506a7d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:36:43 +0200 Subject: [PATCH 087/176] added example of usage raw json for environments --- .../gui_schemas/system_schema/1_examples.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json index dd0f7f20d1..06ce23321a 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json @@ -5,6 +5,18 @@ "is_file": true, "children": [ { + "key": "env_group_test", + "label": "EnvGroup Test", + "type": "dict", + "children": [ + { + "key": "key_to_store_in_system_settings", + "label": "Testing environment group", + "type": "raw-json", + "env_group_key": "test_group" + } + ] + }, { "key": "dict_wrapper", "type": "dict-invisible", "children": [ From fb6061e80be838e113039083b3d00a824fb85a60 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:44:02 +0200 Subject: [PATCH 088/176] changed logic of environment keys loading --- pype/settings/lib.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 7c1adcd8a7..96c3829388 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -299,6 +299,8 @@ def project_settings(project_name): def environments(): - default_values = default_settings()[ENVIRONMENTS_KEY] - studio_values = find_environments(system_settings()) - return apply_overrides(default_values, studio_values) + envs = copy.deepcopy(default_settings()[ENVIRONMENTS_KEY]) + envs_from_system_settings = find_environments(system_settings()) + for env_group_key, values in envs_from_system_settings.items(): + envs[env_group_key] = values + return envs From de6daa65ca5e746dcf6dbc8ed8b90a7426846188 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 19:52:37 +0200 Subject: [PATCH 089/176] cleanup --- pype/tools/settings/settings/widgets/item_types.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 1adebddff7..1127d611d7 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -934,7 +934,6 @@ class NumberWidget(QtWidgets.QWidget, InputObject): class TextWidget(QtWidgets.QWidget, InputObject): default_input_value = "" value_changed = QtCore.Signal(object) - # allow_to_environment = True def __init__( self, input_data, parent, @@ -1038,7 +1037,6 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): class EnumeratorWidget(QtWidgets.QWidget, InputObject): default_input_value = True value_changed = QtCore.Signal(object) - # allow_to_environment = True def __init__( self, input_data, parent, @@ -1441,7 +1439,6 @@ class ListItem(QtWidgets.QWidget, SettingObject): class ListWidget(QtWidgets.QWidget, InputObject): default_input_value = [] value_changed = QtCore.Signal(object) - # allow_to_environment = True def __init__( self, input_data, parent, @@ -2014,7 +2011,6 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): # TODO this is actually input field (do not care if is group or not) value_changed = QtCore.Signal(object) expand_in_grid = True - # allow_to_environment = True def __init__( self, input_data, parent, @@ -2921,7 +2917,6 @@ class PathWidget(QtWidgets.QWidget, SettingObject): "darwin": "MacOS", "linux": "Linux" } - # allow_to_environment = True def __init__( self, input_data, parent, From 14ce8eb4428fead21aaafa8df55d90e5b6a5d26e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 1 Oct 2020 22:54:54 +0200 Subject: [PATCH 090/176] fix saving of environmentes to studio overrides --- pype/tools/settings/settings/widgets/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 6d8694dc7a..87f6554612 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -61,7 +61,7 @@ def convert_gui_data_to_overrides(data, first=True): output = {} if first: output["__override_version__"] = OVERRIDE_VERSION - data = convert_gui_data_with_metadata(data, ("environments",)) + data = convert_gui_data_with_metadata(data) if METADATA_KEY in data: metadata = data.pop(METADATA_KEY) From e7abb30da2dc4c8df14dd9ae173b87eca8b3e9c6 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 1 Oct 2020 23:57:12 +0200 Subject: [PATCH 091/176] add application schemas --- .../system_settings/global/applications.json | 286 ++++++++++++++++-- .../system_settings/global/hosts.json | 34 +++ .../system_schema/0_system_gui_schema.json | 3 + .../1_applications_gui_schema.json | 151 ++------- .../system_schema/1_hosts_gui_schema.json | 139 +++++++++ .../system_schema/system_harmony_schema.json | 86 ++++++ .../system_schema/system_hiero_schema.json | 128 ++++++++ .../system_schema/system_host_exe_schema.json | 39 +++ .../system_schema/system_houdini_schema.json | 52 ++++ .../system_schema/system_maya_schema.json | 69 +++++ .../system_schema/system_nuke_schema.json | 128 ++++++++ .../system_photoshop_schema.json | 35 +++ 12 files changed, 989 insertions(+), 161 deletions(-) create mode 100644 pype/settings/defaults/system_settings/global/hosts.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json diff --git a/pype/settings/defaults/system_settings/global/applications.json b/pype/settings/defaults/system_settings/global/applications.json index e85e5864d9..2cf64e396b 100644 --- a/pype/settings/defaults/system_settings/global/applications.json +++ b/pype/settings/defaults/system_settings/global/applications.json @@ -1,34 +1,256 @@ { - "blender_2.80": false, - "blender_2.81": false, - "blender_2.82": false, - "blender_2.83": true, - "celaction_local": true, - "celaction_remote": true, - "harmony_17": true, - "maya_2017": false, - "maya_2018": false, - "maya_2019": true, - "maya_2020": true, - "nuke_10.0": false, - "nuke_11.2": false, - "nuke_11.3": true, - "nuke_12.0": true, - "nukex_10.0": false, - "nukex_11.2": false, - "nukex_11.3": true, - "nukex_12.0": true, - "nukestudio_10.0": false, - "nukestudio_11.2": false, - "nukestudio_11.3": true, - "nukestudio_12.0": true, - "houdini_16": false, - "houdini_16.5": false, - "houdini_17": false, - "houdini_18": true, - "premiere_2019": false, - "premiere_2020": true, - "resolve_16": true, - "storyboardpro_7": true, - "unreal_4.24": true + "maya": { + "enabled": true, + "environment": {}, + "maya_2020": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "maya_2019": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "maya_2018": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + }, + "nuke": { + "enabled": true, + "environment": {}, + "nuke_12.1": { + "enabled": true, + "nukeX": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "nuke_11.3": { + "enabled": true, + "nukeX": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "nuke_11.2": { + "enabled": true, + "nukeX": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "nuke_11.1": { + "enabled": true, + "nukeX": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "nuke_10": { + "enabled": true, + "nukeX": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + }, + "hiero": { + "enabled": true, + "environment": {}, + "hiero_12.1": { + "enabled": true, + "nukestudio": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "hiero_11.3": { + "enabled": true, + "nukestudio": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "hiero_11.2": { + "enabled": true, + "nukestudio": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "hiero_11.1": { + "enabled": true, + "nukestudio": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "hiero_10": { + "enabled": true, + "nukestudio": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + }, + "houdini": { + "enabled": true, + "environment": {}, + "houdini_18": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "houdini_17": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + }, + "harmony": { + "enabled": true, + "environment_maya": {}, + "harmony_20": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "harmony_19": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "harmony_18": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + }, + "harmony_17": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + }, + "photoshop": { + "enabled": true, + "environment": {}, + "photoshop_2020": { + "enabled": true, + "common": { + "executable": { + "windows": [], + "linux": [], + "mac": [] + }, + "environment": {} + } + } + } } \ No newline at end of file diff --git a/pype/settings/defaults/system_settings/global/hosts.json b/pype/settings/defaults/system_settings/global/hosts.json new file mode 100644 index 0000000000..35ee708df3 --- /dev/null +++ b/pype/settings/defaults/system_settings/global/hosts.json @@ -0,0 +1,34 @@ +{ + "blender_2.80": true, + "blender_2.81": true, + "blender_2.82": true, + "blender_2.83": true, + "celaction_local": true, + "celaction_remote": true, + "harmony_17": true, + "maya_2017": true, + "maya_2018": true, + "maya_2019": true, + "maya_2020": true, + "nuke_10.0": true, + "nuke_11.2": true, + "nuke_11.3": true, + "nuke_12.0": true, + "nukex_10.0": true, + "nukex_11.2": true, + "nukex_11.3": true, + "nukex_12.0": true, + "nukestudio_10.0": true, + "nukestudio_11.2": true, + "nukestudio_11.3": true, + "nukestudio_12.0": true, + "houdini_16": true, + "houdini_16.5": true, + "houdini_17": true, + "houdini_18": true, + "premiere_2019": true, + "premiere_2020": true, + "resolve_16": true, + "storyboardpro_7": true, + "unreal_4.24": true +} \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json index c5f229fc2f..dbae81501e 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json @@ -14,6 +14,9 @@ }, { "type": "schema", "name": "1_applications_gui_schema" + }, { + "type": "schema", + "name": "1_hosts_gui_schema" }, { "type": "schema", "name": "1_tools_gui_schema" diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json index 3427f98253..95e2763f35 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json @@ -3,137 +3,30 @@ "type": "dict", "label": "Applications", "collapsable": true, - "is_group": true, "is_file": true, - "children": [ + "children": [{ + "type": "schema", + "name": "system_maya_schema" + }, { - "type": "boolean", - "key": "blender_2.80", - "label": "Blender 2.80" - }, { - "type": "boolean", - "key": "blender_2.81", - "label": "Blender 2.81" - }, { - "type": "boolean", - "key": "blender_2.82", - "label": "Blender 2.82" - }, { - "type": "boolean", - "key": "blender_2.83", - "label": "Blender 2.83" - }, { - "type": "boolean", - "key": "celaction_local", - "label": "Celaction Local" - }, { - "type": "boolean", - "key": "celaction_remote", - "label": "Celaction Remote" - }, { - "type": "boolean", - "key": "harmony_17", - "label": "Harmony 17" - }, { - "type": "boolean", - "key": "maya_2017", - "label": "Autodest Maya 2017" - }, { - "type": "boolean", - "key": "maya_2018", - "label": "Autodest Maya 2018" - }, { - "type": "boolean", - "key": "maya_2019", - "label": "Autodest Maya 2019" - }, { - "type": "boolean", - "key": "maya_2020", - "label": "Autodest Maya 2020" - }, { - "key": "nuke_10.0", - "type": "boolean", - "label": "Nuke 10.0" - }, { - "type": "boolean", - "key": "nuke_11.2", - "label": "Nuke 11.2" - }, { - "type": "boolean", - "key": "nuke_11.3", - "label": "Nuke 11.3" - }, { - "type": "boolean", - "key": "nuke_12.0", - "label": "Nuke 12.0" - }, { - "type": "boolean", - "key": "nukex_10.0", - "label": "NukeX 10.0" - }, { - "type": "boolean", - "key": "nukex_11.2", - "label": "NukeX 11.2" - }, { - "type": "boolean", - "key": "nukex_11.3", - "label": "NukeX 11.3" - }, { - "type": "boolean", - "key": "nukex_12.0", - "label": "NukeX 12.0" - }, { - "type": "boolean", - "key": "nukestudio_10.0", - "label": "NukeStudio 10.0" - }, { - "type": "boolean", - "key": "nukestudio_11.2", - "label": "NukeStudio 11.2" - }, { - "type": "boolean", - "key": "nukestudio_11.3", - "label": "NukeStudio 11.3" - }, { - "type": "boolean", - "key": "nukestudio_12.0", - "label": "NukeStudio 12.0" - }, { - "type": "boolean", - "key": "houdini_16", - "label": "Houdini 16" - }, { - "type": "boolean", - "key": "houdini_16.5", - "label": "Houdini 16.5" - }, { - "type": "boolean", - "key": "houdini_17", - "label": "Houdini 17" - }, { - "type": "boolean", - "key": "houdini_18", - "label": "Houdini 18" - }, { - "type": "boolean", - "key": "premiere_2019", - "label": "Premiere 2019" - }, { - "type": "boolean", - "key": "premiere_2020", - "label": "Premiere 2020" - }, { - "type": "boolean", - "key": "resolve_16", - "label": "BM DaVinci Resolve 16" - }, { - "type": "boolean", - "key": "storyboardpro_7", - "label": "Storyboard Pro 7" - }, { - "type": "boolean", - "key": "unreal_4.24", - "label": "Unreal Editor 4.24" + "type": "schema", + "name": "system_nuke_schema" + }, + { + "type": "schema", + "name": "system_hiero_schema" + }, + { + "type": "schema", + "name": "system_houdini_schema" + }, + { + "type": "schema", + "name": "system_harmony_schema" + }, + { + "type": "schema", + "name": "system_photoshop_schema" } ] } diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json new file mode 100644 index 0000000000..277b9d1d8e --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json @@ -0,0 +1,139 @@ +{ + "key": "hosts", + "type": "dict", + "label": "Hosts", + "collapsable": true, + "is_group": true, + "is_file": true, + "children": [ + { + "type": "boolean", + "key": "blender_2.80", + "label": "Blender 2.80" + }, { + "type": "boolean", + "key": "blender_2.81", + "label": "Blender 2.81" + }, { + "type": "boolean", + "key": "blender_2.82", + "label": "Blender 2.82" + }, { + "type": "boolean", + "key": "blender_2.83", + "label": "Blender 2.83" + }, { + "type": "boolean", + "key": "celaction_local", + "label": "Celaction Local" + }, { + "type": "boolean", + "key": "celaction_remote", + "label": "Celaction Remote" + }, { + "type": "boolean", + "key": "harmony_17", + "label": "Harmony 17" + }, { + "type": "boolean", + "key": "maya_2017", + "label": "Autodest Maya 2017" + }, { + "type": "boolean", + "key": "maya_2018", + "label": "Autodest Maya 2018" + }, { + "type": "boolean", + "key": "maya_2019", + "label": "Autodest Maya 2019" + }, { + "type": "boolean", + "key": "maya_2020", + "label": "Autodest Maya 2020" + }, { + "key": "nuke_10.0", + "type": "boolean", + "label": "Nuke 10.0" + }, { + "type": "boolean", + "key": "nuke_11.2", + "label": "Nuke 11.2" + }, { + "type": "boolean", + "key": "nuke_11.3", + "label": "Nuke 11.3" + }, { + "type": "boolean", + "key": "nuke_12.0", + "label": "Nuke 12.0" + }, { + "type": "boolean", + "key": "nukex_10.0", + "label": "NukeX 10.0" + }, { + "type": "boolean", + "key": "nukex_11.2", + "label": "NukeX 11.2" + }, { + "type": "boolean", + "key": "nukex_11.3", + "label": "NukeX 11.3" + }, { + "type": "boolean", + "key": "nukex_12.0", + "label": "NukeX 12.0" + }, { + "type": "boolean", + "key": "nukestudio_10.0", + "label": "NukeStudio 10.0" + }, { + "type": "boolean", + "key": "nukestudio_11.2", + "label": "NukeStudio 11.2" + }, { + "type": "boolean", + "key": "nukestudio_11.3", + "label": "NukeStudio 11.3" + }, { + "type": "boolean", + "key": "nukestudio_12.0", + "label": "NukeStudio 12.0" + }, { + "type": "boolean", + "key": "houdini_16", + "label": "Houdini 16" + }, { + "type": "boolean", + "key": "houdini_16.5", + "label": "Houdini 16.5" + }, { + "type": "boolean", + "key": "houdini_17", + "label": "Houdini 17" + }, { + "type": "boolean", + "key": "houdini_18", + "label": "Houdini 18" + }, { + "type": "boolean", + "key": "premiere_2019", + "label": "Premiere 2019" + }, { + "type": "boolean", + "key": "premiere_2020", + "label": "Premiere 2020" + }, { + "type": "boolean", + "key": "resolve_16", + "label": "BM DaVinci Resolve 16" + }, { + "type": "boolean", + "key": "storyboardpro_7", + "label": "Storyboard Pro 7" + }, { + "type": "boolean", + "key": "unreal_4.24", + "label": "Unreal Editor 4.24" + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json new file mode 100644 index 0000000000..4ef97bc8a2 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json @@ -0,0 +1,86 @@ +{ + "type": "dict", + "key": "harmony", + "label": "Toon Boom Harmony", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment_maya", + "label": "Environment" + }, + { + "type": "dict", + "key": "harmony_20", + "label": "20", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "harmony_19", + "label": "19", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "harmony_18", + "label": "18", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "harmony_17", + "label": "17", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json new file mode 100644 index 0000000000..ecbb98b281 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json @@ -0,0 +1,128 @@ +{ + "type": "dict", + "key": "hiero", + "label": "Foundry Hiero / Nuke Studio", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + }, + { + "type": "dict", + "key": "hiero_12.1", + "label": "12.1", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukestudio", + "label": "Nuke Studio" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "hiero_11.3", + "label": "11.3", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukestudio", + "label": "Nuke Studio" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "hiero_11.2", + "label": "11.2", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukestudio", + "label": "Nuke Studio" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "hiero_11.1", + "label": "11.1", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukestudio", + "label": "Nuke Studio" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "hiero_10", + "label": "10", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukestudio", + "label": "Nuke Studio" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json new file mode 100644 index 0000000000..7bf40ba69e --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json @@ -0,0 +1,39 @@ +{ + "type": "dict-invisible", + "key": "common", + "children": [{ + "type": "dict-invisible", + "key": "executable", + "children": [{ + "type": "list", + "key": "windows", + "label": "Windows Executable", + "object_type": { + "type": "text", + "multiline": false + } + }, { + "type": "list", + "key": "linux", + "label": "Linux Executable", + "object_type": { + "type": "text", + "multiline": false + } + }, { + "type": "list", + "key": "mac", + "label": "Mac Executable", + "object_type": { + "type": "text", + "multiline": false + } + }] + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json new file mode 100644 index 0000000000..a6f58da172 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json @@ -0,0 +1,52 @@ +{ + "type": "dict", + "key": "houdini", + "label": "SideFX Houdini", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + }, + { + "type": "dict", + "key": "houdini_18", + "label": "18", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "houdini_17", + "label": "17", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json new file mode 100644 index 0000000000..5c76f65792 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json @@ -0,0 +1,69 @@ +{ + "type": "dict", + "key": "maya", + "label": "Autodesk Maya", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + }, + { + "type": "dict", + "key": "maya_2020", + "label": "2020", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "maya_2019", + "label": "2019", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "maya_2018", + "label": "2018", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json new file mode 100644 index 0000000000..205a4bb11a --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json @@ -0,0 +1,128 @@ +{ + "type": "dict", + "key": "nuke", + "label": "Foundry Nuke", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + }, + { + "type": "dict", + "key": "nuke_12.1", + "label": "12.1", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukeX", + "label": "Nuke X" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "nuke_11.3", + "label": "11.3", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukeX", + "label": "Nuke X" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "nuke_11.2", + "label": "11.2", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukeX", + "label": "Nuke X" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "nuke_11.1", + "label": "11.1", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukeX", + "label": "Nuke X" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + }, + { + "type": "dict", + "key": "nuke_10", + "label": "10", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "nukeX", + "label": "Nuke X" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json new file mode 100644 index 0000000000..d04bcbed09 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json @@ -0,0 +1,35 @@ +{ + "type": "dict", + "key": "photoshop", + "label": "Adobe Photoshop", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "environment", + "label": "Environment" + }, + { + "type": "dict", + "key": "photoshop_2020", + "label": "2020", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "schema", + "name": "system_host_exe_schema" + } + ] + } + ] +} From a1d3b8180701faae9270a8675197a613bd8480a4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:03:52 +0200 Subject: [PATCH 092/176] renamed `1_examples.json` to `example_schema.json` --- .../system_schema/{1_examples.json => example_schema.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pype/tools/settings/settings/gui_schemas/system_schema/{1_examples.json => example_schema.json} (100%) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json similarity index 100% rename from pype/tools/settings/settings/gui_schemas/system_schema/1_examples.json rename to pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json From 39cf227447f2d82d8631dbae40ec3199a4afacfb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:09:48 +0200 Subject: [PATCH 093/176] added example template --- .../system_schema/example_template.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/example_template.json diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json new file mode 100644 index 0000000000..bf09ea6716 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json @@ -0,0 +1,14 @@ +[ + { + "type": "rawj-json", + "label": "{env_label}", + "key": "{env_group_key}", + "env_group_key": "{env_group_key}" + }, { + "type": "path-widget", + "key": "executable_paths", + "label": "{executable_label} - Full paths to executables", + "multiplatform": true, + "multipath": true + } +] From be135af8cee02d6c762311c04bbbec07b5799446 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:17:28 +0200 Subject: [PATCH 094/176] fixed example template --- .../gui_schemas/system_schema/example_template.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json index bf09ea6716..fb629c6170 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json @@ -1,13 +1,13 @@ [ { - "type": "rawj-json", - "label": "{env_label}", - "key": "{env_group_key}", - "env_group_key": "{env_group_key}" + "type": "raw-json", + "label": "{host_label} Environments", + "key": "{host_name}_environments", + "env_group_key": "{host_name}" }, { "type": "path-widget", - "key": "executable_paths", - "label": "{executable_label} - Full paths to executables", + "key": "{host_name}_executables", + "label": "{host_label} - Full paths to executables", "multiplatform": true, "multipath": true } From 3d07421dd95acc7a16dc2efa648a0943aecc79ec Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:17:43 +0200 Subject: [PATCH 095/176] added schema template to example schema --- .../system_schema/example_schema.json | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json index 06ce23321a..ddd4fc7235 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json @@ -5,6 +5,27 @@ "is_file": true, "children": [ { + "type": "dict", + "key": "schema_templates", + "label": "Schema template examples", + "children": [ + { + "type": "schema_template", + "name": "example_template", + "template_data": { + "host_label": "Maya 2019", + "host_name": "maya_2019" + } + }, { + "type": "schema_template", + "name": "example_template", + "template_data": { + "host_label": "Maya 2020", + "host_name": "maya_2020" + } + } + ] + }, { "key": "env_group_test", "label": "EnvGroup Test", "type": "dict", From 42fa4c9871ddb9b7b07eab198f39fb6884ba7835 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:18:58 +0200 Subject: [PATCH 096/176] schemas are also loaded in all subfolders --- pype/tools/settings/settings/widgets/lib.py | 27 ++++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 87f6554612..69f88df954 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -389,19 +389,22 @@ def gui_schema(subfolder, main_schema_name): ) loaded_schemas = {} - for filename in os.listdir(dirpath): - basename, ext = os.path.splitext(filename) - if ext != ".json": - continue + for root, _, filenames in os.walk(dirpath): + for filename in filenames: + basename, ext = os.path.splitext(filename) + if ext != ".json": + continue - filepath = os.path.join(dirpath, filename) - with open(filepath, "r") as json_stream: - try: - schema_data = json.load(json_stream) - except Exception as e: - raise Exception((f"Unable to parse JSON file {json_stream}\n " - f" - {e}")) from e - loaded_schemas[basename] = schema_data + filepath = os.path.join(root, filename) + with open(filepath, "r") as json_stream: + try: + schema_data = json.load(json_stream) + except Exception as exc: + raise Exception(( + f"Unable to parse JSON file {filepath}\n{exc}" + )) from exc + + loaded_schemas[basename] = schema_data main_schema = _fill_inner_schemas( loaded_schemas[main_schema_name], From c81d491198896290c7b0589f675514b7e58fd267 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:19:35 +0200 Subject: [PATCH 097/176] if schema json contain list it is stored as template --- pype/tools/settings/settings/widgets/lib.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 69f88df954..377f947d83 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -389,6 +389,7 @@ def gui_schema(subfolder, main_schema_name): ) loaded_schemas = {} + loaded_schema_templates = {} for root, _, filenames in os.walk(dirpath): for filename in filenames: basename, ext = os.path.splitext(filename) @@ -403,8 +404,10 @@ def gui_schema(subfolder, main_schema_name): raise Exception(( f"Unable to parse JSON file {filepath}\n{exc}" )) from exc - - loaded_schemas[basename] = schema_data + if isinstance(schema_data, list): + loaded_schema_templates[basename] = schema_data + else: + loaded_schemas[basename] = schema_data main_schema = _fill_inner_schemas( loaded_schemas[main_schema_name], From dd29192ffe970587b5288043ae7994911670ecd6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:20:48 +0200 Subject: [PATCH 098/176] implemented filling data of schema template --- pype/tools/settings/settings/widgets/lib.py | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 377f947d83..7e4d5b126c 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -1,4 +1,5 @@ import os +import re import json import copy from pype.settings.lib import M_OVERRIDEN_KEY, M_ENVIRONMENT_KEY @@ -15,6 +16,8 @@ METADATA_KEY = type("METADATA_KEY", (), {})() OVERRIDE_VERSION = 1 CHILD_OFFSET = 15 +key_pattern = re.compile(r"(\{.*?[^{0]*\})") + def convert_gui_data_with_metadata(data, ignored_keys=None): if not data or not isinstance(data, dict): @@ -96,6 +99,58 @@ def convert_overrides_to_gui_data(data, first=True): return output +def _fill_schema_template_data( + template, template_data, required_keys=None, missing_keys=None +): + first = False + if required_keys is None: + first = True + required_keys = set() + missing_keys = set() + + if not template: + output = template + + elif isinstance(template, list): + output = [] + for item in template: + output.append(_fill_schema_template_data( + item, template_data, required_keys, missing_keys + )) + + elif isinstance(template, dict): + output = {} + for key, value in template.items(): + output[key] = _fill_schema_template_data( + value, template_data, required_keys, missing_keys + ) + + elif isinstance(template, str): + # TODO find much better way how to handle filling template data + for replacement_string in key_pattern.findall(template): + key = str(replacement_string[1:-1]) + required_keys.add(key) + if key not in template_data: + missing_keys.add(key) + continue + + value = template_data[key] + if replacement_string == template: + # Replace the value with value from templates data + # - with this is possible to set value with different type + template = value + else: + # Only replace the key in string + template = template.replace(replacement_string, value) + output = template + + else: + output = template + + if first and missing_keys: + raise SchemaTemplateMissingKeys(missing_keys, required_keys) + + return output def _fill_inner_schemas(schema_data, schema_collection): if schema_data["type"] == "schema": raise ValueError("First item in schema data can't be schema.") From 3a53f8a9441e471d989e5be22dff2fcfb10d6d92 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:21:26 +0200 Subject: [PATCH 099/176] implemented function for handling `schema_template` item --- pype/tools/settings/settings/widgets/lib.py | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 7e4d5b126c..aec28c949c 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -151,6 +151,45 @@ def _fill_schema_template_data( raise SchemaTemplateMissingKeys(missing_keys, required_keys) return output + + +def _fill_schema_template(child_data, schema_collection, schema_templates): + template_name = child_data["name"] + template = schema_templates.get(template_name) + if template is None: + if template_name in schema_collection: + raise KeyError(( + "Schema \"{}\" is used as `schema_template`" + ).format(template_name)) + raise KeyError("Schema template \"{}\" was not found".format( + template_name + )) + + template_data = child_data.get("template_data") or {} + try: + filled_child = _fill_schema_template_data( + template, template_data + ) + + except SchemaTemplateMissingKeys as exc: + raise SchemaTemplateMissingKeys( + exc.missing_keys, exc.required_keys, template_name + ) + + output = [] + for item in filled_child: + filled_item = _fill_inner_schemas( + item, schema_collection, schema_templates + ) + if filled_item["type"] == "schema_template": + output.extend(_fill_schema_template( + filled_item, schema_collection, schema_templates + )) + else: + output.append(filled_item) + return output + + def _fill_inner_schemas(schema_data, schema_collection): if schema_data["type"] == "schema": raise ValueError("First item in schema data can't be schema.") From 93f489d0c36cf52ef601e17c51271a918461bf94 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:21:52 +0200 Subject: [PATCH 100/176] implemented exception for missing keys --- pype/tools/settings/settings/widgets/lib.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index aec28c949c..a20bf0608f 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -215,6 +215,26 @@ def _fill_inner_schemas(schema_data, schema_collection): return schema_data +class SchemaTemplateMissingKeys(Exception): + def __init__(self, missing_keys, required_keys, template_name=None): + self.missing_keys = missing_keys + self.required_keys = required_keys + if template_name: + msg = f"Schema template \"{template_name}\" require more keys.\n" + else: + msg = "" + msg += "Required keys: {}\nMissing keys: {}".format( + self.join_keys(required_keys), + self.join_keys(missing_keys) + ) + super(SchemaTemplateMissingKeys, self).__init__(msg) + + def join_keys(self, keys): + return ", ".join([ + f"\"{key}\"" for key in keys + ]) + + class SchemaMissingFileInfo(Exception): def __init__(self, invalid): full_path_keys = [] From bb786b27db619e4107bb339921dcbb2eb3f011fe Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:23:12 +0200 Subject: [PATCH 101/176] _fill_inner_schemas now can work with schema templates --- pype/tools/settings/settings/widgets/lib.py | 42 ++++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index a20bf0608f..9624a0df6a 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -190,7 +190,7 @@ def _fill_schema_template(child_data, schema_collection, schema_templates): return output -def _fill_inner_schemas(schema_data, schema_collection): +def _fill_inner_schemas(schema_data, schema_collection, schema_templates): if schema_data["type"] == "schema": raise ValueError("First item in schema data can't be schema.") @@ -200,16 +200,37 @@ def _fill_inner_schemas(schema_data, schema_collection): new_children = [] for child in children: - if child["type"] != "schema": - new_child = _fill_inner_schemas(child, schema_collection) - new_children.append(new_child) + child_type = child["type"] + if child_type == "schema": + schema_name = child["name"] + if schema_name not in schema_collection: + if schema_name in schema_templates: + raise KeyError(( + "Schema template \"{}\" is used as `schema`" + ).format(schema_name)) + raise KeyError( + "Schema \"{}\" was not found".format(schema_name) + ) + + filled_child = _fill_inner_schemas( + schema_collection[schema_name], + schema_collection, + schema_templates + ) + + elif child_type == "schema_template": + for filled_child in _fill_schema_template( + child, schema_collection, schema_templates + ): + new_children.append(filled_child) continue - new_child = _fill_inner_schemas( - schema_collection[child["name"]], - schema_collection - ) - new_children.append(new_child) + else: + filled_child = _fill_inner_schemas( + child, schema_collection, schema_templates + ) + + new_children.append(filled_child) schema_data["children"] = new_children return schema_data @@ -525,7 +546,8 @@ def gui_schema(subfolder, main_schema_name): main_schema = _fill_inner_schemas( loaded_schemas[main_schema_name], - loaded_schemas + loaded_schemas, + loaded_schema_templates ) validate_schema(main_schema) return main_schema From 0c79c09a7e182fe23f325f6d353142ad0ac9af8c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:30:41 +0200 Subject: [PATCH 102/176] added possibility of default values in template --- pype/tools/settings/settings/widgets/lib.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index 9624a0df6a..569e7bfbb7 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -108,6 +108,19 @@ def _fill_schema_template_data( required_keys = set() missing_keys = set() + _template = [] + default_values = {} + for item in template: + if isinstance(item, dict) and "__default_values__" in item: + default_values = item["__default_values__"] + else: + _template.append(item) + template = _template + + for key, value in default_values.items(): + if key not in template_data: + template_data[key] = value + if not template: output = template From af9be455d9d1a09c197efab502cc258e1bb0645d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 14:31:02 +0200 Subject: [PATCH 103/176] added default values of templates ability to examples --- .../settings/gui_schemas/system_schema/example_schema.json | 3 ++- .../gui_schemas/system_schema/example_template.json | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json index ddd4fc7235..09624006f9 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json @@ -14,7 +14,8 @@ "name": "example_template", "template_data": { "host_label": "Maya 2019", - "host_name": "maya_2019" + "host_name": "maya_2019", + "multiplath_executables": false } }, { "type": "schema_template", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json index fb629c6170..29d3da26c9 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json @@ -1,5 +1,9 @@ [ { + "__default_values__": { + "multiplath_executables": true + } + }, { "type": "raw-json", "label": "{host_label} Environments", "key": "{host_name}_environments", @@ -8,7 +12,7 @@ "type": "path-widget", "key": "{host_name}_executables", "label": "{host_label} - Full paths to executables", - "multiplatform": true, + "multiplatform": "{multiplath_executables}", "multipath": true } ] From d241877895cee6c55a3239b5a6f82e5cdc2b9ce6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 15:02:46 +0200 Subject: [PATCH 104/176] added schema_template to readme --- pype/tools/settings/settings/README.md | 82 ++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/pype/tools/settings/settings/README.md b/pype/tools/settings/settings/README.md index e8b7fcdb57..974a9c932b 100644 --- a/pype/tools/settings/settings/README.md +++ b/pype/tools/settings/settings/README.md @@ -19,6 +19,7 @@ - GUI schemas are huge json files, to be able to split whole configuration into multiple schema there's type `schema` - system configuration schemas are stored in `~/tools/settings/settings/gui_schemas/system_schema/` and project configurations in `~/tools/settings/settings/gui_schemas/projects_schema/` - each schema name is filename of json file except extension (without ".json") +- if content is dictionary content will be used as `schema` else will be used as `schema_template` ### schema - can have only key `"children"` which is list of strings, each string should represent another schema (order matters) string represebts name of the schema @@ -31,6 +32,87 @@ } ``` +### schema_template +- allows to define schema "templates" to not duplicate same content multiple times +```javascript +// EXAMPLE json file content (filename: example_template.json) +[ + { + "__default_values__": { + "multiplath_executables": true + } + }, { + "type": "raw-json", + "label": "{host_label} Environments", + "key": "{host_name}_environments", + "env_group_key": "{host_name}" + }, { + "type": "path-widget", + "key": "{host_name}_executables", + "label": "{host_label} - Full paths to executables", + "multiplatform": "{multiplath_executables}", + "multipath": true + } +] +``` +```javascript +// EXAMPLE usage of the template in schema +{ + "type": "dict", + "key": "schema_template_examples", + "label": "Schema template examples", + "children": [ + { + "type": "schema_template", + // filename of template (example_template.json) + "name": "example_template", + "template_data": { + "host_label": "Maya 2019", + "host_name": "maya_2019", + "multiplath_executables": false + } + }, { + "type": "schema_template", + "name": "example_template", + "template_data": { + "host_label": "Maya 2020", + "host_name": "maya_2020" + } + } + ] +} +``` +- item in schema mush contain `"type"` and `"name"` keys but it is also expected that `"template_data"` will be entered too +- all items in the list, except `__default_values__`, will replace `schema_template` item in schema +- template may contain another template or schema +- it is expected that schema template will have unfilled fields as in example + - unfilled fields are allowed only in values of schema dictionary +```javascript +{ + ... + // Allowed + "key": "{to_fill}" + ... + // Not allowed + "{to_fill}": "value" + ... +} +``` +- Unfilled fields can be also used for non string values, in that case value must contain only one key and value for fill must contain right type. +```javascript +{ + ... + // Allowed + "multiplatform": "{executable_multiplatform}" + ... + // Not allowed + "multiplatform": "{executable_multiplatform}_enhanced_string" + ... +} +``` +- It is possible to define default values for unfilled fields to do so one of items in list must be dictionary with key `"__default_values__"` and value as dictionary with default key: values (as in example above). + + ## Basic Dictionary inputs - these inputs wraps another inputs into {key: value} relation From 03e8f647fd2799652355ec4532ccc30b030698dd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 15:03:16 +0200 Subject: [PATCH 105/176] modified example key --- .../settings/gui_schemas/system_schema/example_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json index 09624006f9..814fe95d0c 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json @@ -6,7 +6,7 @@ "children": [ { "type": "dict", - "key": "schema_templates", + "key": "schema_template_exaples", "label": "Schema template examples", "children": [ { From 7364c6c29def5d779266b451069133d28898c7ab Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 15:09:19 +0200 Subject: [PATCH 106/176] fixed typo --- pype/tools/settings/settings/README.md | 6 +++--- .../settings/gui_schemas/system_schema/example_schema.json | 2 +- .../gui_schemas/system_schema/example_template.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/README.md b/pype/tools/settings/settings/README.md index 974a9c932b..4f4e9d305a 100644 --- a/pype/tools/settings/settings/README.md +++ b/pype/tools/settings/settings/README.md @@ -39,7 +39,7 @@ [ { "__default_values__": { - "multiplath_executables": true + "multipath_executables": true } }, { "type": "raw-json", @@ -50,7 +50,7 @@ "type": "path-widget", "key": "{host_name}_executables", "label": "{host_label} - Full paths to executables", - "multiplatform": "{multiplath_executables}", + "multiplatform": "{multipath_executables}", "multipath": true } ] @@ -69,7 +69,7 @@ "template_data": { "host_label": "Maya 2019", "host_name": "maya_2019", - "multiplath_executables": false + "multipath_executables": false } }, { "type": "schema_template", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json index 814fe95d0c..7612e54116 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_schema.json @@ -15,7 +15,7 @@ "template_data": { "host_label": "Maya 2019", "host_name": "maya_2019", - "multiplath_executables": false + "multipath_executables": false } }, { "type": "schema_template", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json index 29d3da26c9..48a3c955b9 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/example_template.json @@ -1,7 +1,7 @@ [ { "__default_values__": { - "multiplath_executables": true + "multipath_executables": true } }, { "type": "raw-json", @@ -12,7 +12,7 @@ "type": "path-widget", "key": "{host_name}_executables", "label": "{host_label} - Full paths to executables", - "multiplatform": "{multiplath_executables}", + "multiplatform": "{multipath_executables}", "multipath": true } ] From 1b07985680dded6cc8adbc0c44ef21457e72b3e8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 16:07:01 +0200 Subject: [PATCH 107/176] moved back what was removed during merge --- pype/tools/settings/settings/widgets/item_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 375dde566e..822cd93d9b 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1242,6 +1242,7 @@ class RawJsonInput(QtWidgets.QPlainTextEdit): class RawJsonWidget(QtWidgets.QWidget, InputObject): default_input_value = "{}" value_changed = QtCore.Signal(object) + valid_value_types = (str, dict, list, type(NOT_SET)) allow_to_environment = True def __init__( From 805964c5e5b37f6c2aedd04cbcac35b8672d9b16 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 16:17:22 +0200 Subject: [PATCH 108/176] enhanced type check --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 822cd93d9b..ebce465163 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -57,7 +57,7 @@ class SettingObject: return for valid_type in self.valid_value_types: - if isinstance(value, valid_type): + if type(value) is valid_type: return key = getattr(self, "key", None) @@ -281,7 +281,7 @@ class SettingObject: def is_modified(self): """Has object any changes that require saving.""" if self.any_parent_as_widget: - return self._is_modified + return self._is_modified or self.defaults_not_set if self._is_modified or self.defaults_not_set: return True From b94ca1f2d26217f4212d04507a1ef259bd3a9a6d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 16:18:28 +0200 Subject: [PATCH 109/176] TextWidget can have only string --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index ebce465163..535e96a665 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -983,7 +983,7 @@ class NumberWidget(QtWidgets.QWidget, InputObject): class TextWidget(QtWidgets.QWidget, InputObject): default_input_value = "" value_changed = QtCore.Signal(object) - valid_value_types = (int, str) + valid_value_types = (str, ) def __init__( self, input_data, parent, From 3f088b8bebb34a85cf044a06ca883a175a7221cd Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 17:03:38 +0200 Subject: [PATCH 110/176] add hosts schemas to settings --- .../system_settings/global/applications.json | 703 ++++++++++++++---- .../system_schema/0_system_gui_schema.json | 3 - .../1_applications_gui_schema.json | 54 +- .../system_schema/1_hosts_gui_schema.json | 139 ---- .../host_settings/system_blender_schema.json | 35 + .../system_celaction_schema.json | 39 + .../host_settings/system_fusion_schema.json | 35 + .../host_settings/system_harmony_schema.json | 51 ++ .../host_settings/system_host_template.json | 33 + .../host_settings/system_houdini_schema.json | 35 + .../host_settings/system_maya_schema.json | 43 ++ .../host_settings/system_nuke_template.json | 65 ++ .../system_photoshop_schema.json | 27 + .../host_settings/system_resolve_schema.json | 27 + .../host_settings/system_shell_schema.json | 43 ++ .../host_settings/system_unreal_schema.json | 27 + .../system_schema/system_harmony_schema.json | 86 --- .../system_schema/system_hiero_schema.json | 128 ---- .../system_schema/system_host_exe_schema.json | 39 - .../system_schema/system_houdini_schema.json | 52 -- .../system_schema/system_maya_schema.json | 69 -- .../system_schema/system_nuke_schema.json | 128 ---- .../system_photoshop_schema.json | 35 - 23 files changed, 1054 insertions(+), 842 deletions(-) delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_blender_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_celaction_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_fusion_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_harmony_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_houdini_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_maya_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_photoshop_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_resolve_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_shell_schema.json create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_unreal_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json delete mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json diff --git a/pype/settings/defaults/system_settings/global/applications.json b/pype/settings/defaults/system_settings/global/applications.json index 2cf64e396b..222d9e1173 100644 --- a/pype/settings/defaults/system_settings/global/applications.json +++ b/pype/settings/defaults/system_settings/global/applications.json @@ -1,255 +1,638 @@ { "maya": { "enabled": true, - "environment": {}, + "environment": { + "__environment_keys__": { + "maya": [] + } + }, "maya_2020": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "maya_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "maya_2020": [] + } } }, "maya_2019": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "maya_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "maya_2019": [] + } } }, "maya_2018": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "maya_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "maya_2018": [] + } } } }, "nuke": { "enabled": true, - "environment": {}, - "nuke_12.1": { + "environment": { + "__environment_keys__": { + "nuke": [] + } + }, + "nuke_12.0": { "enabled": true, - "nukeX": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "nuke_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nuke_12.0": [] + } } }, "nuke_11.3": { "enabled": true, - "nukeX": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "nuke_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nuke_11.3": [] + } } }, "nuke_11.2": { "enabled": true, - "nukeX": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "nuke_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nuke_11.2": [] + } } }, "nuke_11.1": { "enabled": true, - "nukeX": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "nuke_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nuke_11.1": [] + } } }, - "nuke_10": { + "nuke_10.0": { "enabled": true, - "nukeX": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "nuke_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nuke_10.0": [] + } + } + } + }, + "nukex": { + "enabled": true, + "environment": { + "__environment_keys__": { + "nukex": [] + } + }, + "nukex_12.0": { + "enabled": true, + "nukex_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukex_12.0": [] + } + } + }, + "nukex_11.3": { + "enabled": true, + "nukex_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukex_11.3": [] + } + } + }, + "nukex_11.2": { + "enabled": true, + "nukex_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukex_11.2": [] + } + } + }, + "nukex_11.1": { + "enabled": true, + "nukex_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukex_11.1": [] + } + } + }, + "nukex_10.0": { + "enabled": true, + "nukex_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukex_10.0": [] + } + } + } + }, + "nukestudio": { + "enabled": true, + "environment": { + "__environment_keys__": { + "nukestudio": [] + } + }, + "nukestudio_12.0": { + "enabled": true, + "nukestudio_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukestudio_12.0": [] + } + } + }, + "nukestudio_11.3": { + "enabled": true, + "nukestudio_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukestudio_11.3": [] + } + } + }, + "nukestudio_11.2": { + "enabled": true, + "nukestudio_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukestudio_11.2": [] + } + } + }, + "nukestudio_11.1": { + "enabled": true, + "nukestudio_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukestudio_11.1": [] + } + } + }, + "nukestudio_10.0": { + "enabled": true, + "nukestudio_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "nukestudio_10.0": [] + } } } }, "hiero": { "enabled": true, - "environment": {}, - "hiero_12.1": { + "environment": { + "__environment_keys__": { + "hiero": [] + } + }, + "hiero_12.0": { "enabled": true, - "nukestudio": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "hiero_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "hiero_12.0": [] + } } }, "hiero_11.3": { "enabled": true, - "nukestudio": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "hiero_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "hiero_11.3": [] + } } }, "hiero_11.2": { "enabled": true, - "nukestudio": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "hiero_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "hiero_11.2": [] + } } }, "hiero_11.1": { "enabled": true, - "nukestudio": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "hiero_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "hiero_11.1": [] + } } }, - "hiero_10": { + "hiero_10.0": { "enabled": true, - "nukestudio": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "hiero_executables": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": { + "__environment_keys__": { + "hiero_10.0": [] + } + } + } + }, + "fusion": { + "enabled": true, + "environment": { + "__environment_keys__": { + "fusion": [] + } + }, + "fusion_16": { + "enabled": true, + "fusion_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "fusion_16": [] + } + } + }, + "fusion_9": { + "enabled": true, + "fusion_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "fusion_9": [] + } + } + } + }, + "resolve": { + "enabled": true, + "environment": { + "__environment_keys__": { + "resolve": [] + } + }, + "resolve_16": { + "enabled": true, + "resolve_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "resolve_16": [] + } } } }, "houdini": { "enabled": true, - "environment": {}, + "environment": { + "__environment_keys__": { + "houdini": [] + } + }, "houdini_18": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "houdini_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "houdini_18": [] + } } }, "houdini_17": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "houdini_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "houdini_17": [] + } + } + } + }, + "blender": { + "enabled": true, + "environment": { + "__environment_keys__": { + "blender": [] + } + }, + "blender_2.90": { + "enabled": true, + "blender_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "blender_2.90": [] + } + } + }, + "blender_2.83": { + "enabled": true, + "blender_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "blender_2.83": [] + } } } }, "harmony": { "enabled": true, - "environment_maya": {}, + "environment": { + "__environment_keys__": { + "harmony": [] + } + }, "harmony_20": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "harmony_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "harmony_20": [] + } } }, "harmony_19": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "harmony_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "harmony_19": [] + } } }, "harmony_18": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "harmony_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "harmony_18": [] + } } }, "harmony_17": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "harmony_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "harmony_17": [] + } } } }, "photoshop": { "enabled": true, - "environment": {}, + "environment": { + "__environment_keys__": { + "photoshop": [] + } + }, "photoshop_2020": { "enabled": true, - "common": { - "executable": { - "windows": [], - "linux": [], - "mac": [] - }, - "environment": {} + "photoshop_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "photoshop_2020": [] + } + } + } + }, + "celaction": { + "enabled": true, + "environment": { + "__environment_keys__": { + "celaction": [] + } + }, + "celation_Local": { + "enabled": true, + "celation_executables": "", + "environment": { + "__environment_keys__": { + "celation_Local": [] + } + } + }, + "celation_Publish": { + "enabled": true, + "celation_executables": "", + "environment": { + "__environment_keys__": { + "celation_Publish": [] + } + } + } + }, + "unreal": { + "enabled": true, + "environment": { + "__environment_keys__": { + "unreal": [] + } + }, + "unreal_4.24": { + "enabled": true, + "unreal_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "unreal_4.24": [] + } + } + } + }, + "shell": { + "enabled": true, + "environment": { + "__environment_keys__": { + "shell": [] + } + }, + "python_Python 3.7": { + "enabled": true, + "python_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "python_Python 3.7": [] + } + } + }, + "python_Python 2.7": { + "enabled": true, + "python_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "python_Python 2.7": [] + } + } + }, + "terminal_Terminal": { + "enabled": true, + "terminal_executables": { + "windows": "", + "darwin": "", + "linux": "" + }, + "environment": { + "__environment_keys__": { + "terminal_Terminal": [] + } } } } diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json index dbae81501e..c5f229fc2f 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json @@ -14,9 +14,6 @@ }, { "type": "schema", "name": "1_applications_gui_schema" - }, { - "type": "schema", - "name": "1_hosts_gui_schema" }, { "type": "schema", "name": "1_tools_gui_schema" diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json index 95e2763f35..d1fa4e79f5 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json @@ -9,17 +9,53 @@ "name": "system_maya_schema" }, { - "type": "schema", - "name": "system_nuke_schema" + "type": "schema_template", + "name": "system_nuke_template", + "template_data": { + "nuke_type": "nuke", + "nuke_label": "Nuke" + } + }, + { + "type": "schema_template", + "name": "system_nuke_template", + "template_data": { + "nuke_type": "nukex", + "nuke_label": "Nuke X" + } + }, + { + "type": "schema_template", + "name": "system_nuke_template", + "template_data": { + "nuke_type": "nukestudio", + "nuke_label": "Nuke Studio" + } + }, + { + "type": "schema_template", + "name": "system_nuke_template", + "template_data": { + "nuke_type": "hiero", + "nuke_label": "Hiero" + } }, { "type": "schema", - "name": "system_hiero_schema" + "name": "system_fusion_schema" + }, + { + "type": "schema", + "name": "system_resolve_schema" }, { "type": "schema", "name": "system_houdini_schema" }, + { + "type": "schema", + "name": "system_blender_schema" + }, { "type": "schema", "name": "system_harmony_schema" @@ -27,6 +63,18 @@ { "type": "schema", "name": "system_photoshop_schema" + }, + { + "type": "schema", + "name": "system_celaction_schema" + }, + { + "type": "schema", + "name": "system_unreal_schema" + }, + { + "type": "schema", + "name": "system_shell_schema" } ] } diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json deleted file mode 100644 index 277b9d1d8e..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_hosts_gui_schema.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "key": "hosts", - "type": "dict", - "label": "Hosts", - "collapsable": true, - "is_group": true, - "is_file": true, - "children": [ - { - "type": "boolean", - "key": "blender_2.80", - "label": "Blender 2.80" - }, { - "type": "boolean", - "key": "blender_2.81", - "label": "Blender 2.81" - }, { - "type": "boolean", - "key": "blender_2.82", - "label": "Blender 2.82" - }, { - "type": "boolean", - "key": "blender_2.83", - "label": "Blender 2.83" - }, { - "type": "boolean", - "key": "celaction_local", - "label": "Celaction Local" - }, { - "type": "boolean", - "key": "celaction_remote", - "label": "Celaction Remote" - }, { - "type": "boolean", - "key": "harmony_17", - "label": "Harmony 17" - }, { - "type": "boolean", - "key": "maya_2017", - "label": "Autodest Maya 2017" - }, { - "type": "boolean", - "key": "maya_2018", - "label": "Autodest Maya 2018" - }, { - "type": "boolean", - "key": "maya_2019", - "label": "Autodest Maya 2019" - }, { - "type": "boolean", - "key": "maya_2020", - "label": "Autodest Maya 2020" - }, { - "key": "nuke_10.0", - "type": "boolean", - "label": "Nuke 10.0" - }, { - "type": "boolean", - "key": "nuke_11.2", - "label": "Nuke 11.2" - }, { - "type": "boolean", - "key": "nuke_11.3", - "label": "Nuke 11.3" - }, { - "type": "boolean", - "key": "nuke_12.0", - "label": "Nuke 12.0" - }, { - "type": "boolean", - "key": "nukex_10.0", - "label": "NukeX 10.0" - }, { - "type": "boolean", - "key": "nukex_11.2", - "label": "NukeX 11.2" - }, { - "type": "boolean", - "key": "nukex_11.3", - "label": "NukeX 11.3" - }, { - "type": "boolean", - "key": "nukex_12.0", - "label": "NukeX 12.0" - }, { - "type": "boolean", - "key": "nukestudio_10.0", - "label": "NukeStudio 10.0" - }, { - "type": "boolean", - "key": "nukestudio_11.2", - "label": "NukeStudio 11.2" - }, { - "type": "boolean", - "key": "nukestudio_11.3", - "label": "NukeStudio 11.3" - }, { - "type": "boolean", - "key": "nukestudio_12.0", - "label": "NukeStudio 12.0" - }, { - "type": "boolean", - "key": "houdini_16", - "label": "Houdini 16" - }, { - "type": "boolean", - "key": "houdini_16.5", - "label": "Houdini 16.5" - }, { - "type": "boolean", - "key": "houdini_17", - "label": "Houdini 17" - }, { - "type": "boolean", - "key": "houdini_18", - "label": "Houdini 18" - }, { - "type": "boolean", - "key": "premiere_2019", - "label": "Premiere 2019" - }, { - "type": "boolean", - "key": "premiere_2020", - "label": "Premiere 2020" - }, { - "type": "boolean", - "key": "resolve_16", - "label": "BM DaVinci Resolve 16" - }, { - "type": "boolean", - "key": "storyboardpro_7", - "label": "Storyboard Pro 7" - }, { - "type": "boolean", - "key": "unreal_4.24", - "label": "Unreal Editor 4.24" - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_blender_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_blender_schema.json new file mode 100644 index 0000000000..8600d8de8a --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_blender_schema.json @@ -0,0 +1,35 @@ +{ + "type": "dict", + "key": "blender", + "label": "Blender", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "blender" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2.90", + "host_name": "blender" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2.83", + "host_name": "blender" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_celaction_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_celaction_schema.json new file mode 100644 index 0000000000..36addab00d --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_celaction_schema.json @@ -0,0 +1,39 @@ +{ + "type": "dict", + "key": "celaction", + "label": "CelAction2D", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "celaction" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "Local", + "host_name": "celation", + "multiplatform": false, + "multipath_executables": false + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "Publish", + "host_name": "celation", + "multiplatform": false, + "multipath_executables": false + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_fusion_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_fusion_schema.json new file mode 100644 index 0000000000..b3dc79ef97 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_fusion_schema.json @@ -0,0 +1,35 @@ +{ + "type": "dict", + "key": "fusion", + "label": "Blackmagic Fusion", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "fusion" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "16", + "host_name": "fusion" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "9", + "host_name": "fusion" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_harmony_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_harmony_schema.json new file mode 100644 index 0000000000..10cb929fc4 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_harmony_schema.json @@ -0,0 +1,51 @@ +{ + "type": "dict", + "key": "harmony", + "label": "Toon Boom Harmony", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "harmony" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "20", + "host_name": "harmony" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "19", + "host_name": "harmony" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "18", + "host_name": "harmony" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "17", + "host_name": "harmony" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json new file mode 100644 index 0000000000..dd4d3c8b4b --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json @@ -0,0 +1,33 @@ +[{ + "__default_values__": { + "multipath_executables": false, + "multiplatform": true + } + }, + { + "type": "dict", + "key": "{host_name}_{host_version}", + "label": "{host_version}", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "path-widget", + "key": "{host_name}_executables", + "label": "Executables", + "multiplatform": "{multiplatform}", + "multipath": "{multipath_executables}" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "{host_name}_{host_version}" + } + ] + } +] diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_houdini_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_houdini_schema.json new file mode 100644 index 0000000000..36c6d9fcb2 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_houdini_schema.json @@ -0,0 +1,35 @@ +{ + "type": "dict", + "key": "houdini", + "label": "SideFX Houdini", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "houdini" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "18", + "host_name": "houdini" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "17", + "host_name": "houdini" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_maya_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_maya_schema.json new file mode 100644 index 0000000000..710b62a9cc --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_maya_schema.json @@ -0,0 +1,43 @@ +{ + "type": "dict", + "key": "maya", + "label": "Autodesk Maya", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "maya" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2020", + "host_name": "maya" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2019", + "host_name": "maya" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2018", + "host_name": "maya" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json new file mode 100644 index 0000000000..36d68dba95 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json @@ -0,0 +1,65 @@ +[{ + "type": "dict", + "key": "{nuke_type}", + "label": "Foundry {nuke_label}", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "{nuke_type}" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "12.0", + "host_name": "{nuke_type}", + "multipath_executables": true + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "11.3", + "host_name": "{nuke_type}", + "multipath_executables": true + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "11.2", + "host_name": "{nuke_type}", + "multipath_executables": true + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "11.1", + "host_name": "{nuke_type}", + "multipath_executables": true + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "10.0", + "host_name": "{nuke_type}", + "multipath_executables": true + } + } + ] +} +] diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_photoshop_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_photoshop_schema.json new file mode 100644 index 0000000000..c1062045e7 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_photoshop_schema.json @@ -0,0 +1,27 @@ +{ + "type": "dict", + "key": "photoshop", + "label": "Adobe Photoshop", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "photoshop" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "2020", + "host_name": "photoshop" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_resolve_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_resolve_schema.json new file mode 100644 index 0000000000..364be8208d --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_resolve_schema.json @@ -0,0 +1,27 @@ +{ + "type": "dict", + "key": "resolve", + "label": "Blackmagic DaVinci Resolve", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "resolve" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "16", + "host_name": "resolve" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_shell_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_shell_schema.json new file mode 100644 index 0000000000..22955abc46 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_shell_schema.json @@ -0,0 +1,43 @@ +{ + "type": "dict", + "key": "shell", + "label": "Shell", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "shell" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "Python 3.7", + "host_name": "python" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "Python 2.7", + "host_name": "python" + } + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "Terminal", + "host_name": "terminal" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_unreal_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_unreal_schema.json new file mode 100644 index 0000000000..e0408f9a36 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_unreal_schema.json @@ -0,0 +1,27 @@ +{ + "type": "dict", + "key": "unreal", + "label": "Unreal Editor", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "unreal" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "4.24", + "host_name": "unreal" + } + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json deleted file mode 100644 index 4ef97bc8a2..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_harmony_schema.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "type": "dict", - "key": "harmony", - "label": "Toon Boom Harmony", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment_maya", - "label": "Environment" - }, - { - "type": "dict", - "key": "harmony_20", - "label": "20", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "harmony_19", - "label": "19", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "harmony_18", - "label": "18", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "harmony_17", - "label": "17", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json deleted file mode 100644 index ecbb98b281..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_hiero_schema.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "type": "dict", - "key": "hiero", - "label": "Foundry Hiero / Nuke Studio", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - }, - { - "type": "dict", - "key": "hiero_12.1", - "label": "12.1", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukestudio", - "label": "Nuke Studio" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "hiero_11.3", - "label": "11.3", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukestudio", - "label": "Nuke Studio" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "hiero_11.2", - "label": "11.2", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukestudio", - "label": "Nuke Studio" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "hiero_11.1", - "label": "11.1", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukestudio", - "label": "Nuke Studio" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "hiero_10", - "label": "10", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukestudio", - "label": "Nuke Studio" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json deleted file mode 100644 index 7bf40ba69e..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_host_exe_schema.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "type": "dict-invisible", - "key": "common", - "children": [{ - "type": "dict-invisible", - "key": "executable", - "children": [{ - "type": "list", - "key": "windows", - "label": "Windows Executable", - "object_type": { - "type": "text", - "multiline": false - } - }, { - "type": "list", - "key": "linux", - "label": "Linux Executable", - "object_type": { - "type": "text", - "multiline": false - } - }, { - "type": "list", - "key": "mac", - "label": "Mac Executable", - "object_type": { - "type": "text", - "multiline": false - } - }] - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json deleted file mode 100644 index a6f58da172..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_houdini_schema.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "type": "dict", - "key": "houdini", - "label": "SideFX Houdini", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - }, - { - "type": "dict", - "key": "houdini_18", - "label": "18", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "houdini_17", - "label": "17", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json deleted file mode 100644 index 5c76f65792..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_maya_schema.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "type": "dict", - "key": "maya", - "label": "Autodesk Maya", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - }, - { - "type": "dict", - "key": "maya_2020", - "label": "2020", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "maya_2019", - "label": "2019", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "maya_2018", - "label": "2018", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json deleted file mode 100644 index 205a4bb11a..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_nuke_schema.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "type": "dict", - "key": "nuke", - "label": "Foundry Nuke", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - }, - { - "type": "dict", - "key": "nuke_12.1", - "label": "12.1", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukeX", - "label": "Nuke X" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "nuke_11.3", - "label": "11.3", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukeX", - "label": "Nuke X" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "nuke_11.2", - "label": "11.2", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukeX", - "label": "Nuke X" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "nuke_11.1", - "label": "11.1", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukeX", - "label": "Nuke X" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - }, - { - "type": "dict", - "key": "nuke_10", - "label": "10", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "nukeX", - "label": "Nuke X" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json deleted file mode 100644 index d04bcbed09..0000000000 --- a/pype/tools/settings/settings/gui_schemas/system_schema/system_photoshop_schema.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "type": "dict", - "key": "photoshop", - "label": "Adobe Photoshop", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "environment", - "label": "Environment" - }, - { - "type": "dict", - "key": "photoshop_2020", - "label": "2020", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "schema", - "name": "system_host_exe_schema" - } - ] - } - ] -} From e64f7ad7d6945ec6a5da7faf78e990bf5006ad63 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 17:31:39 +0200 Subject: [PATCH 111/176] add default environments --- .../system_settings/global/applications.json | 282 ++++++++++++++++-- 1 file changed, 252 insertions(+), 30 deletions(-) diff --git a/pype/settings/defaults/system_settings/global/applications.json b/pype/settings/defaults/system_settings/global/applications.json index 222d9e1173..92d7ab0b2f 100644 --- a/pype/settings/defaults/system_settings/global/applications.json +++ b/pype/settings/defaults/system_settings/global/applications.json @@ -3,8 +3,28 @@ "enabled": true, "environment": { "__environment_keys__": { - "maya": [] - } + "maya": [ + "PYTHONPATH", + "MAYA_DISABLE_CLIC_IPM", + "MAYA_DISABLE_CIP", + "MAYA_DISABLE_CER", + "PYMEL_SKIP_MEL_INIT", + "LC_ALL", + "PYPE_LOG_NO_COLORS" + ] + }, + "PYTHONPATH": [ + "{PYPE_SETUP_PATH}/repos/avalon-core/setup/maya", + "{PYPE_SETUP_PATH}/repos/maya-look-assigner", + "{PYTHON_ENV}/python2/Lib/site-packages", + "{PYTHONPATH}" + ], + "MAYA_DISABLE_CLIC_IPM": "Yes", + "MAYA_DISABLE_CIP": "Yes", + "MAYA_DISABLE_CER": "Yes", + "PYMEL_SKIP_MEL_INIT": "Yes", + "LC_ALL": "C", + "PYPE_LOG_NO_COLORS": "Yes" }, "maya_2020": { "enabled": true, @@ -15,7 +35,20 @@ }, "environment": { "__environment_keys__": { - "maya_2020": [] + "maya_2020": [ + "MAYA_VERSION", + "MAYA_LOCATION", + "DYLD_LIBRARY_PATH" + ] + }, + "MAYA_VERSION": "2020", + "MAYA_LOCATION": { + "darwin": "/Applications/Autodesk/maya{MAYA_VERSION}/Maya.app/Contents", + "linux": "/usr/autodesk/maya{MAYA_VERSION}", + "windows": "C:/Program Files/Autodesk/Maya{MAYA_VERSION}" + }, + "DYLD_LIBRARY_PATH": { + "darwin": "{MAYA_LOCATION}/MacOS" } } }, @@ -28,7 +61,20 @@ }, "environment": { "__environment_keys__": { - "maya_2019": [] + "maya_2019": [ + "MAYA_VERSION", + "MAYA_LOCATION", + "DYLD_LIBRARY_PATH" + ] + }, + "MAYA_VERSION": "2019", + "MAYA_LOCATION": { + "darwin": "/Applications/Autodesk/maya{MAYA_VERSION}/Maya.app/Contents", + "linux": "/usr/autodesk/maya{MAYA_VERSION}", + "windows": "C:/Program Files/Autodesk/Maya{MAYA_VERSION}" + }, + "DYLD_LIBRARY_PATH": { + "darwin": "{MAYA_LOCATION}/MacOS" } } }, @@ -41,7 +87,20 @@ }, "environment": { "__environment_keys__": { - "maya_2018": [] + "maya_2018": [ + "MAYA_VERSION", + "MAYA_LOCATION", + "DYLD_LIBRARY_PATH" + ] + }, + "MAYA_VERSION": "2018", + "MAYA_LOCATION": { + "darwin": "/Applications/Autodesk/maya{MAYA_VERSION}/Maya.app/Contents", + "linux": "/usr/autodesk/maya{MAYA_VERSION}", + "windows": "C:/Program Files/Autodesk/Maya{MAYA_VERSION}" + }, + "DYLD_LIBRARY_PATH": { + "darwin": "{MAYA_LOCATION}/MacOS" } } } @@ -50,7 +109,18 @@ "enabled": true, "environment": { "__environment_keys__": { - "nuke": [] + "nuke": [ + "NUKE_PATH", + "PATH" + ] + }, + "NUKE_PATH": [ + "{PYPE_SETUP_PATH}/repos/avalon-core/setup/nuke/nuke_path", + "{PYPE_MODULE_ROOT}/setup/nuke/nuke_path", + "{PYPE_STUDIO_PLUGINS}/nuke" + ], + "PATH": { + "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" } }, "nuke_12.0": { @@ -114,8 +184,13 @@ }, "environment": { "__environment_keys__": { - "nuke_10.0": [] - } + "nuke_10.0": [ + "PYPE_LOG_NO_COLORS", + "QT_PREFERRED_BINDING" + ] + }, + "PYPE_LOG_NO_COLORS": "Yes", + "QT_PREFERRED_BINDING": "PySide" } } }, @@ -123,7 +198,18 @@ "enabled": true, "environment": { "__environment_keys__": { - "nukex": [] + "nukex": [ + "NUKE_PATH", + "PATH" + ] + }, + "NUKE_PATH": [ + "{PYPE_SETUP_PATH}/repos/avalon-core/setup/nuke/nuke_path", + "{PYPE_MODULE_ROOT}/setup/nuke/nuke_path", + "{PYPE_STUDIO_PLUGINS}/nuke" + ], + "PATH": { + "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" } }, "nukex_12.0": { @@ -187,8 +273,13 @@ }, "environment": { "__environment_keys__": { - "nukex_10.0": [] - } + "nukex_10.0": [ + "PYPE_LOG_NO_COLORS", + "QT_PREFERRED_BINDING" + ] + }, + "PYPE_LOG_NO_COLORS": "Yes", + "QT_PREFERRED_BINDING": "PySide" } } }, @@ -196,8 +287,23 @@ "enabled": true, "environment": { "__environment_keys__": { - "nukestudio": [] - } + "nukestudio": [ + "HIERO_PLUGIN_PATH", + "PATH", + "WORKFILES_STARTUP", + "TAG_ASSETBUILD_STARTUP", + "PYPE_LOG_NO_COLORS" + ] + }, + "HIERO_PLUGIN_PATH": [ + "{PYPE_MODULE_ROOT}/setup/nukestudio/hiero_plugin_path" + ], + "PATH": { + "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" + }, + "WORKFILES_STARTUP": "0", + "TAG_ASSETBUILD_STARTUP": "0", + "PYPE_LOG_NO_COLORS": "True" }, "nukestudio_12.0": { "enabled": true, @@ -260,8 +366,13 @@ }, "environment": { "__environment_keys__": { - "nukestudio_10.0": [] - } + "nukestudio_10.0": [ + "PYPE_LOG_NO_COLORS", + "QT_PREFERRED_BINDING" + ] + }, + "PYPE_LOG_NO_COLORS": "Yes", + "QT_PREFERRED_BINDING": "PySide" } } }, @@ -269,8 +380,23 @@ "enabled": true, "environment": { "__environment_keys__": { - "hiero": [] - } + "hiero": [ + "HIERO_PLUGIN_PATH", + "PATH", + "WORKFILES_STARTUP", + "TAG_ASSETBUILD_STARTUP", + "PYPE_LOG_NO_COLORS" + ] + }, + "HIERO_PLUGIN_PATH": [ + "{PYPE_MODULE_ROOT}/setup/nukestudio/hiero_plugin_path" + ], + "PATH": { + "windows": "C:/Program Files (x86)/QuickTime/QTSystem/;{PATH}" + }, + "WORKFILES_STARTUP": "0", + "TAG_ASSETBUILD_STARTUP": "0", + "PYPE_LOG_NO_COLORS": "True" }, "hiero_12.0": { "enabled": true, @@ -333,8 +459,13 @@ }, "environment": { "__environment_keys__": { - "hiero_10.0": [] - } + "hiero_10.0": [ + "PYPE_LOG_NO_COLORS", + "QT_PREFERRED_BINDING" + ] + }, + "PYPE_LOG_NO_COLORS": "Yes", + "QT_PREFERRED_BINDING": "PySide" } } }, @@ -376,8 +507,57 @@ "enabled": true, "environment": { "__environment_keys__": { - "resolve": [] - } + "resolve": [ + "RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR", + "RESOLVE_SCRIPT_API", + "RESOLVE_SCRIPT_LIB", + "RESOLVE_UTILITY_SCRIPTS_DIR", + "PYTHON36_RESOLVE", + "PYTHONPATH", + "PATH", + "PRE_PYTHON_SCRIPT", + "PYPE_LOG_NO_COLORS", + "RESOLVE_DEV" + ] + }, + "RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR": [ + "{STUDIO_SOFT}/davinci_resolve/scripts/python" + ], + "RESOLVE_SCRIPT_API": { + "windows": "{PROGRAMDATA}/Blackmagic Design/DaVinci Resolve/Support/Developer/Scripting", + "darvin": "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting", + "linux": "/opt/resolve/Developer/Scripting" + }, + "RESOLVE_SCRIPT_LIB": { + "windows": "C:/Program Files/Blackmagic Design/DaVinci Resolve/fusionscript.dll", + "darvin": "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so", + "linux": "/opt/resolve/libs/Fusion/fusionscript.so" + }, + "RESOLVE_UTILITY_SCRIPTS_DIR": { + "windows": "{PROGRAMDATA}/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Comp", + "darvin": "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Comp", + "linux": "/opt/resolve/Fusion/Scripts/Comp" + }, + "PYTHON36_RESOLVE": { + "windows": "{LOCALAPPDATA}/Programs/Python/Python36", + "darvin": "~/Library/Python/3.6/bin", + "linux": "/opt/Python/3.6/bin" + }, + "PYTHONPATH": [ + "{PYTHON36_RESOLVE}/Lib/site-packages", + "{VIRTUAL_ENV}/Lib/site-packages", + "{PYTHONPATH}", + "{RESOLVE_SCRIPT_API}/Modules", + "{PYTHONPATH}" + ], + "PATH": [ + "{PYTHON36_RESOLVE}", + "{PYTHON36_RESOLVE}/Scripts", + "{PATH}" + ], + "PRE_PYTHON_SCRIPT": "{PYPE_MODULE_ROOT}/pype/resolve/preload_console.py", + "PYPE_LOG_NO_COLORS": "True", + "RESOLVE_DEV": "True" }, "resolve_16": { "enabled": true, @@ -397,7 +577,20 @@ "enabled": true, "environment": { "__environment_keys__": { - "houdini": [] + "houdini": [ + "HOUDINI_PATH", + "HOUDINI_MENU_PATH" + ] + }, + "HOUDINI_PATH": { + "darwin": "{PYPE_MODULE_ROOT}/setup/houdini:&", + "linux": "{PYPE_MODULE_ROOT}/setup/houdini:&", + "windows": "{PYPE_MODULE_ROOT}/setup/houdini;&" + }, + "HOUDINI_MENU_PATH": { + "darwin": "{PYPE_MODULE_ROOT}/setup/houdini:&", + "linux": "{PYPE_MODULE_ROOT}/setup/houdini:&", + "windows": "{PYPE_MODULE_ROOT}/setup/houdini;&" } }, "houdini_18": { @@ -431,8 +624,18 @@ "enabled": true, "environment": { "__environment_keys__": { - "blender": [] - } + "blender": [ + "BLENDER_USER_SCRIPTS", + "PYTHONPATH", + "CREATE_NEW_CONSOLE" + ] + }, + "BLENDER_USER_SCRIPTS": "{PYPE_SETUP_PATH}/repos/avalon-core/setup/blender", + "PYTHONPATH": [ + "{PYPE_SETUP_PATH}/repos/avalon-core/setup/blender", + "{PYTHONPATH}" + ], + "CREATE_NEW_CONSOLE": "yes" }, "blender_2.90": { "enabled": true, @@ -465,8 +668,13 @@ "enabled": true, "environment": { "__environment_keys__": { - "harmony": [] - } + "harmony": [ + "AVALON_HARMONY_WORKFILES_ON_LAUNCH", + "PYBLISH_GUI_ALWAYS_EXEC" + ] + }, + "AVALON_HARMONY_WORKFILES_ON_LAUNCH": "1", + "PYBLISH_GUI_ALWAYS_EXEC": "1" }, "harmony_20": { "enabled": true, @@ -525,8 +733,19 @@ "enabled": true, "environment": { "__environment_keys__": { - "photoshop": [] - } + "photoshop": [ + "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH", + "PYTHONPATH", + "PYPE_LOG_NO_COLORS", + "WEBSOCKET_URL", + "WORKFILES_SAVE_AS" + ] + }, + "AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH": "1", + "PYTHONPATH": "{PYTHONPATH}", + "PYPE_LOG_NO_COLORS": "Yes", + "WEBSOCKET_URL": "ws://localhost:8099/ws/", + "WORKFILES_SAVE_AS": "Yes" }, "photoshop_2020": { "enabled": true, @@ -546,8 +765,11 @@ "enabled": true, "environment": { "__environment_keys__": { - "celaction": [] - } + "celaction": [ + "CELACTION_TEMPLATE" + ] + }, + "CELACTION_TEMPLATE": "{PYPE_MODULE_ROOT}/pype/hosts/celaction/celaction_template_scene.scn" }, "celation_Local": { "enabled": true, From 633195d3b1f46639dff3ae3b65e5359472e6f2b5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 17:39:17 +0200 Subject: [PATCH 112/176] changed how is modified happens when item used as widget --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 535e96a665..90a6ea04f3 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -789,7 +789,7 @@ class InputObject(SettingObject): False, self._is_invalid, False, - self._is_modified + self.is_modified ) else: state = self.style_state( From d7de4318550f454f29d54cb63a0e63ec410bb168 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 17:58:56 +0200 Subject: [PATCH 113/176] add default paths --- .../system_settings/global/applications.json | 383 ++++++++---------- .../host_settings/system_host_template.json | 2 +- .../host_settings/system_nuke_template.json | 18 - 3 files changed, 179 insertions(+), 224 deletions(-) diff --git a/pype/settings/defaults/system_settings/global/applications.json b/pype/settings/defaults/system_settings/global/applications.json index 92d7ab0b2f..d0a452aaeb 100644 --- a/pype/settings/defaults/system_settings/global/applications.json +++ b/pype/settings/defaults/system_settings/global/applications.json @@ -29,9 +29,15 @@ "maya_2020": { "enabled": true, "maya_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Autodesk\\maya2020\\bin\\maya.exe" + ], + "darwin": [ + "" + ], + "linux": [ + "/usr/autodesk/maya2020/bin/maya" + ] }, "environment": { "__environment_keys__": { @@ -55,9 +61,15 @@ "maya_2019": { "enabled": true, "maya_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Autodesk\\maya2019\\bin\\maya.exe" + ], + "darwin": [ + "" + ], + "linux": [ + "/usr/autodesk/maya2019/bin/maya" + ] }, "environment": { "__environment_keys__": { @@ -81,9 +93,15 @@ "maya_2018": { "enabled": true, "maya_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Autodesk\\maya2018\\bin\\maya.exe" + ], + "darwin": [ + "" + ], + "linux": [ + "/usr/autodesk/maya2018/bin/maya" + ] }, "environment": { "__environment_keys__": { @@ -126,9 +144,13 @@ "nuke_12.0": { "enabled": true, "nuke_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke12.0v1/Nuke12.0" + ] }, "environment": { "__environment_keys__": { @@ -139,9 +161,15 @@ "nuke_11.3": { "enabled": true, "nuke_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.3v4\\Nuke11.3.exe", + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.3v4/Nuke11.3", + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe" + ] }, "environment": { "__environment_keys__": { @@ -152,46 +180,23 @@ "nuke_11.2": { "enabled": true, "nuke_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.2v3\\Nuke11.2.exe", + "C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe", + "C:\\Program Files\\Nuke11.2v1\\Nuke11.2.exe" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.2v3/Nuke11.2", + "/usr/local/Nuke11.2v2/Nuke11.2", + "/usr/local/Nuke11.2v1/Nuke11.2" + ] }, "environment": { "__environment_keys__": { "nuke_11.2": [] } } - }, - "nuke_11.1": { - "enabled": true, - "nuke_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nuke_11.1": [] - } - } - }, - "nuke_10.0": { - "enabled": true, - "nuke_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nuke_10.0": [ - "PYPE_LOG_NO_COLORS", - "QT_PREFERRED_BINDING" - ] - }, - "PYPE_LOG_NO_COLORS": "Yes", - "QT_PREFERRED_BINDING": "PySide" - } } }, "nukex": { @@ -215,9 +220,13 @@ "nukex_12.0": { "enabled": true, "nukex_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe -nukex" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke12.0v1/Nuke12.0 -nukex" + ] }, "environment": { "__environment_keys__": { @@ -228,9 +237,13 @@ "nukex_11.3": { "enabled": true, "nukex_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe -nukex" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.3v1/Nuke11.3 -nukex" + ] }, "environment": { "__environment_keys__": { @@ -241,46 +254,19 @@ "nukex_11.2": { "enabled": true, "nukex_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.2v3\\Nuke11.2.exe -nukex" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.2v3/Nuke11.2 -nukex" + ] }, "environment": { "__environment_keys__": { "nukex_11.2": [] } } - }, - "nukex_11.1": { - "enabled": true, - "nukex_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nukex_11.1": [] - } - } - }, - "nukex_10.0": { - "enabled": true, - "nukex_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nukex_10.0": [ - "PYPE_LOG_NO_COLORS", - "QT_PREFERRED_BINDING" - ] - }, - "PYPE_LOG_NO_COLORS": "Yes", - "QT_PREFERRED_BINDING": "PySide" - } } }, "nukestudio": { @@ -308,9 +294,13 @@ "nukestudio_12.0": { "enabled": true, "nukestudio_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe -studio" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke12.0v1/Nuke12.0 -studio" + ] }, "environment": { "__environment_keys__": { @@ -321,9 +311,13 @@ "nukestudio_11.3": { "enabled": true, "nukestudio_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe -studio" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.3v1/Nuke11.3 -studio" + ] }, "environment": { "__environment_keys__": { @@ -334,46 +328,19 @@ "nukestudio_11.2": { "enabled": true, "nukestudio_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.2v3\\Nuke11.2.exe -studio" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.2v3/Nuke11.2 -studio" + ] }, "environment": { "__environment_keys__": { "nukestudio_11.2": [] } } - }, - "nukestudio_11.1": { - "enabled": true, - "nukestudio_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nukestudio_11.1": [] - } - } - }, - "nukestudio_10.0": { - "enabled": true, - "nukestudio_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "nukestudio_10.0": [ - "PYPE_LOG_NO_COLORS", - "QT_PREFERRED_BINDING" - ] - }, - "PYPE_LOG_NO_COLORS": "Yes", - "QT_PREFERRED_BINDING": "PySide" - } } }, "hiero": { @@ -401,9 +368,13 @@ "hiero_12.0": { "enabled": true, "hiero_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe -hiero" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke12.0v1/Nuke12.0 -hiero" + ] }, "environment": { "__environment_keys__": { @@ -414,9 +385,13 @@ "hiero_11.3": { "enabled": true, "hiero_executables": { - "windows": [], + "windows": [ + "C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe -hiero" + ], "darwin": [], - "linux": [] + "linux": [ + "/usr/local/Nuke11.3v1/Nuke11.3 -hiero" + ] }, "environment": { "__environment_keys__": { @@ -436,37 +411,6 @@ "hiero_11.2": [] } } - }, - "hiero_11.1": { - "enabled": true, - "hiero_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "hiero_11.1": [] - } - } - }, - "hiero_10.0": { - "enabled": true, - "hiero_executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": { - "__environment_keys__": { - "hiero_10.0": [ - "PYPE_LOG_NO_COLORS", - "QT_PREFERRED_BINDING" - ] - }, - "PYPE_LOG_NO_COLORS": "Yes", - "QT_PREFERRED_BINDING": "PySide" - } } }, "fusion": { @@ -479,9 +423,9 @@ "fusion_16": { "enabled": true, "fusion_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -492,9 +436,9 @@ "fusion_9": { "enabled": true, "fusion_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -562,9 +506,11 @@ "resolve_16": { "enabled": true, "resolve_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -596,9 +542,11 @@ "houdini_18": { "enabled": true, "houdini_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Side Effects Software\\Houdini 18.0.287\\bin\\houdini.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -609,9 +557,11 @@ "houdini_17": { "enabled": true, "houdini_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Side Effects Software\\Houdini 17.0.459\\bin\\houdini.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -640,9 +590,11 @@ "blender_2.90": { "enabled": true, "blender_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -653,9 +605,11 @@ "blender_2.83": { "enabled": true, "blender_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Blender Foundation\\Blender 2.83\\blender.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -679,9 +633,11 @@ "harmony_20": { "enabled": true, "harmony_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:/Program Files (x86)/Toon Boom Animation/Toon Boom Harmony 20 Premium/win64/bin/HarmonyPremium.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -692,9 +648,11 @@ "harmony_19": { "enabled": true, "harmony_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:/Program Files (x86)/Toon Boom Animation/Toon Boom Harmony 19 Premium/win64/bin/HarmonyPremium.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -705,9 +663,11 @@ "harmony_18": { "enabled": true, "harmony_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:/Program Files (x86)/Toon Boom Animation/Toon Boom Harmony 17 Premium/win64/bin/HarmonyPremium.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -718,9 +678,11 @@ "harmony_17": { "enabled": true, "harmony_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:/Program Files (x86)/Toon Boom Animation/Toon Boom Harmony 17 Premium/win64/bin/HarmonyPremium.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -750,9 +712,11 @@ "photoshop_2020": { "enabled": true, "photoshop_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Program Files\\Adobe\\Adobe Photoshop 2020\\Photoshop.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -773,7 +737,7 @@ }, "celation_Local": { "enabled": true, - "celation_executables": "", + "celation_executables": "C:\\Program Files (x86)\\CelAction\\CelAction2D.exe", "environment": { "__environment_keys__": { "celation_Local": [] @@ -782,7 +746,7 @@ }, "celation_Publish": { "enabled": true, - "celation_executables": "", + "celation_executables": "%PYPE_PYTHON_EXE% \"%PYPE_MODULE_ROOT%\\pype\\hosts\\celaction\\cli.py\" %*", "environment": { "__environment_keys__": { "celation_Publish": [] @@ -800,9 +764,11 @@ "unreal_4.24": { "enabled": true, "unreal_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "%AVALON_CURRENT_UNREAL_ENGINE%\\Engine\\Binaries\\Win64\\UE4Editor.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -821,9 +787,12 @@ "python_Python 3.7": { "enabled": true, "python_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Python37\\python.exe", + "C:\\Python36\\python.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -834,9 +803,11 @@ "python_Python 2.7": { "enabled": true, "python_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "C:\\Python27\\python.exe" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { @@ -847,9 +818,11 @@ "terminal_Terminal": { "enabled": true, "terminal_executables": { - "windows": "", - "darwin": "", - "linux": "" + "windows": [ + "start cmd" + ], + "darwin": [], + "linux": [] }, "environment": { "__environment_keys__": { diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json index dd4d3c8b4b..b39d6ac79d 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_host_template.json @@ -1,6 +1,6 @@ [{ "__default_values__": { - "multipath_executables": false, + "multipath_executables": true, "multiplatform": true } }, diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json index 36d68dba95..22b2e0c4df 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_nuke_template.json @@ -41,24 +41,6 @@ "host_name": "{nuke_type}", "multipath_executables": true } - }, - { - "type": "schema_template", - "name": "system_host_template", - "template_data": { - "host_version": "11.1", - "host_name": "{nuke_type}", - "multipath_executables": true - } - }, - { - "type": "schema_template", - "name": "system_host_template", - "template_data": { - "host_version": "10.0", - "host_name": "{nuke_type}", - "multipath_executables": true - } } ] } From 4af1c62473a4462bda461a03f10c1632cb980b6d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 17:59:09 +0200 Subject: [PATCH 114/176] fixed modifiable dit --- pype/tools/settings/settings/widgets/item_types.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 90a6ea04f3..706347bd21 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2214,6 +2214,17 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.value_changed.emit(self) + @property + def is_modified(self): + is_modified = super(ModifiableDict, self).is_modified + if is_modified: + return is_modified + + for input_field in self.input_fields: + if input_field.is_modified: + return True + return False + def hierarchical_style_update(self): for input_field in self.input_fields: input_field.hierarchical_style_update() From 1f5cfca44b9d2b426d529b0d0f5f17d8f6f815b8 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 18:13:52 +0200 Subject: [PATCH 115/176] convert remaining environments --- .../system_settings/global/general.json | 62 +- .../system_settings/global/modules.json | 41 +- .../system_schema/0_system_gui_schema.json | 2 +- ..._schema.json => 1_general_gui_schema.json} | 6 + .../system_schema/1_modules_gui_schema.json | 529 +++++++++--------- 5 files changed, 376 insertions(+), 264 deletions(-) rename pype/tools/settings/settings/gui_schemas/system_schema/{1_intents_gui_schema.json => 1_general_gui_schema.json} (69%) diff --git a/pype/settings/defaults/system_settings/global/general.json b/pype/settings/defaults/system_settings/global/general.json index bd501b06eb..c138f74667 100644 --- a/pype/settings/defaults/system_settings/global/general.json +++ b/pype/settings/defaults/system_settings/global/general.json @@ -1,4 +1,62 @@ { - "studio_name": "", - "studio_code": "" + "studio_name": "Studio", + "studio_code": "stu", + "environment": { + "__environment_keys__": { + "global": [ + "PYPE_APP_ROOT", + "PYPE_MODULE_ROOT", + "PYPE_PROJECT_PLUGINS", + "STUDIO_SOFT", + "FFMPEG_PATH", + "DJV_PATH", + "PATH", + "PYPE_OCIO_CONFIG", + "PYTHONPATH", + "PYPE_PROJECT_CONFIGS", + "PYPE_PYTHON_EXE", + "PYBLISH_GUI" + ] + }, + "PYPE_APP_ROOT": "{PYPE_SETUP_PATH}/pypeapp", + "PYPE_MODULE_ROOT": "{PYPE_SETUP_PATH}/repos/pype", + "PYPE_PROJECT_PLUGINS": "", + "STUDIO_SOFT": "{PYP_SETUP_ROOT}/soft", + "FFMPEG_PATH": { + "windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/windows/bin", + "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin", + "linux": "{VIRTUAL_ENV}/localized/ffmpeg_exec/linux:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/linux" + }, + "DJV_PATH": { + "windows": [ + "C:/Program Files/djv-1.1.0-Windows-64/bin/djv_view.exe", + "C:/Program Files/DJV/bin/djv_view.exe", + "{STUDIO_SOFT}/djv/windows/bin/djv_view.exe" + ], + "linux": [ + "usr/local/djv/djv_view", + "{STUDIO_SOFT}/djv/linux/bin/djv_view" + ], + "darwin": "Application/DJV.app/Contents/MacOS/DJV" + }, + "PATH": [ + "{PYPE_CONFIG}/launchers", + "{PYPE_APP_ROOT}", + "{FFMPEG_PATH}", + "{PATH}" + ], + "PYPE_OCIO_CONFIG": "{STUDIO_SOFT}/OpenColorIO-Configs", + "PYTHONPATH": { + "windows": "{VIRTUAL_ENV}/Lib/site-packages;{PYPE_MODULE_ROOT}/pype/tools;{PYTHONPATH}", + "linux": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYTHONPATH}", + "darwin": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYTHONPATH}" + }, + "PYPE_PROJECT_CONFIGS": "{PYPE_SETUP_PATH}/../studio-project-configs", + "PYPE_PYTHON_EXE": { + "windows": "{VIRTUAL_ENV}/Scripts/python.exe", + "linux": "{VIRTUAL_ENV}/Scripts/python", + "darwin": "{VIRTUAL_ENV}/bin/python" + }, + "PYBLISH_GUI": "pyblish_pype" + } } \ No newline at end of file diff --git a/pype/settings/defaults/system_settings/global/modules.json b/pype/settings/defaults/system_settings/global/modules.json index 9bd46602cf..8764ee94ca 100644 --- a/pype/settings/defaults/system_settings/global/modules.json +++ b/pype/settings/defaults/system_settings/global/modules.json @@ -2,7 +2,23 @@ "Avalon": { "AVALON_MONGO": "mongodb://localhost:2707", "AVALON_DB_DATA": "{PYPE_SETUP_PATH}/../mongo_db_data", - "AVALON_THUMBNAIL_ROOT": "{PYPE_SETUP_PATH}/../avalon_thumails" + "AVALON_THUMBNAIL_ROOT": "{PYPE_SETUP_PATH}/../avalon_thumails", + "environment": { + "__environment_keys__": { + "avalon": [ + "AVALON_CONFIG", + "AVALON_PROJECTS", + "AVALON_SCHEMA", + "AVALON_LABEL", + "AVALON_TIMEOUT" + ] + }, + "AVALON_CONFIG": "pype", + "AVALON_PROJECTS": "{PYPE_PROJECTS_PATH}", + "AVALON_SCHEMA": "{PYPE_MODULE_ROOT}/schema", + "AVALON_LABEL": "Pype", + "AVALON_TIMEOUT": "1000" + } }, "Ftrack": { "enabled": true, @@ -34,6 +50,29 @@ "test": "Test" }, "default": "-" + }, + "environment": { + "__environment_keys__": { + "ftrack": [ + "FTRACK_ACTIONS_PATH", + "FTRACK_EVENTS_PATH", + "PYTHONPATH", + "PYBLISHPLUGINPATH" + ] + }, + "FTRACK_ACTIONS_PATH": [ + "{PYPE_MODULE_ROOT}/pype/modules/ftrack/actions" + ], + "FTRACK_EVENTS_PATH": [ + "{PYPE_MODULE_ROOT}/pype/modules/ftrack/events" + ], + "PYTHONPATH": [ + "{PYPE_MODULE_ROOT}/pype/vendor", + "{PYTHONPATH}" + ], + "PYBLISHPLUGINPATH": [ + "{PYPE_MODULE_ROOT}/pype/plugins/ftrack/publish" + ] } }, "Rest Api": { diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json index c5f229fc2f..eb7d707f6a 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/0_system_gui_schema.json @@ -7,7 +7,7 @@ "key": "global", "children": [{ "type": "schema", - "name": "1_intents_gui_schema" + "name": "1_general_gui_schema" },{ "type": "schema", "name": "1_modules_gui_schema" diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_intents_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json similarity index 69% rename from pype/tools/settings/settings/gui_schemas/system_schema/1_intents_gui_schema.json rename to pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json index 7f71da26cd..b83c336237 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_intents_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json @@ -12,5 +12,11 @@ "key": "studio_code", "type": "text", "label": "Studio Short Code" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "global" } ]} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json index d78c11838a..521442cc09 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json @@ -1,283 +1,292 @@ { - "key": "modules", - "type": "dict", - "label": "Modules", - "collapsable": true, - "is_file": true, - "children": [{ - "type": "dict", - "key": "Avalon", - "label": "Avalon", - "collapsable": true, - "children": [ - { - "type": "text", - "key": "AVALON_MONGO", - "label": "Avalon Mongo URL" - }, - { - "type": "text", - "key": "AVALON_DB_DATA", - "label": "Avalon Mongo Data Location" - }, - { - "type": "text", - "key": "AVALON_THUMBNAIL_ROOT", - "label": "Thumbnail Storage Location" - } - ] - },{ + "key": "modules", + "type": "dict", + "label": "Modules", + "collapsable": true, + "is_file": true, + "children": [{ + "type": "dict", + "key": "Avalon", + "label": "Avalon", + "collapsable": true, + "children": [{ + "type": "text", + "key": "AVALON_MONGO", + "label": "Avalon Mongo URL" + }, + { + "type": "text", + "key": "AVALON_DB_DATA", + "label": "Avalon Mongo Data Location" + }, + { + "type": "text", + "key": "AVALON_THUMBNAIL_ROOT", + "label": "Thumbnail Storage Location" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "avalon" + } + ] + }, { "type": "dict", "key": "Ftrack", "label": "Ftrack", "collapsable": true, "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "text", + "key": "ftrack_server", + "label": "Server" + }, + { + "type": "label", + "label": "Additional Ftrack paths" + }, + { + "type": "list", + "key": "ftrack_actions_path", + "label": "Action paths", + "object_type": "text" + }, + { + "type": "list", + "key": "ftrack_events_path", + "label": "Event paths", + "object_type": "text" + }, + { + "type": "label", + "label": "Ftrack event server advanced settings" + }, + { + "type": "text", + "key": "FTRACK_EVENTS_MONGO_DB", + "label": "Event Mongo DB" + }, + { + "type": "text", + "key": "FTRACK_EVENTS_MONGO_COL", + "label": "Events Mongo Collection" + }, + { + "type": "dict", + "key": "sync_to_avalon", + "label": "Sync to avalon", + "children": [{ + "type": "list", + "key": "statuses_name_change", + "label": "Status name change", + "object_type": { + "type": "text", + "multiline": false + } + }] + }, + { + "type": "dict-modifiable", + "key": "status_version_to_task", + "label": "Version to Task status mapping", + "object_type": "text" + }, + { + "type": "dict-modifiable", + "key": "status_update", + "label": "Status Updates", + "object_type": { + "type": "list", + "object_type": "text" + } + }, + { + "key": "intent", + "type": "dict-invisible", + "children": [{ + "type": "dict-modifiable", + "object_type": "text", + "key": "items", + "label": "Intent Key/Label" + }, + { + "key": "default", + "type": "text", + "label": "Defautl Intent" + } + ] + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "ftrack" + } + ] + }, { + "type": "dict", + "key": "Rest Api", + "label": "Rest Api", + "collapsable": true, + "children": [{ + "type": "number", + "key": "default_port", + "label": "Default Port", + "minimum": 1, + "maximum": 65535 + }, + { + "type": "list", + "key": "exclude_ports", + "label": "Exclude ports", + "object_type": { + "type": "number", + "minimum": 1, + "maximum": 65535 + } + } + ] + }, { + "type": "dict", + "key": "Timers Manager", + "label": "Timers Manager", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "number", + "decimal": 2, + "key": "full_time", + "label": "Max idle time" + }, { + "type": "number", + "decimal": 2, + "key": "message_time", + "label": "When dialog will show" + } + ] + }, { + "type": "dict", + "key": "Clockify", + "label": "Clockify", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "text", + "key": "workspace_name", + "label": "Workspace name" + } + ] + }, { + "type": "dict", + "key": "Deadline", + "label": "Deadline", + "collapsable": true, + "checkbox_key": "enabled", "children": [{ "type": "boolean", "key": "enabled", "label": "Enabled" - }, - { - "type": "text", - "key": "ftrack_server", - "label": "Server" - }, - { - "type": "label", - "label": "Additional Ftrack paths" - }, - { - "type": "list", - "key": "ftrack_actions_path", - "label": "Action paths", - "object_type": "text" - }, - { - "type": "list", - "key": "ftrack_events_path", - "label": "Event paths", - "object_type": "text" - }, - { - "type": "label", - "label": "Ftrack event server advanced settings" - }, - { - "type": "text", - "key": "FTRACK_EVENTS_MONGO_DB", - "label": "Event Mongo DB" - }, - { - "type": "text", - "key": "FTRACK_EVENTS_MONGO_COL", - "label": "Events Mongo Collection" - }, - { - "type": "dict", - "key": "sync_to_avalon", - "label": "Sync to avalon", - "children": [{ - "type": "list", - "key": "statuses_name_change", - "label": "Status name change", - "object_type": { - "type": "text", - "multiline": false - } - }] - }, - { - "type": "dict-modifiable", - "key": "status_version_to_task", - "label": "Version to Task status mapping", - "object_type": "text" - }, - { - "type": "dict-modifiable", - "key": "status_update", - "label": "Status Updates", - "object_type": { - "type": "list", - "object_type": "text" - } - }, - { - "key": "intent", - "type": "dict-invisible", - "children": [ - { - "type": "dict-modifiable", - "object_type": "text", - "key": "items", - "label": "Intent Key/Label" - }, - { - "key": "default", - "type": "text", - "label": "Defautl Intent" - } - ] - } - ] - }, { - "type": "dict", - "key": "Rest Api", - "label": "Rest Api", - "collapsable": true, - "children": [{ - "type": "number", - "key": "default_port", - "label": "Default Port", - "minimum": 1, - "maximum": 65535 - }, - { - "type": "list", - "key": "exclude_ports", - "label": "Exclude ports", - "object_type": { - "type": "number", - "minimum": 1, - "maximum": 65535 - } - } - ] - }, { - "type": "dict", - "key": "Timers Manager", - "label": "Timers Manager", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "number", - "decimal": 2, - "key": "full_time", - "label": "Max idle time" }, { - "type": "number", - "decimal": 2, - "key": "message_time", - "label": "When dialog will show" - } - ] - }, { - "type": "dict", - "key": "Clockify", - "label": "Clockify", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "text", - "key": "workspace_name", - "label": "Workspace name" - } - ] - }, { - "type": "dict", - "key": "Deadline", - "label": "Deadline", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - },{ - "type": "text", - "key": "DEADLINE_REST_URL", - "label": "Deadline Resl URL" + "type": "text", + "key": "DEADLINE_REST_URL", + "label": "Deadline Resl URL" }] }, { - "type": "dict", - "key": "Muster", - "label": "Muster", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - },{ - "type": "text", - "key": "MUSTER_REST_URL", - "label": "Muster Resl URL" - },{ - "type": "dict-modifiable", - "object_type": { - "type": "number", - "minimum": 0, - "maximum": 300 - }, - "is_group": true, - "key": "templates_mapping", - "label": "Templates mapping", - "is_file": true - }] - }, { - "type": "dict", - "key": "Logging", - "label": "Logging", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "dict", + "key": "Muster", + "label": "Muster", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, { + "type": "text", + "key": "MUSTER_REST_URL", + "label": "Muster Resl URL" + }, { + "type": "dict-modifiable", + "object_type": { + "type": "number", + "minimum": 0, + "maximum": 300 + }, + "is_group": true, + "key": "templates_mapping", + "label": "Templates mapping", + "is_file": true }] }, { - "type": "dict", - "key": "Adobe Communicator", - "label": "Adobe Communicator", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "dict", + "key": "Logging", + "label": "Logging", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" }] }, { - "type": "dict", - "key": "User setting", - "label": "User setting", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "dict", + "key": "Adobe Communicator", + "label": "Adobe Communicator", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" }] }, { - "type": "dict", - "key": "Standalone Publish", - "label": "Standalone Publish", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "dict", + "key": "User setting", + "label": "User setting", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" }] }, { - "type": "dict", - "key": "Idle Manager", - "label": "Idle Manager", - "collapsable": true, - "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "dict", + "key": "Standalone Publish", + "label": "Standalone Publish", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" }] - } - ] + }, { + "type": "dict", + "key": "Idle Manager", + "label": "Idle Manager", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }] + }] } From 05cbc781517dbee2b6a4fc0031a1a10332acaa96 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 18:31:58 +0200 Subject: [PATCH 116/176] slight visual cleanup --- .../system_settings/global/general.json | 18 ++++-- .../system_schema/1_general_gui_schema.json | 59 ++++++++++++------- .../system_schema/1_modules_gui_schema.json | 11 +++- 3 files changed, 60 insertions(+), 28 deletions(-) diff --git a/pype/settings/defaults/system_settings/global/general.json b/pype/settings/defaults/system_settings/global/general.json index c138f74667..2941ed7332 100644 --- a/pype/settings/defaults/system_settings/global/general.json +++ b/pype/settings/defaults/system_settings/global/general.json @@ -1,13 +1,21 @@ { - "studio_name": "Studio", - "studio_code": "stu", + "studio_name": "convert from \"PYPE_STUDIO_NAME\"", + "studio_code": "convert from \"PYPE_STUDIO_CODE\"", + "project_plugins": { + "windows": "convert from \"PYPE_PROJECT_PLUGINS\"", + "darwin": "", + "linux": "" + }, + "studio_soft": { + "windows": "convert from \"STUDIO_SOFT\"", + "darwin": "", + "linux": "" + }, "environment": { "__environment_keys__": { "global": [ "PYPE_APP_ROOT", "PYPE_MODULE_ROOT", - "PYPE_PROJECT_PLUGINS", - "STUDIO_SOFT", "FFMPEG_PATH", "DJV_PATH", "PATH", @@ -20,8 +28,6 @@ }, "PYPE_APP_ROOT": "{PYPE_SETUP_PATH}/pypeapp", "PYPE_MODULE_ROOT": "{PYPE_SETUP_PATH}/repos/pype", - "PYPE_PROJECT_PLUGINS": "", - "STUDIO_SOFT": "{PYP_SETUP_ROOT}/soft", "FFMPEG_PATH": { "windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/windows/bin", "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin", diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json index b83c336237..15252ab39d 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_general_gui_schema.json @@ -1,22 +1,39 @@ { - "key": "general", - "type": "dict", - "label": "General", - "collapsable": true, - "is_file": true, - "children": [{ - "key": "studio_name", - "type": "text", - "label": "Studio Name" - },{ - "key": "studio_code", - "type": "text", - "label": "Studio Short Code" - }, - { - "key": "environment", - "label": "Environment", - "type": "raw-json", - "env_group_key": "global" - } -]} + "key": "general", + "type": "dict", + "label": "General", + "collapsable": true, + "is_file": true, + "children": [{ + "key": "studio_name", + "type": "text", + "label": "Studio Name" + }, { + "key": "studio_code", + "type": "text", + "label": "Studio Short Code" + }, { + "type": "splitter" + }, { + "key": "project_plugins", + "type": "path-widget", + "label": "Additional Project Plugins Path", + "multiplatform": true, + "multipath": false + }, { + "key": "studio_soft", + "type": "path-widget", + "label": "Studio Software Location", + "multiplatform": true, + "multipath": false + }, { + "type": "splitter" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "global" + } + ] +} diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json index 521442cc09..937eea4097 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_modules_gui_schema.json @@ -47,6 +47,9 @@ "key": "ftrack_server", "label": "Server" }, + { + "type": "splitter" + }, { "type": "label", "label": "Additional Ftrack paths" @@ -63,6 +66,9 @@ "label": "Event paths", "object_type": "text" }, + { + "type": "splitter" + }, { "type": "label", "label": "Ftrack event server advanced settings" @@ -118,10 +124,13 @@ { "key": "default", "type": "text", - "label": "Defautl Intent" + "label": "Default Intent" } ] }, + { + "type": "splitter" + }, { "key": "environment", "label": "Environment", From 9ed866b2bbf85d7f8449f4526a660f80a51d1d30 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 18:35:38 +0200 Subject: [PATCH 117/176] modifiable dict fixed --- .../settings/settings/widgets/item_types.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 706347bd21..f3d51e3f1f 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1464,6 +1464,12 @@ class ListItem(QtWidgets.QWidget, SettingObject): return self.value_input.item_value() return NOT_SET + @property + def is_modified(self): + if self._is_empty: + return False + return self.value_input.is_modified + @property def child_has_studio_override(self): return self.value_input.child_has_studio_override @@ -1708,6 +1714,17 @@ class ListWidget(QtWidgets.QWidget, InputObject): input_field.hierarchical_style_update() self.update_style() + @property + def is_modified(self): + is_modified = super(ListWidget, self).is_modified + if is_modified: + return is_modified + + for input_field in self.input_fields: + if input_field.is_modified: + return True + return False + def update_style(self): if not self.label_widget: return @@ -2027,6 +2044,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): @property def is_modified(self): + if self._is_empty: + return False return self.is_value_modified() or self.is_key_modified() def hierarchical_style_update(self): From 39891d3644e3f3a9989d998a4e6d8553fffe8a0d Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 18:36:19 +0200 Subject: [PATCH 118/176] add DJV to applications --- .../defaults/environments/global.json | 12 -------- .../system_settings/global/applications.json | 28 +++++++++++++++++++ .../1_applications_gui_schema.json | 4 +++ .../host_settings/system_djv_schema.json | 27 ++++++++++++++++++ 4 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_djv_schema.json diff --git a/pype/settings/defaults/environments/global.json b/pype/settings/defaults/environments/global.json index ba467d2f5d..717e337db8 100644 --- a/pype/settings/defaults/environments/global.json +++ b/pype/settings/defaults/environments/global.json @@ -10,18 +10,6 @@ "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin", "linux": "{VIRTUAL_ENV}/localized/ffmpeg_exec/linux:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/linux" }, - "DJV_PATH": { - "windows": [ - "C:/Program Files/djv-1.1.0-Windows-64/bin/djv_view.exe", - "C:/Program Files/DJV/bin/djv_view.exe", - "{STUDIO_SOFT}/djv/windows/bin/djv_view.exe" - ], - "linux": [ - "usr/local/djv/djv_view", - "{STUDIO_SOFT}/djv/linux/bin/djv_view" - ], - "darwin": "Application/DJV.app/Contents/MacOS/DJV" - }, "PATH": [ "{PYPE_CONFIG}/launchers", "{PYPE_APP_ROOT}", diff --git a/pype/settings/defaults/system_settings/global/applications.json b/pype/settings/defaults/system_settings/global/applications.json index d0a452aaeb..b85ec5369c 100644 --- a/pype/settings/defaults/system_settings/global/applications.json +++ b/pype/settings/defaults/system_settings/global/applications.json @@ -830,5 +830,33 @@ } } } + }, + "djvview": { + "enabled": true, + "environment": { + "__environment_keys__": { + "djvview": [] + } + }, + "djvview_1.1": { + "enabled": true, + "djvview_executables": { + "windows": [ + "C:/Program Files/djv-1.1.0-Windows-64/bin/djv_view.exe", + "C:/Program Files/DJV/bin/djv_view.exe" + ], + "darwin": [ + "Application/DJV.app/Contents/MacOS/DJV" + ], + "linux": [ + "usr/local/djv/djv_view" + ] + }, + "environment": { + "__environment_keys__": { + "djvview_1.1": [] + } + } + } } } \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json index d1fa4e79f5..6b73fc3f8c 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/1_applications_gui_schema.json @@ -75,6 +75,10 @@ { "type": "schema", "name": "system_shell_schema" + }, + { + "type": "schema", + "name": "system_djv_schema" } ] } diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_djv_schema.json b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_djv_schema.json new file mode 100644 index 0000000000..704b13443d --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/system_schema/host_settings/system_djv_schema.json @@ -0,0 +1,27 @@ +{ + "type": "dict", + "key": "djvview", + "label": "DJV View", + "collapsable": true, + "checkbox_key": "enabled", + "children": [{ + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "environment", + "label": "Environment", + "type": "raw-json", + "env_group_key": "djvview" + }, + { + "type": "schema_template", + "name": "system_host_template", + "template_data": { + "host_version": "1.1", + "host_name": "djvview" + } + } + ] +} From 6acdf42d8a4b2734adbab99531c68651a235760b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 18:46:00 +0200 Subject: [PATCH 119/176] remove obsolete variables --- .../defaults/system_settings/global/general.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pype/settings/defaults/system_settings/global/general.json b/pype/settings/defaults/system_settings/global/general.json index 2941ed7332..64a70c17f8 100644 --- a/pype/settings/defaults/system_settings/global/general.json +++ b/pype/settings/defaults/system_settings/global/general.json @@ -17,9 +17,7 @@ "PYPE_APP_ROOT", "PYPE_MODULE_ROOT", "FFMPEG_PATH", - "DJV_PATH", "PATH", - "PYPE_OCIO_CONFIG", "PYTHONPATH", "PYPE_PROJECT_CONFIGS", "PYPE_PYTHON_EXE", @@ -33,25 +31,12 @@ "darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin", "linux": "{VIRTUAL_ENV}/localized/ffmpeg_exec/linux:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/linux" }, - "DJV_PATH": { - "windows": [ - "C:/Program Files/djv-1.1.0-Windows-64/bin/djv_view.exe", - "C:/Program Files/DJV/bin/djv_view.exe", - "{STUDIO_SOFT}/djv/windows/bin/djv_view.exe" - ], - "linux": [ - "usr/local/djv/djv_view", - "{STUDIO_SOFT}/djv/linux/bin/djv_view" - ], - "darwin": "Application/DJV.app/Contents/MacOS/DJV" - }, "PATH": [ "{PYPE_CONFIG}/launchers", "{PYPE_APP_ROOT}", "{FFMPEG_PATH}", "{PATH}" ], - "PYPE_OCIO_CONFIG": "{STUDIO_SOFT}/OpenColorIO-Configs", "PYTHONPATH": { "windows": "{VIRTUAL_ENV}/Lib/site-packages;{PYPE_MODULE_ROOT}/pype/tools;{PYTHONPATH}", "linux": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYTHONPATH}", From 6181181097bf085f045990eba1cd102577ba820f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 2 Oct 2020 18:55:10 +0200 Subject: [PATCH 120/176] shrink environments more --- pype/settings/defaults/system_settings/global/general.json | 6 +++--- pype/settings/defaults/system_settings/global/modules.json | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/pype/settings/defaults/system_settings/global/general.json b/pype/settings/defaults/system_settings/global/general.json index 64a70c17f8..23e8a3ff5d 100644 --- a/pype/settings/defaults/system_settings/global/general.json +++ b/pype/settings/defaults/system_settings/global/general.json @@ -38,9 +38,9 @@ "{PATH}" ], "PYTHONPATH": { - "windows": "{VIRTUAL_ENV}/Lib/site-packages;{PYPE_MODULE_ROOT}/pype/tools;{PYTHONPATH}", - "linux": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYTHONPATH}", - "darwin": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYTHONPATH}" + "windows": "{VIRTUAL_ENV}/Lib/site-packages;{PYPE_MODULE_ROOT}/pype/tools;{PYPE_MODULE_ROOT}/pype/vendor;{PYTHONPATH}", + "linux": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYPE_MODULE_ROOT}/pype/vendor:{PYTHONPATH}", + "darwin": "{VIRTUAL_ENV}/lib/python{PYTHON_VERSION}/site-packages:{PYPE_MODULE_ROOT}/pype/tools:{PYPE_MODULE_ROOT}/pype/vendor:{PYTHONPATH}" }, "PYPE_PROJECT_CONFIGS": "{PYPE_SETUP_PATH}/../studio-project-configs", "PYPE_PYTHON_EXE": { diff --git a/pype/settings/defaults/system_settings/global/modules.json b/pype/settings/defaults/system_settings/global/modules.json index 8764ee94ca..b0245f52bd 100644 --- a/pype/settings/defaults/system_settings/global/modules.json +++ b/pype/settings/defaults/system_settings/global/modules.json @@ -56,7 +56,6 @@ "ftrack": [ "FTRACK_ACTIONS_PATH", "FTRACK_EVENTS_PATH", - "PYTHONPATH", "PYBLISHPLUGINPATH" ] }, @@ -66,10 +65,6 @@ "FTRACK_EVENTS_PATH": [ "{PYPE_MODULE_ROOT}/pype/modules/ftrack/events" ], - "PYTHONPATH": [ - "{PYPE_MODULE_ROOT}/pype/vendor", - "{PYTHONPATH}" - ], "PYBLISHPLUGINPATH": [ "{PYPE_MODULE_ROOT}/pype/plugins/ftrack/publish" ] From 0c96044ed05ec7b14b003921800b654b6efd8eb5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 23:04:13 +0200 Subject: [PATCH 121/176] implemented new nice checkbox widget --- .../settings/settings/widgets/widgets.py | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index b0bcf059a5..0d2960f86a 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -288,3 +288,188 @@ class GridLabelWidget(QtWidgets.QWidget): if self.input_field: return self.input_field.show_actions_menu(event) return super(GridLabelWidget, self).mouseReleaseEvent(event) + + +class NiceCheckboxMoveWidget(QtWidgets.QFrame): + def __init__(self, height, border_width, parent): + super(NiceCheckboxMoveWidget, self).__init__(parent=parent) + + self.checkstate = False + + self.half_size = int(height / 2) + self.full_size = self.half_size * 2 + self.border_width = border_width + self.setFixedHeight(self.full_size) + self.setFixedWidth(self.full_size) + + self.setStyleSheet(( + "background: #444444;border-style: none;" + "border-radius: {};border-width:{}px;" + ).format(self.half_size, self.border_width)) + + def update_position(self): + parent_rect = self.parent().rect() + if self.checkstate is True: + pos_x = ( + parent_rect.x() + + parent_rect.width() + - self.full_size + - self.border_width + ) + else: + pos_x = parent_rect.x() + self.border_width + + pos_y = parent_rect.y() + int( + parent_rect.height() / 2 - self.half_size + ) + self.setGeometry(pos_x, pos_y, self.width(), self.height()) + + def state_offset(self): + diff_x = ( + self.parent().rect().width() + - self.full_size + - (2 * self.border_width) + ) + return QtCore.QPoint(diff_x, 0) + + def change_position(self, checkstate): + self.checkstate = checkstate + + self.update_position() + + def resizeEvent(self, event): + super().resizeEvent(event) + self.update_position() + + +class NiceCheckbox(QtWidgets.QFrame): + stateChanged = QtCore.Signal(int) + checked_bg_color = QtGui.QColor(69, 128, 86) + unchecked_bg_color = QtGui.QColor(170, 80, 80) + + def set_bg_color(self, color): + self._bg_color = color + self.setStyleSheet(self._stylesheet_template.format( + color.red(), color.green(), color.blue() + )) + + def bg_color(self): + return self._bg_color + + bgcolor = QtCore.Property(QtGui.QColor, bg_color, set_bg_color) + + def __init__(self, checked=True, height=30, *args, **kwargs): + super(NiceCheckbox, self).__init__(*args, **kwargs) + + self._checkstate = checked + if checked: + bg_color = self.checked_bg_color + else: + bg_color = self.unchecked_bg_color + + self.half_height = int(height / 2) + height = self.half_height * 2 + tenth_height = int(height / 10) + + self.setFixedHeight(height) + self.setFixedWidth((height - tenth_height) * 2) + + move_item_size = height - (2 * tenth_height) + + self.move_item = NiceCheckboxMoveWidget( + move_item_size, tenth_height, self + ) + self.move_item.change_position(self._checkstate) + + self._stylesheet_template = ( + "border-radius: {}px;" + "border-width: {}px;" + "background: #333333;" + "border-style: solid;" + "border-color: #555555;" + ).format(self.half_height, tenth_height) + self._stylesheet_template += "background: rgb({},{},{});" + + self.set_bg_color(bg_color) + + def resizeEvent(self, event): + super(NiceCheckbox, self).resizeEvent(event) + self.move_item.update_position() + + def show(self, *args, **kwargs): + super(NiceCheckbox, self).show(*args, **kwargs) + self.move_item.update_position() + + def checkState(self): + if self._checkstate: + return QtCore.Qt.Checked + else: + return QtCore.Qt.Unchecked + + def _on_checkstate_change(self): + move_start_value = self.move_item.pos() + offset = self.move_item.state_offset() + if self._checkstate is True: + move_end_value = move_start_value + offset + else: + move_end_value = move_start_value - offset + move_animation = QtCore.QPropertyAnimation( + self.move_item, b"pos", self + ) + move_animation.setDuration(150) + move_animation.setEasingCurve(QtCore.QEasingCurve.OutQuad) + move_animation.setStartValue(move_start_value) + move_animation.setEndValue(move_end_value) + + color_animation = QtCore.QPropertyAnimation( + self, b"bgcolor" + ) + color_animation.setDuration(150) + if self._checkstate is True: + color_animation.setStartValue(self.unchecked_bg_color) + color_animation.setEndValue(self.checked_bg_color) + else: + color_animation.setStartValue(self.checked_bg_color) + color_animation.setEndValue(self.unchecked_bg_color) + + anim_group = QtCore.QParallelAnimationGroup(self) + anim_group.addAnimation(move_animation) + anim_group.addAnimation(color_animation) + + def _finished(): + self.move_item.change_position(self._checkstate) + self.stateChanged.emit(self.checkState()) + + anim_group.finished.connect(_finished) + anim_group.start() + + def isChecked(self): + return self._checkstate + + def setChecked(self, checked): + self._checkstate = checked + self._on_checkstate_change() + + def setCheckState(self, state=None): + if state is None: + checkstate = not self._checkstate + elif state == QtCore.Qt.Checked: + checkstate = True + elif state == QtCore.Qt.Unchecked: + checkstate = False + else: + return + + if checkstate == self._checkstate: + return + + self._checkstate = checkstate + + self._on_checkstate_change() + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + self.setCheckState() + event.accept() + return + return super(NiceCheckbox, self).mouseReleaseEvent(event) From 28eccb4d1f3d43265693d345e8c16aa622419123 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 23:04:27 +0200 Subject: [PATCH 122/176] new checkbox widget used in boolean item --- pype/tools/settings/settings/widgets/item_types.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index f3d51e3f1f..551b91e911 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -6,7 +6,8 @@ from .widgets import ( NumberSpinBox, PathInput, GridLabelWidget, - ComboBox + ComboBox, + NiceCheckbox ) from .multiselection_combobox import MultiSelectionComboBox from .lib import NOT_SET, METADATA_KEY, TypeToKlass, CHILD_OFFSET @@ -910,7 +911,11 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): layout.addWidget(label_widget, 0) self.label_widget = label_widget - self.input_field = QtWidgets.QCheckBox(self) + checkbox_height = self.style().pixelMetric( + QtWidgets.QStyle.PM_IndicatorHeight + ) + self.input_field = NiceCheckbox(height=checkbox_height, parent=self) + spacer = QtWidgets.QWidget(self) spacer.setAttribute(QtCore.Qt.WA_TranslucentBackground) From ba18d81448574305c2cc143b81d3871dee10b7d1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 23:11:02 +0200 Subject: [PATCH 123/176] few minor fixes --- pype/tools/settings/settings/widgets/widgets.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 0d2960f86a..b64b1aa8ac 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -407,6 +407,8 @@ class NiceCheckbox(QtWidgets.QFrame): return QtCore.Qt.Unchecked def _on_checkstate_change(self): + self.stateChanged.emit(self.checkState()) + move_start_value = self.move_item.pos() offset = self.move_item.state_offset() if self._checkstate is True: @@ -438,7 +440,6 @@ class NiceCheckbox(QtWidgets.QFrame): def _finished(): self.move_item.change_position(self._checkstate) - self.stateChanged.emit(self.checkState()) anim_group.finished.connect(_finished) anim_group.start() @@ -447,6 +448,8 @@ class NiceCheckbox(QtWidgets.QFrame): return self._checkstate def setChecked(self, checked): + if checked == self._checkstate: + return self._checkstate = checked self._on_checkstate_change() From 91fd0066305172c340e62d91a2c41d627d17159c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 23:32:22 +0200 Subject: [PATCH 124/176] environments metadata are added in `config_value` not in `item_value` --- pype/tools/settings/settings/widgets/item_types.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index f3d51e3f1f..7f22f804a7 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1302,14 +1302,16 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): output = {} for key, value in value.items(): output[key.upper()] = value - - output[METADATA_KEY] = { - "environments": { - self.env_group_key: list(output.keys()) - } - } return output + def config_value(self): + value = self.item_value() + value[METADATA_KEY] = { + "environments": { + self.env_group_key: list(value.keys()) + } + } + return {self.key: value} class ListItem(QtWidgets.QWidget, SettingObject): _btn_size = 20 From baf89fa6c604574fc33c8fc5a5026a10bea6756a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 2 Oct 2020 23:33:07 +0200 Subject: [PATCH 125/176] fixed discard changes --- .../settings/settings/widgets/item_types.py | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 7f22f804a7..8e1ef57942 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -850,6 +850,7 @@ class InputObject(SettingObject): self._is_overriden = False return + self._state = None self._is_modified = False self._is_overriden = self._was_overriden @@ -2517,13 +2518,22 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self._has_studio_override = True def discard_changes(self): - self._is_overriden = self._was_overriden self._is_modified = False + self._is_overriden = self._was_overriden + self._has_studio_override = self._had_studio_override for input_field in self.input_fields: input_field.discard_changes() self._is_modified = self.child_modified + if not self.is_overidable and self.as_widget: + if self.has_studio_override: + self._is_modified = self.studio_value != self.item_value() + else: + self._is_modified = self.default_value != self.item_value() + + self._state = None + self._is_overriden = self._was_overriden def set_as_overriden(self): if self.is_overriden: @@ -2925,11 +2935,20 @@ class DictInvisible(QtWidgets.QWidget, SettingObject): def discard_changes(self): self._is_modified = False self._is_overriden = self._was_overriden + self._has_studio_override = self._had_studio_override for input_field in self.input_fields: input_field.discard_changes() self._is_modified = self.child_modified + if not self.is_overidable and self.as_widget: + if self.has_studio_override: + self._is_modified = self.studio_value != self.item_value() + else: + self._is_modified = self.default_value != self.item_value() + + self._state = None + self._is_overriden = self._was_overriden def set_as_overriden(self): if self.is_overriden: @@ -3331,20 +3350,20 @@ class PathWidget(QtWidgets.QWidget, SettingObject): self._has_studio_override = True def discard_changes(self): + self._is_modified = False self._is_overriden = self._was_overriden self._has_studio_override = self._had_studio_override self.input_field.discard_changes() - if not self.is_overidable: + self._is_modified = self.child_modified + if not self.is_overidable and self.as_widget: if self.has_studio_override: self._is_modified = self.studio_value != self.item_value() else: self._is_modified = self.default_value != self.item_value() - self._is_overriden = False - return - self._is_modified = False + self._state = None self._is_overriden = self._was_overriden def set_as_overriden(self): @@ -3460,11 +3479,20 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): def discard_changes(self): self._is_modified = False self._is_overriden = self._was_overriden + self._has_studio_override = self._had_studio_override - for item in self.input_fields: - item.discard_changes() + for input_field in self.input_fields: + input_field.discard_changes() self._is_modified = self.child_modified + if not self.is_overidable and self.as_widget: + if self.has_studio_override: + self._is_modified = self.studio_value != self.item_value() + else: + self._is_modified = self.default_value != self.item_value() + + self._state = None + self._is_overriden = self._was_overriden def remove_overrides(self): self._is_overriden = False From ef648f61d0d783c40bdbc8daffae862a2474c85c Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 12 Oct 2020 22:44:08 +0200 Subject: [PATCH 126/176] Add .circleci/config.yml --- .circleci/config.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..a5452f329f --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,24 @@ +version: 2.1 + +jobs: + deploy-website: + docker: + - image: circleci/node:10.16 + + steps: + - checkout + - run: + name: Deploying to GitHub Pages + command: | + git config --global user.email "mkolar@users.noreply.github.com" + git config --global user.name "Website Deployment Script" + echo "machine github.com login mkolar password $GITHUB_TOKEN" > ~/.netrc + cd website && yarn install && GIT_USER=mkolar yarn run publish-gh-pages + +workflows: + build_and_deploy: + jobs: + - deploy-website: + filters: + branches: + only: feature/move_documentation From fdc42decf50b6b5331d73c480491b395ef47d817 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Tue, 13 Oct 2020 10:04:50 +0200 Subject: [PATCH 127/176] update ssh --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a5452f329f..4d8bc75ecd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,9 @@ jobs: - image: circleci/node:10.16 steps: + - add_ssh_keys: + fingerprints: + - "06:24:54:b5:92:03:40:04:fc:87:82:c0:71:99:c4:6c" - checkout - run: name: Deploying to GitHub Pages @@ -13,7 +16,7 @@ jobs: git config --global user.email "mkolar@users.noreply.github.com" git config --global user.name "Website Deployment Script" echo "machine github.com login mkolar password $GITHUB_TOKEN" > ~/.netrc - cd website && yarn install && GIT_USER=mkolar yarn run publish-gh-pages + cd website && yarn install && GIT_USER=mkolar yarn run deploy workflows: build_and_deploy: From f24f9983058d036bf2b30601c53d8a99d3b33fdc Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 13 Oct 2020 19:10:11 +0200 Subject: [PATCH 128/176] fix(hiero): review from imagesequence --- pype/plugins/hiero/publish/collect_reviews.py | 62 ++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/pype/plugins/hiero/publish/collect_reviews.py b/pype/plugins/hiero/publish/collect_reviews.py index a444d57d6b..1d961943c5 100644 --- a/pype/plugins/hiero/publish/collect_reviews.py +++ b/pype/plugins/hiero/publish/collect_reviews.py @@ -1,5 +1,7 @@ from pyblish import api import os +import re +import clique class CollectReviews(api.InstancePlugin): @@ -19,6 +21,8 @@ class CollectReviews(api.InstancePlugin): families = ["plate"] def process(self, instance): + is_sequence = instance.data["isSequence"] + # Exclude non-tagged instances. tagged = False for tag in instance.data["tags"]: @@ -83,7 +87,29 @@ class CollectReviews(api.InstancePlugin): file_path = rev_inst.data.get("sourcePath") file_dir = os.path.dirname(file_path) file = os.path.basename(file_path) - ext = os.path.splitext(file)[-1][1:] + ext = os.path.splitext(file)[-1] + + # detect if sequence + if not is_sequence: + # is video file + files = file + else: + files = list() + source_first = instance.data["sourceFirst"] + self.log.debug("_ file: {}".format(file)) + spliter, padding = self.detect_sequence(file) + self.log.debug("_ spliter, padding: {}, {}".format( + spliter, padding)) + base_name = file.split(spliter)[0] + collection = clique.Collection(base_name, ext, padding, set(range( + int(source_first + rev_inst.data.get("sourceInH")), + int(source_first + rev_inst.data.get("sourceOutH") + 1)))) + self.log.debug("_ collection: {}".format(collection)) + real_files = os.listdir(file_dir) + for item in collection: + if item not in real_files: + continue + files.append(item) # change label instance.data["label"] = "{0} - {1} - ({2})".format( @@ -94,7 +120,7 @@ class CollectReviews(api.InstancePlugin): # adding representation for review mov representation = { - "files": file, + "files": files, "stagingDir": file_dir, "frameStart": rev_inst.data.get("sourceIn"), "frameEnd": rev_inst.data.get("sourceOut"), @@ -102,15 +128,15 @@ class CollectReviews(api.InstancePlugin): "frameEndFtrack": rev_inst.data.get("sourceOutH"), "step": 1, "fps": rev_inst.data.get("fps"), - "name": "preview", - "tags": ["preview", "ftrackreview"], - "ext": ext + "name": "review", + "tags": ["review", "ftrackreview"], + "ext": ext[1:] } media_duration = instance.data.get("mediaDuration") clip_duration_h = instance.data.get("clipDurationH") - if media_duration > clip_duration_h: + if media_duration > clip_duration_h and not is_sequence: self.log.debug("Media duration higher: {}".format( (media_duration - clip_duration_h))) representation.update({ @@ -118,7 +144,7 @@ class CollectReviews(api.InstancePlugin): "frameEnd": instance.data.get("sourceOutH"), "tags": ["_cut-bigger", "delete"] }) - elif media_duration < clip_duration_h: + elif media_duration < clip_duration_h and not is_sequence: self.log.debug("Media duration higher: {}".format( (media_duration - clip_duration_h))) representation.update({ @@ -205,3 +231,25 @@ class CollectReviews(api.InstancePlugin): instance.data["versionData"] = version_data instance.data["source"] = instance.data["sourcePath"] + + def detect_sequence(self, file): + """ Get identificating pater for image sequence + + Can find file.0001.ext, file.%02d.ext, file.####.ext + + Return: + string: any matching sequence patern + int: padding of sequnce numbering + """ + foundall = re.findall(r"(#+)|(%\d+d)|[^a-zA-Z](\d+)\.\w+$", file) + if foundall: + found = sorted(list(set(foundall[0])))[-1] + + if "%" in found: + padding = int(re.findall(r"\d+", found)[-1]) + else: + padding = len(found) + + return found, padding + else: + return None From a19814de0b2d8a08be2e293afd7e15437adca74c Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Tue, 13 Oct 2020 23:21:13 +0200 Subject: [PATCH 129/176] Update config.yml --- .circleci/config.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4d8bc75ecd..09d5679e01 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,9 +6,6 @@ jobs: - image: circleci/node:10.16 steps: - - add_ssh_keys: - fingerprints: - - "06:24:54:b5:92:03:40:04:fc:87:82:c0:71:99:c4:6c" - checkout - run: name: Deploying to GitHub Pages @@ -24,4 +21,4 @@ workflows: - deploy-website: filters: branches: - only: feature/move_documentation + only: From 77ad4dce80a0abcaa2243130304d712796c83d56 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Tue, 13 Oct 2020 23:22:17 +0200 Subject: [PATCH 130/176] Update config.yml --- .circleci/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09d5679e01..f821749b08 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,3 @@ jobs: workflows: build_and_deploy: jobs: - - deploy-website: - filters: - branches: - only: From b1687b86ed440cea599a53dfa90c6fe907c625bd Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 14 Oct 2020 13:53:24 +0200 Subject: [PATCH 131/176] disable auto ensure_scene_settings --- pype/hosts/harmony/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index fbf5ca6f12..92434abc77 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -155,8 +155,11 @@ def check_inventory(): def application_launch(): - ensure_scene_settings() - check_inventory() + # FIXME: This is breaking server <-> client communication. + # It is now moved so it it manually called. + # ensure_scene_settings() + # check_inventory() + pass def export_template(backdrops, nodes, filepath): From 49aa669467bfccbd7d8fcb4258a7fd8f1fdb26b7 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 14 Oct 2020 16:21:51 +0200 Subject: [PATCH 132/176] use existing path for thumbnails if it's not published --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index 549dc22d79..f1f49bc922 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -1,5 +1,6 @@ import pyblish.api import json +import os class IntegrateFtrackInstance(pyblish.api.InstancePlugin): @@ -68,6 +69,10 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): "name": "thumbnail" # Default component name is "main". } comp['thumbnail'] = True + if not comp.get("published_path"): + comp['published_path'] = os.path.join(comp['stagingDir'], + comp["files"]) + elif comp.get('ftrackreview') or ("ftrackreview" in comp.get('tags', [])): ''' Ftrack bug requirement: From 67c03d4aa05012fa03cae3e8e317aa8d16c25b8f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 14 Oct 2020 16:22:20 +0200 Subject: [PATCH 133/176] add option to disable render cleanup --- pype/plugins/global/publish/cleanup.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pype/plugins/global/publish/cleanup.py b/pype/plugins/global/publish/cleanup.py index 264a04b8bd..5fded85ccb 100644 --- a/pype/plugins/global/publish/cleanup.py +++ b/pype/plugins/global/publish/cleanup.py @@ -21,6 +21,7 @@ class CleanUp(pyblish.api.InstancePlugin): # Presets paterns = None # list of regex paterns + remove_temp_renders = True def process(self, instance): """Plugin entry point.""" @@ -36,8 +37,9 @@ class CleanUp(pyblish.api.InstancePlugin): ) ) - self.log.info("Cleaning renders new...") - self.clean_renders(instance) + if self.remove_temp_renders: + self.log.info("Cleaning renders new...") + self.clean_renders(instance) if [ef for ef in self.exclude_families if instance.data["family"] in ef]: @@ -85,7 +87,11 @@ class CleanUp(pyblish.api.InstancePlugin): if os.path.normpath(src) != os.path.normpath(dest): if instance_family == 'render' or 'render' in current_families: self.log.info("Removing src: `{}`...".format(src)) - os.remove(src) + try: + os.remove(src) + except PermissionError: + self.log.warning("Insufficient permission to delete {}".format(src)) + continue # add dir for cleanup dirnames.append(os.path.dirname(src)) From afd1fbc40be2aaf1da31d8750334930183aee70d Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 14 Oct 2020 16:23:01 +0200 Subject: [PATCH 134/176] review and burnin don't delete representations, that they don't process --- pype/plugins/global/publish/extract_burnin.py | 4 +--- pype/plugins/global/publish/extract_review.py | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 353f2f27f0..de82722515 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -74,12 +74,10 @@ class ExtractBurnin(pype.api.Extractor): # Remove any representations tagged for deletion. # QUESTION Is possible to have representation with "delete" tag? for repre in tuple(instance.data["representations"]): - if "delete" in repre.get("tags", []): + if all(x in repre.get("tags", []) for x in ['delete', 'burnin']): self.log.debug("Removing representation: {}".format(repre)) instance.data["representations"].remove(repre) - self.log.debug(instance.data["representations"]) - def use_legacy_code(self, instance): presets = instance.context.data.get("presets") if presets is None and self.profiles is None: diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index f4a39a7c31..c17793e682 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -51,6 +51,7 @@ class ExtractReview(pyblish.api.InstancePlugin): to_height = 1080 def process(self, instance): + self.log.debug(instance.data["representations"]) # Skip review when requested. if not instance.data.get("review", True): return @@ -77,7 +78,7 @@ class ExtractReview(pyblish.api.InstancePlugin): # Make sure cleanup happens and pop representations with "delete" tag. for repre in tuple(instance.data["representations"]): tags = repre.get("tags") or [] - if "delete" in tags: + if "delete" in tags and "thumbnail" not in tags: instance.data["representations"].remove(repre) def main_process(self, instance): From 38c37d9cf573cf81d25108d2cc5914aebbd48019 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 14 Oct 2020 16:23:43 +0200 Subject: [PATCH 135/176] add option to rename representations with regex and filename --- .../publish/collect_representation_names.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 pype/plugins/standalonepublisher/publish/collect_representation_names.py diff --git a/pype/plugins/standalonepublisher/publish/collect_representation_names.py b/pype/plugins/standalonepublisher/publish/collect_representation_names.py new file mode 100644 index 0000000000..7c8fb3fe3d --- /dev/null +++ b/pype/plugins/standalonepublisher/publish/collect_representation_names.py @@ -0,0 +1,40 @@ +""" +Requires: + Nothing + +Provides: + Instance +""" + +import pyblish.api +from pprint import pformat +import re +import os + +class CollecRepresentationNames(pyblish.api.InstancePlugin): + """ + Sets the representation names for given families based on RegEx filter + """ + + label = "Collect Representaion Names" + order = pyblish.api.CollectorOrder + families = [] + hosts = ["standalonepublisher"] + name_filter = "" + + def process(self, instance): + self.log.debug(f"instance.data: {pformat(instance.data['representations'])}") + for repre in instance.data['representations']: + self.log.debug(repre['files']) + if isinstance(repre['files'], list): + shortened_name = os.path.splitext(repre['files'][0])[0] + new_repre_name = re.search(self.name_filter, shortened_name) + else: + new_repre_name = re.search(self.name_filter, repre['files']) + + + self.log.debug(new_repre_name.group()) + repre['name'] = new_repre_name.group() + repre['outputName'] = new_repre_name.group() + + self.log.debug(f"instance.data: {pformat(instance.data['representations'])}") From 680d4fab345453a69470f20413c3ad8b0e728cdc Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 14 Oct 2020 16:24:32 +0200 Subject: [PATCH 136/176] delete temp thumbnail file --- .../standalonepublisher/publish/extract_thumbnail.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py index 5882775083..fca4039d0e 100644 --- a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py +++ b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py @@ -112,12 +112,11 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin): 'ext': 'jpg', 'files': filename, "stagingDir": staging_dir, - "thumbnail": True, - "tags": [] + "tags": ["thumbnail"], } # # add Delete tag when temp file was rendered - # if not is_jpeg: - # representation["tags"].append("delete") + if not is_jpeg: + representation["tags"].append("delete") instance.data["representations"].append(representation) From 17dab30fb34bf67f4022dca11d303ea047f797f2 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 15 Oct 2020 09:38:58 +0200 Subject: [PATCH 137/176] feat(hiero): renaming plugin to be used by image sequence --- ...{extract_review_cutup_video.py => extract_review_cutup.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename pype/plugins/hiero/publish/{extract_review_cutup_video.py => extract_review_cutup.py} (99%) diff --git a/pype/plugins/hiero/publish/extract_review_cutup_video.py b/pype/plugins/hiero/publish/extract_review_cutup.py similarity index 99% rename from pype/plugins/hiero/publish/extract_review_cutup_video.py rename to pype/plugins/hiero/publish/extract_review_cutup.py index 868d450fd6..1890f13738 100644 --- a/pype/plugins/hiero/publish/extract_review_cutup_video.py +++ b/pype/plugins/hiero/publish/extract_review_cutup.py @@ -3,12 +3,12 @@ from pyblish import api import pype -class ExtractReviewCutUpVideo(pype.api.Extractor): +class ExtractReviewCutUp(pype.api.Extractor): """Cut up clips from long video file""" order = api.ExtractorOrder # order = api.CollectorOrder + 0.1023 - label = "Extract Review CutUp Video" + label = "Extract Review CutUp" hosts = ["hiero"] families = ["review"] From 9c35bb30fac5cdc85d74e4504502a173332ad41e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 15 Oct 2020 09:53:58 +0200 Subject: [PATCH 138/176] feat(hiero): rename collect reviews to review --- .../hiero/publish/{collect_reviews.py => collect_review.py} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename pype/plugins/hiero/publish/{collect_reviews.py => collect_review.py} (98%) diff --git a/pype/plugins/hiero/publish/collect_reviews.py b/pype/plugins/hiero/publish/collect_review.py similarity index 98% rename from pype/plugins/hiero/publish/collect_reviews.py rename to pype/plugins/hiero/publish/collect_review.py index 1d961943c5..e6715d42b0 100644 --- a/pype/plugins/hiero/publish/collect_reviews.py +++ b/pype/plugins/hiero/publish/collect_review.py @@ -4,7 +4,7 @@ import re import clique -class CollectReviews(api.InstancePlugin): +class CollectReview(api.InstancePlugin): """Collect review from tags. Tag is expected to have metadata: @@ -136,7 +136,7 @@ class CollectReviews(api.InstancePlugin): media_duration = instance.data.get("mediaDuration") clip_duration_h = instance.data.get("clipDurationH") - if media_duration > clip_duration_h and not is_sequence: + if media_duration > clip_duration_h: self.log.debug("Media duration higher: {}".format( (media_duration - clip_duration_h))) representation.update({ @@ -144,7 +144,7 @@ class CollectReviews(api.InstancePlugin): "frameEnd": instance.data.get("sourceOutH"), "tags": ["_cut-bigger", "delete"] }) - elif media_duration < clip_duration_h and not is_sequence: + elif media_duration < clip_duration_h: self.log.debug("Media duration higher: {}".format( (media_duration - clip_duration_h))) representation.update({ From 1aeaa4bba175e0354371cdc8275bb2d4afd0a1b6 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Thu, 15 Oct 2020 09:55:46 +0100 Subject: [PATCH 139/176] Missing audio on farm submission. --- pype/plugins/global/publish/submit_publish_job.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/submit_publish_job.py b/pype/plugins/global/publish/submit_publish_job.py index fd109cf881..30f64f7ab9 100644 --- a/pype/plugins/global/publish/submit_publish_job.py +++ b/pype/plugins/global/publish/submit_publish_job.py @@ -732,7 +732,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "resolutionHeight": data.get("resolutionHeight", 1080), "multipartExr": data.get("multipartExr", False), "jobBatchName": data.get("jobBatchName", ""), - "review": data.get("review", True) + "review": data.get("review", True), + "audio": data.get("audio", []) } if "prerender" in instance.data["families"]: From dba1f34bd773c74d8565de26bb1c3b363c2dcdff Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 15 Oct 2020 12:38:48 +0200 Subject: [PATCH 140/176] feat(hiero): review imagesequence with cuts --- pype/plugins/hiero/publish/collect_clips.py | 4 +- pype/plugins/hiero/publish/collect_review.py | 32 +- .../hiero/publish/extract_review_cutup.py | 349 +++++++++++------- 3 files changed, 235 insertions(+), 150 deletions(-) diff --git a/pype/plugins/hiero/publish/collect_clips.py b/pype/plugins/hiero/publish/collect_clips.py index 2c7ea3ec60..724e4730ed 100644 --- a/pype/plugins/hiero/publish/collect_clips.py +++ b/pype/plugins/hiero/publish/collect_clips.py @@ -143,8 +143,8 @@ class CollectClips(api.ContextPlugin): "asset": asset, "family": "clip", "families": [], - "handleStart": projectdata.get("handleStart", 0), - "handleEnd": projectdata.get("handleEnd", 0), + "handleStart": int(projectdata.get("handleStart", 0)), + "handleEnd": int(projectdata.get("handleEnd", 0)), "fps": context.data["fps"] }) instance = context.create_instance(**data) diff --git a/pype/plugins/hiero/publish/collect_review.py b/pype/plugins/hiero/publish/collect_review.py index e6715d42b0..157b8d88f8 100644 --- a/pype/plugins/hiero/publish/collect_review.py +++ b/pype/plugins/hiero/publish/collect_review.py @@ -16,7 +16,7 @@ class CollectReview(api.InstancePlugin): # Run just before CollectSubsets order = api.CollectorOrder + 0.1022 - label = "Collect Reviews" + label = "Collect Review" hosts = ["hiero"] families = ["plate"] @@ -158,11 +158,17 @@ class CollectReview(api.InstancePlugin): self.log.debug("Added representation: {}".format(representation)) def create_thumbnail(self, instance): + is_sequence = instance.data["isSequence"] item = instance.data["item"] source_path = instance.data["sourcePath"] source_file = os.path.basename(source_path) - head, ext = os.path.splitext(source_file) + spliter, padding = self.detect_sequence(source_file) + + if spliter: + head, ext = source_file.split(spliter) + else: + head, ext = os.path.splitext(source_file) # staging dir creation staging_dir = os.path.dirname( @@ -170,30 +176,28 @@ class CollectReview(api.InstancePlugin): media_duration = instance.data.get("mediaDuration") clip_duration_h = instance.data.get("clipDurationH") + self.log.debug("__ media_duration: {}".format(media_duration)) + self.log.debug("__ clip_duration_h: {}".format(clip_duration_h)) - if media_duration > clip_duration_h: - thumb_frame = instance.data["clipInH"] + ( - (instance.data["clipOutH"] - instance.data["clipInH"]) / 2) - elif media_duration <= clip_duration_h: - thumb_frame = instance.data["sourceIn"] + ( - (instance.data["sourceOut"] - instance.data["sourceIn"]) / 2) - thumb_file = "{}_{}{}".format(head, thumb_frame, ".png") + thumb_frame = int(instance.data["sourceIn"] + ( + (instance.data["sourceOut"] - instance.data["sourceIn"]) / 2)) + + thumb_file = "{}thumbnail{}{}".format(head, thumb_frame, ".png") thumb_path = os.path.join(staging_dir, thumb_file) self.log.debug("__ thumb_path: {}".format(thumb_path)) self.log.debug("__ thumb_frame: {}".format(thumb_frame)) + self.log.debug( + "__ sourceIn: `{}`".format(instance.data["sourceIn"])) + thumbnail = item.thumbnail(thumb_frame).save( thumb_path, format='png' ) - - self.log.debug( - "__ sourceIn: `{}`".format(instance.data["sourceIn"])) self.log.debug( "__ thumbnail: `{}`, frame: `{}`".format(thumbnail, thumb_frame)) self.log.debug("__ thumbnail: {}".format(thumbnail)) - thumb_representation = { 'files': thumb_file, 'stagingDir': staging_dir, @@ -252,4 +256,4 @@ class CollectReview(api.InstancePlugin): return found, padding else: - return None + return None, None diff --git a/pype/plugins/hiero/publish/extract_review_cutup.py b/pype/plugins/hiero/publish/extract_review_cutup.py index 1890f13738..57ec6c1107 100644 --- a/pype/plugins/hiero/publish/extract_review_cutup.py +++ b/pype/plugins/hiero/publish/extract_review_cutup.py @@ -1,6 +1,11 @@ import os +import sys +import six +import errno from pyblish import api import pype +import clique +from avalon.vendor import filelink class ExtractReviewCutUp(pype.api.Extractor): @@ -22,6 +27,9 @@ class ExtractReviewCutUp(pype.api.Extractor): # get representation and loop them representations = inst_data["representations"] + # check if sequence + is_sequence = inst_data["isSequence"] + # get resolution default resolution_width = inst_data["resolutionWidth"] resolution_height = inst_data["resolutionHeight"] @@ -51,174 +59,224 @@ class ExtractReviewCutUp(pype.api.Extractor): self.log.debug("__ repre: {}".format(repre)) - file = repre.get("files") + files = repre.get("files") staging_dir = repre.get("stagingDir") - frame_start = repre.get("frameStart") - frame_end = repre.get("frameEnd") fps = repre.get("fps") ext = repre.get("ext") - new_file_name = "{}_{}".format(asset, file) - - full_input_path = os.path.join( - staging_dir, file) - + # make paths full_output_dir = os.path.join( staging_dir, "cuts") - os.path.isdir(full_output_dir) or os.makedirs(full_output_dir) + if is_sequence: + new_files = list() - full_output_path = os.path.join( - full_output_dir, new_file_name) + # frame range delivery included handles + frame_start = ( + inst_data["frameStart"] - inst_data["handleStart"]) + frame_end = ( + inst_data["frameEnd"] + inst_data["handleEnd"]) + self.log.debug("_ frame_start: {}".format(frame_start)) + self.log.debug("_ frame_end: {}".format(frame_end)) - self.log.debug("__ full_input_path: {}".format(full_input_path)) - self.log.debug("__ full_output_path: {}".format(full_output_path)) + # make collection from input files list + collections, remainder = clique.assemble(files) + collection = collections.pop() + self.log.debug("_ collection: {}".format(collection)) - # check if audio stream is in input video file - ffprob_cmd = ( - "{ffprobe_path} -i \"{full_input_path}\" -show_streams " - "-select_streams a -loglevel error" - ).format(**locals()) - self.log.debug("ffprob_cmd: {}".format(ffprob_cmd)) - audio_check_output = pype.api.subprocess(ffprob_cmd) - self.log.debug("audio_check_output: {}".format(audio_check_output)) + # name components + head = collection.format("{head}") + padding = collection.format("{padding}") + tail = collection.format("{tail}") + self.log.debug("_ head: {}".format(head)) + self.log.debug("_ padding: {}".format(padding)) + self.log.debug("_ tail: {}".format(tail)) - # translate frame to sec - start_sec = float(frame_start) / fps - duration_sec = float(frame_end - frame_start + 1) / fps + # make destination file with instance data + # frame start and end range + index = 0 + for image in collection: + dst_file_num = frame_start + index + dst_file_name = head + str(padding % dst_file_num) + tail + src = os.path.join(staging_dir, image) + dst = os.path.join(full_output_dir, dst_file_name) + self.log.info("Creating temp hardlinks: {}".format(dst)) + self.hardlink_file(src, dst) + new_files.append(dst_file_name) + index += 1 - empty_add = None + self.log.debug("_ new_files: {}".format(new_files)) - # check if not missing frames at start - if (start_sec < 0) or (media_duration < frame_end): - # for later swithing off `-c:v copy` output arg - empty_add = True + else: + # ffmpeg when single file + new_files = "{}_{}".format(asset, files) - # init empty variables - video_empty_start = video_layer_start = "" - audio_empty_start = audio_layer_start = "" - video_empty_end = video_layer_end = "" - audio_empty_end = audio_layer_end = "" - audio_input = audio_output = "" - v_inp_idx = 0 - concat_n = 1 + # frame range + frame_start = repre.get("frameStart") + frame_end = repre.get("frameEnd") - # try to get video native resolution data - try: - resolution_output = pype.api.subprocess(( - "{ffprobe_path} -i \"{full_input_path}\" -v error " - "-select_streams v:0 -show_entries " - "stream=width,height -of csv=s=x:p=0" + full_input_path = os.path.join( + staging_dir, files) + + os.path.isdir(full_output_dir) or os.makedirs(full_output_dir) + + full_output_path = os.path.join( + full_output_dir, new_files) + + self.log.debug( + "__ full_input_path: {}".format(full_input_path)) + self.log.debug( + "__ full_output_path: {}".format(full_output_path)) + + # check if audio stream is in input video file + ffprob_cmd = ( + "{ffprobe_path} -i \"{full_input_path}\" -show_streams " + "-select_streams a -loglevel error" + ).format(**locals()) + self.log.debug("ffprob_cmd: {}".format(ffprob_cmd)) + audio_check_output = pype.api.subprocess(ffprob_cmd) + self.log.debug( + "audio_check_output: {}".format(audio_check_output)) + + # translate frame to sec + start_sec = float(frame_start) / fps + duration_sec = float(frame_end - frame_start + 1) / fps + + empty_add = None + + # check if not missing frames at start + if (start_sec < 0) or (media_duration < frame_end): + # for later swithing off `-c:v copy` output arg + empty_add = True + + # init empty variables + video_empty_start = video_layer_start = "" + audio_empty_start = audio_layer_start = "" + video_empty_end = video_layer_end = "" + audio_empty_end = audio_layer_end = "" + audio_input = audio_output = "" + v_inp_idx = 0 + concat_n = 1 + + # try to get video native resolution data + try: + resolution_output = pype.api.subprocess(( + "{ffprobe_path} -i \"{full_input_path}\" -v error " + "-select_streams v:0 -show_entries " + "stream=width,height -of csv=s=x:p=0" + ).format(**locals())) + + x, y = resolution_output.split("x") + resolution_width = int(x) + resolution_height = int(y) + except Exception as _ex: + self.log.warning( + "Video native resolution is untracable: {}".format( + _ex)) + + if audio_check_output: + # adding input for empty audio + input_args.append("-f lavfi -i anullsrc") + + # define audio empty concat variables + audio_input = "[1:a]" + audio_output = ":a=1" + v_inp_idx = 1 + + # adding input for video black frame + input_args.append(( + "-f lavfi -i \"color=c=black:" + "s={resolution_width}x{resolution_height}:r={fps}\"" ).format(**locals())) - x, y = resolution_output.split("x") - resolution_width = int(x) - resolution_height = int(y) - except Exception as E: - self.log.warning( - "Video native resolution is untracable: {}".format(E)) + if (start_sec < 0): + # recalculate input video timing + empty_start_dur = abs(start_sec) + start_sec = 0 + duration_sec = float(frame_end - ( + frame_start + (empty_start_dur * fps)) + 1) / fps - if audio_check_output: - # adding input for empty audio - input_args.append("-f lavfi -i anullsrc") - - # define audio empty concat variables - audio_input = "[1:a]" - audio_output = ":a=1" - v_inp_idx = 1 - - # adding input for video black frame - input_args.append(( - "-f lavfi -i \"color=c=black:" - "s={resolution_width}x{resolution_height}:r={fps}\"" - ).format(**locals())) - - if (start_sec < 0): - # recalculate input video timing - empty_start_dur = abs(start_sec) - start_sec = 0 - duration_sec = float(frame_end - ( - frame_start + (empty_start_dur * fps)) + 1) / fps - - # define starting empty video concat variables - video_empty_start = ( - "[{v_inp_idx}]trim=duration={empty_start_dur}[gv0];" - ).format(**locals()) - video_layer_start = "[gv0]" - - if audio_check_output: - # define starting empty audio concat variables - audio_empty_start = ( - "[0]atrim=duration={empty_start_dur}[ga0];" + # define starting empty video concat variables + video_empty_start = ( + "[{v_inp_idx}]trim=duration={empty_start_dur}[gv0];" # noqa ).format(**locals()) - audio_layer_start = "[ga0]" + video_layer_start = "[gv0]" - # alter concat number of clips - concat_n += 1 + if audio_check_output: + # define starting empty audio concat variables + audio_empty_start = ( + "[0]atrim=duration={empty_start_dur}[ga0];" + ).format(**locals()) + audio_layer_start = "[ga0]" - # check if not missing frames at the end - if (media_duration < frame_end): - # recalculate timing - empty_end_dur = float(frame_end - media_duration + 1) / fps - duration_sec = float(media_duration - frame_start) / fps + # alter concat number of clips + concat_n += 1 - # define ending empty video concat variables - video_empty_end = ( - "[{v_inp_idx}]trim=duration={empty_end_dur}[gv1];" - ).format(**locals()) - video_layer_end = "[gv1]" + # check if not missing frames at the end + if (media_duration < frame_end): + # recalculate timing + empty_end_dur = float( + frame_end - media_duration + 1) / fps + duration_sec = float( + media_duration - frame_start) / fps - if audio_check_output: - # define ending empty audio concat variables - audio_empty_end = ( - "[0]atrim=duration={empty_end_dur}[ga1];" + # define ending empty video concat variables + video_empty_end = ( + "[{v_inp_idx}]trim=duration={empty_end_dur}[gv1];" ).format(**locals()) - audio_layer_end = "[ga0]" + video_layer_end = "[gv1]" - # alter concat number of clips - concat_n += 1 + if audio_check_output: + # define ending empty audio concat variables + audio_empty_end = ( + "[0]atrim=duration={empty_end_dur}[ga1];" + ).format(**locals()) + audio_layer_end = "[ga0]" - # concatting black frame togather - output_args.append(( - "-filter_complex \"" - "{audio_empty_start}" - "{video_empty_start}" - "{audio_empty_end}" - "{video_empty_end}" - "{video_layer_start}{audio_layer_start}[1:v]{audio_input}" - "{video_layer_end}{audio_layer_end}" - "concat=n={concat_n}:v=1{audio_output}\"" - ).format(**locals())) + # alter concat number of clips + concat_n += 1 - # append ffmpeg input video clip - input_args.append("-ss {:0.2f}".format(start_sec)) - input_args.append("-t {:0.2f}".format(duration_sec)) - input_args.append("-i \"{}\"".format(full_input_path)) + # concatting black frame togather + output_args.append(( + "-filter_complex \"" + "{audio_empty_start}" + "{video_empty_start}" + "{audio_empty_end}" + "{video_empty_end}" + "{video_layer_start}{audio_layer_start}[1:v]{audio_input}" # noqa + "{video_layer_end}{audio_layer_end}" + "concat=n={concat_n}:v=1{audio_output}\"" + ).format(**locals())) - # add copy audio video codec if only shortening clip - if ("_cut-bigger" in tags) and (not empty_add): - output_args.append("-c:v copy") + # append ffmpeg input video clip + input_args.append("-ss {:0.2f}".format(start_sec)) + input_args.append("-t {:0.2f}".format(duration_sec)) + input_args.append("-i \"{}\"".format(full_input_path)) - # make sure it is having no frame to frame comprassion - output_args.append("-intra") + # add copy audio video codec if only shortening clip + if ("_cut-bigger" in tags) and (not empty_add): + output_args.append("-c:v copy") - # output filename - output_args.append("-y \"{}\"".format(full_output_path)) + # make sure it is having no frame to frame comprassion + output_args.append("-intra") - mov_args = [ - ffmpeg_path, - " ".join(input_args), - " ".join(output_args) - ] - subprcs_cmd = " ".join(mov_args) + # output filename + output_args.append("-y \"{}\"".format(full_output_path)) - # run subprocess - self.log.debug("Executing: {}".format(subprcs_cmd)) - output = pype.api.subprocess(subprcs_cmd) - self.log.debug("Output: {}".format(output)) + mov_args = [ + ffmpeg_path, + " ".join(input_args), + " ".join(output_args) + ] + subprcs_cmd = " ".join(mov_args) + + # run subprocess + self.log.debug("Executing: {}".format(subprcs_cmd)) + output = pype.api.subprocess(subprcs_cmd) + self.log.debug("Output: {}".format(output)) repre_new = { - "files": new_file_name, + "files": new_files, "stagingDir": full_output_dir, "frameStart": frame_start, "frameEnd": frame_end, @@ -242,3 +300,26 @@ class ExtractReviewCutUp(pype.api.Extractor): self.log.debug( "Representations: {}".format(representations_new)) instance.data["representations"] = representations_new + + def hardlink_file(self, src, dst): + dirname = os.path.dirname(dst) + + # make sure the destination folder exist + try: + os.makedirs(dirname) + except OSError as e: + if e.errno == errno.EEXIST: + pass + else: + self.log.critical("An unexpected error occurred.") + six.reraise(*sys.exc_info()) + + # create hardlined file + try: + filelink.create(src, dst, filelink.HARDLINK) + except OSError as e: + if e.errno == errno.EEXIST: + pass + else: + self.log.critical("An unexpected error occurred.") + six.reraise(*sys.exc_info()) From 7d78f971925c8d11debbb13725f789efa9f0f8c8 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 15 Oct 2020 13:04:06 +0200 Subject: [PATCH 141/176] fix(hiero): fixing regex expression --- pype/plugins/hiero/publish/collect_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/hiero/publish/collect_review.py b/pype/plugins/hiero/publish/collect_review.py index 157b8d88f8..781afd782a 100644 --- a/pype/plugins/hiero/publish/collect_review.py +++ b/pype/plugins/hiero/publish/collect_review.py @@ -245,7 +245,7 @@ class CollectReview(api.InstancePlugin): string: any matching sequence patern int: padding of sequnce numbering """ - foundall = re.findall(r"(#+)|(%\d+d)|[^a-zA-Z](\d+)\.\w+$", file) + foundall = re.findall(r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file) if foundall: found = sorted(list(set(foundall[0])))[-1] From 863cea4aa72ed30b2d50efeadfd0fb81686b2738 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 15 Oct 2020 13:07:02 +0200 Subject: [PATCH 142/176] hound(hiero) --- pype/plugins/hiero/publish/collect_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/plugins/hiero/publish/collect_review.py b/pype/plugins/hiero/publish/collect_review.py index 781afd782a..f1767b2a68 100644 --- a/pype/plugins/hiero/publish/collect_review.py +++ b/pype/plugins/hiero/publish/collect_review.py @@ -158,7 +158,6 @@ class CollectReview(api.InstancePlugin): self.log.debug("Added representation: {}".format(representation)) def create_thumbnail(self, instance): - is_sequence = instance.data["isSequence"] item = instance.data["item"] source_path = instance.data["sourcePath"] @@ -245,7 +244,8 @@ class CollectReview(api.InstancePlugin): string: any matching sequence patern int: padding of sequnce numbering """ - foundall = re.findall(r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file) + foundall = re.findall( + r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file) if foundall: found = sorted(list(set(foundall[0])))[-1] From 866d18e472c4412fd14a8d04fb7d83de08e8539a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 15 Oct 2020 14:11:44 +0200 Subject: [PATCH 143/176] remove useless logs --- .../publish/collect_representation_names.py | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/collect_representation_names.py b/pype/plugins/standalonepublisher/publish/collect_representation_names.py index 7c8fb3fe3d..c9063c22ed 100644 --- a/pype/plugins/standalonepublisher/publish/collect_representation_names.py +++ b/pype/plugins/standalonepublisher/publish/collect_representation_names.py @@ -1,17 +1,9 @@ -""" -Requires: - Nothing - -Provides: - Instance -""" - -import pyblish.api -from pprint import pformat import re import os +import pyblish.api -class CollecRepresentationNames(pyblish.api.InstancePlugin): + +class CollectRepresentationNames(pyblish.api.InstancePlugin): """ Sets the representation names for given families based on RegEx filter """ @@ -23,18 +15,17 @@ class CollecRepresentationNames(pyblish.api.InstancePlugin): name_filter = "" def process(self, instance): - self.log.debug(f"instance.data: {pformat(instance.data['representations'])}") for repre in instance.data['representations']: - self.log.debug(repre['files']) + new_repre_name = None if isinstance(repre['files'], list): shortened_name = os.path.splitext(repre['files'][0])[0] - new_repre_name = re.search(self.name_filter, shortened_name) + new_repre_name = re.search(self.name_filter, + shortened_name).group() else: - new_repre_name = re.search(self.name_filter, repre['files']) + new_repre_name = re.search(self.name_filter, + repre['files']).group() + if new_repre_name: + repre['name'] = new_repre_name - self.log.debug(new_repre_name.group()) - repre['name'] = new_repre_name.group() - repre['outputName'] = new_repre_name.group() - - self.log.debug(f"instance.data: {pformat(instance.data['representations'])}") + repre['outputName'] = repre['name'] From 5015c90bda93b3c181c4a4e63bb9ee01b55becaf Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 15 Oct 2020 14:12:12 +0200 Subject: [PATCH 144/176] more robust files check --- .../ftrack/publish/integrate_ftrack_instances.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index f1f49bc922..d6bd7f8524 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -69,9 +69,15 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): "name": "thumbnail" # Default component name is "main". } comp['thumbnail'] = True - if not comp.get("published_path"): - comp['published_path'] = os.path.join(comp['stagingDir'], - comp["files"]) + comp_files = comp["files"] + if isinstance(comp_files, (tuple, list, set)): + filename = comp_files[0] + else: + filename = comp_files + + comp['published_path'] = os.path.join( + comp['stagingDir'], filename +) elif comp.get('ftrackreview') or ("ftrackreview" in comp.get('tags', [])): ''' From 50dc4ec5f53c3ddd7187a1d22d44da760e42ad4f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 15 Oct 2020 14:13:43 +0200 Subject: [PATCH 145/176] syntax fix --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index d6bd7f8524..93a07a9fae 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -77,7 +77,7 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): comp['published_path'] = os.path.join( comp['stagingDir'], filename -) + ) elif comp.get('ftrackreview') or ("ftrackreview" in comp.get('tags', [])): ''' From 2d841631006ddc229483fab4502444452f969785 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 15:54:39 +0200 Subject: [PATCH 146/176] change log level of ffmpeg processing --- pype/scripts/otio_burnin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 6607726c73..123e7cfd1e 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -15,7 +15,7 @@ ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe") FFMPEG = ( - '{} -loglevel panic -i "%(input)s" %(filters)s %(args)s%(output)s' + '{} -i "%(input)s" %(filters)s %(args)s%(output)s' ).format(ffmpeg_path) FFPROBE = ( From 6470155aa29836cbaa37fc7fc3baebfd72cd0e5f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 15:54:52 +0200 Subject: [PATCH 147/176] formatting changes --- pype/scripts/otio_burnin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 123e7cfd1e..2ff5f737c9 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -308,8 +308,11 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): % (output, command)) if is_sequence: output = output % kwargs.get("duration") + if not os.path.exists(output): - raise RuntimeError("Failed to generate this fucking file '%s'" % output) + raise RuntimeError( + "Failed to generate this f*cking file '%s'" % output + ) def example(input_path, output_path): From 06905c880b3927611b29a3c0bcfb0e87b7fe879b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 15:55:05 +0200 Subject: [PATCH 148/176] print begin and end of burnin script --- pype/scripts/otio_burnin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 2ff5f737c9..040ce5295c 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -545,6 +545,7 @@ def burnins_from_data( if __name__ == "__main__": + print("* Burnin script started") in_data = json.loads(sys.argv[-1]) burnins_from_data( in_data["input"], @@ -554,3 +555,4 @@ if __name__ == "__main__": options=in_data.get("options"), burnin_values=in_data.get("values") ) + print("* Burnin script has finished") From 3f3dd290831e830778febf40999d5fe09d293f94 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 15:57:33 +0200 Subject: [PATCH 149/176] do not use pype Logger in burnin script --- pype/scripts/otio_burnin.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 040ce5295c..704a08ccbe 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -4,11 +4,9 @@ import re import subprocess import json import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins -from pype.api import Logger, config +from pype.api import config import pype.lib -log = Logger().get_logger("BurninWrapper", "burninwrap") - ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe") @@ -54,7 +52,7 @@ def _streams(source): def get_fps(str_value): if str_value == "0/0": - log.warning("Source has \"r_frame_rate\" value set to \"0/0\".") + print("WARNING: Source has \"r_frame_rate\" value set to \"0/0\".") return "Unknown" items = str_value.split("/") @@ -299,10 +297,10 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): args=args, overwrite=overwrite ) - log.info("Launching command: {}".format(command)) + print("Launching command: {}".format(command)) proc = subprocess.Popen(command, shell=True) - log.info(proc.communicate()[0]) + print(proc.communicate()[0]) if proc.returncode != 0: raise RuntimeError("Failed to render '%s': %s'" % (output, command)) From d37f4a041f58957b728df17c51d1933a73defbf9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 15:59:10 +0200 Subject: [PATCH 150/176] formatting changes --- pype/scripts/otio_burnin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 704a08ccbe..5ff8c5a766 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -302,8 +302,9 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): proc = subprocess.Popen(command, shell=True) print(proc.communicate()[0]) if proc.returncode != 0: - raise RuntimeError("Failed to render '%s': %s'" - % (output, command)) + raise RuntimeError( + "Failed to render '{}': {}'".format(output, command) + ) if is_sequence: output = output % kwargs.get("duration") From 0709da0fd63b815957be178f988a230e61c08f23 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:01:16 +0200 Subject: [PATCH 151/176] make sure ffmpeg output is printed out --- pype/scripts/otio_burnin.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 5ff8c5a766..99611b172c 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -299,8 +299,21 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): ) print("Launching command: {}".format(command)) - proc = subprocess.Popen(command, shell=True) - print(proc.communicate()[0]) + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True + ) + + _stdout, _stderr = proc.communicate() + if _stdout: + print(_stdout.decode("utf-8")) + + # This will probably never happen as ffmpeg use stdout + if _stderr: + print(_stderr.decode("utf-8")) + if proc.returncode != 0: raise RuntimeError( "Failed to render '{}': {}'".format(output, command) From ffa16729dfef1b294f293f9e860bf34c08a56cd6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:02:37 +0200 Subject: [PATCH 152/176] formatting in _subprocess --- pype/lib.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 6fa204b379..4f96b14c8a 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -84,11 +84,11 @@ def get_ffmpeg_tool_path(tool="ffmpeg"): def _subprocess(*args, **kwargs): """Convenience method for getting output errors for subprocess.""" - # make sure environment contains only strings - if not kwargs.get("env"): - filtered_env = {k: str(v) for k, v in os.environ.items()} - else: - filtered_env = {k: str(v) for k, v in kwargs.get("env").items()} + # Get environents from kwarg or use current process environments if were + # not passed. + env = kwargs.get("env") or os.envion + # Make sure environment contains only strings + filtered_env = {k: str(v) for k, v in env.items()} # set overrides kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) From 63b7a2a24458edca21b69b2adbc6d63164809dc1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:03:20 +0200 Subject: [PATCH 153/176] allow to pass logger to _subprocess --- pype/lib.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 4f96b14c8a..8a12e33e63 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -81,8 +81,7 @@ def get_ffmpeg_tool_path(tool="ffmpeg"): # Special naming case for subprocess since its a built-in method. -def _subprocess(*args, **kwargs): - """Convenience method for getting output errors for subprocess.""" +def _subprocess(*args, logger=None, **kwargs): # Get environents from kwarg or use current process environments if were # not passed. @@ -90,6 +89,10 @@ def _subprocess(*args, **kwargs): # Make sure environment contains only strings filtered_env = {k: str(v) for k, v in env.items()} + # Use lib's logger if was not passed with kwargs. + if not logger: + logger = log + # set overrides kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) kwargs['stderr'] = kwargs.get('stderr', subprocess.STDOUT) From dca6d0db27a5b1e5d202d4a49db760e6b01d333e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:03:51 +0200 Subject: [PATCH 154/176] stderr use PIPE instead of STDOUT --- pype/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/lib.py b/pype/lib.py index 8a12e33e63..0f19a68ae6 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -95,7 +95,7 @@ def _subprocess(*args, logger=None, **kwargs): # set overrides kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) - kwargs['stderr'] = kwargs.get('stderr', subprocess.STDOUT) + kwargs['stderr'] = kwargs.get('stderr', subprocess.PIPE) kwargs['stdin'] = kwargs.get('stdin', subprocess.PIPE) kwargs['env'] = filtered_env From 891829a4abd145bc5b0a5df36546b7458f083c8c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:05:15 +0200 Subject: [PATCH 155/176] stdout and stderr are logged at once to logger --- pype/lib.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 0f19a68ae6..978386af3a 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -101,19 +101,14 @@ def _subprocess(*args, logger=None, **kwargs): proc = subprocess.Popen(*args, **kwargs) - output, error = proc.communicate() + _stdout, _stderr = proc.communicate() + if _stdout: + _stdout = _stdout.decode("utf-8") + logger.debug(_stdout) - if output: - output = output.decode("utf-8") - output += "\n" - for line in output.strip().split("\n"): - log.info(line) - - if error: - error = error.decode("utf-8") - error += "\n" - for line in error.strip().split("\n"): - log.error(line) + if _stderr: + _stderr = _stderr.decode("utf-8") + logger.warning(_stderr) if proc.returncode != 0: raise ValueError( From f5707a48e4b11fcedf505bc119959cfcdf66c9e4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:06:00 +0200 Subject: [PATCH 156/176] _subprocess is returning full output with stderr and stdout --- pype/lib.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/lib.py b/pype/lib.py index 978386af3a..5fb9091cc1 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -101,20 +101,26 @@ def _subprocess(*args, logger=None, **kwargs): proc = subprocess.Popen(*args, **kwargs) + full_output = "" _stdout, _stderr = proc.communicate() if _stdout: _stdout = _stdout.decode("utf-8") + full_output += _stdout logger.debug(_stdout) if _stderr: _stderr = _stderr.decode("utf-8") + # Add additional line break if output already containt stdout + if full_output: + full_output += "\n" + full_output += _stderr logger.warning(_stderr) if proc.returncode != 0: raise ValueError( "\"{}\" was not successful:\nOutput: {}\nError: {}".format( args, output, error)) - return output + return full_output def get_hierarchy(asset_name=None): From ae905c0e5768bb040f80d9afe4f1a6224fa2b641 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:06:21 +0200 Subject: [PATCH 157/176] raise Runtime error with stdout ann stderr --- pype/lib.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 5fb9091cc1..9b21878701 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -117,9 +117,15 @@ def _subprocess(*args, logger=None, **kwargs): logger.warning(_stderr) if proc.returncode != 0: - raise ValueError( - "\"{}\" was not successful:\nOutput: {}\nError: {}".format( - args, output, error)) + exc_msg = "Executing arguments was not successful: \"{}\"".format(args) + if _stdout: + exc_msg += "\n\nOutput:\n{}".format(_stdout) + + if _stderr: + exc_msg += "Error:\n{}".format(_stderr) + + raise RuntimeError(exc_msg) + return full_output From cb2ca581e1a5fe55e342d42b6c3da5792c01ab26 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:06:28 +0200 Subject: [PATCH 158/176] added docstring --- pype/lib.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 9b21878701..ff9571de77 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -82,6 +82,23 @@ def get_ffmpeg_tool_path(tool="ffmpeg"): # Special naming case for subprocess since its a built-in method. def _subprocess(*args, logger=None, **kwargs): + """Convenience method for getting output errors for subprocess. + + Entered arguments and keyword arguments are passed to subprocess Popen. + + Args: + logger (logging.Logger): Logger object if want to use different than + lib's logger. + *args: Variable length arument list passed to Popen. + **kwargs : Arbitary keyword arguments passed to Popen. + + Returns: + str: Full output of subprocess concatenated stdout and stderr. + + Raises: + RuntimeError: Exception is raised if process finished with nonzero + return code. + """ # Get environents from kwarg or use current process environments if were # not passed. From 4113c072812a5cc8b8eaf8b436820d3620020cad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 16:07:12 +0200 Subject: [PATCH 159/176] extract review and extract burnin are passing logger to _subprocess --- pype/plugins/global/publish/extract_burnin.py | 3 +-- pype/plugins/global/publish/extract_review.py | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 353f2f27f0..6a164fd1f0 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -229,8 +229,7 @@ class ExtractBurnin(pype.api.Extractor): self.log.debug("Executing: {}".format(args)) # Run burnin script - output = pype.api.subprocess(args, shell=True) - self.log.debug("Output: {}".format(output)) + pype.api.subprocess(args, shell=True, logger=self.log) for filepath in temp_data["full_input_paths"]: filepath = filepath.replace("\\", "/") diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index f4a39a7c31..0a3077ca4f 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -180,8 +180,10 @@ class ExtractReview(pyblish.api.InstancePlugin): # run subprocess self.log.debug("Executing: {}".format(subprcs_cmd)) - output = pype.api.subprocess(subprcs_cmd, shell=True) - self.log.debug("Output: {}".format(output)) + + pype.api.subprocess( + subprcs_cmd, shell=True, logger=self.log + ) output_name = output_def["filename_suffix"] if temp_data["without_handles"]: From 6e0a2542074bca51456f4d50d748281f401b0761 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:13:24 +0200 Subject: [PATCH 160/176] gave ability to enter different mongo db object than avalon.io --- pype/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/lib.py b/pype/lib.py index 6fa204b379..6349ef4cd8 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1408,7 +1408,7 @@ def source_hash(filepath, *args): return "|".join([file_name, time, size] + list(args)).replace(".", ",") -def get_latest_version(asset_name, subset_name): +def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): """Retrieve latest version from `asset_name`, and `subset_name`. Args: From 2852ad1d8e9e90e7bbe2d4522afccc0ab30dda3b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:14:47 +0200 Subject: [PATCH 161/176] if dbcon keyword argument was not passed than use avalon.io --- pype/lib.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 6349ef4cd8..153cde806d 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1415,15 +1415,10 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): asset_name (str): Name of asset. subset_name (str): Name of subset. """ - # Get asset - asset_name = io.find_one( - {"type": "asset", "name": asset_name}, projection={"name": True} - ) - subset = io.find_one( - {"type": "subset", "name": subset_name, "parent": asset_name["_id"]}, - projection={"_id": True, "name": True}, - ) + if not dbcon: + log.debug("Using `avalon.io` for query.") + dbcon = io # Check if subsets actually exists. assert subset, "No subsets found." From b8c4dbed56221f88fc349663c5937b4c34aa3025 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:17:05 +0200 Subject: [PATCH 162/176] do different stuff if project name is specified --- pype/lib.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 153cde806d..41ee730e2a 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1422,6 +1422,14 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): # Check if subsets actually exists. assert subset, "No subsets found." + if project_name and project_name != dbcon.Session.get("AVALON_PROJECT"): + # `avalon.io` has only `_database` attribute + # but `AvalonMongoDB` has `database` + database = getattr(dbcon, "database", dbcon._database) + collection = database[project_name] + else: + project_name = dbcon.Session.get("AVALON_PROJECT") + collection = dbcon # Get version version_projection = { From d937fde322facb27edb1e2ae90ce099ee43f78ec Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:17:31 +0200 Subject: [PATCH 163/176] do not raise exceptions --- pype/lib.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index 41ee730e2a..8f5c4527a0 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1420,8 +1420,6 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): log.debug("Using `avalon.io` for query.") dbcon = io - # Check if subsets actually exists. - assert subset, "No subsets found." if project_name and project_name != dbcon.Session.get("AVALON_PROJECT"): # `avalon.io` has only `_database` attribute # but `AvalonMongoDB` has `database` @@ -1431,21 +1429,9 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): project_name = dbcon.Session.get("AVALON_PROJECT") collection = dbcon - # Get version - version_projection = { - "name": True, - "parent": True, - } - - version = io.find_one( - {"type": "version", "parent": subset["_id"]}, - projection=version_projection, - sort=[("name", -1)], ) - assert version, "No version found, this is a bug" - return version class ApplicationLaunchFailed(Exception): From 730be772a41538afce4f8e1a567ccb1c79efb5f2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:18:17 +0200 Subject: [PATCH 164/176] implemented finding of latest version --- pype/lib.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 8f5c4527a0..527db4a38a 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1429,9 +1429,28 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): project_name = dbcon.Session.get("AVALON_PROJECT") collection = dbcon + # Query asset document id by asset name + asset_doc = collection.find_one( + {"type": "asset", "name": asset_name}, + {"_id": True} ) + if not asset_doc: + return None + subset_doc = collection.find_one( + {"type": "subset", "name": subset_name, "parent": asset_doc["_id"]}, + {"_id": True} + ) + if not subset_doc: + return None + version_doc = collection.find_one( + {"type": "version", "parent": subset_doc["_id"]}, + sort=[("name", -1)], + ) + if not version_doc: + return None + return version_doc class ApplicationLaunchFailed(Exception): From 120865eb7fe917adb1041505c0ce75390d84927d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:18:30 +0200 Subject: [PATCH 165/176] added few loggings --- pype/lib.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 527db4a38a..260281f6bd 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1429,12 +1429,20 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): project_name = dbcon.Session.get("AVALON_PROJECT") collection = dbcon + log.debug(( + "Getting latest version for Project: \"{}\" Asset: \"{}\"" + " and Subset: \"{}\"" + ).format(project_name, asset_name, subset_name)) + # Query asset document id by asset name asset_doc = collection.find_one( {"type": "asset", "name": asset_name}, {"_id": True} ) if not asset_doc: + log.info( + "Asset \"{}\" was not found in Database.".format(asset_name) + ) return None subset_doc = collection.find_one( @@ -1442,6 +1450,9 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): {"_id": True} ) if not subset_doc: + log.info( + "Subset \"{}\" was not found in Database.".format(subset_name) + ) return None version_doc = collection.find_one( @@ -1449,6 +1460,9 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): sort=[("name", -1)], ) if not version_doc: + log.info( + "Subset \"{}\" does not have any version yet.".format(subset_name) + ) return None return version_doc From 27dfb159436ed32d9cb0e210c335433b6788c80c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:18:37 +0200 Subject: [PATCH 166/176] filled docstring --- pype/lib.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 260281f6bd..02ea46c0ff 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1414,6 +1414,13 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): Args: asset_name (str): Name of asset. subset_name (str): Name of subset. + dbcon (avalon.mongodb.AvalonMongoDB, optional): Avalon Mongo connection + with Session. + project_name (str, optional): Find latest version in specific project. + + Returns: + None: If asset, subset or version were not found. + dict: Last version document for entered . """ if not dbcon: From 96048ce6d7c4474df8704c016746c640b08ef24f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:18:59 +0200 Subject: [PATCH 167/176] changed way how get_latest_version is used in nuke's collect_review --- pype/plugins/nuke/publish/collect_review.py | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pype/plugins/nuke/publish/collect_review.py b/pype/plugins/nuke/publish/collect_review.py index e7e8da19a1..3b3786ed09 100644 --- a/pype/plugins/nuke/publish/collect_review.py +++ b/pype/plugins/nuke/publish/collect_review.py @@ -1,3 +1,4 @@ +import os import pyblish.api import pype.api from avalon import io, api @@ -26,20 +27,24 @@ class CollectReview(pyblish.api.InstancePlugin): if not node["review"].value(): return - # Add audio to instance if it exists. - try: - version = pype.api.get_latest_version( - instance.context.data["assetEntity"]["name"], "audioMain" - ) - representation = io.find_one( - {"type": "representation", "parent": version["_id"]} + # * Add audio to instance if exists. + # Find latest versions document + version_doc = pype.api.get_latest_version( + instance.context.data["assetEntity"]["name"], "audioMain" + ) + repre_doc = None + if version_doc: + # Try to find it's representation (Expected there is only one) + repre_doc = io.find_one( + {"type": "representation", "parent": version_doc["_id"]} ) + + # Add audio to instance if representation was found + if repre_doc: instance.data["audio"] = [{ "offset": 0, - "filename": api.get_representation_path(representation) + "filename": api.get_representation_path(repre_doc) }] - except AssertionError: - pass instance.data["families"].append("review") instance.data['families'].append('ftrack') From 4813365aeda92c15b89ead3c5ae578006104e26d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:22:08 +0200 Subject: [PATCH 168/176] added note to doctring --- pype/lib.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index 02ea46c0ff..c4321e0605 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1411,6 +1411,10 @@ def source_hash(filepath, *args): def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): """Retrieve latest version from `asset_name`, and `subset_name`. + Do not use if you want to query more than 5 latest versions as this method + query 3 times to mongo for each call. For those cases is better to use + more efficient way, e.g. with help of aggregations. + Args: asset_name (str): Name of asset. subset_name (str): Name of subset. From c63df5277efb97f715796858d69956442704568a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:25:13 +0200 Subject: [PATCH 169/176] make sure `avalon.io` is installed when using --- pype/lib.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/lib.py b/pype/lib.py index c4321e0605..7370f10756 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -1430,6 +1430,8 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): if not dbcon: log.debug("Using `avalon.io` for query.") dbcon = io + # Make sure is installed + io.install() if project_name and project_name != dbcon.Session.get("AVALON_PROJECT"): # `avalon.io` has only `_database` attribute From a80f1618e63dc25e3dcb7c66f5e56eceb57bede8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Oct 2020 18:34:44 +0200 Subject: [PATCH 170/176] removed unused import --- pype/plugins/nuke/publish/collect_review.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/plugins/nuke/publish/collect_review.py b/pype/plugins/nuke/publish/collect_review.py index 3b3786ed09..42aa910917 100644 --- a/pype/plugins/nuke/publish/collect_review.py +++ b/pype/plugins/nuke/publish/collect_review.py @@ -1,4 +1,3 @@ -import os import pyblish.api import pype.api from avalon import io, api From bdc6a0ca26a833e1365cefcf0f7cb5979e5c6bc4 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Fri, 16 Oct 2020 10:25:46 +0200 Subject: [PATCH 171/176] don't crash if we only have single frame --- pype/plugins/nuke/load/load_sequence.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pype/plugins/nuke/load/load_sequence.py b/pype/plugins/nuke/load/load_sequence.py index c5ce288540..44b9cb4a34 100644 --- a/pype/plugins/nuke/load/load_sequence.py +++ b/pype/plugins/nuke/load/load_sequence.py @@ -119,13 +119,14 @@ class LoadSequence(api.Loader): repr_cont = context["representation"]["context"] if "#" not in file: frame = repr_cont.get("frame") - padding = len(frame) - file = file.replace(frame, "#" * padding) + if frame: + padding = len(frame) + file = file.replace(frame, "#" * padding) read_name = "Read_{0}_{1}_{2}".format( repr_cont["asset"], repr_cont["subset"], - repr_cont["representation"]) + context["representation"]["name"]) # Create the Loader with the filename path set with viewer_update_and_undo_stop(): @@ -249,8 +250,9 @@ class LoadSequence(api.Loader): if "#" not in file: frame = repr_cont.get("frame") - padding = len(frame) - file = file.replace(frame, "#" * padding) + if frame: + padding = len(frame) + file = file.replace(frame, "#" * padding) # Get start frame from version data version = io.find_one({ From 9880488255e134cacf208b0f20bf41f06bb3c364 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 16 Oct 2020 10:49:42 +0200 Subject: [PATCH 172/176] fixed typo --- pype/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/lib.py b/pype/lib.py index ff9571de77..f364945a86 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -102,7 +102,7 @@ def _subprocess(*args, logger=None, **kwargs): # Get environents from kwarg or use current process environments if were # not passed. - env = kwargs.get("env") or os.envion + env = kwargs.get("env") or os.environ # Make sure environment contains only strings filtered_env = {k: str(v) for k, v in env.items()} From 4b742faddd3ec29dc9da11cedb3c9c835b41e5d6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 16 Oct 2020 11:07:33 +0200 Subject: [PATCH 173/176] logger keyword argument is skipped in function definition but is popped from kwargs --- pype/lib.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index f364945a86..f85d689ef9 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -81,7 +81,7 @@ def get_ffmpeg_tool_path(tool="ffmpeg"): # Special naming case for subprocess since its a built-in method. -def _subprocess(*args, logger=None, **kwargs): +def _subprocess(*args, **kwargs): """Convenience method for getting output errors for subprocess. Entered arguments and keyword arguments are passed to subprocess Popen. @@ -107,8 +107,7 @@ def _subprocess(*args, logger=None, **kwargs): filtered_env = {k: str(v) for k, v in env.items()} # Use lib's logger if was not passed with kwargs. - if not logger: - logger = log + logger = kwargs.pop("logger", log) # set overrides kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) From 771ba3e966b59a560d962f4e2a6ab40661eab564 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 16 Oct 2020 11:07:41 +0200 Subject: [PATCH 174/176] modified docstring --- pype/lib.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index f85d689ef9..a53aae2086 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -87,10 +87,10 @@ def _subprocess(*args, **kwargs): Entered arguments and keyword arguments are passed to subprocess Popen. Args: - logger (logging.Logger): Logger object if want to use different than - lib's logger. *args: Variable length arument list passed to Popen. - **kwargs : Arbitary keyword arguments passed to Popen. + **kwargs : Arbitary keyword arguments passed to Popen. Is possible to + pass `logging.Logger` object under "logger" if want to use + different than lib's logger. Returns: str: Full output of subprocess concatenated stdout and stderr. From 54983b04e372ae6a2ec81006f711fc6acff14bd0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 16 Oct 2020 11:23:59 +0200 Subject: [PATCH 175/176] add transparency to filter buttons spacer --- pype/tools/pyblish_pype/widgets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/tools/pyblish_pype/widgets.py b/pype/tools/pyblish_pype/widgets.py index 4da759899e..dc4919c13f 100644 --- a/pype/tools/pyblish_pype/widgets.py +++ b/pype/tools/pyblish_pype/widgets.py @@ -543,7 +543,9 @@ class TerminalFilterWidget(QtWidgets.QWidget): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) # Add spacers - layout.addWidget(QtWidgets.QWidget(), 1) + spacer = QtWidgets.QWidget() + spacer.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(spacer, 1) for btn in filter_buttons: layout.addWidget(btn) From 3ccd3181cde6b77eb4c1cd019adf7738abdf319b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 16 Oct 2020 15:19:59 +0200 Subject: [PATCH 176/176] #636 - Deadline Output Folder Pre-calculate final publish folder to add it to right mouse click option for easier checking in Deadline Monitor --- .../global/publish/submit_publish_job.py | 125 +++++++++++------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/pype/plugins/global/publish/submit_publish_job.py b/pype/plugins/global/publish/submit_publish_job.py index 30f64f7ab9..dcc87188f3 100644 --- a/pype/plugins/global/publish/submit_publish_job.py +++ b/pype/plugins/global/publish/submit_publish_job.py @@ -4,7 +4,8 @@ import os import json import re -from copy import copy +from copy import copy, deepcopy +import pype.api from avalon import api, io from avalon.vendor import requests, clique @@ -42,40 +43,6 @@ def _get_script(path): return str(path) -def get_latest_version(asset_name, subset_name, family): - """Retrieve latest files concerning extendFrame feature.""" - # Get asset - asset_name = io.find_one( - {"type": "asset", "name": asset_name}, projection={"name": True} - ) - - subset = io.find_one( - {"type": "subset", "name": subset_name, "parent": asset_name["_id"]}, - projection={"_id": True, "name": True}, - ) - - # Check if subsets actually exists (pre-run check) - assert subset, "No subsets found, please publish with `extendFrames` off" - - # Get version - version_projection = { - "name": True, - "data.startFrame": True, - "data.endFrame": True, - "parent": True, - } - - version = io.find_one( - {"type": "version", "parent": subset["_id"], "data.families": family}, - projection=version_projection, - sort=[("name", -1)], - ) - - assert version, "No version found, this is a bug" - - return version - - def get_resources(version, extension=None): """Get the files from the specific version.""" query = {"type": "representation", "parent": version["_id"]} @@ -250,7 +217,19 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): subset = data["subset"] job_name = "Publish - {subset}".format(subset=subset) - output_dir = instance.data["outputDir"] + # instance.data.get("subset") != instances[0]["subset"] + # 'Main' vs 'renderMain' + override_version = None + instance_version = instance.data.get("version") # take this if exists + if instance_version != 1: + override_version = instance_version + output_dir = self._get_publish_folder(instance.context.data['anatomy'], + deepcopy( + instance.data["anatomyData"]), + instance.data.get("asset"), + instances[0]["subset"], + 'render', + override_version) # Generate the payload for Deadline submission payload = { @@ -322,7 +301,6 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): payload["JobInfo"].pop("SecondaryPool", None) self.log.info("Submitting Deadline job ...") - # self.log.info(json.dumps(payload, indent=4, sort_keys=True)) url = "{}/api/jobs".format(self.DEADLINE_REST_URL) response = requests.post(url, json=payload, timeout=10) @@ -349,9 +327,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # get latest version of subset # this will stop if subset wasn't published yet - version = get_latest_version( - instance.data.get("asset"), - instance.data.get("subset"), "render") + version = pype.api.get_latest_version(instance.data.get("asset"), + instance.data.get("subset")) # get its files based on extension subset_resources = get_resources(version, representation.get("ext")) r_col, _ = clique.assemble(subset_resources) @@ -732,8 +709,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "resolutionHeight": data.get("resolutionHeight", 1080), "multipartExr": data.get("multipartExr", False), "jobBatchName": data.get("jobBatchName", ""), - "review": data.get("review", True), - "audio": data.get("audio", []) + "review": data.get("review", True) } if "prerender" in instance.data["families"]: @@ -742,7 +718,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "families": []}) # skip locking version if we are creating v01 - instance_version = instance.data.get("version") + instance_version = instance.data.get("version") # take this if exists if instance_version != 1: instance_skeleton_data["version"] = instance_version @@ -998,11 +974,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): prev_start = None prev_end = None - version = get_latest_version( - asset_name=asset, - subset_name=subset, - family='render' - ) + version = pype.api.get_latest_version(asset_name=asset, + subset_name=subset + ) # Set prev start / end frames for comparison if not prev_start and not prev_end: @@ -1018,3 +992,58 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): ) return updated_start, updated_end + + def _get_publish_folder(self, anatomy, template_data, + asset, subset, + family='render', version=None): + """ + Extracted logic to pre-calculate real publish folder, which is + calculated in IntegrateNew inside of Deadline process. + This should match logic in: + 'collect_anatomy_instance_data' - to + get correct anatomy, family, version for subset and + 'collect_resources_path' + get publish_path + + Args: + anatomy (pypeapp.lib.anatomy.Anatomy): + template_data (dict): pre-calculated collected data for process + asset (string): asset name + subset (string): subset name (actually group name of subset) + family (string): for current deadline process it's always 'render' + TODO - for generic use family needs to be dynamically + calculated like IntegrateNew does + version (int): override version from instance if exists + + Returns: + (string): publish folder where rendered and published files will + be stored + based on 'publish' template + """ + if not version: + version = pype.api.get_latest_version(asset, subset) + if version: + version = int(version["name"]) + 1 + + template_data["subset"] = subset + template_data["family"] = "render" + template_data["version"] = version + + anatomy_filled = anatomy.format(template_data) + + if "folder" in anatomy.templates["publish"]: + publish_folder = anatomy_filled["publish"]["folder"] + else: + # solve deprecated situation when `folder` key is not underneath + # `publish` anatomy + project_name = api.Session["AVALON_PROJECT"] + self.log.warning(( + "Deprecation warning: Anatomy does not have set `folder`" + " key underneath `publish` (in global of for project `{}`)." + ).format(project_name)) + + file_path = anatomy_filled["publish"]["path"] + # Directory + publish_folder = os.path.dirname(file_path) + + return publish_folder