diff --git a/pype/tools/launcher/lib.py b/pype/tools/launcher/lib.py index 25270fcbfe..a6d6ff6865 100644 --- a/pype/tools/launcher/lib.py +++ b/pype/tools/launcher/lib.py @@ -100,3 +100,14 @@ def get_action_icon(action): print("Can't load icon \"{}\"".format(icon_name)) return icon + + +def get_action_label(action): + label = getattr(action, "label", None) + if not label: + return action.name + + label_variant = getattr(action, "label_variant", None) + if not label_variant: + return label + return " ".join([label, label_variant]) diff --git a/pype/tools/launcher/models.py b/pype/tools/launcher/models.py index fee09e4f4b..f76e26afde 100644 --- a/pype/tools/launcher/models.py +++ b/pype/tools/launcher/models.py @@ -155,25 +155,57 @@ class ActionModel(QtGui.QStandardItemModel): self.beginResetModel() single_actions = [] + varianted_actions = collections.defaultdict(list) grouped_actions = collections.defaultdict(list) for action in actions: + # Groups group_name = getattr(action, "group", None) - if not group_name: - single_actions.append(action) - else: + + # Lable variants + label = getattr(action, "label", None) + label_variant = getattr(action, "label_variant", None) + if label_variant and not label: + print(( + "Invalid action \"{}\" has set `label_variant` to \"{}\"" + ", but doesn't have set `label` attribute" + ).format(action.name, label_variant)) + action.label_variant = None + label_variant = None + + if group_name: grouped_actions[group_name].append(action) - for group_name, actions in tuple(grouped_actions.items()): - if len(actions) == 1: - grouped_actions.pop(group_name) - single_actions.append(actions[0]) + elif label_variant: + varianted_actions[label].append(action) + else: + single_actions.append(action) items_by_order = collections.defaultdict(list) + for label, actions in tuple(varianted_actions.items()): + if len(actions) == 1: + varianted_actions.pop(label) + single_actions.append(actions[0]) + continue + + icon = None + order = None + for action in actions: + if icon is None: + _icon = lib.get_action_icon(action) + if _icon: + icon = _icon + + if order is None or action.order < order: + order = action.order + + item = QtGui.QStandardItem(icon, action.label) + item.setData(actions, self.ACTION_ROLE) + item.setData(True, self.GROUP_ROLE) + items_by_order[order].append(item) + for action in single_actions: icon = self.get_icon(action) - item = QtGui.QStandardItem( - icon, str(action.label or action.name) - ) + item = QtGui.QStandardItem(icon, lib.get_action_label(action)) item.setData(action, self.ACTION_ROLE) items_by_order[action.order].append(item) @@ -185,7 +217,7 @@ class ActionModel(QtGui.QStandardItemModel): order = action.order if icon is None: - _icon = self.get_icon(action) + _icon = lib.get_action_icon(action) if _icon: icon = _icon diff --git a/pype/tools/launcher/widgets.py b/pype/tools/launcher/widgets.py index c3a908c9dd..774c3de5ee 100644 --- a/pype/tools/launcher/widgets.py +++ b/pype/tools/launcher/widgets.py @@ -1,4 +1,5 @@ import copy +import collections from Qt import QtWidgets, QtCore, QtGui from avalon.vendor import qtawesome @@ -123,13 +124,53 @@ class ActionBar(QtWidgets.QWidget): self.action_clicked.emit(action) return - menu = QtWidgets.QMenu(self) actions = index.data(self.model.ACTION_ROLE) - actions_mapping = {} + by_variant_label = collections.defaultdict(list) + orders = [] for action in actions: - menu_action = QtWidgets.QAction(action.label or action.name) - menu.addAction(menu_action) - actions_mapping[menu_action] = action + # Lable variants + label = getattr(action, "label", None) + label_variant = getattr(action, "label_variant", None) + if label_variant and not label: + label_variant = None + + if not label_variant: + orders.append(action) + continue + + if label not in orders: + orders.append(label) + by_variant_label[label].append(action) + + menu = QtWidgets.QMenu(self) + actions_mapping = {} + + for action_item in orders: + actions = by_variant_label.get(action_item) + if not actions: + action = action_item + elif len(actions) == 1: + action = actions[0] + else: + action = None + + if action: + menu_action = QtWidgets.QAction( + lib.get_action_label(action) + ) + menu.addAction(menu_action) + actions_mapping[menu_action] = action + continue + + sub_menu = QtWidgets.QMenu(label, menu) + for action in actions: + menu_action = QtWidgets.QAction( + lib.get_action_label(action) + ) + sub_menu.addAction(menu_action) + actions_mapping[menu_action] = action + + menu.addMenu(sub_menu) result = menu.exec_(QtGui.QCursor.pos()) if result: