mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
[Automated] Merged develop into main
This commit is contained in:
commit
893e50b545
17 changed files with 376 additions and 102 deletions
|
|
@ -54,6 +54,10 @@ class LoadClip(phiero.SequenceLoader):
|
|||
object_name = self.clip_name_template.format(
|
||||
**context["representation"]["context"])
|
||||
|
||||
# set colorspace
|
||||
if colorspace:
|
||||
track_item.source().setSourceMediaColourTransform(colorspace)
|
||||
|
||||
# add additional metadata from the version to imprint Avalon knob
|
||||
add_keys = [
|
||||
"frameStart", "frameEnd", "source", "author",
|
||||
|
|
@ -109,9 +113,14 @@ class LoadClip(phiero.SequenceLoader):
|
|||
colorspace = version_data.get("colorspace", None)
|
||||
object_name = "{}_{}".format(name, namespace)
|
||||
file = api.get_representation_path(representation).replace("\\", "/")
|
||||
clip = track_item.source()
|
||||
|
||||
# reconnect media to new path
|
||||
track_item.source().reconnectMedia(file)
|
||||
clip.reconnectMedia(file)
|
||||
|
||||
# set colorspace
|
||||
if colorspace:
|
||||
clip.setSourceMediaColourTransform(colorspace)
|
||||
|
||||
# add additional metadata from the version to imprint Avalon knob
|
||||
add_keys = [
|
||||
|
|
@ -160,6 +169,7 @@ class LoadClip(phiero.SequenceLoader):
|
|||
@classmethod
|
||||
def set_item_color(cls, track_item, version):
|
||||
|
||||
clip = track_item.source()
|
||||
# define version name
|
||||
version_name = version.get("name", None)
|
||||
# get all versions in list
|
||||
|
|
@ -172,6 +182,6 @@ class LoadClip(phiero.SequenceLoader):
|
|||
|
||||
# set clip colour
|
||||
if version_name == max_version:
|
||||
track_item.source().binItem().setColor(cls.clip_color_last)
|
||||
clip.binItem().setColor(cls.clip_color_last)
|
||||
else:
|
||||
track_item.source().binItem().setColor(cls.clip_color)
|
||||
clip.binItem().setColor(cls.clip_color)
|
||||
|
|
|
|||
|
|
@ -120,6 +120,13 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
|
|||
# create instance
|
||||
instance = context.create_instance(**data)
|
||||
|
||||
# add colorspace data
|
||||
instance.data.update({
|
||||
"versionData": {
|
||||
"colorspace": track_item.sourceMediaColourTransform(),
|
||||
}
|
||||
})
|
||||
|
||||
# create shot instance for shot attributes create/update
|
||||
self.create_shot_instance(context, **data)
|
||||
|
||||
|
|
@ -133,13 +140,6 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
|
|||
# create audio subset instance
|
||||
self.create_audio_instance(context, **data)
|
||||
|
||||
# add colorspace data
|
||||
instance.data.update({
|
||||
"versionData": {
|
||||
"colorspace": track_item.sourceMediaColourTransform(),
|
||||
}
|
||||
})
|
||||
|
||||
# add audioReview attribute to plate instance data
|
||||
# if reviewTrack is on
|
||||
if tag_data.get("reviewTrack") is not None:
|
||||
|
|
|
|||
|
|
@ -259,7 +259,8 @@ class LoadMov(api.Loader):
|
|||
read_node["last"].setValue(last)
|
||||
read_node['frame_mode'].setValue("start at")
|
||||
|
||||
if int(self.first_frame) == int(read_node['frame'].value()):
|
||||
if int(float(self.first_frame)) == int(
|
||||
float(read_node['frame'].value())):
|
||||
# start at workfile start
|
||||
read_node['frame'].setValue(str(self.first_frame))
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ class CollectTextures(pyblish.api.ContextPlugin):
|
|||
# store origin
|
||||
if family == 'workfile':
|
||||
families = self.workfile_families
|
||||
families.append("texture_batch_workfile")
|
||||
|
||||
new_instance.data["source"] = "standalone publisher"
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class ValidateTextureBatch(pyblish.api.InstancePlugin):
|
|||
label = "Validate Texture Presence"
|
||||
hosts = ["standalonepublisher"]
|
||||
order = openpype.api.ValidateContentsOrder
|
||||
families = ["workfile"]
|
||||
families = ["texture_batch_workfile"]
|
||||
optional = False
|
||||
|
||||
def process(self, instance):
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class ValidateTextureBatchNaming(pyblish.api.InstancePlugin):
|
|||
label = "Validate Texture Batch Naming"
|
||||
hosts = ["standalonepublisher"]
|
||||
order = openpype.api.ValidateContentsOrder
|
||||
families = ["workfile", "textures"]
|
||||
families = ["texture_batch_workfile", "textures"]
|
||||
optional = False
|
||||
|
||||
def process(self, instance):
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class ValidateTextureBatchWorkfiles(pyblish.api.InstancePlugin):
|
|||
label = "Validate Texture Workfile Has Resources"
|
||||
hosts = ["standalonepublisher"]
|
||||
order = openpype.api.ValidateContentsOrder
|
||||
families = ["workfile"]
|
||||
families = ["texture_batch_workfile"]
|
||||
optional = True
|
||||
|
||||
# from presets
|
||||
|
|
|
|||
|
|
@ -1138,7 +1138,8 @@ def prepare_host_environments(data, implementation_envs=True):
|
|||
# Merge dictionaries
|
||||
env_values = _merge_env(tool_env, env_values)
|
||||
|
||||
loaded_env = _merge_env(acre.compute(env_values), data["env"])
|
||||
merged_env = _merge_env(env_values, data["env"])
|
||||
loaded_env = acre.compute(merged_env, cleanup=False)
|
||||
|
||||
final_env = None
|
||||
# Add host specific environments
|
||||
|
|
@ -1189,7 +1190,10 @@ def apply_project_environments_value(project_name, env, project_settings=None):
|
|||
|
||||
env_value = project_settings["global"]["project_environments"]
|
||||
if env_value:
|
||||
env.update(_merge_env(acre.parse(env_value), env))
|
||||
env.update(acre.compute(
|
||||
_merge_env(acre.parse(env_value), env),
|
||||
cleanup=False
|
||||
))
|
||||
return env
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import re
|
|||
import json
|
||||
import copy
|
||||
import inspect
|
||||
import contextlib
|
||||
|
||||
from .exceptions import (
|
||||
SchemaTemplateMissingKeys,
|
||||
|
|
@ -111,6 +112,10 @@ class SchemasHub:
|
|||
self._loaded_templates = {}
|
||||
self._loaded_schemas = {}
|
||||
|
||||
# Store validating and validated dynamic template or schemas
|
||||
self._validating_dynamic = set()
|
||||
self._validated_dynamic = set()
|
||||
|
||||
# It doesn't make sence to reload types on each reset as they can't be
|
||||
# changed
|
||||
self._load_types()
|
||||
|
|
@ -126,6 +131,60 @@ class SchemasHub:
|
|||
def gui_types(self):
|
||||
return self._gui_types
|
||||
|
||||
def get_template_name(self, item_def, default=None):
|
||||
"""Get template name from passed item definition.
|
||||
|
||||
Args:
|
||||
item_def(dict): Definition of item with "type".
|
||||
default(object): Default return value.
|
||||
"""
|
||||
output = default
|
||||
if not item_def or not isinstance(item_def, dict):
|
||||
return output
|
||||
|
||||
item_type = item_def.get("type")
|
||||
if item_type in ("template", "schema_template"):
|
||||
output = item_def["name"]
|
||||
return output
|
||||
|
||||
def is_dynamic_template_validating(self, template_name):
|
||||
"""Is template validating using different entity.
|
||||
|
||||
Returns:
|
||||
bool: Is template validating.
|
||||
"""
|
||||
if template_name in self._validating_dynamic:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_dynamic_template_validated(self, template_name):
|
||||
"""Is template already validated.
|
||||
|
||||
Returns:
|
||||
bool: Is template validated.
|
||||
"""
|
||||
|
||||
if template_name in self._validated_dynamic:
|
||||
return True
|
||||
return False
|
||||
|
||||
@contextlib.contextmanager
|
||||
def validating_dynamic(self, template_name):
|
||||
"""Template name is validating and validated.
|
||||
|
||||
Context manager that cares about storing template name validations of
|
||||
template.
|
||||
|
||||
This is to avoid infinite loop of dynamic children validation.
|
||||
"""
|
||||
self._validating_dynamic.add(template_name)
|
||||
try:
|
||||
yield
|
||||
self._validated_dynamic.add(template_name)
|
||||
|
||||
finally:
|
||||
self._validating_dynamic.remove(template_name)
|
||||
|
||||
def get_schema(self, schema_name):
|
||||
"""Get schema definition data by it's name.
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,20 @@ class ListEntity(EndpointEntity):
|
|||
item_schema = self.schema_data["object_type"]
|
||||
if not isinstance(item_schema, dict):
|
||||
item_schema = {"type": item_schema}
|
||||
self.item_schema = item_schema
|
||||
|
||||
obj_template_name = self.schema_hub.get_template_name(item_schema)
|
||||
_item_schemas = self.schema_hub.resolve_schema_data(item_schema)
|
||||
if len(_item_schemas) == 1:
|
||||
self.item_schema = _item_schemas[0]
|
||||
if self.item_schema != item_schema:
|
||||
if "label" in self.item_schema:
|
||||
self.item_schema.pop("label")
|
||||
self.item_schema["use_label_wrap"] = False
|
||||
else:
|
||||
self.item_schema = _item_schemas
|
||||
|
||||
# Store if was used template or schema
|
||||
self._obj_template_name = obj_template_name
|
||||
|
||||
if self.group_item is None:
|
||||
self.is_group = True
|
||||
|
|
@ -150,6 +163,12 @@ class ListEntity(EndpointEntity):
|
|||
self.initial_value = []
|
||||
|
||||
def schema_validations(self):
|
||||
if isinstance(self.item_schema, list):
|
||||
reason = (
|
||||
"`ListWidget` has multiple items as object type."
|
||||
)
|
||||
raise EntitySchemaError(self, reason)
|
||||
|
||||
super(ListEntity, self).schema_validations()
|
||||
|
||||
if self.is_dynamic_item and self.use_label_wrap:
|
||||
|
|
@ -167,18 +186,36 @@ class ListEntity(EndpointEntity):
|
|||
raise EntitySchemaError(self, reason)
|
||||
|
||||
# Validate object type schema
|
||||
child_validated = False
|
||||
validate_children = True
|
||||
for child_entity in self.children:
|
||||
child_entity.schema_validations()
|
||||
child_validated = True
|
||||
validate_children = False
|
||||
break
|
||||
|
||||
if not child_validated:
|
||||
if validate_children and self._obj_template_name:
|
||||
_validated = self.schema_hub.is_dynamic_template_validated(
|
||||
self._obj_template_name
|
||||
)
|
||||
_validating = self.schema_hub.is_dynamic_template_validating(
|
||||
self._obj_template_name
|
||||
)
|
||||
validate_children = not _validated and not _validating
|
||||
|
||||
if not validate_children:
|
||||
return
|
||||
|
||||
def _validate():
|
||||
idx = 0
|
||||
tmp_child = self._add_new_item(idx)
|
||||
tmp_child.schema_validations()
|
||||
self.children.pop(idx)
|
||||
|
||||
if self._obj_template_name:
|
||||
with self.schema_hub.validating_dynamic(self._obj_template_name):
|
||||
_validate()
|
||||
else:
|
||||
_validate()
|
||||
|
||||
def get_child_path(self, child_obj):
|
||||
result_idx = None
|
||||
for idx, _child_obj in enumerate(self.children):
|
||||
|
|
|
|||
|
|
@ -417,6 +417,8 @@ How output of the schema could look like on save:
|
|||
- there are 2 possible ways how to set the type:
|
||||
1.) dictionary with item modifiers (`number` input has `minimum`, `maximum` and `decimals`) in that case item type must be set as value of `"type"` (example below)
|
||||
2.) item type name as string without modifiers (e.g. `text`)
|
||||
3.) enhancement of 1.) there is also support of `template` type but be carefull about endless loop of templates
|
||||
- goal of using `template` is to easily change same item definitions in multiple lists
|
||||
|
||||
1.) with item modifiers
|
||||
```
|
||||
|
|
@ -442,6 +444,65 @@ How output of the schema could look like on save:
|
|||
}
|
||||
```
|
||||
|
||||
3.) with template definition
|
||||
```
|
||||
# Schema of list item where template is used
|
||||
{
|
||||
"type": "list",
|
||||
"key": "menu_items",
|
||||
"label": "Menu Items",
|
||||
"object_type": {
|
||||
"type": "template",
|
||||
"name": "template_object_example"
|
||||
}
|
||||
}
|
||||
|
||||
# WARNING:
|
||||
# In this example the template use itself inside which will work in `list`
|
||||
# but may cause an issue in other entity types (e.g. `dict`).
|
||||
|
||||
'template_object_example.json' :
|
||||
[
|
||||
{
|
||||
"type": "dict-conditional",
|
||||
"use_label_wrap": true,
|
||||
"collapsible": true,
|
||||
"key": "menu_items",
|
||||
"label": "Menu items",
|
||||
"enum_key": "type",
|
||||
"enum_label": "Type",
|
||||
"enum_children": [
|
||||
{
|
||||
"key": "action",
|
||||
"label": "Action",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"key": "key",
|
||||
"label": "Key"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "menu",
|
||||
"label": "Menu",
|
||||
"children": [
|
||||
{
|
||||
"key": "children",
|
||||
"label": "Children",
|
||||
"type": "list",
|
||||
"object_type": {
|
||||
"type": "template",
|
||||
"name": "template_object_example"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### dict-modifiable
|
||||
- one of dictionary inputs, this is only used as value input
|
||||
- items in this input can be removed and added same way as in `list` input
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
[
|
||||
{
|
||||
"type": "dict-conditional",
|
||||
"use_label_wrap": true,
|
||||
"collapsible": true,
|
||||
"key": "menu_items",
|
||||
"label": "Menu items",
|
||||
"enum_key": "type",
|
||||
"enum_label": "Type",
|
||||
"enum_children": [
|
||||
{
|
||||
"key": "action",
|
||||
"label": "Action",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"key": "key",
|
||||
"label": "Key"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "label",
|
||||
"label": "Label"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "command",
|
||||
"label": "Comand"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "menu",
|
||||
"label": "Menu",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"key": "label",
|
||||
"label": "Label"
|
||||
},
|
||||
{
|
||||
"key": "children",
|
||||
"label": "Children",
|
||||
"type": "list",
|
||||
"object_type": {
|
||||
"type": "template",
|
||||
"name": "example_infinite_hierarchy"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "separator",
|
||||
"label": "Separator"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -82,6 +82,17 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"use_label_wrap": true,
|
||||
"collapsible": true,
|
||||
"key": "infinite_hierarchy",
|
||||
"label": "Infinite list template hierarchy",
|
||||
"object_type": {
|
||||
"type": "template",
|
||||
"name": "example_infinite_hierarchy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "schema_template_exaples",
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ class ListItem(QtWidgets.QWidget):
|
|||
|
||||
self.spacer_widget = spacer_widget
|
||||
|
||||
self._row = -1
|
||||
self._is_last = False
|
||||
|
||||
@property
|
||||
def category_widget(self):
|
||||
return self.entity_widget.category_widget
|
||||
|
|
@ -136,28 +139,40 @@ class ListItem(QtWidgets.QWidget):
|
|||
def add_widget_to_layout(self, widget, label=None):
|
||||
self.content_layout.addWidget(widget, 1)
|
||||
|
||||
def set_row(self, row, is_last):
|
||||
if row == self._row and is_last == self._is_last:
|
||||
return
|
||||
|
||||
trigger_order_changed = (
|
||||
row != self._row
|
||||
or is_last != self._is_last
|
||||
)
|
||||
self._row = row
|
||||
self._is_last = is_last
|
||||
|
||||
if trigger_order_changed:
|
||||
self.order_changed()
|
||||
|
||||
@property
|
||||
def row(self):
|
||||
return self.entity_widget.input_fields.index(self)
|
||||
return self._row
|
||||
|
||||
def parent_rows_count(self):
|
||||
return len(self.entity_widget.input_fields)
|
||||
|
||||
def _on_add_clicked(self):
|
||||
self.entity_widget.add_new_item(row=self.row() + 1)
|
||||
self.entity_widget.add_new_item(row=self.row + 1)
|
||||
|
||||
def _on_remove_clicked(self):
|
||||
self.entity_widget.remove_row(self)
|
||||
|
||||
def _on_up_clicked(self):
|
||||
row = self.row()
|
||||
self.entity_widget.swap_rows(row - 1, row)
|
||||
self.entity_widget.swap_rows(self.row - 1, self.row)
|
||||
|
||||
def _on_down_clicked(self):
|
||||
row = self.row()
|
||||
self.entity_widget.swap_rows(row, row + 1)
|
||||
self.entity_widget.swap_rows(self.row, self.row + 1)
|
||||
|
||||
def order_changed(self):
|
||||
row = self.row()
|
||||
parent_row_count = self.parent_rows_count()
|
||||
if parent_row_count == 1:
|
||||
self.up_btn.setVisible(False)
|
||||
|
|
@ -168,11 +183,11 @@ class ListItem(QtWidgets.QWidget):
|
|||
self.up_btn.setVisible(True)
|
||||
self.down_btn.setVisible(True)
|
||||
|
||||
if row == 0:
|
||||
if self.row == 0:
|
||||
self.up_btn.setEnabled(False)
|
||||
self.down_btn.setEnabled(True)
|
||||
|
||||
elif row == parent_row_count - 1:
|
||||
elif self.row == parent_row_count - 1:
|
||||
self.up_btn.setEnabled(True)
|
||||
self.down_btn.setEnabled(False)
|
||||
|
||||
|
|
@ -191,6 +206,7 @@ class ListWidget(InputWidget):
|
|||
def create_ui(self):
|
||||
self._child_style_state = ""
|
||||
self.input_fields = []
|
||||
self._input_fields_by_entity_id = {}
|
||||
|
||||
main_layout = QtWidgets.QHBoxLayout(self)
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
|
@ -243,8 +259,7 @@ class ListWidget(InputWidget):
|
|||
self.entity_widget.add_widget_to_layout(self, entity_label)
|
||||
|
||||
def set_entity_value(self):
|
||||
for input_field in tuple(self.input_fields):
|
||||
self.remove_row(input_field)
|
||||
self.remove_all_rows()
|
||||
|
||||
for entity in self.entity.children:
|
||||
self.add_row(entity)
|
||||
|
|
@ -262,39 +277,60 @@ class ListWidget(InputWidget):
|
|||
|
||||
def _on_entity_change(self):
|
||||
# TODO do less inefficient
|
||||
input_field_last_idx = len(self.input_fields) - 1
|
||||
child_len = len(self.entity)
|
||||
childen_order = []
|
||||
new_children = []
|
||||
for idx, child_entity in enumerate(self.entity):
|
||||
if idx > input_field_last_idx:
|
||||
self.add_row(child_entity, idx)
|
||||
input_field_last_idx += 1
|
||||
input_field = self._input_fields_by_entity_id.get(child_entity.id)
|
||||
if input_field is not None:
|
||||
childen_order.append(input_field)
|
||||
else:
|
||||
new_children.append((idx, child_entity))
|
||||
|
||||
order_changed = False
|
||||
for idx, input_field in enumerate(childen_order):
|
||||
current_field = self.input_fields[idx]
|
||||
if current_field is input_field:
|
||||
continue
|
||||
order_changed = True
|
||||
old_idx = self.input_fields.index(input_field)
|
||||
self.input_fields[old_idx], self.input_fields[idx] = (
|
||||
current_field, input_field
|
||||
)
|
||||
self.content_layout.insertWidget(idx + 1, input_field)
|
||||
|
||||
if self.input_fields[idx].entity is child_entity:
|
||||
continue
|
||||
kept_len = len(childen_order)
|
||||
fields_len = len(self.input_fields)
|
||||
if fields_len > kept_len:
|
||||
order_changed = True
|
||||
for row in reversed(range(kept_len, fields_len)):
|
||||
self.remove_row(row=row)
|
||||
|
||||
input_field_idx = None
|
||||
for _input_field_idx, input_field in enumerate(self.input_fields):
|
||||
if input_field.entity is child_entity:
|
||||
input_field_idx = _input_field_idx
|
||||
break
|
||||
for idx, child_entity in new_children:
|
||||
order_changed = False
|
||||
self.add_row(child_entity, idx)
|
||||
|
||||
if input_field_idx is None:
|
||||
self.add_row(child_entity, idx)
|
||||
input_field_last_idx += 1
|
||||
continue
|
||||
if not order_changed:
|
||||
return
|
||||
|
||||
input_field = self.input_fields.pop(input_field_idx)
|
||||
self.input_fields.insert(idx, input_field)
|
||||
self.content_layout.insertWidget(idx, input_field)
|
||||
self._on_order_change()
|
||||
|
||||
new_input_field_len = len(self.input_fields)
|
||||
if child_len != new_input_field_len:
|
||||
for _idx in range(child_len, new_input_field_len):
|
||||
# Remove row at the same index
|
||||
self.remove_row(self.input_fields[child_len])
|
||||
input_field_len = self.count()
|
||||
self.empty_row.setVisible(input_field_len == 0)
|
||||
|
||||
self.empty_row.setVisible(self.count() == 0)
|
||||
def _on_order_change(self):
|
||||
last_idx = self.count() - 1
|
||||
previous_input = None
|
||||
for idx, input_field in enumerate(self.input_fields):
|
||||
input_field.set_row(idx, idx == last_idx)
|
||||
next_input = input_field.input_field.focusProxy()
|
||||
if previous_input is not None:
|
||||
self.setTabOrder(previous_input, next_input)
|
||||
else:
|
||||
self.setTabOrder(self, next_input)
|
||||
previous_input = next_input
|
||||
|
||||
if previous_input is not None:
|
||||
self.setTabOrder(previous_input, self)
|
||||
|
||||
def count(self):
|
||||
return len(self.input_fields)
|
||||
|
|
@ -307,32 +343,20 @@ class ListWidget(InputWidget):
|
|||
|
||||
def add_new_item(self, row=None):
|
||||
new_entity = self.entity.add_new_item(row)
|
||||
for input_field in self.input_fields:
|
||||
if input_field.entity is new_entity:
|
||||
input_field.input_field.setFocus(True)
|
||||
break
|
||||
input_field = self._input_fields_by_entity_id.get(new_entity.id)
|
||||
if input_field is not None:
|
||||
input_field.input_field.setFocus(True)
|
||||
return new_entity
|
||||
|
||||
def add_row(self, child_entity, row=None):
|
||||
# Create new item
|
||||
item_widget = ListItem(child_entity, self)
|
||||
|
||||
previous_field = None
|
||||
next_field = None
|
||||
self._input_fields_by_entity_id[child_entity.id] = item_widget
|
||||
|
||||
if row is None:
|
||||
if self.input_fields:
|
||||
previous_field = self.input_fields[-1]
|
||||
self.content_layout.addWidget(item_widget)
|
||||
self.input_fields.append(item_widget)
|
||||
else:
|
||||
if row > 0:
|
||||
previous_field = self.input_fields[row - 1]
|
||||
|
||||
max_index = self.count()
|
||||
if row < max_index:
|
||||
next_field = self.input_fields[row]
|
||||
|
||||
self.content_layout.insertWidget(row + 1, item_widget)
|
||||
self.input_fields.insert(row, item_widget)
|
||||
|
||||
|
|
@ -342,49 +366,53 @@ class ListWidget(InputWidget):
|
|||
# added as widget here which won't because is not in input_fields
|
||||
item_widget.input_field.set_entity_value()
|
||||
|
||||
if previous_field:
|
||||
previous_field.order_changed()
|
||||
self._on_order_change()
|
||||
|
||||
if next_field:
|
||||
next_field.order_changed()
|
||||
|
||||
item_widget.order_changed()
|
||||
|
||||
previous_input = None
|
||||
for input_field in self.input_fields:
|
||||
if previous_input is not None:
|
||||
self.setTabOrder(
|
||||
previous_input, input_field.input_field.focusProxy()
|
||||
)
|
||||
previous_input = input_field.input_field.focusProxy()
|
||||
input_field_len = self.count()
|
||||
self.empty_row.setVisible(input_field_len == 0)
|
||||
|
||||
self.updateGeometry()
|
||||
|
||||
def remove_row(self, item_widget):
|
||||
row = self.input_fields.index(item_widget)
|
||||
previous_field = None
|
||||
next_field = None
|
||||
if row > 0:
|
||||
previous_field = self.input_fields[row - 1]
|
||||
def remove_all_rows(self):
|
||||
self._input_fields_by_entity_id = {}
|
||||
while self.input_fields:
|
||||
item_widget = self.input_fields.pop(0)
|
||||
self.content_layout.removeWidget(item_widget)
|
||||
item_widget.setParent(None)
|
||||
item_widget.deleteLater()
|
||||
|
||||
if row != len(self.input_fields) - 1:
|
||||
next_field = self.input_fields[row + 1]
|
||||
self.empty_row.setVisible(True)
|
||||
|
||||
self.updateGeometry()
|
||||
|
||||
def remove_row(self, item_widget=None, row=None):
|
||||
if item_widget is None:
|
||||
item_widget = self.input_fields[row]
|
||||
elif row is None:
|
||||
row = self.input_fields.index(item_widget)
|
||||
|
||||
self.content_layout.removeWidget(item_widget)
|
||||
self.input_fields.pop(row)
|
||||
self._input_fields_by_entity_id.pop(item_widget.entity.id)
|
||||
item_widget.setParent(None)
|
||||
item_widget.deleteLater()
|
||||
|
||||
if item_widget.entity in self.entity:
|
||||
self.entity.remove(item_widget.entity)
|
||||
|
||||
if previous_field:
|
||||
previous_field.order_changed()
|
||||
rows = self.count()
|
||||
any_item = rows == 0
|
||||
if any_item:
|
||||
start_row = 0
|
||||
if row > 0:
|
||||
start_row = row - 1
|
||||
|
||||
if next_field:
|
||||
next_field.order_changed()
|
||||
last_row = rows - 1
|
||||
_enum = enumerate(self.input_fields[start_row:rows])
|
||||
for idx, _item_widget in _enum:
|
||||
_item_widget.set_row(idx, idx == last_row)
|
||||
|
||||
self.empty_row.setVisible(self.count() == 0)
|
||||
self.empty_row.setVisible(any_item)
|
||||
|
||||
self.updateGeometry()
|
||||
|
||||
|
|
|
|||
2
poetry.lock
generated
2
poetry.lock
generated
|
|
@ -11,7 +11,7 @@ develop = false
|
|||
type = "git"
|
||||
url = "https://github.com/pypeclub/acre.git"
|
||||
reference = "master"
|
||||
resolved_reference = "5a812c6dcfd3aada87adb49be98c548c894d6566"
|
||||
resolved_reference = "55a7c331e6dc5f81639af50ca4a8cc9d73e9273d"
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit cfd4191e364b47de7364096f45d9d9d9a901692a
|
||||
Subproject commit e5c8a15fde77708c924eab3018bda255f17b5390
|
||||
6
start.py
6
start.py
|
|
@ -221,10 +221,14 @@ def set_openpype_global_environments() -> None:
|
|||
all_env = get_environments()
|
||||
general_env = all_env["global"]
|
||||
|
||||
env = acre.merge(
|
||||
merged_env = acre.merge(
|
||||
acre.parse(general_env),
|
||||
dict(os.environ)
|
||||
)
|
||||
env = acre.compute(
|
||||
merged_env,
|
||||
cleanup=False
|
||||
)
|
||||
os.environ.clear()
|
||||
os.environ.update(env)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue