Don't use signals for on_config_changed.

This commit is contained in:
Florian Bruhin 2014-09-28 11:27:52 +02:00
parent 65d1d21d2e
commit 64a119afb2
18 changed files with 135 additions and 158 deletions

View File

@ -129,9 +129,6 @@ style
rewrite. rewrite.
- Use separate logger for config - Use separate logger for config
- Use unittest.Mock and especially unittest.patch more. - Use unittest.Mock and especially unittest.patch more.
- Use decorators for on_config_changed
- Will also make it easier to implement section-changed handlers for
:reload
- Check where using signals would be better than objreg.get. - Check where using signals would be better than objreg.get.
dwb keybindings to possibly implement dwb keybindings to possibly implement

View File

@ -294,7 +294,6 @@ class Application(QApplication):
message_bridge = objreg.get('message-bridge') message_bridge = objreg.get('message-bridge')
mode_manager = objreg.get('mode-manager') mode_manager = objreg.get('mode-manager')
prompter = objreg.get('prompter') prompter = objreg.get('prompter')
command_history = objreg.get('command-history')
download_manager = objreg.get('download-manager') download_manager = objreg.get('download-manager')
config_obj = objreg.get('config') config_obj = objreg.get('config')
key_config = objreg.get('key-config') key_config = objreg.get('key-config')
@ -331,9 +330,6 @@ class Application(QApplication):
# config # config
config_obj.style_changed.connect(style.get_stylesheet.cache_clear) config_obj.style_changed.connect(style.get_stylesheet.cache_clear)
for obj in (tabs, completion, main_window, command_history,
websettings, mode_manager, status, status.txt):
config_obj.changed.connect(obj.on_config_changed)
for obj in kp.values(): for obj in kp.values():
key_config.changed.connect(obj.on_keyconfig_changed) key_config.changed.connect(obj.on_keyconfig_changed)

View File

