Clean up imports
This commit is contained in:
parent
45608ee9f8
commit
d625cde28c
@ -289,7 +289,7 @@ or
|
||||
|
||||
[source,python]
|
||||
----
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils import log
|
||||
...
|
||||
log.foo.debug("Hello World")
|
||||
----
|
||||
|
@ -20,9 +20,10 @@
|
||||
|
||||
"""Entry point for qutebrowser. Simply execute qutebrowser."""
|
||||
|
||||
import qutebrowser.qutebrowser
|
||||
import sys
|
||||
|
||||
import qutebrowser.qutebrowser
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(qutebrowser.qutebrowser.main())
|
||||
|
@ -26,46 +26,28 @@ import faulthandler
|
||||
import configparser
|
||||
import signal
|
||||
import warnings
|
||||
from bdb import BdbQuit
|
||||
from base64 import b64encode
|
||||
from functools import partial
|
||||
import bdb
|
||||
import base64
|
||||
import functools
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||
from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths,
|
||||
qInstallMessageHandler, QObject, QUrl)
|
||||
|
||||
import qutebrowser
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.style as style
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.network.qutescheme as qutescheme
|
||||
import qutebrowser.config.websettings as websettings
|
||||
import qutebrowser.network.proxy as proxy
|
||||
import qutebrowser.browser.quickmarks as quickmarks
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.version as version
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.commands.userscripts as userscripts
|
||||
import qutebrowser.utils.utilcmds as utilcmds
|
||||
from qutebrowser.config.config import ConfigManager
|
||||
from qutebrowser.keyinput.modeman import ModeManager
|
||||
from qutebrowser.widgets.mainwindow import MainWindow
|
||||
from qutebrowser.widgets.console import ConsoleWidget
|
||||
from qutebrowser.widgets.crash import (ExceptionCrashDialog, FatalCrashDialog,
|
||||
ReportDialog)
|
||||
from qutebrowser.keyinput.modeparsers import (NormalKeyParser, HintKeyParser,
|
||||
PromptKeyParser)
|
||||
from qutebrowser.keyinput.keyparser import PassthroughKeyParser
|
||||
from qutebrowser.commands.runners import CommandRunner, SearchRunner
|
||||
from qutebrowser.config.iniparsers import ReadWriteConfigParser
|
||||
from qutebrowser.config.lineparser import LineConfigParser
|
||||
from qutebrowser.browser.cookies import CookieJar
|
||||
from qutebrowser.browser.downloads import DownloadManager
|
||||
from qutebrowser.utils.misc import get_standard_dir, actute_warning
|
||||
from qutebrowser.utils.qt import get_qt_args
|
||||
from qutebrowser.utils.readline import ReadlineBridge
|
||||
from qutebrowser.utils.usertypes import Timer, KeyMode
|
||||
from qutebrowser.commands import userscripts, runners
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.config import (style, config, websettings, iniparsers,
|
||||
lineparser, conftypes)
|
||||
from qutebrowser.network import qutescheme, proxy
|
||||
from qutebrowser.browser import quickmarks, cookies, downloads
|
||||
from qutebrowser.widgets import mainwindow, console, crash
|
||||
from qutebrowser.keyinput import modeparsers, keyparser, modeman
|
||||
from qutebrowser.utils import log, version, message, utilcmds, readline
|
||||
from qutebrowser.utils import url as urlutils
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils import usertypes as utypes
|
||||
|
||||
|
||||
class Application(QApplication):
|
||||
@ -104,9 +86,9 @@ class Application(QApplication):
|
||||
# We don't enable this earlier because some imports trigger
|
||||
# warnings (which are not our fault).
|
||||
warnings.simplefilter('default')
|
||||
qt_args = get_qt_args(args)
|
||||
qt_args = qtutils.get_qt_args(args)
|
||||
log.init.debug("Qt arguments: {}, based on {}".format(qt_args, args))
|
||||
super().__init__(get_qt_args(args))
|
||||
super().__init__(qt_args)
|
||||
self._quit_status = {
|
||||
'crash': True,
|
||||
'tabs': False,
|
||||
@ -129,7 +111,7 @@ class Application(QApplication):
|
||||
self.args = args
|
||||
log.init.debug("Starting init...")
|
||||
self._init_misc()
|
||||
actute_warning()
|
||||
utils.actute_warning()
|
||||
log.init.debug("Initializing config...")
|
||||
self._init_config()
|
||||
log.init.debug("Initializing crashlog...")
|
||||
@ -147,25 +129,25 @@ class Application(QApplication):
|
||||
log.init.debug("Initializing utility commands...")
|
||||
utilcmds.init()
|
||||
log.init.debug("Initializing cookies...")
|
||||
self.cookiejar = CookieJar(self)
|
||||
self.cookiejar = cookies.CookieJar(self)
|
||||
log.init.debug("Initializing commands...")
|
||||
self.commandrunner = CommandRunner()
|
||||
self.commandrunner = runners.CommandRunner()
|
||||
log.init.debug("Initializing search...")
|
||||
self.searchrunner = SearchRunner(self)
|
||||
self.searchrunner = runners.SearchRunner(self)
|
||||
log.init.debug("Initializing downloads...")
|
||||
self.downloadmanager = DownloadManager(self)
|
||||
self.downloadmanager = downloads.DownloadManager(self)
|
||||
log.init.debug("Initializing main window...")
|
||||
self.mainwindow = MainWindow()
|
||||
self.mainwindow = mainwindow.MainWindow()
|
||||
self.modeman.mainwindow = self.mainwindow
|
||||
log.init.debug("Initializing debug console...")
|
||||
self.debugconsole = ConsoleWidget()
|
||||
self.debugconsole = console.ConsoleWidget()
|
||||
log.init.debug("Initializing eventfilter...")
|
||||
self.installEventFilter(self.modeman)
|
||||
self.setQuitOnLastWindowClosed(False)
|
||||
|
||||
log.init.debug("Connecting signals...")
|
||||
self._connect_signals()
|
||||
self.modeman.enter(KeyMode.normal, 'init')
|
||||
self.modeman.enter(utypes.KeyMode.normal, 'init')
|
||||
|
||||
log.init.debug("Showing mainwindow...")
|
||||
if not args.nowindow:
|
||||
@ -183,14 +165,15 @@ class Application(QApplication):
|
||||
def _init_config(self):
|
||||
"""Inizialize and read the config."""
|
||||
if self.args.confdir is None:
|
||||
confdir = get_standard_dir(QStandardPaths.ConfigLocation)
|
||||
confdir = utils.get_standard_dir(QStandardPaths.ConfigLocation)
|
||||
elif self.args.confdir == '':
|
||||
confdir = None
|
||||
else:
|
||||
confdir = self.args.confdir
|
||||
try:
|
||||
self.config = ConfigManager(confdir, 'qutebrowser.conf', self)
|
||||
except (config.ValidationError,
|
||||
self.config = config.ConfigManager(confdir, 'qutebrowser.conf',
|
||||
self)
|
||||
except (conftypes.ValidationError,
|
||||
config.NoOptionError,
|
||||
config.InterpolationSyntaxError,
|
||||
configparser.InterpolationError,
|
||||
@ -207,47 +190,49 @@ class Application(QApplication):
|
||||
msgbox.exec_()
|
||||
# We didn't really initialize much so far, so we just quit hard.
|
||||
sys.exit(1)
|
||||
self.stateconfig = ReadWriteConfigParser(confdir, 'state')
|
||||
self.cmd_history = LineConfigParser(confdir, 'cmd_history',
|
||||
('completion', 'history-length'))
|
||||
self.stateconfig = iniparsers.ReadWriteConfigParser(confdir, 'state')
|
||||
self.cmd_history = lineparser.LineConfigParser(
|
||||
confdir, 'cmd_history', ('completion', 'history-length'))
|
||||
|
||||
def _init_modes(self):
|
||||
"""Inizialize the mode manager and the keyparsers."""
|
||||
self._keyparsers = {
|
||||
KeyMode.normal:
|
||||
NormalKeyParser(self),
|
||||
KeyMode.hint:
|
||||
HintKeyParser(self),
|
||||
KeyMode.insert:
|
||||
PassthroughKeyParser('keybind.insert', self),
|
||||
KeyMode.passthrough:
|
||||
PassthroughKeyParser('keybind.passthrough', self),
|
||||
KeyMode.command:
|
||||
PassthroughKeyParser('keybind.command', self),
|
||||
KeyMode.prompt:
|
||||
PassthroughKeyParser('keybind.prompt', self, warn=False),
|
||||
KeyMode.yesno:
|
||||
PromptKeyParser(self),
|
||||
utypes.KeyMode.normal:
|
||||
modeparsers.NormalKeyParser(self),
|
||||
utypes.KeyMode.hint:
|
||||
modeparsers.HintKeyParser(self),
|
||||
utypes.KeyMode.insert:
|
||||
keyparser.PassthroughKeyParser('keybind.insert', self),
|
||||
utypes.KeyMode.passthrough:
|
||||
keyparser.PassthroughKeyParser('keybind.passthrough', self),
|
||||
utypes.KeyMode.command:
|
||||
keyparser.PassthroughKeyParser('keybind.command', self),
|
||||
utypes.KeyMode.prompt:
|
||||
keyparser.PassthroughKeyParser('keybind.prompt', self,
|
||||
warn=False),
|
||||
utypes.KeyMode.yesno:
|
||||
modeparsers.PromptKeyParser(self),
|
||||
}
|
||||
self.modeman = ModeManager(self)
|
||||
self.modeman.register(KeyMode.normal,
|
||||
self._keyparsers[KeyMode.normal].handle)
|
||||
self.modeman.register(KeyMode.hint,
|
||||
self._keyparsers[KeyMode.hint].handle)
|
||||
self.modeman.register(KeyMode.insert,
|
||||
self._keyparsers[KeyMode.insert].handle,
|
||||
self.modeman = modeman.ModeManager(self)
|
||||
self.modeman.register(utypes.KeyMode.normal,
|
||||
self._keyparsers[utypes.KeyMode.normal].handle)
|
||||
self.modeman.register(utypes.KeyMode.hint,
|
||||
self._keyparsers[utypes.KeyMode.hint].handle)
|
||||
self.modeman.register(utypes.KeyMode.insert,
|
||||
self._keyparsers[utypes.KeyMode.insert].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register(KeyMode.passthrough,
|
||||
self._keyparsers[KeyMode.passthrough].handle,
|
||||
self.modeman.register(
|
||||
utypes.KeyMode.passthrough,
|
||||
self._keyparsers[utypes.KeyMode.passthrough].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register(utypes.KeyMode.command,
|
||||
self._keyparsers[utypes.KeyMode.command].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register(KeyMode.command,
|
||||
self._keyparsers[KeyMode.command].handle,
|
||||
self.modeman.register(utypes.KeyMode.prompt,
|
||||
self._keyparsers[utypes.KeyMode.prompt].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register(KeyMode.prompt,
|
||||
self._keyparsers[KeyMode.prompt].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register(KeyMode.yesno,
|
||||
self._keyparsers[KeyMode.yesno].handle)
|
||||
self.modeman.register(utypes.KeyMode.yesno,
|
||||
self._keyparsers[utypes.KeyMode.yesno].handle)
|
||||
|
||||
def _init_misc(self):
|
||||
"""Initialize misc things."""
|
||||
@ -263,7 +248,7 @@ class Application(QApplication):
|
||||
self.setApplicationName("qutebrowser")
|
||||
self.setApplicationVersion(qutebrowser.__version__)
|
||||
self.messagebridge = message.MessageBridge(self)
|
||||
self.rl_bridge = ReadlineBridge()
|
||||
self.rl_bridge = readline.ReadlineBridge()
|
||||
|
||||
def _handle_segfault(self):
|
||||
"""Handle a segfault from a previous run."""
|
||||
@ -272,8 +257,8 @@ class Application(QApplication):
|
||||
# However this also means if the logfile is there for some weird
|
||||
# reason, we'll *always* log to stderr, but that's still better than no
|
||||
# dialogs at all.
|
||||
logname = os.path.join(get_standard_dir(QStandardPaths.DataLocation),
|
||||
'crash.log')
|
||||
path = utils.get_standard_dir(QStandardPaths.DataLocation)
|
||||
logname = os.path.join(path, 'crash.log')
|
||||
# First check if an old logfile exists.
|
||||
if os.path.exists(logname):
|
||||
with open(logname, 'r', encoding='ascii') as f:
|
||||
@ -287,7 +272,7 @@ class Application(QApplication):
|
||||
log.init.warning("Could not remove crash log!")
|
||||
else:
|
||||
self._init_crashlogfile()
|
||||
self._crashdlg = FatalCrashDialog(data)
|
||||
self._crashdlg = crash.FatalCrashDialog(data)
|
||||
self._crashdlg.show()
|
||||
else:
|
||||
# Crashlog exists but without data.
|
||||
@ -307,8 +292,8 @@ class Application(QApplication):
|
||||
|
||||
def _init_crashlogfile(self):
|
||||
"""Start a new logfile and redirect faulthandler to it."""
|
||||
logname = os.path.join(get_standard_dir(QStandardPaths.DataLocation),
|
||||
'crash.log')
|
||||
path = utils.get_standard_dir(QStandardPaths.DataLocation)
|
||||
logname = os.path.join(path, 'crash.log')
|
||||
self._crashlogfile = open(logname, 'w', encoding='ascii')
|
||||
faulthandler.enable(self._crashlogfile)
|
||||
if (hasattr(faulthandler, 'register') and
|
||||
@ -360,7 +345,7 @@ class Application(QApplication):
|
||||
"""
|
||||
signal.signal(signal.SIGINT, self.interrupt)
|
||||
signal.signal(signal.SIGTERM, self.interrupt)
|
||||
timer = Timer(self, 'python_hacks')
|
||||
timer = utypes.Timer(self, 'python_hacks')
|
||||
timer.start(500)
|
||||
timer.timeout.connect(lambda: None)
|
||||
self._timers.append(timer)
|
||||
@ -392,15 +377,16 @@ class Application(QApplication):
|
||||
cmd.got_search_rev.connect(self.searchrunner.search_rev)
|
||||
cmd.returnPressed.connect(tabs.setFocus)
|
||||
self.searchrunner.do_search.connect(tabs.search)
|
||||
kp[KeyMode.normal].keystring_updated.connect(status.keystring.setText)
|
||||
kp[utypes.KeyMode.normal].keystring_updated.connect(
|
||||
status.keystring.setText)
|
||||
tabs.got_cmd.connect(self.commandrunner.run_safely)
|
||||
|
||||
# hints
|
||||
kp[KeyMode.hint].fire_hint.connect(tabs.fire_hint)
|
||||
kp[KeyMode.hint].filter_hints.connect(tabs.filter_hints)
|
||||
kp[KeyMode.hint].keystring_updated.connect(tabs.handle_hint_key)
|
||||
kp[utypes.KeyMode.hint].fire_hint.connect(tabs.fire_hint)
|
||||
kp[utypes.KeyMode.hint].filter_hints.connect(tabs.filter_hints)
|
||||
kp[utypes.KeyMode.hint].keystring_updated.connect(tabs.handle_hint_key)
|
||||
tabs.hint_strings_updated.connect(
|
||||
kp[KeyMode.hint].on_hint_strings_updated)
|
||||
kp[utypes.KeyMode.hint].on_hint_strings_updated)
|
||||
|
||||
# messages
|
||||
self.messagebridge.s_error.connect(status.disp_error)
|
||||
@ -413,8 +399,8 @@ class Application(QApplication):
|
||||
# config
|
||||
self.config.style_changed.connect(style.invalidate_caches)
|
||||
for obj in (tabs, completion, self.mainwindow, self.cmd_history,
|
||||
websettings, kp[KeyMode.normal], self.modeman, status,
|
||||
status.txt):
|
||||
websettings, kp[utypes.KeyMode.normal], self.modeman,
|
||||
status, status.txt):
|
||||
self.config.changed.connect(obj.on_config_changed)
|
||||
|
||||
# statusbar
|
||||
@ -498,7 +484,8 @@ class Application(QApplication):
|
||||
|
||||
def _save_geometry(self):
|
||||
"""Save the window geometry to the state config."""
|
||||
geom = b64encode(bytes(self.mainwindow.saveGeometry())).decode('ASCII')
|
||||
data = bytes(self.mainwindow.saveGeometry())
|
||||
geom = base64.b64encode(data).decode('ASCII')
|
||||
try:
|
||||
self.stateconfig.add_section('geometry')
|
||||
except configparser.DuplicateSectionError:
|
||||
@ -530,7 +517,7 @@ class Application(QApplication):
|
||||
"""
|
||||
# pylint: disable=broad-except
|
||||
|
||||
if exctype is BdbQuit or not issubclass(exctype, Exception):
|
||||
if exctype is bdb.BdbQuit or not issubclass(exctype, Exception):
|
||||
# pdb exit, KeyboardInterrupt, ...
|
||||
try:
|
||||
self.shutdown()
|
||||
@ -580,8 +567,8 @@ class Application(QApplication):
|
||||
log.destroy.debug("Error while preventing shutdown: {}: {}".format(
|
||||
e.__class__.__name__, e))
|
||||
QApplication.closeAllWindows()
|
||||
self._crashdlg = ExceptionCrashDialog(pages, history, exc, widgets,
|
||||
objects)
|
||||
self._crashdlg = crash.ExceptionCrashDialog(pages, history, exc,
|
||||
widgets, objects)
|
||||
ret = self._crashdlg.exec_()
|
||||
if ret == QDialog.Accepted: # restore
|
||||
self.restart(shutdown=False, pages=pages)
|
||||
@ -655,7 +642,7 @@ class Application(QApplication):
|
||||
history = self.mainwindow.status.cmd.history[-5:]
|
||||
widgets = self.get_all_widgets()
|
||||
objects = self.get_all_objects()
|
||||
self._crashdlg = ReportDialog(pages, history, widgets, objects)
|
||||
self._crashdlg = crash.ReportDialog(pages, history, widgets, objects)
|
||||
self._crashdlg.show()
|
||||
|
||||
@cmdutils.register(instance='', debug=True, name='debug-console')
|
||||
@ -674,7 +661,7 @@ class Application(QApplication):
|
||||
signal.signal(signal.SIGINT, self.interrupt_forcefully)
|
||||
signal.signal(signal.SIGTERM, self.interrupt_forcefully)
|
||||
# If we call shutdown directly here, we get a segfault.
|
||||
QTimer.singleShot(0, partial(self.shutdown, 128 + signum))
|
||||
QTimer.singleShot(0, functools.partial(self.shutdown, 128 + signum))
|
||||
|
||||
def interrupt_forcefully(self, signum, _frame):
|
||||
"""Interrupt forcefully on the second SIGINT/SIGTERM request.
|
||||
@ -689,7 +676,7 @@ class Application(QApplication):
|
||||
signal.signal(signal.SIGTERM, self.interrupt_really_forcefully)
|
||||
# This *should* work without a QTimer, but because of the trouble in
|
||||
# self.interrupt we're better safe than sorry.
|
||||
QTimer.singleShot(0, partial(self.exit, 128 + signum))
|
||||
QTimer.singleShot(0, functools.partial(self.exit, 128 + signum))
|
||||
|
||||
def interrupt_really_forcefully(self, signum, _frame):
|
||||
"""Interrupt with even more force on the third SIGINT/SIGTERM request.
|
||||
@ -722,7 +709,7 @@ class Application(QApplication):
|
||||
# in the real main event loop, or we'll get a segfault.
|
||||
log.destroy.debug("Deferring real shutdown because question was "
|
||||
"active.")
|
||||
QTimer.singleShot(0, partial(self._shutdown, status))
|
||||
QTimer.singleShot(0, functools.partial(self._shutdown, status))
|
||||
else:
|
||||
# If we have no questions to shut down, we are already in the real
|
||||
# event loop, so we can shut down immediately.
|
||||
@ -773,7 +760,7 @@ class Application(QApplication):
|
||||
log.destroy.debug("Deferring QApplication::exit...")
|
||||
# We use a singleshot timer to exit here to minimize the likelyhood of
|
||||
# segfaults.
|
||||
QTimer.singleShot(0, partial(self.exit, status))
|
||||
QTimer.singleShot(0, functools.partial(self.exit, status))
|
||||
|
||||
def exit(self, status):
|
||||
"""Extend QApplication::exit to log the event."""
|
||||
|
@ -29,19 +29,14 @@ from PyQt5.QtGui import QClipboard
|
||||
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
|
||||
from PyQt5.QtWebKitWidgets import QWebInspector
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.browser.hints as hints
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
import qutebrowser.browser.quickmarks as quickmarks
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.commands.userscripts as userscripts
|
||||
from qutebrowser.utils.qt import check_overflow, check_print_compat
|
||||
from qutebrowser.utils.editor import ExternalEditor
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.commands import userscripts
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.browser import hints, quickmarks
|
||||
from qutebrowser.utils import message, webelem, editor, usertypes, log
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils import url as urlutils
|
||||
|
||||
|
||||
class CommandDispatcher:
|
||||
@ -82,7 +77,7 @@ class CommandDispatcher:
|
||||
perc = int(count)
|
||||
else:
|
||||
perc = float(perc)
|
||||
perc = check_overflow(perc, 'int', fatal=False)
|
||||
perc = qtutils.check_overflow(perc, 'int', fatal=False)
|
||||
frame = self._tabs.currentWidget().page().currentFrame()
|
||||
m = frame.scrollBarMaximum(orientation)
|
||||
if m == 0:
|
||||
@ -94,7 +89,7 @@ class CommandDispatcher:
|
||||
widget = self._tabs.currentWidget()
|
||||
frame = widget.page().currentFrame()
|
||||
if frame is None:
|
||||
raise CommandError("No frame focused!")
|
||||
raise cmdexc.CommandError("No frame focused!")
|
||||
widget.hintmanager.follow_prevnext(frame, self._tabs.current_url(),
|
||||
prev, newtab)
|
||||
|
||||
@ -130,10 +125,10 @@ class CommandDispatcher:
|
||||
def _tab_focus_last(self):
|
||||
"""Select the tab which was last focused."""
|
||||
if self._tabs.last_focused is None:
|
||||
raise CommandError("No last focused tab!")
|
||||
raise cmdexc.CommandError("No last focused tab!")
|
||||
idx = self._tabs.indexOf(self._tabs.last_focused)
|
||||
if idx == -1:
|
||||
raise CommandError("Last focused tab vanished!")
|
||||
raise cmdexc.CommandError("Last focused tab vanished!")
|
||||
self._tabs.setCurrentIndex(idx)
|
||||
|
||||
def _editor_cleanup(self, oshandle, filename):
|
||||
@ -142,7 +137,7 @@ class CommandDispatcher:
|
||||
try:
|
||||
os.remove(filename)
|
||||
except PermissionError:
|
||||
raise CommandError("Failed to delete tempfile...")
|
||||
raise cmdexc.CommandError("Failed to delete tempfile...")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def tab_close(self, count=None):
|
||||
@ -173,7 +168,7 @@ class CommandDispatcher:
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.FuzzyUrlError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
if tab is None:
|
||||
if count is None:
|
||||
# We want to open a URL in the current tab, but none exists
|
||||
@ -214,9 +209,9 @@ class CommandDispatcher:
|
||||
Args:
|
||||
count: The tab index to print, or None.
|
||||
"""
|
||||
if not check_print_compat():
|
||||
raise CommandError("Printing on Qt < 5.3.0 on Windows is broken, "
|
||||
"please upgrade!")
|
||||
if not qtutils.check_print_compat():
|
||||
raise cmdexc.CommandError(
|
||||
"Printing on Qt < 5.3.0 on Windows is broken, please upgrade!")
|
||||
tab = self._tabs.cntwidget(count)
|
||||
if tab is not None:
|
||||
preview = QPrintPreviewDialog()
|
||||
@ -231,9 +226,9 @@ class CommandDispatcher:
|
||||
Args:
|
||||
count: The tab index to print, or None.
|
||||
"""
|
||||
if not check_print_compat():
|
||||
raise CommandError("Printing on Qt < 5.3.0 on Windows is broken, "
|
||||
"please upgrade!")
|
||||
if not qtutils.check_print_compat():
|
||||
raise cmdexc.CommandError(
|
||||
"Printing on Qt < 5.3.0 on Windows is broken, please upgrade!")
|
||||
tab = self._tabs.cntwidget(count)
|
||||
if tab is not None:
|
||||
printdiag = QPrintDialog()
|
||||
@ -303,15 +298,17 @@ class CommandDispatcher:
|
||||
widget = self._tabs.currentWidget()
|
||||
frame = widget.page().mainFrame()
|
||||
if frame is None:
|
||||
raise CommandError("No frame focused!")
|
||||
raise cmdexc.CommandError("No frame focused!")
|
||||
try:
|
||||
group_enum = webelem.Group[group.replace('-', '_')]
|
||||
except KeyError:
|
||||
raise CommandError("Unknown hinting group {}!".format(group))
|
||||
raise cmdexc.CommandError("Unknown hinting group {}!".format(
|
||||
group))
|
||||
try:
|
||||
target_enum = hints.Target[target.replace('-', '_')]
|
||||
except KeyError:
|
||||
raise CommandError("Unknown hinting target {}!".format(target))
|
||||
raise cmdexc.CommandError("Unknown hinting target {}!".format(
|
||||
target))
|
||||
widget.hintmanager.start(frame, self._tabs.current_url(), group_enum,
|
||||
target_enum, *args)
|
||||
|
||||
@ -488,7 +485,7 @@ class CommandDispatcher:
|
||||
try:
|
||||
level = cmdutils.arg_or_count(zoom, count, default=100)
|
||||
except ValueError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
tab = self._tabs.currentWidget()
|
||||
tab.zoom_perc(level)
|
||||
|
||||
@ -506,7 +503,7 @@ class CommandDispatcher:
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.FuzzyUrlError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
self._tabs.tabopen(url, background=False, explicit=True)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', split=False)
|
||||
@ -515,7 +512,7 @@ class CommandDispatcher:
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.FuzzyUrlError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
self._tabs.tabopen(url, background=True, explicit=True)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
@ -524,7 +521,7 @@ class CommandDispatcher:
|
||||
if self._tabs.url_stack:
|
||||
self._tabs.tabopen(self._tabs.url_stack.pop())
|
||||
else:
|
||||
raise CommandError("Nothing to undo!")
|
||||
raise cmdexc.CommandError("Nothing to undo!")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def tab_prev(self, count=1):
|
||||
@ -539,7 +536,7 @@ class CommandDispatcher:
|
||||
elif config.get('tabs', 'wrap'):
|
||||
self._tabs.setCurrentIndex(newidx % self._tabs.count())
|
||||
else:
|
||||
raise CommandError("First tab")
|
||||
raise cmdexc.CommandError("First tab")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def tab_next(self, count=1):
|
||||
@ -554,7 +551,7 @@ class CommandDispatcher:
|
||||
elif config.get('tabs', 'wrap'):
|
||||
self._tabs.setCurrentIndex(newidx % self._tabs.count())
|
||||
else:
|
||||
raise CommandError("Last tab")
|
||||
raise cmdexc.CommandError("Last tab")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', nargs=(0, 1))
|
||||
def paste(self, sel=False, tab=False):
|
||||
@ -573,12 +570,12 @@ class CommandDispatcher:
|
||||
target = "Clipboard"
|
||||
text = clipboard.text(mode)
|
||||
if not text:
|
||||
raise CommandError("{} is empty.".format(target))
|
||||
raise cmdexc.CommandError("{} is empty.".format(target))
|
||||
log.misc.debug("{} contained: '{}'".format(target, text))
|
||||
try:
|
||||
url = urlutils.fuzzy_url(text)
|
||||
except urlutils.FuzzyUrlError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
if tab:
|
||||
self._tabs.tabopen(url, explicit=True)
|
||||
else:
|
||||
@ -610,12 +607,13 @@ class CommandDispatcher:
|
||||
idx = cmdutils.arg_or_count(index, count, default=1,
|
||||
countzero=self._tabs.count())
|
||||
except ValueError as e:
|
||||
raise CommandError(e)
|
||||
raise cmdexc.CommandError(e)
|
||||
cmdutils.check_overflow(idx + 1, 'int')
|
||||
if 1 <= idx <= self._tabs.count():
|
||||
self._tabs.setCurrentIndex(idx - 1)
|
||||
else:
|
||||
raise CommandError("There's no tab with index {}!".format(idx))
|
||||
raise cmdexc.CommandError("There's no tab with index {}!".format(
|
||||
idx))
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def tab_move(self, direction=None, count=None):
|
||||
@ -632,11 +630,13 @@ class CommandDispatcher:
|
||||
try:
|
||||
new_idx = self._tab_move_relative(direction, count)
|
||||
except ValueError:
|
||||
raise CommandError("Count must be given for relative moving!")
|
||||
raise cmdexc.CommandError("Count must be given for relative "
|
||||
"moving!")
|
||||
else:
|
||||
raise CommandError("Invalid direction '{}'!".format(direction))
|
||||
raise cmdexc.CommandError("Invalid direction '{}'!".format(
|
||||
direction))
|
||||
if not 0 <= new_idx < self._tabs.count():
|
||||
raise CommandError("Can't move tab to position {}!".format(
|
||||
raise cmdexc.CommandError("Can't move tab to position {}!".format(
|
||||
new_idx))
|
||||
tab = self._tabs.currentWidget()
|
||||
cur_idx = self._tabs.currentIndex()
|
||||
@ -697,7 +697,7 @@ class CommandDispatcher:
|
||||
urlstr = quickmarks.get(name)
|
||||
url = QUrl(urlstr)
|
||||
if not url.isValid():
|
||||
raise CommandError("Invalid URL {} ({})".format(
|
||||
raise cmdexc.CommandError("Invalid URL {} ({})".format(
|
||||
urlstr, url.errorString()))
|
||||
self._tabs.currentWidget().openurl(url)
|
||||
|
||||
@ -719,8 +719,9 @@ class CommandDispatcher:
|
||||
cur = self._tabs.currentWidget()
|
||||
if cur.inspector is None:
|
||||
if not config.get('general', 'developer-extras'):
|
||||
raise CommandError("Please enable developer-extras before "
|
||||
"using the webinspector!")
|
||||
raise cmdexc.CommandError(
|
||||
"Please enable developer-extras before using the "
|
||||
"webinspector!")
|
||||
cur.inspector = QWebInspector()
|
||||
cur.inspector.setPage(cur.page())
|
||||
cur.inspector.show()
|
||||
@ -728,8 +729,9 @@ class CommandDispatcher:
|
||||
cur.inspector.hide()
|
||||
else:
|
||||
if not config.get('general', 'developer-extras'):
|
||||
raise CommandError("Please enable developer-extras before "
|
||||
"using the webinspector!")
|
||||
raise cmdexc.CommandError(
|
||||
"Please enable developer-extras before using the "
|
||||
"webinspector!")
|
||||
else:
|
||||
cur.inspector.show()
|
||||
|
||||
@ -739,7 +741,8 @@ class CommandDispatcher:
|
||||
page = self._tabs.currentWidget().page()
|
||||
self._tabs.download_get.emit(self._tabs.current_url(), page)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', modes=[KeyMode.insert],
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd',
|
||||
modes=[usertypes.KeyMode.insert],
|
||||
hide=True)
|
||||
def open_editor(self):
|
||||
"""Open an external editor with the currently selected form field.
|
||||
@ -756,14 +759,14 @@ class CommandDispatcher:
|
||||
frame = self._tabs.currentWidget().page().currentFrame()
|
||||
elem = webelem.focus_elem(frame)
|
||||
if elem.isNull():
|
||||
raise CommandError("No element focused!")
|
||||
raise cmdexc.CommandError("No element focused!")
|
||||
if not webelem.is_editable(elem, strict=True):
|
||||
raise CommandError("Focused element is not editable!")
|
||||
raise cmdexc.CommandError("Focused element is not editable!")
|
||||
if webelem.is_content_editable(elem):
|
||||
text = elem.toPlainText()
|
||||
else:
|
||||
text = elem.evaluateJavaScript('this.value')
|
||||
self._editor = ExternalEditor(self._tabs)
|
||||
self._editor = editor.ExternalEditor(self._tabs)
|
||||
self._editor.editing_finished.connect(
|
||||
partial(self.on_editing_finished, elem))
|
||||
self._editor.edit(text)
|
||||
@ -778,7 +781,7 @@ class CommandDispatcher:
|
||||
text: The new text to insert.
|
||||
"""
|
||||
if elem.isNull():
|
||||
raise CommandError("Element vanished while editing!")
|
||||
raise cmdexc.CommandError("Element vanished while editing!")
|
||||
if webelem.is_content_editable(elem):
|
||||
log.misc.debug("Filling element {} via setPlainText.".format(
|
||||
webelem.debug_text(elem)))
|
||||
|
@ -22,9 +22,8 @@
|
||||
from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar
|
||||
from PyQt5.QtCore import QStandardPaths, QDateTime
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config.lineparser import LineConfigParser
|
||||
from qutebrowser.utils.misc import get_standard_dir
|
||||
from qutebrowser.config import config, lineparser
|
||||
from qutebrowser.utils import misc as utils
|
||||
|
||||
|
||||
class CookieJar(QNetworkCookieJar):
|
||||
@ -33,8 +32,8 @@ class CookieJar(QNetworkCookieJar):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
datadir = get_standard_dir(QStandardPaths.DataLocation)
|
||||
self._linecp = LineConfigParser(datadir, 'cookies')
|
||||
datadir = utils.get_standard_dir(QStandardPaths.DataLocation)
|
||||
self._linecp = lineparser.LineConfigParser(datadir, 'cookies')
|
||||
cookies = []
|
||||
for line in self._linecp:
|
||||
cookies += QNetworkCookie.parseCookies(line.encode('utf-8'))
|
||||
|
@ -21,21 +21,19 @@
|
||||
|
||||
import os
|
||||
import os.path
|
||||
from functools import partial
|
||||
from collections import deque
|
||||
import functools
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer, QStandardPaths
|
||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.utils.misc as utils
|
||||
from qutebrowser.utils.http import parse_content_disposition
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import message, http, usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import downloads as logger
|
||||
from qutebrowser.utils.usertypes import PromptMode, Question, Timer
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
|
||||
|
||||
class DownloadItem(QObject):
|
||||
@ -92,7 +90,7 @@ class DownloadItem(QObject):
|
||||
self.basename = '???'
|
||||
samples = int(self.SPEED_AVG_WINDOW *
|
||||
(1000 / self.SPEED_REFRESH_INTERVAL))
|
||||
self.speed_avg = deque(maxlen=samples)
|
||||
self.speed_avg = collections.deque(maxlen=samples)
|
||||
self.fileobj = None
|
||||
self.filename = None
|
||||
self.is_cancelled = False
|
||||
@ -111,7 +109,7 @@ class DownloadItem(QObject):
|
||||
QTimer.singleShot(0, lambda: self.error.emit(reply.errorString()))
|
||||
if reply.isFinished():
|
||||
QTimer.singleShot(0, self.finished.emit)
|
||||
self.timer = Timer(self, 'speed_refresh')
|
||||
self.timer = usertypes.Timer(self, 'speed_refresh')
|
||||
self.timer.timeout.connect(self.update_speed)
|
||||
self.timer.setInterval(self.SPEED_REFRESH_INTERVAL)
|
||||
self.timer.start()
|
||||
@ -349,7 +347,7 @@ class DownloadManager(QObject):
|
||||
url: The URL to get, as QUrl
|
||||
page: The QWebPage to get the download from.
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
req = QNetworkRequest(url)
|
||||
reply = page.networkAccessManager().get(req)
|
||||
self.fetch(reply)
|
||||
@ -362,7 +360,7 @@ class DownloadManager(QObject):
|
||||
try:
|
||||
download = self.downloads[count - 1]
|
||||
except IndexError:
|
||||
raise CommandError("There's no download {}!".format(count))
|
||||
raise cmdexc.CommandError("There's no download {}!".format(count))
|
||||
download.cancel()
|
||||
|
||||
@pyqtSlot('QNetworkReply')
|
||||
@ -372,25 +370,27 @@ class DownloadManager(QObject):
|
||||
Args:
|
||||
reply: The QNetworkReply to download.
|
||||
"""
|
||||
_inline, suggested_filename = parse_content_disposition(reply)
|
||||
_inline, suggested_filename = http.parse_content_disposition(reply)
|
||||
logger.debug("fetch: {} -> {}".format(reply.url(), suggested_filename))
|
||||
download = DownloadItem(reply, self)
|
||||
download.finished.connect(partial(self.on_finished, download))
|
||||
download.data_changed.connect(partial(self.on_data_changed, download))
|
||||
download.finished.connect(
|
||||
functools.partial(self.on_finished, download))
|
||||
download.data_changed.connect(
|
||||
functools.partial(self.on_data_changed, download))
|
||||
download.error.connect(self.on_error)
|
||||
download.basename = suggested_filename
|
||||
self.download_about_to_be_added.emit(len(self.downloads) + 1)
|
||||
self.downloads.append(download)
|
||||
self.download_added.emit()
|
||||
|
||||
q = Question(self)
|
||||
q = usertypes.Question(self)
|
||||
q.text = "Save file to:"
|
||||
q.mode = PromptMode.text
|
||||
q.mode = usertypes.PromptMode.text
|
||||
q.default = suggested_filename
|
||||
q.answered.connect(download.set_filename)
|
||||
q.cancelled.connect(download.cancel)
|
||||
q.completed.connect(q.deleteLater)
|
||||
q.destroyed.connect(partial(self.questions.remove, q))
|
||||
q.destroyed.connect(functools.partial(self.questions.remove, q))
|
||||
self.questions.append(q)
|
||||
download.cancelled.connect(q.abort)
|
||||
message.instance().ask(q, blocking=False)
|
||||
|
@ -21,28 +21,28 @@
|
||||
|
||||
import math
|
||||
import subprocess
|
||||
from collections import namedtuple
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl
|
||||
from PyQt5.QtGui import QMouseEvent, QClipboard
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
import qutebrowser.commands.userscripts as userscripts
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import enum, KeyMode
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.utils import message, webelem
|
||||
from qutebrowser.commands import userscripts
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import hints as logger
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
|
||||
|
||||
ElemTuple = namedtuple('ElemTuple', 'elem, label')
|
||||
ElemTuple = collections.namedtuple('ElemTuple', 'elem, label')
|
||||
|
||||
|
||||
Target = enum('Target', 'normal', 'tab', 'tab_bg', 'yank', 'yank_primary',
|
||||
'fill', 'rapid', 'download', 'userscript', 'spawn')
|
||||
Target = usertypes.enum('Target', 'normal', 'tab', 'tab_bg', 'yank',
|
||||
'yank_primary', 'fill', 'rapid', 'download',
|
||||
'userscript', 'spawn')
|
||||
|
||||
|
||||
class HintContext:
|
||||
@ -340,7 +340,7 @@ class HintManager(QObject):
|
||||
Args:
|
||||
url: The URL to open as a QURL.
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
sel = self._context.target == Target.yank_primary
|
||||
mode = QClipboard.Selection if sel else QClipboard.Clipboard
|
||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||
@ -354,7 +354,7 @@ class HintManager(QObject):
|
||||
Args:
|
||||
url: The URL to open as a QUrl.
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
urlstr = url.toDisplayString(QUrl.FullyEncoded)
|
||||
args = self._context.get_args(urlstr)
|
||||
message.set_cmd_text(' '.join(args))
|
||||
@ -370,19 +370,19 @@ class HintManager(QObject):
|
||||
message.error("No suitable link found for this element.",
|
||||
immediately=True)
|
||||
return
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
self.download_get.emit(url, elem.webFrame().page())
|
||||
|
||||
def _call_userscript(self, url):
|
||||
"""Call an userscript from a hint."""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
cmd = self._context.args[0]
|
||||
args = self._context.args[1:]
|
||||
userscripts.run(cmd, *args, url=url)
|
||||
|
||||
def _spawn(self, url):
|
||||
"""Spawn a simple command from a hint."""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||
args = self._context.get_args(urlstr)
|
||||
subprocess.Popen(args)
|
||||
@ -406,7 +406,7 @@ class HintManager(QObject):
|
||||
url = QUrl(text)
|
||||
if url.isRelative():
|
||||
url = baseurl.resolved(url)
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
return url
|
||||
|
||||
def _find_prevnext(self, frame, prev=False):
|
||||
@ -457,11 +457,11 @@ class HintManager(QObject):
|
||||
"""
|
||||
elem = self._find_prevnext(frame, prev)
|
||||
if elem is None:
|
||||
raise CommandError("No {} links found!".format(
|
||||
raise cmdexc.CommandError("No {} links found!".format(
|
||||
"prev" if prev else "forward"))
|
||||
url = self._resolve_url(elem, baseurl)
|
||||
if url is None or not url.isValid():
|
||||
raise CommandError("No {} links found!".format(
|
||||
raise cmdexc.CommandError("No {} links found!".format(
|
||||
"prev" if prev else "forward"))
|
||||
self.openurl.emit(url, newtab)
|
||||
|
||||
@ -488,12 +488,13 @@ class HintManager(QObject):
|
||||
raise ValueError("start() was called with frame=None")
|
||||
if target in (Target.userscript, Target.spawn, Target.fill):
|
||||
if not args:
|
||||
raise CommandError("Additional arguments are required with "
|
||||
"target userscript/spawn/fill.")
|
||||
raise cmdexc.CommandError(
|
||||
"Additional arguments are required with target "
|
||||
"userscript/spawn/fill.")
|
||||
else:
|
||||
if args:
|
||||
raise CommandError("Arguments are only allowed with target "
|
||||
"userscript/spawn.")
|
||||
raise cmdexc.CommandError(
|
||||
"Arguments are only allowed with target userscript/spawn.")
|
||||
elems = []
|
||||
ctx = HintContext()
|
||||
ctx.frames = webelem.get_child_frames(mainframe)
|
||||
@ -503,7 +504,7 @@ class HintManager(QObject):
|
||||
visible_elems = [e for e in elems if filterfunc(e) and
|
||||
webelem.is_visible(e, mainframe)]
|
||||
if not visible_elems:
|
||||
raise CommandError("No elements found.")
|
||||
raise cmdexc.CommandError("No elements found.")
|
||||
ctx.target = target
|
||||
ctx.baseurl = baseurl
|
||||
ctx.args = args
|
||||
@ -516,7 +517,7 @@ class HintManager(QObject):
|
||||
self._connect_frame_signals()
|
||||
self.hint_strings_updated.emit(strings)
|
||||
try:
|
||||
modeman.enter(KeyMode.hint, 'HintManager.start')
|
||||
modeman.enter(usertypes.KeyMode.hint, 'HintManager.start')
|
||||
except modeman.ModeLockedError:
|
||||
self._cleanup()
|
||||
|
||||
@ -560,7 +561,7 @@ class HintManager(QObject):
|
||||
visible[k] = e
|
||||
if not visible:
|
||||
# Whoops, filtered all hints
|
||||
modeman.leave(KeyMode.hint, 'all filtered')
|
||||
modeman.leave(usertypes.KeyMode.hint, 'all filtered')
|
||||
elif len(visible) == 1 and config.get('hints', 'auto-follow'):
|
||||
# unpacking gets us the first (and only) key in the dict.
|
||||
self.fire(*visible)
|
||||
@ -606,12 +607,12 @@ class HintManager(QObject):
|
||||
else:
|
||||
raise ValueError("No suitable handler found!")
|
||||
if self._context.target != Target.rapid:
|
||||
modeman.maybe_leave(KeyMode.hint, 'followed')
|
||||
modeman.maybe_leave(usertypes.KeyMode.hint, 'followed')
|
||||
|
||||
def follow_hint(self):
|
||||
"""Follow the currently selected hint."""
|
||||
if not self._context.to_follow:
|
||||
raise CommandError("No hint to follow")
|
||||
raise cmdexc.CommandError("No hint to follow")
|
||||
self.fire(self._context.to_follow, force=True)
|
||||
|
||||
@pyqtSlot('QSize')
|
||||
@ -627,16 +628,16 @@ class HintManager(QObject):
|
||||
css = self._get_hint_css(elems.elem, elems.label)
|
||||
elems.label.setAttribute('style', css)
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_entered(self, mode):
|
||||
"""Stop hinting when insert mode was entered."""
|
||||
if mode == KeyMode.insert:
|
||||
modeman.maybe_leave(KeyMode.hint, 'insert mode')
|
||||
if mode == usertypes.KeyMode.insert:
|
||||
modeman.maybe_leave(usertypes.KeyMode.hint, 'insert mode')
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Stop hinting when hinting mode was left."""
|
||||
if mode != KeyMode.hint or self._context is None:
|
||||
if mode != usertypes.KeyMode.hint or self._context is None:
|
||||
# We have one HintManager per tab, so when this gets called,
|
||||
# self._context might be None, because the current tab is not
|
||||
# hinting.
|
||||
|
@ -24,29 +24,28 @@ OrderedDict. This is because we read them from a file at start and write them
|
||||
to a file on shutdown, so it makes semse to keep them as strings her.e
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
from collections import OrderedDict
|
||||
import functools
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import QStandardPaths, QUrl
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.utils.usertypes import PromptMode
|
||||
from qutebrowser.config.lineparser import LineConfigParser
|
||||
from qutebrowser.utils.misc import get_standard_dir
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils import message, usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.config import lineparser
|
||||
|
||||
|
||||
marks = OrderedDict()
|
||||
marks = collections.OrderedDict()
|
||||
linecp = None
|
||||
|
||||
|
||||
def init():
|
||||
"""Read quickmarks from the config file."""
|
||||
global linecp
|
||||
confdir = get_standard_dir(QStandardPaths.ConfigLocation)
|
||||
linecp = LineConfigParser(confdir, 'quickmarks')
|
||||
confdir = utils.get_standard_dir(QStandardPaths.ConfigLocation)
|
||||
linecp = lineparser.LineConfigParser(confdir, 'quickmarks')
|
||||
for line in linecp:
|
||||
try:
|
||||
key, url = line.split(maxsplit=1)
|
||||
@ -68,10 +67,10 @@ def prompt_save(url):
|
||||
Args:
|
||||
url: The quickmark url as a QUrl.
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
|
||||
message.ask_async("Add quickmark:", PromptMode.text,
|
||||
partial(quickmark_add, urlstr))
|
||||
message.ask_async("Add quickmark:", usertypes.PromptMode.text,
|
||||
functools.partial(quickmark_add, urlstr))
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@ -83,9 +82,9 @@ def quickmark_add(urlstr, name):
|
||||
name: The name for the new quickmark.
|
||||
"""
|
||||
if not name:
|
||||
raise CommandError("Can't set mark with empty name!")
|
||||
raise cmdexc.CommandError("Can't set mark with empty name!")
|
||||
if not urlstr:
|
||||
raise CommandError("Can't set mark with empty URL!")
|
||||
raise cmdexc.CommandError("Can't set mark with empty URL!")
|
||||
|
||||
def set_mark():
|
||||
"""Really set the quickmark."""
|
||||
@ -101,10 +100,12 @@ def quickmark_add(urlstr, name):
|
||||
def get(name):
|
||||
"""Get the URL of the quickmark named name as a QUrl."""
|
||||
if name not in marks:
|
||||
raise CommandError("Quickmark '{}' does not exist!".format(name))
|
||||
raise cmdexc.CommandError(
|
||||
"Quickmark '{}' does not exist!".format(name))
|
||||
urlstr = marks[name]
|
||||
url = QUrl(urlstr)
|
||||
if not url.isValid():
|
||||
raise CommandError("Invalid URL for quickmark {}: {} ({})".format(
|
||||
name, urlstr, url.errorString()))
|
||||
raise cmdexc.CommandError(
|
||||
"Invalid URL for quickmark {}: {} ({})".format(name, urlstr,
|
||||
url.errorString()))
|
||||
return url
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
"""A filter for signals which either filters or passes them."""
|
||||
|
||||
from functools import partial
|
||||
import functools
|
||||
|
||||
from PyQt5.QtCore import QObject
|
||||
|
||||
from qutebrowser.utils.debug import dbg_signal, signal_name
|
||||
from qutebrowser.widgets.webview import WebView
|
||||
from qutebrowser.utils import debug
|
||||
from qutebrowser.widgets import webview
|
||||
from qutebrowser.utils.log import signals as logger
|
||||
|
||||
|
||||
@ -58,10 +58,10 @@ class SignalFilter(QObject):
|
||||
Return:
|
||||
A partial functon calling _filter_signals with a signal.
|
||||
"""
|
||||
if not isinstance(tab, WebView):
|
||||
if not isinstance(tab, webview.WebView):
|
||||
raise ValueError("Tried to create filter for {} which is no "
|
||||
"WebView!".format(tab))
|
||||
return partial(self._filter_signals, signal, tab)
|
||||
return functools.partial(self._filter_signals, signal, tab)
|
||||
|
||||
def _filter_signals(self, signal, tab, *args):
|
||||
"""Filter signals and trigger TabbedBrowser signals if needed.
|
||||
@ -80,7 +80,7 @@ class SignalFilter(QObject):
|
||||
Emit:
|
||||
The target signal if the sender was the current widget.
|
||||
"""
|
||||
log_signal = signal_name(signal) not in self.BLACKLIST
|
||||
log_signal = debug.signal_name(signal) not in self.BLACKLIST
|
||||
try:
|
||||
tabidx = self._tabs.indexOf(tab)
|
||||
except RuntimeError:
|
||||
@ -89,9 +89,9 @@ class SignalFilter(QObject):
|
||||
if tabidx == self._tabs.currentIndex():
|
||||
if log_signal:
|
||||
logger.debug("emitting: {} (tab {})".format(
|
||||
dbg_signal(signal, args), tabidx))
|
||||
debug.dbg_signal(signal, args), tabidx))
|
||||
signal.emit(*args)
|
||||
else:
|
||||
if log_signal:
|
||||
logger.debug("ignoring: {} (tab {})".format(
|
||||
dbg_signal(signal, args), tabidx))
|
||||
debug.dbg_signal(signal, args), tabidx))
|
||||
|
@ -28,14 +28,11 @@ from PyQt5.QtWidgets import QFileDialog
|
||||
from PyQt5.QtPrintSupport import QPrintDialog
|
||||
from PyQt5.QtWebKitWidgets import QWebPage
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.http as http
|
||||
from qutebrowser.network.networkmanager import NetworkManager
|
||||
from qutebrowser.utils.misc import read_file
|
||||
from qutebrowser.utils.qt import check_print_compat
|
||||
from qutebrowser.utils.usertypes import PromptMode, ClickTarget
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.network import networkmanager
|
||||
from qutebrowser.utils import message, usertypes, log, http
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class BrowserPage(QWebPage):
|
||||
@ -61,7 +58,7 @@ class BrowserPage(QWebPage):
|
||||
QWebPage.ErrorPageExtension: self._handle_errorpage,
|
||||
QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files,
|
||||
}
|
||||
self._networkmanager = NetworkManager(self)
|
||||
self._networkmanager = networkmanager.NetworkManager(self)
|
||||
self.setNetworkAccessManager(self._networkmanager)
|
||||
self.setForwardUnsupportedContent(True)
|
||||
self.printRequested.connect(self.on_print_requested)
|
||||
@ -83,7 +80,8 @@ class BrowserPage(QWebPage):
|
||||
|
||||
http://www.riverbankcomputing.com/pipermail/pyqt/2014-June/034385.html
|
||||
"""
|
||||
answer = message.ask("js: {}".format(msg), PromptMode.text, default)
|
||||
answer = message.ask("js: {}".format(msg), usertypes.PromptMode.text,
|
||||
default)
|
||||
if answer is None:
|
||||
return (False, "")
|
||||
else:
|
||||
@ -122,7 +120,7 @@ class BrowserPage(QWebPage):
|
||||
log.webview.debug("Error domain: {}, error code: {}".format(
|
||||
info.domain, info.error))
|
||||
title = "Error loading page: {}".format(urlstr)
|
||||
errpage.content = read_file('html/error.html').format(
|
||||
errpage.content = utils.read_file('html/error.html').format(
|
||||
title=title, url=urlstr, error=info.errorString, icon='')
|
||||
return True
|
||||
|
||||
@ -158,7 +156,7 @@ class BrowserPage(QWebPage):
|
||||
|
||||
def on_print_requested(self, frame):
|
||||
"""Handle printing when requested via javascript."""
|
||||
if not check_print_compat():
|
||||
if not qtutils.check_print_compat():
|
||||
message.error("Printing on Qt < 5.3.0 on Windows is broken, "
|
||||
"please upgrade!", immediately=True)
|
||||
return
|
||||
@ -246,11 +244,12 @@ class BrowserPage(QWebPage):
|
||||
|
||||
def javaScriptAlert(self, _frame, msg):
|
||||
"""Override javaScriptAlert to use the statusbar."""
|
||||
message.ask("[js alert] {}".format(msg), PromptMode.alert)
|
||||
message.ask("[js alert] {}".format(msg), usertypes.PromptMode.alert)
|
||||
|
||||
def javaScriptConfirm(self, _frame, msg):
|
||||
"""Override javaScriptConfirm to use the statusbar."""
|
||||
ans = message.ask("[js confirm] {}".format(msg), PromptMode.yesno)
|
||||
ans = message.ask("[js confirm] {}".format(msg),
|
||||
usertypes.PromptMode.yesno)
|
||||
return bool(ans)
|
||||
|
||||
def javaScriptConsoleMessage(self, msg, line, source):
|
||||
@ -270,7 +269,7 @@ class BrowserPage(QWebPage):
|
||||
def shouldInterruptJavaScript(self):
|
||||
"""Override shouldInterruptJavaScript to use the statusbar."""
|
||||
answer = message.ask("Interrupt long-running javascript?",
|
||||
PromptMode.yesno)
|
||||
usertypes.PromptMode.yesno)
|
||||
if answer is None:
|
||||
answer = True
|
||||
return answer
|
||||
@ -298,10 +297,10 @@ class BrowserPage(QWebPage):
|
||||
message.error("Invalid link {} clicked!".format(urlstr))
|
||||
log.webview.debug(url.errorString())
|
||||
return False
|
||||
if self._view.open_target == ClickTarget.tab:
|
||||
if self._view.open_target == usertypes.ClickTarget.tab:
|
||||
self._view.tabbedbrowser.tabopen(url, False)
|
||||
return False
|
||||
elif self._view.open_target == ClickTarget.tab_bg:
|
||||
elif self._view.open_target == usertypes.ClickTarget.tab_bg:
|
||||
self._view.tabbedbrowser.tabopen(url, True)
|
||||
return False
|
||||
else:
|
||||
|
@ -22,9 +22,8 @@
|
||||
from PyQt5.QtCore import QCoreApplication, QUrl
|
||||
from PyQt5.QtWebKit import QWebSettings
|
||||
|
||||
from qutebrowser.commands.exceptions import (ArgumentCountError,
|
||||
PrerequisitesError)
|
||||
from qutebrowser.utils.misc import dotted_getattr
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import commands as logger
|
||||
|
||||
|
||||
@ -84,16 +83,18 @@ class Command:
|
||||
curmode = QCoreApplication.instance().modeman.mode
|
||||
if self.modes is not None and curmode not in self.modes:
|
||||
mode_names = '/'.join(mode.name for mode in self.modes)
|
||||
raise PrerequisitesError("{}: This command is only allowed in {} "
|
||||
"mode.".format(self.name, mode_names))
|
||||
raise cmdexc.PrerequisitesError(
|
||||
"{}: This command is only allowed in {} mode.".format(
|
||||
self.name, mode_names))
|
||||
elif self.not_modes is not None and curmode in self.not_modes:
|
||||
mode_names = '/'.join(mode.name for mode in self.not_modes)
|
||||
raise PrerequisitesError("{}: This command is not allowed in {} "
|
||||
"mode.".format(self.name, mode_names))
|
||||
raise cmdexc.PrerequisitesError(
|
||||
"{}: This command is not allowed in {} mode.".format(
|
||||
self.name, mode_names))
|
||||
if self.needs_js and not QWebSettings.globalSettings().testAttribute(
|
||||
QWebSettings.JavascriptEnabled):
|
||||
raise PrerequisitesError("{}: This command needs javascript "
|
||||
"enabled.".format(self.name))
|
||||
raise cmdexc.PrerequisitesError(
|
||||
"{}: This command needs javascript enabled.".format(self.name))
|
||||
if self.nargs[1] is None and self.nargs[0] <= len(args):
|
||||
pass
|
||||
elif self.nargs[0] <= len(args) <= self.nargs[1]:
|
||||
@ -105,8 +106,9 @@ class Command:
|
||||
argcnt = '{}-inf'.format(self.nargs[0])
|
||||
else:
|
||||
argcnt = '{}-{}'.format(self.nargs[0], self.nargs[1])
|
||||
raise ArgumentCountError("{}: {} args expected, but got {}".format(
|
||||
self.name, argcnt, len(args)))
|
||||
raise cmdexc.ArgumentCountError(
|
||||
"{}: {} args expected, but got {}".format(self.name, argcnt,
|
||||
len(args)))
|
||||
|
||||
def run(self, args=None, count=None):
|
||||
"""Run the command.
|
||||
@ -142,7 +144,7 @@ class Command:
|
||||
if self.instance == '':
|
||||
obj = app
|
||||
else:
|
||||
obj = dotted_getattr(app, self.instance)
|
||||
obj = utils.dotted_getattr(app, self.instance)
|
||||
new_args.insert(0, obj)
|
||||
|
||||
if count is not None and self.count:
|
||||
|
@ -22,12 +22,11 @@
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||
from PyQt5.QtWebKitWidgets import QWebPage
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.commands.exceptions import (NoSuchCommandError,
|
||||
CommandMetaError, CommandError)
|
||||
from qutebrowser.utils.misc import safe_shlex_split
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import commands as logger
|
||||
|
||||
|
||||
@ -201,7 +200,7 @@ class CommandRunner:
|
||||
"""
|
||||
parts = text.strip().split(maxsplit=1)
|
||||
if not parts:
|
||||
raise NoSuchCommandError("No command given")
|
||||
raise cmdexc.NoSuchCommandError("No command given")
|
||||
cmdstr = parts[0]
|
||||
if aliases:
|
||||
new_cmd = self._get_alias(text, alias_no_args)
|
||||
@ -217,11 +216,12 @@ class CommandRunner:
|
||||
parts.append('')
|
||||
return parts
|
||||
else:
|
||||
raise NoSuchCommandError('{}: no such command'.format(cmdstr))
|
||||
raise cmdexc.NoSuchCommandError(
|
||||
'{}: no such command'.format(cmdstr))
|
||||
if len(parts) == 1:
|
||||
args = []
|
||||
elif cmd.split:
|
||||
args = safe_shlex_split(parts[1])
|
||||
args = utils.safe_shlex_split(parts[1])
|
||||
else:
|
||||
args = parts[1].split(maxsplit=cmd.nargs[0] - 1)
|
||||
self._cmd = cmd
|
||||
@ -266,7 +266,7 @@ class CommandRunner:
|
||||
"""Run a command and display exceptions in the statusbar."""
|
||||
try:
|
||||
self.run(text, count)
|
||||
except (CommandMetaError, CommandError) as e:
|
||||
except (cmdexc.CommandMetaError, cmdexc.CommandError) as e:
|
||||
message.error(e, immediately=True)
|
||||
|
||||
@pyqtSlot(str, int)
|
||||
@ -277,5 +277,5 @@ class CommandRunner:
|
||||
suitable to use while initializing."""
|
||||
try:
|
||||
self.run(text, count)
|
||||
except (CommandMetaError, CommandError) as e:
|
||||
except (cmdexc.CommandMetaError, cmdexc.CommandError) as e:
|
||||
message.error(e)
|
||||
|
@ -26,17 +26,17 @@ Module attributes:
|
||||
import os
|
||||
import os.path
|
||||
import tempfile
|
||||
from select import select
|
||||
from functools import partial
|
||||
import select
|
||||
import functools
|
||||
|
||||
from PyQt5.QtCore import (pyqtSignal, QObject, QThread, QStandardPaths,
|
||||
QProcessEnvironment, QProcess, QUrl)
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.utils.misc import get_standard_dir
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import procs as logger
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.commands.runners import CommandRunner
|
||||
from qutebrowser.commands import runners
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
|
||||
|
||||
_runners = []
|
||||
@ -83,7 +83,7 @@ class _BlockingFIFOReader(QObject):
|
||||
self.fifo = os.fdopen(fd, 'r')
|
||||
while True:
|
||||
logger.debug("thread loop")
|
||||
ready_r, _ready_w, _ready_e = select([self.fifo], [], [], 1)
|
||||
ready_r, _ready_w, _ready_e = select.select([self.fifo], [], [], 1)
|
||||
if ready_r:
|
||||
logger.debug("reading data")
|
||||
for line in self.fifo:
|
||||
@ -205,7 +205,7 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner):
|
||||
self.thread = None
|
||||
|
||||
def run(self, cmd, *args, env=None):
|
||||
rundir = get_standard_dir(QStandardPaths.RuntimeLocation)
|
||||
rundir = utils.get_standard_dir(QStandardPaths.RuntimeLocation)
|
||||
# tempfile.mktemp is deprecated and discouraged, but we use it here to
|
||||
# create a FIFO since the only other alternative would be to create a
|
||||
# directory and place the FIFO there, which sucks. Since os.kfifo will
|
||||
@ -313,7 +313,8 @@ class _DummyUserscriptRunner:
|
||||
def run(self, _cmd, *_args, _env=None):
|
||||
"""Print an error as userscripts are not supported."""
|
||||
self.finished.emit()
|
||||
raise CommandError("Userscripts are not supported on this platform!")
|
||||
raise cmdexc.CommandError(
|
||||
"Userscripts are not supported on this platform!")
|
||||
|
||||
|
||||
# Here we basically just assign a generic UserscriptRunner class which does the
|
||||
@ -329,7 +330,7 @@ else:
|
||||
def init():
|
||||
"""Initialize the global _commandrunner."""
|
||||
global _commandrunner
|
||||
_commandrunner = CommandRunner()
|
||||
_commandrunner = runners.CommandRunner()
|
||||
|
||||
|
||||
def run(cmd, *args, url):
|
||||
@ -341,4 +342,4 @@ def run(cmd, *args, url):
|
||||
runner.got_cmd.connect(_commandrunner.run_safely)
|
||||
runner.run(cmd, *args, env={'QUTE_URL': urlstr})
|
||||
_runners.append(runner)
|
||||
runner.finished.connect(partial(_runners.remove, runner))
|
||||
runner.finished.connect(functools.partial(_runners.remove, runner))
|
||||
|
@ -24,12 +24,12 @@ Module attributes:
|
||||
"""
|
||||
|
||||
import inspect
|
||||
from collections import Iterable
|
||||
import collections
|
||||
|
||||
import qutebrowser.utils.qt as qtutils
|
||||
from qutebrowser.commands.command import Command
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.commands import command
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
|
||||
cmd_dict = {}
|
||||
|
||||
@ -49,8 +49,9 @@ def check_overflow(arg, ctype):
|
||||
try:
|
||||
qtutils.check_overflow(arg, ctype)
|
||||
except OverflowError:
|
||||
raise CommandError("Numeric argument is too large for internal {} "
|
||||
"representation.".format(ctype))
|
||||
raise cmdexc.CommandError(
|
||||
"Numeric argument is too large for internal {} "
|
||||
"representation.".format(ctype))
|
||||
|
||||
|
||||
def arg_or_count(arg, count, default=None, countzero=None):
|
||||
@ -135,11 +136,11 @@ class register: # pylint: disable=invalid-name
|
||||
self.debug = debug
|
||||
if modes is not None:
|
||||
for m in modes:
|
||||
if not isinstance(m, KeyMode):
|
||||
if not isinstance(m, usertypes.KeyMode):
|
||||
raise TypeError("Mode {} is no KeyMode member!".format(m))
|
||||
if not_modes is not None:
|
||||
for m in not_modes:
|
||||
if not isinstance(m, KeyMode):
|
||||
if not isinstance(m, usertypes.KeyMode):
|
||||
raise TypeError("Mode {} is no KeyMode member!".format(m))
|
||||
|
||||
def __call__(self, func):
|
||||
@ -178,12 +179,11 @@ class register: # pylint: disable=invalid-name
|
||||
desc = func.__doc__.splitlines()[0].strip()
|
||||
else:
|
||||
desc = ""
|
||||
cmd = Command(name=mainname, split=self.split,
|
||||
hide=self.hide, nargs=nargs, count=count, desc=desc,
|
||||
instance=self.instance, handler=func,
|
||||
completion=self.completion, modes=self.modes,
|
||||
not_modes=self.not_modes, needs_js=self.needs_js,
|
||||
debug=self.debug)
|
||||
cmd = command.Command(
|
||||
name=mainname, split=self.split, hide=self.hide, nargs=nargs,
|
||||
count=count, desc=desc, instance=self.instance, handler=func,
|
||||
completion=self.completion, modes=self.modes,
|
||||
not_modes=self.not_modes, needs_js=self.needs_js, debug=self.debug)
|
||||
for name in names:
|
||||
cmd_dict[name] = cmd
|
||||
return func
|
||||
@ -209,7 +209,7 @@ class register: # pylint: disable=invalid-name
|
||||
# we assume count always has a default (and it should!)
|
||||
if self.nargs is not None:
|
||||
# If nargs is overriden, use that.
|
||||
if isinstance(self.nargs, Iterable):
|
||||
if isinstance(self.nargs, collections.Iterable):
|
||||
# Iterable (min, max)
|
||||
# pylint: disable=unpacking-non-sequence
|
||||
minargs, maxargs = self.nargs
|
||||
|
@ -28,18 +28,15 @@ import os
|
||||
import os.path
|
||||
import textwrap
|
||||
import configparser
|
||||
from configparser import ExtendedInterpolation
|
||||
from collections.abc import MutableMapping
|
||||
import collections.abc
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication
|
||||
|
||||
import qutebrowser.config.configdata as configdata
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.config.iniparsers import ReadConfigParser
|
||||
from qutebrowser.config.conftypes import ValidationError
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils import log
|
||||
from qutebrowser.config import configdata, iniparsers, conftypes
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.utils.usertypes import Completion
|
||||
|
||||
|
||||
@ -114,7 +111,7 @@ class ConfigManager(QObject):
|
||||
def __init__(self, configdir, fname, parent=None):
|
||||
super().__init__(parent)
|
||||
self.sections = configdata.DATA
|
||||
self._configparser = ReadConfigParser(configdir, fname)
|
||||
self._configparser = iniparsers.ReadConfigParser(configdir, fname)
|
||||
self._configfile = os.path.join(configdir, fname)
|
||||
self._wrapper_args = {
|
||||
'width': 72,
|
||||
@ -124,7 +121,7 @@ class ConfigManager(QObject):
|
||||
}
|
||||
self._configdir = configdir
|
||||
self._fname = fname
|
||||
self._interpolation = ExtendedInterpolation()
|
||||
self._interpolation = configparser.ExtendedInterpolation()
|
||||
self._proxies = {}
|
||||
for sectname in self.sections.keys():
|
||||
self._proxies[sectname] = SectionProxy(self, sectname)
|
||||
@ -227,7 +224,7 @@ class ConfigManager(QObject):
|
||||
k = k.replace('<eq>', '=')
|
||||
try:
|
||||
self.set('conf', sectname, k, v)
|
||||
except ValidationError as e:
|
||||
except conftypes.ValidationError as e:
|
||||
e.section = sectname
|
||||
e.option = k
|
||||
raise
|
||||
@ -299,7 +296,8 @@ class ConfigManager(QObject):
|
||||
try:
|
||||
val = self.get(sectname, optname, transformed=False)
|
||||
except (NoOptionError, NoSectionError) as e:
|
||||
raise CommandError("get: {} - {}".format(e.__class__.__name__, e))
|
||||
raise cmdexc.CommandError("get: {} - {}".format(
|
||||
e.__class__.__name__, e))
|
||||
else:
|
||||
message.info("{} {} = {}".format(sectname, optname, val),
|
||||
immediately=True)
|
||||
@ -350,9 +348,10 @@ class ConfigManager(QObject):
|
||||
"""
|
||||
try:
|
||||
self.set('conf', sectname, optname, value)
|
||||
except (NoOptionError, NoSectionError, ValidationError,
|
||||
except (NoOptionError, NoSectionError, conftypes.ValidationError,
|
||||
ValueError) as e:
|
||||
raise CommandError("set: {} - {}".format(e.__class__.__name__, e))
|
||||
raise cmdexc.CommandError("set: {} - {}".format(
|
||||
e.__class__.__name__, e))
|
||||
|
||||
@cmdutils.register(name='set-temp', instance='config',
|
||||
completion=[Completion.section, Completion.option,
|
||||
@ -371,8 +370,9 @@ class ConfigManager(QObject):
|
||||
"""
|
||||
try:
|
||||
self.set('temp', sectname, optname, value)
|
||||
except (NoOptionError, NoSectionError, ValidationError) as e:
|
||||
raise CommandError("set: {} - {}".format(e.__class__.__name__, e))
|
||||
except (NoOptionError, NoSectionError, conftypes.ValidationError) as e:
|
||||
raise cmdexc.CommandError("set: {} - {}".format(
|
||||
e.__class__.__name__, e))
|
||||
|
||||
def set(self, layer, sectname, optname, value):
|
||||
"""Set an option.
|
||||
@ -442,7 +442,7 @@ class ConfigManager(QObject):
|
||||
return val
|
||||
|
||||
|
||||
class SectionProxy(MutableMapping):
|
||||
class SectionProxy(collections.abc.MutableMapping):
|
||||
|
||||
"""A proxy for a single section from a config.
|
||||
|
||||
|
@ -27,11 +27,11 @@ DATA: The config defaults, an OrderedDict of sections.
|
||||
"""
|
||||
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
import collections
|
||||
|
||||
from qutebrowser.config import conftypes as typ
|
||||
from qutebrowser.config import sections as sect
|
||||
from qutebrowser.config.value import SettingValue
|
||||
import qutebrowser.config.conftypes as types
|
||||
import qutebrowser.config.sections as sect
|
||||
from qutebrowser.utils.qt import MAXVALS
|
||||
|
||||
|
||||
@ -165,57 +165,57 @@ SECTION_DESC = {
|
||||
}
|
||||
|
||||
|
||||
DATA = OrderedDict([
|
||||
DATA = collections.OrderedDict([
|
||||
('general', sect.KeyValue(
|
||||
('ignore-case',
|
||||
SettingValue(types.IgnoreCase(), 'smart'),
|
||||
SettingValue(typ.IgnoreCase(), 'smart'),
|
||||
"Whether to find text on a page case-insensitively."),
|
||||
|
||||
('wrap-search',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to wrap finding text to the top when arriving at the end."),
|
||||
|
||||
('startpage',
|
||||
SettingValue(types.List(), 'http://www.duckduckgo.com'),
|
||||
SettingValue(typ.List(), 'http://www.duckduckgo.com'),
|
||||
"The default page(s) to open at the start, separated by commas."),
|
||||
|
||||
('auto-search',
|
||||
SettingValue(types.AutoSearch(), 'naive'),
|
||||
SettingValue(typ.AutoSearch(), 'naive'),
|
||||
"Whether to start a search when something else than a URL is "
|
||||
"entered."),
|
||||
|
||||
('auto-save-config',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to save the config automatically on quit."),
|
||||
|
||||
('editor',
|
||||
SettingValue(types.ShellCommand(placeholder=True), 'gvim -f "{}"'),
|
||||
SettingValue(typ.ShellCommand(placeholder=True), 'gvim -f "{}"'),
|
||||
"The editor (and arguments) to use for the `open-editor` command.\n\n"
|
||||
"Use `{}` for the filename. The value gets split like in a shell, so "
|
||||
"you can use `\"` or `'` to quote arguments."),
|
||||
|
||||
('editor-encoding',
|
||||
SettingValue(types.Encoding(), 'utf-8'),
|
||||
SettingValue(typ.Encoding(), 'utf-8'),
|
||||
"Encoding to use for editor."),
|
||||
|
||||
('private-browsing',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Do not record visited pages in the history or store web page "
|
||||
"icons."),
|
||||
|
||||
('developer-extras',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Enable extra tools for Web developers.\n\n"
|
||||
"This needs to be enabled for `:inspector` to work and also adds an "
|
||||
"_Inspect_ entry to the context menu."),
|
||||
|
||||
('print-element-backgrounds',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether the background color and images are also drawn when the "
|
||||
"page is printed."),
|
||||
|
||||
('xss-auditing',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether load requests should be monitored for cross-site scripting "
|
||||
"attempts.\n\n"
|
||||
"Suspicious scripts will be blocked and reported in the inspector's "
|
||||
@ -223,11 +223,11 @@ DATA = OrderedDict([
|
||||
"performance."),
|
||||
|
||||
('site-specific-quirks',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Enable workarounds for broken sites."),
|
||||
|
||||
('default-encoding',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Default encoding to use for websites.\n\n"
|
||||
"The encoding must be a string describing an encoding such as "
|
||||
'_utf-8_, _iso-8859-1_, etc. If left empty a default value will be '
|
||||
@ -236,126 +236,125 @@ DATA = OrderedDict([
|
||||
|
||||
('ui', sect.KeyValue(
|
||||
('zoom-levels',
|
||||
SettingValue(types.PercList(minval=0),
|
||||
SettingValue(typ.PercList(minval=0),
|
||||
'25%,33%,50%,67%,75%,90%,100%,110%,125%,150%,175%,200%,'
|
||||
'250%,300%,400%,500%'),
|
||||
"The available zoom levels, separated by commas."),
|
||||
|
||||
('default-zoom',
|
||||
SettingValue(types.ZoomPerc(), '100%'),
|
||||
SettingValue(typ.ZoomPerc(), '100%'),
|
||||
"The default zoom level."),
|
||||
|
||||
('message-timeout',
|
||||
SettingValue(types.Int(), '2000'),
|
||||
SettingValue(typ.Int(), '2000'),
|
||||
"Time (in ms) to show messages in the statusbar for."),
|
||||
|
||||
('confirm-quit',
|
||||
SettingValue(types.ConfirmQuit(), 'never'),
|
||||
SettingValue(typ.ConfirmQuit(), 'never'),
|
||||
"Whether to confirm quitting the application."),
|
||||
|
||||
('display-statusbar-messages',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to display javascript statusbar messages."),
|
||||
|
||||
('zoom-text-only',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether the zoom factor on a frame applies only to the text or to "
|
||||
"all content."),
|
||||
|
||||
('frame-flattening',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to expand each subframe to its contents.\n\n"
|
||||
"This will flatten all the frames to become one scrollable page."),
|
||||
|
||||
('user-stylesheet',
|
||||
SettingValue(types.WebSettingsFile(), ''),
|
||||
SettingValue(typ.WebSettingsFile(), ''),
|
||||
"User stylesheet to use."),
|
||||
|
||||
('css-media-type',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Set the CSS media type."),
|
||||
)),
|
||||
|
||||
('network', sect.KeyValue(
|
||||
('do-not-track',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Value to send in the `DNT` header."),
|
||||
|
||||
('accept-language',
|
||||
SettingValue(types.String(none_ok=True), 'en-US,en'),
|
||||
SettingValue(typ.String(none_ok=True), 'en-US,en'),
|
||||
"Value to send in the `accept-language` header."),
|
||||
|
||||
('user-agent',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"User agent to send. Empty to send the default."),
|
||||
|
||||
('proxy',
|
||||
SettingValue(types.Proxy(), 'system'),
|
||||
SettingValue(typ.Proxy(), 'system'),
|
||||
"The proxy to use.\n\n"
|
||||
"In addition to the listed values, you can use a `socks://...` or "
|
||||
"`http://...` URL."),
|
||||
|
||||
('ssl-strict',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to validate SSL handshakes."),
|
||||
|
||||
('dns-prefetch',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to try to pre-fetch DNS entries to speed up browsing."),
|
||||
)),
|
||||
|
||||
('completion', sect.KeyValue(
|
||||
('show',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to show the autocompletion window."),
|
||||
|
||||
('height',
|
||||
SettingValue(types.PercOrInt(minperc=0, maxperc=100, minint=1),
|
||||
'50%'),
|
||||
SettingValue(typ.PercOrInt(minperc=0, maxperc=100, minint=1), '50%'),
|
||||
"The height of the completion, in px or as percentage of the "
|
||||
"window."),
|
||||
|
||||
('history-length',
|
||||
SettingValue(types.Int(minval=-1), '100'),
|
||||
SettingValue(typ.Int(minval=-1), '100'),
|
||||
"How many commands to save in the history.\n\n"
|
||||
"0: no history / -1: unlimited"),
|
||||
|
||||
('quick-complete',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to move on to the next part when there's only one possible "
|
||||
"completion left."),
|
||||
|
||||
('shrink',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to shrink the completion to be smaller than the configured "
|
||||
"size if there are no scrollbars."),
|
||||
)),
|
||||
|
||||
('input', sect.KeyValue(
|
||||
('timeout',
|
||||
SettingValue(types.Int(minval=0, maxval=MAXVALS['int']), '500'),
|
||||
SettingValue(typ.Int(minval=0, maxval=MAXVALS['int']), '500'),
|
||||
"Timeout for ambiguous keybindings."),
|
||||
|
||||
('insert-mode-on-plugins',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to switch to insert mode when clicking flash and other "
|
||||
"plugins."),
|
||||
|
||||
('auto-leave-insert-mode',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to leave insert mode if a non-editable element is clicked."),
|
||||
|
||||
('auto-insert-mode',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to automatically enter insert mode if an editable element "
|
||||
"is focused after page load."),
|
||||
|
||||
('forward-unbound-keys',
|
||||
SettingValue(types.ForwardUnboundKeys(), 'auto'),
|
||||
SettingValue(typ.ForwardUnboundKeys(), 'auto'),
|
||||
"Whether to forward unbound keys to the webview in normal mode."),
|
||||
|
||||
('spatial-navigation',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Enables or disables the Spatial Navigation feature\n\n"
|
||||
"Spatial navigation consists in the ability to navigate between "
|
||||
"focusable elements in a Web page, such as hyperlinks and form "
|
||||
@ -365,76 +364,74 @@ DATA = OrderedDict([
|
||||
"right and which element he probably wants."),
|
||||
|
||||
('links-included-in-focus-chain',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
"Whether hyperlinks should be included in the keyboard focus "
|
||||
"chain."),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether hyperlinks should be included in the keyboard focus chain."),
|
||||
)),
|
||||
|
||||
('tabs', sect.KeyValue(
|
||||
('background-tabs',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to open new tabs (middleclick/ctrl+click) in background."),
|
||||
|
||||
('select-on-remove',
|
||||
SettingValue(types.SelectOnRemove(), 'right'),
|
||||
SettingValue(typ.SelectOnRemove(), 'right'),
|
||||
"Which tab to select when the focused tab is removed."),
|
||||
|
||||
('new-tab-position',
|
||||
SettingValue(types.NewTabPosition(), 'right'),
|
||||
SettingValue(typ.NewTabPosition(), 'right'),
|
||||
"How new tabs are positioned."),
|
||||
|
||||
('new-tab-position-explicit',
|
||||
SettingValue(types.NewTabPosition(), 'last'),
|
||||
SettingValue(typ.NewTabPosition(), 'last'),
|
||||
"How new tabs opened explicitely are positioned."),
|
||||
|
||||
('last-close',
|
||||
SettingValue(types.LastClose(), 'ignore'),
|
||||
SettingValue(typ.LastClose(), 'ignore'),
|
||||
"Behaviour when the last tab is closed."),
|
||||
|
||||
('wrap',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to wrap when changing tabs."),
|
||||
|
||||
('movable',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether tabs should be movable."),
|
||||
|
||||
('close-mouse-button',
|
||||
SettingValue(types.CloseButton(), 'middle'),
|
||||
SettingValue(typ.CloseButton(), 'middle'),
|
||||
"On which mouse button to close tabs."),
|
||||
|
||||
('position',
|
||||
SettingValue(types.Position(), 'north'),
|
||||
SettingValue(typ.Position(), 'north'),
|
||||
"The position of the tab bar."),
|
||||
|
||||
('show-favicons',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to show favicons in the tab bar."),
|
||||
|
||||
('width',
|
||||
SettingValue(types.PercOrInt(minperc=0, maxperc=100, minint=1),
|
||||
'20%'),
|
||||
SettingValue(typ.PercOrInt(minperc=0, maxperc=100, minint=1), '20%'),
|
||||
"The width of the tab bar if it's vertical, in px or as percentage "
|
||||
"of the window."),
|
||||
|
||||
('indicator-width',
|
||||
SettingValue(types.Int(minval=0), '3'),
|
||||
SettingValue(typ.Int(minval=0), '3'),
|
||||
"Width of the progress indicator (0 to disable)."),
|
||||
|
||||
('indicator-space',
|
||||
SettingValue(types.Int(minval=0), '3'),
|
||||
SettingValue(typ.Int(minval=0), '3'),
|
||||
"Spacing between tab edge and indicator."),
|
||||
)),
|
||||
|
||||
('storage', sect.KeyValue(
|
||||
('download-directory',
|
||||
SettingValue(types.Directory(none_ok=True), ''),
|
||||
SettingValue(typ.Directory(none_ok=True), ''),
|
||||
"The directory to save downloads to. An empty value selects a "
|
||||
"sensible os-specific default."),
|
||||
|
||||
('maximum-pages-in-cache',
|
||||
SettingValue(types.Int(none_ok=True, minval=0, maxval=MAXVALS['int']),
|
||||
''),
|
||||
SettingValue(
|
||||
typ.Int(none_ok=True, minval=0, maxval=MAXVALS['int']), ''),
|
||||
"The maximum number of pages to hold in the memory page cache.\n\n"
|
||||
"The Page Cache allows for a nicer user experience when navigating "
|
||||
"forth or back to pages in the forward/back history, by pausing and "
|
||||
@ -443,8 +440,8 @@ DATA = OrderedDict([
|
||||
"http://webkit.org/blog/427/webkit-page-cache-i-the-basics/"),
|
||||
|
||||
('object-cache-capacities',
|
||||
SettingValue(types.WebKitBytesList(length=3, maxsize=MAXVALS['int']),
|
||||
''),
|
||||
SettingValue(
|
||||
typ.WebKitBytesList(length=3, maxsize=MAXVALS['int']), ''),
|
||||
"The capacities for the memory cache for dead objects such as "
|
||||
"stylesheets or scripts. Syntax: cacheMinDeadCapacity, cacheMaxDead, "
|
||||
"totalCapacity.\n\n"
|
||||
@ -457,19 +454,19 @@ DATA = OrderedDict([
|
||||
"that the cache should consume *overall*."),
|
||||
|
||||
('offline-storage-default-quota',
|
||||
SettingValue(types.WebKitBytes(maxsize=MAXVALS['int64']), ''),
|
||||
SettingValue(typ.WebKitBytes(maxsize=MAXVALS['int64']), ''),
|
||||
"Default quota for new offline storage databases."),
|
||||
|
||||
('offline-web-application-cache-quota',
|
||||
SettingValue(types.WebKitBytes(maxsize=MAXVALS['int64']), ''),
|
||||
SettingValue(typ.WebKitBytes(maxsize=MAXVALS['int64']), ''),
|
||||
"Quota for the offline web application cache."),
|
||||
|
||||
('offline-storage-database',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether support for the HTML 5 offline storage feature is enabled."),
|
||||
|
||||
('offline-web-application-storage',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether support for the HTML 5 web application cache feature is "
|
||||
"enabled.\n\n"
|
||||
"An application cache acts like an HTTP cache in some sense. For "
|
||||
@ -480,96 +477,96 @@ DATA = OrderedDict([
|
||||
"http://dev.w3.org/html5/spec/Overview.html#appcache"),
|
||||
|
||||
('local-storage',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether support for the HTML 5 local storage feature is enabled."),
|
||||
)),
|
||||
|
||||
('permissions', sect.KeyValue(
|
||||
('allow-images',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether images are automatically loaded in web pages."),
|
||||
|
||||
('allow-javascript',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Enables or disables the running of JavaScript programs."),
|
||||
|
||||
('allow-plugins',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Enables or disables plugins in Web pages.\n\n"
|
||||
'Qt plugins with a mimetype such as "application/x-qt-plugin" are '
|
||||
"not affected by this setting."),
|
||||
|
||||
#('allow-java',
|
||||
# SettingValue(types.Bool(), 'true'),
|
||||
# SettingValue(typ.Bool(), 'true'),
|
||||
# "Enables or disables Java applets. Currently Java applets are "
|
||||
# "not supported"),
|
||||
|
||||
('javascript-can-open-windows',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether JavaScript programs can open new windows."),
|
||||
|
||||
('javascript-can-close-windows',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether JavaScript programs can close windows."),
|
||||
|
||||
('javascript-can-access-clipboard',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether JavaScript programs can read or write to the clipboard."),
|
||||
|
||||
('local-content-can-access-remote-urls',
|
||||
SettingValue(types.Bool(), 'false'),
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether locally loaded documents are allowed to access remote "
|
||||
"urls."),
|
||||
|
||||
('local-content-can-access-file-urls',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether locally loaded documents are allowed to access other local "
|
||||
"urls."),
|
||||
|
||||
('cookies-accept',
|
||||
SettingValue(types.AcceptCookies(), 'default'),
|
||||
SettingValue(typ.AcceptCookies(), 'default'),
|
||||
"Whether to accept cookies."),
|
||||
|
||||
('cookies-store',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to store cookies."),
|
||||
)),
|
||||
|
||||
('hints', sect.KeyValue(
|
||||
('border',
|
||||
SettingValue(types.String(), '1px solid #E3BE23'),
|
||||
SettingValue(typ.String(), '1px solid #E3BE23'),
|
||||
"CSS border value for hints."),
|
||||
|
||||
('opacity',
|
||||
SettingValue(types.Float(minval=0.0, maxval=1.0), '0.7'),
|
||||
SettingValue(typ.Float(minval=0.0, maxval=1.0), '0.7'),
|
||||
"Opacity for hints."),
|
||||
|
||||
('mode',
|
||||
SettingValue(types.HintMode(), 'letter'),
|
||||
SettingValue(typ.HintMode(), 'letter'),
|
||||
"Mode to use for hints."),
|
||||
|
||||
('chars',
|
||||
SettingValue(types.String(minlen=2), 'asdfghjkl'),
|
||||
SettingValue(typ.String(minlen=2), 'asdfghjkl'),
|
||||
"Chars used for hint strings."),
|
||||
|
||||
('auto-follow',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
SettingValue(typ.Bool(), 'true'),
|
||||
"Whether to auto-follow a hint if there's only one left."),
|
||||
|
||||
('next-regexes',
|
||||
SettingValue(types.RegexList(flags=re.IGNORECASE),
|
||||
SettingValue(typ.RegexList(flags=re.IGNORECASE),
|
||||
r'\bnext\b,\bmore\b,\bnewer\b,\b[>→≫]\b,\b(>>|»)\b'),
|
||||
"A comma-separated list of regexes to use for 'next' links."),
|
||||
|
||||
('prev-regexes',
|
||||
SettingValue(types.RegexList(flags=re.IGNORECASE),
|
||||
SettingValue(typ.RegexList(flags=re.IGNORECASE),
|
||||
r'\bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,'
|
||||
r'\b(<<|«)\b'),
|
||||
"A comma-separated list of regexes to use for 'prev' links."),
|
||||
)),
|
||||
|
||||
('searchengines', sect.ValueList(
|
||||
types.SearchEngineName(), types.SearchEngineUrl(),
|
||||
typ.SearchEngineName(), typ.SearchEngineUrl(),
|
||||
('DEFAULT', '${duckduckgo}'),
|
||||
('duckduckgo', 'https://duckduckgo.com/?q={}'),
|
||||
('ddg', '${duckduckgo}'),
|
||||
@ -581,7 +578,7 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('keybind', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('o', 'set-cmd-text ":open "'),
|
||||
('go', 'set-cmd-text :open {url}'),
|
||||
('O', 'set-cmd-text ":open-tab "'),
|
||||
@ -674,7 +671,7 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('keybind.insert', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Ctrl-N>', 'leave-mode'),
|
||||
('<Ctrl-E>', 'open-editor'),
|
||||
@ -682,7 +679,7 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('keybind.hint', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('<Return>', 'follow-hint'),
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Ctrl-N>', 'leave-mode'),
|
||||
@ -690,7 +687,7 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('keybind.passthrough', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Ctrl-[>', '${<Escape>}'),
|
||||
)),
|
||||
@ -699,7 +696,7 @@ DATA = OrderedDict([
|
||||
# text field.
|
||||
|
||||
('keybind.command', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Ctrl-P>', 'command-history-prev'),
|
||||
('<Ctrl-N>', 'command-history-next'),
|
||||
@ -726,7 +723,7 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('keybind.prompt', sect.ValueList(
|
||||
types.KeyBindingName(), types.KeyBinding(),
|
||||
typ.KeyBindingName(), typ.KeyBinding(),
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Return>', 'prompt-accept'),
|
||||
('y', 'prompt-yes'),
|
||||
@ -749,255 +746,255 @@ DATA = OrderedDict([
|
||||
)),
|
||||
|
||||
('aliases', sect.ValueList(
|
||||
types.String(forbidden=' '), types.Command(),
|
||||
typ.String(forbidden=' '), typ.Command(),
|
||||
)),
|
||||
|
||||
('colors', sect.KeyValue(
|
||||
('completion.fg',
|
||||
SettingValue(types.QtColor(), 'white'),
|
||||
SettingValue(typ.QtColor(), 'white'),
|
||||
"Text color of the completion widget."),
|
||||
|
||||
('completion.bg',
|
||||
SettingValue(types.QssColor(), '#333333'),
|
||||
SettingValue(typ.QssColor(), '#333333'),
|
||||
"Background color of the completion widget."),
|
||||
|
||||
('completion.item.bg',
|
||||
SettingValue(types.QssColor(), '${completion.bg}'),
|
||||
SettingValue(typ.QssColor(), '${completion.bg}'),
|
||||
"Background color of completion widget items."),
|
||||
|
||||
('completion.category.fg',
|
||||
SettingValue(types.QtColor(), 'white'),
|
||||
SettingValue(typ.QtColor(), 'white'),
|
||||
"Foreground color of completion widget category headers."),
|
||||
|
||||
('completion.category.bg',
|
||||
SettingValue(types.QssColor(), 'qlineargradient(x1:0, y1:0, x2:0, '
|
||||
SettingValue(typ.QssColor(), 'qlineargradient(x1:0, y1:0, x2:0, '
|
||||
'y2:1, stop:0 #888888, stop:1 #505050)'),
|
||||
"Background color of the completion widget category headers."),
|
||||
|
||||
('completion.category.border.top',
|
||||
SettingValue(types.QssColor(), 'black'),
|
||||
SettingValue(typ.QssColor(), 'black'),
|
||||
"Top border color of the completion widget category headers."),
|
||||
|
||||
('completion.category.border.bottom',
|
||||
SettingValue(types.QssColor(), '${completion.category.border.top}'),
|
||||
SettingValue(typ.QssColor(), '${completion.category.border.top}'),
|
||||
"Bottom border color of the completion widget category headers."),
|
||||
|
||||
('completion.item.selected.fg',
|
||||
SettingValue(types.QtColor(), 'black'),
|
||||
SettingValue(typ.QtColor(), 'black'),
|
||||
"Foreground color of the selected completion item."),
|
||||
|
||||
('completion.item.selected.bg',
|
||||
SettingValue(types.QssColor(), '#e8c000'),
|
||||
SettingValue(typ.QssColor(), '#e8c000'),
|
||||
"Background color of the selected completion item."),
|
||||
|
||||
('completion.item.selected.border.top',
|
||||
SettingValue(types.QssColor(), '#bbbb00'),
|
||||
SettingValue(typ.QssColor(), '#bbbb00'),
|
||||
"Top border color of the completion widget category headers."),
|
||||
|
||||
('completion.item.selected.border.bottom',
|
||||
SettingValue(types.QssColor(), '${completion.item.selected.border.'
|
||||
SettingValue(typ.QssColor(), '${completion.item.selected.border.'
|
||||
'top}'),
|
||||
"Bottom border color of the selected completion item."),
|
||||
|
||||
('completion.match.fg',
|
||||
SettingValue(types.QssColor(), '#ff4444'),
|
||||
SettingValue(typ.QssColor(), '#ff4444'),
|
||||
"Foreground color of the matched text in the completion."),
|
||||
|
||||
('statusbar.bg',
|
||||
SettingValue(types.QssColor(), 'black'),
|
||||
SettingValue(typ.QssColor(), 'black'),
|
||||
"Foreground color of the statusbar."),
|
||||
|
||||
('statusbar.fg',
|
||||
SettingValue(types.QssColor(), 'white'),
|
||||
SettingValue(typ.QssColor(), 'white'),
|
||||
"Foreground color of the statusbar."),
|
||||
|
||||
('statusbar.bg.error',
|
||||
SettingValue(types.QssColor(), 'red'),
|
||||
SettingValue(typ.QssColor(), 'red'),
|
||||
"Background color of the statusbar if there was an error."),
|
||||
|
||||
('statusbar.bg.prompt',
|
||||
SettingValue(types.QssColor(), 'darkblue'),
|
||||
SettingValue(typ.QssColor(), 'darkblue'),
|
||||
"Background color of the statusbar if there is a prompt."),
|
||||
|
||||
('statusbar.bg.insert',
|
||||
SettingValue(types.QssColor(), 'darkgreen'),
|
||||
SettingValue(typ.QssColor(), 'darkgreen'),
|
||||
"Background color of the statusbar in insert mode."),
|
||||
|
||||
('statusbar.progress.bg',
|
||||
SettingValue(types.QssColor(), 'white'),
|
||||
SettingValue(typ.QssColor(), 'white'),
|
||||
"Background color of the progress bar."),
|
||||
|
||||
('statusbar.url.fg',
|
||||
SettingValue(types.QssColor(), '${statusbar.fg}'),
|
||||
SettingValue(typ.QssColor(), '${statusbar.fg}'),
|
||||
"Default foreground color of the URL in the statusbar."),
|
||||
|
||||
('statusbar.url.fg.success',
|
||||
SettingValue(types.QssColor(), 'lime'),
|
||||
SettingValue(typ.QssColor(), 'lime'),
|
||||
"Foreground color of the URL in the statusbar on successful "
|
||||
"load."),
|
||||
|
||||
('statusbar.url.fg.error',
|
||||
SettingValue(types.QssColor(), 'orange'),
|
||||
SettingValue(typ.QssColor(), 'orange'),
|
||||
"Foreground color of the URL in the statusbar on error."),
|
||||
|
||||
('statusbar.url.fg.warn',
|
||||
SettingValue(types.QssColor(), 'yellow'),
|
||||
SettingValue(typ.QssColor(), 'yellow'),
|
||||
"Foreground color of the URL in the statusbar when there's a "
|
||||
"warning."),
|
||||
|
||||
('statusbar.url.fg.hover',
|
||||
SettingValue(types.QssColor(), 'aqua'),
|
||||
"Foreground color of the URL in the statusbar for hovered "
|
||||
"links."),
|
||||
SettingValue(typ.QssColor(), 'aqua'),
|
||||
"Foreground color of the URL in the statusbar for hovered links."),
|
||||
|
||||
('tab.fg',
|
||||
SettingValue(types.QtColor(), 'white'),
|
||||
SettingValue(typ.QtColor(), 'white'),
|
||||
"Foreground color of tabs."),
|
||||
|
||||
('tab.bg.odd',
|
||||
SettingValue(types.QtColor(), 'grey'),
|
||||
SettingValue(typ.QtColor(), 'grey'),
|
||||
"Background color of unselected odd tabs."),
|
||||
|
||||
('tab.bg.even',
|
||||
SettingValue(types.QtColor(), 'darkgrey'),
|
||||
SettingValue(typ.QtColor(), 'darkgrey'),
|
||||
"Background color of unselected even tabs."),
|
||||
|
||||
('tab.bg.selected',
|
||||
SettingValue(types.QtColor(), 'black'),
|
||||
SettingValue(typ.QtColor(), 'black'),
|
||||
"Background color of selected tabs."),
|
||||
|
||||
('tab.bg.bar',
|
||||
SettingValue(types.QtColor(), '#555555'),
|
||||
SettingValue(typ.QtColor(), '#555555'),
|
||||
"Background color of the tabbar."),
|
||||
|
||||
('tab.indicator.start',
|
||||
SettingValue(types.QtColor(), '#0000aa'),
|
||||
SettingValue(typ.QtColor(), '#0000aa'),
|
||||
"Color gradient start for the tab indicator."),
|
||||
|
||||
('tab.indicator.stop',
|
||||
SettingValue(types.QtColor(), '#00aa00'),
|
||||
SettingValue(typ.QtColor(), '#00aa00'),
|
||||
"Color gradient end for the tab indicator."),
|
||||
|
||||
('tab.indicator.error',
|
||||
SettingValue(types.QtColor(), '#ff0000'),
|
||||
SettingValue(typ.QtColor(), '#ff0000'),
|
||||
"Color for the tab indicator on errors.."),
|
||||
|
||||
('tab.indicator.system',
|
||||
SettingValue(types.ColorSystem(), 'rgb'),
|
||||
SettingValue(typ.ColorSystem(), 'rgb'),
|
||||
"Color gradient interpolation system for the tab indicator."),
|
||||
|
||||
('tab.seperator',
|
||||
SettingValue(types.QssColor(), '#555555'),
|
||||
SettingValue(typ.QssColor(), '#555555'),
|
||||
"Color for the tab seperator."),
|
||||
|
||||
('hints.fg',
|
||||
SettingValue(types.CssColor(), 'black'),
|
||||
SettingValue(typ.CssColor(), 'black'),
|
||||
"Font color for hints."),
|
||||
|
||||
('hints.fg.match',
|
||||
SettingValue(types.CssColor(), 'green'),
|
||||
SettingValue(typ.CssColor(), 'green'),
|
||||
"Font color for the matched part of hints."),
|
||||
|
||||
('hints.bg',
|
||||
SettingValue(types.CssColor(), '-webkit-gradient(linear, left top, '
|
||||
'left bottom, color-stop(0%,#FFF785), '
|
||||
'color-stop(100%,#FFC542))'),
|
||||
SettingValue(typ.CssColor(), '-webkit-gradient(linear, left top, '
|
||||
'left bottom, color-stop(0%,#FFF785), '
|
||||
'color-stop(100%,#FFC542))'),
|
||||
"Background color for hints."),
|
||||
|
||||
('downloads.fg',
|
||||
SettingValue(types.QtColor(), '#ffffff'),
|
||||
SettingValue(typ.QtColor(), '#ffffff'),
|
||||
"Foreground color for downloads."),
|
||||
|
||||
('downloads.bg.bar',
|
||||
SettingValue(types.QssColor(), 'black'),
|
||||
SettingValue(typ.QssColor(), 'black'),
|
||||
"Background color for the download bar."),
|
||||
|
||||
('downloads.bg.start',
|
||||
SettingValue(types.QtColor(), '#0000aa'),
|
||||
SettingValue(typ.QtColor(), '#0000aa'),
|
||||
"Color gradient start for downloads."),
|
||||
|
||||
('downloads.bg.stop',
|
||||
SettingValue(types.QtColor(), '#00aa00'),
|
||||
SettingValue(typ.QtColor(), '#00aa00'),
|
||||
"Color gradient end for downloads."),
|
||||
|
||||
('downloads.bg.system',
|
||||
SettingValue(types.ColorSystem(), 'rgb'),
|
||||
SettingValue(typ.ColorSystem(), 'rgb'),
|
||||
"Color gradient interpolation system for downloads."),
|
||||
)),
|
||||
|
||||
('fonts', sect.KeyValue(
|
||||
('_monospace',
|
||||
SettingValue(types.Font(), 'Terminus, Monospace, "DejaVu Sans Mono", '
|
||||
SettingValue(typ.Font(), 'Terminus, Monospace, "DejaVu Sans Mono", '
|
||||
'Consolas, Monaco, "Bitstream Vera Sans Mono", '
|
||||
'"Andale Mono", "Liberation Mono", "Courier New", '
|
||||
'Courier, monospace, Fixed, Terminal'),
|
||||
"Default monospace fonts."),
|
||||
|
||||
('completion',
|
||||
SettingValue(types.Font(), '8pt ${_monospace}'),
|
||||
SettingValue(typ.Font(), '8pt ${_monospace}'),
|
||||
"Font used in the completion widget."),
|
||||
|
||||
('tabbar',
|
||||
SettingValue(types.QtFont(), '8pt ${_monospace}'),
|
||||
SettingValue(typ.QtFont(), '8pt ${_monospace}'),
|
||||
"Font used in the tabbar."),
|
||||
|
||||
('statusbar',
|
||||
SettingValue(types.Font(), '8pt ${_monospace}'),
|
||||
SettingValue(typ.Font(), '8pt ${_monospace}'),
|
||||
"Font used in the statusbar."),
|
||||
|
||||
('downloads',
|
||||
SettingValue(types.Font(), '8pt ${_monospace}'),
|
||||
SettingValue(typ.Font(), '8pt ${_monospace}'),
|
||||
"Font used for the downloadbar."),
|
||||
|
||||
('hints',
|
||||
SettingValue(types.Font(), 'bold 12px Monospace'),
|
||||
SettingValue(typ.Font(), 'bold 12px Monospace'),
|
||||
"Font used for the hints."),
|
||||
|
||||
('debug-console',
|
||||
SettingValue(types.QtFont(), '8pt ${_monospace}'),
|
||||
SettingValue(typ.QtFont(), '8pt ${_monospace}'),
|
||||
"Font used for the debugging console."),
|
||||
|
||||
('web-family-standard',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for standard fonts."),
|
||||
|
||||
('web-family-fixed',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for fixed fonts."),
|
||||
|
||||
('web-family-serif',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for serif fonts."),
|
||||
|
||||
('web-family-sans-serif',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for sans-serif fonts."),
|
||||
|
||||
('web-family-cursive',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for cursive fonts."),
|
||||
|
||||
('web-family-fantasy',
|
||||
SettingValue(types.String(none_ok=True), ''),
|
||||
SettingValue(typ.String(none_ok=True), ''),
|
||||
"Font family for fantasy fonts."),
|
||||
|
||||
('web-size-minimum',
|
||||
SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']),
|
||||
''),
|
||||
SettingValue(
|
||||
typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''),
|
||||
"The hard minimum font size."),
|
||||
|
||||
('web-size-minimum-logical',
|
||||
SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']),
|
||||
''),
|
||||
SettingValue(
|
||||
typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''),
|
||||
"The minimum logical font size that is applied when zooming out."),
|
||||
|
||||
('web-size-default',
|
||||
SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']),
|
||||
''), "The default font size for regular text."),
|
||||
SettingValue(
|
||||
typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''),
|
||||
"The default font size for regular text."),
|
||||
|
||||
('web-size-default-fixed',
|
||||
SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']),
|
||||
''),
|
||||
SettingValue(
|
||||
typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''),
|
||||
"The default font size for fixed-pitch text."),
|
||||
)),
|
||||
])
|
||||
|
@ -23,13 +23,13 @@ import re
|
||||
import shlex
|
||||
import codecs
|
||||
import os.path
|
||||
from sre_constants import error as RegexError
|
||||
import sre_constants
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtGui import QColor, QFont
|
||||
from PyQt5.QtNetwork import QNetworkProxy
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
|
||||
|
||||
SYSTEM_PROXY = object() # Return value for Proxy type
|
||||
@ -734,7 +734,7 @@ class Regex(BaseType):
|
||||
raise ValidationError(value, "may not be empty!")
|
||||
try:
|
||||
re.compile(value, self.flags)
|
||||
except RegexError as e:
|
||||
except sre_constants.error as e:
|
||||
raise ValidationError(value, "must be a valid regex - " + str(e))
|
||||
|
||||
def transform(self, value):
|
||||
@ -762,7 +762,7 @@ class RegexList(List):
|
||||
def validate(self, value):
|
||||
try:
|
||||
vals = self.transform(value)
|
||||
except RegexError as e:
|
||||
except sre_constants.error as e:
|
||||
raise ValidationError(value, "must be a list valid regexes - " +
|
||||
str(e))
|
||||
if not self.none_ok and None in vals:
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
import os
|
||||
import os.path
|
||||
from configparser import ConfigParser
|
||||
import configparser
|
||||
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils import log
|
||||
|
||||
|
||||
class ReadConfigParser(ConfigParser):
|
||||
class ReadConfigParser(configparser.ConfigParser):
|
||||
|
||||
"""Our own ConfigParser subclass to read the main config.
|
||||
|
||||
|
@ -24,7 +24,7 @@ import os.path
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils import log
|
||||
|
||||
|
||||
class LineConfigParser:
|
||||
@ -82,7 +82,7 @@ class LineConfigParser:
|
||||
log.destroy.debug("No data to save.")
|
||||
return
|
||||
# We need to import this here because config needs LineConfigParser.
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config import config
|
||||
limit = -1 if self._limit is None else config.get(*self._limit)
|
||||
if limit == 0:
|
||||
return
|
||||
@ -98,7 +98,7 @@ class LineConfigParser:
|
||||
if self._limit is None:
|
||||
return
|
||||
# We need to import this here because config needs LineConfigParser.
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config import config
|
||||
value = config.get(section, option)
|
||||
if (section, option) == self._limit and value == 0:
|
||||
if os.path.exists(self._configfile):
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
"""Setting sections used for qutebrowser."""
|
||||
|
||||
from collections import OrderedDict, ChainMap
|
||||
import collections
|
||||
|
||||
from qutebrowser.config.value import SettingValue
|
||||
from qutebrowser.config import value as confvalue
|
||||
|
||||
|
||||
class Section:
|
||||
@ -108,7 +108,7 @@ class KeyValue(Section):
|
||||
super().__init__()
|
||||
if not defaults:
|
||||
return
|
||||
self.values = OrderedDict()
|
||||
self.values = collections.OrderedDict()
|
||||
for (k, v, desc) in defaults:
|
||||
assert k not in self.values, k
|
||||
self.values[k] = v
|
||||
@ -160,17 +160,17 @@ class ValueList(Section):
|
||||
self._ordered_value_cache = None
|
||||
self.keytype = keytype
|
||||
self.valtype = valtype
|
||||
self.layers = OrderedDict([
|
||||
('default', OrderedDict()),
|
||||
('conf', OrderedDict()),
|
||||
('temp', OrderedDict()),
|
||||
self.layers = collections.OrderedDict([
|
||||
('default', collections.OrderedDict()),
|
||||
('conf', collections.OrderedDict()),
|
||||
('temp', collections.OrderedDict()),
|
||||
])
|
||||
defaultlayer = self.layers['default']
|
||||
for key, value in defaults:
|
||||
assert key not in defaultlayer, key
|
||||
defaultlayer[key] = SettingValue(valtype, value)
|
||||
self.values = ChainMap(self.layers['temp'], self.layers['conf'],
|
||||
self.layers['default'])
|
||||
defaultlayer[key] = confvalue.SettingValue(valtype, value)
|
||||
self.values = collections.ChainMap(
|
||||
self.layers['temp'], self.layers['conf'], self.layers['default'])
|
||||
|
||||
@property
|
||||
def ordered_values(self):
|
||||
@ -180,7 +180,7 @@ class ValueList(Section):
|
||||
iterating/items/etc. when order matters.
|
||||
"""
|
||||
if self._ordered_value_cache is None:
|
||||
self._ordered_value_cache = OrderedDict()
|
||||
self._ordered_value_cache = collections.OrderedDict()
|
||||
for layer in self.layers.values():
|
||||
self._ordered_value_cache.update(layer)
|
||||
return self._ordered_value_cache
|
||||
@ -190,14 +190,15 @@ class ValueList(Section):
|
||||
if key in self.layers[layer]:
|
||||
self.layers[layer][key].setv(layer, value, interpolated)
|
||||
else:
|
||||
val = SettingValue(self.valtype)
|
||||
val = confvalue.SettingValue(self.valtype)
|
||||
val.setv(layer, value, interpolated)
|
||||
self.layers[layer][key] = val
|
||||
self._ordered_value_cache = None
|
||||
|
||||
def dump_userconfig(self):
|
||||
changed = []
|
||||
mapping = ChainMap(self.layers['temp'], self.layers['conf'])
|
||||
mapping = collections.ChainMap(
|
||||
self.layers['temp'], self.layers['conf'])
|
||||
for k, v in mapping.items():
|
||||
try:
|
||||
if v.value != self.layers['default'][k].value:
|
||||
|
@ -24,13 +24,13 @@ Module attributes:
|
||||
_fontdict: The global cached FontDict.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
import functools
|
||||
|
||||
from PyQt5.QtGui import QColor
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import style as logger
|
||||
from qutebrowser.utils.misc import compact_text
|
||||
|
||||
|
||||
_colordict = None
|
||||
@ -68,9 +68,10 @@ def set_register_stylesheet(obj):
|
||||
"""
|
||||
qss = get_stylesheet(obj.STYLESHEET)
|
||||
logger.debug("stylesheet for {}: {}".format(obj.__class__.__name__,
|
||||
compact_text(qss)))
|
||||
utils.compact_text(qss)))
|
||||
obj.setStyleSheet(qss)
|
||||
config.instance().changed.connect(partial(_update_stylesheet, obj))
|
||||
config.instance().changed.connect(
|
||||
functools.partial(_update_stylesheet, obj))
|
||||
|
||||
|
||||
def _update_stylesheet(obj, _section, _option):
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
"""A single value (with multiple layers possibly) in the config."""
|
||||
|
||||
from collections import OrderedDict
|
||||
import collections
|
||||
|
||||
|
||||
class SettingValue:
|
||||
@ -43,7 +43,8 @@ class SettingValue:
|
||||
default: Raw value to set.
|
||||
"""
|
||||
self.typ = typ
|
||||
self._values = OrderedDict.fromkeys(['temp', 'conf', 'default'])
|
||||
self._values = collections.OrderedDict.fromkeys(
|
||||
['temp', 'conf', 'default'])
|
||||
self._values['default'] = default
|
||||
|
||||
def __str__(self):
|
||||
@ -72,7 +73,7 @@ class SettingValue:
|
||||
startlayer: The first layer to include.
|
||||
"""
|
||||
idx = list(self._values.keys()).index(startlayer)
|
||||
d = OrderedDict(list(self._values.items())[idx:])
|
||||
d = collections.OrderedDict(list(self._values.items())[idx:])
|
||||
return d
|
||||
|
||||
def get_first_value(self, startlayer=None):
|
||||
|
@ -30,11 +30,11 @@ from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtWebKit import QWebSettings
|
||||
from PyQt5.QtCore import QStandardPaths
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils.misc import get_standard_dir
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
|
||||
MapType = enum('MapType', 'attribute', 'setter', 'static_setter')
|
||||
MapType = usertypes.enum('MapType', 'attribute', 'setter', 'static_setter')
|
||||
|
||||
|
||||
MAPPINGS = {
|
||||
@ -177,7 +177,7 @@ def _set_setting(typ, arg, value):
|
||||
def init():
|
||||
"""Initialize the global QWebSettings."""
|
||||
global settings
|
||||
cachedir = get_standard_dir(QStandardPaths.CacheLocation)
|
||||
cachedir = utils.get_standard_dir(QStandardPaths.CacheLocation)
|
||||
QWebSettings.enablePersistentStorage(cachedir)
|
||||
settings = QWebSettings.globalSettings()
|
||||
for sectname, section in MAPPINGS.items():
|
||||
|
@ -21,14 +21,14 @@
|
||||
|
||||
import re
|
||||
import string
|
||||
from functools import partial
|
||||
import functools
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.utils.usertypes import enum, Timer
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import keyboard as logger
|
||||
from qutebrowser.utils.misc import keyevent_to_string, normalize_keystr
|
||||
|
||||
|
||||
class BaseKeyParser(QObject):
|
||||
@ -71,8 +71,9 @@ class BaseKeyParser(QObject):
|
||||
keystring_updated = pyqtSignal(str)
|
||||
do_log = True
|
||||
|
||||
Match = enum('Match', 'partial', 'definitive', 'ambiguous', 'none')
|
||||
Type = enum('Type', 'chain', 'special')
|
||||
Match = usertypes.enum('Match', 'partial', 'definitive', 'ambiguous',
|
||||
'none')
|
||||
Type = usertypes.enum('Type', 'chain', 'special')
|
||||
|
||||
def __init__(self, parent=None, supports_count=None,
|
||||
supports_chains=False):
|
||||
@ -113,7 +114,7 @@ class BaseKeyParser(QObject):
|
||||
Return:
|
||||
True if event has been handled, False otherwise.
|
||||
"""
|
||||
binding = keyevent_to_string(e)
|
||||
binding = utils.keyevent_to_string(e)
|
||||
if binding is None:
|
||||
self._debug_log("Ignoring only-modifier keyeevent.")
|
||||
return False
|
||||
@ -266,11 +267,11 @@ class BaseKeyParser(QObject):
|
||||
# execute in `time' ms
|
||||
self._debug_log("Scheduling execution of {} in {}ms".format(
|
||||
binding, time))
|
||||
self._timer = Timer(self, 'ambigious_match')
|
||||
self._timer = usertypes.Timer(self, 'ambigious_match')
|
||||
self._timer.setSingleShot(True)
|
||||
self._timer.setInterval(time)
|
||||
self._timer.timeout.connect(partial(self.delayed_exec, binding,
|
||||
count))
|
||||
self._timer.timeout.connect(
|
||||
functools.partial(self.delayed_exec, binding, count))
|
||||
self._timer.start()
|
||||
|
||||
def delayed_exec(self, command, count):
|
||||
@ -329,7 +330,7 @@ class BaseKeyParser(QObject):
|
||||
if not cmd:
|
||||
continue
|
||||
elif key.startswith('<') and key.endswith('>'):
|
||||
keystr = normalize_keystr(key[1:-1])
|
||||
keystr = utils.normalize_keystr(key[1:-1])
|
||||
self.special_bindings[keystr] = cmd
|
||||
elif self._supports_chains:
|
||||
self.bindings[key] = cmd
|
||||
|
@ -20,10 +20,9 @@
|
||||
"""Advanced keyparsers."""
|
||||
|
||||
from qutebrowser.keyinput.basekeyparser import BaseKeyParser
|
||||
import qutebrowser.utils.message as message
|
||||
|
||||
from qutebrowser.commands.runners import CommandRunner
|
||||
from qutebrowser.commands.exceptions import CommandMetaError, CommandError
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.commands import runners
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
|
||||
|
||||
class CommandKeyParser(BaseKeyParser):
|
||||
@ -37,12 +36,12 @@ class CommandKeyParser(BaseKeyParser):
|
||||
def __init__(self, parent=None, supports_count=None,
|
||||
supports_chains=False):
|
||||
super().__init__(parent, supports_count, supports_chains)
|
||||
self.commandrunner = CommandRunner()
|
||||
self.commandrunner = runners.CommandRunner()
|
||||
|
||||
def execute(self, cmdstr, _keytype, count=None):
|
||||
try:
|
||||
self.commandrunner.run(cmdstr, count)
|
||||
except (CommandMetaError, CommandError) as e:
|
||||
except (cmdexc.CommandMetaError, cmdexc.CommandError) as e:
|
||||
message.error(e, immediately=True)
|
||||
|
||||
|
||||
|
@ -27,11 +27,11 @@ from PyQt5.QtGui import QWindow
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import modes as logger
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
|
||||
|
||||
class ModeLockedError(Exception):
|
||||
@ -96,8 +96,8 @@ class ModeManager(QObject):
|
||||
arg: The mode which has been left.
|
||||
"""
|
||||
|
||||
entered = pyqtSignal(KeyMode)
|
||||
left = pyqtSignal(KeyMode)
|
||||
entered = pyqtSignal(usertypes.KeyMode)
|
||||
left = pyqtSignal(usertypes.KeyMode)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@ -142,7 +142,7 @@ class ModeManager(QObject):
|
||||
True if event should be filtered, False otherwise.
|
||||
"""
|
||||
handler = self._handlers[self.mode]
|
||||
if self.mode != KeyMode.insert:
|
||||
if self.mode != usertypes.KeyMode.insert:
|
||||
logger.debug("got keypress in mode {} - calling handler {}".format(
|
||||
self.mode, handler.__qualname__))
|
||||
handled = handler(event) if handler is not None else False
|
||||
@ -161,7 +161,7 @@ class ModeManager(QObject):
|
||||
if not filter_this:
|
||||
self._releaseevents_to_pass.append(event)
|
||||
|
||||
if self.mode != KeyMode.insert:
|
||||
if self.mode != usertypes.KeyMode.insert:
|
||||
logger.debug("handled: {}, forward-unbound-keys: {}, passthrough: "
|
||||
"{}, is_non_alnum: {} --> filter: {}".format(
|
||||
handled, self._forward_unbound_keys,
|
||||
@ -186,7 +186,7 @@ class ModeManager(QObject):
|
||||
filter_this = False
|
||||
else:
|
||||
filter_this = True
|
||||
if self.mode != KeyMode.insert:
|
||||
if self.mode != usertypes.KeyMode.insert:
|
||||
logger.debug("filter: {}".format(filter_this))
|
||||
return filter_this
|
||||
|
||||
@ -199,7 +199,7 @@ class ModeManager(QObject):
|
||||
passthrough: Whether to pass keybindings in this mode through to
|
||||
the widgets.
|
||||
"""
|
||||
if not isinstance(mode, KeyMode):
|
||||
if not isinstance(mode, usertypes.KeyMode):
|
||||
raise TypeError("Mode {} is no KeyMode member!".format(mode))
|
||||
self._handlers[mode] = handler
|
||||
if passthrough:
|
||||
@ -215,7 +215,7 @@ class ModeManager(QObject):
|
||||
Emit:
|
||||
entered: With the new mode name.
|
||||
"""
|
||||
if not isinstance(mode, KeyMode):
|
||||
if not isinstance(mode, usertypes.KeyMode):
|
||||
raise TypeError("Mode {} is no KeyMode member!".format(mode))
|
||||
if self.locked:
|
||||
logger.debug("Not entering mode {} because mode is locked to "
|
||||
@ -241,9 +241,9 @@ class ModeManager(QObject):
|
||||
mode: The mode to enter.
|
||||
"""
|
||||
try:
|
||||
m = KeyMode[mode]
|
||||
m = usertypes.KeyMode[mode]
|
||||
except KeyError:
|
||||
raise CommandError("Mode {} does not exist!".format(mode))
|
||||
raise cmdexc.CommandError("Mode {} does not exist!".format(mode))
|
||||
self.enter(m, 'command')
|
||||
|
||||
def leave(self, mode, reason=None):
|
||||
@ -267,10 +267,10 @@ class ModeManager(QObject):
|
||||
self.left.emit(mode)
|
||||
|
||||
@cmdutils.register(instance='modeman', name='leave-mode',
|
||||
not_modes=[KeyMode.normal], hide=True)
|
||||
not_modes=[usertypes.KeyMode.normal], hide=True)
|
||||
def leave_current_mode(self):
|
||||
"""Leave the mode we're currently in."""
|
||||
if self.mode == KeyMode.normal:
|
||||
if self.mode == usertypes.KeyMode.normal:
|
||||
raise ValueError("Can't leave normal mode!")
|
||||
self.leave(self.mode, 'leave current')
|
||||
|
||||
|
@ -25,18 +25,18 @@ Module attributes:
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, Qt
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.keyinput.keyparser import CommandKeyParser
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.keyinput import keyparser
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import keyboard as logger
|
||||
|
||||
|
||||
STARTCHARS = ":/?"
|
||||
LastPress = enum('LastPress', 'none', 'filtertext', 'keystring')
|
||||
LastPress = usertypes.enum('LastPress', 'none', 'filtertext', 'keystring')
|
||||
|
||||
|
||||
class NormalKeyParser(CommandKeyParser):
|
||||
class NormalKeyParser(keyparser.CommandKeyParser):
|
||||
|
||||
"""KeyParser for normalmode with added STARTCHARS detection."""
|
||||
|
||||
@ -63,7 +63,7 @@ class NormalKeyParser(CommandKeyParser):
|
||||
return super()._handle_single_key(e)
|
||||
|
||||
|
||||
class PromptKeyParser(CommandKeyParser):
|
||||
class PromptKeyParser(keyparser.CommandKeyParser):
|
||||
|
||||
"""KeyParser for yes/no prompts."""
|
||||
|
||||
@ -77,7 +77,7 @@ class PromptKeyParser(CommandKeyParser):
|
||||
return '<{}>'.format(self.__class__.__name__)
|
||||
|
||||
|
||||
class HintKeyParser(CommandKeyParser):
|
||||
class HintKeyParser(keyparser.CommandKeyParser):
|
||||
|
||||
"""KeyChainParser for hints.
|
||||
|
||||
|
@ -26,11 +26,11 @@ Module attributes:
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
Role = enum('Role', 'marks', 'sort', start=Qt.UserRole, is_int=True)
|
||||
Role = usertypes.enum('Role', 'marks', 'sort', start=Qt.UserRole, is_int=True)
|
||||
|
||||
|
||||
class BaseCompletionModel(QStandardItemModel):
|
||||
@ -74,7 +74,7 @@ class BaseCompletionModel(QStandardItemModel):
|
||||
index: A QModelIndex of the item to mark.
|
||||
needle: The string to mark.
|
||||
"""
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
haystack = self.data(index)
|
||||
marks = self._get_marks(needle, haystack)
|
||||
ok = self.setData(index, marks, Role.marks)
|
||||
@ -132,7 +132,7 @@ class BaseCompletionModel(QStandardItemModel):
|
||||
Return:
|
||||
The item flags, or Qt.NoItemFlags on error.
|
||||
"""
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
if index.parent().isValid():
|
||||
# item
|
||||
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
from qutebrowser.utils.usertypes import NeighborList
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ class History:
|
||||
items = self.history
|
||||
if not items:
|
||||
raise HistoryEmptyError
|
||||
self._tmphist = NeighborList(items)
|
||||
self._tmphist = usertypes.NeighborList(items)
|
||||
return self._tmphist.lastitem()
|
||||
|
||||
@pyqtSlot()
|
||||
|
@ -21,15 +21,14 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.config.configdata as configdata
|
||||
from qutebrowser.models.basecompletion import BaseCompletionModel
|
||||
from qutebrowser.commands.utils import cmd_dict
|
||||
from qutebrowser.config import config, configdata
|
||||
from qutebrowser.models import basecompletion
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import completion as logger
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
|
||||
|
||||
class SettingSectionCompletionModel(BaseCompletionModel):
|
||||
class SettingSectionCompletionModel(basecompletion.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with settings sections."""
|
||||
|
||||
@ -43,7 +42,7 @@ class SettingSectionCompletionModel(BaseCompletionModel):
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
|
||||
class SettingOptionCompletionModel(BaseCompletionModel):
|
||||
class SettingOptionCompletionModel(basecompletion.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with settings and their descriptions.
|
||||
|
||||
@ -88,14 +87,14 @@ class SettingOptionCompletionModel(BaseCompletionModel):
|
||||
return
|
||||
val = config.get(section, option, raw=True)
|
||||
idx = item.index()
|
||||
qt_ensure_valid(idx)
|
||||
qtutils.qt_ensure_valid(idx)
|
||||
ok = self.setData(idx, val, Qt.DisplayRole)
|
||||
if not ok:
|
||||
raise ValueError("Setting data failed! (section: {}, option: {}, "
|
||||
"value: {})".format(section, option, val))
|
||||
|
||||
|
||||
class SettingValueCompletionModel(BaseCompletionModel):
|
||||
class SettingValueCompletionModel(basecompletion.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with setting values.
|
||||
|
||||
@ -139,14 +138,14 @@ class SettingValueCompletionModel(BaseCompletionModel):
|
||||
if not value:
|
||||
value = '""'
|
||||
idx = self.cur_item.index()
|
||||
qt_ensure_valid(idx)
|
||||
qtutils.qt_ensure_valid(idx)
|
||||
ok = self.setData(idx, value, Qt.DisplayRole)
|
||||
if not ok:
|
||||
raise ValueError("Setting data failed! (section: {}, option: {}, "
|
||||
"value: {})".format(section, option, value))
|
||||
|
||||
|
||||
class CommandCompletionModel(BaseCompletionModel):
|
||||
class CommandCompletionModel(basecompletion.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with all commands and descriptions."""
|
||||
|
||||
@ -154,9 +153,9 @@ class CommandCompletionModel(BaseCompletionModel):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
assert cmd_dict
|
||||
assert cmdutils.cmd_dict
|
||||
cmdlist = []
|
||||
for obj in set(cmd_dict.values()):
|
||||
for obj in set(cmdutils.cmd_dict.values()):
|
||||
if obj.hide or (obj.debug and not
|
||||
QCoreApplication.instance().args.debug):
|
||||
pass
|
||||
|
@ -25,9 +25,9 @@ Contains:
|
||||
|
||||
from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex
|
||||
|
||||
from qutebrowser.models.basecompletion import Role
|
||||
from qutebrowser.models import basecompletion as completion
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import completion as logger
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
|
||||
|
||||
class CompletionFilterModel(QSortFilterProxyModel):
|
||||
@ -81,7 +81,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
count = 0
|
||||
for i in range(self.rowCount()):
|
||||
cat = self.index(i, 0)
|
||||
qt_ensure_valid(cat)
|
||||
qtutils.qt_ensure_valid(cat)
|
||||
count += self.rowCount(cat)
|
||||
return count
|
||||
|
||||
@ -89,10 +89,10 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
"""Return the first item in the model."""
|
||||
for i in range(self.rowCount()):
|
||||
cat = self.index(i, 0)
|
||||
qt_ensure_valid(cat)
|
||||
qtutils.qt_ensure_valid(cat)
|
||||
if cat.model().hasChildren(cat):
|
||||
index = self.index(0, 0, cat)
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
return index
|
||||
return QModelIndex()
|
||||
|
||||
@ -100,10 +100,10 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
"""Return the last item in the model."""
|
||||
for i in range(self.rowCount() - 1, -1, -1):
|
||||
cat = self.index(i, 0)
|
||||
qt_ensure_valid(cat)
|
||||
qtutils.qt_ensure_valid(cat)
|
||||
if cat.model().hasChildren(cat):
|
||||
index = self.index(self.rowCount(cat) - 1, 0, cat)
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
return index
|
||||
return QModelIndex()
|
||||
|
||||
@ -111,12 +111,12 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
"""Mark the given text in all visible items."""
|
||||
for i in range(self.rowCount()):
|
||||
cat = self.index(i, 0)
|
||||
qt_ensure_valid(cat)
|
||||
qtutils.qt_ensure_valid(cat)
|
||||
for k in range(self.rowCount(cat)):
|
||||
index = self.index(k, 0, cat)
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
index = self.mapToSource(index)
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
self.srcmodel.mark_item(index, text)
|
||||
|
||||
def setSourceModel(self, model):
|
||||
@ -142,7 +142,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
if parent == QModelIndex():
|
||||
return True
|
||||
idx = self.srcmodel.index(row, 0, parent)
|
||||
qt_ensure_valid(idx)
|
||||
qtutils.qt_ensure_valid(idx)
|
||||
data = self.srcmodel.data(idx)
|
||||
# TODO more sophisticated filtering
|
||||
if not self.pattern:
|
||||
@ -162,11 +162,11 @@ class CompletionFilterModel(QSortFilterProxyModel):
|
||||
Return:
|
||||
True if left < right, else False
|
||||
"""
|
||||
qt_ensure_valid(lindex)
|
||||
qt_ensure_valid(rindex)
|
||||
qtutils.qt_ensure_valid(lindex)
|
||||
qtutils.qt_ensure_valid(rindex)
|
||||
|
||||
left_sort = self.srcmodel.data(lindex, role=Role.sort)
|
||||
right_sort = self.srcmodel.data(rindex, role=Role.sort)
|
||||
left_sort = self.srcmodel.data(lindex, role=completion.Role.sort)
|
||||
right_sort = self.srcmodel.data(rindex, role=completion.Role.sort)
|
||||
|
||||
if left_sort is not None and right_sort is not None:
|
||||
return left_sort < right_sort
|
||||
|
@ -23,12 +23,12 @@ from PyQt5.QtCore import (pyqtSlot, Qt, QVariant, QAbstractListModel,
|
||||
QModelIndex)
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
Role = enum('Role', 'item', start=Qt.UserRole, is_int=True)
|
||||
Role = usertypes.enum('Role', 'item', start=Qt.UserRole, is_int=True)
|
||||
|
||||
|
||||
class DownloadModel(QAbstractListModel):
|
||||
@ -57,7 +57,7 @@ class DownloadModel(QAbstractListModel):
|
||||
def on_data_changed(self, idx):
|
||||
"""Update view when DownloadManager data changed."""
|
||||
model_idx = self.index(idx, 0)
|
||||
qt_ensure_valid(model_idx)
|
||||
qtutils.qt_ensure_valid(model_idx)
|
||||
self.dataChanged.emit(model_idx, model_idx)
|
||||
|
||||
def last_index(self):
|
||||
@ -79,7 +79,7 @@ class DownloadModel(QAbstractListModel):
|
||||
|
||||
def data(self, index, role):
|
||||
"""Download data from DownloadManager."""
|
||||
qt_ensure_valid(index)
|
||||
qtutils.qt_ensure_valid(index)
|
||||
if index.parent().isValid() or index.column() != 0:
|
||||
return QVariant()
|
||||
|
||||
|
@ -29,12 +29,9 @@ except ImportError:
|
||||
else:
|
||||
SSL_AVAILABLE = QSslSocket.supportsSsl()
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.network.qutescheme import QuteSchemeHandler
|
||||
from qutebrowser.network.schemehandler import ErrorNetworkReply
|
||||
from qutebrowser.utils.usertypes import PromptMode
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import message, log, usertypes
|
||||
from qutebrowser.network import qutescheme, schemehandler
|
||||
|
||||
|
||||
class NetworkManager(QNetworkAccessManager):
|
||||
@ -52,7 +49,7 @@ class NetworkManager(QNetworkAccessManager):
|
||||
super().__init__(parent)
|
||||
self._requests = []
|
||||
self._scheme_handlers = {
|
||||
'qute': QuteSchemeHandler(),
|
||||
'qute': qutescheme.QuteSchemeHandler(),
|
||||
}
|
||||
cookiejar = QCoreApplication.instance().cookiejar
|
||||
parent = cookiejar.parent()
|
||||
@ -105,14 +102,14 @@ class NetworkManager(QNetworkAccessManager):
|
||||
def on_authentication_required(self, _reply, authenticator):
|
||||
"""Called when a website needs authentication."""
|
||||
answer = message.ask("Username ({}):".format(authenticator.realm()),
|
||||
mode=PromptMode.user_pwd)
|
||||
mode=usertypes.PromptMode.user_pwd)
|
||||
self._fill_authenticator(authenticator, answer)
|
||||
|
||||
@pyqtSlot('QNetworkProxy', 'QAuthenticator')
|
||||
def on_proxy_authentication_required(self, _proxy, authenticator):
|
||||
"""Called when a proxy needs authentication."""
|
||||
answer = message.ask("Proxy username ({}):".format(
|
||||
authenticator.realm()), mode=PromptMode.user_pwd)
|
||||
authenticator.realm()), mode=usertypes.PromptMode.user_pwd)
|
||||
self._fill_authenticator(authenticator, answer)
|
||||
|
||||
def createRequest(self, op, req, outgoing_data):
|
||||
@ -131,7 +128,7 @@ class NetworkManager(QNetworkAccessManager):
|
||||
"""
|
||||
scheme = req.url().scheme()
|
||||
if scheme == 'https' and not SSL_AVAILABLE:
|
||||
return ErrorNetworkReply(
|
||||
return schemehandler.ErrorNetworkReply(
|
||||
req, "SSL is not supported by the installed Qt library!",
|
||||
QNetworkReply.ProtocolUnknownError)
|
||||
elif scheme in self._scheme_handlers:
|
||||
|
@ -19,11 +19,11 @@
|
||||
|
||||
"""Handling of proxies."""
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config.conftypes import SYSTEM_PROXY
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkProxyFactory
|
||||
|
||||
from qutebrowser.config import config, conftypes
|
||||
|
||||
|
||||
def init():
|
||||
"""Set the application wide proxy factory."""
|
||||
@ -44,7 +44,7 @@ class ProxyFactory(QNetworkProxyFactory):
|
||||
A list of QNetworkProxy objects in order of preference.
|
||||
"""
|
||||
proxy = config.get('network', 'proxy')
|
||||
if proxy is SYSTEM_PROXY:
|
||||
if proxy is conftypes.SYSTEM_PROXY:
|
||||
return QNetworkProxyFactory.systemProxyForQuery(query)
|
||||
else:
|
||||
return [proxy]
|
||||
|
@ -29,12 +29,10 @@ import html as pyhtml
|
||||
from PyQt5.QtNetwork import QNetworkReply
|
||||
|
||||
import qutebrowser
|
||||
import qutebrowser.utils.log as logutils
|
||||
import qutebrowser.utils.version as version
|
||||
from qutebrowser.network.schemehandler import (SchemeHandler,
|
||||
SpecialNetworkReply,
|
||||
ErrorNetworkReply)
|
||||
from qutebrowser.utils.misc import read_file
|
||||
from qutebrowser.network import schemehandler
|
||||
from qutebrowser.utils import version
|
||||
from qutebrowser.utils import log as logutils
|
||||
from qutebrowser.utils import misc as utils
|
||||
|
||||
|
||||
_HTML_TEMPLATE = """
|
||||
@ -73,7 +71,7 @@ def _get_html(title, snippet, head=None):
|
||||
return html
|
||||
|
||||
|
||||
class QuteSchemeHandler(SchemeHandler):
|
||||
class QuteSchemeHandler(schemehandler.SchemeHandler):
|
||||
|
||||
"""Scheme handler for qute: URLs."""
|
||||
|
||||
@ -97,12 +95,13 @@ class QuteSchemeHandler(SchemeHandler):
|
||||
except AttributeError:
|
||||
errorstr = "No handler found for {}!".format(
|
||||
request.url().toDisplayString())
|
||||
return ErrorNetworkReply(request, errorstr,
|
||||
QNetworkReply.ContentNotFoundError,
|
||||
self.parent())
|
||||
return schemehandler.ErrorNetworkReply(
|
||||
request, errorstr, QNetworkReply.ContentNotFoundError,
|
||||
self.parent())
|
||||
else:
|
||||
data = handler()
|
||||
return SpecialNetworkReply(request, data, 'text/html', self.parent())
|
||||
return schemehandler.SpecialNetworkReply(
|
||||
request, data, 'text/html', self.parent())
|
||||
|
||||
|
||||
class QuteHandlers:
|
||||
@ -171,4 +170,4 @@ class QuteHandlers:
|
||||
@classmethod
|
||||
def gpl(cls):
|
||||
"""Handler for qute:gpl. Return HTML content as bytes."""
|
||||
return read_file('html/COPYING.html').encode('ASCII')
|
||||
return utils.read_file('html/COPYING.html').encode('ASCII')
|
||||
|
@ -37,14 +37,14 @@ except ImportError:
|
||||
sys.exit(100)
|
||||
check_python_version()
|
||||
|
||||
from argparse import ArgumentParser
|
||||
import qutebrowser.utils.earlyinit as earlyinit
|
||||
import argparse
|
||||
from qutebrowser.utils import earlyinit
|
||||
|
||||
|
||||
def get_argparser():
|
||||
"""Get the argparse parser."""
|
||||
parser = ArgumentParser("usage: qutebrowser",
|
||||
description=qutebrowser.__description__)
|
||||
parser = argparse.ArgumentParser("usage: qutebrowser",
|
||||
description=qutebrowser.__description__)
|
||||
parser.add_argument('-c', '--confdir', help="Set config directory (empty "
|
||||
"for no config storage)")
|
||||
parser.add_argument('-V', '--version', help="Show version and quit.",
|
||||
@ -103,7 +103,7 @@ def main():
|
||||
earlyinit.check_pyqt_core()
|
||||
# We do this import late as we need to do the version checking first.
|
||||
# Note we may not import webkit stuff yet as fix_harfbuzz didn't run.
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils import log
|
||||
log.init_log(args)
|
||||
log.init.debug("Log initialized.")
|
||||
log.init.debug("Doing early init.")
|
||||
@ -113,10 +113,10 @@ def main():
|
||||
earlyinit.check_pkg_resources()
|
||||
earlyinit.check_pypeg2()
|
||||
# We do this import late as we need to fix harfbuzz first.
|
||||
from qutebrowser.app import Application
|
||||
from qutebrowser.utils.debug import trace_lines
|
||||
from qutebrowser import app
|
||||
from qutebrowser.utils import debug
|
||||
import PyQt5.QtWidgets as QtWidgets
|
||||
app = Application(args)
|
||||
app = app.Application(args)
|
||||
# We set qApp explicitely here to reduce the risk of segfaults while
|
||||
# quitting.
|
||||
# See https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/561303/comments/7
|
||||
@ -127,6 +127,6 @@ def main():
|
||||
ret = app.exec_()
|
||||
if args.debug_exit:
|
||||
print("Now logging late shutdown.", file=sys.stderr)
|
||||
trace_lines(True)
|
||||
debug.trace_lines(True)
|
||||
QtWidgets.qApp = None
|
||||
return ret
|
||||
|
@ -19,13 +19,13 @@
|
||||
"""Tests for qutebrowser.config.conftypes."""
|
||||
|
||||
import unittest
|
||||
import unittest.mock as mock
|
||||
import re
|
||||
from collections import namedtuple
|
||||
import collections
|
||||
from unittest import mock
|
||||
|
||||
import qutebrowser.config.conftypes as conftypes
|
||||
from qutebrowser.test.stubs import FakeCmdUtils, FakeCommand
|
||||
from qutebrowser.utils.debug import qenum_key
|
||||
from qutebrowser.config import conftypes
|
||||
from qutebrowser.test import stubs
|
||||
from qutebrowser.utils import debug
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtGui import QColor, QFont
|
||||
@ -37,9 +37,10 @@ class Font(QFont):
|
||||
"""A QFont with a nicer repr()."""
|
||||
|
||||
def __repr__(self):
|
||||
weight = debug.qenum_key(QFont, self.weight(), add_base=True,
|
||||
klass=QFont.Weight)
|
||||
return '<Font family={}, pt={}, px={}, weight={}, style={}>'.format(
|
||||
self.family(), self.pointSize(), self.pixelSize(),
|
||||
qenum_key(QFont, self.weight(), add_base=True, klass=QFont.Weight),
|
||||
self.family(), self.pointSize(), self.pixelSize(), weight,
|
||||
self.style())
|
||||
|
||||
@classmethod
|
||||
@ -853,10 +854,10 @@ class CommandTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.old_cmdutils = conftypes.cmdutils
|
||||
commands = {
|
||||
'cmd1': FakeCommand("desc 1"),
|
||||
'cmd2': FakeCommand("desc 2"),
|
||||
'cmd1': stubs.FakeCommand("desc 1"),
|
||||
'cmd2': stubs.FakeCommand("desc 2"),
|
||||
}
|
||||
conftypes.cmdutils = FakeCmdUtils(commands)
|
||||
conftypes.cmdutils = stubs.FakeCmdUtils(commands)
|
||||
self.t = conftypes.Command()
|
||||
|
||||
def tearDown(self):
|
||||
@ -1057,7 +1058,8 @@ class QssColorTests(QtColorTests):
|
||||
self.assertEqual(self.t.transform(v), v, v)
|
||||
|
||||
|
||||
FontDesc = namedtuple('FontDesc', ['style', 'weight', 'pt', 'px', 'family'])
|
||||
FontDesc = collections.namedtuple('FontDesc',
|
||||
['style', 'weight', 'pt', 'px', 'family'])
|
||||
|
||||
|
||||
class FontTests(unittest.TestCase):
|
||||
|
@ -20,13 +20,13 @@
|
||||
"""Helpers needed by tests."""
|
||||
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
from unittest.mock import create_autospec
|
||||
import contextlib
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtGui import QKeyEvent
|
||||
|
||||
|
||||
@contextmanager
|
||||
@contextlib.contextmanager
|
||||
def environ_set_temp(name, value):
|
||||
"""Set a temporary environment variable."""
|
||||
try:
|
||||
@ -43,8 +43,8 @@ def environ_set_temp(name, value):
|
||||
|
||||
def fake_keyevent(key, modifiers=0, text=''):
|
||||
"""Generate a new fake QKeyPressEvent."""
|
||||
mock = create_autospec(QKeyEvent, instance=True)
|
||||
mock.key.return_value = key
|
||||
mock.modifiers.return_value = modifiers
|
||||
mock.text.return_value = text
|
||||
return mock
|
||||
evtmock = mock.create_autospec(QKeyEvent, instance=True)
|
||||
evtmock.key.return_value = key
|
||||
evtmock.modifiers.return_value = modifiers
|
||||
evtmock.text.return_value = text
|
||||
return evtmock
|
||||
|
@ -23,14 +23,14 @@
|
||||
|
||||
import logging
|
||||
import unittest
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import qutebrowser.keyinput.basekeyparser as basekeyparser
|
||||
from qutebrowser.test.stubs import ConfigStub
|
||||
from qutebrowser.test.helpers import fake_keyevent
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from qutebrowser.keyinput import basekeyparser
|
||||
from qutebrowser.test import stubs, helpers
|
||||
|
||||
|
||||
CONFIG = {'test': {'<Ctrl-a>': 'ctrla',
|
||||
'a': 'a',
|
||||
'ba': 'ba',
|
||||
@ -42,7 +42,7 @@ CONFIG = {'test': {'<Ctrl-a>': 'ctrla',
|
||||
|
||||
def setUpModule():
|
||||
"""Mock out some imports in basekeyparser."""
|
||||
basekeyparser.QObject = Mock()
|
||||
basekeyparser.QObject = mock.Mock()
|
||||
logging.disable(logging.WARNING)
|
||||
|
||||
|
||||
@ -99,8 +99,8 @@ class ReadConfigTests(unittest.TestCase):
|
||||
"""Test reading the config."""
|
||||
|
||||
def setUp(self):
|
||||
basekeyparser.config = ConfigStub(CONFIG)
|
||||
basekeyparser.Timer = Mock()
|
||||
basekeyparser.config = stubs.ConfigStub(CONFIG)
|
||||
basekeyparser.usertypes.Timer = mock.Mock()
|
||||
|
||||
def test_read_config_invalid(self):
|
||||
"""Test reading config without setting it before."""
|
||||
@ -131,31 +131,32 @@ class SpecialKeysTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
patcher = patch('qutebrowser.keyinput.basekeyparser.Timer',
|
||||
autospec=True)
|
||||
patcher = mock.patch(
|
||||
'qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
autospec=True)
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
basekeyparser.config = ConfigStub(CONFIG)
|
||||
basekeyparser.config = stubs.ConfigStub(CONFIG)
|
||||
self.kp = basekeyparser.BaseKeyParser()
|
||||
self.kp.execute = Mock()
|
||||
self.kp.execute = mock.Mock()
|
||||
self.kp.read_config('test')
|
||||
|
||||
def test_valid_key(self):
|
||||
"""Test a valid special keyevent."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_X, Qt.ControlModifier))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, Qt.ControlModifier))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_X, Qt.ControlModifier))
|
||||
self.kp.execute.assert_called_once_with('ctrla', self.kp.Type.special)
|
||||
|
||||
def test_invalid_key(self):
|
||||
"""Test an invalid special keyevent."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, (Qt.ControlModifier |
|
||||
Qt.AltModifier)))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, (Qt.ControlModifier |
|
||||
Qt.AltModifier)))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
|
||||
def test_keychain(self):
|
||||
"""Test a keychain."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
|
||||
|
||||
@ -170,35 +171,35 @@ class KeyChainTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Set up mocks and read the test config."""
|
||||
basekeyparser.config = ConfigStub(CONFIG)
|
||||
self.timermock = Mock()
|
||||
basekeyparser.Timer = Mock(return_value=self.timermock)
|
||||
basekeyparser.config = stubs.ConfigStub(CONFIG)
|
||||
self.timermock = mock.Mock()
|
||||
basekeyparser.usertypes.Timer = mock.Mock(return_value=self.timermock)
|
||||
self.kp = basekeyparser.BaseKeyParser(supports_chains=True,
|
||||
supports_count=False)
|
||||
self.kp.execute = Mock()
|
||||
self.kp.execute = mock.Mock()
|
||||
self.kp.read_config('test')
|
||||
|
||||
def test_valid_special_key(self):
|
||||
"""Test valid special key."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_X, Qt.ControlModifier))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, Qt.ControlModifier))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_X, Qt.ControlModifier))
|
||||
self.kp.execute.assert_called_once_with('ctrla', self.kp.Type.special)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_invalid_special_key(self):
|
||||
"""Test invalid special key."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, (Qt.ControlModifier |
|
||||
Qt.AltModifier)))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, (Qt.ControlModifier |
|
||||
Qt.AltModifier)))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_keychain(self):
|
||||
"""Test valid keychain."""
|
||||
# Press 'x' which is ignored because of no match
|
||||
self.kp.handle(fake_keyevent(Qt.Key_X, text='x'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_X, text='x'))
|
||||
# Then start the real chain
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
@ -206,9 +207,10 @@ class KeyChainTests(unittest.TestCase):
|
||||
"""Test ambigious keychain."""
|
||||
# We start with 'a' where the keychain gives us an ambigious result.
|
||||
# Then we check if the timer has been set up correctly
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
basekeyparser.Timer.assert_called_once_with(self.kp, 'ambigious_match')
|
||||
basekeyparser.usertypes.Timer.assert_called_once_with(
|
||||
self.kp, 'ambigious_match')
|
||||
self.timermock.setSingleShot.assert_called_once_with(True)
|
||||
self.timermock.setInterval.assert_called_once_with(100)
|
||||
self.assertTrue(self.timermock.timeout.connect.called)
|
||||
@ -216,15 +218,15 @@ class KeyChainTests(unittest.TestCase):
|
||||
self.timermock.start.assert_called_once_with()
|
||||
# Now we type an 'x' and check 'ax' has been executed and the timer
|
||||
# stopped.
|
||||
self.kp.handle(fake_keyevent(Qt.Key_X, text='x'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_X, text='x'))
|
||||
self.kp.execute.assert_called_once_with('ax', self.kp.Type.chain, None)
|
||||
self.timermock.stop.assert_called_once_with()
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_invalid_keychain(self):
|
||||
"""Test invalid keychain."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_C, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_C, text='c'))
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
|
||||
@ -233,53 +235,53 @@ class CountTests(unittest.TestCase):
|
||||
"""Test execute() with counts."""
|
||||
|
||||
def setUp(self):
|
||||
basekeyparser.config = ConfigStub(CONFIG)
|
||||
basekeyparser.Timer = Mock()
|
||||
basekeyparser.config = stubs.ConfigStub(CONFIG)
|
||||
basekeyparser.usertypes.Timer = mock.Mock()
|
||||
self.kp = basekeyparser.BaseKeyParser(supports_chains=True,
|
||||
supports_count=True)
|
||||
self.kp.execute = Mock()
|
||||
self.kp.execute = mock.Mock()
|
||||
self.kp.read_config('test')
|
||||
|
||||
def test_no_count(self):
|
||||
"""Test with no count added."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_count_0(self):
|
||||
"""Test with count=0."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_0, text='0'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_0, text='0'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, 0)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_count_42(self):
|
||||
"""Test with count=42."""
|
||||
self.kp.handle(fake_keyevent(Qt.Key_4, text='4'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_2, text='2'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='4'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='2'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, 42)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_count_42_invalid(self):
|
||||
"""Test with count=42 and invalid command."""
|
||||
# Invalid call with ccx gets ignored
|
||||
self.kp.handle(fake_keyevent(Qt.Key_4, text='4'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_2, text='2'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='c'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='x'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='4'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='2'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='x'))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
# Valid call with ccc gets the correct count
|
||||
self.kp.handle(fake_keyevent(Qt.Key_4, text='2'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_2, text='3'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_B, text='c'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.handle(fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='2'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='3'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c'))
|
||||
self.kp.execute.assert_called_once_with('ccc', self.kp.Type.chain, 23)
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
"""Fake objects/stubs."""
|
||||
|
||||
from unittest.mock import Mock
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtCore import QPoint, QProcess
|
||||
from PyQt5.QtWebKit import QWebElement
|
||||
@ -73,9 +73,9 @@ class FakeKeyEvent:
|
||||
"""Fake QKeyPressEvent stub."""
|
||||
|
||||
def __init__(self, key, modifiers=0, text=''):
|
||||
self.key = Mock(return_value=key)
|
||||
self.text = Mock(return_value=text)
|
||||
self.modifiers = Mock(return_value=modifiers)
|
||||
self.key = mock.Mock(return_value=key)
|
||||
self.text = mock.Mock(return_value=text)
|
||||
self.modifiers = mock.Mock(return_value=modifiers)
|
||||
|
||||
|
||||
class FakeWebElement:
|
||||
@ -99,10 +99,10 @@ class FakeWebElement:
|
||||
Raise:
|
||||
ValueError if element is not null and geometry/frame are not given.
|
||||
"""
|
||||
self.geometry = Mock(return_value=geometry)
|
||||
self.webFrame = Mock(return_value=frame)
|
||||
self.isNull = Mock(return_value=null)
|
||||
self.tagName = Mock(return_value=tagname)
|
||||
self.geometry = mock.Mock(return_value=geometry)
|
||||
self.webFrame = mock.Mock(return_value=frame)
|
||||
self.isNull = mock.Mock(return_value=null)
|
||||
self.tagName = mock.Mock(return_value=tagname)
|
||||
self._visibility = visibility
|
||||
self._display = display
|
||||
self._attributes = attributes
|
||||
@ -170,9 +170,9 @@ class FakeWebFrame:
|
||||
"""
|
||||
if scroll is None:
|
||||
scroll = QPoint(0, 0)
|
||||
self.geometry = Mock(return_value=geometry)
|
||||
self.scrollPosition = Mock(return_value=scroll)
|
||||
self.parentFrame = Mock(return_value=parent)
|
||||
self.geometry = mock.Mock(return_value=geometry)
|
||||
self.scrollPosition = mock.Mock(return_value=scroll)
|
||||
self.parentFrame = mock.Mock(return_value=parent)
|
||||
|
||||
|
||||
class FakeChildrenFrame:
|
||||
@ -182,7 +182,7 @@ class FakeChildrenFrame:
|
||||
def __init__(self, children=None):
|
||||
if children is None:
|
||||
children = []
|
||||
self.childFrames = Mock(return_value=children)
|
||||
self.childFrames = mock.Mock(return_value=children)
|
||||
|
||||
|
||||
class FakeQApplication:
|
||||
@ -190,8 +190,8 @@ class FakeQApplication:
|
||||
"""Stub to insert as QApplication module."""
|
||||
|
||||
def __init__(self, focus):
|
||||
self.focusWidget = Mock(return_value=focus)
|
||||
self.instance = Mock(return_value=self)
|
||||
self.focusWidget = mock.Mock(return_value=focus)
|
||||
self.instance = mock.Mock(return_value=self)
|
||||
|
||||
|
||||
class FakeUrl:
|
||||
@ -199,7 +199,7 @@ class FakeUrl:
|
||||
"""QUrl stub which provides .path()."""
|
||||
|
||||
def __init__(self, path=None):
|
||||
self.path = Mock(return_value=path)
|
||||
self.path = mock.Mock(return_value=path)
|
||||
|
||||
|
||||
class FakeNetworkReply:
|
||||
@ -217,7 +217,7 @@ class FakeNetworkReply:
|
||||
self.headers = {}
|
||||
else:
|
||||
self.headers = headers
|
||||
self.url = Mock(return_value=url)
|
||||
self.url = mock.Mock(return_value=url)
|
||||
|
||||
def hasRawHeader(self, name):
|
||||
"""Check if the reply has a certain header.
|
||||
@ -282,9 +282,9 @@ class FakeQProcess:
|
||||
UnknownError = QProcess.UnknownError
|
||||
|
||||
def __init__(self, parent=None): # pylint: disable=unused-argument
|
||||
self.finished = Mock()
|
||||
self.error = Mock()
|
||||
self.start = Mock()
|
||||
self.finished = mock.Mock()
|
||||
self.error = mock.Mock()
|
||||
self.start = mock.Mock()
|
||||
|
||||
|
||||
class FakeSignal:
|
||||
|
@ -23,7 +23,7 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from qutebrowser.test.helpers import environ_set_temp
|
||||
from qutebrowser.test import helpers
|
||||
|
||||
|
||||
class TestEnvironSetTemp(unittest.TestCase):
|
||||
@ -33,13 +33,13 @@ class TestEnvironSetTemp(unittest.TestCase):
|
||||
def test_environ_set(self):
|
||||
"""Test environ_set_temp with something which was set already."""
|
||||
os.environ['QUTEBROWSER_ENVIRON_TEST'] = 'oldval'
|
||||
with environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'):
|
||||
with helpers.environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'):
|
||||
self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'newval')
|
||||
self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'oldval')
|
||||
|
||||
def test_environ_unset(self):
|
||||
"""Test environ_set_temp with something which wasn't set yet."""
|
||||
with environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'):
|
||||
with helpers.environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'):
|
||||
self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'newval')
|
||||
self.assertNotIn('QUTEBROWSER_ENVIRON_TEST', os.environ)
|
||||
|
||||
|
@ -23,8 +23,8 @@ import os
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
import qutebrowser.utils.http as httputils
|
||||
from qutebrowser.test.stubs import FakeNetworkReply
|
||||
from qutebrowser.utils import http
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
DEFAULT_NAME = 'qutebrowser-download'
|
||||
@ -39,23 +39,23 @@ class AttachmentTestCase(unittest.TestCase):
|
||||
|
||||
def _check_filename(self, header, filename):
|
||||
"""Check if the passed header has the given filename."""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertIsNotNone(cd_filename)
|
||||
self.assertEqual(cd_filename, filename)
|
||||
self.assertFalse(cd_inline)
|
||||
|
||||
def _check_ignored(self, header):
|
||||
"""Check if the passed header is ignored."""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertEqual(cd_filename, DEFAULT_NAME)
|
||||
self.assertTrue(cd_inline)
|
||||
|
||||
def _check_unnamed(self, header):
|
||||
"""Check if the passed header results in an unnamed attachment."""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertEqual(cd_filename, DEFAULT_NAME)
|
||||
self.assertFalse(cd_inline)
|
||||
|
||||
@ -69,15 +69,15 @@ class InlineTests(unittest.TestCase):
|
||||
|
||||
def _check_filename(self, header, filename):
|
||||
"""Check if the passed header has the given filename."""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertEqual(cd_filename, filename)
|
||||
self.assertTrue(cd_inline)
|
||||
|
||||
def _check_ignored(self, header):
|
||||
"""Check if the passed header is ignored."""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertEqual(cd_filename, DEFAULT_NAME)
|
||||
self.assertTrue(cd_inline)
|
||||
|
||||
@ -134,8 +134,9 @@ class AttachmentTests(AttachmentTestCase):
|
||||
|
||||
UA should offer to download the resource.
|
||||
"""
|
||||
reply = FakeNetworkReply(headers={'Content-Disposition': 'attachment'})
|
||||
cd_inline, cd_filename = httputils.parse_content_disposition(reply)
|
||||
reply = stubs.FakeNetworkReply(
|
||||
headers={'Content-Disposition': 'attachment'})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertFalse(cd_inline)
|
||||
self.assertEqual(cd_filename, DEFAULT_NAME)
|
||||
|
||||
|
@ -25,8 +25,8 @@ test_content_disposition.py file.
|
||||
|
||||
import unittest
|
||||
|
||||
import qutebrowser.utils.http as httputils
|
||||
from qutebrowser.test.stubs import FakeNetworkReply
|
||||
from qutebrowser.utils import http
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
class ParseContentTypeTests(unittest.TestCase):
|
||||
@ -35,30 +35,31 @@ class ParseContentTypeTests(unittest.TestCase):
|
||||
|
||||
def test_not_existing(self):
|
||||
"""Test without any Content-Type header."""
|
||||
reply = FakeNetworkReply()
|
||||
mimetype, rest = httputils.parse_content_type(reply)
|
||||
reply = stubs.FakeNetworkReply()
|
||||
mimetype, rest = http.parse_content_type(reply)
|
||||
self.assertIsNone(mimetype)
|
||||
self.assertIsNone(rest)
|
||||
|
||||
def test_mimetype(self):
|
||||
"""Test with simple Content-Type header."""
|
||||
reply = FakeNetworkReply(headers={'Content-Type': 'image/example'})
|
||||
mimetype, rest = httputils.parse_content_type(reply)
|
||||
reply = stubs.FakeNetworkReply(
|
||||
headers={'Content-Type': 'image/example'})
|
||||
mimetype, rest = http.parse_content_type(reply)
|
||||
self.assertEqual(mimetype, 'image/example')
|
||||
self.assertIsNone(rest)
|
||||
|
||||
def test_empty(self):
|
||||
"""Test with empty Content-Type header."""
|
||||
reply = FakeNetworkReply(headers={'Content-Type': ''})
|
||||
mimetype, rest = httputils.parse_content_type(reply)
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Type': ''})
|
||||
mimetype, rest = http.parse_content_type(reply)
|
||||
self.assertEqual(mimetype, '')
|
||||
self.assertIsNone(rest)
|
||||
|
||||
def test_additional(self):
|
||||
"""Test with Content-Type header with additional informations."""
|
||||
reply = FakeNetworkReply(
|
||||
reply = stubs.FakeNetworkReply(
|
||||
headers={'Content-Type': 'image/example; encoding=UTF-8'})
|
||||
mimetype, rest = httputils.parse_content_type(reply)
|
||||
mimetype, rest = http.parse_content_type(reply)
|
||||
self.assertEqual(mimetype, 'image/example')
|
||||
self.assertEqual(rest, ' encoding=UTF-8')
|
||||
|
||||
|
@ -24,8 +24,8 @@ import unittest
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QStyle, QFrame
|
||||
|
||||
import qutebrowser.utils.debug as debug
|
||||
from qutebrowser.test.stubs import FakeSignal
|
||||
from qutebrowser.utils import debug
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
class QEnumKeyTests(unittest.TestCase):
|
||||
@ -123,7 +123,7 @@ class TestDebug(unittest.TestCase):
|
||||
"""Test signal debug output functions."""
|
||||
|
||||
def setUp(self):
|
||||
self.signal = FakeSignal()
|
||||
self.signal = stubs.FakeSignal()
|
||||
|
||||
def test_signal_name(self):
|
||||
"""Test signal_name()."""
|
||||
|
@ -23,19 +23,19 @@ import os
|
||||
import os.path
|
||||
import unittest
|
||||
import logging
|
||||
from unittest.mock import Mock
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtCore import QProcess
|
||||
|
||||
import qutebrowser.utils.editor as editorutils
|
||||
from qutebrowser.test.stubs import ConfigStub, FakeQProcess
|
||||
from qutebrowser.utils import editor
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
def setUpModule():
|
||||
"""Disable logging and mock out some imports."""
|
||||
logging.disable(logging.INFO)
|
||||
editorutils.message = Mock()
|
||||
editorutils.QProcess = FakeQProcess
|
||||
editor.message = mock.Mock()
|
||||
editor.QProcess = stubs.FakeQProcess
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
@ -52,18 +52,18 @@ class ArgTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.editor = editorutils.ExternalEditor()
|
||||
self.editor = editor.ExternalEditor()
|
||||
|
||||
def test_simple_start_args(self):
|
||||
"""Test starting editor without arguments."""
|
||||
editorutils.config = ConfigStub(
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin'], 'editor-encoding': 'utf-8'}})
|
||||
self.editor.edit("")
|
||||
self.editor.proc.start.assert_called_with("bin", [])
|
||||
|
||||
def test_start_args(self):
|
||||
"""Test starting editor with static arguments."""
|
||||
editorutils.config = ConfigStub(
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin', 'foo', 'bar'],
|
||||
'editor-encoding': 'utf-8'}})
|
||||
self.editor.edit("")
|
||||
@ -71,7 +71,7 @@ class ArgTests(unittest.TestCase):
|
||||
|
||||
def test_placeholder(self):
|
||||
"""Test starting editor with placeholder argument."""
|
||||
editorutils.config = ConfigStub(
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin', 'foo', '{}', 'bar'],
|
||||
'editor-encoding': 'utf-8'}})
|
||||
self.editor.edit("")
|
||||
@ -81,7 +81,7 @@ class ArgTests(unittest.TestCase):
|
||||
|
||||
def test_in_arg_placeholder(self):
|
||||
"""Test starting editor with placeholder argument inside argument."""
|
||||
editorutils.config = ConfigStub(
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin', 'foo{}bar'],
|
||||
'editor-encoding': 'utf-8'}})
|
||||
self.editor.edit("")
|
||||
@ -100,8 +100,8 @@ class FileHandlingTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.editor = editorutils.ExternalEditor()
|
||||
editorutils.config = ConfigStub(
|
||||
self.editor = editor.ExternalEditor()
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}})
|
||||
|
||||
def test_file_handling_closed_ok(self):
|
||||
@ -139,9 +139,9 @@ class TextModifyTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.editor = editorutils.ExternalEditor()
|
||||
self.editor.editing_finished = Mock()
|
||||
editorutils.config = ConfigStub(
|
||||
self.editor = editor.ExternalEditor()
|
||||
self.editor.editing_finished = mock.Mock()
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}})
|
||||
|
||||
def _write(self, text):
|
||||
@ -209,21 +209,21 @@ class ErrorMessageTests(unittest.TestCase):
|
||||
# pylint: disable=maybe-no-member
|
||||
|
||||
def setUp(self):
|
||||
self.editor = editorutils.ExternalEditor()
|
||||
editorutils.config = ConfigStub(
|
||||
self.editor = editor.ExternalEditor()
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}})
|
||||
|
||||
def test_proc_error(self):
|
||||
"""Test on_proc_error."""
|
||||
self.editor.edit("")
|
||||
self.editor.on_proc_error(QProcess.Crashed)
|
||||
self.assertTrue(editorutils.message.error.called)
|
||||
self.assertTrue(editor.message.error.called)
|
||||
|
||||
def test_proc_return(self):
|
||||
"""Test on_proc_finished with a bad exit status."""
|
||||
self.editor.edit("")
|
||||
self.editor.on_proc_closed(1, QProcess.NormalExit)
|
||||
self.assertTrue(editorutils.message.error.called)
|
||||
self.assertTrue(editor.message.error.called)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -26,7 +26,7 @@ import unittest
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils import log
|
||||
|
||||
|
||||
class BaseTest(unittest.TestCase):
|
||||
|
@ -24,14 +24,14 @@ import sys
|
||||
import shutil
|
||||
import unittest
|
||||
import os.path
|
||||
from tempfile import mkdtemp
|
||||
import tempfile
|
||||
|
||||
from PyQt5.QtCore import QStandardPaths, QCoreApplication, Qt
|
||||
from PyQt5.QtGui import QColor
|
||||
|
||||
import qutebrowser.utils.misc as utils
|
||||
from qutebrowser.test.helpers import environ_set_temp, fake_keyevent
|
||||
from qutebrowser.utils.qt import QtValueError
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.test import helpers
|
||||
|
||||
|
||||
class Color(QColor):
|
||||
@ -157,14 +157,14 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.temp_dir = mkdtemp()
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.app = QCoreApplication([])
|
||||
self.app.setApplicationName('qutebrowser')
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_data_explicit(self):
|
||||
"""Test data dir with XDG_DATA_HOME explicitely set."""
|
||||
with environ_set_temp('XDG_DATA_HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('XDG_DATA_HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(QStandardPaths.DataLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir,
|
||||
'qutebrowser'))
|
||||
@ -173,7 +173,7 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_config_explicit(self):
|
||||
"""Test config dir with XDG_CONFIG_HOME explicitely set."""
|
||||
with environ_set_temp('XDG_CONFIG_HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('XDG_CONFIG_HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(QStandardPaths.ConfigLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir,
|
||||
'qutebrowser'))
|
||||
@ -182,7 +182,7 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_cache_explicit(self):
|
||||
"""Test cache dir with XDG_CACHE_HOME explicitely set."""
|
||||
with environ_set_temp('XDG_CACHE_HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('XDG_CACHE_HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(QStandardPaths.CacheLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir,
|
||||
'qutebrowser'))
|
||||
@ -191,7 +191,7 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_data(self):
|
||||
"""Test data dir with XDG_DATA_HOME not set."""
|
||||
with environ_set_temp('HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(QStandardPaths.DataLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.local',
|
||||
'share', 'qutebrowser'))
|
||||
@ -200,7 +200,7 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_config(self):
|
||||
"""Test config dir with XDG_CONFIG_HOME not set."""
|
||||
with environ_set_temp('HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(
|
||||
QStandardPaths.ConfigLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.config',
|
||||
@ -210,7 +210,7 @@ class GetStandardDirLinuxTests(unittest.TestCase):
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_cache(self):
|
||||
"""Test cache dir with XDG_CACHE_HOME not set."""
|
||||
with environ_set_temp('HOME', self.temp_dir):
|
||||
with helpers.environ_set_temp('HOME', self.temp_dir):
|
||||
cur_dir = utils.get_standard_dir(QStandardPaths.CacheLocation)
|
||||
self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.cache',
|
||||
'qutebrowser'))
|
||||
@ -286,12 +286,12 @@ class InterpolateColorTests(unittest.TestCase):
|
||||
|
||||
def test_invalid_start(self):
|
||||
"""Test an invalid start color."""
|
||||
with self.assertRaises(QtValueError):
|
||||
with self.assertRaises(qtutils.QtValueError):
|
||||
utils.interpolate_color(Color(), self.white, 0)
|
||||
|
||||
def test_invalid_end(self):
|
||||
"""Test an invalid end color."""
|
||||
with self.assertRaises(QtValueError):
|
||||
with self.assertRaises(qtutils.QtValueError):
|
||||
utils.interpolate_color(self.white, Color(), 0)
|
||||
|
||||
def test_invalid_percentage(self):
|
||||
@ -464,29 +464,31 @@ class KeyEventToStringTests(unittest.TestCase):
|
||||
|
||||
def test_only_control(self):
|
||||
"""Test keyeevent when only control is pressed."""
|
||||
evt = fake_keyevent(key=Qt.Key_Control, modifiers=Qt.ControlModifier)
|
||||
evt = helpers.fake_keyevent(key=Qt.Key_Control,
|
||||
modifiers=Qt.ControlModifier)
|
||||
self.assertIsNone(utils.keyevent_to_string(evt))
|
||||
|
||||
def test_only_hyper_l(self):
|
||||
"""Test keyeevent when only Hyper_L is pressed."""
|
||||
evt = fake_keyevent(key=Qt.Key_Hyper_L, modifiers=Qt.MetaModifier)
|
||||
evt = helpers.fake_keyevent(key=Qt.Key_Hyper_L,
|
||||
modifiers=Qt.MetaModifier)
|
||||
self.assertIsNone(utils.keyevent_to_string(evt))
|
||||
|
||||
def test_only_key(self):
|
||||
"""Test with a simple key pressed."""
|
||||
evt = fake_keyevent(key=Qt.Key_A)
|
||||
evt = helpers.fake_keyevent(key=Qt.Key_A)
|
||||
self.assertEqual(utils.keyevent_to_string(evt), 'A')
|
||||
|
||||
def test_key_and_modifier(self):
|
||||
"""Test with key and modifier pressed."""
|
||||
evt = fake_keyevent(key=Qt.Key_A, modifiers=Qt.ControlModifier)
|
||||
evt = helpers.fake_keyevent(key=Qt.Key_A, modifiers=Qt.ControlModifier)
|
||||
self.assertEqual(utils.keyevent_to_string(evt), 'Ctrl+A')
|
||||
|
||||
def test_key_and_modifiers(self):
|
||||
"""Test with key and multiple modifier pressed."""
|
||||
evt = fake_keyevent(key=Qt.Key_A,
|
||||
modifiers=(Qt.ControlModifier | Qt.AltModifier |
|
||||
Qt.MetaModifier | Qt.ShiftModifier))
|
||||
evt = helpers.fake_keyevent(
|
||||
key=Qt.Key_A, modifiers=(Qt.ControlModifier | Qt.AltModifier |
|
||||
Qt.MetaModifier | Qt.ShiftModifier))
|
||||
self.assertEqual(utils.keyevent_to_string(evt),
|
||||
'Ctrl+Alt+Meta+Shift+A')
|
||||
|
||||
|
@ -23,7 +23,7 @@ import sys
|
||||
import argparse
|
||||
import unittest
|
||||
|
||||
import qutebrowser.utils.qt as qt
|
||||
from qutebrowser.utils import qt
|
||||
|
||||
|
||||
class CheckOverflowTests(unittest.TestCase):
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
import inspect
|
||||
import unittest
|
||||
from unittest.mock import Mock
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtWidgets import QLineEdit
|
||||
|
||||
import qutebrowser.utils.readline as readline
|
||||
from qutebrowser.test.stubs import FakeQApplication
|
||||
from qutebrowser.utils import readline
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
class NoneWidgetTests(unittest.TestCase):
|
||||
@ -34,7 +34,7 @@ class NoneWidgetTests(unittest.TestCase):
|
||||
"""Tests when the focused widget is None."""
|
||||
|
||||
def setUp(self):
|
||||
readline.QApplication = FakeQApplication(None)
|
||||
readline.QApplication = stubs.FakeQApplication(None)
|
||||
self.bridge = readline.ReadlineBridge()
|
||||
|
||||
def test_none(self):
|
||||
@ -50,9 +50,9 @@ class ReadlineBridgeTest(unittest.TestCase):
|
||||
"""Tests for readline bridge."""
|
||||
|
||||
def setUp(self):
|
||||
self.qle = Mock()
|
||||
self.qle = mock.Mock()
|
||||
self.qle.__class__ = QLineEdit
|
||||
readline.QApplication = FakeQApplication(self.qle)
|
||||
readline.QApplication = stubs.FakeQApplication(self.qle)
|
||||
self.bridge = readline.ReadlineBridge()
|
||||
|
||||
def _set_selected_text(self, text):
|
||||
|
@ -25,8 +25,8 @@ import unittest
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
from qutebrowser.test.stubs import ConfigStub
|
||||
from qutebrowser.utils import url as urlutils
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
CONFIG = {
|
||||
@ -83,7 +83,7 @@ class SearchUrlTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.config = urlutils.config
|
||||
urlutils.config = ConfigStub(CONFIG)
|
||||
urlutils.config = stubs.ConfigStub(CONFIG)
|
||||
|
||||
def test_default_engine(self):
|
||||
"""Test default search engine."""
|
||||
|
@ -23,9 +23,8 @@ import unittest
|
||||
|
||||
from PyQt5.QtCore import QRect, QPoint
|
||||
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
from qutebrowser.test.stubs import (FakeWebElement, FakeWebFrame,
|
||||
FakeChildrenFrame, ConfigStub)
|
||||
from qutebrowser.utils import webelem
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
class IsVisibleInvalidTests(unittest.TestCase):
|
||||
@ -37,7 +36,7 @@ class IsVisibleInvalidTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.frame = FakeWebFrame(QRect(0, 0, 100, 100))
|
||||
self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100))
|
||||
|
||||
def test_nullelem(self):
|
||||
"""Passing an element with isNull() == True.
|
||||
@ -45,7 +44,7 @@ class IsVisibleInvalidTests(unittest.TestCase):
|
||||
geometry() and webFrame() should not be called, and ValueError should
|
||||
be raised.
|
||||
"""
|
||||
elem = FakeWebElement(null=True)
|
||||
elem = stubs.FakeWebElement(null=True)
|
||||
with self.assertRaises(ValueError):
|
||||
webelem.is_visible(elem, self.frame)
|
||||
elem.isNull.assert_called_once_with()
|
||||
@ -54,7 +53,7 @@ class IsVisibleInvalidTests(unittest.TestCase):
|
||||
|
||||
def test_invalid_invisible(self):
|
||||
"""Test elements with an invalid geometry which are invisible."""
|
||||
elem = FakeWebElement(QRect(0, 0, 0, 0), self.frame)
|
||||
elem = stubs.FakeWebElement(QRect(0, 0, 0, 0), self.frame)
|
||||
self.assertFalse(elem.geometry().isValid())
|
||||
self.assertEqual(elem.geometry().x(), 0)
|
||||
self.assertFalse(webelem.is_visible(elem, self.frame))
|
||||
@ -65,7 +64,7 @@ class IsVisibleInvalidTests(unittest.TestCase):
|
||||
This seems to happen sometimes in the real world, with real elements
|
||||
which *are* visible, but don't have a valid geometry.
|
||||
"""
|
||||
elem = FakeWebElement(QRect(10, 10, 0, 0), self.frame)
|
||||
elem = stubs.FakeWebElement(QRect(10, 10, 0, 0), self.frame)
|
||||
self.assertFalse(elem.geometry().isValid())
|
||||
self.assertTrue(webelem.is_visible(elem, self.frame))
|
||||
|
||||
@ -79,16 +78,17 @@ class IsVisibleScrollTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.frame = FakeWebFrame(QRect(0, 0, 100, 100), scroll=QPoint(10, 10))
|
||||
self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100),
|
||||
scroll=QPoint(10, 10))
|
||||
|
||||
def test_invisible(self):
|
||||
"""Test elements which should be invisible due to scrolling."""
|
||||
elem = FakeWebElement(QRect(5, 5, 4, 4), self.frame)
|
||||
elem = stubs.FakeWebElement(QRect(5, 5, 4, 4), self.frame)
|
||||
self.assertFalse(webelem.is_visible(elem, self.frame))
|
||||
|
||||
def test_visible(self):
|
||||
"""Test elements which still should be visible after scrolling."""
|
||||
elem = FakeWebElement(QRect(10, 10, 1, 1), self.frame)
|
||||
elem = stubs.FakeWebElement(QRect(10, 10, 1, 1), self.frame)
|
||||
self.assertTrue(webelem.is_visible(elem, self.frame))
|
||||
|
||||
|
||||
@ -101,29 +101,30 @@ class IsVisibleCssTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.frame = FakeWebFrame(QRect(0, 0, 100, 100))
|
||||
self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100))
|
||||
|
||||
def test_visibility_visible(self):
|
||||
"""Check that elements with "visibility = visible" are visible."""
|
||||
elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
visibility='visible')
|
||||
elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
visibility='visible')
|
||||
self.assertTrue(webelem.is_visible(elem, self.frame))
|
||||
|
||||
def test_visibility_hidden(self):
|
||||
"""Check that elements with "visibility = hidden" are not visible."""
|
||||
elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
visibility='hidden')
|
||||
elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
visibility='hidden')
|
||||
self.assertFalse(webelem.is_visible(elem, self.frame))
|
||||
|
||||
def test_display_inline(self):
|
||||
"""Check that elements with "display = inline" are visible."""
|
||||
elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
display='inline')
|
||||
elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
display='inline')
|
||||
self.assertTrue(webelem.is_visible(elem, self.frame))
|
||||
|
||||
def test_display_none(self):
|
||||
"""Check that elements with "display = none" are not visible."""
|
||||
elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame, display='none')
|
||||
elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame,
|
||||
display='none')
|
||||
self.assertFalse(webelem.is_visible(elem, self.frame))
|
||||
|
||||
|
||||
@ -158,12 +159,13 @@ class IsVisibleIframeTests(unittest.TestCase):
|
||||
##############################
|
||||
300, 0 300, 300
|
||||
"""
|
||||
self.frame = FakeWebFrame(QRect(0, 0, 300, 300))
|
||||
self.iframe = FakeWebFrame(QRect(0, 10, 100, 100), parent=self.frame)
|
||||
self.elem1 = FakeWebElement(QRect(0, 0, 10, 10), self.iframe)
|
||||
self.elem2 = FakeWebElement(QRect(20, 90, 10, 10), self.iframe)
|
||||
self.elem3 = FakeWebElement(QRect(20, 150, 10, 10), self.iframe)
|
||||
self.elem4 = FakeWebElement(QRect(30, 180, 10, 10), self.frame)
|
||||
self.frame = stubs.FakeWebFrame(QRect(0, 0, 300, 300))
|
||||
self.iframe = stubs.FakeWebFrame(QRect(0, 10, 100, 100),
|
||||
parent=self.frame)
|
||||
self.elem1 = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.iframe)
|
||||
self.elem2 = stubs.FakeWebElement(QRect(20, 90, 10, 10), self.iframe)
|
||||
self.elem3 = stubs.FakeWebElement(QRect(20, 150, 10, 10), self.iframe)
|
||||
self.elem4 = stubs.FakeWebElement(QRect(30, 180, 10, 10), self.frame)
|
||||
|
||||
def test_not_scrolled(self):
|
||||
"""Test base situation."""
|
||||
@ -210,17 +212,17 @@ class IsWritableTests(unittest.TestCase):
|
||||
|
||||
def test_writable(self):
|
||||
"""Test a normal element."""
|
||||
elem = FakeWebElement()
|
||||
elem = stubs.FakeWebElement()
|
||||
self.assertTrue(webelem.is_writable(elem))
|
||||
|
||||
def test_disabled(self):
|
||||
"""Test a disabled element."""
|
||||
elem = FakeWebElement(attributes=['disabled'])
|
||||
elem = stubs.FakeWebElement(attributes=['disabled'])
|
||||
self.assertFalse(webelem.is_writable(elem))
|
||||
|
||||
def test_readonly(self):
|
||||
"""Test a readonly element."""
|
||||
elem = FakeWebElement(attributes=['readonly'])
|
||||
elem = stubs.FakeWebElement(attributes=['readonly'])
|
||||
self.assertFalse(webelem.is_writable(elem))
|
||||
|
||||
|
||||
@ -252,7 +254,7 @@ class GetChildFramesTests(unittest.TestCase):
|
||||
|
||||
def test_single_frame(self):
|
||||
"""Test get_child_frames with a single frame without children."""
|
||||
frame = FakeChildrenFrame()
|
||||
frame = stubs.FakeChildrenFrame()
|
||||
children = webelem.get_child_frames(frame)
|
||||
self.assertEqual(len(children), 1)
|
||||
self.assertIs(children[0], frame)
|
||||
@ -265,9 +267,9 @@ class GetChildFramesTests(unittest.TestCase):
|
||||
/ \
|
||||
child1 o o child2
|
||||
"""
|
||||
child1 = FakeChildrenFrame()
|
||||
child2 = FakeChildrenFrame()
|
||||
parent = FakeChildrenFrame([child1, child2])
|
||||
child1 = stubs.FakeChildrenFrame()
|
||||
child2 = stubs.FakeChildrenFrame()
|
||||
parent = stubs.FakeChildrenFrame([child1, child2])
|
||||
children = webelem.get_child_frames(parent)
|
||||
self.assertEqual(len(children), 3)
|
||||
self.assertIs(children[0], parent)
|
||||
@ -286,10 +288,10 @@ class GetChildFramesTests(unittest.TestCase):
|
||||
/\ /\
|
||||
o o o o second
|
||||
"""
|
||||
second = [FakeChildrenFrame() for _ in range(4)]
|
||||
first = [FakeChildrenFrame(second[0:2]),
|
||||
FakeChildrenFrame(second[2:4])]
|
||||
root = FakeChildrenFrame(first)
|
||||
second = [stubs.FakeChildrenFrame() for _ in range(4)]
|
||||
first = [stubs.FakeChildrenFrame(second[0:2]),
|
||||
stubs.FakeChildrenFrame(second[2:4])]
|
||||
root = stubs.FakeChildrenFrame(first)
|
||||
children = webelem.get_child_frames(root)
|
||||
self.assertEqual(len(children), 7)
|
||||
self.assertIs(children[0], root)
|
||||
@ -307,175 +309,189 @@ class IsEditableTests(unittest.TestCase):
|
||||
|
||||
def test_input_plain(self):
|
||||
"""Test with plain input element."""
|
||||
elem = FakeWebElement(tagname='input')
|
||||
elem = stubs.FakeWebElement(tagname='input')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_text(self):
|
||||
"""Test with text input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'text'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'text'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_text_caps(self):
|
||||
"""Test with text input element with caps attributes."""
|
||||
elem = FakeWebElement(tagname='INPUT', attributes={'TYPE': 'TEXT'})
|
||||
elem = stubs.FakeWebElement(tagname='INPUT',
|
||||
attributes={'TYPE': 'TEXT'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_email(self):
|
||||
"""Test with email input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'email'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'email'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_url(self):
|
||||
"""Test with url input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'url'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'url'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_tel(self):
|
||||
"""Test with tel input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'tel'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'tel'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_number(self):
|
||||
"""Test with number input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'number'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'number'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_password(self):
|
||||
"""Test with password input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'password'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'password'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_search(self):
|
||||
"""Test with search input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'search'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'search'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_input_button(self):
|
||||
"""Button should not be editable."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'button'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'button'})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_input_checkbox(self):
|
||||
"""Checkbox should not be editable."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'type': 'checkbox'})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'type': 'checkbox'})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_textarea(self):
|
||||
"""Test textarea element."""
|
||||
elem = FakeWebElement(tagname='textarea')
|
||||
elem = stubs.FakeWebElement(tagname='textarea')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_select(self):
|
||||
"""Test selectbox."""
|
||||
elem = FakeWebElement(tagname='select')
|
||||
elem = stubs.FakeWebElement(tagname='select')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_input_disabled(self):
|
||||
"""Test disabled input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'disabled': None})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'disabled': None})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_input_readonly(self):
|
||||
"""Test readonly input element."""
|
||||
elem = FakeWebElement(tagname='input', attributes={'readonly': None})
|
||||
elem = stubs.FakeWebElement(tagname='input',
|
||||
attributes={'readonly': None})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_textarea_disabled(self):
|
||||
"""Test disabled textarea element."""
|
||||
elem = FakeWebElement(tagname='textarea',
|
||||
attributes={'disabled': None})
|
||||
elem = stubs.FakeWebElement(tagname='textarea',
|
||||
attributes={'disabled': None})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_textarea_readonly(self):
|
||||
"""Test readonly textarea element."""
|
||||
elem = FakeWebElement(tagname='textarea',
|
||||
attributes={'readonly': None})
|
||||
elem = stubs.FakeWebElement(tagname='textarea',
|
||||
attributes={'readonly': None})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_embed_true(self):
|
||||
"""Test embed-element with insert-mode-on-plugins true."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = FakeWebElement(tagname='embed')
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = stubs.FakeWebElement(tagname='embed')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_applet_true(self):
|
||||
"""Test applet-element with insert-mode-on-plugins true."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = FakeWebElement(tagname='applet')
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = stubs.FakeWebElement(tagname='applet')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_embed_false(self):
|
||||
"""Test embed-element with insert-mode-on-plugins false."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = FakeWebElement(tagname='embed')
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = stubs.FakeWebElement(tagname='embed')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_applet_false(self):
|
||||
"""Test applet-element with insert-mode-on-plugins false."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = FakeWebElement(tagname='applet')
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = stubs.FakeWebElement(tagname='applet')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_object_no_type(self):
|
||||
"""Test object-element without type."""
|
||||
elem = FakeWebElement(tagname='object')
|
||||
elem = stubs.FakeWebElement(tagname='object')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_object_image(self):
|
||||
"""Test object-element with image type."""
|
||||
elem = FakeWebElement(tagname='object',
|
||||
attributes={'type': 'image/gif'})
|
||||
elem = stubs.FakeWebElement(tagname='object',
|
||||
attributes={'type': 'image/gif'})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_object_application(self):
|
||||
"""Test object-element with application type."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = FakeWebElement(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = stubs.FakeWebElement(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_object_application_false(self):
|
||||
"""Test object-element with application type but not ...-on-plugins."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = FakeWebElement(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = stubs.FakeWebElement(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_object_classid(self):
|
||||
"""Test object-element with classid."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = FakeWebElement(tagname='object',
|
||||
attributes={'type': 'foo', 'classid': 'foo'})
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': True}})
|
||||
elem = stubs.FakeWebElement(tagname='object',
|
||||
attributes={'type': 'foo',
|
||||
'classid': 'foo'})
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_object_classid_false(self):
|
||||
"""Test object-element with classid but not insert-mode-on-plugins."""
|
||||
webelem.config = ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = FakeWebElement(tagname='object',
|
||||
attributes={'type': 'foo', 'classid': 'foo'})
|
||||
webelem.config = stubs.ConfigStub({'input':
|
||||
{'insert-mode-on-plugins': False}})
|
||||
elem = stubs.FakeWebElement(tagname='object',
|
||||
attributes={'type': 'foo',
|
||||
'classid': 'foo'})
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_div_empty(self):
|
||||
"""Test div-element without class."""
|
||||
elem = FakeWebElement(tagname='div')
|
||||
elem = stubs.FakeWebElement(tagname='div')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_div_noneditable(self):
|
||||
"""Test div-element with non-editableclass."""
|
||||
elem = FakeWebElement(tagname='div', classes='foo-kix-bar')
|
||||
elem = stubs.FakeWebElement(tagname='div', classes='foo-kix-bar')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_div_xik(self):
|
||||
"""Test div-element with xik class."""
|
||||
elem = FakeWebElement(tagname='div', classes='foo kix-foo')
|
||||
elem = stubs.FakeWebElement(tagname='div', classes='foo kix-foo')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
def test_div_xik_caps(self):
|
||||
@ -483,12 +499,13 @@ class IsEditableTests(unittest.TestCase):
|
||||
|
||||
This tests if classes are case sensitive as they should.
|
||||
"""
|
||||
elem = FakeWebElement(tagname='div', classes='KIX-FOO')
|
||||
elem = stubs.FakeWebElement(tagname='div', classes='KIX-FOO')
|
||||
self.assertFalse(webelem.is_editable(elem))
|
||||
|
||||
def test_div_codemirror(self):
|
||||
"""Test div-element with codemirror class."""
|
||||
elem = FakeWebElement(tagname='div', classes='foo CodeMirror-foo')
|
||||
elem = stubs.FakeWebElement(tagname='div',
|
||||
classes='foo CodeMirror-foo')
|
||||
self.assertTrue(webelem.is_editable(elem))
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
# FIXME: Add some more tests, e.g. for is_int
|
||||
|
||||
@ -35,7 +35,7 @@ class EnumTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.enum = enum('Enum', 'one', 'two')
|
||||
self.enum = usertypes.enum('Enum', 'one', 'two')
|
||||
|
||||
def test_values(self):
|
||||
"""Test if enum members resolve to the right values."""
|
||||
@ -54,7 +54,7 @@ class EnumTests(unittest.TestCase):
|
||||
|
||||
def test_start(self):
|
||||
"""Test the start= argument."""
|
||||
e = enum('Enum', 'three', 'four', start=3)
|
||||
e = usertypes.enum('Enum', 'three', 'four', start=3)
|
||||
self.assertEqual(e.three.value, 3)
|
||||
self.assertEqual(e.four.value, 4)
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from qutebrowser.utils.usertypes import NeighborList
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
|
||||
class InitTests(unittest.TestCase):
|
||||
@ -36,27 +36,27 @@ class InitTests(unittest.TestCase):
|
||||
|
||||
def test_empty(self):
|
||||
"""Test constructing an empty NeighborList."""
|
||||
nl = NeighborList()
|
||||
nl = usertypes.NeighborList()
|
||||
self.assertEqual(nl.items, [])
|
||||
|
||||
def test_items(self):
|
||||
"""Test constructing an NeighborList with items."""
|
||||
nl = NeighborList([1, 2, 3])
|
||||
nl = usertypes.NeighborList([1, 2, 3])
|
||||
self.assertEqual(nl.items, [1, 2, 3])
|
||||
|
||||
def test_len(self):
|
||||
"""Test len() on NeighborList."""
|
||||
nl = NeighborList([1, 2, 3])
|
||||
nl = usertypes.NeighborList([1, 2, 3])
|
||||
self.assertEqual(len(nl), 3)
|
||||
|
||||
def test_repr(self):
|
||||
"""Test repr() on NeighborList."""
|
||||
nl = NeighborList([1, 2, 3])
|
||||
nl = usertypes.NeighborList([1, 2, 3])
|
||||
self.assertEqual(repr(nl), 'NeighborList([1, 2, 3])')
|
||||
|
||||
def test_contains(self):
|
||||
"""Test 'in' on NeighborList."""
|
||||
nl = NeighborList([1, 2, 3])
|
||||
nl = usertypes.NeighborList([1, 2, 3])
|
||||
self.assertIn(2, nl)
|
||||
self.assertNotIn(4, nl)
|
||||
|
||||
@ -71,17 +71,17 @@ class DefaultTests(unittest.TestCase):
|
||||
|
||||
def test_simple(self):
|
||||
"""Test default with a numeric argument."""
|
||||
nl = NeighborList([1, 2, 3], default=2)
|
||||
nl = usertypes.NeighborList([1, 2, 3], default=2)
|
||||
self.assertEqual(nl.idx, 1)
|
||||
|
||||
def test_none(self):
|
||||
"""Test default 'None'."""
|
||||
nl = NeighborList([1, 2, None], default=None)
|
||||
nl = usertypes.NeighborList([1, 2, None], default=None)
|
||||
self.assertEqual(nl.idx, 2)
|
||||
|
||||
def test_unset(self):
|
||||
"""Test unset default value."""
|
||||
nl = NeighborList([1, 2, 3])
|
||||
nl = usertypes.NeighborList([1, 2, 3])
|
||||
self.assertIsNone(nl.idx)
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ class EmptyTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList()
|
||||
self.nl = usertypes.NeighborList()
|
||||
|
||||
def test_curitem(self):
|
||||
"""Test curitem with no item."""
|
||||
@ -126,7 +126,7 @@ class ItemTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([1, 2, 3, 4, 5], default=3)
|
||||
self.nl = usertypes.NeighborList([1, 2, 3, 4, 5], default=3)
|
||||
|
||||
def test_curitem(self):
|
||||
"""Test curitem()."""
|
||||
@ -183,11 +183,11 @@ class OneTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([1], default=1)
|
||||
self.nl = usertypes.NeighborList([1], default=1)
|
||||
|
||||
def test_first_wrap(self):
|
||||
"""Test out of bounds previtem() with mode=wrap."""
|
||||
self.nl._mode = NeighborList.Modes.wrap
|
||||
self.nl._mode = usertypes.NeighborList.Modes.wrap
|
||||
self.nl.firstitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
self.assertEqual(self.nl.previtem(), 1)
|
||||
@ -195,7 +195,7 @@ class OneTests(unittest.TestCase):
|
||||
|
||||
def test_first_block(self):
|
||||
"""Test out of bounds previtem() with mode=block."""
|
||||
self.nl._mode = NeighborList.Modes.block
|
||||
self.nl._mode = usertypes.NeighborList.Modes.block
|
||||
self.nl.firstitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
self.assertEqual(self.nl.previtem(), 1)
|
||||
@ -203,7 +203,7 @@ class OneTests(unittest.TestCase):
|
||||
|
||||
def test_first_raise(self):
|
||||
"""Test out of bounds previtem() with mode=raise."""
|
||||
self.nl._mode = NeighborList.Modes.exception
|
||||
self.nl._mode = usertypes.NeighborList.Modes.exception
|
||||
self.nl.firstitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
with self.assertRaises(IndexError):
|
||||
@ -212,7 +212,7 @@ class OneTests(unittest.TestCase):
|
||||
|
||||
def test_last_wrap(self):
|
||||
"""Test out of bounds nextitem() with mode=wrap."""
|
||||
self.nl._mode = NeighborList.Modes.wrap
|
||||
self.nl._mode = usertypes.NeighborList.Modes.wrap
|
||||
self.nl.lastitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
self.assertEqual(self.nl.nextitem(), 1)
|
||||
@ -220,7 +220,7 @@ class OneTests(unittest.TestCase):
|
||||
|
||||
def test_last_block(self):
|
||||
"""Test out of bounds nextitem() with mode=block."""
|
||||
self.nl._mode = NeighborList.Modes.block
|
||||
self.nl._mode = usertypes.NeighborList.Modes.block
|
||||
self.nl.lastitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
self.assertEqual(self.nl.nextitem(), 1)
|
||||
@ -228,7 +228,7 @@ class OneTests(unittest.TestCase):
|
||||
|
||||
def test_last_raise(self):
|
||||
"""Test out of bounds nextitem() with mode=raise."""
|
||||
self.nl._mode = NeighborList.Modes.exception
|
||||
self.nl._mode = usertypes.NeighborList.Modes.exception
|
||||
self.nl.lastitem()
|
||||
self.assertEqual(self.nl.idx, 0)
|
||||
with self.assertRaises(IndexError):
|
||||
@ -245,8 +245,9 @@ class BlockTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([1, 2, 3, 4, 5], default=3,
|
||||
mode=NeighborList.Modes.block)
|
||||
self.nl = usertypes.NeighborList(
|
||||
[1, 2, 3, 4, 5], default=3,
|
||||
mode=usertypes.NeighborList.Modes.block)
|
||||
|
||||
def test_first(self):
|
||||
"""Test ouf of bounds previtem()."""
|
||||
@ -272,8 +273,8 @@ class WrapTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([1, 2, 3, 4, 5], default=3,
|
||||
mode=NeighborList.Modes.wrap)
|
||||
self.nl = usertypes.NeighborList(
|
||||
[1, 2, 3, 4, 5], default=3, mode=usertypes.NeighborList.Modes.wrap)
|
||||
|
||||
def test_first(self):
|
||||
"""Test ouf of bounds previtem()."""
|
||||
@ -299,8 +300,9 @@ class RaiseTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([1, 2, 3, 4, 5], default=3,
|
||||
mode=NeighborList.Modes.exception)
|
||||
self.nl = usertypes.NeighborList(
|
||||
[1, 2, 3, 4, 5], default=3,
|
||||
mode=usertypes.NeighborList.Modes.exception)
|
||||
|
||||
def test_first(self):
|
||||
"""Test ouf of bounds previtem()."""
|
||||
@ -328,7 +330,7 @@ class SnapInTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.nl = NeighborList([20, 9, 1, 5])
|
||||
self.nl = usertypes.NeighborList([20, 9, 1, 5])
|
||||
|
||||
def test_bigger(self):
|
||||
"""Test fuzzyval with snapping to a bigger value."""
|
||||
|
@ -21,15 +21,12 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.config.configdata as configdata
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.config import config, configdata
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import completion as logger
|
||||
from qutebrowser.models import completion as models
|
||||
from qutebrowser.models.completionfilter import CompletionFilterModel as CFM
|
||||
from qutebrowser.models.completion import (
|
||||
CommandCompletionModel, SettingSectionCompletionModel,
|
||||
SettingOptionCompletionModel, SettingValueCompletionModel)
|
||||
from qutebrowser.utils.usertypes import Completion
|
||||
|
||||
|
||||
class Completer(QObject):
|
||||
@ -58,31 +55,32 @@ class Completer(QObject):
|
||||
self.ignore_change = False
|
||||
|
||||
self._models = {
|
||||
Completion.option: {},
|
||||
Completion.value: {},
|
||||
usertypes.Completion.option: {},
|
||||
usertypes.Completion.value: {},
|
||||
}
|
||||
self._init_command_completion()
|
||||
self._init_setting_completions()
|
||||
|
||||
def _init_command_completion(self):
|
||||
"""Initialize the command completion model."""
|
||||
self._models[Completion.command] = CFM(
|
||||
CommandCompletionModel(self), self)
|
||||
self._models[usertypes.Completion.command] = CFM(
|
||||
models.CommandCompletionModel(self), self)
|
||||
|
||||
def _init_setting_completions(self):
|
||||
"""Initialize setting completion models."""
|
||||
self._models[Completion.section] = CFM(
|
||||
SettingSectionCompletionModel(self), self)
|
||||
self._models[Completion.option] = {}
|
||||
self._models[Completion.value] = {}
|
||||
self._models[usertypes.Completion.section] = CFM(
|
||||
models.SettingSectionCompletionModel(self), self)
|
||||
self._models[usertypes.Completion.option] = {}
|
||||
self._models[usertypes.Completion.value] = {}
|
||||
for sectname in configdata.DATA:
|
||||
model = SettingOptionCompletionModel(sectname, self)
|
||||
self._models[Completion.option][sectname] = CFM(model, self)
|
||||
model = models.SettingOptionCompletionModel(sectname, self)
|
||||
self._models[usertypes.Completion.option][sectname] = CFM(
|
||||
model, self)
|
||||
config.instance().changed.connect(model.on_config_changed)
|
||||
self._models[Completion.value][sectname] = {}
|
||||
self._models[usertypes.Completion.value][sectname] = {}
|
||||
for opt in configdata.DATA[sectname].keys():
|
||||
model = SettingValueCompletionModel(sectname, opt, self)
|
||||
self._models[Completion.value][sectname][opt] = CFM(
|
||||
model = models.SettingValueCompletionModel(sectname, opt, self)
|
||||
self._models[usertypes.Completion.value][sectname][opt] = CFM(
|
||||
model, self)
|
||||
config.instance().changed.connect(model.on_config_changed)
|
||||
|
||||
@ -95,7 +93,7 @@ class Completer(QObject):
|
||||
"""
|
||||
if cursor_part == 0:
|
||||
# '|' or 'set|'
|
||||
return self._models[Completion.command]
|
||||
return self._models[usertypes.Completion.command]
|
||||
# delegate completion to command
|
||||
try:
|
||||
completions = cmdutils.cmd_dict[parts[0]].completion
|
||||
@ -115,10 +113,10 @@ class Completer(QObject):
|
||||
return None
|
||||
dbg_completions[idx] = '*' + dbg_completions[idx] + '*'
|
||||
logger.debug("completions: {}".format(', '.join(dbg_completions)))
|
||||
if completion == Completion.option:
|
||||
if completion == usertypes.Completion.option:
|
||||
section = parts[cursor_part - 1]
|
||||
model = self._models[completion].get(section)
|
||||
elif completion == Completion.value:
|
||||
elif completion == usertypes.Completion.value:
|
||||
section = parts[cursor_part - 2]
|
||||
option = parts[cursor_part - 1]
|
||||
try:
|
||||
|
@ -23,13 +23,13 @@ import re
|
||||
import pdb
|
||||
import sys
|
||||
import types
|
||||
from functools import wraps
|
||||
import functools
|
||||
|
||||
from PyQt5.QtCore import pyqtRemoveInputHook, QEvent, QCoreApplication
|
||||
|
||||
from qutebrowser.utils.misc import elide, compact_text
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
|
||||
|
||||
@cmdutils.register(debug=True, name='debug-set-trace')
|
||||
@ -89,7 +89,7 @@ def log_events(klass):
|
||||
"""Class decorator to log Qt events."""
|
||||
old_event = klass.event
|
||||
|
||||
@wraps(old_event)
|
||||
@functools.wraps(old_event)
|
||||
def new_event(self, e, *args, **kwargs):
|
||||
"""Wrapper for event() which logs events."""
|
||||
logger.debug("Event in {}: {}".format(klass.__name__,
|
||||
@ -115,7 +115,7 @@ def trace_lines(do_trace):
|
||||
if sys is not None:
|
||||
loc = '{}:{}'.format(frame.f_code.co_filename, frame.f_lineno)
|
||||
if arg is not None:
|
||||
arg = compact_text(str(arg), 200)
|
||||
arg = utils.compact_text(str(arg), 200)
|
||||
else:
|
||||
arg = ''
|
||||
print("{:11} {:80} {}".format(event, loc, arg), file=sys.stderr)
|
||||
@ -228,5 +228,6 @@ def dbg_signal(sig, args):
|
||||
Return:
|
||||
A human-readable string representation of signal/args.
|
||||
"""
|
||||
argstr = ', '.join([elide(str(a).replace('\n', ' '), 20) for a in args])
|
||||
argstr = ', '.join([utils.elide(str(a).replace('\n', ' '), 20)
|
||||
for a in args])
|
||||
return '{}({})'.format(signal_name(sig), argstr)
|
||||
|
@ -26,9 +26,9 @@ import faulthandler
|
||||
import traceback
|
||||
import signal
|
||||
try:
|
||||
from tkinter import Tk, messagebox # pylint: disable=import-error
|
||||
import tkinter # pylint: disable=import-error
|
||||
except ImportError:
|
||||
Tk = None
|
||||
tkinter = None
|
||||
|
||||
|
||||
def _missing_str(name, debian=None, arch=None, windows=None, pip=None):
|
||||
@ -186,10 +186,10 @@ def check_pyqt_core():
|
||||
text = text.replace('<b>', '')
|
||||
text = text.replace('</b>', '')
|
||||
text = text.replace('<br />', '\n')
|
||||
if Tk:
|
||||
root = Tk()
|
||||
if tkinter:
|
||||
root = tkinter.Tk()
|
||||
root.withdraw()
|
||||
messagebox.showerror("qutebrowser: Fatal error!", text)
|
||||
tkinter.messagebox.showerror("qutebrowser: Fatal error!", text)
|
||||
else:
|
||||
print(text, file=sys.stderr)
|
||||
if '--debug' in sys.argv:
|
||||
|
@ -20,12 +20,12 @@
|
||||
"""Launcher for an external editor."""
|
||||
|
||||
import os
|
||||
from tempfile import mkstemp
|
||||
import tempfile
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QProcess, QObject
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import message
|
||||
from qutebrowser.utils.log import procs as logger
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ class ExternalEditor(QObject):
|
||||
if self.text is not None:
|
||||
raise ValueError("Already editing a file!")
|
||||
self.text = text
|
||||
self.oshandle, self.filename = mkstemp(text=True)
|
||||
self.oshandle, self.filename = tempfile.mkstemp(text=True)
|
||||
if text:
|
||||
encoding = config.get('general', 'editor-encoding')
|
||||
with open(self.filename, 'w', encoding=encoding) as f:
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
import os.path
|
||||
import qutebrowser.utils.rfc6266 as rfc6266
|
||||
from qutebrowser.utils import rfc6266
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkRequest
|
||||
|
@ -24,9 +24,8 @@ import os
|
||||
import sys
|
||||
import html as pyhtml
|
||||
import logging
|
||||
from contextlib import contextmanager
|
||||
from logging import getLogger
|
||||
from collections import deque
|
||||
import contextlib
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import (QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg,
|
||||
qInstallMessageHandler)
|
||||
@ -38,9 +37,9 @@ except ImportError:
|
||||
colorama = None
|
||||
try:
|
||||
# pylint: disable=import-error
|
||||
from colorlog import ColoredFormatter
|
||||
import colorlog
|
||||
except ImportError:
|
||||
ColoredFormatter = None
|
||||
colorlog = None
|
||||
else:
|
||||
# colorlog calls colorama.init() which we don't want, also it breaks our
|
||||
# sys.stdout/sys.stderr if they are None. Bugreports:
|
||||
@ -81,25 +80,25 @@ LOG_COLORS = {
|
||||
|
||||
# The different loggers used.
|
||||
|
||||
statusbar = getLogger('statusbar')
|
||||
completion = getLogger('completion')
|
||||
destroy = getLogger('destroy')
|
||||
modes = getLogger('modes')
|
||||
webview = getLogger('webview')
|
||||
mouse = getLogger('mouse')
|
||||
misc = getLogger('misc')
|
||||
url = getLogger('url')
|
||||
procs = getLogger('procs')
|
||||
commands = getLogger('commands')
|
||||
init = getLogger('init')
|
||||
signals = getLogger('signals')
|
||||
hints = getLogger('hints')
|
||||
keyboard = getLogger('keyboard')
|
||||
downloads = getLogger('downloads')
|
||||
js = getLogger('js') # Javascript console messages
|
||||
qt = getLogger('qt') # Warnings produced by Qt
|
||||
style = getLogger('style')
|
||||
rfc6266 = getLogger('rfc6266')
|
||||
statusbar = logging.getLogger('statusbar')
|
||||
completion = logging.getLogger('completion')
|
||||
destroy = logging.getLogger('destroy')
|
||||
modes = logging.getLogger('modes')
|
||||
webview = logging.getLogger('webview')
|
||||
mouse = logging.getLogger('mouse')
|
||||
misc = logging.getLogger('misc')
|
||||
url = logging.getLogger('url')
|
||||
procs = logging.getLogger('procs')
|
||||
commands = logging.getLogger('commands')
|
||||
init = logging.getLogger('init')
|
||||
signals = logging.getLogger('signals')
|
||||
hints = logging.getLogger('hints')
|
||||
keyboard = logging.getLogger('keyboard')
|
||||
downloads = logging.getLogger('downloads')
|
||||
js = logging.getLogger('js') # Javascript console messages
|
||||
qt = logging.getLogger('qt') # Warnings produced by Qt
|
||||
style = logging.getLogger('style')
|
||||
rfc6266 = logging.getLogger('rfc6266')
|
||||
|
||||
|
||||
ram_handler = None
|
||||
@ -114,7 +113,7 @@ def init_log(args):
|
||||
raise ValueError("Invalid log level: {}".format(args.loglevel))
|
||||
|
||||
console, ram = _init_handlers(numeric_level, args.color, args.loglines)
|
||||
root = getLogger()
|
||||
root = logging.getLogger()
|
||||
if console is not None:
|
||||
if args.logfilter is not None:
|
||||
console.addFilter(LogFilter(args.logfilter.split(',')))
|
||||
@ -126,7 +125,7 @@ def init_log(args):
|
||||
qInstallMessageHandler(qt_message_handler)
|
||||
|
||||
|
||||
@contextmanager
|
||||
@contextlib.contextmanager
|
||||
def disable_qt_msghandler():
|
||||
"""Contextmanager which temporarely disables the Qt message handler."""
|
||||
old_handler = qInstallMessageHandler(None)
|
||||
@ -191,10 +190,10 @@ def _init_formatters(level, color):
|
||||
if sys.stderr is None:
|
||||
return None, ram_formatter, html_formatter, False
|
||||
use_colorama = False
|
||||
if (ColoredFormatter is not None and (os.name == 'posix' or colorama) and
|
||||
if (colorlog is not None and (os.name == 'posix' or colorama) and
|
||||
sys.stderr.isatty() and color):
|
||||
console_formatter = ColoredFormatter(console_fmt_colored, DATEFMT,
|
||||
log_colors=LOG_COLORS)
|
||||
console_formatter = colorlog.ColoredFormatter(
|
||||
console_fmt_colored, DATEFMT, log_colors=LOG_COLORS)
|
||||
if colorama:
|
||||
use_colorama = True
|
||||
else:
|
||||
@ -310,9 +309,9 @@ class RAMHandler(logging.Handler):
|
||||
super().__init__()
|
||||
self.html_formatter = None
|
||||
if capacity != -1:
|
||||
self.data = deque(maxlen=capacity)
|
||||
self.data = collections.deque(maxlen=capacity)
|
||||
else:
|
||||
self.data = deque()
|
||||
self.data = collections.deque()
|
||||
|
||||
def emit(self, record):
|
||||
self.data.append(record)
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QTimer
|
||||
|
||||
from qutebrowser.utils.usertypes import PromptMode, Question
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ def ask(message, mode, default=None):
|
||||
Return:
|
||||
The answer the user gave or None if the prompt was cancelled.
|
||||
"""
|
||||
q = Question()
|
||||
q = usertypes.Question()
|
||||
q.text = message
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
@ -75,9 +75,9 @@ def ask(message, mode, default=None):
|
||||
|
||||
def alert(message):
|
||||
"""Display an alert which needs to be confirmed."""
|
||||
q = Question()
|
||||
q = usertypes.Question()
|
||||
q.text = message
|
||||
q.mode = PromptMode.alert
|
||||
q.mode = usertypes.PromptMode.alert
|
||||
instance().ask(q, blocking=True)
|
||||
q.deleteLater()
|
||||
|
||||
@ -91,10 +91,10 @@ def ask_async(message, mode, handler, default=None):
|
||||
handler: The function to get called with the answer as argument.
|
||||
default: The default value to display.
|
||||
"""
|
||||
if not isinstance(mode, PromptMode):
|
||||
if not isinstance(mode, usertypes.PromptMode):
|
||||
raise TypeError("Mode {} is no PromptMode member!".format(mode))
|
||||
bridge = instance()
|
||||
q = Question(bridge)
|
||||
q = usertypes.Question(bridge)
|
||||
q.text = message
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
@ -113,9 +113,9 @@ def confirm_async(message, yes_action, no_action=None, default=None):
|
||||
default: True/False to set a default value, or None.
|
||||
"""
|
||||
bridge = instance()
|
||||
q = Question(bridge)
|
||||
q = usertypes.Question(bridge)
|
||||
q.text = message
|
||||
q.mode = PromptMode.yesno
|
||||
q.mode = usertypes.PromptMode.yesno
|
||||
q.default = default
|
||||
q.answered_yes.connect(yes_action)
|
||||
if no_action is not None:
|
||||
@ -152,7 +152,7 @@ class MessageBridge(QObject):
|
||||
s_info = pyqtSignal(str, bool)
|
||||
s_set_text = pyqtSignal(str)
|
||||
s_set_cmd_text = pyqtSignal(str)
|
||||
s_question = pyqtSignal(Question, bool)
|
||||
s_question = pyqtSignal(usertypes.Question, bool)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{}>'.format(self.__class__.__name__)
|
||||
|
@ -25,17 +25,17 @@ import sys
|
||||
import shlex
|
||||
import os.path
|
||||
import urllib.request
|
||||
from urllib.parse import urljoin, urlencode
|
||||
from collections import OrderedDict
|
||||
from functools import reduce
|
||||
from contextlib import contextmanager
|
||||
import urllib.parse
|
||||
import collections
|
||||
import functools
|
||||
import contextlib
|
||||
|
||||
from PyQt5.QtCore import QCoreApplication, QStandardPaths, Qt
|
||||
from PyQt5.QtGui import QKeySequence, QColor
|
||||
from pkg_resources import resource_string
|
||||
import pkg_resources
|
||||
|
||||
import qutebrowser
|
||||
from qutebrowser.utils.qt import qt_version_check, qt_ensure_valid
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
def elide(text, length):
|
||||
@ -81,7 +81,8 @@ def read_file(filename):
|
||||
with open(fn, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
else:
|
||||
return resource_string(qutebrowser.__name__, filename).decode('UTF-8')
|
||||
data = pkg_resources.resource_string(qutebrowser.__name__, filename)
|
||||
return data.decode('UTF-8')
|
||||
|
||||
|
||||
def dotted_getattr(obj, path):
|
||||
@ -94,7 +95,7 @@ def dotted_getattr(obj, path):
|
||||
Return:
|
||||
The object at path.
|
||||
"""
|
||||
return reduce(getattr, path.split('.'), obj)
|
||||
return functools.reduce(getattr, path.split('.'), obj)
|
||||
|
||||
|
||||
def safe_shlex_split(s):
|
||||
@ -134,8 +135,8 @@ def pastebin(text):
|
||||
'title': "qutebrowser crash",
|
||||
'name': "qutebrowser",
|
||||
}
|
||||
encoded_data = urlencode(data).encode('utf-8')
|
||||
create_url = urljoin(api_url, 'create')
|
||||
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
|
||||
create_url = urllib.parse.urljoin(api_url, 'create')
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
|
||||
}
|
||||
@ -189,7 +190,7 @@ def actute_warning():
|
||||
return
|
||||
# Qt >= 5.3 doesn't seem to be affected
|
||||
try:
|
||||
if qt_version_check('5.3.0'):
|
||||
if qtutils.qt_version_check('5.3.0'):
|
||||
return
|
||||
except ValueError:
|
||||
pass
|
||||
@ -246,8 +247,8 @@ def interpolate_color(start, end, percent, colorspace=QColor.Rgb):
|
||||
Raise:
|
||||
ValueError if invalid parameters are passed.
|
||||
"""
|
||||
qt_ensure_valid(start)
|
||||
qt_ensure_valid(end)
|
||||
qtutils.qt_ensure_valid(start)
|
||||
qtutils.qt_ensure_valid(end)
|
||||
out = QColor()
|
||||
if colorspace == QColor.Rgb:
|
||||
a_c1, a_c2, a_c3, _alpha = start.getRgb()
|
||||
@ -270,7 +271,7 @@ def interpolate_color(start, end, percent, colorspace=QColor.Rgb):
|
||||
else:
|
||||
raise ValueError("Invalid colorspace!")
|
||||
out = out.convertTo(start.spec())
|
||||
qt_ensure_valid(out)
|
||||
qtutils.qt_ensure_valid(out)
|
||||
return out
|
||||
|
||||
|
||||
@ -400,7 +401,7 @@ def keyevent_to_string(e):
|
||||
A name of the key (combination) as a string or
|
||||
None if only modifiers are pressed..
|
||||
"""
|
||||
modmask2str = OrderedDict([
|
||||
modmask2str = collections.OrderedDict([
|
||||
(Qt.ControlModifier, 'Ctrl'),
|
||||
(Qt.AltModifier, 'Alt'),
|
||||
(Qt.MetaModifier, 'Meta'),
|
||||
@ -460,7 +461,7 @@ class FakeIOStream(io.TextIOBase):
|
||||
return super().isatty()
|
||||
|
||||
|
||||
@contextmanager
|
||||
@contextlib.contextmanager
|
||||
def fake_io(write_func):
|
||||
"""Run code with stdout and stderr replaced by FakeIOStreams.
|
||||
|
||||
@ -482,7 +483,7 @@ def fake_io(write_func):
|
||||
sys.stderr = old_stderr
|
||||
|
||||
|
||||
@contextmanager
|
||||
@contextlib.contextmanager
|
||||
def disabled_excepthook():
|
||||
"""Run code with the exception hook temporarely disabled."""
|
||||
old_excepthook = sys.excepthook
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QLineEdit
|
||||
|
||||
import qutebrowser.commands.utils as cmd
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.utils import usertypes as typ
|
||||
|
||||
|
||||
class ReadlineBridge:
|
||||
@ -45,8 +45,8 @@ class ReadlineBridge:
|
||||
else:
|
||||
return None
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_backward_char(self):
|
||||
"""Move back a character.
|
||||
|
||||
@ -56,8 +56,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.cursorBackward(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_forward_char(self):
|
||||
"""Move forward a character.
|
||||
|
||||
@ -67,8 +67,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.cursorForward(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_backward_word(self):
|
||||
"""Move back to the start of the current or previous word.
|
||||
|
||||
@ -78,8 +78,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.cursorWordBackward(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_forward_word(self):
|
||||
"""Move forward to the end of the next word.
|
||||
|
||||
@ -89,8 +89,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.cursorWordForward(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_beginning_of_line(self):
|
||||
"""Move to the start of the line.
|
||||
|
||||
@ -100,8 +100,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.home(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_end_of_line(self):
|
||||
"""Move to the end of the line.
|
||||
|
||||
@ -111,8 +111,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.end(False)
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_unix_line_discard(self):
|
||||
"""Remove chars backward from the cursor to the beginning of the line.
|
||||
|
||||
@ -124,8 +124,8 @@ class ReadlineBridge:
|
||||
self.deleted[self.widget] = self.widget.selectedText()
|
||||
self.widget.del_()
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_kill_line(self):
|
||||
"""Remove chars from the cursor to the end of the line.
|
||||
|
||||
@ -137,8 +137,8 @@ class ReadlineBridge:
|
||||
self.deleted[self.widget] = self.widget.selectedText()
|
||||
self.widget.del_()
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_unix_word_rubout(self):
|
||||
"""Remove chars from the cursor to the beginning of the word.
|
||||
|
||||
@ -150,8 +150,8 @@ class ReadlineBridge:
|
||||
self.deleted[self.widget] = self.widget.selectedText()
|
||||
self.widget.del_()
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_kill_word(self):
|
||||
"""Remove chars from the cursor to the end of the current word.
|
||||
|
||||
@ -163,8 +163,8 @@ class ReadlineBridge:
|
||||
self.deleted[self.widget] = self.widget.selectedText()
|
||||
self.widget.del_()
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_yank(self):
|
||||
"""Paste the most recently deleted text.
|
||||
|
||||
@ -174,8 +174,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.insert(self.deleted[self.widget])
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_delete_char(self):
|
||||
"""Delete the character after the cursor.
|
||||
|
||||
@ -185,8 +185,8 @@ class ReadlineBridge:
|
||||
return
|
||||
self.widget.del_()
|
||||
|
||||
@cmd.register(instance='rl_bridge', hide=True,
|
||||
modes=[KeyMode.command, KeyMode.prompt])
|
||||
@cmdutils.register(instance='rl_bridge', hide=True,
|
||||
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
|
||||
def rl_backward_delete_char(self):
|
||||
"""Delete the character before the cursor.
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
"""pyPEG parsing for the RFC 6266 (Content-Disposition) header. """
|
||||
|
||||
from collections import namedtuple
|
||||
import collections
|
||||
import urllib.parse
|
||||
import string
|
||||
import re
|
||||
@ -209,7 +209,7 @@ class ContentDispositionValue:
|
||||
peg.optional(';'))
|
||||
|
||||
|
||||
LangTagged = namedtuple('LangTagged', 'string langtag')
|
||||
LangTagged = collections.namedtuple('LangTagged', 'string langtag')
|
||||
|
||||
|
||||
class DuplicateParamError(Exception):
|
||||
|
@ -26,9 +26,9 @@ import urllib.parse
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtNetwork import QHostInfo
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import url as logger
|
||||
from qutebrowser.utils.misc import qt_ensure_valid
|
||||
|
||||
|
||||
# FIXME: we probably could raise some exceptions on invalid URLs
|
||||
@ -65,7 +65,7 @@ def _get_search_url(txt):
|
||||
if not term:
|
||||
raise FuzzyUrlError("No search term given")
|
||||
url = QUrl.fromUserInput(template.format(urllib.parse.quote(term)))
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
return url
|
||||
|
||||
|
||||
@ -143,7 +143,7 @@ def fuzzy_url(urlstr):
|
||||
url = QUrl.fromUserInput(stripped)
|
||||
logger.debug("Converting fuzzy term {} to URL -> {}".format(
|
||||
urlstr, url.toDisplayString()))
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
return url
|
||||
|
||||
|
||||
|
@ -29,8 +29,8 @@ import enum as pyenum
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QObject, QTimer
|
||||
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
from qutebrowser.utils.qt import check_overflow
|
||||
|
||||
|
||||
_UNSET = object()
|
||||
@ -372,13 +372,13 @@ class Timer(QTimer):
|
||||
|
||||
def setInterval(self, msec):
|
||||
"""Extend setInterval to check for overflows."""
|
||||
check_overflow(msec, 'int')
|
||||
qtutils.check_overflow(msec, 'int')
|
||||
super().setInterval(msec)
|
||||
|
||||
def start(self, msec=None):
|
||||
"""Extend start to check for overflows."""
|
||||
if msec is not None:
|
||||
check_overflow(msec, 'int')
|
||||
qtutils.check_overflow(msec, 'int')
|
||||
super().start(msec)
|
||||
else:
|
||||
super().start()
|
||||
|
@ -21,10 +21,10 @@
|
||||
|
||||
from functools import partial
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.utils.usertypes import Timer
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.commands.runners import CommandRunner
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.commands import runners
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
|
||||
|
||||
_timers = []
|
||||
@ -34,7 +34,7 @@ _commandrunner = None
|
||||
def init():
|
||||
"""Initialize the global _commandrunner."""
|
||||
global _commandrunner
|
||||
_commandrunner = CommandRunner()
|
||||
_commandrunner = runners.CommandRunner()
|
||||
|
||||
|
||||
@cmdutils.register(nargs=(2, None))
|
||||
@ -46,15 +46,15 @@ def later(ms, *command):
|
||||
command: The command/args to run.
|
||||
"""
|
||||
ms = int(ms)
|
||||
timer = Timer(name='later')
|
||||
timer = usertypes.Timer(name='later')
|
||||
timer.setSingleShot(True)
|
||||
if ms < 0:
|
||||
raise CommandError("I can't run something in the past!")
|
||||
raise cmdexc.CommandError("I can't run something in the past!")
|
||||
try:
|
||||
timer.setInterval(ms)
|
||||
except OverflowError:
|
||||
raise CommandError("Numeric argument is too large for internal int "
|
||||
"representation.")
|
||||
raise cmdexc.CommandError("Numeric argument is too large for internal "
|
||||
"int representation.")
|
||||
_timers.append(timer)
|
||||
cmdline = ' '.join(command)
|
||||
timer.timeout.connect(partial(_commandrunner.run_safely, cmdline))
|
||||
|
@ -29,7 +29,7 @@ from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, qVersion
|
||||
from PyQt5.QtWebKit import qWebKitVersion
|
||||
|
||||
import qutebrowser
|
||||
from qutebrowser.utils.misc import read_file
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils.log import misc as logger
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ def _git_str():
|
||||
return commit
|
||||
# If that fails, check the git-commit-id file.
|
||||
try:
|
||||
return read_file('git-commit-id')
|
||||
return utils.read_file('git-commit-id')
|
||||
except (FileNotFoundError, ImportError):
|
||||
return None
|
||||
|
||||
|
@ -30,13 +30,13 @@ Module attributes:
|
||||
from PyQt5.QtCore import QRect, QUrl
|
||||
from PyQt5.QtWebKit import QWebElement
|
||||
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.utils.misc import compact_text
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import log, usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
|
||||
|
||||
Group = enum('Group', 'all', 'links', 'images', 'url', 'prevnext', 'focus')
|
||||
Group = usertypes.enum('Group', 'all', 'links', 'images', 'url', 'prevnext',
|
||||
'focus')
|
||||
|
||||
|
||||
SELECTORS = {
|
||||
@ -284,4 +284,4 @@ def focus_elem(frame):
|
||||
|
||||
def debug_text(elem):
|
||||
"""Get a text based on an element suitable for debug output."""
|
||||
return compact_text(elem.toOuterXml(), 500)
|
||||
return utils.compact_text(elem.toOuterXml(), 500)
|
||||
|
@ -26,13 +26,11 @@ subclasses to provide completions.
|
||||
from PyQt5.QtWidgets import QStyle, QTreeView, QSizePolicy
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.widgets.completiondelegate import CompletionItemDelegate
|
||||
from qutebrowser.config.style import set_register_stylesheet
|
||||
from qutebrowser.utils.completer import Completer
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.config import config, style
|
||||
from qutebrowser.widgets import completiondelegate
|
||||
from qutebrowser.utils import completer, usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class CompletionView(QTreeView):
|
||||
@ -94,12 +92,12 @@ class CompletionView(QTreeView):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.completer = Completer(self)
|
||||
self.completer = completer.Completer(self)
|
||||
self.enabled = config.get('completion', 'show')
|
||||
|
||||
self._delegate = CompletionItemDelegate(self)
|
||||
self._delegate = completiondelegate.CompletionItemDelegate(self)
|
||||
self.setItemDelegate(self._delegate)
|
||||
set_register_stylesheet(self)
|
||||
style.set_register_stylesheet(self)
|
||||
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
|
||||
self.setHeaderHidden(True)
|
||||
self.setIndentation(0)
|
||||
@ -169,7 +167,7 @@ class CompletionView(QTreeView):
|
||||
# No completion running at the moment, ignore keypress
|
||||
return
|
||||
idx = self._next_idx(prev)
|
||||
qt_ensure_valid(idx)
|
||||
qtutils.qt_ensure_valid(idx)
|
||||
self.selectionModel().setCurrentIndex(
|
||||
idx, QItemSelectionModel.ClearAndSelect |
|
||||
QItemSelectionModel.Rows)
|
||||
@ -212,13 +210,13 @@ class CompletionView(QTreeView):
|
||||
selmod.clearCurrentIndex()
|
||||
|
||||
@cmdutils.register(instance='mainwindow.completion', hide=True,
|
||||
modes=[KeyMode.command])
|
||||
modes=[usertypes.KeyMode.command])
|
||||
def completion_item_prev(self):
|
||||
"""Select the previous completion item."""
|
||||
self._next_prev_item(prev=True)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.completion', hide=True,
|
||||
modes=[KeyMode.command])
|
||||
modes=[usertypes.KeyMode.command])
|
||||
def completion_item_next(self):
|
||||
"""Select the next completion item."""
|
||||
self._next_prev_item(prev=False)
|
||||
|
@ -28,10 +28,9 @@ from PyQt5.QtCore import QRectF, QSize, Qt
|
||||
from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
|
||||
QTextCursor, QAbstractTextDocumentLayout)
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.models.basecompletion import Role
|
||||
from qutebrowser.config.style import get_stylesheet
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.config import config, style
|
||||
from qutebrowser.models import basecompletion
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class CompletionItemDelegate(QStyledItemDelegate):
|
||||
@ -99,12 +98,12 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
||||
|
||||
text_rect_ = self._style.subElementRect(
|
||||
self._style.SE_ItemViewItemText, self._opt, self._opt.widget)
|
||||
qt_ensure_valid(text_rect_)
|
||||
qtutils.qt_ensure_valid(text_rect_)
|
||||
margin = self._style.pixelMetric(QStyle.PM_FocusFrameHMargin,
|
||||
self._opt, self._opt.widget) + 1
|
||||
# remove width padding
|
||||
text_rect = text_rect_.adjusted(margin, 0, -margin, 0)
|
||||
qt_ensure_valid(text_rect)
|
||||
qtutils.qt_ensure_valid(text_rect)
|
||||
# move text upwards a bit
|
||||
if index.parent().isValid():
|
||||
text_rect.adjust(0, -1, 0, -1)
|
||||
@ -189,7 +188,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
||||
self._doc.setHtml('<b>{}</b>'.format(html.escape(self._opt.text)))
|
||||
self._doc.setDefaultFont(self._opt.font)
|
||||
self._doc.setDefaultTextOption(text_option)
|
||||
self._doc.setDefaultStyleSheet(get_stylesheet("""
|
||||
self._doc.setDefaultStyleSheet(style.get_stylesheet("""
|
||||
.highlight {{
|
||||
{color[completion.match.fg]}
|
||||
}}
|
||||
@ -197,7 +196,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
||||
self._doc.setDocumentMargin(2)
|
||||
|
||||
if index.column() == 0:
|
||||
marks = index.data(Role.marks)
|
||||
marks = index.data(basecompletion.Role.marks)
|
||||
if marks is None:
|
||||
return
|
||||
for mark in marks:
|
||||
@ -218,7 +217,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
||||
o.rect = self._style.subElementRect(
|
||||
self._style.SE_ItemViewItemFocusRect, self._opt, self._opt.widget)
|
||||
o.state |= QStyle.State_KeyboardFocusChange | QStyle.State_Item
|
||||
qt_ensure_valid(o.rect)
|
||||
qtutils.qt_ensure_valid(o.rect)
|
||||
if state & QStyle.State_Enabled:
|
||||
cg = QPalette.Normal
|
||||
else:
|
||||
@ -254,7 +253,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
|
||||
docsize = self._doc.size().toSize()
|
||||
size = self._style.sizeFromContents(QStyle.CT_ItemViewItem, self._opt,
|
||||
docsize, self._opt.widget)
|
||||
qt_ensure_valid(size)
|
||||
qtutils.qt_ensure_valid(size)
|
||||
return size + QSize(10, 3)
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
|
@ -20,19 +20,18 @@
|
||||
"""Debugging console."""
|
||||
|
||||
import sys
|
||||
from code import InteractiveInterpreter
|
||||
import code
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
|
||||
from PyQt5.QtWidgets import QTextEdit, QWidget, QVBoxLayout, QApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.models.cmdhistory import (History, HistoryEmptyError,
|
||||
HistoryEndReachedError)
|
||||
from qutebrowser.utils.misc import fake_io, disabled_excepthook
|
||||
from qutebrowser.widgets.misc import CommandLineEdit
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.models import cmdhistory
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.widgets import misc
|
||||
|
||||
|
||||
class ConsoleLineEdit(CommandLineEdit):
|
||||
class ConsoleLineEdit(misc.CommandLineEdit):
|
||||
|
||||
"""A QLineEdit which executes entered code and provides a history."""
|
||||
|
||||
@ -56,8 +55,8 @@ class ConsoleLineEdit(CommandLineEdit):
|
||||
# console, not just the line edit.
|
||||
'self': parent,
|
||||
}
|
||||
self._interpreter = InteractiveInterpreter(interpreter_locals)
|
||||
self.history = History()
|
||||
self._interpreter = code.InteractiveInterpreter(interpreter_locals)
|
||||
self.history = cmdhistory.History()
|
||||
self.returnPressed.connect(self.execute)
|
||||
self.setText('')
|
||||
|
||||
@ -88,7 +87,7 @@ class ConsoleLineEdit(CommandLineEdit):
|
||||
# same.
|
||||
# - We disable our exception hook, so exceptions from the console get
|
||||
# printed and don't ooen a crashdialog.
|
||||
with fake_io(self.write.emit), disabled_excepthook():
|
||||
with utils.fake_io(self.write.emit), utils.disabled_excepthook():
|
||||
self._more = self._interpreter.runsource(source, '<console>')
|
||||
self.set_prompt(self.curprompt)
|
||||
if not self._more:
|
||||
@ -101,7 +100,8 @@ class ConsoleLineEdit(CommandLineEdit):
|
||||
item = self.history.start(self.text().strip())
|
||||
else:
|
||||
item = self.history.previtem()
|
||||
except (HistoryEmptyError, HistoryEndReachedError):
|
||||
except (cmdhistory.HistoryEmptyError,
|
||||
cmdhistory.HistoryEndReachedError):
|
||||
return
|
||||
self.setText(item)
|
||||
|
||||
@ -111,7 +111,7 @@ class ConsoleLineEdit(CommandLineEdit):
|
||||
return
|
||||
try:
|
||||
item = self.history.nextitem()
|
||||
except HistoryEndReachedError:
|
||||
except cmdhistory.HistoryEndReachedError:
|
||||
return
|
||||
self.setText(item)
|
||||
|
||||
|
@ -21,17 +21,16 @@
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
from urllib.error import URLError
|
||||
from getpass import getuser
|
||||
import urllib.error
|
||||
import getpass
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize
|
||||
from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
|
||||
QVBoxLayout, QHBoxLayout)
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.misc as utils
|
||||
import qutebrowser.utils.log as logutils
|
||||
from qutebrowser.utils.version import version
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import version, log
|
||||
from qutebrowser.utils import misc as utils
|
||||
|
||||
|
||||
class _CrashDialog(QDialog):
|
||||
@ -124,11 +123,11 @@ class _CrashDialog(QDialog):
|
||||
]
|
||||
try:
|
||||
self._crash_info.append(("Contact info",
|
||||
"User: {}".format(getuser())))
|
||||
"User: {}".format(getpass.getuser())))
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self._crash_info.append(("Contact info", "User: {}: {}".format(
|
||||
e.__class__.__name__, e)))
|
||||
self._crash_info.append(("Version info", version()))
|
||||
self._crash_info.append(("Version info", version.version()))
|
||||
try:
|
||||
self._crash_info.append(("Config",
|
||||
config.instance().dump_userconfig()))
|
||||
@ -156,7 +155,7 @@ class _CrashDialog(QDialog):
|
||||
"""Paste the crash info into the pastebin."""
|
||||
try:
|
||||
url = utils.pastebin(self._txt.toPlainText())
|
||||
except (URLError, ValueError) as e:
|
||||
except (urllib.error.URLError, ValueError) as e:
|
||||
self._url.setText('Error while reporting: {}: {}'.format(
|
||||
e.__class__.__name__, e))
|
||||
return
|
||||
@ -228,8 +227,7 @@ class ExceptionCrashDialog(_CrashDialog):
|
||||
("Objects", self._objects),
|
||||
]
|
||||
try:
|
||||
self._crash_info.append(("Debug log",
|
||||
logutils.ram_handler.dump_log()))
|
||||
self._crash_info.append(("Debug log", log.ram_handler.dump_log()))
|
||||
except AttributeError as e:
|
||||
self._crash_info.append(("Debug log", "{}: {}".format(
|
||||
e.__class__.__name__, e)))
|
||||
@ -245,8 +243,8 @@ class FatalCrashDialog(_CrashDialog):
|
||||
_btn_pastebin: The pastebin button.
|
||||
"""
|
||||
|
||||
def __init__(self, log, parent=None):
|
||||
self._log = log
|
||||
def __init__(self, text, parent=None):
|
||||
self._log = text
|
||||
self._btn_ok = None
|
||||
self._btn_pastebin = None
|
||||
super().__init__(parent)
|
||||
@ -329,8 +327,7 @@ class ReportDialog(_CrashDialog):
|
||||
("Objects", self._objects),
|
||||
]
|
||||
try:
|
||||
self._crash_info.append(("Debug log",
|
||||
logutils.ram_handler.dump_log()))
|
||||
self._crash_info.append(("Debug log", log.ram_handler.dump_log()))
|
||||
except AttributeError as e:
|
||||
self._crash_info.append(("Debug log", "{}: {}".format(
|
||||
e.__class__.__name__, e)))
|
||||
|
@ -22,9 +22,9 @@
|
||||
from PyQt5.QtCore import pyqtSlot, QSize, Qt
|
||||
from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu
|
||||
|
||||
from qutebrowser.models.downloadmodel import DownloadModel, Role
|
||||
from qutebrowser.config.style import set_register_stylesheet
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.models import downloadmodel
|
||||
from qutebrowser.config import style
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class DownloadView(QListView):
|
||||
@ -49,13 +49,13 @@ class DownloadView(QListView):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
set_register_stylesheet(self)
|
||||
style.set_register_stylesheet(self)
|
||||
self.setResizeMode(QListView.Adjust)
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
|
||||
self.setFlow(QListView.LeftToRight)
|
||||
self._menu = None
|
||||
self._model = DownloadModel(self)
|
||||
self._model = downloadmodel.DownloadModel(self)
|
||||
self._model.rowsInserted.connect(self.updateGeometry)
|
||||
self._model.rowsRemoved.connect(self.updateGeometry)
|
||||
self.setModel(self._model)
|
||||
@ -73,7 +73,7 @@ class DownloadView(QListView):
|
||||
index = self.indexAt(point)
|
||||
if not index.isValid():
|
||||
return
|
||||
item = self.model().data(index, Role.item)
|
||||
item = self.model().data(index, downloadmodel.Role.item)
|
||||
self._menu = QMenu(self)
|
||||
cancel = self._menu.addAction("Cancel")
|
||||
cancel.triggered.connect(item.cancel)
|
||||
@ -91,5 +91,5 @@ class DownloadView(QListView):
|
||||
size = QSize(0, height + 2)
|
||||
else:
|
||||
size = QSize(0, 0)
|
||||
qt_ensure_valid(size)
|
||||
qtutils.qt_ensure_valid(size)
|
||||
return size
|
||||
|
@ -20,21 +20,17 @@
|
||||
"""The main window of qutebrowser."""
|
||||
|
||||
import binascii
|
||||
from base64 import b64decode
|
||||
import base64
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QRect, QPoint, QCoreApplication, QTimer
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.widgets.statusbar.bar import StatusBar
|
||||
from qutebrowser.widgets.tabbedbrowser import TabbedBrowser
|
||||
from qutebrowser.widgets.completion import CompletionView
|
||||
from qutebrowser.widgets.downloads import DownloadView
|
||||
from qutebrowser.utils.usertypes import PromptMode
|
||||
from qutebrowser.utils.qt import check_overflow
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import message, log, usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.widgets import tabbedbrowser, completion, downloads
|
||||
from qutebrowser.widgets.statusbar import bar
|
||||
|
||||
|
||||
class MainWindow(QWidget):
|
||||
@ -57,9 +53,9 @@ class MainWindow(QWidget):
|
||||
self.setWindowTitle('qutebrowser')
|
||||
try:
|
||||
stateconf = QCoreApplication.instance().stateconfig
|
||||
base64 = stateconf['geometry']['mainwindow']
|
||||
log.init.debug("Restoring mainwindow from {}".format(base64))
|
||||
geom = b64decode(base64, validate=True)
|
||||
data = stateconf['geometry']['mainwindow']
|
||||
log.init.debug("Restoring mainwindow from {}".format(data))
|
||||
geom = base64.b64decode(data, validate=True)
|
||||
except (KeyError, binascii.Error) as e:
|
||||
log.init.warning("Error while reading geometry: {}: {}".format(
|
||||
e.__class__.__name__, e))
|
||||
@ -81,17 +77,17 @@ class MainWindow(QWidget):
|
||||
self._vbox.setContentsMargins(0, 0, 0, 0)
|
||||
self._vbox.setSpacing(0)
|
||||
|
||||
self.downloadview = DownloadView()
|
||||
self.downloadview = downloads.DownloadView()
|
||||
self._vbox.addWidget(self.downloadview)
|
||||
self.downloadview.show()
|
||||
|
||||
self.tabs = TabbedBrowser()
|
||||
self.tabs = tabbedbrowser.TabbedBrowser()
|
||||
self.tabs.title_changed.connect(self.setWindowTitle)
|
||||
self._vbox.addWidget(self.tabs)
|
||||
|
||||
self.completion = CompletionView(self)
|
||||
self.completion = completion.CompletionView(self)
|
||||
|
||||
self.status = StatusBar()
|
||||
self.status = bar.StatusBar()
|
||||
self._vbox.addWidget(self.status)
|
||||
|
||||
# When we're here the statusbar might not even really exist yet, so
|
||||
@ -139,7 +135,7 @@ class MainWindow(QWidget):
|
||||
# hpoint now would be the bottom-left edge of the widget if it was on
|
||||
# the top of the main window.
|
||||
topleft_y = self.height() - self.status.height() - height
|
||||
topleft_y = check_overflow(topleft_y, 'int', fatal=False)
|
||||
topleft_y = qtutils.check_overflow(topleft_y, 'int', fatal=False)
|
||||
topleft = QPoint(0, topleft_y)
|
||||
bottomright = self.status.geometry().topRight()
|
||||
rect = QRect(topleft, bottomright)
|
||||
@ -178,7 +174,8 @@ class MainWindow(QWidget):
|
||||
else:
|
||||
text = "Close {} {}?".format(
|
||||
count, "tab" if count == 1 else "tabs")
|
||||
confirmed = message.ask(text, PromptMode.yesno, default=True)
|
||||
confirmed = message.ask(text, usertypes.PromptMode.yesno,
|
||||
default=True)
|
||||
if confirmed:
|
||||
e.accept()
|
||||
else:
|
||||
|
@ -23,7 +23,7 @@ from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtWidgets import QLineEdit
|
||||
from PyQt5.QtGui import QValidator
|
||||
|
||||
from qutebrowser.models.cmdhistory import History
|
||||
from qutebrowser.models import cmdhistory
|
||||
|
||||
|
||||
class MinimalLineEditMixin:
|
||||
@ -55,7 +55,7 @@ class CommandLineEdit(QLineEdit):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.history = History()
|
||||
self.history = cmdhistory.History()
|
||||
self._validator = _CommandValidator(self)
|
||||
self.setValidator(self._validator)
|
||||
self.textEdited.connect(self.on_text_edited)
|
||||
|
@ -19,27 +19,22 @@
|
||||
|
||||
"""The main statusbar widget."""
|
||||
|
||||
from collections import deque
|
||||
from datetime import datetime
|
||||
import collections
|
||||
import datetime
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
|
||||
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.config import config, style
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import statusbar as logger
|
||||
from qutebrowser.widgets.statusbar.command import Command
|
||||
from qutebrowser.widgets.statusbar.progress import Progress
|
||||
from qutebrowser.widgets.statusbar.text import Text
|
||||
from qutebrowser.widgets.statusbar.keystring import KeyString
|
||||
from qutebrowser.widgets.statusbar.percentage import Percentage
|
||||
from qutebrowser.widgets.statusbar.url import UrlText
|
||||
from qutebrowser.widgets.statusbar.prompt import Prompt
|
||||
from qutebrowser.config.style import set_register_stylesheet, get_stylesheet
|
||||
from qutebrowser.utils.usertypes import Timer, KeyMode, enum
|
||||
from qutebrowser.widgets.statusbar import (command, progress, keystring,
|
||||
percentage, url, prompt)
|
||||
from qutebrowser.widgets.statusbar import text as textwidget
|
||||
|
||||
|
||||
PreviousWidget = enum('PreviousWidget', 'none', 'prompt', 'command')
|
||||
PreviousWidget = usertypes.enum('PreviousWidget', 'none', 'prompt', 'command')
|
||||
|
||||
|
||||
class StatusBar(QWidget):
|
||||
@ -128,7 +123,7 @@ class StatusBar(QWidget):
|
||||
super().__init__(parent)
|
||||
self.setObjectName(self.__class__.__name__)
|
||||
self.setAttribute(Qt.WA_StyledBackground)
|
||||
set_register_stylesheet(self)
|
||||
style.set_register_stylesheet(self)
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
|
||||
|
||||
@ -143,18 +138,18 @@ class StatusBar(QWidget):
|
||||
self._hbox.addLayout(self._stack)
|
||||
self._stack.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.cmd = Command()
|
||||
self.cmd = command.Command()
|
||||
self._stack.addWidget(self.cmd)
|
||||
|
||||
self.txt = Text()
|
||||
self.txt = textwidget.Text()
|
||||
self._stack.addWidget(self.txt)
|
||||
self._timer_was_active = False
|
||||
self._text_queue = deque()
|
||||
self._text_pop_timer = Timer(self, 'statusbar_text_pop')
|
||||
self._text_queue = collections.deque()
|
||||
self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop')
|
||||
self._text_pop_timer.setInterval(config.get('ui', 'message-timeout'))
|
||||
self._text_pop_timer.timeout.connect(self._pop_text)
|
||||
|
||||
self.prompt = Prompt()
|
||||
self.prompt = prompt.Prompt()
|
||||
self._stack.addWidget(self.prompt)
|
||||
self._previous_widget = PreviousWidget.none
|
||||
|
||||
@ -165,19 +160,19 @@ class StatusBar(QWidget):
|
||||
self.prompt.hide_prompt.connect(self._hide_prompt_widget)
|
||||
self._hide_prompt_widget()
|
||||
|
||||
self.keystring = KeyString()
|
||||
self.keystring = keystring.KeyString()
|
||||
self._hbox.addWidget(self.keystring)
|
||||
|
||||
self.url = UrlText()
|
||||
self.url = url.UrlText()
|
||||
self._hbox.addWidget(self.url)
|
||||
|
||||
self.percentage = Percentage()
|
||||
self.percentage = percentage.Percentage()
|
||||
self._hbox.addWidget(self.percentage)
|
||||
|
||||
# We add a parent to Progress here because it calls self.show() based
|
||||
# on some signals, and if that happens before it's added to the layout,
|
||||
# it will quickly blink up as independent window.
|
||||
self.prog = Progress(self)
|
||||
self.prog = progress.Progress(self)
|
||||
self._hbox.addWidget(self.prog)
|
||||
|
||||
def __repr__(self):
|
||||
@ -198,7 +193,7 @@ class StatusBar(QWidget):
|
||||
"""
|
||||
logger.debug("Setting error to {}".format(val))
|
||||
self._error = val
|
||||
self.setStyleSheet(get_stylesheet(self.STYLESHEET))
|
||||
self.setStyleSheet(style.get_stylesheet(self.STYLESHEET))
|
||||
if val:
|
||||
# If we got an error while command/prompt was shown, raise the text
|
||||
# widget.
|
||||
@ -219,7 +214,7 @@ class StatusBar(QWidget):
|
||||
"""
|
||||
logger.debug("Setting prompt_active to {}".format(val))
|
||||
self._prompt_active = val
|
||||
self.setStyleSheet(get_stylesheet(self.STYLESHEET))
|
||||
self.setStyleSheet(style.get_stylesheet(self.STYLESHEET))
|
||||
|
||||
@pyqtProperty(bool)
|
||||
def insert_active(self):
|
||||
@ -236,7 +231,7 @@ class StatusBar(QWidget):
|
||||
"""
|
||||
logger.debug("Setting insert_active to {}".format(val))
|
||||
self._insert_active = val
|
||||
self.setStyleSheet(get_stylesheet(self.STYLESHEET))
|
||||
self.setStyleSheet(style.get_stylesheet(self.STYLESHEET))
|
||||
|
||||
def _pop_text(self):
|
||||
"""Display a text in the statusbar and pop it from _text_queue."""
|
||||
@ -316,7 +311,7 @@ class StatusBar(QWidget):
|
||||
"""
|
||||
# FIXME probably using a QTime here would be easier.
|
||||
logger.debug("Displaying text: {} (error={})".format(text, error))
|
||||
now = datetime.now()
|
||||
now = datetime.datetime.now()
|
||||
mindelta = config.get('ui', 'message-timeout')
|
||||
delta = (None if self._last_text_time is None
|
||||
else now - self._last_text_time)
|
||||
@ -379,20 +374,20 @@ class StatusBar(QWidget):
|
||||
"""Set a normal (persistent) text in the status bar."""
|
||||
self.txt.normaltext = val
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_entered(self, mode):
|
||||
"""Mark certain modes in the commandline."""
|
||||
if mode in modeman.instance().passthrough:
|
||||
self.txt.normaltext = "-- {} MODE --".format(mode.name.upper())
|
||||
if mode == KeyMode.insert:
|
||||
if mode == usertypes.KeyMode.insert:
|
||||
self.insert_active = True
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Clear marked mode."""
|
||||
if mode in modeman.instance().passthrough:
|
||||
self.txt.normaltext = ""
|
||||
if mode == KeyMode.insert:
|
||||
if mode == usertypes.KeyMode.insert:
|
||||
self.insert_active = False
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
|
@ -22,19 +22,17 @@
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import QSizePolicy, QApplication
|
||||
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.widgets.misc import MinimalLineEditMixin, CommandLineEdit
|
||||
from qutebrowser.commands.runners import CommandRunner
|
||||
from qutebrowser.keyinput.modeparsers import STARTCHARS
|
||||
from qutebrowser.keyinput import modeman, modeparsers
|
||||
from qutebrowser.commands import runners
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.widgets import misc
|
||||
from qutebrowser.models import cmdhistory
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils.log import completion as logger
|
||||
from qutebrowser.models.cmdhistory import (HistoryEmptyError,
|
||||
HistoryEndReachedError)
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
|
||||
|
||||
class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
|
||||
|
||||
"""The commandline part of the statusbar.
|
||||
|
||||
@ -76,8 +74,8 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
# for a possible fix.
|
||||
|
||||
def __init__(self, parent=None):
|
||||
CommandLineEdit.__init__(self, parent)
|
||||
MinimalLineEditMixin.__init__(self)
|
||||
misc.CommandLineEdit.__init__(self, parent)
|
||||
misc.MinimalLineEditMixin.__init__(self)
|
||||
self.cursor_part = 0
|
||||
self.history.history = QApplication.instance().cmd_history.data
|
||||
self._empty_item_idx = None
|
||||
@ -92,7 +90,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
text = self.text()
|
||||
if not text:
|
||||
return ''
|
||||
elif text[0] in STARTCHARS:
|
||||
elif text[0] in modeparsers.STARTCHARS:
|
||||
return text[0]
|
||||
else:
|
||||
return ''
|
||||
@ -109,7 +107,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
# Text is only whitespace so we treat this as a single element with
|
||||
# the whitespace.
|
||||
return [text]
|
||||
runner = CommandRunner()
|
||||
runner = runners.CommandRunner()
|
||||
parts = runner.parse(text, fallback=True, alias_no_args=False)
|
||||
if self._empty_item_idx is not None:
|
||||
logger.debug("Empty element queued at {}, inserting.".format(
|
||||
@ -179,8 +177,9 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
strings: A list of strings to set.
|
||||
"""
|
||||
text = ' '.join(strings)
|
||||
if not text[0] in STARTCHARS:
|
||||
raise CommandError("Invalid command text '{}'.".format(text))
|
||||
if not text[0] in modeparsers.STARTCHARS:
|
||||
raise cmdexc.CommandError(
|
||||
"Invalid command text '{}'.".format(text))
|
||||
self.set_cmd_text(text)
|
||||
|
||||
@pyqtSlot(str, bool)
|
||||
@ -215,7 +214,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
self.show_cmd.emit()
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
|
||||
modes=[KeyMode.command])
|
||||
modes=[usertypes.KeyMode.command])
|
||||
def command_history_prev(self):
|
||||
"""Go back in the commandline history."""
|
||||
try:
|
||||
@ -223,26 +222,27 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
item = self.history.start(self.text().strip())
|
||||
else:
|
||||
item = self.history.previtem()
|
||||
except (HistoryEmptyError, HistoryEndReachedError):
|
||||
except (cmdhistory.HistoryEmptyError,
|
||||
cmdhistory.HistoryEndReachedError):
|
||||
return
|
||||
if item:
|
||||
self.set_cmd_text(item)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
|
||||
modes=[KeyMode.command])
|
||||
modes=[usertypes.KeyMode.command])
|
||||
def command_history_next(self):
|
||||
"""Go forward in the commandline history."""
|
||||
if not self.history.browsing:
|
||||
return
|
||||
try:
|
||||
item = self.history.nextitem()
|
||||
except HistoryEndReachedError:
|
||||
except cmdhistory.HistoryEndReachedError:
|
||||
return
|
||||
if item:
|
||||
self.set_cmd_text(item)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
|
||||
modes=[KeyMode.command])
|
||||
modes=[usertypes.KeyMode.command])
|
||||
def command_accept(self):
|
||||
"""Execute the command currently in the commandline.
|
||||
|
||||
@ -258,7 +258,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
}
|
||||
text = self.text()
|
||||
self.history.append(text)
|
||||
modeman.leave(KeyMode.command, 'cmd accept')
|
||||
modeman.leave(usertypes.KeyMode.command, 'cmd accept')
|
||||
if text[0] in signals:
|
||||
signals[text[0]].emit(text.lstrip(text[0]))
|
||||
|
||||
@ -271,7 +271,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
# here, but that's already done for us by cursorPositionChanged
|
||||
# anyways, so we don't need to do it twice.
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Clear up when ommand mode was left.
|
||||
|
||||
@ -286,7 +286,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
clear_completion_selection: Always emitted.
|
||||
hide_completion: Always emitted so the completion is hidden.
|
||||
"""
|
||||
if mode == KeyMode.command:
|
||||
if mode == usertypes.KeyMode.command:
|
||||
self.setText('')
|
||||
self.history.stop()
|
||||
self.hide_cmd.emit()
|
||||
@ -295,14 +295,14 @@ class Command(MinimalLineEditMixin, CommandLineEdit):
|
||||
|
||||
def focusInEvent(self, e):
|
||||
"""Extend focusInEvent to enter command mode."""
|
||||
modeman.maybe_enter(KeyMode.command, 'cmd focus')
|
||||
modeman.maybe_enter(usertypes.KeyMode.command, 'cmd focus')
|
||||
super().focusInEvent(e)
|
||||
|
||||
def setText(self, text):
|
||||
"""Extend setText to set prefix and make sure the prompt is ok."""
|
||||
if not text:
|
||||
pass
|
||||
elif text[0] in STARTCHARS:
|
||||
elif text[0] in modeparsers.STARTCHARS:
|
||||
super().set_prompt(text[0])
|
||||
else:
|
||||
raise AssertionError("setText got called with invalid text "
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
"""Keychain string displayed in the statusbar."""
|
||||
|
||||
from qutebrowser.widgets.statusbar.textbase import TextBase
|
||||
from qutebrowser.widgets.statusbar import textbase
|
||||
|
||||
|
||||
class KeyString(TextBase):
|
||||
class KeyString(textbase.TextBase):
|
||||
|
||||
"""Keychain string displayed in the statusbar."""
|
||||
|
||||
|
@ -21,10 +21,10 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
from qutebrowser.widgets.statusbar.textbase import TextBase
|
||||
from qutebrowser.widgets.statusbar import textbase
|
||||
|
||||
|
||||
class Percentage(TextBase):
|
||||
class Percentage(textbase.TextBase):
|
||||
|
||||
"""Reading percentage displayed in the statusbar."""
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtWidgets import QProgressBar, QSizePolicy
|
||||
|
||||
from qutebrowser.widgets.webview import LoadStatus
|
||||
from qutebrowser.config.style import set_register_stylesheet
|
||||
from qutebrowser.widgets import webview
|
||||
from qutebrowser.config import style
|
||||
|
||||
|
||||
class Progress(QProgressBar):
|
||||
@ -50,7 +50,7 @@ class Progress(QProgressBar):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
set_register_stylesheet(self)
|
||||
style.set_register_stylesheet(self)
|
||||
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Ignored)
|
||||
self.setTextVisible(False)
|
||||
self.hide()
|
||||
@ -72,7 +72,7 @@ class Progress(QProgressBar):
|
||||
# sometimes.
|
||||
return
|
||||
self.setValue(tab.progress)
|
||||
if tab.load_status == LoadStatus.loading:
|
||||
if tab.load_status == webview.LoadStatus.loading:
|
||||
self.show()
|
||||
else:
|
||||
self.hide()
|
||||
|
@ -22,18 +22,17 @@
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtWidgets import QHBoxLayout, QWidget, QLineEdit
|
||||
|
||||
from qutebrowser.widgets.misc import MinimalLineEditMixin
|
||||
from qutebrowser.widgets.statusbar.textbase import TextBase
|
||||
from qutebrowser.widgets.statusbar.prompter import Prompter
|
||||
from qutebrowser.widgets import misc
|
||||
from qutebrowser.widgets.statusbar import textbase, prompter
|
||||
|
||||
|
||||
class PromptLineEdit(MinimalLineEditMixin, QLineEdit):
|
||||
class PromptLineEdit(misc.MinimalLineEditMixin, QLineEdit):
|
||||
|
||||
"""QLineEdit with a minimal stylesheet."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QLineEdit.__init__(self, parent)
|
||||
MinimalLineEditMixin.__init__(self)
|
||||
misc.MinimalLineEditMixin.__init__(self)
|
||||
|
||||
|
||||
class Prompt(QWidget):
|
||||
@ -60,13 +59,13 @@ class Prompt(QWidget):
|
||||
self._hbox.setContentsMargins(0, 0, 0, 0)
|
||||
self._hbox.setSpacing(5)
|
||||
|
||||
self.txt = TextBase()
|
||||
self.txt = textbase.TextBase()
|
||||
self._hbox.addWidget(self.txt)
|
||||
|
||||
self.lineedit = PromptLineEdit()
|
||||
self._hbox.addWidget(self.lineedit)
|
||||
|
||||
self.prompter = Prompter(self)
|
||||
self.prompter = prompter.Prompter(self)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{}>'.format(self.__class__.__name__)
|
||||
|
@ -19,20 +19,21 @@
|
||||
|
||||
"""Manager for questions to be shown in the statusbar."""
|
||||
|
||||
from collections import namedtuple, deque
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QTimer
|
||||
from PyQt5.QtWidgets import QLineEdit
|
||||
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.utils.usertypes import PromptMode, Question, KeyMode
|
||||
from qutebrowser.utils.qt import EventLoop
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.utils.log import statusbar as logger
|
||||
|
||||
|
||||
PromptContext = namedtuple('PromptContext', ['question', 'text', 'input_text',
|
||||
'echo_mode', 'input_visible'])
|
||||
PromptContext = collections.namedtuple('PromptContext',
|
||||
['question', 'text', 'input_text',
|
||||
'echo_mode', 'input_visible'])
|
||||
|
||||
|
||||
class Prompter:
|
||||
@ -67,7 +68,7 @@ class Prompter:
|
||||
def __init__(self, prompt):
|
||||
self.question = None
|
||||
self._loops = []
|
||||
self._queue = deque()
|
||||
self._queue = collections.deque()
|
||||
self._busy = False
|
||||
self._prompt = prompt
|
||||
|
||||
@ -124,7 +125,7 @@ class Prompter:
|
||||
Raise:
|
||||
ValueError if the set PromptMode is invalid.
|
||||
"""
|
||||
if self.question.mode == PromptMode.yesno:
|
||||
if self.question.mode == usertypes.PromptMode.yesno:
|
||||
if self.question.default is None:
|
||||
suffix = ""
|
||||
elif self.question.default:
|
||||
@ -133,23 +134,23 @@ class Prompter:
|
||||
suffix = " (no)"
|
||||
self._prompt.txt.setText(self.question.text + suffix)
|
||||
self._prompt.lineedit.hide()
|
||||
mode = KeyMode.yesno
|
||||
elif self.question.mode == PromptMode.text:
|
||||
mode = usertypes.KeyMode.yesno
|
||||
elif self.question.mode == usertypes.PromptMode.text:
|
||||
self._prompt.txt.setText(self.question.text)
|
||||
if self.question.default:
|
||||
self._prompt.lineedit.setText(self.question.default)
|
||||
self._prompt.lineedit.show()
|
||||
mode = KeyMode.prompt
|
||||
elif self.question.mode == PromptMode.user_pwd:
|
||||
mode = usertypes.KeyMode.prompt
|
||||
elif self.question.mode == usertypes.PromptMode.user_pwd:
|
||||
self._prompt.txt.setText(self.question.text)
|
||||
if self.question.default:
|
||||
self._prompt.lineedit.setText(self.question.default)
|
||||
self._prompt.lineedit.show()
|
||||
mode = KeyMode.prompt
|
||||
elif self.question.mode == PromptMode.alert:
|
||||
mode = usertypes.KeyMode.prompt
|
||||
elif self.question.mode == usertypes.PromptMode.alert:
|
||||
self._prompt.txt.setText(self.question.text + ' (ok)')
|
||||
self._prompt.lineedit.hide()
|
||||
mode = KeyMode.prompt
|
||||
mode = usertypes.KeyMode.prompt
|
||||
else:
|
||||
raise ValueError("Invalid prompt mode!")
|
||||
self._prompt.lineedit.setFocus()
|
||||
@ -174,10 +175,10 @@ class Prompter:
|
||||
else:
|
||||
return False
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Clear and reset input when the mode was left."""
|
||||
if mode in (KeyMode.prompt, KeyMode.yesno):
|
||||
if mode in (usertypes.KeyMode.prompt, usertypes.KeyMode.yesno):
|
||||
self._prompt.txt.setText('')
|
||||
self._prompt.lineedit.clear()
|
||||
self._prompt.lineedit.setEchoMode(QLineEdit.Normal)
|
||||
@ -187,7 +188,8 @@ class Prompter:
|
||||
self.question.cancel()
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True,
|
||||
modes=[KeyMode.prompt, KeyMode.yesno])
|
||||
modes=[usertypes.KeyMode.prompt,
|
||||
usertypes.KeyMode.yesno])
|
||||
def prompt_accept(self):
|
||||
"""Accept the current prompt.
|
||||
|
||||
@ -196,60 +198,60 @@ class Prompter:
|
||||
This executes the next action depending on the question mode, e.g. asks
|
||||
for the password or leaves the mode.
|
||||
"""
|
||||
if (self.question.mode == PromptMode.user_pwd and
|
||||
if (self.question.mode == usertypes.PromptMode.user_pwd and
|
||||
self.question.user is None):
|
||||
# User just entered an username
|
||||
self.question.user = self._prompt.lineedit.text()
|
||||
self._prompt.txt.setText("Password:")
|
||||
self._prompt.lineedit.clear()
|
||||
self._prompt.lineedit.setEchoMode(QLineEdit.Password)
|
||||
elif self.question.mode == PromptMode.user_pwd:
|
||||
elif self.question.mode == usertypes.PromptMode.user_pwd:
|
||||
# User just entered a password
|
||||
password = self._prompt.lineedit.text()
|
||||
self.question.answer = (self.question.user, password)
|
||||
modeman.leave(KeyMode.prompt, 'prompt accept')
|
||||
modeman.leave(usertypes.KeyMode.prompt, 'prompt accept')
|
||||
self.question.done()
|
||||
elif self.question.mode == PromptMode.text:
|
||||
elif self.question.mode == usertypes.PromptMode.text:
|
||||
# User just entered text.
|
||||
self.question.answer = self._prompt.lineedit.text()
|
||||
modeman.leave(KeyMode.prompt, 'prompt accept')
|
||||
modeman.leave(usertypes.KeyMode.prompt, 'prompt accept')
|
||||
self.question.done()
|
||||
elif self.question.mode == PromptMode.yesno:
|
||||
elif self.question.mode == usertypes.PromptMode.yesno:
|
||||
# User wants to accept the default of a yes/no question.
|
||||
self.question.answer = self.question.default
|
||||
modeman.leave(KeyMode.yesno, 'yesno accept')
|
||||
modeman.leave(usertypes.KeyMode.yesno, 'yesno accept')
|
||||
self.question.done()
|
||||
elif self.question.mode == PromptMode.alert:
|
||||
elif self.question.mode == usertypes.PromptMode.alert:
|
||||
# User acknowledged an alert
|
||||
self.question.answer = None
|
||||
modeman.leave(KeyMode.prompt, 'alert accept')
|
||||
modeman.leave(usertypes.KeyMode.prompt, 'alert accept')
|
||||
self.question.done()
|
||||
else:
|
||||
raise ValueError("Invalid question mode!")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True,
|
||||
modes=[KeyMode.yesno])
|
||||
modes=[usertypes.KeyMode.yesno])
|
||||
def prompt_yes(self):
|
||||
"""Answer yes to a yes/no prompt."""
|
||||
if self.question.mode != PromptMode.yesno:
|
||||
if self.question.mode != usertypes.PromptMode.yesno:
|
||||
# We just ignore this if we don't have a yes/no question.
|
||||
return
|
||||
self.question.answer = True
|
||||
modeman.leave(KeyMode.yesno, 'yesno accept')
|
||||
modeman.leave(usertypes.KeyMode.yesno, 'yesno accept')
|
||||
self.question.done()
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True,
|
||||
modes=[KeyMode.yesno])
|
||||
modes=[usertypes.KeyMode.yesno])
|
||||
def prompt_no(self):
|
||||
"""Answer no to a yes/no prompt."""
|
||||
if self.question.mode != PromptMode.yesno:
|
||||
if self.question.mode != usertypes.PromptMode.yesno:
|
||||
# We just ignore this if we don't have a yes/no question.
|
||||
return
|
||||
self.question.answer = False
|
||||
modeman.leave(KeyMode.yesno, 'prompt accept')
|
||||
modeman.leave(usertypes.KeyMode.yesno, 'prompt accept')
|
||||
self.question.done()
|
||||
|
||||
@pyqtSlot(Question, bool)
|
||||
@pyqtSlot(usertypes.Question, bool)
|
||||
def ask_question(self, question, blocking):
|
||||
"""Dispkay a question in the statusbar.
|
||||
|
||||
@ -282,12 +284,12 @@ class Prompter:
|
||||
try:
|
||||
modeman.enter(mode, 'question asked')
|
||||
except modeman.ModeLockedError:
|
||||
if modeman.instance().mode != KeyMode.prompt:
|
||||
if modeman.instance().mode != usertypes.KeyMode.prompt:
|
||||
question.abort()
|
||||
return None
|
||||
modeman.instance().locked = True
|
||||
if blocking:
|
||||
loop = EventLoop()
|
||||
loop = qtutils.EventLoop()
|
||||
self._loops.append(loop)
|
||||
loop.destroyed.connect(lambda: self._loops.remove(loop))
|
||||
question.completed.connect(loop.quit)
|
||||
|
@ -21,11 +21,11 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.widgets.statusbar.textbase import TextBase
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.widgets.statusbar import textbase
|
||||
|
||||
|
||||
class Text(TextBase):
|
||||
class Text(textbase.TextBase):
|
||||
|
||||
"""Text displayed in the statusbar.
|
||||
|
||||
|
@ -23,7 +23,7 @@ from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QLabel, QSizePolicy
|
||||
from PyQt5.QtGui import QPainter
|
||||
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class TextBase(QLabel):
|
||||
@ -79,7 +79,7 @@ class TextBase(QLabel):
|
||||
"""Extend QLabel::resizeEvent to update the elided text afterwards."""
|
||||
super().resizeEvent(e)
|
||||
size = e.size()
|
||||
qt_ensure_valid(size)
|
||||
qtutils.qt_ensure_valid(size)
|
||||
self._update_elided_text(size.width())
|
||||
|
||||
def paintEvent(self, e):
|
||||
@ -90,6 +90,6 @@ class TextBase(QLabel):
|
||||
e.accept()
|
||||
painter = QPainter(self)
|
||||
geom = self.geometry()
|
||||
qt_ensure_valid(geom)
|
||||
qtutils.qt_ensure_valid(geom)
|
||||
painter.drawText(0, 0, geom.width(), geom.height(),
|
||||
self.alignment(), self._elided_text)
|
||||
|
@ -21,17 +21,18 @@
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtProperty, Qt
|
||||
|
||||
from qutebrowser.widgets.webview import LoadStatus
|
||||
from qutebrowser.widgets.statusbar.textbase import TextBase
|
||||
from qutebrowser.config.style import set_register_stylesheet, get_stylesheet
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser.widgets import webview
|
||||
from qutebrowser.widgets.statusbar import textbase
|
||||
from qutebrowser.config import style
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
|
||||
# Note this has entries for success/error/warn from widgets.webview:LoadStatus
|
||||
UrlType = enum('UrlType', 'success', 'error', 'warn', 'hover', 'normal')
|
||||
UrlType = usertypes.enum('UrlType', 'success', 'error', 'warn', 'hover',
|
||||
'normal')
|
||||
|
||||
|
||||
class UrlText(TextBase):
|
||||
class UrlText(textbase.TextBase):
|
||||
|
||||
"""URL displayed in the statusbar.
|
||||
|
||||
@ -80,7 +81,7 @@ class UrlText(TextBase):
|
||||
"""Override TextBase.__init__ to elide in the middle by default."""
|
||||
super().__init__(parent, Qt.ElideMiddle)
|
||||
self.setObjectName(self.__class__.__name__)
|
||||
set_register_stylesheet(self)
|
||||
style.set_register_stylesheet(self)
|
||||
self._hover_url = None
|
||||
self._normal_url = None
|
||||
self._normal_url_type = UrlType.normal
|
||||
@ -104,7 +105,7 @@ class UrlText(TextBase):
|
||||
if not isinstance(val, UrlType):
|
||||
raise TypeError("Type {} is no UrlType member!".format(val))
|
||||
self._urltype = val
|
||||
self.setStyleSheet(get_stylesheet(self.STYLESHEET))
|
||||
self.setStyleSheet(style.get_stylesheet(self.STYLESHEET))
|
||||
|
||||
@property
|
||||
def hover_url(self):
|
||||
@ -164,8 +165,9 @@ class UrlText(TextBase):
|
||||
Args:
|
||||
status_str: The LoadStatus as string.
|
||||
"""
|
||||
status = LoadStatus[status_str]
|
||||
if status in (LoadStatus.success, LoadStatus.error, LoadStatus.warn):
|
||||
status = webview.LoadStatus[status_str]
|
||||
if status in (webview.LoadStatus.success, webview.LoadStatus.error,
|
||||
webview.LoadStatus.warn):
|
||||
self.normal_url_type = UrlType[status_str]
|
||||
else:
|
||||
self.normal_url_type = UrlType.normal
|
||||
|
@ -19,29 +19,25 @@
|
||||
|
||||
"""The main tabbed browser widget."""
|
||||
|
||||
from functools import partial
|
||||
import functools
|
||||
|
||||
from PyQt5.QtWidgets import QSizePolicy
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QSize, QTimer
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWebKitWidgets import QWebPage
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.misc as utils
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.widgets.tabwidget import TabWidget
|
||||
from qutebrowser.widgets.webview import WebView
|
||||
from qutebrowser.browser.signalfilter import SignalFilter
|
||||
from qutebrowser.browser.commands import CommandDispatcher
|
||||
from qutebrowser.utils.qt import qt_ensure_valid, QtValueError
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.widgets import tabwidget, webview
|
||||
from qutebrowser.browser import signalfilter, commands
|
||||
from qutebrowser.utils import log, message, usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
|
||||
|
||||
class TabbedBrowser(TabWidget):
|
||||
class TabbedBrowser(tabwidget.TabWidget):
|
||||
|
||||
"""A TabWidget with QWebViews inside.
|
||||
|
||||
@ -104,7 +100,7 @@ class TabbedBrowser(TabWidget):
|
||||
quit = pyqtSignal()
|
||||
resized = pyqtSignal('QRect')
|
||||
got_cmd = pyqtSignal(str)
|
||||
current_tab_changed = pyqtSignal(WebView)
|
||||
current_tab_changed = pyqtSignal(webview.WebView)
|
||||
title_changed = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@ -116,8 +112,8 @@ class TabbedBrowser(TabWidget):
|
||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
self._tabs = []
|
||||
self.url_stack = []
|
||||
self._filter = SignalFilter(self)
|
||||
self.cmd = CommandDispatcher(self)
|
||||
self._filter = signalfilter.SignalFilter(self)
|
||||
self.cmd = commands.CommandDispatcher(self)
|
||||
self.last_focused = None
|
||||
self._now_focused = None
|
||||
# FIXME adjust this to font size
|
||||
@ -159,7 +155,8 @@ class TabbedBrowser(TabWidget):
|
||||
self._filter.create(self.cur_url_text_changed, tab))
|
||||
tab.load_status_changed.connect(
|
||||
self._filter.create(self.cur_load_status_changed, tab))
|
||||
tab.url_text_changed.connect(partial(self.on_url_text_changed, tab))
|
||||
tab.url_text_changed.connect(
|
||||
functools.partial(self.on_url_text_changed, tab))
|
||||
# hintmanager
|
||||
tab.hintmanager.hint_strings_updated.connect(self.hint_strings_updated)
|
||||
tab.hintmanager.download_get.connect(self.download_get)
|
||||
@ -168,13 +165,18 @@ class TabbedBrowser(TabWidget):
|
||||
# downloads
|
||||
page.start_download.connect(self.start_download)
|
||||
# misc
|
||||
tab.titleChanged.connect(partial(self.on_title_changed, tab))
|
||||
tab.iconChanged.connect(partial(self.on_icon_changed, tab))
|
||||
tab.loadProgress.connect(partial(self.on_load_progress, tab))
|
||||
frame.loadFinished.connect(partial(self.on_load_finished, tab))
|
||||
frame.loadStarted.connect(partial(self.on_load_started, tab))
|
||||
tab.titleChanged.connect(
|
||||
functools.partial(self.on_title_changed, tab))
|
||||
tab.iconChanged.connect(
|
||||
functools.partial(self.on_icon_changed, tab))
|
||||
tab.loadProgress.connect(
|
||||
functools.partial(self.on_load_progress, tab))
|
||||
frame.loadFinished.connect(
|
||||
functools.partial(self.on_load_finished, tab))
|
||||
frame.loadStarted.connect(
|
||||
functools.partial(self.on_load_started, tab))
|
||||
page.windowCloseRequested.connect(
|
||||
partial(self.on_window_close_requested, tab))
|
||||
functools.partial(self.on_window_close_requested, tab))
|
||||
|
||||
def cntwidget(self, count=None):
|
||||
"""Return a widget based on a count/idx.
|
||||
@ -208,13 +210,13 @@ class TabbedBrowser(TabWidget):
|
||||
"""
|
||||
url = self.currentWidget().cur_url
|
||||
try:
|
||||
qt_ensure_valid(url)
|
||||
except QtValueError as e:
|
||||
qtutils.qt_ensure_valid(url)
|
||||
except qtutils.QtValueError as e:
|
||||
msg = "Current URL is invalid"
|
||||
if e.reason:
|
||||
msg += " ({})".format(e.reason)
|
||||
msg += "!"
|
||||
raise CommandError(msg)
|
||||
raise cmdexc.CommandError(msg)
|
||||
return url
|
||||
|
||||
def shutdown(self):
|
||||
@ -264,7 +266,7 @@ class TabbedBrowser(TabWidget):
|
||||
if tab is self.last_focused:
|
||||
self.last_focused = None
|
||||
if not tab.cur_url.isEmpty():
|
||||
qt_ensure_valid(tab.cur_url)
|
||||
qtutils.qt_ensure_valid(tab.cur_url)
|
||||
self.url_stack.append(tab.cur_url)
|
||||
tab.shutdown()
|
||||
self._tabs.remove(tab)
|
||||
@ -279,7 +281,7 @@ class TabbedBrowser(TabWidget):
|
||||
url: The URL to open as QUrl.
|
||||
newtab: True to open URL in a new tab, False otherwise.
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
if newtab:
|
||||
self.tabopen(url, background=False)
|
||||
else:
|
||||
@ -295,7 +297,7 @@ class TabbedBrowser(TabWidget):
|
||||
return
|
||||
self.close_tab(tab)
|
||||
|
||||
@pyqtSlot(WebView)
|
||||
@pyqtSlot(webview.WebView)
|
||||
def on_window_close_requested(self, widget):
|
||||
"""Close a tab with a widget given."""
|
||||
self.close_tab(widget)
|
||||
@ -322,9 +324,9 @@ class TabbedBrowser(TabWidget):
|
||||
The opened WebView instance.
|
||||
"""
|
||||
if url is not None:
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
log.webview.debug("Creating new tab with URL {}".format(url))
|
||||
tab = WebView(self)
|
||||
tab = webview.WebView(self)
|
||||
self._connect_tab_signals(tab)
|
||||
self._tabs.append(tab)
|
||||
if explicit:
|
||||
@ -440,10 +442,10 @@ class TabbedBrowser(TabWidget):
|
||||
@pyqtSlot()
|
||||
def on_cur_load_started(self):
|
||||
"""Leave insert/hint mode when loading started."""
|
||||
modeman.maybe_leave(KeyMode.insert, 'load started')
|
||||
modeman.maybe_leave(KeyMode.hint, 'load started')
|
||||
modeman.maybe_leave(usertypes.KeyMode.insert, 'load started')
|
||||
modeman.maybe_leave(usertypes.KeyMode.hint, 'load started')
|
||||
|
||||
@pyqtSlot(WebView, str)
|
||||
@pyqtSlot(webview.WebView, str)
|
||||
def on_title_changed(self, tab, text):
|
||||
"""Set the title of a tab.
|
||||
|
||||
@ -470,7 +472,7 @@ class TabbedBrowser(TabWidget):
|
||||
if idx == self.currentIndex():
|
||||
self.title_changed.emit('{} - qutebrowser'.format(text))
|
||||
|
||||
@pyqtSlot(WebView, str)
|
||||
@pyqtSlot(webview.WebView, str)
|
||||
def on_url_text_changed(self, tab, url):
|
||||
"""Set the new URL as title if there's no title yet.
|
||||
|
||||
@ -490,7 +492,7 @@ class TabbedBrowser(TabWidget):
|
||||
if not self.tabText(idx):
|
||||
self.setTabText(idx, url)
|
||||
|
||||
@pyqtSlot(WebView)
|
||||
@pyqtSlot(webview.WebView)
|
||||
def on_icon_changed(self, tab):
|
||||
"""Set the icon of a tab.
|
||||
|
||||
@ -512,10 +514,10 @@ class TabbedBrowser(TabWidget):
|
||||
return
|
||||
self.setTabIcon(idx, tab.icon())
|
||||
|
||||
@pyqtSlot(KeyMode)
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Give focus to current tab if command mode was left."""
|
||||
if mode == KeyMode.command:
|
||||
if mode == usertypes.KeyMode.command:
|
||||
self.currentWidget().setFocus()
|
||||
|
||||
@pyqtSlot(int)
|
||||
@ -523,7 +525,7 @@ class TabbedBrowser(TabWidget):
|
||||
"""Set last_focused and leave hinting mode when focus changed."""
|
||||
tab = self.widget(idx)
|
||||
tab.setFocus()
|
||||
modeman.maybe_leave(KeyMode.hint, 'tab changed')
|
||||
modeman.maybe_leave(usertypes.KeyMode.hint, 'tab changed')
|
||||
self.last_focused = self._now_focused
|
||||
self._now_focused = tab
|
||||
self.current_tab_changed.emit(tab)
|
||||
|
@ -32,8 +32,8 @@ from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
||||
QApplication)
|
||||
from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.config import config
|
||||
|
||||
|
||||
PM_TabBarPadding = QStyle.PM_CustomBase
|
||||
@ -211,7 +211,7 @@ class TabBar(QTabBar):
|
||||
# If we *do* have enough space, tabs should occupy the whole window
|
||||
# width.
|
||||
size = QSize(self.width() / self.count(), height)
|
||||
qt_ensure_valid(size)
|
||||
qtutils.qt_ensure_valid(size)
|
||||
return size
|
||||
|
||||
def paintEvent(self, _e):
|
||||
@ -311,7 +311,7 @@ class TabBarStyle(QCommonStyle):
|
||||
elif element == QStyle.CE_TabBarTabLabel:
|
||||
text_rect, icon_rect = self._tab_layout(opt)
|
||||
if not opt.icon.isNull():
|
||||
qt_ensure_valid(icon_rect)
|
||||
qtutils.qt_ensure_valid(icon_rect)
|
||||
icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled
|
||||
else QIcon.Disabled)
|
||||
icon_state = (QIcon.On if opt.state & QStyle.State_Selected
|
||||
@ -382,7 +382,7 @@ class TabBarStyle(QCommonStyle):
|
||||
padding = self.pixelMetric(PM_TabBarPadding, opt)
|
||||
icon_rect = QRect()
|
||||
text_rect = QRect(opt.rect)
|
||||
qt_ensure_valid(text_rect)
|
||||
qtutils.qt_ensure_valid(text_rect)
|
||||
indicator_width = config.get('tabs', 'indicator-width')
|
||||
text_rect.adjust(padding, 0, 0, 0)
|
||||
if indicator_width != 0:
|
||||
@ -419,5 +419,5 @@ class TabBarStyle(QCommonStyle):
|
||||
text_rect.center().y() - tab_icon_size.height() / 2,
|
||||
tab_icon_size.width(), tab_icon_size.height())
|
||||
icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect)
|
||||
qt_ensure_valid(icon_rect)
|
||||
qtutils.qt_ensure_valid(icon_rect)
|
||||
return icon_rect
|
||||
|
@ -24,21 +24,17 @@ from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtWebKit import QWebSettings
|
||||
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils.misc import elide
|
||||
from qutebrowser.utils.qt import qt_ensure_valid
|
||||
from qutebrowser.browser.webpage import BrowserPage
|
||||
from qutebrowser.browser.hints import HintManager
|
||||
from qutebrowser.utils.usertypes import (NeighborList, ClickTarget, KeyMode,
|
||||
enum)
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.utils import message, webelem, log, usertypes
|
||||
from qutebrowser.utils import misc as utils
|
||||
from qutebrowser.utils import qt as qtutils
|
||||
from qutebrowser.browser import webpage, hints
|
||||
from qutebrowser.commands import exceptions as cmdexc
|
||||
|
||||
|
||||
LoadStatus = enum('LoadStatus', 'none', 'success', 'error', 'warn', 'loading')
|
||||
LoadStatus = usertypes.enum('LoadStatus', 'none', 'success', 'error', 'warn',
|
||||
'loading')
|
||||
|
||||
|
||||
class WebView(QWebView):
|
||||
@ -93,7 +89,7 @@ class WebView(QWebView):
|
||||
self.statusbar_message = ''
|
||||
self._old_scroll_pos = (-1, -1)
|
||||
self._open_target = None
|
||||
self.open_target = ClickTarget.normal
|
||||
self.open_target = usertypes.ClickTarget.normal
|
||||
self._force_open_target = None
|
||||
self._zoom = None
|
||||
self._has_ssl_errors = False
|
||||
@ -101,9 +97,9 @@ class WebView(QWebView):
|
||||
self._cur_url = None
|
||||
self.cur_url = QUrl()
|
||||
self.progress = 0
|
||||
self._page = BrowserPage(self)
|
||||
self._page = webpage.BrowserPage(self)
|
||||
self.setPage(self._page)
|
||||
self.hintmanager = HintManager(self)
|
||||
self.hintmanager = hints.HintManager(self)
|
||||
self.hintmanager.mouse_event.connect(self.on_mouse_event)
|
||||
self.hintmanager.set_open_target.connect(self.set_force_open_target)
|
||||
self._page.linkHovered.connect(self.linkHovered)
|
||||
@ -120,7 +116,7 @@ class WebView(QWebView):
|
||||
|
||||
def __repr__(self):
|
||||
url = self.url().toDisplayString()
|
||||
return "WebView(url='{}')".format(elide(url, 50))
|
||||
return "WebView(url='{}')".format(utils.elide(url, 50))
|
||||
|
||||
@property
|
||||
def open_target(self):
|
||||
@ -130,7 +126,7 @@ class WebView(QWebView):
|
||||
@open_target.setter
|
||||
def open_target(self, val):
|
||||
"""Setter for open_target to do type checking."""
|
||||
if not isinstance(val, ClickTarget):
|
||||
if not isinstance(val, usertypes.ClickTarget):
|
||||
raise TypeError("Target {} is no ClickTarget member!".format(val))
|
||||
self._open_target = val
|
||||
|
||||
@ -172,9 +168,10 @@ class WebView(QWebView):
|
||||
|
||||
def _init_neighborlist(self):
|
||||
"""Initialize the _zoom neighborlist."""
|
||||
self._zoom = NeighborList(config.get('ui', 'zoom-levels'),
|
||||
default=config.get('ui', 'default-zoom'),
|
||||
mode=NeighborList.Modes.block)
|
||||
levels = config.get('ui', 'zoom-levels')
|
||||
default = config.get('ui', 'default-zoom')
|
||||
self._zoom = usertypes.NeighborList(
|
||||
levels, default, mode=usertypes.NeighborList.Modes.block)
|
||||
|
||||
def _mousepress_backforward(self, e):
|
||||
"""Handle back/forward mouse button presses.
|
||||
@ -186,13 +183,13 @@ class WebView(QWebView):
|
||||
# Back button on mice which have it.
|
||||
try:
|
||||
self.go_back()
|
||||
except CommandError as ex:
|
||||
except cmdexc.CommandError as ex:
|
||||
message.error(ex, immediately=True)
|
||||
elif e.button() == Qt.XButton2:
|
||||
# Forward button on mice which have it.
|
||||
try:
|
||||
self.go_forward()
|
||||
except CommandError as ex:
|
||||
except cmdexc.CommandError as ex:
|
||||
message.error(ex, immediately=True)
|
||||
|
||||
def _mousepress_insertmode(self, e):
|
||||
@ -233,11 +230,11 @@ class WebView(QWebView):
|
||||
elif ((hitresult.isContentEditable() and webelem.is_writable(elem)) or
|
||||
webelem.is_editable(elem)):
|
||||
log.mouse.debug("Clicked editable element!")
|
||||
modeman.maybe_enter(KeyMode.insert, 'click')
|
||||
modeman.maybe_enter(usertypes.KeyMode.insert, 'click')
|
||||
else:
|
||||
log.mouse.debug("Clicked non-editable element!")
|
||||
if config.get('input', 'auto-leave-insert-mode'):
|
||||
modeman.maybe_leave(KeyMode.insert, 'click')
|
||||
modeman.maybe_leave(usertypes.KeyMode.insert, 'click')
|
||||
|
||||
def mouserelease_insertmode(self):
|
||||
"""If we have an insertmode check scheduled, handle it."""
|
||||
@ -247,11 +244,11 @@ class WebView(QWebView):
|
||||
elem = webelem.focus_elem(self.page().currentFrame())
|
||||
if webelem.is_editable(elem):
|
||||
log.mouse.debug("Clicked editable element (delayed)!")
|
||||
modeman.maybe_enter(KeyMode.insert, 'click-delayed')
|
||||
modeman.maybe_enter(usertypes.KeyMode.insert, 'click-delayed')
|
||||
else:
|
||||
log.mouse.debug("Clicked non-editable element (delayed)!")
|
||||
if config.get('input', 'auto-leave-insert-mode'):
|
||||
modeman.maybe_leave(KeyMode.insert, 'click-delayed')
|
||||
modeman.maybe_leave(usertypes.KeyMode.insert, 'click-delayed')
|
||||
|
||||
def _mousepress_opentarget(self, e):
|
||||
"""Set the open target when something was clicked.
|
||||
@ -267,13 +264,13 @@ class WebView(QWebView):
|
||||
elif (e.button() == Qt.MidButton or
|
||||
e.modifiers() & Qt.ControlModifier):
|
||||
if config.get('tabs', 'background-tabs'):
|
||||
self.open_target = ClickTarget.tab_bg
|
||||
self.open_target = usertypes.ClickTarget.tab_bg
|
||||
else:
|
||||
self.open_target = ClickTarget.tab
|
||||
self.open_target = usertypes.ClickTarget.tab
|
||||
log.mouse.debug("Middle click, setting target: {}".format(
|
||||
self.open_target))
|
||||
else:
|
||||
self.open_target = ClickTarget.normal
|
||||
self.open_target = usertypes.ClickTarget.normal
|
||||
log.mouse.debug("Normal click, setting normal target")
|
||||
|
||||
def shutdown(self):
|
||||
@ -304,7 +301,7 @@ class WebView(QWebView):
|
||||
Emit:
|
||||
titleChanged
|
||||
"""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
urlstr = url.toDisplayString()
|
||||
log.webview.debug("New title: {}".format(urlstr))
|
||||
self.titleChanged.emit(urlstr)
|
||||
@ -321,7 +318,7 @@ class WebView(QWebView):
|
||||
if fuzzyval:
|
||||
self._zoom.fuzzyval = int(perc)
|
||||
if perc < 0:
|
||||
raise CommandError("Can't zoom {}%!".format(perc))
|
||||
raise cmdexc.CommandError("Can't zoom {}%!".format(perc))
|
||||
self.setZoomFactor(float(perc) / 100)
|
||||
message.info("Zoom level: {}%".format(perc))
|
||||
|
||||
@ -349,19 +346,19 @@ class WebView(QWebView):
|
||||
if self.page().history().canGoBack():
|
||||
self.back()
|
||||
else:
|
||||
raise CommandError("At beginning of history.")
|
||||
raise cmdexc.CommandError("At beginning of history.")
|
||||
|
||||
def go_forward(self):
|
||||
"""Go forward a page in the history."""
|
||||
if self.page().history().canGoForward():
|
||||
self.forward()
|
||||
else:
|
||||
raise CommandError("At end of history.")
|
||||
raise cmdexc.CommandError("At end of history.")
|
||||
|
||||
@pyqtSlot('QUrl')
|
||||
def on_url_changed(self, url):
|
||||
"""Update cur_url when URL has changed."""
|
||||
qt_ensure_valid(url)
|
||||
qtutils.qt_ensure_valid(url)
|
||||
self.cur_url = url
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
@ -394,7 +391,7 @@ class WebView(QWebView):
|
||||
self.load_status = LoadStatus.error
|
||||
if not config.get('input', 'auto-insert-mode'):
|
||||
return
|
||||
if modeman.instance().mode == KeyMode.insert or not ok:
|
||||
if modeman.instance().mode == usertypes.KeyMode.insert or not ok:
|
||||
return
|
||||
frame = self.page().currentFrame()
|
||||
elem = frame.findFirstElement(':focus')
|
||||
@ -402,7 +399,7 @@ class WebView(QWebView):
|
||||
if elem.isNull():
|
||||
log.webview.debug("Focused element is null!")
|
||||
elif webelem.is_editable(elem):
|
||||
modeman.maybe_enter(KeyMode.insert, 'load finished')
|
||||
modeman.maybe_enter(usertypes.KeyMode.insert, 'load finished')
|
||||
|
||||
@pyqtSlot(str)
|
||||
def set_force_open_target(self, target):
|
||||
@ -411,7 +408,7 @@ class WebView(QWebView):
|
||||
Args:
|
||||
target: A string to set self._force_open_target to.
|
||||
"""
|
||||
t = getattr(ClickTarget, target)
|
||||
t = getattr(usertypes.ClickTarget, target)
|
||||
log.webview.debug("Setting force target to {}/{}".format(target, t))
|
||||
self._force_open_target = t
|
||||
|
||||
|
@ -25,7 +25,7 @@ import os.path
|
||||
import sys
|
||||
import glob
|
||||
import shutil
|
||||
from fnmatch import fnmatch
|
||||
import fnmatch
|
||||
|
||||
|
||||
recursive_lint = ('__pycache__', '*.pyc')
|
||||
@ -47,11 +47,17 @@ def remove(path):
|
||||
os.remove(path)
|
||||
|
||||
|
||||
for elem in lint:
|
||||
for f in glob.glob(elem):
|
||||
remove(f)
|
||||
def main():
|
||||
"""Clean up lint in the current dir."""
|
||||
for elem in lint:
|
||||
for f in glob.glob(elem):
|
||||
remove(f)
|
||||
|
||||
for root, _dirs, _files in os.walk(os.getcwd()):
|
||||
path = os.path.basename(root)
|
||||
if any([fnmatch.fnmatch(path, e) for e in recursive_lint]):
|
||||
remove(root)
|
||||
|
||||
|
||||
for root, dirs, files in os.walk(os.getcwd()):
|
||||
if any([fnmatch(os.path.basename(root), e) for e in recursive_lint]):
|
||||
remove(root)
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -27,12 +27,12 @@ Builds a standalone executable.
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
from distutils.sysconfig import get_python_lib
|
||||
import distutils
|
||||
|
||||
from cx_Freeze import setup, Executable
|
||||
import cx_Freeze as cx
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
from scripts.setupcommon import setupdata, write_git_file
|
||||
from scripts import setupcommon
|
||||
|
||||
|
||||
try:
|
||||
@ -46,7 +46,8 @@ def get_egl_path():
|
||||
"""Get the path for PyQt5's libEGL.dll."""
|
||||
if not sys.platform.startswith('win'):
|
||||
return None
|
||||
return os.path.join(get_python_lib(), r'PyQt5\libEGL.dll')
|
||||
return os.path.join(distutils.sysconfig.get_python_lib(),
|
||||
r'PyQt5\libEGL.dll')
|
||||
|
||||
build_exe_options = {
|
||||
'include_files': [
|
||||
@ -69,20 +70,20 @@ bdist_msi_options = {
|
||||
|
||||
base = 'Win32GUI' if sys.platform.startswith('win') else None
|
||||
|
||||
executable = Executable('qutebrowser/__main__.py', base=base,
|
||||
targetName='qutebrowser.exe',
|
||||
shortcutName='qutebrowser',
|
||||
shortcutDir='ProgramMenuFolder')
|
||||
executable = cx.Executable('qutebrowser/__main__.py', base=base,
|
||||
targetName='qutebrowser.exe',
|
||||
shortcutName='qutebrowser',
|
||||
shortcutDir='ProgramMenuFolder')
|
||||
|
||||
try:
|
||||
write_git_file()
|
||||
setup(
|
||||
setupcommon.write_git_file()
|
||||
cx.setup(
|
||||
executables=[executable],
|
||||
options={
|
||||
'build_exe': build_exe_options,
|
||||
'bdist_msi': bdist_msi_options,
|
||||
},
|
||||
**setupdata
|
||||
**setupcommon.setupdata
|
||||
)
|
||||
finally:
|
||||
if BASEDIR is not None:
|
||||
|
@ -27,18 +27,18 @@ import html
|
||||
import shutil
|
||||
import inspect
|
||||
import subprocess
|
||||
from collections import Counter, OrderedDict
|
||||
from tempfile import mkstemp
|
||||
import collections
|
||||
import tempfile
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
|
||||
import qutebrowser
|
||||
# We import qutebrowser.app so all @cmdutils-register decorators are run.
|
||||
import qutebrowser.app
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.configdata as configdata
|
||||
import qutebrowser.qutebrowser as qutequtebrowser
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
from qutebrowser import qutebrowser as qutequtebrowser
|
||||
from qutebrowser.commands import utils as cmdutils
|
||||
from qutebrowser.config import configdata
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
|
||||
def _open_file(name, mode='w'):
|
||||
@ -58,8 +58,9 @@ def _parse_docstring(func): # noqa
|
||||
A (short_desc, long_desc, arg_descs) tuple.
|
||||
"""
|
||||
# pylint: disable=too-many-branches
|
||||
State = enum('State', 'short', 'desc', # pylint: disable=invalid-name
|
||||
'desc_hidden', 'arg_start', 'arg_inside', 'misc')
|
||||
State = usertypes.enum('State', 'short', # pylint: disable=invalid-name
|
||||
'desc', 'desc_hidden', 'arg_start', 'arg_inside',
|
||||
'misc')
|
||||
doc = inspect.getdoc(func)
|
||||
lines = doc.splitlines()
|
||||
|
||||
@ -67,7 +68,7 @@ def _parse_docstring(func): # noqa
|
||||
|
||||
short_desc = []
|
||||
long_desc = []
|
||||
arg_descs = OrderedDict()
|
||||
arg_descs = collections.OrderedDict()
|
||||
cur_arg_name = None
|
||||
|
||||
for line in lines:
|
||||
@ -385,7 +386,7 @@ def generate_settings(f):
|
||||
def _get_authors():
|
||||
"""Get a list of authors based on git commit logs."""
|
||||
commits = subprocess.check_output(['git', 'log', '--format=%aN'])
|
||||
cnt = Counter(commits.decode('utf-8').splitlines())
|
||||
cnt = collections.Counter(commits.decode('utf-8').splitlines())
|
||||
return sorted(cnt, key=lambda k: cnt[k])
|
||||
|
||||
|
||||
@ -442,7 +443,7 @@ def generate_manpage_resources(f):
|
||||
|
||||
def regenerate_authors(filename):
|
||||
"""Re-generate the authors inside README based on the commits made."""
|
||||
oshandle, tmpname = mkstemp()
|
||||
oshandle, tmpname = tempfile.mkstemp()
|
||||
with _open_file(filename, mode='r') as infile, \
|
||||
_open_file(oshandle, mode='w') as temp:
|
||||
ignore = False
|
||||
|
@ -20,18 +20,17 @@
|
||||
"""Custom astroid checker for config calls."""
|
||||
|
||||
import astroid
|
||||
from pylint.interfaces import IAstroidChecker
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint import interfaces, checkers
|
||||
from pylint.checkers import utils
|
||||
|
||||
import qutebrowser.config.configdata as configdata
|
||||
from qutebrowser.config import configdata
|
||||
|
||||
|
||||
class ConfigChecker(BaseChecker):
|
||||
class ConfigChecker(checkers.BaseChecker):
|
||||
|
||||
"""Custom astroid checker for config calls."""
|
||||
|
||||
__implements__ = IAstroidChecker
|
||||
__implements__ = interfaces.IAstroidChecker
|
||||
name = 'config'
|
||||
msgs = {
|
||||
'E0000': ('"%s -> %s" is no valid config option.', 'bad-config-call',
|
||||
|
@ -18,15 +18,14 @@
|
||||
|
||||
"""Checker for CRLF in files."""
|
||||
|
||||
from pylint.interfaces import IRawChecker
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint import interfaces, checkers
|
||||
|
||||
|
||||
class CrlfChecker(BaseChecker):
|
||||
class CrlfChecker(checkers.BaseChecker):
|
||||
|
||||
"""Check for CRLF in files."""
|
||||
|
||||
__implements__ = IRawChecker
|
||||
__implements__ = interfaces.IRawChecker
|
||||
|
||||
name = 'crlf'
|
||||
msgs = {'W9001': ('Uses CRLFs', 'crlf', None)}
|
||||
|
@ -20,15 +20,14 @@
|
||||
|
||||
import os.path
|
||||
|
||||
from pylint.interfaces import IRawChecker
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint import interfaces, checkers
|
||||
|
||||
|
||||
class ModelineChecker(BaseChecker):
|
||||
class ModelineChecker(checkers.BaseChecker):
|
||||
|
||||
"""Check for vim modelines in files."""
|
||||
|
||||
__implements__ = IRawChecker
|
||||
__implements__ = interfaces.IRawChecker
|
||||
|
||||
name = 'modeline'
|
||||
msgs = {'W9002': ('Does not have vim modeline', 'modeline-missing', None),
|
||||
|
@ -20,16 +20,15 @@
|
||||
"""Make sure open() has an encoding set."""
|
||||
|
||||
import astroid
|
||||
from pylint.interfaces import IAstroidChecker
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint import interfaces, checkers
|
||||
from pylint.checkers import utils
|
||||
|
||||
|
||||
class OpenEncodingChecker(BaseChecker):
|
||||
class OpenEncodingChecker(checkers.BaseChecker):
|
||||
|
||||
"""Checker to check open() has an encoding set."""
|
||||
|
||||
__implements__ = IAstroidChecker
|
||||
__implements__ = interfaces.IAstroidChecker
|
||||
name = 'open-encoding'
|
||||
|
||||
msgs = {
|
||||
|
@ -38,13 +38,13 @@ import logging
|
||||
import tokenize
|
||||
import configparser
|
||||
import argparse
|
||||
from collections import OrderedDict
|
||||
from functools import partial
|
||||
from contextlib import contextmanager
|
||||
import collections
|
||||
import functools
|
||||
import contextlib
|
||||
|
||||
import colorama as col
|
||||
import pep257
|
||||
from pkg_resources import load_entry_point, DistributionNotFound
|
||||
import pkg_resources as pkg
|
||||
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
@ -59,7 +59,7 @@ config = configparser.ConfigParser()
|
||||
config.read('.run_checks')
|
||||
|
||||
|
||||
@contextmanager
|
||||
@contextlib.contextmanager
|
||||
def _adjusted_pythonpath(name):
|
||||
"""Adjust PYTHONPATH for pylint."""
|
||||
if name == 'pylint':
|
||||
@ -82,7 +82,7 @@ def _run_distutils(name, args):
|
||||
"""Run a checker via its distutils entry point."""
|
||||
sys.argv = [name] + args
|
||||
try:
|
||||
ep = load_entry_point(name, 'console_scripts', name)
|
||||
ep = pkg.load_entry_point(name, 'console_scripts', name)
|
||||
ep()
|
||||
except SystemExit as e:
|
||||
return e.code
|
||||
@ -114,7 +114,7 @@ def run(name, target=None):
|
||||
with _adjusted_pythonpath(name):
|
||||
try:
|
||||
status = _run_distutils(name, args)
|
||||
except DistributionNotFound:
|
||||
except pkg.DistributionNotFound:
|
||||
status = _run_subprocess(name, args)
|
||||
print()
|
||||
return status
|
||||
@ -244,23 +244,23 @@ def _get_args(checker):
|
||||
def _get_checkers():
|
||||
"""Get a dict of checkers we need to execute."""
|
||||
# "Static" checkers
|
||||
checkers = OrderedDict([
|
||||
('global', OrderedDict([
|
||||
checkers = collections.OrderedDict([
|
||||
('global', collections.OrderedDict([
|
||||
('unittest', check_unittest),
|
||||
('git', check_git),
|
||||
])),
|
||||
('setup', OrderedDict([
|
||||
('pyroma', partial(run, 'pyroma')),
|
||||
('check-manifest', partial(run, 'check-manifest')),
|
||||
('setup', collections.OrderedDict([
|
||||
('pyroma', functools.partial(run, 'pyroma')),
|
||||
('check-manifest', functools.partial(run, 'check-manifest')),
|
||||
])),
|
||||
])
|
||||
# "Dynamic" checkers which exist once for each target.
|
||||
for target in config.get('DEFAULT', 'targets').split(','):
|
||||
checkers[target] = OrderedDict([
|
||||
('pep257', partial(check_pep257, target)),
|
||||
('flake8', partial(run, 'flake8', target)),
|
||||
('vcs', partial(check_vcs_conflict, target)),
|
||||
('pylint', partial(run, 'pylint', target)),
|
||||
checkers[target] = collections.OrderedDict([
|
||||
('pep257', functools.partial(check_pep257, target)),
|
||||
('flake8', functools.partial(run, 'flake8', target)),
|
||||
('vcs', functools.partial(check_vcs_conflict, target)),
|
||||
('pylint', functools.partial(run, 'pylint', target)),
|
||||
])
|
||||
return checkers
|
||||
|
||||
@ -279,7 +279,7 @@ def _checker_enabled(args, group, name):
|
||||
def main():
|
||||
"""Main entry point."""
|
||||
col.init()
|
||||
exit_status = OrderedDict()
|
||||
exit_status = collections.OrderedDict()
|
||||
exit_status_bool = {}
|
||||
parser = argparse.ArgumentParser(description='Run various checkers.')
|
||||
parser.add_argument('-s', '--setup', help="Run additional setup checks",
|
||||
|
@ -23,20 +23,20 @@
|
||||
import sys
|
||||
import cProfile
|
||||
import os.path
|
||||
from os import getcwd
|
||||
from tempfile import mkdtemp
|
||||
from subprocess import call
|
||||
from shutil import rmtree
|
||||
import os
|
||||
import tempfile
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
sys.path.insert(0, getcwd())
|
||||
sys.path.insert(0, os.getcwd())
|
||||
|
||||
import qutebrowser.qutebrowser # pylint: disable=unused-import
|
||||
|
||||
tempdir = mkdtemp()
|
||||
tempdir = tempfile.mkdtemp()
|
||||
|
||||
if '--profile-keep' in sys.argv:
|
||||
sys.argv.remove('--profile-keep')
|
||||
profilefile = os.path.join(getcwd(), 'profile')
|
||||
profilefile = os.path.join(os.getcwd(), 'profile')
|
||||
else:
|
||||
profilefile = os.path.join(tempdir, 'profile')
|
||||
if '--profile-noconv' in sys.argv:
|
||||
@ -51,5 +51,6 @@ profiler.run('qutebrowser.qutebrowser.main()')
|
||||
profiler.dump_stats(profilefile)
|
||||
|
||||
if not noconv:
|
||||
call(['pyprof2calltree', '-k', '-i', profilefile, '-o', callgraphfile])
|
||||
rmtree(tempdir)
|
||||
subprocess.call(['pyprof2calltree', '-k', '-i', profilefile,
|
||||
'-o', callgraphfile])
|
||||
shutil.rmtree(tempdir)
|
||||
|
@ -20,7 +20,8 @@
|
||||
|
||||
"""Update 3rd-party files (currently only ez_setup.py)."""
|
||||
|
||||
from urllib.request import urlretrieve
|
||||
import urllib.request
|
||||
|
||||
urlretrieve('https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py',
|
||||
'scripts/ez_setup.py')
|
||||
urllib.request.urlretrieve(
|
||||
'https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py',
|
||||
'scripts/ez_setup.py')
|
||||
|
16
setup.py
16
setup.py
@ -24,11 +24,11 @@
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from scripts.setupcommon import setupdata, write_git_file
|
||||
from scripts import setupcommon as common
|
||||
|
||||
from scripts.ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
from setuptools import setup, find_packages
|
||||
from scripts import ez_setup
|
||||
ez_setup.use_setuptools()
|
||||
import setuptools
|
||||
|
||||
|
||||
try:
|
||||
@ -38,9 +38,9 @@ except NameError:
|
||||
|
||||
|
||||
try:
|
||||
write_git_file()
|
||||
setup(
|
||||
packages=find_packages(exclude=['qutebrowser.test']),
|
||||
common.write_git_file()
|
||||
setuptools.setup(
|
||||
packages=setuptools.find_packages(exclude=['qutebrowser.test']),
|
||||
include_package_data=True,
|
||||
package_data={'qutebrowser': ['html/*', 'git-commit-id']},
|
||||
entry_points={'gui_scripts':
|
||||
@ -51,7 +51,7 @@ try:
|
||||
extras_require={'nice-debugging': ['colorlog', 'colorama'],
|
||||
'checks': ['flake8', 'pylint', 'check-manifest',
|
||||
'pyroma']},
|
||||
**setupdata
|
||||
**common.setupdata
|
||||
)
|
||||
finally:
|
||||
if BASEDIR is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user