def create_radiobutton(self, text, option, default=NoDefault, tip=None, msg_warning=None, msg_info=None, msg_if_enabled=False, button_group=None, restart=False): radiobutton = QRadioButton(text) if button_group is None: if self.default_button_group is None: self.default_button_group = QButtonGroup(self) button_group = self.default_button_group button_group.addButton(radiobutton) if tip is not None: radiobutton.setToolTip(tip) self.radiobuttons[radiobutton] = (option, default) if msg_warning is not None or msg_info is not None: def show_message(is_checked): if is_checked or not msg_if_enabled: if msg_warning is not None: QMessageBox.warning(self, self.get_name(), msg_warning, QMessageBox.Ok) if msg_info is not None: QMessageBox.information(self, self.get_name(), msg_info, QMessageBox.Ok) radiobutton.toggled.connect(show_message) radiobutton.restart_required = restart radiobutton.label_text = text return radiobutton
def create_radiobutton(self, text, option, default=NoDefault, tip=None, msg_warning=None, msg_info=None, msg_if_enabled=False, button_group=None, restart=False, section=None): radiobutton = QRadioButton(text) if button_group is None: if self.default_button_group is None: self.default_button_group = QButtonGroup(self) button_group = self.default_button_group button_group.addButton(radiobutton) if tip is not None: radiobutton.setToolTip(tip) self.radiobuttons[radiobutton] = (section, option, default) if msg_warning is not None or msg_info is not None: def show_message(is_checked): if is_checked or not msg_if_enabled: if msg_warning is not None: QMessageBox.warning(self, self.get_name(), msg_warning, QMessageBox.Ok) if msg_info is not None: QMessageBox.information(self, self.get_name(), msg_info, QMessageBox.Ok) radiobutton.toggled.connect(show_message) radiobutton.restart_required = restart radiobutton.label_text = text return radiobutton
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 AnimationWindow(PyDialog): """ +-------------------+ | Animation | +-------------------------+ | icase ______ | | scale ______ Default | | time ______ Default | | | | nframes ______ Default | | resolu. ______ Default | | Dir ______ Browse | | iFrame ______ | | | | Animations: | | o Scale, Phase, Time | | | | x delete images | | x repeat | # TODO: change to an integer | x make gif | | | | Step, RunAll | | Close | +-------------------------+ TODO: add key-frame support """ def __init__(self, data, win_parent=None): PyDialog.__init__(self, data, win_parent) self.set_font_size(data['font_size']) self.istep = 0 self._animate_type = 'time' self._updated_animation = False self._active_deformation = 0. self._icase_fringe = data['icase_fringe'] self._icase_disp = data['icase_disp'] self._icase_vector = data['icase_vector'] self._default_name = data['name'] self._default_time = data['time'] self._default_fps = data['frames/sec'] self._default_resolution = data['resolution'] self._scale = data['scale'] self._default_scale = data['default_scale'] self._default_is_scale = data['is_scale'] self._arrow_scale = data['arrow_scale'] self._default_arrow_scale = data['default_arrow_scale'] self._phase = data['phase'] self._default_phase = data['default_phase'] self._default_dirname = data['dirname'] self._default_gif_name = os.path.join(self._default_dirname, data['name'] + '.gif') self.animation_types = [ 'Animate Scale', ] #'Animate Phase', #'Animate Time', #'Animate Frequency Sweep' #] self.setWindowTitle('Animate Model') self.create_widgets() self.create_layout() self.set_connections() self.is_gui = False if hasattr(self.win_parent, '_updated_legend'): self.win_parent.is_animate_open = True self.is_gui = True self.on_update_min_max_defaults() def create_widgets(self): """creates the menu objects""" self.box_scale = QGroupBox('Animate Scale') self.box_time = QGroupBox('Animate Time') icase_max = 1000 # TODO: update 1000 self.checkbox_fringe = QCheckBox('Animate') self.checkbox_fringe.setToolTip( 'Animate the fringe in addition to the deflection') #self.checkbox_disp = QCheckBox('Animate') self.checkbox_fringe.setEnabled(False) self.icase_fringe_label = QLabel("iCase (Fringe):") self.icase_fringe_edit = QSpinBox(self) self.icase_fringe_edit.setRange(0, icase_max) self.icase_fringe_edit.setSingleStep(1) if self._icase_fringe is not None: self.icase_fringe_edit.setValue(self._icase_fringe) self.icase_fringe_edit.setToolTip( 'Case Number for the Scale/Phase Animation Type.\n' 'Defaults to the result you had shown when you clicked "Create Animation".\n' 'iCase can be seen by clicking "Apply" on a result.') self.icase_disp_label = QLabel("iCase (Disp):") self.icase_disp_edit = QSpinBox(self) self.icase_disp_edit.setRange(1, icase_max) self.icase_disp_edit.setSingleStep(1) if self._icase_disp is not None: self.icase_disp_edit.setValue(self._icase_disp) self.checkbox_vector = QCheckBox('Animate') self.checkbox_vector.setToolTip( 'Animate the vector in addition to the deflection') self.checkbox_vector.hide() #self.checkbox_disp = QCheckBox('Animate') self.icase_vector_label = QLabel("iCase (Vector):") self.icase_vector_edit = QSpinBox(self) self.icase_vector_edit.setRange(1, icase_max) self.icase_vector_edit.setSingleStep(1) if self._icase_vector is not None: self.icase_vector_edit.setValue(self._icase_vector) self.scale_label = QLabel("True Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") self.scale_edit.setToolTip('Scale factor of the "deflection"') self.scale_button.setToolTip('Sets the scale factor of the gif to %s' % self._scale) self.arrow_scale_label = QLabel("Arrow Scale:") self.arrow_scale_edit = QLineEdit(str(self._scale)) self.arrow_scale_button = QPushButton("Default") self.arrow_scale_edit.setToolTip('Scale factor of the "arrows"') self.arrow_scale_button.setToolTip( 'Sets the arrow scale factor of the gif to %s' % self._arrow_scale) self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) self.time_label = QLabel("Total Time (sec):") self.time_edit = QDoubleSpinBox(self) self.time_edit.setValue(self._default_time) self.time_edit.setRange(0.1, 5. * 60.) self.time_edit.setDecimals(2) self.time_edit.setSingleStep(0.1) self.time_button = QPushButton("Default") self.time_edit.setToolTip("Total time of the gif") self.time_button.setToolTip('Sets the total time of the gif to %.2f' % self._default_time) self.fps_label = QLabel("Frames/Second:") self.fps_edit = QSpinBox(self) self.fps_edit.setRange(1, 60) self.fps_edit.setSingleStep(1) self.fps_edit.setValue(self._default_fps) self.fps_button = QPushButton("Default") self.fps_edit.setToolTip( "A higher FPS is smoother, but may not play well for large gifs") self.fps_button.setToolTip('Sets the FPS to %s' % self._default_fps) self.resolution_label = QLabel("Resolution Scale:") self.resolution_edit = QSpinBox(self) self.resolution_edit.setRange(1, 5) self.resolution_edit.setSingleStep(1) self.resolution_edit.setValue(self._default_resolution) self.resolution_button = QPushButton("Default") self.resolution_edit.setToolTip( 'Scales the window resolution by an integer factor') self.resolution_button.setToolTip('Sets the resolution to %s' % self._default_resolution) #----------------- # Time plot self.fringe_label = QLabel("Fringe") self.icase_fringe_start_edit = QSpinBox(self) self.icase_fringe_start_edit.setRange(0, icase_max) self.icase_fringe_start_edit.setSingleStep(1) self.icase_fringe_start_edit.setValue(self._icase_fringe) self.icase_fringe_start_button = QPushButton("Default") self.icase_fringe_end_edit = QSpinBox(self) self.icase_fringe_end_edit.setRange(0, icase_max) self.icase_fringe_end_edit.setSingleStep(1) self.icase_fringe_end_edit.setValue(self._icase_fringe) self.icase_fringe_end_button = QPushButton("Default") self.icase_fringe_delta_edit = QSpinBox(self) self.icase_fringe_delta_edit.setRange(1, icase_max) self.icase_fringe_delta_edit.setSingleStep(1) self.icase_fringe_delta_edit.setValue(1) self.icase_fringe_delta_button = QPushButton("Default") self.displacement_label = QLabel("Displacement") self.icase_start = QLabel("iCase Start:") self.icase_disp_start_edit = QSpinBox(self) self.icase_disp_start_edit.setRange(0, icase_max) self.icase_disp_start_edit.setSingleStep(1) self.icase_disp_start_edit.setValue(self._icase_fringe) self.icase_disp_start_button = QPushButton("Default") self.icase_end_label = QLabel("iCase End:") self.icase_disp_end_edit = QSpinBox(self) self.icase_disp_end_edit.setRange(0, icase_max) self.icase_disp_end_edit.setSingleStep(1) self.icase_disp_end_edit.setValue(self._icase_fringe) self.icase_disp_end_button = QPushButton("Default") self.icase_delta_label = QLabel("iCase Delta:") self.icase_disp_delta_edit = QSpinBox(self) self.icase_disp_delta_edit.setRange(1, icase_max) self.icase_disp_delta_edit.setSingleStep(1) self.icase_disp_delta_edit.setValue(1) self.icase_disp_delta_button = QPushButton("Default") self.min_value_enable = QCheckBox() self.min_value_label = QLabel("Min Value:") self.min_value_edit = QLineEdit('') #self.min_value_edit.setRange(1, 1000) #self.min_value_edit.setSingleStep(1) #self.min_value_edit.setValue(1) self.min_value_button = QPushButton("Default") self.max_value_enable = QCheckBox() self.max_value_label = QLabel("Max Value:") self.max_value_edit = QLineEdit('') #self.min_value_edit.setRange(1, 1000) # TODO: update 1000 #self.min_value_edit.setSingleStep(1) #self.min_value_edit.setValue(1) self.max_value_button = QPushButton("Default") # TODO: enable this (uncomment) ------------------------------------------ #self.min_value_enable.hide() #self.min_value.hide() #self.min_value_edit.hide() #self.min_value_button.hide() #self.max_value_enable.hide() #self.max_value.hide() #self.max_value_edit.hide() #self.max_value_button.hide() # TODO: enable this (uncomment) ------------------------------------------ self.icase_disp_start_edit.setToolTip( 'The first frame of the animation') self.icase_disp_end_edit.setToolTip( 'The last frame of the animation\n' 'Assumes icase_start + nframes * icase_delta = icase_end') self.icase_disp_delta_edit.setToolTip( 'The frame step size (to skip non-consecutive results).\n' 'Frame skipping can be used to:\n' " - skip across results that you don't want to plot\n" ' - adjust the FPS') self.min_value_edit.setToolTip( 'Min value of the legend (not supported)') self.max_value_edit.setToolTip( 'Max value of the legend (not supported)') #'time' : 0., #'default_time' : 0, #'icase_start' : 10, #'icase_delta' : 3, #'min_value' : 0., #'max_value' : 1000., self.browse_folder_label = QLabel('Output Directory:') self.browse_folder_edit = QLineEdit(str(self._default_dirname)) self.browse_folder_button = QPushButton('Browse') self.browse_folder_edit.setToolTip( 'Location to save the png/gif files') self.gif_label = QLabel("Gif Filename:") self.gif_edit = QLineEdit(str(self._default_name + '.gif')) self.gif_button = QPushButton('Default') self.gif_edit.setToolTip('Name of the gif') self.gif_button.setToolTip('Sets the name of the gif to %s.gif' % self._default_name) # scale / phase if 1: # pragma: no cover self.animate_scale_radio = QRadioButton("Animate Scale") self.animate_phase_radio = QRadioButton("Animate Phase") self.animate_time_radio = QRadioButton("Animate Time") self.animate_freq_sweeep_radio = QRadioButton( "Animate Frequency Sweep") self.animate_scale_radio.setToolTip( 'Animates the scale factor based on the "Animation Type"') self.animate_time_radio.setToolTip( 'Animates the time/load/mode step') self.animate_scale_radio.setChecked(self._default_is_scale) self.animate_phase_radio.setChecked(not self._default_is_scale) self.animate_time_radio.setChecked(False) msg = 'Scale : Animates the scale factor based on the "Animation Profile"\n' if self._default_phase is None: self.animate_phase_radio.setDisabled(True) self.animate_phase_radio.setToolTip( 'Animates the phase angle ' '(only for complex results)') msg += 'Phase : Animates the phase angle (only for complex results)\n' else: self.animate_phase_radio.setToolTip("Animates the phase angle") msg += 'Phase : Animates the phase angle\n' msg += ( 'Time : Animates the time/load/mode step\n' 'Freq Sweep : Animates a complex result across a range of frequencies ' '(not supported)\n') self.animate_freq_sweeep_radio.setDisabled(True) self.animate_freq_sweeep_radio.setToolTip( 'Animates a complex result across a range of frequencies (not supported)' ) else: msg = 'Scale : Animates the scale factor based on the "Animation Profile"\n' if self._default_phase is None: #self.animate_phase_radio.setDisabled(True) #self.animate_phase_radio.setToolTip('Animates the phase angle ' #'(only for complex results)') msg += 'Phase : Animates the phase angle (only for complex results)\n' else: #self.animate_phase_radio.setToolTip("Animates the phase angle") msg += 'Phase : Animates the phase angle\n' msg += ( 'Time : Animates the time/load/mode step\n' 'Freq Sweep : Animates a complex result across a range of frequencies ' '(not supported)\n') self.animation_type = QLabel("Animation Type:") animation_type = OrderedDict() #scale_msg = 'Scale\n' #phase_msg = 'Phase\n' #time_msg = 'Time\n' #animation_types = [ #('Animate Scale', scale_msg), #('Animate Phase', phase_msg), #('Animate Time', time_msg), ##'Animate Frequency Sweep' #] if self._phase is not None: self.animation_types.append('Animate Phase') self.animation_types.append('Animate Time') self.animation_profile_label = QLabel("Animation Profile:") self.animation_profile_edit = QComboBox() for animation_profile in ANIMATION_PROFILES: self.animation_profile_edit.addItem(animation_profile) self.animation_profile_edit.setToolTip('The profile for a scaled GIF') self.animation_type_edit = QComboBox() # TODO: add a tooltip for each item for animation_type in self.animation_types: self.animation_type_edit.addItem(animation_type) #self.animation_type_edit.setToolTip('The profile for a scaled GIF') self.animation_type_edit.setToolTip(msg.rstrip()) self.csv_profile_label = QLabel("CSV profile:") self.csv_profile_edit = QLineEdit() self.csv_profile_browse_button = QPushButton('Browse') self.csv_profile_edit.setToolTip( 'The path to the CSV file of (Scale1, Scale2, Scale3, ...)') #widget = QWidget(self) #horizontal_vertical_group = QButtonGroup(widget) #horizontal_vertical_group.addButton(self.animate_scale_radio) #horizontal_vertical_group.addButton(self.animate_phase_radio) #horizontal_vertical_group.addButton(self.animate_time_radio) #horizontal_vertical_group.addButton(self.animate_freq_sweeep_radio) # animate in gui self.animate_in_gui_checkbox = QCheckBox("Animate In GUI?") self.animate_in_gui_checkbox.setChecked(True) # make images self.make_images_checkbox = QCheckBox("Make images?") self.make_images_checkbox.setChecked(True) # make images self.overwrite_images_checkbox = QCheckBox("Overwrite images?") self.overwrite_images_checkbox.setChecked(True) # delete images when finished self.delete_images_checkbox = QCheckBox("Delete images when finished?") self.delete_images_checkbox.setChecked(True) # endless loop self.repeat_checkbox = QCheckBox("Repeat?") self.repeat_checkbox.setChecked(True) self.repeat_checkbox.setToolTip( "Repeating creates an infinitely looping gif") # endless loop self.make_gif_checkbox = QCheckBox("Make Gif?") if IS_IMAGEIO: self.make_gif_checkbox.setChecked(True) else: self.make_gif_checkbox.setChecked(False) self.make_gif_checkbox.setEnabled(False) self.make_gif_checkbox.setToolTip( 'imageio is not available; install it') # bottom buttons self.step_button = QPushButton("Step") self.wipe_button = QPushButton("Wipe Deformed Shape") self.stop_button = QPushButton("Stop") self.run_button = QPushButton("Run") self.step_button.setToolTip( 'Steps through the animation (for testing)') self.wipe_button.setToolTip( 'Removes the existing "deflecton" from the animation') self.stop_button.setToolTip('Stops the animation') self.run_button.setToolTip('Creates the animation') self.step_button.hide() self.wipe_button.hide() self.wipe_button.setEnabled(False) #self.wipe_button.hide() self.stop_button.setEnabled(False) self.cancel_button = QPushButton("Close") #self.set_grid_time(enabled=False) #self.set_grid_scale(enabled=self._default_is_scale) if self._default_phase: self.on_animate_phase(force=True) set_combo_box_text(self.animation_type_edit, 'Animate Phase') else: self.on_animate_scale(force=True) def set_connections(self): """creates button actions""" self.checkbox_vector.clicked.connect(self.on_checkbox_vector) self.scale_button.clicked.connect(self.on_default_scale) self.arrow_scale_button.clicked.connect(self.on_default_arrow_scale) self.time_button.clicked.connect(self.on_default_time) self.fps_button.clicked.connect(self.on_default_fps) self.resolution_button.clicked.connect(self.on_default_resolution) self.browse_folder_button.clicked.connect(self.on_browse_folder) self.csv_profile_browse_button.clicked.connect(self.on_browse_csv) self.gif_button.clicked.connect(self.on_default_name) self.step_button.clicked.connect(self.on_step) self.wipe_button.clicked.connect(self.on_wipe) self.stop_button.clicked.connect(self.on_stop) self.run_button.clicked.connect(self.on_run) self.min_value_enable.clicked.connect(self.on_min_value_enable) self.max_value_enable.clicked.connect(self.on_max_value_enable) self.min_value_button.clicked.connect(self.on_min_value_default) self.max_value_button.clicked.connect(self.on_max_value_default) self.icase_disp_start_button.clicked.connect( self.on_update_min_max_defaults) #self.animate_scale_radio.clicked.connect(self.on_animate_scale) #self.animate_phase_radio.clicked.connect(self.on_animate_phase) #self.animate_time_radio.clicked.connect(self.on_animate_time) self.animation_type_edit.currentIndexChanged.connect(self.on_animate) #self.animate_freq_sweeep_radio self.cancel_button.clicked.connect(self.on_cancel) self.animate_in_gui_checkbox.clicked.connect(self.on_animate_in_gui) self.animate_in_gui_checkbox.setChecked(True) self.on_animate_in_gui() def on_checkbox_vector(self): is_enabled = self.checkbox_vector.isEnabled() is_checked = self.checkbox_vector.isChecked() enable_edit = is_enabled and is_checked self.icase_vector_label.setEnabled(is_checked) self.icase_vector_edit.setEnabled(enable_edit) def on_animate_in_gui(self): animate_in_gui = self.animate_in_gui_checkbox.isChecked() enable = not animate_in_gui if HIDE_WHEN_INACTIVE: self.make_images_checkbox.setVisible(enable) self.delete_images_checkbox.setVisible(enable) self.make_gif_checkbox.setVisible(enable) self.repeat_checkbox.setVisible(enable) self.resolution_button.setVisible(enable) self.resolution_label.setVisible(enable) self.resolution_edit.setVisible(enable) self.gif_label.setVisible(enable) self.gif_edit.setVisible(enable) self.gif_button.setVisible(enable) self.browse_folder_label.setVisible(enable) self.browse_folder_button.setVisible(enable) self.browse_folder_edit.setVisible(enable) self.step_button.setEnabled(enable) self.make_images_checkbox.setEnabled(enable) self.delete_images_checkbox.setEnabled(enable) self.make_gif_checkbox.setEnabled(enable) self.repeat_checkbox.setEnabled(enable) self.resolution_button.setEnabled(enable) self.resolution_edit.setEnabled(enable) self.gif_edit.setEnabled(enable) self.gif_button.setEnabled(enable) self.browse_folder_button.setEnabled(enable) self.browse_folder_edit.setEnabled(enable) self.step_button.setEnabled(enable) #wipe_button def on_animate(self, value): """ animate pulldown Parameters ---------- value : int index in animation_types """ #animation_types = ['Animate Scale', 'Animate Phase', 'Animate Time', #'Animate Frequency Sweep'] animation_type = self.animation_types[value] if animation_type == 'Animate Scale': self.on_animate_scale() elif animation_type == 'Animate Phase': self.on_animate_phase() elif animation_type == 'Animate Time': self.on_animate_time() else: raise NotImplementedError('value = ', value) def on_animate_time(self, force=False): """enables the secondary input""" #print('on_animate_time') if self._animate_type == 'scale' or force: self.set_grid_scale(False, 'time') self.set_grid_time(True, 'time') self._animate_type = 'time' def on_animate_scale(self, force=False): """enables the secondary input""" #print('on_animate_scale') self.set_grid_scale(True, 'scale') if self._animate_type == 'time' or force: self.set_grid_time(False, 'scale') self._animate_type = 'scale' def on_animate_phase(self, force=False): """enables the secondary input""" #print('on_animate_phase') if self._animate_type == 'scale' or force: self.set_grid_scale(False, 'phase') if self._animate_type == 'time' or force: self.set_grid_time(False, 'phase') self._animate_type = 'phase' def set_grid_scale(self, enabled=True, word=''): """enables/disables the secondary input""" #print('%s-set_grid_scale; enabled = %r' % (word, enabled)) if HIDE_WHEN_INACTIVE: self.box_scale.setVisible(enabled) self.animation_profile_label.setVisible(enabled) self.animation_profile_edit.setVisible(enabled) #self.min_value_enable.setVisible(enabled) #self.max_value_enable.setVisible(enabled) self.animation_profile_label.setEnabled(enabled) self.animation_profile_edit.setEnabled(enabled) # TODO: doesn't work... #self.csv_profile.setEnabled(enabled) #self.csv_profile_edit.setEnabled(enabled) #self.csv_profile_button.setEnabled(enabled) self.min_value_enable.setEnabled(enabled) self.max_value_enable.setEnabled(enabled) self.on_min_value_enable() self.on_max_value_enable() def set_grid_time(self, enabled=True, word=''): """enables/disables the secondary input""" #print('%s-set_grid_time; enabled = %r' % (word, enabled)) if HIDE_WHEN_INACTIVE: self.box_time.setVisible(enabled) self.checkbox_fringe.setVisible(not enabled) self.icase_fringe_label.setVisible(not enabled) self.icase_fringe_edit.setVisible(not enabled) self.icase_disp_label.setVisible(not enabled) self.icase_disp_edit.setVisible(not enabled) self.icase_vector_label.setVisible(not enabled) self.icase_vector_edit.setVisible(not enabled) #self.icase_fringe_delta_edit.setVisible(enabled) self.icase_disp_delta_edit.setVisible(enabled) self.icase_disp_delta_edit.setVisible(enabled) self.fps_label.setVisible(enabled) self.fps_edit.setVisible(enabled) self.fps_button.setVisible(enabled) self.displacement_label.setEnabled(enabled) self.fringe_label.setEnabled(enabled) self.icase_start.setEnabled(enabled) self.icase_disp_start_edit.setEnabled(enabled) self.icase_disp_start_button.setEnabled(enabled) self.icase_fringe_start_edit.setEnabled(enabled) self.icase_fringe_start_button.setEnabled(enabled) self.icase_end_label.setEnabled(enabled) self.icase_disp_end_edit.setEnabled(enabled) self.icase_disp_end_button.setEnabled(enabled) self.icase_fringe_end_edit.setEnabled(enabled) self.icase_fringe_end_button.setEnabled(enabled) self.icase_delta_label.setEnabled(enabled) self.icase_disp_delta_edit.setEnabled(enabled) self.icase_disp_delta_button.setEnabled(enabled) self.icase_fringe_delta_edit.setEnabled(enabled) self.icase_fringe_delta_button.setEnabled(enabled) #----------------------------------------------------------------------- is_min_enabled = self.min_value_enable.isChecked() self.min_value_label.setEnabled(is_min_enabled) self.min_value_edit.setEnabled(is_min_enabled) self.min_value_button.setEnabled(is_min_enabled) is_max_enabled = self.max_value_enable.isChecked() self.max_value_label.setEnabled(is_max_enabled) self.max_value_edit.setEnabled(is_max_enabled) self.max_value_button.setEnabled(is_max_enabled) self.min_value_enable.setEnabled(enabled) self.on_min_value_enable() #self.min_value.setEnabled(enabled) #self.min_value_edit.setEnabled(enabled) #self.min_value_button.setEnabled(enabled) self.max_value_enable.setEnabled(enabled) self.on_max_value_enable() #self.max_value.setEnabled(enabled) #self.max_value_edit.setEnabled(enabled) #self.max_value_button.setEnabled(enabled) self.icase_fringe_label.setEnabled(not enabled) self.icase_fringe_edit.setEnabled(not enabled) self.checkbox_fringe.setEnabled(not enabled) self.icase_disp_label.setEnabled(not enabled) self.icase_disp_edit.setEnabled(not enabled) self.icase_vector_label.setEnabled(not enabled) self.icase_vector_edit.setEnabled(not enabled) self.checkbox_vector.setEnabled(not enabled) self.on_checkbox_vector() self.fps_label.setEnabled(not enabled) self.fps_edit.setEnabled(not enabled) self.fps_button.setEnabled(not enabled) def on_min_value_enable(self): """ The min edit value box is enabled when we switch to time and the box is checked """ is_min_enabled = self.min_value_enable.isChecked( ) and self.min_value_enable.isEnabled() self.min_value_label.setEnabled(is_min_enabled) self.min_value_edit.setEnabled(is_min_enabled) self.min_value_button.setEnabled(is_min_enabled) def on_max_value_enable(self): """ The max edit value box is enabled when we switch to time and the box is checked """ is_max_enabled = self.max_value_enable.isChecked( ) and self.max_value_enable.isEnabled() self.max_value_label.setEnabled(is_max_enabled) self.max_value_edit.setEnabled(is_max_enabled) self.max_value_button.setEnabled(is_max_enabled) def on_update_min_max_defaults(self): """ When the icase is changed, the min/max value default message is changed """ icase = self.icase_disp_start_edit.value() min_value, max_value = self.get_min_max(icase) self.min_value_button.setToolTip('Sets the min value to %g' % min_value) self.max_value_button.setToolTip('Sets the max value to %g' % max_value) def on_min_value_default(self): """When min default icase is pressued, update the value""" icase = self.icase_disp_start_edit.value() min_value = self.get_min_max(icase)[0] self.min_value_edit.setText(str(min_value)) self.min_value_edit.setStyleSheet("QLineEdit{background: white;}") def on_max_value_default(self): """When max default icase is pressued, update the value""" icase = self.icase_disp_start_edit.value() max_value = self.get_min_max(icase)[1] self.max_value_edit.setText(str(max_value)) self.max_value_edit.setStyleSheet("QLineEdit{background: white;}") def on_browse_folder(self): """opens a folder dialog""" dirname = getexistingdirectory(parent=self, caption='Select a Directory', basedir='', options=QFileDialog.ShowDirsOnly) if not dirname: return self.browse_folder_edit.setText(dirname) def on_browse_csv(self): """opens a file dialog""" default_filename = '' file_types = 'Delimited Text (*.txt; *.dat; *.csv)' dirname = open_file_dialog(self, 'Select a CSV File', default_filename, file_types) if not dirname: return self.csv_profile_browse_button.setText(dirname) def on_default_name(self): """sets the default gif name""" self.gif_edit.setText(self._default_name + '.gif') def on_default_scale(self): """sets the default displacement scale factor""" self.scale_edit.setText(str(self._default_scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_arrow_scale(self): """sets the default arrow scale factor""" self.arrow_scale_edit.setText(str(self._default_arrow_scale)) self.arrow_scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_time(self): """sets the default gif time""" self.time_edit.setValue(self._default_time) def on_default_fps(self): """sets the default FPS""" self.fps_edit.setValue(self._default_fps) def on_default_resolution(self): """sets the default image resolution scale factor""" self.resolution_edit.setValue(self._default_resolution) def create_layout(self): """displays the menu objects""" grid = QGridLayout() irow = 0 grid.addWidget(self.icase_fringe_label, irow, 0) grid.addWidget(self.icase_fringe_edit, irow, 1) grid.addWidget(self.checkbox_fringe, irow, 2) irow += 1 grid.addWidget(self.icase_disp_label, irow, 0) grid.addWidget(self.icase_disp_edit, irow, 1) #grid.addWidget(self.checkbox_disp, irow, 2) irow += 1 grid.addWidget(self.icase_vector_label, irow, 0) grid.addWidget(self.icase_vector_edit, irow, 1) grid.addWidget(self.checkbox_vector, irow, 2) irow += 1 grid.addWidget(self.scale_label, irow, 0) grid.addWidget(self.scale_edit, irow, 1) grid.addWidget(self.scale_button, irow, 2) irow += 1 grid.addWidget(self.arrow_scale_label, irow, 0) grid.addWidget(self.arrow_scale_edit, irow, 1) grid.addWidget(self.arrow_scale_button, irow, 2) irow += 1 grid.addWidget(self.time_label, irow, 0) grid.addWidget(self.time_edit, irow, 1) grid.addWidget(self.time_button, irow, 2) irow += 1 # spacer spacer = QLabel('') grid.addWidget(self.fps_label, irow, 0) grid.addWidget(self.fps_edit, irow, 1) grid.addWidget(self.fps_button, irow, 2) irow += 1 grid.addWidget(self.animation_type, irow, 0) grid.addWidget(self.animation_type_edit, irow, 1) irow += 1 grid.addWidget(spacer, irow, 0) irow += 1 #---------- #Time grid_time = QGridLayout() jrow = 0 self.fringe_label.setAlignment(Qt.AlignCenter) self.displacement_label.setAlignment(Qt.AlignCenter) if not IS_TIME_FRINGE: self.fringe_label.hide() self.icase_fringe_delta_edit.hide() self.icase_fringe_start_edit.hide() self.icase_fringe_end_edit.hide() self.icase_fringe_delta_button.hide() grid_time.addWidget(self.displacement_label, jrow, 1) grid_time.addWidget(self.fringe_label, jrow, 2) jrow += 1 grid_time.addWidget(self.icase_start, jrow, 0) grid_time.addWidget(self.icase_disp_start_edit, jrow, 1) grid_time.addWidget(self.icase_fringe_start_edit, jrow, 2) #grid_time.addWidget(self.icase_disp_start_button, jrow, 2) jrow += 1 grid_time.addWidget(self.icase_end_label, jrow, 0) grid_time.addWidget(self.icase_disp_end_edit, jrow, 1) grid_time.addWidget(self.icase_fringe_end_edit, jrow, 2) #grid_time.addWidget(self.icase_end_button, jrow, 2) jrow += 1 grid_time.addWidget(self.icase_delta_label, jrow, 0) grid_time.addWidget(self.icase_disp_delta_edit, jrow, 1) grid_time.addWidget(self.icase_fringe_delta_edit, jrow, 2) #grid_time.addWidget(self.icase_delta_button, jrow, 2) jrow += 1 hbox_min = QHBoxLayout() hbox_min.addWidget(self.min_value_enable) hbox_min.addWidget(self.min_value_label) grid_time.addLayout(hbox_min, jrow, 0) grid_time.addWidget(self.min_value_edit, jrow, 1) grid_time.addWidget(self.min_value_button, jrow, 2) jrow += 1 hbox_max = QHBoxLayout() hbox_max.addWidget(self.max_value_enable) hbox_max.addWidget(self.max_value_label) grid_time.addLayout(hbox_max, jrow, 0) grid_time.addWidget(self.max_value_edit, jrow, 1) grid_time.addWidget(self.max_value_button, jrow, 2) jrow += 1 grid_time.addWidget(spacer, jrow, 0) jrow += 1 #-------------- grid_scale = QGridLayout() grid_scale.addWidget(self.animation_profile_label, 0, 0) grid_scale.addWidget(self.animation_profile_edit, 0, 1) #grid_scale.addWidget(self.csv_profile, 1, 0) #grid_scale.addWidget(self.csv_profile_edit, 1, 1) #grid_scale.addWidget(self.csv_profile_browse_button, 1, 2) self.csv_profile = QLabel("CSV profile:") self.csv_profile_edit = QLineEdit() self.csv_profile_button = QPushButton('Browse') #box_time = QVBoxLayout() # TODO: It's super annoying that the animate time box doesn't # line up with the previous box self.box_scale.setLayout(grid_scale) self.box_time.setLayout(grid_time) #---------- grid2 = QGridLayout() irow = 0 #grid2.addWidget(self.animate_scale_radio, 8, 0) #grid2.addWidget(self.animate_phase_radio, 8, 1) #grid2.addWidget(self.animate_time_radio, 8, 2) #grid2.addWidget(self.animate_freq_sweeep_radio, 8, 3) grid2.addWidget(self.animate_in_gui_checkbox, irow, 0) irow += 1 grid2.addWidget(self.resolution_label, irow, 0) grid2.addWidget(self.resolution_edit, irow, 1) grid2.addWidget(self.resolution_button, irow, 2) irow += 1 grid2.addWidget(self.browse_folder_label, irow, 0) grid2.addWidget(self.browse_folder_edit, irow, 1) grid2.addWidget(self.browse_folder_button, irow, 2) irow += 1 grid2.addWidget(self.gif_label, irow, 0) grid2.addWidget(self.gif_edit, irow, 1) grid2.addWidget(self.gif_button, irow, 2) irow += 1 grid2.addWidget(self.make_images_checkbox, irow, 0) #grid2.addWidget(self.overwrite_images_checkbox, irow, 0) grid2.addWidget(self.delete_images_checkbox, irow, 1) grid2.addWidget(self.make_gif_checkbox, irow, 2) irow += 1 grid2.addWidget(self.repeat_checkbox, irow, 0) irow += 1 grid2.addWidget(spacer, irow, 0) grid_hbox = QHBoxLayout() grid_hbox.addWidget(spacer) grid_hbox.addLayout(grid2) grid_hbox.addWidget(spacer) # bottom buttons step_run_box = QHBoxLayout() step_run_box.addWidget(self.step_button) step_run_box.addWidget(self.wipe_button) step_run_box.addWidget(self.stop_button) step_run_box.addWidget(self.run_button) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.cancel_button) vbox = QVBoxLayout() vbox.addLayout(grid) vbox.addWidget(self.box_scale) vbox.addWidget(self.box_time) #vbox.addLayout(checkboxes) vbox.addLayout(grid_hbox) vbox.addStretch() vbox.addLayout(step_run_box) vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def on_step(self): """click the Step button""" passed, validate_out = self.on_validate() if passed: try: self._make_gif(validate_out, istep=self.istep) self.istep += 1 except IndexError: self._make_gif(validate_out, istep=0) self.istep += 1 self.wipe_button.setEnabled(True) def on_wipe(self): """click the Wipe button""" passed, validate_out = self.on_validate(wipe=True) if passed: self.istep = 0 self._make_gif(validate_out, istep=self.istep) self.wipe_button.setEnabled(False) self.stop_button.setEnabled(False) def on_stop(self): """click the Stop button""" #passed, validate_out = self.on_validate() #if passed: #self._make_gif(validate_out, stop_animation=True) if self.is_gui: self.win_parent.win_parent.stop_animation() self.wipe_button.setEnabled(True) self.stop_button.setEnabled(False) def on_run(self): """click the Run button""" self.istep = 0 self.wipe_button.setEnabled(False) self.stop_button.setEnabled(True) passed, validate_out = self.on_validate() if passed: self._make_gif(validate_out, istep=None) return passed def _make_gif(self, validate_out, istep=None, stop_animation=False): """interface for making the gif""" (icase_fringe, icase_disp, icase_vector, scale, time, fps, animate_in_gui, magnify, output_dir, gifbase, min_value, max_value) = validate_out fps = int(fps) gif_filename = None if not stop_animation and not animate_in_gui and gifbase is not None: if gifbase.lower().endswith('.gif'): gifbase = gifbase[:-4] gif_filename = os.path.join(output_dir, gifbase + '.gif') animate_fringe = self.checkbox_fringe.isChecked() animate_vector = self.checkbox_vector.isChecked() animate_scale = self.animate_scale_radio.isChecked() animate_phase = self.animate_phase_radio.isChecked() animate_time = self.animate_time_radio.isChecked() if not self.checkbox_vector.isEnabled(): icase_vector = None animate_scale = False animate_phase = False animate_time = False if self._animate_type == 'scale': animate_scale = True elif self._animate_type == 'phase': animate_phase = True elif self._animate_type == 'time': animate_time = True else: raise NotImplementedError(self._animate_type) make_images = self.make_images_checkbox.isChecked() delete_images = self.delete_images_checkbox.isChecked() make_gif = self.make_gif_checkbox.isChecked() animation_profile = str(self.animation_profile_edit.currentText()) icase_disp_start = self.icase_disp_start_edit.value() icase_disp_end = self.icase_disp_end_edit.value() icase_disp_delta = self.icase_disp_delta_edit.value() bool_repeat = self.repeat_checkbox.isChecked( ) # TODO: change this to an integer if bool_repeat: nrepeat = 0 else: nrepeat = 1 #self.out_data['is_shown'] = self.show_radio.isChecked() #icase = self._icase if self.is_gui: self.win_parent.win_parent.make_gif( gif_filename, scale, istep=istep, animate_scale=animate_scale, animate_phase=animate_phase, animate_time=animate_time, icase_fringe=icase_fringe, icase_disp=icase_disp, icase_vector=icase_vector, animate_fringe=animate_fringe, animate_vector=animate_vector, icase_start=icase_disp_start, icase_end=icase_disp_end, icase_delta=icase_disp_delta, time=time, animation_profile=animation_profile, nrepeat=nrepeat, fps=fps, magnify=magnify, make_images=make_images, delete_images=delete_images, make_gif=make_gif, stop_animation=stop_animation, animate_in_gui=animate_in_gui, min_value=min_value, max_value=max_value, ) self.out_data['clicked_ok'] = True self.out_data['close'] = True def get_min_max(self, icase): if self.is_gui: (obj, (i, name)) = self.win_parent.win_parent.result_cases[icase] min_value, max_value = obj.get_min_max(i, name) else: return 0., 1.0 return min_value, max_value def on_validate(self, wipe=False): """checks to see if the input is valid""" # requires no special validation icase_fringe, flag0 = check_int(self.icase_fringe_edit) icase_disp, unused_flaga = check_int(self.icase_disp_edit) icase_vector, unused_flagb = check_int(self.icase_vector_edit) #icase_disp = self._icase_disp #icase_vector = self._icase_vector scale, flag1 = check_float(self.scale_edit) time, flag2 = check_float(self.time_edit) fps, flag3 = check_float(self.fps_edit) min_value = max_value = None flag4 = flag5 = True if self.min_value_edit.isEnabled(): min_value, flag4 = check_float(self.min_value_edit) if self.max_value_edit.isEnabled(): max_value, flag5 = check_float(self.max_value_edit) if wipe: animate_in_gui = False scale = 0. flag1 = True else: animate_in_gui = self.animate_in_gui_checkbox.isChecked() if animate_in_gui or wipe: passed = all([flag0, flag1, flag2, flag3, flag4, flag5]) magnify, output_dir, gifbase = None, None, None else: magnify, flag6 = check_int(self.resolution_edit) output_dir, flag7 = self.check_path(self.browse_folder_edit) gifbase, flag8 = self.check_name(self.gif_edit) passed = all([ flag0, flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8 ]) return passed, (icase_fringe, icase_disp, icase_vector, scale, time, fps, animate_in_gui, magnify, output_dir, gifbase, min_value, max_value) @staticmethod def check_name(cell): """verifies that the data is string-able""" 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 def check_path(self, cell): """verifies that the path exists""" text, passed = self.check_name(cell) if not passed: return None, False if os.path.exists(text): cell.setStyleSheet("QLineEdit{background: white;}") return text, True else: cell.setStyleSheet("QLineEdit{background: red;}") return None, False #def on_ok(self): #"""click the OK button""" #passed = self.on_apply() #if passed: #self.win_parent._animation_window_shown = False #self.close() ##self.destroy() def on_cancel(self): """click the Cancel button""" self.on_stop() 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 HighlightLauncher(QWidget): def __init__(self, parent): super().__init__() self.parent = parent # set title self.setWindowTitle("Highlight Editor" if __name__ == "__main__" else config.thisTranslation["highlightEditor"]) # set variables self.setupVariables() # setup interface self.setupUI() def setupVariables(self): self.isRefreshing = False bibleVerseParser = BibleVerseParser(config.parserStandarisation) bookNo2Abb = bibleVerseParser.standardAbbreviation #bookNo2Name = bibleVerseParser.standardFullBookName bookList = [i + 1 for i in range(66)] self.searchList = [ config.thisTranslation["filter"], "{0}-{1}".format( bookNo2Abb["1"], bookNo2Abb["66"]), "{0}-{1}".format( bookNo2Abb["1"], bookNo2Abb["39"]), "{0}-{1}".format( bookNo2Abb["40"], bookNo2Abb["66"]) ] + [bookNo2Abb[str(b)] for b in bookList] #self.searchListToolTips = [config.thisTranslation["filter"], "{0}-{1}".format(bookNo2Name["1"], bookNo2Name["66"]), "{0}-{1}".format(bookNo2Name["1"], bookNo2Name["39"]), "{0}-{1}".format(bookNo2Name["40"], bookNo2Name["66"])] + [bookNo2Name[str(b)] for b in bookList] def refresh(self): self.isRefreshing = True codes = Highlight().isHighlighted(self.parent.parent.bibleTab.b, self.parent.parent.bibleTab.c, self.parent.parent.bibleTab.v) if codes: index = int(codes[0][-1]) - 1 self.collectionRadioButtons[index].setChecked(True) self.noHighlightRadioButton.setText( config.thisTranslation["removeHightlight"]) else: self.noHighlightRadioButton.setChecked(True) self.noHighlightRadioButton.setText( config.thisTranslation["noHightlight"]) self.isRefreshing = False def setupUI(self): layout = QVBoxLayout() columns = QHBoxLayout() leftColumn = QVBoxLayout() rightColumn = QVBoxLayout() self.collectionButton1, self.collectionButton2, self.collectionButton3, self.collectionButton4, self.collectionButton5, self.collectionButton6, self.collectionButton7, self.collectionButton8, self.collectionButton9, self.collectionButton10, self.collectionButton11, self.collectionButton12 = QPushButton( ), QPushButton(), QPushButton(), QPushButton(), QPushButton( ), QPushButton(), QPushButton(), QPushButton(), QPushButton( ), QPushButton(), QPushButton(), QPushButton() self.collectionButtons = ( self.collectionButton1, self.collectionButton2, self.collectionButton3, self.collectionButton4, self.collectionButton5, self.collectionButton6, self.collectionButton7, self.collectionButton8, self.collectionButton9, self.collectionButton10, self.collectionButton11, self.collectionButton12) self.collectionColourButton1, self.collectionColourButton2, self.collectionColourButton3, self.collectionColourButton4, self.collectionColourButton5, self.collectionColourButton6, self.collectionColourButton7, self.collectionColourButton8, self.collectionColourButton9, self.collectionColourButton10, self.collectionColourButton11, self.collectionColourButton12 = QPushButton( ), QPushButton(), QPushButton(), QPushButton(), QPushButton( ), QPushButton(), QPushButton(), QPushButton(), QPushButton( ), QPushButton(), QPushButton(), QPushButton() self.collectionColourButtons = ( self.collectionColourButton1, self.collectionColourButton2, self.collectionColourButton3, self.collectionColourButton4, self.collectionColourButton5, self.collectionColourButton6, self.collectionColourButton7, self.collectionColourButton8, self.collectionColourButton9, self.collectionColourButton10, self.collectionColourButton11, self.collectionColourButton12) self.collectionRadioButton1, self.collectionRadioButton2, self.collectionRadioButton3, self.collectionRadioButton4, self.collectionRadioButton5, self.collectionRadioButton6, self.collectionRadioButton7, self.collectionRadioButton8, self.collectionRadioButton9, self.collectionRadioButton10, self.collectionRadioButton11, self.collectionRadioButton12 = QRadioButton( ), QRadioButton(), QRadioButton(), QRadioButton(), QRadioButton( ), QRadioButton(), QRadioButton(), QRadioButton(), QRadioButton( ), QRadioButton(), QRadioButton(), QRadioButton() self.collectionRadioButtons = ( self.collectionRadioButton1, self.collectionRadioButton2, self.collectionRadioButton3, self.collectionRadioButton4, self.collectionRadioButton5, self.collectionRadioButton6, self.collectionRadioButton7, self.collectionRadioButton8, self.collectionRadioButton9, self.collectionRadioButton10, self.collectionRadioButton11, self.collectionRadioButton12) for index, button in enumerate(self.collectionButtons): subLayout = QHBoxLayout() radioButton = self.collectionRadioButtons[index] radioButton.setFixedWidth(20) radioButton.toggled.connect( lambda checked, option=index: self.highlightOptionChanged( checked, option)) radioButton.setToolTip( config.thisTranslation["selectApplyHighlight"]) subLayout.addWidget(radioButton) button.setText("collection" if __name__ == "__main__" else config.highlightCollections[index]) button.setFixedWidth(170) button.setToolTip(config.thisTranslation["rename"]) button.clicked.connect(partial(self.rename, index)) subLayout.addWidget(button) button = self.collectionColourButtons[index] button.setFixedWidth(50) buttonStyle = "QPushButton {0}background-color: {2}; color: {3};{1}".format( "{", "}", config.highlightDarkThemeColours[index] if config.theme == "dark" else config.highlightLightThemeColours[index], "white" if config.theme == "dark" else "black") button.setStyleSheet(buttonStyle) button.setToolTip(config.thisTranslation["changeColour"]) button.clicked.connect(partial(self.changeColor, index)) subLayout.addWidget(button) combo = QComboBox() combo.setToolTip(config.thisTranslation["filterHighlight"]) combo.addItems(self.searchList) #for index, toolTip in enumerate(self.searchListToolTips): #combo.setItemData(index, toolTip, Qt.ToolTipRole) combo.setFixedWidth(100) combo.currentIndexChanged.connect( lambda selectedIndex, index=index: self.searchHighlight( selectedIndex, index)) subLayout.addWidget(combo) leftColumn.addLayout(subLayout) if ( index % 2 == 0) else rightColumn.addLayout(subLayout) columns.addLayout(leftColumn) columns.addLayout(rightColumn) layout.addLayout(columns) subLayout0 = QHBoxLayout() subLayout = QHBoxLayout() self.noHighlightRadioButton = QRadioButton() self.noHighlightRadioButton.setFixedWidth(20) self.noHighlightRadioButton.toggled.connect( self.highlightOptionChanged) self.noHighlightRadioButton.setToolTip( config.thisTranslation["selectRemoveHighlight"]) subLayout.addWidget(self.noHighlightRadioButton) button = QPushButton(config.thisTranslation["noHightlight"]) button.setToolTip(config.thisTranslation["selectRemoveHighlight"]) button.clicked.connect(lambda: self.highlightOptionChanged(True)) subLayout.addWidget(button) subLayout0.addLayout(subLayout) subLayout = QHBoxLayout() button = QPushButton(config.thisTranslation["allCollections"]) button.setToolTip(config.thisTranslation["allCollections"]) button.clicked.connect(lambda: self.searchHighlight(1, "all")) subLayout.addWidget(button) #subLayout.addWidget(QLabel("All Collections in:")) combo = QComboBox() combo.setToolTip(config.thisTranslation["filterHighlight"]) combo.addItems(self.searchList) combo.setFixedWidth(100) combo.currentIndexChanged.connect( lambda selectedIndex: self.searchHighlight(selectedIndex, "all")) subLayout.addWidget(combo) subLayout0.addLayout(subLayout) layout.addLayout(subLayout0) layout.addStretch() box = QGroupBox(config.thisTranslation["menu_highlights"]) box.setLayout(layout) mainLayout = QVBoxLayout() mainLayout.setSpacing(0) mainLayout.addWidget(box) mainLayout.addStretch() self.setLayout(mainLayout) def highlightOptionChanged(self, checked, option=None): if checked and not self.isRefreshing: if not config.enableVerseHighlighting: config.enableVerseHighlighting = True if option is None: code = "delete" else: code = "hl{0}".format(option + 1) command = "_HIGHLIGHT:::{0}:::{1}".format( code, self.parent.parent.bibleTab.getSelectedReference()) self.parent.parent.runTextCommand(command, reloadMainWindow=True) def searchHighlight(self, selectedIndex, code): if selectedIndex != 0: if not config.enableVerseHighlighting: config.enableVerseHighlighting = True scopes = { 1: "all", 2: "ot", 3: "nt", } scope = scopes.get(selectedIndex, self.searchList[selectedIndex]) command = "SEARCHHIGHLIGHT:::{0}:::{1}".format( code if code == "all" else "hl" + str(code + 1), scope) self.parent.parent.runTextCommand(command) def rename(self, index): newName, ok = QInputDialog.getText(self, "QInputDialog.getText()", config.thisTranslation["edit"], QLineEdit.Normal, config.highlightCollections[index]) if ok and newName: config.highlightCollections[index] = newName self.collectionButtons[index].setText(newName) def changeColor(self, index): color = QColorDialog.getColor( QColor(config.highlightDarkThemeColours[index] if config.theme == "dark" else config.highlightLightThemeColours[index]), self) if color.isValid(): colorName = color.name() if config.theme in ("dark", "night"): config.highlightDarkThemeColours[index] = colorName else: config.highlightLightThemeColours[index] = colorName button = self.collectionColourButtons[index] buttonStyle = "QPushButton {0}background-color: {2}; color: {3};{1}".format( "{", "}", colorName, "white" if config.theme == "dark" else "black") button.setStyleSheet(buttonStyle)
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)
def column1Widget(self): widget = QWidget() widgetLayout0 = QVBoxLayout() bibleWidget = QGroupBox(config.thisTranslation["bible"]) bibleLayout = QVBoxLayout() bibleLayout.setSpacing(10) self.bibleCombo = CheckableComboBox(self.parent.textList, [config.mainText], toolTips=self.parent.textFullNameList) bibleLayout.addLayout(self.parent.comboFeatureLayout("html_searchBible2", self.bibleCombo, self.searchBible)) subLayout = QHBoxLayout() subLayout.setSpacing(5) leftGroupLayout = QVBoxLayout() centerGroupLayout = QVBoxLayout() rightGroupLayout = QVBoxLayout() subLayout.addLayout(leftGroupLayout) subLayout.addLayout(centerGroupLayout) subLayout.addLayout(rightGroupLayout) for index, searchMode in enumerate(self.bibleSearchModeTuple): radioButton = QRadioButton(searchMode) radioButton.setToolTip(config.thisTranslation["searchRB{0}".format(index)]) radioButton.toggled.connect(lambda checked, mode=index: self.searchModeChanged(checked, mode)) if index == config.bibleSearchMode: radioButton.setChecked(True) if index % 3 == 0: leftGroupLayout.addWidget(radioButton) elif index % 3 == 1: centerGroupLayout.addWidget(radioButton) else: rightGroupLayout.addWidget(radioButton) leftGroupLayout.addStretch() centerGroupLayout.addStretch() rightGroupLayout.addStretch() bibleLayout.addLayout(subLayout) if len(config.bibleCollections) > 0: navigationLayout6 = self.navigationLayout6() bibleLayout.addWidget(navigationLayout6) bibleWidget.setLayout(bibleLayout) widgetLayout0.addWidget(bibleWidget) # Books range selection booksWidget = QGroupBox(config.thisTranslation["menu10_books"]) booksLayout = QHBoxLayout() booksLayout.setSpacing(1) for range in [config.thisTranslation["all"], "OT", "NT", "Custom"]: radioButton = QRadioButton(range) radioButton.toggled.connect(lambda checked, range=range: self.booksChanged(checked, range)) if config.bibleSearchRange == range: radioButton.setChecked(True) booksLayout.addWidget(radioButton) if range == "Custom": self.customRangeRadioButton = radioButton self.customBooksRangeSearchField = QLineEdit() self.customBooksRangeSearchField.setText(config.customBooksRangeSearch) self.customBooksRangeSearchField.textChanged.connect(self.customBooksRangeChanged) booksLayout.addWidget(self.customBooksRangeSearchField) booksWidget.setLayout(booksLayout) widgetLayout0.addWidget(booksWidget) subLayout = QHBoxLayout() buttonRow = ( ("menu_bookNotes", lambda: self.runSearchCommand("SEARCHBOOKNOTE")), ("menu_chapterNotes", lambda: self.runSearchCommand("SEARCHCHAPTERNOTE")), ("menu_verseNotes", lambda: self.runSearchCommand("SEARCHVERSENOTE")), ) subLayout.addLayout(self.parent.buttonsLayout(buttonRow)) #subLayout.addWidget(self.highlightNoteSearchResultCheckBox()) #subLayout.addStretch() widgetLayout0.addLayout(subLayout) buttonRow1 = ( ("menu5_names", lambda: self.runSearchCommand("SEARCHTOOL:::HBN")), ("menu5_characters", lambda: self.runSearchCommand("SEARCHTOOL:::EXLBP")), ("menu5_locations", lambda: self.runSearchCommand("SEARCHTOOL:::EXLBL")), ("biblePromises", lambda: self.runSearchCommand("SEARCHBOOK:::Bible_Promises")), ) buttonRow2 = ( ("bibleHarmonies", lambda: self.runSearchCommand("SEARCHBOOK:::Harmonies_and_Parallels")), ("menu5_allBook", lambda: self.runSearchCommand("SEARCHBOOK:::ALL")), ("favouriteBooks", lambda: self.runSearchCommand("SEARCHBOOK:::FAV")), ("pdfFiles", lambda: self.runSearchCommand("SEARCHPDF")), ) buttonRow3 = ( ("allBooksPDF", lambda: self.runSearchCommand("SEARCHALLBOOKSPDF")), ("_blank", lambda: self.blankOperation()), ("_blank", lambda: self.blankOperation()), ("_blank", lambda: self.blankOperation()), ) widgetLayout0.addWidget(self.parent.buttonsWidget((buttonRow1, buttonRow2, buttonRow3))) widgetLayout0.addStretch() widget.setLayout(widgetLayout0) return widget
def setupUI(self): mainLayout = QVBoxLayout() subLayout = QHBoxLayout() subLayout.addWidget(self.searchFieldWidget()) button = QPushButton("Search") button.clicked.connect(self.searchMorphology) subLayout.addWidget(button) mainLayout.addLayout(subLayout) subLayout = QHBoxLayout() subLayout.addWidget(QLabel("Start:")) self.startBookCombo = QComboBox() subLayout.addWidget(self.startBookCombo) self.startBookCombo.addItems(self.bookList) self.startBookCombo.setCurrentIndex(0) subLayout.addWidget(QLabel("End:")) self.endBookCombo = QComboBox() subLayout.addWidget(self.endBookCombo) self.endBookCombo.addItems(self.bookList) self.endBookCombo.setCurrentIndex(65) subLayout.addWidget(QLabel(" ")) button = QPushButton("Entire Bible") button.clicked.connect(lambda: self.selectBookCombos(0, 65)) subLayout.addWidget(button) button = QPushButton("Current Book") button.clicked.connect(lambda: self.selectBookCombos(config.mainB-1, config.mainB-1)) subLayout.addWidget(button) button = QPushButton("OT") button.clicked.connect(lambda: self.selectBookCombos(0, 38)) subLayout.addWidget(button) button = QPushButton("NT") button.clicked.connect(lambda: self.selectBookCombos(39, 65)) subLayout.addWidget(button) button = QPushButton("Gospels") button.clicked.connect(lambda: self.selectBookCombos(39, 42)) subLayout.addWidget(button) subLayout.addStretch() mainLayout.addLayout(subLayout) subLayout = QHBoxLayout() self.searchTypeBox = QGroupBox("Type") layout = QVBoxLayout() self.strongsRadioButton = QRadioButton("Lexical") self.strongsRadioButton.setToolTip("G2424") self.strongsRadioButton.toggled.connect(lambda checked, mode="Lexical": self.searchTypeChanged(checked, mode)) self.strongsRadioButton.setChecked(True) layout.addWidget(self.strongsRadioButton) radioButton = QRadioButton("Word") radioButton.setToolTip("Ἰησοῦς") radioButton.toggled.connect(lambda checked, mode="Word": self.searchTypeChanged(checked, mode)) layout.addWidget(radioButton) radioButton = QRadioButton("Gloss") radioButton.setToolTip("Jesus") radioButton.toggled.connect(lambda checked, mode="Gloss": self.searchTypeChanged(checked, mode)) layout.addWidget(radioButton) # radioButton = QRadioButton("Transliteration") # radioButton.setToolTip("Iēsous") # radioButton.toggled.connect(lambda checked, mode="Transliteration": self.searchTypeChanged(checked, mode)) # layout.addWidget(radioButton) self.searchTypeBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.searchTypeBox) languageList = ["Greek", "Hebrew"] self.languageBox = QGroupBox("Language") layout = QVBoxLayout() for count, lang in enumerate(languageList): button = QRadioButton(lang) button.toggled.connect(lambda checked, mode=lang: self.languageChanged(checked, mode)) layout.addWidget(button) if count == 0: self.greekButton = button self.languageBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.languageBox) posList = ["Adjective", "Adverb", "Article", "Conjunction", "Interjection", "Noun", "Participle", "Preposition", "Pronoun", "Verb", ""] self.posCheckBoxes = [] self.partOfSpeechBox = QGroupBox("Part of speech") layout = QVBoxLayout() for count, pos in enumerate(posList): button = QRadioButton(pos) button.toggled.connect(lambda checked, mode=pos: self.partOfSpeechChanged(checked, mode)) layout.addWidget(button) if count == 0: self.nounButton = button self.partOfSpeechBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.partOfSpeechBox) greekCaseList = ["Accusative", "Dative", "Genitive", "Nominative", "Vocative"] self.greekCaseCheckBoxes = [] self.greekCaseBox = QGroupBox("Case") self.greekCaseBox.hide() layout = QVBoxLayout() for case in greekCaseList: checkbox = QCheckBox(case) layout.addWidget(checkbox) self.greekCaseCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, case=case: self.checkBoxChanged(checked, case, self.greekCaseCheckBoxes)) self.greekCaseBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekCaseBox) greekTenseList = ["Aorist", "Future", "Imperfect", "Perfect", "Pluperfect", "Present"] self.greekTenseCheckBoxes = [] self.greekTenseBox = QGroupBox("Tense") self.greekTenseBox.hide() layout = QVBoxLayout() for tense in greekTenseList: checkbox = QCheckBox(tense) layout.addWidget(checkbox) self.greekTenseCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, tense=tense: self.checkBoxChanged(checked, tense, self.greekTenseCheckBoxes)) self.greekTenseBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekTenseBox) voiceList = ["Active", "Middle", "Passive"] self.voiceCheckBoxes = [] self.voiceBox = QGroupBox("Voice") self.voiceBox.hide() layout = QVBoxLayout() for voice in voiceList: checkbox = QCheckBox(voice) layout.addWidget(checkbox) self.voiceCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, voice=voice: self.checkBoxChanged(checked, voice, self.voiceCheckBoxes)) self.voiceBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.voiceBox) greekMoodList = ["Imperative", "Indicative", "Optative", "Subjunctive"] self.greekMoodCheckBoxes = [] self.greekMoodBox = QGroupBox("Mood") self.greekMoodBox.hide() layout = QVBoxLayout() for mood in greekMoodList: checkbox = QCheckBox(mood) layout.addWidget(checkbox) self.greekMoodCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, mood=mood: self.checkBoxChanged(checked, mood, self.greekMoodCheckBoxes)) self.greekMoodBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekMoodBox) hebrewStateList = ["Construct", "Absolute"] self.hebrewStateCheckBoxes = [] self.hebrewStateBox = QGroupBox("State") self.hebrewStateBox.hide() layout = QVBoxLayout() for state in hebrewStateList: checkbox = QCheckBox(state) layout.addWidget(checkbox) self.hebrewStateCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, state=state: self.checkBoxChanged(checked, state, self.hebrewStateCheckBoxes)) self.hebrewStateBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewStateBox) hebrewStateList = ["Construct", "Absolute"] self.hebrewStateCheckBoxes = [] self.hebrewStateBox = QGroupBox("State") self.hebrewStateBox.hide() layout = QVBoxLayout() for stem in hebrewStateList: checkbox = QCheckBox(stem) layout.addWidget(checkbox) self.hebrewStateCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, stem=stem: self.checkBoxChanged(checked, stem, self.hebrewStateCheckBoxes)) self.hebrewStateBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewStateBox) hebrewPatternList = ["Hif‘il", "Hitpa“el", "Nif‘al", "Pi“el", "Pu“al", "Qal", "Wayyiqtol"] self.hebrewPatternCheckBoxes = [] self.hebrewPatternBox = QGroupBox("State") self.hebrewPatternBox.hide() layout = QVBoxLayout() for stem in hebrewPatternList: checkbox = QCheckBox(stem) layout.addWidget(checkbox) self.hebrewPatternCheckBoxes.append(checkbox) # checkbox.stateChanged.connect(lambda checked, stem=stem: self.checkBoxChanged(checked, stem, self.hebrewPatternCheckBoxes)) self.hebrewPatternBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewPatternBox) personList = ["First", "Second", "Third"] self.personCheckBoxes = [] self.personBox = QGroupBox("Person") self.personBox.hide() layout = QVBoxLayout() for person in personList: checkbox = QCheckBox(person) layout.addWidget(checkbox) self.personCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, person=person: self.checkBoxChanged(checked, person, self.personCheckBoxes)) self.personBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.personBox) numberList = ["Singular", "Plural", "Dual"] self.numberCheckBoxes = [] self.numberBox = QGroupBox("Number") self.numberBox.hide() layout = QVBoxLayout() for number in numberList: checkbox = QCheckBox(number) layout.addWidget(checkbox) self.numberCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, number=number: self.checkBoxChanged(checked, number, self.numberCheckBoxes)) self.numberBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.numberBox) genderList = ["Masculine", "Feminine", "Neuter"] self.genderCheckBoxes = [] self.genderBox = QGroupBox("Gender") self.genderBox.hide() layout = QVBoxLayout() for gender in genderList: checkbox = QCheckBox(gender) layout.addWidget(checkbox) self.genderCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, gender=gender: self.checkBoxChanged(checked, gender, self.genderCheckBoxes)) self.genderBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.genderBox) # TODO: hebrewList = ["Absolute", "", "Infinitive", "Pronominal", ""] self.spacerBox1 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox1.setLayout(layout) subLayout.addWidget(self.spacerBox1) self.spacerBox2 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox2.setLayout(layout) subLayout.addWidget(self.spacerBox2) self.spacerBox3 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox3.setLayout(layout) subLayout.addWidget(self.spacerBox3) self.spacerBox4 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox4.setLayout(layout) subLayout.addWidget(self.spacerBox4) self.spacerBox5 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox5.setLayout(layout) subLayout.addWidget(self.spacerBox5) mainLayout.addLayout(subLayout) mainLayout.addStretch() self.setLayout(mainLayout) self.greekButton.setChecked(True) self.nounButton.setChecked(True)
class MorphologyLauncher(QWidget): def __init__(self, parent): super().__init__() self.setWindowTitle(config.thisTranslation["cp7"]) self.parent = parent self.bookList = BibleBooks.getStandardBookAbbreviations() self.setupUI() def setupUI(self): mainLayout = QVBoxLayout() subLayout = QHBoxLayout() subLayout.addWidget(self.searchFieldWidget()) button = QPushButton("Search") button.clicked.connect(self.searchMorphology) subLayout.addWidget(button) mainLayout.addLayout(subLayout) subLayout = QHBoxLayout() subLayout.addWidget(QLabel("Start:")) self.startBookCombo = QComboBox() subLayout.addWidget(self.startBookCombo) self.startBookCombo.addItems(self.bookList) self.startBookCombo.setCurrentIndex(0) subLayout.addWidget(QLabel("End:")) self.endBookCombo = QComboBox() subLayout.addWidget(self.endBookCombo) self.endBookCombo.addItems(self.bookList) self.endBookCombo.setCurrentIndex(65) subLayout.addWidget(QLabel(" ")) button = QPushButton("Entire Bible") button.clicked.connect(lambda: self.selectBookCombos(0, 65)) subLayout.addWidget(button) button = QPushButton("Current Book") button.clicked.connect(lambda: self.selectBookCombos(config.mainB-1, config.mainB-1)) subLayout.addWidget(button) button = QPushButton("OT") button.clicked.connect(lambda: self.selectBookCombos(0, 38)) subLayout.addWidget(button) button = QPushButton("NT") button.clicked.connect(lambda: self.selectBookCombos(39, 65)) subLayout.addWidget(button) button = QPushButton("Gospels") button.clicked.connect(lambda: self.selectBookCombos(39, 42)) subLayout.addWidget(button) subLayout.addStretch() mainLayout.addLayout(subLayout) subLayout = QHBoxLayout() self.searchTypeBox = QGroupBox("Type") layout = QVBoxLayout() self.strongsRadioButton = QRadioButton("Lexical") self.strongsRadioButton.setToolTip("G2424") self.strongsRadioButton.toggled.connect(lambda checked, mode="Lexical": self.searchTypeChanged(checked, mode)) self.strongsRadioButton.setChecked(True) layout.addWidget(self.strongsRadioButton) radioButton = QRadioButton("Word") radioButton.setToolTip("Ἰησοῦς") radioButton.toggled.connect(lambda checked, mode="Word": self.searchTypeChanged(checked, mode)) layout.addWidget(radioButton) radioButton = QRadioButton("Gloss") radioButton.setToolTip("Jesus") radioButton.toggled.connect(lambda checked, mode="Gloss": self.searchTypeChanged(checked, mode)) layout.addWidget(radioButton) # radioButton = QRadioButton("Transliteration") # radioButton.setToolTip("Iēsous") # radioButton.toggled.connect(lambda checked, mode="Transliteration": self.searchTypeChanged(checked, mode)) # layout.addWidget(radioButton) self.searchTypeBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.searchTypeBox) languageList = ["Greek", "Hebrew"] self.languageBox = QGroupBox("Language") layout = QVBoxLayout() for count, lang in enumerate(languageList): button = QRadioButton(lang) button.toggled.connect(lambda checked, mode=lang: self.languageChanged(checked, mode)) layout.addWidget(button) if count == 0: self.greekButton = button self.languageBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.languageBox) posList = ["Adjective", "Adverb", "Article", "Conjunction", "Interjection", "Noun", "Participle", "Preposition", "Pronoun", "Verb", ""] self.posCheckBoxes = [] self.partOfSpeechBox = QGroupBox("Part of speech") layout = QVBoxLayout() for count, pos in enumerate(posList): button = QRadioButton(pos) button.toggled.connect(lambda checked, mode=pos: self.partOfSpeechChanged(checked, mode)) layout.addWidget(button) if count == 0: self.nounButton = button self.partOfSpeechBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.partOfSpeechBox) greekCaseList = ["Accusative", "Dative", "Genitive", "Nominative", "Vocative"] self.greekCaseCheckBoxes = [] self.greekCaseBox = QGroupBox("Case") self.greekCaseBox.hide() layout = QVBoxLayout() for case in greekCaseList: checkbox = QCheckBox(case) layout.addWidget(checkbox) self.greekCaseCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, case=case: self.checkBoxChanged(checked, case, self.greekCaseCheckBoxes)) self.greekCaseBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekCaseBox) greekTenseList = ["Aorist", "Future", "Imperfect", "Perfect", "Pluperfect", "Present"] self.greekTenseCheckBoxes = [] self.greekTenseBox = QGroupBox("Tense") self.greekTenseBox.hide() layout = QVBoxLayout() for tense in greekTenseList: checkbox = QCheckBox(tense) layout.addWidget(checkbox) self.greekTenseCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, tense=tense: self.checkBoxChanged(checked, tense, self.greekTenseCheckBoxes)) self.greekTenseBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekTenseBox) voiceList = ["Active", "Middle", "Passive"] self.voiceCheckBoxes = [] self.voiceBox = QGroupBox("Voice") self.voiceBox.hide() layout = QVBoxLayout() for voice in voiceList: checkbox = QCheckBox(voice) layout.addWidget(checkbox) self.voiceCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, voice=voice: self.checkBoxChanged(checked, voice, self.voiceCheckBoxes)) self.voiceBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.voiceBox) greekMoodList = ["Imperative", "Indicative", "Optative", "Subjunctive"] self.greekMoodCheckBoxes = [] self.greekMoodBox = QGroupBox("Mood") self.greekMoodBox.hide() layout = QVBoxLayout() for mood in greekMoodList: checkbox = QCheckBox(mood) layout.addWidget(checkbox) self.greekMoodCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, mood=mood: self.checkBoxChanged(checked, mood, self.greekMoodCheckBoxes)) self.greekMoodBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.greekMoodBox) hebrewStateList = ["Construct", "Absolute"] self.hebrewStateCheckBoxes = [] self.hebrewStateBox = QGroupBox("State") self.hebrewStateBox.hide() layout = QVBoxLayout() for state in hebrewStateList: checkbox = QCheckBox(state) layout.addWidget(checkbox) self.hebrewStateCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, state=state: self.checkBoxChanged(checked, state, self.hebrewStateCheckBoxes)) self.hebrewStateBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewStateBox) hebrewStateList = ["Construct", "Absolute"] self.hebrewStateCheckBoxes = [] self.hebrewStateBox = QGroupBox("State") self.hebrewStateBox.hide() layout = QVBoxLayout() for stem in hebrewStateList: checkbox = QCheckBox(stem) layout.addWidget(checkbox) self.hebrewStateCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, stem=stem: self.checkBoxChanged(checked, stem, self.hebrewStateCheckBoxes)) self.hebrewStateBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewStateBox) hebrewPatternList = ["Hif‘il", "Hitpa“el", "Nif‘al", "Pi“el", "Pu“al", "Qal", "Wayyiqtol"] self.hebrewPatternCheckBoxes = [] self.hebrewPatternBox = QGroupBox("State") self.hebrewPatternBox.hide() layout = QVBoxLayout() for stem in hebrewPatternList: checkbox = QCheckBox(stem) layout.addWidget(checkbox) self.hebrewPatternCheckBoxes.append(checkbox) # checkbox.stateChanged.connect(lambda checked, stem=stem: self.checkBoxChanged(checked, stem, self.hebrewPatternCheckBoxes)) self.hebrewPatternBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.hebrewPatternBox) personList = ["First", "Second", "Third"] self.personCheckBoxes = [] self.personBox = QGroupBox("Person") self.personBox.hide() layout = QVBoxLayout() for person in personList: checkbox = QCheckBox(person) layout.addWidget(checkbox) self.personCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, person=person: self.checkBoxChanged(checked, person, self.personCheckBoxes)) self.personBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.personBox) numberList = ["Singular", "Plural", "Dual"] self.numberCheckBoxes = [] self.numberBox = QGroupBox("Number") self.numberBox.hide() layout = QVBoxLayout() for number in numberList: checkbox = QCheckBox(number) layout.addWidget(checkbox) self.numberCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, number=number: self.checkBoxChanged(checked, number, self.numberCheckBoxes)) self.numberBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.numberBox) genderList = ["Masculine", "Feminine", "Neuter"] self.genderCheckBoxes = [] self.genderBox = QGroupBox("Gender") self.genderBox.hide() layout = QVBoxLayout() for gender in genderList: checkbox = QCheckBox(gender) layout.addWidget(checkbox) self.genderCheckBoxes.append(checkbox) checkbox.stateChanged.connect(lambda checked, gender=gender: self.checkBoxChanged(checked, gender, self.genderCheckBoxes)) self.genderBox.setLayout(layout) layout.addStretch() subLayout.addWidget(self.genderBox) # TODO: hebrewList = ["Absolute", "", "Infinitive", "Pronominal", ""] self.spacerBox1 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox1.setLayout(layout) subLayout.addWidget(self.spacerBox1) self.spacerBox2 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox2.setLayout(layout) subLayout.addWidget(self.spacerBox2) self.spacerBox3 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox3.setLayout(layout) subLayout.addWidget(self.spacerBox3) self.spacerBox4 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox4.setLayout(layout) subLayout.addWidget(self.spacerBox4) self.spacerBox5 = QGroupBox(" ") layout = QVBoxLayout() layout.addStretch() self.spacerBox5.setLayout(layout) subLayout.addWidget(self.spacerBox5) mainLayout.addLayout(subLayout) mainLayout.addStretch() self.setLayout(mainLayout) self.greekButton.setChecked(True) self.nounButton.setChecked(True) def selectBookCombos(self, start, end): self.startBookCombo.setCurrentIndex(start) self.endBookCombo.setCurrentIndex(end) def searchTypeChanged(self, checked, type): self.type = type def searchFieldWidget(self): self.searchField = QLineEdit() self.searchField.setClearButtonEnabled(True) self.searchField.setToolTip(config.thisTranslation["menu5_searchItems"]) self.searchField.returnPressed.connect(self.searchMorphology) return self.searchField def checkBoxChanged(self, state, value, checkboxes): if int(state) > 0: for checkbox in checkboxes: if checkbox.isChecked() and value != checkbox.text(): checkbox.setChecked(False) def languageChanged(self, checked, language): if checked: self.language = language self.updateAllCheckboxes() def partOfSpeechChanged(self, checked, pos): if checked: self.pos = pos self.updateAllCheckboxes() def updateAllCheckboxes(self): self.genderBox.hide() self.numberBox.hide() self.greekCaseBox.hide() self.personBox.hide() self.greekTenseBox.hide() self.greekMoodBox.hide() self.voiceBox.hide() self.hebrewStateBox.hide() self.hebrewPatternBox.hide() self.spacerBox1.hide() self.spacerBox2.hide() self.spacerBox3.hide() self.spacerBox4.hide() self.spacerBox5.hide() if self.language == "Greek": if self.pos in ("Noun", "Adjective"): self.greekCaseBox.show() self.numberBox.show() self.genderBox.show() self.spacerBox4.show() self.spacerBox5.show() elif self.pos in ("Pronoun", "Article"): self.greekCaseBox.show() self.numberBox.show() self.genderBox.show() self.personBox.show() self.spacerBox5.show() elif self.pos == "Verb": self.greekTenseBox.show() self.voiceBox.show() self.greekMoodBox.show() self.personBox.show() self.numberBox.show() elif self.pos == "Adverb": self.greekCaseBox.show() self.numberBox.show() self.genderBox.show() self.spacerBox4.show() self.spacerBox5.show() else: self.spacerBox1.show() self.spacerBox2.show() self.spacerBox3.show() self.spacerBox4.show() self.spacerBox5.show() else: if self.pos in ("Noun", "Adjective", "Preposition", "Pronoun"): self.numberBox.show() self.genderBox.show() self.hebrewStateBox.show() self.spacerBox4.show() self.spacerBox5.show() elif self.pos in ("Verb", "Adverb"): self.personBox.show() self.genderBox.show() self.numberBox.show() self.hebrewStateBox.show() self.hebrewPatternBox.show() else: self.spacerBox1.show() self.spacerBox2.show() self.spacerBox3.show() self.spacerBox4.show() self.spacerBox5.show() def searchMorphology(self): searchTerm = self.searchField.text() if len(searchTerm) > 1: morphologyList = [] morphologyList.append(self.pos) if self.language == "Greek": if self.pos in ("Noun", "Adjective"): checkBoxList = [self.greekCaseCheckBoxes, self.numberCheckBoxes, self.genderCheckBoxes] elif self.pos == ("Pronoun", "Article"): checkBoxList = [self.greekCaseCheckBoxes, self.numberCheckBoxes, self.genderCheckBoxes, self.personCheckBoxes] elif self.pos == "Verb": checkBoxList = [self.greekTenseCheckBoxes, self.voiceCheckBoxes, self.greekMoodCheckBoxes, self.personCheckBoxes, self.numberCheckBoxes] elif self.pos == "Adverb": checkBoxList = [self.greekCaseCheckBoxes, self.numberCheckBoxes, self.genderCheckBoxes] else: checkBoxList = [] else: if self.pos in ("Noun", "Adjective", "Preposition", "Pronoun"): checkBoxList = [self.numberCheckBoxes, self.genderCheckBoxes, self.hebrewStateCheckBoxes] elif self.pos in ("Verb", "Adverb"): checkBoxList = [self.personCheckBoxes, self.genderCheckBoxes, self.numberCheckBoxes, self.hebrewStateCheckBoxes, self.hebrewPatternCheckBoxes] else: checkBoxList = [] for checkBoxes in checkBoxList: for checkbox in checkBoxes: if checkbox.isChecked(): morphologyList.append(checkbox.text()) morphology = ",".join(morphologyList) startBook = self.startBookCombo.currentIndex() + 1 endBook = self.endBookCombo.currentIndex() + 1 if endBook < startBook: endBook = startBook if self.type == "Lexical": command = "SEARCHMORPHOLOGYBYLEX:::{0}:::{1}:::{2}-{3}".format(searchTerm, morphology, startBook, endBook) elif self.type == "Word": command = "SEARCHMORPHOLOGYBYWORD:::{0}:::{1}:::{2}-{3}".format(searchTerm, morphology, startBook, endBook) elif self.type == "Gloss": command = "SEARCHMORPHOLOGYBYGLOSS:::{0}:::{1}:::{2}-{3}".format(searchTerm, morphology, startBook, endBook) self.parent.runTextCommand(command)
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)