@ -27,8 +27,10 @@ we borrow some methods and classes from there where it makes sense.
import os import os
import sys import sys
import os.path import os.path
import inspect
import functools import functools
import configparser import configparser
import collections
import collections.abc import collections.abc
from PyQt5.QtCore import pyqtSignal, QObject, QStandardPaths from PyQt5.QtCore import pyqtSignal, QObject, QStandardPaths
@ -36,12 +38,39 @@ from PyQt5.QtWidgets import QMessageBox
from qutebrowser.utils import log from qutebrowser.utils import log
from qutebrowser.config import (configdata, iniparsers, configtypes, from qutebrowser.config import (configdata, iniparsers, configtypes,
textwrapper, lineparser, keyconfparser) textwrapper, keyconfparser)
from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.commands import cmdexc, cmdutils
from qutebrowser.utils import message, objreg, utils from qutebrowser.utils import message, objreg, utils
from qutebrowser.utils.usertypes import Completion from qutebrowser.utils.usertypes import Completion
ChangeHandler = collections.namedtuple('ChangeHandler', ['func', 'section',
'option'])
change_handlers = []
def on_change(func, sectname=None, optname=None):
"""Register a new change handler.
Args:
func: The function to be called on change.
sectname: Filter for the config section.
If None, the handler gets called for all sections.
optname: Filter for the config option.
If None, the handler gets called for all options.
"""
if optname is not None and sectname is None:
raise TypeError("option is {} but section is None!".format(optname))
if sectname is not None and sectname not in configdata.DATA:
raise NoSectionError("Section '{}' does not exist!".format(sectname))
if optname is not None and optname not in configdata.DATA[sectname]:
raise NoOptionError("Option '{}' does not exist in section "
"'{}'!".format(optname, sectname))
change_handlers.append(ChangeHandler(func, sectname, optname))
def get(*args, **kwargs): def get(*args, **kwargs):
"""Convenience method to call get(...) of the config instance.""" """Convenience method to call get(...) of the config instance."""
return objreg.get('config').get(*args, **kwargs) return objreg.get('config').get(*args, **kwargs)
@ -102,6 +131,8 @@ def init(args):
objreg.register('key-config', key_config) objreg.register('key-config', key_config)
state_config = iniparsers.ReadWriteConfigParser(confdir, 'state') state_config = iniparsers.ReadWriteConfigParser(confdir, 'state')
objreg.register('state-config', state_config) objreg.register('state-config', state_config)
# We need to import this here because lineparser needs config.
from qutebrowser.config import lineparser
command_history = lineparser.LineConfigParser( command_history = lineparser.LineConfigParser(
confdir, 'cmd_history', ('completion', 'history-length')) confdir, 'cmd_history', ('completion', 'history-length'))
objreg.register('command-history', command_history) objreg.register('command-history', command_history)
@ -155,8 +186,6 @@ class ConfigManager(QObject):
_initialized: Whether the ConfigManager is fully initialized yet. _initialized: Whether the ConfigManager is fully initialized yet.
Signals: Signals:
changed: Gets emitted when the config has changed.
Args: the changed section, option and new value.
style_changed: When style caches need to be invalidated. style_changed: When style caches need to be invalidated.
Args: the changed section and option. Args: the changed section and option.
""" """
@ -164,7 +193,6 @@ class ConfigManager(QObject):
KEY_ESCAPE = r'\#[' KEY_ESCAPE = r'\#['
ESCAPE_CHAR = '\\' ESCAPE_CHAR = '\\'
changed = pyqtSignal(str, str)
style_changed = pyqtSignal(str, str) style_changed = pyqtSignal(str, str)
def __init__(self, configdir, fname, parent=None): def __init__(self, configdir, fname, parent=None):
@ -285,28 +313,42 @@ class ConfigManager(QObject):
e.option = k e.option = k
raise raise
def _emit_changed(self, sectname, optname): def _changed(self, sectname, optname):
"""Emit the appropriate signals for a changed config option.""" """Notify other objects the config has changed."""
log.misc.debug("Config option changed: {} -> {}".format( log.misc.debug("Config option changed: {} -> {}".format(
sectname, optname)) sectname, optname))
if sectname in ('colors', 'fonts'): if sectname in ('colors', 'fonts'):
self.style_changed.emit(sectname, optname) self.style_changed.emit(sectname, optname)
self.changed.emit(sectname, optname) for handler in change_handlers:
if handler.section is not None and handler.section != sectname:
continue
if handler.option is not None and handler.option != optname:
continue
param_count = len(inspect.signature(handler.func).parameters)
if param_count == 2:
handler.func(sectname, optname)
elif param_count == 1:
handler.func(sectname)
elif param_count == 0:
handler.func()
else:
raise TypeError("Handler {} has invalid signature.".format(
handler.func.__qualname__))
def _after_set(self, changed_sect, changed_opt): def _after_set(self, changed_sect, changed_opt):
"""Clean up caches and emit signals after an option has been set.""" """Clean up caches and emit signals after an option has been set."""
self.get.cache_clear() self.get.cache_clear()
self._emit_changed(changed_sect, changed_opt) self._changed(changed_sect, changed_opt)
# Options in the same section and ${optname} interpolation. # Options in the same section and ${optname} interpolation.
for optname, option in self.sections[changed_sect].items(): for optname, option in self.sections[changed_sect].items():
if '${' + changed_opt + '}' in option.value(): if '${' + changed_opt + '}' in option.value():
self._emit_changed(changed_sect, optname) self._changed(changed_sect, optname)
# Options in any section and ${sectname:optname} interpolation. # Options in any section and ${sectname:optname} interpolation.
for sectname, sect in self.sections.items(): for sectname, sect in self.sections.items():
for optname, option in sect.items(): for optname, option in sect.items():
if ('${' + changed_sect + ':' + changed_opt + '}' in if ('${' + changed_sect + ':' + changed_opt + '}' in
option.value()): option.value()):
self._emit_changed(sectname, optname) self._changed(sectname, optname)
def items(self, sectname, raw=True): def items(self, sectname, raw=True):
"""Get a list of (optname, value) tuples for a section. """Get a list of (optname, value) tuples for a section.

View File

@ -22,9 +22,8 @@
import os import os
import os.path import os.path
from PyQt5.QtCore import pyqtSlot
from qutebrowser.utils import log, utils from qutebrowser.utils import log, utils
from qutebrowser.config import config
class LineConfigParser: class LineConfigParser:
@ -58,6 +57,8 @@ class LineConfigParser:
else: else:
log.init.debug("Reading config from {}".format(self._configfile)) log.init.debug("Reading config from {}".format(self._configfile))
self.read(self._configfile) self.read(self._configfile)
if limit is not None:
config.on_change(self.cleanup_file, *limit)
def __repr__(self): def __repr__(self):
return utils.get_repr(self, constructor=True, return utils.get_repr(self, constructor=True,
@ -98,8 +99,6 @@ class LineConfigParser:
if not self.data: if not self.data:
log.destroy.debug("No data to save.") log.destroy.debug("No data to save.")
return return
# We need to import this here because config needs LineConfigParser.
from qutebrowser.config import config
limit = -1 if self._limit is None else config.get(*self._limit) limit = -1 if self._limit is None else config.get(*self._limit)
if limit == 0: if limit == 0:
return return
@ -113,14 +112,9 @@ class LineConfigParser:
with open(self._configfile, 'w', encoding='utf-8') as f: with open(self._configfile, 'w', encoding='utf-8') as f:
self.write(f, limit) self.write(f, limit)
@pyqtSlot(str, str) def cleanup_file(self, section, option):
def on_config_changed(self, section, option):
"""Delete the file if the limit was changed to 0.""" """Delete the file if the limit was changed to 0."""
if self._limit is None:
return
# We need to import this here because config needs LineConfigParser.
from qutebrowser.config import config
value = config.get(section, option) value = config.get(section, option)
if (section, option) == self._limit and value == 0: if value == 0:
if os.path.exists(self._configfile): if os.path.exists(self._configfile):
os.remove(self._configfile) os.remove(self._configfile)

View File

@ -49,8 +49,6 @@ def set_register_stylesheet(obj):
"""Set the stylesheet for an object based on it's STYLESHEET attribute. """Set the stylesheet for an object based on it's STYLESHEET attribute.
Also, register an update when the config is changed. 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: Args:
obj: The object to set the stylesheet for and register. obj: The object to set the stylesheet for and register.
@ -60,11 +58,10 @@ def set_register_stylesheet(obj):
log.style.vdebug("stylesheet for {}: {}".format( log.style.vdebug("stylesheet for {}: {}".format(
obj.__class__.__name__, qss)) obj.__class__.__name__, qss))
obj.setStyleSheet(qss) obj.setStyleSheet(qss)
objreg.get('config').changed.connect(functools.partial( config.on_change(functools.partial(update_stylesheet, obj))
_update_stylesheet, obj))
def _update_stylesheet(obj, _section, _option): def update_stylesheet(obj):
"""Update the stylesheet for obj.""" """Update the stylesheet for obj."""
obj.setStyleSheet(get_stylesheet(obj.STYLESHEET)) obj.setStyleSheet(get_stylesheet(obj.STYLESHEET))

View File

@ -28,7 +28,6 @@ Module attributes:
import os.path import os.path
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtCore import QStandardPaths from PyQt5.QtCore import QStandardPaths
@ -193,10 +192,10 @@ def init():
for optname, (typ, arg) in section.items(): for optname, (typ, arg) in section.items():
value = config.get(sectname, optname) value = config.get(sectname, optname)
_set_setting(typ, arg, value) _set_setting(typ, arg, value)
config.on_change(update_settings)
@pyqtSlot(str, str) def update_settings(section, option):
def on_config_changed(section, option):
"""Update global settings when qwebsettings changed.""" """Update global settings when qwebsettings changed."""
try: try:
typ, arg = MAPPINGS[section][option] typ, arg = MAPPINGS[section][option]

View File

@ -348,7 +348,7 @@ class BaseKeyParser(QObject):
def on_keyconfig_changed(self, mode): def on_keyconfig_changed(self, mode):
"""Re-read the config if a keybinding was changed.""" """Re-read the config if a keybinding was changed."""
if self._modename is None: if self._modename is None:
raise AttributeError("on_config_changed called but no section " raise AttributeError("on_keyconfig_changed called but no section "
"defined!") "defined!")
if mode == self._modename: if mode == self._modename:
self.read_config() self.read_config()

View File

@ -24,7 +24,7 @@ Module attributes:
""" """
from PyQt5.QtGui import QWindow from PyQt5.QtGui import QWindow
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent from PyQt5.QtCore import pyqtSignal, QObject, QEvent
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from qutebrowser.keyinput import modeparsers, keyparser from qutebrowser.keyinput import modeparsers, keyparser
@ -131,7 +131,9 @@ class ModeManager(QObject):
self.passthrough = [] self.passthrough = []
self._mode_stack = [] self._mode_stack = []
self._releaseevents_to_pass = [] self._releaseevents_to_pass = []
self._forward_unbound_keys = config.get('input', self._forward_unbound_keys = config.get(
'input', 'forward-unbound-keys')
config.on_change(self.set_forward_unbound_keys, 'input',
'forward-unbound-keys') 'forward-unbound-keys')
def __repr__(self): def __repr__(self):
@ -287,12 +289,10 @@ class ModeManager(QObject):
raise ValueError("Can't leave normal mode!") raise ValueError("Can't leave normal mode!")
self.leave(self.mode(), 'leave current') self.leave(self.mode(), 'leave current')
@pyqtSlot(str, str) def set_forward_unbound_keys(self):
def on_config_changed(self, section, option):
"""Update local setting when config changed.""" """Update local setting when config changed."""
if (section, option) == ('input', 'forward-unbound-keys'): self._forward_unbound_keys = config.get(
self._forward_unbound_keys = config.get('input', 'input', 'forward-unbound-keys')
'forward-unbound-keys')
def eventFilter(self, obj, event): def eventFilter(self, obj, event):
"""Filter all events based on the currently set mode. """Filter all events based on the currently set mode.

View File

@ -19,7 +19,7 @@
"""CompletionModels for different usages.""" """CompletionModels for different usages."""
from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtCore import Qt
from qutebrowser.config import config, configdata from qutebrowser.config import config, configdata
from qutebrowser.models import basecompletion from qutebrowser.models import basecompletion
@ -46,7 +46,6 @@ class SettingOptionCompletionModel(basecompletion.BaseCompletionModel):
"""A CompletionModel filled with settings and their descriptions. """A CompletionModel filled with settings and their descriptions.
Attributes: Attributes:
_section: The section of this model.
_misc_items: A dict of the misc. column items which will be set later. _misc_items: A dict of the misc. column items which will be set later.
""" """
@ -57,7 +56,7 @@ class SettingOptionCompletionModel(basecompletion.BaseCompletionModel):
cat = self.new_category(section) cat = self.new_category(section)
sectdata = configdata.DATA[section] sectdata = configdata.DATA[section]
self._misc_items = {} self._misc_items = {}
self._section = section config.on_change(self.update_misc_column, section)
for name in sectdata.keys(): for name in sectdata.keys():
try: try:
desc = sectdata.descriptions[name] desc = sectdata.descriptions[name]
@ -72,11 +71,8 @@ class SettingOptionCompletionModel(basecompletion.BaseCompletionModel):
value) value)
self._misc_items[name] = miscitem self._misc_items[name] = miscitem
@pyqtSlot(str, str) def update_misc_column(self, section, option):
def on_config_changed(self, section, option):
"""Update misc column when config changed.""" """Update misc column when config changed."""
if section != self._section:
return
try: try:
item = self._misc_items[option] item = self._misc_items[option]
except KeyError: except KeyError:
@ -95,19 +91,13 @@ class SettingOptionCompletionModel(basecompletion.BaseCompletionModel):
class SettingValueCompletionModel(basecompletion.BaseCompletionModel): class SettingValueCompletionModel(basecompletion.BaseCompletionModel):
"""A CompletionModel filled with setting values. """A CompletionModel filled with setting values."""
Attributes:
_section: The section of this model.
_option: The option of this model.
"""
# pylint: disable=abstract-method # pylint: disable=abstract-method
def __init__(self, section, option=None, parent=None): def __init__(self, section, option=None, parent=None):
super().__init__(parent) super().__init__(parent)
self._section = section config.on_change(self.update_current_value, section, option)
self._option = option
cur_cat = self.new_category("Current", sort=0) cur_cat = self.new_category("Current", sort=0)
value = config.get(section, option, raw=True) value = config.get(section, option, raw=True)
if not value: if not value:
@ -128,11 +118,8 @@ class SettingValueCompletionModel(basecompletion.BaseCompletionModel):
for (val, desc) in vals: for (val, desc) in vals:
self.new_item(cat, val, desc) self.new_item(cat, val, desc)
@pyqtSlot(str, str) def update_current_value(self, section, option):
def on_config_changed(self, section, option):
"""Update current value when config changed.""" """Update current value when config changed."""
if (section, option) != (self._section, self._option):
return
value = config.get(section, option, raw=True) value = config.get(section, option, raw=True)
if not value: if not value:
value = '""' value = '""'

View File

@ -74,7 +74,6 @@ class Completer(QObject):
def _init_setting_completions(self): def _init_setting_completions(self):
"""Initialize setting completion models.""" """Initialize setting completion models."""
config_obj = objreg.get('config')
self._models[usertypes.Completion.section] = CFM( self._models[usertypes.Completion.section] = CFM(
models.SettingSectionCompletionModel(self), self) models.SettingSectionCompletionModel(self), self)
self._models[usertypes.Completion.option] = {} self._models[usertypes.Completion.option] = {}
@ -83,13 +82,11 @@ class Completer(QObject):
model = models.SettingOptionCompletionModel(sectname, self) model = models.SettingOptionCompletionModel(sectname, self)
self._models[usertypes.Completion.option][sectname] = CFM( self._models[usertypes.Completion.option][sectname] = CFM(
model, self) model, self)
config_obj.changed.connect(model.on_config_changed)
self._models[usertypes.Completion.value][sectname] = {} self._models[usertypes.Completion.value][sectname] = {}
for opt in configdata.DATA[sectname].keys(): for opt in configdata.DATA[sectname].keys():
model = models.SettingValueCompletionModel(sectname, opt, self) model = models.SettingValueCompletionModel(sectname, opt, self)
self._models[usertypes.Completion.value][sectname][opt] = CFM( self._models[usertypes.Completion.value][sectname][opt] = CFM(
model, self) model, self)
config_obj.changed.connect(model.on_config_changed)
def _get_new_completion(self, parts, cursor_part): def _get_new_completion(self, parts, cursor_part):
"""Get a new completion model. """Get a new completion model.

