Merge branch 'develop' into feature/new_publisher_core

This commit is contained in:
iLLiCiTiT 2021-10-22 17:41:01 +02:00
commit 87b8d498fa
55 changed files with 2301 additions and 1543 deletions

View file

@ -95,6 +95,30 @@ def get_local_collection_with_name(name):
return None
def deselect_all():
"""Deselect all objects in the scene.
Blender gives context error if trying to deselect object that it isn't
in object mode.
"""
modes = []
active = bpy.context.view_layer.objects.active
for obj in bpy.data.objects:
if obj.mode != 'OBJECT':
modes.append((obj, obj.mode))
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
for p in modes:
bpy.context.view_layer.objects.active = p[0]
bpy.ops.object.mode_set(mode=p[1])
bpy.context.view_layer.objects.active = active
class Creator(PypeCreatorMixin, blender.Creator):
pass

View file

@ -47,7 +47,7 @@ class CacheModelLoader(plugin.AssetLoader):
bpy.data.objects.remove(empty)
def _process(self, libpath, asset_group, group_name):
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
collection = bpy.context.view_layer.active_layer_collection.collection
@ -109,7 +109,7 @@ class CacheModelLoader(plugin.AssetLoader):
avalon_info = obj[AVALON_PROPERTY]
avalon_info.update({"container_name": group_name})
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
return objects

View file

@ -46,7 +46,7 @@ class FbxModelLoader(plugin.AssetLoader):
bpy.data.objects.remove(obj)
def _process(self, libpath, asset_group, group_name, action):
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
collection = bpy.context.view_layer.active_layer_collection.collection
@ -112,7 +112,7 @@ class FbxModelLoader(plugin.AssetLoader):
avalon_info = obj[AVALON_PROPERTY]
avalon_info.update({"container_name": group_name})
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
return objects

View file

@ -150,7 +150,7 @@ class BlendLayoutLoader(plugin.AssetLoader):
bpy.data.orphans_purge(do_local_ids=False)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
return objects

View file

@ -59,7 +59,7 @@ class JsonLayoutLoader(plugin.AssetLoader):
return None
def _process(self, libpath, asset, asset_group, actions):
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
with open(libpath, "r") as fp:
data = json.load(fp)

View file

@ -93,7 +93,7 @@ class BlendModelLoader(plugin.AssetLoader):
bpy.data.orphans_purge(do_local_ids=False)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
return objects
@ -126,7 +126,7 @@ class BlendModelLoader(plugin.AssetLoader):
asset_group.empty_display_type = 'SINGLE_ARROW'
avalon_container.objects.link(asset_group)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
if options is not None:
parent = options.get('parent')
@ -158,7 +158,7 @@ class BlendModelLoader(plugin.AssetLoader):
bpy.ops.object.parent_set(keep_transform=True)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
objects = self._process(libpath, asset_group, group_name)

View file

@ -156,7 +156,7 @@ class BlendRigLoader(plugin.AssetLoader):
while bpy.data.orphans_purge(do_local_ids=False):
pass
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
return objects
@ -191,7 +191,7 @@ class BlendRigLoader(plugin.AssetLoader):
action = None
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
create_animation = False
@ -227,7 +227,7 @@ class BlendRigLoader(plugin.AssetLoader):
bpy.ops.object.parent_set(keep_transform=True)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
objects = self._process(libpath, asset_group, group_name, action)
@ -250,7 +250,7 @@ class BlendRigLoader(plugin.AssetLoader):
data={"dependencies": str(context["representation"]["_id"])}
)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
bpy.context.scene.collection.objects.link(asset_group)

View file

@ -28,7 +28,7 @@ class ExtractABC(api.Extractor):
# Perform extraction
self.log.info("Performing extraction..")
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
selected = []
asset_group = None
@ -50,7 +50,7 @@ class ExtractABC(api.Extractor):
flatten=False
)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
if "representations" not in instance.data:
instance.data["representations"] = []

View file

@ -24,7 +24,7 @@ class ExtractFBX(api.Extractor):
# Perform extraction
self.log.info("Performing extraction..")
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
selected = []
asset_group = None
@ -60,7 +60,7 @@ class ExtractFBX(api.Extractor):
add_leaf_bones=False
)
bpy.ops.object.select_all(action='DESELECT')
plugin.deselect_all()
for mat in new_materials:
bpy.data.materials.remove(mat)

View file

@ -4,7 +4,6 @@ import copy
import argparse
from avalon import io
from avalon.tools import publish
import pyblish.api
import pyblish.util
@ -13,6 +12,7 @@ from openpype.api import Logger
import openpype
import openpype.hosts.celaction
from openpype.hosts.celaction import api as celaction
from openpype.tools.utils import host_tools
log = Logger().get_logger("Celaction_cli_publisher")
@ -82,7 +82,7 @@ def main():
pyblish.api.register_host(publish_host)
return publish.show()
return host_tools.show_publish()
if __name__ == "__main__":

View file

