mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
OP-1117 - added context menu to Launcher actions to skip opening last workfile
Choice is persistent in Local Setting (only in DB, not exposed to GUI yet.)
This commit is contained in:
parent
f511538b49
commit
75d55b9ac5
8 changed files with 145 additions and 6 deletions
|
|
@ -43,6 +43,7 @@ class GlobalHostDataHook(PreLaunchHook):
|
|||
|
||||
"env": self.launch_context.env,
|
||||
|
||||
"start_last_workfile": self.data.get("start_last_workfile"),
|
||||
"last_workfile_path": self.data.get("last_workfile_path"),
|
||||
|
||||
"log": self.log
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class NonPythonHostHook(PreLaunchHook):
|
|||
)
|
||||
# Add workfile path if exists
|
||||
workfile_path = self.data["last_workfile_path"]
|
||||
if os.path.exists(workfile_path):
|
||||
if workfile_path and os.path.exists(workfile_path):
|
||||
new_launch_args.append(workfile_path)
|
||||
|
||||
# Append as whole list as these areguments should not be separated
|
||||
|
|
|
|||
|
|
@ -1490,6 +1490,11 @@ def _prepare_last_workfile(data, workdir):
|
|||
import avalon.api
|
||||
|
||||
log = data["log"]
|
||||
|
||||
if not data.get("start_last_workfile", True):
|
||||
log.info("Explicitly forbidden to open last workfile, skipping")
|
||||
return
|
||||
|
||||
_workdir_data = data.get("workdir_data")
|
||||
if not _workdir_data:
|
||||
log.info(
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class ApplicationAction(api.Action):
|
|||
icon = None
|
||||
color = None
|
||||
order = 0
|
||||
data = {}
|
||||
|
||||
_log = None
|
||||
required_session_keys = (
|
||||
|
|
@ -103,7 +104,8 @@ class ApplicationAction(api.Action):
|
|||
self.application.launch(
|
||||
project_name=project_name,
|
||||
asset_name=asset_name,
|
||||
task_name=task_name
|
||||
task_name=task_name,
|
||||
**self.data
|
||||
)
|
||||
|
||||
except ApplictionExecutableNotFound as exc:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ VARIANT_GROUP_ROLE = QtCore.Qt.UserRole + 2
|
|||
ACTION_ID_ROLE = QtCore.Qt.UserRole + 3
|
||||
ANIMATION_START_ROLE = QtCore.Qt.UserRole + 4
|
||||
ANIMATION_STATE_ROLE = QtCore.Qt.UserRole + 5
|
||||
FORCE_NOT_OPEN_WORKFILE_ROLE = QtCore.Qt.UserRole + 6
|
||||
|
||||
# Animation length in seconds
|
||||
ANIMATION_LEN = 7
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import time
|
|||
from Qt import QtCore, QtWidgets, QtGui
|
||||
from .constants import (
|
||||
ANIMATION_START_ROLE,
|
||||
ANIMATION_STATE_ROLE
|
||||
ANIMATION_STATE_ROLE,
|
||||
FORCE_NOT_OPEN_WORKFILE_ROLE
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -69,6 +70,16 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
self._draw_animation(painter, option, index)
|
||||
|
||||
super(ActionDelegate, self).paint(painter, option, index)
|
||||
|
||||
if index.data(FORCE_NOT_OPEN_WORKFILE_ROLE):
|
||||
rect = QtCore.QRectF(option.rect.x(), option.rect.height(),
|
||||
5, 5)
|
||||
painter.setPen(QtCore.Qt.transparent)
|
||||
painter.setBrush(QtGui.QColor(200, 0, 0))
|
||||
painter.drawEllipse(rect)
|
||||
|
||||
painter.setBrush(self.extender_bg_brush)
|
||||
|
||||
is_group = False
|
||||
for group_role in self.group_roles:
|
||||
is_group = index.data(group_role)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ from .constants import (
|
|||
ACTION_ROLE,
|
||||
GROUP_ROLE,
|
||||
VARIANT_GROUP_ROLE,
|
||||
ACTION_ID_ROLE
|
||||
ACTION_ID_ROLE,
|
||||
FORCE_NOT_OPEN_WORKFILE_ROLE
|
||||
)
|
||||
from .actions import ApplicationAction
|
||||
from Qt import QtCore, QtGui
|
||||
|
|
@ -16,6 +17,8 @@ from avalon.vendor import qtawesome
|
|||
from avalon import style, api
|
||||
from openpype.lib import ApplicationManager
|
||||
|
||||
from openpype.settings.lib import get_local_settings, save_local_settings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -75,7 +78,8 @@ class ActionModel(QtGui.QStandardItemModel):
|
|||
"group": None,
|
||||
"icon": app.icon,
|
||||
"color": getattr(app, "color", None),
|
||||
"order": getattr(app, "order", None) or 0
|
||||
"order": getattr(app, "order", None) or 0,
|
||||
"data": {}
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -179,11 +183,20 @@ class ActionModel(QtGui.QStandardItemModel):
|
|||
|
||||
self.beginResetModel()
|
||||
|
||||
local_settings = get_local_settings()
|
||||
items = []
|
||||
for order in sorted(items_by_order.keys()):
|
||||
for item in items_by_order[order]:
|
||||
item_id = str(uuid.uuid4())
|
||||
item.setData(item_id, ACTION_ID_ROLE)
|
||||
|
||||
if self.is_force_not_open_workfile(item,
|
||||
local_settings):
|
||||
label = item.text()
|
||||
label += " (Not opening last workfile)"
|
||||
item.setData(label, QtCore.Qt.ToolTipRole)
|
||||
item.setData(True, FORCE_NOT_OPEN_WORKFILE_ROLE)
|
||||
|
||||
self.items_by_id[item_id] = item
|
||||
items.append(item)
|
||||
|
||||
|
|
@ -222,6 +235,75 @@ class ActionModel(QtGui.QStandardItemModel):
|
|||
key=lambda action: (action.order, action.name)
|
||||
)
|
||||
|
||||
def update_force_not_open_workfile_settings(self, is_checked, action):
|
||||
"""Store/remove config for forcing to skip opening last workfile.
|
||||
|
||||
Args:
|
||||
is_checked (bool): True to add, False to remove
|
||||
action (ApplicationAction)
|
||||
"""
|
||||
local_settings = get_local_settings()
|
||||
|
||||
actual_data = self._prepare_compare_data(action)
|
||||
|
||||
force_not_open_workfile = local_settings.get("force_not_open_workfile",
|
||||
[])
|
||||
final_local_sett = local_settings
|
||||
if is_checked:
|
||||
if not force_not_open_workfile:
|
||||
final_local_sett["force_not_open_workfile"] = []
|
||||
|
||||
final_local_sett["force_not_open_workfile"].append(actual_data)
|
||||
else:
|
||||
final_local_sett["force_not_open_workfile"] = []
|
||||
for config in force_not_open_workfile:
|
||||
if config != actual_data:
|
||||
final_local_sett["force_not_open_workfile"].append(config)
|
||||
|
||||
if not final_local_sett["force_not_open_workfile"]:
|
||||
final_local_sett.pop("force_not_open_workfile")
|
||||
|
||||
save_local_settings(final_local_sett)
|
||||
|
||||
def is_force_not_open_workfile(self, item, local_settings):
|
||||
"""Checks if application for task is marked to not open workfile
|
||||
|
||||
There might be specific tasks where is unwanted to open workfile right
|
||||
always (broken file, low performance). This allows artist to mark to
|
||||
skip opening for combination (project, asset, task_name, app)
|
||||
|
||||
Args:
|
||||
item (QStandardItem)
|
||||
local_settings (dict)
|
||||
"""
|
||||
action = item.data(ACTION_ROLE)
|
||||
actual_data = self._prepare_compare_data(action)
|
||||
for config in local_settings.get("force_not_open_workfile", []):
|
||||
if config == actual_data:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _prepare_compare_data(self, action):
|
||||
if isinstance(action, list) and action:
|
||||
action = action[0]
|
||||
|
||||
_session = copy.deepcopy(self.dbcon.Session)
|
||||
session = {
|
||||
key: value
|
||||
for key, value in _session.items()
|
||||
if value
|
||||
}
|
||||
|
||||
actual_data = {
|
||||
"app_label": action.label.lower(),
|
||||
"project_name": session["AVALON_PROJECT"],
|
||||
"asset": session["AVALON_ASSET"],
|
||||
"task_name": session["AVALON_TASK"]
|
||||
}
|
||||
|
||||
return actual_data
|
||||
|
||||
|
||||
class ProjectModel(QtGui.QStandardItemModel):
|
||||
"""List of projects"""
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ from .constants import (
|
|||
ACTION_ID_ROLE,
|
||||
ANIMATION_START_ROLE,
|
||||
ANIMATION_STATE_ROLE,
|
||||
ANIMATION_LEN
|
||||
ANIMATION_LEN,
|
||||
FORCE_NOT_OPEN_WORKFILE_ROLE
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -96,6 +97,7 @@ class ActionBar(QtWidgets.QWidget):
|
|||
view.setViewMode(QtWidgets.QListView.IconMode)
|
||||
view.setResizeMode(QtWidgets.QListView.Adjust)
|
||||
view.setSelectionMode(QtWidgets.QListView.NoSelection)
|
||||
view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
view.setEditTriggers(QtWidgets.QListView.NoEditTriggers)
|
||||
view.setWrapping(True)
|
||||
view.setGridSize(QtCore.QSize(70, 75))
|
||||
|
|
@ -135,6 +137,7 @@ class ActionBar(QtWidgets.QWidget):
|
|||
|
||||
project_handler.projects_refreshed.connect(self._on_projects_refresh)
|
||||
view.clicked.connect(self.on_clicked)
|
||||
view.customContextMenuRequested.connect(self.on_context_menu)
|
||||
|
||||
def discover_actions(self):
|
||||
if self._animation_timer.isActive():
|
||||
|
|
@ -181,6 +184,38 @@ class ActionBar(QtWidgets.QWidget):
|
|||
self._animated_items.add(action_id)
|
||||
self._animation_timer.start()
|
||||
|
||||
def on_context_menu(self, point):
|
||||
"""Creates menu to force skip opening last workfile."""
|
||||
index = self.view.indexAt(point)
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
action_item = index.data(ACTION_ROLE)
|
||||
menu = QtWidgets.QMenu(self.view)
|
||||
checkbox = QtWidgets.QCheckBox("Force not open last workfile",
|
||||
menu)
|
||||
if index.data(FORCE_NOT_OPEN_WORKFILE_ROLE):
|
||||
checkbox.setChecked(True)
|
||||
|
||||
checkbox.stateChanged.connect(
|
||||
lambda: self.on_checkbox_changed(checkbox.isChecked(),
|
||||
action_item))
|
||||
action = QtWidgets.QWidgetAction(menu)
|
||||
action.setDefaultWidget(checkbox)
|
||||
|
||||
menu.addAction(action)
|
||||
|
||||
global_point = self.mapToGlobal(point)
|
||||
action = menu.exec_(global_point)
|
||||
if not action or not action.data():
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
def on_checkbox_changed(self, is_checked, action):
|
||||
self.model.update_force_not_open_workfile_settings(is_checked, action)
|
||||
self.discover_actions() # repaint
|
||||
|
||||
def on_clicked(self, index):
|
||||
if not index or not index.isValid():
|
||||
return
|
||||
|
|
@ -189,6 +224,8 @@ class ActionBar(QtWidgets.QWidget):
|
|||
is_variant_group = index.data(VARIANT_GROUP_ROLE)
|
||||
if not is_group and not is_variant_group:
|
||||
action = index.data(ACTION_ROLE)
|
||||
if index.data(FORCE_NOT_OPEN_WORKFILE_ROLE):
|
||||
action.data["start_last_workfile"] = False
|
||||
self._start_animation(index)
|
||||
self.action_clicked.emit(action)
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue