From bbbe136346e5ab7ef6ce91e7d93186c9290a92a5 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Sun, 4 Feb 2018 11:13:18 +0100 Subject: [PATCH] VerticalTabs: Handle Ctrl+Tab switching tabs in tree order --- src/plugins/VerticalTabs/tablistview.cpp | 23 ++++++- src/plugins/VerticalTabs/tablistview.h | 3 + .../VerticalTabs/verticaltabscontroller.cpp | 22 +++++++ .../VerticalTabs/verticaltabscontroller.h | 11 ++++ .../VerticalTabs/verticaltabsplugin.cpp | 10 +++ src/plugins/VerticalTabs/verticaltabsplugin.h | 1 + .../VerticalTabs/verticaltabswidget.cpp | 62 ++++++++++++++++++- src/plugins/VerticalTabs/verticaltabswidget.h | 7 +++ 8 files changed, 135 insertions(+), 4 deletions(-) diff --git a/src/plugins/VerticalTabs/tablistview.cpp b/src/plugins/VerticalTabs/tablistview.cpp index fa3b901c2..c5a3920a4 100644 --- a/src/plugins/VerticalTabs/tablistview.cpp +++ b/src/plugins/VerticalTabs/tablistview.cpp @@ -83,10 +83,9 @@ void TabListView::adjustStyleOption(QStyleOptionViewItem *option) } else if (model()->rowCount() == 1) { option->viewItemPosition = QStyleOptionViewItem::OnlyOne; } else { - const QRect rect = visualRect(index); - if (!indexAt(QPoint(rect.x() - rect.width() / 2, rect.y())).isValid()) { + if (!indexBefore(index).isValid()) { option->viewItemPosition = QStyleOptionViewItem::Beginning; - } else if (!indexAt(QPoint(rect.x() + rect.width() / 2, rect.y())).isValid()) { + } else if (!indexAfter(index).isValid()) { option->viewItemPosition = QStyleOptionViewItem::End; } else { option->viewItemPosition = QStyleOptionViewItem::Middle; @@ -94,6 +93,24 @@ void TabListView::adjustStyleOption(QStyleOptionViewItem *option) } } +QModelIndex TabListView::indexAfter(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + const QRect rect = visualRect(index); + return indexAt(QPoint(rect.right() + rect.width() / 2, rect.y())); +} + +QModelIndex TabListView::indexBefore(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + const QRect rect = visualRect(index); + return indexAt(QPoint(rect.left() - rect.width() / 2, rect.y())); +} + void TabListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { if (current.data(TabModel::CurrentTabRole).toBool()) { diff --git a/src/plugins/VerticalTabs/tablistview.h b/src/plugins/VerticalTabs/tablistview.h index 0599df444..83ea86d71 100644 --- a/src/plugins/VerticalTabs/tablistview.h +++ b/src/plugins/VerticalTabs/tablistview.h @@ -34,6 +34,9 @@ public: void updateIndex(const QModelIndex &index); void adjustStyleOption(QStyleOptionViewItem *option); + QModelIndex indexAfter(const QModelIndex &index) const; + QModelIndex indexBefore(const QModelIndex &index) const; + private: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()) override; diff --git a/src/plugins/VerticalTabs/verticaltabscontroller.cpp b/src/plugins/VerticalTabs/verticaltabscontroller.cpp index 627818a21..b782c6db0 100644 --- a/src/plugins/VerticalTabs/verticaltabscontroller.cpp +++ b/src/plugins/VerticalTabs/verticaltabscontroller.cpp @@ -19,7 +19,10 @@ #include "verticaltabsplugin.h" #include "verticaltabswidget.h" +#include "tabwidget.h" + #include +#include VerticalTabsController::VerticalTabsController(VerticalTabsPlugin *plugin) : SideBarInterface(plugin) @@ -47,5 +50,24 @@ QWidget *VerticalTabsController::createSideBarWidget(BrowserWindow *window) connect(m_plugin, &VerticalTabsPlugin::viewTypeChanged, widget, &VerticalTabsWidget::setViewType); connect(m_plugin, &VerticalTabsPlugin::styleSheetChanged, widget, &VerticalTabsWidget::setStyleSheet); + m_widgets[window] = widget; return widget; } + +bool VerticalTabsController::handleKeyPress(QKeyEvent *event, TabWidget *tabWidget) +{ + if (event->key() == Qt::Key_Tab && event->modifiers() == Qt::ControlModifier) { + VerticalTabsWidget *widget = m_widgets.value(tabWidget->browserWindow()); + if (widget) { + widget->switchToNextTab(); + return true; + } + } else if (event->key() == Qt::Key_Backtab && event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) { + VerticalTabsWidget *widget = m_widgets.value(tabWidget->browserWindow()); + if (widget) { + widget->switchToPreviousTab(); + return true; + } + } + return false; +} diff --git a/src/plugins/VerticalTabs/verticaltabscontroller.h b/src/plugins/VerticalTabs/verticaltabscontroller.h index 3d69222d2..f324d36e5 100644 --- a/src/plugins/VerticalTabs/verticaltabscontroller.h +++ b/src/plugins/VerticalTabs/verticaltabscontroller.h @@ -17,9 +17,17 @@ * ============================================================ */ #pragma once +#include +#include + #include "sidebarinterface.h" +class QKeyEvent; + +class TabWidget; + class VerticalTabsPlugin; +class VerticalTabsWidget; class VerticalTabsController : public SideBarInterface { @@ -31,6 +39,9 @@ public: QAction *createMenuAction() override; QWidget *createSideBarWidget(BrowserWindow *window) override; + bool handleKeyPress(QKeyEvent *event, TabWidget *tabWidget); + private: VerticalTabsPlugin *m_plugin; + QHash> m_widgets; }; diff --git a/src/plugins/VerticalTabs/verticaltabsplugin.cpp b/src/plugins/VerticalTabs/verticaltabsplugin.cpp index 74051ea37..af4b455ae 100644 --- a/src/plugins/VerticalTabs/verticaltabsplugin.cpp +++ b/src/plugins/VerticalTabs/verticaltabsplugin.cpp @@ -63,6 +63,8 @@ void VerticalTabsPlugin::init(InitState state, const QString &settingsPath) m_controller = new VerticalTabsController(this); SideBarManager::addSidebar(QSL("VerticalTabs"), m_controller); + QZ_REGISTER_EVENT_HANDLER(PluginProxy::KeyPressHandler); + setWebTabBehavior(m_addChildBehavior); loadStyleSheet(m_theme); @@ -103,6 +105,14 @@ void VerticalTabsPlugin::showSettings(QWidget *parent) settings->exec(); } +bool VerticalTabsPlugin::keyPress(const Qz::ObjectName &type, QObject *obj, QKeyEvent *event) +{ + if (type == Qz::ON_TabWidget) { + return m_controller->handleKeyPress(event, static_cast(obj)); + } + return false; +} + VerticalTabsPlugin::ViewType VerticalTabsPlugin::viewType() const { return m_viewType; diff --git a/src/plugins/VerticalTabs/verticaltabsplugin.h b/src/plugins/VerticalTabs/verticaltabsplugin.h index fda6d2590..1c1736189 100644 --- a/src/plugins/VerticalTabs/verticaltabsplugin.h +++ b/src/plugins/VerticalTabs/verticaltabsplugin.h @@ -38,6 +38,7 @@ public: bool testPlugin() override; QTranslator* getTranslator(const QString &locale) override; void showSettings(QWidget *parent = nullptr) override; + bool keyPress(const Qz::ObjectName &type, QObject *obj, QKeyEvent *event) override; enum ViewType { TabListView, diff --git a/src/plugins/VerticalTabs/verticaltabswidget.cpp b/src/plugins/VerticalTabs/verticaltabswidget.cpp index 31e156adf..be57da3d7 100644 --- a/src/plugins/VerticalTabs/verticaltabswidget.cpp +++ b/src/plugins/VerticalTabs/verticaltabswidget.cpp @@ -20,9 +20,11 @@ #include "tablistview.h" #include "tabfiltermodel.h" +#include "webtab.h" #include "tabmodel.h" #include "toolbutton.h" #include "tabtreemodel.h" +#include "tabbedwebview.h" #include "browserwindow.h" #include @@ -36,7 +38,7 @@ VerticalTabsWidget::VerticalTabsWidget(BrowserWindow *window) layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); - TabListView *m_pinnedView = new TabListView(this); + m_pinnedView = new TabListView(this); TabFilterModel *model = new TabFilterModel(m_pinnedView); model->setFilterPinnedTabs(false); model->setSourceModel(m_window->tabModel()); @@ -86,3 +88,61 @@ void VerticalTabsWidget::setViewType(VerticalTabsPlugin::ViewType type) break; }; } + +void VerticalTabsWidget::switchToNextTab() +{ + WebTab *tab = nextTab(); + if (tab) { + tab->makeCurrentTab(); + } +} + +void VerticalTabsWidget::switchToPreviousTab() +{ + WebTab *tab = previousTab(); + if (tab) { + tab->makeCurrentTab(); + } +} + +WebTab *VerticalTabsWidget::nextTab() const +{ + QModelIndex next; + if (m_window->weView()->webTab()->isPinned()) { + next = m_pinnedView->indexAfter(m_pinnedView->currentIndex()); + if (!next.isValid()) { + next = m_normalView->model()->index(0, 0); + } + } else { + next = m_normalView->indexBelow(m_normalView->currentIndex()); + if (!next.isValid()) { + next = m_pinnedView->model()->index(0, 0); + } + } + return next.data(TabModel::WebTabRole).value(); +} + +WebTab *VerticalTabsWidget::previousTab() const +{ + QModelIndex previous; + if (m_window->weView()->webTab()->isPinned()) { + previous = m_pinnedView->indexBefore(m_pinnedView->currentIndex()); + if (!previous.isValid()) { + previous = m_normalView->model()->index(m_normalView->model()->rowCount() - 1, 0); + while (previous.isValid()) { + const QModelIndex below = m_normalView->indexBelow(previous); + if (below.isValid()) { + previous = below; + } else { + break; + } + } + } + } else { + previous = m_normalView->indexAbove(m_normalView->currentIndex()); + if (!previous.isValid()) { + previous = m_pinnedView->model()->index(m_pinnedView->model()->rowCount() - 1, 0); + } + } + return previous.data(TabModel::WebTabRole).value(); +} diff --git a/src/plugins/VerticalTabs/verticaltabswidget.h b/src/plugins/VerticalTabs/verticaltabswidget.h index b506d0282..bfa215d0a 100644 --- a/src/plugins/VerticalTabs/verticaltabswidget.h +++ b/src/plugins/VerticalTabs/verticaltabswidget.h @@ -21,6 +21,7 @@ #include "verticaltabsplugin.h" +class WebTab; class BrowserWindow; class TabTreeModel; @@ -35,7 +36,13 @@ public: void setViewType(VerticalTabsPlugin::ViewType type); + void switchToNextTab(); + void switchToPreviousTab(); + private: + WebTab *nextTab() const; + WebTab *previousTab() const; + BrowserWindow *m_window; TabListView *m_pinnedView; TabTreeView *m_normalView;