/******************************************************************************* ** ** smolbote: yet another qute browser ** Copyright (C) 2017 Xian Nox ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . ** ******************************************************************************/ #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include "browser.h" #include #include #include #include "forms/aboutdialog.h" #include #include MainWindow::MainWindow(QUrl defaultUrl, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), navigationToolBar(new QToolBar(tr("Navigation"), this)), tabToolBar(new QToolBar(tr("Tab bar"), this)), tabBar(new WebViewTabBar(this)), urlLineEdit(new UrlLineEdit(navigationToolBar)), progressBar(new LoadingBar(this)) { // set up UI ui->setupUi(this); // Dockable widget styling setDockOptions(dockOptions() | AllowTabbedDocks | ForceTabbedDocks); setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North); setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North); // Main menu QMenuBar *menuBar = new QMenuBar(this); menuBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); // Browser menu QMenu *browserMenu = new QMenu(qApp->applicationName(), menuBar); menuBar->addMenu(browserMenu); browserMenu->addAction(tr("New Window"), this, SLOT(handleNewWindow()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowNew").toString())); browserMenu->addAction(tr("New Tab"), this, SLOT(addNewTab()), QKeySequence::fromString(sSettings->value("window.shortcuts.tabNew").toString())); browserMenu->addSeparator(); browserMenu->addAction(tr("About"), this, SLOT(about()), QKeySequence(tr("F1"))); browserMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt())); browserMenu->addAction(tr("Quit"), qApp, SLOT(quit()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowClose").toString())); // Tools menu QMenu *toolsMenu = new QMenu(tr("Tools"), menuBar); menuBar->addMenu(toolsMenu); QAction *downloadsAction = toolsMenu->addAction(tr("Downloads"), Browser::instance()->downloads(), SLOT(show())); downloadsAction->setParent(this); downloadsAction->setShortcut(QKeySequence::fromString(sSettings->value("downloads.dialogShortcut").toString())); QAction *bookmarksAction = toolsMenu->addAction(tr("Bookmarks"), Browser::instance()->bookmarks(), SLOT(show())); bookmarksAction->setParent(this); bookmarksAction->setShortcut(QKeySequence(sSettings->value("bookmarks.dialogShortcut").toString())); toolsMenu->addSeparator(); toolsMenu->addAction(tr("Blocker"), qApp->blocklists(), SLOT(show()), QKeySequence::fromString(sSettings->value("blocker.shortcut").toString())); // Profile menu QMenu *profileMenu = new QMenu(tr("Profile"), menuBar); menuBar->addMenu(profileMenu); profileMenu->addAction(tr("View profile"), this, SLOT(profileAction())); profileMenu->addAction(tr("Load profile"), this, SLOT(loadProfile())); //profileMenu->addAction(tr("Settings")); profileMenu->addAction(tr("Cookies"), this, SLOT(cookiesAction())); // Add the toolbars // tabToolBar: main menu and tab list tabToolBar->setMovable(sSettings->value("window.ui.tabtoolbarMovable", true).toBool()); tabToolBar->addWidget(menuBar); tabToolBar->addWidget(tabBar); this->addToolBar(Qt::TopToolBarArea, tabToolBar); this->addToolBarBreak(Qt::TopToolBarArea); // navigationToolBar: address bar navigationToolBar->setMovable(sSettings->value("window.ui.navtoolbarMovable", true).toBool()); // page actions QToolButton *backButton = new QToolButton(this); backButton->setIcon(style()->standardIcon(QStyle::SP_ArrowBack)); connect(backButton, SIGNAL(clicked()), tabBar->signalMapper(), SLOT(map())); tabBar->signalMapper()->setMapping(backButton, QWebEnginePage::Back); QToolButton *forwardButton = new QToolButton(this); forwardButton->setIcon(style()->standardIcon(QStyle::SP_ArrowForward)); connect(forwardButton, SIGNAL(clicked()), tabBar->signalMapper(), SLOT(map())); tabBar->signalMapper()->setMapping(forwardButton, QWebEnginePage::Forward); QToolButton *reloadButton = new QToolButton(this); reloadButton->setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); connect(reloadButton, SIGNAL(clicked()), tabBar->signalMapper(), SLOT(map())); tabBar->signalMapper()->setMapping(reloadButton, QWebEnginePage::Reload); navigationToolBar->addWidget(backButton); navigationToolBar->addWidget(forwardButton); navigationToolBar->addWidget(reloadButton); navigationToolBar->addWidget(urlLineEdit); this->addToolBar(Qt::TopToolBarArea, navigationToolBar); // connect signals connect(urlLineEdit, SIGNAL(returnPressed()), this, SLOT(handleUrlChanged())); connect(tabBar, SIGNAL(currentTabChanged(WebView*)), this, SLOT(handleTabChanged(WebView*))); // Load profile m_profile = qApp->profile(sSettings->value("browser.profile.default").toString()); // loading bar ui->statusBar->addPermanentWidget(progressBar); // shortcuts QAction *focusAddressAction = new QAction(this); focusAddressAction->setShortcut(QKeySequence::fromString(sSettings->value("window.shortcuts.focusAddress").toString())); connect(focusAddressAction, SIGNAL(triggered(bool)), this, SLOT(focusAddress())); addAction(focusAddressAction); if(!defaultUrl.isEmpty()) { addNewTab(defaultUrl); } else { addNewTab(sSettings->value("general.homepage", QUrl("about:blank")).toUrl()); } resize(sSettings->value("window.width", 800).toInt(), sSettings->value("window.height", 600).toInt()); if(sSettings->value("window.maximized", false).toBool()) { showMaximized(); } } MainWindow::MainWindow(const QStringList urlList, QWidget *parent) : MainWindow(QUrl(""), parent) { QStringList::const_iterator i; for(i = urlList.constBegin(); i != urlList.constEnd(); ++i) { addNewTab(QUrl::fromUserInput(*i)); } } MainWindow::~MainWindow() { delete ui; } void MainWindow::addTabbedDock(Qt::DockWidgetArea area, QDockWidget *widget) { QList allDockWidgets = findChildren(); QVector areaDockWidgets; for(QDockWidget *w : allDockWidgets) { if(dockWidgetArea(w) == area) { areaDockWidgets.append(w); } } if(areaDockWidgets.empty()) { // no other widgets addDockWidget(area, widget); } else { tabifyDockWidget(areaDockWidgets.last(), widget); } } void MainWindow::addNewTab(const QUrl &url) { if(!url.isEmpty()) { tabBar->addTab(m_profile, url); } else { tabBar->addTab(m_profile, sSettings->value("general.newtab").toUrl()); } } void MainWindow::focusAddress() { urlLineEdit->setFocus(); urlLineEdit->selectAll(); } void MainWindow::closeEvent(QCloseEvent *event) { if(tabBar->count() > 1) { int ret = QMessageBox::warning(this, tr("Close window?"), tr("Close multiple tabs?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if(ret == QMessageBox::No) { event->ignore(); return; } } QMainWindow::closeEvent(event); } void MainWindow::about() { AboutDialog *dlg = new AboutDialog(this); dlg->exec(); } void MainWindow::loadProfile(const QString name) { if(name.isEmpty()) { bool ok; QString _name = QInputDialog::getText(this, tr("Load Profile"), tr("Enter Profile name"), QLineEdit::Normal, QString(""), &ok); if(ok) { m_profile = qApp->profile(_name); } else { return; } } else { m_profile = qApp->profile(name); } tabBar->setProfile(m_profile); } void MainWindow::handleNewWindow(const QUrl &url) { Browser::instance()->addWindow(new MainWindow(url)); } void MainWindow::handleTabChanged(WebView *view) { Q_ASSERT(view); // clear the parent of the central widget so it doesn't get deleted centralWidget()->setParent(0); // disconnect signals disconnect(centralWidget()); // set new central widget setCentralWidget(view); // connect signals connect(view, SIGNAL(urlChanged(QUrl)), urlLineEdit, SLOT(setUrl(QUrl))); connect(view, SIGNAL(titleChanged(QString)), this, SLOT(handleTitleUpdated(QString))); connect(view, SIGNAL(linkHovered(QString)), ui->statusBar, SLOT(showMessage(QString))); progressBar->connectWebView(view); // update UI urlLineEdit->setUrl(view->url()); this->handleTitleUpdated(view->title()); centralWidget()->setFocus(); } void MainWindow::handleUrlChanged() { tabBar->currentView()->load(urlLineEdit->url()); } void MainWindow::handleTitleUpdated(const QString &title) { setWindowTitle(sSettings->value("window.title").toString().replace("title", title).replace("profile", m_profile->storageName())); } void MainWindow::profileAction() { m_profile->dialog()->showProfile(); } void MainWindow::cookiesAction() { m_profile->dialog()->showCookies(); }