Add ModeManager

This commit is contained in:
Florian Bruhin 2014-04-23 16:57:12 +02:00
parent 53a5460c11
commit 8b5daad367
4 changed files with 113 additions and 33 deletions

View File

@ -53,6 +53,7 @@ import qutebrowser.config.style as style
import qutebrowser.config.config as config
import qutebrowser.network.qutescheme as qutescheme
import qutebrowser.utils.message as message
import qutebrowser.utils.modemanager as modemanager
from qutebrowser.widgets.mainwindow import MainWindow
from qutebrowser.widgets.crash import CrashDialog
from qutebrowser.commands.keys import CommandKeyParser
@ -83,7 +84,6 @@ class QuteBrowser(QApplication):
_timers: List of used QTimers so they don't get GCed.
_shutting_down: True if we're currently shutting down.
_quit_status: The current quitting status.
_mode: The mode we're currently in.
_opened_urls: List of opened URLs.
"""
@ -93,7 +93,6 @@ class QuteBrowser(QApplication):
self._timers = []
self._opened_urls = []
self._shutting_down = False
self._mode = None
sys.excepthook = self._exception_hook
@ -130,10 +129,11 @@ class QuteBrowser(QApplication):
}
self._init_cmds()
self.mainwindow = MainWindow()
modemanager.init(self.mainwindow.tabs.keypress, self._keyparsers, self)
self.setQuitOnLastWindowClosed(False)
self._connect_signals()
self.set_mode("normal")
modemanager.enter("normal")
self.mainwindow.show()
self._python_hacks()
@ -246,7 +246,6 @@ class QuteBrowser(QApplication):
# misc
self.lastWindowClosed.connect(self.shutdown)
tabs.quit.connect(self.shutdown)
tabs.set_mode.connect(self.set_mode)
tabs.currentChanged.connect(self.mainwindow.update_inspector)
# status bar
@ -401,20 +400,6 @@ class QuteBrowser(QApplication):
logging.debug("maybe_quit quitting.")
self.quit()
@pyqtSlot(str)
def set_mode(self, mode):
"""Set a key input mode.
Args:
mode: The new mode to set, as an index for self._keyparsers.
"""
if self._mode is not None:
oldhandler = self._keyparsers[self._mode]
self.mainwindow.tabs.keypress.disconnect(oldhandler.handle)
handler = self._keyparsers[mode]
self.mainwindow.tabs.keypress.connect(handler.handle)
self._mode = mode
@cmdutils.register(instance='', maxsplit=0)
def pyeval(self, s):
"""Evaluate a python string and display the results as a webpage.

View File

