Пример #1
0
    def _create_axis_label_widget(self, axis):
        """Create the axis label widget which accompanies its slider.

        Parameters
        ----------
        axis : int
            axis index

        Returns
        -------
        label : QLabel
            A label with the given text
        """
        label = QLineEdit()
        label.setText(self.dims.axis_labels[axis])
        label.home(False)
        label.setToolTip('Axis label')
        label.setAcceptDrops(False)
        label.setEnabled(True)

        def changeText():
            with self.dims.events.axis_labels.blocker():
                self.dims.set_axis_label(axis, label.text())
            label.clearFocus()
            self.setFocus()

        label.editingFinished.connect(changeText)
        return label
Пример #2
0
class ExportPanel(QWidget):
    updateExportButton = Signal(str, bool)
    runExport = Signal(dict)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setMinimumWidth(500)
        self.setMinimumHeight(200)
        self._dynamic = False

        self.setWindowTitle("Export data")
        self.activateWindow()

        layout = QFormLayout()

        self._column_keys_input = QLineEdit()
        self._column_keys_input.setMinimumWidth(250)
        self._column_keys_input.setText("*")
        layout.addRow("Columns to export:", self._column_keys_input)

        self._time_index_input = QLineEdit()
        self._time_index_input.setMinimumWidth(250)
        self._time_index_input.setText("raw")
        layout.addRow("Time index:", self._time_index_input)

        file_name_button = QToolButton()
        file_name_button.setText("Browse")
        file_name_button.clicked.connect(self.selectFileDirectory)
        self._defaultPath = QDir.currentPath() + "/export.csv"
        self._file_name = QLineEdit()
        self._file_name.setEnabled(False)
        self._file_name.setText(self._defaultPath)
        self._file_name.setMinimumWidth(250)

        file_name_layout = QHBoxLayout()
        file_name_layout.addWidget(self._file_name)
        file_name_layout.addWidget(file_name_button)
        layout.addRow("Select directory to save files to:", file_name_layout)

        self.setLayout(layout)

    def selectFileDirectory(self):
        directory = QFileDialog(self).getExistingDirectory(
            self, "Directory", self._file_name.text(),
            QFileDialog.ShowDirsOnly)
        if str(directory).__len__() > 0:
            self._file_name.setText(str(directory))

    def export(self):

        path = self._file_name.text()
        time_index = self._time_index_input.text()
        column_keys = self._column_keys_input.text()
        values = {
            "output_file": path,
            "time_index": time_index,
            "column_keys": column_keys,
        }
        self.runExport.emit(values)
Пример #3
0
    def __init__(self, layer):
        super().__init__()

        self.layer = layer
        self.layer.events.select.connect(self._on_select_change)
        self.layer.events.deselect.connect(self._on_deselect_change)
        self.layer.events.name.connect(self._on_name_change)
        self.layer.events.visible.connect(self._on_visible_change)
        self.layer.events.thumbnail.connect(self._on_thumbnail_change)

        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setObjectName('layer')

        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)

        tb = QLabel(self)
        tb.setObjectName('thumbnail')
        tb.setToolTip(trans._('Layer thumbnail'))
        self.thumbnailLabel = tb
        self._on_thumbnail_change()
        self.layout.addWidget(tb)

        cb = QCheckBox(self)
        cb.setObjectName('visibility')
        cb.setToolTip(trans._('Layer visibility'))
        cb.setChecked(self.layer.visible)
        cb.setProperty('mode', 'visibility')
        cb.stateChanged.connect(self.changeVisible)
        self.visibleCheckBox = cb
        self.layout.addWidget(cb)

        textbox = QLineEdit(self)
        textbox.setText(layer.name)
        textbox.home(False)
        textbox.setToolTip(self.layer.name)
        textbox.setAcceptDrops(False)
        textbox.setEnabled(True)
        textbox.editingFinished.connect(self.changeText)
        self.nameTextBox = textbox
        self.layout.addWidget(textbox)

        ltb = QLabel(self)
        layer_type = type(layer).__name__
        ltb.setObjectName(layer_type)
        ltb.setProperty('layer_type_label', True)
        ltb.setToolTip(trans._('Layer type'))
        self.typeLabel = ltb
        self.layout.addWidget(ltb)

        msg = trans._('Click to select\nDrag to rearrange')
        self.setToolTip(msg)
        self.setSelected(self.layer.selected)
Пример #4
0
 def __init__(self, parent, expected_ops, actual_ops):
     super(SyncDetailsDialog, self).__init__(parent)
     self.setupUi(self)
     for idx, actual_op in enumerate(actual_ops):
         actual = actual_ops[idx]
         expected = expected_ops[idx]
         path = QLineEdit(self.scrollAreaWidgetContents)
         path.setReadOnly(True)
         path.setEnabled(False)
         path.setText(actual['path'])
         requested = QLineEdit(self.scrollAreaWidgetContents)
         requested.setReadOnly(True)
         path.setEnabled(False)
         requested.setText(str(expected['value']))
         actual_text = QLineEdit(self.scrollAreaWidgetContents)
         actual_text.setReadOnly(True)
         path.setEnabled(False)
         actual_text.setText(str(actual['value']))
         status = QToolButton(self)
         if actual['op'] != expected['op'] or actual['path'] != expected['path'] or actual['value'] != expected['value']:
             status.setIcon(qta.icon('fa5s.times', color='red'))
         else:
             status.setIcon(qta.icon('fa5s.check', color='green'))
         self.gridLayout_2.addWidget(path, idx+1, 0, 1, 1)
         self.gridLayout_2.addWidget(requested, idx+1, 1, 1, 1)
         self.gridLayout_2.addWidget(actual_text, idx+1, 2, 1, 1)
         self.gridLayout_2.addWidget(status, idx+1, 3, 1, 1)
Пример #5
0
class ReferenceDialog(QDialog):
    def __init__(self, parent):
        super().__init__(parent)
        self.setWindowTitle("Set reference")
        vbox = QVBoxLayout(self)
        grid = QGridLayout()
        self.average = QRadioButton("Average")
        self.channels = QRadioButton("Channel(s):")
        self.average.toggled.connect(self.toggle)
        self.channellist = QLineEdit()
        self.channellist.setEnabled(False)
        self.average.setChecked(True)
        grid.addWidget(self.average, 0, 0)
        grid.addWidget(self.channels, 1, 0)
        grid.addWidget(self.channellist, 1, 1)
        vbox.addLayout(grid)
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)

    def toggle(self):
        if self.average.isChecked():
            self.channellist.setEnabled(False)
        else:
            self.channellist.setEnabled(True)
Пример #6
0
class ContentsWidget(QWidget):
    """Import wizard contents widget"""
    asDataChanged = Signal(bool)
    
    def __init__(self, parent, text):
        QWidget.__init__(self, parent)

        self.text_editor = QTextEdit(self)
        self.text_editor.setText(text)
        self.text_editor.setReadOnly(True)

        # Type frame
        type_layout = QHBoxLayout()
        type_label = QLabel(_("Import as"))
        type_layout.addWidget(type_label)
        data_btn = QRadioButton(_("data"))
        data_btn.setChecked(True)
        self._as_data= True
        type_layout.addWidget(data_btn)
        code_btn = QRadioButton(_("code"))
        self._as_code = False
        type_layout.addWidget(code_btn)
        txt_btn = QRadioButton(_("text"))
        type_layout.addWidget(txt_btn)

        h_spacer = QSpacerItem(40, 20,
                               QSizePolicy.Expanding, QSizePolicy.Minimum)
        type_layout.addItem(h_spacer)
        type_frame = QFrame()
        type_frame.setLayout(type_layout)

        # Opts frame
        grid_layout = QGridLayout()
        grid_layout.setSpacing(0)

        col_label = QLabel(_("Column separator:"))
        grid_layout.addWidget(col_label, 0, 0)
        col_w = QWidget()
        col_btn_layout = QHBoxLayout()
        self.tab_btn = QRadioButton(_("Tab"))
        self.tab_btn.setChecked(False)
        col_btn_layout.addWidget(self.tab_btn)
        other_btn_col = QRadioButton(_("other"))
        other_btn_col.setChecked(True)
        col_btn_layout.addWidget(other_btn_col)
        col_w.setLayout(col_btn_layout)
        grid_layout.addWidget(col_w, 0, 1)
        self.line_edt = QLineEdit(",")
        self.line_edt.setMaximumWidth(30)
        self.line_edt.setEnabled(True)
        other_btn_col.toggled.connect(self.line_edt.setEnabled)
        grid_layout.addWidget(self.line_edt, 0, 2)

        row_label = QLabel(_("Row separator:"))
        grid_layout.addWidget(row_label, 1, 0)
        row_w = QWidget()
        row_btn_layout = QHBoxLayout()
        self.eol_btn = QRadioButton(_("EOL"))
        self.eol_btn.setChecked(True)
        row_btn_layout.addWidget(self.eol_btn)
        other_btn_row = QRadioButton(_("other"))
        row_btn_layout.addWidget(other_btn_row)
        row_w.setLayout(row_btn_layout)
        grid_layout.addWidget(row_w, 1, 1)
        self.line_edt_row = QLineEdit(";")
        self.line_edt_row.setMaximumWidth(30)
        self.line_edt_row.setEnabled(False)
        other_btn_row.toggled.connect(self.line_edt_row.setEnabled)
        grid_layout.addWidget(self.line_edt_row, 1, 2)

        grid_layout.setRowMinimumHeight(2, 15)

        other_group = QGroupBox(_("Additional options"))
        other_layout = QGridLayout()
        other_group.setLayout(other_layout)

        skiprows_label = QLabel(_("Skip rows:"))
        other_layout.addWidget(skiprows_label, 0, 0)
        self.skiprows_edt = QLineEdit('0')
        self.skiprows_edt.setMaximumWidth(30)
        intvalid = QIntValidator(0, len(to_text_string(text).splitlines()),
                                 self.skiprows_edt)
        self.skiprows_edt.setValidator(intvalid)
        other_layout.addWidget(self.skiprows_edt, 0, 1)

        other_layout.setColumnMinimumWidth(2, 5)

        comments_label = QLabel(_("Comments:"))
        other_layout.addWidget(comments_label, 0, 3)
        self.comments_edt = QLineEdit('#')
        self.comments_edt.setMaximumWidth(30)
        other_layout.addWidget(self.comments_edt, 0, 4)

        self.trnsp_box = QCheckBox(_("Transpose"))
        #self.trnsp_box.setEnabled(False)
        other_layout.addWidget(self.trnsp_box, 1, 0, 2, 0)

        grid_layout.addWidget(other_group, 3, 0, 2, 0)

        opts_frame = QFrame()
        opts_frame.setLayout(grid_layout)

        data_btn.toggled.connect(opts_frame.setEnabled)
        data_btn.toggled.connect(self.set_as_data)
        code_btn.toggled.connect(self.set_as_code)
#        self.connect(txt_btn, SIGNAL("toggled(bool)"),
#                     self, SLOT("is_text(bool)"))

        # Final layout
        layout = QVBoxLayout()
        layout.addWidget(type_frame)
        layout.addWidget(self.text_editor)
        layout.addWidget(opts_frame)
        self.setLayout(layout)

    def get_as_data(self):
        """Return if data type conversion"""
        return self._as_data

    def get_as_code(self):
        """Return if code type conversion"""
        return self._as_code

    def get_as_num(self):
        """Return if numeric type conversion"""
        return self._as_num

    def get_col_sep(self):
        """Return the column separator"""
        if self.tab_btn.isChecked():
            return u"\t"
        return to_text_string(self.line_edt.text())

    def get_row_sep(self):
        """Return the row separator"""
        if self.eol_btn.isChecked():
            return u"\n"
        return to_text_string(self.line_edt_row.text())

    def get_skiprows(self):
        """Return number of lines to be skipped"""
        return int(to_text_string(self.skiprows_edt.text()))

    def get_comments(self):
        """Return comment string"""
        return to_text_string(self.comments_edt.text())

    @Slot(bool)
    def set_as_data(self, as_data):
        """Set if data type conversion"""
        self._as_data = as_data
        self.asDataChanged.emit(as_data)

    @Slot(bool)
    def set_as_code(self, as_code):
        """Set if code type conversion"""
        self._as_code = as_code
Пример #7
0
class ElementWindow(PyDialog):
    """
    +------------------------+
    |                        |
    |- + controls            |
    |  |                     |
    |  +-- name              |
    |  |                     |
    |  +-- name              |
    |                        |
    | Create/Edit/Delete     |
    | Type             SKIN3 |
    | eid              ____  |
    | pid              ____  |
    | n1               ____  |
    | n2               ____  |
    | n3               ____  |
    |                        |
    |                 Apply  |
    |                        |
    +------------------------+

    TODO: handle losing focus not still picking, which can cause the property_id
          to get set to the element_id/node_id
    """
    def __init__(self, data, controls, win_parent=None):
        """create a cONTROL surface"""
        PyDialog.__init__(self, data, win_parent)
        self._updated_menu = False

        self.controls = controls

        self.comment_label = QLabel('Comment')
        self.comment_edit = QLineEdit()

        self.eid_label = QLabel('Element ID')
        self.eid_edit = QElementEdit(self,
                                     str(''),
                                     pick_style='single',
                                     tab_to_next=False)

        self.pid_label = QLabel('Property ID')
        self.pid_edit = QLineEdit()

        self.mid_label = QLabel('Material ID')
        self.mid_edit = QLineEdit()

        self.n1_label = QLabel('Node 1')
        self.n2_label = QLabel('Node 2')
        self.n3_label = QLabel('Node 3')
        self.n4_label = QLabel('Node 4')
        self.n5_label = QLabel('Node 5')
        self.n6_label = QLabel('Node 6')
        self.n7_label = QLabel('Node 7')
        self.n8_label = QLabel('Node 8')
        self.n9_label = QLabel('Node 9')
        self.n10_label = QLabel('Node 10')
        self.n1_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n2_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n3_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n4_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n5_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n6_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n7_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n8_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n9_edit = QNodeEdit(self,
                                 str(''),
                                 pick_style='single',
                                 tab_to_next=True)
        self.n10_edit = QNodeEdit(self,
                                  str(''),
                                  pick_style='single',
                                  tab_to_next=True)

        for inode in range(3, 10 + 1):  # 3-10
            inode_label = 'n%i_label' % inode
            inode_edit = 'n%i_edit' % inode
            getattr(self, inode_label).setVisible(False)
            getattr(self, inode_edit).setVisible(False)

        self.mcsid_label = QLabel('Material Coord')
        self.mcsid_pulldown = QComboBox()

        self.element_type_label = QLabel('Element Type')
        self.element_type_pulldown = QComboBox()

        ELEMENT_TYPES = ['CROD', 'CONROD', 'CTRIA3', 'CQUAD4']
        self.element_types = ELEMENT_TYPES
        for element_type in ELEMENT_TYPES:
            self.element_type_pulldown.addItem(element_type)
        self.element_type = ELEMENT_TYPES[0]

        self.method_type_label = QLabel('Method Type')
        self.method_type_pulldown = QComboBox()
        self.method_types = ['Create', 'Edit', 'Delete']
        METHOD_TYPES = ['Create', 'Edit', 'Delete']
        for method_type in METHOD_TYPES:
            self.method_type_pulldown.addItem(method_type)
        self.method_type = METHOD_TYPES[0]

        #cases = get_cases_from_tree(self.controls)
        #parent = self
        #name = 'main'
        #data = self.controls
        #choices = cases

        #self.results_widget_label = QLabel('Results:')
        #self.results_widget = ResultsWindow(
        #parent, name, data, choices,
        #include_clear=False, include_delete=True,
        #include_results=False)

        self.add_button = QPushButton('Create')
        self.delete_button = QPushButton('Delete')
        self.apply_button = QPushButton('Apply')
        self.setup_layout()
        self.setup_connections()

    def setup_connections(self):
        self.element_type_pulldown.currentIndexChanged.connect(
            self.on_element_type)
        self.method_type_pulldown.currentIndexChanged.connect(
            self.on_method_type)

    def on_element_type(self, value):
        """
        element type pulldown (BEAM, SKIN3, SKIN4)

        Parameters
        ----------
        value : int
            index in element_types
        """
        #animation_types = [BEAM, SKIN3, SKIN4]
        element_type = self.element_types[value]
        #func_map = {
        #'CROD': self.on_show_crod,
        #'CONROD': self.on_show_conrod,
        #'CTRIA3': self.on_show_shell,
        #'CQUAD4': self.on_show_shell,
        #}
        #func = func_map[element_type]
        param_map = {
            'CROD': ['pid'],
            'CONROD': ['mid'],
            'CTRIA3': ['pid', 'n3', 'mcsid'],
            'CQUAD4': ['pid', 'n3', 'n4', 'mcsid'],
        }
        params = param_map[element_type]
        self._update_func(element_type, params)

    def _update_func(self, element_type, params):
        """updates the menu"""
        is_pid = 'pid' in params
        is_mid = 'mid' in params
        is_mcsid = 'mcsid' in params
        self.pid_label.setVisible(is_pid)
        self.pid_edit.setVisible(is_pid)

        self.mid_label.setVisible(is_mid)
        self.mid_edit.setVisible(is_mid)

        for inode in range(3, 10 + 1):  # 3-10
            is_ni = 'n%i' % inode in params
            inode_label = 'n%i_label' % inode
            inode_edit = 'n%i_edit' % inode
            getattr(self, inode_label).setVisible(is_ni)
            getattr(self, inode_edit).setVisible(is_ni)

        self.mcsid_label.setVisible(is_mcsid)
        self.mcsid_pulldown.setVisible(is_mcsid)

    def on_method_type(self, value):
        """
        element type pulldown (Create, Edit, Delete)

        Parameters
        ----------
        value : int
            index in element_types
        """
        #animation_types = [BEAM, SKIN3, SKIN4]
        method_type = self.method_types[value]
        enable = True
        if method_type == 'Create':
            pass
            #self.on_show_beam()
        elif method_type == 'Edit':
            pass
            #self.on_show_skin3()
        elif method_type == 'Delete':
            enable = False
            #self.on_show_skin4()
        else:
            raise NotImplementedError('value = ', value)
        self.pid_edit.setEnabled(enable)
        self.mid_edit.setEnabled(enable)
        self.n1_edit.setEnabled(enable)
        self.n2_edit.setEnabled(enable)

        for inode in range(3, 10 + 1):  # 3-10
            inode_label = 'n%i_label' % inode
            inode_edit = 'n%i_edit' % inode
            getattr(self, inode_label).setEnabled(enable)
            getattr(self, inode_edit).setEnabled(enable)
        #self.n3_edit.setEnabled(enable)
        #self.n4_edit.setEnabled(enable)
        self.mcsid_pulldown.setEnabled(enable)
        self.comment_edit.setEnabled(enable)

    def setup_layout(self):
        irow = 0
        grid = QGridLayout()

        grid.addWidget(self.method_type_label, irow, 1)
        grid.addWidget(self.method_type_pulldown, irow, 2)
        irow += 1

        grid.addWidget(self.element_type_label, irow, 1)
        grid.addWidget(self.element_type_pulldown, irow, 2)
        irow += 1

        grid.addWidget(self.eid_label, irow, 1)
        grid.addWidget(self.eid_edit, irow, 2)
        irow += 1

        grid.addWidget(self.pid_label, irow, 1)
        grid.addWidget(self.pid_edit, irow, 2)
        irow += 1

        grid.addWidget(self.mid_label, irow, 1)
        grid.addWidget(self.mid_edit, irow, 2)
        irow += 1

        for inode in range(1, 10 + 1):  # 1-10
            inode_label = 'n%i_label' % inode
            inode_edit = 'n%i_edit' % inode
            ni_label = getattr(self, inode_label)
            ni_edit = getattr(self, inode_edit)

            grid.addWidget(ni_label, irow, 1)
            grid.addWidget(ni_edit, irow, 2)
            irow += 1

        grid.addWidget(self.mcsid_label, irow, 1)
        grid.addWidget(self.mcsid_pulldown, irow, 2)
        irow += 1

        grid.addWidget(self.comment_label, irow, 1)
        grid.addWidget(self.comment_edit, irow, 2)
        irow += 1

        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.add_button)
        ok_cancel_box.addWidget(self.delete_button)

        vbox = QVBoxLayout()
        #vbox.addWidget(self.results_widget_label)
        #vbox.addWidget(self.results_widget)
        vbox.addLayout(grid)
        vbox.addStretch()
        vbox.addLayout(ok_cancel_box)

        self.setLayout(vbox)
        self.setWindowTitle('Define Element')

        self.mid_label.setVisible(False)
        self.mid_edit.setVisible(False)

        self.n3_label.setVisible(False)
        self.n3_edit.setVisible(False)

        self.n4_label.setVisible(False)
        self.n4_edit.setVisible(False)

        self.mcsid_label.setVisible(False)
        self.mcsid_pulldown.setVisible(False)
Пример #8
0
class NameCategoryPrompt(ExToolWindow):

    def __init__(self, main_window, parent=None):
        super(NameCategoryPrompt, self).__init__(parent)
        self.setWindowTitle(tr("Plugin properties"))
        self.ui = main_window
        self.create_controls()

    def checks_changed(self):
        menu = self.chk_menu.isChecked()
        toolbar = self.chk_toolbar.isChecked()
        icon = self.chk_icon.isChecked()

        if menu or toolbar:
            self.txt_category.setEnabled(True)
        else:
            self.txt_category.setEnabled(False)

        self.txt_iconpath.setEnabled(icon)
        self.btn_browse_icon.setEnabled(icon)

    def browse_icon(self):
        formats = QtGui.QImageReader.supportedImageFormats()
        formats = [str(f, encoding='ascii') for f in formats]
        # Add one filter that takes all supported:
        type_filter = tr("Supported formats")
        type_filter += ' (*.{0})'.format(' *.'.join(formats))
        # Add all as individual options
        type_filter += ';;' + tr("All files") + \
            ' (*.*) ;;*.' + ';;*.'.join(formats)
        path = QtWidgets.QFileDialog.getOpenFileName(self,
            tr("Pick icon"),
            os.path.dirname(self.ui.cur_dir),
            type_filter)
        if isinstance(path, tuple):    # Pyside returns tuple, PyQt not
            path = path[0]
        if path is None:
            return
        self.txt_iconpath.setText(path)

    def create_controls(self):
        self.txt_name = QLineEdit()
        self.chk_menu = QCheckBox(tr("Menu entry"))
        self.chk_menu.setChecked(True)
        self.chk_toolbar = QCheckBox(tr("Toolbar button"))
        self.chk_toolbar.setChecked(True)
        self.txt_category = QLineEdit()
        self.chk_icon = QCheckBox()
        self.chk_toolbar.setChecked(False)
        self.txt_iconpath = QLineEdit()
        self.btn_browse_icon = QPushButton("...")
        self.txt_iconpath.setEnabled(False)
        self.btn_browse_icon.setEnabled(False)
        btns = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
                                QtCore.Qt.Horizontal)

        self.chk_menu.toggled.connect(self.checks_changed)
        self.chk_toolbar.toggled.connect(self.checks_changed)
        self.chk_icon.toggled.connect(self.checks_changed)
        self.btn_browse_icon.clicked.connect(self.browse_icon)
        btns.accepted.connect(self.accept)
        btns.rejected.connect(self.reject)

        hbox = QHBoxLayout()
        for w in [self.chk_icon, self.txt_iconpath, self.btn_browse_icon]:
            hbox.addWidget(w)

        form = QFormLayout()
        form.addRow(tr("Name"), self.txt_name)
        form.addRow(self.chk_menu, self.chk_toolbar)
        form.addRow(tr("Category"), self.txt_category)
        form.addRow(tr("Icon"), hbox)

        vbox = QVBoxLayout(self)
        vbox.addLayout(form)
        vbox.addWidget(btns)

        self.setLayout(vbox)
Пример #9
0
class RunConfigOptions(QWidget):
    """Run configuration options"""

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.current_radio = None
        self.dedicated_radio = None
        self.systerm_radio = None

        self.runconf = RunConfiguration()

        firstrun_o = CONF.get("run", ALWAYS_OPEN_FIRST_RUN_OPTION, False)

        # --- General settings ----
        common_group = QGroupBox(_("General settings"))
        common_layout = QGridLayout()
        common_group.setLayout(common_layout)
        self.clo_cb = QCheckBox(_("Command line options:"))
        common_layout.addWidget(self.clo_cb, 0, 0)
        self.clo_edit = QLineEdit()
        self.clo_cb.toggled.connect(self.clo_edit.setEnabled)
        self.clo_edit.setEnabled(False)
        common_layout.addWidget(self.clo_edit, 0, 1)
        self.wd_cb = QCheckBox(_("Working directory:"))
        common_layout.addWidget(self.wd_cb, 1, 0)
        wd_layout = QHBoxLayout()
        self.wd_edit = QLineEdit()
        self.wd_cb.toggled.connect(self.wd_edit.setEnabled)
        self.wd_edit.setEnabled(False)
        wd_layout.addWidget(self.wd_edit)
        browse_btn = QPushButton(ima.icon("DirOpenIcon"), "", self)
        browse_btn.setToolTip(_("Select directory"))
        browse_btn.clicked.connect(self.select_directory)
        wd_layout.addWidget(browse_btn)
        common_layout.addLayout(wd_layout, 1, 1)
        self.post_mortem_cb = QCheckBox(_("Enter debugging mode when " "errors appear during execution"))
        common_layout.addWidget(self.post_mortem_cb)

        # --- Interpreter ---
        interpreter_group = QGroupBox(_("Console"))
        interpreter_layout = QVBoxLayout()
        interpreter_group.setLayout(interpreter_layout)
        self.current_radio = QRadioButton(CURRENT_INTERPRETER)
        interpreter_layout.addWidget(self.current_radio)
        self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER)
        interpreter_layout.addWidget(self.dedicated_radio)
        self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER)
        interpreter_layout.addWidget(self.systerm_radio)

        # --- Dedicated interpreter ---
        new_group = QGroupBox(_("Dedicated Python console"))
        self.current_radio.toggled.connect(new_group.setDisabled)
        new_layout = QGridLayout()
        new_group.setLayout(new_layout)
        self.interact_cb = QCheckBox(_("Interact with the Python " "console after execution"))
        new_layout.addWidget(self.interact_cb, 1, 0, 1, -1)

        self.show_kill_warning_cb = QCheckBox(_("Show warning when killing" " running process"))

        new_layout.addWidget(self.show_kill_warning_cb, 2, 0, 1, -1)
        self.pclo_cb = QCheckBox(_("Command line options:"))
        new_layout.addWidget(self.pclo_cb, 3, 0)
        self.pclo_edit = QLineEdit()
        self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled)
        self.pclo_edit.setEnabled(False)
        self.pclo_edit.setToolTip(_("<b>-u</b> is added to the " "other options you set here"))
        new_layout.addWidget(self.pclo_edit, 3, 1)

        # Checkbox to preserve the old behavior, i.e. always open the dialog
        # on first run
        hline = QFrame()
        hline.setFrameShape(QFrame.HLine)
        hline.setFrameShadow(QFrame.Sunken)
        self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog"))
        self.firstrun_cb.clicked.connect(self.set_firstrun_o)
        self.firstrun_cb.setChecked(firstrun_o)

        layout = QVBoxLayout()
        layout.addWidget(interpreter_group)
        layout.addWidget(common_group)
        layout.addWidget(new_group)
        layout.addWidget(hline)
        layout.addWidget(self.firstrun_cb)
        self.setLayout(layout)

    def select_directory(self):
        """Select directory"""
        basedir = to_text_string(self.wd_edit.text())
        if not osp.isdir(basedir):
            basedir = getcwd()
        directory = getexistingdirectory(self, _("Select directory"), basedir)
        if directory:
            self.wd_edit.setText(directory)
            self.wd_cb.setChecked(True)

    def set(self, options):
        self.runconf.set(options)
        self.clo_cb.setChecked(self.runconf.args_enabled)
        self.clo_edit.setText(self.runconf.args)
        self.wd_cb.setChecked(self.runconf.wdir_enabled)
        self.wd_edit.setText(self.runconf.wdir)
        if self.runconf.current:
            self.current_radio.setChecked(True)
        elif self.runconf.systerm:
            self.systerm_radio.setChecked(True)
        else:
            self.dedicated_radio.setChecked(True)
        self.interact_cb.setChecked(self.runconf.interact)
        self.show_kill_warning_cb.setChecked(self.runconf.show_kill_warning)
        self.post_mortem_cb.setChecked(self.runconf.post_mortem)
        self.pclo_cb.setChecked(self.runconf.python_args_enabled)
        self.pclo_edit.setText(self.runconf.python_args)

    def get(self):
        self.runconf.args_enabled = self.clo_cb.isChecked()
        self.runconf.args = to_text_string(self.clo_edit.text())
        self.runconf.wdir_enabled = self.wd_cb.isChecked()
        self.runconf.wdir = to_text_string(self.wd_edit.text())
        self.runconf.current = self.current_radio.isChecked()
        self.runconf.systerm = self.systerm_radio.isChecked()
        self.runconf.interact = self.interact_cb.isChecked()
        self.runconf.show_kill_warning = self.show_kill_warning_cb.isChecked()
        self.runconf.post_mortem = self.post_mortem_cb.isChecked()
        self.runconf.python_args_enabled = self.pclo_cb.isChecked()
        self.runconf.python_args = to_text_string(self.pclo_edit.text())
        return self.runconf.get()

    def is_valid(self):
        wdir = to_text_string(self.wd_edit.text())
        if not self.wd_cb.isChecked() or osp.isdir(wdir):
            return True
        else:
            QMessageBox.critical(
                self, _("Run configuration"), _("The following working directory is " "not valid:<br><b>%s</b>") % wdir
            )
            return False

    def set_firstrun_o(self):
        CONF.set("run", ALWAYS_OPEN_FIRST_RUN_OPTION, self.firstrun_cb.isChecked())
Пример #10
0
class NewSpaceDialog(QDialog):

    def __init__(self, parent=None, parentList=(), currIndex=0):
        QDialog.__init__(
            self, parent, flags=Qt.WindowSystemMenuHint | Qt.WindowTitleHint)

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle('Create New Space')
        self.treeview = parent
        self.reply = None

        parentLabel = QLabel(_("Parent"))
        self.parentBox = QComboBox(self)
        self.parentBox.addItems(parentList)
        self.parentBox.setCurrentIndex(currIndex)

        nameLabel = QLabel(_("Space Name"))
        self.nameEdit = QLineEdit(self)
        self.importWidget = ImportAsWidget(self, self.nameEdit)

        basesTitle = QLabel(_("Base Spaces"))
        self.basesLine = QLineEdit()
        self.basesLine.setReadOnly(True)
        self.basesLine.setEnabled(False)
        self.basesEditButton = QPushButton(_("Edit"))
        self.basesEditButton.clicked.connect(self.on_base_edit)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        mainLayout = QGridLayout(self)
        mainLayout.addWidget(parentLabel, 0, 0)
        mainLayout.addWidget(self.parentBox, 0, 1)
        mainLayout.addWidget(nameLabel, 1, 0)
        mainLayout.addWidget(self.nameEdit, 1, 1)
        mainLayout.addWidget(self.importWidget, 2, 0, 1, 2)
        mainLayout.addWidget(basesTitle, 3, 0)
        mainLayout.addWidget(self.basesLine, 3, 1)
        mainLayout.addWidget(self.basesEditButton, 3, 2)
        mainLayout.addWidget(self.buttonBox, 4, 0, 1, 2)
        self.setLayout(mainLayout)

    def accept(self) -> None:

        reply = {
            'accepted': True,
            'parent': self.parentBox.currentText(),
            'name': self.nameEdit.text(),
            'bases': self.basesLine.text(),
            'define_var': self.importWidget.shouldImport.isChecked(),
            'varname': self.importWidget.nameEdit.text()
        }
        if reply['define_var']:
            varname = reply['varname']
            if not check_varname(varname):
                QMessageBox.critical(
                    self,
                    'Error',
                    'Invalid variable name: %s' % varname
                )
                return
        self.treeview.reply = reply
        super().accept()

    def reject(self) -> None:
        self.treeview.reply = {'accepted': False}
        super().reject()

    def on_base_edit(self):
        selected = self.basesLine.text().strip()
        if selected:
            selected = [base.strip() for base in selected.split(",")]
        else:
            selected = []

        if self.treeview.model():
            allItems = self.treeview.model().rootItem.getChildSpaceList()
        else:
            allItems = []

        dialog = SelectBaseSpacesDialog(
            self,
            allItems=allItems,
            selectedItems=selected
        )
        dialog.exec()
        if self.reply['accepted']:
            self.basesLine.setText(self.reply['value'])
Пример #11
0
class GroupsModify(PyDialog):
    """
    +-------------------------------+
    |     Groups : Modify           |
    +-------------------------------+
    |                               |
    |  Name        xxx Default      |
    |  Nodes       xxx Default Show |
    |  Color       xxx Default      |
    |  Add         xxx Add     Show |
    |  Remove      xxx Remove  Show |
    |                               |
    |      Set  OK Cancel           |
    +-------------------------------+
    """
    def __init__(self,
                 data,
                 win_parent=None,
                 model_name=None,
                 group_active='main'):
        super(GroupsModify, self).__init__(data, win_parent)
        self.set_font_size(data['font_size'])
        self._updated_groups = False
        self.model_name = model_name
        self.actors = []

        #self.out_data = data

        #print(data)
        self.keys = get_groups_sorted_by_name(data)

        self.active_key = self.keys.index(group_active)

        group_obj = data[self.active_key]
        unused_name = group_obj.name

        self.imain = 0
        self.nrows = len(self.keys)

        self._default_name = group_obj.name
        self._default_elements = group_obj.element_str
        self.elements_pound = group_obj.elements_pound

        self.table = QListWidget(parent=None)
        self.table.clear()
        self.table.addItems(self.keys)

        self.setWindowTitle('Groups: Modify')
        self.create_widgets()
        self.create_layout()
        self.set_connections()

        self.on_set_as_main()

    def create_widgets(self):
        """creates the menu objects"""
        #icon = QtGui.QPixmap(os.path.join(ICON_PATH, 'node.png'))
        #icon = QtGui.QPixmap(os.path.join(ICON_PATH, 'element.png'))
        # Name
        self.pick_style_label = QLabel('Pick Style:')
        #self.pick_node_button = QPushButton('Node')
        self.pick_element_button = QPushButton('Element')
        self.pick_area_button = QPushButton('Area')
        #self.pick_node_button.setIcon(icon)
        #self.pick_area_button.setIcon(icon)

        # Name
        self.name_label = QLabel('Name:')
        self.name_set = QPushButton('Set')
        self.name_edit = QLineEdit(str(self._default_name).strip())
        self.name_button = QPushButton('Default')

        # elements
        self.elements_label = QLabel('Element IDs:')
        self.elements_edit = QLineEdit(str(self._default_elements).strip())
        self.elements_button = QPushButton('Default')
        self.elements_highlight_button = QPushButton('Show')

        # add
        self.add_label = QLabel('Add Elements:')
        self.add_edit = QElementEdit(self, self.model_name, pick_style='area')
        self.add_button = QPushButton('Add')
        self.add_highlight_button = QPushButton('Show')

        # remove
        self.remove_label = QLabel('Remove Elements:')
        self.remove_edit = QElementEdit(self,
                                        self.model_name,
                                        pick_style='area')
        self.remove_button = QPushButton('Remove')
        self.remove_highlight_button = QPushButton('Show')

        # applies a unique implicitly
        self.eids = parse_patran_syntax(str(self._default_elements),
                                        pound=self.elements_pound)

        # closing
        #self.apply_button = QPushButton('Apply')
        self.ok_button = QPushButton('Close')
        #self.cancel_button = QPushButton('Cancel')

        self.set_as_main_button = QPushButton('Set As Main')
        self.create_group_button = QPushButton('Create New Group')
        self.delete_group_button = QPushButton('Delete Group')

        self.name_label.setEnabled(False)
        self.name_set.setEnabled(False)
        self.name_edit.setEnabled(False)
        self.name_button.setEnabled(False)

        self.elements_label.setEnabled(False)
        self.elements_button.setEnabled(False)
        self.elements_edit.setEnabled(False)
        self.elements_highlight_button.setEnabled(False)

        self.add_label.setEnabled(False)
        self.add_button.setEnabled(False)
        self.add_edit.setEnabled(False)
        self.add_highlight_button.setEnabled(False)

        self.remove_label.setEnabled(False)
        self.remove_button.setEnabled(False)
        self.remove_edit.setEnabled(False)
        self.remove_highlight_button.setEnabled(False)

        #self.apply_button.setEnabled(False)
        #self.ok_button.setEnabled(False)

    def create_layout(self):
        """displays the menu objects"""
        hbox = QHBoxLayout()
        hbox.addWidget(self.pick_style_label)
        hbox.addWidget(self.pick_element_button)
        hbox.addWidget(self.pick_area_button)
        hbox.addStretch()

        grid = QGridLayout()
        irow = 0
        grid.addWidget(self.name_label, irow, 0)
        grid.addWidget(self.name_edit, irow, 1)
        grid.addWidget(self.name_set, irow, 2)
        grid.addWidget(self.name_button, irow, 3)
        irow += 1

        grid.addWidget(self.elements_label, irow, 0)
        grid.addWidget(self.elements_edit, irow, 1)
        grid.addWidget(self.elements_button, irow, 2)
        grid.addWidget(self.elements_highlight_button, irow, 3)
        irow += 1

        grid.addWidget(self.add_label, irow, 0)
        grid.addWidget(self.add_edit, irow, 1)
        grid.addWidget(self.add_button, irow, 2)
        grid.addWidget(self.add_highlight_button, irow, 3)
        irow += 1

        grid.addWidget(self.remove_label, irow, 0)
        grid.addWidget(self.remove_edit, irow, 1)
        grid.addWidget(self.remove_button, irow, 2)
        grid.addWidget(self.remove_highlight_button, irow, 3)
        irow += 1

        ok_cancel_box = QHBoxLayout()
        #ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.ok_button)
        #ok_cancel_box.addWidget(self.cancel_button)

        main_create_delete = QHBoxLayout()
        main_create_delete.addWidget(self.set_as_main_button)
        main_create_delete.addWidget(self.create_group_button)
        main_create_delete.addWidget(self.delete_group_button)

        vbox = QVBoxLayout()
        vbox.addWidget(self.table)
        vbox.addLayout(hbox)
        vbox.addLayout(grid)
        vbox.addLayout(main_create_delete)
        vbox.addStretch()
        vbox.addLayout(ok_cancel_box)
        self.setLayout(vbox)

    def on_set_name(self):
        self.remove_highlight_actor()
        name = str(self.name_edit.text()).strip()
        if name not in self.keys:
            self.name_edit.setStyleSheet("QLineEdit{background: white;}")
            group = self.out_data[self.active_key]
            group.name = name
            self.keys[self.active_key] = name
            self.recreate_table()
        elif name != self.keys[self.active_key]:
            self.name_edit.setStyleSheet('QLineEdit{background: red;}')
        elif name == self.keys[self.active_key]:
            self.name_edit.setStyleSheet('QLineEdit{background: white;}')

    def on_pick_element(self):
        self.add_edit.pick_style = 'single'
        self.remove_edit.pick_style = 'single'

    def on_pick_area(self):
        self.add_edit.pick_style = 'area'
        self.remove_edit.pick_style = 'area'

    def set_connections(self):
        """creates the actions for the menu"""
        self.pick_element_button.clicked.connect(self.on_pick_element)
        self.pick_area_button.clicked.connect(self.on_pick_area)

        self.name_set.clicked.connect(self.on_set_name)
        self.name_button.clicked.connect(self.on_default_name)
        self.elements_button.clicked.connect(self.on_default_elements)
        self.elements_highlight_button.clicked.connect(
            self.on_highlight_elements)

        self.add_button.clicked.connect(self.on_add)
        self.add_highlight_button.clicked.connect(self.on_highlight_add)

        self.remove_button.clicked.connect(self.on_remove)
        self.remove_highlight_button.clicked.connect(self.on_highlight_remove)

        self.table.itemClicked.connect(self.on_update_active_key)
        self.ok_button.clicked.connect(self.on_ok)

        self.set_as_main_button.clicked.connect(self.on_set_as_main)
        self.create_group_button.clicked.connect(self.on_create_group)
        self.delete_group_button.clicked.connect(self.on_delete_group)

    def on_create_group(self):
        self.remove_highlight_actor()

        irow = self.nrows
        new_key = f'Group {irow:d}'
        while new_key in self.keys:
            irow += 1
            new_key = f'Group {irow:d}'
        irow = self.nrows

        self.keys.append(new_key)
        group = Group(new_key,
                      element_str='',
                      elements_pound=self.elements_pound,
                      editable=True)
        self.out_data[irow] = group

        self.table.reset()
        self.table.addItems(self.keys)
        self.nrows += 1

        #----------------------------------
        # update internal parameters
        #self.out_data = items
        if self.imain > self.active_key:
            self.imain += 1

        #make the new group the default
        self.active_key = self.nrows - 1

        self.keys = get_groups_sorted_by_name(self.out_data)
        self.recreate_table()

    def recreate_table(self):
        # update gui
        self.table.clear()
        self.table.addItems(self.keys)
        item = self.table.item(self.imain)

        bold = QtGui.QFont()
        bold.setBold(True)
        bold.setItalic(True)
        item.setFont(bold)
        self.table.update()

        # update key
        name = self.keys[self.active_key]
        self._update_active_key_by_name(name)

    def on_delete_group(self):
        self.remove_highlight_actor()
        if self.active_key == 0:
            return

        #self.deleted_groups.add(self.imain)
        items = {}
        j = 0
        for i, key in sorted(self.out_data.items()):
            if isinstance(i, int):
                continue
            if i != self.active_key:
                items[j] = key
                j += 1

        # update internal parameters
        self.out_data = items
        if self.imain >= self.active_key:
            self.imain = max(0, self.imain - 1)
        self.active_key = max(0, self.active_key - 1)
        self.nrows -= 1
        self.keys = [group.name for key, group in sorted(items.items())]

        self.recreate_table()

        # update key
        name = self.keys[self.active_key]
        self._update_active_key_by_name(name)

    def on_set_as_main(self):
        bold = QtGui.QFont()
        bold.setBold(True)
        bold.setItalic(True)

        normal = QtGui.QFont()
        normal.setBold(False)
        normal.setItalic(False)

        obj = self.table.item(self.imain)
        obj.setFont(normal)

        self.imain = self.active_key
        obj = self.table.item(self.imain)
        obj.setFont(bold)
        group = self.out_data[self.imain]
        self._default_elements = group.element_str
        self._default_name = group.name
        self.on_update_main()

    def on_update_main(self):
        """adds/removes the elements to the main actor when add/remove is pressed"""
        group = self.out_data[self.imain]
        if self._default_name == group.name and self.win_parent is not None:
            # we're not testing the menu
            self.win_parent.post_group(group, update_groups=True)

    def closeEvent(self, event):
        """closes the window"""
        self.remove_highlight_actor()
        self.out_data['close'] = True
        event.accept()

    def remove_highlight_actor(self):
        """removes the highlighted actor"""
        gui = self.win_parent
        remove_actors_from_gui(gui, self.actors, render=True)
        self.actors = []

    def on_highlight(self, nids=None, eids=None):
        """highlights the nodes"""
        gui = self.win_parent
        unused_name = self.keys[self.active_key]

        if gui is not None:
            self.remove_highlight_actor()
            ## TODO: super strange; doesn't work...
            mouse_actions = gui.mouse_actions
            grid = mouse_actions.get_grid_selected(self.model_name)
            #all_nodes = mouse_actions.node_ids
            all_elements = mouse_actions.element_ids

            actors = create_highlighted_actors(gui,
                                               grid,
                                               all_nodes=None,
                                               nodes=nids,
                                               all_elements=all_elements,
                                               elements=eids,
                                               add_actors=False)
            if actors:
                add_actors_to_gui(gui, actors, render=True)
                self.actors = actors

    def on_highlight_elements(self):
        """highlights the active elements"""
        self.on_highlight(eids=self.eids)

    def on_highlight_add(self):
        """highlights the elements to add"""
        eids, is_valid = check_patran_syntax(self.add_edit,
                                             pound=self.elements_pound)
        if not is_valid:
            #self.add_edit.setStyleSheet("QLineEdit{background: red;}")
            return
        self.on_highlight(eids=eids)

    def on_highlight_remove(self):
        """highlights the elements to remove"""
        eids, is_valid = check_patran_syntax(self.remove_edit)
        if not is_valid:
            #self.remove_edit.setStyleSheet("QLineEdit{background: red;}")
            return
        self.on_highlight(eids=eids)

    def on_add(self):
        self.remove_highlight_actor()
        eids, is_valid = check_patran_syntax(self.add_edit,
                                             pound=self.elements_pound)
        #adict, is_valid = check_patran_syntax_dict(self.add_edit)
        if not is_valid:
            #self.add_edit.setStyleSheet("QLineEdit{background: red;}")
            return

        self.eids = unique(hstack([self.eids, eids]))
        #self.eids = _add(adict, ['e', 'elem', 'element'], self.eids)
        #self.cids = _add(adict, ['c', 'cid', 'coord'], self.cids)
        self._apply_cids_eids()

        self.add_edit.clear()
        self.add_edit.setStyleSheet("QLineEdit{background: white;}")
        self.on_update_main()

    def _apply_cids_eids(self):
        #ctext = _get_collapsed_text(self.cids)
        etext = _get_collapsed_text(self.eids)

        #self.coords_edit.setText(str(ctext.lstrip()))
        self.elements_edit.setText(str(etext.lstrip()))
        self.out_data[self.active_key].element_ids = self.eids

    def on_remove(self):
        self.remove_highlight_actor()
        eids, is_valid = check_patran_syntax(self.remove_edit)
        #adict, is_valid = check_patran_syntax_dict(self.remove_edit)
        if not is_valid:
            #self.remove_edit.setStyleSheet("QLineEdit{background: red;}")
            return

        #self.eids = _remove(adict, ['e', 'elem', 'element'], self.eids)
        #self.cids = _remove(adict, ['c', 'cid', 'coord'], self.cids)
        self.eids = setdiff1d(self.eids, eids)
        self._apply_cids_eids()

        self.remove_edit.clear()
        self.remove_edit.setStyleSheet(QLINE_EDIT_BASIC)
        self.on_update_main()

    def on_default_name(self):
        self.remove_highlight_actor()
        name = str(self._default_name)
        self.name_edit.setText(name)
        self.name_edit.setStyleSheet("QLineEdit{background: white;}")

    def on_default_elements(self):
        self.remove_highlight_actor()
        element_str = str(self._default_elements)
        self.elements_edit.setText(element_str)
        self.elements_edit.setStyleSheet("QLineEdit{background: white;}")
        group = self.out_data[self.active_key]
        group.element_str = element_str

    def check_name(self, cell):
        cell_value = cell.text()
        try:
            text = str(cell_value).strip()
        except UnicodeEncodeError:
            cell.setStyleSheet("QLineEdit{background: red;}")
            return None, False

        if len(text):
            cell.setStyleSheet("QLineEdit{background: white;}")
            return text, True
        else:
            cell.setStyleSheet("QLineEdit{background: red;}")
            return None, False

        if self._default_name != text:
            if self._default_name in self.out_data:
                cell.setStyleSheet("QLineEdit{background: white;}")
                return text, True
            else:
                cell.setStyleSheet("QLineEdit{background: red;}")
                return None, False

    def on_validate(self):
        name, flag0 = self.check_name(self.name_edit)
        unused_elements, flag1 = check_patran_syntax(self.elements_edit,
                                                     pound=self.elements_pound)
        #coords_value, flag2 = check_patran_syntax(
        #self.coords_edit, pound=self.coords_pound)

        if all([flag0, flag1]):
            self._default_name = name
            self._default_elements = self.eids
            self.out_data['clicked_ok'] = True
            self.out_data['close'] = True
            return True
        return False

    def on_apply(self, force=False):
        passed = self.on_validate()
        if passed or force:
            self.win_parent._apply_modify_groups(self.out_data)
        return passed

    def on_ok(self):
        passed = self.on_apply()
        if passed:
            self.close()
            #self.destroy()

    def on_cancel(self):
        self.remove_highlight_actor()
        self.out_data['close'] = True
        self.close()

    def on_update_active_key(self, index):
        self.update_active_key(index)
        #str(index.text())

    def update_active_key(self, index):
        #old_obj = self.out_data[self.imain]
        name = str(index.text())
        self._update_active_key_by_name(name)

    def _update_active_key_by_name(self, name):
        if name in self.keys:
            self.active_key = self.keys.index(name)
        else:
            # we (hopefully) just removed a row
            #self.active_key = self.keys[self.active_key]
            pass

        self.name_edit.setText(name)
        obj = self.out_data[self.active_key]

        self.eids = parse_patran_syntax(obj.element_str,
                                        pound=obj.elements_pound)
        self._default_elements = obj.element_str
        self._default_name = name
        self._apply_cids_eids()

        self.set_as_main_button.setEnabled(True)

        if name in ['main', 'anti-main']:
            enabled = False
            self.elements_edit.setEnabled(False)
            if name == 'anti-main':
                self.set_as_main_button.setEnabled(False)
            #self.apply_button.setEnabled(False)
            #self.ok_button.setEnabled(False)
        else:
            enabled = True
            self.elements_highlight_button.setEnabled(True)
            self.add_label.setEnabled(True)
            self.add_highlight_button.setEnabled(True)
            self.remove_highlight_button.setEnabled(True)
            #self.apply_button.setEnabled(True)
            #self.ok_button.setEnabled(True)

        self.name_label.setEnabled(enabled)
        self.name_set.setEnabled(enabled)
        self.name_edit.setEnabled(enabled)
        self.name_button.setEnabled(enabled)
        self.elements_label.setEnabled(enabled)
        self.elements_button.setEnabled(enabled)
        self.add_button.setEnabled(enabled)
        self.add_edit.setEnabled(enabled)

        self.remove_label.setEnabled(enabled)
        self.remove_button.setEnabled(enabled)
        self.remove_edit.setEnabled(enabled)
        self.delete_group_button.setEnabled(enabled)
Пример #12
0
class ProjectDialog(QDialog):
    """Project creation dialog."""

    sig_project_creation_requested = Signal(str, str, object)
    """
    This signal is emitted to request the Projects plugin the creation of a
    project.

    Parameters
    ----------
    project_path: str
        Location of project.
    project_type: str
        Type of project as defined by project types.
    project_packages: object
        Package to install. Currently not in use.
    """
    def __init__(self, parent, project_types):
        """Project creation dialog."""
        super(ProjectDialog, self).__init__(parent=parent)
        self.plugin = parent
        self._project_types = project_types
        self.project_data = {}

        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)

        self.project_name = None
        self.location = get_home_dir()

        # Widgets
        projects_url = "http://docs.spyder-ide.org/current/panes/projects.html"
        self.description_label = QLabel(
            _("Select a new or existing directory to create a new Spyder "
              "project in it. To learn more about projects, take a look at "
              "our <a href=\"{0}\">documentation</a>.").format(projects_url))
        self.description_label.setOpenExternalLinks(True)
        self.description_label.setWordWrap(True)

        self.groupbox = QGroupBox()
        self.radio_new_dir = QRadioButton(_("New directory"))
        self.radio_from_dir = QRadioButton(_("Existing directory"))

        self.label_project_name = QLabel(_('Project name'))
        self.label_location = QLabel(_('Location'))
        self.label_project_type = QLabel(_('Project type'))

        self.text_project_name = QLineEdit()
        self.text_location = QLineEdit(get_home_dir())
        self.combo_project_type = QComboBox()

        self.label_information = QLabel("")
        self.label_information.hide()

        self.button_select_location = create_toolbutton(
            self,
            triggered=self.select_location,
            icon=ima.icon('DirOpenIcon'),
            tip=_("Select directory"))
        self.button_cancel = QPushButton(_('Cancel'))
        self.button_create = QPushButton(_('Create'))

        self.bbox = QDialogButtonBox(Qt.Horizontal)
        self.bbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.button_create, QDialogButtonBox.ActionRole)

        # Widget setup
        self.radio_new_dir.setChecked(True)
        self.text_location.setEnabled(True)
        self.text_location.setReadOnly(True)
        self.button_cancel.setDefault(True)
        self.button_cancel.setAutoDefault(True)
        self.button_create.setEnabled(False)
        for (id_, name) in [(pt_id, pt.get_name())
                            for pt_id, pt in project_types.items()]:
            self.combo_project_type.addItem(name, id_)

        self.setWindowTitle(_('Create new project'))

        # Layouts
        layout_top = QHBoxLayout()
        layout_top.addWidget(self.radio_new_dir)
        layout_top.addSpacing(15)
        layout_top.addWidget(self.radio_from_dir)
        layout_top.addSpacing(200)
        self.groupbox.setLayout(layout_top)

        layout_grid = QGridLayout()
        layout_grid.addWidget(self.label_project_name, 0, 0)
        layout_grid.addWidget(self.text_project_name, 0, 1, 1, 2)
        layout_grid.addWidget(self.label_location, 1, 0)
        layout_grid.addWidget(self.text_location, 1, 1)
        layout_grid.addWidget(self.button_select_location, 1, 2)
        layout_grid.addWidget(self.label_project_type, 2, 0)
        layout_grid.addWidget(self.combo_project_type, 2, 1, 1, 2)
        layout_grid.addWidget(self.label_information, 3, 0, 1, 3)

        layout = QVBoxLayout()
        layout.addWidget(self.description_label)
        layout.addSpacing(3)
        layout.addWidget(self.groupbox)
        layout.addSpacing(8)
        layout.addLayout(layout_grid)
        layout.addSpacing(8)
        layout.addWidget(self.bbox)
        layout.setSizeConstraint(layout.SetFixedSize)

        self.setLayout(layout)

        # Signals and slots
        self.button_create.clicked.connect(self.create_project)
        self.button_cancel.clicked.connect(self.close)
        self.radio_from_dir.clicked.connect(self.update_location)
        self.radio_new_dir.clicked.connect(self.update_location)
        self.text_project_name.textChanged.connect(self.update_location)

    def select_location(self):
        """Select directory."""
        location = osp.normpath(
            getexistingdirectory(
                self,
                _("Select directory"),
                self.location,
            ))

        if location and location != '.':
            if is_writable(location):
                self.location = location
                self.text_project_name.setText(osp.basename(location))
                self.update_location()

    def update_location(self, text=''):
        """Update text of location and validate it."""
        msg = ''
        path_validation = False
        path = self.location
        name = self.text_project_name.text().strip()

        # Setup
        self.text_project_name.setEnabled(self.radio_new_dir.isChecked())
        self.label_information.setText('')
        self.label_information.hide()

        if name and self.radio_new_dir.isChecked():
            # Allow to create projects only on new directories.
            path = osp.join(self.location, name)
            path_validation = not osp.isdir(path)
            if not path_validation:
                msg = _("This directory already exists!")
        elif self.radio_from_dir.isChecked():
            # Allow to create projects in current directories that are not
            # Spyder projects.
            path = self.location
            path_validation = not osp.isdir(osp.join(path, '.spyproject'))
            if not path_validation:
                msg = _("This directory is already a Spyder project!")

        # Set path in text_location
        self.text_location.setText(path)

        # Validate project name with the method from the currently selected
        # project.
        project_type_id = self.combo_project_type.currentData()
        validate_func = self._project_types[project_type_id].validate_name
        project_name_validation, project_msg = validate_func(path, name)
        if not project_name_validation:
            if msg:
                msg = msg + '\n\n' + project_msg
            else:
                msg = project_msg

        # Set message
        if msg:
            self.label_information.show()
            self.label_information.setText('\n' + msg)

        # Allow to create project if validation was successful
        validated = path_validation and project_name_validation
        self.button_create.setEnabled(validated)

        # Set default state of buttons according to validation
        # Fixes spyder-ide/spyder#16745
        if validated:
            self.button_create.setDefault(True)
            self.button_create.setAutoDefault(True)
        else:
            self.button_cancel.setDefault(True)
            self.button_cancel.setAutoDefault(True)

    def create_project(self):
        """Create project."""
        self.project_data = {
            "root_path": self.text_location.text(),
            "project_type": self.combo_project_type.currentData(),
        }
        self.sig_project_creation_requested.emit(
            self.text_location.text(),
            self.combo_project_type.currentData(),
            [],
        )
        self.accept()
class OptionSelectorMainWindow(QtWidgets.QWidget):

    optionType = ["CALL", "PUT", "C&P"]
    optionPropertiesList = [
        'code', 'last_price', 'option_type', 'strike_time',
        'option_strike_price', 'option_open_interest', 'volume',
        'option_delta', 'option_gamma', 'option_vega'
    ]

    def __init__(self,
                 optionSelectorEngine,
                 eventEngine,
                 mainWindow=None,
                 parent=None):
        try:
            super(OptionSelectorMainWindow, self).__init__(parent)
            self.optionSelectorEngine = optionSelectorEngine
            self.eventEngine = eventEngine
            self.mainWindow = mainWindow

            self.optionSelectorEngine.start()
            self.initUi()
            self.registerEvent()
            self.forUT()

        except:
            traceback.print_exc()

    def initUi(self):
        try:
            self.setWindowTitle(u"期权选择器")
            self.setMinimumWidth(1200)
            self.setMinimumHeight(800)

            labelStockCode = QLabel(u"代码")
            labelStockPrice = QLabel(u"价格(非实时)")
            labelSTDTimes = QLabel(u"标准差倍数")
            labelSTDValue = QLabel(u"标准差")
            labelSTDDays = QLabel(u"计算天数")
            lableStartDate = QLabel(u"开始日期")
            labelEndDate = QLabel(u"结束日期")
            labelType = QLabel(u"类型")
            labelStrikePrice = QLabel(u"行权价范围")

            self.lineStockCode = QLineEdit()
            self.lineStockPrice = QLineEdit()
            self.lineStockPrice.setEnabled(False)
            self.lineSTDTimes = QLineEdit()
            self.lineSTDValue = QLineEdit()
            self.lineSTDValue.setEnabled(False)
            self.lineSTDDays = QLineEdit()
            self.lineStartDate = QLineEdit()
            self.lineEndDate = QLineEdit()
            self.comboxType = QComboBox()
            self.comboxType.addItems(self.optionType)
            self.lineLowStrikePrice = QLineEdit()
            self.lineHighStrikePrice = QLineEdit()

            btQry = QPushButton(u"查询")
            btSort = QPushButton(u"排序开关")

            glayout = QGridLayout()
            glayout.addWidget(labelStockCode, 0, 0)
            glayout.addWidget(labelStockPrice, 0, 1)
            glayout.addWidget(labelSTDTimes, 0, 2)
            glayout.addWidget(labelSTDValue, 0, 3)
            glayout.addWidget(labelSTDDays, 0, 4)

            glayout.addWidget(self.lineStockCode, 1, 0)
            glayout.addWidget(self.lineStockPrice, 1, 1)
            glayout.addWidget(self.lineSTDTimes, 1, 2)
            glayout.addWidget(self.lineSTDValue, 1, 3)
            glayout.addWidget(self.lineSTDDays, 1, 4)
            self.lineStockCode.setMaximumWidth(150)
            self.lineStockPrice.setMaximumWidth(150)
            self.lineSTDTimes.setMaximumWidth(80)
            self.lineSTDValue.setMaximumWidth(150)
            self.lineSTDDays.setMaximumWidth(80)

            glayout.addWidget(lableStartDate, 2, 0)
            glayout.addWidget(labelEndDate, 2, 1)
            glayout.addWidget(labelType, 2, 2)
            glayout.addWidget(labelStrikePrice, 2, 3)

            glayout.addWidget(self.lineStartDate, 3, 0)
            glayout.addWidget(self.lineEndDate, 3, 1)
            glayout.addWidget(self.comboxType, 3, 2)
            glayout.addWidget(self.lineLowStrikePrice, 3, 3)
            glayout.addWidget(self.lineHighStrikePrice, 3, 4)

            self.lineStartDate.setMaximumWidth(150)
            self.lineEndDate.setMaximumWidth(150)
            self.lineLowStrikePrice.setMaximumWidth(150)
            self.lineHighStrikePrice.setMaximumWidth(150)

            glayout.addWidget(btQry, 4, 0)
            glayout.addWidget(btSort, 4, 1)

            vbox = QVBoxLayout()
            # 策略状态组件
            self.optionSelectorMonitorWidget = OptionSelectorMonitor(self.optionSelectorEngine, self.eventEngine, \
                                                                     self.mainWindow)
            groupBoxStraMonitor = GroupBoxWithSinglWidget(
                self.optionSelectorMonitorWidget, u"期权信息")

            vbox.addLayout(glayout)
            vbox.addWidget(groupBoxStraMonitor)
            self.setLayout(vbox)

            btQry.clicked.connect(self.qryOptionList)
            btSort.clicked.connect(self.switchSort)
            self.lineStockCode.returnPressed.connect(self.pressPriceReturn)
            self.optionSelectorMonitorWidget.itemDoubleClicked.connect(
                self.passOptionSelectorDataToMainWindow)

        except:
            traceback.print_exc()

    def pressPriceReturn(self):
        self.qryStockPrice()
        # self.updateDefaultOptionStrikePrice()

    def cleanPriceRetrun(self):
        self.lineSTDValue.clear()
        self.lineLowStrikePrice.clear()
        self.lineHighStrikePrice.clear()
        self.lineStockPrice.clear()

    def qryStockPrice(self):
        try:
            self.cleanPriceRetrun()

            code = self.lineStockCode.text()
            df = self.optionSelectorEngine.qryMarketSnapshot(code)
            # 设置当前价格
            if len(df) > 0:
                price = df['last_price'][0]
                self.lineStockPrice.setText(str(price))
                # 记录昨收价
                preClosePrice = df['prev_close_price'][0]
            else:
                # error
                return

            #  计算估计近日来的标准差
            numOfDays = self.lineSTDDays.text()
            try:
                numOfDays = int(numOfDays)
            except:
                raise Exception(u"计算天数输入错误 %s" % numOfDays)

            std = self.optionSelectorEngine.calSTD(code, numOfDays)
            if std >= 0:
                # 设置行权价范围
                times = self.lineSTDTimes.text()
                try:
                    times = round(float(times), 3)
                except:
                    self.writeLog(u"方差倍数设置不正确")
                    return

                lowPrice = (preClosePrice * (1 - std * times))
                highPrice = (preClosePrice * (1 + std * times))
                lowPrice = round(lowPrice, 3)
                highPrice = round(highPrice, 3)
                self.lineSTDValue.setText(str(round(std, 4)))
                self.lineLowStrikePrice.setText(str(lowPrice))
                self.lineHighStrikePrice.setText(str(highPrice))
            else:
                # 无法计算波动范围
                self.writeLog(u"无法计算标准差 %s %s" % (code, numOfDays))

        except:
            traceback.print_exc()

    def updateDefaultOptionStrikePrice(self):
        try:
            # 默认区间是 0.9 - 1.1 倍股价
            priceStr = self.lineStockPrice.text()
            price = float(priceStr)
            lowPrice = int(price * 0.9)
            highPrice = int(price * 1.1)
            self.lineLowStrikePrice.setText(str(lowPrice))
            self.lineHighStrikePrice.setText(str(highPrice))
        except:
            pass

    def passOptionSelectorDataToMainWindow(self, cell):
        try:
            optionSelectorData = cell.data
            self.mainWindow.accpetOptionData(optionSelectorData,
                                             "OptionSprites")
        except:
            traceback.print_exc()

    def switchSort(self):
        self.optionSelectorMonitorWidget.switchSort()

    def qryOptionList(self):
        try:
            # 先查询最新股票价格
            # self.qryStockPrice()
            stockCode = self.lineStockCode.text()
            startDate = self.lineStartDate.text()
            endDate = self.lineEndDate.text()
            optLowPriceStr = self.lineLowStrikePrice.text()
            optHighPriceStr = self.lineHighStrikePrice.text()

            # 检查code,startDate, endDate, lowPrice, highPrice
            # Todo
            try:
                optLowPrice = 0
                optLowPrice = round(float(optLowPriceStr), 3)
            except:
                pass

            try:
                optHighPrice = 0
                optHighPrice = round(float(optHighPriceStr), 3)
            except:
                pass

            optType = self.comboxType.currentText()

            self.optionSelectorEngine.qryOptionList(stockCode, startDate,
                                                    endDate, optLowPrice,
                                                    optHighPrice, optType)
            self.updateDisplay()
        except:
            traceback.print_exc()

    def updateDisplay(self):
        try:
            stockCode = self.lineStockCode.text()
            df1 = self.optionSelectorEngine.getOptionDF(stockCode)

            # 查询返回有满足条件的option
            if len(df1) > 0:
                optionDF = df1[self.optionPropertiesList]
                optionDF = optionDF.sort_values(
                    ["option_strike_price", "strike_time"], ascending=False)
                # 清除原来数据
                self.optionSelectorMonitorWidget.setRowCount(0)
                self.optionSelectorMonitorWidget.clearContents()
                # 更新符合条件的数据
                for index, row in optionDF.iterrows():
                    data = VtOptionSelectorData()
                    data.code = row['code']
                    data.last_price = row['last_price']
                    data.option_type = row['option_type']
                    data.strike_time = row['strike_time']
                    data.option_strike_price = row['option_strike_price']
                    data.option_open_interest = row['option_open_interest']
                    data.volume = row['volume']
                    data.option_delta = row['option_delta']
                    data.option_gamma = row['option_gamma']
                    data.option_vega = row['option_vega']

                    self.optionSelectorMonitorWidget.updateData(data)

        except:
            traceback.print_exc()

    def registerEvent(self):
        pass

    def forUT(self):
        self.lineStockCode.setText("US.AAPL")
        dtToday = datetime.today()
        dtStr = dtToday.strftime("%Y-%m-%d")
        dtEnd = dtToday + timedelta(days=45)
        dtEndStr = dtEnd.strftime("%Y-%m-%d")
        self.lineStartDate.setText(dtStr)
        self.lineEndDate.setText(dtEndStr)
        self.lineLowStrikePrice.setText("160")
        self.lineHighStrikePrice.setText("190")
        self.lineSTDTimes.setText("1.0")
        self.lineSTDDays.setText("30")

    def writeLog(self, content):
        try:
            log = VtLogData()
            log.logContent = content
            log.gatewayName = 'OPTION_SELECTOR_MAIN_WINDOW'
            event = Event(type_=EVENT_LOG)
            event.dict_['data'] = log
            self.eventEngine.put(event)
        except:
            traceback.print_exc()
Пример #14
0
class ProjectDialog(QDialog):
    """Project creation dialog."""

    # path, type, packages
    sig_project_creation_requested = Signal(object, object, object)

    def __init__(self, parent):
        """Project creation dialog."""
        super(ProjectDialog, self).__init__(parent=parent)

        # Variables
        current_python_version = '.'.join([to_text_string(sys.version_info[0]),
                                           to_text_string(sys.version_info[1])])
        python_versions = ['2.7', '3.4', '3.5']
        if current_python_version not in python_versions:
            python_versions.append(current_python_version)
            python_versions = sorted(python_versions)

        self.project_name = None
        self.location = get_home_dir()

        # Widgets
        self.groupbox = QGroupBox()
        self.radio_new_dir = QRadioButton(_("New directory"))
        self.radio_from_dir = QRadioButton(_("Existing directory"))

        self.label_project_name = QLabel(_('Project name'))
        self.label_location = QLabel(_('Location'))
        self.label_project_type = QLabel(_('Project type'))
        self.label_python_version = QLabel(_('Python version'))

        self.text_project_name = QLineEdit()
        self.text_location = QLineEdit(get_home_dir())
        self.combo_project_type = QComboBox()
        self.combo_python_version = QComboBox()

        self.button_select_location = QToolButton()
        self.button_cancel = QPushButton(_('Cancel'))
        self.button_create = QPushButton(_('Create'))

        self.bbox = QDialogButtonBox(Qt.Horizontal)
        self.bbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.button_create, QDialogButtonBox.ActionRole)

        # Widget setup
        self.combo_python_version.addItems(python_versions)
        self.radio_new_dir.setChecked(True)
        self.text_location.setEnabled(True)
        self.text_location.setReadOnly(True)
        self.button_select_location.setIcon(get_std_icon('DirOpenIcon'))
        self.button_cancel.setDefault(True)
        self.button_cancel.setAutoDefault(True)
        self.button_create.setEnabled(False)
        self.combo_project_type.addItems(self._get_project_types())
        self.combo_python_version.setCurrentIndex(
            python_versions.index(current_python_version))
        self.setWindowTitle(_('Create new project'))
        self.setFixedWidth(500)
        self.label_python_version.setVisible(False)
        self.combo_python_version.setVisible(False)

        # Layouts        
        layout_top = QHBoxLayout()
        layout_top.addWidget(self.radio_new_dir)
        layout_top.addWidget(self.radio_from_dir)
        layout_top.addStretch(1)
        self.groupbox.setLayout(layout_top)

        layout_grid = QGridLayout()
        layout_grid.addWidget(self.label_project_name, 0, 0)
        layout_grid.addWidget(self.text_project_name, 0, 1, 1, 2)
        layout_grid.addWidget(self.label_location, 1, 0)
        layout_grid.addWidget(self.text_location, 1, 1)
        layout_grid.addWidget(self.button_select_location, 1, 2)
        layout_grid.addWidget(self.label_project_type, 2, 0)
        layout_grid.addWidget(self.combo_project_type, 2, 1, 1, 2)
        layout_grid.addWidget(self.label_python_version, 3, 0)
        layout_grid.addWidget(self.combo_python_version, 3, 1, 1, 2)

        layout = QVBoxLayout()
        layout.addWidget(self.groupbox)
        layout.addSpacing(10)
        layout.addLayout(layout_grid)
        layout.addStretch()
        layout.addSpacing(20)
        layout.addWidget(self.bbox)

        self.setLayout(layout)

        # Signals and slots
        self.button_select_location.clicked.connect(self.select_location)
        self.button_create.clicked.connect(self.create_project)
        self.button_cancel.clicked.connect(self.close)
        self.radio_from_dir.clicked.connect(self.update_location)
        self.radio_new_dir.clicked.connect(self.update_location)
        self.text_project_name.textChanged.connect(self.update_location)

    def _get_project_types(self):
        """Get all available project types."""
        project_types = get_available_project_types()
        projects = []

        for project in project_types:
            projects.append(project.PROJECT_TYPE_NAME)

        return projects

    def select_location(self):
        """Select directory."""
        location = osp.normpath(getexistingdirectory(self,
                                                     _("Select directory"),
                                                     self.location))

        if location:
            if is_writable(location):
                self.location = location
                self.update_location()

    def update_location(self, text=''):
        """Update text of location."""
        self.text_project_name.setEnabled(self.radio_new_dir.isChecked())
        name = self.text_project_name.text().strip()

        if name and self.radio_new_dir.isChecked():
            path = osp.join(self.location, name)
            self.button_create.setDisabled(os.path.isdir(path))
        elif self.radio_from_dir.isChecked():
            self.button_create.setEnabled(True)
            path = self.location
        else:
            self.button_create.setEnabled(False)
            path = self.location
        
        self.text_location.setText(path)
        
    def create_project(self):
        """Create project."""
        packages = ['python={0}'.format(self.combo_python_version.currentText())]
        self.sig_project_creation_requested.emit(
            self.text_location.text(),
            self.combo_project_type.currentText(),
            packages)
        self.accept()
