1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 18:56:34 +01:00

SpeedDial: Implement loading page thumbnails

QWebEngineView must be visible in order to grab page contents, so
loading thumbnails is creating a new background window that is loading
the page.
This commit is contained in:
David Rosca 2015-08-28 20:43:37 +02:00
parent fc204b3b46
commit 832bd37114
5 changed files with 45 additions and 107 deletions

View File

@ -151,7 +151,7 @@ function onReloadClick(box) {
return; return;
$(img).attr('src', LOADING_IMAGE); $(img).attr('src', LOADING_IMAGE);
external.speedDial.loadThumbnail(url); external.speedDial.loadThumbnail(url, false);
} }
function boxEdited() { function boxEdited() {
@ -167,19 +167,20 @@ function boxEdited() {
var changedUrl = a.getAttribute('href'); var changedUrl = a.getAttribute('href');
var fetchTitleChecked = document.getElementById('fetchTitle').checked; var fetchTitleChecked = document.getElementById('fetchTitle').checked;
var pages = allPages();
if (fetchTitleChecked || (originalUrl != changedUrl && changedUrl !== '') ) { if (fetchTitleChecked || (originalUrl != changedUrl && changedUrl !== '') ) {
var img = box.getElementsByTagName('img')[0]; var img = box.getElementsByTagName('img')[0];
img.setAttribute('src', LOADING_IMAGE); img.setAttribute('src', LOADING_IMAGE);
$('#fadeOverlay').fadeOut("slow", function() { $('#fadeOverlay').fadeOut("slow", function() {
$("#fadeOverlay").remove(); $("#fadeOverlay").remove();
external.speedDial.loadThumbnail(a.getAttribute('href'), fetchTitleChecked);
external.speedDial.removeImageForUrl(a.getAttribute('href'));
}); });
external.speedDial.loadThumbnail(a.getAttribute('href'), fetchTitleChecked);
} else { } else {
hideEditBox(); hideEditBox();
} }
external.speedDial.changed(allPages()); external.speedDial.changed(pages);
}); });
} }
@ -240,7 +241,7 @@ function addBox(url, title, img_source) {
document.getElementById("quickdial").appendChild(div); document.getElementById("quickdial").appendChild(div);
if (img_source == LOADING_IMAGE) { if (img_source == LOADING_IMAGE) {
external.speedDial.loadThumbnail(url); external.speedDial.loadThumbnail(url, false);
} }
return div; return div;
@ -264,7 +265,6 @@ function setTitleToUrl(url, title) {
continue; continue;
var boxUrl = box.getElementsByTagName('a')[0].getAttribute('href'); var boxUrl = box.getElementsByTagName('a')[0].getAttribute('href');
console.log(boxUrl + " > " + url);
if (url != boxUrl) if (url != boxUrl)
continue; continue;
@ -283,7 +283,7 @@ function setImageToUrl(url, img_source) {
if ($(imgElement).size() == 0) if ($(imgElement).size() == 0)
return; return;
$(imgElement).attr('src', img_source + '?' + new Date()); $(imgElement).attr('src', img_source/* + '?' + new Date()*/);
}); });
} }
@ -320,7 +320,7 @@ function removeBox(id) {
} }
function alignPage() { function alignPage() {
$('head').append('<style>#quickdial img[src*=".png"]{height:auto;width:'+DIAL_WIDTH+'px}</style>'); $('head').append('<style>#quickdial img{height:auto;width:'+DIAL_WIDTH+'px}</style>');
$('#quickdial div.entry').css({'width' : DIAL_WIDTH + 'px', $('#quickdial div.entry').css({'width' : DIAL_WIDTH + 'px',
'height' : Math.round(DIAL_WIDTH / 1.54) + 'px'}); 'height' : Math.round(DIAL_WIDTH / 1.54) + 'px'});
@ -430,11 +430,13 @@ $(document).ready(function () {
function init() function init()
{ {
%INITIAL-SCRIPT% %INITIAL-SCRIPT%
external.speedDial.pagesChanged.connect(function() { external.speedDial.pagesChanged.connect(function() {
window.location.reload(); window.location.reload();
}); });
alignPage(); external.speedDial.thumbnailLoaded.connect(setImageToUrl);
external.speedDial.pageTitleLoaded.connect(setTitleToUrl);
$(window).resize(function() { alignPage(); }); $(window).resize(function() { alignPage(); });
$("div").disableSelection(); $("div").disableSelection();
@ -448,6 +450,8 @@ function init()
external.speedDial.changed(allPages()); external.speedDial.changed(allPages());
} }
}); });
alignPage();
} }
// Initialize // Initialize

View File

@ -206,15 +206,15 @@ QString SpeedDial::initialScript()
QString imgSource = m_thumbnailsDir + QCryptographicHash::hash(page.url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png"; QString imgSource = m_thumbnailsDir + QCryptographicHash::hash(page.url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png";
if (!QFile(imgSource).exists()) { if (!QFile(imgSource).exists()) {
//imgSource = "qrc:html/loading.gif"; imgSource = "qrc:html/loading.gif";
imgSource = "qrc:html/broken-page.png";
if (page.url.isEmpty()) { if (page.url.isEmpty()) {
imgSource.clear(); imgSource.clear();
} }
} }
else { else {
imgSource = QUrl::fromLocalFile(imgSource).toString(); QByteArray data = QzTools::pixmapToByteArray(QPixmap(imgSource));
imgSource = QByteArrayLiteral("data:image/png;base64,") + data;
} }
m_initialScript.append(QString("addBox('%1', '%2', '%3');\n").arg(page.url, page.title, imgSource)); m_initialScript.append(QString("addBox('%1', '%2', '%3');\n").arg(page.url, page.title, imgSource));
@ -259,14 +259,12 @@ void SpeedDial::loadThumbnail(const QString &url, bool loadTitle)
return; return;
} }
#if QTWEBENGINE_DISABLED
PageThumbnailer* thumbnailer = new PageThumbnailer(this); PageThumbnailer* thumbnailer = new PageThumbnailer(this);
thumbnailer->setUrl(QUrl::fromEncoded(url.toUtf8())); thumbnailer->setUrl(QUrl::fromEncoded(url.toUtf8()));
thumbnailer->setLoadTitle(loadTitle); thumbnailer->setLoadTitle(loadTitle);
connect(thumbnailer, SIGNAL(thumbnailCreated(QPixmap)), this, SLOT(thumbnailCreated(QPixmap))); connect(thumbnailer, SIGNAL(thumbnailCreated(QPixmap)), this, SLOT(thumbnailCreated(QPixmap)));
thumbnailer->start(); thumbnailer->start();
#endif
} }
void SpeedDial::removeImageForUrl(const QString &url) void SpeedDial::removeImageForUrl(const QString &url)
@ -322,7 +320,6 @@ void SpeedDial::setSdCentered(int cntr)
void SpeedDial::thumbnailCreated(const QPixmap &pixmap) void SpeedDial::thumbnailCreated(const QPixmap &pixmap)
{ {
#if QTWEBENGINE_DISABLED
PageThumbnailer* thumbnailer = qobject_cast<PageThumbnailer*>(sender()); PageThumbnailer* thumbnailer = qobject_cast<PageThumbnailer*>(sender());
if (!thumbnailer) { if (!thumbnailer) {
return; return;
@ -342,22 +339,17 @@ void SpeedDial::thumbnailCreated(const QPixmap &pixmap)
if (!pixmap.save(fileName, "PNG")) { if (!pixmap.save(fileName, "PNG")) {
qWarning() << "SpeedDial::thumbnailCreated Cannot save thumbnail to " << fileName; qWarning() << "SpeedDial::thumbnailCreated Cannot save thumbnail to " << fileName;
} }
//fileName = QUrl::fromLocalFile(fileName).toString();
fileName = QUrl::fromLocalFile(fileName).toString();
} }
m_regenerateScript = true; m_regenerateScript = true;
pages();
foreach (QWebEngineFrame* frame, pages()) {
frame->evaluateJavaScript(QString("setImageToUrl('%1', '%2');").arg(escapeUrl(url), escapeTitle(fileName)));
if (loadTitle) {
frame->evaluateJavaScript(QString("setTitleToUrl('%1', '%2');").arg(escapeUrl(url), escapeTitle(title)));
}
}
thumbnailer->deleteLater(); thumbnailer->deleteLater();
#endif
if (loadTitle)
emit pageTitleLoaded(url, title);
QByteArray data = QzTools::pixmapToByteArray(QPixmap(fileName));
emit thumbnailLoaded(url, QString(QByteArrayLiteral("data:image/png;base64,") + data));
} }
QString SpeedDial::escapeTitle(QString title) const QString SpeedDial::escapeTitle(QString title) const

View File

@ -65,10 +65,12 @@ public:
signals: signals:
void pagesChanged(); void pagesChanged();
void thumbnailLoaded(const QString &url, const QString &src);
void pageTitleLoaded(const QString &url, const QString &title);
public slots: public slots:
void changed(const QString &allPages); void changed(const QString &allPages);
void loadThumbnail(const QString &url, bool loadTitle = false); void loadThumbnail(const QString &url, bool loadTitle);
void removeImageForUrl(const QString &url); void removeImageForUrl(const QString &url);
QString getOpenFileName(); QString getOpenFileName();

View File

@ -16,51 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */ * ============================================================ */
#include "pagethumbnailer.h" #include "pagethumbnailer.h"
#include "mainapplication.h"
#include "networkmanagerproxy.h"
#if QTWEBENGINE_DISABLED
#include <QWebEnginePage>
#include <QWebEngineFrame>
#include <QPainter> #include <QPainter>
#include <QApplication>
CleanPluginFactory::CleanPluginFactory(QObject* parent) #include <QWebEngineView>
: QWebPluginFactory(parent)
{
}
QList<QWebPluginFactory::Plugin> CleanPluginFactory::plugins() const
{
return QList<QWebPluginFactory::Plugin>();
}
QObject* CleanPluginFactory::create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const
{
Q_UNUSED(mimeType)
Q_UNUSED(url)
Q_UNUSED(argumentNames)
Q_UNUSED(argumentValues)
return new QObject;
}
PageThumbnailer::PageThumbnailer(QObject* parent) PageThumbnailer::PageThumbnailer(QObject* parent)
: QObject(parent) : QObject(parent)
, m_page(new QWebEnginePage(this)) , m_view(new QWebEngineView())
, m_size(QSize(450, 253)) , m_size(QSize(450, 253))
, m_loadTitle(false) , m_loadTitle(false)
{ {
NetworkManagerProxy* networkProxy = new NetworkManagerProxy(this);
networkProxy->setPrimaryNetworkAccessManager(mApp->networkManager());
m_page->setNetworkAccessManager(networkProxy);
m_page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
m_page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
// HD Ready -,-
// Every page should fit in this resolution // Every page should fit in this resolution
m_page->setViewportSize(QSize(1280, 720)); m_view->resize(QSize(1280, 720));
// Well ...
QWidget *w = QApplication::activeWindow();
m_view->show();
if (w) {
QApplication::setActiveWindow(w);
w->activateWindow();
}
} }
void PageThumbnailer::setSize(const QSize &size) void PageThumbnailer::setSize(const QSize &size)
@ -98,22 +74,14 @@ QString PageThumbnailer::title()
if (title.isEmpty()) { if (title.isEmpty()) {
title = m_url.toString(); title = m_url.toString();
} }
return title; return title;
} }
void PageThumbnailer::setEnableFlash(bool enable)
{
if (!enable) {
m_page->setPluginFactory(new CleanPluginFactory);
}
}
void PageThumbnailer::start() void PageThumbnailer::start()
{ {
m_page->mainFrame()->load(m_url); m_view->load(m_url);
connect(m_page, SIGNAL(loadFinished(bool)), this, SLOT(createThumbnail(bool))); connect(m_view, &QWebEngineView::loadFinished, this, &PageThumbnailer::createThumbnail);
} }
void PageThumbnailer::createThumbnail(bool status) void PageThumbnailer::createThumbnail(bool status)
@ -123,23 +91,12 @@ void PageThumbnailer::createThumbnail(bool status)
return; return;
} }
m_title = m_page->mainFrame()->title().trimmed(); m_title = m_view->title().trimmed();
QPixmap pixmap(2 * m_size); emit thumbnailCreated(m_view->grab().scaled(m_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
qreal scalingFactor = 2 * static_cast<qreal>(m_size.width()) / 1280;
QPainter painter(&pixmap);
painter.scale(scalingFactor, scalingFactor);
m_page->mainFrame()->render(&painter, QWebEngineFrame::ContentsLayer);
painter.end();
emit thumbnailCreated(pixmap.scaled(m_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
} }
PageThumbnailer::~PageThumbnailer() PageThumbnailer::~PageThumbnailer()
{ {
m_page->deleteLater(); m_view->deleteLater();
} }
#endif

View File

@ -18,28 +18,15 @@
#ifndef PAGETHUMBNAILER_H #ifndef PAGETHUMBNAILER_H
#define PAGETHUMBNAILER_H #define PAGETHUMBNAILER_H
#if QTWEBENGINE_DISABLED
#include <QObject> #include <QObject>
#include <QSize> #include <QSize>
#include <QUrl> #include <QUrl>
#include <QWebPluginFactory>
#include "qzcommon.h" #include "qzcommon.h"
class QWebEnginePage; class QWebEngineView;
class QPixmap; class QPixmap;
class QUPZILLA_EXPORT CleanPluginFactory : public QWebPluginFactory
{
Q_OBJECT
public:
explicit CleanPluginFactory(QObject* parent = 0);
QList<QWebPluginFactory::Plugin> plugins() const;
QObject* create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const;
};
class QUPZILLA_EXPORT PageThumbnailer : public QObject class QUPZILLA_EXPORT PageThumbnailer : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -56,8 +43,6 @@ public:
void setLoadTitle(bool load); void setLoadTitle(bool load);
QString title(); QString title();
void setEnableFlash(bool enable);
void start(); void start();
signals: signals:
@ -69,7 +54,7 @@ private slots:
void createThumbnail(bool status); void createThumbnail(bool status);
private: private:
QWebEnginePage* m_page; QWebEngineView* m_view;
QSize m_size; QSize m_size;
QUrl m_url; QUrl m_url;
@ -77,6 +62,4 @@ private:
bool m_loadTitle; bool m_loadTitle;
}; };
#endif
#endif // PAGETHUMBNAILER_H #endif // PAGETHUMBNAILER_H