mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
SyncServer - implemented priority in SummaryView
SummaryDetail not implemented Still some kinks to iron out
This commit is contained in:
parent
81baab0372
commit
ad87c65b75
3 changed files with 134 additions and 7 deletions
|
|
@ -1,9 +1,11 @@
|
|||
from Qt import QtCore
|
||||
from Qt import QtCore, QtWidgets, QtGui
|
||||
from Qt.QtCore import Qt
|
||||
import attr
|
||||
import abc
|
||||
import six
|
||||
|
||||
from openpype.lib import PypeLogger
|
||||
from avalon.vendor import qtawesome
|
||||
|
||||
|
||||
log = PypeLogger().get_logger("SyncServer")
|
||||
|
|
@ -164,3 +166,56 @@ def get_item_by_id(model, object_id):
|
|||
index = model.get_index(object_id)
|
||||
item = model.data(index, FullItemRole)
|
||||
return item
|
||||
|
||||
|
||||
class PriorityDelegate(QtWidgets.QStyledItemDelegate):
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
super(PriorityDelegate, self).paint(painter, option, index)
|
||||
|
||||
if option.widget.selectionModel().isSelected(index) or \
|
||||
option.state & QtWidgets.QStyle.State_MouseOver:
|
||||
edit_icon = qtawesome.icon("fa.edit", color="white")
|
||||
state = QtGui.QIcon.On
|
||||
mode = QtGui.QIcon.Selected
|
||||
|
||||
icon_side = 16
|
||||
icon_rect = QtCore.QRect(
|
||||
option.rect.left() + option.rect.width() - icon_side - 4,
|
||||
option.rect.top() + ((option.rect.height() - icon_side) / 2),
|
||||
icon_side,
|
||||
icon_side
|
||||
)
|
||||
|
||||
edit_icon.paint(
|
||||
painter, icon_rect,
|
||||
QtCore.Qt.AlignRight, mode, state
|
||||
)
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
editor = PriorityLineEdit(
|
||||
parent,
|
||||
option.widget.selectionModel().selectedRows())
|
||||
editor.setValidator(QtGui.QIntValidator(0, 1000, self))
|
||||
editor.setFocus(True)
|
||||
return editor
|
||||
|
||||
def setModelData(self, editor, model, index):
|
||||
for index in editor.selected_idxs:
|
||||
model.set_priority_data(index, editor.text())
|
||||
|
||||
|
||||
class PriorityLineEdit(QtWidgets.QLineEdit):
|
||||
"""Special LineEdit to consume Enter and store selected indexes"""
|
||||
def __init__(self, parent=None, selected_idxs=None):
|
||||
self.selected_idxs = selected_idxs
|
||||
super(PriorityLineEdit, self).__init__(parent)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
result = super(PriorityLineEdit, self).keyPressEvent(event)
|
||||
if (
|
||||
event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter)
|
||||
):
|
||||
return event.accept()
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from Qt import QtCore
|
|||
from Qt.QtCore import Qt
|
||||
|
||||
from avalon.tools.delegates import pretty_timestamp
|
||||
from avalon.vendor import qtawesome
|
||||
|
||||
from openpype.lib import PypeLogger
|
||||
|
||||
|
|
@ -41,6 +42,8 @@ class _SyncRepresentationModel(QtCore.QAbstractTableModel):
|
|||
PAGE_SIZE = 20 # default page size to query for
|
||||
REFRESH_SEC = 5000 # in seconds, requery DB for new status
|
||||
|
||||
DEFAULT_PRIORITY = 50
|
||||
|
||||
@property
|
||||
def dbcon(self):
|
||||
"""
|
||||
|
|
@ -79,6 +82,14 @@ class _SyncRepresentationModel(QtCore.QAbstractTableModel):
|
|||
return self.COLUMN_LABELS[section][0] # return name
|
||||
|
||||
def get_column(self, index):
|
||||
"""
|
||||
Returns info about column
|
||||
|
||||
Args:
|
||||
index (QModelIndex)
|
||||
Returns:
|
||||
(tuple): (COLUMN_NAME: COLUMN_LABEL)
|
||||
"""
|
||||
return self.COLUMN_LABELS[index]
|
||||
|
||||
def get_header_index(self, value):
|
||||
|
|
@ -109,7 +120,8 @@ class _SyncRepresentationModel(QtCore.QAbstractTableModel):
|
|||
than single page of records)
|
||||
"""
|
||||
if self.sync_server.is_paused() or \
|
||||
self.sync_server.is_project_paused(self.project):
|
||||
self.sync_server.is_project_paused(self.project) or \
|
||||
self.is_editing:
|
||||
return
|
||||
self.refresh_started.emit()
|
||||
self.beginResetModel()
|
||||
|
|
@ -191,7 +203,7 @@ class _SyncRepresentationModel(QtCore.QAbstractTableModel):
|
|||
self.sort = {self.SORT_BY_COLUMN[index]: order} # reset
|
||||
# add last one
|
||||
for key, val in backup_sort.items():
|
||||
if key != '_id':
|
||||
if key != '_id' and key != self.SORT_BY_COLUMN[index]:
|
||||
self.sort[key] = val
|
||||
break
|
||||
# add default one
|
||||
|
|
@ -363,7 +375,7 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
"updated_dt_remote", # remote created_dt
|
||||
"files_count", # count of files
|
||||
"files_size", # file size of all files
|
||||
"context.asset", # priority TODO
|
||||
"priority", # priority
|
||||
"status" # status
|
||||
]
|
||||
|
||||
|
|
@ -374,6 +386,8 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
'representation': lib.MultiSelectFilter('representation')
|
||||
}
|
||||
|
||||
EDITABLE_COLUMNS = ["priority"]
|
||||
|
||||
refresh_started = QtCore.Signal()
|
||||
refresh_finished = QtCore.Signal()
|
||||
|
||||
|
|
@ -413,6 +427,9 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
self._word_filter = None
|
||||
self._column_filtering = {}
|
||||
|
||||
self.edit_icon = qtawesome.icon("fa.edit", color="white")
|
||||
self.is_editing = False
|
||||
|
||||
self._word_filter = None
|
||||
|
||||
self._initialized = False
|
||||
|
|
@ -472,7 +489,7 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
return item.status == lib.STATUS[2] and \
|
||||
item.remote_progress < 1
|
||||
|
||||
if role == Qt.DisplayRole:
|
||||
if role in (Qt.DisplayRole, Qt.EditRole):
|
||||
# because of ImageDelegate
|
||||
if header_value in ['remote_site', 'local_site']:
|
||||
return ""
|
||||
|
|
@ -549,7 +566,7 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
avg_progress_remote,
|
||||
repre.get("files_count", 1),
|
||||
lib.pretty_size(repre.get("files_size", 0)),
|
||||
1,
|
||||
repre.get("priority"),
|
||||
lib.STATUS[repre.get("status", -1)],
|
||||
files[0].get('path')
|
||||
)
|
||||
|
|
@ -668,6 +685,10 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
'$cond': [{'$size': "$order_local.paused"},
|
||||
1,
|
||||
0]},
|
||||
'priority': {
|
||||
'$cond': [{'$size': '$order_local.priority'},
|
||||
{'$first': '$order_local.priority'},
|
||||
self.DEFAULT_PRIORITY]},
|
||||
}},
|
||||
{'$group': {
|
||||
'_id': '$_id',
|
||||
|
|
@ -690,7 +711,8 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
'failed_local_tries': {'$sum': '$failed_local_tries'},
|
||||
'paused_remote': {'$sum': '$paused_remote'},
|
||||
'paused_local': {'$sum': '$paused_local'},
|
||||
'updated_dt_local': {'$max': "$updated_dt_local"}
|
||||
'updated_dt_local': {'$max': "$updated_dt_local"},
|
||||
'priority': {'$max': "$priority"},
|
||||
}},
|
||||
{"$project": self.projection}
|
||||
]
|
||||
|
|
@ -772,6 +794,7 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
'updated_dt_local': 1,
|
||||
'paused_remote': 1,
|
||||
'paused_local': 1,
|
||||
'priority': 1,
|
||||
'status': {
|
||||
'$switch': {
|
||||
'branches': [
|
||||
|
|
@ -818,6 +841,27 @@ class SyncRepresentationSummaryModel(_SyncRepresentationModel):
|
|||
}
|
||||
}
|
||||
|
||||
def set_priority_data(self, index, value):
|
||||
"""
|
||||
Sets 'priority' flag and value on active site for selected reprs.
|
||||
|
||||
Args:
|
||||
index (QItemIndex): selected index from View
|
||||
value (int): priority value
|
||||
|
||||
Updates DB
|
||||
"""
|
||||
repre_id = self.data(index, Qt.UserRole)
|
||||
|
||||
representation = list(self.dbcon.find({"type": "representation",
|
||||
"_id": repre_id}))
|
||||
if representation:
|
||||
self.sync_server.update_db(self.project, None, None,
|
||||
representation.pop(), self.active_site,
|
||||
priority=value)
|
||||
self.is_editing = False
|
||||
self.refresh(None, self._rec_loaded)
|
||||
|
||||
|
||||
class SyncRepresentationDetailModel(_SyncRepresentationModel):
|
||||
"""
|
||||
|
|
@ -901,6 +945,8 @@ class SyncRepresentationDetailModel(_SyncRepresentationModel):
|
|||
self._initialized = False
|
||||
self._column_filtering = {}
|
||||
|
||||
self.is_editing = False
|
||||
|
||||
self.sync_server = sync_server
|
||||
# TODO think about admin mode
|
||||
# this is for regular user, always only single local and single remote
|
||||
|
|
|
|||
|
|
@ -171,6 +171,13 @@ class _SyncRepresentationWidget(QtWidgets.QWidget):
|
|||
"""
|
||||
Opens representation dialog with all files after doubleclick
|
||||
"""
|
||||
# priority editing
|
||||
column_name = self.model.get_column(index.column())
|
||||
if column_name[0] in self.model.EDITABLE_COLUMNS:
|
||||
self.model.is_editing = True
|
||||
self.table_view.openPersistentEditor(index)
|
||||
return
|
||||
|
||||
_id = self.model.data(index, Qt.UserRole)
|
||||
detail_window = SyncServerDetailWindow(
|
||||
self.sync_server, _id, self.model.project)
|
||||
|
|
@ -253,6 +260,11 @@ class _SyncRepresentationWidget(QtWidgets.QWidget):
|
|||
actions_mapping[action] = self._remove_site
|
||||
menu.addAction(action)
|
||||
|
||||
action = QtWidgets.QAction("Change priority")
|
||||
action_kwarg_map[action] = self._get_action_kwargs(active_site)
|
||||
actions_mapping[action] = self._change_priority
|
||||
menu.addAction(action)
|
||||
|
||||
# # temp for testing only !!!
|
||||
# action = QtWidgets.QAction("Download")
|
||||
# action_kwarg_map[action] = self._get_action_kwargs(active_site)
|
||||
|
|
@ -397,6 +409,15 @@ class _SyncRepresentationWidget(QtWidgets.QWidget):
|
|||
except OSError:
|
||||
raise OSError('unsupported xdg-open call??')
|
||||
|
||||
def _change_priority(self, **kwargs):
|
||||
"""Open editor to change priority on first selected row"""
|
||||
if self._selected_ids:
|
||||
index = self.model.get_index(self._selected_ids[0]) # column = 0
|
||||
column_no = self.model.get_header_index("priority") # real column
|
||||
real_index = self.model.index(index.row(), column_no)
|
||||
self.model.is_editing = True
|
||||
self.table_view.openPersistentEditor(real_index)
|
||||
|
||||
def _get_progress(self, item, site_name, opposite=False):
|
||||
"""Returns progress value according to site (side)"""
|
||||
progress = {'local': item.local_progress,
|
||||
|
|
@ -470,6 +491,7 @@ class SyncRepresentationSummaryWidget(_SyncRepresentationWidget):
|
|||
-1, Qt.AscendingOrder)
|
||||
table_view.setAlternatingRowColors(True)
|
||||
table_view.verticalHeader().hide()
|
||||
table_view.viewport().setAttribute(QtCore.Qt.WA_Hover, True)
|
||||
|
||||
column = table_view.model().get_header_index("local_site")
|
||||
delegate = ImageDelegate(self)
|
||||
|
|
@ -479,6 +501,10 @@ class SyncRepresentationSummaryWidget(_SyncRepresentationWidget):
|
|||
delegate = ImageDelegate(self)
|
||||
table_view.setItemDelegateForColumn(column, delegate)
|
||||
|
||||
column = table_view.model().get_header_index("priority")
|
||||
priority_delegate = lib.PriorityDelegate(self)
|
||||
table_view.setItemDelegateForColumn(column, priority_delegate)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addLayout(top_bar_layout)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue