mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge pull request #137 from ynput/enhancement/traypublisher-using-ayon-projects-model
TrayPublisher: Use AYON projects model
This commit is contained in:
commit
d856bd0cb5
4 changed files with 49 additions and 188 deletions
|
|
@ -3,6 +3,10 @@ from .projects_widget import (
|
|||
ProjectsCombobox,
|
||||
ProjectsQtModel,
|
||||
ProjectSortFilterProxy,
|
||||
PROJECT_NAME_ROLE,
|
||||
PROJECT_IS_CURRENT_ROLE,
|
||||
PROJECT_IS_ACTIVE_ROLE,
|
||||
PROJECT_IS_LIBRARY_ROLE,
|
||||
)
|
||||
|
||||
from .folders_widget import (
|
||||
|
|
@ -28,6 +32,10 @@ __all__ = (
|
|||
"ProjectsCombobox",
|
||||
"ProjectsQtModel",
|
||||
"ProjectSortFilterProxy",
|
||||
"PROJECT_NAME_ROLE",
|
||||
"PROJECT_IS_CURRENT_ROLE",
|
||||
"PROJECT_IS_ACTIVE_ROLE",
|
||||
"PROJECT_IS_LIBRARY_ROLE",
|
||||
|
||||
"FoldersWidget",
|
||||
"FoldersQtModel",
|
||||
|
|
|
|||
|
|
@ -47,6 +47,22 @@ class ProjectsQtModel(QtGui.QStandardItemModel):
|
|||
def has_content(self):
|
||||
return len(self._project_items) > 0
|
||||
|
||||
def get_index_by_project_name(self, project_name):
|
||||
"""Get index of project by name.
|
||||
|
||||
Args:
|
||||
project_name (str): Project name.
|
||||
|
||||
Returns:
|
||||
QtCore.QModelIndex: Index of project item. Index is not valid
|
||||
if project is not found.
|
||||
|
||||
"""
|
||||
item = self._project_items.get(project_name)
|
||||
if item is None:
|
||||
return QtCore.QModelIndex()
|
||||
return self.indexFromItem(item)
|
||||
|
||||
def set_select_item_visible(self, visible):
|
||||
if self._select_item_visible is visible:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -10,22 +10,31 @@ import platform
|
|||
|
||||
from qtpy import QtWidgets, QtCore
|
||||
import qtawesome
|
||||
import appdirs
|
||||
|
||||
from ayon_core.lib import JSONSettingRegistry, is_running_from_build
|
||||
from ayon_core.lib import AYONSettingsRegistry, is_running_from_build
|
||||
from ayon_core.pipeline import install_host
|
||||
from ayon_core.hosts.traypublisher.api import TrayPublisherHost
|
||||
from ayon_core.tools.publisher.control_qt import QtPublisherController
|
||||
from ayon_core.tools.publisher.window import PublisherWindow
|
||||
from ayon_core.tools.utils import PlaceholderLineEdit, get_ayon_qt_app
|
||||
from ayon_core.tools.utils.constants import PROJECT_NAME_ROLE
|
||||
from ayon_core.tools.utils.models import (
|
||||
ProjectModel,
|
||||
ProjectSortFilterProxy
|
||||
from ayon_core.tools.ayon_utils.models import ProjectsModel
|
||||
from ayon_core.tools.ayon_utils.widgets import (
|
||||
ProjectsQtModel,
|
||||
ProjectSortFilterProxy,
|
||||
PROJECT_NAME_ROLE,
|
||||
)
|
||||
|
||||
|
||||
class TrayPublisherRegistry(AYONSettingsRegistry):
|
||||
def __init__(self):
|
||||
super(TrayPublisherRegistry, self).__init__("traypublisher")
|
||||
|
||||
|
||||
class TrayPublisherController(QtPublisherController):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TrayPublisherController, self).__init__(*args, **kwargs)
|
||||
self._projects_model = ProjectsModel(self)
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
return self._host
|
||||
|
|
@ -34,28 +43,14 @@ class TrayPublisherController(QtPublisherController):
|
|||
self._hierarchy_model.reset()
|
||||
self._asset_docs_cache.reset()
|
||||
|
||||
|
||||
class TrayPublisherRegistry(JSONSettingRegistry):
|
||||
"""Class handling AYON general settings registry.
|
||||
|
||||
Attributes:
|
||||
vendor (str): Name used for path construction.
|
||||
product (str): Additional name used for path construction.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.vendor = "pypeclub"
|
||||
self.product = "openpype"
|
||||
name = "tray_publisher"
|
||||
path = appdirs.user_data_dir(self.product, self.vendor)
|
||||
super(TrayPublisherRegistry, self).__init__(name, path)
|
||||
def get_project_items(self, sender=None):
|
||||
return self._projects_model.get_project_items(sender)
|
||||
|
||||
|
||||
class StandaloneOverlayWidget(QtWidgets.QFrame):
|
||||
project_selected = QtCore.Signal(str)
|
||||
|
||||
def __init__(self, publisher_window):
|
||||
def __init__(self, controller, publisher_window):
|
||||
super(StandaloneOverlayWidget, self).__init__(publisher_window)
|
||||
self.setObjectName("OverlayFrame")
|
||||
|
||||
|
|
@ -67,7 +62,7 @@ class StandaloneOverlayWidget(QtWidgets.QFrame):
|
|||
header_label = QtWidgets.QLabel("Choose project", content_widget)
|
||||
header_label.setObjectName("ChooseProjectLabel")
|
||||
# Create project models and view
|
||||
projects_model = ProjectModel()
|
||||
projects_model = ProjectsQtModel(controller)
|
||||
projects_proxy = ProjectSortFilterProxy()
|
||||
projects_proxy.setSourceModel(projects_model)
|
||||
projects_proxy.setFilterKeyColumn(0)
|
||||
|
|
@ -138,12 +133,11 @@ class StandaloneOverlayWidget(QtWidgets.QFrame):
|
|||
project_name = None
|
||||
|
||||
if project_name:
|
||||
index = None
|
||||
src_index = self._projects_model.find_project(project_name)
|
||||
if src_index is not None:
|
||||
index = self._projects_proxy.mapFromSource(src_index)
|
||||
|
||||
if index is not None:
|
||||
src_index = self._projects_model.get_index_by_project_name(
|
||||
project_name
|
||||
)
|
||||
index = self._projects_proxy.mapFromSource(src_index)
|
||||
if index.isValid():
|
||||
selection_model = self._projects_view.selectionModel()
|
||||
selection_model.select(
|
||||
index,
|
||||
|
|
@ -202,7 +196,7 @@ class TrayPublishWindow(PublisherWindow):
|
|||
|
||||
self.setWindowFlags(flags)
|
||||
|
||||
overlay_widget = StandaloneOverlayWidget(self)
|
||||
overlay_widget = StandaloneOverlayWidget(controller, self)
|
||||
|
||||
btns_widget = self._header_extra_widget
|
||||
|
||||
|
|
|
|||
|
|
@ -243,160 +243,3 @@ class RecursiveSortFilterProxyModel(QtCore.QSortFilterProxyModel):
|
|||
return super(RecursiveSortFilterProxyModel, self).filterAcceptsRow(
|
||||
row, parent_index
|
||||
)
|
||||
|
||||
|
||||
# TODO remove 'ProjectModel' and 'ProjectSortFilterProxy' classes
|
||||
# - replace their usage with current 'ayon_utils' models
|
||||
class ProjectModel(QtGui.QStandardItemModel):
|
||||
def __init__(
|
||||
self, only_active=True, add_default_project=False, *args, **kwargs
|
||||
):
|
||||
super(ProjectModel, self).__init__(*args, **kwargs)
|
||||
|
||||
self._only_active = only_active
|
||||
self._add_default_project = add_default_project
|
||||
|
||||
self._default_item = None
|
||||
self._items_by_name = {}
|
||||
self._refreshed = False
|
||||
|
||||
def set_default_project_available(self, available=True):
|
||||
if available is None:
|
||||
available = not self._add_default_project
|
||||
|
||||
if self._add_default_project == available:
|
||||
return
|
||||
|
||||
self._add_default_project = available
|
||||
if not available and self._default_item is not None:
|
||||
root_item = self.invisibleRootItem()
|
||||
root_item.removeRow(self._default_item.row())
|
||||
self._default_item = None
|
||||
|
||||
def set_only_active(self, only_active=True):
|
||||
if only_active is None:
|
||||
only_active = not self._only_active
|
||||
|
||||
if self._only_active == only_active:
|
||||
return
|
||||
|
||||
self._only_active = only_active
|
||||
|
||||
if self._refreshed:
|
||||
self.refresh()
|
||||
|
||||
def project_name_is_available(self, project_name):
|
||||
"""Check availability of project name in current items."""
|
||||
return project_name in self._items_by_name
|
||||
|
||||
def refresh(self):
|
||||
# Change '_refreshed' state
|
||||
self._refreshed = True
|
||||
new_items = []
|
||||
# Add default item to model if should
|
||||
if self._add_default_project and self._default_item is None:
|
||||
item = QtGui.QStandardItem(DEFAULT_PROJECT_LABEL)
|
||||
item.setData(None, PROJECT_NAME_ROLE)
|
||||
item.setData(True, PROJECT_IS_ACTIVE_ROLE)
|
||||
new_items.append(item)
|
||||
self._default_item = item
|
||||
|
||||
project_names = set()
|
||||
project_docs = get_projects(
|
||||
inactive=not self._only_active,
|
||||
fields=["name", "data.active"]
|
||||
)
|
||||
for project_doc in project_docs:
|
||||
project_name = project_doc["name"]
|
||||
project_names.add(project_name)
|
||||
if project_name in self._items_by_name:
|
||||
item = self._items_by_name[project_name]
|
||||
else:
|
||||
item = QtGui.QStandardItem(project_name)
|
||||
|
||||
self._items_by_name[project_name] = item
|
||||
new_items.append(item)
|
||||
|
||||
is_active = project_doc.get("data", {}).get("active", True)
|
||||
item.setData(project_name, PROJECT_NAME_ROLE)
|
||||
item.setData(is_active, PROJECT_IS_ACTIVE_ROLE)
|
||||
|
||||
if not is_active:
|
||||
font = item.font()
|
||||
font.setItalic(True)
|
||||
item.setFont(font)
|
||||
|
||||
root_item = self.invisibleRootItem()
|
||||
for project_name in tuple(self._items_by_name.keys()):
|
||||
if project_name not in project_names:
|
||||
item = self._items_by_name.pop(project_name)
|
||||
root_item.removeRow(item.row())
|
||||
|
||||
if new_items:
|
||||
root_item.appendRows(new_items)
|
||||
|
||||
def find_project(self, project_name):
|
||||
"""
|
||||
Get index of 'project_name' value.
|
||||
|
||||
Args:
|
||||
project_name (str):
|
||||
Returns:
|
||||
(QModelIndex)
|
||||
"""
|
||||
val = self._items_by_name.get(project_name)
|
||||
if val:
|
||||
return self.indexFromItem(val)
|
||||
|
||||
|
||||
class ProjectSortFilterProxy(QtCore.QSortFilterProxyModel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ProjectSortFilterProxy, self).__init__(*args, **kwargs)
|
||||
self._filter_enabled = True
|
||||
# Disable case sensitivity
|
||||
self.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
|
||||
def lessThan(self, left_index, right_index):
|
||||
if left_index.data(PROJECT_NAME_ROLE) is None:
|
||||
return True
|
||||
|
||||
if right_index.data(PROJECT_NAME_ROLE) is None:
|
||||
return False
|
||||
|
||||
left_is_active = left_index.data(PROJECT_IS_ACTIVE_ROLE)
|
||||
right_is_active = right_index.data(PROJECT_IS_ACTIVE_ROLE)
|
||||
if right_is_active == left_is_active:
|
||||
return super(ProjectSortFilterProxy, self).lessThan(
|
||||
left_index, right_index
|
||||
)
|
||||
|
||||
if left_is_active:
|
||||
return True
|
||||
return False
|
||||
|
||||
def filterAcceptsRow(self, source_row, source_parent):
|
||||
index = self.sourceModel().index(source_row, 0, source_parent)
|
||||
string_pattern = self.filterRegularExpression().pattern()
|
||||
if self._filter_enabled:
|
||||
result = self._custom_index_filter(index)
|
||||
if result is not None:
|
||||
project_name = index.data(PROJECT_NAME_ROLE)
|
||||
if project_name is None:
|
||||
return result
|
||||
return string_pattern.lower() in project_name.lower()
|
||||
|
||||
return super(ProjectSortFilterProxy, self).filterAcceptsRow(
|
||||
source_row, source_parent
|
||||
)
|
||||
|
||||
def _custom_index_filter(self, index):
|
||||
is_active = bool(index.data(PROJECT_IS_ACTIVE_ROLE))
|
||||
|
||||
return is_active
|
||||
|
||||
def is_filter_enabled(self):
|
||||
return self._filter_enabled
|
||||
|
||||
def set_filter_enabled(self, value):
|
||||
self._filter_enabled = value
|
||||
self.invalidateFilter()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue