308 lines
11 KiB
C++
Executable File
308 lines
11 KiB
C++
Executable File
// This file is part of RSS Guard.
|
|
//
|
|
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
|
|
//
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
#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 <QScrollBar>
|
|
#include <QToolBar>
|
|
#include <QWebEngineSettings>
|
|
#include <QToolTip>
|
|
#include <QWidgetAction>
|
|
|
|
|
|
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<Message> &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>() << 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<Message>() << *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<Message>() << *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>() << 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>() << 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;
|
|
}
|