1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
from typing import TYPE_CHECKING
from qtpy.QtCore import Slot # type:ignore
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QMenu, QApplication, QInputDialog
from ..cancel_mng import CancelOp, CancellableAction
if TYPE_CHECKING:
from patchbay_manager import PatchbayManager
_translate = QApplication.translate
class ViewsMenu(QMenu):
def __init__(self, parent: QMenu, mng: 'PatchbayManager'):
QMenu.__init__(self, parent)
self.mng = mng
self.setTitle(
_translate('views_menu', 'Views'))
self.setIcon(QIcon.fromTheme('view-group'))
self._build()
def _are_there_absents(self) -> bool:
group_names = set[str]()
for group in self.mng.groups:
group_names.add(group.name)
if self.mng.views.get(self.mng.view_number) is None:
return False
for gpos in self.mng.views.iter_group_poses(
view_num=self.mng.view_number):
if gpos.group_name not in group_names:
return True
return False
def _build(self):
self.clear()
view_keys = list[int]()
if self.mng is not None:
view_keys = [k for k in self.mng.views.keys()]
for index, view_data in self.mng.views.items():
view_text = view_data.name
if not view_text:
view_text = _translate('views_menu', 'View n°%i') % index
if 0 <= index <= 9:
view_text += f'\tAlt+{index}'
view_act = self.addAction(view_text)
view_act.setData(index)
view_act.triggered.connect(self._change_view)
if index == self.mng.view_number:
view_act.setEnabled(False)
self.addSeparator()
act_mv_view = self.addAction(
_translate('views_menu', 'Rename'))
act_mv_view.setIcon(QIcon.fromTheme('edit-rename'))
act_mv_view.triggered.connect(self._rename_view)
act_rm_view = self.addAction(
_translate('views_menu', 'Remove'))
act_rm_view.setIcon(QIcon.fromTheme('edit-delete'))
act_rm_view.triggered.connect(self._remove_view)
act_clear_absents = self.addAction(
_translate('views_menu', 'Forget the positions of those absent'))
act_clear_absents.setIcon(QIcon.fromTheme('edit-clear-all'))
act_clear_absents.triggered.connect(self._clear_absents)
change_num_menu = QMenu(
_translate('views_menu', 'Change view number to...'), self)
if view_keys:
n_nums_in_change_menu = max(max(view_keys) + 2, 10)
else:
n_nums_in_change_menu = 10
for i in range(1, n_nums_in_change_menu):
act_new_view_num = change_num_menu.addAction(str(i))
if self.mng is not None:
view_data = self.mng.views.get(i)
if view_data is not None:
if view_data.name:
act_new_view_num.setText(f'{i}\t{view_data.name}')
if i == self.mng.view_number:
act_new_view_num.setEnabled(False)
else:
act_new_view_num.setIcon(QIcon.fromTheme('reverse'))
act_new_view_num.setData(i)
act_new_view_num.triggered.connect(self._change_view_number)
self.addMenu(change_num_menu)
self.addSeparator()
act_remove_others = self.addAction(
QIcon.fromTheme('edit-delete'),
_translate('views_menu', 'Remove all other views'))
act_remove_others.triggered.connect(self._remove_all_other_views)
act_new_view = self.addAction(
_translate('views_menu', 'New view'))
act_new_view.setIcon(QIcon.fromTheme('document-new'))
act_new_view.triggered.connect(self._new_view)
if len(view_keys) <= 1:
act_rm_view.setEnabled(False)
act_remove_others.setEnabled(False)
if not self._are_there_absents():
act_clear_absents.setEnabled(False)
@Slot()
def _change_view(self):
view_number: int = self.sender().data() # type:ignore
with CancellableAction(self.mng, CancelOp.VIEW_CHOICE) as a:
a.name = _translate('undo', 'Change view %i -> %i') % (
self.mng.view_number, view_number)
self.mng.change_view(view_number)
@Slot()
def _rename_view(self):
view_data = self.mng.views.get(self.mng.view_number)
if view_data is None:
view_name = ''
else:
view_name = view_data.name
if self.mng.main_win is None:
return
new_name, ok = QInputDialog.getText(
self.mng.main_win,
_translate('views_menu', 'Rename view'),
_translate('views_menu', 'New view name :'),
text=view_name)
if ok:
with CancellableAction(self.mng, CancelOp.ALL_VIEWS_NO_POS) as a:
a.name = _translate('undo', 'View %i renamed to "%s"') % (
self.mng.view_number, new_name)
self.mng.rename_current_view(new_name)
@Slot()
def _clear_absents(self):
sender_text: str = self.sender().text() # type:ignore
with CancellableAction(self.mng, CancelOp.VIEW) as a:
a.name = sender_text
self.mng.clear_absents_in_view()
self._build()
@Slot()
def _change_view_number(self):
new_num: int = self.sender().data() # type:ignore
with CancellableAction(self.mng, CancelOp.ALL_VIEWS) as a:
a.name = _translate('undo', 'Change view number %i to %i') % (
self.mng.view_number, new_num)
self.mng.change_view_number(new_num)
@Slot()
def _remove_all_other_views(self):
sender_text: str = self.sender().text() # type:ignore
with CancellableAction(self.mng, CancelOp.ALL_VIEWS) as a:
a.name = sender_text
self.mng.remove_all_other_views()
@Slot()
def _new_view(self):
sender_text: str = self.sender().text() # type:ignore
with CancellableAction(self.mng, CancelOp.ALL_VIEWS) as a:
a.name = sender_text
self.mng.new_view()
@Slot()
def _remove_view(self):
sender_text: str = self.sender().text() # type:ignore
with CancellableAction(self.mng, CancelOp.ALL_VIEWS) as a:
a.name = sender_text
self.mng.remove_view(self.mng.view_number)
def showEvent(self, event) -> None:
self._build()
super().showEvent(event)
|