View File

@ -95,6 +95,9 @@ class CompletionView(QTreeView):
completer_obj = completer.Completer() completer_obj = completer.Completer()
objreg.register('completer', completer_obj) objreg.register('completer', completer_obj)
self.enabled = config.get('completion', 'show') self.enabled = config.get('completion', 'show')
config.on_change(self.set_enabled, 'completion', 'show')
# FIXME
#config.on_change(self.init_command_completion, 'aliases')
self._delegate = completiondelegate.CompletionItemDelegate(self) self._delegate = completiondelegate.CompletionItemDelegate(self)
self.setItemDelegate(self._delegate) self.setItemDelegate(self._delegate)
@ -195,13 +198,9 @@ class CompletionView(QTreeView):
if config.get('completion', 'shrink'): if config.get('completion', 'shrink'):
self.resize_completion.emit() self.resize_completion.emit()
@pyqtSlot(str, str) def set_enabled(self):
def on_config_changed(self, section, option):
"""Update self.enabled when the config changed.""" """Update self.enabled when the config changed."""
if section == 'completion' and option == 'show':
self.enabled = config.get('completion', 'show') self.enabled = config.get('completion', 'show')
elif section == 'aliases':
self._init_command_completion()
@pyqtSlot() @pyqtSlot()
def on_clear_completion_selection(self): def on_clear_completion_selection(self):

View File

