Skip to content

Commit

Permalink
ENH: Context menus for Happi, Ophyd and string list widgets (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
JJL772 authored Jul 15, 2022
1 parent cea9a23 commit 03daedd
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 10 deletions.
44 changes: 38 additions & 6 deletions atef/widgets/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
from apischema import deserialize, serialize
from pydm.widgets.drawing import PyDMDrawingLine
from qtpy import QtWidgets
from qtpy.QtCore import QEvent, QObject, QTimer
from qtpy.QtCore import QEvent, QObject, QPoint, Qt, QTimer
from qtpy.QtCore import Signal as QSignal
from qtpy.QtGui import QColor, QPalette
from qtpy.QtGui import QClipboard, QColor, QGuiApplication, QPalette
from qtpy.QtWidgets import (QAction, QCheckBox, QComboBox, QFileDialog,
QFormLayout, QHBoxLayout, QInputDialog, QLabel,
QLayout, QLineEdit, QMainWindow, QMessageBox,
QPlainTextEdit, QPushButton, QStyle, QTabWidget,
QToolButton, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget)
QLayout, QLineEdit, QMainWindow, QMenu,
QMessageBox, QPlainTextEdit, QPushButton, QStyle,
QTabWidget, QToolButton, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget)

from .. import util
from ..check import (Comparison, Equals, Greater, GreaterOrEqual, Less,
Expand Down Expand Up @@ -1278,6 +1278,9 @@ def _setup_ui(self):
for starting_value in starting_list or []:
self._add_item(starting_value, init=True)

self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.customContextMenuRequested.connect(self._show_context_menu)

# def test():
# text, success = QtWidgets.QInputDialog.getText(
# self, "Device name", "Device name?"
Expand Down Expand Up @@ -1428,6 +1431,35 @@ def edit_items(self, old_items: List[str], new_items: List[str]) -> None:
else:
self._edit_item(old, new)

def _show_context_menu(self, pos: QPoint):
"""
Displays a context menu that provides copy & remove actions
to the user
Parameters
----------
pos : QPoint
Position to display the menu at
"""
if len(self.list_strings.selectedItems()) <= 0:
return

menu = QMenu(self)

def copy_selected():
items = self.list_strings.selectedItems()
text = '\n'.join([x.text() for x in items])
if len(text) > 0:
QGuiApplication.clipboard().setText(text, QClipboard.Mode.Clipboard)

copy = menu.addAction('&Copy')
copy.triggered.connect(copy_selected)

remove = menu.addAction('&Remove')
remove.triggered.connect(self._remove_item_request)

menu.exec(self.mapToGlobal(pos))


class DeviceListWidget(StringListWithDialog):
"""
Expand Down
12 changes: 11 additions & 1 deletion atef/widgets/happi.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,17 @@ def _list_view_context_menu(self, pos: QtCore.QPoint) -> None:
"""Context menu for the happi list view."""
self.menu = QtWidgets.QMenu(self)
index: QtCore.QModelIndex = self.happi_list_view.indexAt(pos)
if index is not None:

if index is not None and index.data() is not None:
# Add action to add the selected device
add_action = self.menu.addAction(f'&Add Device: {index.data()}')

def items_added():
self.happi_items_chosen.emit([index.data()])

add_action.triggered.connect(items_added)

# Add action to copy the text
def copy(*_):
copy_to_clipboard(index.data())

Expand Down
28 changes: 25 additions & 3 deletions atef/widgets/ophyd.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ class OphydDeviceTableView(QtWidgets.QTableView):
attributes_selected: ClassVar[QtCore.Signal] = QtCore.Signal(
list # List[OphydAttributeData]
)
context_menu_helper: Callable[[], QtWidgets.QMenu]

def __init__(
self,
Expand Down Expand Up @@ -604,7 +605,10 @@ def clear(self):

def _table_context_menu(self, pos: QtCore.QPoint) -> None:
"""Context menu for the table."""
self.menu = QtWidgets.QMenu(self)
if self.context_menu_helper:
self.menu = self.context_menu_helper()
else:
self.menu = QtWidgets.QMenu(self)
index: QtCore.QModelIndex = self.indexAt(pos)
if index is not None:
def copy(*_):
Expand All @@ -613,17 +617,24 @@ def copy(*_):
def select_attr(*_):
self.attributes_selected.emit([row_data])

standard_actions = []

if index.data() is not None:
copy_action = self.menu.addAction(f"&Copy: {index.data()}")
copy_action = QtWidgets.QAction(f'&Copy: {index.data()}')
standard_actions.append(copy_action)
copy_action.triggered.connect(copy)

row_data = self.get_data_from_proxy_index(index)
if row_data is not None:
select_action = self.menu.addAction(
select_action = QtWidgets.QAction(
f"&Select attribute: {row_data.attr}"
)
standard_actions.append(select_action)
select_action.triggered.connect(select_attr)

# Insert the standard actions above the custom ones
self.menu.insertActions(self.menu.actions()[0], standard_actions)

self.menu.exec_(self.mapToGlobal(pos))

def get_data_from_proxy_index(
Expand Down Expand Up @@ -747,6 +758,8 @@ def update_data():
if model is not None:
model.start()

self.device_table_view.context_menu_helper = self._create_context_menu

self.edit_filter.textEdited.connect(set_filter)
self.button_update_data.clicked.connect(update_data)
# For now, we are disabling polling for device tables. Update at the
Expand Down Expand Up @@ -780,6 +793,15 @@ def select_single_attr(index: QtCore.QModelIndex) -> None:
self.attributes_selected.emit
)

def _create_context_menu(self):
"""Handler for when the device table view is right clicked."""
attrs = self.device_table_view.selected_attribute_data
if not attrs or not self.custom_menu_helper:
return QtWidgets.QMenu()

self._custom_menu = self.custom_menu_helper(attrs)
return self._custom_menu

def _select_attrs_clicked(self):
"""Handler for when attributes are selected."""
attrs = self.device_table_view.selected_attribute_data
Expand Down

0 comments on commit 03daedd

Please sign in to comment.