Пример #1
0
    def coord_line_edit(self):
        template = QRegExp(r"[-]?\d*\.?\d{0,3}")
        validator = QRegExpValidator(template)

        line = QLineEdit("0.0")
        line.setValidator(validator)
        line.setFixedWidth(60)
        # line.editingFinished.connect(self.update_dist_to_target)
        line.textChanged.connect(self.update_dist_to_target)

        return line
Пример #2
0
class ParameterEditBox(QWidget):

    def __init__(self, name: str, para: Parameter, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        if para.type not in ["LIST_OF_INT", "LIST_OF_FLOAT", int, float]:
            raise ValueError(f"{self.__class__.__name__} does not support parameter of type {para.type}")
        self._parameter = para
        self._name = name
        self.value_input = QLineEdit(self)
        if self._parameter.info is not None:
            self.value_input.setToolTip(self._parameter.info)
        self._set_text()
        self.value_input.editingFinished.connect(self._update_value)

        layout = QHBoxLayout(self)
        self.value_input.setMaximumWidth(70)
        self.value_input.setFixedWidth(70)
        layout.addWidget(QLabel(self._name))
        layout.addWidget(self.value_input)
        layout.setContentsMargins(0,0,0,0)
    
    def _set_text(self):
        if isinstance(self._parameter.type, str) and "LIST" in self._parameter.type:
            self.value_input.setText(", ".join(list(map(str, self._parameter.value))))
        else:
            self.value_input.setText(str(self._parameter.value))
    
    def _update_value(self):
        text = self.value_input.text()
        try:
            if self._parameter.type == "LIST_OF_INT":
                self._parameter.value = list(map(int, text.split(",")))
            elif self._parameter.type == "LIST_OF_FLOAT":
                self._parameter.value = list(map(float, text.split(",")))
            elif self._parameter.type is float:
                self._parameter.value = float(text)
            elif self._parameter.type is int:
                self._parameter.value = int(text)
        except Exception as e:
            self._set_text()
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Critical)
            msg.setWindowTitle('Setting Error')
            msg.setText('Illegal Parameter Setting')
            msg.setInformativeText(f"{text} is illegal for the parameter.<br>" + str(e))
            msg.setStandardButtons(QMessageBox.Ok)
            msg.show()
Пример #3
0
class ConfigCobrapyDialog(QDialog):
    """A dialog to set values in cobrapy-config.txt"""

    def __init__(self, appdata: CnaData):
        QDialog.__init__(self)
        self.setWindowTitle("Configure COBRApy")

        self.appdata = appdata
        self.layout = QVBoxLayout()

        # allow MILP solvers only?
        avail_solvers = list(set(solvers.keys()) - {'scipy'}) # SCIPY currently not even usable for FBA

        h2 = QHBoxLayout()
        label = QLabel("Default solver:\n(set when loading a model)")
        h2.addWidget(label)
        self.default_solver = QComboBox()
        self.default_solver.addItems(avail_solvers)
        self.default_solver.setCurrentIndex(avail_solvers.index(interface_to_str(cobra.Configuration().solver)))
        h2.addWidget(self.default_solver)
        self.layout.addItem(h2)

        h9 = QHBoxLayout()
        label = QLabel("Solver for current model:")
        h9.addWidget(label)
        self.current_solver = QComboBox()
        self.current_solver.addItems(avail_solvers)
        self.current_solver.setCurrentIndex(avail_solvers.index(interface_to_str(appdata.project.cobra_py_model.problem)))
        h9.addWidget(self.current_solver)
        self.layout.addItem(h9)

        h7 = QHBoxLayout()
        label = QLabel(
            "Number of processes for multiprocessing (e.g. FVA):")
        h7.addWidget(label)
        self.num_processes = QLineEdit()
        self.num_processes.setFixedWidth(100)
        self.num_processes.setText(str(cobra.Configuration().processes))
        validator = QIntValidator(1, cpu_count(), self)
        self.num_processes.setValidator(validator)
        h7.addWidget(self.num_processes)
        self.layout.addItem(h7)

        h8 = QHBoxLayout()
        label = QLabel(
            "Default tolerance:\n(set when loading a model)")
        h8.addWidget(label)
        self.default_tolerance = QLineEdit()
        self.default_tolerance.setFixedWidth(100)
        self.default_tolerance.setText(str(cobra.Configuration().tolerance))
        validator = QDoubleValidator(self)
        validator.setBottom(1e-9) # probably a reasonable consensus value
        self.default_tolerance.setValidator(validator)
        h8.addWidget(self.default_tolerance)
        self.layout.addItem(h8)

        h10 = QHBoxLayout()
        label = QLabel(
            "Tolerance for current model:")
        h10.addWidget(label)
        self.current_tolerance = QLineEdit()
        self.current_tolerance.setFixedWidth(100)
        self.current_tolerance.setText(str(self.appdata.project.cobra_py_model.tolerance))
        validator = QDoubleValidator(self)
        validator.setBottom(0)
        self.current_tolerance.setValidator(validator)
        h10.addWidget(self.current_tolerance)
        self.layout.addItem(h10)

        l2 = QHBoxLayout()
        self.button = QPushButton("Apply Changes")
        self.cancel = QPushButton("Close")
        l2.addWidget(self.button)
        l2.addWidget(self.cancel)
        self.layout.addItem(l2)
        self.setLayout(self.layout)

        self.cancel.clicked.connect(self.reject)
        self.button.clicked.connect(self.apply)


    def apply(self):
        cobra.Configuration().solver = self.default_solver.currentText()
        cobra.Configuration().processes = int(self.num_processes.text())
        try:
            val = float(self.default_tolerance.text())
            if 1e-9 <= val <= 0.1:
                cobra.Configuration().tolerance = val
            else:
                raise ValueError
        except:
            QMessageBox.critical(self, "Cannot set default tolerance", "Choose a value between 0.1 and 1e-9 as default tolerance.")
            return
        try:
            self.appdata.project.cobra_py_model.solver = self.current_solver.currentText()
            self.appdata.project.cobra_py_model.tolerance = float(self.current_tolerance.text())
        except Exception as e:
            QMessageBox.critical(self, "Cannot set current solver/tolerance", str(e))
            return

        parser = configparser.ConfigParser()
        parser.add_section('cobrapy-config')
        parser.set('cobrapy-config', 'solver', interface_to_str(cobra.Configuration().solver))
        parser.set('cobrapy-config', 'processes', str(cobra.Configuration().processes))
        parser.set('cobrapy-config', 'tolerance', str(cobra.Configuration().tolerance))
        
        try:
            fp = open(self.appdata.cobrapy_conf_path, "w")
        except FileNotFoundError:
            os.makedirs(appdirs.user_config_dir(
                "cnapy", roaming=True, appauthor=False))
            fp = open(self.appdata.cobrapy_conf_path, "w")

        parser.write(fp)
        fp.close()

        self.accept()
Пример #4
0
class LineListPane(QWidget):

    # this builds a single pane dedicated to a single list.

    def __init__(self, table_view, linelist, sort_proxy, caller, *args,
                 **kwargs):
        super().__init__(None, *args, **kwargs)

        self.table_view = table_view
        self.linelist = linelist
        self._sort_proxy = sort_proxy
        self._caller = caller

        self._build_GUI(linelist, table_view)

    def _build_GUI(self, linelist, table_view):
        panel_layout = QVBoxLayout()
        panel_layout.setSizeConstraint(QLayout.SetMaximumSize)
        self.setLayout(panel_layout)
        # header with line list metadata.
        info = QTextBrowser()
        info.setMaximumHeight(100)
        info.setAutoFillBackground(True)
        info.setStyleSheet("background-color: rgb(230,230,230);")
        for comment in linelist.meta['comments']:
            info.append(comment)

        # buttons and selectors dedicated to the specific list
        # displayed in this pane.
        button_pane = QWidget()
        hlayout = QGridLayout()

        # 'add set' button
        self.create_set_button = QPushButton(self)
        self.create_set_button.setObjectName("add_set_button")
        _translate = QCoreApplication.translate
        self.create_set_button.setText(_translate("MainWindow", "Create set"))
        self.create_set_button.setToolTip(
            "Create new line set from selected lines.")
        self.create_set_button.setSizePolicy(QSizePolicy.Minimum,
                                             QSizePolicy.Minimum)
        hlayout.addWidget(self.create_set_button, 1, 0)

        # the create_set button is enabled/disabled by logic elsewhere
        self.create_set_button.setEnabled(False)
        self.create_set_button.clicked.connect(lambda: self._createSet())

        # 'deselect all' button
        deselect_button = QPushButton(self)
        deselect_button.setObjectName("deselect_button")
        _translate = QCoreApplication.translate
        deselect_button.setText(_translate("MainWindow", "Deselect"))
        deselect_button.setToolTip("Un-select everything on this set.")
        deselect_button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        hlayout.addWidget(deselect_button, 1, 1)
        deselect_button.clicked.connect(lambda: table_view.clearSelection())

        # color picker
        self.combo_box_color = QComboBox(self)
        self.combo_box_color.setObjectName("color_selector")
        self.combo_box_color.setToolTip(
            "Color for selected lines in this set.")
        model = self.combo_box_color.model()
        for cname in ID_COLORS:
            item = QStandardItem(cname)
            item.setForeground(ID_COLORS[cname])
            item.setData(QColor(ID_COLORS[cname]), role=Qt.UserRole)
            model.appendRow(item)
        hlayout.addWidget(self.combo_box_color, 1, 2)
        hlayout.addWidget(QLabel("Color"), 0, 2)

        # plotting height
        self.height_textbox = QLineEdit(str(DEFAULT_HEIGHT))
        validator = QDoubleValidator()
        validator.setRange(0.05, 0.95, decimals=2)
        self.height_textbox.setValidator(validator)
        self.height_textbox.setFixedWidth(50)
        self.height_textbox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.height_textbox.setToolTip("Relative height to plot.")
        hlayout.addWidget(self.height_textbox, 1, 3)
        hlayout.addWidget(QLabel("Height"), 0, 3)

        # redshift
        self.redshift_textbox = QLineEdit(str(0.0))
        validator = QDoubleValidator()
        validator.setRange(-1.e5, 1.e10, decimals=4)
        self.redshift_textbox.setValidator(validator)
        self.redshift_textbox.setFixedWidth(70)
        self.redshift_textbox.setSizePolicy(QSizePolicy.Fixed,
                                            QSizePolicy.Fixed)
        self.redshift_textbox.setToolTip("Redshift lines by")
        hlayout.addWidget(self.redshift_textbox, 1, 4)
        hlayout.addWidget(QLabel("Redshift"), 0, 4)

        # redshift units
        self.combo_box_z_units = QComboBox(self)
        self.combo_box_z_units.setObjectName("redshift_units")
        self.combo_box_z_units.setToolTip("Redshift units.")
        model = self.combo_box_z_units.model()
        for uname in ['z', 'km/s']:
            item = QStandardItem(uname)
            model.appendRow(item)
        hlayout.addWidget(self.combo_box_z_units, 1, 5)

        # put it all together.
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        hlayout.addItem(spacerItem, 1, 6)
        button_pane.setLayout(hlayout)

        panel_layout.addWidget(info)
        panel_layout.addWidget(table_view)
        panel_layout.addWidget(button_pane)

    def __eq__(self, other):
        return self.__dict__ == other.__dict__

    def setLineSetsTabbedPane(self, pane):
        self._sets_tabbed_pane = pane

        # this must be set only once per tabbed pane, otherwise multiple
        # signal handlers can result in more than one tab being closed
        # when just one closing request is posted.
        self._sets_tabbed_pane.tabCloseRequested.connect(self.tab_close)

    def _createSet(self):
        # build list with only the selected rows. These must be model
        # rows, not view rows!
        selected_view_rows = self.table_view.selectionModel().selectedRows()
        selected_model_rows = [
            self._sort_proxy.mapToSource(x) for x in selected_view_rows
        ]

        if len(selected_model_rows) > 0:
            r = [x for x in selected_model_rows]
            local_list = self.linelist.extract_rows(r)

            # name is used to match lists with table views
            local_list.name = self.linelist.name

            table_model = LineListTableModel(local_list)
            pane, table_view = _createLineListPane(local_list, table_model,
                                                   self._caller)

            pane._sets_tabbed_pane = self._sets_tabbed_pane
            table_view.selectionModel().selectionChanged.connect(
                self._caller._countSelections)
            table_view.selectionModel().selectionChanged.connect(
                pane.handle_button_activation)

            self._sets_tabbed_pane.addTab(pane,
                                          str(self._sets_tabbed_pane.count()))

    def tab_close(self, index):
        self._sets_tabbed_pane.removeTab(index)

    def handle_button_activation(self):
        nselected = len(self.table_view.selectionModel().selectedRows())
        self.create_set_button.setEnabled(nselected > 0)
Пример #5
0
    def _build_waverange_dialog(self, wave_range, line_list):

        dialog = QDialog(parent=self.centralWidget)
        dialog.setWindowTitle("Wavelength range")
        dialog.setWindowModality(Qt.ApplicationModal)
        dialog.resize(370, 250)

        button_ok = QPushButton("OK")
        button_ok.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        button_cancel = QPushButton("Cancel")
        button_cancel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        button_ok.clicked.connect(dialog.accept)
        button_cancel.clicked.connect(dialog.reject)

        min_text = QLineEdit("%.2f" % wave_range[0].value)
        max_text = QLineEdit("%.2f" % wave_range[1].value)

        validator = QDoubleValidator()
        validator.setBottom(0.0)
        validator.setDecimals(2)
        min_text.setValidator(validator)
        max_text.setValidator(validator)

        min_text.setFixedWidth(150)
        max_text.setFixedWidth(150)
        min_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        max_text.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        min_text.setToolTip("Minimum wavelength to read from list.")
        max_text.setToolTip("Maximum wavelength to read from list.")

        nlines_label = self._compute_nlines_in_waverange(
            line_list, min_text, max_text)

        min_text.editingFinished.connect(
            lambda: self._compute_nlines_in_waverange(
                line_list, min_text, max_text, label=nlines_label))
        max_text.editingFinished.connect(
            lambda: self._compute_nlines_in_waverange(
                line_list, min_text, max_text, label=nlines_label))

        # set up layouts and widgets for the dialog.
        text_pane = QWidget()
        text_layout = QGridLayout()

        text_layout.addWidget(min_text, 1, 0)
        text_layout.addWidget(QLabel("Minimum wavelength"), 0, 0)
        text_layout.addWidget(max_text, 1, 1)
        text_layout.addWidget(QLabel("Maximum wavelength"), 0, 1)

        spacerItem = QSpacerItem(40, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        text_layout.addItem(spacerItem, 1, 2)
        text_pane.setLayout(text_layout)

        label_pane = QWidget()
        label_layout = QHBoxLayout()
        label_layout.addWidget(nlines_label)
        label_layout.addWidget(QLabel(" lines included in range."))
        label_layout.addStretch()
        label_pane.setLayout(label_layout)

        button_pane = QWidget()
        button_layout = QHBoxLayout()

        button_layout.addStretch()
        button_layout.addWidget(button_cancel)
        button_layout.addWidget(button_ok)
        button_pane.setLayout(button_layout)

        dialog_layout = QVBoxLayout()
        dialog_layout.setSizeConstraint(QLayout.SetMaximumSize)

        dialog_layout.addWidget(text_pane)
        dialog_layout.addWidget(label_pane)
        dialog_layout.addStretch()
        dialog_layout.addWidget(button_pane)

        dialog.setLayout(dialog_layout)

        button_ok.setDefault(True)
        button_cancel.setDefault(False)

        accepted = dialog.exec_() > 0

        amin = amax = None
        if accepted:
            return self._get_range_from_textfields(min_text, max_text)

        return (amin, amax)
Пример #6
0
def create_wwwc_tab(apply_adjust):
    Conf = namedtuple("Conf", "min max step default")
    ww_conf = Conf(0, 2000, 1, 350)
    wc_conf = Conf(-2000, 2000, 1, 50)

    tab = QWidget()
    tab.layout = QFormLayout()

    # BUG: 只有一个负号的时候会变成0,应该保留负号
    ww_edit = QLineEdit()
    ww_edit.setValidator(QtGui.QIntValidator(ww_conf.min, ww_conf.max))
    ww_edit.setFixedWidth(50)
    wc_edit = QLineEdit()
    wc_edit.setValidator(QtGui.QIntValidator(wc_conf.min, wc_conf.max))
    wc_edit.setFixedWidth(50)

    ww_slider = QSlider(Qt.Horizontal)  # 窗宽滑动条
    ww_slider.setMinimum(ww_conf.min)
    ww_slider.setMaximum(ww_conf.max)
    ww_slider.setSingleStep(ww_conf.step)
    ww_slider.setValue(ww_conf.default)

    wc_slider = QSlider(Qt.Horizontal)  # 窗位滑动条
    wc_slider.setMinimum(wc_conf.min)
    wc_slider.setMaximum(wc_conf.max)
    wc_slider.setSingleStep(wc_conf.step)
    wc_slider.setValue(wc_conf.default)

    ww_label = QLabel()
    ww_label.setText("窗宽:  ")
    wc_label = QLabel()
    wc_label.setText("窗位:  ")

    ww_combo = QHBoxLayout()
    ww_combo.addWidget(ww_edit)
    ww_combo.addWidget(ww_slider)
    wc_combo = QHBoxLayout()
    wc_combo.addWidget(wc_edit)
    wc_combo.addWidget(wc_slider)

    tab.layout.addRow(ww_label, ww_combo)
    tab.layout.addRow(wc_label, wc_combo)

    tab.setLayout(tab.layout)

    def slider_change(slider, editor):
        def func():
            editor.setText(str(slider.value()))
            apply_adjust(
                functools.partial(wwwc, ww_slider.value(), wc_slider.value()))

        return func

    def edit_changed(editor, slider):
        def func():
            value = editor.text()
            if value == "" or value == "-":
                value = 0
            value = int(value)
            slider.setValue(value)

        return func

    ww_slider.valueChanged.connect(slider_change(ww_slider, ww_edit))
    wc_slider.valueChanged.connect(slider_change(wc_slider, wc_edit))
    ww_edit.textChanged.connect(edit_changed(ww_edit, ww_slider))
    # wc_edit.textChanged.connect(wc_edit_change)

    return tab, "WW/WC"
Пример #7
0
class ContourOptionsDialog(QDialog):
    """
    Dialog box for selecting contour options
    """
    def __init__(self, contour_settings):
        super(ContourOptionsDialog,
              self).__init__(contour_settings.cubeviz_layout)
        self.setWindowFlags(self.windowFlags() | Qt.Tool)
        self.setWindowTitle("Contour Options")

        self.is_preview_active = False  # preview mode?

        self.contour_settings = contour_settings  # ref to caller ContourSettings
        self.image_viewer = self.contour_settings.image_viewer  # ref to image viewer
        self.options = self.contour_settings.options  # ref to ContourSettings options

        self._colormap_members = self.contour_settings.colormap_members  # Colormap options
        self._colormap_index = DEFAULT_GLUE_COLORMAP_INDEX  # Currently selected colormap
        if "cmap" in self.options:
            if self.options["cmap"] in self._colormap_members:
                self._colormap_index = self._colormap_members.index(
                    self.options["cmap"])

        # Is there a user spacing?
        if self.contour_settings.spacing is None:
            self.is_custom_spacing = False
        else:
            self.is_custom_spacing = True
        # Is there a user min?
        if self.contour_settings.vmin is None:
            self.is_vmin = False
        else:
            self.is_vmin = True
        # Is there a user max?
        if self.contour_settings.vmax is None:
            self.is_vmax = False
        else:
            self.is_vmax = True

        self.add_contour_label = self.contour_settings.add_contour_label  # bool

        self._init_ui()

    def _init_ui(self):

        # Line 1: Color map
        self.colormap_label = QLabel("Color Scheme: ")

        self.colormap_combo = QColormapCombo()
        self.colormap_combo.addItem("", userData=cm.viridis)
        self.colormap_combo._update_icons()
        self.colormap_combo.setCurrentIndex(self._colormap_index)
        self.colormap_combo.setMaximumWidth(150)
        self.colormap_combo.currentIndexChanged.connect(
            self._on_colormap_change)

        #   hbl is short for Horizontal Box Layout
        hbl1 = QHBoxLayout()
        hbl1.addWidget(self.colormap_label)
        hbl1.addWidget(self.colormap_combo)

        # Line 2: Display contour labels
        self.contour_label_checkBox = QCheckBox("Contour labels (font size):")
        if self.contour_settings.add_contour_label:
            self.contour_label_checkBox.setChecked(True)
        self.contour_label_checkBox.toggled.connect(self.toggle_labels)

        font_string = str(self.contour_settings.font_size)
        self.font_size_input = QLineEdit(font_string)
        self.font_size_input.setFixedWidth(150)
        self.font_size_input.setDisabled(
            not self.contour_settings.add_contour_label)

        hbl2 = QHBoxLayout()
        hbl2.addWidget(self.contour_label_checkBox)
        hbl2.addWidget(self.font_size_input)

        # Line 3: Contour Spacing
        self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):")
        if self.is_custom_spacing:
            self.custom_spacing_checkBox.setChecked(True)
        self.custom_spacing_checkBox.toggled.connect(self.custom_spacing)

        self.spacing_input = QLineEdit()
        self.spacing_input.setFixedWidth(150)
        self.spacing_input.setDisabled(not self.is_custom_spacing)
        spacing = ""
        if self.is_custom_spacing:
            spacing = str(self.contour_settings.spacing)
        elif self.contour_settings.data_spacing is not None:
            spacing = self.contour_settings.data_spacing
            spacing = "{0:1.4f}".format(spacing)
        self.spacing_default_text = spacing
        self.spacing_input.setText(spacing)

        hbl3 = QHBoxLayout()
        hbl3.addWidget(self.custom_spacing_checkBox)
        hbl3.addWidget(self.spacing_input)

        # Line 4: Vmax
        self.vmax_checkBox = QCheckBox("Set max:")

        self.vmax_input = QLineEdit()
        self.vmax_input.setFixedWidth(150)
        self.vmax_input.setDisabled(not self.is_vmax)

        vmax = ""
        if self.is_vmax:
            self.vmax_checkBox.setChecked(True)
            vmax = str(self.contour_settings.vmax)
        elif self.contour_settings.data_max is not None:
            vmax = self.contour_settings.data_max
            vmax = "{0:1.4f}".format(vmax)
        self.vmax_input.setText(vmax)
        self.vmax_default_text = vmax

        self.vmax_checkBox.toggled.connect(self.toggle_vmax)

        hbl4 = QHBoxLayout()
        hbl4.addWidget(self.vmax_checkBox)
        hbl4.addWidget(self.vmax_input)

        # Line 5: Vmin
        self.vmin_checkBox = QCheckBox("Set min:")

        self.vmin_input = QLineEdit()
        self.vmin_input.setFixedWidth(150)
        self.vmin_input.setDisabled(not self.is_vmin)

        vmin = ""
        if self.is_vmin:
            self.vmin_checkBox.setChecked(True)
            vmin = str(self.contour_settings.vmin)
        elif self.contour_settings.data_min is not None:
            vmin = self.contour_settings.data_min
            vmin = "{0:1.4f}".format(vmin)
        self.vmin_input.setText(vmin)
        self.vmin_default_text = vmin

        self.vmin_checkBox.toggled.connect(self.toggle_vmin)

        hbl5 = QHBoxLayout()
        hbl5.addWidget(self.vmin_checkBox)
        hbl5.addWidget(self.vmin_input)

        # Line f:
        self.previewButton = QPushButton("Preview")
        self.previewButton.clicked.connect(self.preview)

        self.defaultButton = QPushButton("Reset")
        self.defaultButton.clicked.connect(self.default)

        self.okButton = QPushButton("OK")
        self.okButton.clicked.connect(self.finish)
        self.okButton.setDefault(True)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(self.cancel)

        hblf = QHBoxLayout()
        hblf.addStretch(1)
        hblf.addWidget(self.previewButton)
        hblf.addWidget(self.defaultButton)
        hblf.addWidget(self.cancelButton)
        hblf.addWidget(self.okButton)

        vbl = QVBoxLayout()
        vbl.addLayout(hbl1)
        vbl.addLayout(hbl2)
        vbl.addLayout(hbl3)
        vbl.addLayout(hbl4)
        vbl.addLayout(hbl5)
        vbl.addLayout(hblf)

        self.setLayout(vbl)

        self.show()

    def update_data_vals(self, vmin="", vmax="", spacing="1"):

        self.vmin_default_text = vmin

        if not self.is_vmin:
            self.vmin_input.setText(vmin)

        self.vmax_default_text = vmax
        if not self.is_vmax:
            self.vmax_input.setText(vmax)

        self.spacing_default_text = spacing
        if not self.is_custom_spacing:
            self.spacing_input.setText(spacing)

    def _on_colormap_change(self, index):
        """Combo index changed handler"""
        self._colormap_index = index

    def custom_spacing(self):
        """Checkbox toggled handler"""
        if self.is_custom_spacing:
            self.is_custom_spacing = False
            self.spacing_input.setDisabled(True)
            self.spacing_input.setText(self.spacing_default_text)
            self.spacing_input.setStyleSheet("")
        else:
            self.is_custom_spacing = True
            self.spacing_input.setDisabled(False)

    def toggle_labels(self):
        """Checkbox toggled handler"""
        if self.add_contour_label:
            self.add_contour_label = False
            self.font_size_input.setDisabled(True)
            font_string = str(self.contour_settings.font_size)
            self.font_size_input.setText(font_string)
            self.font_size_input.setStyleSheet("")
        else:
            self.add_contour_label = True
            self.font_size_input.setDisabled(False)

    def toggle_vmax(self):
        """Checkbox toggled handler"""
        if self.is_vmax:
            self.is_vmax = False
            self.vmax_input.setDisabled(True)
            self.vmax_input.setText(self.vmax_default_text)
            self.vmax_input.setStyleSheet("")
        else:
            self.is_vmax = True
            self.vmax_input.setDisabled(False)

    def toggle_vmin(self):
        """Checkbox toggled handler"""
        if self.is_vmin:
            self.is_vmin = False
            self.vmin_input.setDisabled(True)
            self.vmin_input.setText(self.vmin_default_text)
            self.vmin_input.setStyleSheet("")
        else:
            self.is_vmin = True
            self.vmin_input.setDisabled(False)

    def input_validation(self):
        red = "background-color: rgba(255, 0, 0, 128);"

        def float_check(min_val=None):
            if user_input.text() == "":
                user_input.setStyleSheet(red)
                return False
            else:
                try:
                    value = float(user_input.text())
                    if min_val is not None:
                        if value <= min_val:
                            user_input.setStyleSheet(red)
                            return False
                    else:
                        user_input.setStyleSheet("")
                except ValueError:
                    user_input.setStyleSheet(red)
                    return False
            return True

        def int_check(min_val=None):
            if user_input.text() == "":
                user_input.setStyleSheet(red)
                return False
            else:
                try:
                    value = int(user_input.text())
                    if min_val is not None:
                        if value <= min_val:
                            user_input.setStyleSheet(red)
                            return False
                    else:
                        user_input.setStyleSheet("")
                except ValueError:
                    user_input.setStyleSheet(red)
                    return False
            return True

        success = True

        # Check 1: spacing_input
        if self.is_custom_spacing:
            user_input = self.spacing_input
            float_check(0)
            success = success and float_check()

        # Check 2: font_size_input
        if self.add_contour_label:
            user_input = self.font_size_input
            int_check(0)
            success = success and int_check()

        # Check 3: vmax
        if self.is_vmax:
            user_input = self.vmax_input
            float_check()
            success = success and float_check()

        # Check 4: vmax
        if self.is_vmin:
            user_input = self.vmin_input
            float_check()
            success = success and float_check()

        # Check 5: vmax and vmin
        if self.is_vmax and self.is_vmin and success:
            vmax = float(self.vmax_input.text())
            vmin = float(self.vmin_input.text())
            if vmax <= vmin:
                self.vmax_input.setStyleSheet(red)
                self.vmin_input.setStyleSheet(red)
                success = False

        return success

    def finish(self):
        """
        Ok button pressed. Finalize
        options and send to image viewer
         """
        success = self.input_validation()

        if not success:
            return

        # Change Color Map
        self._colormap_index = self.colormap_combo.currentIndex()
        colormap = self._colormap_members[self._colormap_index]
        self.contour_settings.options["cmap"] = colormap

        # labels
        self.contour_settings.add_contour_label = self.add_contour_label

        # font size
        if self.add_contour_label:
            font_size = int(self.font_size_input.text())
            self.contour_settings.font_size = font_size
        else:
            self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE

        # Spacing
        if self.is_custom_spacing:
            self.contour_settings.spacing = float(self.spacing_input.text())
        else:
            self.contour_settings.spacing = None

        # vmax
        if self.is_vmax:
            vmax = float(self.vmax_input.text())
            self.contour_settings.vmax = vmax
            self.contour_settings.options["vmax"] = vmax
        else:
            self.contour_settings.vmax = None
            self.contour_settings.options["vmax"] = None

        # vmin
        if self.is_vmin:
            vmin = float(self.vmin_input.text())
            self.contour_settings.vmin = vmin
            self.contour_settings.options["vmin"] = vmin
        else:
            self.contour_settings.vmin = None
            self.contour_settings.options["vmin"] = None

        # Redraw contour
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()

        self.close()

    def preview(self):
        """
        Prepare preview contour settings
        and send to image viewer
        """
        success = self.input_validation()

        if not success:
            return

        image_viewer = self.contour_settings.image_viewer
        preview_settings = ContourSettings(image_viewer)
        preview_settings.dialog = self
        preview_settings.options = self.contour_settings.options.copy()
        preview_settings.spacing = self.contour_settings.spacing

        # Change Color Map
        self._colormap_index = self.colormap_combo.currentIndex()
        colormap = self._colormap_members[self._colormap_index]
        preview_settings.options["cmap"] = colormap

        # labels
        add_contour_label = self.contour_label_checkBox.isChecked()
        preview_settings.add_contour_label = add_contour_label

        # font size
        if add_contour_label:
            font_size = int(self.font_size_input.text())
            preview_settings.font_size = font_size

        # Spacing
        if self.is_custom_spacing:
            preview_settings.spacing = float(self.spacing_input.text())
        else:
            preview_settings.spacing = None

        # vmax
        if self.is_vmax:
            vmax = float(self.vmax_input.text())
            preview_settings.vmax = vmax
            preview_settings.options["vmax"] = vmax
        else:
            preview_settings.vmax = None
            preview_settings.options["vmax"] = None

        # vmin
        if self.is_vmin:
            vmin = float(self.vmin_input.text())
            preview_settings.vmin = vmin
            preview_settings.options["vmin"] = vmin
        else:
            preview_settings.vmin = None
            preview_settings.options["vmin"] = None

        # Redraw contour
        if image_viewer.is_contour_active:
            self.is_preview_active = True
            image_viewer.set_contour_preview(preview_settings)
        else:
            message = "Contour map is currently switched off. " \
                      "Please turn on the contour map by selecting " \
                      "a component from the contour map drop-down menu."
            info = QMessageBox.critical(self, "Error", message)

    def default(self):
        """
        Set options back to default
        and send to image viewer
        """
        self.contour_settings.options = self.contour_settings.default_options()
        self.contour_settings.spacing = None
        self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE
        self.contour_settings.vmax = None
        self.contour_settings.vmin = None
        self.contour_settings.add_contour_label = False
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()
        self.contour_settings.options_dialog()

    def cancel(self):
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()
        self.close()

    def closeEvent(self, event):
        """closeEvent handler"""
        if self.is_preview_active:
            self.contour_settings.image_viewer.end_contour_preview()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.cancel()
Пример #8
0
    def populate_unit_layout(self, unit_layout, gui=None):
        """
        Populate horizontal layout (living on conversion gui)
        with appropriate widgets. Set wave attribute to current
        wavelength.

        Layouts:
            10^[QLineEdit] X [QComboBox] / [QComboBox]
                        or
            10^[QLineEdit] X [QComboBox]

        :param unit_layout: (QHBoxLayout) Horizontal layout
        :param gui: conversion gui
        :return: updated unit_layout
        """

        power = self._get_current_power()

        unit_layout.addWidget(QLabel("10^"))
        power_input = QLineEdit(str(power))
        power_input.setFixedWidth(30)
        self.power_input = power_input
        power_input.textChanged.connect(self._update_message)
        unit_layout.addWidget(power_input)

        unit_layout.addWidget(QLabel("   X   "))

        flux_unit_str = self.spectral_flux_density.to_string()
        flux_options = FLUX_UNIT_REGISTRY.get_unit_list(current_unit=flux_unit_str)
        if flux_unit_str in flux_options:
            index = flux_options.index(flux_unit_str)
        else:
            index = find_unit_index(flux_options, flux_unit_str)
            if index is None:
                flux_options.append(flux_unit_str)
                index = flux_options.index(flux_unit_str)
        flux_combo = QComboBox()
        flux_combo.addItems(flux_options)
        flux_combo.setCurrentIndex(index)
        flux_combo.currentIndexChanged.connect(self._on_flux_combo_change)
        flux_combo.currentIndexChanged.connect(self._update_message)
        self.flux_combo = flux_combo
        unit_layout.addWidget(flux_combo)

        if self.area is not None:
            division = QLabel("   /   ")
            unit_layout.addWidget(division)

            area_str = self.area.to_string()
            if self.controller is None:
                no_pixel_area = True
            else:
                no_pixel_area = self.controller.pixel_area is None

            if self.area.decompose() == u.pix.decompose() and no_pixel_area:
                area_options = AREA_UNIT_REGISTRY.get_unit_list(pixel_only=True)
            elif 'solid angle' in self.area.physical_type and no_pixel_area:
                area_options = AREA_UNIT_REGISTRY.get_unit_list(solid_angle_only=True)
            else:
                area_options = AREA_UNIT_REGISTRY.get_unit_list()

            if area_str in area_options:
                index = area_options.index(area_str)
            else:
                index = find_unit_index(area_options, area_str)
                if index is None:
                    area_options.append(area_str)
                    index = area_options.index(area_str)
            area_combo = QComboBox()
            area_combo.width()
            area_combo.addItems(area_options)
            area_combo.setCurrentIndex(index)
            area_combo.currentIndexChanged.connect(self._update_message)
            self.area_combo = area_combo
            unit_layout.addWidget(area_combo)
        unit_layout.addStretch(1)
        unit_layout.setSpacing(0)

        if self.message_box is not None:
            self._update_message()

        if gui is not None:
            cubeviz_layout = gui.cubeviz_layout
            if cubeviz_layout is not None:
                self.wave = cubeviz_layout.get_wavelength()
        return unit_layout
Пример #9
0
    def populate_unit_layout(self, unit_layout, gui=None):
        """
        Populate horizontal layout (living on conversion gui)
        with appropriate widgets. Set wave attribute to current
        wavelength.

        Layouts:
            10^[QLineEdit] X [QComboBox] / [QComboBox]
                        or
            10^[QLineEdit] X [QComboBox]

        :param unit_layout: (QHBoxLayout) Horizontal layout
        :param gui: conversion gui
        :return: updated unit_layout
        """

        power = self._get_current_power()

        unit_layout.addWidget(QLabel("10^"))
        power_input = QLineEdit(str(power))
        power_input.setFixedWidth(30)
        self.power_input = power_input
        power_input.textChanged.connect(self._update_message)
        unit_layout.addWidget(power_input)

        unit_layout.addWidget(QLabel("   X   "))

        flux_unit_str = self.spectral_flux_density.to_string()
        flux_options = FLUX_UNIT_REGISTRY.compose_unit_list(current_unit=flux_unit_str)
        if flux_unit_str in flux_options:
            index = flux_options.index(flux_unit_str)
        else:
            index = find_unit_index(flux_options, flux_unit_str)
            if index is None:
                flux_options.append(flux_unit_str)
                index = flux_options.index(flux_unit_str)
        flux_combo = QComboBox()
        flux_combo.addItems(flux_options)
        flux_combo.setCurrentIndex(index)
        flux_combo.currentIndexChanged.connect(self._on_flux_combo_change)
        flux_combo.currentIndexChanged.connect(self._update_message)
        self.flux_combo = flux_combo
        unit_layout.addWidget(flux_combo)

        if self.area is not None:
            division = QLabel("   /   ")
            unit_layout.addWidget(division)

            area_str = self.area.to_string()

            no_pixel_area = self.pixel_area is None

            if self.area.decompose() == u.pix.decompose() and no_pixel_area:
                area_options = AREA_UNIT_REGISTRY.compose_unit_list(pixel_only=True)
            elif 'solid angle' in self.area.physical_type and no_pixel_area:
                area_options = AREA_UNIT_REGISTRY.compose_unit_list(solid_angle_only=True)
            else:
                area_options = AREA_UNIT_REGISTRY.compose_unit_list()

            if area_str in area_options:
                index = area_options.index(area_str)
            else:
                index = find_unit_index(area_options, area_str)
                if index is None:
                    area_options.append(area_str)
                    index = area_options.index(area_str)
            area_combo = QComboBox()
            area_combo.width()
            area_combo.addItems(area_options)
            area_combo.setCurrentIndex(index)
            area_combo.currentIndexChanged.connect(self._update_message)
            self.area_combo = area_combo
            unit_layout.addWidget(area_combo)
        unit_layout.addStretch(1)
        unit_layout.setSpacing(0)

        if self.message_box is not None:
            self._update_message()

        return unit_layout
Пример #10
0
class MiniControl(QWidget):
    def __init__(self, parent, selectedTab=0):
        super().__init__()
        self.textButtonStyleEnabled = "QPushButton {background-color: #151B54; color: white;} QPushButton:hover {background-color: #333972;} QPushButton:pressed { background-color: #515790;}"
        self.textButtonStyleDisabled = "QPushButton {background-color: #323232; color: #323232;} QPushButton:hover {background-color: #323232;} QPushButton:pressed { background-color: #323232;}"
        self.setWindowTitle(config.thisTranslation["remote_control"])
        self.parent = parent
        self.devotionals = sorted(
            glob.glob(config.marvelData + "/devotionals/*.devotional"))
        # specify window size
        if config.qtMaterial and config.qtMaterialTheme:
            self.resizeWindow(1 / 2, 1 / 3)
        else:
            self.resizeWindow(2 / 5, 1 / 3)
        self.resizeEvent = (lambda old_method:
                            (lambda event:
                             (self.onResized(event), old_method(event))[-1]))(
                                 self.resizeEvent)
        self.bibleButtons = {}
        self.commentaryButtons = {}
        self.bookIntroButtons = {}
        # setup interface
        self.bible_layout = None
        self.setupUI()
        self.tabs.setCurrentIndex(selectedTab)

    # window appearance
    def resizeWindow(self, widthFactor, heightFactor):
        availableGeometry = QGuiApplication.instance().desktop(
        ).availableGeometry()
        self.setMinimumWidth(500)
        self.resize(availableGeometry.width() * widthFactor,
                    availableGeometry.height() * heightFactor)

    def onResized(self, event):
        pass

    def closeEvent(self, event):
        config.miniControl = False

    # manage key capture
    def event(self, event):
        if event.type() == QEvent.KeyRelease:
            if event.modifiers() == Qt.ControlModifier:
                if event.key() == Qt.Key_B:
                    self.tabs.setCurrentIndex(0)
                elif event.key() == Qt.Key_T:
                    self.tabs.setCurrentIndex(1)
                elif event.key() == Qt.Key_C:
                    self.tabs.setCurrentIndex(2)
                elif event.key() == Qt.Key_L:
                    self.tabs.setCurrentIndex(3)
                elif event.key() == Qt.Key_D:
                    self.tabs.setCurrentIndex(4)
                elif event.key() == Qt.Key_O:
                    self.tabs.setCurrentIndex(5)
            elif event.key() == Qt.Key_Escape:
                self.close()
        return QWidget.event(self, event)

    # setup ui
    def setupUI(self):
        textButtonStyle = "QPushButton {background-color: #151B54; color: white;} QPushButton:hover {background-color: #333972;} QPushButton:pressed { background-color: #515790;}"

        mainLayout = QGridLayout()

        commandBox = QVBoxLayout()
        commandBox.setSpacing(3)

        commandBar = QWidget()
        commandLayout1 = QBoxLayout(QBoxLayout.LeftToRight)
        commandLayout1.setSpacing(5)
        self.searchLineEdit = QLineEdit()
        self.searchLineEdit.setClearButtonEnabled(True)
        self.searchLineEdit.setToolTip(
            config.thisTranslation["enter_command_here"])
        self.searchLineEdit.returnPressed.connect(self.searchLineEntered)
        self.searchLineEdit.setFixedWidth(450)
        commandLayout1.addWidget(self.searchLineEdit)

        enterButton = QPushButton(config.thisTranslation["enter"])
        enterButton.setFixedWidth(100)
        enterButton.clicked.connect(self.searchLineEntered)
        commandLayout1.addWidget(enterButton)

        # commandLayout1.addStretch()
        commandBox.addLayout(commandLayout1)

        if config.showMiniKeyboardInMiniControl:
            commandLayout2 = QBoxLayout(QBoxLayout.LeftToRight)
            commandLayout2.setSpacing(5)

            keys = [
                '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ':', '-',
                ',', '.', ' ', '<', 'X'
            ]
            for key in keys:
                button = QPushButton(key)
                button.setMaximumWidth(30)
                button.clicked.connect(partial(self.keyEntryAction, key))
                commandLayout2.addWidget(button)

            commandLayout2.addStretch()
            commandBox.addLayout(commandLayout2)

        if config.showMiniKeyboardInMiniControl and config.isTtsInstalled:
            ttsLayout = QBoxLayout(QBoxLayout.LeftToRight)
            ttsLayout.setSpacing(5)

            self.languageCombo = QComboBox()
            ttsLayout.addWidget(self.languageCombo)
            if config.espeak:
                languages = TtsLanguages().isoLang2epeakLang
            else:
                languages = TtsLanguages().isoLang2qlocaleLang
            self.languageCodes = list(languages.keys())
            for code in self.languageCodes:
                self.languageCombo.addItem(languages[code][1])
            # Check if selected tts engine has the language user specify.
            if not (config.ttsDefaultLangauge in self.languageCodes):
                config.ttsDefaultLangauge = "en"
            # Set initial item
            initialIndex = self.languageCodes.index(config.ttsDefaultLangauge)
            self.languageCombo.setCurrentIndex(initialIndex)

            # setting tts default language here is confusing; better place in menu
            #setDefaultButton = QPushButton(config.thisTranslation["setDefault"])
            #setDefaultButton.setFixedWidth(130)
            #setDefaultButton.clicked.connect(self.setTtsDefaultLanguage)
            #ttsLayout.addWidget(setDefaultButton)

            speakButton = QPushButton(config.thisTranslation["speak"])
            speakButton.setFixedWidth(100)
            speakButton.clicked.connect(self.speakCommandFieldText)
            ttsLayout.addWidget(speakButton)

            stopButton = QPushButton(config.thisTranslation["stop"])
            stopButton.setFixedWidth(100)
            stopButton.clicked.connect(
                self.parent.textCommandParser.stopTtsAudio)
            ttsLayout.addWidget(stopButton)

            ttsLayout.addStretch()

            commandBox.addLayout(ttsLayout)

        commandBar.setLayout(commandBox)
        mainLayout.addWidget(commandBar, 0, 0, Qt.AlignCenter)

        self.tabs = QTabWidget()
        self.tabs.currentChanged.connect(self.tabChanged)
        mainLayout.addWidget(self.tabs, 1, 0, Qt.AlignCenter)

        parser = BibleVerseParser(config.parserStandarisation)
        self.bookMap = parser.standardAbbreviation
        bookNums = list(self.bookMap.keys())
        self.bookNumGps = [
            bookNums[0:10],
            bookNums[10:20],
            bookNums[20:30],
            bookNums[30:39],
            bookNums[39:49],
            bookNums[49:59],
            bookNums[59:69],
            bookNums[69:79],
            bookNums[79:86],
            bookNums[86:94],
            bookNums[94:99],
            bookNums[99:104],
            bookNums[104:110],
            bookNums[110:119],
            bookNums[119:124],
            bookNums[124:129],
            bookNums[129:139],
            bookNums[139:149],
            bookNums[149:159],
            bookNums[159:169],
            bookNums[169:174],
            bookNums[174:179],
            bookNums[179:189],
            bookNums[189:199],
        ]

        # Bible books tab

        self.bible = QWidget()
        self.populateBooksButtons(config.mainText)
        self.tabs.addTab(self.bible, config.thisTranslation["bible"])

        # Bible translations tab

        self.biblesBox = QWidget()
        self.biblesBoxContainer = QVBoxLayout()
        collectionsLayout = self.newRowLayout()
        if len(config.bibleCollections) > 0:
            button = QPushButton("All")
            button.setStyleSheet(textButtonStyle)
            button.clicked.connect(partial(self.selectCollection, "All"))
            collectionsLayout.addWidget(button)
            count = 0
            for collection in sorted(config.bibleCollections.keys()):
                button = QPushButton(collection)
                button.setStyleSheet(textButtonStyle)
                button.clicked.connect(
                    partial(self.selectCollection, collection))
                collectionsLayout.addWidget(button)
                count += 1
                if count > 5:
                    count = 0
                    self.biblesBoxContainer.addLayout(collectionsLayout)
                    collectionsLayout = self.newRowLayout()

        self.biblesBoxContainer.addLayout(collectionsLayout)
        self.bibleBoxWidget = QWidget()
        self.bibleBoxLayout = QVBoxLayout()
        self.bibleBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.bibleBoxLayout.setSpacing(1)
        row_layout = self.newRowLayout()
        row_layout.setContentsMargins(0, 0, 0, 0)
        row_layout.setSpacing(1)
        biblesSqlite = BiblesSqlite()
        bibles = biblesSqlite.getBibleList()
        count = 0
        for bible in bibles:
            button = QPushButton(bible)
            if bible in config.bibleDescription:
                button.setToolTip("{0}".format(config.bibleDescription[bible]))
            button.clicked.connect(partial(self.bibleAction, bible))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                self.bibleBoxLayout.addLayout(row_layout)
                row_layout = self.newRowLayout()
            self.bibleButtons[bible] = button
        self.bibleBoxLayout.addLayout(row_layout)
        self.bibleBoxLayout.addStretch()
        self.biblesBoxContainer.addLayout(self.bibleBoxLayout)
        self.biblesBoxContainer.addStretch()
        self.biblesBox.setLayout(self.biblesBoxContainer)
        self.tabs.addTab(self.biblesBox,
                         config.thisTranslation["translations"])

        # Commentaries tab

        commentaries_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setContentsMargins(0, 0, 0, 0)
        box_layout.setSpacing(1)
        row_layout = self.newRowLayout()
        button = QPushButton(config.thisTranslation["activeOnly"])
        button.setStyleSheet(textButtonStyle)
        button.clicked.connect(self.activeCommentaries)
        row_layout.addWidget(button)
        box_layout.addLayout(row_layout)
        row_layout = self.newRowLayout()
        commentaries = Commentary().getCommentaryList()
        count = 0
        for commentary in commentaries:
            button = QPushButton(commentary)
            button.setToolTip(Commentary.fileLookup[commentary])
            button.clicked.connect(partial(self.commentaryAction, commentary))
            self.commentaryButtons[commentary] = button
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        commentaries_box.setLayout(box_layout)

        self.tabs.addTab(commentaries_box,
                         config.thisTranslation["commentaries"])

        # Lexicons tab

        lexicons_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setContentsMargins(0, 0, 0, 0)
        box_layout.setSpacing(1)
        row_layout = self.newRowLayout()
        lexicons = LexiconData().lexiconList
        count = 0
        for lexicon in lexicons:
            button = QPushButton(lexicon)
            if lexicon in config.lexiconDescription:
                button.setToolTip("{0}".format(
                    config.lexiconDescription[lexicon]))
            button.clicked.connect(partial(self.lexiconAction, lexicon))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        lexicons_box.setLayout(box_layout)

        self.tabs.addTab(lexicons_box, config.thisTranslation["lexicons"])

        # Dictionaries tab

        dictionaries_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setContentsMargins(0, 0, 0, 0)
        box_layout.setSpacing(1)
        row_layout = self.newRowLayout()
        dictionaries = IndexesSqlite().dictionaryList
        count = 0
        for dictionary in dictionaries:
            button = QPushButton(dictionary[0])
            button.setToolTip(dictionary[1])
            button.clicked.connect(
                partial(self.dictionaryAction, dictionary[0]))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        dictionaries_box.setLayout(box_layout)

        self.tabs.addTab(dictionaries_box,
                         config.thisTranslation["dictionaries"])

        # Book intros tab

        bookIntros_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setContentsMargins(0, 0, 0, 0)
        box_layout.setSpacing(1)
        row_layout = self.newRowLayout()
        button = QPushButton(config.thisTranslation["activeOnly"])
        button.setStyleSheet(textButtonStyle)
        button.clicked.connect(self.activeBookIntros)
        row_layout.addWidget(button)
        box_layout.addLayout(row_layout)
        row_layout = self.newRowLayout()
        commentaries = Commentary().getCommentaryList()
        count = 0
        for commentary in commentaries:
            button = QPushButton(commentary)
            button.setToolTip(Commentary.fileLookup[commentary])
            button.clicked.connect(partial(self.bookIntroAction, commentary))
            self.bookIntroButtons[commentary] = button
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        bookIntros_box.setLayout(box_layout)

        self.tabs.addTab(bookIntros_box, config.thisTranslation["bookIntro"])

        # Devotionals tab

        if len(self.devotionals) > 0:
            devotionals_box = QWidget()
            box_layout = QVBoxLayout()
            box_layout.setContentsMargins(0, 0, 0, 0)
            box_layout.setSpacing(1)
            row_layout = self.newRowLayout()
            count = 0
            for file in self.devotionals:
                name = Path(file).stem
                button = QPushButton(name)
                # button.setToolTip(dictionary[1])
                button.clicked.connect(partial(self.devotionalAction, name))
                row_layout.addWidget(button)
                count += 1
                if count > 2:
                    count = 0
                    box_layout.addLayout(row_layout)
                    row_layout.addStretch()
                    row_layout = self.newRowLayout()
            for i in range(count, 3):
                button = QPushButton("")
                row_layout.addWidget(button)
            box_layout.addLayout(row_layout)
            box_layout.addStretch()
            devotionals_box.setLayout(box_layout)

            self.tabs.addTab(devotionals_box,
                             config.thisTranslation["devotionals"])

        self.tabs.setCurrentIndex(config.miniControlInitialTab)
        self.setLayout(mainLayout)

    def populateBooksButtons(self, bibleName):
        books = Bible(bibleName).getBookList()
        if self.bible_layout is not None:
            while self.bible_layout.count():
                child = self.bible_layout.takeAt(0)
                if child.widget():
                    child.widget().deleteLater()
        else:
            self.bible_layout = QVBoxLayout()
        self.bible_layout.setContentsMargins(0, 0, 0, 0)
        self.bible_layout.setSpacing(1)
        for bookNumGp in self.bookNumGps:
            gp = QWidget()
            layout = self.newRowLayout()
            for bookNum in bookNumGp:
                if int(bookNum) in books:
                    text = self.bookMap[bookNum]
                    button = QPushButton(text)
                    if config.developer:
                        button.setToolTip("{0} - {1}".format(
                            BibleBooks.eng[bookNum][1], bookNum))
                    else:
                        button.setToolTip("{0}".format(
                            BibleBooks.eng[bookNum][1]))
                    button.clicked.connect(
                        partial(self.bibleBookAction, bookNum))
                    layout.addWidget(button)
            gp.setLayout(layout)
            self.bible_layout.addWidget(gp)
        # for bookNumGp in self.bookNumGps[5:]:
        #     gp = QWidget()
        #     layout = self.newRowLayout()
        #     for bookNum in bookNumGp:
        #         text = self.bookMap[bookNum]
        #         button = QPushButton(text)
        #         button.clicked.connect(partial(self.bibleBookAction, bookNum))
        #         layout.addWidget(button)
        #     gp.setLayout(layout)
        #     bible_layout.addWidget(gp)
        self.bible_layout.addStretch()
        self.bible.setLayout(self.bible_layout)

    def newRowLayout(self):
        row_layout = QHBoxLayout()
        row_layout.setContentsMargins(0, 0, 0, 0)
        row_layout.setSpacing(1)
        return row_layout

    def tabChanged(self, index):
        prefix = ""
        if index == 0:
            prefix = "BIBLE:::{0}:::".format(config.mainText)
        elif index == 1:
            prefix = "TEXT:::"
        elif index == 2:
            prefix = "COMMENTARY:::{0}:::".format(config.commentaryText)
        elif index == 3:
            prefix = "LEXICON:::"
        elif index == 4:
            prefix = "SEARCHTOOL:::"
        if not config.clearCommandEntry:
            self.searchLineEdit.setText(prefix)

    def searchLineEntered(self):

        saveOpenBibleWindowContentOnNextTab = config.openBibleWindowContentOnNextTab
        searchString = self.searchLineEdit.text()
        if ":::" not in searchString or ":::{0}:::".format(
                config.mainText) in searchString:
            config.openBibleWindowContentOnNextTab = False
        self.parent.textCommandLineEdit.setText(searchString)
        self.parent.runTextCommand(searchString)
        self.searchLineEdit.setFocus()
        self.populateBooksButtons(config.mainText)
        config.openBibleWindowContentOnNextTab = saveOpenBibleWindowContentOnNextTab

    #def setTtsDefaultLanguage(self):
    #config.ttsDefaultLangauge = self.languageCodes[self.languageCombo.currentIndex()]

    def speakCommandFieldText(self):
        text = self.searchLineEdit.text()
        if ":::" in text:
            text = text.split(":::")[-1]
        command = "SPEAK:::{0}:::{1}".format(
            self.languageCodes[self.languageCombo.currentIndex()], text)
        self.runCommmand(command)

    def bibleBookAction(self, book):
        command = "{0} ".format(self.bookMap[book])
        self.runCommmand(command)
        self.searchLineEdit.setFocus()

    def keyEntryAction(self, key):
        text = self.searchLineEdit.text()
        if key == "X":
            text = ""
        elif key == "<":
            text = text[:-1]
        else:
            text += key
        self.searchLineEdit.setText(text)

    def bibleAction(self, bible):
        command = "BIBLE:::{0}:::{1}".format(
            bible,
            self.parent.verseReference("main")[1])
        self.runCommmand(command)
        command = "_bibleinfo:::{0}".format(bible)
        self.parent.runTextCommand(command)
        self.populateBooksButtons(config.mainText)

    def commentaryAction(self, commentary):
        command = "COMMENTARY:::{0}:::{1}".format(
            commentary,
            self.parent.verseReference("main")[1])
        self.runCommmand(command)
        command = "_commentaryinfo:::{0}".format(commentary)
        self.parent.runTextCommand(command)

    def bookIntroAction(self, commentary):
        command = "COMMENTARY:::{0}:::{1}".format(
            commentary,
            BibleBooks().eng[str(config.mainB)][-1])
        self.runCommmand(command)
        command = "_commentaryinfo:::{0}".format(commentary)
        self.parent.runTextCommand(command)

    def devotionalAction(self, devotional):
        command = "DEVOTIONAL:::{0}".format(devotional)
        self.runCommmand(command)

    def lexiconAction(self, lexicon):
        searchString = self.searchLineEdit.text()
        if ":::" not in searchString:
            TextCommandParser.last_lexicon_entry = searchString
        command = "SEARCHLEXICON:::{0}:::{1}".format(
            lexicon, TextCommandParser.last_lexicon_entry)
        self.runCommmand(command)

    def dictionaryAction(self, dictionary):
        searchString = self.searchLineEdit.text()
        if ":::" not in searchString:
            TextCommandParser.last_text_search = searchString
        command = "SEARCHTOOL:::{0}:::{1}".format(
            dictionary, TextCommandParser.last_text_search)
        self.runCommmand(command)

    def runCommmand(self, command):
        self.searchLineEdit.setText(command)
        self.parent.runTextCommand(command)
        self.parent.textCommandLineEdit.setText(command)
        self.populateBooksButtons(config.mainText)

    def selectCollection(self, collection):

        if not collection == "All":
            biblesInCollection = config.bibleCollections[collection]
        for bible in self.bibleButtons.keys():
            button = self.bibleButtons[bible]
            if collection == "All":
                button.setEnabled(True)
                button.setStyleSheet("")
            else:
                if bible in biblesInCollection:
                    button.setEnabled(True)
                    button.setStyleSheet("")
                else:
                    button.setEnabled(False)
                    button.setStyleSheet(self.textButtonStyleDisabled)

    def activeCommentaries(self):
        activeCommentaries = [
            item[0]
            for item in Commentary().getCommentaryListThatHasBookAndChapter(
                config.mainB, config.mainC)
        ]
        for commentary in self.commentaryButtons.keys():
            button = self.commentaryButtons[commentary]
            if commentary in activeCommentaries:
                button.setEnabled(True)
                button.setStyleSheet("")
            else:
                button.setEnabled(False)
                button.setStyleSheet(self.textButtonStyleDisabled)

    def activeBookIntros(self):
        activeCommentaries = [
            item[0]
            for item in Commentary().getCommentaryListThatHasBookAndChapter(
                config.mainB, 0)
        ]
        for commentary in self.bookIntroButtons.keys():
            button = self.bookIntroButtons[commentary]
            if commentary in activeCommentaries:
                button.setEnabled(True)
                button.setStyleSheet("")
            else:
                button.setEnabled(False)
                button.setStyleSheet(self.textButtonStyleDisabled)
Пример #11
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
Пример #12
0
class ConfigDialog(QDialog):
    """A dialog to set values in cnapy-config.txt"""
    def __init__(self, appdata: CnaData):
        QDialog.__init__(self)
        self.setWindowTitle("Configure CNApy")

        cross_icon = QIcon(":/icons/cross.png")
        cross = cross_icon.pixmap(QSize(32, 32))

        self.appdata = appdata
        self.oeng = appdata.octave_engine
        self.meng = appdata.matlab_engine
        self.layout = QVBoxLayout()
        self.cna_ok = False

        descr = QLabel("\
            Some functionalities in CNApy need a working CNA installation.\n \
            To use CNA you need either Matlab >= R2019 or Octave >= 5 .\n \
            Below you can choose a Matlab directory or the Octave executable.\n \
            Only if one of the engines is green your CNA directory can be validated."
                       )
        self.layout.addWidget(descr)
        ml = QHBoxLayout()
        label = QLabel("Matlab")
        label.setFixedWidth(100)
        ml.addWidget(label)
        self.ml_label = QLabel()
        self.ml_label.setPixmap(cross)
        self.ml_label.setFixedWidth(100)
        ml.addWidget(self.ml_label)
        self.choose_ml_path_btn = QPushButton("Choose Matlab folder")
        self.choose_ml_path_btn.setFixedWidth(300)
        ml.addWidget(self.choose_ml_path_btn)
        label2 = QLabel("")
        label2.setFixedWidth(30)
        ml.addWidget(label2)
        self.matlab_path = QLabel()
        self.matlab_path.setMinimumWidth(200)
        self.matlab_path.setText(self.appdata.matlab_path)
        ml.addWidget(self.matlab_path)

        self.layout.addItem(ml)

        oc = QHBoxLayout()
        label = QLabel("Octave")
        label.setFixedWidth(100)
        oc.addWidget(label)
        self.oc_label = QLabel()
        self.oc_label.setPixmap(cross)
        self.oc_label.setFixedWidth(100)
        oc.addWidget(self.oc_label)

        self.choose_oc_exe_btn = QPushButton("Choose Octave octave-cli(.exe)")
        self.choose_oc_exe_btn.setFixedWidth(300)
        oc.addWidget(self.choose_oc_exe_btn)

        label2 = QLabel("")
        label2.setFixedWidth(30)
        oc.addWidget(label2)

        self.oc_exe = QLabel()
        self.oc_exe.setText(self.appdata.octave_executable)
        self.oc_exe.setMinimumWidth(200)
        oc.addWidget(self.oc_exe)

        self.layout.addItem(oc)

        h9 = QHBoxLayout()
        label = QLabel("Selected engine:")
        h9.addWidget(label)
        label2 = QLabel("")
        label2.setFixedWidth(30)
        h9.addWidget(label2)
        self.selected_engine = QComboBox()
        self.selected_engine.addItem("None")
        h9.addWidget(self.selected_engine)
        label2 = QLabel("")
        label2.setMinimumWidth(200)
        h9.addWidget(label2)
        self.layout.addItem(h9)

        cna_l = QHBoxLayout()
        label = QLabel("CNA")
        label.setFixedWidth(100)
        cna_l.addWidget(label)
        self.cna_label = QLabel()
        self.cna_label.setPixmap(cross)
        self.cna_label.setFixedWidth(100)
        cna_l.addWidget(self.cna_label)
        self.choose_cna_path_btn = QPushButton("Choose CNA directory")
        self.choose_cna_path_btn.setFixedWidth(300)
        cna_l.addWidget(self.choose_cna_path_btn)
        label2 = QLabel("")
        label2.setFixedWidth(30)
        cna_l.addWidget(label2)

        self.cna_path = QLabel()
        self.cna_path.setMinimumWidth(200)
        self.cna_path.setText(self.appdata.cna_path)
        cna_l.addWidget(self.cna_path)
        self.layout.addItem(cna_l)

        h2 = QHBoxLayout()
        label = QLabel("Default color for values in a scenario:")
        h2.addWidget(label)
        self.scen_color_btn = QPushButton()
        self.scen_color_btn.setFixedWidth(100)
        palette = self.scen_color_btn.palette()
        palette.setColor(QPalette.Button, self.appdata.scen_color)
        self.scen_color_btn.setPalette(palette)
        h2.addWidget(self.scen_color_btn)
        self.layout.addItem(h2)

        h3 = QHBoxLayout()
        label = QLabel(
            "Default color for computed values not part of the scenario:")
        h3.addWidget(label)
        self.comp_color_btn = QPushButton()
        self.comp_color_btn.setFixedWidth(100)
        palette = self.comp_color_btn.palette()
        palette.setColor(QPalette.Button, self.appdata.comp_color)
        self.comp_color_btn.setPalette(palette)
        h3.addWidget(self.comp_color_btn)
        self.layout.addItem(h3)

        h4 = QHBoxLayout()
        label = QLabel("Special Color used for non equal flux bounds:")
        h4.addWidget(label)
        self.spec1_color_btn = QPushButton()
        self.spec1_color_btn.setFixedWidth(100)
        palette = self.spec1_color_btn.palette()
        palette.setColor(QPalette.Button, self.appdata.special_color_1)
        self.spec1_color_btn.setPalette(palette)
        h4.addWidget(self.spec1_color_btn)
        self.layout.addItem(h4)

        h5 = QHBoxLayout()
        label = QLabel(
            "Special Color 2 used for non equal flux bounds that exclude 0:")
        h5.addWidget(label)
        self.spec2_color_btn = QPushButton()
        self.spec2_color_btn.setFixedWidth(100)
        palette = self.spec2_color_btn.palette()
        palette.setColor(QPalette.Button, self.appdata.special_color_2)
        self.spec2_color_btn.setPalette(palette)
        h5.addWidget(self.spec2_color_btn)
        self.layout.addItem(h5)

        h6 = QHBoxLayout()
        label = QLabel("Color used for empty reaction boxes:")
        h6.addWidget(label)
        self.default_color_btn = QPushButton()
        self.default_color_btn.setFixedWidth(100)
        palette = self.default_color_btn.palette()
        palette.setColor(QPalette.Button, self.appdata.default_color)
        self.default_color_btn.setPalette(palette)
        h6.addWidget(self.default_color_btn)
        self.layout.addItem(h6)

        h = QHBoxLayout()
        label = QLabel("Work directory:")
        h.addWidget(label)
        self.work_directory = QPushButton()
        self.work_directory.setText(self.appdata.work_directory)
        h.addWidget(self.work_directory)
        self.layout.addItem(h)

        h7 = QHBoxLayout()
        label = QLabel("Shown number of digits after the decimal point:")
        h7.addWidget(label)
        self.rounding = QLineEdit()
        self.rounding.setFixedWidth(100)
        self.rounding.setText(str(self.appdata.rounding))
        validator = QIntValidator(0, 20, self)
        self.rounding.setValidator(validator)
        h7.addWidget(self.rounding)
        self.layout.addItem(h7)

        h8 = QHBoxLayout()
        label = QLabel(
            "Absolute tolerance used to compare float values in the UI:")
        h8.addWidget(label)
        self.abs_tol = QLineEdit()
        self.abs_tol.setFixedWidth(100)
        self.abs_tol.setText(str(self.appdata.abs_tol))
        validator = QDoubleValidator(self)
        validator.setTop(1)
        self.abs_tol.setValidator(validator)
        h8.addWidget(self.abs_tol)
        self.layout.addItem(h8)

        l2 = QHBoxLayout()
        self.button = QPushButton("Apply Changes")
        self.cancel = QPushButton("Close")
        l2.addWidget(self.button)
        l2.addWidget(self.cancel)
        self.layout.addItem(l2)
        self.setLayout(self.layout)

        # Connecting the signal
        self.choose_ml_path_btn.clicked.connect(self.choose_ml_path)
        self.choose_oc_exe_btn.clicked.connect(self.choose_oc_exe)
        self.choose_cna_path_btn.clicked.connect(self.choose_cna_path)
        self.work_directory.clicked.connect(self.choose_work_directory)
        self.scen_color_btn.clicked.connect(self.choose_scen_color)
        self.comp_color_btn.clicked.connect(self.choose_comp_color)
        self.spec1_color_btn.clicked.connect(self.choose_spec1_color)
        self.spec2_color_btn.clicked.connect(self.choose_spec2_color)
        self.default_color_btn.clicked.connect(self.choose_default_color)
        self.selected_engine.currentTextChanged.connect(self.update)
        self.cancel.clicked.connect(self.reject)
        self.button.clicked.connect(self.apply)

        self.check_all()

        if self.meng is not None:
            self.selected_engine.insertItem(1, "Matlab")
            if self.appdata.selected_engine == "matlab":
                self.selected_engine.setCurrentIndex(1)
        if self.oeng is not None:
            self.selected_engine.insertItem(1, "Octave")
            if self.appdata.selected_engine == "octave":
                self.selected_engine.setCurrentIndex(1)

        self.update()

    def update(self):
        cross_icon = QIcon(":/icons/cross.png")
        cross = cross_icon.pixmap(QSize(32, 32))
        check_icon = QIcon(":/icons/check.png")
        check = check_icon.pixmap(QSize(32, 32))

        selected_engine = self.selected_engine.currentText()

        if selected_engine == "None":
            qmark_icon = QIcon(":/icons/qmark.png")
            qmark = qmark_icon.pixmap(QSize(32, 32))
            self.cna_label.setPixmap(qmark)
        else:
            if self.cna_ok:
                self.cna_label.setPixmap(check)
            else:
                self.cna_label.setPixmap(cross)
        if self.oeng is not None:
            # disable button if octave is already working
            self.oc_label.setPixmap(check)
        else:
            self.oc_label.setPixmap(cross)

        if self.meng is not None:
            self.ml_label.setPixmap(check)
        else:
            self.ml_label.setPixmap(cross)

        self.selected_engine.currentTextChanged.disconnect(self.update)
        self.selected_engine.clear()
        self.selected_engine.addItem("None")
        if self.meng is not None:
            self.selected_engine.addItem("Matlab")
        if self.oeng is not None:
            self.selected_engine.addItem("Octave")
#
        if selected_engine is "None":
            self.selected_engine.setCurrentIndex(0)
        if selected_engine == "Matlab":
            self.selected_engine.setCurrentIndex(1)
        if selected_engine == "Octave":
            if self.selected_engine.count() == 2:
                self.selected_engine.setCurrentIndex(1)
            elif self.selected_engine.count() == 3:
                self.selected_engine.setCurrentIndex(2)

        self.selected_engine.currentTextChanged.connect(self.update)

    def choose_ml_path(self):
        dialog = QFileDialog(self, directory=self.matlab_path.text())
        dialog.setFileMode(QFileDialog.DirectoryOnly)
        directory: str = dialog.getExistingDirectory()
        if not directory or len(
                directory) == 0 or not os.path.exists(directory):
            return

        self.choose_ml_path_btn.setEnabled(False)
        self.matlab_path.setText(directory)
        self.try_install_matlab_engine(directory)
        self.check_matlab()
        self.choose_ml_path_btn.setEnabled(True)
        self.update()

    def try_install_matlab_engine(self, directory: str):
        try:
            path = os.path.join(directory, 'extern/engines/python')
            cwd = os.getcwd()
            os.chdir(path)
            temp_dir = TemporaryDirectory()
            os.system("python setup.py build --build-base=" + temp_dir.name +
                      ' install')
            os.chdir(cwd)
        except FileNotFoundError:
            # no Matlab engine found
            pass

    def choose_oc_exe(self):

        dialog = QFileDialog(self, directory=self.oc_exe.text())
        filename: str = dialog.getOpenFileName(directory=os.getcwd())[0]
        if not filename or len(filename) == 0 or not os.path.exists(filename):
            return

        self.oc_exe.setText(filename)
        if os.path.isfile(filename):
            os.environ['OCTAVE_EXECUTABLE'] = filename

        self.choose_oc_exe_btn.setEnabled(False)
        self.check_octave()
        self.choose_oc_exe_btn.setEnabled(True)
        self.update()

    def check_all(self):
        self.check_octave()
        self.check_matlab()
        self.check_cna()

    def check_octave(self):
        if self.oeng is None:
            self.oeng = try_octave_engine(self.oc_exe.text())

    def check_matlab(self):
        # only recheck matlab if necessary
        if self.meng is None:
            self.meng = try_matlab_engine()

    def choose_cna_path(self):
        dialog = QFileDialog(self, directory=self.cna_path.text())
        dialog.setFileMode(QFileDialog.DirectoryOnly)
        directory: str = dialog.getExistingDirectory()
        if not directory or len(
                directory) == 0 or not os.path.exists(directory):
            return

        self.cna_path.setText(directory)
        self.update()
        self.reset_engine()
        self.check_cna()
        self.update()

    def choose_work_directory(self):
        dialog = QFileDialog(self, directory=self.work_directory.text())
        directory: str = dialog.getExistingDirectory()
        if not directory or len(
                directory) == 0 or not os.path.exists(directory):
            return
        self.work_directory.setText(directory)

    def reset_engine(self):
        # This resets the engines
        if self.oeng is None:
            self.meng = try_matlab_engine()
        else:
            self.oeng = try_octave_engine(self.oc_exe.text())

    def check_cna(self):

        if self.oeng is not None:
            self.cna_ok = try_cna(self.oeng, self.cna_path.text())
        elif self.meng is not None:
            self.cna_ok = try_cna(self.meng, self.cna_path.text())

    def choose_scen_color(self):
        palette = self.scen_color_btn.palette()
        initial = palette.color(QPalette.Button)

        dialog = QColorDialog(self)
        color: str = dialog.getColor(initial)
        if color.isValid():
            palette.setColor(QPalette.Button, color)
            self.scen_color_btn.setPalette(palette)

    def choose_comp_color(self):
        palette = self.comp_color_btn.palette()
        initial = palette.color(QPalette.Button)

        dialog = QColorDialog(self)
        color: str = dialog.getColor(initial)
        if color.isValid():
            palette.setColor(QPalette.Button, color)
            self.comp_color_btn.setPalette(palette)

    def choose_spec1_color(self):
        palette = self.spec1_color_btn.palette()
        initial = palette.color(QPalette.Button)

        dialog = QColorDialog(self)
        color: str = dialog.getColor(initial)
        if color.isValid():
            palette.setColor(QPalette.Button, color)
            self.spec1_color_btn.setPalette(palette)

    def choose_spec2_color(self):
        palette = self.spec2_color_btn.palette()
        initial = palette.color(QPalette.Button)

        dialog = QColorDialog(self)
        color: str = dialog.getColor(initial)
        if color.isValid():
            palette.setColor(QPalette.Button, color)
            self.spec2_color_btn.setPalette(palette)

    def choose_default_color(self):
        palette = self.default_color_btn.palette()
        initial = palette.color(QPalette.Button)

        dialog = QColorDialog(self)
        color: str = dialog.getColor(initial)
        if color.isValid():
            palette.setColor(QPalette.Button, color)
            self.default_color_btn.setPalette(palette)

    def apply(self):
        self.appdata.matlab_path = self.matlab_path.text()
        self.appdata.octave_executable = self.oc_exe.text()
        self.appdata.cna_path = self.cna_path.text()
        self.appdata.matlab_engine = self.meng
        self.appdata.octave_engine = self.oeng

        if self.selected_engine.currentText() == "None":
            self.appdata.selected_engine = None
        elif self.selected_engine.currentText() == "Matlab":
            self.appdata.selected_engine = "matlab"
        elif self.selected_engine.currentText() == "Octave":
            self.appdata.selected_engine = "octave"

        self.appdata.select_engine()

        self.appdata.window.disable_enable_dependent_actions()

        self.appdata.work_directory = self.work_directory.text()

        palette = self.scen_color_btn.palette()
        self.appdata.scen_color = palette.color(QPalette.Button)

        palette = self.comp_color_btn.palette()
        self.appdata.comp_color = palette.color(QPalette.Button)

        palette = self.spec1_color_btn.palette()
        self.appdata.special_color_1 = palette.color(QPalette.Button)

        palette = self.spec2_color_btn.palette()
        self.appdata.special_color_2 = palette.color(QPalette.Button)

        palette = self.default_color_btn.palette()
        self.appdata.default_color = palette.color(QPalette.Button)

        self.appdata.rounding = int(self.rounding.text())
        self.appdata.abs_tol = float(self.abs_tol.text())

        parser = configparser.ConfigParser()
        parser.add_section('cnapy-config')
        parser.set('cnapy-config', 'version', self.appdata.version)
        parser.set('cnapy-config', 'matlab_path', self.appdata.matlab_path)
        parser.set('cnapy-config', 'OCTAVE_EXECUTABLE',
                   self.appdata.octave_executable)
        parser.set('cnapy-config', 'work_directory',
                   self.appdata.work_directory)
        parser.set('cnapy-config', 'cna_path', self.appdata.cna_path)
        parser.set('cnapy-config', 'scen_color',
                   str(self.appdata.scen_color.rgb()))
        parser.set('cnapy-config', 'comp_color',
                   str(self.appdata.comp_color.rgb()))
        parser.set('cnapy-config', 'spec1_color',
                   str(self.appdata.special_color_1.rgb()))
        parser.set('cnapy-config', 'spec2_color',
                   str(self.appdata.special_color_2.rgb()))
        parser.set('cnapy-config', 'default_color',
                   str(self.appdata.default_color.rgb()))
        parser.set('cnapy-config', 'rounding', str(self.appdata.rounding))
        parser.set('cnapy-config', 'abs_tol', str(self.appdata.abs_tol))
        parser.set('cnapy-config', 'selected_engine',
                   str(self.appdata.selected_engine))

        try:
            fp = open(self.appdata.conf_path, "w")
        except FileNotFoundError:
            os.makedirs(
                appdirs.user_config_dir("cnapy", roaming=True,
                                        appauthor=False))
            fp = open(self.appdata.conf_path, "w")

        parser.write(fp)
        fp.close()

        self.accept()
Пример #13
0
class ContourOptionsDialog(QDialog):
    """
    Dialog box for selecting contour options
    """
    def __init__(self, contour_settings):
        super(ContourOptionsDialog, self).__init__(contour_settings.cubeviz_layout)
        self.setWindowFlags(self.windowFlags() | Qt.Tool)
        self.setWindowTitle("Contour Options")

        self.is_preview_active = False  # preview mode?

        self.contour_settings = contour_settings  # ref to caller ContourSettings
        self.image_viewer = self.contour_settings.image_viewer  # ref to image viewer
        self.options = self.contour_settings.options  # ref to ContourSettings options

        self._colormap_members = self.contour_settings.colormap_members  # Colormap options
        self._colormap_index = DEFAULT_GLUE_COLORMAP_INDEX  # Currently selected colormap
        if "cmap" in self.options:
            if self.options["cmap"] in self._colormap_members:
                self._colormap_index = self._colormap_members.index(self.options["cmap"])

        # Is there a user spacing?
        if self.contour_settings.spacing is None:
            self.is_custom_spacing = False
        else:
            self.is_custom_spacing = True
        # Is there a user min?
        if self.contour_settings.vmin is None:
            self.is_vmin = False
        else:
            self.is_vmin = True
        # Is there a user max?
        if self.contour_settings.vmax is None:
            self.is_vmax = False
        else:
            self.is_vmax = True

        self.add_contour_label = self.contour_settings.add_contour_label  # bool

        self._init_ui()

    def _init_ui(self):

        # Line 1: Color map
        self.colormap_label = QLabel("Color Scheme: ")

        self.colormap_combo = QColormapCombo()
        self.colormap_combo.addItem("", userData=UserDataWrapper(cm.viridis))
        self.colormap_combo._update_icons()
        self.colormap_combo.setCurrentIndex(self._colormap_index)
        self.colormap_combo.setMaximumWidth(150)
        self.colormap_combo.currentIndexChanged.connect(
            self._on_colormap_change)

        #   hbl is short for Horizontal Box Layout
        hbl1 = QHBoxLayout()
        hbl1.addWidget(self.colormap_label)
        hbl1.addWidget(self.colormap_combo)

        # Line 2: Display contour labels
        self.contour_label_checkBox = QCheckBox("Contour labels (font size):")
        if self.contour_settings.add_contour_label:
            self.contour_label_checkBox.setChecked(True)
        self.contour_label_checkBox.toggled.connect(self.toggle_labels)

        font_string = str(self.contour_settings.font_size)
        self.font_size_input = QLineEdit(font_string)
        self.font_size_input.setFixedWidth(150)
        self.font_size_input.setDisabled(
            not self.contour_settings.add_contour_label)

        hbl2 = QHBoxLayout()
        hbl2.addWidget(self.contour_label_checkBox)
        hbl2.addWidget(self.font_size_input)

        # Line 3: Contour Spacing
        self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):")
        if self.is_custom_spacing:
            self.custom_spacing_checkBox.setChecked(True)
        self.custom_spacing_checkBox.toggled.connect(self.custom_spacing)

        self.spacing_input = QLineEdit()
        self.spacing_input.setFixedWidth(150)
        self.spacing_input.setDisabled(not self.is_custom_spacing)
        spacing = ""
        if self.is_custom_spacing:
            spacing = str(self.contour_settings.spacing)
        elif self.contour_settings.data_spacing is not None:
            spacing = self.contour_settings.data_spacing
            spacing = "{0:1.4f}".format(spacing)
        self.spacing_default_text = spacing
        self.spacing_input.setText(spacing)

        hbl3 = QHBoxLayout()
        hbl3.addWidget(self.custom_spacing_checkBox)
        hbl3.addWidget(self.spacing_input)

        # Line 4: Vmax
        self.vmax_checkBox = QCheckBox("Set max:")

        self.vmax_input = QLineEdit()
        self.vmax_input.setFixedWidth(150)
        self.vmax_input.setDisabled(not self.is_vmax)

        vmax = ""
        if self.is_vmax:
            self.vmax_checkBox.setChecked(True)
            vmax = str(self.contour_settings.vmax)
        elif self.contour_settings.data_max is not None:
            vmax = self.contour_settings.data_max
            vmax = "{0:1.4f}".format(vmax)
        self.vmax_input.setText(vmax)
        self.vmax_default_text = vmax

        self.vmax_checkBox.toggled.connect(self.toggle_vmax)

        hbl4 = QHBoxLayout()
        hbl4.addWidget(self.vmax_checkBox)
        hbl4.addWidget(self.vmax_input)

        # Line 5: Vmin
        self.vmin_checkBox = QCheckBox("Set min:")

        self.vmin_input = QLineEdit()
        self.vmin_input.setFixedWidth(150)
        self.vmin_input.setDisabled(not self.is_vmin)

        vmin = ""
        if self.is_vmin:
            self.vmin_checkBox.setChecked(True)
            vmin = str(self.contour_settings.vmin)
        elif self.contour_settings.data_min is not None:
            vmin = self.contour_settings.data_min
            vmin = "{0:1.4f}".format(vmin)
        self.vmin_input.setText(vmin)
        self.vmin_default_text = vmin

        self.vmin_checkBox.toggled.connect(self.toggle_vmin)

        hbl5 = QHBoxLayout()
        hbl5.addWidget(self.vmin_checkBox)
        hbl5.addWidget(self.vmin_input)

        # Line f:
        self.previewButton = QPushButton("Preview")
        self.previewButton.clicked.connect(self.preview)

        self.defaultButton = QPushButton("Reset")
        self.defaultButton.clicked.connect(self.default)

        self.okButton = QPushButton("OK")
        self.okButton.clicked.connect(self.finish)
        self.okButton.setDefault(True)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(self.cancel)

        hblf = QHBoxLayout()
        hblf.addStretch(1)
        hblf.addWidget(self.previewButton)
        hblf.addWidget(self.defaultButton)
        hblf.addWidget(self.cancelButton)
        hblf.addWidget(self.okButton)

        vbl = QVBoxLayout()
        vbl.addLayout(hbl1)
        vbl.addLayout(hbl2)
        vbl.addLayout(hbl3)
        vbl.addLayout(hbl4)
        vbl.addLayout(hbl5)
        vbl.addLayout(hblf)

        self.setLayout(vbl)

        self.show()

    def update_data_vals(self, vmin="", vmax="", spacing="1"):

        self.vmin_default_text = vmin

        if not self.is_vmin:
            self.vmin_input.setText(vmin)

        self.vmax_default_text = vmax
        if not self.is_vmax:
            self.vmax_input.setText(vmax)

        self.spacing_default_text = spacing
        if not self.is_custom_spacing:
            self.spacing_input.setText(spacing)

    def _on_colormap_change(self, index):
        """Combo index changed handler"""
        self._colormap_index = index

    def custom_spacing(self):
        """Checkbox toggled handler"""
        if self.is_custom_spacing:
            self.is_custom_spacing = False
            self.spacing_input.setDisabled(True)
            spacing = ""
            if self.contour_settings.data_spacing:
                spacing = self.contour_settings.data_spacing
                spacing = "{0:1.4f}".format(spacing)
            self.spacing_input.setText(spacing)
            self.spacing_input.setStyleSheet("")
        else:
            self.is_custom_spacing = True
            self.spacing_input.setDisabled(False)

    def toggle_labels(self):
        """Checkbox toggled handler"""
        if self.add_contour_label:
            self.add_contour_label = False
            self.font_size_input.setDisabled(True)
            font_string = str(self.contour_settings.font_size)
            self.font_size_input.setText(font_string)
            self.font_size_input.setStyleSheet("")
        else:
            self.add_contour_label = True
            self.font_size_input.setDisabled(False)

    def toggle_vmax(self):
        """Checkbox toggled handler"""
        if self.is_vmax:
            self.is_vmax = False
            self.vmax_input.setDisabled(True)
            vmax = ""
            if self.contour_settings.data_max:
                vmax = self.contour_settings.data_max
                vmax = "{0:1.4f}".format(vmax)
            self.vmax_input.setText(vmax)
            self.vmax_input.setStyleSheet("")
        else:
            self.is_vmax = True
            self.vmax_input.setDisabled(False)

    def toggle_vmin(self):
        """Checkbox toggled handler"""
        if self.is_vmin:
            self.is_vmin = False
            self.vmin_input.setDisabled(True)
            vmin = ""
            if self.contour_settings.data_min:
                vmin = self.contour_settings.data_min
                vmin = "{0:1.4f}".format(vmin)
            self.vmin_input.setText(vmin)
            self.vmin_input.setStyleSheet("")
        else:
            self.is_vmin = True
            self.vmin_input.setDisabled(False)

    def input_validation(self):
        red = "background-color: rgba(255, 0, 0, 128);"

        def float_check(min_val=None):
            if user_input.text() == "":
                user_input.setStyleSheet(red)
                return False
            else:
                try:
                    value = float(user_input.text())
                    if min_val is not None:
                        if value <= min_val:
                            user_input.setStyleSheet(red)
                            return False
                    else:
                        user_input.setStyleSheet("")
                except ValueError:
                    user_input.setStyleSheet(red)
                    return False
            return True

        def int_check(min_val=None):
            if user_input.text() == "":
                user_input.setStyleSheet(red)
                return False
            else:
                try:
                    value = int(user_input.text())
                    if min_val is not None:
                        if value <= min_val:
                            user_input.setStyleSheet(red)
                            return False
                    else:
                        user_input.setStyleSheet("")
                except ValueError:
                    user_input.setStyleSheet(red)
                    return False
            return True

        success = True

        # Check 1: spacing_input
        if self.is_custom_spacing:
            user_input = self.spacing_input
            float_check(0)
            success = success and float_check()

        # Check 2: font_size_input
        if self.add_contour_label:
            user_input = self.font_size_input
            int_check(0)
            success = success and int_check()

        # Check 3: vmax
        if self.is_vmax:
            user_input = self.vmax_input
            float_check()
            success = success and float_check()

        # Check 4: vmax
        if self.is_vmin:
            user_input = self.vmin_input
            float_check()
            success = success and float_check()

        # Check 5: vmax and vmin
        if self.is_vmax and self.is_vmin and success:
            vmax = float(self.vmax_input.text())
            vmin = float(self.vmin_input.text())
            if vmax <= vmin:
                self.vmax_input.setStyleSheet(red)
                self.vmin_input.setStyleSheet(red)
                success = False

        return success

    def finish(self):
        """
        Ok button pressed. Finalize
        options and send to image viewer
         """
        success = self.input_validation()

        if not success:
            return

        # Change Color Map
        self._colormap_index = self.colormap_combo.currentIndex()
        colormap = self._colormap_members[self._colormap_index]
        self.contour_settings.options["cmap"] = colormap

        # labels
        self.contour_settings.add_contour_label = self.add_contour_label

        # font size
        if self.add_contour_label:
            font_size = int(self.font_size_input.text())
            self.contour_settings.font_size = font_size
        else:
            self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE

        # Spacing
        if self.is_custom_spacing:
            self.contour_settings.spacing = float(self.spacing_input.text())
        else:
            self.contour_settings.spacing = None

        # vmax
        if self.is_vmax:
            vmax = float(self.vmax_input.text())
            self.contour_settings.vmax = vmax
            self.contour_settings.options["vmax"] = vmax
        else:
            self.contour_settings.vmax = None
            self.contour_settings.options["vmax"] = None

        # vmin
        if self.is_vmin:
            vmin = float(self.vmin_input.text())
            self.contour_settings.vmin = vmin
            self.contour_settings.options["vmin"] = vmin
        else:
            self.contour_settings.vmin = None
            self.contour_settings.options["vmin"] = None

        # Redraw contour
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()

        self.close()

    def preview(self):
        """
        Prepare preview contour settings
        and send to image viewer
        """
        success = self.input_validation()

        if not success:
            return

        image_viewer = self.contour_settings.image_viewer
        preview_settings = ContourSettings(image_viewer)
        preview_settings.dialog = self
        preview_settings.options = self.contour_settings.options.copy()
        preview_settings.spacing = self.contour_settings.spacing

        # Change Color Map
        self._colormap_index = self.colormap_combo.currentIndex()
        colormap = self._colormap_members[self._colormap_index]
        preview_settings.options["cmap"] = colormap

        # labels
        add_contour_label = self.contour_label_checkBox.isChecked()
        preview_settings.add_contour_label = add_contour_label

        # font size
        if add_contour_label:
            font_size = int(self.font_size_input.text())
            preview_settings.font_size = font_size

        # Spacing
        if self.is_custom_spacing:
            preview_settings.spacing = float(self.spacing_input.text())
        else:
            preview_settings.spacing = None

        # vmax
        if self.is_vmax:
            vmax = float(self.vmax_input.text())
            preview_settings.vmax = vmax
            preview_settings.options["vmax"] = vmax
        else:
            preview_settings.vmax = None
            preview_settings.options["vmax"] = None

        # vmin
        if self.is_vmin:
            vmin = float(self.vmin_input.text())
            preview_settings.vmin = vmin
            preview_settings.options["vmin"] = vmin
        else:
            preview_settings.vmin = None
            preview_settings.options["vmin"] = None

        # Redraw contour
        if image_viewer.is_contour_active:
            self.is_preview_active = True
            image_viewer.set_contour_preview(preview_settings)
        else:
            message = "Contour map is currently switched off. " \
                      "Please turn on the contour map by selecting " \
                      "a component from the contour map drop-down menu."
            info = QMessageBox.critical(self, "Error", message)

    def default(self):
        """
        Set options back to default
        and send to image viewer
        """
        self.contour_settings.options = self.contour_settings.default_options()
        self.contour_settings.spacing = None
        self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE
        self.contour_settings.vmax = None
        self.contour_settings.vmin = None
        self.contour_settings.add_contour_label = False
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()
        self.contour_settings.options_dialog()

    def cancel(self):
        if self.contour_settings.image_viewer.is_contour_active:
            self.contour_settings.draw_function()
        self.close()

    def closeEvent(self, event):
        """closeEvent handler"""
        if self.is_preview_active:
            self.contour_settings.image_viewer.end_contour_preview()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.cancel()
Пример #14
0
class BufferWidget(QWidget):
    def __init__(self, buffer_settings):
        super(BufferWidget, self).__init__()

        # Settings
        self.buffer_settings = buffer_settings
        if not self.buffer_settings:
            self.buffer_settings['buffer_length'] = '{:.3f}'.format(
                BUFFERLENGTH)
            self.buffer_settings['sample_length'] = '{:.3f}'.format(
                SAMPLELENGTH)
            self.buffer_settings['delay_buffer'] = '{:.3f}'.format(DELAYBUFFER)
            self.buffer_settings['overwrite_depth'] = OVERWRITEDEPTH
            self.buffer_settings['electrode_settings'] = {}

        self.buffer_widgets = {}

        buffer_layout = QGridLayout(self)
        row = -1
        if 'electrode_settings' in self.buffer_settings.keys():
            for label, sett in self.buffer_settings[
                    'electrode_settings'].items():
                row += 1
                buffer_layout.addWidget(QLabel(label), row, 0, 1, 1)
                self.buffer_widgets[label] = {}
                self.buffer_widgets[label]['chk_threshold'] = QCheckBox(
                    "Threshold")
                self.buffer_widgets[label]['chk_threshold'].setChecked(
                    bool(sett['threshold']))
                self.buffer_widgets[label]['edit_validity'] = QLineEdit()
                self.buffer_widgets[label]['edit_validity'].setText(
                    str(sett['validity']))

                buffer_layout.addWidget(
                    self.buffer_widgets[label]['chk_threshold'], row, 1, 1, 1)
                buffer_layout.addWidget(QLabel('Validity Threshold (%)'), row,
                                        2, 1, 1)
                buffer_layout.addWidget(
                    self.buffer_widgets[label]['edit_validity'], row, 3, 1, 1)

            row += 1
            buffer_layout.addWidget(QLabel("Depth buffer size (s): "), row, 0,
                                    1, 1)
            self.edit_buffer_length = QLineEdit(
                self.buffer_settings['buffer_length'])
            self.edit_buffer_length.setInputMask("0.000")
            self.edit_buffer_length.setFixedWidth(40)
            buffer_layout.addWidget(self.edit_buffer_length, row, 1, 1, 1)

            row += 1
            buffer_layout.addWidget(QLabel("Depth samples size (s): "), row, 0,
                                    1, 1)
            self.edit_sample_length = QLineEdit(
                self.buffer_settings['sample_length'])
            self.edit_sample_length.setInputMask("0.000")
            self.edit_sample_length.setFixedWidth(40)
            buffer_layout.addWidget(self.edit_sample_length, row, 1, 1, 1)

            row += 1
            buffer_layout.addWidget(QLabel("Delay depth recording (s): "), row,
                                    0, 1, 1)
            self.delay_buffer = QLineEdit(self.buffer_settings['delay_buffer'])
            self.delay_buffer.setInputMask("0.000")
            self.delay_buffer.setFixedWidth(40)
            buffer_layout.addWidget(self.delay_buffer, row, 1, 1, 1)

            row += 1
            self.overwrite_depth = QCheckBox("Overwrite depth values")
            self.overwrite_depth.setChecked(
                self.buffer_settings['overwrite_depth'])
            buffer_layout.addWidget(self.overwrite_depth, row, 0, 1, 1)

    def to_dict(self):
        # convert all fields to dictionary and return it
        self.buffer_settings['buffer_length'] = self.edit_buffer_length.text()
        self.buffer_settings['sample_length'] = self.edit_sample_length.text()
        self.buffer_settings['delay_buffer'] = self.delay_buffer.text()
        self.buffer_settings[
            'overwrite_depth'] = self.overwrite_depth.isChecked()

        for key, value in self.buffer_widgets.items():
            self.buffer_settings['electrode_settings'][key] = {}
            self.buffer_settings['electrode_settings'][key][
                'threshold'] = value['chk_threshold'].isChecked()
            self.buffer_settings['electrode_settings'][key][
                'validity'] = float(value['edit_validity'].text())
Пример #15
0
class MiniControl(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.setWindowTitle(config.thisTranslation["remote_control"])
        self.parent = parent
        # specify window size
        if config.qtMaterial and config.qtMaterialTheme:
            self.resizeWindow(1 / 2, 1 / 3)
        else:
            self.resizeWindow(2 / 5, 1 / 3)
        self.resizeEvent = (lambda old_method:
                            (lambda event:
                             (self.onResized(event), old_method(event))[-1]))(
                                 self.resizeEvent)
        # setup interface
        self.setupUI()

    # window appearance
    def resizeWindow(self, widthFactor, heightFactor):
        availableGeometry = QGuiApplication.instance().desktop(
        ).availableGeometry()
        self.setMinimumWidth(500)
        self.resize(availableGeometry.width() * widthFactor,
                    availableGeometry.height() * heightFactor)

    def onResized(self, event):
        pass

    def closeEvent(self, event):
        config.miniControl = False

    # manage key capture
    def event(self, event):
        if event.type() == QEvent.KeyRelease:
            if event.modifiers() == Qt.ControlModifier:
                if event.key() == Qt.Key_B:
                    self.tabs.setCurrentIndex(0)
                elif event.key() == Qt.Key_T:
                    self.tabs.setCurrentIndex(1)
                elif event.key() == Qt.Key_C:
                    self.tabs.setCurrentIndex(2)
                elif event.key() == Qt.Key_L:
                    self.tabs.setCurrentIndex(3)
                elif event.key() == Qt.Key_D:
                    self.tabs.setCurrentIndex(4)
            elif event.key() == Qt.Key_Escape:
                self.close()
        return QWidget.event(self, event)

    # setup ui
    def setupUI(self):
        mainLayout = QGridLayout()

        commandBox = QVBoxLayout()
        commandBox.setSpacing(3)

        commandBar = QWidget()
        commandLayout1 = QBoxLayout(QBoxLayout.LeftToRight)
        commandLayout1.setSpacing(5)
        self.searchLineEdit = QLineEdit()
        self.searchLineEdit.setClearButtonEnabled(True)
        self.searchLineEdit.setToolTip(
            config.thisTranslation["enter_command_here"])
        self.searchLineEdit.returnPressed.connect(self.searchLineEntered)
        self.searchLineEdit.setFixedWidth(300)
        commandLayout1.addWidget(self.searchLineEdit)

        enterButton = QPushButton(config.thisTranslation["enter"])
        enterButton.setFixedWidth(100)
        enterButton.clicked.connect(self.searchLineEntered)
        commandLayout1.addWidget(enterButton)

        commandLayout1.addStretch()
        commandBox.addLayout(commandLayout1)

        commandLayout2 = QBoxLayout(QBoxLayout.LeftToRight)
        commandLayout2.setSpacing(5)

        keys = [
            '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ':', '-', ',',
            '.', ' ', '<', 'X'
        ]
        for key in keys:
            button = QPushButton(key)
            button.setMaximumWidth(30)
            button.clicked.connect(partial(self.keyEntryAction, key))
            commandLayout2.addWidget(button)

        commandLayout2.addStretch()
        commandBox.addLayout(commandLayout2)

        if config.isTtsInstalled:
            ttsLayout = QBoxLayout(QBoxLayout.LeftToRight)
            ttsLayout.setSpacing(5)

            self.languageCombo = QComboBox()
            ttsLayout.addWidget(self.languageCombo)
            if config.espeak:
                languages = TtsLanguages().isoLang2epeakLang
            else:
                languages = TtsLanguages().isoLang2qlocaleLang
            self.languageCodes = list(languages.keys())
            for code in self.languageCodes:
                self.languageCombo.addItem(languages[code][1])
            # Check if selected tts engine has the language user specify.
            if not (config.ttsDefaultLangauge in self.languageCodes):
                config.ttsDefaultLangauge = "en"
            # Set initial item
            initialIndex = self.languageCodes.index(config.ttsDefaultLangauge)
            self.languageCombo.setCurrentIndex(initialIndex)

            # setting tts default language here is confusing; better place in menu
            #setDefaultButton = QPushButton(config.thisTranslation["setDefault"])
            #setDefaultButton.setFixedWidth(130)
            #setDefaultButton.clicked.connect(self.setTtsDefaultLanguage)
            #ttsLayout.addWidget(setDefaultButton)

            speakButton = QPushButton(config.thisTranslation["speak"])
            speakButton.setFixedWidth(100)
            speakButton.clicked.connect(self.speakCommandFieldText)
            ttsLayout.addWidget(speakButton)

            stopButton = QPushButton(config.thisTranslation["stop"])
            stopButton.setFixedWidth(100)
            stopButton.clicked.connect(
                self.parent.textCommandParser.stopTtsAudio)
            ttsLayout.addWidget(stopButton)

            ttsLayout.addStretch()

            commandBox.addLayout(ttsLayout)

        commandBar.setLayout(commandBox)
        mainLayout.addWidget(commandBar, 0, 0, Qt.AlignCenter)

        self.tabs = QTabWidget()
        self.tabs.currentChanged.connect(self.tabChanged)
        mainLayout.addWidget(self.tabs, 1, 0, Qt.AlignCenter)

        parser = BibleVerseParser(config.parserStandarisation)
        self.bookMap = parser.standardAbbreviation
        bookNums = list(self.bookMap.keys())
        bookNumGps = [
            bookNums[0:10],
            bookNums[10:20],
            bookNums[20:30],
            bookNums[30:39],
            bookNums[39:49],
            bookNums[49:59],
            bookNums[59:66],
        ]

        bible = QWidget()
        bible_layout = QVBoxLayout()
        bible_layout.setMargin(0)
        bible_layout.setSpacing(0)
        for bookNumGp in bookNumGps[0:5]:
            gp = QWidget()
            layout = self.newRowLayout()
            for bookNum in bookNumGp:
                text = self.bookMap[bookNum]
                button = QPushButton(text)
                button.clicked.connect(partial(self.bibleBookAction, bookNum))
                layout.addWidget(button)
            gp.setLayout(layout)
            bible_layout.addWidget(gp)

        for bookNumGp in bookNumGps[5:]:
            gp = QWidget()
            layout = self.newRowLayout()
            for bookNum in bookNumGp:
                text = self.bookMap[bookNum]
                button = QPushButton(text)
                button.clicked.connect(partial(self.bibleBookAction, bookNum))
                layout.addWidget(button)
            gp.setLayout(layout)
            bible_layout.addWidget(gp)

        bible_layout.addStretch()
        bible.setLayout(bible_layout)
        self.tabs.addTab(bible, config.thisTranslation["bible"])

        bibles_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setMargin(0)
        box_layout.setSpacing(0)
        row_layout = self.newRowLayout()
        biblesSqlite = BiblesSqlite()
        bibles = biblesSqlite.getBibleList()
        count = 0
        for bible in bibles:
            button = QPushButton(bible)
            button.clicked.connect(partial(self.bibleAction, bible))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        bibles_box.setLayout(box_layout)

        self.tabs.addTab(bibles_box, config.thisTranslation["translations"])

        commentaries_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setMargin(0)
        box_layout.setSpacing(0)
        row_layout = self.newRowLayout()
        commentaries = Commentary().getCommentaryList()
        count = 0
        for commentary in commentaries:
            button = QPushButton(commentary)
            button.clicked.connect(partial(self.commentaryAction, commentary))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        commentaries_box.setLayout(box_layout)

        self.tabs.addTab(commentaries_box,
                         config.thisTranslation["commentaries"])

        lexicons_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setMargin(0)
        box_layout.setSpacing(0)
        row_layout = self.newRowLayout()
        lexicons = LexiconData().lexiconList
        count = 0
        for lexicon in lexicons:
            button = QPushButton(lexicon)
            button.clicked.connect(partial(self.lexiconAction, lexicon))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        lexicons_box.setLayout(box_layout)

        self.tabs.addTab(lexicons_box, config.thisTranslation["lexicons"])

        dictionaries_box = QWidget()
        box_layout = QVBoxLayout()
        box_layout.setMargin(0)
        box_layout.setSpacing(0)
        row_layout = self.newRowLayout()
        dictionaries = IndexesSqlite().dictionaryList
        count = 0
        for dictionary in dictionaries:
            button = QPushButton(dictionary[0])
            button.setToolTip(dictionary[1])
            button.clicked.connect(
                partial(self.dictionaryAction, dictionary[0]))
            row_layout.addWidget(button)
            count += 1
            if count > 6:
                count = 0
                box_layout.addLayout(row_layout)
                row_layout = self.newRowLayout()
        box_layout.addLayout(row_layout)
        box_layout.addStretch()
        dictionaries_box.setLayout(box_layout)

        self.tabs.addTab(dictionaries_box,
                         config.thisTranslation["dictionaries"])
        self.tabs.setCurrentIndex(config.miniControlInitialTab)
        self.setLayout(mainLayout)

    def newRowLayout(self):
        row_layout = QHBoxLayout()
        row_layout.setSpacing(0)
        row_layout.setMargin(0)
        return row_layout

    def tabChanged(self, index):
        prefix = ""
        if index == 0:
            prefix = "BIBLE:::{0}:::".format(config.mainText)
        elif index == 1:
            prefix = "TEXT:::"
        elif index == 2:
            prefix = "COMMENTARY:::{0}:::".format(config.commentaryText)
        elif index == 3:
            prefix = "LEXICON:::"
        elif index == 4:
            prefix = "SEARCHTOOL:::"
        if not config.clearCommandEntry:
            self.searchLineEdit.setText(prefix)

    def searchLineEntered(self):
        searchString = self.searchLineEdit.text()
        self.parent.textCommandLineEdit.setText(searchString)
        self.parent.runTextCommand(searchString)
        self.searchLineEdit.setFocus()

    #def setTtsDefaultLanguage(self):
    #config.ttsDefaultLangauge = self.languageCodes[self.languageCombo.currentIndex()]

    def speakCommandFieldText(self):
        text = self.searchLineEdit.text()
        if ":::" in text:
            text = text.split(":::")[-1]
        command = "SPEAK:::{0}:::{1}".format(
            self.languageCodes[self.languageCombo.currentIndex()], text)
        self.runCommmand(command)

    def bibleBookAction(self, book):
        command = "{0} ".format(self.bookMap[book])
        self.runCommmand(command)
        self.searchLineEdit.setFocus()

    def keyEntryAction(self, key):
        text = self.searchLineEdit.text()
        if key == "X":
            text = ""
        elif key == "<":
            text = text[:-1]
        else:
            text += key
        self.searchLineEdit.setText(text)

    def bibleAction(self, bible):
        command = "BIBLE:::{0}:::{1}".format(
            bible,
            self.parent.verseReference("main")[1])
        self.runCommmand(command)
        command = "_bibleinfo:::{0}".format(bible)
        self.parent.runTextCommand(command)

    def commentaryAction(self, commentary):
        command = "COMMENTARY:::{0}:::{1}".format(
            commentary,
            self.parent.verseReference("main")[1])
        self.runCommmand(command)
        command = "_commentaryinfo:::{0}".format(commentary)
        self.parent.runTextCommand(command)

    def lexiconAction(self, lexicon):
        command = "LEXICON:::{0}:::{1}".format(
            lexicon, TextCommandParser.last_lexicon_entry)
        self.runCommmand(command)

    def dictionaryAction(self, dictionary):
        command = "SEARCHTOOL:::{0}:::{1}".format(
            dictionary, TextCommandParser.last_text_search)
        self.runCommmand(command)

    def runCommmand(self, command):
        self.searchLineEdit.setText(command)
        self.parent.runTextCommand(command)
        self.parent.textCommandLineEdit.setText(command)