diff options
-rw-r--r-- | board.cpp | 17 | ||||
-rw-r--r-- | global.h | 2 | ||||
-rw-r--r-- | imagecache.cpp | 16 | ||||
-rw-r--r-- | imagecache.h | 13 | ||||
-rw-r--r-- | imagenetworkaccessmanager.cpp | 23 | ||||
-rw-r--r-- | imagenetworkaccessmanager.h | 23 | ||||
-rw-r--r-- | imageprovider.cpp | 110 | ||||
-rw-r--r-- | imageprovider.h | 25 | ||||
-rw-r--r-- | main.cpp | 9 | ||||
-rw-r--r-- | tapasboard.pro | 6 |
10 files changed, 87 insertions, 157 deletions
@@ -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() @@ -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 @@ -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 |