From e68dbcfd937a3de352152857ef9ad146a7c89bfc Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Tue, 7 Aug 2018 10:18:28 +0200 Subject: Move SubWindow to src/subwindow --- src/CMakeLists.txt | 10 +- src/browser.cpp | 2 +- src/mainwindow/mainwindow.cpp | 18 ++-- src/mainwindow/mainwindow.h | 1 - src/mainwindow/mainwindow.ui | 28 +++--- src/mainwindow/subwindow.cpp | 171 ---------------------------------- src/mainwindow/subwindow.h | 51 ---------- src/mainwindow/widgets/tabwidget.cpp | 123 ------------------------ src/mainwindow/widgets/tabwidget.h | 37 -------- src/session.cpp | 2 +- src/subwindow/subwindow.cpp | 176 +++++++++++++++++++++++++++++++++++ src/subwindow/subwindow.h | 51 ++++++++++ src/subwindow/tabwidget.cpp | 123 ++++++++++++++++++++++++ src/subwindow/tabwidget.h | 37 ++++++++ src/webengine/webview.cpp | 2 +- 15 files changed, 418 insertions(+), 414 deletions(-) delete mode 100644 src/mainwindow/subwindow.cpp delete mode 100644 src/mainwindow/subwindow.h delete mode 100644 src/mainwindow/widgets/tabwidget.cpp delete mode 100644 src/mainwindow/widgets/tabwidget.h create mode 100644 src/subwindow/subwindow.cpp create mode 100644 src/subwindow/subwindow.h create mode 100644 src/subwindow/tabwidget.cpp create mode 100644 src/subwindow/tabwidget.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c7b6df..4549155 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,8 +21,6 @@ set(poi_SRC mainwindow/mainwindow.cpp mainwindow/mainwindow.h mainwindow/mainwindow.ui - mainwindow/subwindow.cpp - mainwindow/subwindow.h mainwindow/widgets/dockwidget.cpp mainwindow/widgets/dockwidget.h mainwindow/widgets/navigationbar.cpp @@ -30,8 +28,12 @@ set(poi_SRC mainwindow/widgets/searchform.cpp mainwindow/widgets/searchform.h mainwindow/widgets/searchform.ui - mainwindow/widgets/tabwidget.cpp - mainwindow/widgets/tabwidget.h + + # subwindow + subwindow/subwindow.cpp + subwindow/subwindow.h + subwindow/tabwidget.cpp + subwindow/tabwidget.h # webengine webengine/urlinterceptor.cpp diff --git a/src/browser.cpp b/src/browser.cpp index 46018fb..375796c 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -9,7 +9,7 @@ #include "browser.h" #include "addressbar/addressbar.h" #include "mainwindow/mainwindow.h" -#include "mainwindow/subwindow.h" +#include "subwindow/subwindow.h" #include "webengine/urlinterceptor.h" #include #include diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp index 6cf3f84..7f9cdcc 100644 --- a/src/mainwindow/mainwindow.cpp +++ b/src/mainwindow/mainwindow.cpp @@ -10,7 +10,7 @@ #include "ui_mainwindow.h" #include "addressbar/addressbar.h" #include "browser.h" -#include "subwindow.h" +#include "subwindow/subwindow.h" #include "webengine/webview.h" #include "widgets/dockwidget.h" #include "widgets/navigationbar.h" @@ -137,13 +137,11 @@ MainWindow::MainWindow(const std::unique_ptr &config, QWidget *pa // connect window menu { - connect(ui->actionTileWindows, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows); - config->setShortcut(ui->actionTileWindows, "mainwindow.shortcuts.tileWindows"); + connect(ui->actionTileSubwindows, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows); + config->setShortcut(ui->actionTileSubwindows, "mainwindow.shortcuts.tileWindows"); - connect(ui->actionCascadeWindows, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows); - config->setShortcut(ui->actionCascadeWindows, "mainwindow.shortcuts.cascadeWindows"); - - subWindowAction = ui->actionCurrentWindow; + connect(ui->actionCascadeSubwindows, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows); + config->setShortcut(ui->actionCascadeSubwindows, "mainwindow.shortcuts.cascadeWindows"); } // connect page menu @@ -205,16 +203,16 @@ MainWindow::MainWindow(const std::unique_ptr &config, QWidget *pa disconnect(viewChangedConnection); disconnect(searchBoxConnection); disconnect(statusBarConnection); - subWindowAction->setMenu(nullptr); + ui->actionCurrentSubwindow->setMenu(nullptr); auto *w = qobject_cast(window); if(w == nullptr) { // no current subwindow, clear everything setView(nullptr); - subWindowAction->setMenu(nullptr); + ui->actionCurrentSubwindow->setMenu(nullptr); } else { setView(w->currentView()); - subWindowAction->setMenu(w->systemMenu()); + ui->actionCurrentSubwindow->setMenu(w->systemMenu()); viewChangedConnection = connect(w, &SubWindow::currentViewChanged, this, &MainWindow::setView); statusBarConnection = connect(w, &SubWindow::showStatusMessage, statusBar(), &QStatusBar::showMessage); } diff --git a/src/mainwindow/mainwindow.h b/src/mainwindow/mainwindow.h index 3768348..3abeb39 100644 --- a/src/mainwindow/mainwindow.h +++ b/src/mainwindow/mainwindow.h @@ -65,7 +65,6 @@ protected: private: Ui::MainWindow *ui; - QAction *subWindowAction = nullptr; QMenu *toolsMenu = nullptr; QMenu *pageLoadProfileMenu = nullptr; diff --git a/src/mainwindow/mainwindow.ui b/src/mainwindow/mainwindow.ui index d670b66..cb6d39e 100644 --- a/src/mainwindow/mainwindow.ui +++ b/src/mainwindow/mainwindow.ui @@ -37,19 +37,19 @@ - Session + Sessio&n - + - Wi&ndow + S&ubwindow - - + + - + @@ -69,7 +69,7 @@ - + @@ -109,19 +109,19 @@ &Load Session - + - &Tile Windows + &Tile Subwindows - + - &Cascade Windows + &Cascade Subwindows - + - Current &Window + Current &Subwindow @@ -146,7 +146,7 @@ - Developer Tools + &Developer Tools diff --git a/src/mainwindow/subwindow.cpp b/src/mainwindow/subwindow.cpp deleted file mode 100644 index bdb852a..0000000 --- a/src/mainwindow/subwindow.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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 "subwindow.h" -#include "browser.h" -#include "webengine/webview.h" -#include "widgets/tabwidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "profilemanager.h" -#include - -SubWindow::SubWindow(const std::unique_ptr &config, QWidget *parent, Qt::WindowFlags flags) - : QMdiSubWindow(parent, flags) - , tabWidget(new TabWidget(this)) -{ - // delete this window when it closes - setAttribute(Qt::WA_DeleteOnClose, true); - - resize(800, 600); - setWidget(tabWidget); - - m_profile = WebProfile::defaultProfile(); - - // system menu - { - auto *menu = systemMenu(); - menu->addSeparator(); - - auto *profileName_action = menu->addAction(tr("Profile: %1").arg(m_profile->name())); - profileName_action->setEnabled(false); - auto *loadProfile_menu = menu->addMenu(tr("Load profile")); - - Browser *browser = qobject_cast(qApp); - Q_CHECK_PTR(browser); - - ProfileIterator it(ProfileManager::profileList()); - while(it.hasNext()) { - it.next(); - auto *profile =it.value(); - auto *loadAction = loadProfile_menu->addAction(profile->name()); - - connect(loadAction, &QAction::triggered, this, [=]() { - this->setProfile(profile); - profileName_action->setText(tr("Profile: %1").arg(profile->name())); - }); - } - } - - // new tab button - auto *newTab_button = new QToolButton(this); - newTab_button->setIcon(style()->standardIcon(QStyle::SP_FileIcon)); - newTab_button->setToolTip(tr("Add tab")); - newTab_button->setShortcut(QKeySequence(config->value("window.shortcuts.new").value())); - connect(newTab_button, &QToolButton::clicked, this, [=]() { - auto index = addTab(WebProfile::defaultProfile()->newtab()); - tabWidget->setCurrentIndex(index); - }); - tabWidget->setCornerWidget(newTab_button, Qt::TopRightCorner); - - // general actions - auto *closeTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.close").value()), this); - connect(closeTab_shortcut, &QShortcut::activated, this, [=]() { - tabWidget->deleteTab(tabWidget->currentIndex()); - }); - - auto *leftTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.left").value()), this); - connect(leftTab_shortcut, &QShortcut::activated, this, [=]() { - tabWidget->setCurrentIndex(qMax(0, tabWidget->currentIndex() - 1)); - }); - - auto *rightTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.right").value()), this); - connect(rightTab_shortcut, &QShortcut::activated, this, [=]() { - tabWidget->setCurrentIndex(qMin(tabWidget->currentIndex() + 1, tabWidget->count() - 1)); - }); - - auto *fullScreen_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.fullscreen").value()), this); - connect(fullScreen_shortcut, &QShortcut::activated, this, [=]() { - auto *w = this->window(); - if(w->isFullScreen()) - w->showNormal(); - else - w->showFullScreen(); - }); - - connect(tabWidget, &TabWidget::currentChanged, [this](int index) { - if(index < 0) { - // last tab has been closed - close(); - } else { - auto *view = dynamic_cast(tabWidget->widget(index)); - Q_CHECK_PTR(view); - - disconnect(titleConnection); - disconnect(linkHoveredConnection); - - titleConnection = connect(view, &WebView::titleChanged, this, [this](const QString &title) { - auto *v = qobject_cast(sender()); - this->setWindowTitle(QString("%1 :%2").arg(title, v->profile()->name())); - }); - setWindowTitle(QString("%1 :%2").arg(view->title(), view->profile()->name())); - - linkHoveredConnection = connect(view->page(), &WebPage::linkHovered, this, [this](const QString &url) { - if(!url.isEmpty()) - emit showStatusMessage(url, 3000); - }); - - emit currentViewChanged(view); - } - }); -} - -SubWindow::~SubWindow() -{ - delete tabWidget; -} - -WebView *SubWindow::currentView() -{ - return qobject_cast(tabWidget->currentWidget()); -} - -WebView *SubWindow::view(int index) const -{ - return qobject_cast(tabWidget->widget(index)); -} - -int SubWindow::tabCount() const -{ - return tabWidget->count(); -} - -void SubWindow::setProfile(WebProfile *profile) -{ - Q_CHECK_PTR(profile); - this->m_profile = profile; - for(int i = 0; i < tabWidget->count(); ++i) { - auto *view = qobject_cast(tabWidget->widget(i)); - view->setProfile(profile); - } -} - -WebProfile *SubWindow::profile() const -{ - return m_profile; -} - -int SubWindow::addTab(const QUrl &url, WebProfile *profile) -{ - auto *view = new WebView((profile == nullptr) ? m_profile : profile, this); - if(!url.isEmpty()) - view->load(url); - return tabWidget->addTab(view); -} - -void SubWindow::setCurrentTab(int index) -{ - tabWidget->setCurrentIndex(index); -} diff --git a/src/mainwindow/subwindow.h b/src/mainwindow/subwindow.h deleted file mode 100644 index b7c4aee..0000000 --- a/src/mainwindow/subwindow.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 - */ - -#ifndef SMOLBOTE_SUBWINDOW_H -#define SMOLBOTE_SUBWINDOW_H - -#include -#include -#include - -class TabWidget; -class WebView; -class WebProfile; -class Configuration; -class SubWindow : public QMdiSubWindow -{ - Q_OBJECT - -public: - explicit SubWindow(const std::unique_ptr &config, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); - ~SubWindow() override; - - WebView *currentView(); - WebView *view(int index) const; - int tabCount() const; - - void setProfile(WebProfile *profile); - WebProfile *profile() const; - -signals: - void currentViewChanged(WebView *view); - void showStatusMessage(const QString &message, int timeout = 0); - -public slots: - int addTab(const QUrl &url = QUrl(), WebProfile *profile = nullptr); - void setCurrentTab(int index); - -private: - WebProfile *m_profile; - TabWidget *tabWidget; - - QMetaObject::Connection titleConnection; - QMetaObject::Connection linkHoveredConnection; -}; - -#endif // SMOLBOTE_SUBWINDOW_H diff --git a/src/mainwindow/widgets/tabwidget.cpp b/src/mainwindow/widgets/tabwidget.cpp deleted file mode 100644 index 1ddfc95..0000000 --- a/src/mainwindow/widgets/tabwidget.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 "tabwidget.h" -#include "browser.h" -#include "webengine/webview.h" -#include -#include -#include -#include -#include - -TabWidget::TabWidget(QWidget *parent) - : QTabWidget(parent) -{ - setStyleSheet("QTabBar::tab { width: 200px; }"); - - setTabsClosable(true); - //setTabBarAutoHide(true); - setElideMode(Qt::ElideRight); - setMovable(true); - - connect(this, &TabWidget::tabCloseRequested, this, &TabWidget::deleteTab); - - // when changing tabs, give focus to the widget - // otherwise when closing tabs, the tabwidget will retain focus - connect(this, &TabWidget::currentChanged, this, [this](int index) { - if(widget(index)) - widget(index)->setFocus(); - }); - - // context menu - tabContextMenu = new QMenu(this); - auto *closeTab = tabContextMenu->addAction(tr("Close Tab")); - connect(closeTab, &QAction::triggered, this, [this]() { - deleteTab(this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos()))); - }); - - auto *closeTabsLeft = tabContextMenu->addAction(tr("Close Tabs left")); - connect(closeTabsLeft, &QAction::triggered, this, [this]() { - int idx = this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos())); - for(int i = idx - 1; i >= 0; --i) { - deleteTab(i); - } - }); - - auto *closeTabsRight = tabContextMenu->addAction(tr("Close Tabs right")); - connect(closeTabsRight, &QAction::triggered, this, [this]() { - int idx = this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos())); - for(int i = count() - 1; i > idx; --i) { - deleteTab(i); - } - }); -} - -TabWidget::~TabWidget() -{ - for(int i = count() - 1; i >= 0; i--) { - delete widget(i); - } -} - -int TabWidget::addTab(WebView *view) -{ - Q_ASSERT_X(view != nullptr, "TabWidget::addTab", "Tried to add null view"); - - int idx = QTabWidget::addTab(view, view->title()); - connect(view, &WebView::titleChanged, [this, view](const QString &title) { - int idx = this->indexOf(view); - Q_ASSERT(idx != -1); - - this->setTabText(idx, title); - }); - connect(view, &WebView::iconChanged, [this, view](const QIcon &icon) { - int idx = this->indexOf(view); - Q_ASSERT(idx != -1); - - this->setTabIcon(idx, icon); - }); - - return idx; -} - -void TabWidget::deleteTab(int index) -{ - // deleting the widget automatically removes the tab? - auto *w = widget(index); - disconnect(w); - delete w; - - if(count() == 0) - parentWidget()->close(); -} - -void TabWidget::contextMenuEvent(QContextMenuEvent *event) -{ - // check if the context menu was called on a tab - int tabIndex = tabBar()->tabAt(event->pos()); - if(tabIndex < 0) { - return; - } - - tabContextMenu->exec(event->globalPos()); -} - -void TabWidget::mousePressEvent(QMouseEvent *event) -{ - if(event->button() == Qt::MiddleButton) { - int index = tabBar()->tabAt(event->pos()); - if(index >= 0) { - deleteTab(index); - } - event->accept(); - return; - } - - QTabWidget::mousePressEvent(event); -} diff --git a/src/mainwindow/widgets/tabwidget.h b/src/mainwindow/widgets/tabwidget.h deleted file mode 100644 index 793e041..0000000 --- a/src/mainwindow/widgets/tabwidget.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - */ - -#ifndef SMOLBOTE_TABWIDGET_H -#define SMOLBOTE_TABWIDGET_H - -#include - -class QAction; -class QMenu; -class WebView; -class TabWidget : public QTabWidget -{ - Q_OBJECT - -public: - explicit TabWidget(QWidget *parent = nullptr); - ~TabWidget() override; - -public slots: - int addTab(WebView *view); - void deleteTab(int index); - -protected: - void contextMenuEvent(QContextMenuEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - -private: - QMenu *tabContextMenu; -}; - -#endif // SMOLBOTE_TABWIDGET_H diff --git a/src/session.cpp b/src/session.cpp index 0cbb0e8..0781cd7 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -8,7 +8,7 @@ #include "session.h" #include "mainwindow/mainwindow.h" -#include "mainwindow/subwindow.h" +#include "subwindow/subwindow.h" #include #include #include "webengine/webview.h" diff --git a/src/subwindow/subwindow.cpp b/src/subwindow/subwindow.cpp new file mode 100644 index 0000000..580bf68 --- /dev/null +++ b/src/subwindow/subwindow.cpp @@ -0,0 +1,176 @@ +/* + * 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 "subwindow.h" +#include "browser.h" +#include "webengine/webview.h" +#include "tabwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "profilemanager.h" +#include + +SubWindow::SubWindow(const std::unique_ptr &config, QWidget *parent, Qt::WindowFlags flags) + : QMdiSubWindow(parent, flags) + , tabWidget(new TabWidget(this)) +{ + // delete this window when it closes + setAttribute(Qt::WA_DeleteOnClose, true); + + resize(800, 600); + setWidget(tabWidget); + + m_profile = WebProfile::defaultProfile(); + + // system menu + { + QMenu *menu = systemMenu(); + auto *firstAction = menu->actions().at(0); + + auto *profileName_action = new QAction(tr("Profile: %1").arg(m_profile->name()), menu); + profileName_action->setEnabled(false); + menu->insertAction(firstAction, profileName_action); + + auto *loadProfile_menu = new QMenu(tr("Load profile"), menu); + menu->insertMenu(firstAction, loadProfile_menu); + + Browser *browser = qobject_cast(qApp); + Q_CHECK_PTR(browser); + + ProfileIterator it(ProfileManager::profileList()); + while(it.hasNext()) { + it.next(); + auto *profile = it.value(); + auto *loadAction = loadProfile_menu->addAction(profile->name()); + + connect(loadAction, &QAction::triggered, this, [=]() { + this->setProfile(profile); + profileName_action->setText(tr("Profile: %1").arg(profile->name())); + }); + } + + menu->insertSeparator(firstAction); + } + + // new tab button + auto *newTab_button = new QToolButton(this); + newTab_button->setIcon(style()->standardIcon(QStyle::SP_FileIcon)); + newTab_button->setToolTip(tr("Add tab")); + newTab_button->setShortcut(QKeySequence(config->value("window.shortcuts.new").value())); + connect(newTab_button, &QToolButton::clicked, this, [=]() { + auto index = addTab(WebProfile::defaultProfile()->newtab()); + tabWidget->setCurrentIndex(index); + }); + tabWidget->setCornerWidget(newTab_button, Qt::TopRightCorner); + + // general actions + auto *closeTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.close").value()), this); + connect(closeTab_shortcut, &QShortcut::activated, this, [=]() { + tabWidget->deleteTab(tabWidget->currentIndex()); + }); + + auto *leftTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.left").value()), this); + connect(leftTab_shortcut, &QShortcut::activated, this, [=]() { + tabWidget->setCurrentIndex(qMax(0, tabWidget->currentIndex() - 1)); + }); + + auto *rightTab_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.right").value()), this); + connect(rightTab_shortcut, &QShortcut::activated, this, [=]() { + tabWidget->setCurrentIndex(qMin(tabWidget->currentIndex() + 1, tabWidget->count() - 1)); + }); + + auto *fullScreen_shortcut = new QShortcut(QKeySequence(config->value("window.shortcuts.fullscreen").value()), this); + connect(fullScreen_shortcut, &QShortcut::activated, this, [=]() { + auto *w = this->window(); + if(w->isFullScreen()) + w->showNormal(); + else + w->showFullScreen(); + }); + + connect(tabWidget, &TabWidget::currentChanged, [this](int index) { + if(index < 0) { + // last tab has been closed + close(); + } else { + auto *view = dynamic_cast(tabWidget->widget(index)); + Q_CHECK_PTR(view); + + disconnect(titleConnection); + disconnect(linkHoveredConnection); + + titleConnection = connect(view, &WebView::titleChanged, this, [this](const QString &title) { + auto *v = qobject_cast(sender()); + this->setWindowTitle(QString("%1 :%2").arg(title, v->profile()->name())); + }); + setWindowTitle(QString("%1 :%2").arg(view->title(), view->profile()->name())); + + linkHoveredConnection = connect(view->page(), &WebPage::linkHovered, this, [this](const QString &url) { + if(!url.isEmpty()) + emit showStatusMessage(url, 3000); + }); + + emit currentViewChanged(view); + } + }); +} + +SubWindow::~SubWindow() +{ + delete tabWidget; +} + +WebView *SubWindow::currentView() +{ + return qobject_cast(tabWidget->currentWidget()); +} + +WebView *SubWindow::view(int index) const +{ + return qobject_cast(tabWidget->widget(index)); +} + +int SubWindow::tabCount() const +{ + return tabWidget->count(); +} + +void SubWindow::setProfile(WebProfile *profile) +{ + Q_CHECK_PTR(profile); + this->m_profile = profile; + for(int i = 0; i < tabWidget->count(); ++i) { + auto *view = qobject_cast(tabWidget->widget(i)); + view->setProfile(profile); + } +} + +WebProfile *SubWindow::profile() const +{ + return m_profile; +} + +int SubWindow::addTab(const QUrl &url, WebProfile *profile) +{ + auto *view = new WebView((profile == nullptr) ? m_profile : profile, this); + if(!url.isEmpty()) + view->load(url); + return tabWidget->addTab(view); +} + +void SubWindow::setCurrentTab(int index) +{ + tabWidget->setCurrentIndex(index); +} diff --git a/src/subwindow/subwindow.h b/src/subwindow/subwindow.h new file mode 100644 index 0000000..b7c4aee --- /dev/null +++ b/src/subwindow/subwindow.h @@ -0,0 +1,51 @@ +/* + * 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 + */ + +#ifndef SMOLBOTE_SUBWINDOW_H +#define SMOLBOTE_SUBWINDOW_H + +#include +#include +#include + +class TabWidget; +class WebView; +class WebProfile; +class Configuration; +class SubWindow : public QMdiSubWindow +{ + Q_OBJECT + +public: + explicit SubWindow(const std::unique_ptr &config, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + ~SubWindow() override; + + WebView *currentView(); + WebView *view(int index) const; + int tabCount() const; + + void setProfile(WebProfile *profile); + WebProfile *profile() const; + +signals: + void currentViewChanged(WebView *view); + void showStatusMessage(const QString &message, int timeout = 0); + +public slots: + int addTab(const QUrl &url = QUrl(), WebProfile *profile = nullptr); + void setCurrentTab(int index); + +private: + WebProfile *m_profile; + TabWidget *tabWidget; + + QMetaObject::Connection titleConnection; + QMetaObject::Connection linkHoveredConnection; +}; + +#endif // SMOLBOTE_SUBWINDOW_H diff --git a/src/subwindow/tabwidget.cpp b/src/subwindow/tabwidget.cpp new file mode 100644 index 0000000..1ddfc95 --- /dev/null +++ b/src/subwindow/tabwidget.cpp @@ -0,0 +1,123 @@ +/* + * 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 "tabwidget.h" +#include "browser.h" +#include "webengine/webview.h" +#include +#include +#include +#include +#include + +TabWidget::TabWidget(QWidget *parent) + : QTabWidget(parent) +{ + setStyleSheet("QTabBar::tab { width: 200px; }"); + + setTabsClosable(true); + //setTabBarAutoHide(true); + setElideMode(Qt::ElideRight); + setMovable(true); + + connect(this, &TabWidget::tabCloseRequested, this, &TabWidget::deleteTab); + + // when changing tabs, give focus to the widget + // otherwise when closing tabs, the tabwidget will retain focus + connect(this, &TabWidget::currentChanged, this, [this](int index) { + if(widget(index)) + widget(index)->setFocus(); + }); + + // context menu + tabContextMenu = new QMenu(this); + auto *closeTab = tabContextMenu->addAction(tr("Close Tab")); + connect(closeTab, &QAction::triggered, this, [this]() { + deleteTab(this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos()))); + }); + + auto *closeTabsLeft = tabContextMenu->addAction(tr("Close Tabs left")); + connect(closeTabsLeft, &QAction::triggered, this, [this]() { + int idx = this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos())); + for(int i = idx - 1; i >= 0; --i) { + deleteTab(i); + } + }); + + auto *closeTabsRight = tabContextMenu->addAction(tr("Close Tabs right")); + connect(closeTabsRight, &QAction::triggered, this, [this]() { + int idx = this->tabBar()->tabAt(mapFromGlobal(tabContextMenu->pos())); + for(int i = count() - 1; i > idx; --i) { + deleteTab(i); + } + }); +} + +TabWidget::~TabWidget() +{ + for(int i = count() - 1; i >= 0; i--) { + delete widget(i); + } +} + +int TabWidget::addTab(WebView *view) +{ + Q_ASSERT_X(view != nullptr, "TabWidget::addTab", "Tried to add null view"); + + int idx = QTabWidget::addTab(view, view->title()); + connect(view, &WebView::titleChanged, [this, view](const QString &title) { + int idx = this->indexOf(view); + Q_ASSERT(idx != -1); + + this->setTabText(idx, title); + }); + connect(view, &WebView::iconChanged, [this, view](const QIcon &icon) { + int idx = this->indexOf(view); + Q_ASSERT(idx != -1); + + this->setTabIcon(idx, icon); + }); + + return idx; +} + +void TabWidget::deleteTab(int index) +{ + // deleting the widget automatically removes the tab? + auto *w = widget(index); + disconnect(w); + delete w; + + if(count() == 0) + parentWidget()->close(); +} + +void TabWidget::contextMenuEvent(QContextMenuEvent *event) +{ + // check if the context menu was called on a tab + int tabIndex = tabBar()->tabAt(event->pos()); + if(tabIndex < 0) { + return; + } + + tabContextMenu->exec(event->globalPos()); +} + +void TabWidget::mousePressEvent(QMouseEvent *event) +{ + if(event->button() == Qt::MiddleButton) { + int index = tabBar()->tabAt(event->pos()); + if(index >= 0) { + deleteTab(index); + } + event->accept(); + return; + } + + QTabWidget::mousePressEvent(event); +} diff --git a/src/subwindow/tabwidget.h b/src/subwindow/tabwidget.h new file mode 100644 index 0000000..793e041 --- /dev/null +++ b/src/subwindow/tabwidget.h @@ -0,0 +1,37 @@ +/* + * 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 + */ + +#ifndef SMOLBOTE_TABWIDGET_H +#define SMOLBOTE_TABWIDGET_H + +#include + +class QAction; +class QMenu; +class WebView; +class TabWidget : public QTabWidget +{ + Q_OBJECT + +public: + explicit TabWidget(QWidget *parent = nullptr); + ~TabWidget() override; + +public slots: + int addTab(WebView *view); + void deleteTab(int index); + +protected: + void contextMenuEvent(QContextMenuEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + +private: + QMenu *tabContextMenu; +}; + +#endif // SMOLBOTE_TABWIDGET_H diff --git a/src/webengine/webview.cpp b/src/webengine/webview.cpp index 8e137de..14cb020 100644 --- a/src/webengine/webview.cpp +++ b/src/webengine/webview.cpp @@ -7,7 +7,7 @@ */ #include "webview.h" -#include "mainwindow/subwindow.h" +#include "subwindow/subwindow.h" #include "webpage.h" #include "webprofile.h" #include -- cgit v1.2.1