mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' of github.com:pypeclub/OpenPype into chore/add_validate_frame_range_to_traypublisher
This commit is contained in:
commit
b32f153a9c
12 changed files with 199 additions and 66 deletions
54
CHANGELOG.md
54
CHANGELOG.md
|
|
@ -1,8 +1,35 @@
|
|||
# Changelog
|
||||
|
||||
## [3.12.2-nightly.1](https://github.com/pypeclub/OpenPype/tree/HEAD)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.12.1...HEAD)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- Ftrack: Automatic daily review session creation can define trigger hour [\#3516](https://github.com/pypeclub/OpenPype/pull/3516)
|
||||
- Ftrack: add source into Note [\#3509](https://github.com/pypeclub/OpenPype/pull/3509)
|
||||
- Ftrack: Trigger custom ftrack topic of project structure creation [\#3506](https://github.com/pypeclub/OpenPype/pull/3506)
|
||||
- Settings UI: Add extract to file action on project view [\#3505](https://github.com/pypeclub/OpenPype/pull/3505)
|
||||
- General: Event system [\#3499](https://github.com/pypeclub/OpenPype/pull/3499)
|
||||
- NewPublisher: Keep plugins with mismatch target in report [\#3498](https://github.com/pypeclub/OpenPype/pull/3498)
|
||||
- Nuke: load clip with options from settings [\#3497](https://github.com/pypeclub/OpenPype/pull/3497)
|
||||
- Migrate basic families to the new Tray Publisher [\#3469](https://github.com/pypeclub/OpenPype/pull/3469)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- General: Fix hash of centos oiio archive [\#3519](https://github.com/pypeclub/OpenPype/pull/3519)
|
||||
- TrayPublisher: Simple creation enhancements and fixes [\#3513](https://github.com/pypeclub/OpenPype/pull/3513)
|
||||
- NewPublisher: Publish attributes are properly collected [\#3510](https://github.com/pypeclub/OpenPype/pull/3510)
|
||||
- TrayPublisher: Make sure host name is filled [\#3504](https://github.com/pypeclub/OpenPype/pull/3504)
|
||||
- NewPublisher: Groups work and enum multivalue [\#3501](https://github.com/pypeclub/OpenPype/pull/3501)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
- TimersManager: Use query functions [\#3495](https://github.com/pypeclub/OpenPype/pull/3495)
|
||||
|
||||
## [3.12.1](https://github.com/pypeclub/OpenPype/tree/3.12.1) (2022-07-13)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.12.0...3.12.1)
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.12.1-nightly.6...3.12.1)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
|
|
@ -45,8 +72,6 @@
|
|||
- LogViewer: Escape html characters in log message [\#3443](https://github.com/pypeclub/OpenPype/pull/3443)
|
||||
- Nuke: Slate frame is integrated [\#3427](https://github.com/pypeclub/OpenPype/pull/3427)
|
||||
- Maya: Camera extra data - additional fix for \#3304 [\#3386](https://github.com/pypeclub/OpenPype/pull/3386)
|
||||
- Maya: Handle excluding `model` family from frame range validator. [\#3370](https://github.com/pypeclub/OpenPype/pull/3370)
|
||||
- Harmony: audio validator has wrong logic [\#3364](https://github.com/pypeclub/OpenPype/pull/3364)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
|
|
@ -76,7 +101,6 @@
|
|||
|
||||
- Webserver: Added CORS middleware [\#3422](https://github.com/pypeclub/OpenPype/pull/3422)
|
||||
- Attribute Defs UI: Files widget show what is allowed to drop in [\#3411](https://github.com/pypeclub/OpenPype/pull/3411)
|
||||
- General: Add ability to change user value for templates [\#3366](https://github.com/pypeclub/OpenPype/pull/3366)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
|
|
@ -87,10 +111,7 @@
|
|||
- Nuke: Collect representation files based on Write [\#3407](https://github.com/pypeclub/OpenPype/pull/3407)
|
||||
- General: Filter representations before integration start [\#3398](https://github.com/pypeclub/OpenPype/pull/3398)
|
||||
- Maya: look collector typo [\#3392](https://github.com/pypeclub/OpenPype/pull/3392)
|
||||
- TVPaint: Make sure exit code is set to not None [\#3382](https://github.com/pypeclub/OpenPype/pull/3382)
|
||||
- Maya: vray device aspect ratio fix [\#3381](https://github.com/pypeclub/OpenPype/pull/3381)
|
||||
- Flame: bunch of publishing issues [\#3377](https://github.com/pypeclub/OpenPype/pull/3377)
|
||||
- Harmony: added unc path to zifile command in Harmony [\#3372](https://github.com/pypeclub/OpenPype/pull/3372)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
|
|
@ -101,30 +122,11 @@
|
|||
- Hiero: Use client query functions [\#3393](https://github.com/pypeclub/OpenPype/pull/3393)
|
||||
- Nuke: Use client query functions [\#3391](https://github.com/pypeclub/OpenPype/pull/3391)
|
||||
- Maya: Use client query functions [\#3385](https://github.com/pypeclub/OpenPype/pull/3385)
|
||||
- Harmony: Use client query functions [\#3378](https://github.com/pypeclub/OpenPype/pull/3378)
|
||||
- Celaction: Use client query functions [\#3376](https://github.com/pypeclub/OpenPype/pull/3376)
|
||||
- Photoshop: Use client query functions [\#3375](https://github.com/pypeclub/OpenPype/pull/3375)
|
||||
- AfterEffects: Use client query functions [\#3374](https://github.com/pypeclub/OpenPype/pull/3374)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Sync Queue: Added far future value for null values for dates [\#3371](https://github.com/pypeclub/OpenPype/pull/3371)
|
||||
- Maya - added support for single frame playblast review [\#3369](https://github.com/pypeclub/OpenPype/pull/3369)
|
||||
|
||||
## [3.11.1](https://github.com/pypeclub/OpenPype/tree/3.11.1) (2022-06-20)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.11.1-nightly.1...3.11.1)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- Pyblish Pype: Hiding/Close issues [\#3367](https://github.com/pypeclub/OpenPype/pull/3367)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- Nuke: bake streams with slate on farm [\#3368](https://github.com/pypeclub/OpenPype/pull/3368)
|
||||
- Nuke: Fix missing variable in extract thumbnail [\#3363](https://github.com/pypeclub/OpenPype/pull/3363)
|
||||
- Nuke: Fix precollect writes [\#3361](https://github.com/pypeclub/OpenPype/pull/3361)
|
||||
|
||||
## [3.11.0](https://github.com/pypeclub/OpenPype/tree/3.11.0) (2022-06-17)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.11.0-nightly.4...3.11.0)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import collections
|
|||
import ftrack_api
|
||||
|
||||
from openpype.lib import get_datetime_data
|
||||
from openpype.api import get_project_settings
|
||||
from openpype.settings.lib import (
|
||||
get_project_settings,
|
||||
get_default_project_settings
|
||||
)
|
||||
from openpype_modules.ftrack.lib import ServerAction
|
||||
|
||||
|
||||
|
|
@ -79,6 +82,35 @@ class CreateDailyReviewSessionServerAction(ServerAction):
|
|||
)
|
||||
return True
|
||||
|
||||
def _calculate_next_cycle_delta(self):
|
||||
studio_default_settings = get_default_project_settings()
|
||||
action_settings = (
|
||||
studio_default_settings
|
||||
["ftrack"]
|
||||
[self.settings_frack_subkey]
|
||||
[self.settings_key]
|
||||
)
|
||||
cycle_hour_start = action_settings.get("cycle_hour_start")
|
||||
if not cycle_hour_start:
|
||||
h = m = s = 0
|
||||
else:
|
||||
h, m, s = cycle_hour_start
|
||||
|
||||
# Create threading timer which will trigger creation of report
|
||||
# at the 00:00:01 of next day
|
||||
# - callback will trigger another timer which will have 1 day offset
|
||||
now = datetime.datetime.now()
|
||||
# Create object of today morning
|
||||
expected_next_trigger = datetime.datetime(
|
||||
now.year, now.month, now.day, h, m, s
|
||||
)
|
||||
if expected_next_trigger > now:
|
||||
seconds = (expected_next_trigger - now).total_seconds()
|
||||
else:
|
||||
expected_next_trigger += self._day_delta
|
||||
seconds = (expected_next_trigger - now).total_seconds()
|
||||
return seconds, expected_next_trigger
|
||||
|
||||
def register(self, *args, **kwargs):
|
||||
"""Override register to be able trigger """
|
||||
# Register server action as would be normally
|
||||
|
|
@ -86,22 +118,14 @@ class CreateDailyReviewSessionServerAction(ServerAction):
|
|||
*args, **kwargs
|
||||
)
|
||||
|
||||
# Create threading timer which will trigger creation of report
|
||||
# at the 00:00:01 of next day
|
||||
# - callback will trigger another timer which will have 1 day offset
|
||||
now = datetime.datetime.now()
|
||||
# Create object of today morning
|
||||
today_morning = datetime.datetime(
|
||||
now.year, now.month, now.day, 0, 0, 1
|
||||
)
|
||||
# Add a day delta (to calculate next day date)
|
||||
next_day_morning = today_morning + self._day_delta
|
||||
# Calculate first delta in seconds for first threading timer
|
||||
first_delta = (next_day_morning - now).total_seconds()
|
||||
seconds_delta, cycle_time = self._calculate_next_cycle_delta()
|
||||
|
||||
# Store cycle time which will be used to create next timer
|
||||
self._last_cyle_time = next_day_morning
|
||||
self._last_cyle_time = cycle_time
|
||||
# Create timer thread
|
||||
self._cycle_timer = threading.Timer(first_delta, self._timer_callback)
|
||||
self._cycle_timer = threading.Timer(
|
||||
seconds_delta, self._timer_callback
|
||||
)
|
||||
self._cycle_timer.start()
|
||||
|
||||
self._check_review_session()
|
||||
|
|
@ -111,13 +135,12 @@ class CreateDailyReviewSessionServerAction(ServerAction):
|
|||
self._cycle_timer is not None
|
||||
and self._last_cyle_time is not None
|
||||
):
|
||||
now = datetime.datetime.now()
|
||||
while self._last_cyle_time < now:
|
||||
self._last_cyle_time = self._last_cyle_time + self._day_delta
|
||||
seconds_delta, cycle_time = self._calculate_next_cycle_delta()
|
||||
self._last_cyle_time = cycle_time
|
||||
|
||||
delay = (self._last_cyle_time - now).total_seconds()
|
||||
|
||||
self._cycle_timer = threading.Timer(delay, self._timer_callback)
|
||||
self._cycle_timer = threading.Timer(
|
||||
seconds_delta, self._timer_callback
|
||||
)
|
||||
self._cycle_timer.start()
|
||||
self._check_review_session()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
|||
"imagesequence", "render", "render2d", "prerender",
|
||||
"source", "plate", "take"
|
||||
]
|
||||
hosts = ["shell", "fusion", "resolve"]
|
||||
hosts = ["shell", "fusion", "resolve", "traypublisher"]
|
||||
enabled = False
|
||||
|
||||
# presetable attribute
|
||||
|
|
@ -46,6 +46,10 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
|||
self.log.info("Skipping - no review set on instance.")
|
||||
return
|
||||
|
||||
if self._already_has_thumbnail(instance):
|
||||
self.log.info("Thumbnail representation already present.")
|
||||
return
|
||||
|
||||
filtered_repres = self._get_filtered_repres(instance)
|
||||
for repre in filtered_repres:
|
||||
repre_files = repre["files"]
|
||||
|
|
@ -102,6 +106,14 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
|
|||
# There is no need to create more then one thumbnail
|
||||
break
|
||||
|
||||
def _already_has_thumbnail(self, instance):
|
||||
for repre in instance.data.get("representations", []):
|
||||
self.log.info("repre {}".format(repre))
|
||||
if repre["name"] == "thumbnail":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _get_filtered_repres(self, instance):
|
||||
filtered_repres = []
|
||||
src_repres = instance.data.get("representations") or []
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@
|
|||
"Project Manager"
|
||||
],
|
||||
"cycle_enabled": false,
|
||||
"cycle_hour_start": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"review_session_template": "{yy}{mm}{dd}"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -410,7 +410,41 @@
|
|||
{
|
||||
"type": "boolean",
|
||||
"key": "cycle_enabled",
|
||||
"label": "Create daily review session"
|
||||
"label": "Run automatically every day"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "list-strict",
|
||||
"key": "cycle_hour_start",
|
||||
"label": "Create daily review session at",
|
||||
"tooltip": "This may take affect on next day",
|
||||
"object_types": [
|
||||
{
|
||||
"label": "H:",
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 23,
|
||||
"decimal": 0
|
||||
}, {
|
||||
"label": "M:",
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 59,
|
||||
"decimal": 0
|
||||
}, {
|
||||
"label": "S:",
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 59,
|
||||
"decimal": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "This can't be overriden per project and any change will take effect on the next day or on restart of event server."
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ class GroupWidget(QtWidgets.QWidget):
|
|||
instances(list<CreatedInstance>): List of instances in
|
||||
CreateContext.
|
||||
"""
|
||||
|
||||
# Store instances by id and by subset name
|
||||
instances_by_id = {}
|
||||
instances_by_subset_name = collections.defaultdict(list)
|
||||
|
|
@ -142,6 +143,7 @@ class GroupWidget(QtWidgets.QWidget):
|
|||
|
||||
class CardWidget(BaseClickableFrame):
|
||||
"""Clickable card used as bigger button."""
|
||||
|
||||
selected = QtCore.Signal(str, str)
|
||||
# Group identifier of card
|
||||
# - this must be set because if send when mouse is released with card id
|
||||
|
|
@ -178,6 +180,7 @@ class ContextCardWidget(CardWidget):
|
|||
|
||||
Is not visually under group widget and is always at the top of card view.
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
super(ContextCardWidget, self).__init__(parent)
|
||||
|
||||
|
|
@ -204,13 +207,14 @@ class ContextCardWidget(CardWidget):
|
|||
|
||||
class InstanceCardWidget(CardWidget):
|
||||
"""Card widget representing instance."""
|
||||
|
||||
active_changed = QtCore.Signal()
|
||||
|
||||
def __init__(self, instance, group_icon, parent):
|
||||
super(InstanceCardWidget, self).__init__(parent)
|
||||
|
||||
self._id = instance.id
|
||||
self._group_identifier = instance.creator_label
|
||||
self._group_identifier = instance.group_label
|
||||
self._group_icon = group_icon
|
||||
|
||||
self.instance = instance
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from .widgets import (
|
||||
CustomTextComboBox,
|
||||
PlaceholderLineEdit,
|
||||
BaseClickableFrame,
|
||||
ClickableFrame,
|
||||
|
|
@ -28,6 +29,7 @@ from .overlay_messages import (
|
|||
|
||||
|
||||
__all__ = (
|
||||
"CustomTextComboBox",
|
||||
"PlaceholderLineEdit",
|
||||
"BaseClickableFrame",
|
||||
"ClickableFrame",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,28 @@ from openpype.style import (
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CustomTextComboBox(QtWidgets.QComboBox):
|
||||
"""Combobox which can have different text showed."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._custom_text = None
|
||||
super(CustomTextComboBox, self).__init__(*args, **kwargs)
|
||||
|
||||
def set_custom_text(self, text=None):
|
||||
if self._custom_text != text:
|
||||
self._custom_text = text
|
||||
self.repaint()
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QtWidgets.QStylePainter(self)
|
||||
option = QtWidgets.QStyleOptionComboBox()
|
||||
self.initStyleOption(option)
|
||||
if self._custom_text is not None:
|
||||
option.currentText = self._custom_text
|
||||
painter.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, option)
|
||||
painter.drawControl(QtWidgets.QStyle.CE_ComboBoxLabel, option)
|
||||
|
||||
|
||||
class PlaceholderLineEdit(QtWidgets.QLineEdit):
|
||||
"""Set placeholder color of QLineEdit in Qt 5.12 and higher."""
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
|
|||
32
openpype/vendor/python/common/capture.py
vendored
32
openpype/vendor/python/common/capture.py
vendored
|
|
@ -403,7 +403,7 @@ def apply_view(panel, **options):
|
|||
camera_options = options.get("camera_options", {})
|
||||
_iteritems = getattr(camera_options, "iteritems", camera_options.items)
|
||||
for key, value in _iteritems:
|
||||
cmds.setAttr("{0}.{1}".format(camera, key), value)
|
||||
_safe_setAttr("{0}.{1}".format(camera, key), value)
|
||||
|
||||
# Viewport options
|
||||
viewport_options = options.get("viewport_options", {})
|
||||
|
|
@ -417,7 +417,7 @@ def apply_view(panel, **options):
|
|||
)
|
||||
for key, value in _iteritems():
|
||||
attr = "hardwareRenderingGlobals.{0}".format(key)
|
||||
cmds.setAttr(attr, value)
|
||||
_safe_setAttr(attr, value)
|
||||
|
||||
|
||||
def parse_active_panel():
|
||||
|
|
@ -551,10 +551,10 @@ def apply_scene(**options):
|
|||
cmds.playbackOptions(maxTime=options["end_frame"])
|
||||
|
||||
if "width" in options:
|
||||
cmds.setAttr("defaultResolution.width", options["width"])
|
||||
_safe_setAttr("defaultResolution.width", options["width"])
|
||||
|
||||
if "height" in options:
|
||||
cmds.setAttr("defaultResolution.height", options["height"])
|
||||
_safe_setAttr("defaultResolution.height", options["height"])
|
||||
|
||||
if "compression" in options:
|
||||
cmds.optionVar(
|
||||
|
|
@ -665,7 +665,7 @@ def _applied_camera_options(options, panel):
|
|||
|
||||
_iteritems = getattr(options, "iteritems", options.items)
|
||||
for opt, value in _iteritems():
|
||||
cmds.setAttr(camera + "." + opt, value)
|
||||
_safe_setAttr(camera + "." + opt, value)
|
||||
|
||||
try:
|
||||
yield
|
||||
|
|
@ -673,7 +673,7 @@ def _applied_camera_options(options, panel):
|
|||
if old_options:
|
||||
_iteritems = getattr(old_options, "iteritems", old_options.items)
|
||||
for opt, value in _iteritems():
|
||||
cmds.setAttr(camera + "." + opt, value)
|
||||
_safe_setAttr(camera + "." + opt, value)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -760,7 +760,7 @@ def _applied_viewport2_options(options):
|
|||
# Apply settings
|
||||
_iteritems = getattr(options, "iteritems", options.items)
|
||||
for opt, value in _iteritems():
|
||||
cmds.setAttr("hardwareRenderingGlobals." + opt, value)
|
||||
_safe_setAttr("hardwareRenderingGlobals." + opt, value)
|
||||
|
||||
try:
|
||||
yield
|
||||
|
|
@ -768,7 +768,7 @@ def _applied_viewport2_options(options):
|
|||
# Restore previous settings
|
||||
_iteritems = getattr(original, "iteritems", original.items)
|
||||
for opt, value in _iteritems():
|
||||
cmds.setAttr("hardwareRenderingGlobals." + opt, value)
|
||||
_safe_setAttr("hardwareRenderingGlobals." + opt, value)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -802,14 +802,14 @@ def _maintain_camera(panel, camera):
|
|||
else:
|
||||
state = dict((camera, cmds.getAttr(camera + ".rnd"))
|
||||
for camera in cmds.ls(type="camera"))
|
||||
cmds.setAttr(camera + ".rnd", True)
|
||||
_safe_setAttr(camera + ".rnd", True)
|
||||
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
_iteritems = getattr(state, "iteritems", state.items)
|
||||
for camera, renderable in _iteritems():
|
||||
cmds.setAttr(camera + ".rnd", renderable)
|
||||
_safe_setAttr(camera + ".rnd", renderable)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -846,6 +846,18 @@ def _in_standalone():
|
|||
return not hasattr(cmds, "about") or cmds.about(batch=True)
|
||||
|
||||
|
||||
def _safe_setAttr(*args, **kwargs):
|
||||
"""Wrapper to handle failures when attribute is locked.
|
||||
|
||||
Temporary hotfix until better approach (store value, unlock, set new,
|
||||
return old, lock again) is implemented.
|
||||
"""
|
||||
try:
|
||||
cmds.setAttr(*args, **kwargs)
|
||||
except RuntimeError:
|
||||
print("Cannot setAttr {}!".format(args))
|
||||
|
||||
|
||||
# --------------------------------
|
||||
#
|
||||
# Apply version specific settings
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.12.1"
|
||||
__version__ = "3.12.2-nightly.1"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from openpype.lib.attribute_definitions import (
|
|||
UISeparatorDef,
|
||||
UILabelDef
|
||||
)
|
||||
from openpype.tools.utils import CustomTextComboBox
|
||||
from openpype.widgets.nice_checkbox import NiceCheckbox
|
||||
|
||||
from .files_widget import FilesWidget
|
||||
|
|
@ -369,8 +370,12 @@ class BoolAttrWidget(_BaseAttrDefWidget):
|
|||
|
||||
|
||||
class EnumAttrWidget(_BaseAttrDefWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._multivalue = False
|
||||
super(EnumAttrWidget, self).__init__(*args, **kwargs)
|
||||
|
||||
def _ui_init(self):
|
||||
input_widget = QtWidgets.QComboBox(self)
|
||||
input_widget = CustomTextComboBox(self)
|
||||
combo_delegate = QtWidgets.QStyledItemDelegate(input_widget)
|
||||
input_widget.setItemDelegate(combo_delegate)
|
||||
|
||||
|
|
@ -394,6 +399,9 @@ class EnumAttrWidget(_BaseAttrDefWidget):
|
|||
|
||||
def _on_value_change(self):
|
||||
new_value = self.current_value()
|
||||
if self._multivalue:
|
||||
self._multivalue = False
|
||||
self._input_widget.set_custom_text(None)
|
||||
self.value_changed.emit(new_value, self.attr_def.id)
|
||||
|
||||
def current_value(self):
|
||||
|
|
@ -401,14 +409,23 @@ class EnumAttrWidget(_BaseAttrDefWidget):
|
|||
return self._input_widget.itemData(idx)
|
||||
|
||||
def set_value(self, value, multivalue=False):
|
||||
if multivalue:
|
||||
set_value = set(value)
|
||||
if len(set_value) == 1:
|
||||
multivalue = False
|
||||
value = tuple(set_value)[0]
|
||||
|
||||
if not multivalue:
|
||||
idx = self._input_widget.findData(value)
|
||||
cur_idx = self._input_widget.currentIndex()
|
||||
if idx != cur_idx and idx >= 0:
|
||||
self._input_widget.setCurrentIndex(idx)
|
||||
|
||||
else:
|
||||
self._input_widget.lineEdit().setText("Multiselection")
|
||||
custom_text = None
|
||||
if multivalue:
|
||||
custom_text = "< Multiselection >"
|
||||
self._input_widget.set_custom_text(custom_text)
|
||||
self._multivalue = multivalue
|
||||
|
||||
|
||||
class UnknownAttrWidget(_BaseAttrDefWidget):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "OpenPype"
|
||||
version = "3.12.1" # OpenPype
|
||||
version = "3.12.2-nightly.1" # OpenPype
|
||||
description = "Open VFX and Animation pipeline with support."
|
||||
authors = ["OpenPype Team <info@openpype.io>"]
|
||||
license = "MIT License"
|
||||
|
|
@ -135,7 +135,7 @@ hash = "b9950f5d2fa3720b52b8be55bacf5f56d33f9e029d38ee86534995f3d8d253d2"
|
|||
|
||||
[openpype.thirdparty.oiio.linux]
|
||||
url = "https://distribute.openpype.io/thirdparty/oiio_tools-2.2.20-linux-centos7.tgz"
|
||||
hash = "be1abf8a50e9da5913298447421af0a17829d83ed6252ae1d40da7fa36a78787"
|
||||
hash = "3894dec7e4e521463891a869586850e8605f5fd604858b674c87323bf33e273d"
|
||||
|
||||
[openpype.thirdparty.oiio.darwin]
|
||||
url = "https://distribute.openpype.io/thirdparty/oiio-2.2.0-darwin.tgz"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue