class ModuleCard(QGroupBox): """ Widget used inside Selection to display information about an API or Player as a selectable card. """ def __init__(self, module: BaseModuleData, selected: bool = False) -> None: """ A card with the cards's basic info. """ super().__init__(module.short_name) self.module = module self.setFont(Fonts.smalltext) self.setMinimumHeight(270) self.setMaximumHeight(400) self.setMinimumWidth(220) self.setMaximumWidth(300) self.layout = QVBoxLayout(self) self.setup_icon(module.icon) self.setup_text(module.description) self.setup_button(module.installed, selected) def setup_icon(self, icon: str) -> None: self.icon = QPixmap(icon) self.icon_label = QLabel() self.icon_label.setPixmap(self.icon) self.icon_label.setAlignment(Qt.AlignHCenter) self.layout.addWidget(self.icon_label) def setup_text(self, description: str) -> None: self.text = QLabel(description) self.text.setStyleSheet("padding: 10px 3px") self.text.setWordWrap(True) self.text.setFont(Fonts.smalltext) self.text.setAlignment(Qt.AlignHCenter) self.text.setTextFormat(Qt.RichText) self.text.setTextInteractionFlags(Qt.TextBrowserInteraction) self.text.setOpenExternalLinks(True) self.layout.addWidget(self.text) def setup_button(self, enabled: bool, selected: bool) -> None: """ The button will be disabled but still shown if `enabled` is false. """ self.button = QRadioButton("USE" if enabled else "Not Installed") self.button.setEnabled(enabled) self.button.setChecked(selected) font = Fonts.text font.setItalic(True) self.button.setFont(font) self.layout.addWidget(self.button)
class LegendPropertiesWindow(PyDialog): """ +-------------------+ | Legend Properties | +-----------------------+ | Title ______ Default | | Min ______ Default | | Max ______ Default | | Format ______ Default | | Scale ______ Default | | Phase ______ Default | | Number of Colors ____ | | Number of Labels ____ | | Label Size ____ | (TODO) | ColorMap ____ | (TODO) | | | x Min/Max (Blue->Red) | | o Max/Min (Red->Blue) | | | | x Vertical/Horizontal | | x Show/Hide | | | | Animate | | Apply OK Cancel | +-----------------------+ """ def __init__(self, data, win_parent=None): PyDialog.__init__(self, data, win_parent) self._updated_legend = False self._animation_window_shown = False self._icase = data['icase'] self._default_icase = self._icase self._default_name = data['name'] self._default_min = data['min'] self._default_max = data['max'] self._default_scale = data['default_scale'] self._scale = data['scale'] self._default_phase = data['default_phase'] self._phase = data['phase'] self._default_format = data['default_format'] self._format = data['format'] self._default_labelsize = data['default_labelsize'] self._labelsize = data['labelsize'] self._default_nlabels = data['default_nlabels'] self._nlabels = data['nlabels'] self._default_ncolors = data['default_ncolors'] self._ncolors = data['ncolors'] self._default_colormap = data['default_colormap'] self._colormap = data['colormap'] self._default_is_low_to_high = data['is_low_to_high'] self._default_is_discrete = data['is_discrete'] self._default_is_horizontal = data['is_horizontal'] self._default_is_shown = data['is_shown'] self._is_normals = data['is_normals'] self._update_defaults_to_blank() #self.setupUi(self) self.setWindowTitle('Legend Properties') self.create_widgets() self.create_layout() self.set_connections() self.set_font_size(data['font_size']) def _update_defaults_to_blank(self): """Changes the default (None) to a blank string""" if self._default_colormap is None: self._default_colormap = 'jet' if self._default_labelsize is None: self._default_labelsize = '' if self._default_ncolors is None: self._default_ncolors = '' if self._default_nlabels is None: self._default_nlabels = '' if self._colormap is None: self._colormap = 'jet' if self._labelsize is None: self._labelsize = '' if self._ncolors is None: self._ncolors = '' if self._nlabels is None: self._nlabels = '' def update_legend(self, icase, name, min_value, max_value, data_format, scale, phase, nlabels, labelsize, ncolors, colormap, default_title, default_min_value, default_max_value, default_data_format, default_scale, default_phase, default_nlabels, default_labelsize, default_ncolors, default_colormap, is_low_to_high, is_horizontal_scalar_bar, is_normals, font_size=8): """ We need to update the legend if there's been a result change request """ self.set_font_size(font_size) if icase != self._default_icase: self._icase = icase self._default_icase = icase self._default_name = default_title self._default_min = default_min_value self._default_max = default_max_value self._default_format = default_data_format self._default_is_low_to_high = is_low_to_high self._default_is_discrete = True self._default_is_horizontal = is_horizontal_scalar_bar self._default_scale = default_scale self._default_phase = default_phase self._default_nlabels = default_nlabels self._default_labelsize = default_labelsize self._default_ncolors = default_ncolors self._default_colormap = default_colormap self._is_normals = is_normals if colormap is None: colormap = 'jet' if labelsize is None: labelsize = '' if ncolors is None: ncolors = '' if nlabels is None: nlabels = '' self._update_defaults_to_blank() assert isinstance(scale, float), 'scale=%r' % scale assert isinstance(default_scale, float), 'default_scale=%r' % default_scale if self._default_scale == 0.0: self.scale.setEnabled(False) self.scale_edit.setEnabled(False) self.scale_button.setEnabled(False) else: self.scale.setEnabled(True) self.scale_edit.setEnabled(True) self.scale_button.setEnabled(True) if self._default_phase is None: self._phase = None self.phase.setEnabled(False) self.phase_edit.setEnabled(False) self.phase_button.setEnabled(False) self.phase_edit.setText('0.0') self.phase_edit.setStyleSheet("QLineEdit{background: white;}") else: self._phase = phase self.phase.setEnabled(True) self.phase_edit.setEnabled(True) self.phase_button.setEnabled(True) self.phase_edit.setText(str(phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") #self.on_default_name() #self.on_default_min() #self.on_default_max() #self.on_default_format() #self.on_default_scale() # reset defaults self._name = name self.name_edit.setText(name) self.name_edit.setStyleSheet("QLineEdit{background: white;}") self.min_edit.setText(str(min_value)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") self.max_edit.setText(str(max_value)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") self.format_edit.setText(str(data_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") self._scale = scale self.scale_edit.setText(str(scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(nlabels)) self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.labelsize_edit.setText(str(labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") self.ncolors_edit.setText(str(ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") self.colormap_edit.setCurrentIndex( colormap_keys.index(str(colormap))) # lots of hacking for the Normal vectors enable = True if self._is_normals: enable = False self.max.setVisible(enable) self.min.setVisible(enable) self.max_edit.setVisible(enable) self.min_edit.setVisible(enable) self.max_button.setVisible(enable) self.min_button.setVisible(enable) self.show_radio.setVisible(enable) self.hide_radio.setVisible(enable) self.low_to_high_radio.setVisible(enable) self.high_to_low_radio.setVisible(enable) self.format.setVisible(enable) self.format_edit.setVisible(enable) self.format_edit.setVisible(enable) self.format_button.setVisible(enable) self.nlabels.setVisible(enable) self.nlabels_edit.setVisible(enable) self.nlabels_button.setVisible(enable) self.ncolors.setVisible(enable) self.ncolors_edit.setVisible(enable) self.ncolors_button.setVisible(enable) self.grid2_title.setVisible(enable) self.vertical_radio.setVisible(enable) self.horizontal_radio.setVisible(enable) self.colormap.setVisible(enable) self.colormap_edit.setVisible(enable) self.colormap_button.setVisible(enable) self.on_apply() def create_widgets(self): """creates the menu objects""" # Name self.name = QLabel("Title:") self.name_edit = QLineEdit(str(self._default_name)) self.name_button = QPushButton("Default") # Min self.min = QLabel("Min:") self.min_edit = QLineEdit(str(self._default_min)) self.min_button = QPushButton("Default") # Max self.max = QLabel("Max:") self.max_edit = QLineEdit(str(self._default_max)) self.max_button = QPushButton("Default") #--------------------------------------- # Format self.format = QLabel("Format (e.g. %.3f, %g, %.6e):") self.format_edit = QLineEdit(str(self._format)) self.format_button = QPushButton("Default") #--------------------------------------- # Scale self.scale = QLabel("Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") if self._default_scale == 0.0: self.scale.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) # Phase self.phase = QLabel("Phase (deg):") self.phase_edit = QLineEdit(str(self._phase)) self.phase_button = QPushButton("Default") if self._default_phase is None: self.phase.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) self.phase_edit.setText('0.0') #tip = QtGui.QToolTip() #tip.setTe #self.format_edit.toolTip(tip) #--------------------------------------- # nlabels self.nlabels = QLabel("Number of Labels:") self.nlabels_edit = QLineEdit(str(self._nlabels)) self.nlabels_button = QPushButton("Default") self.labelsize = QLabel("Label Size:") self.labelsize_edit = QLineEdit(str(self._labelsize)) self.labelsize_button = QPushButton("Default") self.ncolors = QLabel("Number of Colors:") self.ncolors_edit = QLineEdit(str(self._ncolors)) self.ncolors_button = QPushButton("Default") self.colormap = QLabel("Color Map:") self.colormap_edit = QComboBox(self) self.colormap_button = QPushButton("Default") for key in colormap_keys: self.colormap_edit.addItem(key) self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap)) # -------------------------------------------------------------- # the header self.grid2_title = QLabel("Color Scale:") # red/blue or blue/red self.low_to_high_radio = QRadioButton('Low -> High') self.high_to_low_radio = QRadioButton('High -> Low') widget = QWidget(self) low_to_high_group = QButtonGroup(widget) low_to_high_group.addButton(self.low_to_high_radio) low_to_high_group.addButton(self.high_to_low_radio) self.low_to_high_radio.setChecked(self._default_is_low_to_high) self.high_to_low_radio.setChecked(not self._default_is_low_to_high) # horizontal / vertical self.horizontal_radio = QRadioButton("Horizontal") self.vertical_radio = QRadioButton("Vertical") widget = QWidget(self) horizontal_vertical_group = QButtonGroup(widget) horizontal_vertical_group.addButton(self.horizontal_radio) horizontal_vertical_group.addButton(self.vertical_radio) self.horizontal_radio.setChecked(self._default_is_horizontal) self.vertical_radio.setChecked(not self._default_is_horizontal) # on / off self.show_radio = QRadioButton("Show") self.hide_radio = QRadioButton("Hide") widget = QWidget(self) show_hide_group = QButtonGroup(widget) show_hide_group.addButton(self.show_radio) show_hide_group.addButton(self.hide_radio) self.show_radio.setChecked(self._default_is_shown) self.hide_radio.setChecked(not self._default_is_shown) # -------------------------------------------------------------- if self._is_normals: self.max.hide() self.min.hide() self.max_edit.hide() self.min_edit.hide() self.max_button.hide() self.min_button.hide() self.format.hide() self.format_edit.hide() self.format_button.hide() self.nlabels.hide() self.nlabels_edit.hide() self.nlabels_button.hide() self.ncolors.hide() self.ncolors_edit.hide() self.ncolors_button.hide() self.grid2_title.hide() self.vertical_radio.hide() self.horizontal_radio.hide() self.show_radio.hide() self.hide_radio.hide() self.low_to_high_radio.hide() self.high_to_low_radio.hide() self.colormap.hide() self.colormap_edit.hide() self.colormap_button.hide() self.animate_button = QPushButton('Create Animation') if self._default_scale == 0.0: self.animate_button.setEnabled(False) self.animate_button.setToolTip( 'This must be a displacement-like result to animate') # closing self.apply_button = QPushButton("Apply") self.ok_button = QPushButton("OK") self.cancel_button = QPushButton("Cancel") def create_layout(self): """displays the menu objects""" grid = QGridLayout() grid.addWidget(self.name, 0, 0) grid.addWidget(self.name_edit, 0, 1) grid.addWidget(self.name_button, 0, 2) grid.addWidget(self.min, 1, 0) grid.addWidget(self.min_edit, 1, 1) grid.addWidget(self.min_button, 1, 2) grid.addWidget(self.max, 2, 0) grid.addWidget(self.max_edit, 2, 1) grid.addWidget(self.max_button, 2, 2) grid.addWidget(self.format, 3, 0) grid.addWidget(self.format_edit, 3, 1) grid.addWidget(self.format_button, 3, 2) grid.addWidget(self.scale, 4, 0) grid.addWidget(self.scale_edit, 4, 1) grid.addWidget(self.scale_button, 4, 2) grid.addWidget(self.phase, 5, 0) grid.addWidget(self.phase_edit, 5, 1) grid.addWidget(self.phase_button, 5, 2) grid.addWidget(self.nlabels, 6, 0) grid.addWidget(self.nlabels_edit, 6, 1) grid.addWidget(self.nlabels_button, 6, 2) #grid.addWidget(self.labelsize, 6, 0) #grid.addWidget(self.labelsize_edit, 6, 1) #grid.addWidget(self.labelsize_button, 6, 2) grid.addWidget(self.ncolors, 7, 0) grid.addWidget(self.ncolors_edit, 7, 1) grid.addWidget(self.ncolors_button, 7, 2) grid.addWidget(self.colormap, 8, 0) grid.addWidget(self.colormap_edit, 8, 1) grid.addWidget(self.colormap_button, 8, 2) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.cancel_button) grid2 = QGridLayout() grid2.addWidget(self.grid2_title, 0, 0) grid2.addWidget(self.low_to_high_radio, 1, 0) grid2.addWidget(self.high_to_low_radio, 2, 0) grid2.addWidget(self.vertical_radio, 1, 1) grid2.addWidget(self.horizontal_radio, 2, 1) grid2.addWidget(self.show_radio, 1, 2) grid2.addWidget(self.hide_radio, 2, 2) grid2.addWidget(self.animate_button, 3, 1) #grid2.setSpacing(0) vbox = QVBoxLayout() vbox.addLayout(grid) #vbox.addLayout(checkboxes) vbox.addLayout(grid2) vbox.addStretch() vbox.addLayout(ok_cancel_box) #Create central widget, add layout and set #central_widget = QtGui.QWidget() #central_widget.setLayout(vbox) #self.setCentralWidget(central_widget) self.setLayout(vbox) def set_connections(self): """creates the actions for the buttons""" self.name_button.clicked.connect(self.on_default_name) self.min_button.clicked.connect(self.on_default_min) self.max_button.clicked.connect(self.on_default_max) self.format_button.clicked.connect(self.on_default_format) self.scale_button.clicked.connect(self.on_default_scale) self.phase_button.clicked.connect(self.on_default_phase) self.nlabels_button.clicked.connect(self.on_default_nlabels) self.labelsize_button.clicked.connect(self.on_default_labelsize) self.ncolors_button.clicked.connect(self.on_default_ncolors) self.colormap_button.clicked.connect(self.on_default_colormap) self.animate_button.clicked.connect(self.on_animate) self.show_radio.clicked.connect(self.on_show_hide) self.hide_radio.clicked.connect(self.on_show_hide) self.apply_button.clicked.connect(self.on_apply) self.ok_button.clicked.connect(self.on_ok) self.cancel_button.clicked.connect(self.on_cancel) if qt_version == 4: self.connect(self, QtCore.SIGNAL('triggered()'), self.closeEvent) #self.colormap_edit.activated[str].connect(self.onActivated) #else: # closeEvent??? def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font) self.name_edit.setFont(font) self.min_edit.setFont(font) self.max_edit.setFont(font) self.format_edit.setFont(font) self.scale_edit.setFont(font) self.phase_edit.setFont(font) self.nlabels_edit.setFont(font) self.labelsize_edit.setFont(font) self.ncolors_edit.setFont(font) def on_animate(self): """opens the animation window""" name, flag0 = self.check_name(self.name_edit) if not flag0: return scale, flag1 = self.check_float(self.scale_edit) if not flag1: scale = self._scale data = { 'font_size': self.out_data['font_size'], 'icase': self._icase, 'name': name, 'time': 2, 'frames/sec': 30, 'resolution': 1, 'iframe': 0, 'scale': scale, 'default_scale': self._default_scale, 'is_scale': self._default_phase is None, 'phase': self._phase, 'default_phase': self._default_phase, 'dirname': os.path.abspath(os.getcwd()), 'clicked_ok': False, 'close': False, } if not self._animation_window_shown: self._animation_window = AnimationWindow(data, win_parent=self) self._animation_window.show() self._animation_window_shown = True self._animation_window.exec_() else: self._animation_window.activateWindow() if data['close']: if not self._animation_window._updated_animation: #self._apply_animation(data) pass self._animation_window_shown = False del self._animation_window else: self._animation_window.activateWindow() def on_default_name(self): """action when user clicks 'Default' for name""" name = str(self._default_name) self.name_edit.setText(name) self.name_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_min(self): """action when user clicks 'Default' for min value""" self.min_edit.setText(str(self._default_min)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_max(self): """action when user clicks 'Default' for max value""" self.max_edit.setText(str(self._default_max)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_format(self): """action when user clicks 'Default' for the number format""" self.format_edit.setText(str(self._default_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_scale(self): """action when user clicks 'Default' for scale factor""" self.scale_edit.setText(str(self._default_scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_phase(self): """action when user clicks 'Default' for phase angle""" self.phase_edit.setText(str(self._default_phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_ncolors(self): """action when user clicks 'Default' for number of colors""" self.ncolors_edit.setText(str(self._default_ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_colormap(self): """action when user clicks 'Default' for the color map""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) def on_default_nlabels(self): """action when user clicks 'Default' for number of labels""" self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(self._default_nlabels)) def on_default_labelsize(self): """action when user clicks 'Default' for number of labelsize""" self.labelsize_edit.setText(str(self._default_labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") def on_show_hide(self): """action when user clicks the 'Show/Hide' radio button""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) is_shown = self.show_radio.isChecked() self.vertical_radio.setEnabled(is_shown) self.horizontal_radio.setEnabled(is_shown) @staticmethod def check_name(cell): cell_value = cell.text() try: text = str(cell_value).strip() except UnicodeEncodeError: cell.setStyleSheet("QLineEdit{background: red;}") return None, False if len(text): cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False @staticmethod def check_colormap(cell): text = str(cell.text()).strip() if text in colormap_keys: cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False def on_validate(self): name_value, flag0 = self.check_name(self.name_edit) min_value, flag1 = self.check_float(self.min_edit) max_value, flag2 = self.check_float(self.max_edit) format_value, flag3 = self.check_format(self.format_edit) scale, flag4 = self.check_float(self.scale_edit) phase, flag5 = self.check_float(self.phase_edit) nlabels, flag6 = self.check_positive_int_or_blank(self.nlabels_edit) ncolors, flag7 = self.check_positive_int_or_blank(self.ncolors_edit) labelsize, flag8 = self.check_positive_int_or_blank( self.labelsize_edit) colormap = str(self.colormap_edit.currentText()) if all([flag0, flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8]): if 'i' in format_value: format_value = '%i' assert isinstance(scale, float), scale self.out_data['name'] = name_value self.out_data['min'] = min_value self.out_data['max'] = max_value self.out_data['format'] = format_value self.out_data['scale'] = scale self.out_data['phase'] = phase self.out_data['nlabels'] = nlabels self.out_data['ncolors'] = ncolors self.out_data['labelsize'] = labelsize self.out_data['colormap'] = colormap self.out_data['is_low_to_high'] = self.low_to_high_radio.isChecked( ) self.out_data['is_horizontal'] = self.horizontal_radio.isChecked() self.out_data['is_shown'] = self.show_radio.isChecked() self.out_data['clicked_ok'] = True self.out_data['close'] = True #print('self.out_data = ', self.out_data) #print("name = %r" % self.name_edit.text()) #print("min = %r" % self.min_edit.text()) #print("max = %r" % self.max_edit.text()) #print("format = %r" % self.format_edit.text()) return True return False def on_apply(self): passed = self.on_validate() if passed: self.win_parent._apply_legend(self.out_data) return passed def on_ok(self): passed = self.on_apply() if passed: self.close() #self.destroy() def on_cancel(self): self.out_data['close'] = True self.close()
class FindOptions(QWidget): """Find widget with options""" REGEX_INVALID = "background-color:rgb(255, 175, 90);" find = Signal() stop = Signal() redirect_stdio = Signal(bool) def __init__(self, parent, search_text, search_text_regexp, search_path, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options): QWidget.__init__(self, parent) if search_path is None: search_path = getcwd() self.path = '' self.project_path = None self.file_path = None if not isinstance(search_text, (list, tuple)): search_text = [search_text] if not isinstance(search_path, (list, tuple)): search_path = [search_path] if not isinstance(exclude, (list, tuple)): exclude = [exclude] self.supported_encodings = supported_encodings # Layout 1 hlayout1 = QHBoxLayout() self.search_text = PatternComboBox(self, search_text, _("Search pattern")) self.edit_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.edit_regexp.setCheckable(True) self.edit_regexp.setChecked(search_text_regexp) self.more_widgets = () self.more_options = create_toolbutton(self, toggled=self.toggle_more_options) self.more_options.setCheckable(True) self.more_options.setChecked(more_options) self.ok_button = create_toolbutton(self, text=_("Search"), icon=ima.icon('find'), triggered=lambda: self.find.emit(), tip=_("Start search"), text_beside_icon=True) self.ok_button.clicked.connect(self.update_combos) self.stop_button = create_toolbutton( self, text=_("Stop"), icon=ima.icon('editclear'), triggered=lambda: self.stop.emit(), tip=_("Stop search"), text_beside_icon=True) self.stop_button.setEnabled(False) for widget in [ self.search_text, self.edit_regexp, self.ok_button, self.stop_button, self.more_options ]: hlayout1.addWidget(widget) # Layout 2 hlayout2 = QHBoxLayout() self.exclude_pattern = PatternComboBox(self, exclude, _("Excluded filenames pattern")) if exclude_idx is not None and exclude_idx >= 0 \ and exclude_idx < self.exclude_pattern.count(): self.exclude_pattern.setCurrentIndex(exclude_idx) self.exclude_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.exclude_regexp.setCheckable(True) self.exclude_regexp.setChecked(exclude_regexp) exclude_label = QLabel(_("Exclude:")) exclude_label.setBuddy(self.exclude_pattern) for widget in [ exclude_label, self.exclude_pattern, self.exclude_regexp ]: hlayout2.addWidget(widget) # Layout 3 hlayout3 = QHBoxLayout() self.global_path_search = QRadioButton( _("Current working " "directory"), self) self.global_path_search.setChecked(True) self.global_path_search.setToolTip( _("Search in all files and " "directories present on the" "current Spyder path")) self.project_search = QRadioButton(_("Project"), self) self.project_search.setToolTip( _("Search in all files and " "directories present on the" "current project path (If opened)")) self.project_search.setEnabled(False) self.file_search = QRadioButton(_("File"), self) self.file_search.setToolTip(_("Search in current opened file")) for wid in [ self.global_path_search, self.project_search, self.file_search ]: hlayout3.addWidget(wid) hlayout3.addStretch(1) self.search_text.valid.connect(lambda valid: self.find.emit()) self.exclude_pattern.valid.connect(lambda valid: self.find.emit()) vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addLayout(hlayout1) vlayout.addLayout(hlayout2) vlayout.addLayout(hlayout3) self.more_widgets = (hlayout2, ) self.toggle_more_options(more_options) self.setLayout(vlayout) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) @Slot(bool) def toggle_more_options(self, state): for layout in self.more_widgets: for index in range(layout.count()): if state and self.isVisible() or not state: layout.itemAt(index).widget().setVisible(state) if state: icon = ima.icon('options_less') tip = _('Hide advanced options') else: icon = ima.icon('options_more') tip = _('Show advanced options') self.more_options.setIcon(icon) self.more_options.setToolTip(tip) def update_combos(self): self.search_text.lineEdit().returnPressed.emit() self.exclude_pattern.lineEdit().returnPressed.emit() def set_search_text(self, text): if text: self.search_text.add_text(text) self.search_text.lineEdit().selectAll() self.search_text.setFocus() def get_options(self, all=False): # Getting options self.search_text.lineEdit().setStyleSheet("") self.exclude_pattern.lineEdit().setStyleSheet("") utext = to_text_string(self.search_text.currentText()) if not utext: return try: texts = [(utext.encode('utf-8'), 'utf-8')] except UnicodeEncodeError: texts = [] for enc in self.supported_encodings: try: texts.append((utext.encode(enc), enc)) except UnicodeDecodeError: pass text_re = self.edit_regexp.isChecked() exclude = to_text_string(self.exclude_pattern.currentText()) exclude_re = self.exclude_regexp.isChecked() python_path = False global_path_search = self.global_path_search.isChecked() project_search = self.project_search.isChecked() file_search = self.file_search.isChecked() if global_path_search: path = self.path elif project_search: path = self.project_path else: path = self.file_path # Finding text occurrences if not exclude_re: exclude = fnmatch.translate(exclude) else: try: exclude = re.compile(exclude) except Exception: exclude_edit = self.exclude_pattern.lineEdit() exclude_edit.setStyleSheet(self.REGEX_INVALID) return None if text_re: try: texts = [(re.compile(x[0]), x[1]) for x in texts] except Exception: self.search_text.lineEdit().setStyleSheet(self.REGEX_INVALID) return None if all: search_text = [ to_text_string(self.search_text.itemText(index)) for index in range(self.search_text.count()) ] exclude = [ to_text_string(self.exclude_pattern.itemText(index)) for index in range(self.exclude_pattern.count()) ] exclude_idx = self.exclude_pattern.currentIndex() more_options = self.more_options.isChecked() return (search_text, text_re, [], exclude, exclude_idx, exclude_re, python_path, more_options) else: return (path, file_search, exclude, texts, text_re) @Slot() def select_directory(self): """Select directory""" self.redirect_stdio.emit(False) directory = getexistingdirectory(self, _("Select directory"), self.dir_combo.currentText()) if directory: self.set_directory(directory) self.redirect_stdio.emit(True) def set_directory(self, directory): self.path = to_text_string(osp.abspath(to_text_string(directory))) def set_project_path(self, path): self.project_path = to_text_string(osp.abspath(to_text_string(path))) self.project_search.setEnabled(True) def disable_project_search(self): self.project_search.setEnabled(False) self.project_search.setChecked(False) self.project_path = None def set_file_path(self, path): self.file_path = path def keyPressEvent(self, event): """Reimplemented to handle key events""" ctrl = event.modifiers() & Qt.ControlModifier shift = event.modifiers() & Qt.ShiftModifier if event.key() in (Qt.Key_Enter, Qt.Key_Return): self.find.emit() elif event.key() == Qt.Key_F and ctrl and shift: # Toggle find widgets self.parent().toggle_visibility.emit(not self.isVisible()) else: QWidget.keyPressEvent(self, event)
class LegendPropertiesWindow(PyDialog): """ +-------------------+ | Legend Properties | +-----------------------+ | Title ______ Default | | Min ______ Default | | Max ______ Default | | Format ______ Default | | Scale ______ Default | | Phase ______ Default | | Number of Colors ____ | | Number of Labels ____ | | Label Size ____ | (TODO) | ColorMap ____ | (TODO) | | | x Min/Max (Blue->Red) | | o Max/Min (Red->Blue) | | | | x Vertical/Horizontal | | x Show/Hide | | | | Animate | | Apply OK Cancel | +-----------------------+ """ def __init__(self, data, win_parent=None, show_animation_button=True): PyDialog.__init__(self, data, win_parent) self.is_gui = win_parent is not None self._updated_legend = False self.external_call = True #if win_parent is None: self._icase_fringe = data['icase_fringe'] self._icase_disp = data['icase_disp'] self._icase_vector = data['icase_vector'] #else: #self._icase_fringe = data['icase'] #self._icase_disp = data['icase'] #self._icase_vector = data['icase'] self._default_icase_fringe = self._icase_fringe self._default_icase_disp = self._icase_disp self._default_icase_vector = self._icase_vector #print('*icase_fringe=%s icase_disp=%s icase_vector=%s' % ( #self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) self._default_title = data['title'] self._default_min = data['min_value'] self._default_max = data['max_value'] self._default_scale = data['default_scale'] self._scale = data['scale'] #if win_parent is None: self._default_arrow_scale = data['default_arrow_scale'] self._arrow_scale = data['arrow_scale'] #else: #self._default_arrow_scale = data['default_scale'] #self._arrow_scale = data['scale'] self._default_phase = data['default_phase'] self._phase = data['phase'] self._default_format = data['default_format'] self._format = data['format'] self._default_labelsize = data['default_labelsize'] self._labelsize = data['labelsize'] self._default_nlabels = data['default_nlabels'] self._nlabels = data['nlabels'] self._default_ncolors = data['default_ncolors'] self._ncolors = data['ncolors'] self._default_colormap = data['default_colormap'] self._colormap = data['colormap'] self._default_is_low_to_high = data['is_low_to_high'] self._default_is_discrete = data['is_discrete'] self._default_is_horizontal = data['is_horizontal'] self._default_is_shown = data['is_shown'] self._is_fringe = data['is_fringe'] self._update_defaults_to_blank() self.setWindowTitle('Legend Properties') self.create_widgets(show_animation_button=show_animation_button) self.create_layout() self.set_connections() self.set_font_size(data['font_size']) def _update_defaults_to_blank(self): """Changes the default (None) to a blank string""" if self._default_colormap is None: self._default_colormap = 'jet' if self._default_labelsize is None: self._default_labelsize = '' if self._default_ncolors is None: self._default_ncolors = '' if self._default_nlabels is None: self._default_nlabels = '' if self._colormap is None: self._colormap = 'jet' if self._labelsize is None: self._labelsize = '' if self._ncolors is None: self._ncolors = '' if self._nlabels is None: self._nlabels = '' def update_legend(self, icase_fringe, icase_disp, icase_vector, title, min_value, max_value, data_format, nlabels, labelsize, ncolors, colormap, is_fringe, scale, phase, arrow_scale, default_title, default_min_value, default_max_value, default_data_format, default_nlabels, default_labelsize, default_ncolors, default_colormap, default_scale, default_phase, default_arrow_scale, font_size=8, external_call=False): """ We need to update the legend if there's been a result change request """ self.external_call = external_call self.set_font_size(font_size) update_fringe = False update_disp = False update_vector = False #print('update_legend; fringe=%s disp=%s vector=%s' % ( #icase_fringe, icase_disp, icase_vector)) #print('update_legend; default: fringe=%s disp=%s vector=%s' % ( # self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) if icase_fringe != self._default_icase_fringe: self._icase_fringe = icase_fringe self._default_icase_fringe = icase_fringe update_fringe = True #is_fringe = icase_fringe is not None is_disp = icase_disp is not None is_vector = icase_vector is not None if icase_disp != self._default_icase_disp: assert isinstance( scale, float_types), 'scale=%r type=%s' % (scale, type(scale)) #assert isinstance(default_scale, float), 'default_scale=%r' % default_scale self._icase_disp = icase_disp self._default_icase_disp = icase_disp self._default_scale = default_scale self._default_phase = default_phase update_disp = True if icase_vector != self._default_icase_vector: assert isinstance( arrow_scale, float_types), 'arrow_scale=%r type=%s' % (arrow_scale, type(scale)) #assert isinstance(default_arrow_scale, float), 'default_arrow_scale=%r' % default_arrow_scale self._icase_vector = icase_vector self._default_icase_vector = icase_vector self._default_arrow_scale = default_arrow_scale update_vector = True #print('*update_legend; default: fringe=%s disp=%s vector=%s' % ( # self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) #print('update_fringe=%s update_disp=%s update_vector=%s' % ( # update_fringe, update_disp, update_vector)) #print('is_fringe=%s is_disp=%s is_vector=%s' % ( # is_fringe, is_disp, is_vector)) if update_fringe: self._icase_fringe = icase_fringe self._default_icase_fringe = icase_fringe self._default_title = default_title self._default_min = default_min_value self._default_max = default_max_value self._default_format = default_data_format #self._default_is_low_to_high = is_low_to_high self._default_is_discrete = True #self._default_is_horizontal = is_horizontal_scalar_bar self._default_nlabels = default_nlabels self._default_labelsize = default_labelsize self._default_ncolors = default_ncolors self._default_colormap = default_colormap self._is_fringe = is_fringe if colormap is None: colormap = 'jet' if labelsize is None: labelsize = '' if ncolors is None: ncolors = '' if nlabels is None: nlabels = '' self._update_defaults_to_blank() #----------------------------------------------------------------------- update = update_fringe or update_disp or update_vector if update: #self.scale_label.setEnabled(is_disp) #self.scale_edit.setEnabled(is_disp) #self.scale_button.setEnabled(is_disp) self.scale_label.setVisible(is_disp) self.scale_edit.setVisible(is_disp) self.scale_button.setVisible(is_disp) is_complex_disp = self._default_phase is not None self.phase_label.setVisible(is_complex_disp) self.phase_edit.setVisible(is_complex_disp) self.phase_button.setVisible(is_complex_disp) self._scale = set_cell_to_blank_if_value_is_none( self.scale_edit, scale) self._phase = set_cell_to_blank_if_value_is_none( self.phase_edit, phase) if self._default_icase_disp is None: # or self._default_icase_vector is None: self.animate_button.setEnabled(False) self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF) else: self.animate_button.setEnabled(True) self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON) #----------------------------------------------------------------------- if update: #self.arrow_scale_label.setEnabled(is_vector) #self.arrow_scale_edit.setEnabled(is_vector) #self.arrow_scale_button.setEnabled(is_vector) self.arrow_scale_label.setVisible(is_vector) self.arrow_scale_edit.setVisible(is_vector) self.arrow_scale_button.setVisible(is_vector) self._arrow_scale = set_cell_to_blank_if_value_is_none( self.arrow_scale_edit, arrow_scale) #----------------------------------------------------------------------- if update_fringe: #self.on_default_title() #self.on_default_min() #self.on_default_max() #self.on_default_format() #self.on_default_scale() # reset defaults self.title_edit.setText(title) self.title_edit.setStyleSheet("QLineEdit{background: white;}") self.min_edit.setText(str(min_value)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") self.max_edit.setText(str(max_value)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") self.format_edit.setText(str(data_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(nlabels)) self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.labelsize_edit.setText(str(labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") self.ncolors_edit.setText(str(ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") self.colormap_edit.setCurrentIndex( colormap_keys.index(str(colormap))) self._set_legend_fringe(self._is_fringe) if update: self.on_apply() self.external_call = True #print('---------------------------------') def clear_disp(self): """hides dispacement blocks""" self._icase_disp = None self._default_icase_disp = None self.scale_label.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) self.phase_label.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) def clear_vector(self): """hides vector blocks""" self._icase_vector = None self._default_icase_vector = None self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) def clear(self): """hides fringe, displacemnt, and vector blocks""" self._icase_fringe = None self._default_icase_fringe = None self._set_legend_fringe(False) self.clear_disp() self.clear_vector() def _set_legend_fringe(self, is_fringe): """ Show/hide buttons if we dont have a result. This is used for normals. A result can still exist (i.e., icase_fringe is not None). """ # lots of hacking for the Normal vectors self._is_fringe = is_fringe #self._default_icase_fringe = None enable = True if not is_fringe: enable = False show_title = self._icase_fringe is not None self.title_label.setVisible(show_title) self.title_edit.setVisible(show_title) self.title_button.setVisible(show_title) self.max_label.setVisible(enable) self.min_label.setVisible(enable) self.max_edit.setVisible(enable) self.min_edit.setVisible(enable) self.max_button.setVisible(enable) self.min_button.setVisible(enable) self.show_radio.setVisible(enable) self.hide_radio.setVisible(enable) self.low_to_high_radio.setVisible(enable) self.high_to_low_radio.setVisible(enable) self.format_label.setVisible(enable) self.format_edit.setVisible(enable) self.format_edit.setVisible(enable) self.format_button.setVisible(enable) self.nlabels_label.setVisible(enable) self.nlabels_edit.setVisible(enable) self.nlabels_button.setVisible(enable) self.ncolors_label.setVisible(enable) self.ncolors_edit.setVisible(enable) self.ncolors_button.setVisible(enable) self.grid2_title.setVisible(enable) self.vertical_radio.setVisible(enable) self.horizontal_radio.setVisible(enable) self.colormap_label.setVisible(enable) self.colormap_edit.setVisible(enable) self.colormap_button.setVisible(enable) def create_widgets(self, show_animation_button=True): """creates the menu objects""" # title self.title_label = QLabel("Title:") self.title_edit = QLineEdit(str(self._default_title)) self.title_button = QPushButton("Default") # Min self.min_label = QLabel("Min:") self.min_edit = QLineEdit(str(self._default_min)) self.min_button = QPushButton("Default") # Max self.max_label = QLabel("Max:") self.max_edit = QLineEdit(str(self._default_max)) self.max_button = QPushButton("Default") #--------------------------------------- # Format self.format_label = QLabel("Format (e.g. %.3f, %g, %.6e):") self.format_edit = QLineEdit(str(self._format)) self.format_button = QPushButton("Default") #--------------------------------------- # Scale self.scale_label = QLabel("True Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") if self._icase_disp is None: self.scale_label.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) # Phase self.phase_label = QLabel("Phase (deg):") self.phase_edit = QLineEdit(str(self._phase)) self.phase_button = QPushButton("Default") if self._icase_disp is None or self._default_phase is None: self.phase_label.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) self.phase_edit.setText('0.0') #--------------------------------------- self.arrow_scale_label = QLabel("Arrow Scale:") self.arrow_scale_edit = QLineEdit(str(self._arrow_scale)) self.arrow_scale_button = QPushButton("Default") if self._icase_vector is None: self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) #tip = QtGui.QToolTip() #tip.setTe #self.format_edit.toolTip(tip) #--------------------------------------- # nlabels self.nlabels_label = QLabel("Number of Labels:") self.nlabels_edit = QLineEdit(str(self._nlabels)) self.nlabels_button = QPushButton("Default") self.labelsize_label = QLabel("Label Size:") self.labelsize_edit = QLineEdit(str(self._labelsize)) self.labelsize_button = QPushButton("Default") self.ncolors_label = QLabel("Number of Colors:") self.ncolors_edit = QLineEdit(str(self._ncolors)) self.ncolors_button = QPushButton("Default") self.colormap_label = QLabel("Color Map:") self.colormap_edit = QComboBox(self) self.colormap_button = QPushButton("Default") for key in colormap_keys: self.colormap_edit.addItem(key) self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap)) # -------------------------------------------------------------- # the header self.grid2_title = QLabel("Color Scale:") # red/blue or blue/red self.low_to_high_radio = QRadioButton('Low -> High') self.high_to_low_radio = QRadioButton('High -> Low') widget = QWidget(self) low_to_high_group = QButtonGroup(widget) low_to_high_group.addButton(self.low_to_high_radio) low_to_high_group.addButton(self.high_to_low_radio) self.low_to_high_radio.setChecked(self._default_is_low_to_high) self.high_to_low_radio.setChecked(not self._default_is_low_to_high) # horizontal / vertical self.horizontal_radio = QRadioButton("Horizontal") self.vertical_radio = QRadioButton("Vertical") widget = QWidget(self) horizontal_vertical_group = QButtonGroup(widget) horizontal_vertical_group.addButton(self.horizontal_radio) horizontal_vertical_group.addButton(self.vertical_radio) self.horizontal_radio.setChecked(self._default_is_horizontal) self.vertical_radio.setChecked(not self._default_is_horizontal) # on / off self.show_radio = QRadioButton("Show") self.hide_radio = QRadioButton("Hide") widget = QWidget(self) show_hide_group = QButtonGroup(widget) show_hide_group.addButton(self.show_radio) show_hide_group.addButton(self.hide_radio) self.show_radio.setChecked(self._default_is_shown) self.hide_radio.setChecked(not self._default_is_shown) # -------------------------------------------------------------- if self._icase_fringe is None: self.title_label.setVisible(False) self.title_edit.setVisible(False) self.title_button.setVisible(False) if not self._is_fringe: self.max_label.hide() self.min_label.hide() self.max_edit.hide() self.min_edit.hide() self.max_button.hide() self.min_button.hide() self.format_label.hide() self.format_edit.hide() self.format_button.hide() self.nlabels_label.hide() self.nlabels_edit.hide() self.nlabels_button.hide() self.ncolors_label.hide() self.ncolors_edit.hide() self.ncolors_button.hide() self.grid2_title.hide() self.vertical_radio.hide() self.horizontal_radio.hide() self.show_radio.hide() self.hide_radio.hide() self.low_to_high_radio.hide() self.high_to_low_radio.hide() self.colormap_label.hide() self.colormap_edit.hide() self.colormap_button.hide() self.animate_button = QPushButton('Create Animation') self.animate_button.setVisible(show_animation_button) #self.advanced_button = QPushButton('Advanced') if self._default_icase_disp is None: # or self._default_icase_vector is None: self.animate_button.setEnabled(False) self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF) else: self.animate_button.setEnabled(True) self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON) # closing self.apply_button = QPushButton("Apply") self.ok_button = QPushButton("OK") self.cancel_button = QPushButton("Cancel") def create_layout(self): """displays the menu objects""" grid = QGridLayout() grid.addWidget(self.title_label, 0, 0) grid.addWidget(self.title_edit, 0, 1) grid.addWidget(self.title_button, 0, 2) grid.addWidget(self.min_label, 1, 0) grid.addWidget(self.min_edit, 1, 1) grid.addWidget(self.min_button, 1, 2) grid.addWidget(self.max_label, 2, 0) grid.addWidget(self.max_edit, 2, 1) grid.addWidget(self.max_button, 2, 2) grid.addWidget(self.format_label, 3, 0) grid.addWidget(self.format_edit, 3, 1) grid.addWidget(self.format_button, 3, 2) grid.addWidget(self.scale_label, 4, 0) grid.addWidget(self.scale_edit, 4, 1) grid.addWidget(self.scale_button, 4, 2) grid.addWidget(self.phase_label, 6, 0) grid.addWidget(self.phase_edit, 6, 1) grid.addWidget(self.phase_button, 6, 2) grid.addWidget(self.arrow_scale_label, 5, 0) grid.addWidget(self.arrow_scale_edit, 5, 1) grid.addWidget(self.arrow_scale_button, 5, 2) grid.addWidget(self.nlabels_label, 7, 0) grid.addWidget(self.nlabels_edit, 7, 1) grid.addWidget(self.nlabels_button, 7, 2) #grid.addWidget(self.labelsize_label, 6, 0) #grid.addWidget(self.labelsize_edit, 6, 1) #grid.addWidget(self.labelsize_button, 6, 2) grid.addWidget(self.ncolors_label, 8, 0) grid.addWidget(self.ncolors_edit, 8, 1) grid.addWidget(self.ncolors_button, 8, 2) grid.addWidget(self.colormap_label, 9, 0) grid.addWidget(self.colormap_edit, 9, 1) grid.addWidget(self.colormap_button, 9, 2) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.cancel_button) grid2 = QGridLayout() grid2.addWidget(self.grid2_title, 0, 0) grid2.addWidget(self.low_to_high_radio, 1, 0) grid2.addWidget(self.high_to_low_radio, 2, 0) grid2.addWidget(self.vertical_radio, 1, 1) grid2.addWidget(self.horizontal_radio, 2, 1) grid2.addWidget(self.show_radio, 1, 2) grid2.addWidget(self.hide_radio, 2, 2) grid2.addWidget(self.animate_button, 3, 1) #grid2.setSpacing(0) vbox = QVBoxLayout() vbox.addLayout(grid) #vbox.addLayout(checkboxes) vbox.addLayout(grid2) vbox.addStretch() vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def set_connections(self): """creates the actions for the menu""" self.title_button.clicked.connect(self.on_default_title) self.min_button.clicked.connect(self.on_default_min) self.max_button.clicked.connect(self.on_default_max) self.format_button.clicked.connect(self.on_default_format) self.scale_button.clicked.connect(self.on_default_scale) self.arrow_scale_button.clicked.connect(self.on_default_arrow_scale) self.phase_button.clicked.connect(self.on_default_phase) self.nlabels_button.clicked.connect(self.on_default_nlabels) self.labelsize_button.clicked.connect(self.on_default_labelsize) self.ncolors_button.clicked.connect(self.on_default_ncolors) self.colormap_button.clicked.connect(self.on_default_colormap) self.animate_button.clicked.connect(self.on_animate) self.show_radio.clicked.connect(self.on_show_hide) self.hide_radio.clicked.connect(self.on_show_hide) self.apply_button.clicked.connect(self.on_apply) self.ok_button.clicked.connect(self.on_ok) self.cancel_button.clicked.connect(self.on_cancel) def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font) self.title_edit.setFont(font) self.min_edit.setFont(font) self.max_edit.setFont(font) self.format_edit.setFont(font) self.scale_edit.setFont(font) self.phase_edit.setFont(font) self.nlabels_edit.setFont(font) self.labelsize_edit.setFont(font) self.ncolors_edit.setFont(font) def on_animate(self): """opens the animation window""" title, flag0 = check_name_str(self.title_edit) if not flag0: return scale, flag1 = check_float(self.scale_edit) if not flag1: scale = self._scale data = { 'font_size': self.out_data['font_size'], 'icase_fringe': self._icase_fringe, 'icase_disp': self._icase_disp, 'icase_vector': self._icase_vector, 'title': title, 'time': 2, 'frames/sec': 30, 'resolution': 1, 'iframe': 0, 'scale': scale, 'default_scale': self._default_scale, 'arrow_scale': scale, 'default_arrow_scale': self._default_arrow_scale, 'is_scale': self._default_phase is None, 'phase': self._phase, 'default_phase': self._default_phase, 'dirname': os.path.abspath(os.getcwd()), 'clicked_ok': False, 'close': False, } self.win_parent.legend_obj.set_animation_window(data) def on_default_title(self): """action when user clicks 'Default' for title""" title = str(self._default_title) self.title_edit.setText(title) self.title_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_min(self): """action when user clicks 'Default' for min value""" self.min_edit.setText(str(self._default_min)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_max(self): """action when user clicks 'Default' for max value""" self.max_edit.setText(str(self._default_max)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_format(self): """action when user clicks 'Default' for the number format""" self.format_edit.setText(str(self._default_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_scale(self): """action when user clicks 'Default' for scale factor""" self.scale_edit.setText(str(self._default_scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_arrow_scale(self): """action when user clicks 'Default' for arrow_scale factor""" self.arrow_scale_edit.setText(str(self._default_arrow_scale)) self.arrow_scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_phase(self): """action when user clicks 'Default' for phase angle""" self.phase_edit.setText(str(self._default_phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_ncolors(self): """action when user clicks 'Default' for number of colors""" self.ncolors_edit.setText(str(self._default_ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_colormap(self): """action when user clicks 'Default' for the color map""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) def on_default_nlabels(self): """action when user clicks 'Default' for number of labels""" self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(self._default_nlabels)) def on_default_labelsize(self): """action when user clicks 'Default' for number of labelsize""" self.labelsize_edit.setText(str(self._default_labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") def on_show_hide(self): """action when user clicks the 'Show/Hide' radio button""" #self.colormap_edit.setCurrentIndex(colormap_keys.index(self._default_colormap)) is_shown = self.show_radio.isChecked() self.nlabels_edit.setEnabled(is_shown) self.nlabels_button.setEnabled(is_shown) self.ncolors_edit.setEnabled(is_shown) self.ncolors_button.setEnabled(is_shown) self.high_to_low_radio.setEnabled(is_shown) self.low_to_high_radio.setEnabled(is_shown) self.colormap_edit.setEnabled(is_shown) self.colormap_button.setEnabled(is_shown) self.vertical_radio.setEnabled(is_shown) self.horizontal_radio.setEnabled(is_shown) def show_legend(self): """shows the legend""" self._set_legend(True) def hide_legend(self): """hides the legend""" self._set_legend(False) def _set_legend(self, is_shown): """shows/hides the legend""" self.show_radio.setChecked(is_shown) self.hide_radio.setChecked(not is_shown) #if self.is_gui: #self.win_parent.scalar_bar_actor.SetVisibility(is_shown) def on_validate(self): """checks to see if the ``on_apply`` method can be called""" show_title = self._icase_fringe is not None flag_title = True title_value = '' if show_title: title_value, flag_title = check_name_str(self.title_edit) flag_fringe = True min_value = max_value = format_value = nlabels = ncolors = labelsize = colormap = None if self._icase_fringe is not None: min_value, flag1 = check_float(self.min_edit) max_value, flag2 = check_float(self.max_edit) format_value, flag3 = check_format(self.format_edit) nlabels, flag4 = check_positive_int_or_blank(self.nlabels_edit) ncolors, flag5 = check_positive_int_or_blank(self.ncolors_edit) labelsize, flag6 = check_positive_int_or_blank(self.labelsize_edit) colormap = str(self.colormap_edit.currentText()) if flag3 and 'i' in format_value: format_value = '%i' flag_fringe = all([flag1, flag2, flag3, flag4, flag5, flag6]) flag_disp = True scale = phase = None if self._icase_disp is not None: scale, flag1 = check_float(self.scale_edit) phase, flag2 = check_float(self.phase_edit) assert isinstance(scale, float), scale flag_disp = all([flag1, flag2]) flag_vector = True arrow_scale = None if self._icase_vector is not None: arrow_scale, flag_vector = check_float(self.arrow_scale_edit) if all([flag_title, flag_fringe, flag_disp, flag_vector]): self.out_data['title'] = title_value self.out_data['min_value'] = min_value self.out_data['max_value'] = max_value self.out_data['format'] = format_value self.out_data['scale'] = scale self.out_data['phase'] = phase self.out_data['arrow_scale'] = arrow_scale self.out_data['nlabels'] = nlabels self.out_data['ncolors'] = ncolors self.out_data['labelsize'] = labelsize self.out_data['colormap'] = colormap self.out_data['is_low_to_high'] = self.low_to_high_radio.isChecked( ) self.out_data['is_horizontal'] = self.horizontal_radio.isChecked() self.out_data['is_shown'] = self.show_radio.isChecked() self.out_data['clicked_ok'] = True self.out_data['close'] = True #print('self.out_data = ', self.out_data) #print("title = %r" % self.title_edit.text()) #print("min = %r" % self.min_edit.text()) #print("max = %r" % self.max_edit.text()) #print("format = %r" % self.format_edit.text()) return True return False def on_apply(self): """applies the current values""" passed = self.on_validate() if passed and self.external_call: self.win_parent.legend_obj._apply_legend(self.out_data) self.external_call = True return passed def on_ok(self): """applies the current values and closes the window""" passed = self.on_apply() if passed: self.close() #self.destroy() def on_cancel(self): """closes the windows and reverts the legend""" self.out_data['close'] = True self.close()
class MCSDialog(QDialog): """A dialog to perform minimal cut set computation""" def __init__(self, appdata: CnaData, centralwidget): QDialog.__init__(self) self.setWindowTitle("Minimal Cut Sets Computation") self.appdata = appdata self.centralwidget = centralwidget self.eng = appdata.engine self.out = io.StringIO() self.err = io.StringIO() self.layout = QVBoxLayout() l1 = QLabel("Target Region(s)") self.layout.addWidget(l1) s1 = QHBoxLayout() completer = QCompleter( self.appdata.project.cobra_py_model.reactions.list_attr("id"), self) completer.setCaseSensitivity(Qt.CaseInsensitive) self.target_list = QTableWidget(1, 4) self.target_list.setHorizontalHeaderLabels( ["region no", "T", "≥/≤", "t"]) self.target_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.target_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed) self.target_list.horizontalHeader().resizeSection(0, 100) self.target_list.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed) self.target_list.horizontalHeader().resizeSection(2, 50) item = QLineEdit("1") self.target_list.setCellWidget(0, 0, item) item2 = QLineEdit("") item2.setCompleter(completer) self.target_list.setCellWidget(0, 1, item2) combo = QComboBox(self.target_list) combo.insertItem(1, "≤") combo.insertItem(2, "≥") self.target_list.setCellWidget(0, 2, combo) item = QLineEdit("0") self.target_list.setCellWidget(0, 3, item) s1.addWidget(self.target_list) s11 = QVBoxLayout() self.add_target = QPushButton("+") self.add_target.clicked.connect(self.add_target_region) self.rem_target = QPushButton("-") self.rem_target.clicked.connect(self.rem_target_region) s11.addWidget(self.add_target) s11.addWidget(self.rem_target) s1.addItem(s11) self.layout.addItem(s1) l2 = QLabel("Desired Region(s)") self.layout.addWidget(l2) s2 = QHBoxLayout() self.desired_list = QTableWidget(1, 4) self.desired_list.setHorizontalHeaderLabels( ["region no", "D", "≥/≤", "d"]) self.desired_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.desired_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed) self.desired_list.horizontalHeader().resizeSection(0, 100) self.desired_list.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed) self.desired_list.horizontalHeader().resizeSection(2, 50) item = QLineEdit("1") self.desired_list.setCellWidget(0, 0, item) item2 = QLineEdit("") item2.setCompleter(completer) self.desired_list.setCellWidget(0, 1, item2) combo = QComboBox(self.desired_list) combo.insertItem(1, "≤") combo.insertItem(2, "≥") self.desired_list.setCellWidget(0, 2, combo) item = QLineEdit("0") self.desired_list.setCellWidget(0, 3, item) s2.addWidget(self.desired_list) s21 = QVBoxLayout() self.add_desire = QPushButton("+") self.add_desire.clicked.connect(self.add_desired_region) self.rem_desire = QPushButton("-") self.rem_desire.clicked.connect(self.rem_desired_region) s21.addWidget(self.add_desire) s21.addWidget(self.rem_desire) s2.addItem(s21) self.layout.addItem(s2) s3 = QHBoxLayout() sgx = QVBoxLayout() self.gen_kos = QCheckBox("Gene KOs") self.exclude_boundary = QCheckBox( "Exclude boundary\nreactions as cuts") sg1 = QHBoxLayout() s31 = QVBoxLayout() l = QLabel("Max. Solutions") s31.addWidget(l) l = QLabel("Max. Size") s31.addWidget(l) l = QLabel("Time Limit [sec]") s31.addWidget(l) sg1.addItem(s31) s32 = QVBoxLayout() self.max_solu = QLineEdit("inf") self.max_solu.setMaximumWidth(50) s32.addWidget(self.max_solu) self.max_size = QLineEdit("7") self.max_size.setMaximumWidth(50) s32.addWidget(self.max_size) self.time_limit = QLineEdit("inf") self.time_limit.setMaximumWidth(50) s32.addWidget(self.time_limit) sg1.addItem(s32) sgx.addWidget(self.gen_kos) sgx.addWidget(self.exclude_boundary) sgx.addItem(sg1) s3.addItem(sgx) g3 = QGroupBox("Solver") s33 = QVBoxLayout() self.bg1 = QButtonGroup() optlang_solver_name = interface_to_str( appdata.project.cobra_py_model.problem) self.solver_optlang = QRadioButton(f"{optlang_solver_name} (optlang)") self.solver_optlang.setToolTip( "Uses the solver specified by the current model.") s33.addWidget(self.solver_optlang) self.bg1.addButton(self.solver_optlang) self.solver_cplex_matlab = QRadioButton("CPLEX (MATLAB)") self.solver_cplex_matlab.setToolTip( "Only enabled with MATLAB and CPLEX") s33.addWidget(self.solver_cplex_matlab) self.bg1.addButton(self.solver_cplex_matlab) self.solver_cplex_java = QRadioButton("CPLEX (Octave)") self.solver_cplex_java.setToolTip("Only enabled with Octave and CPLEX") s33.addWidget(self.solver_cplex_java) self.bg1.addButton(self.solver_cplex_java) self.solver_intlinprog = QRadioButton("intlinprog (MATLAB)") self.solver_intlinprog.setToolTip("Only enabled with MATLAB") s33.addWidget(self.solver_intlinprog) self.bg1.addButton(self.solver_intlinprog) self.solver_glpk = QRadioButton("GLPK (Octave/MATLAB)") s33.addWidget(self.solver_glpk) self.bg1.addButton(self.solver_glpk) self.bg1.buttonClicked.connect(self.configure_solver_options) g3.setLayout(s33) s3.addWidget(g3) g4 = QGroupBox("MCS search") s34 = QVBoxLayout() self.bg2 = QButtonGroup() self.any_mcs = QRadioButton("any MCS (fast)") self.any_mcs.setChecked(True) s34.addWidget(self.any_mcs) self.bg2.addButton(self.any_mcs) # Search type: by cardinality only with CPLEX possible self.mcs_by_cardinality = QRadioButton("by cardinality") s34.addWidget(self.mcs_by_cardinality) self.bg2.addButton(self.mcs_by_cardinality) self.smalles_mcs_first = QRadioButton("smallest MCS first") s34.addWidget(self.smalles_mcs_first) self.bg2.addButton(self.smalles_mcs_first) g4.setLayout(s34) s3.addWidget(g4) self.layout.addItem(s3) # Disable incompatible combinations if appdata.selected_engine == 'None': self.solver_optlang.setChecked(True) self.solver_cplex_matlab.setEnabled(False) self.solver_cplex_java.setEnabled(False) self.solver_glpk.setEnabled(False) self.solver_intlinprog.setEnabled(False) if optlang_solver_name != 'cplex': self.mcs_by_cardinality.setEnabled(False) else: self.solver_glpk.setChecked(True) if not self.eng.is_cplex_matlab_ready(): self.solver_cplex_matlab.setEnabled(False) if not self.eng.is_cplex_java_ready(): self.solver_cplex_java.setEnabled(False) if self.appdata.is_matlab_set(): self.solver_cplex_java.setEnabled(False) if not self.appdata.is_matlab_set(): self.solver_cplex_matlab.setEnabled(False) self.solver_intlinprog.setEnabled(False) self.configure_solver_options() s4 = QVBoxLayout() self.consider_scenario = QCheckBox( "Consider constraint given by scenario") s4.addWidget(self.consider_scenario) self.advanced = QCheckBox( "Advanced: Define knockout/addition costs for genes/reactions") self.advanced.setEnabled(False) s4.addWidget(self.advanced) self.layout.addItem(s4) buttons = QHBoxLayout() # self.save = QPushButton("save") # buttons.addWidget(self.save) # self.load = QPushButton("load") # buttons.addWidget(self.load) self.compute_mcs = QPushButton("Compute MCS") buttons.addWidget(self.compute_mcs) # self.compute_mcs2 = QPushButton("Compute MCS2") # buttons.addWidget(self.compute_mcs2) self.cancel = QPushButton("Close") buttons.addWidget(self.cancel) self.layout.addItem(buttons) # max width for buttons self.add_target.setMaximumWidth(20) self.rem_target.setMaximumWidth(20) self.add_desire.setMaximumWidth(20) self.rem_desire.setMaximumWidth(20) self.setLayout(self.layout) # Connecting the signal self.cancel.clicked.connect(self.reject) self.compute_mcs.clicked.connect(self.compute) @Slot() def configure_solver_options(self): optlang_solver_name = interface_to_str( self.appdata.project.cobra_py_model.problem) if self.solver_optlang.isChecked(): self.gen_kos.setChecked(False) self.gen_kos.setEnabled(False) self.exclude_boundary.setEnabled(True) if optlang_solver_name != 'cplex': if self.mcs_by_cardinality.isChecked(): self.mcs_by_cardinality.setChecked(False) self.any_mcs.setChecked(True) self.mcs_by_cardinality.setEnabled(False) self.mcs_by_cardinality.setChecked(False) else: self.gen_kos.setEnabled(True) self.exclude_boundary.setChecked(False) self.exclude_boundary.setEnabled(False) self.mcs_by_cardinality.setEnabled(True) def add_target_region(self): i = self.target_list.rowCount() self.target_list.insertRow(i) completer = QCompleter( self.appdata.project.cobra_py_model.reactions.list_attr("id"), self) completer.setCaseSensitivity(Qt.CaseInsensitive) item = QLineEdit("1") self.target_list.setCellWidget(i, 0, item) item2 = QLineEdit("") item2.setCompleter(completer) self.target_list.setCellWidget(i, 1, item2) combo = QComboBox(self.target_list) combo.insertItem(1, "≤") combo.insertItem(2, "≥") self.target_list.setCellWidget(i, 2, combo) item = QLineEdit("0") self.target_list.setCellWidget(i, 3, item) def add_desired_region(self): i = self.desired_list.rowCount() self.desired_list.insertRow(i) completer = QCompleter( self.appdata.project.cobra_py_model.reactions.list_attr("id"), self) completer.setCaseSensitivity(Qt.CaseInsensitive) item = QLineEdit("1") self.desired_list.setCellWidget(i, 0, item) item2 = QLineEdit("") item2.setCompleter(completer) self.desired_list.setCellWidget(i, 1, item2) combo = QComboBox(self.desired_list) combo.insertItem(1, "≤") combo.insertItem(2, "≥") self.desired_list.setCellWidget(i, 2, combo) item = QLineEdit("0") self.desired_list.setCellWidget(i, 3, item) def rem_target_region(self): i = self.target_list.rowCount() self.target_list.removeRow(i-1) def rem_desired_region(self): i = self.desired_list.rowCount() self.desired_list.removeRow(i-1) def compute(self): if self.solver_optlang.isChecked(): self.compute_optlang() else: self.compute_legacy() def compute_legacy(self): self.setCursor(Qt.BusyCursor) # create CobraModel for matlab with self.appdata.project.cobra_py_model as model: if self.consider_scenario.isChecked(): # integrate scenario into model bounds for r in self.appdata.project.scen_values.keys(): model.reactions.get_by_id( r).bounds = self.appdata.project.scen_values[r] cobra.io.save_matlab_model(model, os.path.join( self.appdata.cna_path, "cobra_model.mat"), varname="cbmodel") self.eng.eval("load('cobra_model.mat')", nargout=0) try: self.eng.eval("cnap = CNAcobra2cna(cbmodel);", nargout=0, stdout=self.out, stderr=self.err) except Exception: output = io.StringIO() traceback.print_exc(file=output) exstr = output.getvalue() print(exstr) QMessageBox.warning(self, 'Unknown exception occured!', exstr+'\nPlease report the problem to:\n\ \nhttps://github.com/cnapy-org/CNApy/issues') return self.eng.eval("genes = [];", nargout=0, stdout=self.out, stderr=self.err) cmd = "maxSolutions = " + str(float(self.max_solu.text())) + ";" self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err) cmd = "maxSize = " + str(int(self.max_size.text())) + ";" self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err) cmd = "milp_time_limit = " + str(float(self.time_limit.text())) + ";" self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err) if self.gen_kos.isChecked(): self.eng.eval("gKOs = 1;", nargout=0) else: self.eng.eval("gKOs = 0;", nargout=0) if self.advanced.isChecked(): self.eng.eval("advanced_on = 1;", nargout=0) else: self.eng.eval("advanced_on = 0;", nargout=0) if self.solver_intlinprog.isChecked(): self.eng.eval("solver = 'intlinprog';", nargout=0) if self.solver_cplex_java.isChecked(): self.eng.eval("solver = 'java_cplex_new';", nargout=0) if self.solver_cplex_matlab.isChecked(): self.eng.eval("solver = 'matlab_cplex';", nargout=0) if self.solver_glpk.isChecked(): self.eng.eval("solver = 'glpk';", nargout=0) if self.any_mcs.isChecked(): self.eng.eval("mcs_search_mode = 'search_1';", nargout=0) elif self.mcs_by_cardinality.isChecked(): self.eng.eval("mcs_search_mode = 'search_2';", nargout=0) elif self.smalles_mcs_first.isChecked(): self.eng.eval("mcs_search_mode = 'search_3';", nargout=0) rows = self.target_list.rowCount() for i in range(0, rows): p1 = self.target_list.cellWidget(i, 0).text() p2 = self.target_list.cellWidget(i, 1).text() if self.target_list.cellWidget(i, 2).currentText() == '≤': p3 = "<=" else: p3 = ">=" p4 = self.target_list.cellWidget(i, 3).text() cmd = "dg_T = {[" + p1+"], '" + p2 + \ "', '" + p3 + "', [" + p4 + "']};" self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err) rows = self.desired_list.rowCount() for i in range(0, rows): p1 = self.desired_list.cellWidget(i, 0).text() p2 = self.desired_list.cellWidget(i, 1).text() if self.desired_list.cellWidget(i, 2).currentText() == '≤': p3 = "<=" else: p3 = ">=" p4 = self.desired_list.cellWidget(i, 3).text() cmd = "dg_D = {[" + p1+"], '" + p2 + \ "', '" + p3 + "', [" + p4 + "']};" self.eng.eval(cmd, nargout=0) # get some data self.eng.eval("reac_id = cellstr(cnap.reacID).';", nargout=0, stdout=self.out, stderr=self.err) mcs = [] values = [] reactions = [] reac_id = [] if self.appdata.is_matlab_set(): reac_id = self.eng.workspace['reac_id'] try: self.eng.eval("[mcs] = cnapy_compute_mcs(cnap, genes, maxSolutions, maxSize, milp_time_limit, gKOs, advanced_on, solver, mcs_search_mode, dg_T,dg_D);", nargout=0) except Exception: output = io.StringIO() traceback.print_exc(file=output) exstr = output.getvalue() print(exstr) QMessageBox.warning(self, 'Unknown exception occured!', exstr+'\nPlease report the problem to:\n\ \nhttps://github.com/cnapy-org/CNApy/issues') return else: self.eng.eval("[reaction, mcs, value] = find(mcs);", nargout=0, stdout=self.out, stderr=self.err) reactions = self.eng.workspace['reaction'] mcs = self.eng.workspace['mcs'] values = self.eng.workspace['value'] elif self.appdata.is_octave_ready(): reac_id = self.eng.pull('reac_id') reac_id = reac_id[0] try: self.eng.eval("[mcs] = cnapy_compute_mcs(cnap, genes, maxSolutions, maxSize, milp_time_limit, gKOs, advanced_on, solver, mcs_search_mode, dg_T,dg_D);", nargout=0) except Exception: output = io.StringIO() traceback.print_exc(file=output) exstr = output.getvalue() print(exstr) QMessageBox.warning(self, 'Unknown exception occured!', exstr+'\nPlease report the problem to:\n\ \nhttps://github.com/cnapy-org/CNApy/issues') return else: self.eng.eval("[reaction, mcs, value] = find(mcs);", nargout=0, stdout=self.out, stderr=self.err) reactions = self.eng.pull('reaction') mcs = self.eng.pull('mcs') values = self.eng.pull('value') if len(mcs) == 0: QMessageBox.information(self, 'No cut sets', 'Cut sets have not been calculated or do not exist.') else: last_mcs = 1 omcs = [] current_mcs = {} for i in range(0, len(reactions)): reacid = int(reactions[i][0]) reaction = reac_id[reacid-1] c_mcs = int(mcs[i][0]) c_value = int(values[i][0]) if c_value == -1: # -1 stands for removed which is 0 in the ui c_value = 0 if c_mcs > last_mcs: omcs.append(current_mcs) last_mcs = c_mcs current_mcs = {} current_mcs[reaction] = c_value omcs.append(current_mcs) self.appdata.project.modes = omcs self.centralwidget.mode_navigator.current = 0 QMessageBox.information(self, 'Cut sets found', str(len(omcs))+' Cut sets have been calculated.') self.centralwidget.update_mode() self.centralwidget.mode_navigator.title.setText("MCS Navigation") self.setCursor(Qt.ArrowCursor) def compute_optlang(self): self.setCursor(Qt.BusyCursor) max_mcs_num = float(self.max_solu.text()) max_mcs_size = int(self.max_size.text()) timeout = float(self.time_limit.text()) if timeout is float('inf'): timeout = None # if self.gen_kos.isChecked(): # self.eng.eval("gKOs = 1;", nargout=0) # else: # self.eng.eval("gKOs = 0;", nargout=0) # if self.advanced.isChecked(): # self.eng.eval("advanced_on = 1;", nargout=0) # else: # self.eng.eval("advanced_on = 0;", nargout=0) if self.smalles_mcs_first.isChecked(): enum_method = 1 elif self.mcs_by_cardinality.isChecked(): enum_method = 2 elif self.any_mcs.isChecked(): enum_method = 3 with self.appdata.project.cobra_py_model as model: if self.consider_scenario.isChecked(): # integrate scenario into model bounds for r in self.appdata.project.scen_values.keys(): model.reactions.get_by_id( r).bounds = self.appdata.project.scen_values[r] reac_id = model.reactions.list_attr("id") reac_id_symbols = cMCS_enumerator.get_reac_id_symbols(reac_id) rows = self.target_list.rowCount() targets = dict() for i in range(0, rows): p1 = self.target_list.cellWidget(i, 0).text() p2 = self.target_list.cellWidget(i, 1).text() if len(p1) > 0 and len(p2) > 0: if self.target_list.cellWidget(i, 2).currentText() == '≤': p3 = "<=" else: p3 = ">=" p4 = float(self.target_list.cellWidget(i, 3).text()) targets.setdefault(p1, []).append((p2, p3, p4)) targets = list(targets.values()) targets = [cMCS_enumerator.relations2leq_matrix(cMCS_enumerator.parse_relations( t, reac_id_symbols=reac_id_symbols), reac_id) for t in targets] rows = self.desired_list.rowCount() desired = dict() for i in range(0, rows): p1 = self.desired_list.cellWidget(i, 0).text() p2 = self.desired_list.cellWidget(i, 1).text() if len(p1) > 0 and len(p2) > 0: if self.desired_list.cellWidget(i, 2).currentText() == '≤': p3 = "<=" else: p3 = ">=" p4 = float(self.desired_list.cellWidget(i, 3).text()) desired.setdefault(p1, []).append((p2, p3, p4)) desired = list(desired.values()) desired = [cMCS_enumerator.relations2leq_matrix(cMCS_enumerator.parse_relations( d, reac_id_symbols=reac_id_symbols), reac_id) for d in desired] try: mcs = cMCS_enumerator.compute_mcs(model, targets=targets, desired=desired, enum_method=enum_method, max_mcs_size=max_mcs_size, max_mcs_num=max_mcs_num, timeout=timeout, exclude_boundary_reactions_as_cuts=self.exclude_boundary.isChecked()) except cMCS_enumerator.InfeasibleRegion as e: QMessageBox.warning(self, 'Cannot calculate MCS', str(e)) return targets, desired except Exception: output = io.StringIO() traceback.print_exc(file=output) exstr = output.getvalue() print(exstr) QMessageBox.warning(self, 'An exception has occured!', exstr+'\nPlease report the problem to:\n\ \nhttps://github.com/cnapy-org/CNApy/issues') return targets, desired finally: self.setCursor(Qt.ArrowCursor) if len(mcs) == 0: QMessageBox.information(self, 'No cut sets', 'Cut sets have not been calculated or do not exist.') return targets, desired omcs = [{reac_id[i]: 0 for i in m} for m in mcs] self.appdata.project.modes = omcs self.centralwidget.mode_navigator.current = 0 QMessageBox.information(self, 'Cut sets found', str(len(omcs))+' Cut sets have been calculated.') self.centralwidget.update_mode() self.centralwidget.mode_navigator.title.setText("MCS Navigation")
class FindOptions(QWidget): """Find widget with options""" find = Signal() stop = Signal() def __init__(self, parent, search_text, search_text_regexp, search_path, include, include_idx, include_regexp, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options): QWidget.__init__(self, parent) if search_path is None: search_path = getcwd() if not isinstance(search_text, (list, tuple)): search_text = [search_text] if not isinstance(search_path, (list, tuple)): search_path = [search_path] if not isinstance(include, (list, tuple)): include = [include] if not isinstance(exclude, (list, tuple)): exclude = [exclude] self.supported_encodings = supported_encodings # Layout 1 hlayout1 = QHBoxLayout() self.search_text = PatternComboBox(self, search_text, _("Search pattern")) self.edit_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.edit_regexp.setCheckable(True) self.edit_regexp.setChecked(search_text_regexp) self.more_widgets = () self.more_options = create_toolbutton(self, toggled=self.toggle_more_options) self.more_options.setCheckable(True) self.more_options.setChecked(more_options) self.ok_button = create_toolbutton(self, text=_("Search"), icon=ima.icon('DialogApplyButton'), triggered=lambda: self.find.emit(), tip=_("Start search"), text_beside_icon=True) self.ok_button.clicked.connect(self.update_combos) self.stop_button = create_toolbutton( self, text=_("Stop"), icon=ima.icon('stop'), triggered=lambda: self.stop.emit(), tip=_("Stop search"), text_beside_icon=True) self.stop_button.setEnabled(False) for widget in [ self.search_text, self.edit_regexp, self.ok_button, self.stop_button, self.more_options ]: hlayout1.addWidget(widget) # Layout 2 hlayout2 = QHBoxLayout() self.include_pattern = PatternComboBox(self, include, _("Included filenames pattern")) if include_idx is not None and include_idx >= 0 \ and include_idx < self.include_pattern.count(): self.include_pattern.setCurrentIndex(include_idx) self.include_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.include_regexp.setCheckable(True) self.include_regexp.setChecked(include_regexp) include_label = QLabel(_("Include:")) include_label.setBuddy(self.include_pattern) self.exclude_pattern = PatternComboBox(self, exclude, _("Excluded filenames pattern")) if exclude_idx is not None and exclude_idx >= 0 \ and exclude_idx < self.exclude_pattern.count(): self.exclude_pattern.setCurrentIndex(exclude_idx) self.exclude_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.exclude_regexp.setCheckable(True) self.exclude_regexp.setChecked(exclude_regexp) exclude_label = QLabel(_("Exclude:")) exclude_label.setBuddy(self.exclude_pattern) for widget in [ include_label, self.include_pattern, self.include_regexp, exclude_label, self.exclude_pattern, self.exclude_regexp ]: hlayout2.addWidget(widget) # Layout 3 hlayout3 = QHBoxLayout() self.python_path = QRadioButton(_("PYTHONPATH"), self) self.python_path.setChecked(in_python_path) self.python_path.setToolTip( _("Search in all directories listed in sys.path which" " are outside the Python installation directory")) self.hg_manifest = QRadioButton(_("Hg repository"), self) self.detect_hg_repository() self.hg_manifest.setToolTip( _("Search in current directory hg repository")) self.custom_dir = QRadioButton(_("Here:"), self) self.custom_dir.setChecked(not in_python_path) self.dir_combo = PathComboBox(self) self.dir_combo.addItems(search_path) self.dir_combo.setToolTip(_("Search recursively in this directory")) self.dir_combo.open_dir.connect(self.set_directory) self.python_path.toggled.connect(self.dir_combo.setDisabled) self.hg_manifest.toggled.connect(self.dir_combo.setDisabled) browse = create_toolbutton(self, icon=ima.icon('DirOpenIcon'), tip=_('Browse a search directory'), triggered=self.select_directory) for widget in [ self.python_path, self.hg_manifest, self.custom_dir, self.dir_combo, browse ]: hlayout3.addWidget(widget) self.search_text.valid.connect(lambda valid: self.find.emit()) vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addLayout(hlayout1) vlayout.addLayout(hlayout2) vlayout.addLayout(hlayout3) self.more_widgets = (hlayout2, hlayout3) self.toggle_more_options(more_options) self.setLayout(vlayout) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) @Slot(bool) def toggle_more_options(self, state): for layout in self.more_widgets: for index in range(layout.count()): if state and self.isVisible() or not state: layout.itemAt(index).widget().setVisible(state) if state: icon = ima.icon('options_less') tip = _('Hide advanced options') else: icon = ima.icon('options_more') tip = _('Show advanced options') self.more_options.setIcon(icon) self.more_options.setToolTip(tip) def update_combos(self): self.search_text.lineEdit().returnPressed.emit() self.include_pattern.lineEdit().returnPressed.emit() self.exclude_pattern.lineEdit().returnPressed.emit() def detect_hg_repository(self, path=None): if path is None: path = getcwd() hg_repository = is_hg_installed() and get_vcs_root(path) is not None self.hg_manifest.setEnabled(hg_repository) if not hg_repository and self.hg_manifest.isChecked(): self.custom_dir.setChecked(True) def set_search_text(self, text): if text: self.search_text.add_text(text) self.search_text.lineEdit().selectAll() self.search_text.setFocus() def get_options(self, all=False): # Getting options utext = to_text_string(self.search_text.currentText()) if not utext: return try: texts = [(utext.encode('ascii'), 'ascii')] except UnicodeEncodeError: texts = [] for enc in self.supported_encodings: try: texts.append((utext.encode(enc), enc)) except UnicodeDecodeError: pass text_re = self.edit_regexp.isChecked() include = to_text_string(self.include_pattern.currentText()) include_re = self.include_regexp.isChecked() exclude = to_text_string(self.exclude_pattern.currentText()) exclude_re = self.exclude_regexp.isChecked() python_path = self.python_path.isChecked() hg_manifest = self.hg_manifest.isChecked() path = osp.abspath(to_text_string(self.dir_combo.currentText())) # Finding text occurrences if not include_re: include = fnmatch.translate(include) if not exclude_re: exclude = fnmatch.translate(exclude) if all: search_text = [to_text_string(self.search_text.itemText(index)) \ for index in range(self.search_text.count())] search_path = [to_text_string(self.dir_combo.itemText(index)) \ for index in range(self.dir_combo.count())] include = [to_text_string(self.include_pattern.itemText(index)) \ for index in range(self.include_pattern.count())] include_idx = self.include_pattern.currentIndex() exclude = [to_text_string(self.exclude_pattern.itemText(index)) \ for index in range(self.exclude_pattern.count())] exclude_idx = self.exclude_pattern.currentIndex() more_options = self.more_options.isChecked() return (search_text, text_re, search_path, include, include_idx, include_re, exclude, exclude_idx, exclude_re, python_path, more_options) else: return (path, python_path, hg_manifest, include, exclude, texts, text_re) @Slot() def select_directory(self): """Select directory""" self.parent().redirect_stdio.emit(False) directory = getexistingdirectory(self, _("Select directory"), self.dir_combo.currentText()) if directory: self.set_directory(directory) self.parent().redirect_stdio.emit(True) def set_directory(self, directory): path = to_text_string(osp.abspath(to_text_string(directory))) self.dir_combo.setEditText(path) self.detect_hg_repository(path) def keyPressEvent(self, event): """Reimplemented to handle key events""" ctrl = event.modifiers() & Qt.ControlModifier shift = event.modifiers() & Qt.ShiftModifier if event.key() in (Qt.Key_Enter, Qt.Key_Return): self.find.emit() elif event.key() == Qt.Key_F and ctrl and shift: # Toggle find widgets self.parent().toggle_visibility.emit(not self.isVisible()) else: QWidget.keyPressEvent(self, event)
class FindOptions(QWidget): """Find widget with options""" find = Signal() stop = Signal() def __init__(self, parent, search_text, search_text_regexp, search_path, include, include_idx, include_regexp, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options): QWidget.__init__(self, parent) if search_path is None: search_path = getcwd() if not isinstance(search_text, (list, tuple)): search_text = [search_text] if not isinstance(search_path, (list, tuple)): search_path = [search_path] if not isinstance(include, (list, tuple)): include = [include] if not isinstance(exclude, (list, tuple)): exclude = [exclude] self.supported_encodings = supported_encodings # Layout 1 hlayout1 = QHBoxLayout() self.search_text = PatternComboBox(self, search_text, _("Search pattern")) self.edit_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.edit_regexp.setCheckable(True) self.edit_regexp.setChecked(search_text_regexp) self.more_widgets = () self.more_options = create_toolbutton(self, toggled=self.toggle_more_options) self.more_options.setCheckable(True) self.more_options.setChecked(more_options) self.ok_button = create_toolbutton(self, text=_("Search"), icon=ima.icon('DialogApplyButton'), triggered=lambda: self.find.emit(), tip=_("Start search"), text_beside_icon=True) self.ok_button.clicked.connect(self.update_combos) self.stop_button = create_toolbutton(self, text=_("Stop"), icon=ima.icon('stop'), triggered=lambda: self.stop.emit(), tip=_("Stop search"), text_beside_icon=True) self.stop_button.setEnabled(False) for widget in [self.search_text, self.edit_regexp, self.ok_button, self.stop_button, self.more_options]: hlayout1.addWidget(widget) # Layout 2 hlayout2 = QHBoxLayout() self.include_pattern = PatternComboBox(self, include, _("Included filenames pattern")) if include_idx is not None and include_idx >= 0 \ and include_idx < self.include_pattern.count(): self.include_pattern.setCurrentIndex(include_idx) self.include_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.include_regexp.setCheckable(True) self.include_regexp.setChecked(include_regexp) include_label = QLabel(_("Include:")) include_label.setBuddy(self.include_pattern) self.exclude_pattern = PatternComboBox(self, exclude, _("Excluded filenames pattern")) if exclude_idx is not None and exclude_idx >= 0 \ and exclude_idx < self.exclude_pattern.count(): self.exclude_pattern.setCurrentIndex(exclude_idx) self.exclude_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.exclude_regexp.setCheckable(True) self.exclude_regexp.setChecked(exclude_regexp) exclude_label = QLabel(_("Exclude:")) exclude_label.setBuddy(self.exclude_pattern) for widget in [include_label, self.include_pattern, self.include_regexp, exclude_label, self.exclude_pattern, self.exclude_regexp]: hlayout2.addWidget(widget) # Layout 3 hlayout3 = QHBoxLayout() self.python_path = QRadioButton(_("PYTHONPATH"), self) self.python_path.setChecked(in_python_path) self.python_path.setToolTip(_( "Search in all directories listed in sys.path which" " are outside the Python installation directory")) self.hg_manifest = QRadioButton(_("Hg repository"), self) self.detect_hg_repository() self.hg_manifest.setToolTip( _("Search in current directory hg repository")) self.custom_dir = QRadioButton(_("Here:"), self) self.custom_dir.setChecked(not in_python_path) self.dir_combo = PathComboBox(self) self.dir_combo.addItems(search_path) self.dir_combo.setToolTip(_("Search recursively in this directory")) self.dir_combo.open_dir.connect(self.set_directory) self.python_path.toggled.connect(self.dir_combo.setDisabled) self.hg_manifest.toggled.connect(self.dir_combo.setDisabled) browse = create_toolbutton(self, icon=ima.icon('DirOpenIcon'), tip=_('Browse a search directory'), triggered=self.select_directory) for widget in [self.python_path, self.hg_manifest, self.custom_dir, self.dir_combo, browse]: hlayout3.addWidget(widget) self.search_text.valid.connect(lambda valid: self.find.emit()) self.include_pattern.valid.connect(lambda valid: self.find.emit()) self.exclude_pattern.valid.connect(lambda valid: self.find.emit()) self.dir_combo.valid.connect(lambda valid: self.find.emit()) vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addLayout(hlayout1) vlayout.addLayout(hlayout2) vlayout.addLayout(hlayout3) self.more_widgets = (hlayout2, hlayout3) self.toggle_more_options(more_options) self.setLayout(vlayout) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) @Slot(bool) def toggle_more_options(self, state): for layout in self.more_widgets: for index in range(layout.count()): if state and self.isVisible() or not state: layout.itemAt(index).widget().setVisible(state) if state: icon = ima.icon('options_less') tip = _('Hide advanced options') else: icon = ima.icon('options_more') tip = _('Show advanced options') self.more_options.setIcon(icon) self.more_options.setToolTip(tip) def update_combos(self): self.search_text.lineEdit().returnPressed.emit() self.include_pattern.lineEdit().returnPressed.emit() self.exclude_pattern.lineEdit().returnPressed.emit() def detect_hg_repository(self, path=None): if path is None: path = getcwd() hg_repository = is_hg_installed() and get_vcs_root(path) is not None self.hg_manifest.setEnabled(hg_repository) if not hg_repository and self.hg_manifest.isChecked(): self.custom_dir.setChecked(True) def set_search_text(self, text): if text: self.search_text.add_text(text) self.search_text.lineEdit().selectAll() self.search_text.setFocus() def get_options(self, all=False): # Getting options utext = to_text_string(self.search_text.currentText()) if not utext: return try: texts = [(utext.encode('ascii'), 'ascii')] except UnicodeEncodeError: texts = [] for enc in self.supported_encodings: try: texts.append((utext.encode(enc), enc)) except UnicodeDecodeError: pass text_re = self.edit_regexp.isChecked() include = to_text_string(self.include_pattern.currentText()) include_re = self.include_regexp.isChecked() exclude = to_text_string(self.exclude_pattern.currentText()) exclude_re = self.exclude_regexp.isChecked() python_path = self.python_path.isChecked() hg_manifest = self.hg_manifest.isChecked() path = osp.abspath( to_text_string( self.dir_combo.currentText() ) ) # Finding text occurrences if not include_re: include = fnmatch.translate(include) if not exclude_re: exclude = fnmatch.translate(exclude) if all: search_text = [to_text_string(self.search_text.itemText(index)) \ for index in range(self.search_text.count())] search_path = [to_text_string(self.dir_combo.itemText(index)) \ for index in range(self.dir_combo.count())] include = [to_text_string(self.include_pattern.itemText(index)) \ for index in range(self.include_pattern.count())] include_idx = self.include_pattern.currentIndex() exclude = [to_text_string(self.exclude_pattern.itemText(index)) \ for index in range(self.exclude_pattern.count())] exclude_idx = self.exclude_pattern.currentIndex() more_options = self.more_options.isChecked() return (search_text, text_re, search_path, include, include_idx, include_re, exclude, exclude_idx, exclude_re, python_path, more_options) else: return (path, python_path, hg_manifest, include, exclude, texts, text_re) @Slot() def select_directory(self): """Select directory""" self.parent().redirect_stdio.emit(False) directory = getexistingdirectory(self, _("Select directory"), self.dir_combo.currentText()) if directory: self.set_directory(directory) self.parent().redirect_stdio.emit(True) def set_directory(self, directory): path = to_text_string(osp.abspath(to_text_string(directory))) self.dir_combo.setEditText(path) self.detect_hg_repository(path) def keyPressEvent(self, event): """Reimplemented to handle key events""" ctrl = event.modifiers() & Qt.ControlModifier shift = event.modifiers() & Qt.ShiftModifier if event.key() in (Qt.Key_Enter, Qt.Key_Return): self.find.emit() elif event.key() == Qt.Key_F and ctrl and shift: # Toggle find widgets self.parent().toggle_visibility.emit(not self.isVisible()) else: QWidget.keyPressEvent(self, event)