@ -1,8 +1,6 @@
from .pipeline import (
install,
uninstall,
publish,
launch_workfiles_app
uninstall
)
from .utils import (
@ -22,12 +20,9 @@ __all__ = [
# pipeline
"install",
"uninstall",
"publish",
"launch_workfiles_app",
# utils
"setup",
"get_resolve_module",
# lib
"get_additional_data",

View file

@ -3,19 +3,7 @@ import sys
from Qt import QtWidgets, QtCore
from .pipeline import (
publish,
launch_workfiles_app
)
from avalon.tools import (
creator,
sceneinventory,
)
from openpype.tools import (
loader,
libraryloader
)
from openpype.tools.utils import host_tools
from openpype.hosts.fusion.scripts import (
set_rendermode,
@ -36,7 +24,7 @@ def load_stylesheet():
class Spacer(QtWidgets.QWidget):
def __init__(self, height, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
super(Spacer, self).__init__(*args, **kwargs)
self.setFixedHeight(height)
@ -53,7 +41,7 @@ class Spacer(QtWidgets.QWidget):
class OpenPypeMenu(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
super(OpenPypeMenu, self).__init__(*args, **kwargs)
self.setObjectName("OpenPypeMenu")
@ -117,27 +105,27 @@ class OpenPypeMenu(QtWidgets.QWidget):
def on_workfile_clicked(self):
print("Clicked Workfile")
launch_workfiles_app()
host_tools.show_workfiles()
def on_create_clicked(self):
print("Clicked Create")
creator.show()
host_tools.show_creator()
def on_publish_clicked(self):
print("Clicked Publish")
publish(None)
host_tools.show_publish()
def on_load_clicked(self):
print("Clicked Load")
loader.show(use_context=True)
host_tools.show_loader(use_context=True)
def on_inventory_clicked(self):
print("Clicked Inventory")
sceneinventory.show()
host_tools.show_scene_inventory()
def on_libload_clicked(self):
print("Clicked Library")
libraryloader.show()
host_tools.show_library_loader()
def on_rendernode_clicked(self):
from avalon import style

View file

@ -3,7 +3,6 @@ Basic avalon integration
"""
import os
from openpype.tools import workfiles
from avalon import api as avalon
from pyblish import api as pyblish
from openpype.api import Logger
@ -98,14 +97,3 @@ def on_pyblish_instance_toggled(instance, new_value, old_value):
current = attrs["TOOLB_PassThrough"]
if current != passthrough:
tool.SetAttrs({"TOOLB_PassThrough": passthrough})
def launch_workfiles_app(*args):
workdir = os.environ["AVALON_WORKDIR"]
workfiles.show(workdir)
def publish(parent):
"""Shorthand to publish from within host"""
from avalon.tools import publish
return publish.show(parent)

View file

@ -3,17 +3,14 @@
import os
from pathlib import Path
import logging
import re
from openpype import lib
from openpype.api import (get_current_project_settings)
import openpype.hosts.harmony
import pyblish.api
from avalon import io, harmony
import avalon.api
import avalon.tools.sceneinventory
log = logging.getLogger("openpype.hosts.harmony")

View file

@ -2,6 +2,7 @@ import os
import sys
import hiero.core
from openpype.api import Logger
from openpype.tools.utils import host_tools
from avalon.api import Session
from hiero.ui import findMenuAction
@ -41,8 +42,6 @@ def menu_install():
apply_colorspace_project, apply_colorspace_clips
)
# here is the best place to add menu
from avalon.tools import creator, sceneinventory
from openpype.tools import loader
from avalon.vendor.Qt import QtGui
menu_name = os.environ['AVALON_LABEL']
@ -87,15 +86,15 @@ def menu_install():
creator_action = menu.addAction("Create ...")
creator_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png"))
creator_action.triggered.connect(creator.show)
creator_action.triggered.connect(host_tools.show_creator)
loader_action = menu.addAction("Load ...")
loader_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png"))
loader_action.triggered.connect(loader.show)
loader_action.triggered.connect(host_tools.show_loader)
sceneinventory_action = menu.addAction("Manage ...")
sceneinventory_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png"))
sceneinventory_action.triggered.connect(sceneinventory.show)
sceneinventory_action.triggered.connect(host_tools.show_scene_inventory)
menu.addSeparator()
if os.getenv("OPENPYPE_DEVELOP"):

View file

@ -4,13 +4,12 @@ Basic avalon integration
import os
import contextlib
from collections import OrderedDict
from avalon.tools import publish as _publish
from openpype.tools import workfiles
from avalon.pipeline import AVALON_CONTAINER_ID
from avalon import api as avalon
from avalon import schema
from pyblish import api as pyblish
from openpype.api import Logger
from openpype.tools.utils import host_tools
from . import lib, menu, events
log = Logger().get_logger(__name__)
@ -211,15 +210,13 @@ def update_container(track_item, data=None):
def launch_workfiles_app(*args):
''' Wrapping function for workfiles launcher '''
workdir = os.environ["AVALON_WORKDIR"]
# show workfile gui
workfiles.show(workdir)
host_tools.show_workfiles()
def publish(parent):
"""Shorthand to publish from within host"""
return _publish.show(parent)
return host_tools.show_publish(parent)
@contextlib.contextmanager

View file

@ -7,24 +7,30 @@
<scriptItem id="avalon_create">
<label>Create ...</label>
<scriptCode><![CDATA[
from avalon.tools import creator
creator.show()
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_creator(parent)
]]></scriptCode>
</scriptItem>
<scriptItem id="avalon_load">
<label>Load ...</label>
<scriptCode><![CDATA[
from openpype.tools import loader
loader.show(use_context=True)
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_loader(parent=parent, use_context=True)
]]></scriptCode>
</scriptItem>
<scriptItem id="avalon_manage">
<label>Manage ...</label>
<scriptCode><![CDATA[
from avalon.tools import cbsceneinventory
cbsceneinventory.show()
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_scene_inventory(parent)
]]></scriptCode>
</scriptItem>
@ -32,9 +38,9 @@ cbsceneinventory.show()
<label>Publish ...</label>
<scriptCode><![CDATA[
import hou
from avalon.tools import publish
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
publish.show(parent)
host_tools.show_publish(parent)
]]></scriptCode>
</scriptItem>
@ -43,9 +49,10 @@ publish.show(parent)
<scriptItem id="workfiles">
<label>Work Files ...</label>
<scriptCode><![CDATA[
import hou, os
from openpype.tools import workfiles
workfiles.show(os.environ["AVALON_WORKDIR"])
import hou
from openpype.tools.utils import host_tools
parent = hou.qt.mainWindow()
host_tools.show_workfiles(parent)
]]></scriptCode>
</scriptItem>

View file

@ -8,7 +8,7 @@ from avalon import api as avalon
from avalon import pipeline
from avalon.maya import suspended_refresh
from avalon.maya.pipeline import IS_HEADLESS
from openpype.tools import workfiles
from openpype.tools.utils import host_tools
from pyblish import api as pyblish
from openpype.lib import any_outdated
import openpype.hosts.maya
@ -208,16 +208,12 @@ def on_init(_):
launch_workfiles = os.environ.get("WORKFILES_STARTUP")
if launch_workfiles:
safe_deferred(launch_workfiles_app)
safe_deferred(host_tools.show_workfiles)
if not IS_HEADLESS:
safe_deferred(override_toolbox_ui)
def launch_workfiles_app():
workfiles.show(os.environ["AVALON_WORKDIR"])
def on_before_save(return_code, _):
"""Run validation for scene's FPS prior to saving"""
return lib.validate_fps()

View file

@ -1,10 +1,16 @@
"""A set of commands that install overrides to Maya's UI"""
import os
import logging
from functools import partial
import maya.cmds as mc
import maya.mel as mel
from functools import partial
import os
import logging
from avalon.maya import pipeline
from openpype.api import resources
from openpype.tools.utils import host_tools
log = logging.getLogger(__name__)
@ -69,39 +75,8 @@ def override_component_mask_commands():
def override_toolbox_ui():
"""Add custom buttons in Toolbox as replacement for Maya web help icon."""
inventory = None
loader = None
launch_workfiles_app = None
mayalookassigner = None
try:
import avalon.tools.sceneinventory as inventory
except Exception:
log.warning("Could not import SceneInventory tool")
try:
import openpype.tools.loader as loader
except Exception:
log.warning("Could not import Loader tool")
try:
from avalon.maya.pipeline import launch_workfiles_app
except Exception:
log.warning("Could not import Workfiles tool")
try:
from openpype.tools import mayalookassigner
except Exception:
log.warning("Could not import Maya Look assigner tool")
from openpype.api import resources
icons = resources.get_resource("icons")
if not any((
mayalookassigner, launch_workfiles_app, loader, inventory
)):
return
# Ensure the maya web icon on toolbox exists
web_button = "ToolBox|MainToolboxLayout|mayaWebButton"
if not mc.iconTextButton(web_button, query=True, exists=True):
@ -120,14 +95,23 @@ def override_toolbox_ui():
# Create our controls
background_color = (0.267, 0.267, 0.267)
controls = []
if mayalookassigner:
look_assigner = None
try:
look_assigner = host_tools.get_tool_by_name(
"lookassigner",
parent=pipeline._parent
)
except Exception:
log.warning("Couldn't create Look assigner window.", exc_info=True)
if look_assigner is not None:
controls.append(
mc.iconTextButton(
"pype_toolbox_lookmanager",
annotation="Look Manager",
label="Look Manager",
image=os.path.join(icons, "lookmanager.png"),
command=lambda: mayalookassigner.show(),
command=host_tools.show_look_assigner,
bgc=background_color,
width=icon_size,
height=icon_size,
@ -135,50 +119,53 @@ def override_toolbox_ui():
)
)
if launch_workfiles_app:
controls.append(
mc.iconTextButton(
"pype_toolbox_workfiles",
annotation="Work Files",
label="Work Files",
image=os.path.join(icons, "workfiles.png"),
command=lambda: launch_workfiles_app(),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
controls.append(
mc.iconTextButton(
"pype_toolbox_workfiles",
annotation="Work Files",
label="Work Files",
image=os.path.join(icons, "workfiles.png"),
command=lambda: host_tools.show_workfiles(
parent=pipeline._parent
),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
)
if loader:
controls.append(
mc.iconTextButton(
"pype_toolbox_loader",
annotation="Loader",
label="Loader",
image=os.path.join(icons, "loader.png"),
command=lambda: loader.show(use_context=True),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
controls.append(
mc.iconTextButton(
"pype_toolbox_loader",
annotation="Loader",
label="Loader",
image=os.path.join(icons, "loader.png"),
command=lambda: host_tools.show_loader(
parent=pipeline._parent, use_context=True
),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
)
if inventory:
controls.append(
mc.iconTextButton(
"pype_toolbox_manager",
annotation="Inventory",
label="Inventory",
image=os.path.join(icons, "inventory.png"),
command=lambda: inventory.show(),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
controls.append(
mc.iconTextButton(
"pype_toolbox_manager",
annotation="Inventory",
label="Inventory",
image=os.path.join(icons, "inventory.png"),
command=lambda: host_tools.show_scene_inventory(
parent=pipeline._parent
),
bgc=background_color,
width=icon_size,
height=icon_size,
parent=parent
)
)
# Add the buttons on the bottom and stack
# them above each other with side padding

View file

@ -2,13 +2,15 @@ import sys
import os
import logging
from avalon.vendor.Qt import QtWidgets, QtGui
from avalon.maya import pipeline
from openpype.api import BuildWorkfile
import maya.cmds as cmds
from openpype.settings import get_project_settings
from Qt import QtWidgets, QtGui
self = sys.modules[__name__]
import maya.cmds as cmds
from avalon.maya import pipeline
from openpype.api import BuildWorkfile
from openpype.settings import get_project_settings
from openpype.tools.utils import host_tools
log = logging.getLogger(__name__)
@ -19,10 +21,8 @@ def _get_menu(menu_name=None):
if menu_name is None:
menu_name = pipeline._menu
widgets = dict((
w.objectName(), w) for w in QtWidgets.QApplication.allWidgets())
menu = widgets.get(menu_name)
return menu
widgets = {w.objectName(): w for w in QtWidgets.QApplication.allWidgets()}
return widgets.get(menu_name)
def deferred():
@ -36,25 +36,52 @@ def deferred():
)
def add_look_assigner_item():
import mayalookassigner
cmds.menuItem(
"Look assigner",
parent=pipeline._menu,
command=lambda *args: mayalookassigner.show()
command=lambda *args: host_tools.show_look_assigner(
pipeline._parent
)
)
def modify_workfiles():
from openpype.tools import workfiles
def launch_workfiles_app(*_args, **_kwargs):
workfiles.show(
os.path.join(
cmds.workspace(query=True, rootDirectory=True),
cmds.workspace(fileRuleEntry="scene")
),
parent=pipeline._parent
def add_experimental_item():
cmds.menuItem(
"Experimental tools...",
parent=pipeline._menu,
command=lambda *args: host_tools.show_experimental_tools_dialog(
pipeline._parent
)
)
def add_scripts_menu():
try:
import scriptsmenu.launchformaya as launchformaya
except ImportError:
log.warning(
"Skipping studio.menu install, because "
"'scriptsmenu' module seems unavailable."
)
return
# load configuration of custom menu
project_settings = get_project_settings(os.getenv("AVALON_PROJECT"))
config = project_settings["maya"]["scriptsmenu"]["definition"]
_menu = project_settings["maya"]["scriptsmenu"]["name"]
if not config:
log.warning("Skipping studio menu, no definition found.")
return
# run the launcher for Maya menu
studio_menu = launchformaya.main(
title=_menu.title(),
objectName=_menu.title().lower().replace(" ", "_")
)
# apply configuration
studio_menu.build_from_configuration(studio_menu, config)
def modify_workfiles():
# Find the pipeline menu
top_menu = _get_menu()
@ -75,7 +102,7 @@ def deferred():
cmds.menuItem(
"Work Files",
parent=pipeline._menu,
command=launch_workfiles_app,
command=lambda *args: host_tools.show_workfiles(pipeline._parent),
insertAfter=after_action
)
@ -109,38 +136,13 @@ def deferred():
log.info("Attempting to install scripts menu ...")
# add_scripts_menu()
add_build_workfiles_item()
add_look_assigner_item()
add_experimental_item()
modify_workfiles()
remove_project_manager()
try:
import scriptsmenu.launchformaya as launchformaya
import scriptsmenu.scriptsmenu as scriptsmenu
except ImportError:
log.warning(
"Skipping studio.menu install, because "
"'scriptsmenu' module seems unavailable."
)
return
# load configuration of custom menu
project_settings = get_project_settings(os.getenv("AVALON_PROJECT"))
config = project_settings["maya"]["scriptsmenu"]["definition"]
_menu = project_settings["maya"]["scriptsmenu"]["name"]
if not config:
log.warning("Skipping studio menu, no definition found.")
return
# run the launcher for Maya menu
studio_menu = launchformaya.main(
title=_menu.title(),
objectName=_menu.title().lower().replace(" ", "_")
)
# apply configuration
studio_menu.build_from_configuration(studio_menu, config)
add_scripts_menu()
def uninstall():
@ -161,7 +163,7 @@ def install():
return
# Allow time for uninstallation to finish.
cmds.evalDeferred(deferred)
cmds.evalDeferred(deferred, lowestPriority=True)
def popup():

View file

@ -244,17 +244,17 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
# metadata file will be located in top-most common
# directory.
# TODO: use `os.path.commonpath()` after switch to Python 3
publish_meta_path = os.path.normpath(publish_meta_path)
common_publish_meta_path = os.path.splitdrive(
publish_meta_path)[0]
if common_publish_meta_path:
common_publish_meta_path += os.path.sep
for part in publish_meta_path.split("/"):
for part in publish_meta_path.replace(
common_publish_meta_path, "").split(os.path.sep):
common_publish_meta_path = os.path.join(
common_publish_meta_path, part)
if part == expected_layer_name:
break
common_publish_meta_path = common_publish_meta_path.replace(
"\\", "/")
self.log.info(
"Publish meta path: {}".format(common_publish_meta_path))

View file

@ -7,7 +7,6 @@ from collections import OrderedDict
from avalon import api, io, lib
from openpype.tools import workfiles
import avalon.nuke
from avalon.nuke import lib as anlib
from avalon.nuke import (
@ -24,7 +23,7 @@ from openpype.api import (
get_current_project_settings,
ApplicationManager
)
from openpype.tools.utils import host_tools
import nuke
from .utils import set_context_favorites
@ -1662,7 +1661,7 @@ def launch_workfiles_app():
if not opnl.workfiles_launched:
opnl.workfiles_launched = True
workfiles.show(os.environ["AVALON_WORKDIR"])
host_tools.show_workfiles()
def process_workfile_builder():

View file

@ -4,7 +4,7 @@ from avalon.api import Session
from .lib import WorkfileSettings
from openpype.api import Logger, BuildWorkfile, get_current_project_settings
from openpype.tools import workfiles
from openpype.tools.utils import host_tools
log = Logger().get_logger(__name__)
@ -25,7 +25,7 @@ def install():
menu.removeItem(rm_item[1].name())
menu.addCommand(
name,
workfiles.show,
host_tools.show_workfiles,
index=2
)
menu.addSeparator(index=3)
@ -84,6 +84,12 @@ def install():
)
log.debug("Adding menu item: {}".format(name))
# Add experimental tools action
menu.addSeparator()
menu.addCommand(
"Experimental tools...",
host_tools.show_experimental_tools_dialog
)
# adding shortcuts
add_shortcuts_from_presets()

View file

@ -8,15 +8,7 @@ from .pipeline import (
launch_workfiles_app
)
from avalon.tools import (
creator,
sceneinventory,
subsetmanager
)
from openpype.tools import (
loader,
libraryloader,
)
from openpype.tools.utils import host_tools
def load_stylesheet():
@ -32,7 +24,7 @@ def load_stylesheet():
class Spacer(QtWidgets.QWidget):
def __init__(self, height, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
super(Spacer, self).__init__(*args, **kwargs)
self.setFixedHeight(height)
@ -49,7 +41,7 @@ class Spacer(QtWidgets.QWidget):
class OpenPypeMenu(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
super(OpenPypeMenu, self).__init__(*args, **kwargs)
self.setObjectName("OpenPypeMenu")
@ -119,7 +111,7 @@ class OpenPypeMenu(QtWidgets.QWidget):
def on_create_clicked(self):
print("Clicked Create")
creator.show()
host_tools.show_creator()
def on_publish_clicked(self):
print("Clicked Publish")
@ -127,19 +119,19 @@ class OpenPypeMenu(QtWidgets.QWidget):
def on_load_clicked(self):
print("Clicked Load")
loader.show(use_context=True)
host_tools.show_loader(use_context=True)
def on_inventory_clicked(self):
print("Clicked Inventory")
sceneinventory.show()
host_tools.show_scene_inventory()
def on_subsetm_clicked(self):
print("Clicked Subset Manager")
subsetmanager.show()
host_tools.show_subset_manager()
def on_libload_clicked(self):
print("Clicked Library")
libraryloader.show()
host_tools.show_library_loader()
def on_rename_clicked(self):
print("Clicked Rename")

View file

@ -4,7 +4,6 @@ Basic avalon integration
import os
import contextlib
from collections import OrderedDict
from openpype.tools import workfiles
from avalon import api as avalon
from avalon import schema
from avalon.pipeline import AVALON_CONTAINER_ID
@ -12,6 +11,7 @@ from pyblish import api as pyblish
from openpype.api import Logger
from . import lib
from . import PLUGINS_DIR
from openpype.tools.utils import host_tools
log = Logger().get_logger(__name__)
PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish")
@ -212,14 +212,12 @@ def update_container(timeline_item, data=None):
def launch_workfiles_app(*args):
workdir = os.environ["AVALON_WORKDIR"]
workfiles.show(workdir)
host_tools.show_workfiles()
def publish(parent):
"""Shorthand to publish from within host"""
from avalon.tools import publish
return publish.show(parent)
return host_tools.show_publish()
@contextlib.contextmanager

View file

@ -0,0 +1,37 @@
import pyblish.api
import openpype.api
import os
class ValidateSources(pyblish.api.InstancePlugin):
"""Validates source files.
Loops through all 'files' in 'stagingDir' if actually exist. They might
got deleted between starting of SP and now.
"""
order = openpype.api.ValidateContentsOrder
label = "Check source files"
optional = True # only for unforeseeable cases
hosts = ["standalonepublisher"]
def process(self, instance):
self.log.info("instance {}".format(instance.data))
for repr in instance.data["representations"]:
files = []
if isinstance(repr["files"], str):
files.append(repr["files"])
else:
files = list(repr["files"])
for file_name in files:
source_file = os.path.join(repr["stagingDir"],
file_name)
if not os.path.exists(source_file):
raise ValueError("File {} not found".format(source_file))

View file

@ -1,6 +1,5 @@
import os
import openpype
from openpype import resources
from openpype.modules import OpenPypeModule
from openpype_interfaces import ITrayModule
@ -52,16 +51,12 @@ class AvalonModule(OpenPypeModule, ITrayModule):
def tray_init(self):
# Add library tool
try:
from Qt import QtGui
from avalon import style
from openpype.tools.libraryloader import LibraryLoaderWindow
self.libraryloader = LibraryLoaderWindow(
icon=QtGui.QIcon(resources.get_openpype_icon_filepath()),
show_projects=True,
show_libraries=True
)
self.libraryloader.setStyleSheet(style.load_stylesheet())
except Exception:
self.log.warning(
"Couldn't load Library loader tool for tray.",
@ -70,6 +65,9 @@ class AvalonModule(OpenPypeModule, ITrayModule):
# Definition of Tray menu
def tray_menu(self, tray_menu):
if self.libraryloader is None:
return
from Qt import QtWidgets
# Actions
action_library_loader = QtWidgets.QAction(
@ -87,6 +85,9 @@ class AvalonModule(OpenPypeModule, ITrayModule):
return
def show_library_loader(self):
if self.libraryloader is None:
return
self.libraryloader.show()
# Raise and activate the window

View file

@ -3,6 +3,7 @@ import json
from avalon.api import AvalonMongoDB
from openpype.api import ProjectSettings
from openpype.lib import create_project
from openpype.settings import SaveWarningExc
from openpype_modules.ftrack.lib import (
ServerAction,
@ -312,7 +313,6 @@ class PrepareProjectServer(ServerAction):
if not in_data:
return
root_values = {}
root_key = "__root__"
for key in tuple(in_data.keys()):
@ -392,7 +392,12 @@ class PrepareProjectServer(ServerAction):
else:
attributes_entity[key] = value
project_settings.save()
try:
project_settings.save()
except SaveWarningExc as exc:
self.log.info("Few warnings happened during settings save:")
for warning in exc.warnings:
self.log.info(str(warning))
# Change custom attributes on project
if custom_attribute_values:

View file

@ -3,6 +3,7 @@ import json
from avalon.api import AvalonMongoDB
from openpype.api import ProjectSettings
from openpype.lib import create_project
from openpype.settings import SaveWarningExc
from openpype_modules.ftrack.lib import (
BaseAction,
@ -417,7 +418,12 @@ class PrepareProjectLocal(BaseAction):
else:
attributes_entity[key] = value
project_settings.save()
try:
project_settings.save()
except SaveWarningExc as exc:
self.log.info("Few warnings happened during settings save:")
for warning in exc.warnings:
self.log.info(str(warning))
# Change custom attributes on project
if custom_attribute_values:

View file

@ -12,12 +12,36 @@ _FONT_IDS = None
current_dir = os.path.dirname(os.path.abspath(__file__))
def _get_colors_raw_data():
"""Read data file with stylesheet fill values.
Returns:
dict: Loaded data for stylesheet.
"""
data_path = os.path.join(current_dir, "data.json")
with open(data_path, "r") as data_stream:
data = json.load(data_stream)
return data
def get_colors_data():
"""Only color data from stylesheet data."""
data = _get_colors_raw_data()
return data.get("color") or {}
def _convert_color_values_to_objects(value):
"""Parse all string values in dictionary to Color definitions.
Recursive function calling itself if value is dictionary.
Args:
value (dict, str): String is parsed into color definition object and
dictionary is passed into this function.
Raises:
TypeError: If value in color data do not contain string of dictionary.
"""
if isinstance(value, dict):
output = {}
for _key, _value in value.items():
@ -32,6 +56,11 @@ def _convert_color_values_to_objects(value):
def get_objected_colors():
"""Colors parsed from stylesheet data into color definitions.
Returns:
dict: Parsed color objects by keys in data.
"""
colors_data = get_colors_data()
output = {}
for key, value in colors_data.items():
@ -39,14 +68,15 @@ def get_objected_colors():
return output
def _get_colors_raw_data():
data_path = os.path.join(current_dir, "data.json")
with open(data_path, "r") as data_stream:
data = json.load(data_stream)
return data
def _load_stylesheet():
"""Load strylesheet and trigger all related callbacks.
Style require more than a stylesheet string. Stylesheet string
contains paths to resources which must be registered into Qt application
and load fonts used in stylesheets.
Also replace values from stylesheet data into stylesheet text.
"""
from . import qrc_resources
qrc_resources.qInitResources()
@ -78,6 +108,7 @@ def _load_stylesheet():
def _load_font():
"""Load and register fonts into Qt application."""
from Qt import QtGui
global _FONT_IDS
@ -117,6 +148,7 @@ def _load_font():
def load_stylesheet():
"""Load and return OpenPype Qt stylesheet."""
global _STYLESHEET_CACHE
if _STYLESHEET_CACHE is None:
_STYLESHEET_CACHE = _load_stylesheet()
@ -125,4 +157,5 @@ def load_stylesheet():
def app_icon_path():
"""Path to OpenPype icon."""
return resources.get_openpype_icon_filepath()

View file

@ -1,7 +1,27 @@
"""Color definitions that can be used to parse strings for stylesheet.
Each definition must have available method `get_qcolor` which should return
`QtGui.QColor` representation of the color.
# TODO create abstract class to force this method implementation
Usage: Some colors may be not be used only in stylesheet but is required to
use them in code too. To not hardcode these color values into code it is better
to use same colors that are available fro stylesheets.
It is possible that some colors may not be used in stylesheet at all and thei
definition is used only in code.
"""
import re
def parse_color(value):
"""Parse string value of color to one of objected representation.
Args:
value(str): Color definition usable in stylesheet.
"""
modified_value = value.strip().lower()
if modified_value.startswith("hsla"):
return HSLAColor(value)
@ -21,12 +41,30 @@ def parse_color(value):
def create_qcolor(*args):
"""Create QtGui.QColor object.
Args:
*args (tuple): It is possible to pass initialization arguments for
Qcolor.
"""
from Qt import QtGui
return QtGui.QColor(*args)
def min_max_check(value, min_value, max_value):
"""Validate number value if is in passed range.
Args:
value (int, float): Value which is validated.
min_value (int, float): Minimum possible value. Validation is skipped
if passed value is None.
max_value (int, float): Maximum possible value. Validation is skipped
if passed value is None.
Raises:
ValueError: When 'value' is out of specified range.
"""
if min_value is not None and value < min_value:
raise ValueError("Minimum expected value is '{}' got '{}'".format(
min_value, value
@ -39,6 +77,16 @@ def min_max_check(value, min_value, max_value):
def int_validation(value, min_value=None, max_value=None):
"""Validation of integer value within range.
Args:
value (int): Validated value.
min_value (int): Minimum possible value.
max_value (int): Maximum possible value.
Raises:
TypeError: If 'value' is not 'int' type.
"""
if not isinstance(value, int):
raise TypeError((
"Invalid type of hue expected 'int' got {}"
@ -48,6 +96,16 @@ def int_validation(value, min_value=None, max_value=None):
def float_validation(value, min_value=None, max_value=None):
"""Validation of float value within range.
Args:
value (float): Validated value.
min_value (float): Minimum possible value.
max_value (float): Maximum possible value.
Raises:
TypeError: If 'value' is not 'float' type.
"""
if not isinstance(value, float):
raise TypeError((
"Invalid type of hue expected 'int' got {}"
@ -57,6 +115,11 @@ def float_validation(value, min_value=None, max_value=None):
class UnknownColor:
"""Color from stylesheet data without known color definition.
This is backup for unknown color definitions which may be for example
constants or definition not yet defined by class.
"""
def __init__(self, value):
self.value = value
@ -65,6 +128,14 @@ class UnknownColor:
class HEXColor:
"""Hex color definition.
Hex color is defined by '#' and 3 or 6 hex values (0-F).
Examples:
"#fff"
"#f3f3f3"
"""
regex = re.compile(r"[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$")
def __init__(self, color_string):
@ -92,6 +163,7 @@ class HEXColor:
@classmethod
def hex_to_rgb(cls, value):
"""Convert hex value to rgb."""
hex_value = value.lstrip("#")
if not cls.regex.match(hex_value):
raise ValueError("\"{}\" is not a valid HEX code.".format(value))
@ -111,6 +183,13 @@ class HEXColor:
class RGBColor:
"""Color defined by red green and blue values.
Each color has possible integer range 0-255.
Examples:
"rgb(255, 127, 0)"
"""
def __init__(self, value):
modified_color = value.lower().strip()
content = modified_color.rstrip(")").lstrip("rgb(")
@ -146,6 +225,13 @@ class RGBColor:
class RGBAColor:
"""Color defined by red green, blue and alpha values.
Each color has possible integer range 0-255.
Examples:
"rgba(255, 127, 0, 127)"
"""
def __init__(self, value):
modified_color = value.lower().strip()
content = modified_color.rstrip(")").lstrip("rgba(")
@ -155,7 +241,10 @@ class RGBAColor:
red = int(red_str)
green = int(green_str)
blue = int(blue_str)
alpha = int(alpha_str)
if "." in alpha_str:
alpha = int(float(alpha_str) * 100)
else:
alpha = int(alpha_str)
int_validation(red, 0, 255)
int_validation(green, 0, 255)
@ -188,6 +277,15 @@ class RGBAColor:
class HSLColor:
"""Color defined by hue, saturation and light values.
Hue is defined as integer in rage 0-360. Saturation and light can be
defined as float or percent value.
Examples:
"hsl(27, 0.7, 0.3)"
"hsl(27, 70%, 30%)"
"""
def __init__(self, value):
modified_color = value.lower().strip()
content = modified_color.rstrip(")").lstrip("hsl(")
@ -232,6 +330,16 @@ class HSLColor:
class HSLAColor:
"""Color defined by hue, saturation, light and alpha values.
Hue is defined as integer in rage 0-360. Saturation and light can be
defined as float (0-1 range) or percent value(0-100%). And alpha
as float (0-1 range).
Examples:
"hsl(27, 0.7, 0.3)"
"hsl(27, 70%, 30%)"
"""
def __init__(self, value):
modified_color = value.lower().strip()
content = modified_color.rstrip(")").lstrip("hsla(")
@ -248,10 +356,8 @@ class HSLAColor:
light = float(light_str.rstrip("%")) / 100
else:
light = float(light_str)
alpha = float(alpha_str)
if isinstance(alpha, int):
alpha = float(alpha)
alpha = float(alpha_str)
int_validation(hue, 0, 360)
float_validation(sat, 0, 1)

View file

@ -28,27 +28,37 @@
"bg": "#2C313A",
"bg-inputs": "#21252B",
"bg-buttons": "#434a56",
"bg-button-hover": "hsla(220, 14%, 70%, .3)",
"bg-button-hover": "rgba(168, 175, 189, 0.3)",
"bg-inputs-disabled": "#2C313A",
"bg-buttons-disabled": "#434a56",
"bg-splitter": "#434a56",
"bg-splitter-hover": "rgba(168, 175, 189, 0.3)",
"bg-menu-separator": "rgba(75, 83, 98, 127)",
"bg-scroll-handle": "#4B5362",
"bg-view": "#21252B",
"bg-view-header": "#373D48",
"bg-view-hover": "hsla(220, 14%, 70%, .3)",
"bg-view-hover": "rgba(168, 175, 189, .3)",
"bg-view-alternate": "rgb(36, 42, 50)",
"bg-view-disabled": "#434a56",
"bg-view-alternate-disabled": "#2C313A",
"bg-view-selection": "hsla(200, 60%, 60%, .4)",
"bg-view-selection-hover": "hsla(200, 60%, 60%, .8)",
"bg-view-selection": "rgba(92, 173, 214, .4)",
"bg-view-selection-hover": "rgba(92, 173, 214, .8)",
"border": "#373D48",
"border-hover": "hsla(220, 14%, 70%, .3)",
"border-hover": "rgba(168, 175, 189, .3)",
"border-focus": "hsl(200, 60%, 60%)",
"loader": {
"asset-view": {
"selected": "rgba(168, 175, 189, 0.6)",
"hover": "rgba(168, 175, 189, 0.3)",
"selected-hover": "rgba(168, 175, 189, 0.7)"
}
},
"publisher": {
"error": "#AA5050",
"success": "#458056",

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View file

@ -10,19 +10,7 @@ from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x00\xa0\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1c\x1f\x24\
\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\
\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\
\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\
\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x07\x30\
\x00\x00\x07\x06\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x00\x31\xac\xdc\x63\
@ -80,10 +68,10 @@ qt_resource_data = b"\
\x65\x3d\x22\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\x36\
\x2d\x32\x2e\x31\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x6f\x64\
\x69\x66\x79\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\
\x30\x30\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x65\x74\x61\x64\
\x61\x74\x61\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\
\x30\x30\x22\x3e\x0a\x20\x20\x20\x3c\x78\x6d\x70\x4d\x4d\x3a\x48\
\x69\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\
\x3a\x53\x65\x71\x3e\x0a\x20\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\
@ -94,14 +82,14 @@ qt_resource_data = b"\
\x6e\x69\x74\x79\x20\x44\x65\x73\x69\x67\x6e\x65\x72\x20\x31\x2e\
\x39\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\
\x3a\x77\x68\x65\x6e\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\x2d\x33\
\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\x30\x30\
\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\x30\x30\
\x22\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x53\x65\
\x71\x3e\x0a\x20\x20\x20\x3c\x2f\x78\x6d\x70\x4d\x4d\x3a\x48\x69\
\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x3c\x2f\x72\x64\x66\x3a\x44\
\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x3e\x0a\x20\x3c\x2f\x72\
\x64\x66\x3a\x52\x44\x46\x3e\x0a\x3c\x2f\x78\x3a\x78\x6d\x70\x6d\
\x65\x74\x61\x3e\x0a\x3c\x3f\x78\x70\x61\x63\x6b\x65\x74\x20\x65\
\x6e\x64\x3d\x22\x72\x22\x3f\x3e\x48\x8b\x5b\x5e\x00\x00\x01\x83\
\x6e\x64\x3d\x22\x72\x22\x3f\x3e\x85\x9d\x9f\x08\x00\x00\x01\x83\
\x69\x43\x43\x50\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\
\x36\x2d\x32\x2e\x31\x00\x00\x28\x91\x75\x91\xcf\x2b\x44\x51\x14\
\xc7\x3f\x66\x68\xfc\x18\x8d\x62\x61\x31\x65\x12\x16\x42\x83\x12\
@ -128,30 +116,15 @@ qt_resource_data = b"\
\xfd\xec\x73\x74\x07\xd1\x35\xf9\xaa\x4b\xd8\xd9\x85\x0e\x39\xef\
\x59\xf8\x06\x8e\xfd\x67\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x97\x49\x44\x41\x54\x18\x95\x6d\xcf\xb1\x6a\x02\x41\
\x14\x85\xe1\x6f\xb7\xb6\xd0\x27\x48\x3d\x56\x69\x03\xb1\xb4\x48\
\x3b\x6c\xa5\xf1\x39\xf6\x59\x02\x56\x42\xba\x61\x0a\x0b\x3b\x1b\
\x1b\x6b\x41\x18\x02\x29\x6d\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\
\x9f\xff\x5c\xee\xa9\x62\x2a\x13\x4c\x73\x13\x6e\x46\x26\xa6\xf2\
\x82\xae\x46\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a\x5b\x74\
\xd8\xc7\x54\xc2\x40\x9a\x63\x8f\x3f\x7c\x55\x3d\x7c\xc5\x09\x77\
\xbc\xa1\xc2\x19\x33\x2c\x72\x13\x2e\xd5\xe0\xc2\x12\x07\x5c\x51\
\x23\xe0\x23\x37\xe1\xa8\x4f\x0e\x7f\xda\x60\xd7\xaf\x9f\xb9\x09\
\xdf\x63\x05\xff\xe5\x75\x4c\x65\xf5\xcc\x1f\x0d\x33\x2c\x83\xb6\
\x06\x44\x83\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa5\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x0b\x02\x04\x6d\
\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\
\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x00\x6d\x49\x44\x41\x54\x18\x95\x75\xcf\xc1\x09\xc2\x50\
\x10\x84\xe1\xd7\x85\x07\x9b\xd0\x43\x40\xd2\x82\x78\x14\x7b\x30\
\x57\x21\x8d\x84\x60\x3f\x62\x4b\x7a\x48\xcc\x97\x83\xfb\x30\x04\
\xdf\x9c\x86\x7f\x67\x99\xdd\x84\x0d\xaa\x54\x10\x6a\x6c\x13\x1e\
\xbe\xba\xfe\x09\x35\x31\x7b\xe6\x8d\x0f\x26\x1c\x17\xa1\x53\xb0\
\x11\x87\x0c\x2f\x01\x07\xec\xb0\x0f\x3f\xe1\xbc\xae\x69\xa3\xe6\
\x85\x77\xf8\x5b\xe9\xf0\xbb\x9f\xfa\xd2\x83\x39\xdc\xa3\x5b\xf3\
\x19\x2e\xa8\x89\xb5\x30\xf7\x43\xa0\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa0\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -164,6 +137,19 @@ qt_resource_data = b"\
\x05\x73\x3e\xc0\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x4e\
\x8a\x00\x9c\x93\x22\x80\x61\x1a\x0a\x00\x00\x29\x95\x08\xaf\x88\
\xac\xba\x34\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x07\xad\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -289,6 +275,45 @@ qt_resource_data = b"\
\x5e\x78\xa2\x9e\x0e\xa7\x20\x74\x47\x39\x1d\xf6\xe1\x95\x2b\xd6\
\xb1\x44\x8e\x0e\xcb\x58\xf0\x0f\x52\x8a\x79\x18\xdc\xe2\x02\x70\
\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1d\x00\xb0\
\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa0\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -313,18 +338,26 @@ qt_resource_data = b"\
\x0d\xe6\x7c\x80\xb1\x18\x91\x05\x52\x04\xe0\x42\x08\x15\x29\x02\
\x0c\x0c\x8c\xc8\x02\x08\x95\x68\x00\x00\xac\xac\x07\x90\x4e\x65\
\x34\xac\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\x9e\
\x00\x00\x00\x45\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xde\
\x00\x00\x00\x0c\x49\x44\x41\x54\x08\x99\x63\x60\x60\x60\x00\x00\
\x00\x04\x00\x01\xa3\x0a\x15\xe3\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x00\xa5\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\
\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\
\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x0b\x02\x04\x6d\
\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\
\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x00\xa5\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -341,15 +374,170 @@ qt_resource_data = b"\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1f\x20\xb9\
\x8d\x77\xe9\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xe6\x7c\x60\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x48\x11\x40\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x23\xed\x08\xaf\x64\x9f\x0f\x15\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa5\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x0b\x02\x04\x6d\
\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\
\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x07\x30\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x00\x31\xac\xdc\x63\
\x00\x00\x04\xb0\x69\x54\x58\x74\x58\x4d\x4c\x3a\x63\x6f\x6d\x2e\
\x61\x64\x6f\x62\x65\x2e\x78\x6d\x70\x00\x00\x00\x00\x00\x3c\x3f\
\x78\x70\x61\x63\x6b\x65\x74\x20\x62\x65\x67\x69\x6e\x3d\x22\xef\
\xbb\xbf\x22\x20\x69\x64\x3d\x22\x57\x35\x4d\x30\x4d\x70\x43\x65\
\x68\x69\x48\x7a\x72\x65\x53\x7a\x4e\x54\x63\x7a\x6b\x63\x39\x64\
\x22\x3f\x3e\x0a\x3c\x78\x3a\x78\x6d\x70\x6d\x65\x74\x61\x20\x78\
\x6d\x6c\x6e\x73\x3a\x78\x3d\x22\x61\x64\x6f\x62\x65\x3a\x6e\x73\
\x3a\x6d\x65\x74\x61\x2f\x22\x20\x78\x3a\x78\x6d\x70\x74\x6b\x3d\
\x22\x58\x4d\x50\x20\x43\x6f\x72\x65\x20\x35\x2e\x35\x2e\x30\x22\
\x3e\x0a\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x20\x78\x6d\x6c\x6e\
\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\
\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\
\x73\x23\x22\x3e\x0a\x20\x20\x3c\x72\x64\x66\x3a\x44\x65\x73\x63\
\x72\x69\x70\x74\x69\x6f\x6e\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\
\x74\x3d\x22\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x65\
\x78\x69\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\x73\x2e\x61\
\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x65\x78\x69\x66\x2f\x31\x2e\
\x30\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x74\x69\
\x66\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\x73\x2e\x61\x64\
\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x74\x69\x66\x66\x2f\x31\x2e\x30\
\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x70\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\
\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x70\x68\x6f\x74\
\x6f\x73\x68\x6f\x70\x2f\x31\x2e\x30\x2f\x22\x0a\x20\x20\x20\x20\
\x78\x6d\x6c\x6e\x73\x3a\x78\x6d\x70\x3d\x22\x68\x74\x74\x70\x3a\
\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\
\x61\x70\x2f\x31\x2e\x30\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\
\x6e\x73\x3a\x78\x6d\x70\x4d\x4d\x3d\x22\x68\x74\x74\x70\x3a\x2f\
\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\x61\
\x70\x2f\x31\x2e\x30\x2f\x6d\x6d\x2f\x22\x0a\x20\x20\x20\x20\x78\
\x6d\x6c\x6e\x73\x3a\x73\x74\x45\x76\x74\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\
\x78\x61\x70\x2f\x31\x2e\x30\x2f\x73\x54\x79\x70\x65\x2f\x52\x65\
\x73\x6f\x75\x72\x63\x65\x45\x76\x65\x6e\x74\x23\x22\x0a\x20\x20\
\x20\x65\x78\x69\x66\x3a\x50\x69\x78\x65\x6c\x58\x44\x69\x6d\x65\
\x6e\x73\x69\x6f\x6e\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x65\x78\
\x69\x66\x3a\x50\x69\x78\x65\x6c\x59\x44\x69\x6d\x65\x6e\x73\x69\
\x6f\x6e\x3d\x22\x37\x22\x0a\x20\x20\x20\x65\x78\x69\x66\x3a\x43\
\x6f\x6c\x6f\x72\x53\x70\x61\x63\x65\x3d\x22\x31\x22\x0a\x20\x20\
\x20\x74\x69\x66\x66\x3a\x49\x6d\x61\x67\x65\x57\x69\x64\x74\x68\
\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x74\x69\x66\x66\x3a\x49\x6d\
\x61\x67\x65\x4c\x65\x6e\x67\x74\x68\x3d\x22\x37\x22\x0a\x20\x20\
\x20\x74\x69\x66\x66\x3a\x52\x65\x73\x6f\x6c\x75\x74\x69\x6f\x6e\
\x55\x6e\x69\x74\x3d\x22\x32\x22\x0a\x20\x20\x20\x74\x69\x66\x66\
\x3a\x58\x52\x65\x73\x6f\x6c\x75\x74\x69\x6f\x6e\x3d\x22\x37\x32\
\x2e\x30\x22\x0a\x20\x20\x20\x74\x69\x66\x66\x3a\x59\x52\x65\x73\
\x6f\x6c\x75\x74\x69\x6f\x6e\x3d\x22\x37\x32\x2e\x30\x22\x0a\x20\
\x20\x20\x70\x68\x6f\x74\x6f\x73\x68\x6f\x70\x3a\x43\x6f\x6c\x6f\
\x72\x4d\x6f\x64\x65\x3d\x22\x33\x22\x0a\x20\x20\x20\x70\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x3a\x49\x43\x43\x50\x72\x6f\x66\x69\x6c\
\x65\x3d\x22\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\x36\
\x2d\x32\x2e\x31\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x6f\x64\
\x69\x66\x79\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\
\x30\x30\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x65\x74\x61\x64\
\x61\x74\x61\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\
\x30\x30\x22\x3e\x0a\x20\x20\x20\x3c\x78\x6d\x70\x4d\x4d\x3a\x48\
\x69\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\
\x3a\x53\x65\x71\x3e\x0a\x20\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\
\x6c\x69\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\x3a\x61\
\x63\x74\x69\x6f\x6e\x3d\x22\x70\x72\x6f\x64\x75\x63\x65\x64\x22\
\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\x3a\x73\x6f\x66\
\x74\x77\x61\x72\x65\x41\x67\x65\x6e\x74\x3d\x22\x41\x66\x66\x69\
\x6e\x69\x74\x79\x20\x44\x65\x73\x69\x67\x6e\x65\x72\x20\x31\x2e\
\x39\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\
\x3a\x77\x68\x65\x6e\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\x2d\x33\
\x31\x54\x31\x32\x3a\x33\x33\x3a\x31\x34\x2b\x30\x32\x3a\x30\x30\
\x22\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x53\x65\
\x71\x3e\x0a\x20\x20\x20\x3c\x2f\x78\x6d\x70\x4d\x4d\x3a\x48\x69\
\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x3c\x2f\x72\x64\x66\x3a\x44\
\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x3e\x0a\x20\x3c\x2f\x72\
\x64\x66\x3a\x52\x44\x46\x3e\x0a\x3c\x2f\x78\x3a\x78\x6d\x70\x6d\
\x65\x74\x61\x3e\x0a\x3c\x3f\x78\x70\x61\x63\x6b\x65\x74\x20\x65\
\x6e\x64\x3d\x22\x72\x22\x3f\x3e\x48\x8b\x5b\x5e\x00\x00\x01\x83\
\x69\x43\x43\x50\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\
\x36\x2d\x32\x2e\x31\x00\x00\x28\x91\x75\x91\xcf\x2b\x44\x51\x14\
\xc7\x3f\x66\x68\xfc\x18\x8d\x62\x61\x31\x65\x12\x16\x42\x83\x12\
\x1b\x8b\x99\x18\x0a\x8b\x99\x51\x7e\x6d\x66\x9e\x79\x33\x6a\xde\
\x78\xbd\x37\xd2\x64\xab\x6c\xa7\x28\xb1\xf1\x6b\xc1\x5f\xc0\x56\
\x59\x2b\x45\xa4\x64\xa7\xac\x89\x0d\x7a\xce\x9b\x51\x23\x99\x73\
\x3b\xf7\x7c\xee\xf7\xde\x73\xba\xf7\x5c\x70\x44\xd3\x8a\x66\x56\
\xfa\x41\xcb\x64\x8d\x70\x28\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\
\x85\x1a\x3a\xf1\xc6\x14\x53\x9f\x8c\x8c\x46\x29\x6b\xef\xb7\x54\
\xd8\xf1\xba\xdb\xae\x55\xfe\xdc\xbf\x56\xb7\x98\x30\x15\xa8\xa8\
\x16\x1e\x56\x74\x23\x2b\x3c\x26\x3c\xb1\x9a\xd5\x6d\xde\x12\x6e\
\x52\x52\xb1\x45\xe1\x13\xe1\x2e\x43\x2e\x28\x7c\x63\xeb\xf1\x22\
\x3f\xdb\x9c\x2c\xf2\xa7\xcd\x46\x34\x1c\x04\x47\x83\xb0\x2f\xf9\
\x8b\xe3\xbf\x58\x49\x19\x9a\xb0\xbc\x9c\x36\x2d\xbd\xa2\xfc\xdc\
\xc7\x7e\x89\x3b\x91\x99\x8e\x48\x6c\x15\xf7\x62\x12\x26\x44\x00\
\x1f\xe3\x8c\x10\x64\x80\x5e\x86\x64\x1e\xa0\x9b\x3e\x7a\x64\x45\
\x99\x7c\x7f\x21\x7f\x8a\x65\xc9\x55\x64\xd6\xc9\x61\xb0\x44\x92\
\x14\x59\xba\x44\x5d\x91\xea\x09\x89\xaa\xe8\x09\x19\x69\x72\x76\
\xff\xff\xf6\xd5\x54\xfb\xfb\x8a\xd5\xdd\x01\xa8\x7a\xb4\xac\xd7\
\x76\x70\x6d\xc2\x57\xde\xb2\x3e\x0e\x2c\xeb\xeb\x10\x9c\x0f\x70\
\x9e\x29\xe5\x2f\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9e\x75\
\x38\xbd\x28\x69\xf1\x6d\x38\xdb\x80\xe6\x7b\x3d\x66\xc4\x0a\x92\
\x53\xdc\xa1\xaa\xf0\x72\x0c\xf5\xb3\xd0\x78\x05\xb5\xf3\xc5\x9e\
\xfd\xec\x73\x74\x07\xd1\x35\xf9\xaa\x4b\xd8\xd9\x85\x0e\x39\xef\
\x59\xf8\x06\x8e\xfd\x67\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x97\x49\x44\x41\x54\x18\x95\x6d\xcf\xb1\x6a\x02\x41\
\x14\x85\xe1\x6f\xb7\xb6\xd0\x27\x48\x3d\x56\x69\x03\xb1\xb4\x48\
\x3b\x6c\xa5\xf1\x39\xf6\x59\x02\x56\x42\xba\x61\x0a\x0b\x3b\x1b\
\x1b\x6b\x41\x18\x02\x29\x6d\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\
\x9f\xff\x5c\xee\xa9\x62\x2a\x13\x4c\x73\x13\x6e\x46\x26\xa6\xf2\
\x82\xae\x46\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a\x5b\x74\
\xd8\xc7\x54\xc2\x40\x9a\x63\x8f\x3f\x7c\x55\x3d\x7c\xc5\x09\x77\
\xbc\xa1\xc2\x19\x33\x2c\x72\x13\x2e\xd5\xe0\xc2\x12\x07\x5c\x51\
\x23\xe0\x23\x37\xe1\xa8\x4f\x0e\x7f\xda\x60\xd7\xaf\x9f\xb9\x09\
\xdf\x63\x05\xff\xe5\x75\x4c\x65\xf5\xcc\x1f\x0d\x33\x2c\x83\xb6\
\x06\x44\x83\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa0\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1c\x1f\x24\
\xc6\x09\x17\x00\x00\x00\x24\x49\x44\x41\x54\x08\xd7\x63\x60\x40\
\x05\xff\xcf\xc3\x58\x4c\xc8\x5c\x26\x64\x59\x26\x64\xc5\x70\x0e\
\xa3\x21\x9c\xc3\x68\x88\x61\x1a\x0a\x00\x00\x6d\x84\x09\x75\x37\
\x9e\xd9\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1d\x00\xb0\
\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x07\xdd\
\x89\
@ -479,45 +667,6 @@ qt_resource_data = b"\
\x71\x5b\x73\x5c\x40\x48\xa5\xdd\x61\x81\x0d\x9e\x6b\x8e\xff\xfd\
\xcf\x3f\xcc\x31\xe9\x01\x1c\x00\x73\x52\x2d\x71\xe4\x4a\x1b\x69\
\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa5\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\x9c\x53\x34\xfc\x5d\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x0b\x02\x04\x6d\
\x98\x1b\x69\x00\x00\x00\x29\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18\x32\x32\x30\x20\x0b\x32\x1a\
\x32\x30\x30\x42\x98\x10\x41\x46\x43\x14\x13\x50\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2\x2f\x48\xdf\x4a\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1f\x20\xb9\
\x8d\x77\xe9\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xe6\x7c\x60\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x48\x11\x40\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x23\xed\x08\xaf\x64\x9f\x0f\x15\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\x9e\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -530,160 +679,18 @@ qt_resource_data = b"\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\
\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\
\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x00\x00\x00\x9e\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce\x7c\x4e\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x3b\xdc\
\x3b\x0c\x9b\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x00\x8c\x0c\x0c\x73\x3e\x20\x0b\xa4\x08\x30\x32\x30\x20\x0b\xa6\
\x08\x30\x30\x30\x42\x98\x10\xc1\x14\x01\x14\x13\x50\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90\x5d\x66\x1f\x83\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1d\x00\xb0\
\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\xa6\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x14\x1d\x00\xb0\
\xd5\x35\xa3\x00\x00\x00\x2a\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x06\xfe\x9f\x67\x60\x60\x42\x30\xa1\x1c\x08\x93\x81\x81\x09\xc1\
\x64\x60\x60\x62\x60\x60\x34\x44\xe2\x20\x73\x19\x90\x8d\x40\x02\
\x00\x64\x40\x09\x75\x86\xb3\xad\x9c\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x07\x06\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x00\x31\xac\xdc\x63\
\x00\x00\x04\xb0\x69\x54\x58\x74\x58\x4d\x4c\x3a\x63\x6f\x6d\x2e\
\x61\x64\x6f\x62\x65\x2e\x78\x6d\x70\x00\x00\x00\x00\x00\x3c\x3f\
\x78\x70\x61\x63\x6b\x65\x74\x20\x62\x65\x67\x69\x6e\x3d\x22\xef\
\xbb\xbf\x22\x20\x69\x64\x3d\x22\x57\x35\x4d\x30\x4d\x70\x43\x65\
\x68\x69\x48\x7a\x72\x65\x53\x7a\x4e\x54\x63\x7a\x6b\x63\x39\x64\
\x22\x3f\x3e\x0a\x3c\x78\x3a\x78\x6d\x70\x6d\x65\x74\x61\x20\x78\
\x6d\x6c\x6e\x73\x3a\x78\x3d\x22\x61\x64\x6f\x62\x65\x3a\x6e\x73\
\x3a\x6d\x65\x74\x61\x2f\x22\x20\x78\x3a\x78\x6d\x70\x74\x6b\x3d\
\x22\x58\x4d\x50\x20\x43\x6f\x72\x65\x20\x35\x2e\x35\x2e\x30\x22\
\x3e\x0a\x20\x3c\x72\x64\x66\x3a\x52\x44\x46\x20\x78\x6d\x6c\x6e\
\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\
\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\
\x73\x23\x22\x3e\x0a\x20\x20\x3c\x72\x64\x66\x3a\x44\x65\x73\x63\
\x72\x69\x70\x74\x69\x6f\x6e\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\
\x74\x3d\x22\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x65\
\x78\x69\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\x73\x2e\x61\
\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x65\x78\x69\x66\x2f\x31\x2e\
\x30\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x74\x69\
\x66\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\x73\x2e\x61\x64\
\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x74\x69\x66\x66\x2f\x31\x2e\x30\
\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x70\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x6e\
\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x70\x68\x6f\x74\
\x6f\x73\x68\x6f\x70\x2f\x31\x2e\x30\x2f\x22\x0a\x20\x20\x20\x20\
\x78\x6d\x6c\x6e\x73\x3a\x78\x6d\x70\x3d\x22\x68\x74\x74\x70\x3a\
\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\
\x61\x70\x2f\x31\x2e\x30\x2f\x22\x0a\x20\x20\x20\x20\x78\x6d\x6c\
\x6e\x73\x3a\x78\x6d\x70\x4d\x4d\x3d\x22\x68\x74\x74\x70\x3a\x2f\
\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\x78\x61\
\x70\x2f\x31\x2e\x30\x2f\x6d\x6d\x2f\x22\x0a\x20\x20\x20\x20\x78\
\x6d\x6c\x6e\x73\x3a\x73\x74\x45\x76\x74\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x6e\x73\x2e\x61\x64\x6f\x62\x65\x2e\x63\x6f\x6d\x2f\
\x78\x61\x70\x2f\x31\x2e\x30\x2f\x73\x54\x79\x70\x65\x2f\x52\x65\
\x73\x6f\x75\x72\x63\x65\x45\x76\x65\x6e\x74\x23\x22\x0a\x20\x20\
\x20\x65\x78\x69\x66\x3a\x50\x69\x78\x65\x6c\x58\x44\x69\x6d\x65\
\x6e\x73\x69\x6f\x6e\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x65\x78\
\x69\x66\x3a\x50\x69\x78\x65\x6c\x59\x44\x69\x6d\x65\x6e\x73\x69\
\x6f\x6e\x3d\x22\x37\x22\x0a\x20\x20\x20\x65\x78\x69\x66\x3a\x43\
\x6f\x6c\x6f\x72\x53\x70\x61\x63\x65\x3d\x22\x31\x22\x0a\x20\x20\
\x20\x74\x69\x66\x66\x3a\x49\x6d\x61\x67\x65\x57\x69\x64\x74\x68\
\x3d\x22\x31\x30\x22\x0a\x20\x20\x20\x74\x69\x66\x66\x3a\x49\x6d\
\x61\x67\x65\x4c\x65\x6e\x67\x74\x68\x3d\x22\x37\x22\x0a\x20\x20\
\x20\x74\x69\x66\x66\x3a\x52\x65\x73\x6f\x6c\x75\x74\x69\x6f\x6e\
\x55\x6e\x69\x74\x3d\x22\x32\x22\x0a\x20\x20\x20\x74\x69\x66\x66\
\x3a\x58\x52\x65\x73\x6f\x6c\x75\x74\x69\x6f\x6e\x3d\x22\x37\x32\
\x2e\x30\x22\x0a\x20\x20\x20\x74\x69\x66\x66\x3a\x59\x52\x65\x73\
\x6f\x6c\x75\x74\x69\x6f\x6e\x3d\x22\x37\x32\x2e\x30\x22\x0a\x20\
\x20\x20\x70\x68\x6f\x74\x6f\x73\x68\x6f\x70\x3a\x43\x6f\x6c\x6f\
\x72\x4d\x6f\x64\x65\x3d\x22\x33\x22\x0a\x20\x20\x20\x70\x68\x6f\
\x74\x6f\x73\x68\x6f\x70\x3a\x49\x43\x43\x50\x72\x6f\x66\x69\x6c\
\x65\x3d\x22\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\x36\
\x2d\x32\x2e\x31\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x6f\x64\
\x69\x66\x79\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\
\x30\x30\x22\x0a\x20\x20\x20\x78\x6d\x70\x3a\x4d\x65\x74\x61\x64\
\x61\x74\x61\x44\x61\x74\x65\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\
\x2d\x33\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\
\x30\x30\x22\x3e\x0a\x20\x20\x20\x3c\x78\x6d\x70\x4d\x4d\x3a\x48\
\x69\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x20\x20\x3c\x72\x64\x66\
\x3a\x53\x65\x71\x3e\x0a\x20\x20\x20\x20\x20\x3c\x72\x64\x66\x3a\
\x6c\x69\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\x3a\x61\
\x63\x74\x69\x6f\x6e\x3d\x22\x70\x72\x6f\x64\x75\x63\x65\x64\x22\
\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\x3a\x73\x6f\x66\
\x74\x77\x61\x72\x65\x41\x67\x65\x6e\x74\x3d\x22\x41\x66\x66\x69\
\x6e\x69\x74\x79\x20\x44\x65\x73\x69\x67\x6e\x65\x72\x20\x31\x2e\
\x39\x2e\x32\x22\x0a\x20\x20\x20\x20\x20\x20\x73\x74\x45\x76\x74\
\x3a\x77\x68\x65\x6e\x3d\x22\x32\x30\x32\x31\x2d\x30\x35\x2d\x33\
\x31\x54\x31\x32\x3a\x33\x30\x3a\x31\x31\x2b\x30\x32\x3a\x30\x30\
\x22\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x72\x64\x66\x3a\x53\x65\
\x71\x3e\x0a\x20\x20\x20\x3c\x2f\x78\x6d\x70\x4d\x4d\x3a\x48\x69\
\x73\x74\x6f\x72\x79\x3e\x0a\x20\x20\x3c\x2f\x72\x64\x66\x3a\x44\
\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e\x3e\x0a\x20\x3c\x2f\x72\
\x64\x66\x3a\x52\x44\x46\x3e\x0a\x3c\x2f\x78\x3a\x78\x6d\x70\x6d\
\x65\x74\x61\x3e\x0a\x3c\x3f\x78\x70\x61\x63\x6b\x65\x74\x20\x65\
\x6e\x64\x3d\x22\x72\x22\x3f\x3e\x85\x9d\x9f\x08\x00\x00\x01\x83\
\x69\x43\x43\x50\x73\x52\x47\x42\x20\x49\x45\x43\x36\x31\x39\x36\
\x36\x2d\x32\x2e\x31\x00\x00\x28\x91\x75\x91\xcf\x2b\x44\x51\x14\
\xc7\x3f\x66\x68\xfc\x18\x8d\x62\x61\x31\x65\x12\x16\x42\x83\x12\
\x1b\x8b\x99\x18\x0a\x8b\x99\x51\x7e\x6d\x66\x9e\x79\x33\x6a\xde\
\x78\xbd\x37\xd2\x64\xab\x6c\xa7\x28\xb1\xf1\x6b\xc1\x5f\xc0\x56\
\x59\x2b\x45\xa4\x64\xa7\xac\x89\x0d\x7a\xce\x9b\x51\x23\x99\x73\
\x3b\xf7\x7c\xee\xf7\xde\x73\xba\xf7\x5c\x70\x44\xd3\x8a\x66\x56\
\xfa\x41\xcb\x64\x8d\x70\x28\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\
\x85\x1a\x3a\xf1\xc6\x14\x53\x9f\x8c\x8c\x46\x29\x6b\xef\xb7\x54\
\xd8\xf1\xba\xdb\xae\x55\xfe\xdc\xbf\x56\xb7\x98\x30\x15\xa8\xa8\
\x16\x1e\x56\x74\x23\x2b\x3c\x26\x3c\xb1\x9a\xd5\x6d\xde\x12\x6e\
\x52\x52\xb1\x45\xe1\x13\xe1\x2e\x43\x2e\x28\x7c\x63\xeb\xf1\x22\
\x3f\xdb\x9c\x2c\xf2\xa7\xcd\x46\x34\x1c\x04\x47\x83\xb0\x2f\xf9\
\x8b\xe3\xbf\x58\x49\x19\x9a\xb0\xbc\x9c\x36\x2d\xbd\xa2\xfc\xdc\
\xc7\x7e\x89\x3b\x91\x99\x8e\x48\x6c\x15\xf7\x62\x12\x26\x44\x00\
\x1f\xe3\x8c\x10\x64\x80\x5e\x86\x64\x1e\xa0\x9b\x3e\x7a\x64\x45\
\x99\x7c\x7f\x21\x7f\x8a\x65\xc9\x55\x64\xd6\xc9\x61\xb0\x44\x92\
\x14\x59\xba\x44\x5d\x91\xea\x09\x89\xaa\xe8\x09\x19\x69\x72\x76\
\xff\xff\xf6\xd5\x54\xfb\xfb\x8a\xd5\xdd\x01\xa8\x7a\xb4\xac\xd7\
\x76\x70\x6d\xc2\x57\xde\xb2\x3e\x0e\x2c\xeb\xeb\x10\x9c\x0f\x70\
\x9e\x29\xe5\x2f\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9e\x75\
\x38\xbd\x28\x69\xf1\x6d\x38\xdb\x80\xe6\x7b\x3d\x66\xc4\x0a\x92\
\x53\xdc\xa1\xaa\xf0\x72\x0c\xf5\xb3\xd0\x78\x05\xb5\xf3\xc5\x9e\
\xfd\xec\x73\x74\x07\xd1\x35\xf9\xaa\x4b\xd8\xd9\x85\x0e\x39\xef\
\x59\xf8\x06\x8e\xfd\x67\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09\x70\
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x6d\x49\x44\x41\x54\x18\x95\x75\xcf\xc1\x09\xc2\x50\
\x10\x84\xe1\xd7\x85\x07\x9b\xd0\x43\x40\xd2\x82\x78\x14\x7b\x30\
\x57\x21\x8d\x84\x60\x3f\x62\x4b\x7a\x48\xcc\x97\x83\xfb\x30\x04\
\xdf\x9c\x86\x7f\x67\x99\xdd\x84\x0d\xaa\x54\x10\x6a\x6c\x13\x1e\
\xbe\xba\xfe\x09\x35\x31\x7b\xe6\x8d\x0f\x26\x1c\x17\xa1\x53\xb0\
\x11\x87\x0c\x2f\x01\x07\xec\xb0\x0f\x3f\xe1\xbc\xae\x69\xa3\xe6\
\x85\x77\xf8\x5b\xe9\xf0\xbb\x9f\xfa\xd2\x83\x39\xdc\xa3\x5b\xf3\
\x19\x2e\xa8\x89\xb5\x30\xf7\x43\xa0\x00\x00\x00\x00\x49\x45\x4e\
\x44\xae\x42\x60\x82\
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8\x2e\x00\x00\x00\x22\x49\x44\x41\x54\x08\xd7\x63\x60\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1\x42\x48\x2a\x0c\x19\
\x18\x18\x91\x05\x10\x2a\xd1\x00\x00\xca\xb5\x07\xd2\x76\xbb\xb2\
\xc5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
"
qt_resource_name = b"\
@ -696,119 +703,124 @@ qt_resource_name = b"\
\x00\x69\
\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
\x00\x0f\
\x02\x9f\x05\x87\
\x00\x72\
\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x12\
\x05\x8f\x9d\x07\
\x06\x53\x25\xa7\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x1b\
\x03\x5a\x32\x27\
\x00\x63\
\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\
\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x18\
\x03\x8e\xde\x67\
\x00\x72\
\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\
\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x11\
\x0b\xda\x30\xa7\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\
\x00\x12\
\x03\x8d\x04\x47\
\x00\x72\
\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x15\
\x0f\xf3\xc0\x07\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\
\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0f\
\x01\x73\x8b\x07\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0e\
\x04\xa2\xfc\xa7\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x12\
\x01\x2e\x03\x27\
\x00\x63\
\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x14\
\x04\x5e\x2d\xa7\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x5f\x00\x6f\x00\x6e\x00\x2e\
\x00\x70\x00\x6e\x00\x67\
\x00\x17\
\x0c\xab\x51\x07\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\
\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x11\
\x01\x1f\xc3\x87\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\
\x00\x17\
\x0c\x65\xce\x07\
\x00\x6c\
\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\
\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0c\
\x06\xe6\xe6\x67\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x15\
\x03\x27\x72\x67\
\x00\x63\
\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\
\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x11\
\x0b\xda\x30\xa7\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\
\x00\x17\
\x0c\xab\x51\x07\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\
\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x11\
\x00\xb8\x8c\x07\
\x00\x6c\
\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\
\x00\x12\
\x01\x2e\x03\x27\
\x00\x63\
\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x0f\
\x02\x9f\x05\x87\
\x00\x72\
\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x15\
\x0f\xf3\xc0\x07\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\
\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0f\
\x0c\xe2\x68\x67\
\x00\x74\
\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x70\x00\x61\x00\x72\x00\x65\x00\x6e\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0e\
\x04\xa2\xfc\xa7\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x1b\
\x03\x5a\x32\x27\
\x00\x63\
\x00\x6f\x00\x6d\x00\x62\x00\x6f\x00\x62\x00\x6f\x00\x78\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\
\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x17\
\x0c\x65\xce\x07\
\x00\x6c\
\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x64\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\
\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x11\
\x01\x1f\xc3\x87\
\x00\x64\
\x00\x6f\x00\x77\x00\x6e\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\
\x00\x12\
\x05\x8f\x9d\x07\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x12\
\x03\x8d\x04\x47\
\x00\x72\
\x00\x69\x00\x67\x00\x68\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\
\x00\x67\
\x00\x0e\
\x0e\xde\xfa\xc7\
\x00\x6c\
\x00\x65\x00\x66\x00\x74\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0f\
\x06\x53\x25\xa7\
\x00\x14\
\x04\x5e\x2d\xa7\
\x00\x62\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x6f\x00\x70\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x72\x00\x61\x00\x6e\x00\x63\x00\x68\x00\x5f\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x5f\x00\x6f\x00\x6e\x00\x2e\
\x00\x70\x00\x6e\x00\x67\
\x00\x0c\
\x06\xe6\xe6\x67\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0f\
\x01\x73\x8b\x07\
\x00\x75\
\x00\x70\x00\x5f\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x16\x00\x02\x00\x00\x00\x13\x00\x00\x00\x03\
\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x3c\
\x00\x00\x02\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x9d\
\x00\x00\x01\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x13\x68\
\x00\x00\x01\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x12\x1d\
\x00\x00\x00\x16\x00\x02\x00\x00\x00\x14\x00\x00\x00\x03\
\x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x10\xb3\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x15\x93\
\x00\x00\x01\x36\x00\x00\x00\x00\x00\x01\x00\x00\x11\x5d\
\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x27\x41\
\x00\x00\x01\x60\x00\x00\x00\x00\x00\x01\x00\x00\x12\x07\
\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x07\xae\
\x00\x00\x01\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x14\x40\
\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x70\
\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x07\x0a\
\x00\x00\x03\x08\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xbe\
\x00\x00\x01\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x13\x97\
\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x00\x16\x3c\
\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x92\
\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x07\xd8\
\x00\x00\x01\x10\x00\x00\x00\x00\x00\x01\x00\x00\x10\xd6\
\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x08\x81\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x00\x14\x12\
\x00\x00\x01\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x12\xbf\
\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x00\xa4\
\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x20\x90\
\x00\x00\x02\x98\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xf0\
\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x09\x25\
\x00\x00\x02\x64\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x46\
\x00\x00\x02\x08\x00\x00\x00\x00\x00\x01\x00\x00\x1b\xf3\
\x00\x00\x03\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xe6\
\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x11\x7a\
\x00\x00\x03\x36\x00\x00\x00\x00\x00\x01\x00\x00\x26\x9f\
\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x08\x58\
\x00\x00\x02\x36\x00\x00\x00\x00\x00\x01\x00\x00\x14\xe9\
\x00\x00\x00\xda\x00\x00\x00\x00\x00\x01\x00\x00\x10\x09\
\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x13\x4e\
\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x14\
\x00\x00\x01\x84\x00\x00\x00\x00\x00\x01\x00\x00\x12\xab\
"
qt_resource_struct_v2 = b"\
@ -816,49 +828,50 @@ qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x16\x00\x02\x00\x00\x00\x13\x00\x00\x00\x03\
\x00\x00\x00\x16\x00\x02\x00\x00\x00\x14\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x3c\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x02\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x9d\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x01\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x13\x68\
\x00\x00\x01\x79\xb4\x72\xcc\x9c\
\x00\x00\x01\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x12\x1d\
\x00\x00\x01\x76\x41\x9d\xa2\x39\
\x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x10\xb3\
\x00\x00\x01\x79\xec\x37\x3f\xbc\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x15\x93\
\x00\x00\x01\x79\xec\x37\x3f\xba\
\x00\x00\x01\x36\x00\x00\x00\x00\x00\x01\x00\x00\x11\x5d\
\x00\x00\x01\x79\xec\x37\x3f\xb6\
\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x27\x41\
\x00\x00\x01\x79\xec\x37\x3f\xc0\
\x00\x00\x01\x60\x00\x00\x00\x00\x00\x01\x00\x00\x12\x07\
\x00\x00\x01\x79\xec\x37\x3f\xbc\
\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x07\xae\
\x00\x00\x01\x79\xec\x37\x3f\xb7\
\x00\x00\x01\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x14\x40\
\x00\x00\x01\x79\xec\x37\x3f\xb7\
\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x70\
\x00\x00\x01\x79\xec\x37\x3f\xbe\
\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x07\x0a\
\x00\x00\x01\x79\xec\x37\x3f\xbd\
\x00\x00\x03\x08\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xbe\
\x00\x00\x01\x79\xec\x37\x3f\xb4\
\x00\x00\x01\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x13\x97\
\x00\x00\x01\x79\xec\x37\x3f\xb8\
\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x00\x16\x3c\
\x00\x00\x01\x79\xec\x37\x3f\xb5\
\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x76\x41\x9d\xa2\x37\
\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x92\
\x00\x00\x01\x79\xb4\x72\xcc\x9c\
\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x07\xd8\
\x00\x00\x01\x79\xb4\x72\xcc\x9c\
\x00\x00\x01\x10\x00\x00\x00\x00\x00\x01\x00\x00\x10\xd6\
\x00\x00\x01\x76\x41\x9d\xa2\x37\
\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x08\x81\
\x00\x00\x01\x76\x41\x9d\xa2\x37\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x00\x14\x12\
\x00\x00\x01\x79\xc2\x05\x2b\x60\
\x00\x00\x01\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x12\xbf\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x00\xa4\
\x00\x00\x01\x79\xc1\xfc\x16\x91\
\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x20\x90\
\x00\x00\x01\x79\xc1\xf9\x4b\x78\
\x00\x00\x02\x98\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xf0\
\x00\x00\x01\x76\x41\x9d\xa2\x39\
\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x09\x25\
\x00\x00\x01\x79\xc2\x05\x91\x2a\
\x00\x00\x02\x64\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x46\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x02\x08\x00\x00\x00\x00\x00\x01\x00\x00\x1b\xf3\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x03\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xe6\
\x00\x00\x01\x76\x41\x9d\xa2\x35\
\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x11\x7a\
\x00\x00\x01\x76\x41\x9d\xa2\x39\
\x00\x00\x01\x79\xec\x37\x3f\xb5\
\x00\x00\x03\x36\x00\x00\x00\x00\x00\x01\x00\x00\x26\x9f\
\x00\x00\x01\x79\xec\x37\x3f\xbe\
\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x08\x58\
\x00\x00\x01\x79\xec\x37\x3f\xb3\
\x00\x00\x02\x36\x00\x00\x00\x00\x00\x01\x00\x00\x14\xe9\
\x00\x00\x01\x79\xec\x37\x3f\xbb\
\x00\x00\x00\xda\x00\x00\x00\x00\x00\x01\x00\x00\x10\x09\
\x00\x00\x01\x79\xec\x37\x3f\xb9\
\x00\x00\x01\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x13\x4e\
\x00\x00\x01\x7c\xa7\x41\xfc\x00\
\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x14\
\x00\x00\x01\x79\xec\x37\x3f\xbb\
\x00\x00\x01\x84\x00\x00\x00\x00\x00\x01\x00\x00\x12\xab\
\x00\x00\x01\x79\xec\x37\x3f\xbf\
"
qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
rcc_version = 1

View file

@ -1,75 +1,15 @@
# Resource object code (Python 3)
# Created by: object code
# Created by: The Resource Compiler for Qt version 5.15.2
# -*- coding: utf-8 -*-
# Resource object code
#
# Created: Fri Oct 22 11:42:52 2021
# by: The Resource Compiler for PySide2 (Qt v5.6.1)
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore
qt_resource_data = b"\
\x00\x00\x00\x9f\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x14\x1f\xf9\
#\xd9\x0b\x00\x00\x00#IDAT\x08\xd7c`\xc0\
\x0d\xe6|\x80\xb1\x18\x91\x05R\x04\xe0B\x08\x15)\x02\
\x0c\x0c\x8c\xc8\x02\x08\x95h\x00\x00\xac\xac\x07\x90Ne\
4\xac\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f\x0d\xfc\
R+\x9c\x00\x00\x00$IDAT\x08\xd7c`@\
\x05s>\xc0XL\xc8\x5c&dY&d\xc5pN\
\x8a\x00\x9c\x93\x22\x80a\x1a\x0a\x00\x00)\x95\x08\xaf\x88\
\xac\xba4\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@ -83,31 +23,33 @@ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
d``b``4D\xe2 s\x19\x90\x8d@\x02\
\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\x9e\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\
\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\
\xc5\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\x9e\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\
\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\
\xc5\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x07\x06\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x070\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\
@ -165,10 +107,10 @@ toshop:ICCProfil\
e=\x22sRGB IEC61966\
-2.1\x22\x0a xmp:Mod\
ifyDate=\x222021-05\
-31T12:30:11+02:\
-31T12:33:14+02:\
00\x22\x0a xmp:Metad\
ataDate=\x222021-05\
-31T12:30:11+02:\
-31T12:33:14+02:\
00\x22>\x0a <xmpMM:H\
istory>\x0a <rdf\
:Seq>\x0a <rdf:\
@ -179,14 +121,14 @@ twareAgent=\x22Affi\
nity Designer 1.\
9.2\x22\x0a stEvt\
:when=\x222021-05-3\
1T12:30:11+02:00\
1T12:33:14+02:00\
\x22/>\x0a </rdf:Se\
q>\x0a </xmpMM:Hi\
story>\x0a </rdf:D\
escription>\x0a </r\
df:RDF>\x0a</x:xmpm\
eta>\x0a<?xpacket e\
nd=\x22r\x22?>\x85\x9d\x9f\x08\x00\x00\x01\x83\
nd=\x22r\x22?>H\x8b[^\x00\x00\x01\x83\
iCCPsRGB IEC6196\
6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\
\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\
@ -213,28 +155,54 @@ S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\
\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\
Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00mIDAT\x18\x95u\xcf\xc1\x09\xc2P\
\x10\x84\xe1\xd7\x85\x07\x9b\xd0C@\xd2\x82x\x14{0\
W!\x8d\x84`?bKzH\xcc\x97\x83\xfb0\x04\
\xdf\x9c\x86\x7fg\x99\xdd\x84\x0d\xaaT\x10jl\x13\x1e\
\xbe\xba\xfe\x0951{\xe6\x8d\x0f&\x1c\x17\xa1S\xb0\
\x11\x87\x0c/\x01\x07\xec\xb0\x0f?\xe1\xbc\xaei\xa3\xe6\
\x85w\xf8[\xe9\xf0\xbb\x9f\xfa\xd2\x839\xdc\xa3[\xf3\
\x19.\xa8\x89\xb50\xf7C\xa0\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa6\
\x00\x00\x00\x97IDAT\x18\x95m\xcf\xb1j\x02A\
\x14\x85\xe1o\xb7\xb6\xd0'H=Vi\x03\xb1\xb4H\
;l\xa5\xf19\xf6Y\x02VB\xbaa\x0a\x0b;\x1b\
\x1bkA\x18\x02)m\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\
\x9f\xff\x5c\xee\xa9b*\x13Ls\x13nF&\xa6\xf2\
\x82\xaeF\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a[t\
\xd8\xc7T\xc2@\x9ac\x8f?|U=|\xc5\x09w\
\xbc\xa1\xc2\x193,r\x13.\xd5\xe0\xc2\x12\x07\x5cQ\
#\xe0#7\xe1\xa8O\x0e\x7f\xda`\xd7\xaf\x9f\xb9\x09\
\xdfc\x05\xff\xe5uLe\xf5\xcc\x1f\x0d3,\x83\xb6\
\x06D\x83\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f \xb9\
\x8dw\xe9\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x06\xe6|```B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\
d``b`H\x11@\xe2 s\x19\x90\x8d@\x02\
\x00#\xed\x08\xafd\x9f\x0f\x15\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\
\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\
\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\
\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\
\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\x9e\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\
\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\
\xc5\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x07\xdd\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@ -363,6 +331,221 @@ zpp\xf0\xe3\x0e.\xa4\xd2\xae\xf0\x8a\xf7\x9a\xe3V\
q[s\x5c@H\xa5\xdda\x81\x0d\x9ek\x8e\xff\xfd\
\xcf?\xcc1\xe9\x01\x1c\x00sR-q\xe4J\x1bi\
\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\x9e\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15\x0f\xfd\
\x8f\xf8.\x00\x00\x00\x22IDAT\x08\xd7c`\xc0\
\x0d\xfe\x9f\x87\xb1\x18\x91\x05\x18\x0d\xe1BH*\x0c\x19\
\x18\x18\x91\x05\x10*\xd1\x00\x00\xca\xb5\x07\xd2v\xbb\xb2\
\xc5\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f\x0d\xfc\
R+\x9c\x00\x00\x00$IDAT\x08\xd7c`@\
\x05s>\xc0XL\xc8\x5c&dY&d\xc5pN\
\x8a\x00\x9c\x93\x22\x80a\x1a\x0a\x00\x00)\x95\x08\xaf\x88\
\xac\xba4\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\x9f\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x14\x1f\xf9\
#\xd9\x0b\x00\x00\x00#IDAT\x08\xd7c`\xc0\
\x0d\xe6|\x80\xb1\x18\x91\x05R\x04\xe0B\x08\x15)\x02\
\x0c\x0c\x8c\xc8\x02\x08\x95h\x00\x00\xac\xac\x07\x90Ne\
4\xac\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x07\x06\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\
\x00\x00\x04\xb0iTXtXML:com.\
adobe.xmp\x00\x00\x00\x00\x00<?\
xpacket begin=\x22\xef\
\xbb\xbf\x22 id=\x22W5M0MpCe\
hiHzreSzNTczkc9d\
\x22?>\x0a<x:xmpmeta x\
mlns:x=\x22adobe:ns\
:meta/\x22 x:xmptk=\
\x22XMP Core 5.5.0\x22\
>\x0a <rdf:RDF xmln\
s:rdf=\x22http://ww\
w.w3.org/1999/02\
/22-rdf-syntax-n\
s#\x22>\x0a <rdf:Desc\
ription rdf:abou\
t=\x22\x22\x0a xmlns:e\
xif=\x22http://ns.a\
dobe.com/exif/1.\
0/\x22\x0a xmlns:ti\
ff=\x22http://ns.ad\
obe.com/tiff/1.0\
/\x22\x0a xmlns:pho\
toshop=\x22http://n\
s.adobe.com/phot\
oshop/1.0/\x22\x0a \
xmlns:xmp=\x22http:\
//ns.adobe.com/x\
ap/1.0/\x22\x0a xml\
ns:xmpMM=\x22http:/\
/ns.adobe.com/xa\
p/1.0/mm/\x22\x0a x\
mlns:stEvt=\x22http\
://ns.adobe.com/\
xap/1.0/sType/Re\
sourceEvent#\x22\x0a \
exif:PixelXDime\
nsion=\x2210\x22\x0a ex\
if:PixelYDimensi\
on=\x227\x22\x0a exif:C\
olorSpace=\x221\x22\x0a \
tiff:ImageWidth\
=\x2210\x22\x0a tiff:Im\
ageLength=\x227\x22\x0a \
tiff:Resolution\
Unit=\x222\x22\x0a tiff\
:XResolution=\x2272\
.0\x22\x0a tiff:YRes\
olution=\x2272.0\x22\x0a \
photoshop:Colo\
rMode=\x223\x22\x0a pho\
toshop:ICCProfil\
e=\x22sRGB IEC61966\
-2.1\x22\x0a xmp:Mod\
ifyDate=\x222021-05\
-31T12:30:11+02:\
00\x22\x0a xmp:Metad\
ataDate=\x222021-05\
-31T12:30:11+02:\
00\x22>\x0a <xmpMM:H\
istory>\x0a <rdf\
:Seq>\x0a <rdf:\
li\x0a stEvt:a\
ction=\x22produced\x22\
\x0a stEvt:sof\
twareAgent=\x22Affi\
nity Designer 1.\
9.2\x22\x0a stEvt\
:when=\x222021-05-3\
1T12:30:11+02:00\
\x22/>\x0a </rdf:Se\
q>\x0a </xmpMM:Hi\
story>\x0a </rdf:D\
escription>\x0a </r\
df:RDF>\x0a</x:xmpm\
eta>\x0a<?xpacket e\
nd=\x22r\x22?>\x85\x9d\x9f\x08\x00\x00\x01\x83\
iCCPsRGB IEC6196\
6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\
\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\
\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\
x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\
Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\
;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\
\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\
\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\
\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\
\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\
RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\
?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\
\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\
\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\
\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\
\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\
\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\
\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\
vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\
\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\
8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\
S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\
\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\
Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00mIDAT\x18\x95u\xcf\xc1\x09\xc2P\
\x10\x84\xe1\xd7\x85\x07\x9b\xd0C@\xd2\x82x\x14{0\
W!\x8d\x84`?bKzH\xcc\x97\x83\xfb0\x04\
\xdf\x9c\x86\x7fg\x99\xdd\x84\x0d\xaaT\x10jl\x13\x1e\
\xbe\xba\xfe\x0951{\xe6\x8d\x0f&\x1c\x17\xa1S\xb0\
\x11\x87\x0c/\x01\x07\xec\xb0\x0f?\xe1\xbc\xaei\xa3\xe6\
\x85w\xf8[\xe9\xf0\xbb\x9f\xfa\xd2\x839\xdc\xa3[\xf3\
\x19.\xa8\x89\xb50\xf7C\xa0\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1f \xb9\
\x8dw\xe9\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x06\xe6|```B0\xa1\x1c\x08\x93\x81\x81\x09\xc1\
d``b`H\x11@\xe2 s\x19\x90\x8d@\x02\
\x00#\xed\x08\xafd\x9f\x0f\x15\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\
\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\
\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\
\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\
\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x07\xad\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
@ -501,186 +684,6 @@ HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
d``b``4D\xe2 s\x19\x90\x8d@\x02\
\x00d@\x09u\x86\xb3\xad\x9c\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa5\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\x9cS4\xfc]\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x0b\x02\x04m\
\x98\x1bi\x00\x00\x00)IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0c\xff\xcf\xa3\x08\x18220 \x0b2\x1a\
200B\x98\x10AFC\x14\x13P\xb5\xa3\x01\x00\
\xd6\x10\x07\xd2/H\xdfJ\x00\x00\x00\x00IEND\
\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\
\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\
\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\
\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\
\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x070\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x0a\x00\x00\x00\x07\x08\x06\x00\x00\x001\xac\xdcc\
\x00\x00\x04\xb0iTXtXML:com.\
adobe.xmp\x00\x00\x00\x00\x00<?\
xpacket begin=\x22\xef\
\xbb\xbf\x22 id=\x22W5M0MpCe\
hiHzreSzNTczkc9d\
\x22?>\x0a<x:xmpmeta x\
mlns:x=\x22adobe:ns\
:meta/\x22 x:xmptk=\
\x22XMP Core 5.5.0\x22\
>\x0a <rdf:RDF xmln\
s:rdf=\x22http://ww\
w.w3.org/1999/02\
/22-rdf-syntax-n\
s#\x22>\x0a <rdf:Desc\
ription rdf:abou\
t=\x22\x22\x0a xmlns:e\
xif=\x22http://ns.a\
dobe.com/exif/1.\
0/\x22\x0a xmlns:ti\
ff=\x22http://ns.ad\
obe.com/tiff/1.0\
/\x22\x0a xmlns:pho\
toshop=\x22http://n\
s.adobe.com/phot\
oshop/1.0/\x22\x0a \
xmlns:xmp=\x22http:\
//ns.adobe.com/x\
ap/1.0/\x22\x0a xml\
ns:xmpMM=\x22http:/\
/ns.adobe.com/xa\
p/1.0/mm/\x22\x0a x\
mlns:stEvt=\x22http\
://ns.adobe.com/\
xap/1.0/sType/Re\
sourceEvent#\x22\x0a \
exif:PixelXDime\
nsion=\x2210\x22\x0a ex\
if:PixelYDimensi\
on=\x227\x22\x0a exif:C\
olorSpace=\x221\x22\x0a \
tiff:ImageWidth\
=\x2210\x22\x0a tiff:Im\
ageLength=\x227\x22\x0a \
tiff:Resolution\
Unit=\x222\x22\x0a tiff\
:XResolution=\x2272\
.0\x22\x0a tiff:YRes\
olution=\x2272.0\x22\x0a \
photoshop:Colo\
rMode=\x223\x22\x0a pho\
toshop:ICCProfil\
e=\x22sRGB IEC61966\
-2.1\x22\x0a xmp:Mod\
ifyDate=\x222021-05\
-31T12:33:14+02:\
00\x22\x0a xmp:Metad\
ataDate=\x222021-05\
-31T12:33:14+02:\
00\x22>\x0a <xmpMM:H\
istory>\x0a <rdf\
:Seq>\x0a <rdf:\
li\x0a stEvt:a\
ction=\x22produced\x22\
\x0a stEvt:sof\
twareAgent=\x22Affi\
nity Designer 1.\
9.2\x22\x0a stEvt\
:when=\x222021-05-3\
1T12:33:14+02:00\
\x22/>\x0a </rdf:Se\
q>\x0a </xmpMM:Hi\
story>\x0a </rdf:D\
escription>\x0a </r\
df:RDF>\x0a</x:xmpm\
eta>\x0a<?xpacket e\
nd=\x22r\x22?>H\x8b[^\x00\x00\x01\x83\
iCCPsRGB IEC6196\
6-2.1\x00\x00(\x91u\x91\xcf+DQ\x14\
\xc7?fh\xfc\x18\x8dba1e\x12\x16B\x83\x12\
\x1b\x8b\x99\x18\x0a\x8b\x99Q~mf\x9ey3j\xde\
x\xbd7\xd2d\xabl\xa7(\xb1\xf1k\xc1_\xc0V\
Y+E\xa4d\xa7\xac\x89\x0dz\xce\x9bQ#\x99s\
;\xf7|\xee\xf7\xdes\xba\xf7\x5cpD\xd3\x8afV\
\xfaA\xcbd\x8dp(\xe0\x9b\x99\x9d\xf3\xb9\x9e\xa8\xa2\
\x85\x1a:\xf1\xc6\x14S\x9f\x8c\x8cF)k\xef\xb7T\
\xd8\xf1\xba\xdb\xaeU\xfe\xdc\xbfV\xb7\x980\x15\xa8\xa8\
\x16\x1eVt#+<&<\xb1\x9a\xd5m\xde\x12n\
RR\xb1E\xe1\x13\xe1.C.(|c\xeb\xf1\x22\
?\xdb\x9c,\xf2\xa7\xcdF4\x1c\x04G\x83\xb0/\xf9\
\x8b\xe3\xbfXI\x19\x9a\xb0\xbc\x9c6-\xbd\xa2\xfc\xdc\
\xc7~\x89;\x91\x99\x8eHl\x15\xf7b\x12&D\x00\
\x1f\xe3\x8c\x10d\x80^\x86d\x1e\xa0\x9b>zdE\
\x99|\x7f!\x7f\x8ae\xc9Ud\xd6\xc9a\xb0D\x92\
\x14Y\xbaD]\x91\xea\x09\x89\xaa\xe8\x09\x19irv\
\xff\xff\xf6\xd5T\xfb\xfb\x8a\xd5\xdd\x01\xa8z\xb4\xac\xd7\
vpm\xc2W\xde\xb2>\x0e,\xeb\xeb\x10\x9c\x0fp\
\x9e)\xe5/\xef\xc3\xe0\x9b\xe8\xf9\x92\xd6\xb6\x07\x9eu\
8\xbd(i\xf1m8\xdb\x80\xe6{=f\xc4\x0a\x92\
S\xdc\xa1\xaa\xf0r\x0c\xf5\xb3\xd0x\x05\xb5\xf3\xc5\x9e\
\xfd\xecst\x07\xd15\xf9\xaaK\xd8\xd9\x85\x0e9\xef\
Y\xf8\x06\x8e\xfdg\xf8\xfd\x8a\x18\x97\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x97IDAT\x18\x95m\xcf\xb1j\x02A\
\x14\x85\xe1o\xb7\xb6\xd0'H=Vi\x03\xb1\xb4H\
;l\xa5\xf19\xf6Y\x02VB\xbaa\x0a\x0b;\x1b\
\x1bkA\x18\x02)m\xe3\xbe\x82\xcd\x06\x16\xd9\xdb\xdd\
\x9f\xff\x5c\xee\xa9b*\x13Ls\x13nF&\xa6\xf2\
\x82\xaeF\x8b\xdf\x98\xca\xfb\x88\xb4\xc0\x0f\xda\x1a[t\
\xd8\xc7T\xc2@\x9ac\x8f?|U=|\xc5\x09w\
\xbc\xa1\xc2\x193,r\x13.\xd5\xe0\xc2\x12\x07\x5cQ\
#\xe0#7\xe1\xa8O\x0e\x7f\xda`\xd7\xaf\x9f\xb9\x09\
\xdfc\x05\xff\xe5uLe\xf5\xcc\x1f\x0d3,\x83\xb6\
\x06D\x83\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
\x00\x00\x00\xa0\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x06\x00\x00\x00\x09\x08\x04\x00\x00\x00\xbb\x93\x95\x16\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x14\x1c\x1f$\
\xc6\x09\x17\x00\x00\x00$IDAT\x08\xd7c`@\
\x05\xff\xcf\xc3XL\xc8\x5c&dY&d\xc5p\x0e\
\xa3!\x9c\xc3h\x88a\x1a\x0a\x00\x00m\x84\x09u7\
\x9e\xd9#\x00\x00\x00\x00IEND\xaeB`\x82\
\x00\x00\x00\xa6\
\x89\
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
\x00\x00\x09\x00\x00\x00\x06\x08\x04\x00\x00\x00\xbb\xce|N\
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09p\
HYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
\x00\x00\x00\x07tIME\x07\xdc\x08\x17\x08\x15;\xdc\
;\x0c\x9b\x00\x00\x00*IDAT\x08\xd7c`\xc0\
\x00\x8c\x0c\x0cs> \x0b\xa4\x08020 \x0b\xa6\
\x08000B\x98\x10\xc1\x14\x01\x14\x13P\xb5\xa3\x01\
\x00\xc6\xb9\x07\x90]f\x1f\x83\x00\x00\x00\x00IEN\
D\xaeB`\x82\
"
qt_resource_name = b"\
@ -692,62 +695,6 @@ qt_resource_name = b"\
\x07\x03}\xc3\
\x00i\
\x00m\x00a\x00g\x00e\x00s\
\x00\x15\
\x0f\xf3\xc0\x07\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\
\x00.\x00p\x00n\x00g\
\x00\x12\
\x01.\x03'\
\x00c\
\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\
\x00g\
\x00\x0e\
\x04\xa2\xfc\xa7\
\x00d\
\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x1b\
\x03Z2'\
\x00c\
\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\
\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x18\
\x03\x8e\xdeg\
\x00r\
\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\
\x00l\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x11\
\x00\xb8\x8c\x07\
\x00l\
\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\
\
\x00\x0f\
\x01s\x8b\x07\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\
\x00\x0c\
\x06\xe6\xe6g\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x0f\
\x06S%\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00.\x00p\x00n\x00g\
\x00\x17\
\x0ce\xce\x07\
\x00l\
\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\
\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x14\
\x04^-\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00_\x00o\x00n\x00.\
\x00p\x00n\x00g\
\x00\x11\
\x0b\xda0\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00.\x00p\x00n\x00g\
\
\x00\x0e\
\x0e\xde\xfa\xc7\
\x00l\
@ -757,87 +704,121 @@ qt_resource_name = b"\
\x00d\
\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\
\
\x00\x0f\
\x02\x9f\x05\x87\
\x00r\
\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x12\
\x01.\x03'\
\x00c\
\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\
\x00g\
\x00\x12\
\x05\x8f\x9d\x07\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00_\x00o\x00n\x00.\x00p\x00n\
\x00g\
\x00\x17\
\x0c\xabQ\x07\
\x00d\
\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\
\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x12\
\x03\x8d\x04G\
\x00r\
\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\
\x00g\
\x00\x0f\
\x01s\x8b\x07\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\
\x00\x1b\
\x03Z2'\
\x00c\
\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\
\x00s\x00a\x00b\x00l\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x14\
\x04^-\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00_\x00o\x00n\x00.\
\x00p\x00n\x00g\
\x00\x0c\
\x06\xe6\xe6g\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x17\
\x0c\xabQ\x07\
\x00d\
\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\
\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x15\
\x03'rg\
\x00c\
\x00o\x00m\x00b\x00o\x00b\x00o\x00x\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\
\x00.\x00p\x00n\x00g\
\x00\x0e\
\x04\xa2\xfc\xa7\
\x00d\
\x00o\x00w\x00n\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x18\
\x03\x8e\xdeg\
\x00r\
\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\
\x00l\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x15\
\x0f\xf3\xc0\x07\
\x00u\
\x00p\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\x00e\x00d\
\x00.\x00p\x00n\x00g\
\x00\x0f\
\x06S%\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00o\x00p\x00e\x00n\x00.\x00p\x00n\x00g\
\x00\x17\
\x0ce\xce\x07\
\x00l\
\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00d\x00i\x00s\x00a\x00b\x00l\
\x00e\x00d\x00.\x00p\x00n\x00g\
\x00\x0f\
\x02\x9f\x05\x87\
\x00r\
\x00i\x00g\x00h\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00.\x00p\x00n\x00g\
\x00\x11\
\x0b\xda0\xa7\
\x00b\
\x00r\x00a\x00n\x00c\x00h\x00_\x00c\x00l\x00o\x00s\x00e\x00d\x00.\x00p\x00n\x00g\
\
\x00\x11\
\x00\xb8\x8c\x07\
\x00l\
\x00e\x00f\x00t\x00_\x00a\x00r\x00r\x00o\x00w\x00_\x00o\x00n\x00.\x00p\x00n\x00g\
\
"
qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x16\x00\x02\x00\x00\x00\x13\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x01\x16\x00\x00\x00\x00\x00\x01\x00\x00\x03C\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x02P\x00\x00\x00\x00\x00\x01\x00\x00\x1d!\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x00X\x00\x00\x00\x00\x00\x01\x00\x00\x00\xa3\
\x00\x00\x01y\xb4r\xcc\x9c\
\x00\x00\x01>\x00\x00\x00\x00\x00\x01\x00\x00\x03\xed\
\x00\x00\x01vA\x9d\xa29\
\x00\x00\x02x\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xca\
\x00\x00\x01vA\x9d\xa27\
\x00\x00\x03$\x00\x00\x00\x00\x00\x01\x00\x00&\xf0\
\x00\x00\x01y\xb4r\xcc\x9c\
\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x01\xf6\
\x00\x00\x01y\xb4r\xcc\x9c\
\x00\x00\x02\xfa\x00\x00\x00\x00\x00\x01\x00\x00&L\
\x00\x00\x01vA\x9d\xa27\
\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x01\x00\x00\x02\x9f\
\x00\x00\x01vA\x9d\xa27\
\x00\x00\x01\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xe5\
\x00\x00\x01y\xc2\x05+`\
\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x01M\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x02\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x1en\
\x00\x00\x01y\xc1\xfc\x16\x91\
\x00\x00\x01\x80\x00\x00\x00\x00\x00\x01\x00\x00\x051\
\x00\x00\x01y\xc1\xf9Kx\
\x00\x00\x01b\x00\x00\x00\x00\x00\x01\x00\x00\x04\x8f\
\x00\x00\x01vA\x9d\xa29\
\x00\x00\x02\x06\x00\x00\x00\x00\x00\x01\x00\x00\x14\xc6\
\x00\x00\x01y\xc2\x05\x91*\
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x0c;\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x02\xc6\x00\x00\x00\x00\x00\x01\x00\x00%\xa2\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x02.\x00\x00\x00\x00\x00\x01\x00\x00\x1cw\
\x00\x00\x01vA\x9d\xa25\
\x00\x00\x03,\x00\x00\x00\x00\x00\x01\x00\x00&\xf0\
\x00\x00\x00J\x00\x00\x00\x00\x00\x01\x00\x00\x00\xaa\
\x00\x00\x00r\x00\x00\x00\x00\x00\x01\x00\x00\x01S\
\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x09\xd5\
\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x9b\
\x00\x00\x01\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x14M\
\x00\x00\x01\x14\x00\x00\x00\x00\x00\x01\x00\x00\x0aw\
\x00\x00\x00\xc6\x00\x00\x00\x00\x00\x01\x00\x00\x091\
\x00\x00\x02\x22\x00\x00\x00\x00\x00\x01\x00\x00\x15\xa0\
\x00\x00\x01P\x00\x00\x00\x00\x00\x01\x00\x00\x0b \
\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x14\xf7\
\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x01\xfd\
\x00\x00\x02\x88\x00\x00\x00\x00\x00\x01\x00\x00\x16\xe7\
\x00\x00\x01~\x00\x00\x00\x00\x00\x01\x00\x00\x13\x01\
\x00\x00\x03\x04\x00\x00\x00\x00\x00\x01\x00\x00\x1f?\
\x00\x00\x02\xac\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xf1\
\x00\x00\x01\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x13\xa3\
\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01vA\x9d\xa29\
\x00\x00\x02X\x00\x00\x00\x00\x00\x01\x00\x00\x16D\
"
def qInitResources():
QtCore.qRegisterResourceData(
0x03, qt_resource_struct, qt_resource_name, qt_resource_data
0x01, qt_resource_struct, qt_resource_name, qt_resource_data
)
def qCleanupResources():
QtCore.qUnregisterResourceData(
0x03, qt_resource_struct, qt_resource_name, qt_resource_data
0x01, qt_resource_struct, qt_resource_name, qt_resource_data
)

View file

@ -19,5 +19,6 @@
<file>images/up_arrow.png</file>
<file>images/up_arrow_disabled.png</file>
<file>images/up_arrow_on.png</file>
<file>images/transparent.png</file>
</qresource>
</RCC>

View file

@ -206,12 +206,28 @@ QComboBox::down-arrow, QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QC
}
/* Splitter */
QSplitter {
border: none;
QSplitter::handle {
border: 3px solid transparent;
}
QSplitter::handle {
border: 1px dotted {color:bg-menu-separator};
QSplitter::handle:horizontal {
/* must be single like because of Nuke*/
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:0.3 rgba(0, 0, 0, 0),stop:0.5 {color:bg-splitter},stop:0.7 rgba(0, 0, 0, 0));
}
QSplitter::handle:vertical {
/* must be single like because of Nuke*/
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0.3 rgba(0, 0, 0, 0),stop:0.5 {color:bg-splitter},stop:0.7 rgba(0, 0, 0, 0));
}
QSplitter::handle:horizontal:hover {
/* must be single like because of Nuke*/
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:0.3 rgba(0, 0, 0, 0),stop:0.5 {color:bg-splitter-hover},stop:0.7 rgba(0, 0, 0, 0));
}
QSplitter::handle:vertical:hover {
/* must be single like because of Nuke*/
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0.3 rgba(0, 0, 0, 0),stop:0.5 {color:bg-splitter-hover},stop:0.7 rgba(0, 0, 0, 0));
}
/* SLider */
@ -238,18 +254,15 @@ QSlider::groove:focus {
border-color: {color:border-focus};
}
QSlider::handle {
background: qlineargradient(
x1: 0, y1: 0.5,
x2: 1, y2: 0.5,
stop: 0 {palette:blue-base},
stop: 1 {palette:green-base}
);
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5,stop: 0 {palette:blue-base},stop: 1 {palette:green-base});
border: 1px solid #5c5c5c;
width: 10px;
height: 10px;
border-radius: 5px;
}
QSlider::handle:horizontal {
margin: -2px 0;
}
@ -258,12 +271,8 @@ QSlider::handle:vertical {
}
QSlider::handle:disabled {
background: qlineargradient(
x1:0, y1:0,
x2:1, y2:1,
stop:0 {color:bg-buttons},
stop:1 {color:bg-buttons-disabled}
);
/* must be single like because of Nuke*/
background: qlineargradient(x1:0, y1:0,x2:1, y2:1,stop:0 {color:bg-buttons},stop:1 {color:bg-buttons-disabled});
}
/* Tab widget*/
@ -281,19 +290,15 @@ QTabBar::tab {
border-left: 3px solid transparent;
border-top: 1px solid {color:border};
border-right: 1px solid {color:border};
background: qlineargradient(
x1: 0, y1: 1, x2: 0, y2: 0,
stop: 0.5 {color:bg}, stop: 1.0 {color:bg-inputs}
);
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,stop: 0.5 {color:bg}, stop: 1.0 {color:bg-inputs});
}
QTabBar::tab:selected {
background: {color:grey-lighter};
border-left: 3px solid {color:border-focus};
background: qlineargradient(
x1: 0, y1: 1, x2: 0, y2: 0,
stop: 0.5 {color:bg}, stop: 1.0 {color:border}
);
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,stop: 0.5 {color:bg}, stop: 1.0 {color:border});
}
QTabBar::tab:!selected {
@ -341,6 +346,15 @@ QHeaderView::section:first {
QHeaderView::section:last {
border-right: none;
}
QHeaderView::down-arrow {
image: url(:/openpype/images/down_arrow.png);
}
QHeaderView::up-arrow {
image: url(:/openpype/images/up_arrow.png);
}
/* Views QListView QTreeView QTableView */
QAbstractItemView {
border: 0px solid {color:border};
@ -399,23 +413,42 @@ QAbstractItemView::branch:open:has-children:has-siblings {
QAbstractItemView::branch:open:has-children:!has-siblings:hover,
QAbstractItemView::branch:open:has-children:has-siblings:hover {
border-image: none;
image: url(:/openpype/images//branch_open_on.png);
image: url(:/openpype/images/branch_open_on.png);
background: transparent;
}
QAbstractItemView::branch:has-children:!has-siblings:closed,
QAbstractItemView::branch:closed:has-children:has-siblings {
border-image: none;
image: url(:/openpype/images//branch_closed.png);
image: url(:/openpype/images/branch_closed.png);
background: transparent;
}
QAbstractItemView::branch:has-children:!has-siblings:closed:hover,
QAbstractItemView::branch:closed:has-children:has-siblings:hover {
border-image: none;
image: url(:/openpype/images//branch_closed_on.png);
image: url(:/openpype/images/branch_closed_on.png);
background: transparent;
}
QAbstractItemView::branch:has-siblings:!adjoins-item {
border-image: none;
image: url(:/openpype/images/transparent.png);
background: transparent;
}
QAbstractItemView::branch:has-siblings:adjoins-item {
border-image: none;
image: url(:/openpype/images/transparent.png);
background: transparent;
}
QAbstractItemView::branch:!has-children:!has-siblings:adjoins-item {
border-image: none;
image: url(:/openpype/images/transparent.png);
background: transparent;
}
/* Progress bar */
QProgressBar {
border: 1px solid {color:border};
@ -431,12 +464,8 @@ QProgressBar:vertical {
}
QProgressBar::chunk {
background: qlineargradient(
x1: 0, y1: 0.5,
x2: 1, y2: 0.5,
stop: 0 {palette:blue-base},
stop: 1 {palette:green-base}
);
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 0.5,x2: 1, y2: 0.5,stop: 0 {palette:blue-base},stop: 1 {palette:green-base});
}
/* Scroll bars */
@ -645,6 +674,19 @@ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
font-family: "Roboto Mono";
}
#SubsetView::item, #RepresentationView:item {
padding: 5px 1px;
border: 0px;
}
#OptionalActionBody, #OptionalActionOption {
background: transparent;
}
#OptionalActionBody[state="hover"], #OptionalActionOption[state="hover"] {
background: {color:bg-view-hover};
}
/* New Create/Publish UI */
#PublishLogConsole {
font-family: "Roboto Mono";

View file

@ -3,12 +3,12 @@ from .tools_def import (
LOCAL_EXPERIMENTAL_KEY
)
from .dialog import ExperimentalDialog
from .dialog import ExperimentalToolsDialog
__all__ = (
"ExperimentalTools",
"LOCAL_EXPERIMENTAL_KEY",
"ExperimentalDialog"
"ExperimentalToolsDialog"
)

View file

@ -21,16 +21,17 @@ class ToolButton(QtWidgets.QPushButton):
self.triggered.emit(self._identifier)
class ExperimentalDialog(QtWidgets.QDialog):
class ExperimentalToolsDialog(QtWidgets.QDialog):
refresh_interval = 3000
def __init__(self, parent=None):
super(ExperimentalDialog, self).__init__(parent)
super(ExperimentalToolsDialog, self).__init__(parent)
self.setWindowTitle("OpenPype Experimental tools")
icon = QtGui.QIcon(app_icon_path())
self.setWindowIcon(icon)
self.setStyleSheet(load_stylesheet())
# Widgets for cases there are not available experimental tools
empty_widget = QtWidgets.QWidget(self)
empty_label = QtWidgets.QLabel(
@ -50,16 +51,42 @@ class ExperimentalDialog(QtWidgets.QDialog):
empty_layout.addStretch(1)
empty_layout.addLayout(empty_btns_layout)
content_widget = QtWidgets.QWidget(self)
# Content of Experimental tools
content_layout = QtWidgets.QVBoxLayout(content_widget)
# Layout where buttons are added
content_layout = QtWidgets.QVBoxLayout()
content_layout.setContentsMargins(0, 0, 0, 0)
# Separator line
separator_widget = QtWidgets.QWidget(self)
separator_widget.setObjectName("Separator")
separator_widget.setMinimumHeight(2)
separator_widget.setMaximumHeight(2)
# Label describing how to turn off tools
tool_btns_widget = QtWidgets.QWidget(self)
tool_btns_label = QtWidgets.QLabel(
(
"You can enable these features in"
"<br><b>OpenPype tray -> Settings -> Experimental tools</b>"
),
tool_btns_widget
)
tool_btns_label.setAlignment(QtCore.Qt.AlignCenter)
tool_btns_layout = QtWidgets.QVBoxLayout(tool_btns_widget)
tool_btns_layout.setContentsMargins(0, 0, 0, 0)
tool_btns_layout.addLayout(content_layout)
tool_btns_layout.addStretch(1)
tool_btns_layout.addWidget(separator_widget, 0)
tool_btns_layout.addWidget(tool_btns_label, 0)
experimental_tools = ExperimentalTools()
# Main layout
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(empty_widget, 1)
layout.addWidget(content_widget, 1)
layout.addWidget(tool_btns_widget, 1)
refresh_timer = QtCore.QTimer()
refresh_timer.setInterval(self.refresh_interval)
@ -68,7 +95,7 @@ class ExperimentalDialog(QtWidgets.QDialog):
ok_btn.clicked.connect(self._on_ok_click)
self._empty_widget = empty_widget
self._content_widget = content_widget
self._tool_btns_widget = tool_btns_widget
self._content_layout = content_layout
self._experimental_tools = experimental_tools
@ -95,7 +122,7 @@ class ExperimentalDialog(QtWidgets.QDialog):
button = self._buttons_by_tool_identifier[identifier]
else:
is_new = True
button = ToolButton(identifier, self)
button = ToolButton(identifier, self._tool_btns_widget)
button.triggered.connect(self._on_btn_trigger)
self._buttons_by_tool_identifier[identifier] = button
self._content_layout.insertWidget(idx, button)
@ -112,6 +139,9 @@ class ExperimentalDialog(QtWidgets.QDialog):
"\n\nOpenPype Tray > Settings > Experimental Tools"
))
if tool.enabled != button.isEnabled():
button.setEnabled(tool.enabled)
for identifier in buttons_to_remove:
button = self._buttons_by_tool_identifier.pop(identifier)
button.setVisible(False)
@ -126,7 +156,7 @@ class ExperimentalDialog(QtWidgets.QDialog):
def _set_visibility(self):
content_visible = self._is_content_visible()
self._content_widget.setVisible(content_visible)
self._tool_btns_widget.setVisible(content_visible)
self._empty_widget.setVisible(not content_visible)
def _on_ok_click(self):
@ -138,7 +168,7 @@ class ExperimentalDialog(QtWidgets.QDialog):
tool.execute()
def showEvent(self, event):
super(ExperimentalDialog, self).showEvent(event)
super(ExperimentalToolsDialog, self).showEvent(event)
if self._refresh_on_active:
# Start/Restart timer
@ -151,6 +181,8 @@ class ExperimentalDialog(QtWidgets.QDialog):
if self._first_show:
self._first_show = False
# Set stylesheet
self.setStyleSheet(load_stylesheet())
# Resize dialog if there is not content
if not self._is_content_visible():
size = self.size()
@ -164,7 +196,7 @@ class ExperimentalDialog(QtWidgets.QDialog):
self._refresh_timer.start()
self.refresh()
super(ExperimentalDialog, self).changeEvent(event)
super(ExperimentalToolsDialog, self).changeEvent(event)
def _on_refresh_timeout(self):
# Stop timer if window is not visible

View file

@ -8,6 +8,8 @@ LOCAL_EXPERIMENTAL_KEY = "experimental_tools"
class ExperimentalTool:
"""Definition of experimental tool.
Definition is used in local settings and in experimental tools dialog.
Args:
identifier (str): String identifier of tool (unique).
label (str): Label shown in UI.
@ -69,6 +71,20 @@ class ExperimentalTools:
"Combined creation and publishing into one tool."
)
]
# --- Example tool (callback will just print on click) ---
# def example_callback(*args):
# print("Triggered tool")
#
# experimental_tools = [
# ExperimentalTool(
# "example",
# "Example experimental tool",
# example_callback,
# "Example tool tooltip."
# )
# ]
# Try to get host name from env variable `AVALON_APP`
if not host_name:
host_name = os.environ.get("AVALON_APP")
@ -97,13 +113,32 @@ class ExperimentalTools:
).format(tool.identifier))
tools_by_identifier[tool.identifier] = tool
self.tools_by_identifier = tools_by_identifier
self.tools = experimental_tools
self._tools_by_identifier = tools_by_identifier
self._tools = experimental_tools
self._parent_widget = parent
self._publisher_tool = None
@property
def tools(self):
"""Tools in list.
Returns:
list: Tools filtered by host name if filtering was enabled
on initialization.
"""
return self._tools
@property
def tools_by_identifier(self):
"""Tools by their identifier.
Returns:
dict: Tools by identifier filtered by host name if filtering
was enabled on initialization.
"""
return self._tools_by_identifier
def refresh_availability(self):
"""Reload local settings and check if any tool changed ability."""
local_settings = get_local_settings()
experimental_settings = (
local_settings.get(LOCAL_EXPERIMENTAL_KEY)

View file

@ -2,8 +2,8 @@ import sys
from Qt import QtWidgets, QtCore, QtGui
from avalon import style
from avalon.api import AvalonMongoDB
from openpype import style
from openpype.tools.utils import lib as tools_lib
from openpype.tools.loader.widgets import (
ThumbnailWidget,
@ -28,152 +28,182 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
tool_title = "Library Loader 0.5"
tool_name = "library_loader"
message_timeout = 5000
def __init__(
self, parent=None, icon=None, show_projects=False, show_libraries=True
):
super(LibraryLoaderWindow, self).__init__(parent)
# Window modifications
self.setWindowTitle(self.tool_title)
window_flags = QtCore.Qt.Window
if not parent:
window_flags |= QtCore.Qt.WindowStaysOnTopHint
self.setWindowFlags(window_flags)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
icon = QtGui.QIcon(style.app_icon_path())
self.setWindowIcon(icon)
self._first_show = True
self._initial_refresh = False
self._ignore_project_change = False
# Enable minimize and maximize for app
self.setWindowTitle(self.tool_title)
self.setWindowFlags(QtCore.Qt.Window)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
if icon is not None:
self.setWindowIcon(icon)
# self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dbcon = AvalonMongoDB()
dbcon.install()
dbcon.Session["AVALON_PROJECT"] = None
body = QtWidgets.QWidget()
footer = QtWidgets.QWidget()
footer.setFixedHeight(20)
container = QtWidgets.QWidget()
self.dbcon = AvalonMongoDB()
self.dbcon.install()
self.dbcon.Session["AVALON_PROJECT"] = None
self.dbcon = dbcon
self.show_projects = show_projects
self.show_libraries = show_libraries
# Groups config
self.groups_config = tools_lib.GroupsConfig(self.dbcon)
self.family_config_cache = tools_lib.FamilyConfigCache(self.dbcon)
self.groups_config = tools_lib.GroupsConfig(dbcon)
self.family_config_cache = tools_lib.FamilyConfigCache(dbcon)
assets = AssetWidget(
self.dbcon, multiselection=True, parent=self
# UI initialization
main_splitter = QtWidgets.QSplitter(self)
# --- Left part ---
left_side_splitter = QtWidgets.QSplitter(main_splitter)
left_side_splitter.setOrientation(QtCore.Qt.Vertical)
# Project combobox
projects_combobox = QtWidgets.QComboBox(left_side_splitter)
combobox_delegate = QtWidgets.QStyledItemDelegate(self)
projects_combobox.setItemDelegate(combobox_delegate)
# Assets widget
assets_widget = AssetWidget(
dbcon, multiselection=True, parent=left_side_splitter
)
families = FamilyListView(
self.dbcon, self.family_config_cache, parent=self
# Families widget
families_filter_view = FamilyListView(
dbcon, self.family_config_cache, left_side_splitter
)
subsets = LibrarySubsetWidget(
self.dbcon,
left_side_splitter.addWidget(projects_combobox)
left_side_splitter.addWidget(assets_widget)
left_side_splitter.addWidget(families_filter_view)
left_side_splitter.setStretchFactor(1, 65)
left_side_splitter.setStretchFactor(2, 35)
# --- Middle part ---
# Subsets widget
subsets_widget = LibrarySubsetWidget(
dbcon,
self.groups_config,
self.family_config_cache,
tool_name=self.tool_name,
parent=self
)
version = VersionWidget(self.dbcon)
thumbnail = ThumbnailWidget(self.dbcon)
# Project
self.combo_projects = QtWidgets.QComboBox()
# Create splitter to show / hide family filters
asset_filter_splitter = QtWidgets.QSplitter()
asset_filter_splitter.setOrientation(QtCore.Qt.Vertical)
asset_filter_splitter.addWidget(self.combo_projects)
asset_filter_splitter.addWidget(assets)
asset_filter_splitter.addWidget(families)
asset_filter_splitter.setStretchFactor(1, 65)
asset_filter_splitter.setStretchFactor(2, 35)
manager = ModulesManager()
sync_server = manager.modules_by_name["sync_server"]
representations = RepresentationWidget(self.dbcon)
thumb_ver_splitter = QtWidgets.QSplitter()
# --- Right part ---
thumb_ver_splitter = QtWidgets.QSplitter(main_splitter)
thumb_ver_splitter.setOrientation(QtCore.Qt.Vertical)
thumb_ver_splitter.addWidget(thumbnail)
thumb_ver_splitter.addWidget(version)
if sync_server.enabled:
thumb_ver_splitter.addWidget(representations)
thumbnail_widget = ThumbnailWidget(dbcon, parent=thumb_ver_splitter)
version_info_widget = VersionWidget(dbcon, parent=thumb_ver_splitter)
thumb_ver_splitter.addWidget(thumbnail_widget)
thumb_ver_splitter.addWidget(version_info_widget)
thumb_ver_splitter.setStretchFactor(0, 30)
thumb_ver_splitter.setStretchFactor(1, 35)
container_layout = QtWidgets.QHBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)
split = QtWidgets.QSplitter()
split.addWidget(asset_filter_splitter)
split.addWidget(subsets)
split.addWidget(thumb_ver_splitter)
split.setSizes([180, 950, 200])
container_layout.addWidget(split)
manager = ModulesManager()
sync_server = manager.modules_by_name.get("sync_server")
sync_server_enabled = False
if sync_server is not None:
sync_server_enabled = sync_server.enabled
body_layout = QtWidgets.QHBoxLayout(body)
body_layout.addWidget(container)
body_layout.setContentsMargins(0, 0, 0, 0)
repres_widget = None
if sync_server_enabled:
repres_widget = RepresentationWidget(
dbcon, self.tool_name, parent=thumb_ver_splitter
)
thumb_ver_splitter.addWidget(repres_widget)
message = QtWidgets.QLabel()
message.hide()
main_splitter.addWidget(left_side_splitter)
main_splitter.addWidget(subsets_widget)
main_splitter.addWidget(thumb_ver_splitter)
if sync_server_enabled:
main_splitter.setSizes([250, 1000, 550])
else:
main_splitter.setSizes([250, 850, 200])
footer_layout = QtWidgets.QVBoxLayout(footer)
footer_layout.addWidget(message)
# --- Footer ---
footer_widget = QtWidgets.QWidget(self)
footer_widget.setFixedHeight(20)
message_label = QtWidgets.QLabel(footer_widget)
footer_layout = QtWidgets.QVBoxLayout(footer_widget)
footer_layout.setContentsMargins(0, 0, 0, 0)
footer_layout.addWidget(message_label)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(body)
layout.addWidget(footer)
layout.addWidget(main_splitter)
layout.addWidget(footer_widget)
self.data = {
"widgets": {
"families": families,
"assets": assets,
"subsets": subsets,
"version": version,
"thumbnail": thumbnail,
"representations": representations
},
"label": {
"message": message,
},
"state": {
"assetIds": None
}
}
families.active_changed.connect(subsets.set_family_filters)
assets.selection_changed.connect(self.on_assetschanged)
assets.refresh_triggered.connect(self.on_assetschanged)
assets.view.clicked.connect(self.on_assetview_click)
subsets.active_changed.connect(self.on_subsetschanged)
subsets.version_changed.connect(self.on_versionschanged)
subsets.refreshed.connect(self._on_subset_refresh)
self.combo_projects.currentTextChanged.connect(self.on_project_change)
message_timer = QtCore.QTimer()
message_timer.setInterval(self.message_timeout)
message_timer.setSingleShot(True)
message_timer.timeout.connect(self._on_message_timeout)
families_filter_view.active_changed.connect(
self._on_family_filter_change
)
assets_widget.selection_changed.connect(self.on_assetschanged)
assets_widget.refresh_triggered.connect(self.on_assetschanged)
assets_widget.view.clicked.connect(self.on_assetview_click)
subsets_widget.active_changed.connect(self.on_subsetschanged)
subsets_widget.version_changed.connect(self.on_versionschanged)
subsets_widget.refreshed.connect(self._on_subset_refresh)
projects_combobox.currentTextChanged.connect(self.on_project_change)
self.sync_server = sync_server
self._sync_server_enabled = sync_server_enabled
# Set default thumbnail on start
thumbnail.set_thumbnail(None)
self._combobox_delegate = combobox_delegate
self._projects_combobox = projects_combobox
self._assets_widget = assets_widget
self._families_filter_view = families_filter_view
# Defaults
if sync_server.enabled:
split.setSizes([250, 1000, 550])
self.resize(1800, 900)
else:
split.setSizes([250, 850, 200])
self.resize(1300, 700)
self._subsets_widget = subsets_widget
self._version_info_widget = version_info_widget
self._thumbnail_widget = thumbnail_widget
self._repres_widget = repres_widget
self._message_label = message_label
self._message_timer = message_timer
def showEvent(self, event):
super(LibraryLoaderWindow, self).showEvent(event)
if self._first_show:
self._first_show = False
self.setStyleSheet(style.load_stylesheet())
if self._sync_server_enabled:
self.resize(1800, 900)
else:
self.resize(1300, 700)
if not self._initial_refresh:
self._initial_refresh = True
self.refresh()
def on_assetview_click(self, *args):
subsets_widget = self.data["widgets"]["subsets"]
selection_model = subsets_widget.view.selectionModel()
selection_model = self._subsets_widget.view.selectionModel()
if selection_model.selectedIndexes():
selection_model.clearSelection()
@ -184,7 +214,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
self._ignore_project_change = True
# Cleanup
self.combo_projects.clear()
self._projects_combobox.clear()
# Fill combobox with projects
select_project_item = QtGui.QStandardItem("< Select project >")
@ -199,18 +229,18 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
item.setData(project_name, QtCore.Qt.UserRole + 1)
combobox_items.append(item)
root_item = self.combo_projects.model().invisibleRootItem()
root_item = self._projects_combobox.model().invisibleRootItem()
root_item.appendRows(combobox_items)
index = 0
self._ignore_project_change = False
if old_project_name:
index = self.combo_projects.findText(
index = self._projects_combobox.findText(
old_project_name, QtCore.Qt.MatchFixedString
)
self.combo_projects.setCurrentIndex(index)
self._projects_combobox.setCurrentIndex(index)
def get_filtered_projects(self):
projects = list()
@ -228,8 +258,8 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
if self._ignore_project_change:
return
row = self.combo_projects.currentIndex()
index = self.combo_projects.model().index(row, 0)
row = self._projects_combobox.currentIndex()
index = self._projects_combobox.model().index(row, 0)
project_name = index.data(QtCore.Qt.UserRole + 1)
self.dbcon.Session["AVALON_PROJECT"] = project_name
@ -242,11 +272,9 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
"Config `%s` has no function `install`" % _config.__name__
)
subsets = self.data["widgets"]["subsets"]
representations = self.data["widgets"]["representations"]
subsets.on_project_change(self.dbcon.Session["AVALON_PROJECT"])
representations.on_project_change(self.dbcon.Session["AVALON_PROJECT"])
self._subsets_widget.on_project_change(project_name)
if self._repres_widget:
self._repres_widget.on_project_change(project_name)
self.family_config_cache.refresh()
self.groups_config.refresh()
@ -260,13 +288,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
@property
def current_project(self):
if (
not self.dbcon.active_project() or
self.dbcon.active_project() == ""
):
return None
return self.dbcon.active_project()
return self.dbcon.active_project() or None
# -------------------------------
# Delay calling blocking methods
@ -289,12 +311,11 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
tools_lib.schedule(self._versionschanged, 150, channel="mongo")
def _on_subset_refresh(self, has_item):
subsets_widget = self.data["widgets"]["subsets"]
families_view = self.data["widgets"]["families"]
subsets_widget.set_loading_state(loading=False, empty=not has_item)
families = subsets_widget.get_subsets_families()
families_view.set_enabled_families(families)
self._subsets_widget.set_loading_state(
loading=False, empty=not has_item
)
families = self._subsets_widget.get_subsets_families()
self._families_filter_view.set_enabled_families(families)
def set_context(self, context, refresh=True):
self.echo("Setting context: {}".format(context))
@ -304,6 +325,9 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
)
# ------------------------------
def _on_family_filter_change(self, families):
self._subsets_widget.set_family_filters(families)
def _refresh(self):
if not self._initial_refresh:
self._initial_refresh = True
@ -319,74 +343,69 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
)
assert project_doc, "This is a bug"
assets_widget = self.data["widgets"]["assets"]
families_view = self.data["widgets"]["families"]
families_view.set_enabled_families(set())
families_view.refresh()
self._families_filter_view.set_enabled_families(set())
self._families_filter_view.refresh()
assets_widget.model.stop_fetch_thread()
assets_widget.refresh()
assets_widget.setFocus()
self._assets_widget.model.stop_fetch_thread()
self._assets_widget.refresh()
self._assets_widget.setFocus()
def clear_assets_underlines(self):
last_asset_ids = self.data["state"]["assetIds"]
if not last_asset_ids:
return
assets_widget = self.data["widgets"]["assets"]
id_role = assets_widget.model.ObjectIdRole
assets_model = self._assets_widget.model
id_role = assets_model.ObjectIdRole
for index in tools_lib.iter_model_rows(assets_widget.model, 0):
for index in tools_lib.iter_model_rows(assets_model, 0):
if index.data(id_role) not in last_asset_ids:
continue
assets_widget.model.setData(
index, [], assets_widget.model.subsetColorsRole
assets_model.setData(
index, [], assets_model.subsetColorsRole
)
def _assetschanged(self):
"""Selected assets have changed"""
assets_widget = self.data["widgets"]["assets"]
subsets_widget = self.data["widgets"]["subsets"]
subsets_model = subsets_widget.model
subsets_model = self._subsets_widget.model
subsets_model.clear()
self.clear_assets_underlines()
if not self.dbcon.Session.get("AVALON_PROJECT"):
subsets_widget.set_loading_state(
self._subsets_widget.set_loading_state(
loading=False,
empty=True
)
return
# filter None docs they are silo
asset_docs = assets_widget.get_selected_assets()
asset_docs = self._assets_widget.get_selected_assets()
if len(asset_docs) == 0:
return
asset_ids = [asset_doc["_id"] for asset_doc in asset_docs]
# Start loading
subsets_widget.set_loading_state(
self._subsets_widget.set_loading_state(
loading=bool(asset_ids),
empty=True
)
subsets_model.set_assets(asset_ids)
subsets_widget.view.setColumnHidden(
self._subsets_widget.view.setColumnHidden(
subsets_model.Columns.index("asset"),
len(asset_ids) < 2
)
# Clear the version information on asset change
self.data["widgets"]["version"].set_version(None)
self.data["widgets"]["thumbnail"].set_thumbnail(asset_docs)
self._version_info_widget.set_version(None)
self._thumbnail_widget.set_thumbnail(asset_docs)
self.data["state"]["assetIds"] = asset_ids
representations = self.data["widgets"]["representations"]
# reset repre list
representations.set_version_ids([])
self._repres_widget.set_version_ids([])
def _subsetschanged(self):
asset_ids = self.data["state"]["assetIds"]
@ -395,8 +414,9 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
self._versionschanged()
return
subsets = self.data["widgets"]["subsets"]
selected_subsets = subsets.selected_subsets(_merged=True, _other=False)
selected_subsets = self._subsets_widget.selected_subsets(
_merged=True, _other=False
)
asset_models = {}
asset_ids = []
@ -417,26 +437,24 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
self.clear_assets_underlines()
assets_widget = self.data["widgets"]["assets"]
indexes = assets_widget.view.selectionModel().selectedRows()
indexes = self._assets_widget.view.selectionModel().selectedRows()
assets_model = self._assets_widget.model
for index in indexes:
id = index.data(assets_widget.model.ObjectIdRole)
id = index.data(assets_model.ObjectIdRole)
if id not in asset_models:
continue
assets_widget.model.setData(
index, asset_models[id], assets_widget.model.subsetColorsRole
assets_model.setData(
index, asset_models[id], assets_model.subsetColorsRole
)
# Trigger repaint
assets_widget.view.updateGeometries()
self._assets_widget.view.updateGeometries()
# Set version in Version Widget
self._versionschanged()
def _versionschanged(self):
subsets = self.data["widgets"]["subsets"]
selection = subsets.view.selectionModel()
selection = self._subsets_widget.view.selectionModel()
# Active must be in the selected rows otherwise we
# assume it's not actually an "active" current index.
@ -445,7 +463,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
active = selection.currentIndex()
rows = selection.selectedRows(column=active.column())
if active and active in rows:
item = active.data(subsets.model.ItemRole)
item = active.data(self._subsets_widget.model.ItemRole)
if (
item is not None
and not (item.get("isGroup") or item.get("isMerged"))
@ -457,7 +475,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
for index in rows:
if not index or not index.isValid():
continue
item = index.data(subsets.model.ItemRole)
item = index.data(self._subsets_widget.model.ItemRole)
if (
item is None
or item.get("isGroup")
@ -466,20 +484,18 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
continue
version_docs.append(item["version_document"])
self.data["widgets"]["version"].set_version(version_doc)
self._version_info_widget.set_version(version_doc)
thumbnail_docs = version_docs
if not thumbnail_docs:
assets_widget = self.data["widgets"]["assets"]
asset_docs = assets_widget.get_selected_assets()
asset_docs = self._assets_widget.get_selected_assets()
if len(asset_docs) > 0:
thumbnail_docs = asset_docs
self.data["widgets"]["thumbnail"].set_thumbnail(thumbnail_docs)
self._thumbnail_widget.set_thumbnail(thumbnail_docs)
representations = self.data["widgets"]["representations"]
version_ids = [doc["_id"] for doc in version_docs or []]
representations.set_version_ids(version_ids)
self._repres_widget.set_version_ids(version_ids)
def _set_context(self, context, refresh=True):
"""Set the selection in the interface using a context.
@ -507,16 +523,15 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
# scheduled refresh and the silo tabs are not shown.
self._refresh_assets()
asset_widget = self.data["widgets"]["assets"]
asset_widget.select_assets(asset)
self._assets_widget.select_assets(asset)
def _on_message_timeout(self):
self._message_label.setText("")
def echo(self, message):
widget = self.data["label"]["message"]
widget.setText(str(message))
widget.show()
self._message_label.setText(str(message))
print(message)
tools_lib.schedule(widget.hide, 5000, channel="message")
self._message_timer.start()
def closeEvent(self, event):
# Kill on holding SHIFT
@ -573,7 +588,6 @@ def show(
window = LibraryLoaderWindow(
parent, icon, show_projects, show_libraries
)
window.setStyleSheet(style.load_stylesheet())
window.show()
module.window = window

View file

@ -1,10 +1,10 @@
import sys
from Qt import QtWidgets, QtCore
from avalon import api, io, style, pipeline
from avalon import api, io, pipeline
from openpype import style
from openpype.tools.utils.widgets import AssetWidget
from openpype.tools.utils import lib
from .widgets import (
@ -37,6 +37,7 @@ class LoaderWindow(QtWidgets.QDialog):
"""Asset loader interface"""
tool_name = "loader"
message_timeout = 5000
def __init__(self, parent=None):
super(LoaderWindow, self).__init__(parent)
@ -51,86 +52,91 @@ class LoaderWindow(QtWidgets.QDialog):
self.family_config_cache = lib.FamilyConfigCache(io)
# Enable minimize and maximize for app
self.setWindowFlags(QtCore.Qt.Window)
window_flags = QtCore.Qt.Window
if not parent:
window_flags |= QtCore.Qt.WindowStaysOnTopHint
self.setWindowFlags(window_flags)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
body = QtWidgets.QWidget()
footer = QtWidgets.QWidget()
footer.setFixedHeight(20)
main_splitter = QtWidgets.QSplitter(self)
container = QtWidgets.QWidget()
# --- Left part ---
left_side_splitter = QtWidgets.QSplitter(main_splitter)
left_side_splitter.setOrientation(QtCore.Qt.Vertical)
assets = AssetWidget(io, multiselection=True, parent=self)
assets.set_current_asset_btn_visibility(True)
# Assets widget
assets_widget = AssetWidget(
io, multiselection=True, parent=left_side_splitter
)
assets_widget.set_current_asset_btn_visibility(True)
families = FamilyListView(io, self.family_config_cache, self)
subsets = SubsetWidget(
# Families widget
families_filter_view = FamilyListView(
io, self.family_config_cache, left_side_splitter
)
left_side_splitter.addWidget(assets_widget)
left_side_splitter.addWidget(families_filter_view)
left_side_splitter.setStretchFactor(0, 65)
left_side_splitter.setStretchFactor(1, 35)
# --- Middle part ---
# Subsets widget
subsets_widget = SubsetWidget(
io,
self.groups_config,
self.family_config_cache,
tool_name=self.tool_name,
parent=self
parent=main_splitter
)
version = VersionWidget(io)
thumbnail = ThumbnailWidget(io)
representations = RepresentationWidget(io, self.tool_name)
manager = ModulesManager()
sync_server = manager.modules_by_name["sync_server"]
thumb_ver_splitter = QtWidgets.QSplitter()
# --- Right part ---
thumb_ver_splitter = QtWidgets.QSplitter(main_splitter)
thumb_ver_splitter.setOrientation(QtCore.Qt.Vertical)
thumb_ver_splitter.addWidget(thumbnail)
thumb_ver_splitter.addWidget(version)
if sync_server.enabled:
thumb_ver_splitter.addWidget(representations)
thumbnail_widget = ThumbnailWidget(io, parent=thumb_ver_splitter)
version_info_widget = VersionWidget(io, parent=thumb_ver_splitter)
thumb_ver_splitter.addWidget(thumbnail_widget)
thumb_ver_splitter.addWidget(version_info_widget)
thumb_ver_splitter.setStretchFactor(0, 30)
thumb_ver_splitter.setStretchFactor(1, 35)
# Create splitter to show / hide family filters
asset_filter_splitter = QtWidgets.QSplitter()
asset_filter_splitter.setOrientation(QtCore.Qt.Vertical)
asset_filter_splitter.addWidget(assets)
asset_filter_splitter.addWidget(families)
asset_filter_splitter.setStretchFactor(0, 65)
asset_filter_splitter.setStretchFactor(1, 35)
manager = ModulesManager()
sync_server = manager.modules_by_name.get("sync_server")
sync_server_enabled = False
if sync_server is not None:
sync_server_enabled = sync_server.enabled
container_layout = QtWidgets.QHBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)
split = QtWidgets.QSplitter()
split.addWidget(asset_filter_splitter)
split.addWidget(subsets)
split.addWidget(thumb_ver_splitter)
repres_widget = None
if sync_server_enabled:
repres_widget = RepresentationWidget(
io, self.tool_name, parent=thumb_ver_splitter
)
thumb_ver_splitter.addWidget(repres_widget)
container_layout.addWidget(split)
main_splitter.addWidget(left_side_splitter)
main_splitter.addWidget(subsets_widget)
main_splitter.addWidget(thumb_ver_splitter)
body_layout = QtWidgets.QHBoxLayout(body)
body_layout.addWidget(container)
body_layout.setContentsMargins(0, 0, 0, 0)
if sync_server_enabled:
main_splitter.setSizes([250, 1000, 550])
else:
main_splitter.setSizes([250, 850, 200])
message = QtWidgets.QLabel()
message.hide()
footer_widget = QtWidgets.QWidget(self)
footer_layout = QtWidgets.QVBoxLayout(footer)
footer_layout.addWidget(message)
message_label = QtWidgets.QLabel(footer_widget)
footer_layout = QtWidgets.QHBoxLayout(footer_widget)
footer_layout.setContentsMargins(0, 0, 0, 0)
footer_layout.addWidget(message_label, 1)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(body)
layout.addWidget(footer)
layout.addWidget(main_splitter, 1)
layout.addWidget(footer_widget, 0)
self.data = {
"widgets": {
"families": families,
"assets": assets,
"subsets": subsets,
"version": version,
"thumbnail": thumbnail,
"representations": representations
},
"label": {
"message": message,
},
"state": {
"assetIds": None
}
@ -139,19 +145,43 @@ class LoaderWindow(QtWidgets.QDialog):
overlay_frame = OverlayFrame("Loading...", self)
overlay_frame.setVisible(False)
families.active_changed.connect(subsets.set_family_filters)
assets.selection_changed.connect(self.on_assetschanged)
assets.refresh_triggered.connect(self.on_assetschanged)
assets.view.clicked.connect(self.on_assetview_click)
subsets.active_changed.connect(self.on_subsetschanged)
subsets.version_changed.connect(self.on_versionschanged)
subsets.refreshed.connect(self._on_subset_refresh)
message_timer = QtCore.QTimer()
message_timer.setInterval(self.message_timeout)
message_timer.setSingleShot(True)
subsets.load_started.connect(self._on_load_start)
subsets.load_ended.connect(self._on_load_end)
representations.load_started.connect(self._on_load_start)
representations.load_ended.connect(self._on_load_end)
message_timer.timeout.connect(self._on_message_timeout)
families_filter_view.active_changed.connect(
self._on_family_filter_change
)
assets_widget.selection_changed.connect(self.on_assetschanged)
assets_widget.refresh_triggered.connect(self.on_assetschanged)
# TODO do not touch view in asset widget
assets_widget.view.clicked.connect(self.on_assetview_click)
subsets_widget.active_changed.connect(self.on_subsetschanged)
subsets_widget.version_changed.connect(self.on_versionschanged)
subsets_widget.refreshed.connect(self._on_subset_refresh)
subsets_widget.load_started.connect(self._on_load_start)
subsets_widget.load_ended.connect(self._on_load_end)
repres_widget.load_started.connect(self._on_load_start)
repres_widget.load_ended.connect(self._on_load_end)
self._sync_server_enabled = sync_server_enabled
self._assets_widget = assets_widget
self._families_filter_view = families_filter_view
self._subsets_widget = subsets_widget
self._version_info_widget = version_info_widget
self._thumbnail_widget = thumbnail_widget
self._repres_widget = repres_widget
self._message_label = message_label
self._message_timer = message_timer
# TODO add overlay using stack widget
self._overlay_frame = overlay_frame
self.family_config_cache.refresh()
@ -160,13 +190,7 @@ class LoaderWindow(QtWidgets.QDialog):
self._refresh()
self._assetschanged()
# Defaults
if sync_server.enabled:
split.setSizes([250, 1000, 550])
self.resize(1800, 900)
else:
split.setSizes([250, 850, 200])
self.resize(1300, 700)
self._first_show = True
def resizeEvent(self, event):
super(LoaderWindow, self).resizeEvent(event)
@ -176,13 +200,23 @@ class LoaderWindow(QtWidgets.QDialog):
super(LoaderWindow, self).moveEvent(event)
self._overlay_frame.move(0, 0)
def showEvent(self, event):
super(LoaderWindow, self).showEvent(event)
if self._first_show:
self._first_show = False
self.setStyleSheet(style.load_stylesheet())
if self._sync_server_enabled:
self.resize(1800, 900)
else:
self.resize(1300, 700)
# -------------------------------
# Delay calling blocking methods
# -------------------------------
def on_assetview_click(self, *args):
subsets_widget = self.data["widgets"]["subsets"]
selection_model = subsets_widget.view.selectionModel()
# TODO do not touch inner attributes of subset widget
selection_model = self._subsets_widget.view.selectionModel()
if selection_model.selectedIndexes():
selection_model.clearSelection()
@ -216,12 +250,11 @@ class LoaderWindow(QtWidgets.QDialog):
self._overlay_frame.setVisible(False)
def _on_subset_refresh(self, has_item):
subsets_widget = self.data["widgets"]["subsets"]
families_view = self.data["widgets"]["families"]
subsets_widget.set_loading_state(loading=False, empty=not has_item)
families = subsets_widget.get_subsets_families()
families_view.set_enabled_families(families)
self._subsets_widget.set_loading_state(
loading=False, empty=not has_item
)
families = self._subsets_widget.get_subsets_families()
self._families_filter_view.set_enabled_families(families)
def _on_load_end(self):
# Delay hiding as click events happened during loading should be
@ -229,14 +262,14 @@ class LoaderWindow(QtWidgets.QDialog):
QtCore.QTimer.singleShot(100, self._hide_overlay)
# ------------------------------
def _on_family_filter_change(self, families):
self._subsets_widget.set_family_filters(families)
def on_context_task_change(self, *args, **kwargs):
assets_widget = self.data["widgets"]["assets"]
families_view = self.data["widgets"]["families"]
# Refresh families config
families_view.refresh()
self._families_filter_view.refresh()
# Change to context asset on context change
assets_widget.select_assets(io.Session["AVALON_ASSET"])
self._assets_widget.select_assets(io.Session["AVALON_ASSET"])
def _refresh(self):
"""Load assets from database"""
@ -245,12 +278,10 @@ class LoaderWindow(QtWidgets.QDialog):
project = io.find_one({"type": "project"}, {"type": 1})
assert project, "Project was not found! This is a bug"
assets_widget = self.data["widgets"]["assets"]
assets_widget.refresh()
assets_widget.setFocus()
self._assets_widget.refresh()
self._assets_widget.setFocus()
families_view = self.data["widgets"]["families"]
families_view.refresh()
self._families_filter_view.refresh()
def clear_assets_underlines(self):
"""Clear colors from asset data to remove colored underlines
@ -258,11 +289,12 @@ class LoaderWindow(QtWidgets.QDialog):
own selected subsets. These colors must be cleared from asset data
on selection change so they match current selection.
"""
last_asset_ids = self.data["state"]["assetIds"]
# TODO do not touch inner attributes of asset widget
last_asset_ids = self.data["state"]["assetIds"] or []
if not last_asset_ids:
return
assets_widget = self.data["widgets"]["assets"]
assets_widget = self._assets_widget
id_role = assets_widget.model.ObjectIdRole
for index in lib.iter_model_rows(assets_widget.model, 0):
@ -275,15 +307,15 @@ class LoaderWindow(QtWidgets.QDialog):
def _assetschanged(self):
"""Selected assets have changed"""
assets_widget = self.data["widgets"]["assets"]
subsets_widget = self.data["widgets"]["subsets"]
subsets_widget = self._subsets_widget
# TODO do not touch subset widget inner attributes
subsets_model = subsets_widget.model
subsets_model.clear()
self.clear_assets_underlines()
# filter None docs they are silo
asset_docs = assets_widget.get_selected_assets()
asset_docs = self._assets_widget.get_selected_assets()
asset_ids = [asset_doc["_id"] for asset_doc in asset_docs]
# Start loading
@ -299,14 +331,14 @@ class LoaderWindow(QtWidgets.QDialog):
)
# Clear the version information on asset change
self.data["widgets"]["version"].set_version(None)
self.data["widgets"]["thumbnail"].set_thumbnail(asset_docs)
self._thumbnail_widget.set_thumbnail(asset_docs)
self._version_info_widget.set_version(None)
self.data["state"]["assetIds"] = asset_ids
representations = self.data["widgets"]["representations"]
# reset repre list
representations.set_version_ids([])
if self._repres_widget is not None:
self._repres_widget.set_version_ids([])
def _subsetschanged(self):
asset_ids = self.data["state"]["assetIds"]
@ -315,8 +347,9 @@ class LoaderWindow(QtWidgets.QDialog):
self._versionschanged()
return
subsets = self.data["widgets"]["subsets"]
selected_subsets = subsets.selected_subsets(_merged=True, _other=False)
selected_subsets = self._subsets_widget.selected_subsets(
_merged=True, _other=False
)
asset_models = {}
asset_ids = []
@ -337,7 +370,8 @@ class LoaderWindow(QtWidgets.QDialog):
self.clear_assets_underlines()
assets_widget = self.data["widgets"]["assets"]
# TODO do not use inner attributes of asset widget
assets_widget = self._assets_widget
indexes = assets_widget.view.selectionModel().selectedRows()
for index in indexes:
@ -354,7 +388,7 @@ class LoaderWindow(QtWidgets.QDialog):
self._versionschanged()
def _versionschanged(self):
subsets = self.data["widgets"]["subsets"]
subsets = self._subsets_widget
selection = subsets.view.selectionModel()
# Active must be in the selected rows otherwise we
@ -386,23 +420,24 @@ class LoaderWindow(QtWidgets.QDialog):
else:
version_docs.append(item["version_document"])
self.data["widgets"]["version"].set_version(version_doc)
self._version_info_widget.set_version(version_doc)
thumbnail_docs = version_docs
assets_widget = self.data["widgets"]["assets"]
asset_docs = assets_widget.get_selected_assets()
asset_docs = self._assets_widget.get_selected_assets()
if not thumbnail_docs:
if len(asset_docs) > 0:
thumbnail_docs = asset_docs
self.data["widgets"]["thumbnail"].set_thumbnail(thumbnail_docs)
self._thumbnail_widget.set_thumbnail(thumbnail_docs)
representations = self.data["widgets"]["representations"]
version_ids = [doc["_id"] for doc in version_docs or []]
representations.set_version_ids(version_ids)
if self._repres_widget is not None:
version_ids = [doc["_id"] for doc in version_docs or []]
self._repres_widget.set_version_ids(version_ids)
# representations.change_visibility("subset", len(rows) > 1)
# representations.change_visibility("asset", len(asset_docs) > 1)
# self._repres_widget.change_visibility("subset", len(rows) > 1)
# self._repres_widget.change_visibility(
# "asset", len(asset_docs) > 1
# )
def _set_context(self, context, refresh=True):
"""Set the selection in the interface using a context.
@ -435,16 +470,15 @@ class LoaderWindow(QtWidgets.QDialog):
# scheduled refresh and the silo tabs are not shown.
self._refresh()
asset_widget = self.data["widgets"]["assets"]
asset_widget.select_assets(asset)
self._assets_widget.select_assets(asset)
def _on_message_timeout(self):
self._message_label.setText("")
def echo(self, message):
widget = self.data["label"]["message"]
widget.setText(str(message))
widget.show()
self._message_label.setText(str(message))
print(message)
lib.schedule(widget.hide, 5000, channel="message")
self._message_timer.start()
def closeEvent(self, event):
# Kill on holding SHIFT
@ -472,7 +506,7 @@ class LoaderWindow(QtWidgets.QDialog):
event.setAccepted(True) # Avoid interfering other widgets
def show_grouping_dialog(self):
subsets = self.data["widgets"]["subsets"]
subsets = self._subsets_widget
if not subsets.is_groupable():
self.echo("Grouping not enabled.")
return
@ -511,7 +545,8 @@ class SubsetGroupingDialog(QtWidgets.QDialog):
self.items = items
self.groups_config = groups_config
self.subsets = parent.data["widgets"]["subsets"]
# TODO do not touch inner attributes
self.subsets = parent._subsets_widget
self.asset_ids = parent.data["state"]["assetIds"]
name = QtWidgets.QLineEdit()
@ -630,7 +665,6 @@ def show(debug=False, parent=None, use_context=False):
with lib.application():
window = LoaderWindow(parent)
window.setStyleSheet(style.load_stylesheet())
window.show()
if use_context:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Before After
Before After

View file

@ -37,12 +37,13 @@ class OverlayFrame(QtWidgets.QFrame):
super(OverlayFrame, self).__init__(parent)
label_widget = QtWidgets.QLabel(label, self)
label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(label_widget, 1, QtCore.Qt.AlignCenter)
self.label_widget = label_widget
label_widget.setStyleSheet("background: transparent;")
self.setStyleSheet((
"background: rgba(0, 0, 0, 127);"
"font-size: 60pt;"
@ -159,36 +160,40 @@ class SubsetWidget(QtWidgets.QWidget):
grouping=enable_grouping
)
proxy = SubsetFilterProxyModel()
proxy.setSourceModel(model)
proxy.setDynamicSortFilter(True)
proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
family_proxy = FamiliesFilterProxyModel()
family_proxy.setSourceModel(proxy)
subset_filter = QtWidgets.QLineEdit()
subset_filter = QtWidgets.QLineEdit(self)
subset_filter.setPlaceholderText("Filter subsets..")
groupable = QtWidgets.QCheckBox("Enable Grouping")
groupable.setChecked(enable_grouping)
group_checkbox = QtWidgets.QCheckBox("Enable Grouping", self)
group_checkbox.setChecked(enable_grouping)
top_bar_layout = QtWidgets.QHBoxLayout()
top_bar_layout.addWidget(subset_filter)
top_bar_layout.addWidget(groupable)
top_bar_layout.addWidget(group_checkbox)
view = TreeViewSpinner()
view = TreeViewSpinner(self)
view.setModel(family_proxy)
view.setObjectName("SubsetView")
view.setIndentation(20)
view.setStyleSheet("""
QTreeView::item{
padding: 5px 1px;
border: 0px;
}
""")
view.setAllColumnsShowFocus(True)
view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
view.setSortingEnabled(True)
view.sortByColumn(1, QtCore.Qt.AscendingOrder)
view.setAlternatingRowColors(True)
# Set view delegates
version_delegate = VersionDelegate(self.dbcon)
version_delegate = VersionDelegate(self.dbcon, view)
column = model.Columns.index("version")
view.setItemDelegateForColumn(column, version_delegate)
time_delegate = PrettyTimeDelegate()
time_delegate = PrettyTimeDelegate(view)
column = model.Columns.index("time")
view.setItemDelegateForColumn(column, time_delegate)
@ -197,54 +202,39 @@ class SubsetWidget(QtWidgets.QWidget):
layout.addLayout(top_bar_layout)
layout.addWidget(view)
view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
view.setSortingEnabled(True)
view.sortByColumn(1, QtCore.Qt.AscendingOrder)
view.setAlternatingRowColors(True)
self.data = {
"delegates": {
"version": version_delegate,
"time": time_delegate
},
"state": {
"groupable": groupable
}
}
self.proxy = proxy
self.model = model
self.view = view
self.filter = subset_filter
self.family_proxy = family_proxy
# settings and connections
self.proxy.setSourceModel(self.model)
self.proxy.setDynamicSortFilter(True)
self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.view.setModel(self.family_proxy)
self.view.customContextMenuRequested.connect(self.on_context_menu)
for column_name, width in self.default_widths:
idx = model.Columns.index(column_name)
view.setColumnWidth(idx, width)
self.model = model
self.view = view
actual_project = dbcon.Session["AVALON_PROJECT"]
self.on_project_change(actual_project)
view.customContextMenuRequested.connect(self.on_context_menu)
selection = view.selectionModel()
selection.selectionChanged.connect(self.active_changed)
version_delegate.version_changed.connect(self.version_changed)
groupable.stateChanged.connect(self.set_grouping)
group_checkbox.stateChanged.connect(self.set_grouping)
self.filter.textChanged.connect(self.proxy.setFilterRegExp)
self.filter.textChanged.connect(self.view.expandAll)
subset_filter.textChanged.connect(proxy.setFilterRegExp)
subset_filter.textChanged.connect(view.expandAll)
model.refreshed.connect(self.refreshed)
self.proxy = proxy
self.family_proxy = family_proxy
self._subset_filter = subset_filter
self._group_checkbox = group_checkbox
self._version_delegate = version_delegate
self._time_delegate = time_delegate
self.model.refresh()
def get_subsets_families(self):
@ -254,7 +244,7 @@ class SubsetWidget(QtWidgets.QWidget):
self.family_proxy.setFamiliesFilter(families)
def is_groupable(self):
return self.data["state"]["groupable"].checkState()
return self._group_checkbox.isChecked()
def set_grouping(self, state):
with tools_lib.preserve_selection(tree_view=self.view,
@ -755,6 +745,7 @@ class ThumbnailWidget(QtWidgets.QLabel):
"default_thumbnail.png"
)
self.default_pix = QtGui.QPixmap(default_pix_path)
self.set_pixmap()
def height(self):
width = self.width()
@ -786,7 +777,10 @@ class ThumbnailWidget(QtWidgets.QLabel):
def scale_pixmap(self, pixmap):
return pixmap.scaled(
self.width(), self.height(), QtCore.Qt.KeepAspectRatio
self.width(),
self.height(),
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation
)
def set_thumbnail(self, entity=None):
@ -1128,7 +1122,8 @@ class RepresentationWidget(QtWidgets.QWidget):
label = QtWidgets.QLabel("Representations", self)
tree_view = DeselectableTreeView()
tree_view = DeselectableTreeView(parent=self)
tree_view.setObjectName("RepresentationView")
tree_view.setModel(proxy_model)
tree_view.setAllColumnsShowFocus(True)
tree_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
@ -1138,12 +1133,6 @@ class RepresentationWidget(QtWidgets.QWidget):
tree_view.sortByColumn(1, QtCore.Qt.AscendingOrder)
tree_view.setAlternatingRowColors(True)
tree_view.setIndentation(20)
tree_view.setStyleSheet("""
QTreeView::item{
padding: 5px 1px;
border: 0px;
}
""")
tree_view.collapseAll()
for column_name, width in self.default_widths:

View file

@ -28,7 +28,7 @@ class LocalExperimentalToolsWidgets(QtWidgets.QWidget):
layout.addRow(empty_label)
experimental_defs = ExperimentalTools()
experimental_defs = ExperimentalTools(filter_hosts=False)
checkboxes_by_identifier = {}
for tool in experimental_defs.tools:
checkbox = QtWidgets.QCheckBox(self)

View file

@ -7,6 +7,7 @@ import Qt
from Qt import QtWidgets, QtGui, QtCore
from avalon.lib import HeroVersionType
from openpype.style import get_objected_colors
from .models import (
AssetModel,
TreeModel
@ -24,6 +25,19 @@ log = logging.getLogger(__name__)
class AssetDelegate(QtWidgets.QItemDelegate):
bar_height = 3
def __init__(self, *args, **kwargs):
super(AssetDelegate, self).__init__(*args, **kwargs)
asset_view_colors = get_objected_colors()["loader"]["asset-view"]
self._selected_color = (
asset_view_colors["selected"].get_qcolor()
)
self._hover_color = (
asset_view_colors["hover"].get_qcolor()
)
self._selected_hover_color = (
asset_view_colors["selected-hover"].get_qcolor()
)
def sizeHint(self, option, index):
result = super(AssetDelegate, self).sizeHint(option, index)
height = result.height()
@ -66,17 +80,20 @@ class AssetDelegate(QtWidgets.QItemDelegate):
counter += 1
# Background
bg_color = QtGui.QColor(60, 60, 60)
if option.state & QtWidgets.QStyle.State_Selected:
if len(subset_colors) == 0:
item_rect.setTop(item_rect.top() + (self.bar_height / 2))
if option.state & QtWidgets.QStyle.State_MouseOver:
bg_color.setRgb(70, 70, 70)
bg_color = self._selected_hover_color
else:
bg_color = self._selected_color
else:
item_rect.setTop(item_rect.top() + (self.bar_height / 2))
if option.state & QtWidgets.QStyle.State_MouseOver:
bg_color.setAlpha(100)
bg_color = self._hover_color
else:
bg_color = QtGui.QColor()
bg_color.setAlpha(0)
# When not needed to do a rounded corners (easier and without

View file

@ -0,0 +1,398 @@
"""Single access point to all tools usable in hosts.
It is possible to create `HostToolsHelper` in host implementaion or
use singleton approach with global functions (using helper anyway).
"""
import avalon.api
class HostToolsHelper:
"""Create and cache tool windows in memory.
Almost all methods expect parent widget but the parent is used only on
first tool creation.
Class may also contain tools that are available only for one or few hosts.
"""
def __init__(self, parent=None):
self._log = None
# Global parent for all tools (may and may not be set)
self._parent = parent
# Prepare attributes for all tools
self._workfiles_tool = None
self._loader_tool = None
self._creator_tool = None
self._subset_manager_tool = None
self._scene_inventory_tool = None
self._library_loader_tool = None
self._look_assigner_tool = None
self._experimental_tools_dialog = None
@property
def log(self):
if self._log is None:
from openpype.api import Logger
self._log = Logger.get_logger(self.__class__.__name__)
return self._log
def get_workfiles_tool(self, parent):
"""Create, cache and return workfiles tool window."""
if self._workfiles_tool is None:
from openpype.tools.workfiles.app import (
Window, validate_host_requirements
)
# Host validation
host = avalon.api.registered_host()
validate_host_requirements(host)
workfiles_window = Window(parent=parent)
self._workfiles_tool = workfiles_window
return self._workfiles_tool
def show_workfiles(self, parent=None, use_context=None, save=None):
"""Workfiles tool for changing context and saving workfiles."""
from avalon import style
if use_context is None:
use_context = True
if save is None:
save = True
workfiles_tool = self.get_workfiles_tool(parent)
if use_context:
context = {
"asset": avalon.api.Session["AVALON_ASSET"],
"silo": avalon.api.Session["AVALON_SILO"],
"task": avalon.api.Session["AVALON_TASK"]
}
workfiles_tool.set_context(context)
if save:
workfiles_tool.set_save_enabled(save)
workfiles_tool.refresh()
workfiles_tool.show()
# Pull window to the front.
workfiles_tool.raise_()
workfiles_tool.activateWindow()
workfiles_tool.setStyleSheet(style.load_stylesheet())
def get_loader_tool(self, parent):
"""Create, cache and return loader tool window."""
if self._loader_tool is None:
from openpype.tools.loader import LoaderWindow
loader_window = LoaderWindow(parent=parent or self._parent)
self._loader_tool = loader_window
return self._loader_tool
def show_loader(self, parent=None, use_context=None):
"""Loader tool for loading representations."""
loader_tool = self.get_loader_tool(parent)
loader_tool.show()
loader_tool.raise_()
loader_tool.activateWindow()
if use_context is None:
use_context = False
if use_context:
context = {"asset": avalon.api.Session["AVALON_ASSET"]}
loader_tool.set_context(context, refresh=True)
else:
loader_tool.refresh()
def get_creator_tool(self, parent):
"""Create, cache and return creator tool window."""
if self._creator_tool is None:
from avalon.tools.creator.app import Window
creator_window = Window(parent=parent or self._parent)
self._creator_tool = creator_window
return self._creator_tool
def show_creator(self, parent=None):
"""Show tool to create new instantes for publishing."""
from avalon import style
creator_tool = self.get_creator_tool(parent)
creator_tool.refresh()
creator_tool.show()
creator_tool.setStyleSheet(style.load_stylesheet())
# Pull window to the front.
creator_tool.raise_()
creator_tool.activateWindow()
def get_subset_manager_tool(self, parent):
"""Create, cache and return subset manager tool window."""
if self._subset_manager_tool is None:
from avalon.tools.subsetmanager import Window
subset_manager_window = Window(parent=parent or self._parent)
self._subset_manager_tool = subset_manager_window
return self._subset_manager_tool
def show_subset_manager(self, parent=None):
"""Show tool display/remove existing created instances."""
from avalon import style
subset_manager_tool = self.get_subset_manager_tool(parent)
subset_manager_tool.show()
subset_manager_tool.setStyleSheet(style.load_stylesheet())
# Pull window to the front.
subset_manager_tool.raise_()
subset_manager_tool.activateWindow()
def get_scene_inventory_tool(self, parent):
"""Create, cache and return scene inventory tool window."""
if self._scene_inventory_tool is None:
from avalon.tools.sceneinventory.app import Window
scene_inventory_window = Window(parent=parent or self._parent)
self._scene_inventory_tool = scene_inventory_window
return self._scene_inventory_tool
def show_scene_inventory(self, parent=None):
"""Show tool maintain loaded containers."""
from avalon import style
scene_inventory_tool = self.get_scene_inventory_tool(parent)
scene_inventory_tool.show()
scene_inventory_tool.refresh()
scene_inventory_tool.setStyleSheet(style.load_stylesheet())
# Pull window to the front.
scene_inventory_tool.raise_()
scene_inventory_tool.activateWindow()
def get_library_loader_tool(self, parent):
"""Create, cache and return library loader tool window."""
if self._library_loader_tool is None:
from openpype.tools.libraryloader import LibraryLoaderWindow
library_window = LibraryLoaderWindow(
parent=parent or self._parent
)
self._library_loader_tool = library_window
return self._library_loader_tool
def show_library_loader(self, parent=None):
"""Loader tool for loading representations from library project."""
library_loader_tool = self.get_library_loader_tool(parent)
library_loader_tool.show()
library_loader_tool.raise_()
library_loader_tool.activateWindow()
library_loader_tool.refresh()
def show_publish(self, parent=None):
"""Publish UI."""
from avalon.tools import publish
publish.show(parent)
def get_look_assigner_tool(self, parent):
"""Create, cache and return look assigner tool window."""
if self._look_assigner_tool is None:
import mayalookassigner
mayalookassigner_window = mayalookassigner.App(parent)
self._look_assigner_tool = mayalookassigner_window
return self._look_assigner_tool
def show_look_assigner(self, parent=None):
"""Look manager is Maya specific tool for look management."""
from avalon import style
look_assigner_tool = self.get_look_assigner_tool(parent)
look_assigner_tool.show()
look_assigner_tool.setStyleSheet(style.load_stylesheet())
def get_experimental_tools_dialog(self, parent=None):
"""Dialog of experimental tools.
For some hosts it is not easy to modify menu of tools. For
those cases was addded experimental tools dialog which is Qt based
and can dynamically filled by experimental tools so
host need only single "Experimental tools" button to see them.
Dialog can be also empty with a message that there are not available
experimental tools.
"""
if self._experimental_tools_dialog is None:
from openpype.tools.experimental_tools import (
ExperimentalToolsDialog
)
self._experimental_tools_dialog = ExperimentalToolsDialog(parent)
return self._experimental_tools_dialog
def show_experimental_tools_dialog(self, parent=None):
"""Show dialog with experimental tools."""
dialog = self.get_experimental_tools_dialog(parent)
dialog.show()
dialog.raise_()
dialog.activateWindow()
def get_tool_by_name(self, tool_name, parent=None, *args, **kwargs):
"""Show tool by it's name.
This is helper for
"""
if tool_name == "workfiles":
return self.get_workfiles_tool(parent, *args, **kwargs)
elif tool_name == "loader":
return self.get_loader_tool(parent, *args, **kwargs)
elif tool_name == "libraryloader":
return self.get_library_loader_tool(parent, *args, **kwargs)
elif tool_name == "creator":
return self.get_creator_tool(parent, *args, **kwargs)
elif tool_name == "subsetmanager":
return self.get_subset_manager_tool(parent, *args, **kwargs)
elif tool_name == "sceneinventory":
return self.get_scene_inventory_tool(parent, *args, **kwargs)
elif tool_name == "lookassigner":
return self.get_look_assigner_tool(parent, *args, **kwargs)
elif tool_name == "publish":
self.log.info("Can't return publish tool window.")
elif tool_name == "experimental_tools":
return self.get_experimental_tools_dialog(parent, *args, **kwargs)
else:
self.log.warning(
"Can't show unknown tool name: \"{}\"".format(tool_name)
)
def show_tool_by_name(self, tool_name, parent=None, *args, **kwargs):
"""Show tool by it's name.
This is helper for
"""
if tool_name == "workfiles":
self.show_workfiles(parent, *args, **kwargs)
elif tool_name == "loader":
self.show_loader(parent, *args, **kwargs)
elif tool_name == "libraryloader":
self.show_library_loader(parent, *args, **kwargs)
elif tool_name == "creator":
self.show_creator(parent, *args, **kwargs)
elif tool_name == "subsetmanager":
self.show_subset_manager(parent, *args, **kwargs)
elif tool_name == "sceneinventory":
self.show_scene_inventory(parent, *args, **kwargs)
elif tool_name == "lookassigner":
self.show_look_assigner(parent, *args, **kwargs)
elif tool_name == "publish":
self.show_publish(parent, *args, **kwargs)
elif tool_name == "experimental_tools":
self.show_experimental_tools_dialog(parent, *args, **kwargs)
else:
self.log.warning(
"Can't show unknown tool name: \"{}\"".format(tool_name)
)
class _SingletonPoint:
"""Singleton access to host tools.
Some hosts don't have ability to create 'HostToolsHelper' object anc can
only register function callbacks. For those cases is created this singleton
point where 'HostToolsHelper' is created "in shared memory".
"""
helper = None
@classmethod
def _create_helper(cls):
if cls.helper is None:
cls.helper = HostToolsHelper()
@classmethod
def show_tool_by_name(cls, tool_name, parent=None, *args, **kwargs):
cls._create_helper()
cls.helper.show_tool_by_name(tool_name, parent, *args, **kwargs)
@classmethod
def get_tool_by_name(cls, tool_name, parent=None, *args, **kwargs):
cls._create_helper()
return cls.helper.get_tool_by_name(tool_name, parent, *args, **kwargs)
# Function callbacks using singleton acces point
def get_tool_by_name(tool_name, parent=None, *args, **kwargs):
return _SingletonPoint.get_tool_by_name(tool_name, parent, *args, **kwargs)
def show_tool_by_name(tool_name, parent=None, *args, **kwargs):
_SingletonPoint.show_tool_by_name(tool_name, parent, *args, **kwargs)
def show_workfiles(parent=None, use_context=None, save=None):
_SingletonPoint.show_tool_by_name(
"workfiles", parent, use_context=use_context, save=save
)
def show_loader(parent=None, use_context=None):
_SingletonPoint.show_tool_by_name(
"loader", parent, use_context=use_context
)
def show_library_loader(parent=None):
_SingletonPoint.show_tool_by_name("libraryloader", parent)
def show_creator(parent=None):
_SingletonPoint.show_tool_by_name("creator", parent)
def show_subset_manager(parent=None):
_SingletonPoint.show_tool_by_name("subsetmanager", parent)
def show_scene_inventory(parent=None):
_SingletonPoint.show_tool_by_name("sceneinventory", parent)
def show_look_assigner(parent=None):
_SingletonPoint.show_tool_by_name("lookassigner", parent)
def show_publish(parent=None):
_SingletonPoint.show_tool_by_name("publish", parent)
def show_experimental_tools_dialog(parent=None):
_SingletonPoint.show_tool_by_name("experimental_tools", parent)

View file

@ -68,8 +68,8 @@ class AssetsView(TreeViewSpinner, DeselectableTreeView):
This implements a context menu.
"""
def __init__(self):
super(AssetsView, self).__init__()
def __init__(self, parent=None):
super(AssetsView, self).__init__(parent)
self.setIndentation(15)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.setHeaderHidden(True)

View file

@ -35,28 +35,19 @@ class AssetWidget(QtWidgets.QWidget):
self.dbcon = dbcon
self.setContentsMargins(0, 0, 0, 0)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(4)
# Tree View
model = AssetModel(dbcon=self.dbcon, parent=self)
proxy = RecursiveSortFilterProxyModel()
proxy.setSourceModel(model)
proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
view = AssetsView()
view = AssetsView(self)
view.setModel(proxy)
if multiselection:
asset_delegate = AssetDelegate()
view.setSelectionMode(view.ExtendedSelection)
view.setItemDelegate(asset_delegate)
# Header
header = QtWidgets.QHBoxLayout()
icon = qtawesome.icon("fa.arrow-down", color=style.colors.light)
set_current_asset_btn = QtWidgets.QPushButton(icon, "")
set_current_asset_btn.setToolTip("Go to Asset from current Session")
@ -64,22 +55,28 @@ class AssetWidget(QtWidgets.QWidget):
set_current_asset_btn.setVisible(False)
icon = qtawesome.icon("fa.refresh", color=style.colors.light)
refresh = QtWidgets.QPushButton(icon, "")
refresh = QtWidgets.QPushButton(icon, "", parent=self)
refresh.setToolTip("Refresh items")
filter = QtWidgets.QLineEdit()
filter.textChanged.connect(proxy.setFilterFixedString)
filter.setPlaceholderText("Filter assets..")
filter_input = QtWidgets.QLineEdit(self)
filter_input.setPlaceholderText("Filter assets..")
header.addWidget(filter)
header.addWidget(set_current_asset_btn)
header.addWidget(refresh)
# Header
header_layout = QtWidgets.QHBoxLayout()
header_layout.addWidget(filter_input)
header_layout.addWidget(set_current_asset_btn)
header_layout.addWidget(refresh)
# Layout
layout.addLayout(header)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(4)
layout.addLayout(header_layout)
layout.addWidget(view)
# Signals/Slots
filter_input.textChanged.connect(proxy.setFilterFixedString)
selection = view.selectionModel()
selection.selectionChanged.connect(self.selection_changed)
selection.currentChanged.connect(self.current_changed)
@ -313,7 +310,6 @@ class OptionalMenu(QtWidgets.QMenu):
actions that were instances of `QtWidgets.QWidgetAction`.
"""
def mouseReleaseEvent(self, event):
"""Emit option clicked signal if mouse released on it"""
active = self.actionAt(event.pos())
@ -352,6 +348,7 @@ class OptionalAction(QtWidgets.QWidgetAction):
self.use_option = use_option
self.option_tip = ""
self.optioned = False
self.widget = None
def createWidget(self, parent):
widget = OptionalActionWidget(self.label, parent)
@ -377,20 +374,10 @@ class OptionalAction(QtWidgets.QWidgetAction):
self.optioned = True
def set_highlight(self, state, global_pos=None):
body = self.widget.body
option = self.widget.option
role = QtGui.QPalette.Highlight if state else QtGui.QPalette.Window
body.setBackgroundRole(role)
body.setAutoFillBackground(state)
if not self.use_option:
return
state = option.is_hovered(global_pos)
role = QtGui.QPalette.Highlight if state else QtGui.QPalette.Window
option.setBackgroundRole(role)
option.setAutoFillBackground(state)
option_state = False
if self.use_option:
option_state = self.widget.option.is_hovered(global_pos)
self.widget.set_hover_properties(state, option_state)
class OptionalActionWidget(QtWidgets.QWidget):
@ -399,30 +386,33 @@ class OptionalActionWidget(QtWidgets.QWidget):
def __init__(self, label, parent=None):
super(OptionalActionWidget, self).__init__(parent)
body = QtWidgets.QWidget()
body.setStyleSheet("background: transparent;")
body_widget = QtWidgets.QWidget(self)
body_widget.setObjectName("OptionalActionBody")
icon = QtWidgets.QLabel()
label = QtWidgets.QLabel(label)
option = OptionBox(body)
icon = QtWidgets.QLabel(body_widget)
label = QtWidgets.QLabel(label, body_widget)
# (NOTE) For removing ugly QLable shadow FX when highlighted in Nuke.
# See https://stackoverflow.com/q/52838690/4145300
label.setStyle(QtWidgets.QStyleFactory.create("Plastique"))
option = OptionBox(body_widget)
option.setObjectName("OptionalActionOption")
icon.setFixedSize(24, 16)
option.setFixedSize(30, 30)
layout = QtWidgets.QHBoxLayout(body)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(2)
layout.addWidget(icon)
layout.addWidget(label)
layout.addSpacing(6)
body_layout = QtWidgets.QHBoxLayout(body_widget)
body_layout.setContentsMargins(4, 0, 4, 0)
body_layout.setSpacing(2)
body_layout.addWidget(icon)
body_layout.addWidget(label)
layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(6, 1, 2, 1)
layout.setContentsMargins(2, 1, 2, 1)
layout.setSpacing(0)
layout.addWidget(body)
layout.addWidget(body_widget)
layout.addWidget(option)
body.setMouseTracking(True)
body_widget.setMouseTracking(True)
label.setMouseTracking(True)
option.setMouseTracking(True)
self.setMouseTracking(True)
@ -431,11 +421,24 @@ class OptionalActionWidget(QtWidgets.QWidget):
self.icon = icon
self.label = label
self.option = option
self.body = body
self.body = body_widget
# (NOTE) For removing ugly QLable shadow FX when highlighted in Nuke.
# See https://stackoverflow.com/q/52838690/4145300
label.setStyle(QtWidgets.QStyleFactory.create("Plastique"))
def set_hover_properties(self, hovered, option_hovered):
body_state = ""
option_state = ""
if hovered:
body_state = "hover"
if option_hovered:
option_state = "hover"
if self.body.property("state") != body_state:
self.body.setProperty("state", body_state)
self.body.style().polish(self.body)
if self.option.property("state") != option_state:
self.option.setProperty("state", option_state)
self.option.style().polish(self.option)
def setIcon(self, icon):
pixmap = icon.pixmap(16, 16)
@ -456,8 +459,6 @@ class OptionBox(QtWidgets.QLabel):
pixmap = icon.pixmap(18, 18)
self.setPixmap(pixmap)
self.setStyleSheet("background: transparent;")
def is_hovered(self, global_pos):
if global_pos is None:
return False
@ -476,20 +477,20 @@ class OptionDialog(QtWidgets.QDialog):
def create(self, options):
parser = qargparse.QArgumentParser(arguments=options)
decision = QtWidgets.QWidget()
accept = QtWidgets.QPushButton("Accept")
cancel = QtWidgets.QPushButton("Cancel")
decision_widget = QtWidgets.QWidget(self)
accept_btn = QtWidgets.QPushButton("Accept", decision_widget)
cancel_btn = QtWidgets.QPushButton("Cancel", decision_widget)
layout = QtWidgets.QHBoxLayout(decision)
layout.addWidget(accept)
layout.addWidget(cancel)
decision_layout = QtWidgets.QHBoxLayout(decision_widget)
decision_layout.addWidget(accept_btn)
decision_layout.addWidget(cancel_btn)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(parser)
layout.addWidget(decision)
layout.addWidget(decision_widget)
accept.clicked.connect(self.accept)
cancel.clicked.connect(self.reject)
accept_btn.clicked.connect(self.accept)
cancel_btn.clicked.connect(self.reject)
parser.changed.connect(self.on_changed)
def on_changed(self, argument):

View file

@ -944,7 +944,10 @@ class Window(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent=parent)
self.setWindowTitle(self.title)
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint)
window_flags = QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint
if not parent:
window_flags |= QtCore.Qt.WindowStaysOnTopHint
self.setWindowFlags(window_flags)
# Create pages widget and set it as central widget
pages_widget = QtWidgets.QStackedWidget(self)
@ -1015,6 +1018,9 @@ class Window(QtWidgets.QMainWindow):
"""
def set_save_enabled(self, enabled):
self.files_widget.btn_save.setEnabled(enabled)
def on_task_changed(self):
# Since we query the disk give it slightly more delay
tools_lib.schedule(self._on_task_changed, 100, channel="mongo")
@ -1187,7 +1193,7 @@ def show(root=None, debug=False, parent=None, use_context=True, save=True):
}
window.set_context(context)
window.files_widget.btn_save.setEnabled(save)
window.set_save_enabled(save)
window.show()
window.setStyleSheet(style.load_stylesheet())

94
poetry.lock generated
View file

@ -782,7 +782,7 @@ six = "*"
[[package]]
name = "pillow"
version = "8.2.0"
version = "8.3.2"
description = "Python Imaging Library (Fork)"
category = "main"
optional = false
@ -1538,7 +1538,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt
[metadata]
lock-version = "1.1"
python-versions = "3.7.*"
content-hash = "ff2bfa35a7304378917a0c25d7d7af9f81a130288d95789bdf7429f071e80b69"
content-hash = "fb6db80d126fe7ef2d1d06d0381b6d11445d6d3e54b33585f6b0a0b6b0b9d372"
[metadata.files]
acre = []
@ -2058,40 +2058,59 @@ pathlib2 = [
{file = "pathlib2-2.3.5.tar.gz", hash = "sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"},
]
pillow = [
{file = "Pillow-8.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:dc38f57d8f20f06dd7c3161c59ca2c86893632623f33a42d592f097b00f720a9"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a013cbe25d20c2e0c4e85a9daf438f85121a4d0344ddc76e33fd7e3965d9af4b"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8bb1e155a74e1bfbacd84555ea62fa21c58e0b4e7e6b20e4447b8d07990ac78b"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c5236606e8570542ed424849f7852a0ff0bce2c4c8d0ba05cc202a5a9c97dee9"},
{file = "Pillow-8.2.0-cp36-cp36m-win32.whl", hash = "sha256:12e5e7471f9b637762453da74e390e56cc43e486a88289995c1f4c1dc0bfe727"},
{file = "Pillow-8.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5afe6b237a0b81bd54b53f835a153770802f164c5570bab5e005aad693dab87f"},
{file = "Pillow-8.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:cb7a09e173903541fa888ba010c345893cd9fc1b5891aaf060f6ca77b6a3722d"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0d19d70ee7c2ba97631bae1e7d4725cdb2ecf238178096e8c82ee481e189168a"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:083781abd261bdabf090ad07bb69f8f5599943ddb539d64497ed021b2a67e5a9"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c6b39294464b03457f9064e98c124e09008b35a62e3189d3513e5148611c9388"},
{file = "Pillow-8.2.0-cp37-cp37m-win32.whl", hash = "sha256:01425106e4e8cee195a411f729cff2a7d61813b0b11737c12bd5991f5f14bcd5"},
{file = "Pillow-8.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3b570f84a6161cf8865c4e08adf629441f56e32f180f7aa4ccbd2e0a5a02cba2"},
{file = "Pillow-8.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:031a6c88c77d08aab84fecc05c3cde8414cd6f8406f4d2b16fed1e97634cc8a4"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:66cc56579fd91f517290ab02c51e3a80f581aba45fd924fcdee01fa06e635812"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c32cc3145928c4305d142ebec682419a6c0a8ce9e33db900027ddca1ec39178"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:624b977355cde8b065f6d51b98497d6cd5fbdd4f36405f7a8790e3376125e2bb"},
{file = "Pillow-8.2.0-cp38-cp38-win32.whl", hash = "sha256:5cbf3e3b1014dddc45496e8cf38b9f099c95a326275885199f427825c6522232"},
{file = "Pillow-8.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:463822e2f0d81459e113372a168f2ff59723e78528f91f0bd25680ac185cf797"},
{file = "Pillow-8.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:95d5ef984eff897850f3a83883363da64aae1000e79cb3c321915468e8c6add5"},
{file = "Pillow-8.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b91c36492a4bbb1ee855b7d16fe51379e5f96b85692dc8210831fbb24c43e484"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d68cb92c408261f806b15923834203f024110a2e2872ecb0bd2a110f89d3c602"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f217c3954ce5fd88303fc0c317af55d5e0204106d86dea17eb8205700d47dec2"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5b70110acb39f3aff6b74cf09bb4169b167e2660dabc304c1e25b6555fa781ef"},
{file = "Pillow-8.2.0-cp39-cp39-win32.whl", hash = "sha256:a7d5e9fad90eff8f6f6106d3b98b553a88b6f976e51fce287192a5d2d5363713"},
{file = "Pillow-8.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:238c197fc275b475e87c1453b05b467d2d02c2915fdfdd4af126145ff2e4610c"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0e04d61f0064b545b989126197930807c86bcbd4534d39168f4aa5fda39bb8f9"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_i686.whl", hash = "sha256:63728564c1410d99e6d1ae8e3b810fe012bc440952168af0a2877e8ff5ab96b9"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c03c07ed32c5324939b19e36ae5f75c660c81461e312a41aea30acdd46f93a7c"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:4d98abdd6b1e3bf1a1cbb14c3895226816e666749ac040c4e2554231068c639b"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8b56553c0345ad6dcb2e9b433ae47d67f95fc23fe28a0bde15a120f25257e291"},
{file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
{file = "Pillow-8.3.2-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:c691b26283c3a31594683217d746f1dad59a7ae1d4cfc24626d7a064a11197d4"},
{file = "Pillow-8.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f514c2717012859ccb349c97862568fdc0479aad85b0270d6b5a6509dbc142e2"},
{file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be25cb93442c6d2f8702c599b51184bd3ccd83adebd08886b682173e09ef0c3f"},
{file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d675a876b295afa114ca8bf42d7f86b5fb1298e1b6bb9a24405a3f6c8338811c"},
{file = "Pillow-8.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59697568a0455764a094585b2551fd76bfd6b959c9f92d4bdec9d0e14616303a"},
{file = "Pillow-8.3.2-cp310-cp310-win32.whl", hash = "sha256:2d5e9dc0bf1b5d9048a94c48d0813b6c96fccfa4ccf276d9c36308840f40c228"},
{file = "Pillow-8.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:11c27e74bab423eb3c9232d97553111cc0be81b74b47165f07ebfdd29d825875"},
{file = "Pillow-8.3.2-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:11eb7f98165d56042545c9e6db3ce394ed8b45089a67124298f0473b29cb60b2"},
{file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f23b2d3079522fdf3c09de6517f625f7a964f916c956527bed805ac043799b8"},
{file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19ec4cfe4b961edc249b0e04b5618666c23a83bc35842dea2bfd5dfa0157f81b"},
{file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5a31c07cea5edbaeb4bdba6f2b87db7d3dc0f446f379d907e51cc70ea375629"},
{file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15ccb81a6ffc57ea0137f9f3ac2737ffa1d11f786244d719639df17476d399a7"},
{file = "Pillow-8.3.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8f284dc1695caf71a74f24993b7c7473d77bc760be45f776a2c2f4e04c170550"},
{file = "Pillow-8.3.2-cp36-cp36m-win32.whl", hash = "sha256:4abc247b31a98f29e5224f2d31ef15f86a71f79c7f4d2ac345a5d551d6393073"},
{file = "Pillow-8.3.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a048dad5ed6ad1fad338c02c609b862dfaa921fcd065d747194a6805f91f2196"},
{file = "Pillow-8.3.2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:06d1adaa284696785375fa80a6a8eb309be722cf4ef8949518beb34487a3df71"},
{file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd24054aaf21e70a51e2a2a5ed1183560d3a69e6f9594a4bfe360a46f94eba83"},
{file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a330bf7014ee034046db43ccbb05c766aa9e70b8d6c5260bfc38d73103b0ba"},
{file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13654b521fb98abdecec105ea3fb5ba863d1548c9b58831dd5105bb3873569f1"},
{file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1bd983c565f92779be456ece2479840ec39d386007cd4ae83382646293d681b"},
{file = "Pillow-8.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4326ea1e2722f3dc00ed77c36d3b5354b8fb7399fb59230249ea6d59cbed90da"},
{file = "Pillow-8.3.2-cp37-cp37m-win32.whl", hash = "sha256:085a90a99404b859a4b6c3daa42afde17cb3ad3115e44a75f0d7b4a32f06a6c9"},
{file = "Pillow-8.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:18a07a683805d32826c09acfce44a90bf474e6a66ce482b1c7fcd3757d588df3"},
{file = "Pillow-8.3.2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4e59e99fd680e2b8b11bbd463f3c9450ab799305d5f2bafb74fefba6ac058616"},
{file = "Pillow-8.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4d89a2e9219a526401015153c0e9dd48319ea6ab9fe3b066a20aa9aee23d9fd3"},
{file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56fd98c8294f57636084f4b076b75f86c57b2a63a8410c0cd172bc93695ee979"},
{file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b11c9d310a3522b0fd3c35667914271f570576a0e387701f370eb39d45f08a4"},
{file = "Pillow-8.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0412516dcc9de9b0a1e0ae25a280015809de8270f134cc2c1e32c4eeb397cf30"},
{file = "Pillow-8.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bcb04ff12e79b28be6c9988f275e7ab69f01cc2ba319fb3114f87817bb7c74b6"},
{file = "Pillow-8.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0b9911ec70731711c3b6ebcde26caea620cbdd9dcb73c67b0730c8817f24711b"},
{file = "Pillow-8.3.2-cp38-cp38-win32.whl", hash = "sha256:ce2e5e04bb86da6187f96d7bab3f93a7877830981b37f0287dd6479e27a10341"},
{file = "Pillow-8.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:35d27687f027ad25a8d0ef45dd5208ef044c588003cdcedf05afb00dbc5c2deb"},
{file = "Pillow-8.3.2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:04835e68ef12904bc3e1fd002b33eea0779320d4346082bd5b24bec12ad9c3e9"},
{file = "Pillow-8.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10e00f7336780ca7d3653cf3ac26f068fa11b5a96894ea29a64d3dc4b810d630"},
{file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cde7a4d3687f21cffdf5bb171172070bb95e02af448c4c8b2f223d783214056"},
{file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c3ff00110835bdda2b1e2b07f4a2548a39744bb7de5946dc8e95517c4fb2ca6"},
{file = "Pillow-8.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d409030bf3bd05fa66fb5fdedc39c521b397f61ad04309c90444e893d05f7d"},
{file = "Pillow-8.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bff50ba9891be0a004ef48828e012babaaf7da204d81ab9be37480b9020a82b"},
{file = "Pillow-8.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7dbfbc0020aa1d9bc1b0b8bcf255a7d73f4ad0336f8fd2533fcc54a4ccfb9441"},
{file = "Pillow-8.3.2-cp39-cp39-win32.whl", hash = "sha256:963ebdc5365d748185fdb06daf2ac758116deecb2277ec5ae98139f93844bc09"},
{file = "Pillow-8.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:cc9d0dec711c914ed500f1d0d3822868760954dce98dfb0b7382a854aee55d19"},
{file = "Pillow-8.3.2-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2c661542c6f71dfd9dc82d9d29a8386287e82813b0375b3a02983feac69ef864"},
{file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:548794f99ff52a73a156771a0402f5e1c35285bd981046a502d7e4793e8facaa"},
{file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b68f565a4175e12e68ca900af8910e8fe48aaa48fd3ca853494f384e11c8bcd"},
{file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:838eb85de6d9307c19c655c726f8d13b8b646f144ca6b3771fa62b711ebf7624"},
{file = "Pillow-8.3.2-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:feb5db446e96bfecfec078b943cc07744cc759893cef045aa8b8b6d6aaa8274e"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:fc0db32f7223b094964e71729c0361f93db43664dd1ec86d3df217853cedda87"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd4fd83aa912d7b89b4b4a1580d30e2a4242f3936882a3f433586e5ab97ed0d5"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d0c8ebbfd439c37624db98f3877d9ed12c137cadd99dde2d2eae0dab0bbfc355"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cb3dd7f23b044b0737317f892d399f9e2f0b3a02b22b2c692851fb8120d82c6"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a66566f8a22561fc1a88dc87606c69b84fa9ce724f99522cf922c801ec68f5c1"},
{file = "Pillow-8.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ce651ca46d0202c302a535d3047c55a0131a720cf554a578fc1b8a2aff0e7d96"},
{file = "Pillow-8.3.2.tar.gz", hash = "sha256:dde3f3ed8d00c72631bc19cbfff8ad3b6215062a5eed402381ad365f82f0c18c"},
]
pluggy = [
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
@ -2294,6 +2313,7 @@ pynput = [
pyobjc-core = [
{file = "pyobjc-core-7.3.tar.gz", hash = "sha256:5081aedf8bb40aac1a8ad95adac9e44e148a882686ded614adf46bb67fd67574"},
{file = "pyobjc_core-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a1f1e6b457127cbf2b5bd2b94520a7c89fb590b739911eadb2b0499a3a5b0e6f"},
{file = "pyobjc_core-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:ed708cc47bae8b711f81f252af09898a5f986c7a38cec5ad5623d571d328bff8"},
{file = "pyobjc_core-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e93ad769a20b908778fe950f62a843a6d8f0fa71996e5f3cc9fab5ae7d17771"},
{file = "pyobjc_core-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f63fd37bbf3785af4ddb2f86cad5ca81c62cfc7d1c0099637ca18343c3656c1"},
{file = "pyobjc_core-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9b1311f72f2e170742a7ee3a8149f52c35158dc024a21e88d6f1e52ba5d718b"},
@ -2303,6 +2323,7 @@ pyobjc-core = [
pyobjc-framework-cocoa = [
{file = "pyobjc-framework-Cocoa-7.3.tar.gz", hash = "sha256:b18d05e7a795a3455ad191c3e43d6bfa673c2a4fd480bb1ccf57191051b80b7e"},
{file = "pyobjc_framework_Cocoa-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1e31376806e5de883a1d7c7c87d9ff2a8b09fc05d267e0dfce6e42409fb70c67"},
{file = "pyobjc_framework_Cocoa-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d999387927284346035cb63ebb51f86331abc41f9376f9a6970e7f18207db392"},
{file = "pyobjc_framework_Cocoa-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9edffdfa6dd1f71f21b531c3e61fdd3e4d5d3bf6c5a528c98e88828cd60bac11"},
{file = "pyobjc_framework_Cocoa-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:35a6340437a4e0109a302150b7d1f6baf57004ccf74834f9e6062fcafe2fd8d7"},
{file = "pyobjc_framework_Cocoa-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c3886f2608ab3ed02482f8b2ebf9f782b324c559e84b52cfd92dba8a1109872"},
@ -2312,6 +2333,7 @@ pyobjc-framework-cocoa = [
pyobjc-framework-quartz = [
{file = "pyobjc-framework-Quartz-7.3.tar.gz", hash = "sha256:98812844c34262def980bdf60923a875cd43428a8375b6fd53bd2cd800eccf0b"},
{file = "pyobjc_framework_Quartz-7.3-1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1139bc6874c0f8b58f0b8602015e0994198bc506a6bcec1071208de32b55ed26"},
{file = "pyobjc_framework_Quartz-7.3-1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d94a3ed7051266c52392ec07d3b5adbf28d4be83341a24df0d88639344dcd84f"},
{file = "pyobjc_framework_Quartz-7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ef18f5a16511ded65980bf4f5983ea5d35c88224dbad1b3112abd29c60413ea"},
{file = "pyobjc_framework_Quartz-7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b41eec8d4b10c7c7e011e2f9051367f5499ef315ba52dfbae573c3a2e05469c"},
{file = "pyobjc_framework_Quartz-7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c65456ed045dfe1711d0298734e5a3ad670f8c770f7eb3b19979256c388bdd2"},

View file

@ -45,7 +45,7 @@ jsonschema = "^3.2.0"
keyring = "^22.0.1"
log4mongo = "^1.7"
pathlib2= "^2.3.5" # deadline submit publish job only (single place, maybe not needed?)
Pillow = "^8.1" # only used for slates prototype
Pillow = "^8.3" # only used for slates prototype
pyblish-base = "^1.8.8"
pynput = "^1.7.2" # idle manager in tray
pymongo = "^3.11.2"

View file

@ -27,7 +27,7 @@ def get_release_type_github(Log, github_token):
return "minor"
if any(label in labels for label in patch_labels):
return "path"
return "patch"
return None

View file

@ -116,8 +116,8 @@ module.exports = {
// Optional: Algolia search parameters
searchParameters: {},
},
googleAnalytics: {
trackingID: 'G-HHJZ9VF0FG',
gtag: {
trackingID: 'G-DTKXMFENFY',
// Optional fields.
anonymizeIP: false, // Should IPs be anonymized?
},

View file

@ -2175,11 +2175,11 @@ autoprefixer@^10.0.2, autoprefixer@^10.2.5:
postcss-value-parser "^4.1.0"
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.10.0"
follow-redirects "^1.14.0"
babel-loader@^8.2.2:
version "8.2.2"
@ -3982,10 +3982,10 @@ flux@^4.0.1:
fbemitter "^3.0.0"
fbjs "^3.0.0"
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==
follow-redirects@^1.0.0, follow-redirects@^1.14.0:
version "1.14.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
for-in@^1.0.2:
version "1.0.2"