Source code for siriushla.as_ap_configdb.pvsconfigs.read_and_save

"""Read configuration window."""
import logging
import time

from qtpy.QtCore import Slot
from qtpy.QtGui import QKeySequence, QKeyEvent
from qtpy.QtWidgets import QWidget, QComboBox, QPushButton, \
    QVBoxLayout, QTableView, QMessageBox, QApplication

from siriuspy.envars import VACA_PREFIX as _VACA_PREFIX
from siriuspy.clientconfigdb import ConfigDBException, ConfigDBClient
from siriushla.widgets.windows import SiriusMainWindow
from siriushla.common.epics.wrapper import PyEpicsWrapper
from siriushla.common.epics.task import EpicsConnector, EpicsGetter
from siriushla.widgets.dialog import ReportDialog, ProgressDialog
from ..models import ConfigPVsTypeModel, PVConfigurationTableModel
from .. import SaveConfigDialog
from .delegate import PVConfigurationDelegate


class _CustomTable(QTableView):

    def keyPressEvent(self, event):
        if event.type() == QKeyEvent.KeyPress:
            if event.matches(QKeySequence.Copy):
                indexes = self.selectionModel().selectedIndexes()
                if len(indexes) == 1:
                    index = indexes[0]
                    if index.column() == 2:
                        value = self.model().data(index)
                        QApplication.instance().clipboard().setText(str(value))
                else:
                    QMessageBox.information(
                        self, 'Copy', 'No support for multi-cell copying')
            elif event.matches(QKeySequence.Paste):
                value = QApplication.instance().clipboard().text()
                indexes = self.selectionModel().selectedIndexes()
                for index in indexes:
                    self.pasteDelay(index, value)

    def pasteDelay(self, index, value):
        if index.column() != 2:
            return
        try:
            value = float(value)
        except ValueError:
            return
        self.model().setData(index, value)


[docs] class ReadAndSaveConfig2ServerWindow(SiriusMainWindow): """Read configuration window.""" def __init__(self, client, wrapper=PyEpicsWrapper, parent=None): """Constructor.""" super().__init__(parent) self._client = client self._wrapper = wrapper self._current_config = None self._valid_config = False self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.INFO) self._setup_ui() self._central_widget.setStyleSheet(""" #CentralWidget { min-width: 40em; min-height: 40em; } """) self.setWindowTitle('Create new configuration') self._type_cb.setCurrentText('global_config') def _setup_ui(self): # Set central widget self._central_widget = QWidget() self._central_widget.setObjectName('CentralWidget') self._central_widget.layout = QVBoxLayout() self._central_widget.setLayout(self._central_widget.layout) self.setCentralWidget(self._central_widget) # Add combo box with types self._type_cb = QComboBox(self) self._type_cb.setObjectName('type_cb') self._type_cb.setModel(ConfigPVsTypeModel(self._client, self._type_cb)) # Add LineEdit for configuration name # self._name_le = QLineEdit(self) # self._name_le.setObjectName('name_le') # Add configuration table self._table = _CustomTable(self) self._table.setObjectName('config_tbl') self._table.setModel(PVConfigurationTableModel()) self._table.setItemDelegate(PVConfigurationDelegate()) # Add Read Button self._read_btn = QPushButton('Read', self) self._read_btn.setObjectName('read_btn') self._read_btn.setEnabled(False) # Add Save Button self._save_btn = QPushButton('Save', self) self._save_btn.setObjectName('save_btn') self._save_btn.setEnabled(False) # Add widgets self._central_widget.layout.addWidget(self._type_cb) # self._central_widget.layout.addWidget(self._name_le) self._central_widget.layout.addWidget(self._read_btn) self._central_widget.layout.addWidget(self._table) self._central_widget.layout.addWidget(self._save_btn) # Add signals self._type_cb.currentTextChanged.connect(self._fill_table) self._read_btn.clicked.connect(self._read) self._save_btn.clicked.connect(self._save) @Slot(str) def _fill_table(self, config_type): self._table.model().config_type = config_type self._table.resizeColumnsToContents() self._is_configuration_valid() @Slot() def _read(self): failed_items = [] tbl_data = self._table.model().model_data # Get PVs vp = _VACA_PREFIX pvs = {data[0]: i for i, data in enumerate(tbl_data)} defvals = [data[1] for data in tbl_data] if len(pvs) != len(tbl_data): QMessageBox.warning( self, 'Error', 'Configuration has duplicated values') return # Create thread to read PVs pvsl = list(pvs) connt = EpicsConnector(pvsl, self._wrapper, parent=self) task = EpicsGetter(pvsl, defvals, self._wrapper, parent=self) task.itemRead.connect( lambda pv, value: self._fill_value(pvs[pv.replace(vp, '')], value)) task.itemNotRead.connect(failed_items.append) # Show progress dialog time.sleep(1) dlg = ProgressDialog( ['Connecting to PVs', 'Reading PVs...'], [connt, task], self) ret = dlg.exec_() if ret == dlg.Rejected: return # Show failed items for item in failed_items: self.logger.warn('Failed to get {}'.format(item)) self._report = ReportDialog(failed_items, self) self._report.show() self._table.resizeColumnsToContents() # if not failed_items: self._save_btn.setEnabled(True) @Slot() def _fill_value(self, row, value): self.logger.debug('Setting value {} in row {}'.format(value, row)) index = self._table.model().createIndex(row, 1) self._table.model().setData(index, value) def _save(self): config_type = self._type_cb.currentText() success = False error = '' label = 'Please select a name' # Ask for a name until it is either canceled or succesfully inserted while not success: # config_name, status = QInputDialog.getText( # self, 'Configuration Name', error + label) config_name, status = SaveConfigDialog(config_type, self).exec() if not status or not config_name: return # Check status and configuration name if not ConfigDBClient.check_valid_configname(config_name): self.logger.warning('Name not allowed') error = 'Name not allowed<br>' else: success = True # Get config_type, config_name, data and insert new configuration data = self._table.model().model_data try: ret = self._client.insert_config( config_name, {'pvs': data}, config_type=config_type) except (TypeError, ConfigDBException) as err: QMessageBox.warning(self, 'Save', '{}'.format(str(err))) else: self._save_btn.setEnabled(False) QMessageBox.information(self, 'Save', 'Saved successfully') def _is_configuration_valid(self): if self._table.model().model_data: self._config_valid = True else: self._config_valid = False self._read_btn.setEnabled(self._config_valid)