summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Diamantini <adjam7@gmail.com>2012-07-25 10:44:49 +0200
committerAndrea Diamantini <adjam7@gmail.com>2012-12-10 02:48:04 +0100
commit4ea8138fcaf25b4d866ccafc277ab624d0b24441 (patch)
tree0e14399f6237418a3643173eb69c8df05543469b
parentRe-view and re-add tab highlight feature (diff)
downloadrekonq-4ea8138fcaf25b4d866ccafc277ab624d0b24441.tar.xz
Re-add WebSnap class & included API in WebWindow for tab preview
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/websnap.cpp164
-rw-r--r--src/websnap.h118
-rw-r--r--src/webwindow/webwindow.cpp7
-rw-r--r--src/webwindow/webwindow.h3
5 files changed, 294 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eefabbc5..31966664 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,6 +13,8 @@ set(rekonq_KDEINIT_SRCS
#----------------------------------------
webwindow/webpage.cpp
webwindow/webwindow.cpp
+ #----------------------------------------
+ websnap.cpp
)
diff --git a/src/websnap.cpp b/src/websnap.cpp
new file mode 100644
index 00000000..6440136e
--- /dev/null
+++ b/src/websnap.cpp
@@ -0,0 +1,164 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
+*
+*
+* This program 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 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Self Includes
+#include "websnap.h"
+#include "websnap.moc"
+
+// KDE Includes
+#include <KStandardDirs>
+
+// Qt Includes
+#include <QSize>
+#include <QFile>
+
+#include <QCryptographicHash>
+
+#include <QPainter>
+#include <QAction>
+
+#include <QWebFrame>
+#include <QWebSettings>
+
+
+WebSnap::WebSnap(const QUrl& url, QObject *parent)
+ : QObject(parent)
+ , m_url(url)
+{
+ // this to not register websnap history
+ m_page.settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
+
+ // this to not let this page open other windows
+ m_page.settings()->setAttribute(QWebSettings::PluginsEnabled, false);
+ m_page.settings()->setAttribute(QWebSettings::JavascriptEnabled, false);
+
+ connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(saveResult(bool)));
+
+ QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
+}
+
+
+WebSnap::~WebSnap()
+{
+ m_page.action(QWebPage::Stop)->trigger();
+ m_page.deleteLater();
+}
+
+
+void WebSnap::load()
+{
+ m_page.mainFrame()->load(m_url);
+}
+
+
+
+QPixmap WebSnap::render(const QWebPage &page, int w, int h)
+{
+ // create the page image
+ QPixmap pageImage = QPixmap(w, h);
+ pageImage.fill(Qt::transparent);
+
+ // render it
+ QPainter p(&pageImage);
+ page.mainFrame()->render(&p, QWebFrame::ContentsLayer);
+ p.end();
+
+ return pageImage;
+}
+
+
+// NOTE
+// to render page preview in a safe way, you CANNOT work with scrollbars!
+// In fact, disabling temporarily them DOES NOT work without reloading a page
+// that is something we CANNOT do.
+QPixmap WebSnap::renderPagePreview(const QWebPage &page, int w, int h)
+{
+ // store actual viewportsize
+ QSize oldSize = page.viewportSize();
+
+ // prepare page
+ // NOTE: I saw some sites with strange CMS and with absurd content size width (eg: 8584553)
+ // This usually leads setViewportSize to crash :(
+ // So, ensure renderWidth is no more than 2000.
+ int renderWidth = page.mainFrame()->contentsSize().width();
+ if (renderWidth > 2000)
+ renderWidth = 2000;
+ int renderHeight = renderWidth * ((0.0 + h) / w);
+
+ page.setViewportSize(QSize(renderWidth, renderHeight));
+
+ // consider scrollbars and render the page
+ bool verticalScrollBarActive = !page.mainFrame()->scrollBarGeometry(Qt::Vertical).isEmpty();
+ if (verticalScrollBarActive)
+ renderWidth -= 15;
+
+ bool horizontalScrollBarActive = !page.mainFrame()->scrollBarGeometry(Qt::Horizontal).isEmpty();
+ if (horizontalScrollBarActive)
+ renderHeight -= 15;
+
+ QPixmap pageImage = WebSnap::render(page, renderWidth, renderHeight);
+
+ // resize image
+ pageImage = pageImage.scaled(w, h, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
+
+ // restore page state
+ page.setViewportSize(oldSize);
+
+ return pageImage;
+}
+
+
+QString WebSnap::imagePathFromUrl(const QUrl &url)
+{
+ QByteArray name = url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash);
+
+ QByteArray hashedName = QCryptographicHash::hash(name, QCryptographicHash::Md5).toHex();
+
+ return KStandardDirs::locateLocal("cache", QString("thumbs/") + hashedName + ".png", true);
+}
+
+
+void WebSnap::saveResult(bool ok)
+{
+ if (ok)
+ {
+ QPixmap image = renderPagePreview(m_page, defaultWidth, defaultHeight);
+ QString path = imagePathFromUrl(m_url);
+ QFile::remove(path);
+ image.save(path);
+ }
+
+ emit snapDone(ok);
+
+ this->deleteLater();
+}
+
+
+bool WebSnap::existsImage(const QUrl &u)
+{
+ return QFile::exists(imagePathFromUrl(u));
+}
diff --git a/src/websnap.h b/src/websnap.h
new file mode 100644
index 00000000..9d3c214d
--- /dev/null
+++ b/src/websnap.h
@@ -0,0 +1,118 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
+*
+*
+* This program 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 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+#ifndef WEB_SNAP_H
+#define WEB_SNAP_H
+
+
+// Qt Includes
+#include <QObject>
+#include <QWebPage>
+#include <QUrl>
+
+// Forward Declarations
+class QPixmap;
+
+/**
+ * This class is used in many classes of rekonq to produce an image
+ * based on the site corresponding to the url passed as argument.
+ * It also cached the images to not retrieve them every time :)
+ *
+ * Heavily based on Graphics-Dojo WebSnap example (thanks!)
+ *
+ * We use this in the following rekonq classes:
+ *
+ * - TabBar class: to show a tab preview (given a page, you show AND save an image)
+ * - PreviewSelector class: to save new favorite selection (given a page, you show AND save an image)
+ *
+ * - NewTabPage class: to show the favorites page "preview" (given an url, you show AND save an image)
+ *
+ */
+
+class WebSnap : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Creates a WebSnap object. It will load the url in one WebPage
+ * and snap an image from it.
+ *
+ * @param url the url to load
+ * @param parent the object parent
+ */
+ explicit WebSnap(const QUrl &url, QObject *parent = 0);
+
+ ~WebSnap();
+
+ /**
+ * Snaps a pixmap of size w * h from a page
+ *
+ * @param page the page to snap
+ * @param w the image width
+ * @param h the image height
+ *
+ * @return the pixmap snapped from the page
+ */
+ static QPixmap renderPagePreview(const QWebPage &page, int w = defaultWidth, int h = defaultHeight);
+
+ /**
+ * Guess the local path where the image for the url provided
+ * should be
+ *
+ * @param url the url to guess snap path
+ *
+ * @return the local path of the url snap
+ */
+ static QString imagePathFromUrl(const QUrl &url);
+
+ /**
+ * Determines if a snap exists for that url
+ *
+ */
+ static bool existsImage(const QUrl &url);
+
+
+private Q_SLOTS:
+ void saveResult(bool ok = true);
+ void load();
+
+Q_SIGNALS:
+ void snapDone(bool ok);
+
+private:
+ // Constants
+ static const int defaultWidth = 200;
+ static const int defaultHeight = 150;
+ QWebPage m_page;
+ QUrl m_url;
+
+ //render a preview: common part of renderPagePreview() and renderTabPreview()
+ static QPixmap render(const QWebPage &page, int w, int h);
+};
+
+#endif // WEB_SNAP_H
diff --git a/src/webwindow/webwindow.cpp b/src/webwindow/webwindow.cpp
index 631c9a2c..6d0d4d72 100644
--- a/src/webwindow/webwindow.cpp
+++ b/src/webwindow/webwindow.cpp
@@ -22,6 +22,7 @@
#include "webwindow.moc"
#include "webpage.h"
+#include "websnap.h"
#include <QUrl>
#include <QLineEdit>
@@ -148,3 +149,9 @@ QIcon WebWindow::icon() const
{
return _view->icon();
}
+
+
+QPixmap WebWindow::tabPreview(int width, int height)
+{
+ return WebSnap::renderPagePreview(*page(), width, height);
+}
diff --git a/src/webwindow/webwindow.h b/src/webwindow/webwindow.h
index 7d72ed34..189f111f 100644
--- a/src/webwindow/webwindow.h
+++ b/src/webwindow/webwindow.h
@@ -29,6 +29,7 @@ class WebPage;
class QWebView;
class QLineEdit;
+class QPixmap;
class QUrl;
@@ -47,6 +48,8 @@ public:
QUrl url() const;
QString title() const;
QIcon icon() const;
+
+ QPixmap tabPreview(int width, int height);
private Q_SLOTS:
void checkLoadUrl();