diff --git a/pype/standalonepublish/app.py b/pype/standalonepublish/app.py index 31a7763ace..ba7dcaa978 100644 --- a/pype/standalonepublish/app.py +++ b/pype/standalonepublish/app.py @@ -92,10 +92,9 @@ class Window(QtWidgets.QDialog): return self._db def on_start(self): - self.initialized = True # Refresh asset input in Family widget self.on_asset_changed() - self.validation() + self.widget_components.validation() self.shadow_widget = ShadowWidget(self) self.shadow_widget.setVisible(False) @@ -156,19 +155,10 @@ class Window(QtWidgets.QDialog): if self.shadow_widget.isVisible(): self.shadow_widget.setVisible(False) - def validation(self): - if not self.initialized: - return - valid = self.valid_family and self.valid_components - self.widget_components.set_valid(valid) - def set_valid_family(self, valid): self.valid_family = valid - self.validation() - - def set_valid_components(self, valid): - self.valid_components = valid - self.validation() + if hasattr(self, 'widget_components'): + self.widget_components.validation() def collect_data(self): data = {} diff --git a/pype/standalonepublish/widgets/widget_component_item.py b/pype/standalonepublish/widgets/widget_component_item.py index 6dec892d91..2e0df9a00c 100644 --- a/pype/standalonepublish/widgets/widget_component_item.py +++ b/pype/standalonepublish/widgets/widget_component_item.py @@ -13,9 +13,11 @@ class ComponentItem(QtWidgets.QFrame): signal_remove = QtCore.Signal(object) signal_thumbnail = QtCore.Signal(object) signal_preview = QtCore.Signal(object) + signal_repre_change = QtCore.Signal(object, object) def __init__(self, parent, main_parent): super().__init__() + self.has_valid_repre = True self.actions = [] self.resize(290, 70) self.setMinimumSize(QtCore.QSize(0, 70)) @@ -183,6 +185,7 @@ class ComponentItem(QtWidgets.QFrame): self.remove.clicked.connect(self._remove) self.thumbnail.clicked.connect(self._thumbnail_clicked) self.preview.clicked.connect(self._preview_clicked) + self.input_repre.textChanged.connect(self._handle_duplicate_repre) name = data['name'] representation = data['representation'] ext = data['ext'] @@ -238,6 +241,13 @@ class ComponentItem(QtWidgets.QFrame): self.btn_action_menu.clicked.connect(self.show_actions) self.action_menu.setStyleSheet(style.load_stylesheet()) + def set_repre_name_valid(self, valid): + self.has_valid_repre = valid + if valid: + self.input_repre.setStyleSheet("") + else: + self.input_repre.setStyleSheet("border: 1px solid red;") + def split_sequence(self): self.parent_widget.split_items(self) @@ -257,6 +267,9 @@ class ComponentItem(QtWidgets.QFrame): def _preview_clicked(self): self.signal_preview.emit(self) + def _handle_duplicate_repre(self, repre_name): + self.signal_repre_change.emit(self, repre_name) + def is_thumbnail(self): return self.thumbnail.checked diff --git a/pype/standalonepublish/widgets/widget_components.py b/pype/standalonepublish/widgets/widget_components.py index 5cc66de0b5..326aefe693 100644 --- a/pype/standalonepublish/widgets/widget_components.py +++ b/pype/standalonepublish/widgets/widget_components.py @@ -7,6 +7,11 @@ from .. import publish class ComponentsWidget(QtWidgets.QWidget): def __init__(self, parent): super().__init__() + self.initialized = False + self.valid_components = False + self.valid_family = False + self.valid_repre_names = False + body = QtWidgets.QWidget() self.parent_widget = parent self.drop_frame = DropDataFrame(self) @@ -39,12 +44,25 @@ class ComponentsWidget(QtWidgets.QWidget): self.btn_browse.clicked.connect(self._browse) self.btn_publish.clicked.connect(self._publish) + self.initialized = True - def set_valid(self, in_bool): - self.btn_publish.setEnabled(in_bool) + def validation(self): + if self.initialized is False: + return + valid = ( + self.parent_widget.valid_family and + self.valid_components and + self.valid_repre_names + ) + self.btn_publish.setEnabled(valid) - def set_valid_components(self, in_bool): - self.parent_widget.set_valid_components(in_bool) + def set_valid_components(self, valid): + self.valid_components = valid + self.validation() + + def set_valid_repre_names(self, valid): + self.valid_repre_names = valid + self.validation() def process_mime_data(self, mime_data): self.drop_frame.process_ent_mime(mime_data) diff --git a/pype/standalonepublish/widgets/widget_drop_frame.py b/pype/standalonepublish/widgets/widget_drop_frame.py index 644f53a732..89c4352717 100644 --- a/pype/standalonepublish/widgets/widget_drop_frame.py +++ b/pype/standalonepublish/widgets/widget_drop_frame.py @@ -1,4 +1,5 @@ import os +import re import clique import subprocess from pypeapp import config @@ -83,6 +84,7 @@ class DropDataFrame(QtWidgets.QFrame): new_component.signal_thumbnail.connect( self._set_thumbnail ) + new_component.signal_repre_change.connect(self.repre_name_changed) for action in actions: new_component.add_action(action) @@ -114,13 +116,19 @@ class DropDataFrame(QtWidgets.QFrame): checked_item.change_preview(False) in_item.change_preview() - def _remove_item(self, item): - index = self.components_list.widget_index(item) + def _remove_item(self, in_item): + index = self.components_list.widget_index(in_item) self.components_list.remove_widget(index) - if item in self.items: - self.removed.append(item) - self.items.remove(item) + if in_item in self.items: + self.removed.append(in_item) + self.items.remove(in_item) self._refresh_view() + if in_item.has_valid_repre: + return + for item in self.items: + if item.has_valid_repre: + continue + self.repre_name_changed(item, item.input_repre.text()) def _refresh_view(self): _bool = len(self.items) == 0 @@ -338,8 +346,50 @@ class DropDataFrame(QtWidgets.QFrame): actions.append('split') if found is False: + new_repre = self.handle_new_repre_name(data['representation']) + data['representation'] = new_repre self._add_item(data, actions) + def handle_new_repre_name(self, repre_name): + renamed = False + for item in self.items: + if repre_name == item.input_repre.text(): + check_regex = '\(\w+\)$' + result = re.findall(check_regex, repre_name) + next_num = 2 + if len(result) == 1: + repre_name = repre_name.replace(result[0], '') + next_num = int(result[0].replace('(', '').replace(')', '')) + next_num += 1 + repre_name = '{}({})'.format(repre_name, next_num) + renamed = True + break + if renamed: + return self.handle_new_repre_name(repre_name) + return repre_name + + def repre_name_changed(self, in_item, repre_name): + is_valid = True + for item in self.items: + if item == in_item: + continue + if item.input_repre.text() == repre_name: + item.set_repre_name_valid(False) + in_item.set_repre_name_valid(False) + is_valid = False + global_valid = is_valid + if is_valid: + in_item.set_repre_name_valid(True) + for item in self.items: + if item.has_valid_repre: + continue + self.repre_name_changed(item, item.input_repre.text()) + for item in self.items: + if not item.has_valid_repre: + global_valid = False + break + self.parent_widget.set_valid_repre_names(global_valid) + def merge_items(self, in_item): self.parent_widget.working_start() items = []