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=ima.icon('copywop'), triggered=self.copy_without_prompts) clear_line_action = create_action( self, _("Clear line"), QKeySequence(CONF.get_shortcut('console', 'Clear line')), icon=ima.icon('editdelete'), tip=_("Clear line"), triggered=self.clear_line) clear_action = create_action( self, _("Clear shell"), QKeySequence(CONF.get_shortcut('console', 'Clear shell')), icon=ima.icon('editclear'), 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 _create_dockwidget(self): """Add to parent QMainWindow as a dock widget""" # Creating dock widget dock = SpyderDockWidget(self.get_plugin_title(), self.main) # Set properties dock.setObjectName(self.__class__.__name__ + "_dw") dock.setAllowedAreas(dock.ALLOWED_AREAS) dock.setFeatures(dock.FEATURES) dock.setWidget(self) self._update_margins() dock.visibilityChanged.connect(self._visibility_changed) dock.topLevelChanged.connect(self._on_top_level_changed) dock.sig_plugin_closed.connect(self._plugin_closed) self.dockwidget = dock # NOTE: Don't use the default option of CONF.get to assign a # None shortcut to plugins that don't have one. That will mess # the creation of our Keyboard Shortcuts prefs page try: context = '_' name = 'switch to {}'.format(self.CONF_SECTION) self.shortcut = CONF.get_shortcut(context, name, plugin_name=self.CONF_SECTION) except (configparser.NoSectionError, configparser.NoOptionError): pass if self.shortcut is not None and self.main is not None: sc = QShortcut(QKeySequence(self.shortcut), self.main, self.switch_to_plugin) self.register_shortcut(sc, "_", "Switch to {}".format(self.CONF_SECTION)) return (dock, dock.LOCATION)
def context_menu_requested(self, event): """Popup context menu.""" if self.fig: pos = QPoint(event.x(), event.y()) context_menu = QMenu(self) context_menu.addAction( ima.icon('filesave'), _("Save plot as..."), lambda: self.sig_save_fig_requested.emit(), QKeySequence(CONF.get_shortcut('plots', 'save'))) context_menu.addAction( ima.icon('editcopy'), _("Copy Image"), self.copy_figure, QKeySequence(CONF.get_shortcut('plots', 'copy'))) context_menu.addAction( ima.icon('editclear'), _("Remove plot"), lambda: self.sig_clear_fig_requested.emit(), QKeySequence(CONF.get_shortcut('plots', 'close'))) context_menu.popup(self.mapToGlobal(pos))
def context_menu_requested(self, event): """Popup context menu.""" if self.fig: pos = QPoint(event.x(), event.y()) context_menu = QMenu(self) context_menu.addAction( ima.icon('editcopy'), "Copy Image", self.copy_figure, QKeySequence(CONF.get_shortcut('plots', 'copy'))) context_menu.popup(self.mapToGlobal(pos))
def add_shortcut_to_tooltip(action, context, name): """Add the shortcut associated with a given action to its tooltip""" if not hasattr(action, '_tooltip_backup'): # We store the original tooltip of the action without its associated # shortcut so that we can update the tooltip properly if shortcuts # are changed by the user over the course of the current session. # See spyder-ide/spyder#10726. action._tooltip_backup = action.toolTip() action.setToolTip(action._tooltip_backup + ' (%s)' % CONF.get_shortcut(context=context, name=name))
def add_actions_to_context_menu(self, menu): """Add actions to IPython widget context menu""" inspect_action = create_action( self, _("Inspect current object"), QKeySequence(CONF.get_shortcut('console', 'inspect current object')), icon=ima.icon('MessageBoxInformation'), triggered=self.inspect_object) clear_line_action = create_action( self, _("Clear line or block"), QKeySequence(CONF.get_shortcut('console', 'clear line')), triggered=self.clear_line) reset_namespace_action = create_action(self, _("Remove all variables"), QKeySequence( CONF.get_shortcut( 'ipython_console', 'reset namespace')), icon=ima.icon('editdelete'), triggered=self.reset_namespace) clear_console_action = create_action( self, _("Clear console"), QKeySequence(CONF.get_shortcut('console', 'clear shell')), triggered=self.clear_console) quit_action = create_action(self, _("&Quit"), icon=ima.icon('exit'), triggered=self.exit_callback) add_actions( menu, (None, inspect_action, clear_line_action, clear_console_action, reset_namespace_action, None, quit_action)) return menu
def add_shortcut_to_tooltip(action, context, name): """Add the shortcut associated with a given action to its tooltip""" if not hasattr(action, '_tooltip_backup'): # We store the original tooltip of the action without its associated # shortcut so that we can update the tooltip properly if shortcuts # are changed by the user over the course of the current session. # See spyder-ide/spyder#10726. action._tooltip_backup = action.toolTip() try: # Some shortcuts might not be assigned so we need to catch the error shortcut = CONF.get_shortcut(context=context, name=name) except (configparser.NoSectionError, configparser.NoOptionError): shortcut = None if shortcut: keyseq = QKeySequence(shortcut) # See: spyder-ide/spyder#12168 string = keyseq.toString(QKeySequence.NativeText) action.setToolTip(u'{0} ({1})'.format(action._tooltip_backup, string))
def get_shortcut(self, name: str, context: Optional[str] = None) -> str: """ Get a shortcut sequence stored under the given name and context. Parameters ---------- name: str Key identifier under which the shortcut is stored. context: Optional[str] Name of the context (plugin) where the shortcut was defined. Returns ------- shortcut: str Key sequence of the shortcut. Raises ------ spyder.py3compat.configparser.NoOptionError If the section does not exist in the configuration. """ context = self.CONF_SECTION if context is None else context return CONF.get_shortcut(context, name)
def load(self): self.key = CONF.get_shortcut(self.context, self.name)
def setup_toolbar(self): """Setup the toolbar""" savefig_btn = create_toolbutton(self, icon=ima.icon('filesave'), tip=_("Save Image As..."), triggered=self.save_figure) saveall_btn = create_toolbutton(self, icon=ima.icon('save_all'), tip=_("Save All Images..."), triggered=self.save_all_figures) copyfig_btn = create_toolbutton( self, icon=ima.icon('editcopy'), tip=_("Copy plot to clipboard as image (%s)" % CONF.get_shortcut('plots', 'copy')), triggered=self.copy_figure) closefig_btn = create_toolbutton(self, icon=ima.icon('editclear'), tip=_("Remove image"), triggered=self.close_figure) closeall_btn = create_toolbutton( self, icon=ima.icon('filecloseall'), tip=_("Remove all images from the explorer"), triggered=self.close_all_figures) vsep1 = QFrame() vsep1.setFrameStyle(53) goback_btn = create_toolbutton(self, icon=ima.icon('ArrowBack'), tip=_("Previous Figure ({})".format( CONF.get_shortcut( 'plots', 'previous figure'))), triggered=self.go_previous_thumbnail) gonext_btn = create_toolbutton(self, icon=ima.icon('ArrowForward'), tip=_("Next Figure ({})".format( CONF.get_shortcut( 'plots', 'next figure'))), triggered=self.go_next_thumbnail) vsep2 = QFrame() vsep2.setFrameStyle(53) self.zoom_out_btn = create_toolbutton( self, icon=ima.icon('zoom_out'), tip=_("Zoom out (Ctrl + mouse-wheel-down)"), triggered=self.zoom_out) self.zoom_in_btn = create_toolbutton( self, icon=ima.icon('zoom_in'), tip=_("Zoom in (Ctrl + mouse-wheel-up)"), triggered=self.zoom_in) self.zoom_disp = QSpinBox() self.zoom_disp.setAlignment(Qt.AlignCenter) self.zoom_disp.setButtonSymbols(QSpinBox.NoButtons) self.zoom_disp.setReadOnly(True) self.zoom_disp.setSuffix(' %') self.zoom_disp.setRange(0, 9999) self.zoom_disp.setValue(100) self.figviewer.sig_zoom_changed.connect(self.zoom_disp.setValue) zoom_pan = QWidget() layout = QHBoxLayout(zoom_pan) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.zoom_out_btn) layout.addWidget(self.zoom_in_btn) layout.addWidget(self.zoom_disp) return [ savefig_btn, saveall_btn, copyfig_btn, closefig_btn, closeall_btn, vsep1, goback_btn, gonext_btn, vsep2, zoom_pan ]
def test_default_keybinding_values(): """ Assert that the default Spyder keybindings for the keyboard shortcuts are as expected. This is required because we do not use the keybindings saved in Spyder's config to simulate the user keyboard action, due to the fact that it is complicated to convert and pass reliably a sequence of key strings to qtbot.keyClicks. """ # Assert default keybindings. assert CONF.get_shortcut('editor', 'start of document') == 'Ctrl+Home' assert CONF.get_shortcut('editor', 'end of document') == 'Ctrl+End' assert CONF.get_shortcut('editor', 'delete') == 'Del' assert CONF.get_shortcut('editor', 'undo') == 'Ctrl+Z' assert CONF.get_shortcut('editor', 'redo') == 'Ctrl+Shift+Z' assert CONF.get_shortcut('editor', 'copy') == 'Ctrl+C' assert CONF.get_shortcut('editor', 'paste') == 'Ctrl+V' assert CONF.get_shortcut('editor', 'cut') == 'Ctrl+X' assert CONF.get_shortcut('editor', 'select all') == 'Ctrl+A' assert CONF.get_shortcut('editor', 'delete line') == 'Ctrl+D' assert CONF.get_shortcut('editor', 'transform to lowercase') == 'Ctrl+U' assert CONF.get_shortcut('editor', 'transform to uppercase') == 'Ctrl+Shift+U' assert CONF.get_shortcut('editor', 'go to line') == 'Ctrl+L' assert CONF.get_shortcut('editor', 'next word') == 'Ctrl+Right' assert CONF.get_shortcut('editor', 'previous word') == 'Ctrl+Left'
def __init__(self, parent): """Widget constructor.""" SpyderPluginWidget.__init__(self, parent) self.tab_widget = None self.menu_actions = None self.server_retries = 0 self.server_ready = False self.port = select_port(default_port=8071) self.cmd = find_program(self.get_option('shell')) self.CONF = CONF self.server_stdout = subprocess.PIPE self.server_stderr = subprocess.PIPE self.stdout_file = osp.join(getcwd(), 'spyder_terminal_out.log') self.stderr_file = osp.join(getcwd(), 'spyder_terminal_err.log') if DEV: self.server_stdout = open(self.stdout_file, 'w') self.server_stderr = open(self.stderr_file, 'w') self.server = subprocess.Popen([ sys.executable, '-m', 'spyder_terminal.server', '--port', str(self.port), '--shell', self.cmd ], stdout=self.server_stdout, stderr=self.server_stderr) self.main = parent self.terms = [] self.untitled_num = 0 self.project_path = None self.current_file_path = None self.current_cwd = getcwd() try: # Spyder 3 self.initialize_plugin() except AttributeError: # Spyder 4 pass layout = QVBoxLayout() new_term_btn = create_toolbutton(self, icon=ima.icon('expand_selection'), tip=_('Open a new terminal'), triggered=self.create_new_term) corner_widgets = { Qt.TopRightCorner: [new_term_btn, self.options_button] } self.tabwidget = Tabs(self, menu=self._options_menu, actions=self.menu_actions, corner_widgets=corner_widgets, rename_tabs=True) if hasattr(self.tabwidget, 'setDocumentMode') \ and not sys.platform == 'darwin': # Don't set document mode to true on OSX because it generates # a crash when the console is detached from the main window # Fixes Issue 561 self.tabwidget.setDocumentMode(True) self.tabwidget.currentChanged.connect(self.refresh_plugin) self.tabwidget.move_data.connect(self.move_tab) self.tabwidget.set_close_function(self.close_term) layout.addWidget(self.tabwidget) self.setLayout(layout) new_term_shortcut = QShortcut( CONF.get_shortcut(CONF_SECTION, 'new_term'), self, self.create_new_term) new_term_shortcut.setContext(Qt.WidgetWithChildrenShortcut) self.color_scheme = CONF.get('appearance', 'ui_theme') self.theme = CONF.get('appearance', 'selected') self.__wait_server_to_start()