2014-02-26 07:41:40 +01:00
|
|
|
// This file is part of RSS Guard.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2011-2014 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/>.
|
|
|
|
|
2014-03-26 13:30:18 +01:00
|
|
|
#include "network-web/webview.h"
|
2013-12-21 21:08:52 +01:00
|
|
|
|
|
|
|
#include "core/defs.h"
|
|
|
|
#include "core/settings.h"
|
2014-03-26 12:23:27 +01:00
|
|
|
#include "network-web/webpage.h"
|
2013-12-21 21:08:52 +01:00
|
|
|
#include "gui/skinfactory.h"
|
|
|
|
#include "gui/iconthemefactory.h"
|
|
|
|
|
2013-07-14 08:04:24 +02:00
|
|
|
#include <QStyleOptionFrameV3>
|
2013-07-21 11:26:57 +02:00
|
|
|
#include <QAction>
|
|
|
|
#include <QMenu>
|
2013-09-30 18:18:23 +02:00
|
|
|
#include <QDir>
|
|
|
|
#include <QFile>
|
2013-07-21 11:26:57 +02:00
|
|
|
#include <QWebFrame>
|
|
|
|
#include <QContextMenuEvent>
|
2013-11-12 19:42:09 +01:00
|
|
|
#include <QDateTime>
|
2014-02-17 18:12:24 +01:00
|
|
|
#include <QClipboard>
|
2013-07-14 08:04:24 +02:00
|
|
|
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
WebView::WebView(QWidget *parent)
|
2013-12-23 10:43:45 +01:00
|
|
|
: QWebView(parent), m_page(new WebPage(this)) {
|
2013-07-14 08:04:24 +02:00
|
|
|
setPage(m_page);
|
2013-08-30 20:26:39 +02:00
|
|
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
2013-07-21 21:02:34 +02:00
|
|
|
initializeActions();
|
2013-07-20 20:30:27 +02:00
|
|
|
createConnections();
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
WebView::~WebView() {
|
2013-07-21 21:02:34 +02:00
|
|
|
qDebug("Destroying BaseWebView.");
|
2013-07-20 20:30:27 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::onLoadFinished(bool ok) {
|
2013-07-20 20:30:27 +02:00
|
|
|
// If page was not loaded, then display custom error page.
|
|
|
|
if (!ok) {
|
|
|
|
displayErrorPage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-17 18:12:24 +01:00
|
|
|
void WebView::copySelectedText() {
|
|
|
|
QApplication::clipboard()->setText(selectedText());
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::openLinkInNewTab() {
|
2013-08-30 17:40:17 +02:00
|
|
|
emit linkMiddleClicked(m_contextLinkUrl);
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::openImageInNewTab() {
|
2013-08-30 17:40:17 +02:00
|
|
|
emit linkMiddleClicked(m_contextImageUrl);
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::createConnections() {
|
2013-08-30 17:40:17 +02:00
|
|
|
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
|
|
|
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)),
|
|
|
|
this, SLOT(popupContextMenu(QPoint)));
|
|
|
|
|
2014-02-17 18:12:24 +01:00
|
|
|
connect(m_actionOpenLinkNewTab, SIGNAL(triggered()), this, SLOT(openLinkInNewTab()));
|
2013-09-28 21:25:42 +02:00
|
|
|
connect(m_actionOpenImageNewTab, SIGNAL(triggered()), this, SLOT(openImageInNewTab()));
|
2013-07-20 20:30:27 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::setupIcons() {
|
2014-02-02 10:27:11 +01:00
|
|
|
m_actionReload->setIcon(IconThemeFactory::instance()->fromTheme("go-refresh"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionCopySelectedItem->setIcon(IconThemeFactory::instance()->fromTheme("edit-copy"));
|
2014-01-10 09:18:29 +01:00
|
|
|
m_actionCopyLink->setIcon(IconThemeFactory::instance()->fromTheme("edit-copy"));
|
2014-02-02 10:27:11 +01:00
|
|
|
m_actionCopyImage->setIcon(IconThemeFactory::instance()->fromTheme("edit-copy-image"));
|
2013-11-24 17:15:04 +01:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040800
|
2014-01-10 09:18:29 +01:00
|
|
|
m_actionCopyImageUrl->setIcon(IconThemeFactory::instance()->fromTheme("edit-copy"));
|
2013-11-24 17:15:04 +01:00
|
|
|
#endif
|
|
|
|
|
2014-01-10 09:18:29 +01:00
|
|
|
m_actionOpenLinkThisTab->setIcon(IconThemeFactory::instance()->fromTheme("text-html"));
|
|
|
|
m_actionOpenLinkNewTab->setIcon(IconThemeFactory::instance()->fromTheme("text-html"));
|
2014-02-02 10:27:11 +01:00
|
|
|
m_actionOpenImageNewTab->setIcon(IconThemeFactory::instance()->fromTheme("edit-copy-image"));
|
2013-07-21 21:02:34 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::initializeActions() {
|
2013-07-21 21:02:34 +02:00
|
|
|
// Create needed actions.
|
|
|
|
m_actionReload = pageAction(QWebPage::Reload);
|
|
|
|
m_actionReload->setParent(this);
|
|
|
|
m_actionReload->setText(tr("Reload web page"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionReload->setToolTip(tr("Reload current web page."));
|
|
|
|
|
|
|
|
m_actionCopySelectedItem = pageAction(QWebPage::Copy);
|
|
|
|
m_actionCopySelectedItem->setParent(this);
|
|
|
|
m_actionCopySelectedItem->setText(tr("Copy selection"));
|
|
|
|
m_actionCopySelectedItem->setToolTip(tr("Copies current selection into the clipboard."));
|
2013-07-21 21:02:34 +02:00
|
|
|
|
2014-02-18 14:24:51 +01:00
|
|
|
#if defined(Q_OS_OS2)
|
|
|
|
m_actionCopySelectedItem->setShortcut(QKeySequence::Copy);
|
|
|
|
addAction(m_actionCopySelectedItem);
|
|
|
|
#endif
|
|
|
|
|
2013-07-21 21:02:34 +02:00
|
|
|
m_actionCopyLink = pageAction(QWebPage::CopyLinkToClipboard);
|
|
|
|
m_actionCopyLink->setParent(this);
|
|
|
|
m_actionCopyLink->setText(tr("Copy link url"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionCopyLink->setToolTip(tr("Copy link url to clipboard."));
|
2013-07-21 21:02:34 +02:00
|
|
|
|
|
|
|
m_actionCopyImage = pageAction(QWebPage::CopyImageToClipboard);
|
|
|
|
m_actionCopyImage->setParent(this);
|
|
|
|
m_actionCopyImage->setText(tr("Copy image"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionCopyImage->setToolTip(tr("Copy image to clipboard."));
|
2013-07-21 21:02:34 +02:00
|
|
|
|
2013-11-24 17:15:04 +01:00
|
|
|
#if QT_VERSION >= 0x040800
|
2013-07-21 21:02:34 +02:00
|
|
|
m_actionCopyImageUrl = pageAction(QWebPage::CopyImageUrlToClipboard);
|
|
|
|
m_actionCopyImageUrl->setParent(this);
|
|
|
|
m_actionCopyImageUrl->setText(tr("Copy image url"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionCopyImageUrl->setToolTip(tr("Copy image url to clipboard."));
|
2013-11-24 17:15:04 +01:00
|
|
|
#endif
|
2013-08-05 21:31:41 +02:00
|
|
|
|
|
|
|
m_actionOpenLinkNewTab = pageAction(QWebPage::OpenLinkInNewWindow);
|
|
|
|
m_actionOpenLinkNewTab->setParent(this);
|
|
|
|
m_actionOpenLinkNewTab->setText(tr("Open link in new tab"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionOpenLinkNewTab->setToolTip(tr("Open this hyperlink in new tab."));
|
2013-08-30 17:40:17 +02:00
|
|
|
|
|
|
|
m_actionOpenLinkThisTab = pageAction(QWebPage::OpenLink);
|
|
|
|
m_actionOpenLinkThisTab->setParent(this);
|
|
|
|
m_actionOpenLinkThisTab->setText(tr("Follow link"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionOpenLinkThisTab->setToolTip(tr("Open the hyperlink in this tab."));
|
2013-08-30 17:40:17 +02:00
|
|
|
|
|
|
|
m_actionOpenImageNewTab = pageAction(QWebPage::OpenImageInNewWindow);
|
|
|
|
m_actionOpenImageNewTab->setParent(this);
|
|
|
|
m_actionOpenImageNewTab->setText(tr("Open image in new tab"));
|
2014-02-17 18:12:24 +01:00
|
|
|
m_actionOpenImageNewTab->setToolTip(tr("Open this image in this tab."));
|
2013-07-21 21:02:34 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::displayErrorPage() {
|
2014-01-10 09:18:29 +01:00
|
|
|
setHtml(SkinFactory::instance()->currentMarkupLayout().arg(
|
2014-01-03 13:15:05 +01:00
|
|
|
tr("Error page"),
|
2014-01-10 09:18:29 +01:00
|
|
|
SkinFactory::instance()->currentMarkup().arg(tr("Page not found"),
|
2014-02-17 18:12:24 +01:00
|
|
|
tr("Check your internet connection or website address"),
|
|
|
|
QString(),
|
|
|
|
tr("This failure can be caused by:<br><ul>"
|
|
|
|
"<li>non-functional internet connection,</li>"
|
|
|
|
"<li>incorrect website address,</li>"
|
|
|
|
"<li>bad proxy server settings,</li>"
|
|
|
|
"<li>target destination outage,</li>"
|
|
|
|
"<li>many other things.</li>"
|
|
|
|
"</ul>"),
|
|
|
|
QDateTime::currentDateTime().toString(Qt::DefaultLocaleLongDate))));
|
2013-07-14 08:04:24 +02:00
|
|
|
}
|
2013-07-08 20:58:24 +02:00
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::popupContextMenu(const QPoint &pos) {
|
2013-07-21 11:26:57 +02:00
|
|
|
QMenu context_menu(tr("Web browser"), this);
|
|
|
|
QMenu image_submenu(tr("Image"), &context_menu);
|
2013-08-30 17:40:17 +02:00
|
|
|
QMenu link_submenu(tr("Hyperlink"), this);
|
2013-07-24 19:06:09 +02:00
|
|
|
QWebHitTestResult hit_result = page()->mainFrame()->hitTestContent(pos);
|
2013-07-21 11:26:57 +02:00
|
|
|
|
2014-02-02 10:27:11 +01:00
|
|
|
image_submenu.setIcon(IconThemeFactory::instance()->fromTheme("image-generic"));
|
2014-01-10 09:18:29 +01:00
|
|
|
link_submenu.setIcon(IconThemeFactory::instance()->fromTheme("text-html"));
|
2013-07-21 21:02:34 +02:00
|
|
|
|
|
|
|
// Assemble the menu from actions.
|
|
|
|
context_menu.addAction(m_actionReload);
|
2014-02-17 18:12:24 +01:00
|
|
|
context_menu.addAction(m_actionCopySelectedItem);
|
2013-07-21 11:26:57 +02:00
|
|
|
|
2013-08-30 17:40:17 +02:00
|
|
|
QUrl hit_url = hit_result.linkUrl();
|
|
|
|
QUrl hit_image_url = hit_result.imageUrl();
|
|
|
|
|
|
|
|
if (hit_url.isValid()) {
|
|
|
|
m_contextLinkUrl = hit_url;
|
|
|
|
|
|
|
|
context_menu.addMenu(&link_submenu);
|
|
|
|
link_submenu.addAction(m_actionOpenLinkThisTab);
|
|
|
|
link_submenu.addAction(m_actionOpenLinkNewTab);
|
|
|
|
link_submenu.addAction(m_actionCopyLink);
|
2013-07-21 11:26:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!hit_result.pixmap().isNull()) {
|
2013-07-21 21:02:34 +02:00
|
|
|
// Add 'Image' menu, because if user clicked image it needs to be visible.
|
2013-07-21 11:26:57 +02:00
|
|
|
context_menu.addMenu(&image_submenu);
|
|
|
|
|
2013-08-30 17:40:17 +02:00
|
|
|
if (hit_image_url.isValid()) {
|
|
|
|
m_contextImageUrl = hit_image_url;
|
|
|
|
image_submenu.addAction(m_actionOpenImageNewTab);
|
2013-11-24 17:15:04 +01:00
|
|
|
|
|
|
|
#if QT_VERSION >= 0x040800
|
2013-08-30 17:40:17 +02:00
|
|
|
image_submenu.addAction(m_actionCopyImageUrl);
|
2013-11-24 17:15:04 +01:00
|
|
|
#endif
|
2013-08-30 17:40:17 +02:00
|
|
|
}
|
2013-07-21 21:02:34 +02:00
|
|
|
image_submenu.addAction(m_actionCopyImage);
|
2013-07-21 11:26:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Display the menu.
|
2013-07-24 19:06:09 +02:00
|
|
|
context_menu.exec(mapToGlobal(pos));
|
2013-07-21 11:26:57 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::mousePressEvent(QMouseEvent *event) {
|
2013-08-30 20:26:39 +02:00
|
|
|
if (event->button() & Qt::LeftButton && event->modifiers() & Qt::ControlModifier) {
|
2013-07-23 20:42:06 +02:00
|
|
|
QWebHitTestResult hit_result = page()->mainFrame()->hitTestContent(event->pos());
|
|
|
|
|
|
|
|
// Check if user clicked with middle mouse button on some
|
|
|
|
// hyperlink.
|
2013-08-03 16:22:40 +02:00
|
|
|
QUrl link_url = hit_result.linkUrl();
|
|
|
|
QUrl image_url = hit_result.imageUrl();
|
|
|
|
|
|
|
|
if (link_url.isValid()) {
|
|
|
|
emit linkMiddleClicked(link_url);
|
2013-07-23 20:42:06 +02:00
|
|
|
// No more handling of event is now needed. Return.
|
|
|
|
return;
|
|
|
|
}
|
2013-08-03 16:22:40 +02:00
|
|
|
else if (image_url.isValid()) {
|
|
|
|
emit linkMiddleClicked(image_url);
|
|
|
|
return;
|
|
|
|
}
|
2013-07-23 20:42:06 +02:00
|
|
|
}
|
2013-08-30 20:26:39 +02:00
|
|
|
else if (event->button() & Qt::MiddleButton) {
|
2013-07-24 19:06:09 +02:00
|
|
|
m_gestureOrigin = event->pos();
|
2013-08-30 20:26:39 +02:00
|
|
|
return;
|
2013-07-24 19:06:09 +02:00
|
|
|
}
|
2013-07-23 20:42:06 +02:00
|
|
|
|
|
|
|
QWebView::mousePressEvent(event);
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::mouseReleaseEvent(QMouseEvent *event) {
|
2013-08-30 20:26:39 +02:00
|
|
|
if (event->button() & Qt::MiddleButton) {
|
2014-01-10 09:18:29 +01:00
|
|
|
bool are_gestures_enabled = Settings::instance()->value(APP_CFG_BROWSER,
|
2014-02-17 18:12:24 +01:00
|
|
|
"gestures_enabled",
|
|
|
|
true).toBool();
|
2013-07-24 19:06:09 +02:00
|
|
|
if (are_gestures_enabled) {
|
|
|
|
QPoint release_point = event->pos();
|
|
|
|
int left_move = m_gestureOrigin.x() - release_point.x();
|
2013-08-30 20:26:39 +02:00
|
|
|
int right_move = -left_move;
|
2013-07-24 19:06:09 +02:00
|
|
|
int top_move = m_gestureOrigin.y() - release_point.y();
|
2013-08-30 20:26:39 +02:00
|
|
|
int bottom_move = -top_move;
|
2013-07-24 19:06:09 +02:00
|
|
|
int total_max = qMax(qMax(qMax(left_move, right_move),
|
|
|
|
qMax(top_move, bottom_move)),
|
|
|
|
40);
|
|
|
|
|
2013-08-30 20:26:39 +02:00
|
|
|
if (total_max == left_move) {
|
2013-07-24 19:06:09 +02:00
|
|
|
back();
|
|
|
|
}
|
2013-08-30 20:26:39 +02:00
|
|
|
else if (total_max == right_move) {
|
2013-07-24 19:06:09 +02:00
|
|
|
forward();
|
|
|
|
}
|
2013-08-30 20:26:39 +02:00
|
|
|
else if (total_max == top_move) {
|
2013-07-24 19:06:09 +02:00
|
|
|
reload();
|
|
|
|
}
|
2013-08-30 20:26:39 +02:00
|
|
|
else if (total_max == bottom_move) {
|
2013-07-24 19:06:09 +02:00
|
|
|
emit newTabRequested();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-30 20:26:39 +02:00
|
|
|
|
|
|
|
QWebView::mouseReleaseEvent(event);
|
2013-07-23 20:42:06 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
void WebView::wheelEvent(QWheelEvent *event) {
|
2013-11-05 19:33:21 +01:00
|
|
|
if (event->modifiers() & Qt::ControlModifier) {
|
|
|
|
if (event->delta() > 0) {
|
|
|
|
increaseWebPageZoom();
|
|
|
|
emit zoomFactorChanged();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (event->delta() < 0) {
|
|
|
|
decreaseWebPageZoom();
|
|
|
|
emit zoomFactorChanged();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QWebView::wheelEvent(event);
|
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
bool WebView::increaseWebPageZoom() {
|
2013-10-15 21:10:54 +02:00
|
|
|
qreal new_factor = zoomFactor() + 0.1;
|
|
|
|
|
|
|
|
if (new_factor >= 0.0 && new_factor <= MAX_ZOOM_FACTOR) {
|
|
|
|
setZoomFactor(new_factor);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-28 21:25:42 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
bool WebView::decreaseWebPageZoom() {
|
2013-10-15 21:10:54 +02:00
|
|
|
qreal new_factor = zoomFactor() - 0.1;
|
|
|
|
|
|
|
|
if (new_factor >= 0.0 && new_factor <= MAX_ZOOM_FACTOR) {
|
|
|
|
setZoomFactor(new_factor);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-28 21:25:42 +02:00
|
|
|
}
|
|
|
|
|
2013-12-22 18:06:30 +01:00
|
|
|
bool WebView::resetWebPageZoom() {
|
2013-10-15 21:10:54 +02:00
|
|
|
qreal new_factor = 1.0;
|
|
|
|
|
|
|
|
if (new_factor != zoomFactor()) {
|
|
|
|
setZoomFactor(new_factor);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-28 09:49:43 +02:00
|
|
|
}
|