/* * 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 #include TabBar::TabBar(const QHash &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); }