diff options
Diffstat (limited to 'src/mainwindow/widgets')
-rw-r--r-- | src/mainwindow/widgets/loadingbar.cpp | 2 | ||||
-rw-r--r-- | src/mainwindow/widgets/navigationbar.cpp | 115 | ||||
-rw-r--r-- | src/mainwindow/widgets/navigationbar.h | 41 | ||||
-rw-r--r-- | src/mainwindow/widgets/searchform.cpp | 4 | ||||
-rw-r--r-- | src/mainwindow/widgets/tabbar.cpp | 171 | ||||
-rw-r--r-- | src/mainwindow/widgets/tabbar.h | 56 | ||||
-rw-r--r-- | src/mainwindow/widgets/tabwidget.cpp | 121 | ||||
-rw-r--r-- | src/mainwindow/widgets/tabwidget.h | 40 |
8 files changed, 236 insertions, 314 deletions
diff --git a/src/mainwindow/widgets/loadingbar.cpp b/src/mainwindow/widgets/loadingbar.cpp index 76eafc4..61e3eae 100644 --- a/src/mainwindow/widgets/loadingbar.cpp +++ b/src/mainwindow/widgets/loadingbar.cpp @@ -7,8 +7,8 @@ */ #include "loadingbar.h" -#include <QTimer> #include "webengine/webview.h" +#include <QTimer> LoadingBar::LoadingBar(QWidget *parent) : QProgressBar(parent) diff --git a/src/mainwindow/widgets/navigationbar.cpp b/src/mainwindow/widgets/navigationbar.cpp index 0652159..e2c714e 100644 --- a/src/mainwindow/widgets/navigationbar.cpp +++ b/src/mainwindow/widgets/navigationbar.cpp @@ -7,7 +7,9 @@ */ #include "navigationbar.h" -#include "mainwindow/mainwindow.h" +#include "addressbar/urllineedit.h" +#include "configuration/configuration.h" +#include "webengine/webview.h" #include <QHBoxLayout> #include <QMenu> #include <QShortcut> @@ -15,99 +17,94 @@ #include <QToolBar> #include <QToolButton> #include <QWebEngineHistory> -#include "webengine/webview.h" -#include "configuration/configuration.h" -NavigationBar::NavigationBar(MainWindow *parent) - : QObject(parent) +NavigationBar::NavigationBar(const QHash<QString, QString> &conf, QWidget *parent) + : QToolBar(parent) { qStyle = parent->style(); // Back button - backButton = new QToolButton(parent); - backButton->setIcon(qStyle->standardIcon(QStyle::SP_ArrowBack)); - backButton->setShortcut(QString::fromStdString(parent->m_config->value<std::string>("browser.shortcuts.back").value())); - connect(backButton, &QToolButton::clicked, this, [this]() { + backAction = addAction(qStyle->standardIcon(QStyle::SP_ArrowBack), tr("Back")); + backAction->setShortcut(QKeySequence(conf.value("navigation.shortcuts.back"))); + connect(backAction, &QAction::triggered, this, [this]() { m_view->history()->back(); }); - auto *backMenu = new QMenu(backButton); - backButton->setMenu(backMenu); + auto *backMenu = new QMenu(this); connect(backMenu, &QMenu::aboutToShow, this, [this, backMenu]() { backMenu->clear(); - const QList<QWebEngineHistoryItem> items = m_view->history()->backItems(10); - for(const QWebEngineHistoryItem &i : items) { - QAction *a = backMenu->addAction(i.title()); - connect(a, &QAction::triggered, this, [i, this]() { - m_view->history()->goToItem(i); + for(const QWebEngineHistoryItem &item : m_view->history()->backItems(10)) { + auto *action = backMenu->addAction(item.title()); + connect(action, &QAction::triggered, this, [item, this]() { + m_view->history()->goToItem(item); }); } }); + backAction->setMenu(backMenu); // Forward button - forwardButton = new QToolButton(parent); - forwardButton->setIcon(qStyle->standardIcon(QStyle::SP_ArrowForward)); - forwardButton->setShortcut(QString::fromStdString(parent->m_config->value<std::string>("browser.shortcuts.forward").value())); - connect(forwardButton, &QToolButton::clicked, this, [this]() { + forwardAction = addAction(qStyle->standardIcon(QStyle::SP_ArrowForward), tr("Forward")); + forwardAction->setShortcut(QKeySequence(conf.value("navigation.shortcuts.forward"))); + connect(forwardAction, &QAction::triggered, this, [this]() { m_view->history()->forward(); }); - auto *forwardMenu = new QMenu(forwardButton); - forwardButton->setMenu(forwardMenu); + auto *forwardMenu = new QMenu(this); connect(forwardMenu, &QMenu::aboutToShow, this, [this, forwardMenu]() { forwardMenu->clear(); - const QList<QWebEngineHistoryItem> items = m_view->history()->forwardItems(10); - for(const QWebEngineHistoryItem &i : items) { - QAction *a = forwardMenu->addAction(i.title()); - connect(a, &QAction::triggered, this, [i, this]() { - m_view->history()->goToItem(i); + for(const QWebEngineHistoryItem &item : m_view->history()->forwardItems(10)) { + auto *action = forwardMenu->addAction(item.title()); + connect(action, &QAction::triggered, this, [item, this]() { + m_view->history()->goToItem(item); }); } }); + forwardAction->setMenu(forwardMenu); // Stop/Refresh button - stopReloadButton = new QToolButton(parent); - stopReloadButton->setIcon(qStyle->standardIcon(QStyle::SP_BrowserReload)); - stopReloadButton->setShortcut(QString::fromStdString(parent->m_config->value<std::string>("browser.shortcuts.refresh").value())); - connect(stopReloadButton, &QToolButton::clicked, this, [this]() { + stopReloadAction = addAction(qStyle->standardIcon(QStyle::SP_BrowserReload), tr("Reload")); + stopReloadAction->setShortcut(QKeySequence(conf.value("navigation.shortcuts.refresh"))); + connect(stopReloadAction, &QAction::triggered, this, [this]() { if(m_view->isLoaded()) m_view->reload(); else m_view->stop(); }); - auto *reloadShortcut = new QShortcut( - QString::fromStdString(parent->m_config->value<std::string>("browser.shortcuts.reload").value()), - parent); - connect(reloadShortcut, &QShortcut::activated, this, [this]() { - m_view->reload(); - }); - // Home button - homeButton = new QToolButton(parent); - homeButton->setIcon(qStyle->standardIcon(QStyle::SP_DirHomeIcon)); - homeButton->setShortcut(QString::fromStdString(parent->m_config->value<std::string>("browser.shortcuts.home").value())); - connect(homeButton, &QToolButton::clicked, this, [this, parent]() { - m_view->load(parent->m_profile->homepage()); + homeAction = addAction(qStyle->standardIcon(QStyle::SP_DirHomeIcon), tr("Home")); + homeAction->setShortcut(QKeySequence(conf.value("navigation.shortcuts.home"))); + connect(homeAction, &QAction::triggered, this, [this]() { + m_view->triggerViewAction(WebView::GoHome); }); -} -void NavigationBar::addWidgetsTo(QToolBar *toolBar) -{ - toolBar->addWidget(backButton); - toolBar->addWidget(forwardButton); - toolBar->addWidget(stopReloadButton); - toolBar->addWidget(homeButton); + QHash<QString, QString> a; + addressBar = new UrlLineEdit(a, this); + addWidget(addressBar); + + auto *focusShortcut = new QShortcut(QKeySequence("F4"), this); + connect(focusShortcut, &QShortcut::activated, this, [this]() { + addressBar->setFocus(); + addressBar->selectAll(); + }); } void NavigationBar::connectWebView(WebView *view) { - Q_CHECK_PTR(view); m_view = view; disconnect(loadStartedConnection); disconnect(loadFinishedConnection); + if(view == nullptr) { + backAction->setEnabled(false); + forwardAction->setEnabled(false); + stopReloadAction->setEnabled(false); + homeAction->setEnabled(false); + + return; + } + if(view->isLoaded()) { update_loadFinished(); } else { @@ -116,18 +113,22 @@ void NavigationBar::connectWebView(WebView *view) loadStartedConnection = connect(view, &QWebEngineView::loadStarted, this, &NavigationBar::update_loadStarted); loadFinishedConnection = connect(view, &WebView::loaded, this, &NavigationBar::update_loadFinished); + stopReloadAction->setEnabled(true); + homeAction->setEnabled(true); + + addressBar->connectWebView(view); } void NavigationBar::update_loadStarted() { - backButton->setEnabled(m_view->history()->canGoForward()); - forwardButton->setEnabled(m_view->history()->canGoForward()); - stopReloadButton->setIcon(qStyle->standardIcon(QStyle::SP_BrowserStop)); + backAction->setEnabled(m_view->history()->canGoForward()); + forwardAction->setEnabled(m_view->history()->canGoForward()); + stopReloadAction->setIcon(qStyle->standardIcon(QStyle::SP_BrowserStop)); } void NavigationBar::update_loadFinished() { - backButton->setEnabled(m_view->history()->canGoBack()); - forwardButton->setEnabled(m_view->history()->canGoForward()); - stopReloadButton->setIcon(qStyle->standardIcon(QStyle::SP_BrowserReload)); + backAction->setEnabled(m_view->history()->canGoBack()); + forwardAction->setEnabled(m_view->history()->canGoForward()); + stopReloadAction->setIcon(qStyle->standardIcon(QStyle::SP_BrowserReload)); } diff --git a/src/mainwindow/widgets/navigationbar.h b/src/mainwindow/widgets/navigationbar.h index fd0579d..1b4cc05 100644 --- a/src/mainwindow/widgets/navigationbar.h +++ b/src/mainwindow/widgets/navigationbar.h @@ -6,36 +6,21 @@ * SPDX-License-Identifier: GPL-3.0 */ -/* - * Why is this class a QObject and not a QWidget, and why don't we add the - * NavigationBar itself to the toolbar? - * That was the original idea: make a NavBar class, friend it from MainWindow - * to gain access to the config, but there's a couple of issues: - * - adding QToolButtons to a widget that's inside a toolbar makes the buttons - * look absolutely hideous: they're smaller and have a border for some reason - * - if you stylesheet the border away (which is a pain), they're still not - * the same size - * And so we ended up having this class only exist to contain all of the logic - * for the nav buttons (which cuts down the code in MainWindow). - */ - -#ifndef NAVIGATIONBAR_H -#define NAVIGATIONBAR_H +#ifndef SMOLBOTE_NAVIGATIONBAR_H +#define SMOLBOTE_NAVIGATIONBAR_H -#include <QObject> +#include <QToolBar> -class QStyle; -class QToolBar; -class QToolButton; -class MainWindow; +class UrlLineEdit; class WebView; -class NavigationBar : public QObject +class NavigationBar : public QToolBar { Q_OBJECT + public: - explicit NavigationBar(MainWindow *parent = nullptr); + explicit NavigationBar(const QHash<QString, QString> &conf, QWidget *parent = nullptr); - void addWidgetsTo(QToolBar *toolBar); +public slots: void connectWebView(WebView *view); private slots: @@ -45,11 +30,13 @@ private slots: private: QStyle *qStyle; WebView *m_view; - QToolButton *backButton, *forwardButton; - QToolButton *stopReloadButton; - QToolButton *homeButton; + + QAction *backAction, *forwardAction; + QAction *stopReloadAction; + QAction *homeAction; + UrlLineEdit *addressBar; QMetaObject::Connection loadStartedConnection, loadFinishedConnection; }; -#endif //NAVIGATIONBAR_H +#endif // SMOLBOTE_NAVIGATIONBAR_H diff --git a/src/mainwindow/widgets/searchform.cpp b/src/mainwindow/widgets/searchform.cpp index 8ac1bc2..07b8426 100644 --- a/src/mainwindow/widgets/searchform.cpp +++ b/src/mainwindow/widgets/searchform.cpp @@ -7,11 +7,11 @@ */ #include "searchform.h" +#include "configuration/configuration.h" #include "mainwindow/mainwindow.h" #include "ui_searchform.h" -#include <QAction> #include "webengine/webview.h" -#include "configuration/configuration.h" +#include <QAction> SearchForm::SearchForm(MainWindow *parentWindow, QWidget *parent) : QWidget(parent) diff --git a/src/mainwindow/widgets/tabbar.cpp b/src/mainwindow/widgets/tabbar.cpp deleted file mode 100644 index ef32ef0..0000000 --- a/src/mainwindow/widgets/tabbar.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 "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); -} diff --git a/src/mainwindow/widgets/tabbar.h b/src/mainwindow/widgets/tabbar.h deleted file mode 100644 index f4b7414..0000000 --- a/src/mainwindow/widgets/tabbar.h +++ /dev/null @@ -1,56 +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_TABBAR_H -#define SMOLBOTE_TABBAR_H - -#include <QTabBar> - -class MainWindow; -class WebView; -class WebEngineProfile; -class QMenu; -class TabBar : public QTabBar -{ - Q_OBJECT - -public: - explicit TabBar(const QHash<QString, QString> &config, MainWindow *parent = nullptr); - ~TabBar() override; - - void setProfile(WebEngineProfile *profile); - WebView *currentView(); - -signals: - void currentTabChanged(WebView *view); - -public slots: - int addTab(WebView *view); - void removeTab(int index); - -protected: - void contextMenuEvent(QContextMenuEvent *event) override; - QSize tabSizeHint(int index) const override; - -private slots: - void handleCurrentChanged(int index); - void updateVectorArrangement(int from, int to); - -private: - // store all views in a vector since tabs can only store a QVariant, and that can't easily take a pointer - QVector<WebView *> m_views; - - QMenu *tabContextMenu; - - QAction *newTab_action; - QAction *closeTab_action; - QAction *leftTab_action; - QAction *rightTab_action; -}; - -#endif // SMOLBOTE_TABBAR_H diff --git a/src/mainwindow/widgets/tabwidget.cpp b/src/mainwindow/widgets/tabwidget.cpp new file mode 100644 index 0000000..21476cd --- /dev/null +++ b/src/mainwindow/widgets/tabwidget.cpp @@ -0,0 +1,121 @@ +/* + * 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 "webengine/webview.h" +#include <QAction> +#include <QContextMenuEvent> +#include <QMenu> +#include <QTabBar> + +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); + + // general actions + closeTab_action = new QAction(this); + closeTab_action->setShortcut(QKeySequence("Ctrl+X")); + connect(closeTab_action, &QAction::triggered, this, [this]() { + this->deleteTab(this->currentIndex()); + }); + addAction(closeTab_action); + + leftTab_action = new QAction(this); + leftTab_action->setShortcut(QKeySequence("Ctrl+O")); + connect(leftTab_action, &QAction::triggered, this, [this]() { + this->setCurrentIndex(qMax(0, this->currentIndex() - 1)); + }); + addAction(leftTab_action); + + rightTab_action = new QAction(this); + rightTab_action->setShortcut(QKeySequence("Ctrl+P")); + connect(rightTab_action, &QAction::triggered, this, [this]() { + this->setCurrentIndex(qMin(this->currentIndex() + 1, this->count() - 1)); + }); + addAction(rightTab_action); + + // 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_CHECK_PTR(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? + if(count() > 1) { + widget(index)->deleteLater(); + removeTab(index); + } else + 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()); +} diff --git a/src/mainwindow/widgets/tabwidget.h b/src/mainwindow/widgets/tabwidget.h new file mode 100644 index 0000000..b7aad63 --- /dev/null +++ b/src/mainwindow/widgets/tabwidget.h @@ -0,0 +1,40 @@ +/* + * 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 <QTabWidget> + +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; + +private: + QAction *closeTab_action; + QAction *leftTab_action; + QAction *rightTab_action; + + QMenu *tabContextMenu; +}; + +#endif // SMOLBOTE_TABWIDGET_H |