/* * 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/gitea/aqua/smolbote * * SPDX-License-Identifier: GPL-3.0 */ #include "mainwindow.h" #include "addressbar.h" #include "bookmarks/bookmarkstoolbar.h" #include "bookmarks/bookmarkswidget.h" #include "browser.h" #include "configuration.h" #include "menubar.h" #include "session/session.h" #include "session/sessiondialog.h" #include "subwindow/subwindow.h" #include "webengine/webprofile.h" #include "webengine/webprofilemanager.h" #include "webengine/webview.h" #include "widgets/dockwidget.h" #include "widgets/navigationbar.h" #include "widgets/searchform.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , mdiArea(new QMdiArea(this)) { Configuration config; // create UI setWindowTitle(config.value("mainwindow.title").value()); resize(config.value("mainwindow.width").value(), config.value("mainwindow.height").value()); if(config.value("mainwindow.maximized").value_or(false)) { setWindowState(Qt::WindowMaximized); } show(); // current subwindow shortcut { QAction *subwindowMenuAction = new QAction(this); QMainWindow::addAction(subwindowMenuAction); config.shortcut(*subwindowMenuAction, "shortcuts.subwindow.menu"); connect(subwindowMenuAction, &QAction::triggered, this, [this]() { QMdiSubWindow *window = mdiArea->currentSubWindow(); if(window != nullptr) { // show the menu at the subwindow position // position has to be global, and mapped by the mdiArea (parentWidget() of the subwindow) const auto position = mdiArea->mapToGlobal(window->pos()); window->systemMenu()->exec(position); } }); } navigationToolBar = new NavigationBar(this); navigationToolBar->setMovable(config.value("navigation.movable").value_or(false)); addToolBar(Qt::TopToolBarArea, navigationToolBar); navigationToolBar->connectWebView(nullptr); addressBar = new AddressBar(this); navigationToolBar->addWidget(addressBar); Browser *app = qobject_cast(qApp); this->addToolBarBreak(); this->addToolBar(new BookmarksToolbar(app->bookmarks()->model(), this)); m_menuBar = new MenuBar(this); this->setMenuBar(m_menuBar); mdiArea->setBackground(Qt::NoBrush); setCentralWidget(mdiArea); mdiArea->setFocus(); // status bar searchBox = new SearchForm(this); statusBar()->addPermanentWidget(searchBox); searchBox->setVisible(false); // connect signlas connect(mdiArea, &QMdiArea::subWindowActivated, this, [this](QMdiSubWindow *window) { disconnect(viewChangedConnection); disconnect(searchBoxConnection); disconnect(statusBarConnection); auto *w = qobject_cast(window); if(w == nullptr) { // no current subwindow, clear everything setView(nullptr); } else { setView(w->currentView()); viewChangedConnection = connect(w, &SubWindow::currentViewChanged, this, &MainWindow::setView); statusBarConnection = connect(w, &SubWindow::showStatusMessage, statusBar(), &QStatusBar::showMessage); } }); // address bar connect(addressBar, &AddressBar::search, this, [this](const QString &term) { if(this->currentView != nullptr) { currentView->search(term); currentView->setFocus(); } }); connect(addressBar, &AddressBar::load, this, [this](const QUrl &url) { if(this->currentView != nullptr) { currentView->load(url); currentView->setFocus(); } }); connect(addressBar, &AddressBar::giveFocus, this, [this]() { if(this->currentView != nullptr) { currentView->setFocus(); } }); // search box auto *searchAction = new QAction(this); config.shortcut(*searchAction, "shortcuts.window.search"); connect(searchAction, &QAction::triggered, this, [this]() { /* QTBUG-18665 * When focusing out of the search box and hiding it, the first * (or earlier?) subwindow gets activated for some reason. */ if(searchBox->isVisible()) { auto *w = mdiArea->currentSubWindow(); searchBox->hide(); mdiArea->setActiveSubWindow(w); } else { searchBox->show(); } }); QMainWindow::addAction(searchAction); } MainWindow::~MainWindow() { disconnect(viewChangedConnection); disconnect(searchBoxConnection); disconnect(statusBarConnection); disconnect(addressBar); } void MainWindow::addDockWidget(Qt::DockWidgetArea area, QWidget *widget) { QDockWidget *lastDock = nullptr; const auto docks = findChildren(); for(QDockWidget *dock : docks) { if(dockWidgetArea(dock) == area) lastDock = dock; } DockWidget *dock = new DockWidget(widget->windowTitle(), this); dock->setMinimumWidth(460); dock->setWidget(widget); if(lastDock == nullptr) QMainWindow::addDockWidget(area, dock); else tabifyDockWidget(lastDock, dock); } void MainWindow::removeDockWidget(QWidget *widget) { const auto docks = this->findChildren(); for(QDockWidget *dock : docks) { if(dock->widget() == widget) { dock->widget()->setParent(nullptr); dock->close(); } } } void MainWindow::createTab(const QUrl &url) { auto *w = qobject_cast(mdiArea->currentSubWindow()); if(w != nullptr) { w->addTab(url); } } const QVector MainWindow::subWindows() const { QVector list; const auto subwindows = mdiArea->subWindowList(); for(auto *w : subwindows) { auto *subwindow = qobject_cast(w); if(subwindow != nullptr) list.append(subwindow); } return list; } SubWindow *MainWindow::currentSubWindow() const { return qobject_cast(mdiArea->currentSubWindow()); } SubWindow *MainWindow::createSubWindow(WebProfile *profile, bool openProfileNewtab) { bool shouldMaximize = true; // if there is a current window, use its maximize state if(auto *currentWindow = qobject_cast(mdiArea->currentSubWindow()); currentWindow != nullptr) { shouldMaximize = currentWindow->isMaximized(); } auto *w = new SubWindow(this); m_menuBar->insertSubWindow(w); w->setProfile(profile); mdiArea->addSubWindow(w); if(shouldMaximize) w->showMaximized(); else w->show(); w->setFocus(); if(openProfileNewtab) w->addTab(w->profile()->newtab()); return w; } void MainWindow::setView(WebView *view) { if(currentView != nullptr) { // disconnect old view disconnect(currentView, nullptr, addressBar, nullptr); } currentView = view; if(view != nullptr) { connect(view, &WebView::urlChanged, addressBar, &AddressBar::setUrl); addressBar->setUrl(view->url()); connect(view, &WebView::loadProgress, addressBar, &AddressBar::setProgress); addressBar->setProgress(100); } else { addressBar->setUrl(QUrl()); addressBar->setProgress(100); } navigationToolBar->connectWebView(view); searchBox->setView(view); } void MainWindow::closeEvent(QCloseEvent *event) { if(mdiArea->subWindowList().count() > 1) { int choice = QMessageBox::question(this, tr("Close multiple subwindows?"), tr("Do you want to close all subwindows?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if(choice == QMessageBox::No) { event->ignore(); return; } } mdiArea->closeAllSubWindows(); if(mdiArea->currentSubWindow() != nullptr) event->ignore(); else event->accept(); }