def create_scedit(self, text, option, default=NoDefault, tip=None, without_layout=False): label = QLabel(text) clayout = ColorLayout(QColor(Qt.black), self) clayout.lineedit.setMaximumWidth(80) if tip is not None: clayout.setToolTip(tip) cb_bold = QCheckBox() cb_bold.setIcon(get_icon("bold.png")) cb_bold.setToolTip(_("Bold")) cb_italic = QCheckBox() cb_italic.setIcon(get_icon("italic.png")) cb_italic.setToolTip(_("Italic")) self.scedits[(clayout, cb_bold, cb_italic)] = (option, default) if without_layout: return label, clayout, cb_bold, cb_italic layout = QHBoxLayout() layout.addWidget(label) layout.addLayout(clayout) layout.addSpacing(10) layout.addWidget(cb_bold) layout.addWidget(cb_italic) layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.setLayout(layout) return widget
def setup(self, fname): """Setup Run Configuration dialog with filename *fname*""" combo_label = QLabel(_("Select a run configuration:")) self.combo = QComboBox() self.combo.setMaxVisibleItems(20) self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.stack = QStackedWidget() configurations = _get_run_configurations() for index, (filename, options) in enumerate(configurations): if fname == filename: break else: # There is no run configuration for script *fname*: # creating a temporary configuration that will be kept only if # dialog changes are accepted by the user configurations.insert(0, (fname, RunConfiguration(fname).get())) index = 0 for filename, options in configurations: widget = RunConfigOptions(self) widget.set(options) self.combo.addItem(filename) self.stack.addWidget(widget) self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.stack.setCurrentIndex) self.combo.setCurrentIndex(index) self.add_widgets(combo_label, self.combo, 10, self.stack) self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self.setWindowTitle(_("Run Settings"))
def delete_file(self, fname, multiple, yes_to_all): """Delete file""" if multiple: buttons = QMessageBox.Yes | QMessageBox.YesAll | QMessageBox.No | QMessageBox.Cancel else: buttons = QMessageBox.Yes | QMessageBox.No if yes_to_all is None: answer = QMessageBox.warning( self, _("Delete"), _("Do you really want " "to delete <b>%s</b>?") % osp.basename(fname), buttons ) if answer == QMessageBox.No: return yes_to_all elif answer == QMessageBox.Cancel: return False elif answer == QMessageBox.YesAll: yes_to_all = True try: if osp.isfile(fname): misc.remove_file(fname) self.parent_widget.emit(SIGNAL("removed(QString)"), fname) else: self.remove_tree(fname) self.parent_widget.emit(SIGNAL("removed_tree(QString)"), fname) return yes_to_all except EnvironmentError, error: action_str = _("delete") QMessageBox.critical( self, _("Project Explorer"), _("<b>Unable to %s <i>%s</i></b>" "<br><br>Error message:<br>%s") % (action_str, fname, unicode(error)), )
def synchronize(self): """ Synchronize Spyder's path list with PYTHONPATH environment variable Only apply to: current user, on Windows platforms """ answer = QMessageBox.question(self, _("Synchronize"), _("This will synchronize Spyder's path list with " "<b>PYTHONPATH</b> environment variable for current user, " "allowing you to run your Python modules outside Spyder " "without having to configure sys.path. " "<br>Do you want to clear contents of PYTHONPATH before " "adding Spyder's path list?"), QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if answer == QMessageBox.Cancel: return elif answer == QMessageBox.Yes: remove = True else: remove = False from SMlib.utils.environ import (get_user_env, set_user_env, listdict2envdict) env = get_user_env() if remove: ppath = self.pathlist+self.ro_pathlist else: ppath = env.get('PYTHONPATH', []) if not isinstance(ppath, list): ppath = [ppath] ppath = [path for path in ppath if path not in (self.pathlist+self.ro_pathlist)] ppath.extend(self.pathlist+self.ro_pathlist) env['PYTHONPATH'] = ppath set_user_env( listdict2envdict(env), parent=self )
def move(self, fnames=None): """Move files/directories""" if fnames is None: fnames = self.get_selected_filenames() orig = fixpath(osp.dirname(fnames[0])) while True: self.parent_widget.emit(SIGNAL("redirect_stdio(bool)"), False) folder = getexistingdirectory(self, _("Select directory"), orig) self.parent_widget.emit(SIGNAL("redirect_stdio(bool)"), True) if folder: folder = fixpath(folder) if folder != orig: break else: return for fname in fnames: basename = osp.basename(fname) try: misc.move_file(fname, osp.join(folder, basename)) except EnvironmentError, error: QMessageBox.critical( self, _("Error"), _("<b>Unable to move <i>%s</i></b>" "<br><br>Error message:<br>%s") % (basename, unicode(error)), )
def setup_top_toolbar(self, layout): toolbar = [] movetop_button = create_toolbutton(self, text=_("Move to top"), icon=get_icon('2uparrow.png'), triggered=lambda: self.move_to(absolute=0), text_beside_icon=True) toolbar.append(movetop_button) moveup_button = create_toolbutton(self, text=_("Move up"), icon=get_icon('1uparrow.png'), triggered=lambda: self.move_to(relative=-1), text_beside_icon=True) toolbar.append(moveup_button) movedown_button = create_toolbutton(self, text=_("Move down"), icon=get_icon('1downarrow.png'), triggered=lambda: self.move_to(relative=1), text_beside_icon=True) toolbar.append(movedown_button) movebottom_button = create_toolbutton(self, text=_("Move to bottom"), icon=get_icon('2downarrow.png'), triggered=lambda: self.move_to(absolute=1), text_beside_icon=True) toolbar.append(movebottom_button) self.selection_widgets.extend(toolbar) self._add_widgets_to_layout(layout, toolbar) return toolbar
def remove_path(self): answer = QMessageBox.warning(self, _("Remove path"), _("Do you really want to remove selected path?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.pop(self.listwidget.currentRow()) self.update_list()
def show_docstring(self, text, call=False, force=False): """Show docstring or arguments""" text = unicode(text) # Useful only for ExternalShellBase insp_enabled = self.inspector_enabled or force if force and self.inspector is not None: self.inspector.dockwidget.setVisible(True) self.inspector.dockwidget.raise_() if insp_enabled and (self.inspector is not None) and \ (self.inspector.dockwidget.isVisible()): # ObjectInspector widget exists and is visible self.inspector.set_shell(self) self.inspector.set_object_text(text, ignore_unknown=True) self.setFocus() # if inspector was not at top level, raising it to # top will automatically give it focus because of # the visibility_changed signal, so we must give # focus back to shell if call and self.calltips: # Display argument list if this is function call iscallable = self.iscallable(text) if iscallable is not None: if iscallable: arglist = self.get_arglist(text) if isinstance(arglist, bool): arglist = [] if arglist: self.show_calltip(_("Arguments"), arglist, '#129625') elif self.calltips: # inspector is not visible or link is disabled doc = self.get__doc__(text) if doc is not None: self.show_calltip(_("Documentation"), doc)
def __init__(self, value, parent=None): QGridLayout.__init__(self) font = tuple_to_qfont(value) assert font is not None # Font family self.family = QFontComboBox(parent) self.family.setCurrentFont(font) self.addWidget(self.family, 0, 0, 1, -1) # Font size self.size = QComboBox(parent) self.size.setEditable(True) sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72] size = font.pointSize() if size not in sizelist: sizelist.append(size) sizelist.sort() self.size.addItems([str(s) for s in sizelist]) self.size.setCurrentIndex(sizelist.index(size)) self.addWidget(self.size, 1, 0) # Italic or not self.italic = QCheckBox(_("Italic"), parent) self.italic.setChecked(font.italic()) self.addWidget(self.italic, 1, 1) # Bold or not self.bold = QCheckBox(_("Bold"), parent) self.bold.setChecked(font.bold()) self.addWidget(self.bold, 1, 2)
def get_toolbar_buttons(self): if self.run_button is None: self.run_button = create_toolbutton(self, text=_("Run"), icon=get_icon('run.png'), tip=_("Run again this program"), triggered=self.start_shell) if self.kill_button is None: self.kill_button = create_toolbutton(self, text=_("Kill"), icon=get_icon('kill.png'), tip=_("Kills the current process, " "causing it to exit immediately")) buttons = [self.run_button] if self.options_button is None: options = self.get_options_menu() if options: self.options_button = create_toolbutton(self, text=_("Options"), icon=get_icon('tooloptions.png')) self.options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, options) self.options_button.setMenu(menu) if self.options_button is not None: buttons.append(self.options_button) buttons.append(self.kill_button) return buttons
def save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = os.getcwdu() filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() if self.is_internal_shell: wsfilter = self.get_internal_shell_filter('picklable', check_all=True) namespace = wsfilter(self.shellwidget.interpreter.namespace).copy() error_message = iofunctions.save(namespace, filename) else: settings = self.get_view_settings() error_message = monitor_save_globals(self._get_sock(), settings, filename) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical(self, _("Save data"), _("<b>Unable to save current workspace</b>" "<br><br>Error message:<br>%s") % error_message) self.save_button.setEnabled(self.filename is not None)
def create_context_menu_actions(self): """Create context menu actions""" actions = [] fnames = self.get_selected_filenames() new_actions = self.create_file_new_actions(fnames) if len(new_actions) > 1: # Creating a submenu only if there is more than one entry new_act_menu = QMenu(_("New"), self) add_actions(new_act_menu, new_actions) actions.append(new_act_menu) else: actions += new_actions import_actions = self.create_file_import_actions(fnames) if len(import_actions) > 1: # Creating a submenu only if there is more than one entry import_act_menu = QMenu(_("Import"), self) add_actions(import_act_menu, import_actions) actions.append(import_act_menu) else: actions += import_actions if actions: actions.append(None) if fnames: actions += self.create_file_manage_actions(fnames) if actions: actions.append(None) if fnames and all([osp.isdir(_fn) for _fn in fnames]): actions += self.create_folder_manage_actions(fnames) if actions: actions.append(None) actions += self.common_actions return actions
def get_plugin_actions(self): """Return a list of actions related to plugin""" # Font font_action = create_action(self, _("&Font..."), None, 'font.png', _("Set font style"), triggered=self.change_font) self.treewidget.common_actions.append(font_action) return []
def change_max_line_count(self): "Change maximum line count" "" mlc, valid = QInputDialog.getInteger( self, _("Buffer"), _("Maximum line count"), self.get_option("max_line_count"), 0, 1000000 ) if valid: self.shell.setMaximumBlockCount(mlc) self.set_option("max_line_count", mlc)
def change_history_depth(self): "Change history max entries""" depth, valid = QInputDialog.getInteger(self, _('History'), _('Maximum entries'), self.get_option('max_entries'), 10, 10000) if valid: self.set_option('max_entries', depth)
def get_arguments(self): arguments, valid = QInputDialog.getText(self, _('Arguments'), _('Command line arguments:'), QLineEdit.Normal, self.arguments) if valid: self.arguments = unicode(arguments) return valid
def __init__(self, parent): QWebView.__init__(self, parent) self.zoom_factor = 1. self.zoom_out_action = create_action(self, _("Zoom out"), icon=get_icon('zoom_out.png'), triggered=self.zoom_out) self.zoom_in_action = create_action(self, _("Zoom in"), icon=get_icon('zoom_in.png'), triggered=self.zoom_in)
def is_valid(self): wdir = unicode(self.wd_edit.text()) if not self.wd_cb.isChecked() or osp.isdir(wdir): return True else: QMessageBox.critical(self, _("Run configuration"), _("The following working directory is " "not valid:<br><b>%s</b>") % wdir) return False
def edit_filter(self): """Edit name filters""" filters, valid = QInputDialog.getText( self, _("Edit filename filters"), _("Name filters:"), QLineEdit.Normal, ", ".join(self.name_filters) ) if valid: filters = [f.strip() for f in unicode(filters).split(",")] self.parent_widget.sig_option_changed.emit("name_filters", filters) self.set_name_filters(filters)
def vcs_command(self, fnames, tool): """VCS command (Mercurial, git...)""" try: for path in sorted(fnames): vcs.run_vcs_tool(path, tool=tool) except RuntimeError, error: QMessageBox.critical( self, _("Error"), _("<b>Unable to find external program.</b>" "<br><br>%s") % unicode(error) )
def __init__(self, parent): BaseComboBox.__init__(self, parent) self.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.font = QFont() self.connect(self, SIGNAL("editTextChanged(QString)"), self.validate) self.connect(self, SIGNAL("activated(QString)"), lambda qstr: self.validate(qstr, editing=False)) self.set_default_style() self.tips = {True: _("Press enter to validate this entry"), False: _('This entry is incorrect')}
def setup_page(self): settings_group = QGroupBox(_("Settings")) hist_spin = self.create_spinbox( _("History depth: "), _(" entries"), 'max_entries', min_=10, max_=10000, step=10, tip=_("Set maximum line count")) sourcecode_group = QGroupBox(_("Source code")) wrap_mode_box = self.create_checkbox(_("Wrap lines"), 'wrap') go_to_eof_box = self.create_checkbox( _("Scroll automatically to last entry"), 'go_to_eof') font_group = self.create_fontgroup(option=None, text=_("Font style"), fontfilters=QFontComboBox.MonospacedFonts) names = CONF.get('color_schemes', 'names') choices = zip(names, names) cs_combo = self.create_combobox(_("Syntax color scheme: "), choices, 'color_scheme_name') settings_layout = QVBoxLayout() settings_layout.addWidget(hist_spin) settings_group.setLayout(settings_layout) sourcecode_layout = QVBoxLayout() sourcecode_layout.addWidget(wrap_mode_box) sourcecode_layout.addWidget(go_to_eof_box) sourcecode_layout.addWidget(cs_combo) sourcecode_group.setLayout(sourcecode_layout) vlayout = QVBoxLayout() vlayout.addWidget(settings_group) vlayout.addWidget(font_group) vlayout.addWidget(sourcecode_group) vlayout.addStretch(1) self.setLayout(vlayout)
def select_file(self, edit, filters=None): """Select File""" basedir = osp.dirname(unicode(edit.text())) if not osp.isdir(basedir): basedir = os.getcwdu() if filters is None: filters = _("All files (*)") title = _("Select file") filename, _selfilter = getopenfilename(self, title, basedir, filters) if filename: edit.setText(filename)
def change_exteditor(self): """Change external editor path""" path, valid = QInputDialog.getText( self, _("External editor"), _("External editor executable path:"), QLineEdit.Normal, self.get_option("external_editor/path"), ) if valid: self.set_option("external_editor/path", unicode(path))
def __init__(self, parent, adjust_to_contents=False): EditableComboBox.__init__(self, parent) if adjust_to_contents: self.setSizeAdjustPolicy(QComboBox.AdjustToContents) else: self.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.tips = {True: _("Press enter to validate this path"), False: _('This path is incorrect.\n' 'Enter a correct directory path,\n' 'then press enter to validate')}
def __init__(self, parent, statusbar): StatusBarWidget.__init__(self, parent, statusbar) layout = self.layout() layout.addWidget(QLabel(_("Line:"))) self.line = QLabel() self.line.setFont(self.label_font) layout.addWidget(self.line) layout.addWidget(QLabel(_("Column:"))) self.column = QLabel() self.column.setFont(self.label_font) layout.addWidget(self.column) self.setLayout(layout)
def setup_common_actions(self): """Setup context menu common actions""" # Filters filters_action = create_action( self, _("Edit filename filters..."), None, get_icon("filter.png"), triggered=self.edit_filter ) # Show all files all_action = create_action(self, _("Show all files"), toggled=self.toggle_all) all_action.setChecked(self.show_all) self.toggle_all(self.show_all) return [filters_action, all_action]
def change_format(self): """Change display format""" format, valid = QInputDialog.getText( self, _("Format"), _("Float formatting"), QLineEdit.Normal, self.model.get_format() ) if valid: format = str(format) try: format % 1.1 except: QMessageBox.critical(self, _("Error"), _("Format (%s) is incorrect") % format) return self.model.set_format(format)
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_name = 'options_less.png' tip = _('Hide advanced options') else: icon_name = 'options_more.png' tip = _('Show advanced options') self.more_options.setIcon(get_icon(icon_name)) self.more_options.setToolTip(tip)
def setup(self): if self.is_method(): self.setToolTip(0, _("Method defined at line %s") % str(self.line)) name = unicode(self.text(0)) if name.startswith('__'): self.set_icon('private2.png') elif name.startswith('_'): self.set_icon('private1.png') else: self.set_icon('method.png') else: self.set_icon('function.png') self.setToolTip(0, _("Function defined at line %s" ) % str(self.line))
def __init__(self, parent, search_text = r"# ?TODO|# ?FIXME|# ?XXX", search_text_regexp=True, search_path=None, include=[".", ".py"], include_idx=None, include_regexp=True, exclude=r"\.pyc$|\.orig$|\.hg|\.svn", exclude_idx=None, exclude_regexp=True, supported_encodings=("utf-8", "iso-8859-1", "cp1252"), in_python_path=False, more_options=False): QWidget.__init__(self, parent) self.setWindowTitle(_('Find in files')) self.search_thread = None self.get_pythonpath_callback = None self.find_options = FindOptions(self, search_text, search_text_regexp, search_path, include, include_idx, include_regexp, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options) self.connect(self.find_options, SIGNAL('find()'), self.find) self.connect(self.find_options, SIGNAL('stop()'), self.stop_and_reset_thread) self.result_browser = ResultsBrowser(self) collapse_btn = create_toolbutton(self) collapse_btn.setDefaultAction(self.result_browser.collapse_all_action) expand_btn = create_toolbutton(self) expand_btn.setDefaultAction(self.result_browser.expand_all_action) restore_btn = create_toolbutton(self) restore_btn.setDefaultAction(self.result_browser.restore_action) # collapse_sel_btn = create_toolbutton(self) # collapse_sel_btn.setDefaultAction( # self.result_browser.collapse_selection_action) # expand_sel_btn = create_toolbutton(self) # expand_sel_btn.setDefaultAction( # self.result_browser.expand_selection_action) btn_layout = QVBoxLayout() btn_layout.setAlignment(Qt.AlignTop) for widget in [collapse_btn, expand_btn, restore_btn]: # collapse_sel_btn, expand_sel_btn]: btn_layout.addWidget(widget) hlayout = QHBoxLayout() hlayout.addWidget(self.result_browser) hlayout.addLayout(btn_layout) layout = QVBoxLayout() left, _x, right, bottom = layout.getContentsMargins() layout.setContentsMargins(left, 0, right, bottom) layout.addWidget(self.find_options) layout.addLayout(hlayout) self.setLayout(layout)
def help(self): """Help on Spyder console""" QMessageBox.about( self, _("Help"), """<b>%s</b> <p><i>%s</i><br> edit foobar.py <p><i>%s</i><br> xedit foobar.py <p><i>%s</i><br> run foobar.py <p><i>%s</i><br> clear x, y <p><i>%s</i><br> !ls <p><i>%s</i><br> object? <p><i>%s</i><br> result = oedit(object) """ % (_('Shell special commands:'), _('Internal editor:'), _('External editor:'), _('Run script:'), _('Remove references:'), _('System commands:'), _('Python help:'), _('GUI-based editor:')))
def find_string_in_files(self): self.results = {} self.nb = 0 self.error_flag = False for fname in self.filenames: with QMutexLocker(self.mutex): if self.stopped: return try: for lineno, line in enumerate(open(fname)): for text, enc in self.texts: if self.text_re: found = re.search(text, line) if found is not None: break else: found = line.find(text) if found > -1: break try: line_dec = line.decode(enc) except UnicodeDecodeError: line_dec = line if self.text_re: for match in re.finditer(text, line): res = self.results.get(osp.abspath(fname), []) res.append((lineno+1, match.start(), line_dec)) self.results[osp.abspath(fname)] = res self.nb += 1 else: while found > -1: res = self.results.get(osp.abspath(fname), []) res.append((lineno+1, found, line_dec)) self.results[osp.abspath(fname)] = res for text, enc in self.texts: found = line.find(text, found+1) if found > -1: break self.nb += 1 except IOError, (_errno, _strerror): self.error_flag = _("permission denied errors were encountered") except re.error: self.error_flag = _("invalid regular expression")
def get_options_menu(self): self.show_time_action = create_action( self, _("Show elapsed time"), toggled=self.set_elapsed_time_visible) self.show_time_action.setChecked(self.show_elapsed_time) actions = [self.show_time_action] if self.menu_actions is not None: actions += [None] + self.menu_actions return actions
def create_browsedir(self, text, option, default=NoDefault, tip=None): widget = self.create_lineedit(text, option, default, alignment=Qt.Horizontal) for edit in self.lineedits: if widget.isAncestorOf(edit): break msg = _("Invalid directory path") self.validate_data[edit] = (osp.isdir, msg) browse_btn = QPushButton(get_std_icon('DirOpenIcon'), "", self) browse_btn.setToolTip(_("Select directory")) self.connect(browse_btn, SIGNAL("clicked()"), lambda: self.select_directory(edit)) layout = QHBoxLayout() layout.addWidget(widget) layout.addWidget(browse_btn) layout.setContentsMargins(0, 0, 0, 0) browsedir = QWidget(self) browsedir.setLayout(layout) return browsedir
def setup_menu(self): """Setup context menu""" self.copy_action = create_action(self, _( "Copy"), shortcut=keybinding("Copy"), icon=get_icon('editcopy.png'), triggered=self.copy, context=Qt.WidgetShortcut) menu = QMenu(self) add_actions(menu, [self.copy_action, ]) return menu
def set_buttons_runnning_state(self, state): ExternalShellBase.set_buttons_runnning_state(self, state) self.interact_action.setEnabled(not state and not self.is_interpreter) self.debug_action.setEnabled(not state and not self.is_interpreter) self.args_action.setEnabled(not state and not self.is_interpreter) if state: if self.arguments: argstr = _("Arguments: %s") % self.arguments else: argstr = _("No argument") else: argstr = _("Arguments...") self.args_action.setText(argstr) self.terminate_button.setVisible(not self.is_interpreter and state) if not state: self.toggle_globals_explorer(False) for btn in (self.cwd_button, self.env_button, self.syspath_button): btn.setEnabled(state and self.monitor_enabled) if self.namespacebrowser_button is not None: self.namespacebrowser_button.setEnabled(state)
def add_path(self): self.emit(SIGNAL('redirect_stdio(bool)'), False) directory = getexistingdirectory(self, _("Select directory"), self.last_path) self.emit(SIGNAL('redirect_stdio(bool)'), True) if directory: directory = osp.abspath(directory) self.last_path = directory if directory in self.pathlist: answer = QMessageBox.question( self, _("Add path"), _("This directory is already included in Spyder path " "list.<br>Do you want to move it to the top of " "the list?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.remove(directory) else: return self.pathlist.insert(0, directory) self.update_list()
def get_actions_from_items(self, items): """Reimplemented OneColumnTree method""" fromcursor_act = create_action(self, text=_('Go to cursor position'), icon=get_icon('fromcursor.png'), triggered=self.go_to_cursor_position) fullpath_act = create_action(self, text=_('Show absolute path'), toggled=self.toggle_fullpath_mode) fullpath_act.setChecked(self.show_fullpath) allfiles_act = create_action(self, text=_('Show all files'), toggled=self.toggle_show_all_files) allfiles_act.setChecked(self.show_all_files) comment_act = create_action(self, text=_('Show special comments'), toggled=self.toggle_show_comments) comment_act.setChecked(self.show_comments) actions = [fullpath_act, allfiles_act, comment_act, fromcursor_act] return actions
def add_button_box(self, stdbtns): """Create dialog button box and add it to the dialog layout""" bbox = QDialogButtonBox(stdbtns) run_btn = bbox.addButton(_("Run"), QDialogButtonBox.AcceptRole) self.connect(run_btn, SIGNAL('clicked()'), self.run_btn_clicked) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) self.layout().addLayout(btnlayout)
def create_new_file(self, current_path, title, filters, create_func): """Create new file Returns True if successful""" if current_path is None: current_path = '' if osp.isfile(current_path): current_path = osp.dirname(current_path) self.parent_widget.emit(SIGNAL('redirect_stdio(bool)'), False) fname, _selfilter = getsavefilename(self, title, current_path, filters) self.parent_widget.emit(SIGNAL('redirect_stdio(bool)'), True) if fname: try: create_func(fname) return fname except EnvironmentError, error: QMessageBox.critical( self, _("New file"), _("<b>Unable to create file <i>%s</i>" "</b><br><br>Error message:<br>%s") % (fname, unicode(error)))
def setup_page(self): self.table = ShortcutsTable(self) self.connect(self.table.model, SIGNAL("dataChanged(QModelIndex,QModelIndex)"), lambda i1, i2, opt='': self.has_been_modified(opt)) vlayout = QVBoxLayout() vlayout.addWidget(self.table) reset_btn = QPushButton(_("Reset to default values")) self.connect(reset_btn, SIGNAL('clicked()'), self.reset_to_default) vlayout.addWidget(reset_btn) self.setLayout(vlayout)
def save_historylog(self): """Save current history log (all text in console)""" title = _("Save history log") self.emit(SIGNAL('redirect_stdio(bool)'), False) filename, _selfilter = getsavefilename( self, title, self.historylog_filename, "%s (*.log)" % _("History logs")) self.emit(SIGNAL('redirect_stdio(bool)'), True) if filename: filename = osp.normpath(filename) try: encoding.write(unicode(self.get_text_with_eol()), filename) self.historylog_filename = filename CONF.set('main', 'historylog_filename', filename) except EnvironmentError, error: QMessageBox.critical( self, title, _("<b>Unable to save file '%s'</b>" "<br><br>Error message:<br>%s") % (osp.basename(filename), unicode(error)))
def check_shortcuts(self): """Check shortcuts for conflicts""" conflicts = [] for index, sh1 in enumerate(self.model.shortcuts): if index == len(self.model.shortcuts)-1: break for sh2 in self.model.shortcuts[index+1:]: if sh2 is sh1: continue if str(sh2.key) == str(sh1.key) \ and (sh1.context == sh2.context or sh1.context == '_' or sh2.context == '_'): conflicts.append((sh1, sh2)) if conflicts: self.parent().emit(SIGNAL('show_this_page()')) cstr = "\n".join(['%s <---> %s' % (sh1, sh2) for sh1, sh2 in conflicts]) QMessageBox.warning(self, _( "Conflicts"), _("The following conflicts have been " "detected:")+"\n"+cstr, QMessageBox.Ok)
def create_folder_manage_actions(self, fnames): """Return folder management actions""" actions = [] if os.name == 'nt': _title = _("Open command prompt here") else: _title = _("Open terminal here") action = create_action( self, _title, icon="cmdprompt.png", triggered=lambda fnames=fnames: self.open_terminal(fnames)) actions.append(action) _title = _("Open Python interpreter here") action = create_action( self, _title, icon="python.png", triggered=lambda fnames=fnames: self.open_interpreter(fnames)) actions.append(action) return actions
def register_plugin(self): """Register plugin in Spyder's main window""" self.get_pythonpath_callback = self.main.get_spyder_pythonpath self.main.add_dockwidget(self) self.connect(self, SIGNAL("edit_goto(QString,int,QString)"), self.main.editor.load) self.connect(self, SIGNAL('redirect_stdio(bool)'), self.main.redirect_internalshell_stdio) self.connect(self.main.workingdirectory, SIGNAL("refresh_findinfiles()"), self.refreshdir) findinfiles_action = create_action( self, _("&Find in files"), "Ctrl+Shift+F", 'findf.png', triggered=self.findinfiles_callback, tip=_("Search text in multiple files")) self.main.search_menu_actions += [None, findinfiles_action] self.main.search_toolbar_actions += [None, findinfiles_action]
def setup_common_actions(self): """Setup context menu common actions""" self.collapse_all_action = create_action(self, text=_('Collapse all'), icon=get_icon('collapse.png'), triggered=self.collapseAll) self.expand_all_action = create_action(self, text=_('Expand all'), icon=get_icon('expand.png'), triggered=self.expandAll) self.restore_action = create_action( self, text=_('Restore'), tip=_('Restore original tree layout'), icon=get_icon('restore.png'), triggered=self.restore) self.collapse_selection_action = create_action( self, text=_('Collapse selection'), icon=get_icon('collapse_selection.png'), triggered=self.collapse_selection) self.expand_selection_action = create_action( self, text=_('Expand selection'), icon=get_icon('expand_selection.png'), triggered=self.expand_selection) return [ self.collapse_all_action, self.expand_all_action, self.restore_action, None, self.collapse_selection_action, self.expand_selection_action ]
def rename_file(self, fname): """Rename file""" path, valid = QInputDialog.getText(self, _('Rename'), _('New name:'), QLineEdit.Normal, osp.basename(fname)) if valid: path = osp.join(osp.dirname(fname), unicode(path)) if path == fname: return if osp.exists(path): if QMessageBox.warning( self, _("Rename"), _("Do you really want to rename <b>%s</b> and " "overwrite the existing file <b>%s</b>?") % (osp.basename(fname), osp.basename(path)), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return try: misc.rename_file(fname, path) self.parent_widget.emit( \ SIGNAL("renamed(QString,QString)"), fname, path) return path except EnvironmentError, error: QMessageBox.critical( self, _("Rename"), _("<b>Unable to rename file <i>%s</i></b>" "<br><br>Error message:<br>%s") % (osp.basename(fname), unicode(error)))
def show_help(self, obj_text, ignore_unknown=False): """Show help""" shell = self.get_shell() if shell is None: return obj_text = unicode(obj_text) if not shell.is_defined(obj_text): if self.get_option('automatic_import') and\ self.internal_shell.is_defined(obj_text, force_import=True): shell = self.internal_shell else: shell = None doc_text = None source_text = None if shell is not None: doc_text = shell.get_doc(obj_text) if isinstance(doc_text, bool): doc_text = None source_text = shell.get_source(obj_text) is_code = False if self.rich_help: self.set_sphinx_text(doc_text) if ignore_unknown: return doc_text is not None else: return True elif self.docstring: hlp_text = doc_text if hlp_text is None: hlp_text = source_text if hlp_text is None: hlp_text = self.no_doc_string if ignore_unknown: return False else: hlp_text = source_text if hlp_text is None: hlp_text = doc_text if hlp_text is None: hlp_text = _("No source code available.") if ignore_unknown: return False else: is_code = True self.set_plain_text(hlp_text, is_code=is_code) return True
def create_fontgroup(self, option=None, text=None, tip=None, fontfilters=None): """Option=None -> setting plugin font""" fontlabel = QLabel(_("Font: ")) fontbox = QFontComboBox() if fontfilters is not None: fontbox.setFontFilters(fontfilters) sizelabel = QLabel(" "+_("Size: ")) sizebox = QSpinBox() sizebox.setRange(7, 100) self.fontboxes[(fontbox, sizebox)] = option layout = QHBoxLayout() for subwidget in (fontlabel, fontbox, sizelabel, sizebox): layout.addWidget(subwidget) layout.addStretch(1) if text is None: text = _("Font style") group = QGroupBox(text) group.setLayout(layout) if tip is not None: group.setToolTip(tip) return group
def __init__(self, parent=None, pathlist=None, ro_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = os.getcwdu() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(get_icon('pythonpath.png')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.connect(self.listwidget, SIGNAL("currentRowChanged(int)"), self.refresh) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) bottom_layout.addWidget(bbox) self.update_list() self.refresh()
def setup_page(self): sourcecode_group = QGroupBox(_("Source code")) wrap_mode_box = self.create_checkbox(_("Wrap lines"), 'wrap') names = CONF.get('color_schemes', 'names') choices = zip(names, names) cs_combo = self.create_combobox(_("Syntax color scheme: "), choices, 'color_scheme_name') sourcecode_layout = QVBoxLayout() sourcecode_layout.addWidget(wrap_mode_box) sourcecode_layout.addWidget(cs_combo) sourcecode_group.setLayout(sourcecode_layout) plain_text_font_group = self.create_fontgroup(option=None, text=_("Plain text font style"), fontfilters=QFontComboBox.MonospacedFonts) rich_text_font_group = self.create_fontgroup(option='rich_text', text=_("Rich text font style")) features_group = QGroupBox(_("Additional features")) math_box = self.create_checkbox(_("Render mathematical equations"), 'math') req_sphinx = sphinx_version is not None and \ programs.is_module_installed('sphinx', '>=1.1') math_box.setEnabled(req_sphinx) if not req_sphinx: sphinx_tip = _("This feature requires Sphinx 1.1 or superior.") if sphinx_version is not None: sphinx_tip += "\n" + _("Sphinx %s is currently installed." ) % sphinx_version math_box.setToolTip(sphinx_tip) features_layout = QVBoxLayout() features_layout.addWidget(math_box) features_group.setLayout(features_layout) vlayout = QVBoxLayout() vlayout.addWidget(rich_text_font_group) vlayout.addWidget(plain_text_font_group) vlayout.addWidget(features_group) vlayout.addWidget(sourcecode_group) vlayout.addStretch(1) self.setLayout(vlayout)
def _set_step(self, step): """Proceed to a given step""" new_tab = self.tab_widget.currentIndex() + step assert new_tab < self.tab_widget.count() and new_tab >= 0 if new_tab == self.tab_widget.count() - 1: try: self.table_widget.open_data( self._get_plain_text(), self.text_widget.get_col_sep(), self.text_widget.get_row_sep(), self.text_widget.trnsp_box.isChecked(), self.text_widget.get_skiprows(), self.text_widget.get_comments()) self.done_btn.setEnabled(True) self.done_btn.setDefault(True) self.fwd_btn.setEnabled(False) self.back_btn.setEnabled(True) except (SyntaxError, AssertionError), error: QMessageBox.critical( self, _("Import wizard"), _("<b>Unable to proceed to next step</b>" "<br><br>Please check your entries." "<br><br>Error message:<br>%s") % str(error)) return
def setup_buttons(self): fromcursor_btn = create_toolbutton( self, icon=get_icon("fromcursor.png"), tip=_('Go to cursor position'), triggered=self.treewidget.go_to_cursor_position) collapse_btn = create_toolbutton(self) collapse_btn.setDefaultAction( self.treewidget.collapse_selection_action) expand_btn = create_toolbutton(self) expand_btn.setDefaultAction(self.treewidget.expand_selection_action) restore_btn = create_toolbutton(self) restore_btn.setDefaultAction(self.treewidget.restore_action) return (fromcursor_btn, collapse_btn, expand_btn, restore_btn)
def setup_context_menu(self): """Reimplements ShellBaseWidget method""" ShellBaseWidget.setup_context_menu(self) self.copy_without_prompts_action = create_action( self, _("Copy without prompts"), icon=get_icon('copywop.png'), triggered=self.copy_without_prompts) clear_line_action = create_action(self, _("Clear line"), QKeySequence("Shift+Escape"), icon=get_icon('eraser.png'), tip=_("Clear line"), triggered=self.clear_line) clear_action = create_action(self, _("Clear shell"), QKeySequence("Ctrl+L"), icon=get_icon('clear.png'), tip=_("Clear shell contents " "('cls' command)"), triggered=self.clear_terminal) add_actions(self.menu, (self.copy_without_prompts_action, clear_line_action, clear_action))
def __init__(self, parent, data, readonly=False, xlabels=None, ylabels=None): QWidget.__init__(self, parent) self.data = data self.old_data_shape = None if len(self.data.shape) == 1: self.old_data_shape = self.data.shape self.data.shape = (self.data.shape[0], 1) elif len(self.data.shape) == 0: self.old_data_shape = self.data.shape self.data.shape = (1, 1) format = SUPPORTED_FORMATS.get(data.dtype.name, '%s') self.model = ArrayModel(self.data, format=format, xlabels=xlabels, ylabels=ylabels, readonly=readonly, parent=self) self.view = ArrayView(self, self.model, data.dtype, data.shape) btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) btn = QPushButton(_( "Format")) # disable format button for int type btn.setEnabled(is_float(data.dtype)) btn_layout.addWidget(btn) self.connect(btn, SIGNAL("clicked()"), self.change_format) btn = QPushButton(_( "Resize")) btn_layout.addWidget(btn) self.connect(btn, SIGNAL("clicked()"), self.view.resize_to_contents) bgcolor = QCheckBox(_( 'Background color')) bgcolor.setChecked(self.model.bgcolor_enabled) bgcolor.setEnabled(self.model.bgcolor_enabled) self.connect(bgcolor, SIGNAL("stateChanged(int)"), self.model.bgcolor) btn_layout.addWidget(bgcolor) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(btn_layout) self.setLayout(layout)
def set_user_env(reg, parent=None): """Set HKCU (current user) environment variables""" reg = listdict2envdict(reg) types = dict() key = OpenKey(HKEY_CURRENT_USER, "Environment") for name in reg: try: _x, types[name] = QueryValueEx(key, name) except WindowsError: types[name] = REG_EXPAND_SZ key = OpenKey(HKEY_CURRENT_USER, "Environment", 0, KEY_SET_VALUE) for name in reg: SetValueEx(key, name, 0, types[name], reg[name]) try: from win32gui import SendMessageTimeout from win32con import (HWND_BROADCAST, WM_SETTINGCHANGE, SMTO_ABORTIFHUNG) SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment", SMTO_ABORTIFHUNG, 5000) except ImportError: QMessageBox.warning(parent, _("Warning"), _("Module <b>pywin32 was not found</b>.<br>" "Please restart this Windows <i>session</i> " "(not the computer) for changes to take effect."))
def run_vcs_tool(path, tool): """If path is a valid VCS repository, run the corresponding VCS tool Supported VCS tools: 'commit', 'browse' Return False if the VCS tool is not installed""" infos = get_vcs_infos(get_vcs_root(path)) for name, args in infos[tool]: if programs.find_program(name): programs.run_program(name, args, cwd=path) return else: raise RuntimeError( _("For %s support, please install one of the<br/> " "following tools:<br/><br/> %s") % (infos['name'], ', '.join([name for name, cmd in infos['commit']])))
def synchronize(self): """ Synchronize Spyder's path list with PYTHONPATH environment variable Only apply to: current user, on Windows platforms """ answer = QMessageBox.question( self, _("Synchronize"), _("This will synchronize Spyder's path list with " "<b>PYTHONPATH</b> environment variable for current user, " "allowing you to run your Python modules outside Spyder " "without having to configure sys.path. " "<br>Do you want to clear contents of PYTHONPATH before " "adding Spyder's path list?"), QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if answer == QMessageBox.Cancel: return elif answer == QMessageBox.Yes: remove = True else: remove = False from SMlib.utils.environ import (get_user_env, set_user_env, listdict2envdict) env = get_user_env() if remove: ppath = self.pathlist + self.ro_pathlist else: ppath = env.get('PYTHONPATH', []) if not isinstance(ppath, list): ppath = [ppath] ppath = [ path for path in ppath if path not in (self.pathlist + self.ro_pathlist) ] ppath.extend(self.pathlist + self.ro_pathlist) env['PYTHONPATH'] = ppath set_user_env(listdict2envdict(env), parent=self)
def __init__(self, text, title='', font=None, parent=None, readonly=False, size=(400, 300)): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.text = None self._conv = str if isinstance(text, str) else unicode self.layout = QVBoxLayout() self.setLayout(self.layout) # Text edit self.edit = QTextEdit(parent) self.connect(self.edit, SIGNAL('textChanged()'), self.text_changed) self.edit.setReadOnly(readonly) self.edit.setPlainText(text) if font is None: font = get_font('texteditor') self.edit.setFont(font) self.layout.addWidget(self.edit) # Buttons configuration buttons = QDialogButtonBox.Ok if not readonly: buttons = buttons | QDialogButtonBox.Cancel bbox = QDialogButtonBox(buttons) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.layout.addWidget(bbox) # Make the dialog act as a window self.setWindowFlags(Qt.Window) self.setWindowIcon(get_icon('edit.png')) self.setWindowTitle(_("Text editor") + \ "%s" % (" - "+str(title) if str(title) else "")) self.resize(size[0], size[1])