def _handle_wheel(self, e): """Zoom on Ctrl-Mousewheel. Args: e: The QWheelEvent. """ if self._ignore_wheel_event: # See https://github.com/glimpsebrowser/glimpsebrowser/issues/395 self._ignore_wheel_event = False return True if e.modifiers() & Qt.ControlModifier: mode = modeman.instance(self._tab.win_id).mode if mode == usertypes.KeyMode.passthrough: return False divider = config.val.zoom.mouse_divider if divider == 0: return False factor = self._tab.zoom.factor() + (e.angleDelta().y() / divider) if factor < 0: return False perc = int(100 * factor) message.info("Zoom level: {}%".format(perc), replace=True) self._tab.zoom.set_factor(factor) elif e.modifiers() & Qt.ShiftModifier: if e.angleDelta().y() > 0: self._tab.scroller.left() else: self._tab.scroller.right() return True return False
def yank(self, url, context): """Yank an element to the clipboard or primary selection. Args: url: The URL to open as a QUrl. context: The HintContext to use. """ sel = (context.target == Target.yank_primary and utils.supports_selection()) flags = QUrl.FullyEncoded | QUrl.RemovePassword if url.scheme() == 'mailto': flags |= QUrl.RemoveScheme urlstr = url.toString(flags) new_content = urlstr # only second and consecutive yanks are to append to the clipboard if context.rapid and not context.first_run: try: old_content = utils.get_clipboard(selection=sel) except utils.ClipboardEmptyError: pass else: new_content = os.linesep.join([old_content, new_content]) utils.set_clipboard(new_content, selection=sel) msg = "Yanked URL to {}: {}".format( "primary selection" if sel else "clipboard", urlstr) message.info(msg)
def _on_finished(self, code, status): """Show a message when the process finished.""" self._started = False log.procs.debug("Process finished with code {}, status {}.".format( code, status)) encoding = locale.getpreferredencoding(do_setlocale=False) stderr = bytes(self._proc.readAllStandardError()).decode( encoding, 'replace') stdout = bytes(self._proc.readAllStandardOutput()).decode( encoding, 'replace') if status == QProcess.CrashExit: exitinfo = "{} crashed!".format(self._what.capitalize()) message.error(exitinfo) elif status == QProcess.NormalExit and code == 0: exitinfo = "{} exited successfully.".format( self._what.capitalize()) if self.verbose: message.info(exitinfo) else: assert status == QProcess.NormalExit # We call this 'status' here as it makes more sense to the user - # it's actually 'code'. exitinfo = ("{} exited with status {}, see :messages for " "details.").format(self._what.capitalize(), code) message.error(exitinfo) if stdout: log.procs.error("Process stdout:\n" + stdout.strip()) if stderr: log.procs.error("Process stderr:\n" + stderr.strip()) glimpsescheme.spawn_output = self._spawn_format(exitinfo, stdout, stderr)
def _pre_start(self, cmd, args): """Prepare starting of a QProcess.""" if self._started: raise ValueError("Trying to start a running QProcess!") self.cmd = cmd self.args = args fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args)) log.procs.debug("Executing: {}".format(fake_cmdline)) if self.verbose: message.info('Executing: ' + fake_cmdline)
def _print_value(self, option: str, pattern: typing.Optional[urlmatch.UrlPattern]) -> None: """Print the value of the given option.""" with self._handle_config_error(): value = self._config.get_str(option, pattern=pattern) text = "{} = {}".format(option, value) if pattern is not None: text += " for {}".format(pattern) message.info(text)
def backup(self): """Create a backup if the content has changed from the original.""" if not self._content: return try: fname = self._create_tempfile(self._content, 'glimpsebrowser-editor-backup-') message.info('Editor backup at {}'.format(fname)) except OSError as e: message.error('Failed to create editor backup: {}'.format(e))
def bind(self, win_id: str, key: str = None, command: str = None, *, mode: str = 'normal', default: bool = False) -> None: """Bind a key to a command. If no command is given, show the current binding for the given key. Using :bind without any arguments opens a page showing all keybindings. Args: key: The keychain to bind. Examples of valid keychains are `gC`, `<Ctrl-X>` or `<Ctrl-C>a`. command: The command to execute, with optional args. mode: The mode to bind the key in (default: `normal`). See `:help bindings.commands` for the available modes. default: If given, restore a default binding. """ if key is None: tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) tabbed_browser.load_url(QUrl('glimpse://bindings'), newtab=True) return seq = self._parse_key(key) if command is None: if default: # :bind --default: Restore default with self._handle_config_error(): self._keyconfig.bind_default(seq, mode=mode, save_yaml=True) return # No --default -> print binding with self._handle_config_error(): cmd = self._keyconfig.get_command(seq, mode) if cmd is None: message.info("{} is unbound in {} mode".format(seq, mode)) else: message.info("{} is bound to '{}' in {} mode".format( seq, cmd, mode)) return with self._handle_config_error(): self._keyconfig.bind(seq, command, mode=mode, save_yaml=True)
def record_macro_command(self, win_id, register=None): """Start or stop recording a macro. Args: register: Which register to store the macro in. """ if self._recording_macro is None: if register is None: mode_manager = modeman.instance(win_id) mode_manager.enter(usertypes.KeyMode.record_macro, 'record_macro') else: self.record_macro(register) else: message.info("Macro '{}' recorded.".format(self._recording_macro)) self._recording_macro = None
def prompt_yank(self, sel=False): """Yank URL to clipboard or primary selection. Args: sel: Use the primary selection instead of the clipboard. """ question = self._prompt.question if question.url is None: message.error('No URL found.') return if sel and utils.supports_selection(): target = 'primary selection' else: sel = False target = 'clipboard' utils.set_clipboard(question.url, sel) message.info("Yanked to {}: {}".format(target, question.url))
def session_save(self, name: typing.Union[str, Sentinel] = default, current: bool = False, quiet: bool = False, force: bool = False, only_active_window: bool = False, with_private: bool = False, win_id: int = None) -> None: """Save a session. Args: name: The name of the session. If not given, the session configured in session.default_name is saved. current: Save the current session instead of the default. quiet: Don't show confirmation message. force: Force saving internal sessions (starting with an underline). only_active_window: Saves only tabs of the currently active window. with_private: Include private windows. """ if (not isinstance(name, Sentinel) and name.startswith('_') and not force): raise cmdutils.CommandError("{} is an internal session, use " "--force to save anyways." .format(name)) if current: if self._current is None: raise cmdutils.CommandError("No session loaded currently!") name = self._current assert not name.startswith('_') try: if only_active_window: name = self.save(name, only_window=win_id, with_private=True) else: name = self.save(name, with_private=with_private) except SessionError as e: raise cmdutils.CommandError("Error while saving session: {}" .format(e)) else: if quiet: log.sessions.debug("Saved session {}.".format(name)) else: message.info("Saved session {}.".format(name))
def debug_dump_history(self, dest): """Dump the history to a file in the old pre-SQL format. Args: dest: Where to write the file to. """ dest = os.path.expanduser(dest) lines = ('{}{} {} {}'.format(int(x.atime), '-r' * x.redirect, x.url, x.title) for x in self.select(sort_by='atime', sort_order='asc')) try: with open(dest, 'w', encoding='utf-8') as f: f.write('\n'.join(lines)) message.info("Dumped history to {}".format(dest)) except OSError as e: raise cmdutils.CommandError( 'Could not write history: {}'.format(e))
def record_macro(self, register): """Start recording a macro.""" message.info("Recording macro '{}'...".format(register)) self._macros[register] = [] self._recording_macro = register
def _yank_url(url): utils.set_clipboard(url) message.info("Version url {} yanked to clipboard.".format(url))
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: # Copyright 2017-2019 Florian Bruhin (The Compiler) <*****@*****.**> # # This file is part of glimpsebrowser. # # glimpsebrowser is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # glimpsebrowser is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with glimpsebrowser. If not, see <http://www.gnu.org/licenses/>. """Simple test file for :debug-pyeval.""" from glimpsebrowser.utils import message message.info("Hello World")