Be PEP257 compliant.

This commit is contained in:
Florian Bruhin 2014-02-07 20:21:50 +01:00
parent e8b01b2b31
commit 01633007e0
22 changed files with 229 additions and 47 deletions

View File

@ -2,7 +2,7 @@
Files:
__init__.py - This file.
__main__.py - Entry point for qutebrowser, to use\
__main__.py - Entry point for qutebrowser, to use
'python -m qutebrowser'.
app.py - Main qutebrowser application>
simplebrowser.py - Simple browser for testing purposes.
@ -11,6 +11,7 @@ Subpackages:
commands - Handling of commands and key parsing.
utils - Misc utility code.
widgets - Qt widgets displayed on the screen.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>

View File

@ -1,4 +1,4 @@
""" Initialization of qutebrowser and application-wide things """
"""Initialization of qutebrowser and application-wide things."""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
@ -44,13 +44,16 @@ from qutebrowser.utils.appdirs import AppDirs
class QuteBrowser(QApplication):
"""Main object for qutebrowser.
Can be used like this:
>>> app = QuteBrowser()
>>> sys.exit(app.exec_())
"""
dirs = None # AppDirs - config/cache directories
config = None # Config(Parser) object
mainwindow = None
@ -112,6 +115,7 @@ class QuteBrowser(QApplication):
"""Process initial positional args.
URLs to open have no prefix, commands to execute begin with a colon.
"""
opened_urls = False
@ -135,6 +139,7 @@ class QuteBrowser(QApplication):
It'll try very hard to write all open tabs to a file, and then exit
gracefully.
"""
# pylint: disable=broad-except
@ -178,6 +183,7 @@ class QuteBrowser(QApplication):
This sets up the uncaught exception hook, quits with an appropriate
exit status, and handles Ctrl+C properly by passing control to the
Python interpreter once all 500ms.
"""
signal(SIGINT, lambda *args: self.exit(128 + SIGINT))
self.timer = QTimer()
@ -220,6 +226,7 @@ class QuteBrowser(QApplication):
"""Initialisation of the qutebrowser commands.
Registers all commands, connects its signals, and sets up keyparser.
"""
cmdutils.register_all()
for cmd in cmdutils.cmd_dict.values():
@ -238,6 +245,7 @@ class QuteBrowser(QApplication):
tpl -- A tuple in the form (count, argv) where argv is [cmd, arg, ...]
All handlers supporting a count should have a keyword argument count.
"""
(count, argv) = tpl
cmd = argv[0]
@ -283,6 +291,7 @@ class QuteBrowser(QApplication):
s -- The string to evaluate.
:pyeval command handler.
"""
try:
r = eval(s)
@ -296,5 +305,6 @@ class QuteBrowser(QApplication):
"""Crash for debugging purposes.
:crash command handler.
"""
raise Exception

View File

@ -6,15 +6,12 @@ via inspect.
A command class can set the following properties:
nargs -- Number of arguments. Either a number, '?' (0 or 1), '+' (1 or
more), or '*' (any). Default: 0
more), or '*' (any). Default: 0
name -- The name of the command, or a list of aliases.
split_args -- If arguments should be split or not. Default: True
count -- If the command supports a count. Default: False
hide -- If the command should be hidden in tab completion. Default: False
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -38,9 +35,11 @@ from qutebrowser.commands.template import Command
class Open(Command):
"""Open a page in the current or [count]th tab.
arg: The URL to open.
"""
nargs = 1
@ -49,15 +48,19 @@ class Open(Command):
class OpenCur(Command):
"""Fill the statusbar with :open and the current url."""
nargs = 0
hide = True
class TabOpen(Command):
"""Open a page in a new tab.
arg: The URL to open.
"""
nargs = 1
@ -65,71 +68,93 @@ class TabOpen(Command):
class TabOpenCur(Command):
"""Fill the statusbar with :tabopen and the current url."""
nargs = 0
hide = True
class TabClose(Command):
"""Close the current tab, or tab [count]."""
nargs = 0
count = True
class TabNext(Command):
"""Switch to the next tab, or skip [count] tabs."""
nargs = 0
count = True
class TabPrev(Command):
"""Switch to the previous tab, or skip [count] tabs."""
nargs = 0
count = True
class Quit(Command):
"""Quit qutebrowser."""
name = ['quit', 'q']
nargs = 0
class Reload(Command):
"""Reload the current page, or the page in tab [count]."""
nargs = 0
count = True
class Stop(Command):
"""Stop loading the current page, or the page in tab [count]."""
nargs = 0
count = True
class Back(Command):
"""Go back one/[count] page(s) in the history."""
nargs = 0
count = True
class Forward(Command):
"""Go forward one/[count] page(s) in the history."""
nargs = 0
count = True
class Print(Command):
"""Print the current page, or the page in tab [count]."""
nargs = 0
count = True
class Scroll(Command):
"""Scroll in x/y direction by a number of pixels.
arg 1: delta x
arg 2: delta y
count: multiplicator
"""
nargs = 2
@ -138,15 +163,19 @@ class Scroll(Command):
class Undo(Command):
"""Undo closing a tab."""
nargs = 0
class ScrollPercX(Command):
"""Scroll N percent horizontally.
optional arg: How many percent to scroll.
count: How many percent to scroll.
"""
nargs = '?'
@ -156,10 +185,12 @@ class ScrollPercX(Command):
class ScrollPercY(Command):
"""Scroll N percent vertically.
optional arg: How many percent to scroll.
count: How many percent to scroll.
"""
nargs = '?'
@ -169,9 +200,11 @@ class ScrollPercY(Command):
class PyEval(Command):
"""Evaluate python code.
arg: The python code to evaluate.
"""
nargs = 1
@ -179,6 +212,7 @@ class PyEval(Command):
class NextSearch(Command):
"""Jump to the next or [count]th next search term."""
nargs = 0
@ -187,42 +221,52 @@ class NextSearch(Command):
class Yank(Command):
"""Yank the URL of the current tab to the clipboard.
optional arg: If 'sel', yank to the primary selection.
"""
nargs = '?'
class YankTitle(Command):
"""Yank the title of the current tab to the clipboard.
optional arg: If 'sel', yank to the primary selection.
"""
nargs = '?'
class Paste(Command):
"""Open an URL from the clipboard.
optional arg: If 'sel', paste from the primary selection.
"""
nargs = '?'
class TabPaste(Command):
"""Open an URL from the clipboard in a new tab.
optional arg: If 'sel', paste from the primary selection.
"""
nargs = '?'
class Crash(Command):
"""Simply raise an exception for debugging."""
nargs = 0
hide = True

