Refactor signals

This commit is contained in:
Florian Bruhin 2016-06-13 14:44:41 +02:00
parent 4305966f7b
commit 048f7dcaf5
4 changed files with 124 additions and 41 deletions

View File

@ -19,6 +19,8 @@
"""Base class for a wrapper over QWebView/QWebEngineView."""
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QLayout
@ -48,11 +50,41 @@ class AbstractTab(QWidget):
"""A wrapper over the given widget to hide its API and expose another one.
We use this to unify QWebView QWebEngineView.
We use this to unify QWebView and QWebEngineView.
Signals:
See related Qt signals.
"""
window_close_requested = pyqtSignal()
link_hovered = pyqtSignal(str)
load_started = pyqtSignal()
load_progress = pyqtSignal(int)
load_finished = pyqtSignal(bool)
scroll_pos_changed = pyqtSignal(int, int)
icon_changed = pyqtSignal(QIcon)
url_text_changed = pyqtSignal(str) # FIXME get rid of this altogether?
title_changed = pyqtSignal(str)
load_status_changed = pyqtSignal(str)
def __init__(self, widget, parent=None):
super().__init__(parent)
self._layout = WrapperLayout(widget, self)
self._widget = widget
widget.setParent(self)
@property
def cur_url(self):
raise NotImplementedError
@property
def progress(self):
raise NotImplementedError
@property
def load_status(self):
raise NotImplementedError
@property
def scroll_pos(self):
raise NotImplementedError

View File

