/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "browserapplication.h" #include "bookmarks.h" #include "browsermainwindow.h" #include "cookiejar.h" #include "downloadmanager.h" #include "history.h" #include "networkaccessmanager.h" #include "tabwidget.h" #include "webview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include DownloadManager *BrowserApplication::s_downloadManager = 0; HistoryManager *BrowserApplication::s_historyManager = 0; NetworkAccessManager *BrowserApplication::s_networkAccessManager = 0; BookmarksManager *BrowserApplication::s_bookmarksManager = 0; static void showHelp(QCommandLineParser &parser, const QString errorMessage = QString()) { QString text; QTextStream str(&text); str << ""; if (!errorMessage.isEmpty()) str << errorMessage; str << "
" << parser.helpText() << "
"; QMessageBox box(errorMessage.isEmpty() ? QMessageBox::Information : QMessageBox::Warning, QGuiApplication::applicationDisplayName(), text, QMessageBox::Ok); box.setTextInteractionFlags(Qt::TextBrowserInteraction); box.exec(); } BrowserApplication::BrowserApplication(int &argc, char **argv) : QApplication(argc, argv) , m_localServer(0) , m_initialUrl(QString()) , m_correctlyInitialized(false) { QCoreApplication::setOrganizationName(QLatin1String("Qt")); QCoreApplication::setApplicationName(QLatin1String("demobrowser")); QCoreApplication::setApplicationVersion(QLatin1String("0.1")); QCommandLineParser commandLineParser; commandLineParser.addPositionalArgument(QStringLiteral("url"), QStringLiteral("The url to be loaded in the browser window.")); if (!commandLineParser.parse(QCoreApplication::arguments())) { showHelp(commandLineParser, QStringLiteral("

Invalid argument

")); return; } QStringList args = commandLineParser.positionalArguments(); if (args.count() > 1) { showHelp(commandLineParser, QStringLiteral("

Too many arguments.

")); return; } else if (args.count() == 1) { m_initialUrl = args.at(0); } if (!m_initialUrl.isEmpty() && !QUrl::fromUserInput(m_initialUrl).isValid()) { showHelp(commandLineParser, QString("

%1 is not a valid url

").arg(m_initialUrl)); return; } m_correctlyInitialized = true; QString serverName = QCoreApplication::applicationName() + QString::fromLatin1(QT_VERSION_STR).remove('.') + QLatin1String("webkit"); QLocalSocket socket; socket.connectToServer(serverName); if (socket.waitForConnected(500)) { QTextStream stream(&socket); stream << m_initialUrl; stream.flush(); socket.waitForBytesWritten(); return; } #if defined(Q_OS_OSX) QApplication::setQuitOnLastWindowClosed(false); #else QApplication::setQuitOnLastWindowClosed(true); #endif m_localServer = new QLocalServer(this); connect(m_localServer, SIGNAL(newConnection()), this, SLOT(newLocalSocketConnection())); if (!m_localServer->listen(serverName)) { if (m_localServer->serverError() == QAbstractSocket::AddressInUseError && QFile::exists(m_localServer->serverName())) { QFile::remove(m_localServer->serverName()); m_localServer->listen(serverName); } } #ifndef QT_NO_OPENSSL if (!QSslSocket::supportsSsl()) { QMessageBox::information(0, "Demo Browser", "This system does not support OpenSSL. SSL websites will not be available."); } #endif QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl"); QString localSysName = QLocale::system().name(); installTranslator(QLatin1String("qt_") + localSysName); QSettings settings; settings.beginGroup(QLatin1String("sessions")); m_lastSession = settings.value(QLatin1String("lastSession")).toByteArray(); settings.endGroup(); #if defined(Q_OS_OSX) connect(this, SIGNAL(lastWindowClosed()), this, SLOT(lastWindowClosed())); #endif QTimer::singleShot(0, this, SLOT(postLaunch())); } BrowserApplication::~BrowserApplication() { delete s_downloadManager; for (int i = 0; i < m_mainWindows.size(); ++i) { BrowserMainWindow *window = m_mainWindows.at(i); delete window; } delete s_networkAccessManager; delete s_bookmarksManager; } #if defined(Q_OS_OSX) void BrowserApplication::lastWindowClosed() { clean(); BrowserMainWindow *mw = new BrowserMainWindow; mw->slotHome(); m_mainWindows.prepend(mw); } #endif BrowserApplication *BrowserApplication::instance() { return (static_cast(QCoreApplication::instance())); } #if defined(Q_OS_OSX) #include void BrowserApplication::quitBrowser() { clean(); int tabCount = 0; for (int i = 0; i < m_mainWindows.count(); ++i) { tabCount += m_mainWindows.at(i)->tabWidget()->count(); } if (tabCount > 1) { int ret = QMessageBox::warning(mainWindow(), QString(), tr("There are %1 windows and %2 tabs open\n" "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (ret == QMessageBox::No) return; } exit(0); } #endif /*! Any actions that can be delayed until the window is visible */ void BrowserApplication::postLaunch() { QString directory = QStandardPaths::writableLocation(QStandardPaths::DataLocation); if (directory.isEmpty()) directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); QWebSettings::setIconDatabasePath(directory); QWebSettings::setOfflineStoragePath(directory); setWindowIcon(QIcon(QLatin1String(":browser.svg"))); loadSettings(); // newMainWindow() needs to be called in main() for this to happen if (m_mainWindows.count() > 0) { if (!m_initialUrl.isEmpty()) mainWindow()->loadPage(m_initialUrl); else mainWindow()->slotHome(); } BrowserApplication::historyManager(); } void BrowserApplication::loadSettings() { QSettings settings; settings.beginGroup(QLatin1String("websettings")); QWebSettings *defaultSettings = QWebSettings::globalSettings(); QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); QFont standardFont = QFont(standardFontFamily, standardFontSize); standardFont = qvariant_cast(settings.value(QLatin1String("standardFont"), standardFont)); defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family()); defaultSettings->setFontSize(QWebSettings::DefaultFontSize, standardFont.pointSize()); QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); QFont fixedFont = QFont(fixedFontFamily, fixedFontSize); fixedFont = qvariant_cast(settings.value(QLatin1String("fixedFont"), fixedFont)); defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family()); defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fixedFont.pointSize()); defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool()); defaultSettings->setAttribute(QWebSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool()); QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl(); defaultSettings->setUserStyleSheetUrl(url); defaultSettings->setAttribute(QWebSettings::DnsPrefetchEnabled, true); settings.endGroup(); } QList BrowserApplication::mainWindows() { clean(); QList list; for (int i = 0; i < m_mainWindows.count(); ++i) list.append(m_mainWindows.at(i)); return list; } void BrowserApplication::clean() { // cleanup any deleted main windows first for (int i = m_mainWindows.count() - 1; i >= 0; --i) if (m_mainWindows.at(i).isNull()) m_mainWindows.removeAt(i); } void BrowserApplication::saveSession() { QWebSettings *globalSettings = QWebSettings::globalSettings(); if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) return; clean(); QSettings settings; settings.beginGroup(QLatin1String("sessions")); QByteArray data; QBuffer buffer(&data); QDataStream stream(&buffer); buffer.open(QIODevice::ReadWrite); stream << m_mainWindows.count(); for (int i = 0; i < m_mainWindows.count(); ++i) stream << m_mainWindows.at(i)->saveState(); settings.setValue(QLatin1String("lastSession"), data); settings.endGroup(); } bool BrowserApplication::canRestoreSession() const { return !m_lastSession.isEmpty(); } void BrowserApplication::restoreLastSession() { QList windows; QBuffer buffer(&m_lastSession); QDataStream stream(&buffer); buffer.open(QIODevice::ReadOnly); int windowCount; stream >> windowCount; for (int i = 0; i < windowCount; ++i) { QByteArray windowState; stream >> windowState; windows.append(windowState); } for (int i = 0; i < windows.count(); ++i) { BrowserMainWindow *newWindow = 0; if (m_mainWindows.count() == 1 && mainWindow()->tabWidget()->count() == 1 && mainWindow()->currentTab()->url() == QUrl()) { newWindow = mainWindow(); } else { newWindow = newMainWindow(); } newWindow->restoreState(windows.at(i)); } } bool BrowserApplication::isTheOnlyBrowser() const { return (m_localServer != 0); } bool BrowserApplication::isCorrectlyInitialized() const { return m_correctlyInitialized; } void BrowserApplication::installTranslator(const QString &name) { QTranslator *translator = new QTranslator(this); translator->load(name, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); QApplication::installTranslator(translator); } #if defined(Q_OS_OSX) bool BrowserApplication::event(QEvent* event) { switch (event->type()) { case QEvent::ApplicationActivate: { clean(); if (!m_mainWindows.isEmpty()) { BrowserMainWindow *mw = mainWindow(); if (mw && !mw->isMinimized()) { mainWindow()->show(); } return true; } } case QEvent::FileOpen: if (!m_mainWindows.isEmpty()) { mainWindow()->loadPage(static_cast(event)->file()); return true; } default: break; } return QApplication::event(event); } #endif void BrowserApplication::openUrl(const QUrl &url) { mainWindow()->loadPage(url.toString()); } BrowserMainWindow *BrowserApplication::newMainWindow() { BrowserMainWindow *browser = new BrowserMainWindow(); m_mainWindows.prepend(browser); browser->show(); return browser; } BrowserMainWindow *BrowserApplication::mainWindow() { clean(); if (m_mainWindows.isEmpty()) newMainWindow(); return m_mainWindows[0]; } void BrowserApplication::newLocalSocketConnection() { QLocalSocket *socket = m_localServer->nextPendingConnection(); if (!socket) return; socket->waitForReadyRead(1000); QTextStream stream(socket); QString url; stream >> url; if (!url.isEmpty()) { QSettings settings; settings.beginGroup(QLatin1String("general")); int openLinksIn = settings.value(QLatin1String("openLinksIn"), 0).toInt(); settings.endGroup(); if (openLinksIn == 1) newMainWindow(); else mainWindow()->tabWidget()->newTab(); openUrl(url); } delete socket; mainWindow()->raise(); mainWindow()->activateWindow(); } CookieJar *BrowserApplication::cookieJar() { return (CookieJar*)networkAccessManager()->cookieJar(); } DownloadManager *BrowserApplication::downloadManager() { if (!s_downloadManager) { s_downloadManager = new DownloadManager(); } return s_downloadManager; } NetworkAccessManager *BrowserApplication::networkAccessManager() { if (!s_networkAccessManager) { s_networkAccessManager = new NetworkAccessManager(); s_networkAccessManager->setCookieJar(new CookieJar); } return s_networkAccessManager; } HistoryManager *BrowserApplication::historyManager() { if (!s_historyManager) { s_historyManager = new HistoryManager(); QWebHistoryInterface::setDefaultInterface(s_historyManager); } return s_historyManager; } BookmarksManager *BrowserApplication::bookmarksManager() { if (!s_bookmarksManager) { s_bookmarksManager = new BookmarksManager; } return s_bookmarksManager; } QIcon BrowserApplication::icon(const QUrl &url) const { QIcon icon = QWebSettings::iconForUrl(url); if (!icon.isNull()) return icon.pixmap(16, 16); if (m_defaultIcon.isNull()) m_defaultIcon = QIcon(QLatin1String(":defaulticon.png")); return m_defaultIcon.pixmap(16, 16); }