Source code for typhos.textedit

"""
Multiline text edit widget.

Variety support pending:
- Text format
"""
import logging

import numpy as np
from pydm.widgets.base import PyDMWritableWidget
from qtpy import QtWidgets

from . import variety

logger = logging.getLogger(__name__)


[docs]@variety.uses_key_handlers @variety.use_for_variety_write('text-multiline') class TyphosTextEdit(QtWidgets.QWidget, PyDMWritableWidget): """ A writable, multiline text editor with support for PyDM Channels. Parameters ---------- parent : QWidget The parent widget. init_channel : str, optional The channel to be used by the widget. """ def __init__(self, parent=None, init_channel=None, variety_metadata=None, ophyd_signal=None): self._display_text = None self._encoding = "utf-8" self._delimiter = '\n' self._ophyd_signal = ophyd_signal self._format = 'plain' self._raw_value = None QtWidgets.QWidget.__init__(self, parent) PyDMWritableWidget.__init__(self, init_channel=init_channel) # superclasses do *not* support cooperative init: # super().__init__(self, parent=parent, init_channel=init_channel) self._setup_ui() self.variety_metadata = variety_metadata def _setup_ui(self): layout = QtWidgets.QVBoxLayout() self.setLayout(layout) self._text_edit = QtWidgets.QTextEdit() self._send_button = QtWidgets.QPushButton('Send') self._send_button.clicked.connect(self._send_clicked) self._revert_button = QtWidgets.QPushButton('Revert') self._revert_button.clicked.connect(self._revert_clicked) self._button_layout = QtWidgets.QHBoxLayout() self._button_layout.addWidget(self._revert_button) self._button_layout.addWidget(self._send_button) layout.addWidget(self._text_edit) layout.addLayout(self._button_layout) def _revert_clicked(self): self._set_text(self._display_text) def _send_clicked(self): self.send_value()
[docs] def value_changed(self, value): """Receive and update the TyphosTextEdit for a new channel value.""" self._raw_value = value super().value_changed(self._from_wire(value)) self.set_display()
def _to_wire(self, text=None): """TextEdit text -> numpy array.""" if text is None: # text-format: toMarkdown, toHtml text = self._text_edit.toPlainText() text = self._delimiter.join(text.splitlines()) return np.array(list(text.encode(self._encoding)), dtype=np.uint8) def _from_wire(self, value): """numpy array/string/bytes -> string.""" if isinstance(value, (list, np.ndarray)): return bytes(value).decode(self._encoding) return value def _set_text(self, text): return self._text_edit.setText(text)
[docs] def send_value(self): """Emit a :attr:`send_value_signal` to update channel value.""" send_value = self._to_wire() try: self.send_value_signal[np.ndarray].emit(send_value) except ValueError: logger.exception( "send_value error %r with type %r and format %r (widget %r).", send_value, self.channeltype, self._display_format_type, self.objectName() ) self._text_edit.document().setModified(False)
[docs] def write_access_changed(self, new_write_access): """ Change the TyphosTextEdit to read only if write access is denied """ super().write_access_changed(new_write_access) self._text_edit.setReadOnly(not new_write_access) self._send_button.setVisible(new_write_access) self._revert_button.setVisible(new_write_access)
[docs] def set_display(self): """Set the text display of the TyphosTextEdit.""" if self.value is None or self._text_edit.document().isModified(): return self._display_text = str(self.value) self._set_text(self._display_text)
variety_metadata = variety.create_variety_property() def _reinterpret_text(self): """Re-interpret the raw value, if formatting and such change.""" if self._raw_value is not None: self.value_changed(self._raw_value) @variety.key_handler('delimiter') def _variety_key_handler_delimiter(self, delimiter): self._delimiter = delimiter @variety.key_handler('encoding') def _variety_key_handler_encoding(self, encoding): self._encoding = encoding self._reinterpret_text() @variety.key_handler('format') def _variety_key_handler_format(self, format_): self._format = format_ if format_ != 'plain': logger.warning('Non-plain formats not yet implemented.') self._reinterpret_text()