Пример #15
0
class AlarmTreeEditorDisplay(Display):
    def __init__(self, parent=None):
        super(AlarmTreeEditorDisplay, self).__init__(parent=parent)

        self.app = QApplication.instance()

        # set up the ui
        self.setup_ui()

        # allow add and remove row
        self.add_button.clicked.connect(self.insertChild)
        self.remove_button.clicked.connect(self.removeItem)
        self.remove_button.setEnabled(True)

        # connect save changes
        self.button_box.accepted.connect(self.save_property_changes)

        # upon tree view selection, change the item view
        self.tree_view.selectionModel().selectionChanged.connect(
            self.handle_selection)
        self.tree_view.tree_model.dataChanged.connect(self.item_change)

        self.file_dialog = QFileDialog()
        self.open_config_action = QAction("Open", self)
        self.open_config_action.triggered.connect(self.open_file)
        self.toolbar.addAction(self.open_config_action)

        self.save_config_action = QAction("Save", self)
        self.save_config_action.triggered.connect(self.save_configuration)
        self.toolbar.addAction(self.save_config_action)

        # update configuration name
        self.tree_label.editingFinished.connect(self._update_config_name)

        # default open size
        self.resize(800, 600)

        self.config_tool = PhoebusConfigTool()

    def setup_ui(self):
        self.main_layout = QGridLayout()
        self.setLayout(self.main_layout)

        # add toolbar
        self.toolbar = QToolBar()
        self.main_layout.setMenuBar(self.toolbar)

        # create the tree view layout and add/remove buttons
        self.tree_view_layout = QVBoxLayout()
        self.tree_view = PyDMAlarmTree(self,
                                       config_name="UNITITLED",
                                       edit_mode=True)
        self.tree_view.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.tree_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tree_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tree_view.setHeaderHidden(True)

        # Drag/drop
        self.tree_view.setDragDropMode(QAbstractItemView.InternalMove)
        self.tree_view.setDragEnabled(True)
        self.tree_view.setAcceptDrops(True)

        # view sizing
        self.tree_view.setColumnWidth(0, 160)
        self.tree_view.setColumnWidth(1, 160)
        self.tree_view.setColumnWidth(2, 160)

        # lable for tree view
        configuration_indicator = QLabel("Configuration:")
        self.tree_label = QLineEdit("Untitled")

        self.tree_label_layout = QHBoxLayout()
        self.tree_label_layout.addWidget(configuration_indicator)
        self.tree_label_layout.addWidget(self.tree_label)

        self.tree_view_layout.addLayout(self.tree_label_layout)
        self.tree_view_layout.addWidget(self.tree_view)

        # add/ remove buttons
        self.add_remove_layout = QHBoxLayout()
        spacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                             QSizePolicy.Minimum)
        self.add_remove_layout.addItem(spacer)
        self.add_button = QPushButton("New", self)
        self.add_remove_layout.addWidget(self.add_button)
        self.remove_button = QPushButton("Remove", self)
        self.add_remove_layout.addWidget(self.remove_button)
        self.tree_view_layout.addLayout(self.add_remove_layout)

        # add the tree view to the window
        self.main_layout.addLayout(self.tree_view_layout, 0, 0)

        self.property_layout = QVBoxLayout()
        self.property_layout.addWidget(QLabel("Alarm Properties"))

        # crate property view
        self.property_data_layout = QStackedLayout()
        self.property_layout.addLayout(self.property_data_layout)

        self.property_widget_config = QWidget()
        self.property_widget_config.setWindowTitle("config")

        # create group widget
        self.property_widget_group = QWidget()
        self.property_widget_group.setWindowTitle("group")

        self.property_view_layout_group = QGridLayout()

        # add label
        self.label_edit_group = QLineEdit()
        self.label_label_group = QLabel("NAME")

        # add guidance
        self.guidance_edit_group = QLineEdit()
        self.guidance_label_group = QLabel("GUIDANCE")

        self.property_view_layout_group.addWidget(self.label_label_group, 1, 0)
        self.property_view_layout_group.addWidget(self.label_edit_group, 1, 1)

        self.property_view_layout_group.addWidget(self.guidance_label_group, 2,
                                                  0)
        self.property_view_layout_group.addWidget(self.guidance_edit_group, 2,
                                                  1)

        spacer = QSpacerItem(40, 200, QSizePolicy.Expanding,
                             QSizePolicy.Minimum)

        self.property_view_layout_group.addItem(spacer, 3, 0)
        self.property_view_layout_group.addItem(spacer, 4, 0)
        self.property_view_layout_group.addItem(spacer, 5, 0)
        self.property_view_layout_group.addItem(spacer, 6, 0)
        self.property_view_layout_group.addItem(spacer, 7, 0)
        self.property_view_layout_group.addItem(spacer, 8, 0)

        # create pv widget
        self.property_widget_pv = QWidget()
        self.property_widget_pv.setWindowTitle("pv")

        self.property_view_layout_pv = QGridLayout()

        # add label
        self.label_edit_pv = QLineEdit()
        self.label_label_pv = QLabel("NAME")

        # add guidance
        self.guidance_edit_pv = QLineEdit()
        self.guidance_label_pv = QLabel("GUIDANCE")

        self.property_view_layout_pv.addWidget(self.label_label_pv, 1, 0)
        self.property_view_layout_pv.addWidget(self.label_edit_pv, 1, 1, 1, 3)

        self.property_view_layout_pv.addWidget(self.guidance_label_pv, 2, 0)
        self.property_view_layout_pv.addWidget(self.guidance_edit_pv, 2, 1, 1,
                                               3)

        # add description
        self.description_edit = QLineEdit()
        self.description_label = QLabel("DESCRIPTION")
        self.property_view_layout_pv.addWidget(self.description_label, 3, 0)
        self.property_view_layout_pv.addWidget(self.description_edit, 3, 1, 1,
                                               3)

        # add delay
        self.delay_edit = QLineEdit()
        self.delay_label = QLabel("DELAY")
        self.property_view_layout_pv.addWidget(self.delay_label, 4, 0)
        self.property_view_layout_pv.addWidget(self.delay_edit, 4, 1, 1, 3)
        self.delay_edit.setValidator(QIntValidator())

        # add count
        self.count_edit = QLineEdit()
        self.count_label = QLabel("COUNT")
        self.property_view_layout_pv.addWidget(self.count_label, 5, 0)
        self.property_view_layout_pv.addWidget(self.count_edit, 5, 1, 1, 3)
        self.count_edit.setValidator(QIntValidator())

        # add filter/force pv
        self.filter_edit = QLineEdit()
        self.filter_label = QLabel("ENABLING FILTER")
        self.property_view_layout_pv.addWidget(self.filter_label, 6, 0)
        self.property_view_layout_pv.addWidget(self.filter_edit, 6, 1, 1, 3)

        # enabled, latching, annunciating
        self.enabled_check = QCheckBox("ENABLED")
        self.annunciating_check = QCheckBox("ANNUNCIATING")
        self.latching_check = QCheckBox("LATCHING")
        self.property_view_layout_pv.addWidget(self.enabled_check, 7, 0)
        self.property_view_layout_pv.addWidget(self.annunciating_check, 7, 1)
        self.property_view_layout_pv.addWidget(self.latching_check, 7, 2)

        self.property_view_layout_pv.addItem(spacer, 8, 0)

        # create save button
        self.button_box = QDialogButtonBox(self)
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.addButton("Save Properties",
                                  QDialogButtonBox.AcceptRole)

        self.property_layout.addWidget(self.button_box)
        # self.property_layout.addLayout(self.property_view_layout)

        self.property_widget_pv.setLayout(self.property_view_layout_pv)
        self.property_widget_group.setLayout(self.property_view_layout_group)

        self.property_data_layout.addWidget(self.property_widget_config)
        self.property_data_layout.addWidget(self.property_widget_pv)
        self.property_data_layout.addWidget(self.property_widget_group)

        self.main_layout.addLayout(self.property_layout, 0, 1)

        self.setWindowTitle("Alarm Tree Editor")
        self.tree_view.expandAll()

    def minimumSizeHint(self):
        # This is the default recommended size
        # for this screen
        return QSize(400, 200)

    def insertChild(self):
        index = self.tree_view.selectionModel().currentIndex()
        model = self.tree_view.model()

        if model.columnCount(index) == 0:
            if not model.insertColumn(0, index):
                return

        if not model.insertRow(0, index):
            return

        for column in range(model.columnCount(index)):
            child = model.index(0, column, index)
            model.set_data(child, label="NEW_ITEM", role=Qt.EditRole)

    def removeItem(self):
        index = self.tree_view.selectionModel().currentIndex()
        self.tree_view.model().removeRow(index.row(), index.parent())

    @Slot()
    def save_property_changes(self):
        index = self.tree_view.selectionModel().currentIndex()
        item = self.tree_view.model().getItem(index)
        if item.is_group:
            guidance = self.guidance_edit_group.text()
            label = self.label_edit_group.text()
        else:
            guidance = self.guidance_edit_pv.text()
            label = self.label_edit_pv.text()

        self.tree_view.model().set_data(
            index,
            label=label,
            description=self.description_edit.text(),
            delay=self.delay_edit.text(),
            count=self.count_edit.text(),
            enabled=self.enabled_check.isChecked(),
            annunciating=self.annunciating_check.isChecked(),
            latching=self.latching_check.isChecked(),
            alarm_filter=self.filter_edit.text(),
            guidance=guidance,
            role=Qt.EditRole,
        )

    @Slot()
    def handle_selection(self):
        self.remove_button.setEnabled(
            self.tree_view.selectionModel().hasSelection())

        index = self.tree_view.selectionModel().currentIndex()
        item = self.tree_view.model().getItem(index)

        if item.is_group:
            self.guidance_edit_group.setText(item.guidance)
            self.label_edit_group.setText(item.label)
        else:
            self.guidance_edit_pv.setText(item.guidance)
            self.label_edit_pv.setText(item.label)

        if item.is_group:
            # black for configuration screen
            if not item.parent:
                self.property_data_layout.setCurrentWidget(
                    self.property_widget_config)
            # otherwise show group screen and set all disables
            else:
                self.property_data_layout.setCurrentWidget(
                    self.property_widget_group)
                self.description_edit.setEnabled(False)
                self.description_edit.setVisible(False)
                self.description_label.setVisible(False)

                self.count_edit.setEnabled(False)
                self.count_edit.setVisible(False)
                self.count_label.setVisible(False)

                self.delay_edit.setEnabled(False)
                self.delay_edit.setVisible(False)
                self.delay_label.setVisible(False)

                self.latching_check.setEnabled(False)
                self.latching_check.setVisible(False)

                self.annunciating_check.setEnabled(False)
                self.annunciating_check.setVisible(False)

                self.filter_edit.setEnabled(False)
                self.filter_edit.setVisible(False)
                self.filter_label.setVisible(False)

        # set pv enabled
        else:
            self.property_data_layout.setCurrentWidget(self.property_widget_pv)
            self.description_edit.setEnabled(True)
            self.description_edit.setVisible(True)
            self.description_label.setVisible(True)

            self.count_edit.setEnabled(True)
            self.count_edit.setVisible(True)
            self.count_label.setVisible(True)

            self.delay_edit.setEnabled(True)
            self.delay_edit.setVisible(True)
            self.delay_label.setVisible(True)

            self.latching_check.setEnabled(True)
            self.latching_check.setVisible(True)

            self.annunciating_check.setEnabled(True)
            self.annunciating_check.setVisible(True)

            self.filter_edit.setEnabled(True)
            self.filter_edit.setVisible(True)
            self.filter_label.setVisible(True)

            if item.enabled:
                self.enabled_check.setChecked(True)
            else:
                self.enabled_check.setChecked(False)

            if item.latching:
                self.latching_check.setChecked(True)
            else:
                self.latching_check.setChecked(False)

            if item.annunciating:
                self.annunciating_check.setChecked(True)
            else:
                self.annunciating_check.setChecked(False)

    @Slot()
    def item_change(self):
        index = self.tree_view.selectionModel().currentIndex()
        item = self.tree_view.model().getItem(index)

        if item.is_group:
            self.guidance_edit_group.setText(item.guidance)
            self.label_edit_group.setText(item.label)
        else:
            self.guidance_edit_pv.setText(item.guidance)
            self.label_edit_pv.setText(item.label)

        if item.is_group:
            if not item.parent():
                self.property_data_layout.setCurrentWidget(
                    self.property_widget_config)

            else:
                self.property_data_layout.setCurrentWidget(
                    self.property_widget_group)

            self.description_edit.setEnabled(False)
            self.description_edit.setVisible(False)
            self.description_label.setVisible(False)

            self.count_edit.setEnabled(False)
            self.count_edit.setVisible(False)
            self.count_label.setVisible(False)

            self.delay_edit.setEnabled(False)
            self.delay_edit.setVisible(False)
            self.delay_label.setVisible(False)

            self.latching_check.setEnabled(False)
            self.latching_check.setVisible(False)

            self.annunciating_check.setEnabled(False)
            self.annunciating_check.setVisible(False)

            self.filter_edit.setEnabled(False)
            self.filter_edit.setVisible(False)
            self.filter_label.setVisible(False)

        else:
            self.delay_edit.setText(item.delay)
            self.count_edit.setText(item.count)

            if item.enabled:
                self.enabled_check.setChecked(True)
            else:
                self.enabled_check.setChecked(False)

            self.property_data_layout.setCurrentWidget(self.property_widget_pv)
            self.description_edit.setEnabled(True)
            self.description_edit.setVisible(True)
            self.description_label.setVisible(True)

            self.count_edit.setEnabled(True)
            self.count_edit.setVisible(True)
            self.count_label.setVisible(True)

            self.delay_edit.setEnabled(True)
            self.delay_edit.setVisible(True)
            self.delay_label.setVisible(True)

            self.latching_check.setEnabled(True)
            self.latching_check.setVisible(True)

            self.annunciating_check.setEnabled(True)
            self.annunciating_check.setVisible(True)

            self.filter_edit.setEnabled(True)
            self.filter_edit.setVisible(True)
            self.filter_label.setVisible(True)

            if item.latching:
                self.latching_check.setChecked(True)
            else:
                self.latching_check.setChecked(False)

            if item.annunciating:
                self.annunciating_check.setChecked(True)
            else:
                self.annunciating_check.setChecked(False)

    def ui_filepath(self):
        # No UI file is being used
        return None

    @Slot(bool)
    def open_file(self, checked):
        modifiers = QApplication.keyboardModifiers()
        try:
            curr_file = self.current_file()
            folder = os.path.dirname(curr_file)
        except Exception:
            folder = os.getcwd()

        filename = QFileDialog.getOpenFileName(
            self, "Open File...", folder,
            "XML (*.xml);; ALH Config (*.alhConfig)")
        filename = filename[0] if isinstance(filename,
                                             (list, tuple)) else filename

        if filename:
            filename = str(filename)

            # if alh file selected, open conversion prompt
            if filename[-9:] == "alhConfig":
                self.legacy_window = LegacyWindow(filename)
                self.legacy_window.exec_()

                if self.legacy_window.converted_filename:
                    self.import_configuration(
                        self.legacy_window.converted_filename)

            else:
                self.import_configuration(filename)

    def import_configuration(self, filename):
        nodes = self.config_tool.parse_config(filename)
        self.tree_view.model().import_hierarchy(nodes)
        self.tree_label.setText(self.tree_view.model()._nodes[0].label)

    @Slot()
    def save_configuration(self):
        modifiers = QApplication.keyboardModifiers()
        try:
            curr_file = self.current_file()
            folder = os.path.dirname(curr_file)
        except Exception:
            folder = os.getcwd()

        filename = QFileDialog.getSaveFileName(self, "Save File...", folder,
                                               "Configration files (*.xml)")
        filename = filename[0] if isinstance(filename,
                                             (list, tuple)) else filename

        self.config_tool.save_configuration(self.tree_view.model()._root_item,
                                            filename)

    def _update_config_name(self):
        name = self.tree_label.text()
        self.tree_view.model()._nodes[0].label = name

    def _import_legacy_file(self):
        convert_alh_to_phoebus()
Пример #16
0
class LSPServerEditor(QDialog):
    DEFAULT_HOST = '127.0.0.1'
    DEFAULT_PORT = 2084
    DEFAULT_CMD = ''
    DEFAULT_ARGS = ''
    DEFAULT_CONFIGURATION = '{}'
    DEFAULT_EXTERNAL = False
    HOST_REGEX = re.compile(r'^\w+([.]\w+)*$')
    NON_EMPTY_REGEX = re.compile(r'^\S+$')
    JSON_VALID = _('JSON valid')
    JSON_INVALID = _('JSON invalid')

    def __init__(self, parent, language=None, cmd='', host='127.0.0.1',
                 port=2084, args='', external=False, configurations={},
                 **kwargs):
        super(LSPServerEditor, self).__init__(parent)
        self.parent = parent
        self.external = external
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_ok = bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = bbox.button(QDialogButtonBox.Cancel)
        self.button_ok.setEnabled(False)

        description = _('To create a new configuration, '
                        'you need to select a programming '
                        'language, along with a executable '
                        'name for the server to execute '
                        '(If the instance is local), '
                        'and the host and port. Finally, '
                        'you need to provide the '
                        'arguments that the server accepts. '
                        'The placeholders <tt>%(host)s</tt> and '
                        '<tt>%(port)s</tt> refer to the host '
                        'and the port, respectively.')
        server_settings_description = QLabel(description)
        server_settings_description.setWordWrap(True)

        lang_label = QLabel(_('Language:'))
        self.lang_cb = QComboBox(self)
        self.lang_cb.setToolTip(_('Programming language provided '
                                  'by the LSP server'))
        self.lang_cb.addItem(_('Select a language'))
        self.lang_cb.addItems(LSP_LANGUAGES)

        if language is not None:
            idx = LSP_LANGUAGES.index(language)
            self.lang_cb.setCurrentIndex(idx + 1)
            self.button_ok.setEnabled(True)

        host_label = QLabel(_('Host:'))
        self.host_input = QLineEdit(self)
        self.host_input.setToolTip(_('Name of the host that will provide '
                                     'access to the server'))
        self.host_input.setText(host)
        self.host_input.textChanged.connect(lambda x: self.validate())

        port_label = QLabel(_('Port:'))
        self.port_spinner = QSpinBox(self)
        self.port_spinner.setToolTip(_('TCP port number of the server'))
        self.port_spinner.setMinimum(1)
        self.port_spinner.setMaximum(60000)
        self.port_spinner.setValue(port)

        cmd_label = QLabel(_('Command to execute:'))
        self.cmd_input = QLineEdit(self)
        self.cmd_input.setToolTip(_('Command used to start the '
                                    'LSP server locally'))
        self.cmd_input.setText(cmd)

        if not external:
            self.cmd_input.textChanged.connect(lambda x: self.validate())

        args_label = QLabel(_('Server arguments:'))
        self.args_input = QLineEdit(self)
        self.args_input.setToolTip(_('Additional arguments required to '
                                     'start the server'))
        self.args_input.setText(args)

        conf_label = QLabel(_('LSP Server Configurations:'))
        self.conf_input = CodeEditor(None)
        self.conf_input.textChanged.connect(self.validate)
        color_scheme = CONF.get('appearance', 'selected')
        self.conf_input.setup_editor(
            language='JSON',
            color_scheme=color_scheme,
            wrap=False,
            edge_line=True,
            highlight_current_line=True,
            highlight_current_cell=True,
            occurrence_highlighting=True,
            auto_unindent=True,
            font=get_font(),
            filename='config.json')
        self.conf_input.setToolTip(_('Additional LSP server configurations '
                                     'set at runtime. JSON required'))
        conf_text = '{}'
        try:
            conf_text = json.dumps(configurations, indent=4, sort_keys=True)
        except Exception:
            pass
        self.conf_input.set_text(conf_text)
        self.json_label = QLabel(self.JSON_VALID, self)

        self.external_cb = QCheckBox(_('External server'), self)
        self.external_cb.setToolTip(_('Check if the server runs '
                                      'on a remote location'))
        self.external_cb.setChecked(external)
        self.external_cb.stateChanged.connect(self.set_local_options)

        hlayout = QHBoxLayout()
        general_vlayout = QVBoxLayout()
        general_vlayout.addWidget(server_settings_description)

        vlayout = QVBoxLayout()
        lang_layout = QVBoxLayout()
        lang_layout.addWidget(lang_label)
        lang_layout.addWidget(self.lang_cb)

        # layout2 = QHBoxLayout()
        # layout2.addLayout(lang_layout)
        lang_layout.addWidget(self.external_cb)
        vlayout.addLayout(lang_layout)

        host_layout = QVBoxLayout()
        host_layout.addWidget(host_label)
        host_layout.addWidget(self.host_input)

        port_layout = QVBoxLayout()
        port_layout.addWidget(port_label)
        port_layout.addWidget(self.port_spinner)

        conn_info_layout = QHBoxLayout()
        conn_info_layout.addLayout(host_layout)
        conn_info_layout.addLayout(port_layout)
        vlayout.addLayout(conn_info_layout)

        cmd_layout = QVBoxLayout()
        cmd_layout.addWidget(cmd_label)
        cmd_layout.addWidget(self.cmd_input)
        vlayout.addLayout(cmd_layout)

        args_layout = QVBoxLayout()
        args_layout.addWidget(args_label)
        args_layout.addWidget(self.args_input)
        vlayout.addLayout(args_layout)

        conf_layout = QVBoxLayout()
        conf_layout.addWidget(conf_label)
        conf_layout.addWidget(self.conf_input)
        conf_layout.addWidget(self.json_label)

        hlayout.addLayout(vlayout)
        hlayout.addLayout(conf_layout)
        general_vlayout.addLayout(hlayout)

        general_vlayout.addWidget(bbox)
        self.setLayout(general_vlayout)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        self.lang_cb.currentIndexChanged.connect(
            self.lang_selection_changed)
        self.form_status(False)
        if language is not None:
            self.form_status(True)
            self.validate()

    @Slot()
    def validate(self):
        host_text = self.host_input.text()
        cmd_text = self.cmd_input.text()
        if not self.HOST_REGEX.match(host_text):
            self.button_ok.setEnabled(False)
            self.host_input.setStyleSheet("QLineEdit{border: 1px solid red;}")
            self.host_input.setToolTip('Hostname must be valid')
            return
        else:
            self.host_input.setStyleSheet(
                "QLineEdit{border: 1px solid green;}")
            self.host_input.setToolTip('Hostname is valid')
            self.button_ok.setEnabled(True)

        if not self.external:
            if not self.NON_EMPTY_REGEX.match(cmd_text):
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Command must be non empty')
                return

            if find_program(cmd_text) is None:
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid red;}")
                self.cmd_input.setToolTip('Program was not found '
                                          'on your system')
                return
            else:
                self.cmd_input.setStyleSheet(
                    "QLineEdit{border: 1px solid green;}")
                self.cmd_input.setToolTip('Program was found on your system')
                self.button_ok.setEnabled(True)
        try:
            json.loads(self.conf_input.toPlainText())
            try:
                self.json_label.setText(self.JSON_VALID)
            except:
                pass
        except (ValueError, json.decoder.JSONDecodeError):
            try:
                self.json_label.setText(self.JSON_INVALID)
                self.button_ok.setEnabled(False)
            except:
                pass

    def form_status(self, status):
        self.host_input.setEnabled(status)
        self.port_spinner.setEnabled(status)
        self.external_cb.setEnabled(status)
        self.cmd_input.setEnabled(status)
        self.args_input.setEnabled(status)
        self.conf_input.setEnabled(status)
        self.json_label.setVisible(status)

    @Slot()
    def lang_selection_changed(self):
        idx = self.lang_cb.currentIndex()
        if idx == 0:
            self.set_defaults()
            self.form_status(False)
            self.button_ok.setEnabled(False)
        else:
            server = self.parent.get_server_by_lang(LSP_LANGUAGES[idx - 1])
            self.form_status(True)
            if server is not None:
                self.host_input.setText(server.host)
                self.port_spinner.setValue(server.port)
                self.external_cb.setChecked(server.external)
                self.cmd_input.setText(server.cmd)
                self.args_input.setText(server.args)
                self.conf_input.set_text(json.dumps(server.configurations))
                self.json_label.setText(self.JSON_VALID)
                self.button_ok.setEnabled(True)
            else:
                self.set_defaults()

    def set_defaults(self):
        self.cmd_input.setStyleSheet('')
        self.host_input.setStyleSheet('')
        self.host_input.setText(self.DEFAULT_HOST)
        self.port_spinner.setValue(self.DEFAULT_PORT)
        self.external_cb.setChecked(self.DEFAULT_EXTERNAL)
        self.cmd_input.setText(self.DEFAULT_CMD)
        self.args_input.setText(self.DEFAULT_ARGS)
        self.conf_input.set_text(self.DEFAULT_CONFIGURATION)
        self.json_label.setText(self.JSON_VALID)

    @Slot(bool)
    @Slot(int)
    def set_local_options(self, enabled):
        self.external = enabled
        self.cmd_input.setEnabled(True)
        self.args_input.setEnabled(True)
        if enabled:
            self.cmd_input.setEnabled(False)
            self.cmd_input.setStyleSheet('')
            self.args_input.setEnabled(False)
        try:
            self.validate()
        except:
            pass

    def get_options(self):
        language_idx = self.lang_cb.currentIndex()
        language = LSP_LANGUAGES[language_idx - 1]
        host = self.host_input.text()
        port = int(self.port_spinner.value())
        external = self.external_cb.isChecked()
        args = self.args_input.text()
        cmd = self.cmd_input.text()
        configurations = json.loads(self.conf_input.toPlainText())
        server = LSPServer(language=language.lower(), cmd=cmd, args=args,
                           host=host, port=port, external=external,
                           configurations=configurations)
        return server
Пример #17
0
class FeaturesPlotWidget(CustomWidget):
    call_manage_settings = Signal()

    def __init__(self, *args, **kwargs):

        # define status images
        self.status_icons = {
            -2:
            QPixmap(
                os.path.join(os.path.dirname(__file__), 'icons',
                             'depth_status_delay.png')),
            -1:
            QPixmap(
                os.path.join(os.path.dirname(__file__), 'icons',
                             'depth_status_in_use.png')),
            1:
            QPixmap(
                os.path.join(os.path.dirname(__file__), 'icons',
                             'depth_status_done.png')),
            0:
            QPixmap(
                os.path.join(os.path.dirname(__file__), 'icons',
                             'depth_status_off.png')),
        }

        # Settings
        self.subject_settings = None
        self.procedure_settings = None
        self.depth_settings = None
        self.features_settings = None

        # Plot options
        self.plot_config = {}
        self.y_range = uVRANGE
        self.plot_stack = QStackedWidget()
        # generate a dict {chan_label: {Feature:[stack idx, latest_datum]}}
        self.stack_dict = {}

        # shared memory to display the currently monitored electrode
        self.monitored_channel_mem = QSharedMemory()
        self.monitored_channel_mem.setKey("MonitoredChannelMemory")
        self.monitored_channel_mem.attach(QSharedMemory.ReadOnly)

        # wrap up init
        super(FeaturesPlotWidget, self).__init__(*args, **kwargs)
        self.move(WINDOWDIMS_FEATURES[0], WINDOWDIMS_FEATURES[1])
        self.resize(WINDOWDIMS_FEATURES[2], WINDOWDIMS_FEATURES[3])
        self.setMaximumWidth(WINDOWDIMS_FEATURES[2])

        # initialize plots
        self.layout().addWidget(self.plot_stack)
        self.refresh_axes()  # Extra time on purpose.

        # Define and start processes
        # will only start processes when settings are received
        self.depth_wrapper = ProcessWrapper('Depth_Process')
        self.depth_process_running = False

        self.features_wrapper = ProcessWrapper('Features_Process')
        self.features_process_running = False

    def create_control_panel(self):
        # define Qt GUI elements
        layout = QHBoxLayout()

        layout_L = QVBoxLayout()
        layout_L1 = QHBoxLayout()

        # layout_L1.addSpacing(10)
        layout_L1.addWidget(
            QLabel("Electrode: ", alignment=Qt.AlignVCenter | Qt.AlignRight))
        # Channel selection
        self.chan_select = QComboBox()
        self.chan_select.addItem("None")
        self.chan_select.setMinimumWidth(70)
        self.chan_select.setEnabled(False)
        layout_L1.addWidget(self.chan_select)

        layout_L1.addSpacing(20)

        # features selection
        layout_L1.addWidget(
            QLabel("Feature set: ", alignment=Qt.AlignVCenter | Qt.AlignRight))
        self.feature_select = QComboBox()
        self.feature_select.setMinimumWidth(60)
        self.feature_select.addItems(['Raw', 'Mapping'])
        self.feature_select.setCurrentIndex(0)
        layout_L1.addWidget(self.feature_select)

        layout_L.addLayout(layout_L1)
        layout_L.addSpacing(5)

        layout_L2 = QHBoxLayout()
        layout_L2.addSpacing(10)
        layout_L2.addWidget(
            QLabel("+/- ", alignment=Qt.AlignVCenter | Qt.AlignRight))
        self.range_edit = QLineEdit("{:.2f}".format(uVRANGE))
        self.range_edit.setMaximumWidth(50)
        layout_L2.addWidget(self.range_edit)

        layout_L2.addSpacing(30)

        self.do_hp = QCheckBox('HP')
        self.do_hp.setChecked(True)
        layout_L2.addWidget(self.do_hp)

        layout_L2.addSpacing(30)

        self.sweep_control = QCheckBox("Match SweepGUI.")
        self.sweep_control.setChecked(True)
        self.sweep_control.setEnabled(True)
        layout_L2.addWidget(self.sweep_control)

        layout_L.addLayout(layout_L2)

        layout_R = QHBoxLayout()

        self.bt_refresh = QPushButton("Refresh")
        self.bt_refresh.setMaximumWidth(50)
        layout_R.addWidget(self.bt_refresh)

        layout_R.addSpacing(20)

        self.btn_settings = QPushButton("Settings")
        self.btn_settings.setMaximumWidth(50)
        layout_R.addWidget(self.btn_settings)

        layout_R.addSpacing(20)

        self.features_process_btn = QPushButton('Features')
        self.features_process_btn.setMaximumWidth(50)
        self.features_process_btn.setStyleSheet("QPushButton { color: white; "
                                                "background-color : red; "
                                                "border-color : red; "
                                                "border-width: 2px}")
        self.features_process_btn.clicked.connect(
            self.features_process_btn_callback)
        layout_R.addWidget(self.features_process_btn)

        layout_R.addSpacing(5)

        self.depth_process_btn = QPushButton('Record')
        self.depth_process_btn.setMaximumWidth(50)
        self.depth_process_btn.setStyleSheet("QPushButton { color: white; "
                                             "background-color : red; "
                                             "border-color : red; "
                                             "border-width: 2px}")
        self.depth_process_btn.clicked.connect(self.depth_process_btn_callback)
        layout_R.addWidget(self.depth_process_btn)

        layout_R.addSpacing(20)

        self.status_label = QLabel()
        self.status_label.setPixmap(self.status_icons[0])
        layout_R.addWidget(self.status_label)
        layout_R.addSpacing(10)

        layout.addLayout(layout_L)
        layout.addStretch()
        layout.addLayout(layout_R)

        # layout.addSpacing(10)
        self.layout().addLayout(layout)

        # callbacks
        self.btn_settings.clicked.connect(self.call_manage_settings.emit)
        self.chan_select.currentIndexChanged.connect(
            self.manage_feat_chan_select)
        self.feature_select.currentIndexChanged.connect(
            self.manage_feat_chan_select)
        self.sweep_control.clicked.connect(self.manage_sweep_control)
        self.range_edit.editingFinished.connect(self.manage_range_edit)
        self.bt_refresh.clicked.connect(self.manage_refresh)

    def depth_process_btn_callback(self):
        # kill
        if self.depth_process_running:
            self.manage_depth_process(False)
            self.manage_nsp(False)
        else:
            # if we terminate and re-start the processes, we need to re-enable the shared memory
            self.depth_wrapper.manage_shared_memory()

            # re-send the settings
            self.depth_wrapper.send_settings(self.depth_settings)

            # start nsp recording
            if self.manage_nsp(True) == 0:
                # re-start the worker
                self.manage_depth_process(True)

    def features_process_btn_callback(self):
        # kill
        if self.features_process_running:
            self.manage_feature_process(False)
        else:
            # if we terminate and re-start the processes, we need to re-enable the shared memory
            self.features_wrapper.manage_shared_memory()

            # re-send the settings
            self.features_wrapper.send_settings(self.features_settings)

            # re-start the worker
            self.manage_feature_process(True)

    # GUI Callbacks
    def manage_feat_chan_select(self):
        self.plot_stack.setCurrentIndex(
            self.stack_dict[self.chan_select.currentText()][
                self.feature_select.currentText()][0])

    def manage_sweep_control(self):
        if self.sweep_control.isChecked(
        ) and self.monitored_channel_mem.isAttached():
            self.chan_select.setEnabled(False)
            self.do_hp.setEnabled(False)
            self.range_edit.setEnabled(False)
            self.read_from_shared_memory()
        else:
            self.chan_select.setEnabled(True)
            self.do_hp.setEnabled(True)
            self.range_edit.setEnabled(True)

    def manage_range_edit(self):
        # need to do it like this because if we simply read the QLineEdit.text() on update calls, it breaks during
        # typing the new range values.
        self.y_range = float(self.range_edit.text())

    @staticmethod
    def parse_patient_name(full_name):
        # parse the subject information
        names = full_name.split(' ')
        m_name = ''
        m_idx = -1
        l_idx = -1
        for idx, n in enumerate(names):
            if all([x.isupper() for x in n]):
                m_idx = idx
                l_idx = idx + 1
                m_name = n
                break

        f_name = str.join(' ', names[:m_idx])
        l_name = str.join(' ', names[l_idx:])
        return f_name, m_name, l_name

    def manage_nsp(self, on_off):
        f_name, m_name, l_name = self.parse_patient_name(
            self.subject_settings['name'])
        file_info = {
            'filename':
            os.path.normpath(
                os.path.join(
                    BASEPATH, self.subject_settings['id'],
                    self.procedure_settings['date'].strftime('%m%d%y') + '_' +
                    self.subject_settings['id'] + '_' +
                    self.procedure_settings['target_name'] + '_' +
                    self.procedure_settings['recording_config'])),
            'comment':
            self.subject_settings['NSP_comment'],
            'patient_info': {
                'ID': self.subject_settings['id'],
                # if only single name, returned in l_name
                'firstname': f_name if f_name else l_name,
                'middlename': m_name,  # TODO: implement MiddleName
                'lastname': l_name,
                'DOBMonth': self.subject_settings['birthday'].month,
                'DOBDay': self.subject_settings['birthday'].day,
                'DOBYear': self.subject_settings['birthday'].year
            }
        }

        if not CbSdkConnection().is_connected:
            CbSdkConnection().connect()

        return CbSdkConnection().set_recording_state(on_off, file_info)

    def manage_depth_process(self, on_off):
        # start process
        if on_off and not self.depth_process_running:
            self.depth_wrapper.start_worker()
            self.depth_process_running = True
        else:
            self.depth_wrapper.kill_worker()
            self.depth_process_running = False

    def manage_feature_process(self, on_off):
        if on_off and not self.features_process_running:
            self.features_wrapper.start_worker()
            self.features_process_running = True
        else:
            self.features_wrapper.kill_worker()
            self.features_process_running = False

    def manage_refresh(self):
        self.plot_stack.widget(self.stack_dict[self.chan_select.currentText()][
            self.feature_select.currentText()][0]).clear_plot()
        self.stack_dict[self.chan_select.currentText()][
            self.feature_select.currentText()][1] = 0

    def process_settings(self, sub_sett, proc_sett, depth_sett, feat_sett):
        self.subject_settings = dict(sub_sett)
        self.procedure_settings = dict(proc_sett)
        self.depth_settings = dict(depth_sett)
        self.features_settings = dict(feat_sett)

        # validate that we have some data in the electrode_settings. If the NSP is not connected we will have
        # to load the channel names from the DB. Also we want to keep the FeaturesGUI unaware of the DB channels.
        if len(self.depth_settings['electrode_settings']) == 0:
            self.depth_settings['electrode_settings'] = {}
            for lbl in DBWrapper().list_channel_labels():
                self.depth_settings['electrode_settings'][lbl] = DEPTHSETTINGS
            CbSdkConnection().is_simulating = True

        # set new features
        self.feature_select.setCurrentIndex(0)  # Raw
        while self.feature_select.count() > 2:  # Raw and Mapping
            self.feature_select.removeItem(2)
        self.feature_select.addItems(self.features_settings['features'].keys())

        # set new channels
        self.chan_select.setCurrentIndex(0)  # None
        while self.chan_select.count() > 1:
            self.chan_select.removeItem(1)
        self.chan_select.addItems(
            self.depth_settings['electrode_settings'].keys())

        # clear and update stacked widget
        to_delete = [
            self.plot_stack.widget(x) for x in range(self.plot_stack.count())
        ]
        for wid in to_delete:
            self.plot_stack.removeWidget(wid)
            wid.deleteLater()
            wid = None
        self.stack_dict = {}
        self.create_plots()

        self.depth_wrapper.send_settings(self.depth_settings)
        self.features_wrapper.send_settings(self.features_settings)

        if not self.features_process_running:
            self.manage_feature_process(True)

        # self.clear()
        self.read_from_shared_memory()

    def create_plots(self, theme='dark', **kwargs):
        # Collect PlotWidget configuration
        self.plot_config['theme'] = theme
        self.plot_config['color_iterator'] = -1
        self.plot_config['x_range'] = XRANGE_FEATURES
        self.plot_config['y_range'] = uVRANGE
        self.plot_config['do_hp'] = True

        labels = []
        for ii in range(0, self.chan_select.count()):
            labels.append(self.chan_select.itemText(ii))
        # labels.extend(self.channel_labels)

        features = []
        for ii in range(0, self.feature_select.count()):
            features.append(self.feature_select.itemText(ii))

        stack_idx = 0
        for lbl_idx, lbl in enumerate(labels):
            self.stack_dict[lbl] = {}
            self.plot_config['color_iterator'] = lbl_idx - 1
            self.plot_config['title'] = lbl
            for feat in features:
                self.stack_dict[lbl][feat] = [stack_idx, 0]
                # TODO: not hard-coding??
                if feat == 'Raw':
                    self.plot_stack.addWidget(RawPlots(dict(self.plot_config)))
                elif feat == 'Mapping':
                    self.plot_stack.addWidget(
                        MappingPlots(dict(self.plot_config)))
                elif feat == 'STN':
                    self.plot_stack.addWidget(STNPlots(dict(self.plot_config)))
                elif feat == 'LFP':
                    self.plot_stack.addWidget(LFPPlots(dict(self.plot_config)))
                elif feat == 'Spikes':
                    self.plot_stack.addWidget(
                        SpikePlots(dict(self.plot_config)))
                else:
                    self.plot_stack.addWidget(
                        NullPlotWidget(dict(self.plot_config)))
                stack_idx += 1

        self.plot_stack.setCurrentIndex(0)

    def refresh_axes(self):
        pass

    def clear(self):
        # set the current datum of all stacks to 0
        for lbl in self.stack_dict:
            for feat in self.stack_dict[lbl]:
                self.stack_dict[lbl][feat][1] = 0
                self.plot_stack.widget(
                    self.stack_dict[lbl][feat][0]).clear_plot()

    def update(self):
        # Depth process
        output = self.depth_wrapper.worker_status()
        self.status_label.setPixmap(self.status_icons[output])

        if self.depth_wrapper.is_running():
            self.depth_process_btn.setStyleSheet("QPushButton { color: white; "
                                                 "background-color : green; "
                                                 "border-color : green; "
                                                 "border-width: 2px}")
        else:
            self.depth_process_running = False
            self.depth_process_btn.setStyleSheet("QPushButton { color: white; "
                                                 "background-color : red; "
                                                 "border-color : red; "
                                                 "border-width: 2px}")

        if self.features_wrapper.is_running():
            self.features_process_btn.setStyleSheet(
                "QPushButton { color: white; "
                "background-color : green; "
                "border-color : green; "
                "border-width: 2px}")
        else:
            self.features_process_running = False
            self.features_process_btn.setStyleSheet(
                "QPushButton { color: white; "
                "background-color : red; "
                "border-color : red; "
                "border-width: 2px}")

        if self.sweep_control.isChecked():
            self.read_from_shared_memory()

        # features plot
        curr_chan_lbl = self.chan_select.currentText()
        if curr_chan_lbl != 'None':
            curr_feat = self.feature_select.currentText()
            do_hp = self.do_hp.isChecked()

            if do_hp != self.plot_stack.currentWidget().plot_config['do_hp'] or \
                    self.y_range != self.plot_stack.currentWidget().plot_config['y_range']:
                self.plot_stack.currentWidget().clear_plot()
                self.stack_dict[curr_chan_lbl][curr_feat][1] = 0
                self.plot_stack.currentWidget().plot_config['do_hp'] = do_hp
                self.plot_stack.currentWidget(
                ).plot_config['y_range'] = self.y_range

            curr_datum = self.stack_dict[curr_chan_lbl][curr_feat][1]
            if curr_feat == 'Raw':
                all_data = DBWrapper().load_depth_data(chan_lbl=curr_chan_lbl,
                                                       gt=curr_datum,
                                                       do_hp=do_hp,
                                                       return_uV=True)
            elif curr_feat == 'Mapping':
                all_data = DBWrapper().load_mapping_response(
                    chan_lbl=curr_chan_lbl, gt=curr_datum)
            else:
                all_data = DBWrapper().load_features_data(
                    category=curr_feat, chan_lbl=curr_chan_lbl, gt=curr_datum)
            if all_data:
                self.plot_stack.currentWidget().update_plot(dict(all_data))
                self.stack_dict[curr_chan_lbl][curr_feat][1] = max(
                    all_data.keys())

    def kill_processes(self):
        self.manage_depth_process(False)
        self.manage_feature_process(False)

    def read_from_shared_memory(self):
        if self.monitored_channel_mem.isAttached():
            self.monitored_channel_mem.lock()
            settings = np.frombuffer(self.monitored_channel_mem.data(),
                                     dtype=np.float)[-3:]
            self.chan_select.setCurrentIndex(int(settings[0]))
            self.range_edit.setText(str(settings[1]))
            self.manage_range_edit()
            self.do_hp.setChecked(bool(settings[2]))
            self.monitored_channel_mem.unlock()
        else:
            self.monitored_channel_mem.attach()
            # self.sweep_control.setChecked(False)
            self.manage_sweep_control()
Пример #18
0
class RunConfigOptions(QWidget):
    """Run configuration options"""
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.dir = None
        self.runconf = RunConfiguration()
        firstrun_o = CONF.get('run', ALWAYS_OPEN_FIRST_RUN_OPTION, False)

        # --- Interpreter ---
        interpreter_group = QGroupBox(_("Console"))
        interpreter_layout = QVBoxLayout()
        interpreter_group.setLayout(interpreter_layout)

        self.current_radio = QRadioButton(CURRENT_INTERPRETER)
        interpreter_layout.addWidget(self.current_radio)

        self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER)
        interpreter_layout.addWidget(self.dedicated_radio)

        self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER)
        interpreter_layout.addWidget(self.systerm_radio)

        # --- General settings ----
        common_group = QGroupBox(_("General settings"))
        common_layout = QGridLayout()
        common_group.setLayout(common_layout)

        self.clear_var_cb = QCheckBox(CLEAR_ALL_VARIABLES)
        common_layout.addWidget(self.clear_var_cb, 0, 0)

        self.post_mortem_cb = QCheckBox(POST_MORTEM)
        common_layout.addWidget(self.post_mortem_cb, 1, 0)

        self.clo_cb = QCheckBox(_("Command line options:"))
        common_layout.addWidget(self.clo_cb, 2, 0)
        self.clo_edit = QLineEdit()
        self.clo_cb.toggled.connect(self.clo_edit.setEnabled)
        self.clo_edit.setEnabled(False)
        common_layout.addWidget(self.clo_edit, 2, 1)

        # --- Working directory ---
        wdir_group = QGroupBox(_("Working Directory settings"))
        wdir_layout = QVBoxLayout()
        wdir_group.setLayout(wdir_layout)

        self.file_dir_radio = QRadioButton(FILE_DIR)
        wdir_layout.addWidget(self.file_dir_radio)

        self.cwd_radio = QRadioButton(CW_DIR)
        wdir_layout.addWidget(self.cwd_radio)

        fixed_dir_layout = QHBoxLayout()
        self.fixed_dir_radio = QRadioButton(FIXED_DIR)
        fixed_dir_layout.addWidget(self.fixed_dir_radio)
        self.wd_edit = QLineEdit()
        self.fixed_dir_radio.toggled.connect(self.wd_edit.setEnabled)
        self.wd_edit.setEnabled(False)
        fixed_dir_layout.addWidget(self.wd_edit)
        browse_btn = QPushButton(ima.icon('DirOpenIcon'), '', self)
        browse_btn.setToolTip(_("Select directory"))
        browse_btn.clicked.connect(self.select_directory)
        fixed_dir_layout.addWidget(browse_btn)
        wdir_layout.addLayout(fixed_dir_layout)

        # --- System terminal ---
        external_group = QGroupBox(_("External system terminal"))
        external_group.setDisabled(True)

        self.systerm_radio.toggled.connect(external_group.setEnabled)

        external_layout = QGridLayout()
        external_group.setLayout(external_layout)
        self.interact_cb = QCheckBox(INTERACT)
        external_layout.addWidget(self.interact_cb, 1, 0, 1, -1)

        self.pclo_cb = QCheckBox(_("Command line options:"))
        external_layout.addWidget(self.pclo_cb, 3, 0)
        self.pclo_edit = QLineEdit()
        self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled)
        self.pclo_edit.setEnabled(False)
        self.pclo_edit.setToolTip(_("<b>-u</b> is added to the "
                                    "other options you set here"))
        external_layout.addWidget(self.pclo_edit, 3, 1)

        # Checkbox to preserve the old behavior, i.e. always open the dialog
        # on first run
        hline = QFrame()
        hline.setFrameShape(QFrame.HLine)
        hline.setFrameShadow(QFrame.Sunken)
        self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog"))
        self.firstrun_cb.clicked.connect(self.set_firstrun_o)
        self.firstrun_cb.setChecked(firstrun_o)

        layout = QVBoxLayout()
        layout.addWidget(interpreter_group)
        layout.addWidget(common_group)
        layout.addWidget(wdir_group)
        layout.addWidget(external_group)
        layout.addWidget(hline)
        layout.addWidget(self.firstrun_cb)
        self.setLayout(layout)

    def select_directory(self):
        """Select directory"""
        basedir = to_text_string(self.wd_edit.text())
        if not osp.isdir(basedir):
            basedir = getcwd_or_home()
        directory = getexistingdirectory(self, _("Select directory"), basedir)
        if directory:
            self.wd_edit.setText(directory)
            self.dir = directory

    def set(self, options):
        self.runconf.set(options)
        self.clo_cb.setChecked(self.runconf.args_enabled)
        self.clo_edit.setText(self.runconf.args)
        if self.runconf.current:
            self.current_radio.setChecked(True)
        elif self.runconf.systerm:
            self.systerm_radio.setChecked(True)
        else:
            self.dedicated_radio.setChecked(True)
        self.interact_cb.setChecked(self.runconf.interact)
        self.post_mortem_cb.setChecked(self.runconf.post_mortem)
        self.pclo_cb.setChecked(self.runconf.python_args_enabled)
        self.pclo_edit.setText(self.runconf.python_args)
        self.clear_var_cb.setChecked(self.runconf.clear_namespace)
        self.file_dir_radio.setChecked(self.runconf.file_dir)
        self.cwd_radio.setChecked(self.runconf.cw_dir)
        self.fixed_dir_radio.setChecked(self.runconf.fixed_dir)
        self.dir = self.runconf.dir
        self.wd_edit.setText(self.dir)

    def get(self):
        self.runconf.args_enabled = self.clo_cb.isChecked()
        self.runconf.args = to_text_string(self.clo_edit.text())
        self.runconf.current = self.current_radio.isChecked()
        self.runconf.systerm = self.systerm_radio.isChecked()
        self.runconf.interact = self.interact_cb.isChecked()
        self.runconf.post_mortem = self.post_mortem_cb.isChecked()
        self.runconf.python_args_enabled = self.pclo_cb.isChecked()
        self.runconf.python_args = to_text_string(self.pclo_edit.text())
        self.runconf.clear_namespace = self.clear_var_cb.isChecked()
        self.runconf.file_dir = self.file_dir_radio.isChecked()
        self.runconf.cw_dir = self.cwd_radio.isChecked()
        self.runconf.fixed_dir = self.fixed_dir_radio.isChecked()
        self.runconf.dir = self.wd_edit.text()
        return self.runconf.get()

    def is_valid(self):
        wdir = to_text_string(self.wd_edit.text())
        if not self.fixed_dir_radio.isChecked() or osp.isdir(wdir):
            return True
        else:
            QMessageBox.critical(self, _("Run configuration"),
                                 _("The following working directory is "
                                   "not valid:<br><b>%s</b>") % wdir)
            return False

    def set_firstrun_o(self):
        CONF.set('run', ALWAYS_OPEN_FIRST_RUN_OPTION,
                 self.firstrun_cb.isChecked())
Пример #19
0
    def __init__(self, layer):
        super().__init__()

        self.layer = layer
        layer.events.select.connect(self._on_select)
        layer.events.deselect.connect(self._on_deselect)
        layer.events.name.connect(self._on_layer_name_change)
        layer.events.blending.connect(self._on_blending_change)
        layer.events.opacity.connect(self._on_opacity_change)
        layer.events.visible.connect(self._on_visible_change)

        self.setObjectName('layer')

        self.grid_layout = QGridLayout()

        cb = QCheckBox(self)
        cb.setObjectName('visibility')
        cb.setToolTip('Layer visibility')
        cb.setChecked(self.layer.visible)
        cb.setProperty('mode', 'visibility')
        cb.stateChanged.connect(lambda state=cb: self.changeVisible(state))
        self.visibleCheckBox = cb
        self.grid_layout.addWidget(cb, 0, 0)

        textbox = QLineEdit(self)
        textbox.setText(layer.name)
        textbox.home(False)
        textbox.setToolTip('Layer name')
        textbox.setFixedWidth(122)
        textbox.setAcceptDrops(False)
        textbox.setEnabled(True)
        textbox.editingFinished.connect(self.changeText)
        self.nameTextBox = textbox
        self.grid_layout.addWidget(textbox, 0, 1)

        self.grid_layout.addWidget(QLabel('opacity:'), 1, 0)
        sld = QSlider(Qt.Horizontal, self)
        sld.setFocusPolicy(Qt.NoFocus)
        sld.setFixedWidth(110)
        sld.setMinimum(0)
        sld.setMaximum(100)
        sld.setSingleStep(1)
        sld.setValue(self.layer.opacity * 100)
        sld.valueChanged[int].connect(
            lambda value=sld: self.changeOpacity(value))
        self.opacitySilder = sld
        self.grid_layout.addWidget(sld, 1, 1)

        blend_comboBox = QComboBox()
        for blend in self.layer._blending_modes:
            blend_comboBox.addItem(blend)
        index = blend_comboBox.findText(self.layer.blending,
                                        Qt.MatchFixedString)
        blend_comboBox.setCurrentIndex(index)
        blend_comboBox.activated[str].connect(
            lambda text=blend_comboBox: self.changeBlending(text))
        self.blendComboBox = blend_comboBox
        self.grid_layout.addWidget(QLabel('blending:'), 2, 0)
        self.grid_layout.addWidget(blend_comboBox, 2, 1)

        self.setLayout(self.grid_layout)
        msg = 'Click to select\nDrag to rearrange\nDouble click to expand'
        self.setToolTip(msg)
        self.setExpanded(False)
        self.setFixedWidth(250)
        self.grid_layout.setColumnMinimumWidth(0, 100)
        self.grid_layout.setColumnMinimumWidth(1, 100)
        self.layer.selected = True