@ -0,0 +1,58 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Wrapper over our (QtWebKit) WebView."""
from PyQt5.QtCore import pyqtSlot
from qutebrowser.browser.tab import AbstractTab
from qutebrowser.browser.webkit.webview import WebView
class WebViewTab(AbstractTab):
def __init__(self, win_id, parent=None):
widget = WebView(win_id)
super().__init__(widget)
self._connect_signals()
def _connect_signals(self):
view = self._widget
page = view.page()
frame = page.mainFrame()
page.windowCloseRequested.connect(self.window_close_requested)
page.linkHovered.connect(self.link_hovered)
page.loadProgress.connect(self.load_progress)
frame.loadStarted.connect(self.load_started)
view.scroll_pos_changed.connect(self.scroll_pos_changed)
view.titleChanged.connect(self.title_changed)
view.url_text_changed.connect(self.url_text_changed)
view.load_status_changed.connect(self.load_status_changed)
# Make sure we emit an appropriate status when loading finished.
# While Qt has a bool "ok" attribute for loadFinished, it always is True
# when using error pages...
# See https://github.com/The-Compiler/qutebrowser/issues/84
frame.loadFinished.connect(lambda:
self.load_finished.emit(
not self._widget.page().error_occured))
# Emit iconChanged with a QIcon like QWebEngineView does.
view.iconChanged.connect(lambda:
self.icon_changed.emit(self._widget.icon()))

View File

@ -140,8 +140,8 @@ class UrlText(textbase.TextBase):
self._normal_url_type = UrlType.normal
self._update_url()
@pyqtSlot(str, str, str)
def set_hover_url(self, link, _title, _text):
@pyqtSlot(str)
def set_hover_url(self, link):
"""Setter to be used as a Qt slot.
Saves old shown URL in self._old_url and restores it later if a link is
@ -149,8 +149,6 @@ class UrlText(textbase.TextBase):
Args:
link: The link which was hovered (string)
_title: The title of the hovered link (string)
_text: The text of the hovered link (string)
"""
if link:
qurl = QUrl(link)

View File

@ -30,7 +30,7 @@ from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.mainwindow import tabwidget
from qutebrowser.browser import signalfilter
from qutebrowser.browser.webkit import webview
from qutebrowser.browser.webkit import webview, webkittab
from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
urlutils, message)
@ -71,13 +71,13 @@ class TabbedBrowser(tabwidget.TabWidget):
default_window_icon: The qutebrowser window icon
Signals:
cur_progress: Progress of the current tab changed (loadProgress).
cur_load_started: Current tab started loading (loadStarted)
cur_load_finished: Current tab finished loading (loadFinished)
cur_progress: Progress of the current tab changed (load_progress).
cur_load_started: Current tab started loading (load_started)
cur_load_finished: Current tab finished loading (load_finished)
cur_statusbar_message: Current tab got a statusbar message
(statusBarMessage)
cur_url_text_changed: Current URL text changed.
cur_link_hovered: Link hovered in current tab (linkHovered)
cur_link_hovered: Link hovered in current tab (link_hovered)
cur_scroll_perc_changed: Scroll percentage of current tab changed.
arg 1: x-position in %.
arg 2: y-position in %.
@ -95,7 +95,7 @@ class TabbedBrowser(tabwidget.TabWidget):
cur_load_finished = pyqtSignal(bool)
cur_statusbar_message = pyqtSignal(str)
cur_url_text_changed = pyqtSignal(str)
cur_link_hovered = pyqtSignal(str, str, str)
cur_link_hovered = pyqtSignal(str)
cur_scroll_perc_changed = pyqtSignal(int, int)
cur_load_status_changed = pyqtSignal(str)
close_window = pyqtSignal()
@ -170,19 +170,18 @@ class TabbedBrowser(tabwidget.TabWidget):
def _connect_tab_signals(self, tab):
"""Set up the needed signals for tab."""
page = tab.page()
frame = page.mainFrame()
# filtered signals
tab.linkHovered.connect(
tab.link_hovered.connect(
self._filter.create(self.cur_link_hovered, tab))
tab.loadProgress.connect(
tab.load_progress.connect(
self._filter.create(self.cur_progress, tab))
frame.loadFinished.connect(
tab.load_finished.connect(
self._filter.create(self.cur_load_finished, tab))
frame.loadStarted.connect(
tab.load_started.connect(
self._filter.create(self.cur_load_started, tab))
tab.statusBarMessage.connect(
self._filter.create(self.cur_statusbar_message, tab))
# https://github.com/The-Compiler/qutebrowser/issues/1579
# tab.statusBarMessage.connect(
# self._filter.create(self.cur_statusbar_message, tab))
tab.scroll_pos_changed.connect(
self._filter.create(self.cur_scroll_perc_changed, tab))
tab.scroll_pos_changed.connect(self.on_scroll_pos_changed)
@ -193,17 +192,17 @@ class TabbedBrowser(tabwidget.TabWidget):
tab.url_text_changed.connect(
functools.partial(self.on_url_text_changed, tab))
# misc
tab.titleChanged.connect(
tab.title_changed.connect(
functools.partial(self.on_title_changed, tab))
tab.iconChanged.connect(
tab.icon_changed.connect(
functools.partial(self.on_icon_changed, tab))
tab.loadProgress.connect(
tab.load_progress.connect(
functools.partial(self.on_load_progress, tab))
frame.loadFinished.connect(
tab.load_finished.connect(
functools.partial(self.on_load_finished, tab))
frame.loadStarted.connect(
tab.load_started.connect(
functools.partial(self.on_load_started, tab))
page.windowCloseRequested.connect(
tab.window_close_requested.connect(
functools.partial(self.on_window_close_requested, tab))
def current_url(self):
@ -378,7 +377,7 @@ class TabbedBrowser(tabwidget.TabWidget):
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=window.win_id)
return tabbed_browser.tabopen(url, background, explicit)
tab = webview.WebView(self._win_id, self)
tab = webkittab.WebViewTab(self._win_id, self)
self._connect_tab_signals(tab)
idx = self._get_new_tab_idx(explicit)
self.insertTab(idx, tab, "")
@ -479,7 +478,7 @@ class TabbedBrowser(tabwidget.TabWidget):
def on_title_changed(self, tab, text):
"""Set the title of a tab.
Slot for the titleChanged signal of any tab.
Slot for the title_changed signal of any tab.
Args:
tab: The WebView where the title was changed.
@ -515,14 +514,15 @@ class TabbedBrowser(tabwidget.TabWidget):
if not self.page_title(idx):
self.set_page_title(idx, url)
@pyqtSlot(webview.WebView)
def on_icon_changed(self, tab):
@pyqtSlot(webview.WebView, QIcon)
def on_icon_changed(self, tab, icon):
"""Set the icon of a tab.
Slot for the iconChanged signal of any tab.
Args:
tab: The WebView where the title was changed.
icon: The new icon
"""
if not config.get('tabs', 'show-favicons'):
return
@ -531,9 +531,9 @@ class TabbedBrowser(tabwidget.TabWidget):
except TabDeletedError:
# We can get signals for tabs we already deleted...
return
self.setTabIcon(idx, tab.icon())
self.setTabIcon(idx, icon)
if config.get('tabs', 'tabs-are-windows'):
self.window().setWindowIcon(tab.icon())
self.window().setWindowIcon(icon)
@pyqtSlot(usertypes.KeyMode)
def on_mode_left(self, mode):
@ -589,25 +589,20 @@ class TabbedBrowser(tabwidget.TabWidget):
if idx == self.currentIndex():
self.update_window_title()
def on_load_finished(self, tab):
"""Adjust tab indicator when loading finished.
We don't take loadFinished's ok argument here as it always seems to be
true when the QWebPage has an ErrorPageExtension implemented.
See https://github.com/The-Compiler/qutebrowser/issues/84
"""
def on_load_finished(self, tab, ok):
"""Adjust tab indicator when loading finished."""
try:
idx = self._tab_index(tab)
except TabDeletedError:
# We can get signals for tabs we already deleted...
return
if tab.page().error_occurred:
color = config.get('colors', 'tabs.indicator.error')
else:
if ok:
start = config.get('colors', 'tabs.indicator.start')
stop = config.get('colors', 'tabs.indicator.stop')
system = config.get('colors', 'tabs.indicator.system')
color = utils.interpolate_color(start, stop, 100, system)
else:
color = config.get('colors', 'tabs.indicator.error')
self.set_tab_indicator_color(idx, color)
self.update_tab_title(idx)
if idx == self.currentIndex():