/* * 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 "mainwindow.h" #include "addressbar/addressbar.h" #include "webengine/webview.h" #include "widgets/navigationbar.h" #include "widgets/searchform.h" #include "subwindow.h" #include #include #include "widgets/dockwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "browser.h" #ifdef PLASMA_BLUR #include #endif MainWindow::MainWindow(std::shared_ptr &config, QWidget *parent) : QMainWindow(parent) , mdiArea(new QMdiArea(this)) { Q_ASSERT(config); m_config = config; #ifdef PLASMA_BLUR setAttribute(Qt::WA_TranslucentBackground, true); KWindowEffects::enableBlurBehind(this->winId(), true); #endif // create UI setWindowTitle(QString::fromStdString(config->value("mainwindow.title").value())); resize(config->value("mainwindow.width").value(), config->value("mainwindow.height").value()); if(config->value("mainwindow.maximized").value()) { setWindowState(Qt::WindowMaximized); } show(); createMenuBar(); navigationToolBar = new NavigationBar(config->section("navigation"), this); navigationToolBar->setMovable(config->value("navigation.movable").value()); addToolBar(Qt::TopToolBarArea, navigationToolBar); navigationToolBar->connectWebView(nullptr); addressBar = new AddressBar(config->section("addressbar"), this); navigationToolBar->addWidget(addressBar); 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); subWindowAction->setMenu(nullptr); auto *w = qobject_cast(window); if(w == nullptr) { // no current subwindow, clear everything setView(nullptr); subWindowAction->setMenu(nullptr); } else { setView(w->currentView()); subWindowAction->setMenu(w->systemMenu()); viewChangedConnection = connect(w, &SubWindow::currentViewChanged, this, &MainWindow::setView); statusBarConnection = connect(w, &SubWindow::showStatusMessage, statusBar(), &QStatusBar::showMessage); } }); auto *searchShortcut = new QShortcut(QKeySequence(config->value("mainwindow.shortcuts.search").value().c_str()), this); connect(searchShortcut, &QShortcut::activated, 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(); } }); } MainWindow::~MainWindow() { disconnect(viewChangedConnection); disconnect(searchConnection); disconnect(searchBoxConnection); disconnect(statusBarConnection); } void MainWindow::createMenuBar() { Q_CHECK_PTR(mdiArea); auto *smolboteMenu = menuBar()->addMenu(qApp->applicationDisplayName()); smolboteMenu->addAction(tr("New subwindow"), this, [this]() { createSubWindow(); }, QKeySequence(m_config->value("mainwindow.shortcuts.newGroup").value().c_str())); smolboteMenu->addAction(tr("New window"), this, []() { auto *browser = qobject_cast(qApp); if(browser) browser->createWindow(); }, QKeySequence(m_config->value("mainwindow.shortcuts.newWindow").value().c_str())); smolboteMenu->addSeparator(); smolboteMenu->addAction(tr("About"), this, [this]() { auto *dlg = new AboutDialog(this); dlg->exec(); }, QKeySequence(m_config->value("mainwindow.shortcuts.about").value().c_str())); smolboteMenu->addAction(tr("About Qt"), qApp, &QApplication::aboutQt); smolboteMenu->addSeparator(); smolboteMenu->addAction(tr("Quit"), qApp, &QApplication::quit, QKeySequence(m_config->value("mainwindow.shortcuts.quit").value().c_str())); auto *windowMenu = menuBar()->addMenu(tr("Window")); windowMenu->addAction(tr("Tile windows"), mdiArea, &QMdiArea::tileSubWindows, QKeySequence(m_config->value("mainwindow.shortcuts.tileWindows").value().c_str())); windowMenu->addAction(tr("Cascade windows"), mdiArea, &QMdiArea::cascadeSubWindows, QKeySequence(m_config->value("mainwindow.shortcuts.cascadeWindows").value().c_str())); subWindowAction = windowMenu->addAction(tr("Current window")); toolsMenu = menuBar()->addMenu(tr("Tools")); } void MainWindow::addAction(ActionLocation where, QAction *action) { switch(where) { case ToolsMenu: toolsMenu->addAction(action); break; default: QMainWindow::addAction(action); break; } } void MainWindow::addDockWidget(Qt::DockWidgetArea area, QWidget *widget) { QDockWidget *lastDock = nullptr; for(QDockWidget *dock : findChildren()) { 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 = createSubWindow(url.toString()); } else { w->addTab(url); } } SubWindow *MainWindow::currentSubWindow() const { return qobject_cast(mdiArea->currentSubWindow()); } SubWindow *MainWindow::createSubWindow(const QString &url) { auto *w = new SubWindow(m_config->section("window"), this); mdiArea->addSubWindow(w); w->showMaximized(); w->setFocus(); QJsonObject session; session.insert("profile", ""); QJsonArray urls; if(!url.isEmpty()) urls.append(url); session.insert("tabs", urls); w->restoreSession(session); return w; } void MainWindow::setView(WebView *view) { disconnect(searchConnection); addressBar->setView(view); if(view) { addressBar->setPageMenu(view->pageMenu()); addressBar->setToolsMenu(view->toolsMenu()); searchConnection = connect(addressBar, &AddressBar::search, view, &WebView::search); } else { addressBar->setPageMenu(nullptr); addressBar->setToolsMenu(nullptr); } 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()) event->ignore(); else event->accept(); }