Merge pull request #1151 from pypeclub/feature/modifiable_dict_required_keys

Modifiable dict with required keys
This commit is contained in:
Milan Kolar 2021-03-22 11:39:28 +01:00 committed by GitHub
commit 6d58c3be8f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 10 deletions

View file

@ -7,7 +7,8 @@ from .lib import (
from . import EndpointEntity
from .exceptions import (
DefaultsNotDefined,
StudioDefaultsNotDefined
StudioDefaultsNotDefined,
RequiredKeyModified
)
from pype.settings.constants import (
METADATA_KEYS,
@ -51,6 +52,8 @@ class DictMutableKeysEntity(EndpointEntity):
return key in self.children_by_key
def pop(self, key, *args, **kwargs):
if key in self.required_keys:
raise RequiredKeyModified(self.path, key)
result = self.children_by_key.pop(key, *args, **kwargs)
self.on_change()
return result
@ -93,6 +96,9 @@ class DictMutableKeysEntity(EndpointEntity):
child_obj.set(value)
def change_key(self, old_key, new_key):
if old_key in self.required_keys:
raise RequiredKeyModified(self.path, old_key)
if new_key == old_key:
return
self.children_by_key[new_key] = self.children_by_key.pop(old_key)
@ -309,6 +315,10 @@ class DictMutableKeysEntity(EndpointEntity):
for key in tuple(self.children_by_key.keys()):
self.children_by_key.pop(key)
for required_key in self.required_keys:
if required_key not in new_value:
new_value[required_key] = NOT_SET
# Create new children
children_label_by_id = {}
metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {}
@ -441,7 +451,13 @@ class DictMutableKeysEntity(EndpointEntity):
def update_default_value(self, value):
value = self._check_update_value(value, "default")
self.has_default_value = value is not NOT_SET
has_default_value = value is not NOT_SET
if has_default_value:
for required_key in self.required_keys:
if required_key not in value:
has_default_value = False
break
self.has_default_value = has_default_value
value, metadata = self._prepare_value(value)
self._default_value = value
self._default_metadata = metadata

View file

@ -28,7 +28,17 @@ class InvalidValueType(Exception):
super(InvalidValueType, self).__init__(msg)
class SchemaMissingFileInfo(Exception):
class RequiredKeyModified(KeyError):
def __init__(self, entity_path, key):
msg = "{} - Tried to modify required key \"{}\"."
super(RequiredKeyModified, self).__init__(msg.format(entity_path, key))
class SchemaError(Exception):
pass
class SchemaMissingFileInfo(SchemaError):
def __init__(self, invalid):
full_path_keys = []
for item in invalid:
@ -41,7 +51,7 @@ class SchemaMissingFileInfo(Exception):
super(SchemaMissingFileInfo, self).__init__(msg)
class SchemeGroupHierarchyBug(Exception):
class SchemeGroupHierarchyBug(SchemaError):
def __init__(self, entity_path):
msg = (
"Items with attribute \"is_group\" can't have another item with"
@ -50,7 +60,7 @@ class SchemeGroupHierarchyBug(Exception):
super(SchemeGroupHierarchyBug, self).__init__(msg)
class SchemaDuplicatedKeys(Exception):
class SchemaDuplicatedKeys(SchemaError):
def __init__(self, entity_path, key):
msg = (
"Schema item contain duplicated key \"{}\" in"
@ -59,7 +69,7 @@ class SchemaDuplicatedKeys(Exception):
super(SchemaDuplicatedKeys, self).__init__(msg)
class SchemaDuplicatedEnvGroupKeys(Exception):
class SchemaDuplicatedEnvGroupKeys(SchemaError):
def __init__(self, invalid):
items = []
for key_path, keys in invalid.items():
@ -74,7 +84,7 @@ class SchemaDuplicatedEnvGroupKeys(Exception):
super(SchemaDuplicatedEnvGroupKeys, self).__init__(msg)
class SchemaTemplateMissingKeys(Exception):
class SchemaTemplateMissingKeys(SchemaError):
def __init__(self, missing_keys, required_keys, template_name=None):
self.missing_keys = missing_keys
self.required_keys = required_keys

View file

@ -141,6 +141,16 @@
"maximum": 100
}
},
{
"type": "dict-modifiable",
"key": "modifiable_dict_with_required_keys",
"label": "Modifiable dict with required keys",
"required_keys": [
"key_1",
"key_2"
],
"object_type": "text"
},
{
"type": "list-strict",
"key": "strict_list_labels_horizontal",

View file

@ -358,7 +358,8 @@ class ModifiableDictItem(QtWidgets.QWidget):
self.add_btn.setEnabled(False)
def set_as_last_required(self):
self.add_btn.setEnabled(True)
if not self.collapsible_key:
self.add_btn.setEnabled(True)
def _on_focus_lose(self):
if (
@ -827,10 +828,25 @@ class DictMutableKeysWidget(BaseWidget):
while self.input_fields:
self.remove_row(self.input_fields[0])
for key, child_entity in self.entity.items():
keys_order = list(self.entity.required_keys)
last_required = None
if keys_order:
last_required = keys_order[-1]
for key in self.entity.keys():
if key in keys_order:
continue
keys_order.append(key)
for key in keys_order:
child_entity = self.entity[key]
input_field = self.add_widget_for_child(child_entity)
input_field.origin_key = key
input_field.set_key(key)
if key in self.entity.required_keys:
input_field.set_as_required(key)
if key == last_required:
input_field.set_as_last_required()
else:
input_field.set_key(key)
if self.entity.collapsible_key:
label = self.entity.get_child_label(child_entity)
input_field.origin_key_label = label