@ -28,6 +28,7 @@ from PyQt5.QtWidgets import QApplication
import qutebrowser.config.config as config
import qutebrowser.utils.message as message
import qutebrowser.utils.url as urlutils
import qutebrowser.utils.modemanager as modemanager
from qutebrowser.utils.keyparser import KeyParser
@ -104,8 +105,6 @@ class HintManager(QObject):
Signals:
hint_strings_updated: Emitted when the possible hint strings changed.
arg: A list of hint strings.
set_mode: Emitted when the input mode should be changed.
arg: The new mode, as a string.
mouse_event: Mouse event to be posted in the web view.
arg: A QMouseEvent
openurl: Open a new url
@ -146,7 +145,6 @@ class HintManager(QObject):
"""
hint_strings_updated = pyqtSignal(list)
set_mode = pyqtSignal(str)
mouse_event = pyqtSignal('QMouseEvent')
set_open_target = pyqtSignal(str)
set_cmd_text = pyqtSignal(str)
@ -353,7 +351,6 @@ class HintManager(QObject):
Emit:
hint_strings_updated: Emitted to update keypraser.
set_mode: Emitted to enter hinting mode
"""
self._target = target
self._baseurl = baseurl
@ -395,14 +392,10 @@ class HintManager(QObject):
self._elems[string] = ElemTuple(e, label)
frame.contentsSizeChanged.connect(self.on_contents_size_changed)
self.hint_strings_updated.emit(strings)
self.set_mode.emit("hint")
modemanager.enter("hint")
def stop(self):
"""Stop hinting.
Emit:
set_mode: Emitted to leave hinting mode.
"""
"""Stop hinting."""
for elem in self._elems.values():
elem.label.removeFromDocument()
self._frame.contentsSizeChanged.disconnect(
@ -410,7 +403,7 @@ class HintManager(QObject):
self._elems = {}
self._target = None
self._frame = None
self.set_mode.emit("normal")
modemanager.enter("normal")
message.clear()
def handle_partial_key(self, keystr):

View File

@ -0,0 +1,106 @@
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
# qutebrowser 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.
#
# qutebrowser 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 qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Mode manager singleton which handles the current keyboard mode.
Module attributes:
manager: The ModeManager instance.
"""
import logging
from PyQt5.QtCore import QObject
manager = None
def init(source, parsers=None, parent=None):
"""Initialize the global ModeManager.
This needs to be done by hand because the import time is before Qt is ready
for everything.
Args:
source: The keypress source signal.
parsers: A dict of KeyParsers to register.
parent: Parent to use for ModeManager.
"""
global manager
manager = ModeManager(source, parsers, parent)
def enter(mode):
"""Enter the mode 'mode'."""
manager.enter(mode)
def register(mode, handler):
"""Register a new mode.
Args:
mode: The name of the mode.
handler: Handler for keyPressEvents.
"""
manager.register(mode, handler)
class ModeManager(QObject):
"""Manager for keyboard modes.
Attributes:
_source: The keypress source signal.
_handlers: A dictionary of modes and their handlers.
mode: The current mode.
"""
def __init__(self, sourcesig, parsers=None, parent=None):
"""Constructor.
Args:
sourcesig: The signal which gets emitted on a keypress.
parsers: A list of parsers to register.
"""
super().__init__(parent)
self._source = sourcesig
self._handlers = {}
self.mode = None
if parsers is not None:
for name, parser in parsers.items():
self._handlers[name] = parser.handle
def register(self, mode, handler):
"""Register a new mode.
Args:
mode: The name of the mode.
handler: Handler for keyPressEvents.
"""
self._handlers[mode] = handler
def enter(self, mode):
"""Enter a new mode."""
oldmode = self.mode
logging.debug("Switching mode: {} -> {}".format(oldmode, mode))
if oldmode is not None:
try:
self._source.disconnect(self._handlers[oldmode])
except TypeError:
logging.debug("Could not disconnect mode {}".format(oldmode))
self._source.connect(self._handlers[mode])
self.mode = mode

View File

@ -69,8 +69,6 @@ class TabbedBrowser(TabWidget):
arg 2: y-position in %.
hint_strings_updated: Hint strings were updated.
arg: A list of hint strings.
set_mode: The input mode should be changed.
arg: The new mode as a string.
keypress: A key was pressed.
arg: The QKeyEvent leading to the keypress.
shutdown_complete: The shuttdown is completed.
@ -89,7 +87,6 @@ class TabbedBrowser(TabWidget):
cur_scroll_perc_changed = pyqtSignal(int, int)
hint_strings_updated = pyqtSignal(list)
set_cmd_text = pyqtSignal(str)
set_mode = pyqtSignal(str)
keypress = pyqtSignal('QKeyEvent')
shutdown_complete = pyqtSignal()
quit = pyqtSignal()
@ -143,7 +140,6 @@ class TabbedBrowser(TabWidget):
tab.urlChanged.connect(self._filter.create(self.cur_url_changed))
# hintmanager
tab.hintmanager.hint_strings_updated.connect(self.hint_strings_updated)
tab.hintmanager.set_mode.connect(self.set_mode)
tab.hintmanager.set_cmd_text.connect(self.set_cmd_text)
# misc
tab.titleChanged.connect(self.on_title_changed)