diff --git a/icons/applications-internet.png b/icons/applications-internet.png new file mode 100644 index 00000000..adc9fd41 Binary files /dev/null and b/icons/applications-internet.png differ diff --git a/src/downloader.cpp b/src/downloader.cpp new file mode 100644 index 00000000..f5f3c636 --- /dev/null +++ b/src/downloader.cpp @@ -0,0 +1,63 @@ +#include +#include +#include "downloader.h" + +#include + + +Downloader::Downloader() +{ + connect(&manager, SIGNAL(finished(QNetworkReply*)), + SLOT(downloadFinished(QNetworkReply*))); +} + +void Downloader::doDownload(const Download &dl) +{ + QUrl url(dl.url()); + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::User, QVariant(dl.file())); + QNetworkReply *reply = manager.get(request); + + currentDownloads.append(reply); +} + +bool Downloader::saveToDisk(const QString &filename, QIODevice *data) +{ + QFile file(filename); + + if (!file.open(QIODevice::WriteOnly)) { + fprintf(stderr, "Could not open %s for writing: %s\n", + qPrintable(filename), qPrintable(file.errorString())); + return false; + } + + file.write(data->readAll()); + file.close(); + + return true; +} + +void Downloader::downloadFinished(QNetworkReply *reply) +{ + QUrl url = reply->url(); + if (reply->error()) { + fprintf(stderr, "Download of %s failed: %s\n", + url.toEncoded().constData(), qPrintable(reply->errorString())); + } else { + QString filename = reply->request().attribute(QNetworkRequest::User) + .toString(); + saveToDisk(filename, reply); + } + + currentDownloads.removeAll(reply); + reply->deleteLater(); + + if (currentDownloads.isEmpty()) + emit finished(); +} + +void Downloader::get(const QList &list) +{ + for (int i = 0; i < list.count(); i++) + doDownload(list.at(i)); +} diff --git a/src/downloader.h b/src/downloader.h new file mode 100644 index 00000000..20479bbe --- /dev/null +++ b/src/downloader.h @@ -0,0 +1,52 @@ +#ifndef DOWNLOADER_H +#define DOWNLOADER_H + +#include +#include +#include +#include +#include + + +class Download +{ +public: + Download(const QString &url, const QString &file) + {_url = url; _file = file;} + const QString& url() const {return _url;} + const QString& file() const {return _file;} + +private: + QString _url; + QString _file; +}; + + +class Downloader : public QObject +{ + Q_OBJECT + +public: + static Downloader& instance() + {static Downloader i; return i;} + void get(const QList &list); + +signals: + void finished(); + +private slots: + void downloadFinished(QNetworkReply *reply); + +private: + Downloader(); + Downloader(Downloader const&); + void operator=(Downloader const&); + + void doDownload(const Download &dl); + bool saveToDisk(const QString &filename, QIODevice *data); + + QNetworkAccessManager manager; + QList currentDownloads; +}; + +#endif // DOWNLOADER_H diff --git a/src/map.cpp b/src/map.cpp new file mode 100644 index 00000000..f76d7031 --- /dev/null +++ b/src/map.cpp @@ -0,0 +1,54 @@ +#include +#include +#include "downloader.h" +#include "ll.h" +#include "map.h" + +#include + +#define TILES_DIR "tiles" + +Map::Map(const QString &name, const QString &url) +{ + _name = name; + _url = url; + + connect(&Downloader::instance(), SIGNAL(finished()), this, + SLOT(emitLoaded())); + + QDir::home().mkpath(QString(TILES_DIR"/%1").arg(_name)); +} + +void Map::emitLoaded() +{ + emit loaded(); +} + +void Map::loadTiles(QList &list) +{ + QList dl; + + for (int i = 0; i < list.size(); ++i) { + Tile &t = list[i]; + QString file = QString("%1/"TILES_DIR"/%2/%3-%4-%5.png") + .arg(QDir::homePath()).arg(_name).arg(t.zoom()).arg(t.xy().rx()) + .arg(t.xy().ry()); + QFileInfo fi(file); + + if (fi.exists()) + t.pixmap().load(file); + else { + t.pixmap() = QPixmap(TILE_SIZE, TILE_SIZE); + t.pixmap().fill(); + + QString url(_url); + url.replace("$z", QString::number(t.zoom())); + url.replace("$x", QString::number(t.xy().x())); + url.replace("$y", QString::number(t.xy().y())); + dl.append(Download(url, file)); + } + } + + if (!dl.empty()) + Downloader::instance().get(dl); +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 00000000..1729b788 --- /dev/null +++ b/src/map.h @@ -0,0 +1,45 @@ +#ifndef MAP_H +#define MAP_H + +#include +#include "downloader.h" + + +class Tile +{ +public: + Tile(const QPoint &xy, int zoom) + {_xy = xy; _zoom = zoom;} + + int zoom() {return _zoom;} + QPoint& xy() {return _xy;} + QPixmap& pixmap() {return _pixmap;} + +private: + int _zoom; + QPoint _xy; + QPixmap _pixmap; +}; + +class Map : public QObject +{ + Q_OBJECT + +signals: + void loaded(); + +public: + Map(const QString &name, const QString &url); + + const QString &name() {return _name;} + void loadTiles(QList &list); + +private slots: + void emitLoaded(); + +private: + QString _name; + QString _url; +}; + +#endif // MAP_H