def start(self): """Main method of the WorkerUpdates worker""" self.url = 'https://api.github.com/repos/spyder-ide/spyder/releases' self.update_available = False self.latest_release = __version__ error_msg = None try: page = urlopen(self.url) try: data = page.read() # Needed step for python3 compatibility if not isinstance(data, str): data = data.decode() data = json.loads(data) releases = [item['tag_name'].replace('v', '') for item in data] version = __version__ result = self.check_update_available(version, releases) self.update_available, self.latest_release = result except Exception: error_msg = _('Unable to retrieve information.') except HTTPError: error_msg = _('Unable to retrieve information.') except URLError: error_msg = _('Unable to connect to the internet. <br><br>Make ' 'sure the connection is working properly.') except Exception: error_msg = _('Unable to check for updates.') self.error = error_msg self.sig_ready.emit()
def update_warning(self, warning_type=NO_WARNING, conflicts=[]): """Update warning label to reflect conflict status of new shortcut""" if warning_type == NO_WARNING: warn = False tip = 'This shortcut is correct!' elif warning_type == SEQUENCE_CONFLICT: template = '<i>{0}<b>{1}</b></i>' tip_title = _('The new shorcut conflicts with:') + '<br>' tip_body = '' for s in conflicts: tip_body += ' - {0}: {1}<br>'.format(s.context, s.name) tip_body = tip_body[:-4] # Removing last <br> tip = template.format(tip_title, tip_body) warn = True elif warning_type == SEQUENCE_LENGTH: # Sequences with 5 keysequences (i.e. Ctrl+1, Ctrl+2, Ctrl+3, # Ctrl+4, Ctrl+5) are invalid template = '<i>{0}</i>' tip = _('A compound sequence can have {break} a maximum of ' '4 subsequences.{break}').format(**{'break': '<br>'}) warn = True elif warning_type == INVALID_KEY: template = '<i>{0}</i>' tip = _('Invalid key entered') + '<br>' warn = True self.helper_button.show() if warn: self.label_warning.show() self.helper_button.setIcon(get_std_icon('MessageBoxWarning')) self.button_ok.setEnabled(False) else: self.helper_button.setIcon(get_std_icon('DialogApplyButton')) self.label_warning.setText(tip)
def run_script_in_current_client(self, filename, wdir, args, debug): """Run script in current client, if any""" norm = lambda text: remove_backslashes(to_text_string(text)) client = self.get_current_client() if client is not None: # Internal kernels, use runfile if client.kernel_widget_id is not None: line = "%s('%s'" % ('debugfile' if debug else 'runfile', norm(filename)) if args: line += ", args='%s'" % norm(args) if wdir: line += ", wdir='%s'" % norm(wdir) line += ")" else: # External kernels, use %run line = "%run " if debug: line += "-d " line += "\"%s\"" % to_text_string(filename) if args: line += " %s" % norm(args) self.execute_python_code(line) self.visibility_changed(True) self.raise_() else: #XXX: not sure it can really happen QMessageBox.warning(self, _('Warning'), _("No IPython console is currently available to run <b>%s</b>." "<br><br>Please open a new one and try again." ) % osp.basename(filename), QMessageBox.Ok)
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 get_toolbar_buttons(self): ExternalShellBase.get_toolbar_buttons(self) if self.namespacebrowser_button is None and self.stand_alone is not None: self.namespacebrowser_button = create_toolbutton( self, text=_("Variables"), icon=get_icon("dictedit.png"), tip=_("Show/hide global variables explorer"), toggled=self.toggle_globals_explorer, text_beside_icon=True, ) if self.terminate_button is None: self.terminate_button = create_toolbutton( self, text=_("Terminate"), icon=get_icon("stop.png"), tip=_( "Attempts to stop the process. The process\n" "may not exit as a result of clicking this\n" "button (it is given the chance to prompt\n" "the user for any unsaved files, etc)." ), ) buttons = [] if self.namespacebrowser_button is not None: buttons.append(self.namespacebrowser_button) buttons += [self.run_button, self.terminate_button, self.kill_button, self.options_button] return buttons
def setup_page(self): # Widgets self.table = ShortcutsTable(self) self.finder = ShortcutFinder(self.table, self.table.set_regex) self.table.finder = self.finder self.label_finder = QLabel(_('Search: ')) self.reset_btn = QPushButton(_("Reset to default values")) # Layout hlayout = QHBoxLayout() vlayout = QVBoxLayout() hlayout.addWidget(self.label_finder) hlayout.addWidget(self.finder) vlayout.addWidget(self.table) vlayout.addLayout(hlayout) vlayout.addWidget(self.reset_btn) self.setLayout(vlayout) self.setTabOrder(self.table, self.finder) self.setTabOrder(self.finder, self.reset_btn) # Signals and slots self.table.proxy_model.dataChanged.connect( lambda i1, i2, opt='': self.has_been_modified(opt)) self.reset_btn.clicked.connect(self.reset_to_default)
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 save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = getcwd() 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_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 _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) as 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 elif new_tab == 0: self.done_btn.setEnabled(False) self.fwd_btn.setEnabled(True) self.back_btn.setEnabled(False) self._focus_tab(new_tab)
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 setup(self): iofuncs = self.get_internal_funcs() + self.get_3rd_party_funcs() load_extensions = {} save_extensions = {} load_funcs = {} save_funcs = {} load_filters = [] save_filters = [] load_ext = [] for ext, name, loadfunc, savefunc in iofuncs: filter_str = to_text_string(name + " (*%s)" % ext) if loadfunc is not None: load_filters.append(filter_str) load_extensions[filter_str] = ext load_funcs[ext] = loadfunc load_ext.append(ext) if savefunc is not None: save_extensions[filter_str] = ext save_filters.append(filter_str) save_funcs[ext] = savefunc load_filters.insert(0, to_text_string(_("Supported files") + " (*" + " *".join(load_ext) + ")")) load_filters.append(to_text_string(_("All files (*.*)"))) self.load_filters = "\n".join(load_filters) self.save_filters = "\n".join(save_filters) self.load_funcs = load_funcs self.save_funcs = save_funcs self.load_extensions = load_extensions self.save_extensions = save_extensions
def set_user_env(reg, parent=None): """Set HKCU (current user) environment variables""" reg = listdict2envdict(reg) types = dict() key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment") for name in reg: try: _x, types[name] = winreg.QueryValueEx(key, name) except WindowsError: types[name] = winreg.REG_EXPAND_SZ key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_SET_VALUE) for name in reg: winreg.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 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 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.removed.emit(fname) else: self.remove_tree(fname) self.parent_widget.removed_tree.emit(fname) return yes_to_all except EnvironmentError as 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, to_text_string(error))) return False
def __init__(self, parent): QWebView.__init__(self, parent) self.zoom_factor = 1.0 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 get_arguments(self): arguments, valid = QInputDialog.getText( self, _("Arguments"), _("Command line arguments:"), QLineEdit.Normal, self.arguments ) if valid: self.arguments = to_text_string(arguments) return valid
def create_new_folder(self, current_path, title, subtitle, is_package): """Create new folder""" if current_path is None: current_path = '' if osp.isfile(current_path): current_path = osp.dirname(current_path) name, valid = QInputDialog.getText(self, title, subtitle, QLineEdit.Normal, "") if valid: dirname = osp.join(current_path, to_text_string(name)) try: os.mkdir(dirname) except EnvironmentError as error: QMessageBox.critical(self, title, _("<b>Unable " "to create folder <i>%s</i></b>" "<br><br>Error message:<br>%s" ) % (dirname, to_text_string(error))) finally: if is_package: fname = osp.join(dirname, '__init__.py') try: with open(fname, 'wb') as f: f.write(to_binary_string('#')) return dirname except EnvironmentError as error: QMessageBox.critical(self, title, _("<b>Unable " "to create file <i>%s</i></b>" "<br><br>Error message:<br>%s" ) % (fname, to_text_string(error)))
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 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 spyderlib.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 new_module(self, basedir): """New module""" title = _("New module") filters = _("Python scripts")+" (*.py *.pyw *.ipy)" create_func = lambda fname: self.parent_widget.emit( \ SIGNAL("create_module(QString)"), fname) self.create_new_file(basedir, title, filters, create_func)
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 __init__(self, parent): QWidget.__init__(self, parent) vert_layout = QVBoxLayout() # Type frame type_layout = QHBoxLayout() type_label = QLabel(_("Import as")) type_layout.addWidget(type_label) self.array_btn = array_btn = QRadioButton(_("array")) array_btn.setEnabled(ndarray is not FakeObject) array_btn.setChecked(ndarray is not FakeObject) type_layout.addWidget(array_btn) list_btn = QRadioButton(_("list")) list_btn.setChecked(not array_btn.isChecked()) type_layout.addWidget(list_btn) if pd: self.df_btn = df_btn = QRadioButton(_("DataFrame")) df_btn.setChecked(False) type_layout.addWidget(df_btn) h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) type_layout.addItem(h_spacer) type_frame = QFrame() type_frame.setLayout(type_layout) self._table_view = PreviewTable(self) vert_layout.addWidget(type_frame) vert_layout.addWidget(self._table_view) self.setLayout(vert_layout)
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 setup_bottom_toolbar(self, layout, sync=True): toolbar = [] add_button = create_toolbutton( self, text=_("Add path"), icon=get_icon("edit_add.png"), triggered=self.add_path, text_beside_icon=True ) toolbar.append(add_button) remove_button = create_toolbutton( self, text=_("Remove path"), icon=get_icon("edit_remove.png"), triggered=self.remove_path, text_beside_icon=True, ) toolbar.append(remove_button) self.selection_widgets.append(remove_button) self._add_widgets_to_layout(layout, toolbar) layout.addStretch(1) if os.name == "nt" and sync: self.sync_button = create_toolbutton( self, text=_("Synchronize..."), icon=get_icon("synchronize.png"), triggered=self.synchronize, tip=_("Synchronize Spyder's path list with PYTHONPATH " "environment variable"), text_beside_icon=True, ) layout.addWidget(self.sync_button) return toolbar
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 get_toolbar_buttons(self): """Return toolbar buttons list""" #TODO: Eventually add some buttons (Empty for now) # (see for example: spyderlib/widgets/externalshell/baseshell.py) buttons = [] # Code to add the stop button if self.stop_button is None: self.stop_button = create_toolbutton(self, text=_("Stop"), icon=self.stop_icon, tip=_("Stop the current command")) self.disable_stop_button() # set click event handler self.stop_button.clicked.connect(self.stop_button_click_handler) if self.stop_button is not None: buttons.append(self.stop_button) if self.options_button is None: options = self.get_options_menu() if options: self.options_button = create_toolbutton(self, text=_('Options'), icon=ima.icon('tooloptions')) 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) return buttons
def setup_and_check(self, data, title=''): """ Setup DataFrameEditor: return False if data is not supported, True otherwise """ self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) # in case title is not a string else: title = _("%s editor") % data.__class__.__name__ if isinstance(data, TimeSeries): self.is_time_series = True data = data.to_frame() self.setWindowTitle(title) self.resize(600, 500) self.dataModel = DataFrameModel(data, parent=self) self.dataTable = DataFrameView(self, self.dataModel) self.layout.addWidget(self.dataTable) self.setLayout(self.layout) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) btn_layout = QHBoxLayout() btn = QPushButton(_("Format")) # disable format button for int type btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton(_('Resize')) btn_layout.addWidget(btn) btn.clicked.connect(self.dataTable.resizeColumnsToContents) bgcolor = QCheckBox(_('Background color')) bgcolor.setChecked(self.dataModel.bgcolor_enabled) bgcolor.setEnabled(self.dataModel.bgcolor_enabled) bgcolor.stateChanged.connect(self.change_bgcolor_enable) btn_layout.addWidget(bgcolor) self.bgcolor_global = QCheckBox(_('Column min/max')) self.bgcolor_global.setChecked(self.dataModel.colum_avg_enabled) self.bgcolor_global.setEnabled(not self.is_time_series and self.dataModel.bgcolor_enabled) self.bgcolor_global.stateChanged.connect(self.dataModel.colum_avg) btn_layout.addWidget(self.bgcolor_global) btn_layout.addStretch() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btn_layout.addWidget(bbox) self.layout.addLayout(btn_layout, 2, 0) return True
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', to_text_string(path))
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 get_value(self, name): value = monitor_get_global(self._get_sock(), name) if value is None: if communicate(self._get_sock(), '%s is not None' % name): import pickle msg = to_text_string( _("Object <b>%s</b> is not picklable") % name) raise pickle.PicklingError(msg) return value
def set_running_state(self, state=True): self.set_buttons_runnning_state(state) self.shell.setReadOnly(not state) if state: if self.state_label is not None: self.state_label.setText( _("<span style=\'color: #44AA44\'><b>Running...</b></span>" )) self.t0 = time() self.timer.timeout.connect(self.show_time) self.timer.start(1000) else: if self.state_label is not None: self.state_label.setText(_('Terminated.')) try: self.timer.timeout.disconnect(self.show_time) except: pass
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")) browse_btn.clicked.connect(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 get_plugin_actions(self): """Return a list of actions related to plugin""" new_project_act = create_action(self, text=_('New project...'), icon=get_icon('project_expanded.png'), triggered=self.create_new_project) font_action = create_action(self, _("&Font..."), None, 'font.png', _("Set font style"), triggered=self.change_font) self.treewidget.common_actions += (None, font_action) self.main.file_menu_actions.insert(1, new_project_act) return []
def headerData(self, section, orientation, role=Qt.DisplayRole): """Qt Override.""" if role == Qt.TextAlignmentRole: if orientation == Qt.Horizontal: return to_qvariant(int(Qt.AlignHCenter | Qt.AlignVCenter)) return to_qvariant(int(Qt.AlignRight | Qt.AlignVCenter)) if role != Qt.DisplayRole: return to_qvariant() if orientation == Qt.Horizontal: if section == CONTEXT: return to_qvariant(_("Context")) elif section == NAME: return to_qvariant(_("Name")) elif section == SEQUENCE: return to_qvariant(_("Shortcut")) elif section == SEARCH_SCORE: return to_qvariant(_("Score")) return to_qvariant()
def select_directory(self): """Select directory""" basedir = to_text_string(self.wd_edit.text()) if not osp.isdir(basedir): basedir = getcwd() directory = getexistingdirectory(self, _("Select directory"), basedir) if directory: self.wd_edit.setText(directory) self.wd_cb.setChecked(True)
def select_directory(self, edit): """Select directory""" basedir = to_text_string(edit.text()) if not osp.isdir(basedir): basedir = getcwd() title = _("Select directory") directory = getexistingdirectory(self, title, basedir) if directory: edit.setText(directory)
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"), icon='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 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 __init__(self, parent=None): super(WinUserEnvDialog, self).__init__(parent) self.setup(get_user_env(), title="HKEY_CURRENT_USER\Environment", width=600) if parent is None: parent = self QMessageBox.warning( parent, _("Warning"), _("If you accept changes, " "this will modify the current user environment " "variables directly <b>in Windows registry</b>. " "Use it with precautions, at your own risks.<br>" "<br>Note that for changes to take effect, you will " "need to restart the parent process of this applica" "tion (simply restart Spyder if you have executed it " "from a Windows shortcut, otherwise restart any " "application from which you may have executed it, " "like <i>Python(x,y) Home</i> for example)"))
def setup_page(self): self.table = ShortcutsTable(self) self.table.model.dataChanged.connect( lambda i1, i2, opt='': self.has_been_modified(opt)) vlayout = QVBoxLayout() vlayout.addWidget(self.table) reset_btn = QPushButton(_("Reset to default values")) reset_btn.clicked.connect(self.reset_to_default) vlayout.addWidget(reset_btn) self.setLayout(vlayout)
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_loading_page(self): loading_template = Template(LOADING) loading_img = get_image_path('loading_sprites.png') if os.name == 'nt': loading_img = loading_img.replace('\\', '/') message = _("Connecting to kernel...") page = loading_template.substitute(css_path=CSS_PATH, loading_img=loading_img, message=message) return page
def setup_menu(self): """Setup context menu""" self.copy_action = create_action(self, _('Copy'), shortcut=keybinding('Copy'), icon=ima.icon('editcopy'), triggered=self.copy, context=Qt.WidgetShortcut) menu = QMenu(self) add_actions(menu, [self.copy_action, ]) return menu
def update_warning(self): """ """ widget = self._button_warning if not self.is_valid(): tip = _('Array dimensions not valid') widget.setIcon(ima.icon('MessageBoxWarning')) widget.setToolTip(tip) QToolTip.showText(self._widget.mapToGlobal(QPoint(0, 5)), tip) else: self._button_warning.setToolTip('')
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=ima.icon('cmdprompt'), triggered=lambda: self.open_terminal(fnames)) actions.append(action) _title = _("Open Python console here") action = create_action(self, _title, icon=ima.icon('python'), triggered=lambda: self.open_interpreter(fnames)) actions.append(action) return actions
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 as error: QMessageBox.critical(self, _("New file"), _("<b>Unable to create file <i>%s</i>" "</b><br><br>Error message:<br>%s" ) % (fname, to_text_string(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 test_msgcheckbox(): from spyderlib.utils.qthelpers import qapplication app = qapplication() box = MessageCheckBox() box.setWindowTitle(_("Spyder updates")) box.setText("Testing checkbox") box.set_checkbox_text("Check for updates on startup?") box.setStandardButtons(QMessageBox.Ok) box.setDefaultButton(QMessageBox.Ok) box.setIcon(QMessageBox.Information) box.exec_()
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) run_btn.clicked.connect(self.run_btn_clicked) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) self.layout().addLayout(btnlayout)
def save_historylog(self): """Save current history log (all text in console)""" title = _("Save history log") self.redirect_stdio.emit(False) filename, _selfilter = getsavefilename(self, title, self.historylog_filename, "%s (*.log)" % _("History logs")) self.redirect_stdio.emit(True) if filename: filename = osp.normpath(filename) try: encoding.write(to_text_string(self.get_text_with_eol()), filename) self.historylog_filename = filename CONF.set('main', 'historylog_filename', filename) except EnvironmentError as error: QMessageBox.critical(self, title, _("<b>Unable to save file '%s'</b>" "<br><br>Error message:<br>%s" ) % (osp.basename(filename), to_text_string(error)))
def restart_kernel(self, client): """ Create a new kernel and connect it to `client` if the user asks for it """ # Took this bit of code (until if result == ) from the IPython project # (qt/frontend_widget.py - restart_kernel). # Licensed under the BSD license message = _('Are you sure you want to restart the kernel?') buttons = QMessageBox.Yes | QMessageBox.No result = QMessageBox.question(self, _('Restart kernel?'), message, buttons) if result == QMessageBox.Yes: client.show_restart_animation() # Close old kernel tab idx = self.extconsole.get_shell_index_from_id( client.kernel_widget_id) self.extconsole.close_console(index=idx, from_ipyclient=True) # Create a new one and connect it to the client self.extconsole.start_ipykernel(client)
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 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().show_this_page.emit() 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_file_new_actions(self, fnames): """Return actions for submenu 'New...'""" if not fnames: return [] new_file_act = create_action(self, _("File..."), icon='filenew.png', triggered=lambda: self.new_file(fnames[-1])) new_module_act = create_action(self, _("Module..."), icon='py.png', triggered=lambda: self.new_module(fnames[-1])) new_folder_act = create_action(self, _("Folder..."), icon='folder_new.png', triggered=lambda: self.new_folder(fnames[-1])) new_package_act = create_action(self, _("Package..."), icon=get_icon('package_collapsed.png'), triggered=lambda: self.new_package(fnames[-1])) return [new_file_act, new_folder_act, None, new_module_act, new_package_act]
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 get_plugin_actions(self): """Return a list of actions related to plugin""" history_action = create_action(self, _("History..."), None, 'history.png', _("Set history maximum entries"), triggered=self.change_history_depth) font_action = create_action(self, _("&Font..."), None, 'font.png', _("Set shell font style"), triggered=self.change_font) self.wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode) self.wrap_action.setChecked(self.get_option('wrap')) self.menu_actions = [history_action, font_action, self.wrap_action] return self.menu_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 __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 # Display text as unicode if it comes as bytes, so users see # its right representation if is_binary_string(text): self.is_binary = True text = to_text_string(text, 'utf8') else: self.is_binary = False self.layout = QVBoxLayout() self.setLayout(self.layout) # Text edit self.edit = QTextEdit(parent) self.edit.textChanged.connect(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) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) self.layout.addWidget(bbox) # Make the dialog act as a window self.setWindowFlags(Qt.Window) self.setWindowIcon(ima.icon('edit')) self.setWindowTitle(_("Text editor") + \ "%s" % (" - "+str(title) if str(title) else "")) self.resize(size[0], size[1])
def add_path(self): self.redirect_stdio.emit(False) directory = getexistingdirectory(self, _("Select directory"), self.last_path) self.redirect_stdio.emit(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()