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
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
 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)
Beispiel #6
0
 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)
Beispiel #8
0
    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
Beispiel #9
0
    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))
Beispiel #10
0
    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))
Beispiel #11
0
    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))
Beispiel #12
0
 def record_macro(self, register):
     """Start recording a macro."""
     message.info("Recording macro '{}'...".format(register))
     self._macros[register] = []
     self._recording_macro = register
Beispiel #13
0
 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")