Merge branch 'Kingdread-issue-1015'

This commit is contained in:
Florian Bruhin 2015-10-24 08:08:03 +02:00
commit 857a70ded7
4 changed files with 96 additions and 58 deletions

View File

@ -141,9 +141,9 @@ Contributors, sorted by the number of commits in descending order:
* Martin Tournoij * Martin Tournoij
* Raphael Pierzina * Raphael Pierzina
* Joel Torstensson * Joel Torstensson
* Daniel
* Claude * Claude
* Lamar Pavel * Lamar Pavel
* Daniel
* Nathan Isom * Nathan Isom
* Austin Anderson * Austin Anderson
* Artur Shaik * Artur Shaik

View File

@ -465,59 +465,6 @@ class TabBar(QTabBar):
super().tabRemoved(idx) super().tabRemoved(idx)
self._tabhide() self._tabhide()
def addTab(self, icon_or_text, text_or_empty=None):
"""Override addTab to use our own text setting logic.
Unfortunately QTabBar::addTab has these two overloads:
- const QIcon & icon, const QString & label
- const QString & label
This means we'll get different arguments based on the chosen overload.
Args:
icon_or_text: Either the QIcon to add or the label.
text_or_empty: Either the label or None.
Return:
The index of the newly added tab.
"""
if text_or_empty is None:
icon = None
text = icon_or_text
new_idx = super().addTab('')
else:
icon = icon_or_text
text = text_or_empty
new_idx = super().addTab(icon, '')
self.set_page_title(new_idx, text)
def insertTab(self, idx, icon_or_text, text_or_empty=None):
"""Override insertTab to use our own text setting logic.
Unfortunately QTabBar::insertTab has these two overloads:
- int index, const QIcon & icon, const QString & label
- int index, const QString & label
This means we'll get different arguments based on the chosen overload.
Args:
idx: Where to insert the widget.
icon_or_text: Either the QIcon to add or the label.
text_or_empty: Either the label or None.
Return:
The index of the newly added tab.
"""
if text_or_empty is None:
icon = None
text = icon_or_text
new_idx = super().InsertTab(idx, '')
else:
icon = icon_or_text
text = text_or_empty
new_idx = super().insertTab(idx, icon, '')
self.set_page_title(new_idx, text)
def wheelEvent(self, e): def wheelEvent(self, e):
"""Override wheelEvent to make the action configurable. """Override wheelEvent to make the action configurable.
@ -629,7 +576,7 @@ class TabBarStyle(QCommonStyle):
# any sophisticated drawing. # any sophisticated drawing.
super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget) super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
elif element == QStyle.CE_TabBarTabLabel: elif element == QStyle.CE_TabBarTabLabel:
if not opt.icon.isNull(): if not opt.icon.isNull() and layouts.icon.isValid():
self._draw_icon(layouts, opt, p) self._draw_icon(layouts, opt, p)
alignment = Qt.AlignLeft | Qt.AlignVCenter | Qt.TextHideMnemonic alignment = Qt.AlignLeft | Qt.AlignVCenter | Qt.TextHideMnemonic
self._style.drawItemText(p, layouts.text, alignment, opt.palette, self._style.drawItemText(p, layouts.text, alignment, opt.palette,
@ -721,6 +668,7 @@ class TabBarStyle(QCommonStyle):
else: else:
icon_padding = self.pixelMetric(PixelMetrics.icon_padding, opt) icon_padding = self.pixelMetric(PixelMetrics.icon_padding, opt)
icon_rect = self._get_icon_rect(opt, text_rect) icon_rect = self._get_icon_rect(opt, text_rect)
if icon_rect.isValid():
text_rect.adjust(icon_rect.width() + icon_padding, 0, 0, 0) text_rect.adjust(icon_rect.width() + icon_padding, 0, 0, 0)
text_rect = self._style.visualRect(opt.direction, opt.rect, text_rect) text_rect = self._style.visualRect(opt.direction, opt.rect, text_rect)
@ -751,5 +699,4 @@ class TabBarStyle(QCommonStyle):
icon_rect = QRect(text_rect.left(), text_rect.top() + 1, icon_rect = QRect(text_rect.left(), text_rect.top() + 1,
tab_icon_size.width(), tab_icon_size.height()) tab_icon_size.width(), tab_icon_size.height())
icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect) icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect)
qtutils.ensure_valid(icon_rect)
return icon_rect return icon_rect

View File

@ -26,8 +26,9 @@ from unittest import mock
from PyQt5.QtCore import pyqtSignal, QPoint, QProcess, QObject from PyQt5.QtCore import pyqtSignal, QPoint, QProcess, QObject
from PyQt5.QtNetwork import (QNetworkRequest, QAbstractNetworkCache, from PyQt5.QtNetwork import (QNetworkRequest, QAbstractNetworkCache,
QNetworkCacheMetaData) QNetworkCacheMetaData)
from PyQt5.QtWidgets import QCommonStyle from PyQt5.QtWidgets import QCommonStyle, QWidget
from qutebrowser.browser import webview
from qutebrowser.config import configexc from qutebrowser.config import configexc
@ -204,6 +205,18 @@ def fake_qprocess():
return m return m
class FakeWebView(QWidget):
"""Fake WebView which can be added to a tab."""
def __init__(self):
super().__init__()
self.progress = 0
self.scroll_pos = (-1, -1)
self.load_status = webview.LoadStatus.none
self.tab_id = 0
class FakeSignal: class FakeSignal:
"""Fake pyqtSignal stub which does nothing. """Fake pyqtSignal stub which does nothing.

View File

@ -0,0 +1,78 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015 Daniel Schadt
#
# 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/>.
"""Tests for the custom TabWidget/TabBar."""
import pytest
from qutebrowser.mainwindow import tabwidget
from qutebrowser.config import configtypes
from PyQt5.QtGui import QIcon, QPixmap, QFont, QColor
class TestTabWidget:
"""Tests for TabWidget."""
CONFIG = {
'fonts': {
'tabbar': QFont(),
},
'tabs': {
'show-switching-delay': 800,
'movable': True,
'position': 0,
'select-on-remove': 1,
'show': 'always',
'padding': configtypes.PaddingValues(0, 0, 5, 5),
'indicator-width': 3,
'indicator-padding': configtypes.PaddingValues(2, 2, 0, 4),
'title-format': '{index}: {title}',
},
'colors': {
'tabs.bg.bar': QColor(),
'tabs.bg.selected.even': QColor(),
'tabs.fg.selected.even': QColor(),
}
}
@pytest.fixture
def widget(self, qtbot, config_stub):
config_stub.data = self.CONFIG
w = tabwidget.TabWidget(0)
qtbot.addWidget(w)
return w
def test_small_icon_doesnt_crash(self, widget, qtbot, stubs):
"""Test that setting a small icon doesn't produce a crash.
Regression test for #1015.
"""
# Size taken from issue report
pixmap = QPixmap(72, 1)
icon = QIcon(pixmap)
page = stubs.FakeWebView()
widget.addTab(page, icon, 'foobar')
widget.show()
qtbot.waitForWindowShown(widget)
# We need to call close() here because closing needs the stubbed config
# on OS X, but when qtbot closes it, the config stub is already gone.
# WORKAROUND for https://github.com/pytest-dev/pytest-qt/issues/106
# https://github.com/The-Compiler/qutebrowser/pull/1048#issuecomment-150660769
widget.close()