summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board.cpp17
-rw-r--r--global.h2
-rw-r--r--imagecache.cpp16
-rw-r--r--imagecache.h13
-rw-r--r--imagenetworkaccessmanager.cpp23
-rw-r--r--imagenetworkaccessmanager.h23
-rw-r--r--imageprovider.cpp110
-rw-r--r--imageprovider.h25
-rw-r--r--main.cpp9
-rw-r--r--tapasboard.pro6
10 files changed, 87 insertions, 157 deletions
diff --git a/board.cpp b/board.cpp
index 1be4076..fc9e0ad 100644
--- a/board.cpp
+++ b/board.cpp
@@ -118,19 +118,6 @@ QString Board::bbcodeToRichText(QString text) const
text.replace(pair.first, pair.second);
}
- // Unfortunately, we have to process images separately
- static QRegExp img_bbcode("\\[img\\]([^[]*)\\[/img\\]", Qt::CaseInsensitive);
- int pos = 0;
- while ((pos = img_bbcode.indexIn(text, pos)) != -1) {
- QString imageUrl = img_bbcode.cap(1);
- QString providerUrl = image_provider->getProviderImageUrl(imageUrl);
- qDebug() << "Image" << imageUrl << "->" << providerUrl;
- text.replace(pos, img_bbcode.matchedLength(), "<img src=\"" + providerUrl + "\" />");
- }
-
- // HTML newlines
- text.replace("\n", "<br>");
-
return text;
}
@@ -323,7 +310,11 @@ void Board::initializeBbCode()
_bbcodes << qMakePair(QRegExp("\\[url=([^]]*)\\]", Qt::CaseInsensitive), QString("<a href=\"\\1\">"));
_bbcodes << qMakePair(QRegExp("\\[/url\\]", Qt::CaseInsensitive), QString("</a>"));
+ _bbcodes << qMakePair(QRegExp("\\[img\\]([^[]*)\\[/img\\]", Qt::CaseInsensitive), QString("<img src=\"\\1\" />"));
+
_bbcodes << qMakePair(QRegExp("\\[hr\\]", Qt::CaseInsensitive), QString("<hr>"));
+
+ _bbcodes << qMakePair(QRegExp("\n"), QString("<br>"));
}
void Board::fetchConfigIfOutdated()
diff --git a/global.h b/global.h
index 9eefb17..4ecc890 100644
--- a/global.h
+++ b/global.h
@@ -2,7 +2,6 @@
#define GLOBAL_H
#include "boardmanager.h"
-#include "imageprovider.h"
/** Time the forum config settings should be considered up to date, in days. */
#define BOARD_CONFIG_TTL 2
@@ -30,6 +29,5 @@
// Some singletons
extern BoardManager *board_manager;
-extern ImageProvider *image_provider;
#endif // GLOBAL_H
diff --git a/imagecache.cpp b/imagecache.cpp
new file mode 100644
index 0000000..e59ffdf
--- /dev/null
+++ b/imagecache.cpp
@@ -0,0 +1,16 @@
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+
+#include "global.h"
+#include "imagecache.h"
+
+ImageCache::ImageCache(QObject *parent) :
+ QNetworkDiskCache(parent)
+{
+ QString cache_path = board_manager->getCachePath() + "/images";
+ QDir dir;
+ if (!dir.mkpath(cache_path)) {
+ qWarning() << "Could not create image cache path" << cache_path;
+ }
+ setCacheDirectory(cache_path);
+}
diff --git a/imagecache.h b/imagecache.h
new file mode 100644
index 0000000..2553c80
--- /dev/null
+++ b/imagecache.h
@@ -0,0 +1,13 @@
+#ifndef IMAGECACHE_H
+#define IMAGECACHE_H
+
+#include <QtNetwork/QNetworkDiskCache>
+
+class ImageCache : public QNetworkDiskCache
+{
+ Q_OBJECT
+public:
+ explicit ImageCache(QObject *parent = 0);
+};
+
+#endif // IMAGECACHE_H
diff --git a/imagenetworkaccessmanager.cpp b/imagenetworkaccessmanager.cpp
new file mode 100644
index 0000000..ab4509b
--- /dev/null
+++ b/imagenetworkaccessmanager.cpp
@@ -0,0 +1,23 @@
+#include <QtNetwork/QNetworkRequest>
+
+#include "imagecache.h"
+#include "imagenetworkaccessmanager.h"
+
+ImageNetworkAccessManager::ImageNetworkAccessManager(QObject *parent) :
+ QNetworkAccessManager(parent)
+{
+ setCache(new ImageCache);
+}
+
+QNetworkReply * ImageNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
+{
+ QNetworkRequest new_request(request);
+ new_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+ QNetworkRequest::PreferCache);
+ return QNetworkAccessManager::createRequest(op, new_request, outgoingData);
+}
+
+QNetworkAccessManager * ImageNetworkAccessManagerFactory::create(QObject *parent)
+{
+ return new ImageNetworkAccessManager(parent);
+}
diff --git a/imagenetworkaccessmanager.h b/imagenetworkaccessmanager.h
new file mode 100644
index 0000000..9dfb586
--- /dev/null
+++ b/imagenetworkaccessmanager.h
@@ -0,0 +1,23 @@
+#ifndef IMAGENETWORKACCESSMANAGER_H
+#define IMAGENETWORKACCESSMANAGER_H
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtDeclarative/QDeclarativeNetworkAccessManagerFactory>
+
+class ImageNetworkAccessManager : public QNetworkAccessManager
+{
+ Q_OBJECT
+public:
+ explicit ImageNetworkAccessManager(QObject *parent = 0);
+
+protected:
+ QNetworkReply * createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData);
+};
+
+class ImageNetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
+{
+public:
+ QNetworkAccessManager * create(QObject *parent);
+};
+
+#endif // IMAGENETWORKACCESSMANAGER_H
diff --git a/imageprovider.cpp b/imageprovider.cpp
deleted file mode 100644
index 6fb2807..0000000
--- a/imageprovider.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <QtCore/QCryptographicHash>
-#include <QtCore/QDir>
-#include <QtCore/QEventLoop>
-#include <QtCore/QUrl>
-#include <QtCore/QDebug>
-#include <QtNetwork/QNetworkRequest>
-#include <QtNetwork/QNetworkReply>
-
-#include "global.h"
-#include "imageprovider.h"
-
-// Warning: QML might call requestImage() from another thread. Be careful.
-
-ImageProvider::ImageProvider() :
- QDeclarativeImageProvider(Image),
- _cachePath(board_manager->getCachePath() + "/images"),
- _manager(new QNetworkAccessManager)
-{
- QDir dir;
- if (!dir.mkpath(_cachePath)) {
- qWarning() << "Could not create image cache path";
- }
-}
-
-ImageProvider::~ImageProvider()
-{
- delete _manager;
-}
-
-QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
-{
- QString remoteUrl = QUrl::fromPercentEncoding(id.toUtf8());
- QString localPath = getCachedImagePath(remoteUrl);
-
- qDebug() << "Loading image for " << remoteUrl;
-
- if (!QFile::exists(localPath)) {
- if (!fetchImage(remoteUrl)) {
- qWarning() << "Failed to fetch remote image" << remoteUrl;
- }
- } else {
- qDebug() << "Local file exists" << localPath;
- }
-
- QImage image(localPath);
- QImage result;
-
- if (image.isNull()) {
- qWarning() << "Failed to load local image" << localPath;
- }
-
- if (requestedSize.isValid()) {
- result = image.scaled(requestedSize, Qt::KeepAspectRatio);
- } else {
- result = image;
- }
- if (size) {
- *size = result.size();
- }
-
- return result;
-}
-
-QString ImageProvider::getProviderImageUrl(const QString &remoteUrl)
-{
- return "image://tapasboard/" + QString::fromUtf8(QUrl::toPercentEncoding(remoteUrl));
-}
-
-QString ImageProvider::getCachedImagePath(const QString &remoteUrl)
-{
- static const QRegExp regexp("[^a-z0-9]+");
- QString url = remoteUrl.toLower();
-
- // Grab the extension before applying the regexp
- QString extension;
- int dot_pos = url.lastIndexOf('.');
-
- if (dot_pos != -1) {
- extension = url.mid(dot_pos);
- }
-
- url.replace(regexp, "_");
-
- return _cachePath + "/" + url + extension;
-}
-
-bool ImageProvider::fetchImage(const QString &remoteUrl)
-{
- QString localPath = getCachedImagePath(remoteUrl);
-
- QNetworkRequest request(remoteUrl);
- QNetworkReply *reply = _manager->get(request);
- qDebug() << "Start download of" << remoteUrl;
-
- QEventLoop loop;
- loop.connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
-
- loop.exec();
-
- qDebug() << "End download of" << remoteUrl;
- QFile localFile(localPath);
- if (localFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- localFile.write(reply->readAll());
- localFile.close();
- }
-
- reply->deleteLater();
-
- return true;
-}
diff --git a/imageprovider.h b/imageprovider.h
deleted file mode 100644
index 43c8b28..0000000
--- a/imageprovider.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef IMAGEPROVIDER_H
-#define IMAGEPROVIDER_H
-
-#include <QtNetwork/QNetworkAccessManager>
-#include <QtDeclarative/QDeclarativeImageProvider>
-
-class ImageProvider : public QDeclarativeImageProvider
-{
-public:
- ImageProvider();
- ~ImageProvider();
-
- QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize = QSize());
-
- QString getProviderImageUrl(const QString &remoteUrl);
- QString getCachedImagePath(const QString &remoteUrl);
-
- bool fetchImage(const QString &remoteUrl);
-
-private:
- QString _cachePath;
- QNetworkAccessManager *_manager;
-};
-
-#endif // IMAGEPROVIDER_H
diff --git a/main.cpp b/main.cpp
index 3c8f813..52086e4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,17 +1,17 @@
#include <QtGui/QApplication>
+#include <QtNetwork/QNetworkAccessManager>
#include <QtDeclarative/QtDeclarative>
#include "qmlapplicationviewer.h"
#include "global.h"
#include "board.h"
-#include "imageprovider.h"
+#include "imagenetworkaccessmanager.h"
#include "favoritesmodel.h"
#include "boardmodel.h"
#include "forummodel.h"
#include "topicmodel.h"
BoardManager *board_manager;
-ImageProvider *image_provider;
Q_DECL_EXPORT int main(int argc, char *argv[])
{
@@ -23,8 +23,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
QScopedPointer<BoardManager> manager(new BoardManager);
board_manager = manager.data(); // Set the global pointer to this singleton
- QScopedPointer<ImageProvider> provider(new ImageProvider);
- image_provider = provider.data();
+ QScopedPointer<ImageNetworkAccessManagerFactory> image_nam_factory(new ImageNetworkAccessManagerFactory);
qmlRegisterType<FavoritesModel>("com.javispedro.tapasboard", 1, 0, "FavoritesModel");
qmlRegisterType<BoardModel>("com.javispedro.tapasboard", 1, 0, "BoardModel");
@@ -32,7 +31,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qmlRegisterType<TopicModel>("com.javispedro.tapasboard", 1, 0, "TopicModel");
QmlApplicationViewer viewer;
- viewer.engine()->addImageProvider("tapasboard", image_provider);
+ viewer.engine()->setNetworkAccessManagerFactory(image_nam_factory.data());
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tapasboard/main.qml"));
viewer.showExpanded();
diff --git a/tapasboard.pro b/tapasboard.pro
index a13dfc7..a1173d5 100644
--- a/tapasboard.pro
+++ b/tapasboard.pro
@@ -46,7 +46,8 @@ SOURCES += main.cpp \
topicmodel.cpp \
fetchpostsaction.cpp \
favoritesmodel.cpp \
- imageprovider.cpp
+ imagecache.cpp \
+ imagenetworkaccessmanager.cpp
# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
@@ -77,4 +78,5 @@ HEADERS += \
topicmodel.h \
fetchpostsaction.h \
favoritesmodel.h \
- imageprovider.h
+ imagecache.h \
+ imagenetworkaccessmanager.h