1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 10:46:35 +01:00

Added TabStackedWidget + ComboTabBar

Set of patches:
Introduce TabStackedWidget+ComboTabbar
[Windows] Fix enabling blur background in fullscreen
[ComboTabBar] Fix some issues with pinned tabs
[ComboTabBar] Don't use pointer to integer,
Implement TabStackedWidget::keyPressEvent() and fix changing tab by wheel event
Fix animation delay of dragged tab's buttons.
[ComboTabBar] Add themable scrollButtons
This commit is contained in:
S. Razi Alavizadeh 2013-11-26 14:14:36 +01:00 committed by nowrep
parent ed8ec5ab4a
commit bff614144b
18 changed files with 2417 additions and 315 deletions

View File

@ -1173,7 +1173,9 @@ bool MainApplication::restoreStateSlot(QupZilla* window, RestoreData recoveryDat
else {
// QTabWidget::count() - count of tabs is not updated after closing
// recovery tab ...
int tabCount = window->tabWidget()->count();
// update: it seems with ComboTabBar QTabWidget::count() is updated,
// we add pinnedTabCounts to currentTab!
int tabCount = window->tabWidget()->pinnedTabsCount();
RestoreManager::WindowData data = recoveryData.first();
data.currentTab += tabCount;
recoveryData.remove(0);

View File

@ -87,6 +87,7 @@
#include <QMessageBox>
#include <QDesktopWidget>
#include <QToolTip>
#include <QScrollArea>
#if QT_VERSION < 0x050000
#include "qwebkitversion.h"
@ -274,6 +275,8 @@ void QupZilla::postLaunch()
setUpdatesEnabled(true);
raise();
activateWindow();
QTimer::singleShot(0, tabWidget()->getTabBar(), SLOT(ensureVisible()));
}
void QupZilla::setupUi()
@ -344,7 +347,7 @@ void QupZilla::setupUi()
m_navigationContainer->setLayout(l);
m_mainSplitter->addWidget(m_tabWidget);
m_mainLayout->addWidget(m_navigationContainer);
triggerTabsOnTop(tabsOnTop());
m_mainLayout->addWidget(m_mainSplitter);
m_mainSplitter->setCollapsible(0, false);
@ -838,7 +841,7 @@ void QupZilla::loadSettings()
if (m_usingTransparentBackground && !makeTransparent) {
QtWin::extendFrameIntoClientArea(this, 0, 0, 0, 0);
QtWin::enableBlurBehindWindow(this, false);
QtWin::enableBlurBehindWindow(m_tabWidget->getTabBar(), false);
m_tabWidget->getTabBar()->enableBluredBackground(false);
m_usingTransparentBackground = false;
}
#endif
@ -866,11 +869,14 @@ void QupZilla::loadSettings()
m_usingTransparentBackground = true;
QtWin::enableBlurBehindWindow(m_tabWidget->getTabBar(), true);
QtWin::extendFrameIntoClientArea(this);
if (!isFullScreen()) {
m_tabWidget->getTabBar()->enableBluredBackground(true);
QtWin::extendFrameIntoClientArea(this);
}
//install event filter
menuBar()->installEventFilter(this);
m_tabWidget->getTabBar()->installEventFilter(this);
m_navigationBar->installEventFilter(this);
m_bookmarksToolbar->installEventFilter(this);
statusBar()->installEventFilter(this);
@ -923,15 +929,6 @@ Qz::BrowserWindow QupZilla::windowType() const
return m_windowType;
}
QWidget* QupZilla::navigationContainer() const
{
if (!tabsOnTop()) {
return 0;
}
return m_navigationContainer;
}
void QupZilla::popupToolbarsMenu(const QPoint &pos)
{
aboutToShowViewMenu();
@ -1692,10 +1689,12 @@ void QupZilla::showBookmarkImport()
void QupZilla::triggerTabsOnTop(bool enable)
{
if (enable) {
m_tabWidget->showNavigationBar(m_navigationContainer);
m_mainLayout->insertWidget(0, m_tabWidget->getTabBar());
m_mainLayout->insertWidget(1, m_navigationContainer);
}
else {
m_mainLayout->insertWidget(0, m_navigationContainer);
m_mainLayout->insertWidget(1, m_tabWidget->getTabBar());
}
m_tabsOnTopState = enable ? 1 : 0;
@ -1797,9 +1796,10 @@ void QupZilla::webSearch()
void QupZilla::searchOnPage()
{
SearchToolBar* toolBar = searchToolBar();
const int searchPos = tabsOnTop() ? 1 : 2;
if (!toolBar) {
const int searchPos = 3;
toolBar = new SearchToolBar(weView(), this);
m_mainLayout->insertWidget(searchPos, toolBar);
}
@ -1892,6 +1892,7 @@ bool QupZilla::event(QEvent* event)
emit setWebViewMouseTracking(true);
#ifdef Q_OS_WIN
if (m_usingTransparentBackground) {
m_tabWidget->getTabBar()->enableBluredBackground(false);
QtWin::extendFrameIntoClientArea(this, 0, 0, 0 , 0);
QtWin::enableBlurBehindWindow(this, false);
}
@ -1915,6 +1916,7 @@ bool QupZilla::event(QEvent* event)
emit setWebViewMouseTracking(false);
#ifdef Q_OS_WIN
if (m_usingTransparentBackground) {
m_tabWidget->getTabBar()->enableBluredBackground(true);
applyBlurToMainWindow(true);
}
#endif
@ -2231,7 +2233,7 @@ void QupZilla::closeEvent(QCloseEvent* event)
SearchToolBar* QupZilla::searchToolBar()
{
SearchToolBar* toolBar = 0;
const int searchPos = tabsOnTop() ? 1 : 2;
const int searchPos = 3;
if (m_mainLayout->count() == searchPos + 1) {
toolBar = qobject_cast<SearchToolBar*>(m_mainLayout->itemAt(searchPos)->widget());

View File

@ -107,7 +107,6 @@ public:
QMenu* menuHelp() { return m_menuHelp; }
QMenu* superMenu() { return m_superMenu; }
QWidget* navigationContainer() const;
void popupToolbarsMenu(const QPoint &pos);
bool isClosing() { return m_isClosing; }

View File

@ -248,7 +248,9 @@ SOURCES += \
tools/aesinterface.cpp \
autofill/passwordbackends/databaseencryptedpasswordbackend.cpp \
network/sslerrordialog.cpp \
adblock/adblocksearchtree.cpp
adblock/adblocksearchtree.cpp \
tools/tabstackedwidget.cpp \
tools/combotabbar.cpp
HEADERS += \
@ -433,7 +435,9 @@ HEADERS += \
tools/aesinterface.h \
autofill/passwordbackends/databaseencryptedpasswordbackend.h \
network/sslerrordialog.h \
adblock/adblocksearchtree.h
adblock/adblocksearchtree.h \
tools/tabstackedwidget.h \
tools/combotabbar.h
FORMS += \
preferences/autofillmanager.ui \

View File

@ -369,11 +369,13 @@ void LocationBar::contextMenuEvent(QContextMenuEvent* event)
void LocationBar::focusInEvent(QFocusEvent* event)
{
const QString &stringUrl = convertUrlToText(m_webView->url());
if (m_webView) {
const QString &stringUrl = convertUrlToText(m_webView->url());
// Text has been edited, let's show go button
if (stringUrl != text()) {
showGoButton();
// Text has been edited, let's show go button
if (stringUrl != text()) {
showGoButton();
}
}
LineEdit::focusInEvent(event);

View File

@ -350,7 +350,7 @@ void NavigationBar::goAtHistoryIndexInNewTab(int index)
void NavigationBar::refreshHistory()
{
if (mApp->isClosing() || p_QupZilla->isClosing()) {
if (mApp->isClosing() || p_QupZilla->isClosing() || !p_QupZilla->weView()) {
return;
}

File diff suppressed because it is too large Load Diff

320
src/lib/tools/combotabbar.h Normal file
View File

@ -0,0 +1,320 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2013 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef COMBOTABBAR_H
#define COMBOTABBAR_H
#include "qz_namespace.h"
#include <QTabBar>
#include <QScrollBar>
#include <QAbstractButton>
#include <QEasingCurve>
class QScrollArea;
class QPropertyAnimation;
class QStyleOptionTabBarBaseV2;
class QHBoxLayout;
class TabBarScrollWidget;
class TabBarHelper;
class ToolButton;
class QT_QUPZILLA_EXPORT ComboTabBar : public QWidget
{
Q_OBJECT
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
Q_PROPERTY(int count READ count)
friend class TabBarHelper;
public:
enum SizeType {
PinnedTabWidth,
ActiveTabMinimumWidth,
NormalTabMinimumWidth,
NormalTabMaximumWidth,
OverflowedTabWidth,
ExtraReservedWidth
};
explicit ComboTabBar(QWidget* parent = 0);
int addTab(const QString &text);
int addTab(const QIcon &icon, const QString &text);
int insertTab(int index, const QString &text);
int insertTab(int index, const QIcon &icon, const QString &text, bool pinned = false);
void removeTab(int index);
void moveTab(int from, int to);
bool isTabEnabled(int index) const;
void setTabEnabled(int index, bool enabled);
QColor tabTextColor(int index) const;
void setTabTextColor(int index, const QColor &color);
QRect tabRect(int index) const;
int tabAt(const QPoint &pos) const;
int mainTabBarCurrentIndex() const;
int currentIndex() const;
int count() const;
void setDrawBase(bool drawTheBase);
bool drawBase() const;
Qt::TextElideMode elideMode() const;
void setElideMode(Qt::TextElideMode elide);
QString tabText(int index) const;
void setTabText(int index, const QString &text);
void setTabToolTip(int index, const QString &tip);
QString tabToolTip(int index) const;
bool tabsClosable() const;
void setTabsClosable(bool closable);
void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget);
QWidget* tabButton(int index, QTabBar::ButtonPosition position) const;
QTabBar::SelectionBehavior selectionBehaviorOnRemove() const;
void setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior behavior);
bool expanding() const;
void setExpanding(bool enabled);
bool isMovable() const;
void setMovable(bool movable);
bool documentMode() const;
void setDocumentMode(bool set);
int pinnedTabsCount() const;
int normalTabsCount() const;
bool isPinned(int index) const;
void setMaxVisiblePinnedTab(int max);
void setObjectName(const QString &name);
void setMouseTracking(bool enable);
void insertCloseButton(int index);
void setCloseButtonsToolTip(const QString &tip);
void enableBluredBackground(bool enable);
QTabBar::ButtonPosition iconButtonPosition();
QTabBar::ButtonPosition closeButtonPosition();
bool validIndex(int index) const;
void setCurrentNextEnabledIndex(int offset);
bool usesScrollButtons() const;
void setUsesScrollButtons(bool useButtons);
void addMainBarWidget(QWidget* widget, Qt::Alignment align, int stretch = 0, Qt::Alignment layoutAlignment = 0);
public slots:
void setUpLayout();
void ensureVisible(int index = -1, int xmargin = -1);
void setCurrentIndex(int index);
private slots:
void setMinimumWidthes();
void slotCurrentChanged(int index);
void slotTabCloseRequested(int index);
void slotTabMoved(int from, int to);
void closeTabFromButton();
protected:
int mainTabBarWidth() const;
int pinTabBarWidth() const;
void wheelEvent(QWheelEvent* event);
void showEvent(QShowEvent* event);
void resizeEvent(QResizeEvent* event);
bool eventFilter(QObject* obj, QEvent* ev);
virtual int comboTabBarPixelMetric(SizeType sizeType) const;
virtual QSize tabSizeHint(int index, bool fast = false) const;
virtual void tabInserted(int index);
virtual void tabRemoved(int index);
virtual void tabLayoutChange();
private:
TabBarHelper* localTabBar(int index = -1) const;
int toLocalIndex(int globalIndex) const;
inline TabBarHelper* mainTabBar() { return m_mainTabBar; }
void updatePinnedTabBarVisibility();
QHBoxLayout* m_mainLayout;
TabBarHelper* m_mainTabBar;
TabBarHelper* m_pinnedTabBar;
TabBarScrollWidget* m_mainTabBarWidget;
TabBarScrollWidget* m_pinnedTabBarWidget;
int m_maxVisiblePinnedTab;
QString m_closeButtonsToolTip;
bool m_heightIsDirty;
bool m_mainBarOverFlowed;
int m_dragOffset;
bool m_usesScrollButtons;
signals:
void overFlowChanged(bool overFlow);
void currentChanged(int index);
void tabCloseRequested(int index);
void tabMoved(int from, int to);
void scrollBarValueChanged(int value);
};
class QT_QUPZILLA_EXPORT TabBarHelper : public QTabBar
{
Q_OBJECT
public:
explicit TabBarHelper(ComboTabBar* comboTabBar);
void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget);
QSize tabSizeHint(int index) const;
QSize baseClassTabSizeHint(int index) const;
bool isActiveTabBar();
void setActiveTabBar(bool activate);
void setScrollArea(QScrollArea* scrollArea);
void useFastTabSizeHint(bool enabled);
bool isDisplayedOnViewPort(int globalLeft, int globalRight);
void enableBluredBackground(bool enable);
public slots:
void setCurrentIndex(int index);
private slots:
void resetDragState();
private:
void initStyleBaseOption(QStyleOptionTabBarBaseV2* optTabBase, QTabBar* tabbar, QSize size);
bool event(QEvent* ev);
void paintEvent(QPaintEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
ComboTabBar* m_comboTabBar;
QScrollArea* m_scrollArea;
int m_pressedIndex;
bool m_dragInProgress;
int m_pressedGlobalX;
bool m_activeTabBar;
bool m_useFastTabSizeHint;
bool m_bluredBackground;
};
class QT_QUPZILLA_EXPORT TabScrollBar : public QScrollBar
{
Q_OBJECT
public:
explicit TabScrollBar(QWidget* parent = 0);
~TabScrollBar();
void animateToValue(int to, QEasingCurve::Type type = QEasingCurve::InOutExpo);
bool isOverFlowed();
void wheelEvent(QWheelEvent* event);
private:
QPropertyAnimation* m_animation;
};
class QT_QUPZILLA_EXPORT TabBarScrollWidget : public QWidget
{
Q_OBJECT
public:
explicit TabBarScrollWidget(QTabBar* tabBar, QWidget* parent = 0);
void addLeftWidget(QWidget* widget, int stretch = 0, Qt::Alignment alignment = 0);
void addRightWidget(QWidget* widget, int stretch = 0, Qt::Alignment alignment = 0);
QTabBar* tabBar();
QScrollArea* scrollArea();
TabScrollBar* scrollBar();
void scrollByWheel(QWheelEvent* event);
bool usesScrollButtons() const;
void setUsesScrollButtons(bool useButtons);
void setContainersName(const QString &name);
void enableBluredBackground(bool enable);
public slots:
void ensureVisible(int index = -1, int xmargin = 132);
void scrollToLeft(int n = 1);
void scrollToRight(int n = 1);
void scrollToLeftEdge();
void scrollToRightEdge();
void setUpLayout();
private slots:
void scrollBarValueChange();
void overFlowChanged(bool overflowed);
void scrollStart();
void scrollStop();
private:
bool eventFilter(QObject* obj, QEvent* ev);
void mouseMoveEvent(QMouseEvent* event);
QTabBar* m_tabBar;
QScrollArea* m_scrollArea;
TabScrollBar* m_scrollBar;
QHBoxLayout* m_leftLayout;
QHBoxLayout* m_rightLayout;
ToolButton* m_rightScrollButton;
ToolButton* m_leftScrollButton;
QWidget* m_leftContainer;
QWidget* m_rightContainer;
bool m_usesScrollButtons;
bool m_bluredBackground;
QPropertyAnimation* m_scrollByButtonAnim;
};
// Class for close button on tabs
// * taken from qtabbar.cpp
class CloseButton : public QAbstractButton
{
Q_OBJECT
public:
CloseButton(QWidget* parent = 0);
QSize sizeHint() const;
QSize minimumSizeHint() const;
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
void paintEvent(QPaintEvent* event);
};
#endif // COMBOTABBAR_H

View File

@ -0,0 +1,303 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2013 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
*
* Some code was taken from qtabwidget.cpp
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "tabstackedwidget.h"
#include "combotabbar.h"
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QKeyEvent>
#include <QApplication>
// Note: just some of QTabWidget's methods were implemented
TabStackedWidget::TabStackedWidget(QWidget* parent)
: QWidget(parent)
, m_stack(0)
, m_tabBar(0)
{
m_stack = new QStackedWidget(this);
m_mainLayout = new QVBoxLayout;
m_mainLayout->setSpacing(0);
m_mainLayout->setContentsMargins(0, 0, 0, 0);
m_mainLayout->addWidget(m_stack);
setLayout(m_mainLayout);
setTabBar(new ComboTabBar);
connect(m_stack, SIGNAL(widgetRemoved(int)), this, SLOT(tabWasRemoved(int)));
}
TabStackedWidget::~TabStackedWidget()
{
}
ComboTabBar* TabStackedWidget::tabBar()
{
return m_tabBar;
}
void TabStackedWidget::setTabBar(ComboTabBar* tb)
{
Q_ASSERT(tb);
if (tb->parentWidget() != this) {
tb->setParent(this);
tb->show();
}
delete m_tabBar;
m_dirtyTabBar = true;
m_tabBar = tb;
setFocusProxy(m_tabBar);
connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showTab(int)));
connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(tabWasMoved(int,int)));
if (m_tabBar->tabsClosable()) {
connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SIGNAL(tabCloseRequested(int)));
}
setDocumentMode(m_tabBar->documentMode());
m_tabBar->installEventFilter(this);
setUpLayout();
}
bool TabStackedWidget::isValid(int index)
{
return (index < m_stack->count() && index >= 0);
}
void TabStackedWidget::tabWasRemoved(int index)
{
m_tabBar->removeTab(index);
}
void TabStackedWidget::tabWasMoved(int from, int to)
{
m_stack->blockSignals(true);
QWidget* w = m_stack->widget(from);
m_stack->removeWidget(w);
m_stack->insertWidget(to, w);
m_stack->setCurrentIndex(currentIndex());
m_stack->blockSignals(false);
}
void TabStackedWidget::setUpLayout()
{
if (!m_tabBar->isVisible()) {
m_dirtyTabBar = true;
return;
}
m_tabBar->setElideMode(m_tabBar->elideMode());
m_dirtyTabBar = false;
}
bool TabStackedWidget::eventFilter(QObject* obj, QEvent* event)
{
if (m_dirtyTabBar && obj == m_tabBar && event->type() == QEvent::Show) {
setUpLayout();
}
return false;
}
void TabStackedWidget::keyPressEvent(QKeyEvent* event)
{
if (((event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab) &&
count() > 1 && event->modifiers() & Qt::ControlModifier)
#ifdef QT_KEYPAD_NAVIGATION
|| QApplication::keypadNavigationEnabled() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) && count() > 1
#endif
) {
int pageCount = count();
int page = currentIndex();
int dx = (event->key() == Qt::Key_Backtab || event->modifiers() & Qt::ShiftModifier) ? -1 : 1;
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right)) {
dx = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1;
}
#endif
for (int pass = 0; pass < pageCount; ++pass) {
page += dx;
if (page < 0
#ifdef QT_KEYPAD_NAVIGATION
&& !event->isAutoRepeat()
#endif
) {
page = count() - 1;
}
else if (page >= pageCount
#ifdef QT_KEYPAD_NAVIGATION
&& !event->isAutoRepeat()
#endif
) {
page = 0;
}
if (m_tabBar->isTabEnabled(page)) {
setCurrentIndex(page);
break;
}
}
if (!QApplication::focusWidget()) {
m_tabBar->setFocus();
}
}
else {
event->ignore();
}
}
void TabStackedWidget::showTab(int index)
{
if (isValid(index)) {
m_stack->setCurrentIndex(index);
}
emit currentChanged(index);
}
bool TabStackedWidget::documentMode() const
{
return m_tabBar->documentMode();
}
void TabStackedWidget::setDocumentMode(bool enabled)
{
m_tabBar->setDocumentMode(enabled);
m_tabBar->setExpanding(!enabled);
m_tabBar->setDrawBase(enabled);
}
int TabStackedWidget::addTab(QWidget* widget, const QString &label, bool pinned)
{
return insertTab(-1, widget, label, pinned);
}
int TabStackedWidget::insertTab(int index, QWidget* w, const QString &label, bool pinned)
{
if (!w) {
return -1;
}
if (pinned) {
index = index < 0 ? m_tabBar->pinnedTabsCount() : qMin(index, m_tabBar->pinnedTabsCount());
index = m_stack->insertWidget(index, w);
m_tabBar->insertTab(index, QIcon(), label, true);
}
else {
index = index < 0 ? -1 : qMax(index, m_tabBar->pinnedTabsCount());
index = m_stack->insertWidget(index, w);
m_tabBar->insertTab(index, QIcon(), label, false);
}
return index;
}
QString TabStackedWidget::tabText(int index) const
{
return m_tabBar->tabText(index);
}
void TabStackedWidget::setTabText(int index, const QString &label)
{
m_tabBar->setTabText(index, label);
}
QString TabStackedWidget::tabToolTip(int index) const
{
return m_tabBar->tabToolTip(index);
}
void TabStackedWidget::setTabToolTip(int index, const QString &tip)
{
m_tabBar->setTabToolTip(index, tip);
}
int TabStackedWidget::pinUnPinTab(int index, const QString &title)
{
int newIndex = -1;
if (QWidget* w = m_stack->widget(index)) {
QWidget* button = m_tabBar->tabButton(index, m_tabBar->iconButtonPosition());
m_tabBar->setTabButton(index, m_tabBar->iconButtonPosition(), 0);
if (index < m_tabBar->pinnedTabsCount()) {
// Unpin
// fix selecting and loading a tab after removing the tab that contains 'w'
// by blocking ComboTabBar::currentChanged()
m_tabBar->blockSignals(true);
m_stack->removeWidget(w);
m_tabBar->blockSignals(false);
newIndex = insertTab(m_tabBar->pinnedTabsCount(), w, title, false);
}
else {
// Pin // same as above
m_tabBar->blockSignals(true);
m_stack->removeWidget(w);
m_tabBar->blockSignals(false);
newIndex = insertTab(0, w, QString(), true);
}
m_tabBar->setTabButton(newIndex, m_tabBar->iconButtonPosition(), button);
}
return newIndex;
}
void TabStackedWidget::removeTab(int index)
{
if (QWidget* w = m_stack->widget(index)) {
m_stack->removeWidget(w);
}
}
int TabStackedWidget::currentIndex() const
{
return m_tabBar->currentIndex();
}
void TabStackedWidget::setCurrentIndex(int index)
{
m_tabBar->setCurrentIndex(index);
}
QWidget* TabStackedWidget::currentWidget() const
{
return m_stack->currentWidget();
}
void TabStackedWidget::setCurrentWidget(QWidget* widget)
{
m_tabBar->setCurrentIndex(indexOf(widget));
}
QWidget* TabStackedWidget::widget(int index) const
{
return m_stack->widget(index);
}
int TabStackedWidget::indexOf(QWidget* widget) const
{
return m_stack->indexOf(widget);
}
int TabStackedWidget::count() const
{
return m_tabBar->count();
}

View File

@ -0,0 +1,91 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2013 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef TABSTACKEDWIDGET_H
#define TABSTACKEDWIDGET_H
#include "qz_namespace.h"
#include <QWidget>
class ComboTabBar;
class QStackedWidget;
class QVBoxLayout;
class QT_QUPZILLA_EXPORT TabStackedWidget : public QWidget
{
Q_OBJECT
public:
explicit TabStackedWidget(QWidget* parent = 0);
~TabStackedWidget();
ComboTabBar* tabBar();
void setTabBar(ComboTabBar* tb);
bool isValid(int index);
bool documentMode() const;
void setDocumentMode(bool enabled);
int addTab(QWidget* widget, const QString &label, bool pinned = false);
int insertTab(int index, QWidget* widget, const QString &label, bool pinned = false);
QString tabText(int index) const;
void setTabText(int index, const QString &label);
QString tabToolTip(int index) const;
void setTabToolTip(int index, const QString &tip);
int pinUnPinTab(int index, const QString &title = QString());
void removeTab(int index);
void setUpLayout();
int currentIndex() const;
QWidget* currentWidget() const;
QWidget* widget(int index) const;
int indexOf(QWidget* widget) const;
int count() const;
public slots:
void setCurrentIndex(int index);
void setCurrentWidget(QWidget* widget);
private:
QStackedWidget* m_stack;
ComboTabBar* m_tabBar;
QVBoxLayout* m_mainLayout;
bool m_dirtyTabBar;
private slots:
void tabWasRemoved(int index);
void showTab(int index);
void tabWasMoved(int from, int to);
protected:
bool eventFilter(QObject* obj, QEvent* event);
void keyPressEvent(QKeyEvent* event);
signals:
void currentChanged(int index);
void tabCloseRequested(int index);
};
#endif // TABSTACKEDWIDGET_H

View File

@ -27,6 +27,7 @@ ToolButton::ToolButton(QWidget* parent)
: QToolButton(parent)
, m_usingMultiIcon(false)
, m_showMenuInside(false)
, m_forceHidden(false)
{
setMinimumWidth(16);
}
@ -66,6 +67,24 @@ bool ToolButton::showMenuInside() const
return m_showMenuInside;
}
void ToolButton::setVisible(bool visible)
{
QToolButton::setVisible(!m_forceHidden && visible);
}
bool ToolButton::isForceHidden()
{
return m_forceHidden;
}
void ToolButton::setForceHidden(bool enable)
{
m_forceHidden = enable;
if (m_forceHidden) {
hide();
}
}
void ToolButton::setData(const QVariant &data)
{
m_data = data;

View File

@ -53,6 +53,10 @@ public:
void setShowMenuInside(bool inside);
bool showMenuInside() const;
virtual void setVisible(bool visible);
bool isForceHidden();
void setForceHidden(bool enable);
signals:
void middleMouseClicked();
void controlClicked();
@ -77,6 +81,7 @@ private:
QString m_themeIcon;
QVariant m_data;
bool m_forceHidden;
};
#endif // TOOLBUTTON_H

View File

@ -36,18 +36,21 @@
#include <QApplication>
#include <QTimer>
#include <QRect>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QDebug>
#define MAXIMUM_TAB_WIDTH 250
#define MINIMUM_TAB_WIDTH 125
#define OVERFLOWED_TAB_WIDTH 100
TabBar::TabBar(QupZilla* mainClass, TabWidget* tabWidget)
: QTabBar()
: ComboTabBar()
, p_QupZilla(mainClass)
, m_tabWidget(tabWidget)
, m_tabPreview(new TabPreview(mainClass, tabWidget))
, m_tabPreview(new TabPreview(mainClass, mainClass))
, m_showTabPreviews(false)
, m_clickedTab(0)
, m_pinnedTabsCount(0)
, m_normalTabWidth(0)
, m_activeTabWidth(0)
{
@ -64,13 +67,18 @@ TabBar::TabBar(QupZilla* mainClass, TabWidget* tabWidget)
connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(m_tabWidget, SIGNAL(pinnedTabClosed()), this, SLOT(pinnedTabClosed()));
connect(m_tabWidget, SIGNAL(pinnedTabAdded()), this, SLOT(pinnedTabAdded()));
m_tabPreviewTimer = new QTimer(this);
m_tabPreviewTimer->setInterval(200);
m_tabPreviewTimer->setSingleShot(true);
connect(m_tabPreviewTimer, SIGNAL(timeout()), m_tabPreview, SLOT(hideAnimated()));
// ComboTabBar features
setUsesScrollButtons(true);
setCloseButtonsToolTip(QupZilla::tr("Close Tab"));
setMaxVisiblePinnedTab(0);
connect(this, SIGNAL(overFlowChanged(bool)), this, SLOT(overFlowChange(bool)));
connect(this, SIGNAL(scrollBarValueChanged(int)), this, SLOT(hideTabPreview()));
}
void TabBar::loadSettings()
@ -84,6 +92,8 @@ void TabBar::loadSettings()
settings.endGroup();
setSelectionBehaviorOnRemove(activateLastTab ? QTabBar::SelectPreviousTab : QTabBar::SelectRightTab);
setUpLayout();
}
void TabBar::updateVisibilityWithFullscreen(bool visible)
@ -96,7 +106,7 @@ void TabBar::updateVisibilityWithFullscreen(bool visible)
visible = !(count() == 1 && m_hideTabBarWithOneTab);
}
QTabBar::setVisible(visible);
ComboTabBar::setVisible(visible);
if (visible) {
setGeometry(m_originalGeometry);
@ -128,7 +138,7 @@ void TabBar::setVisible(bool visible)
}
hideTabPreview(false);
QTabBar::setVisible(visible);
ComboTabBar::setVisible(visible);
}
void TabBar::contextMenuRequested(const QPoint &position)
@ -198,7 +208,7 @@ void TabBar::closeAllButCurrent()
}
}
QSize TabBar::tabSizeHint(int index) const
QSize TabBar::tabSizeHint(int index, bool fast) const
{
if (!isVisible() || !mApp->proxyStyle()) {
// Don't calculate it when tabbar is not visible
@ -211,15 +221,19 @@ QSize TabBar::tabSizeHint(int index) const
static int PINNED_TAB_WIDTH = -1;
static int MINIMUM_ACTIVE_TAB_WIDTH = -1;
if (PINNED_TAB_WIDTH == -1) {
PINNED_TAB_WIDTH = 16 + mApp->proxyStyle()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0, this);
MINIMUM_ACTIVE_TAB_WIDTH = PINNED_TAB_WIDTH + mApp->proxyStyle()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this);
// We want to be sure buttonAddTab and buttonListTabs can't cover the active tab
MINIMUM_ACTIVE_TAB_WIDTH = qMax(MINIMUM_ACTIVE_TAB_WIDTH, 6 + m_tabWidget->buttonListTabs()->width() + m_tabWidget->buttonAddTab()->width());
if (comboTabBarPixelMetric(ComboTabBar::PinnedTabWidth) > 0) {
PINNED_TAB_WIDTH = comboTabBarPixelMetric(ComboTabBar::PinnedTabWidth);
MINIMUM_ACTIVE_TAB_WIDTH = comboTabBarPixelMetric(ComboTabBar::ActiveTabMinimumWidth);
}
QSize size = ComboTabBar::tabSizeHint(index);
// The overflowed tabs have similar size and we can use this fast method
if (fast) {
size.setWidth(index >= pinnedTabsCount() ? OVERFLOWED_TAB_WIDTH : PINNED_TAB_WIDTH);
return size;
}
QSize size = QTabBar::tabSizeHint(index);
WebTab* webTab = qobject_cast<WebTab*>(m_tabWidget->widget(index));
TabBar* tabBar = const_cast <TabBar*>(this);
@ -227,12 +241,16 @@ QSize TabBar::tabSizeHint(int index) const
size.setWidth(PINNED_TAB_WIDTH);
}
else {
int availableWidth = width() - (PINNED_TAB_WIDTH * m_pinnedTabsCount) - m_tabWidget->buttonListTabs()->width() - m_tabWidget->buttonAddTab()->width();
int availableWidth = mainTabBarWidth();
if (!m_tabWidget->buttonListTabs()->isForceHidden()) {
availableWidth -= comboTabBarPixelMetric(ExtraReservedWidth);
}
if (availableWidth < 0) {
return QSize(-1, -1);
}
int normalTabsCount = count() - m_pinnedTabsCount;
const int normalTabsCount = ComboTabBar::normalTabsCount();
if (availableWidth >= MAXIMUM_TAB_WIDTH * normalTabsCount) {
m_normalTabWidth = MAXIMUM_TAB_WIDTH;
size.setWidth(m_normalTabWidth);
@ -257,7 +275,7 @@ QSize TabBar::tabSizeHint(int index) const
if (maxWidthForTab < PINNED_TAB_WIDTH) {
// FIXME: It overflows now
m_normalTabWidth = PINNED_TAB_WIDTH;
if (index == currentIndex()) {
if (index == mainTabBarCurrentIndex()) {
size.setWidth(realTabWidth);
}
else {
@ -294,7 +312,7 @@ QSize TabBar::tabSizeHint(int index) const
m_normalTabWidth = maxWidthForTab;
// Fill any empty space (we've got from rounding) with active tab
if (index == currentIndex()) {
if (index == mainTabBarCurrentIndex()) {
if (adjustingActiveTab) {
m_activeTabWidth = (availableWidth - MINIMUM_ACTIVE_TAB_WIDTH
- maxWidthForTab * (normalTabsCount - 1)) + realTabWidth;
@ -312,10 +330,10 @@ QSize TabBar::tabSizeHint(int index) const
}
if (index == count() - 1) {
WebTab* currentTab = qobject_cast<WebTab*>(m_tabWidget->widget(currentIndex()));
int xForAddTabButton = (PINNED_TAB_WIDTH * m_pinnedTabsCount) + (count() - m_pinnedTabsCount) * (m_normalTabWidth);
WebTab* lastMainActiveTab = qobject_cast<WebTab*>(m_tabWidget->widget(mainTabBarCurrentIndex()));
int xForAddTabButton = pinTabBarWidth() + normalTabsCount() * m_normalTabWidth;
if (currentTab && !currentTab->isPinned() && m_activeTabWidth > m_normalTabWidth) {
if (lastMainActiveTab && m_activeTabWidth > m_normalTabWidth) {
xForAddTabButton += m_activeTabWidth - m_normalTabWidth;
}
@ -330,6 +348,47 @@ QSize TabBar::tabSizeHint(int index) const
return size;
}
int TabBar::comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const
{
if (!mApp->proxyStyle() || !isVisible()) {
return -1;
}
static int PINNED_TAB_WIDTH = -1;
static int MINIMUM_ACTIVE_TAB_WIDTH = -1;
if (PINNED_TAB_WIDTH == -1) {
PINNED_TAB_WIDTH = 16 + mApp->proxyStyle()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0, this);
MINIMUM_ACTIVE_TAB_WIDTH = PINNED_TAB_WIDTH + mApp->proxyStyle()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this);
}
switch (sizeType) {
case ComboTabBar::PinnedTabWidth:
return PINNED_TAB_WIDTH;
break;
case ComboTabBar::ActiveTabMinimumWidth:
return MINIMUM_ACTIVE_TAB_WIDTH;
break;
case ComboTabBar::NormalTabMinimumWidth:
return MINIMUM_TAB_WIDTH;
break;
case ComboTabBar::NormalTabMaximumWidth:
return MAXIMUM_TAB_WIDTH;
break;
case ComboTabBar::OverflowedTabWidth:
return OVERFLOWED_TAB_WIDTH;
break;
case ComboTabBar::ExtraReservedWidth:
return m_tabWidget->buttonListTabs()->width() +
m_tabWidget->buttonAddTab()->width();
break;
default:
break;
}
return -1;
}
void TabBar::showCloseButton(int index)
{
if (!validIndex(index)) {
@ -343,9 +402,7 @@ void TabBar::showCloseButton(int index)
return;
}
QAbstractButton* closeButton = new CloseButton(this);
connect(closeButton, SIGNAL(clicked()), this, SLOT(closeTabFromButton()));
setTabButton(index, closeButtonPosition(), closeButton);
insertCloseButton(index);
}
void TabBar::hideCloseButton(int index)
@ -423,6 +480,8 @@ void TabBar::currentTabChanged(int index)
showCloseButton(index);
hideCloseButton(m_tabWidget->lastTabIndex());
ensureVisible(index);
m_tabWidget->currentTabChanged(index);
}
@ -447,13 +506,6 @@ void TabBar::pinTab()
webTab->pinTab(m_clickedTab);
if (webTab->isPinned()) {
m_pinnedTabsCount++;
}
else {
m_pinnedTabsCount--;
}
// We need to recalculate size of all tabs and repaint tabbar
// Unfortunately, Qt doesn't offer refresh() function as a public API
@ -461,36 +513,6 @@ void TabBar::pinTab()
setElideMode(elideMode());
}
void TabBar::pinnedTabClosed()
{
m_pinnedTabsCount--;
}
void TabBar::pinnedTabAdded()
{
m_pinnedTabsCount++;
}
int TabBar::pinnedTabsCount()
{
return m_pinnedTabsCount;
}
int TabBar::normalTabsCount()
{
return count() - m_pinnedTabsCount;
}
QTabBar::ButtonPosition TabBar::iconButtonPosition()
{
return (closeButtonPosition() == QTabBar::RightSide ? QTabBar::LeftSide : QTabBar::RightSide);
}
QTabBar::ButtonPosition TabBar::closeButtonPosition()
{
return (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this);
}
void TabBar::overrideTabTextColor(int index, QColor color)
{
if (!m_originalTabTextColor.isValid()) {
@ -514,7 +536,11 @@ void TabBar::showTabPreview()
m_tabPreviewTimer->stop();
m_tabPreview->setWebTab(webTab, m_tabPreview->previewIndex() == currentIndex());
m_tabPreview->showOnRect(tabRect(m_tabPreview->previewIndex()));
QRect r(tabRect(m_tabPreview->previewIndex()));
r.setTopLeft(mapTo(p_QupZilla, r.topLeft()));
r.setBottomRight(mapTo(p_QupZilla, r.bottomRight()));
m_tabPreview->showOnRect(r);
}
void TabBar::hideTabPreview(bool delayed)
@ -527,6 +553,28 @@ void TabBar::hideTabPreview(bool delayed)
}
}
void TabBar::overFlowChange(bool overFlowed)
{
if (overFlowed) {
m_tabWidget->buttonAddTab()->setForceHidden(true);
m_tabWidget->buttonListTabs()->setForceHidden(true);
// Restore close buttons according to preferences
if (OVERFLOWED_TAB_WIDTH >= MINIMUM_TAB_WIDTH && !tabsClosable()) {
setTabsClosable(true);
}
m_tabWidget->setUpLayout();
ensureVisible(currentIndex());
}
else {
m_tabWidget->buttonAddTab()->setForceHidden(false);
m_tabWidget->buttonListTabs()->setForceHidden(false);
m_tabWidget->showButtons();
m_tabWidget->setUpLayout();
}
}
void TabBar::tabInserted(int index)
{
Q_UNUSED(index)
@ -538,7 +586,6 @@ void TabBar::tabRemoved(int index)
{
Q_UNUSED(index)
m_tabWidget->showNavigationBar(p_QupZilla->navigationContainer());
showCloseButton(currentIndex());
setVisible(!(count() == 1 && m_hideTabBarWithOneTab));
}
@ -554,7 +601,7 @@ void TabBar::mouseDoubleClickEvent(QMouseEvent* event)
return;
}
QTabBar::mouseDoubleClickEvent(event);
ComboTabBar::mouseDoubleClickEvent(event);
}
void TabBar::mousePressEvent(QMouseEvent* event)
@ -572,7 +619,7 @@ void TabBar::mousePressEvent(QMouseEvent* event)
m_dragStartPosition = QPoint();
}
QTabBar::mousePressEvent(event);
ComboTabBar::mousePressEvent(event);
}
void TabBar::mouseMoveEvent(QMouseEvent* event)
@ -600,7 +647,7 @@ void TabBar::mouseMoveEvent(QMouseEvent* event)
}
}
QTabBar::mouseMoveEvent(event);
ComboTabBar::mouseMoveEvent(event);
}
void TabBar::mouseReleaseEvent(QMouseEvent* event)
@ -616,7 +663,7 @@ void TabBar::mouseReleaseEvent(QMouseEvent* event)
}
if (!rect().contains(event->pos())) {
QTabBar::mouseReleaseEvent(event);
ComboTabBar::mouseReleaseEvent(event);
return;
}
@ -630,7 +677,7 @@ void TabBar::mouseReleaseEvent(QMouseEvent* event)
return;
}
QTabBar::mouseReleaseEvent(event);
ComboTabBar::mouseReleaseEvent(event);
}
bool TabBar::event(QEvent* event)
@ -654,7 +701,23 @@ bool TabBar::event(QEvent* event)
break;
}
return QTabBar::event(event);
return ComboTabBar::event(event);
}
void TabBar::resizeEvent(QResizeEvent* e)
{
QPoint posit;
posit.setY(0);
if (isRightToLeft()) {
posit.setX(0);
}
else {
posit.setX(width() - m_tabWidget->buttonListTabs()->width());
}
m_tabWidget->buttonListTabs()->move(posit);
ComboTabBar::resizeEvent(e);
}
void TabBar::wheelEvent(QWheelEvent* event)
@ -663,7 +726,7 @@ void TabBar::wheelEvent(QWheelEvent* event)
return;
}
QTabBar::wheelEvent(event);
ComboTabBar::wheelEvent(event);
}
void TabBar::dragEnterEvent(QDragEnterEvent* event)
@ -675,7 +738,7 @@ void TabBar::dragEnterEvent(QDragEnterEvent* event)
return;
}
QTabBar::dragEnterEvent(event);
ComboTabBar::dragEnterEvent(event);
}
void TabBar::dropEvent(QDropEvent* event)
@ -683,7 +746,7 @@ void TabBar::dropEvent(QDropEvent* event)
const QMimeData* mime = event->mimeData();
if (!mime->hasUrls()) {
QTabBar::dropEvent(event);
ComboTabBar::dropEvent(event);
return;
}
@ -705,71 +768,3 @@ void TabBar::disconnectObjects()
{
disconnect(this);
}
CloseButton::CloseButton(QWidget* parent)
: QAbstractButton(parent)
{
setFocusPolicy(Qt::NoFocus);
setCursor(Qt::ArrowCursor);
setToolTip(QupZilla::tr("Close Tab"));
resize(sizeHint());
}
QSize CloseButton::sizeHint() const
{
ensurePolished();
int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this);
int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this);
return QSize(width, height);
}
QSize CloseButton::minimumSizeHint() const
{
return sizeHint();
}
void CloseButton::enterEvent(QEvent* event)
{
if (isEnabled()) {
update();
}
QAbstractButton::enterEvent(event);
}
void CloseButton::leaveEvent(QEvent* event)
{
if (isEnabled()) {
update();
}
QAbstractButton::leaveEvent(event);
}
void CloseButton::paintEvent(QPaintEvent*)
{
QPainter p(this);
QStyleOption opt;
opt.init(this);
opt.state |= QStyle::State_AutoRaise;
if (isEnabled() && underMouse() && !isChecked() && !isDown()) {
opt.state |= QStyle::State_Raised;
}
if (isChecked()) {
opt.state |= QStyle::State_On;
}
if (isDown()) {
opt.state |= QStyle::State_Sunken;
}
if (TabBar* tb = qobject_cast<TabBar*>(parent())) {
int index = tb->currentIndex();
if (tb->tabButton(index, tb->closeButtonPosition()) == this) {
opt.state |= QStyle::State_Selected;
}
}
style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
}

View File

@ -18,9 +18,9 @@
#ifndef TABBAR_H
#define TABBAR_H
#include <QTabBar>
#include "combotabbar.h"
#include <QRect>
#include <QAbstractButton>
#include "qz_namespace.h"
@ -28,7 +28,7 @@ class QupZilla;
class TabWidget;
class TabPreview;
class QT_QUPZILLA_EXPORT TabBar : public QTabBar
class QT_QUPZILLA_EXPORT TabBar : public ComboTabBar
{
Q_OBJECT
public:
@ -39,12 +39,6 @@ public:
void setVisible(bool visible);
void updateVisibilityWithFullscreen(bool visible);
int pinnedTabsCount();
int normalTabsCount();
QTabBar::ButtonPosition iconButtonPosition();
QTabBar::ButtonPosition closeButtonPosition();
void overrideTabTextColor(int index, QColor color);
void restoreTabTextColor(int index);
@ -69,8 +63,6 @@ signals:
private slots:
void currentTabChanged(int index);
void pinnedTabAdded();
void pinnedTabClosed();
void contextMenuRequested(const QPoint &position);
void reloadTab() { emit reloadTab(m_clickedTab); }
@ -88,6 +80,8 @@ private slots:
void showTabPreview();
void hideTabPreview(bool delayed = true);
void overFlowChange(bool overFlowed);
private:
inline bool validIndex(int index) const { return index >= 0 && index < count(); }
@ -102,11 +96,13 @@ private:
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
bool event(QEvent* event);
void resizeEvent(QResizeEvent* e);
void dragEnterEvent(QDragEnterEvent* event);
void dropEvent(QDropEvent* event);
QSize tabSizeHint(int index) const;
QSize tabSizeHint(int index, bool fast) const;
int comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const;
QupZilla* p_QupZilla;
TabWidget* m_tabWidget;
@ -117,7 +113,6 @@ private:
bool m_hideTabBarWithOneTab;
int m_clickedTab;
int m_pinnedTabsCount;
mutable int m_normalTabWidth;
mutable int m_activeTabWidth;
@ -127,21 +122,4 @@ private:
QPoint m_dragStartPosition;
};
// Class for close button on tabs
// * taken from qtabbar.cpp
class CloseButton : public QAbstractButton
{
Q_OBJECT
public:
CloseButton(QWidget* parent = 0);
QSize sizeHint() const;
QSize minimumSizeHint() const;
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
void paintEvent(QPaintEvent* event);
};
#endif // TABBAR_H

View File

@ -41,9 +41,10 @@
#include <QWebHistory>
#include <QClipboard>
#include <QFile>
#include <QScrollArea>
AddTabButton::AddTabButton(TabWidget* tabWidget, TabBar* tabBar)
: ToolButton(tabWidget)
: ToolButton(tabBar)
, m_tabBar(tabBar)
, m_tabWidget(tabWidget)
{
@ -111,7 +112,7 @@ void MenuTabs::mouseReleaseEvent(QMouseEvent* event)
}
TabWidget::TabWidget(QupZilla* mainClass, QWidget* parent)
: QTabWidget(parent)
: TabStackedWidget(parent)
, p_QupZilla(mainClass)
, m_lastTabIndex(-1)
, m_lastBackgroundTabIndex(-1)
@ -139,9 +140,9 @@ TabWidget::TabWidget(QupZilla* mainClass, QWidget* parent)
connect(m_tabBar, SIGNAL(showButtons()), this, SLOT(showButtons()));
connect(m_tabBar, SIGNAL(hideButtons()), this, SLOT(hideButtons()));
m_buttonListTabs = new ToolButton(this);
m_buttonListTabs = new ToolButton(m_tabBar);
m_buttonListTabs->setObjectName("tabwidget-button-opentabs");
m_menuTabs = new MenuTabs(this);
m_menuTabs = new MenuTabs(m_tabBar);
m_buttonListTabs->setMenu(m_menuTabs);
m_buttonListTabs->setPopupMode(QToolButton::InstantPopup);
m_buttonListTabs->setToolTip(tr("List of tabs"));
@ -153,6 +154,22 @@ TabWidget::TabWidget(QupZilla* mainClass, QWidget* parent)
connect(m_buttonAddTab, SIGNAL(clicked()), p_QupZilla, SLOT(addTab()));
connect(m_menuTabs, SIGNAL(aboutToShow()), this, SLOT(aboutToShowClosedTabsMenu()));
// copy of buttons
m_buttonListTabs2 = new ToolButton(m_tabBar);
m_buttonListTabs2->setObjectName("tabwidget-button-opentabs");
m_buttonListTabs2->setMenu(m_menuTabs);
m_buttonListTabs2->setPopupMode(QToolButton::InstantPopup);
m_buttonListTabs2->setToolTip(tr("List of tabs"));
m_buttonListTabs2->setAutoRaise(true);
m_buttonListTabs2->setFocusPolicy(Qt::NoFocus);
m_buttonAddTab2 = new AddTabButton(this, m_tabBar);
connect(m_buttonAddTab2, SIGNAL(clicked()), p_QupZilla, SLOT(addTab()));
m_tabBar->addMainBarWidget(m_buttonAddTab2, Qt::AlignRight);
m_tabBar->addMainBarWidget(m_buttonListTabs2, Qt::AlignRight);
m_buttonAddTab2->hide();
m_buttonListTabs2->hide();
connect(m_tabBar, SIGNAL(overFlowChanged(bool)), this, SLOT(tabBarOverFlowChanged(bool)));
loadSettings();
}
@ -180,22 +197,6 @@ void TabWidget::loadSettings()
}
}
void TabWidget::resizeEvent(QResizeEvent* e)
{
QPoint posit;
posit.setY(0);
//RTL Support
if (QApplication::layoutDirection() == Qt::RightToLeft) {
posit.setX(0);
}
else {
posit.setX(width() - m_buttonListTabs->width());
}
m_buttonListTabs->move(posit);
QTabWidget::resizeEvent(e);
}
WebTab* TabWidget::weTab()
{
return weTab(currentIndex());
@ -218,6 +219,12 @@ void TabWidget::hideButtons()
m_buttonAddTab->hide();
}
void TabWidget::tabBarOverFlowChanged(bool overFlowed)
{
m_buttonAddTab2->setVisible(overFlowed);
m_buttonListTabs2->setVisible(overFlowed);
}
void TabWidget::moveAddTabButton(int posX)
{
int posY = (m_tabBar->height() - m_buttonAddTab->height()) / 2;
@ -282,27 +289,30 @@ void TabWidget::actionChangeIndex()
if (QAction* action = qobject_cast<QAction*>(sender())) {
WebTab* tab = qobject_cast<WebTab*>(qvariant_cast<QWidget*>(action->data()));
if (tab) {
// needed when clicking on action of the current tab
m_tabBar->ensureVisible(tab->tabIndex());
setCurrentIndex(tab->tabIndex());
}
}
}
int TabWidget::addView(const QUrl &url, const Qz::NewTabPositionFlags &openFlags, bool selectLine)
int TabWidget::addView(const QUrl &url, const Qz::NewTabPositionFlags &openFlags, bool selectLine, bool pinned)
{
return addView(QNetworkRequest(url), openFlags, selectLine);
return addView(QNetworkRequest(url), openFlags, selectLine, pinned);
}
int TabWidget::addView(const QNetworkRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine)
int TabWidget::addView(const QNetworkRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine, bool pinned)
{
return addView(req, tr("New tab"), openFlags, selectLine);
return addView(req, tr("New tab"), openFlags, selectLine, -1, pinned);
}
int TabWidget::addView(const QUrl &url, const QString &title, const Qz::NewTabPositionFlags &openFlags, bool selectLine, int position)
int TabWidget::addView(const QUrl &url, const QString &title, const Qz::NewTabPositionFlags &openFlags, bool selectLine, int position, bool pinned)
{
return addView(QNetworkRequest(url), title, openFlags, selectLine, position);
return addView(QNetworkRequest(url), title, openFlags, selectLine, position, pinned);
}
int TabWidget::addView(QNetworkRequest req, const QString &title, const Qz::NewTabPositionFlags &openFlags, bool selectLine, int position)
int TabWidget::addView(QNetworkRequest req, const QString &title, const Qz::NewTabPositionFlags &openFlags, bool selectLine, int position, bool pinned)
{
#ifdef Q_OS_WIN
if (p_QupZilla->isTransparentBackgroundAllowed()) {
@ -338,10 +348,10 @@ int TabWidget::addView(QNetworkRequest req, const QString &title, const Qz::NewT
int index;
if (position == -1) {
index = addTab(new WebTab(p_QupZilla, locBar), QString());
index = addTab(new WebTab(p_QupZilla, locBar), QString(), pinned);
}
else {
index = insertTab(position, new WebTab(p_QupZilla, locBar), QString());
index = insertTab(position, new WebTab(p_QupZilla, locBar), QString(), pinned);
}
TabbedWebView* webView = weTab(index)->view();
@ -453,10 +463,6 @@ void TabWidget::closeTab(int index, bool force)
}
}
if (webTab->isPinned()) {
emit pinnedTabClosed();
}
m_locationBars->removeWidget(webView->webTab()->locationBar());
disconnect(webView, SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int)));
disconnect(webView, SIGNAL(changed()), mApp, SLOT(setStateChanged()));
@ -502,7 +508,6 @@ void TabWidget::currentTabChanged(int index)
webTab->setCurrentTab();
p_QupZilla->currentTabChanged();
showNavigationBar(p_QupZilla->navigationContainer());
}
void TabWidget::tabMoved(int before, int after)
@ -556,7 +561,7 @@ void TabWidget::setCurrentIndex(int index)
{
m_lastTabIndex = currentIndex();
QTabWidget::setCurrentIndex(index);
TabStackedWidget::setCurrentIndex(index);
}
void TabWidget::setTabIcon(int index, const QIcon &icon)
@ -592,7 +597,7 @@ void TabWidget::setTabText(int index, const QString &text)
}
setTabToolTip(index, text);
QTabWidget::setTabText(index, newtext);
TabStackedWidget::setTabText(index, newtext);
}
void TabWidget::nextTab()
@ -631,15 +636,6 @@ int TabWidget::lastTabIndex() const
return m_lastTabIndex;
}
void TabWidget::showNavigationBar(QWidget* bar)
{
WebTab* tab = weTab();
if (tab) {
tab->showNavigationBar(bar);
}
}
TabBar* TabWidget::getTabBar() const
{
return m_tabBar;
@ -904,19 +900,18 @@ void TabWidget::restorePinnedTabs()
int addedIndex;
if (!historyState.isEmpty()) {
addedIndex = addView(QUrl(), Qz::NT_CleanSelectedTab);
addedIndex = addView(QUrl(), Qz::NT_CleanSelectedTab, false, true);
weTab(addedIndex)->p_restoreTab(url, historyState);
}
else {
addedIndex = addView(url);
addedIndex = addView(url, tr("New tab"), Qz::NT_SelectedTab, false, -1, true);
}
WebTab* webTab = weTab(addedIndex);
if (webTab) {
webTab->setPinned(true);
emit pinnedTabAdded();
}
m_tabBar->updatePinnedTabCloseButton(addedIndex);

View File

@ -23,6 +23,7 @@
#include <QNetworkRequest>
#include <QMenu>
#include "tabstackedwidget.h"
#include "toolbutton.h"
#include "qz_namespace.h"
#include "webtab.h"
@ -64,7 +65,7 @@ private:
void mouseReleaseEvent(QMouseEvent* event);
};
class QT_QUPZILLA_EXPORT TabWidget : public QTabWidget
class QT_QUPZILLA_EXPORT TabWidget : public TabStackedWidget
{
Q_OBJECT
public:
@ -95,8 +96,6 @@ public:
int pinnedTabsCount() const;
int lastTabIndex() const;
void showNavigationBar(QWidget* bar);
TabBar* getTabBar() const;
ClosedTabsManager* closedTabsManager() const;
QList<WebTab*> allTabs(bool withPinned = true);
@ -108,16 +107,12 @@ public:
void disconnectObjects();
signals:
void pinnedTabClosed();
void pinnedTabAdded();
public slots:
int addView(const QUrl &url, const Qz::NewTabPositionFlags &openFlags, bool selectLine = false);
int addView(const QNetworkRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine = false);
int addView(const QUrl &url, const Qz::NewTabPositionFlags &openFlags, bool selectLine = false, bool pinned = false);
int addView(const QNetworkRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine = false, bool pinned = false);
int addView(const QUrl &url, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1);
int addView(QNetworkRequest req, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1);
int addView(const QUrl &url, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1, bool pinned = false);
int addView(QNetworkRequest req, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1, bool pinned = false);
int addView(WebTab* tab);
void addTabFromClipboard();
@ -138,6 +133,8 @@ public slots:
void showButtons();
void hideButtons();
void tabBarOverFlowChanged(bool overFlowed);
private slots:
void aboutToShowTabsMenu();
void actionChangeIndex();
@ -149,8 +146,6 @@ private:
inline bool validIndex(int index) const { return index >= 0 && index < count(); }
void resizeEvent(QResizeEvent* e);
bool m_dontQuitWithOneTab;
bool m_closedInsteadOpened;
bool m_newTabAfterActive;
@ -168,6 +163,8 @@ private:
MenuTabs* m_menuTabs;
ToolButton* m_buttonListTabs;
AddTabButton* m_buttonAddTab;
ToolButton* m_buttonListTabs2;
AddTabButton* m_buttonAddTab2;
ClosedTabsManager* m_closedTabsManager;
QStackedWidget* m_locationBars;

View File

@ -180,9 +180,6 @@ void WebTab::moveToWindow(QupZilla* window)
{
p_QupZilla = window;
hideNavigationBar();
showNavigationBar(p_QupZilla->navigationContainer());
m_view->moveToWindow(p_QupZilla);
}
@ -343,7 +340,7 @@ QPixmap WebTab::renderTabPreview()
void WebTab::showNotification(QWidget* notif)
{
const int notifPos = p_QupZilla->tabsOnTop() ? 1 : 0;
const int notifPos = 0;
if (m_layout->count() > notifPos + 1) {
delete m_layout->itemAt(notifPos)->widget();
@ -366,24 +363,6 @@ int WebTab::tabIndex() const
return m_view->tabIndex();
}
void WebTab::showNavigationBar(QWidget* bar)
{
if (bar) {
m_navigationContainer = bar;
m_layout->insertWidget(0, m_navigationContainer);
// Needed to prevent flickering when closing tabs
m_navigationContainer->setUpdatesEnabled(true);
if (p_QupZilla->isFullScreen()) {
m_navigationContainer->setVisible(p_QupZilla->tabWidget()->getTabBar()->isVisible());
}
else {
m_navigationContainer->show();
}
}
}
void WebTab::pinTab(int index)
{
TabWidget* tabWidget = p_QupZilla->tabWidget();
@ -391,19 +370,9 @@ void WebTab::pinTab(int index)
return;
}
if (m_pinned) { //Unpin tab
m_pinned = false;
tabWidget->setTabText(index, m_view->title());
tabWidget->getTabBar()->updatePinnedTabCloseButton(index);
}
else { // Pin tab
m_pinned = true;
tabWidget->setCurrentIndex(0); // <<-- those 2 lines fixes
tabWidget->getTabBar()->moveTab(index, 0); // | weird behavior with bad
tabWidget->setTabText(0, QString()); // | tabwidget update if we
tabWidget->setCurrentIndex(0); // <<-- are moving current tab
tabWidget->getTabBar()->updatePinnedTabCloseButton(0);
}
m_pinned = !m_pinned;
index = tabWidget->pinUnPinTab(index, m_view->title());
tabWidget->setCurrentIndex(index);
}
void WebTab::disconnectObjects()
@ -413,27 +382,7 @@ void WebTab::disconnectObjects()
disconnect(m_view);
}
void WebTab::hideNavigationBar()
{
if (m_navigationContainer && p_QupZilla->tabsOnTop()) {
m_layout->removeWidget(m_navigationContainer);
// Needed to prevent flickering when closing tabs
m_navigationContainer->setUpdatesEnabled(false);
m_navigationContainer->hide();
// Needed to prevent deleting m_navigationContainer in ~QWidget
m_navigationContainer->setParent(p_QupZilla);
}
}
WebTab::~WebTab()
{
// #838 !p_QupZilla->isClosing() fixes crash on app close with Oxygen theme
if (!p_QupZilla->isClosing()) {
hideNavigationBar();
}
delete m_locationBar.data();
}

View File

@ -78,7 +78,6 @@ public:
void setPinned(bool state);
int tabIndex() const;
void showNavigationBar(QWidget* bar);
void setLocationBar(LocationBar* bar);
LocationBar* locationBar() const;
@ -103,8 +102,6 @@ private slots:
void slotRestore();
private:
void hideNavigationBar();
QupZilla* p_QupZilla;
TabbedWebView* m_view;
QVBoxLayout* m_layout;