View File

@ -1,6 +1,7 @@
"""Exception classes for commands.utils and commands.template.
Defined here to avoid circular dependency hell.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -22,10 +23,14 @@ Defined here to avoid circular dependency hell.
class NoSuchCommandError(ValueError):
"""Raised when a command wasn't found."""
pass
class ArgumentCountError(TypeError):
"""Raised when a command was called with an invalid count of arguments."""
pass

View File

@ -31,7 +31,9 @@ startchars = ":/?"
class KeyParser(QObject):
"""Parser for vim-like key sequences."""
keystring = '' # The currently entered key sequence
# Signal emitted when the statusbar should set a partial command
set_cmd_text = pyqtSignal(str)
@ -55,6 +57,7 @@ class KeyParser(QObject):
Config format: key = command, e.g.:
gg = scrollstart
"""
for (key, cmd) in sect.items():
if key.startswith('@') and key.endswith('@'):
@ -71,6 +74,7 @@ class KeyParser(QObject):
"""Handle a new keypress and call the respective handlers.
e -- the KeyPressEvent from Qt
"""
handled = self._handle_modifier_key(e)
if not handled:
@ -83,6 +87,7 @@ class KeyParser(QObject):
Returns True if the keypress has been handled, and False if not.
e -- the KeyPressEvent from Qt
"""
MODMASK2STR = {
Qt.ControlModifier: 'Ctrl',
@ -118,6 +123,7 @@ class KeyParser(QObject):
displays an error.
e -- the KeyPressEvent from Qt
"""
# FIXME maybe we can do this in an easier way by using QKeySeqyence
# which has a matches method.
@ -169,6 +175,7 @@ class KeyParser(QObject):
"""Try to match a given keystring with any bound keychain.
cmdstr_needle: The command string to find.
"""
try:
cmdstr_hay = self.bindings[cmdstr_needle]
@ -187,9 +194,10 @@ class KeyParser(QObject):
return (self.MATCH_NONE, None)
def _normalize_keystr(self, keystr):
"""Normalizes a keystring like Ctrl-Q to a keystring like Ctrl+Q.
"""Normalize a keystring like Ctrl-Q to a keystring like Ctrl+Q.
keystr -- The key combination as a string.
"""
replacements = [
('Control', 'Ctrl'),
@ -205,11 +213,12 @@ class KeyParser(QObject):
return keystr
def _run_or_fill(self, cmdstr, count=None, ignore_exc=True):
"""Runs the command in cmdstr or fills the statusbar if args missing.
"""Run the command in cmdstr or fill the statusbar if args missing.
cmdstr -- The command string.
count -- Optional command count.
ignore_exc -- Ignore exceptions.
"""
try:
self.commandparser.run(cmdstr, count=count, ignore_exc=ignore_exc)

View File

@ -25,9 +25,11 @@ from qutebrowser.commands.exceptions import ArgumentCountError
class Command(QObject):
"""Base skeleton for a command.
See the module documentation for qutebrowser.commands.commands for details.
"""
# FIXME:
@ -53,8 +55,10 @@ class Command(QObject):
self.mainname = self.name[0]
def check(self, args):
"""Check if the argument count is valid. Raise ArgumentCountError if
not.
"""Check if the argument count is valid.
Raise ArgumentCountError if not.
"""
if ((isinstance(self.nargs, int) and len(args) != self.nargs) or
(self.nargs == '?' and len(args) > 1) or
@ -63,10 +67,11 @@ class Command(QObject):
raise ArgumentCountError
def run(self, args=None, count=None):
"""Runs the command.
"""Run the command.
args -- Arguments to the command.
count -- Command repetition count.
"""
dbgout = ["command called:", self.mainname]
if args:

View File

@ -48,7 +48,9 @@ def register_all():
class SearchParser(QObject):
"""Parse qutebrowser searches."""
text = None
flags = 0
do_search = pyqtSignal(str, 'QWebPage::FindFlags')
@ -57,6 +59,7 @@ class SearchParser(QObject):
"""Search for a text on a website.
text -- The text to search for.
"""
self._search(text)
@ -64,6 +67,7 @@ class SearchParser(QObject):
"""Search for a text on a website in reverse direction.
text -- The text to search for.
"""
self._search(text, rev=True)
@ -72,6 +76,7 @@ class SearchParser(QObject):
text -- The text to search for.
rev -- Search direction.
"""
if self.text != text:
self.do_search.emit('', 0)
@ -93,7 +98,9 @@ class SearchParser(QObject):
class CommandParser(QObject):
"""Parse qutebrowser commandline commands."""
text = ''
cmd = ''
args = []
@ -103,6 +110,7 @@ class CommandParser(QObject):
"""Split the commandline text into command and arguments.
Raise NoSuchCommandError if a command wasn't found.
"""
self.text = text
parts = self.text.strip().split(maxsplit=1)
@ -142,6 +150,7 @@ class CommandParser(QObject):
Raise NoSuchCommandError if a command wasn't found, and
ArgumentCountError if a command was called with the wrong count of
arguments.
"""
try:
self._parse(text)

View File

@ -1,4 +1,4 @@
"""Utility functions"""
"""Misc utility functions."""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
@ -62,6 +62,7 @@ def _git_str():
"""Try to find out git version and return a string if possible.
Return None if there was an error or we're not in a git repo.
"""
# FIXME this runs in PWD, not the qutebrowser dir?!
if not os.path.isdir(".git"):

View File

@ -42,6 +42,7 @@ def handle(url):
"""Handle about page with an url.
Returns HTML content.
"""
if not is_about_url(url):
raise ValueError
@ -59,11 +60,13 @@ def _get_html(title, snippet):
title -- The title the page should have.
snippet -- The html snippet.
"""
return _html_template.format(title=title, body=snippet).encode('UTF-8')
class AboutHandlers:
"""Handlers for about:... pages."""
@classmethod

View File

@ -4,6 +4,7 @@ Contains:
CompletionModel -- A simple tree model based on Python data.
CompletionItem -- One item in the CompletionModel.
CompletionFilterModel -- A QSortFilterProxyModel subclass for completions.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -34,6 +35,7 @@ class CompletionModel(QAbstractItemModel):
"""A simple tree model based on Python OrderdDict containing tuples.
Used for showing completions later in the CompletionView.
"""
def __init__(self, parent=None):
@ -48,6 +50,7 @@ class CompletionModel(QAbstractItemModel):
"""Remove rows from the model.
Overrides QAbstractItemModel::removeRows.
"""
node = self._node(parent)
self.beginRemoveRows(parent, position, position + count - 1)
@ -59,6 +62,7 @@ class CompletionModel(QAbstractItemModel):
Returns the CompletionItem for index, or the root CompletionItem if the
index was invalid.
"""
if index.isValid():
return self.id_map[index.internalId()]
@ -69,6 +73,7 @@ class CompletionModel(QAbstractItemModel):
"""Return the column count in the model.
Overrides QAbstractItemModel::columnCount.
"""
# pylint: disable=unused-argument
return self.root.column_count()
@ -78,6 +83,7 @@ class CompletionModel(QAbstractItemModel):
Returns an invalid QVariant on error.
Overrides QAbstractItemModel::data.
"""
if not index.isValid():
return QVariant()
@ -95,6 +101,7 @@ class CompletionModel(QAbstractItemModel):
Returns Qt.NoItemFlags on error.
Overrides QAbstractItemModel::flags.
"""
# FIXME categories are not selectable, but moving via arrow keys still
# tries to select them
@ -111,6 +118,7 @@ class CompletionModel(QAbstractItemModel):
Returns an invalid QVariant on error.
Overrides QAbstractItemModel::headerData.
"""
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return QVariant(self.root.data(section))
@ -121,6 +129,7 @@ class CompletionModel(QAbstractItemModel):
Returns True on success, False on failure.
Overrides QAbstractItemModel::setData.
"""
if not index.isValid():
return False
@ -137,6 +146,7 @@ class CompletionModel(QAbstractItemModel):
Returns an invalid QModelIndex on failure.
Overrides QAbstractItemModel::index.
"""
if (0 <= row < self.rowCount(parent) and
0 <= column < self.columnCount(parent)):
@ -162,6 +172,7 @@ class CompletionModel(QAbstractItemModel):
Returns an invalid QModelIndex on failure.
Overrides QAbstractItemModel::parent.
"""
if not index.isValid():
return QModelIndex()
@ -171,10 +182,11 @@ class CompletionModel(QAbstractItemModel):
return self.createIndex(item.row(), 0, id(item))
def rowCount(self, parent=QModelIndex()):
"""Return the rowCount (children count) for a parent.
"""Return the children count of an item.
Uses the root frame if parent is invalid.
Overrides QAbstractItemModel::data.
"""
if parent.column() > 0:
return 0
@ -191,6 +203,7 @@ class CompletionModel(QAbstractItemModel):
Raises NotImplementedError, should be overwritten in a superclass.
Overrides QAbstractItemModel::sort.
"""
raise NotImplementedError
@ -209,6 +222,7 @@ class CompletionModel(QAbstractItemModel):
"""Mark a string in all items (children of root-children).
needle -- The string to mark.
"""
for i in range(self.rowCount()):
cat = self.index(i, 0)
@ -234,6 +248,7 @@ class CompletionModel(QAbstractItemModel):
class CompletionItem():
"""An item (row) in a CompletionModel."""
parent = None
@ -246,6 +261,7 @@ class CompletionItem():
data -- The data for the model, as tuple (columns).
parent -- An optional parent item.
"""
self.parent = parent
self._data = data
@ -256,6 +272,7 @@ class CompletionItem():
"""Get the data for role/column.
Raise ValueError if the role is invalid.
"""
if role == Qt.DisplayRole:
return self._data[column]
@ -268,6 +285,7 @@ class CompletionItem():
"""Set the data for column/role to value.
Raise ValueError if the role is invalid.
"""
if role == Qt.DisplayRole:
self._data[column] = value
@ -307,6 +325,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
"""Set a new source model and clear the pattern.
model -- The new source model.
"""
self.setSourceModel(model)
self.srcmodel = model
@ -320,6 +339,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
If the current completion model overrides sort(), it is used.
If not, the default implementation in QCompletionFilterModel is called.
"""
self._pattern = val
self.invalidateFilter()
@ -342,6 +362,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
Returns True if self.pattern is contained in item, or if it's a root
item (category). Else returns False.
"""
if parent == QModelIndex():
return True
@ -360,6 +381,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
Prefers all items which start with self.pattern. Other than that, uses
normal Python string sorting.
"""
left = self.srcmodel.data(lindex).value()
right = self.srcmodel.data(rindex).value()
@ -377,11 +399,11 @@ class CompletionFilterModel(QSortFilterProxyModel):
return left < right
def first_item(self):
"""Returns the first item in the model."""
"""Return the first item in the model."""
cat = self.index(0, 0)
return self.index(0, 0, cat)
def last_item(self):
"""Returns the last item in the model."""
"""Return the last item in the model."""
cat = self.index(self.rowCount() - 1, 0)
return self.index(self.rowCount(cat) - 1, 0, cat)

View File

@ -4,6 +4,7 @@ config -- The main Config object.
colordict -- All configured colors.
default_config -- The default config as dict.
MONOSPACE -- A list of suitable monospace fonts.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -128,10 +129,10 @@ def get_stylesheet(template):
class ColorDict(dict):
"""A dict aimed at Qt stylesheet colors."""
def __getitem__(self, key):
"""Override dict __getitem__.
If a value wasn't found, return an empty string.
@ -141,8 +142,8 @@ class ColorDict(dict):
If the key has a .bg. element in it, return background-color: X;.
In all other cases, return the plain value.
"""
"""
try:
val = super().__getitem__(key)
except KeyError:
@ -158,6 +159,7 @@ class ColorDict(dict):
"""Get a value without the transformations done in __getitem__.
Returns a value, or None if the value wasn't found.
"""
try:
return super().__getitem__(key)
@ -166,6 +168,7 @@ class ColorDict(dict):
class Config(ConfigParser):
"""Our own ConfigParser subclass."""
configdir = None
@ -177,6 +180,7 @@ class Config(ConfigParser):
"""Config constructor.
configdir -- directory to store the config in.
"""
super().__init__(interpolation=ExtendedInterpolation())
self.default_cp = ConfigParser(interpolation=ExtendedInterpolation())
@ -197,6 +201,7 @@ class Config(ConfigParser):
"""Get an item from the configparser or default dict.
Extends ConfigParser's __getitem__.
"""
try:
return super().__getitem__(key)
@ -207,6 +212,7 @@ class Config(ConfigParser):
"""Get an item from the configparser or default dict.
Extends ConfigParser's get().
"""
if 'fallback' in kwargs:
del kwargs['fallback']
@ -226,9 +232,7 @@ class Config(ConfigParser):
os.fsync(f.fileno())
def dump_userconfig(self):
"""Returns the part of the config which was changed by the user as a
string.
"""
"""Return the part of the config which was changed by the user."""
with io.StringIO() as f:
self.write(f)
return f.getvalue()

View File

@ -2,6 +2,7 @@
In its own file so it doesn't include any Qt stuff, because if it did, it
wouldn't work.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -33,6 +34,7 @@ def fix():
This fixes crashes on various sites.
See https://bugreports.qt-project.org/browse/QTBUG-36099
"""
if sys.platform.startswith('linux'):
# Switch to old but stable font rendering engine

View File

@ -19,6 +19,7 @@ def urlstring(url):
"""Return an QUrl as string.
qurl -- URL as string or QUrl.
"""
return url.url() if isinstance(url, QUrl) else url
@ -27,6 +28,7 @@ def fuzzy_url(url):
"""Return a QUrl based on an user input which is URL or search term.
url -- URL to load as QUrl or string.
"""
u = qurl(url)
urlstr = urlstring(url)

View File

@ -27,6 +27,7 @@ import qutebrowser.utils as utils
class CrashDialog(QDialog):
"""Dialog which gets shown after there was a crash."""
def __init__(self, pages, cmdhist, exc):

View File

@ -2,6 +2,7 @@
Defines BrowserTab (our own QWebView subclass) and TabbedBrowser (a TabWidget
containing BrowserTabs).
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -38,6 +39,7 @@ from qutebrowser.widgets.tabbar import TabWidget
class TabbedBrowser(TabWidget):
"""A TabWidget with QWebViews inside.
Provides methods to manage tabs, convenience methods to interact with the
@ -49,6 +51,7 @@ class TabbedBrowser(TabWidget):
emitted again if the current tab changes.
- the signal gets filtered with _filter_signals and self.cur_* gets
emitted if the signal occured in the current tab.
"""
cur_progress = pyqtSignal(int) # Progress of the current tab changed
@ -74,6 +77,7 @@ class TabbedBrowser(TabWidget):
"""Open a new tab with a given url.
Also connect all the signals we need to _filter_signals.
"""
logging.debug("Opening {}".format(url))
url = urlutils.qurl(url)
@ -104,6 +108,7 @@ class TabbedBrowser(TabWidget):
Command handler for :open.
url -- The URL to open.
"""
tab = self._widget(count)
if tab is not None:
@ -118,6 +123,7 @@ class TabbedBrowser(TabWidget):
"""Undo closing a tab.
Command handler for :undo.
"""
if self._url_stack:
self.tabopen(self._url_stack.pop())
@ -126,6 +132,7 @@ class TabbedBrowser(TabWidget):
"""Close the current/[count]th tab.
Command handler for :close.
"""
if self.count() > 1:
idx = self.currentIndex() if count is None else count - 1
@ -142,6 +149,7 @@ class TabbedBrowser(TabWidget):
"""Reload the current/[count]th tab.
Command handler for :reload.
"""
tab = self._widget(count)
if tab is not None:
@ -151,6 +159,7 @@ class TabbedBrowser(TabWidget):
"""Stop loading in the current/[count]th tab.
Command handler for :stop.
"""
tab = self._widget(count)
if tab is not None:
@ -160,6 +169,7 @@ class TabbedBrowser(TabWidget):
"""Print the current/[count]th tab.
Command handler for :print.
"""
# FIXME that does not what I expect
tab = self._widget(count)
@ -173,6 +183,7 @@ class TabbedBrowser(TabWidget):
Go back for 1 page if count is unset, else go back [count] pages.
Command handler for :back.
"""
# FIXME display warning if beginning of history
for i in range(count): # pylint: disable=unused-variable
@ -183,6 +194,7 @@ class TabbedBrowser(TabWidget):
Go forward for 1 page if count is unset, else go forward [count] pages.
Command handler for :forward.
"""
# FIXME display warning if end of history
for i in range(count): # pylint: disable=unused-variable
@ -193,13 +205,15 @@ class TabbedBrowser(TabWidget):
text -- The text to search for.
flags -- The QWebPage::FindFlags.
"""
self.currentWidget().findText(text, flags)
def cur_scroll(self, dx, dy, count=1):
"""Scroll the current tab by count * dx/dy
"""Scroll the current tab by count * dx/dy.
Command handler for :scroll.
"""
dx = int(count) * int(dx)
dy = int(count) * int(dy)
@ -207,17 +221,21 @@ class TabbedBrowser(TabWidget):
def cur_scroll_percent_x(self, perc=None, count=None):
"""Scroll the current tab to a specific percent of the page.
Accepts percentage either as argument, or as count.
Command handler for :scroll_perc_x.
"""
self._cur_scroll_percent(perc, count, Qt.Horizontal)
def cur_scroll_percent_y(self, perc=None, count=None):
"""Scroll the current tab to a specific percent of the page
"""Scroll the current tab to a specific percent of the page.
Accepts percentage either as argument, or as count.
Command handler for :scroll_perc_y
"""
self._cur_scroll_percent(perc, count, Qt.Vertical)
@ -239,6 +257,7 @@ class TabbedBrowser(TabWidget):
"""Switch to the ([count]th) previous tab.
Command handler for :tabprev.
"""
idx = self.currentIndex()
if idx - count >= 0:
@ -251,6 +270,7 @@ class TabbedBrowser(TabWidget):
"""Switch to the ([count]th) next tab.
Command handler for :tabnext.
"""
idx = self.currentIndex()
if idx + count < self.count():
@ -263,6 +283,7 @@ class TabbedBrowser(TabWidget):
"""Scroll when space is pressed.
This gets called from the space QShortcut in __init__.
"""
try:
amount = config.config['general']['space_scroll']
@ -274,6 +295,7 @@ class TabbedBrowser(TabWidget):
"""Yank the current url to the clipboard or primary selection.
Command handler for :yank.
"""
clip = QApplication.clipboard()
url = self.currentWidget().url().toString()
@ -285,6 +307,7 @@ class TabbedBrowser(TabWidget):
"""Yank the current title to the clipboard or primary selection.
Command handler for :yanktitle.
"""
clip = QApplication.clipboard()
title = self.tabText(self.currentIndex())
@ -296,6 +319,7 @@ class TabbedBrowser(TabWidget):
"""Open a page from the clipboard.
Command handler for :paste.
"""
# FIXME what happens for invalid URLs?
clip = QApplication.clipboard()
@ -308,6 +332,7 @@ class TabbedBrowser(TabWidget):
"""Open a page from the clipboard in a new tab.
Command handler for :paste.
"""
# FIXME what happens for invalid URLs?
clip = QApplication.clipboard()
@ -325,6 +350,7 @@ class TabbedBrowser(TabWidget):
"""Return a widget based on a count/idx.
If count is None, return the current widget.
"""
if count is None:
return self.currentWidget()
@ -337,6 +363,7 @@ class TabbedBrowser(TabWidget):
"""Set the title of a tab.
Slot for the titleChanged signal of any tab.
"""
logging.debug('title changed to "{}"'.format(text))
if text:
@ -345,12 +372,14 @@ class TabbedBrowser(TabWidget):
logging.debug('ignoring title change')
def _filter_factory(self, signal):
"""Returns a partial functon calling _filter_signals with a signal."""
"""Return a partial functon calling _filter_signals with a signal."""
return functools.partial(self._filter_signals, signal)
def _filter_signals(self, signal, *args):
"""Filter signals and trigger TabbedBrowser signals if the signal
was sent from the _current_ tab and not from any other one.
"""Filter signals and trigger TabbedBrowser signals if needed.
Triggers signal if the original signal was sent from the _current_ tab
and not from any other one.
The original signal does not matter, since we get the new signal and
all args.
@ -360,6 +389,7 @@ class TabbedBrowser(TabWidget):
signal -- The signal to emit if the sender was the current widget.
*args -- The args to pass to the signal.
"""
# FIXME BUG the signal cache ordering seems to be weird sometimes.
# How to reproduce:
@ -394,6 +424,7 @@ class TabbedBrowser(TabWidget):
Populates all signals from the signal cache.
Slot for the currentChanged signal.
"""
for (sigstr, (signal, args)) in self.widget(idx).signal_cache.items():
dbgstr = "{} ({})".format(sigstr, ','.join([str(e) for e in args]))
@ -402,10 +433,13 @@ class TabbedBrowser(TabWidget):
class BrowserTab(QWebView):
"""One browser tab in TabbedBrowser.
Our own subclass of a QWebView with some added bells and whistles.
"""
progress = 0
scroll_pos_changed = pyqtSignal(int, int)
open_tab = pyqtSignal('QUrl')
@ -427,6 +461,7 @@ class BrowserTab(QWebView):
"""Open an URL in the browser.
url -- The URL to load, as string or QUrl.
"""
u = urlutils.fuzzy_url(url)
logging.debug('New title: {}'.format(u.url()))
@ -449,6 +484,7 @@ class BrowserTab(QWebView):
tab (middle-click or control) or not, and does so.
url -- The url to handle, as string or QUrl.
"""
if self._open_new_tab:
self.open_tab.emit(url)
@ -461,6 +497,7 @@ class BrowserTab(QWebView):
Slot for the loadProgress signal.
prog -- New progress.
"""
self.progress = prog
@ -473,6 +510,7 @@ class BrowserTab(QWebView):
watched -- The watched Qt object.
e -- The new event.
"""
if watched == self and e.type() == QEvent.Paint:
frame = self.page().mainFrame()
@ -499,7 +537,8 @@ class BrowserTab(QWebView):
This also is a bit of a hack, but it seems it's the only possible way.
Set the _open_new_tab attribute accordingly.
e -- The arrived event
e -- The arrived event.
"""
if e.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonDblClick]:
self._open_new_tab = (e.button() == Qt.MidButton or

View File

@ -1,8 +1,8 @@
"""Completion view which appears when something is typed in the statusbar
command section.
"""Completion view for statusbar command section.
Defines a CompletionView which uses CompletionFiterModel and CompletionModel
subclasses to provide completions.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
@ -37,12 +37,14 @@ from qutebrowser.commands.utils import CommandCompletionModel
class CompletionView(QTreeView):
"""The view showing available completions.
Based on QTreeView but heavily customized so root elements show as category
headers, and children show as flat list.
Highlights completions based on marks in the UserRole.
"""
_stylesheet = """
@ -111,6 +113,7 @@ class CompletionView(QTreeView):
Called from cmd_text_changed().
model -- A QAbstractItemModel with available completions.
"""
self.model.setsrc(self.completion_models[model])
self.expandAll()
@ -121,6 +124,7 @@ class CompletionView(QTreeView):
Slot for the resized signal of the statusbar.
geom -- A QRect containing the statusbar geometry.
"""
bottomleft = geom.topLeft()
bottomright = geom.topRight()
@ -135,6 +139,7 @@ class CompletionView(QTreeView):
Slot for the textChanged signal of the statusbar command widget.
text -- The new text
"""
if self.ignore_next:
# Text changed by a completion, so we don't have to complete again.
@ -161,6 +166,7 @@ class CompletionView(QTreeView):
statusbar. Called by key_(s)tab_handler in statusbar.command.
shift -- Whether shift is pressed or not.
"""
if not self.completing:
# No completion running at the moment, ignore keypress
@ -179,6 +185,7 @@ class CompletionView(QTreeView):
Used by tab_handler.
upwards -- Get previous item, not next.
"""
idx = self.selectionModel().currentIndex()
if not idx.isValid():
@ -197,6 +204,7 @@ class CompletionView(QTreeView):
class CompletionItemDelegate(QStyledItemDelegate):
"""Delegate used by CompletionView to draw individual items.
Mainly a cleaned up port of Qt's way to draw a TreeView item, except it
@ -204,6 +212,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
Original implementation:
qt/src/gui/styles/qcommonstyle.cpp:drawControl:2153
"""
opt = None
@ -211,10 +220,11 @@ class CompletionItemDelegate(QStyledItemDelegate):
painter = None
def sizeHint(self, option, index):
"""Overrides sizeHint of QStyledItemDelegate.
"""Override sizeHint of QStyledItemDelegate.
Returns the cell size based on the QTextDocument size, but might not
work correctly yet.
"""
value = index.data(Qt.SizeHintRole)
if value is not None:
@ -228,7 +238,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
docsize, self.opt.widget) + QSize(10, 0)
def paint(self, painter, option, index):
"""Overrides the QStyledItemDelegate paint function."""
"""Override the QStyledItemDelegate paint function."""
painter.save()
self.painter = painter
@ -244,12 +254,12 @@ class CompletionItemDelegate(QStyledItemDelegate):
painter.restore()
def _draw_background(self):
"""Draw the background of an ItemViewItem"""
"""Draw the background of an ItemViewItem."""
self.style.drawPrimitive(self.style.PE_PanelItemViewItem, self.opt,
self.painter, self.opt.widget)
def _draw_icon(self):
"""Draw the icon of an ItemViewItem"""
"""Draw the icon of an ItemViewItem."""
icon_rect = self.style.subElementRect(
self.style.SE_ItemViewItemDecoration, self.opt, self.opt.widget)
@ -269,6 +279,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
in Qt: We use a QTextDocument to draw text.
index of the item of the item -- The QModelIndex of the item to draw.
"""
if not self.opt.text:
return
@ -311,6 +322,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
doc -- The QTextDocument to draw.
text_rect -- The QRect to clip the drawing to.
"""
clip = QRectF(0, 0, text_rect.width(), text_rect.height())
doc.drawContents(self.painter, clip)
@ -319,6 +331,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
"""Return the QTextDocument of an item.
index -- The QModelIndex of the item to draw.
"""
# FIXME we probably should do eliding here. See
# qcommonstyle.cpp:viewItemDrawText
@ -358,7 +371,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
return doc
def _draw_focus_rect(self):
"""Draws the focus rectangle of an ItemViewItem"""
"""Draw the focus rectangle of an ItemViewItem."""
state = self.opt.state
if not state & QStyle.State_HasFocus:
return

View File

@ -25,11 +25,14 @@ from qutebrowser.widgets.completion import CompletionView
class MainWindow(QMainWindow):
"""The main window of QuteBrowser.
Adds all needed components to a vbox, initializes subwidgets and connects
signals.
"""
cwidget = None
vbox = None
tabs = None

View File

@ -27,7 +27,9 @@ from qutebrowser.widgets.statusbar.progress import Progress
class StatusBar(QWidget):
"""The statusbar at the bottom of the mainwindow"""
"""The statusbar at the bottom of the mainwindow."""
hbox = None
cmd = None
txt = None
@ -46,7 +48,7 @@ class StatusBar(QWidget):
"""
def __setattr__(self, name, value):
"""Update the stylesheet if relevant attributes have been changed"""
"""Update the stylesheet if relevant attributes have been changed."""
super().__setattr__(name, value)
if name == 'fgcolor' and value is not None:
config.colordict['statusbar.fg.__cur__'] = value
@ -78,13 +80,13 @@ class StatusBar(QWidget):
self.hbox.addWidget(self.prog)
def disp_error(self, text):
"""Displays an error in the statusbar"""
"""Displaysan error in the statusbar."""
self.bgcolor = config.colordict.getraw('statusbar.bg.error')
self.fgcolor = config.colordict.getraw('statusbar.fg.error')
self.txt.error = text
def clear_error(self):
"""Clears a displayed error from the status bar"""
"""Clear a displayed error from the status bar."""
self.bgcolor = config.colordict.getraw('statusbar.bg')
self.fgcolor = config.colordict.getraw('statusbar.fg')
self.txt.error = ''
@ -93,6 +95,7 @@ class StatusBar(QWidget):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.
e -- The QResizeEvent.
"""
super().resizeEvent(e)
self.resized.emit(self.geometry())

View File

@ -27,7 +27,9 @@ import qutebrowser.commands.keys as keys
class Command(QLineEdit):
"""The commandline part of the statusbar."""
# Emitted when a command is triggered by the user
got_cmd = pyqtSignal(str)
# Emitted for searches triggered by the user
@ -108,13 +110,12 @@ class Command(QLineEdit):
super().focusInEvent(e)
def _histbrowse_start(self):
"""Start browsing to the history.
Called when the user presses the up/down key and wasn't browsing the
history already.
"""
"""
pre = self.text().strip()
logging.debug('Preset text: "{}"'.format(pre))
if pre:
@ -157,16 +158,17 @@ class Command(QLineEdit):
class Validator(QValidator):
"""Validator to prevent the : from getting deleted"""
"""Validator to prevent the : from getting deleted."""
def validate(self, string, pos):
"""Overrides QValidator::validate.
"""Override QValidator::validate.
string -- The string to validate.
pos -- The current curser position.
Returns a tuple (status, string, pos) as a QValidator should.\
Returns a tuple (status, string, pos) as a QValidator should.
"""
if any(string.startswith(c) for c in keys.startchars):
return (QValidator.Acceptable, string, pos)

View File

@ -23,7 +23,9 @@ from PyQt5.QtWidgets import QProgressBar, QSizePolicy
class Progress(QProgressBar):
"""The progress bar part of the status bar."""
statusbar = None
color = None
_stylesheet = """
@ -67,12 +69,11 @@ class Progress(QProgressBar):
self.show()
def load_finished(self, ok):
"""Hide the progress bar or color it red, depending on ok.
Slot for the loadFinished signal of a QWebView.
"""
"""
if ok:
self.color = config.colordict.getraw('status.progress.bg')
self.hide()

View File

@ -26,7 +26,9 @@ class Text(QLabel):
"""The text part of the status bar.
Contains several parts (keystring, error, text, scrollperc) which are later
joined and displayed."""
joined and displayed.
"""
keystring = ''
error = ''

View File

@ -24,6 +24,7 @@ import qutebrowser.utils.config as config
class TabWidget(QTabWidget):
"""The tabwidget used for TabbedBrowser."""
# FIXME there is still some ugly 1px white stripe from somewhere if we do