added workfiles page to launcher window

This commit is contained in:
Jakub Trllo 2025-09-12 12:58:37 +02:00
parent d960694f45
commit 0794db9ac2
3 changed files with 190 additions and 3 deletions

View file

@ -12,6 +12,8 @@ from ayon_core.tools.utils import (
)
from ayon_core.tools.utils.lib import checkstate_int_to_enum
from .workfiles_page import WorkfilesPage
class HierarchyPage(QtWidgets.QWidget):
def __init__(self, controller, parent):
@ -73,10 +75,15 @@ class HierarchyPage(QtWidgets.QWidget):
# - Tasks widget
tasks_widget = TasksWidget(controller, content_body)
# - Third page - Workfiles
workfiles_page = WorkfilesPage(controller, content_body)
content_body.addWidget(folders_widget)
content_body.addWidget(tasks_widget)
content_body.setStretchFactor(0, 100)
content_body.setStretchFactor(1, 65)
content_body.addWidget(workfiles_page)
content_body.setStretchFactor(0, 120)
content_body.setStretchFactor(1, 85)
content_body.setStretchFactor(2, 220)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
@ -99,6 +106,7 @@ class HierarchyPage(QtWidgets.QWidget):
self._my_tasks_checkbox = my_tasks_checkbox
self._folders_widget = folders_widget
self._tasks_widget = tasks_widget
self._workfiles_page = workfiles_page
self._project_name = None
@ -117,6 +125,7 @@ class HierarchyPage(QtWidgets.QWidget):
def refresh(self):
self._folders_widget.refresh()
self._tasks_widget.refresh()
self._workfiles_page.refresh()
self._on_my_tasks_checkbox_state_changed(
self._my_tasks_checkbox.checkState()
)

View file

@ -177,7 +177,7 @@ class LauncherWindow(QtWidgets.QWidget):
self._page_slide_anim = page_slide_anim
hierarchy_page.setVisible(not self._is_on_projects_page)
self.resize(520, 740)
self.resize(920, 740)
def showEvent(self, event):
super().showEvent(event)

View file

@ -0,0 +1,178 @@
from typing import Optional
import ayon_api
from qtpy import QtCore, QtWidgets, QtGui
from ayon_core.tools.utils import get_qt_icon
from ayon_core.tools.launcher.abstract import AbstractLauncherFrontEnd
VERSION_ROLE = QtCore.Qt.UserRole + 1
class WorkfilesModel(QtGui.QStandardItemModel):
refreshed = QtCore.Signal()
def __init__(self, controller: AbstractLauncherFrontEnd) -> None:
super().__init__()
self.setColumnCount(1)
self.setHeaderData(0, QtCore.Qt.Horizontal, "Workfiles")
controller.register_event_callback(
"selection.project.changed",
self._on_selection_project_changed,
)
controller.register_event_callback(
"selection.folder.changed",
self._on_selection_folder_changed,
)
controller.register_event_callback(
"selection.task.changed",
self._on_selection_task_changed,
)
self._controller = controller
self._selected_project_name = None
self._selected_folder_id = None
self._selected_task_id = None
self._transparent_icon = None
self._cached_icons = {}
def refresh(self) -> None:
root_item = self.invisibleRootItem()
root_item.removeRows(0, root_item.rowCount())
workfile_items = self._controller.get_workfile_items(
self._selected_project_name, self._selected_task_id
)
new_items = []
for workfile_item in workfile_items:
icon = self._get_icon(workfile_item.icon)
item = QtGui.QStandardItem(workfile_item.filename)
item.setData(icon, QtCore.Qt.DecorationRole)
item.setData(workfile_item.version, VERSION_ROLE)
flags = QtCore.Qt.NoItemFlags
if workfile_item.exists:
flags = QtCore.Qt.ItemIsEnabled
item.setFlags(flags)
new_items.append(item)
if not new_items:
title = "< No workfiles >"
if not self._selected_project_name:
title = "< Select a project >"
elif not self._selected_folder_id:
title = "< Select a folder >"
elif not self._selected_task_id:
title = "< Select a task >"
item = QtGui.QStandardItem(title)
item.setFlags(QtCore.Qt.NoItemFlags)
new_items.append(item)
root_item.appendRows(new_items)
self.refreshed.emit()
def _on_selection_project_changed(self, event) -> None:
self._selected_project_name = event["project_name"]
self._selected_folder_id = None
self._selected_task_id = None
self.refresh()
def _on_selection_folder_changed(self, event) -> None:
self._selected_project_name = event["project_name"]
self._selected_folder_id = event["folder_id"]
self._selected_task_id = None
self.refresh()
def _on_selection_task_changed(self, event) -> None:
self._selected_project_name = event["project_name"]
self._selected_folder_id = event["folder_id"]
self._selected_task_id = event["task_id"]
self.refresh()
def _get_transparent_icon(self) -> QtGui.QIcon:
if self._transparent_icon is None:
self._transparent_icon = get_qt_icon({
"type": "transparent", "size": 256
})
return self._transparent_icon
def _get_icon(self, icon_url: Optional[str]) -> QtGui.QIcon:
if icon_url is None:
return self._get_transparent_icon()
icon = self._cached_icons.get(icon_url)
if icon is not None:
return icon
base_url = ayon_api.get_base_url()
if icon_url.startswith(base_url):
icon_def = {
"type": "ayon_url",
"url": icon_url[len(base_url) + 1:],
}
else:
icon_def = {
"type": "url",
"url": icon_url,
}
icon = get_qt_icon(icon_def)
if icon is None:
icon = self._get_transparent_icon()
self._cached_icons[icon_url] = icon
return icon
class WorkfilesProxyModel(QtCore.QSortFilterProxyModel):
def lessThan(self, left, right) -> bool:
# left_version = left.data(VERSION_ROLE)
# right_version = right.data(VERSION_ROLE)
# if left_version != right_version:
# if left_version is None:
# return False
# if right_version is None:
# return True
#
# return left_version > right_version
return not super().lessThan(left, right)
class WorkfilesView(QtWidgets.QTreeView):
def drawBranches(self, painter, rect, index):
return
class WorkfilesPage(QtWidgets.QWidget):
def __init__(
self,
controller: AbstractLauncherFrontEnd,
parent: QtWidgets.QWidget,
) -> None:
super().__init__(parent)
workfiles_view = WorkfilesView(self)
workfiles_view.setIndentation(0)
workfiles_model = WorkfilesModel(controller)
workfiles_proxy = WorkfilesProxyModel()
workfiles_proxy.setSourceModel(workfiles_model)
workfiles_view.setModel(workfiles_proxy)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(workfiles_view, 1)
workfiles_model.refreshed.connect(self._on_refresh)
self._controller = controller
self._workfiles_view = workfiles_view
self._workfiles_model = workfiles_model
self._workfiles_proxy = workfiles_proxy
def refresh(self) -> None:
self._workfiles_model.refresh()
def _on_refresh(self) -> None:
self._workfiles_proxy.sort(0)