diff options
Diffstat (limited to 'src/mainwindow/widgets/tabbar.cpp')
-rw-r--r-- | src/mainwindow/widgets/tabbar.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/mainwindow/widgets/tabbar.cpp b/src/mainwindow/widgets/tabbar.cpp new file mode 100644 index 0000000..ef32ef0 --- /dev/null +++ b/src/mainwindow/widgets/tabbar.cpp @@ -0,0 +1,171 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "tabbar.h" +#include "mainwindow/mainwindow.h" +#include "webengine/webengineprofile.h" +#include "webengine/webview.h" +#include <QContextMenuEvent> +#include <QMenu> + +TabBar::TabBar(const QHash<QString, QString> &config, MainWindow *parent) + : QTabBar(parent) +{ + Q_CHECK_PTR(parent); + + setElideMode(Qt::ElideRight); + setTabsClosable(true); + setMovable(true); + setContextMenuPolicy(Qt::DefaultContextMenu); + + connect(this, &TabBar::tabCloseRequested, this, &TabBar::removeTab); + connect(this, &TabBar::currentChanged, this, &TabBar::handleCurrentChanged); + connect(this, &TabBar::tabMoved, this, &TabBar::updateVectorArrangement); + + newTab_action = new QAction(tr("New Tab"), parent); + newTab_action->setObjectName("newTab_action"); + newTab_action->setShortcut(QKeySequence(config["tabbar.shortcuts.new"])); + connect(newTab_action, &QAction::triggered, parent, [parent, this]() { + parent->newTab(parent->profile()->newtab()); + }); + parent->addAction(newTab_action); + + closeTab_action = new QAction(tr("Close Tab"), parent); + closeTab_action->setObjectName("closeTab_action"); + closeTab_action->setShortcut(QKeySequence(config["tabbar.shortcuts.close"])); + connect(closeTab_action, &QAction::triggered, this, [this]() { + removeTab(currentIndex()); + }); + parent->addAction(closeTab_action); + + leftTab_action = new QAction(tr("Left Tab"), parent); + leftTab_action->setObjectName("leftTab_action"); + leftTab_action->setShortcut(QKeySequence(config["tabbar.shortcuts.left"])); + connect(leftTab_action, &QAction::triggered, this, [this]() { + setCurrentIndex(currentIndex() - 1); + }); + parent->addAction(leftTab_action); + + rightTab_action = new QAction(tr("Right Tab"), parent); + rightTab_action->setObjectName("rightTab_action"); + rightTab_action->setShortcut(QKeySequence(config["tabbar.shortcuts.right"])); + connect(rightTab_action, &QAction::triggered, this, [this]() { + setCurrentIndex(currentIndex() + 1); + }); + parent->addAction(rightTab_action); + + // tab context menu + { + tabContextMenu = new QMenu(this); + + auto *closeTab = tabContextMenu->addAction(tr("Close Tab")); + connect(closeTab, &QAction::triggered, this, [this]() { + removeTab(tabAt(mapFromGlobal(tabContextMenu->pos()))); + }); + + auto *closeTabsLeft = tabContextMenu->addAction(tr("Close Tabs left")); + connect(closeTabsLeft, &QAction::triggered, this, [this]() { + int idx = tabAt(mapFromGlobal(tabContextMenu->pos())); + for(int i = idx - 1; i >= 0; --i) { + removeTab(i); + } + }); + + auto *closeTabsRight = tabContextMenu->addAction(tr("Close Tabs right")); + connect(closeTabsRight, &QAction::triggered, this, [this]() { + int idx = tabAt(mapFromGlobal(tabContextMenu->pos())); + for(int i = count() - 1; i > idx; --i) { + removeTab(i); + } + }); + } +} + +TabBar::~TabBar() +{ + // cleanup + qDeleteAll(m_views); + m_views.clear(); +} + +void TabBar::setProfile(WebEngineProfile *profile) +{ + Q_CHECK_PTR(profile); + + for(auto view : qAsConst(m_views)) { + auto *page = new WebPage(profile); + page->load(view->url()); + view->page()->deleteLater(); + view->setPage(page); + } +} + +WebView *TabBar::currentView() +{ + return m_views.at(currentIndex()); +} + +int TabBar::addTab(WebView *view) +{ + m_views.append(view); + + connect(view, &QWebEngineView::titleChanged, [this, view](const QString &title) { + int index = m_views.indexOf(view); + setTabText(index, title); + setTabToolTip(index, title); + }); + connect(view, &QWebEngineView::iconChanged, [this, view](const QIcon &icon) { + int index = m_views.indexOf(view); + setTabIcon(index, icon); + }); + + return QTabBar::addTab("New Tab"); +} + +void TabBar::removeTab(int index) +{ + // remove the tab data from the index + m_views.at(index)->deleteLater(); + m_views.remove(index); + + // remove the tab from the QTabBar + // this emits the currentTabChanged signal, so it should be done after the view is removed from the index + QTabBar::removeTab(index); +} + +void TabBar::contextMenuEvent(QContextMenuEvent *event) +{ + // check if the context menu was called on a tab + int tabIndex = tabAt(event->pos()); + if(tabIndex < 0) { + return; + } + + tabContextMenu->exec(event->globalPos()); +} + +QSize TabBar::tabSizeHint(int index) const +{ + Q_UNUSED(index) + return QSize(200, this->height()); +} + +void TabBar::handleCurrentChanged(int index) +{ + if(index < 0) { + newTab_action->trigger(); + return; + } + + emit currentTabChanged(m_views.at(index)); +} + +void TabBar::updateVectorArrangement(int from, int to) +{ + m_views.move(from, to); +} |