@ -51,7 +51,8 @@ class ConsoleLineEdit(misc.CommandLineEdit):
sys.ps2 = '... ' sys.ps2 = '... '
super().__init__(parent) super().__init__(parent)
self.set_prompt(sys.ps1) self.set_prompt(sys.ps1)
self.setFont(config.get('fonts', 'debug-console')) self.update_font()
config.on_change(self.update_font, 'fonts', 'debug-console')
self._more = False self._more = False
self._buffer = [] self._buffer = []
interpreter_locals = { interpreter_locals = {
@ -144,9 +145,8 @@ class ConsoleLineEdit(misc.CommandLineEdit):
else: else:
super().keyPressEvent(e) super().keyPressEvent(e)
def on_config_changed(self, section, option): def update_font(self):
"""Update font when config changed.""" """Set the correct font."""
if section == 'fonts' and option == 'debug-console':
self.setFont(config.get('fonts', 'debug-console')) self.setFont(config.get('fonts', 'debug-console'))
@ -158,15 +158,15 @@ class ConsoleTextEdit(QTextEdit):
super().__init__(parent) super().__init__(parent)
self.setAcceptRichText(False) self.setAcceptRichText(False)
self.setReadOnly(True) self.setReadOnly(True)
self.setFont(config.get('fonts', 'debug-console')) config.on_change(self.update_font, 'fonts', 'debug-console')
self.update_font()
self.setFocusPolicy(Qt.NoFocus) self.setFocusPolicy(Qt.NoFocus)
def __repr__(self): def __repr__(self):
return utils.get_repr(self) return utils.get_repr(self)
def on_config_changed(self, section, option): def update_font(self):
"""Update font when config changed.""" """Update font when config changed."""
if section == 'fonts' and option == 'debug-console':
self.setFont(config.get('fonts', 'debug-console')) self.setFont(config.get('fonts', 'debug-console'))
@ -194,9 +194,3 @@ class ConsoleWidget(QWidget):
def __repr__(self): def __repr__(self):
return utils.get_repr(self, visible=self.isVisible()) return utils.get_repr(self, visible=self.isVisible())
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update font when config changed."""
self._lineedit.on_config_changed(section, option)
self._output.on_config_changed(section, option)

View File

@ -95,6 +95,9 @@ class MainWindow(QWidget):
# resizing will fail. Therefore, we use singleShot QTimers to make sure # resizing will fail. Therefore, we use singleShot QTimers to make sure
# we defer this until everything else is initialized. # we defer this until everything else is initialized.
QTimer.singleShot(0, self._connect_resize_completion) QTimer.singleShot(0, self._connect_resize_completion)
config.on_change(self.resize_completion, 'completion', 'height')
config.on_change(self.resize_completion, 'completion', 'shrink')
#self.retranslateUi(MainWindow) #self.retranslateUi(MainWindow)
#self.tabWidget.setCurrentIndex(0) #self.tabWidget.setCurrentIndex(0)
#QtCore.QMetaObject.connectSlotsByName(MainWindow) #QtCore.QMetaObject.connectSlotsByName(MainWindow)
@ -111,12 +114,6 @@ class MainWindow(QWidget):
"""Set some sensible default geometry.""" """Set some sensible default geometry."""
self.setGeometry(QRect(50, 50, 800, 600)) self.setGeometry(QRect(50, 50, 800, 600))
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Resize completion if config changed."""
if section == 'completion' and option in ('height', 'shrink'):
self.resize_completion()
@pyqtSlot() @pyqtSlot()
def resize_completion(self): def resize_completion(self):
"""Adjust completion according to config.""" """Adjust completion according to config."""

View File

@ -141,8 +141,9 @@ class StatusBar(QWidget):
self._timer_was_active = False self._timer_was_active = False
self._text_queue = collections.deque() self._text_queue = collections.deque()
self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') 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._text_pop_timer.timeout.connect(self._pop_text)
self.set_pop_timer_interval()
config.on_change(self.set_pop_timer_interval, 'ui', 'message-timeout')
self.prompt = prompt.Prompt() self.prompt = prompt.Prompt()
self._stack.addWidget(self.prompt) self._stack.addWidget(self.prompt)
@ -391,12 +392,9 @@ class StatusBar(QWidget):
if mode == usertypes.KeyMode.insert: if mode == usertypes.KeyMode.insert:
self._set_insert_active(False) self._set_insert_active(False)
@pyqtSlot(str, str) def set_pop_timer_interval(self):
def on_config_changed(self, section, option):
"""Update message timeout when config changed.""" """Update message timeout when config changed."""
if section == 'ui' and option == 'message-timeout': self._text_pop_timer.setInterval(config.get('ui', 'message-timeout'))
self._text_pop_timer.setInterval(config.get('ui',
'message-timeout'))
def resizeEvent(self, e): def resizeEvent(self, e):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards. """Extend resizeEvent of QWidget to emit a resized signal afterwards.

View File

@ -46,6 +46,7 @@ class Text(textbase.TextBase):
self._normaltext = '' self._normaltext = ''
self._temptext = '' self._temptext = ''
self._jstext = '' self._jstext = ''
config.on_change(self.update_text, 'ui', 'display-statusbar-messages')
def set_text(self, which, text): def set_text(self, which, text):
"""Set a text. """Set a text.
@ -64,7 +65,7 @@ class Text(textbase.TextBase):
self._jstext = text self._jstext = text
else: else:
raise ValueError("Invalid value {} for which!".format(which)) raise ValueError("Invalid value {} for which!".format(which))
self._update_text() self.update_text()
@pyqtSlot(str) @pyqtSlot(str)
def maybe_reset_text(self, text): def maybe_reset_text(self, text):
@ -75,7 +76,7 @@ class Text(textbase.TextBase):
else: else:
log.misc.debug("Ignoring reset: '{}'".format(text)) log.misc.debug("Ignoring reset: '{}'".format(text))
def _update_text(self): def update_text(self):
"""Update QLabel text when needed.""" """Update QLabel text when needed."""
if self._temptext: if self._temptext:
self.setText(self._temptext) self.setText(self._temptext)
@ -100,9 +101,3 @@ class Text(textbase.TextBase):
def on_tab_changed(self, tab): def on_tab_changed(self, tab):
"""Set the correct jstext when the current tab changed.""" """Set the correct jstext when the current tab changed."""
self._jstext = tab.statusbar_message self._jstext = tab.statusbar_message
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update text if display-statusbar-messages option changed."""
if (section, option) == ('ui', 'display-statusbar-messages'):
self._update_text()

View File

@ -113,6 +113,7 @@ class TabbedBrowser(tabwidget.TabWidget):
self._now_focused = None self._now_focused = None
# FIXME adjust this to font size # FIXME adjust this to font size
self.setIconSize(QSize(12, 12)) self.setIconSize(QSize(12, 12))
config.on_change(self.update_favicons, 'tabs', 'show-favicons')
def __repr__(self): def __repr__(self):
return utils.get_repr(self, count=self.count()) return utils.get_repr(self, count=self.count())
@ -381,13 +382,8 @@ class TabbedBrowser(tabwidget.TabWidget):
# We first want QWebPage to refresh. # We first want QWebPage to refresh.
QTimer.singleShot(0, check_scroll_pos) QTimer.singleShot(0, check_scroll_pos)
@pyqtSlot(str, str) def update_favicons(self):
def on_config_changed(self, section, option): """Update favicons when config was changed."""
"""Update tab config when config was changed."""
super().on_config_changed(section, option)
for tab in self._tabs:
tab.on_config_changed(section, option)
if (section, option) == ('tabs', 'show-favicons'):
show = config.get('tabs', 'show-favicons') show = config.get('tabs', 'show-favicons')
for i, tab in enumerate(self.widgets()): for i, tab in enumerate(self.widgets()):
if show: if show:

View File

@ -26,7 +26,7 @@ Module attributes:
import functools import functools
from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect, QPoint, QTimer from PyQt5.QtCore import Qt, QSize, QRect, QPoint, QTimer
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle, from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
QStyle, QStylePainter, QStyleOptionTab) QStyle, QStylePainter, QStyleOptionTab)
from PyQt5.QtGui import QIcon, QPalette, QColor from PyQt5.QtGui import QIcon, QPalette, QColor
@ -52,9 +52,10 @@ class TabWidget(QTabWidget):
self.setElideMode(Qt.ElideRight) self.setElideMode(Qt.ElideRight)
self.setUsesScrollButtons(True) self.setUsesScrollButtons(True)
bar.setDrawBase(False) bar.setDrawBase(False)
self._init_config() self.init_config()
config.on_change(self.init_config, 'tabs')
def _init_config(self): def init_config(self):
"""Initialize attributes based on the config.""" """Initialize attributes based on the config."""
position_conv = { position_conv = {
'north': QTabWidget.North, 'north': QTabWidget.North,
@ -78,13 +79,6 @@ class TabWidget(QTabWidget):
tabbar.setSelectionBehaviorOnRemove(select_conv[selstr]) tabbar.setSelectionBehaviorOnRemove(select_conv[selstr])
tabbar.refresh() tabbar.refresh()
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update attributes when config changed."""
self.tabBar().on_config_changed(section, option)
if section == 'tabs':
self._init_config()
class TabBar(QTabBar): class TabBar(QTabBar):
@ -101,18 +95,19 @@ class TabBar(QTabBar):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.setStyle(TabBarStyle(self.style())) self.setStyle(TabBarStyle(self.style()))
self.setFont(config.get('fonts', 'tabbar')) self.set_font()
config.on_change(self.set_font, 'fonts', 'tabbar')
self.vertical = False self.vertical = False
self.setAutoFillBackground(True) self.setAutoFillBackground(True)
p = self.palette() self.set_colors()
p.setColor(QPalette.Window, config.get('colors', 'tab.bg.bar')) config.on_change(self.set_colors, 'colors', 'tab.bg.bar')
self.setPalette(p) QTimer.singleShot(0, self.autohide)
QTimer.singleShot(0, self._autohide) config.on_change(self.autohide, 'tabs', 'auto-hide')
def __repr__(self): def __repr__(self):
return utils.get_repr(self, count=self.count()) return utils.get_repr(self, count=self.count())
def _autohide(self): def autohide(self):
"""Auto-hide the tabbar if needed.""" """Auto-hide the tabbar if needed."""
auto_hide = config.get('tabs', 'auto-hide') auto_hide = config.get('tabs', 'auto-hide')
if auto_hide and self.count() == 1: if auto_hide and self.count() == 1:
@ -136,17 +131,15 @@ class TabBar(QTabBar):
self.setTabData(idx, color) self.setTabData(idx, color)
self.update(self.tabRect(idx)) self.update(self.tabRect(idx))
@pyqtSlot(str, str) def set_font(self):
def on_config_changed(self, section, option): """Set the tabbar font."""
"""Update attributes when config changed."""
if section == 'fonts' and option == 'tabbar':
self.setFont(config.get('fonts', 'tabbar')) self.setFont(config.get('fonts', 'tabbar'))
elif section == 'colors' and option == 'tab.bg.bar':
def set_colors(self):
"""Set the tabbar colors."""
p = self.palette() p = self.palette()
p.setColor(QPalette.Window, config.get('colors', 'tab.bg.bar')) p.setColor(QPalette.Window, config.get('colors', 'tab.bg.bar'))
self.setPalette(p) self.setPalette(p)
elif section == 'tabs' and option == 'auto-hide':
self._autohide()
def mousePressEvent(self, e): def mousePressEvent(self, e):
"""Override mousePressEvent to close tabs if configured.""" """Override mousePressEvent to close tabs if configured."""
@ -256,12 +249,12 @@ class TabBar(QTabBar):
def tabInserted(self, idx): def tabInserted(self, idx):
"""Show the tabbar if configured to hide and >1 tab is open.""" """Show the tabbar if configured to hide and >1 tab is open."""
self._autohide() self.autohide()
super().tabInserted(idx) super().tabInserted(idx)
def tabRemoved(self, idx): def tabRemoved(self, idx):
"""Hide the tabbar if configured when only one tab is open.""" """Hide the tabbar if configured when only one tab is open."""
self._autohide() self.autohide()
super().tabRemoved(idx) super().tabRemoved(idx)

View File

@ -91,7 +91,9 @@ class WebView(QWebView):
self._force_open_target = None self._force_open_target = None
self._zoom = None self._zoom = None
self._has_ssl_errors = False self._has_ssl_errors = False
self._init_neighborlist() self.init_neighborlist()
config.on_change(self.init_neighborlist, 'ui', 'zoom-levels')
config.on_change(self.init_neighborlist, 'ui', 'default-zoom')
self._cur_url = None self._cur_url = None
self.cur_url = QUrl() self.cur_url = QUrl()
self.progress = 0 self.progress = 0
@ -133,7 +135,7 @@ class WebView(QWebView):
self.load_status = val self.load_status = val
self.load_status_changed.emit(val.name) self.load_status_changed.emit(val.name)
def _init_neighborlist(self): def init_neighborlist(self):
"""Initialize the _zoom neighborlist.""" """Initialize the _zoom neighborlist."""
levels = config.get('ui', 'zoom-levels') levels = config.get('ui', 'zoom-levels')
default = config.get('ui', 'default-zoom') default = config.get('ui', 'default-zoom')
@ -333,12 +335,6 @@ class WebView(QWebView):
self.cur_url = url self.cur_url = url
self.url_text_changed.emit(url.toDisplayString()) self.url_text_changed.emit(url.toDisplayString())
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update tab config when config was changed."""
if section == 'ui' and option in ('zoom-levels', 'default-zoom'):
self._init_neighborlist()
@pyqtSlot('QMouseEvent') @pyqtSlot('QMouseEvent')
def on_mouse_event(self, evt): def on_mouse_event(self, evt):
"""Post a new mouseevent from a hintmanager.""" """Post a new mouseevent from a hintmanager."""