changed select context dialog

This commit is contained in:
Jakub Trllo 2023-01-05 10:18:06 +01:00
parent 5d4be57504
commit 4c43acde9d
2 changed files with 717 additions and 53 deletions

View file

@ -1,17 +1,42 @@
import re
import collections
from openpype.client import get_projects, get_assets
from openpype.client import (
get_projects,
get_assets,
get_asset_by_id,
get_subset_by_id,
get_version_by_id,
get_representations,
)
from openpype.settings import get_project_settings
from openpype.lib import prepare_template_data
from openpype.lib.events import EventSystem
from openpype.pipeline.create import (
SUBSET_NAME_ALLOWED_SYMBOLS,
get_subset_name_template,
)
class AssetItem:
def __init__(self, entity_id, name, icon, parent_id):
def __init__(
self,
entity_id,
name,
icon_name,
icon_color,
parent_id,
has_children
):
self.id = entity_id
self.name = name
self.icon = icon
self.icon_name = icon_name
self.icon_color = icon_color
self.parent_id = parent_id
self.has_children = has_children
@classmethod
def from_doc(cls, asset_doc):
def from_doc(cls, asset_doc, has_children=True):
parent_id = asset_doc["data"].get("visualParent")
if parent_id is not None:
parent_id = str(parent_id)
@ -19,7 +44,9 @@ class AssetItem:
str(asset_doc["_id"]),
asset_doc["name"],
asset_doc["data"].get("icon"),
parent_id
asset_doc["data"].get("color"),
parent_id,
has_children
)
@ -76,6 +103,9 @@ class EntitiesModel:
self.refresh_assets(project_name)
return dict(self._assets_by_project[project_name])
def get_asset_by_id(self, project_name, asset_id):
return self._assets_by_project[project_name].get(asset_id)
def get_tasks(self, project_name, asset_id):
if not project_name or not asset_id:
return []
@ -85,6 +115,8 @@ class EntitiesModel:
all_task_items = self._tasks_by_asset_id[project_name]
asset_task_items = all_task_items.get(asset_id)
if not asset_task_items:
return []
return list(asset_task_items)
def refresh_projects(self, force=False):
@ -113,12 +145,25 @@ class EntitiesModel:
return
project_doc = self._project_docs_by_name[project_name]
asset_docs_by_parent_id = collections.defaultdict(list)
for asset_doc in get_assets(project_name):
asset_item = AssetItem.from_doc(asset_doc)
parent_id = asset_doc["data"].get("visualParent")
asset_docs_by_parent_id[parent_id].append(asset_doc)
hierarchy_queue = collections.deque()
for asset_doc in asset_docs_by_parent_id[None]:
hierarchy_queue.append(asset_doc)
while hierarchy_queue:
asset_doc = hierarchy_queue.popleft()
children = asset_docs_by_parent_id[asset_doc["_id"]]
asset_item = AssetItem.from_doc(asset_doc, len(children) > 0)
asset_items_by_id[asset_item.id] = asset_item
task_items_by_asset_id[asset_item.id] = (
TaskItem.from_asset_doc(asset_doc, project_doc)
)
for child in children:
hierarchy_queue.append(child)
def refresh_assets(self, project_name, force=False):
self._event_system.emit(
@ -184,21 +229,330 @@ class SelectionModel:
)
class RepublisherDialogController:
def __init__(self):
class UserPublishValues:
"""Helper object to validate values required for push to different project.
Args:
event_system (EventSystem): Event system to catch and emit events.
new_asset_name (str): Name of new asset name.
variant (str): Variant for new subset name in new project.
"""
asset_name_regex = re.compile("^[a-zA-Z0-9_.]+$")
variant_regex = re.compile("^[{}]+$".format(SUBSET_NAME_ALLOWED_SYMBOLS))
def __init__(self, event_system):
self._event_system = event_system
self._new_asset_name = None
self._variant = None
self._comment = None
self._is_variant_valid = False
self._is_new_asset_name_valid = False
self.set_new_asset("")
self.set_variant("")
self.set_comment("")
@property
def new_asset_name(self):
return self._new_asset_name
@property
def variant(self):
return self._variant
@property
def comment(self):
return self._comment
@property
def is_variant_valid(self):
return self._is_variant_valid
@property
def is_new_asset_name_valid(self):
return self._is_new_asset_name_valid
@property
def is_valid(self):
return self.is_variant_valid and self.is_new_asset_name_valid
def set_variant(self, variant):
if variant == self._variant:
return
old_variant = self._variant
old_is_valid = self._is_variant_valid
self._variant = variant
is_valid = False
if variant:
is_valid = self.variant_regex.match(variant) is not None
self._is_variant_valid = is_valid
changes = {
key: {"new": new, "old": old}
for key, old, new in (
("variant", old_variant, variant),
("is_valid", old_is_valid, is_valid)
)
}
self._event_system.emit(
"variant.changed",
{
"variant": variant,
"is_valid": self._is_variant_valid,
"changes": changes
},
"user_values"
)
def set_new_asset(self, asset_name):
if self._new_asset_name == asset_name:
return
old_asset_name = self._new_asset_name
old_is_valid = self._is_new_asset_name_valid
self._new_asset_name = asset_name
is_valid = True
if asset_name:
is_valid = (
self.asset_name_regex.match(asset_name) is not None
)
self._is_new_asset_name_valid = is_valid
changes = {
key: {"new": new, "old": old}
for key, old, new in (
("new_asset_name", old_asset_name, asset_name),
("is_valid", old_is_valid, is_valid)
)
}
self._event_system.emit(
"new_asset_name.changed",
{
"new_asset_name": self._new_asset_name,
"is_valid": self._is_new_asset_name_valid,
"changes": changes
},
"user_values"
)
def set_comment(self, comment):
if comment == self._comment:
return
old_comment = self._comment
self._comment = comment
self._event_system.emit(
"comment.changed",
{
"new_asset_name": comment,
"changes": {
"comment": {"new": comment, "old": old_comment}
}
},
"user_values"
)
class PushToContextController:
def __init__(self, project_name=None, version_id=None):
self._src_project_name = None
self._src_version_id = None
self._src_asset_doc = None
self._src_subset_doc = None
self._src_version_doc = None
event_system = EventSystem()
entities_model = EntitiesModel(event_system)
selection_model = SelectionModel(event_system)
user_values = UserPublishValues(event_system)
self._event_system = event_system
self._entities_model = entities_model
self._selection_model = selection_model
self.dst_project_name = None
self.dst_asset_id = None
self.dst_task_name = None
self._user_values = user_values
event_system.add_callback("project.changed", self._on_project_change)
event_system.add_callback("asset.changed", self._invalidate)
event_system.add_callback("variant.changed", self._invalidate)
event_system.add_callback("new_asset_name.changed", self._invalidate)
self._submission_enabled = False
self.set_source(project_name, version_id)
def _get_task_info_from_repre_docs(self, asset_doc, repre_docs):
asset_tasks = asset_doc["data"].get("tasks") or {}
found_comb = []
for repre_doc in repre_docs:
context = repre_doc["context"]
task_info = context.get("task")
if task_info is None:
continue
task_name = None
task_type = None
if isinstance(task_info, str):
task_name = task_info
asset_task_info = asset_tasks.get(task_info) or {}
task_type = asset_task_info.get("type")
elif isinstance(task_info, dict):
task_name = task_info.get("name")
task_type = task_info.get("type")
if task_name and task_type:
return task_name, task_type
if task_name:
found_comb.append((task_name, task_type))
for task_name, task_type in found_comb:
return task_name, task_type
return None, None
def _get_src_variant(self):
project_name = self._src_project_name
version_doc = self._src_version_doc
asset_doc = self._src_asset_doc
repre_docs = get_representations(
project_name, version_ids=[version_doc["_id"]]
)
task_name, task_type = self._get_task_info_from_repre_docs(
asset_doc, repre_docs
)
project_settings = get_project_settings(project_name)
subset_doc = self.src_subset_doc
family = subset_doc["data"].get("family")
if not family:
family = subset_doc["data"]["families"][0]
template = get_subset_name_template(
self._src_project_name,
family,
task_name,
task_type,
None,
project_settings=project_settings
)
template_low = template.lower()
variant_placeholder = "{variant}"
if (
variant_placeholder not in template_low
or (not task_name and "{task" in template_low)
):
return ""
idx = template_low.index(variant_placeholder)
template_s = template[:idx]
template_e = template[idx + len(variant_placeholder):]
fill_data = prepare_template_data({
"family": family,
"task": task_name
})
try:
subset_s = template_s.format(**fill_data)
subset_e = template_e.format(**fill_data)
except Exception as exc:
print("Failed format", exc)
return ""
subset_name = self.src_subset_doc["name"]
if (
(subset_s and not subset_name.startswith(subset_s))
or (subset_e and not subset_name.endswith(subset_e))
):
return ""
if subset_s:
subset_name = subset_name[len(subset_s):]
if subset_e:
subset_name = subset_name[:len(subset_e)]
return subset_name
def set_source(self, project_name, version_id):
if (
project_name == self._src_project_name
and version_id == self._src_version_id
):
return
self._src_project_name = project_name
self._src_version_id = version_id
asset_doc = None
subset_doc = None
version_doc = None
if project_name and version_id:
version_doc = get_version_by_id(project_name, version_id)
if version_doc:
subset_doc = get_subset_by_id(project_name, version_doc["parent"])
if subset_doc:
asset_doc = get_asset_by_id(project_name, subset_doc["parent"])
self._src_asset_doc = asset_doc
self._src_subset_doc = subset_doc
self._src_version_doc = version_doc
if asset_doc:
self.user_values.set_new_asset(asset_doc["name"])
variant = self._get_src_variant()
if variant:
self.user_values.set_variant(variant)
comment = version_doc["data"].get("comment")
if comment:
self.user_values.set_comment(comment)
self._event_system.emit(
"source.changed", {
"project_name": project_name,
"version_id": version_id
},
"controller"
)
@property
def src_project_name(self):
return self._src_project_name
@property
def src_version_id(self):
return self._src_version_id
@property
def src_label(self):
if not self._src_project_name or not self._src_version_id:
return "Source is not defined"
asset_doc = self.src_asset_doc
if not asset_doc:
return "Source is invalid"
asset_path_parts = list(asset_doc["data"]["parents"])
asset_path_parts.append(asset_doc["name"])
asset_path = "/".join(asset_path_parts)
subset_doc = self.src_subset_doc
version_doc = self.src_version_doc
return "Source: {}/{}/{}/v{:0>3}".format(
self._src_project_name,
asset_path,
subset_doc["name"],
version_doc["name"]
)
@property
def src_version_doc(self):
return self._src_version_doc
@property
def src_subset_doc(self):
return self._src_subset_doc
@property
def src_asset_doc(self):
return self._src_asset_doc
@property
def event_system(self):
@ -212,11 +566,60 @@ class RepublisherDialogController:
def selection_model(self):
return self._selection_model
@property
def user_values(self):
return self._user_values
@property
def submission_enabled(self):
return self._submission_enabled
def _on_project_change(self, event):
project_name = event["project_name"]
self.model.refresh_assets(project_name)
self._invalidate()
def _invalidate(self):
submission_enabled = self._check_submit_validations()
if submission_enabled == self._submission_enabled:
return
self._submission_enabled = submission_enabled
self._event_system.emit(
"submission.enabled.changed",
{"enabled": submission_enabled},
"controller"
)
def _check_submit_validations(self):
if not self._user_values.is_valid:
return False
if not self.selection_model.project_name:
return False
if (
not self._user_values.new_asset_name
and not self.selection_model.asset_id
):
return False
return True
def get_selected_asset_name(self):
project_name = self._selection_model.project_name
asset_id = self._selection_model.asset_id
if not project_name or not asset_id:
return None
asset_item = self._entities_model.get_asset_by_id(
project_name, asset_id
)
if asset_item:
return asset_item.name
return None
def submit(self):
if not self.submission_enabled:
return
project_name = self.selection_model.project_name
asset_id = self.selection_model.asset_id
task_name = self.selection_model.task_name

View file

@ -1,17 +1,23 @@
import re
import collections
from qtpy import QtWidgets, QtGui, QtCore
from openpype.style import load_stylesheet
from openpype.style import load_stylesheet, get_app_icon_path
from openpype.tools.utils import (
PlaceholderLineEdit,
SeparatorWidget,
get_asset_icon_by_name,
set_style_property,
)
from .control import RepublisherDialogController
from .control import PushToContextController
PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 1
ASSET_NAME_ROLE = QtCore.Qt.UserRole + 2
ASSET_ICON_ROLE = QtCore.Qt.UserRole + 3
ASSET_ID_ROLE = QtCore.Qt.UserRole + 4
TASK_NAME_ROLE = QtCore.Qt.UserRole + 5
TASK_TYPE_ROLE = QtCore.Qt.UserRole + 6
ASSET_ID_ROLE = QtCore.Qt.UserRole + 3
TASK_NAME_ROLE = QtCore.Qt.UserRole + 4
TASK_TYPE_ROLE = QtCore.Qt.UserRole + 5
class ProjectsModel(QtGui.QStandardItemModel):
@ -19,6 +25,8 @@ class ProjectsModel(QtGui.QStandardItemModel):
refreshing_text = "< Refreshing >"
select_project_text = "< Select Project >"
refreshed = QtCore.Signal()
def __init__(self, controller):
super(ProjectsModel, self).__init__()
self._controller = controller
@ -59,7 +67,7 @@ class ProjectsModel(QtGui.QStandardItemModel):
if project_name is None:
continue
item = self._items.pop(project_name)
root_item.removeRow(item.row())
root_item.takeRow(item.row())
for project_name in project_names:
if project_name in self._items:
@ -70,6 +78,7 @@ class ProjectsModel(QtGui.QStandardItemModel):
if new_items:
root_item.appendRows(new_items)
self.refreshed.emit()
class ProjectProxyModel(QtCore.QSortFilterProxyModel):
@ -94,6 +103,7 @@ class ProjectProxyModel(QtCore.QSortFilterProxyModel):
class AssetsModel(QtGui.QStandardItemModel):
items_changed = QtCore.Signal()
empty_text = "< Empty >"
def __init__(self, controller):
@ -151,6 +161,7 @@ class AssetsModel(QtGui.QStandardItemModel):
self._last_project = project_name
self._clear()
self.items_changed.emit()
def _on_refresh_start(self, event):
pass
@ -165,11 +176,13 @@ class AssetsModel(QtGui.QStandardItemModel):
if project_name is None:
if None not in self._items:
self._clear()
self.items_changed.emit()
return
asset_items_by_id = self._controller.model.get_assets(project_name)
if not asset_items_by_id:
self._clear()
self.items_changed.emit()
return
assets_by_parent_id = collections.defaultdict(list)
@ -201,9 +214,12 @@ class AssetsModel(QtGui.QStandardItemModel):
elif item.parent() is not parent_item:
new_items.append(item)
icon = get_asset_icon_by_name(
asset_item.icon_name, asset_item.icon_color
)
item.setData(asset_item.name, QtCore.Qt.DisplayRole)
item.setData(icon, QtCore.Qt.DecorationRole)
item.setData(asset_item.id, ASSET_ID_ROLE)
item.setData(asset_item.icon, ASSET_ICON_ROLE)
hierarchy_queue.append((asset_item.id, item))
@ -216,10 +232,13 @@ class AssetsModel(QtGui.QStandardItemModel):
continue
parent = item.parent()
if parent is not None:
parent.removeRow(item.row())
parent.takeRow(item.row())
self.items_changed.emit()
class TasksModel(QtGui.QStandardItemModel):
items_changed = QtCore.Signal()
empty_text = "< Empty >"
def __init__(self, controller):
@ -277,6 +296,7 @@ class TasksModel(QtGui.QStandardItemModel):
self._last_project = project_name
self._clear()
self.items_changed.emit()
def _on_asset_refresh_finish(self, event):
self._refresh(event["project_name"])
@ -293,6 +313,7 @@ class TasksModel(QtGui.QStandardItemModel):
if project_name is None:
if None not in self._items:
self._clear()
self.items_changed.emit()
return
asset_id = self._controller.selection_model.asset_id
@ -301,6 +322,7 @@ class TasksModel(QtGui.QStandardItemModel):
)
if not task_items:
self._clear()
self.items_changed.emit()
return
root_item = self.invisibleRootItem()
@ -338,74 +360,153 @@ class TasksModel(QtGui.QStandardItemModel):
if parent is not None:
parent.removeRow(item.row())
self.items_changed.emit()
class RepublisherDialogWindow(QtWidgets.QWidget):
class PushToContextSelectWindow(QtWidgets.QWidget):
def __init__(self, controller=None):
super(RepublisherDialogWindow, self).__init__()
super(PushToContextSelectWindow, self).__init__()
if controller is None:
controller = RepublisherDialogController()
controller = PushToContextController()
self._controller = controller
main_splitter = QtWidgets.QSplitter(self)
self.setWindowTitle("Push to project (select context)")
self.setWindowIcon(QtGui.QIcon(get_app_icon_path()))
left_widget = QtWidgets.QWidget(main_splitter)
header_widget = QtWidgets.QWidget(self)
project_combobox = QtWidgets.QComboBox(left_widget)
header_label = QtWidgets.QLabel(controller.src_label, header_widget)
header_layout = QtWidgets.QHBoxLayout(header_widget)
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.addWidget(header_label)
main_splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal, self)
context_widget = QtWidgets.QWidget(main_splitter)
project_combobox = QtWidgets.QComboBox(context_widget)
project_model = ProjectsModel(controller)
project_proxy = ProjectProxyModel()
project_proxy.setSourceModel(project_model)
project_proxy.setDynamicSortFilter(True)
project_delegate = QtWidgets.QStyledItemDelegate()
project_combobox.setItemDelegate(project_delegate)
project_combobox.setModel(project_proxy)
asset_view = QtWidgets.QTreeView(left_widget)
asset_task_splitter = QtWidgets.QSplitter(
QtCore.Qt.Vertical, context_widget
)
asset_view = QtWidgets.QTreeView(asset_task_splitter)
asset_view.setHeaderHidden(True)
asset_model = AssetsModel(controller)
asset_view.setModel(asset_model)
asset_proxy = QtCore.QSortFilterProxyModel()
asset_proxy.setSourceModel(asset_model)
asset_proxy.setDynamicSortFilter(True)
asset_view.setModel(asset_proxy)
left_layout = QtWidgets.QVBoxLayout(left_widget)
left_layout.setContentsMargins(0, 0, 0, 0)
left_layout.addWidget(project_combobox, 0)
left_layout.addWidget(asset_view, 1)
right_widget = QtWidgets.QWidget(main_splitter)
task_view = QtWidgets.QListView(right_widget)
task_view = QtWidgets.QListView(asset_task_splitter)
task_proxy = QtCore.QSortFilterProxyModel()
task_model = TasksModel(controller)
task_proxy.setSourceModel(task_model)
task_proxy.setDynamicSortFilter(True)
task_view.setModel(task_proxy)
right_layout = QtWidgets.QVBoxLayout(right_widget)
right_layout.setContentsMargins(0, 0, 0, 0)
right_layout.addWidget(task_view, 1)
asset_task_splitter.addWidget(asset_view)
asset_task_splitter.addWidget(task_view)
main_splitter.addWidget(left_widget)
main_splitter.addWidget(right_widget)
context_layout = QtWidgets.QVBoxLayout(context_widget)
context_layout.setContentsMargins(0, 0, 0, 0)
context_layout.addWidget(project_combobox, 0)
context_layout.addWidget(asset_task_splitter, 1)
# --- Inputs widget ---
inputs_widget = QtWidgets.QWidget(main_splitter)
asset_name_input = PlaceholderLineEdit(inputs_widget)
asset_name_input.setPlaceholderText("< Name of new asset >")
asset_name_input.setObjectName("ValidatedLineEdit")
variant_input = PlaceholderLineEdit(inputs_widget)
variant_input.setPlaceholderText("< Variant >")
variant_input.setObjectName("ValidatedLineEdit")
comment_input = PlaceholderLineEdit(inputs_widget)
comment_input.setPlaceholderText("< Publish comment >")
inputs_layout = QtWidgets.QFormLayout(inputs_widget)
inputs_layout.setContentsMargins(0, 0, 0, 0)
inputs_layout.addRow("New asset name", asset_name_input)
inputs_layout.addRow("Variant", variant_input)
inputs_layout.addRow("Comment", comment_input)
main_splitter.addWidget(context_widget)
main_splitter.addWidget(inputs_widget)
# --- Buttons widget ---
btns_widget = QtWidgets.QWidget(self)
close_btn = QtWidgets.QPushButton("Close", btns_widget)
select_btn = QtWidgets.QPushButton("Select", btns_widget)
cancel_btn = QtWidgets.QPushButton("Cancel", btns_widget)
publish_btn = QtWidgets.QPushButton("Publish", btns_widget)
btns_layout = QtWidgets.QHBoxLayout(btns_widget)
btns_layout.setContentsMargins(0, 0, 0, 0)
btns_layout.addStretch(1)
btns_layout.addWidget(close_btn, 0)
btns_layout.addWidget(select_btn, 0)
btns_layout.addWidget(cancel_btn, 0)
btns_layout.addWidget(publish_btn, 0)
main_layout = QtWidgets.QHBoxLayout(self)
sep_1 = SeparatorWidget(parent=self)
sep_2 = SeparatorWidget(parent=self)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(header_widget, 0)
main_layout.addWidget(sep_1, 0)
main_layout.addWidget(main_splitter, 1)
main_layout.addWidget(sep_2, 0)
main_layout.addWidget(btns_widget, 0)
show_timer = QtCore.QTimer()
show_timer.setInterval(1)
user_input_changed_timer = QtCore.QTimer()
user_input_changed_timer.setInterval(200)
user_input_changed_timer.setSingleShot(True)
show_timer.timeout.connect(self._on_show_timer)
user_input_changed_timer.timeout.connect(self._on_user_input_timer)
asset_name_input.textChanged.connect(self._on_new_asset_change)
variant_input.textChanged.connect(self._on_variant_change)
comment_input.textChanged.connect(self._on_comment_change)
project_model.refreshed.connect(self._on_projects_refresh)
project_combobox.currentIndexChanged.connect(self._on_project_change)
asset_view.selectionModel().selectionChanged.connect(
self._on_asset_change
)
asset_model.items_changed.connect(self._on_asset_model_change)
task_view.selectionModel().selectionChanged.connect(
self._on_task_change
)
select_btn.clicked.connect(self._on_select_click)
close_btn.clicked.connect(self._on_close_click)
task_model.items_changed.connect(self._on_task_model_change)
publish_btn.clicked.connect(self._on_select_click)
cancel_btn.clicked.connect(self._on_close_click)
controller.event_system.add_callback(
"new_asset_name.changed", self._on_controller_new_asset_change
)
controller.event_system.add_callback(
"variant.changed", self._on_controller_variant_change
)
controller.event_system.add_callback(
"comment.changed", self._on_controller_comment_change
)
controller.event_system.add_callback(
"submission.enabled.changed", self._on_submission_change
)
controller.event_system.add_callback(
"source.changed", self._on_controller_source_change
)
self._header_label = header_label
self._main_splitter = main_splitter
self._project_combobox = project_combobox
self._project_model = project_model
@ -414,17 +515,153 @@ class RepublisherDialogWindow(QtWidgets.QWidget):
self._asset_view = asset_view
self._asset_model = asset_model
self._asset_proxy_model = asset_proxy
self._task_view = task_view
self._task_proxy_model = task_proxy
self._variant_input = variant_input
self._asset_name_input = asset_name_input
self._comment_input = comment_input
self._publish_btn = publish_btn
self._user_input_changed_timer = user_input_changed_timer
# Store current value on input text change
# The value is unset when is passed to controller
# The goal is to have controll over changes happened during user change
# in UI and controller auto-changes
self._variant_input_text = None
self._new_asset_name_input_text = None
self._comment_input_text = None
self._show_timer = show_timer
self._show_counter = 2
self._first_show = True
publish_btn.setEnabled(False)
if controller.user_values.new_asset_name:
asset_name_input.setText(controller.user_values.new_asset_name)
if controller.user_values.variant:
variant_input.setText(controller.user_values.variant)
self._invalidate_variant()
self._invalidate_new_asset_name()
@property
def controller(self):
return self._controller
def showEvent(self, event):
super(RepublisherDialogWindow, self).showEvent(event)
super(PushToContextSelectWindow, self).showEvent(event)
if self._first_show:
self._first_show = False
self._controller.model.refresh_projects()
self.setStyleSheet(load_stylesheet())
self._invalidate_variant()
self._show_timer.start()
def _on_show_timer(self):
if self._show_counter == 0:
self._show_timer.stop()
return
self._show_counter -= 1
if self._show_counter == 1:
width = 740
height = 640
inputs_width = 360
self.resize(width, height)
self._main_splitter.setSizes([width - inputs_width, inputs_width])
if self._show_counter > 0:
return
self._controller.model.refresh_projects()
def _on_new_asset_change(self, text):
self._new_asset_name_input_text = text
self._user_input_changed_timer.start()
def _on_variant_change(self, text):
self._variant_input_text = text
self._user_input_changed_timer.start()
def _on_comment_change(self, text):
self._comment_input_text = text
self._user_input_changed_timer.start()
def _on_user_input_timer(self):
asset_name = self._new_asset_name_input_text
if asset_name is not None:
self._new_asset_name_input_text = None
self._controller.user_values.set_new_asset(asset_name)
variant = self._variant_input_text
if variant is not None:
self._variant_input_text = None
self._controller.user_values.set_variant(variant)
comment = self._comment_input_text
if comment is not None:
self._comment_input_text = None
self._controller.user_values.set_comment(comment)
def _on_controller_new_asset_change(self, event):
asset_name = event["changes"]["new_asset_name"]["new"]
if (
self._new_asset_name_input_text is None
and asset_name != self._asset_name_input.text()
):
self._asset_name_input.setText(asset_name)
self._invalidate_new_asset_name()
def _on_controller_variant_change(self, event):
is_valid_changes = event["changes"]["is_valid"]
variant = event["changes"]["variant"]["new"]
if (
self._variant_input_text is None
and variant != self._variant_input.text()
):
self._variant_input.setText(variant)
if is_valid_changes["old"] != is_valid_changes["new"]:
self._invalidate_variant()
def _on_controller_comment_change(self, event):
comment = event["comment"]
if (
self._comment_input_text is None
and comment != self._comment_input.text()
):
self._comment_input.setText(comment)
def _on_controller_source_change(self):
self._header_label.setText(self._controller.src_label)
def _invalidate_new_asset_name(self):
asset_name = self._controller.user_values.new_asset_name
self._task_view.setVisible(not asset_name)
valid = None
if asset_name:
valid = self._controller.user_values.is_new_asset_name_valid
state = ""
if valid is True:
state = "valid"
elif valid is False:
state = "invalid"
set_style_property(self._asset_name_input, "state", state)
def _invalidate_variant(self):
valid = self._controller.user_values.is_variant_valid
state = "invalid"
if valid is True:
state = "valid"
set_style_property(self._variant_input, "state", state)
def _on_projects_refresh(self):
self._project_proxy.sort(0, QtCore.Qt.AscendingOrder)
def _on_project_change(self):
idx = self._project_combobox.currentIndex()
@ -445,6 +682,12 @@ class RepublisherDialogWindow(QtWidgets.QWidget):
asset_id = model.data(index, ASSET_ID_ROLE)
self._controller.selection_model.select_asset(asset_id)
def _on_asset_model_change(self):
self._asset_proxy_model.sort(0, QtCore.Qt.AscendingOrder)
def _on_task_model_change(self):
self._task_proxy_model.sort(0, QtCore.Qt.AscendingOrder)
def _on_task_change(self):
indexes = self._task_view.selectedIndexes()
index = next(iter(indexes), None)
@ -454,6 +697,9 @@ class RepublisherDialogWindow(QtWidgets.QWidget):
task_name = model.data(index, TASK_NAME_ROLE)
self._controller.selection_model.select_task(task_name)
def _on_submission_change(self, event):
self._publish_btn.setEnabled(event["enabled"])
def _on_close_click(self):
self.close()
@ -464,14 +710,29 @@ class RepublisherDialogWindow(QtWidgets.QWidget):
def main():
app = QtWidgets.QApplication.instance()
if not app:
# 'AA_EnableHighDpiScaling' must be set before app instance creation
high_dpi_scale_attr = getattr(
QtCore.Qt, "AA_EnableHighDpiScaling", None
)
if high_dpi_scale_attr is not None:
QtWidgets.QApplication.setAttribute(high_dpi_scale_attr)
app = QtWidgets.QApplication([])
for attr_name in (
"AA_UseHighDpiPixmaps",
):
attr = getattr(QtCore.Qt, attr_name, None)
if attr is not None:
app.setAttribute(attr)
# TODO find way how to get these
project_name = None
representation_id = None
version_id = None
# Show window dialog
window = RepublisherDialogWindow()
window = PushToContextSelectWindow()
window.controller.set_source(project_name, version_id)
window.show()
app.exec_()