// This file is part of RSS Guard. // // Copyright (C) 2011-2016 by Martin Rotter // // RSS Guard 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. // // RSS Guard 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 RSS Guard. If not, see . #include "gui/webbrowser.h" #include "miscellaneous/application.h" #include "miscellaneous/databasequeries.h" #include "network-web/networkfactory.h" #include "network-web/webfactory.h" #include "gui/messagebox.h" #include "gui/webviewer.h" #include "gui/discoverfeedsbutton.h" #include "gui/locationlineedit.h" #include "services/abstract/serviceroot.h" #include #include #include #include #include void WebBrowser::createConnections() { connect(m_webView, &WebViewer::messageStatusChangeRequested, this, &WebBrowser::receiveMessageStatusChangeRequest); connect(m_txtLocation,SIGNAL(submitted(QString)), this, SLOT(loadUrl(QString))); connect(m_webView, SIGNAL(urlChanged(QUrl)), this, SLOT(updateUrl(QUrl))); // Change location textbox status according to webpage status. connect(m_webView, SIGNAL(loadStarted()), this, SLOT(onLoadingStarted())); connect(m_webView, SIGNAL(loadProgress(int)), this, SLOT(onLoadingProgress(int))); connect(m_webView, SIGNAL(loadFinished(bool)), this, SLOT(onLoadingFinished(bool))); // Forward title/icon changes. connect(m_webView, SIGNAL(titleChanged(QString)), this, SLOT(onTitleChanged(QString))); connect(m_webView, SIGNAL(iconChanged(QIcon)), this, SLOT(onIconChanged(QIcon))); } void WebBrowser::updateUrl(const QUrl &url) { QString url_string = url.toString(); m_txtLocation->setText(url_string); //setNavigationBarVisible(url_string != INTERNAL_URL_EMPTY && url_string != INTERNAL_URL_NEWSPAPER); } void WebBrowser::loadUrl(const QUrl &url) { if (url.isValid()) { m_webView->load(url); } } WebBrowser::WebBrowser(QWidget *parent) : TabContent(parent), m_layout(new QVBoxLayout(this)), m_toolBar(new QToolBar(tr("Navigation panel"), this)), m_webView(new WebViewer(this)), m_txtLocation(new LocationLineEdit(this)), m_btnDiscoverFeeds(new DiscoverFeedsButton(this)), m_actionBack(m_webView->pageAction(QWebEnginePage::Back)), m_actionForward(m_webView->pageAction(QWebEnginePage::Forward)), m_actionReload(m_webView->pageAction(QWebEnginePage::Reload)), m_actionStop(m_webView->pageAction(QWebEnginePage::Stop)) { // Initialize the components and layout. initializeLayout(); setFocusProxy(m_txtLocation); setTabOrder(m_txtLocation, m_toolBar); setTabOrder(m_toolBar, m_webView); createConnections(); reloadFontSettings(); } WebBrowser::~WebBrowser() { // Delete members. Do not use scoped pointers here. delete m_layout; } void WebBrowser::reloadFontSettings() { QFont fon; fon.fromString(qApp->settings()->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString()); QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::StandardFont, fon.family()); QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, fon.pointSize()); } void WebBrowser::increaseZoom() { m_webView->increaseWebPageZoom(); } void WebBrowser::decreaseZoom() { m_webView->decreaseWebPageZoom(); } void WebBrowser::resetZoom() { m_webView->resetWebPageZoom(); } void WebBrowser::clear() { m_webView->clear(); m_messages.clear(); hide(); } void WebBrowser::loadUrl(const QString &url) { return loadUrl(QUrl::fromUserInput(url)); } void WebBrowser::loadMessages(const QList &messages, RootItem *root) { if (m_messages.size() == messages.size()) { for (int i = 0; i < messages.size(); i++) { if (m_messages.at(i).m_id != messages.at(i).m_id) { break; } if (i == messages.size() - 1) { // We checked last items, both collections contain the same messages. return; } } } m_messages = messages; m_root = root; if (!m_root.isNull()) { m_webView->loadMessages(messages); show(); } } void WebBrowser::loadMessage(const Message &message, RootItem *root) { loadMessages(QList() << message, root); } void WebBrowser::receiveMessageStatusChangeRequest(int message_id, WebPage::MessageStatusChange change) { switch (change) { case WebPage::MarkRead: markMessageAsRead(message_id, true); break; case WebPage::MarkUnread: markMessageAsRead(message_id, false); break; case WebPage::MarkStarred: switchMessageImportance(message_id, true); break; case WebPage::MarkUnstarred: switchMessageImportance(message_id, false); break; default: break; } } void WebBrowser::onTitleChanged(const QString &new_title) { if (new_title.isEmpty()) { //: Webbrowser tab title when no title is available. emit titleChanged(m_index, tr("No title")); } else { emit titleChanged(m_index, new_title); } } void WebBrowser::onIconChanged(const QIcon &icon) { emit iconChanged(m_index, icon); } void WebBrowser::initializeLayout() { m_toolBar->setFloatable(false); m_toolBar->setMovable(false); m_toolBar->setAllowedAreas(Qt::TopToolBarArea); // Modify action texts. m_actionBack->setText(tr("Back")); m_actionBack->setToolTip(tr("Go back.")); m_actionForward->setText(tr("Forward")); m_actionForward->setToolTip(tr("Go forward.")); m_actionReload->setText(tr("Reload")); m_actionReload->setToolTip(tr("Reload current web page.")); m_actionStop->setText(tr("Stop")); m_actionStop->setToolTip(tr("Stop web page loading.")); QWidgetAction *act_discover = new QWidgetAction(this); act_discover->setDefaultWidget(m_btnDiscoverFeeds); // Add needed actions into toolbar. m_toolBar->addAction(m_actionBack); m_toolBar->addAction(m_actionForward); m_toolBar->addAction(m_actionReload); m_toolBar->addAction(m_actionStop); m_toolBar->addAction(act_discover); m_toolBar->addWidget(m_txtLocation); m_loadingProgress = new QProgressBar(this); m_loadingProgress->setFixedHeight(5); m_loadingProgress->setMinimum(0); m_loadingProgress->setTextVisible(false); m_loadingProgress->setMaximum(100); m_loadingProgress->setAttribute(Qt::WA_TranslucentBackground); // Setup layout. m_layout->addWidget(m_toolBar); m_layout->addWidget(m_webView); m_layout->addWidget(m_loadingProgress); m_layout->setMargin(0); m_layout->setSpacing(0); } void WebBrowser::onLoadingStarted() { m_btnDiscoverFeeds->clearFeedAddresses(); m_loadingProgress->show(); } void WebBrowser::onLoadingProgress(int progress) { m_loadingProgress->setValue(progress); } void WebBrowser::onLoadingFinished(bool success) { if (success) { // Let's check if there are any feeds defined on the web and eventually // display "Add feeds" button. m_webView->page()->toHtml([this](const QString &result){ this->m_btnDiscoverFeeds->setFeedAddresses(NetworkFactory::extractFeedLinksFromHtmlPage(m_webView->url(), result)); }); } else { m_btnDiscoverFeeds->clearFeedAddresses(); } m_loadingProgress->hide(); m_loadingProgress->setValue(0); } void WebBrowser::markMessageAsRead(int id, bool read) { if (!m_root.isNull()) { Message *msg = findMessage(id); if (msg != nullptr && m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(), QList() << *msg, read ? RootItem::Read : RootItem::Unread)) { DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), QStringList() << QString::number(msg->m_id), read ? RootItem::Read : RootItem::Unread); m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(), QList() << *msg, read ? RootItem::Read : RootItem::Unread); emit markMessageRead(msg->m_id, read ? RootItem::Read : RootItem::Unread); msg->m_isRead = read ? RootItem::Read : RootItem::Unread; } } } void WebBrowser::switchMessageImportance(int id, bool checked) { if (!m_root.isNull()) { Message *msg = findMessage(id); if (msg != nullptr && m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(), QList() << ImportanceChange(*msg, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important))) { DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), QStringList() << QString::number(msg->m_id)); m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(), QList() << ImportanceChange(*msg, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important)); emit markMessageImportant(msg->m_id, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important); msg->m_isImportant = checked; } } } Message *WebBrowser::findMessage(int id) { for (int i = 0; i < m_messages.size(); i++) { if (m_messages.at(i).m_id == id) { return &m_messages[i]; } } return nullptr; }