This commit is contained in:
Florian Bruhin 2014-04-17 17:44:27 +02:00
parent 975d83b50e
commit 39f580d9f1
30 changed files with 239 additions and 151 deletions

View File

@ -168,7 +168,11 @@ class QuteBrowser(QApplication):
return parser.parse_args()
def _initlog(self):
"""Initialisation of the logging output."""
"""Initialisation of the logging output.
Raise:
ValueError if there was an invalid loglevel.
"""
loglevel = 'debug' if self._args.debug else self._args.loglevel
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
@ -190,7 +194,7 @@ class QuteBrowser(QApplication):
def _init_cmds(self):
"""Initialisation of the qutebrowser commands.
Registers all commands, connects its signals, and sets up keyparser.
Registers all commands and connects their signals.
"""
for key, cmd in sorted(cmdutils.cmd_dict.items()):
cmd.signal.connect(self.command_handler)

View File

@ -37,26 +37,22 @@ class CurCommandDispatcher(QObject):
cmdutils.register() decorators are run, currentWidget() will return None.
Attributes:
tabs: The TabbedBrowser object.
_tabs: The TabbedBrowser object.
Signals:
temp_message: Connected to TabbedBrowser signal.
"""
# FIXME maybe subclassing would be more clean?
temp_message = pyqtSignal(str)
def __init__(self, parent):
"""Constructor.
Uses setattr to get some methods from parent.
Args:
parent: The TabbedBrowser for this dispatcher.
"""
super().__init__(parent)
self.tabs = parent
self._tabs = parent
def _scroll_percent(self, perc=None, count=None, orientation=None):
"""Inner logic for scroll_percent_(x|y).
@ -72,7 +68,7 @@ class CurCommandDispatcher(QObject):
perc = int(count)
else:
perc = float(perc)
frame = self.tabs.currentWidget().page_.mainFrame()
frame = self._tabs.currentWidget().page_.mainFrame()
m = frame.scrollBarMaximum(orientation)
if m == 0:
return
@ -88,12 +84,12 @@ class CurCommandDispatcher(QObject):
url: The URL to open.
count: The tab index to open the URL in, or None.
"""
tab = self.tabs.cntwidget(count)
tab = self._tabs.cntwidget(count)
if tab is None:
if count is None:
# We want to open an URL in the current tab, but none exists
# yet.
self.tabs.tabopen(url)
self._tabs.tabopen(url)
else:
# Explicit count with a tab that doesn't exist.
return
@ -109,7 +105,7 @@ class CurCommandDispatcher(QObject):
Args:
count: The tab index to reload, or None.
"""
tab = self.tabs.cntwidget(count)
tab = self._tabs.cntwidget(count)
if tab is not None:
tab.reload()
@ -122,7 +118,7 @@ class CurCommandDispatcher(QObject):
Args:
count: The tab index to stop, or None.
"""
tab = self.tabs.cntwidget(count)
tab = self._tabs.cntwidget(count)
if tab is not None:
tab.stop()
@ -136,7 +132,7 @@ class CurCommandDispatcher(QObject):
count: The tab index to print, or None.
"""
# FIXME that does not what I expect
tab = self.tabs.cntwidget(count)
tab = self._tabs.cntwidget(count)
if tab is not None:
preview = QPrintPreviewDialog(self)
preview.paintRequested.connect(tab.print)
@ -153,7 +149,7 @@ class CurCommandDispatcher(QObject):
"""
# FIXME display warning if beginning of history
for _ in range(count):
self.tabs.currentWidget().back()
self._tabs.currentWidget().back()
@cmdutils.register(instance='mainwindow.tabs.cur')
def forward(self, count=1):
@ -166,7 +162,7 @@ class CurCommandDispatcher(QObject):
"""
# FIXME display warning if end of history
for _ in range(count):
self.tabs.currentWidget().forward()
self._tabs.currentWidget().forward()
@pyqtSlot(str, int)
def search(self, text, flags):
@ -176,7 +172,7 @@ class CurCommandDispatcher(QObject):
text: The text to search for.
flags: The QWebPage::FindFlags.
"""
self.tabs.currentWidget().findText(text, flags)
self._tabs.currentWidget().findText(text, flags)
@cmdutils.register(instance='mainwindow.tabs.cur', hide=True)
def scroll(self, dx, dy, count=1):
@ -191,7 +187,7 @@ class CurCommandDispatcher(QObject):
"""
dx = int(count) * float(dx)
dy = int(count) * float(dy)
self.tabs.currentWidget().page_.mainFrame().scroll(dx, dy)
self._tabs.currentWidget().page_.mainFrame().scroll(dx, dy)
@cmdutils.register(instance='mainwindow.tabs.cur', name='scroll_perc_x',
hide=True)
@ -229,7 +225,7 @@ class CurCommandDispatcher(QObject):
count: multiplier
"""
# FIXME this might not work with HTML frames
page = self.tabs.currentWidget().page_
page = self._tabs.currentWidget().page_
size = page.viewportSize()
page.mainFrame().scroll(int(count) * float(mx) * size.width(),
int(count) * float(my) * size.height())
@ -247,7 +243,7 @@ class CurCommandDispatcher(QObject):
temp_message to display a temporary message.
"""
clip = QApplication.clipboard()
url = urlutils.urlstring(self.tabs.currentWidget().url())
url = urlutils.urlstring(self._tabs.currentWidget().url())
mode = QClipboard.Selection if sel else QClipboard.Clipboard
clip.setText(url, mode)
self.temp_message.emit('URL yanked to {}'.format(
@ -266,7 +262,7 @@ class CurCommandDispatcher(QObject):
temp_message to display a temporary message.
"""
clip = QApplication.clipboard()
title = self.tabs.tabText(self.tabs.currentIndex())
title = self._tabs.tabText(self._tabs.currentIndex())
mode = QClipboard.Selection if sel else QClipboard.Clipboard
clip.setText(title, mode)
self.temp_message.emit('Title yanked to {}'.format(
@ -279,7 +275,7 @@ class CurCommandDispatcher(QObject):
Args:
count: How many steps to take.
"""
tab = self.tabs.currentWidget()
tab = self._tabs.currentWidget()
tab.zoom(count)
@cmdutils.register(instance='mainwindow.tabs.cur', name='zoomout')
@ -289,5 +285,5 @@ class CurCommandDispatcher(QObject):
Args:
count: How many steps to take.
"""
tab = self.tabs.currentWidget()
tab = self._tabs.currentWidget()
tab.zoom(-count)

View File

@ -91,7 +91,7 @@ class SignalFilter(QObject):
if self._tabs.currentWidget() == sender:
if log_signal:
logging.debug(' emitting')
return signal.emit(*args)
signal.emit(*args)
else:
if log_signal:
logging.debug(' ignoring')

View File

@ -117,6 +117,6 @@ class Command(QObject):
self.signal.emit((self.instance, self.handler.__name__, None,
args))
elif count is not None and self.count:
return self.handler(*args, count=count)
self.handler(*args, count=count)
else:
return self.handler(*args)
self.handler(*args)

View File

@ -15,7 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Parse keypresses/keychains in the main window."""
"""Parse keypresses/keychains in the main window.
Module attributes:
STARTCHARS: Possible chars for starting a commandline input.
"""
import re
import logging
@ -27,7 +31,6 @@ import qutebrowser.config.config as config
from qutebrowser.commands.parsers import (CommandParser, ArgumentCountError,
NoSuchCommandError)
# Possible chars for starting a commandline input
STARTCHARS = ":/?"
@ -35,6 +38,12 @@ class KeyParser(QObject):
"""Parser for vim-like key sequences.
Class Attributes:
MATCH_PARTIAL: Constant for a partial match (no keychain matched yet,
but it's still possible in the future.
MATCH_DEFINITIVE: Constant for a full match (keychain matches exactly).
MATCH_NONE: Constant for no match (no more matches possible).
Attributes:
commandparser: Commandparser instance.
_keystring: The currently entered key sequence
@ -241,7 +250,7 @@ class KeyParser(QObject):
"""Read the configuration.
Config format: key = command, e.g.:
gg = scrollstart
gg = scrollstart
"""
sect = config.instance['keybind']
if not sect.items():

View File

@ -27,6 +27,25 @@ from qutebrowser.commands.exceptions import (ArgumentCountError,
NoSuchCommandError)
def split_cmdline(text):
"""Convenience function to split a commandline into it's logical parts.
Args:
text: The string to split.
Return:
A list of strings.
"""
parser = CommandParser()
try:
parts = parser.parse(text)
except NoSuchCommandError:
parts = text.split(' ')
if text.endswith(' '):
parts.append('')
return parts
class SearchParser(QObject):
"""Parse qutebrowser searches.
@ -44,9 +63,9 @@ class SearchParser(QObject):
do_search = pyqtSignal(str, 'QWebPage::FindFlags')
def __init__(self, parent=None):
super().__init__(parent)
self._text = None
self._flags = 0
super().__init__(parent)
def _search(self, text, rev=False):
"""Search for a text on the current page.
@ -181,7 +200,7 @@ class CommandParser:
Raise:
NoSuchCommandError: if a command wasn't found.
ArgumentCountError: if a command was called with the wrong count of
arguments.
arguments.
Return:
True if command was called (handler returnstatus is ignored!).
@ -210,22 +229,3 @@ class CommandParser:
raise
self._run(count=count)
return True
def split_cmdline(text):
"""Split a commandline into it's logical parts.
Arguments:
text: The string to split.
Return:
A list of strings.
"""
parser = CommandParser()
try:
parts = parser.parse(text)
except NoSuchCommandError:
parts = text.split(' ')
if text.endswith(' '):
parts.append('')
return parts

View File

@ -15,14 +15,17 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Contains various command utils and a global command dict."""
"""Contains various command utils and a global command dict.
Module attributes:
cmd_dict: A mapping from command-strings to command objects.
"""
import inspect
from collections import Iterable
from qutebrowser.commands.command import Command
# A mapping from command-strings to command objects.
cmd_dict = {}
@ -52,7 +55,7 @@ class register: # pylint: disable=invalid-name
Gets called on parse-time with the decorator arguments.
Arguments:
Args:
See class attributes.
"""
self.name = name
@ -70,7 +73,7 @@ class register: # pylint: disable=invalid-name
Doesn't actually decorate anything, but creates a Command object and
registers it in the cmd_dict.
Arguments:
Args:
func: The function to be decorated.
Return:

View File

@ -20,6 +20,11 @@
This borrows a lot of ideas from configparser, but also has some things that
are fundamentally different. This is why nothing inherts from configparser, but
we borrow some methods and classes from there where it makes sense.
Module attributes:
instance: The "qutebrowser.conf" Config instance.
state: The "state" ReadWriteConfigParser instance.
cmd_history: The "cmd_history" LineConfigParser instance.
"""
import os
@ -32,7 +37,6 @@ from collections.abc import MutableMapping
from PyQt5.QtCore import pyqtSignal, QObject
#from qutebrowser.utils.misc import read_file
import qutebrowser.config.configdata as configdata
import qutebrowser.commands.utils as cmdutils
import qutebrowser.utils.message as message
@ -41,7 +45,7 @@ from qutebrowser.config.iniparsers import (ReadConfigParser,
ReadWriteConfigParser)
from qutebrowser.config.lineparser import LineConfigParser
instance = None # The main config instance
instance = None
state = None
cmd_history = None
@ -104,7 +108,7 @@ class Config(QObject):
def __init__(self, configdir, fname, parent=None):
super().__init__(parent)
self.sections = configdata.data
self.sections = configdata.DATA
self._configparser = ReadConfigParser(configdir, fname)
self._configfile = os.path.join(configdir, fname)
self._wrapper_args = {
@ -197,7 +201,7 @@ class Config(QObject):
def has_option(self, section, option):
"""Check if option exists in section.
Arguments:
Args:
section: The section name.
option: The option name
@ -211,7 +215,7 @@ class Config(QObject):
def remove_option(self, section, option):
"""Remove an option.
Arguments:
Args:
section: The section where to remove an option.
option: The option name to remove.
@ -233,14 +237,7 @@ class Config(QObject):
def get_wrapper(self, section, option):
"""Get the value from a section/option.
Wrapper for the get-command to output the value in the status bar
Arguments:
section: Section to get the value from
option: The option to get.
Return:
The value of the option.
Wrapper for the get-command to output the value in the status bar.
"""
val = self.get(section, option)
message.info("{} {} = {}".format(section, option, val))
@ -248,10 +245,13 @@ class Config(QObject):
def get(self, section, option, raw=False):
"""Get the value from a section/option.
Arguments:
Args:
section: The section to get the option from.
option: The option name
raw: Whether to get the uninterpolated, untransformed value.
Return:
The value of the option.
"""
logging.debug("getting {} -> {}".format(section, option))
try:
@ -277,9 +277,6 @@ class Config(QObject):
"""Set an option.
Wrapper for self.set() to output exceptions in the status bar.
Arguments:
*args: Get passed to self.set().
"""
try:
self.set('conf', section, option, value)
@ -292,9 +289,6 @@ class Config(QObject):
"""Set a temporary option.
Wrapper for self.set() to output exceptions in the status bar.
Arguments:
*args: Get passed to self.set().
"""
try:
self.set('temp', section, option, value)
@ -305,6 +299,7 @@ class Config(QObject):
"""Set an option.
Args:
layer: A layer name as string (conf/temp/default).
section: The name of the section to change.
option: The name of the option to change.
value: The new value.
@ -376,7 +371,7 @@ class SectionProxy(MutableMapping):
def __init__(self, conf, name):
"""Create a view on a section.
Arguments:
Args:
conf: The Config object.
name: The section name.
"""
@ -418,7 +413,7 @@ class SectionProxy(MutableMapping):
We deliberately don't support the default argument here, but have a raw
argument instead.
Arguments:
Args:
option: The option name to get.
raw: Whether to get a raw value or not.
"""

View File

@ -15,7 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Configuration data for config.py."""
"""Configuration data for config.py.
Module attributes:
FIRST_COMMENT: The initial comment header to place in the config.
SECTION_DESC: A dictionary with descriptions for sections.
DATA: The config defaults, an OrderedDict of sections.
"""
from collections import OrderedDict
@ -96,7 +103,7 @@ SECTION_DESC = {
}
data = OrderedDict([
DATA = OrderedDict([
('general', sect.KeyValue(
('show_completion',
SettingValue(types.Bool, "true"),

View File

@ -60,7 +60,7 @@ class BaseType:
"""A type used for a setting value.
Attributes:
Class attributes:
valid_values: Possible values if they can be expressed as a fixed
string. ValidValues instance.
typestr: The name of the type to appear in the config.
@ -96,7 +96,7 @@ class BaseType:
Raise:
ValidationError if the value was invalid.
NotImplementedError if self.valid_values is not defined and this
method should be overridden.
method should be overridden.
"""
if self.valid_values is not None:
if value not in self.valid_values:
@ -120,7 +120,11 @@ class String(BaseType):
class Bool(BaseType):
"""Base class for a boolean setting."""
"""Base class for a boolean setting.
Class attributes:
_BOOLEAN_STATES: A dictionary of strings mapped to their bool meanings.
"""
valid_values = ValidValues('true', 'false', show=False)
typestr = 'bool'
@ -198,7 +202,7 @@ class Perc(BaseType):
except ValueError:
raise ValidationError(value, "invalid percentage!")
else:
if not 0 <= intval:
if not intval >= 0:
raise ValidationError(value, "percentage needs to be >= 0!")

View File

@ -59,7 +59,7 @@ class LineConfigParser:
def write(self, fp, limit=-1):
"""Write the data to a file.
Arguments:
Args:
fp: A file object to write the data to.
limit: How many lines to write, or -1 for no limit.
"""

View File

@ -81,7 +81,7 @@ class Section:
def setv(self, layer, key, value):
"""Set the value on a layer.
Arguments:
Args:
layer: The layer to set the value on, an element name of the
ValueLayers dict.
key: The key of the element to set.
@ -166,7 +166,7 @@ class ValueList(Section):
def __init__(self, keytype, valtype, *defaults):
"""Wrap types over default values. Take care when overriding this.
Arguments:
Args:
keytype: The type to be used for keys.
valtype: The type to be used for values.
*defaults: A (key, value) list of default values.

View File

@ -15,7 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Utilities related to the look&feel of qutebrowser."""
"""Utilities related to the look&feel of qutebrowser.
Module attributes:
_colordict: The global cached ColorDict.
_fontdict: The global cached FontDict.
"""
from functools import partial
@ -46,6 +51,12 @@ def set_register_stylesheet(obj):
"""Set the stylesheet for an object based on it's STYLESHEET attribute.
Also, register an update when the config is changed.
This isn't really good OOP, but it's the cleanest solution I could think
of.
Args:
obj: The object to set the stylesheet for and register.
Must have a STYLESHEET attribute.
"""
obj.setStyleSheet(get_stylesheet(obj.STYLESHEET))
config.instance.changed.connect(partial(_update_stylesheet, obj))

View File

@ -93,7 +93,7 @@ class SettingValue:
def setv(self, layer, value):
"""Set the value on a layer.
Arguments:
Args:
layer: The layer to set the value on, an element name of the
ValueLayers dict.
value: The value to set.

View File

@ -15,7 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Bridge from QWebSettings to our own settings."""
"""Bridge from QWebSettings to our own settings.
Module attributes:
MAPPING: A mapping from internal setting names to QWebSetting enum
constants.
settings: The global QWebSettings singleton instance.
"""
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWebKit import QWebSettings

View File

@ -86,7 +86,14 @@ class History:
self._tmphist = None
def previtem(self):
"""Get the previous item in the temp history, or start browsing."""
"""Get the previous item in the temp history.
start() needs to be called before calling this.
Raise:
ValueError if start() wasn't called.
HistoryEndReachedError if the first item was reached.
"""
if not self.browsing:
raise ValueError("Currently not browsing history")
try:
@ -95,7 +102,14 @@ class History:
raise HistoryEndReachedError
def nextitem(self):
"""Get the next item in the temp history."""
"""Get the next item in the temp history.
start() needs to be called before calling this.
Raise:
ValueError if start() wasn't called.
HistoryEndReachedError if the last item was reached.
"""
if not self.browsing:
raise ValueError("Currently not browsing history")
try:

View File

@ -15,7 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""The base completion model for completion in the command line."""
"""The base completion model for completion in the command line.
Module attributes:
ROLE_MARKS: The role index used for marks.
"""
import logging
from PyQt5.QtCore import Qt, QVariant, QAbstractItemModel, QModelIndex

View File

@ -30,7 +30,7 @@ class SettingSectionCompletionModel(CompletionModel):
def __init__(self, parent=None):
super().__init__(parent)
cat = self.new_category("Config sections")
for name in configdata.data.keys():
for name in configdata.DATA.keys():
desc = configdata.SECTION_DESC[name].splitlines()[0].strip()
self.new_item(cat, name, desc)
@ -44,7 +44,7 @@ class SettingOptionCompletionModel(CompletionModel):
def __init__(self, section, parent=None):
super().__init__(parent)
cat = self.new_category("Config options for {}".format(section))
sectdata = configdata.data[section]
sectdata = configdata.DATA[section]
for name, _ in sectdata.items():
try:
desc = sectdata.descriptions[name]
@ -62,7 +62,7 @@ class SettingValueCompletionModel(CompletionModel):
def __init__(self, section, option, parent=None):
super().__init__(parent)
cat = self.new_category("Setting values for {}".format(option))
vals = configdata.data[section][option].typ.valid_values
vals = configdata.DATA[section][option].typ.valid_values
if vals is None:
raise NoCompletionsError
for val in vals:

View File

@ -15,7 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Handler functions for different qute:... pages."""
"""Handler functions for different qute:... pages.
Module attributes:
_HTML_TEMPLATE: The HTML boilerplate used to convert text into html.
pyeval_output: The output of the last :pyeval command.
"""
import logging
@ -52,6 +57,7 @@ def _get_html(title, snippet):
Return:
HTML content as bytes.
"""
# FIXME we should html-escape the body
return _HTML_TEMPLATE.format(title=title, body=snippet).encode('UTF-8')

View File

@ -41,7 +41,7 @@ def set_trace():
print(" from PyQt5 import QtCore; QtCore.pyqtRestoreInputHook()")
print("before executing c(ontinue).")
pyqtRemoveInputHook()
return pdb_set_trace()
pdb_set_trace()
def trace_lines(do_trace):
@ -51,7 +51,11 @@ def trace_lines(do_trace):
do_trace: Whether to start tracing (True) or stop it (False).
"""
def trace(frame, event, _):
"""Trace function passed to sys.settrace."""
"""Trace function passed to sys.settrace.
Return:
Itself, so tracing continues.
"""
print("{}, {}:{}".format(event, frame.f_code.co_filename,
frame.f_lineno))
return trace

View File

@ -15,19 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Message singleton so we don't have to define unneeded signals."""
"""Message singleton so we don't have to define unneeded signals.
Module attributes:
bridge: The MessageBridge instance.
"""
from PyQt5.QtCore import QObject, pyqtSignal
class MessageBridge(QObject):
"""Bridge for messages to be shown in the statusbar."""
error = pyqtSignal(str)
info = pyqtSignal(str)
bridge = None
@ -49,3 +45,11 @@ def error(message):
def info(message):
"""Display an info message in the statusbar."""
bridge.info.emit(message)
class MessageBridge(QObject):
"""Bridge for messages to be shown in the statusbar."""
error = pyqtSignal(str)
info = pyqtSignal(str)

View File

@ -27,13 +27,6 @@ from PyQt5.QtCore import QUrl
import qutebrowser.config.config as config
class SearchEngineError(Exception):
"""Exception raised when a search engine wasn't found."""
pass
def _get_search_url(txt):
"""Get a search engine URL for a text.
@ -202,3 +195,10 @@ def is_url(url):
return _is_url_naive(url)
else:
raise ValueError("Invalid autosearch value")
class SearchEngineError(Exception):
"""Exception raised when a search engine wasn't found."""
pass

View File

@ -15,11 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Custom useful datatypes."""
"""Custom useful datatypes.
Module attributes:
_UNSET: Used as default argument in the constructor so default can be None.
"""
import logging
# Used as default argument in the constructor so default can be None.
_UNSET = object()
@ -27,10 +30,12 @@ class NeighborList:
"""A list of items which saves it current position.
Attributes:
Class attributes:
BLOCK/WRAP/RAISE: Modes, see constructor documentation.
_items: A list of all items, accessed through item property.
Attributes:
idx: The current position in the list.
_items: A list of all items, accessed through item property.
_mode: The current mode.
"""

View File

@ -210,6 +210,9 @@ class BrowserTab(QWebView):
Emit:
scroll_pos_changed; If the scroll position changed.
Return:
The superclass event return value.
"""
frame = self.page_.mainFrame()
new_pos = (frame.scrollBarValue(Qt.Horizontal),

View File

@ -53,10 +53,12 @@ class CompletionView(QTreeView):
Highlights completions based on marks in the ROLE_MARKS data.
Class attributes:
STYLESHEET: The stylesheet template for the CompletionView.
Attributes:
_model: The currently active filter model.
_lastmodel: The model set in the last iteration.
STYLESHEET: The stylesheet template for the CompletionView.
_completion_models: dict of available completion models.
_ignore_next: Whether to ignore the next cmd_text_changed signal.
_enabled: Whether showing the CompletionView is enabled.
@ -110,10 +112,10 @@ class CompletionView(QTreeView):
'section': CompletionFilterModel(SettingSectionCompletionModel(
self)),
}
for sect in configdata.data.keys():
for sect in configdata.DATA.keys():
self._completion_models['option_' + sect] = CompletionFilterModel(
SettingOptionCompletionModel(sect, self))
for opt in configdata.data[sect].keys():
for opt in configdata.DATA[sect].keys():
try:
modelname = 'value_{}_{}'.format(sect, opt)
self._completion_models[modelname] = (
@ -349,7 +351,7 @@ class _CompletionItemDelegate(QStyledItemDelegate):
in Qt: We use a QTextDocument to draw text.
Args:
index -- The QModelIndex of the item to draw.
index: The QModelIndex of the item to draw.
"""
if not self._opt.text:
return

View File

@ -77,9 +77,6 @@ class MainWindow(QWidget):
self.status = StatusBar()
self._vbox.addWidget(self.status)
#self.status.resized.connect(self.completion.resize_to_bar)
#self.status.moved.connect(self.completion.move_to_bar)
#self.tabs.resized.connect(self.completion.on_browser_resized)
self.tabs.cur_progress.connect(self.status.prog.setValue)
self.tabs.cur_load_finished.connect(self.status.prog.hide)
self.tabs.cur_load_finished.connect(
@ -106,6 +103,10 @@ class MainWindow(QWidget):
#self.tabWidget.setCurrentIndex(0)
#QtCore.QMetaObject.connectSlotsByName(MainWindow)
def _set_default_geometry(self):
"""Set some sensible default geometry."""
self.setGeometry(QRect(50, 50, 800, 600))
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Resize completion if config changed."""
@ -129,10 +130,6 @@ class MainWindow(QWidget):
bottomright -= QPoint(0, self.inspector.height())
self.completion.setGeometry(QRect(topleft, bottomright))
def _set_default_geometry(self):
"""Set some sensible default geometry."""
self.setGeometry(QRect(50, 50, 800, 600))
@cmdutils.register(instance='mainwindow', name='inspector')
def toggle_inspector(self):
"""Toggle the web inspector."""
@ -142,7 +139,7 @@ class MainWindow(QWidget):
else:
if not config.get('webkit', 'developer_extras_enabled'):
self.status.disp_error("Please enable developer-extras before "
"using the webinspector!")
"using the webinspector!")
else:
self.inspector.show()
self.resize_completion()

View File

@ -35,6 +35,9 @@ class StatusBar(QWidget):
"""The statusbar at the bottom of the mainwindow.
Class attributes:
STYLESHEET: The stylesheet template.
Attributes:
cmd: The Command widget in the statusbar.
txt: The Text widget in the statusbar.
@ -46,7 +49,6 @@ class StatusBar(QWidget):
_stack: The QStackedLayout with cmd/txt widgets.
_error: If there currently is an error, accessed through the error
property.
STYLESHEET: The stylesheet template.
Signals:
resized: Emitted when the statusbar has resized, so the completion
@ -59,6 +61,7 @@ class StatusBar(QWidget):
resized = pyqtSignal('QRect')
moved = pyqtSignal('QPoint')
STYLESHEET = """
QWidget#StatusBar[error="false"] {{
{color[statusbar.bg]}
@ -103,7 +106,6 @@ class StatusBar(QWidget):
self._hide_cmd_widget()
self._hbox.addLayout(self._stack)
#self._hbox.addStretch()
self.keystring = _KeyString(self)
self._hbox.addWidget(self.keystring)
@ -248,7 +250,6 @@ class _Command(QLineEdit):
def __init__(self, statusbar):
super().__init__(statusbar)
# FIXME
self._statusbar = statusbar
self.setStyleSheet("""
QLineEdit {
@ -343,7 +344,7 @@ class _Command(QLineEdit):
"""
# FIXME we should consider the cursor position.
text = self.text()
if text[0] in ':/?':
if text[0] in keys.STARTCHARS:
prefix = text[0]
text = text[1:]
else:
@ -398,7 +399,7 @@ class _Progress(QProgressBar):
"""The progress bar part of the status bar.
Attributes:
Class attributes:
STYLESHEET: The stylesheet template.
"""
@ -583,12 +584,14 @@ class _Url(TextBase):
"""URL displayed in the statusbar.
Class attributes:
STYLESHEET: The stylesheet template.
Attributes:
_old_url: The URL displayed before the hover URL.
_old_urltype: The type of the URL displayed before the hover URL.
_urltype: The current URL type. One of normal/ok/error/warn/hover.
Accessed via the urltype property.
STYLESHEET: The stylesheet template.
"""
STYLESHEET = """

View File

@ -285,7 +285,7 @@ class TabbedBrowser(TabWidget):
if idx - count >= 0:
self.setCurrentIndex(idx - count)
else:
# FIXME
# FIXME display message or wrap
pass
@cmdutils.register(instance='mainwindow.tabs', name='tabnext')
@ -301,7 +301,7 @@ class TabbedBrowser(TabWidget):
if idx + count < self.count():
self.setCurrentIndex(idx + count)
else:
# FIXME
# FIXME display message or wrap
pass
@cmdutils.register(instance='mainwindow.tabs')

View File

@ -29,15 +29,13 @@ class TabWidget(QTabWidget):
"""The tabwidget used for TabbedBrowser.
Attributes:
Class attributes:
STYLESHEET: The stylesheet template to be used.
"""
# FIXME there is still some ugly 1px white stripe from somewhere if we do
# background-color: grey for QTabBar...
# pylint: disable=unused-argument
STYLESHEET = """
QTabWidget::pane {{
position: absolute;
@ -99,6 +97,7 @@ class TabWidget(QTabWidget):
except KeyError:
pass
# pylint: disable=unused-argument
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update attributes when config changed."""

View File

@ -1,8 +1,3 @@
""" Run different codecheckers over a codebase.
Runs flake8, pylint, pep257 and a CRLF/whitespace/conflict-checker by default.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
@ -20,6 +15,15 @@ Runs flake8, pylint, pep257 and a CRLF/whitespace/conflict-checker by default.
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
""" Run different codecheckers over a codebase.
Runs flake8, pylint, pep257 and a CRLF/whitespace/conflict-checker by default.
Module attributes:
status: An OrderedDict for return status values.
option: A dictionary with options.
"""
import sys
import subprocess
import os
@ -56,10 +60,11 @@ options = {
def run(name, args=None):
""" Run a checker via distutils with optional args.
"""Run a checker via distutils with optional args.
name -- Name of the checker/binary
args -- Option list of arguments to pass
Arguments:
name: Name of the checker/binary
args: Option list of arguments to pass
"""
sys.argv = [name, options['target']]
if args is not None:
@ -84,6 +89,7 @@ def run(name, args=None):
def check_pep257(args=None):
"""Run pep257 checker with args passed."""
sys.argv = ['pep257', options['target']]
if args is not None:
sys.argv += args
@ -97,14 +103,14 @@ def check_pep257(args=None):
def check_line():
"""Checks a filetree for CRLFs, conflict markers and weird whitespace"""
"""Run _check_file over a filetree."""
print("====== line ======")
ret = []
try:
for (dirpath, dirnames, filenames) in os.walk(options['target']):
for name in (e for e in filenames if e.endswith('.py')):
fn = os.path.join(dirpath, name)
ret.append(_check_line(fn))
ret.append(_check_file(fn))
status['line'] = all(ret)
except Exception as e:
print('{}: {}'.format(e.__class__.__name__, e))
@ -112,7 +118,8 @@ def check_line():
print()
def _check_line(fn):
def _check_file(fn):
"""Check a single file for CRLFs, conflict markers and weird whitespace."""
with open(fn, 'rb') as f:
for line in f:
if b'\r\n' in line:
@ -132,6 +139,11 @@ def _check_line(fn):
def _get_args(checker):
"""Construct the arguments for a given checker.
Return:
A list of commandline arguments.
"""
args = []
if checker == 'pylint':
try: