Merge branch 'laitiju' into map
authorSami Rämö <sami.ramo@ixonos.com>
Thu, 1 Apr 2010 10:57:12 +0000 (13:57 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Thu, 1 Apr 2010 10:57:12 +0000 (13:57 +0300)
Conflicts:
src/map/mapengine.cpp
src/map/mapengine.h
src/src.pro
tests/testmap/testmapscene/testmapscene.pro
tests/testmap/testmaptile/testmaptile.pro
tests/testmap/testmapview/testmapview.cpp
tests/testmap/testmapview/testmapview.pro

16 files changed:
src/main.cpp
src/map/mapengine.cpp
src/map/mapengine.h
src/map/mapfetcher.cpp [new file with mode: 0644]
src/map/mapfetcher.h [new file with mode: 0644]
src/map/mapfetcherqueue.cpp [new file with mode: 0644]
src/map/mapfetcherqueue.h [new file with mode: 0644]
src/src.pro
src/ui/mainwindow.cpp
src/ui/mainwindow.h
tests/testmap/testmapfetcher/networkaccessmanagermock.cpp [new file with mode: 0644]
tests/testmap/testmapfetcher/networkaccessmanagermock.h [new file with mode: 0644]
tests/testmap/testmapfetcher/networkreplymock.cpp [new file with mode: 0644]
tests/testmap/testmapfetcher/networkreplymock.h [new file with mode: 0644]
tests/testmap/testmapfetcher/testmapfetcher.cpp [new file with mode: 0644]
tests/testmap/testmapfetcher/testmapfetcher.pro [new file with mode: 0644]

index b5978ac..92e7e87 100644 (file)
@@ -19,9 +19,9 @@
     USA.
  */
 
-
 #include <QtGui/QApplication>
 #include "ui/mainwindow.h"
+#include "mapfetcherqueue.h"
 
 int main(int argc, char *argv[])
 {
index 3f68907..5c57fdd 100644 (file)
@@ -3,6 +3,7 @@
    Copyright (C) 2010  Ixonos Plc. Authors:
 
        Sami Rämö - sami.ramo@ixonos.com
+       Jussi Laitinen - jussi.laitinen@ixonos.com
 
    Situare is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -28,6 +29,9 @@
 #include "maptile.h"
 //#include "mapscene.h"
 
+#include <QtCore>
+#include <QtGlobal>
+
 MapEngine::MapEngine(MapView *mapView, QWidget *parent)
     : QObject(parent)
 {
@@ -70,3 +74,32 @@ void MapEngine::mapImageReceived(const QUrl *url, const QPixmap *pixmap)
 //    mapTile->setPixmap();
 //    m_mapScene->addMapTile(mapTile);
 }
+
+QPoint MapEngine::latLonToTile(qreal latitude, qreal longitude, int zoom)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    qreal z = static_cast<qreal>(1 << zoom);
+
+    qreal x = static_cast<qreal>((longitude + 180.0) / 360.0);
+    qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
+                                / cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
+
+    return QPoint(qFloor(x*z), qFloor(y*z));
+}
+
+qreal MapEngine::tileXToLongitude(int x, int zoom)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    qreal z = static_cast<qreal>(1 << zoom);
+    qreal lon = x / z * 360.0 - 180.0;
+    qDebug() << lon;
+    return lon;
+}
+
+qreal MapEngine::tileYToLatitude(int y, int zoom)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    qreal z = static_cast<qreal>(1 << zoom);
+    qreal n = M_PI - 2 * M_PI * y / zoom;
+    return 180.0 / (M_PI * atan(0.5 * exp(n) - exp(-n)));
+}
index 54acd78..5bffa13 100644 (file)
@@ -3,6 +3,7 @@
    Copyright (C) 2010  Ixonos Plc. Authors:
 
        Sami Rämö - sami.ramo@ixonos.com
+       Jussi Laitinen - jussi.laitinen@ixonos.com
 
    Situare is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    USA.
 */
 
-
-
 #ifndef MAPENGINE_H
 #define MAPENGINE_H
 
 #include <math.h>
 
+#include <QtCore>
+
 #include "mapview.h"
 #include "mapscene.h"
 
@@ -64,6 +65,28 @@ public:
     /// \param latLonCoordinate Latitude & longitude coordinates for location
     void setViewLocation(QPointF latLonCoordinate);
 
+    QPoint latLonToTile(qreal latitude, qreal longitude, int zoom);
+
+    /**
+    * @brief Transforms tile x value to longitude.
+    *
+    * @fn tileXToLongitude
+    * @param x tile x value
+    * @param zoom zoom value
+    * @return qreal longitude
+    */
+    qreal tileXToLongitude(int x, int zoom);
+
+    /**
+    * @brief Transforms tile y value to latitude.
+    *
+    * @fn tileYToLatitude
+    * @param y tile y value
+    * @param zoom zoom value
+    * @return qreal latitude
+    */
+    qreal tileYToLatitude(int y, int zoom);
+
 private slots:
     void mapImageReceived(const QUrl *url, const QPixmap *pixmap);
 
diff --git a/src/map/mapfetcher.cpp b/src/map/mapfetcher.cpp
new file mode 100644 (file)
index 0000000..807b2fa
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QDebug>
+#include <QPixmap>
+#include <QNetworkDiskCache>
+#include <QDesktopServices>
+
+#include "mapfetcher.h"
+
+static int MAX_PARALLEL_DOWNLOADS = 2;
+
+MapFetcher::MapFetcher(QObject *parent, QNetworkAccessManager *manager)
+    : QObject(parent), m_manager(manager)
+{
+    QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
+
+    diskCache->setCacheDirectory(QDesktopServices::storageLocation(
+            QDesktopServices::CacheLocation));
+
+    m_manager->setCache(diskCache);
+
+    connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
+}
+
+void MapFetcher::fetchMapImage(const QUrl &url)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (url.isEmpty() || !url.isValid())
+        return;
+
+    if (downloadQueue.length() < MAX_PARALLEL_DOWNLOADS)
+        QTimer::singleShot(0, this, SLOT(startNextDownload()));
+
+    downloadQueue.enqueue(url);
+}
+
+void MapFetcher::startNextDownload()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (downloadQueue.isEmpty())
+        return;
+
+    QUrl url = downloadQueue.dequeue();
+    QNetworkRequest request(url);
+    request.setRawHeader("User-Agent", "Map Test");
+    request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+                                              QNetworkRequest::PreferCache);
+
+    QNetworkReply *reply = m_manager->get(request);
+    currentDownloads.append(reply);
+}
+
+void MapFetcher::downloadFinished(QNetworkReply *reply)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    if (reply->error() == QNetworkReply::NoError) {
+        QImage image;
+        QUrl url = reply->url();
+
+        if (!image.load(reply, 0))
+            image = QImage();
+
+        emit mapImageReceived(url, QPixmap::fromImage(image));
+    }
+    else {
+        emit error(reply->errorString());
+    }
+
+    currentDownloads.removeAll(reply);
+    reply->deleteLater();
+    startNextDownload();
+}
+
+MapFetcher::~MapFetcher()
+{
+
+}
diff --git a/src/map/mapfetcher.h b/src/map/mapfetcher.h
new file mode 100644 (file)
index 0000000..9aab8d8
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#ifndef MAPFETCHER_H
+#define MAPFETCHER_H
+
+#include <QtCore>
+#include <QNetworkAccessManager>
+
+#include "mapfetcher.h"
+
+class QNetworkReply;
+class QUrl;
+
+/**
+* @brief MapFetcher handles requests to get map tiles.
+*
+*
+*
+* @class MapFetcher mapfetcher.h "map/mapfetcher.h"
+*/
+class MapFetcher : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+    * @brief Constructor for MapFetcher.
+    *
+    * @fn MapFetcher
+    * @param parent parent object
+    */
+    MapFetcher(QObject *parent = 0, QNetworkAccessManager *manager = 0);
+
+    ~MapFetcher();
+
+    /**
+    * @brief Fetch image from given URL.
+    *
+    * @fn fetchMapImage
+    * @param url URL to image
+    */
+    void fetchMapImage(const QUrl &url);
+
+signals:    
+    /**
+    * @brief Signal which is emitted when a map tile
+    * is received from the server and loaded to pixmap.
+    *
+    * @fn mapImageReceived
+    * @param url URL to image
+    * @param image image pixmap
+    */
+    void mapImageReceived(const QUrl &url, const QPixmap &image);
+
+    /**
+    * @brief Signal which is emitted when there is error
+    * in network reply.
+    *
+    * @fn error
+    * @param message error message
+    */
+    void error(const QString &message);
+
+public slots:
+
+    /**
+    * @brief This slot is called when network manager has finished
+    * the download.
+    *
+    * @fn downloadFinished
+    * @param reply
+    */
+    void downloadFinished(QNetworkReply *reply);
+
+    /**
+    * @brief This slot is called when next download is started.
+    *
+    * @fn startNextDownload
+    */
+    void startNextDownload();
+
+private:
+
+    QNetworkAccessManager *m_manager;
+    QList<QNetworkReply*> currentDownloads;
+    QQueue<QUrl> downloadQueue;
+};
+
+#endif
diff --git a/src/map/mapfetcherqueue.cpp b/src/map/mapfetcherqueue.cpp
new file mode 100644 (file)
index 0000000..180ce05
--- /dev/null
@@ -0,0 +1,105 @@
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QDebug>
+#include <QPixmap>
+#include <QNetworkDiskCache>
+#include <QDesktopServices>
+#include <QTimer>
+#include <QMutex>
+
+#include "mapfetcherqueue.h"
+
+static int MAX_QUEUE = 10;
+
+MapFetcherQueue::MapFetcherQueue(QObject *parent)
+    : QObject(parent)
+    , downloadCount(0)
+{
+    QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
+    diskCache->setCacheDirectory(QDesktopServices::storageLocation(
+            QDesktopServices::CacheLocation));
+    m_manager.setCache(diskCache);
+}
+
+void MapFetcherQueue::fetchMapImage(const QUrl &url)
+{
+    if (url.isEmpty())
+        return;
+
+    if (downloadQueue.isEmpty())
+        QTimer::singleShot(0, this, SLOT(startNextDownload()));
+
+    if (downloadQueue.length() >= MAX_QUEUE) {
+            qDebug() << "removed from queue";
+            deleteCurrent();
+            downloadQueue.dequeue();
+        }
+
+    downloadQueue.enqueue(url);
+    qDebug() << "fetchMapImage() " << url.path();
+}
+
+void MapFetcherQueue::startNextDownload()
+{
+    if (downloadQueue.isEmpty())
+        return;
+
+    QUrl url = downloadQueue.dequeue();
+
+    QNetworkRequest request(url);
+    request.setRawHeader("User-Agent", "Map Test");
+    request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+                                              QNetworkRequest::PreferCache);
+
+    currentDownload = m_manager.get(request);
+    connect(currentDownload, SIGNAL(finished()), this, SLOT(downloadFinished()));
+    connect(currentDownload, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
+    connect(currentDownload, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkError()));
+}
+
+void MapFetcherQueue::downloadFinished()
+{
+    static int counter = 0;
+    qDebug() << "downloadFinished(): " << counter++;
+
+    deleteCurrent();
+    startNextDownload();
+}
+
+void MapFetcherQueue::deleteCurrent()
+{
+    mutex.lock();
+    if (currentDownload != NULL)
+        currentDownload->deleteLater();
+    mutex.unlock();
+}
+
+void MapFetcherQueue::downloadReadyRead()
+{
+    qDebug() << "downloadReadyRead()" << currentDownload->url().path();
+
+    if (currentDownload->error()) {
+        qDebug() << "ERROR";
+        emit error(currentDownload->errorString());
+    }
+    else {
+        QImage image;
+        QUrl url = currentDownload->url();
+        if (!image.load(currentDownload, 0))
+            image = QImage();
+
+        emit mapImageReceived(url, QPixmap::fromImage(image));
+    }
+}
+
+void MapFetcherQueue::networkError()
+{
+    emit error(currentDownload->errorString());
+}
+
+MapFetcherQueue::~MapFetcherQueue()
+{
+
+}
diff --git a/src/map/mapfetcherqueue.h b/src/map/mapfetcherqueue.h
new file mode 100644 (file)
index 0000000..9b33d65
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef MAPFETCHERQUEUE_H
+#define MAPFETCHERQUEUE_H
+
+#include <QtCore>
+#include <QNetworkAccessManager>
+
+class QNetworkReply;
+class QUrl;
+class QMutex;
+
+#include "mapfetcher.h"
+
+/**
+* @brief MapFetcher handles requests to get map tiles.
+*
+*
+*
+* @class MapFetcher mapfetcher.h "map/mapfetcher.h"
+*/
+class MapFetcherQueue : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+    * @brief Constructor for MapFetcher.
+    *
+    * @fn MapFetcher
+    * @param parent parent object
+    */
+    MapFetcherQueue(QObject *parent = 0);
+
+    ~MapFetcherQueue();
+
+    /**
+    * @brief Fetch image from given URL.
+    *
+    * @fn fetchMapImage
+    * @param url URL to image
+    */
+    void fetchMapImage(const QUrl &url);
+
+    void deleteCurrent();
+
+signals:
+    /**
+    * @brief Signal which is emitted when a map tile
+    * is received from the server and loaded to pixmap.
+    *
+    * @fn mapImageReceived
+    * @param url URL to image
+    * @param image image pixmap
+    */
+    void mapImageReceived(const QUrl &url, const QPixmap &image);
+
+    /**
+    * @brief Signal which is emitted when there is error
+    * in network reply.
+    *
+    * @fn error
+    * @param message error message
+    */
+    void error(const QString &message);
+
+private slots:
+    /**
+    * @brief This slot is called when network manager has finished
+    * the download.
+    *
+    * @fn downloadFinished
+    * @param reply
+    */
+    void downloadFinished();
+
+    void startNextDownload();
+    void downloadReadyRead();
+    void networkError();
+
+
+private:
+    QNetworkAccessManager m_manager;
+    QQueue<QUrl> downloadQueue;
+    QNetworkReply *currentDownload;
+    QTime downloadTime;
+    QMutex mutex;
+
+    int downloadCount;
+};
+
+#endif
index 37136c4..b782baf 100644 (file)
@@ -10,7 +10,8 @@ SOURCES += main.cpp \
     map/mapengine.cpp \
     map/mapview.cpp \
     map/mapscene.cpp \
-    map/maptile.cpp
+    map/maptile.cpp \
+    map/mapfetcher.cpp
 
 HEADERS += ui/mainwindow.h \
     ui/mapviewscreen.h \
@@ -18,7 +19,8 @@ HEADERS += ui/mainwindow.h \
     map/mapengine.h \
     map/mapview.h \
     map/mapscene.h \
-    map/maptile.h
+    map/maptile.h \
+    map/mapfetcher.h
 
 
 # -----------------------------------------------------------------
index 91ef5a3..e69de29 100644 (file)
@@ -1,112 +0,0 @@
-/*
-   Situare - A location system for Facebook
-   Copyright (C) 2010  Ixonos Plc. Authors:
-
-      Henri Lampela - henri.lampela@ixonos.com
-      Kaj Wallin - kaj.wallin@ixonos.com
-
-   Situare is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as published by the Free Software Foundation.
-
-   Situare 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 Situare; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-   USA.
-*/
-
-#include <QtGui>
-#include "mainwindow.h"
-#include "listviewscreen.h"
-#include "mapviewscreen.h"
-
-MainWindow::MainWindow(QWidget *parent)
-    : QMainWindow(parent)
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    QWidget *widget = new QWidget;
-    setCentralWidget(widget);
-    createViews();
-    QVBoxLayout *mainLayout = new QVBoxLayout;
-    infoLabel = new QLabel(tr("Click \"view\", to change between views"),this);
-    infoLabel->setAttribute(Qt::WA_TranslucentBackground, true);
-    mainLayout->addWidget(infoLabel);
-    mainLayout->addWidget(situareViews);
-    widget->setLayout(mainLayout);
-    createMenus();
-
-    setWindowTitle(tr("View"));
-}
-
-MainWindow::~MainWindow()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    delete toListViewAct;
-    delete toMapViewAct;
-    delete situareViews;
-    delete infoLabel;
-}
-
-void MainWindow::createMenus()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    toListViewAct = new QAction(tr("List"), this);
-    connect(toListViewAct, SIGNAL(triggered()), this, SLOT(toListView()));
-    toMapViewAct = new QAction(tr("Map"), this);
-    connect(toMapViewAct, SIGNAL(triggered()), this, SLOT(toMapView()));
-    viewMenu = menuBar()->addMenu(tr("View"));
-    viewMenu->addAction(toListViewAct);
-    viewMenu->addAction(toMapViewAct);
-}
-
-void MainWindow::createViews()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    situareViews = new QStackedWidget;
-    situareViews->addWidget(new ListViewScreen);
-    situareViews->addWidget(new MapViewScreen);
-}
-
-void MainWindow::toListView()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    switchView(0);
-}
-
-void MainWindow::toMapView()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-    switchView(1);
-}
-
-void MainWindow::switchView(int nextIndex)
-{
-    qDebug() << __PRETTY_FUNCTION__ << ":" << nextIndex;
-    if (nextIndex < 0 || nextIndex > 1) {
-        qDebug() << tr("Illegal parameter value in MainWindow::switchView");
-        return;
-    }
-    situareViews->setCurrentIndex(nextIndex);
-    infoLabel->setText(tr("Current: %1").arg(situareViews->currentIndex()));
-    switch (situareViews->currentIndex()) {
-        case 0:
-            setWindowTitle(tr("List"));
-            break;
-        case 1:
-            setWindowTitle(tr("Map"));
-            break;
-        default:
-            qDebug() << tr("Illegal switch value in MainWindow::switchView");
-            break;
-    }
-}
-
-int MainWindow::getViewIndex()
-{
-    return situareViews->currentIndex();
-}
index 7651280..e69de29 100644 (file)
@@ -1,121 +0,0 @@
-/*
-   Situare - A location system for Facebook
-   Copyright (C) 2010  Ixonos Plc. Authors:
-
-      Henri Lampela - henri.lampela@ixonos.com
-      Kaj Wallin - kaj.wallin@ixonos.com
-
-   Situare is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as published by the Free Software Foundation.
-
-   Situare 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 Situare; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-   USA.
-*/
-
-
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include <QtGui/QMainWindow>
-#include <QWidget>
-#include <QDebug>
-
-class QLabel;
-class QStackedWidget;
-
-/**
-* @Main Window Class
-*
-* @class MainWindow mainwindow.h "src/ui/mainwindow.h"
-*/
-class MainWindow : public QMainWindow
-{
-    Q_OBJECT
-
-public:
-    MainWindow(QWidget *parent = 0);
-    ~MainWindow();
-
-    /**
-    * @brief Public method to get current index of the view. Used for Unit testing
-    *
-    * @fn getViewIndex
-    */
-    int getViewIndex();
-
-private:
-    /**
-    * @brief Private method to create List and Map views as a stacked widget
-    *
-    * @fn createViews
-    */
-    void createViews();
-    /**
-    * @brief Widget Stack object for the List and Map Views
-    *
-    * @var situareViews
-    */
-    QStackedWidget *situareViews;
-
-    /**
-    * @brief Private method to create the Menu items
-    *
-    * @fn createMenus
-    */
-    void createMenus();
-    QMenu *viewMenu;
-
-    /**
-    * @brief Action item for changing view to List View
-    *
-    * @var toListViewAct
-    */
-    QAction *toListViewAct;
-    /**
-    * @brief Action item for changing view to Map View
-    *
-    * @var toMapViewAct
-    */
-    QAction *toMapViewAct;
-
-    /**
-    * @brief Method used to switch active view.
-    *
-    * @fn switchView
-    * @param int 0 for listview, 1 for mapview
-    */
-    void switchView(int);
-
-    /**
-    * @brief DUMMY LABEL, REMOVE WHEN BOTH VIEWS ARE COMPLETE
-    *
-    * @var infoLabel
-    * @todo REMOVE THIS
-    */
-    QLabel *infoLabel;
-
-
-public slots:
-    /**
-    * @brief Public slot, which initiates toListViewAct action to switch view
-    *
-    * @fn toListView
-    */
-    void toListView();
-    /**
-    * @brief Public slot, which initiates toMapViewAct action to switch view
-    *
-    * @fn toMapView
-    */
-    void toMapView();
-};
-
-#endif // MAINWINDOW_H
diff --git a/tests/testmap/testmapfetcher/networkaccessmanagermock.cpp b/tests/testmap/testmapfetcher/networkaccessmanagermock.cpp
new file mode 100644 (file)
index 0000000..0a998c8
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#include <QNetworkAccessManager>
+#include <QDebug>
+#include <QTimer>
+#include <QImage>
+#include <QBuffer>
+#include "networkaccessmanagermock.h"
+#include "networkreplymock.h"
+
+
+
+NetworkAccessManagerMock::NetworkAccessManagerMock(QNetworkAccessManager *manager, QObject *parent)
+    : QNetworkAccessManager(parent)
+    , mode(0)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    setCache(manager->cache());
+    setCookieJar(manager->cookieJar());
+    //setProxy(manager->proxy());
+    setProxyFactory(manager->proxyFactory());
+
+    //connect(this, SIGNAL(error(QNetworkRequest*)), this, SLOT(generateError(QNetworkRequest)));
+}
+
+void NetworkAccessManagerMock::setMode(int mode)
+{
+    this->mode = mode;
+}
+
+void NetworkAccessManagerMock::debug()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+NetworkReplyMock *NetworkAccessManagerMock::get(const QNetworkRequest &request)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    this->request = request;
+    reply = new NetworkReplyMock(this);
+
+    switch (this->mode) {
+
+    case NetworkAccessManagerMock::CORRECT:
+        QTimer::singleShot(0, this, SLOT(generateCorrectReply()));
+        break;
+    case NetworkAccessManagerMock::INCORRECT:
+        QTimer::singleShot(0, this, SLOT(generateError()));
+        break;
+    case NetworkAccessManagerMock::DELAYED_CORRECT:
+        QTimer::singleShot(0, this, SLOT(generateDelayedCorrectReply()));
+        break;
+    case NetworkAccessManagerMock::CORRUPTED_IMAGE:
+        QTimer::singleShot(0, this, SLOT(generateCorruptedImageReply()));
+        break;
+    default:
+        QTimer::singleShot(0, this, SLOT(generateCorrectReply()));
+        break;
+    }
+
+    return reply;
+}
+
+void NetworkAccessManagerMock::generateError()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    reply->setUrl(request.url());
+    reply->setError(QNetworkReply::HostNotFoundError, "Host not found");
+    emit finished(reply);
+}
+
+void NetworkAccessManagerMock::generateCorrectReply()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    reply->setUrl(request.url());
+    QImage image;
+    if (!image.load("res/images/static/testTile.png", 0))
+        image = QImage();
+    else
+        qDebug() << "image loaded";
+
+    QByteArray array;
+    QBuffer buffer(&array);
+    buffer.open(QBuffer::WriteOnly);
+    if (image.save(&buffer, "PNG"))
+        qDebug() << "image saved";
+    buffer.close();
+    reply->setData(array);
+    emit finished(reply);
+}
+
+void NetworkAccessManagerMock::generateDelayedCorrectReply()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    QTimer::singleShot(4000, this, SLOT(generateCorrectReply()));
+}
+
+void NetworkAccessManagerMock::generateCorruptedImageReply()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    reply->setUrl(request.url());
+    QImage image;
+    if (!image.load("res/images/static/testTile.png", 0))
+        image = QImage();
+    else
+        qDebug() << "image loaded";
+
+    QByteArray array;
+    array.append("PNG.?ASDSADSDSADSAD");
+    reply->setData(array);
+    emit finished(reply);
+}
diff --git a/tests/testmap/testmapfetcher/networkaccessmanagermock.h b/tests/testmap/testmapfetcher/networkaccessmanagermock.h
new file mode 100644 (file)
index 0000000..7e3c6ca
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#ifndef NETWORKACCESSMANAGERMOCK_H
+#define NETWORKACCESSMANAGERMOCK_H
+
+#include <QNetworkAccessManager>
+#include "networkreplymock.h"
+
+class NetworkAccessManagerMock : public QNetworkAccessManager
+{
+    Q_OBJECT
+
+public:
+    NetworkAccessManagerMock(QNetworkAccessManager *manager = 0, QObject *parent = 0);
+
+    NetworkReplyMock *get(const QNetworkRequest &request);
+
+    void setMode(int mode);
+
+    void debug();
+
+    enum {CORRECT, INCORRECT, DELAYED_CORRECT, CORRUPTED_IMAGE};
+
+signals:
+    void finished(NetworkReplyMock *reply);
+
+private slots:
+    void generateError();
+    void generateCorrectReply();
+    void generateDelayedCorrectReply();
+    void generateCorruptedImageReply();
+
+private:
+    NetworkReplyMock *reply;
+    QNetworkRequest request;
+    int mode;
+};
+
+#endif // NETWORKACCESSMANAGERMOCK_H
diff --git a/tests/testmap/testmapfetcher/networkreplymock.cpp b/tests/testmap/testmapfetcher/networkreplymock.cpp
new file mode 100644 (file)
index 0000000..26af540
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#include <QNetworkReply>
+#include <QDebug>
+
+#include "networkreplymock.h"
+
+NetworkReplyMock::NetworkReplyMock(QObject *parent)
+    : QNetworkReply(parent)
+    , m_offset(0)
+
+{
+
+}
+
+void NetworkReplyMock::setError(NetworkError errorCode, const QString &errorString)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    QNetworkReply::setError(errorCode, errorString);
+}
+
+
+qint64 NetworkReplyMock::readData(char *data, qint64 maxLen)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    if (m_offset < m_content.size()) {
+        qint64 number = qMin(maxLen, m_content.size() - m_offset);
+        memcpy(data, m_content.constData() + m_offset, number);
+        m_offset += number;
+        return number;
+    }
+    else {
+        return -1;
+    }
+}
+
+QByteArray NetworkReplyMock::readAll()
+{
+    return m_content;
+}
+
+void NetworkReplyMock::setUrl(const QUrl &url)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    QNetworkReply::setUrl(url);
+}
+
+void NetworkReplyMock::abort()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+void NetworkReplyMock::test()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+void NetworkReplyMock::setData(const QByteArray &content)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
+    setHeader(QNetworkRequest::ContentLengthHeader, QVariant(this->m_content.size()));
+    m_content.append(content);
+    qDebug() << "Content size: " << m_content.size();
+}
diff --git a/tests/testmap/testmapfetcher/networkreplymock.h b/tests/testmap/testmapfetcher/networkreplymock.h
new file mode 100644 (file)
index 0000000..54c81ee
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#ifndef NETWORKREPLYMOCK_H
+#define NETWORKREPLYMOCK_H
+
+#include <QNetworkReply>
+#include <QDebug>
+
+class NetworkReplyMock : public QNetworkReply
+{
+    Q_OBJECT
+
+public:
+    NetworkReplyMock(QObject *parent = 0);
+    void abort();
+    qint64 bytesAvailable() const
+    {
+        return m_content.size() - m_offset;
+    }
+    bool isSequential() const
+    {
+        return true;
+    }
+    void setError(NetworkError errorCode, const QString &errorString);
+    void setData(const QByteArray &content);
+    void setUrl(const QUrl &url);
+    void test();
+    QByteArray readAll();
+
+protected:
+    qint64 readData(char *data, qint64 maxlen);
+
+private:
+    QByteArray m_content;
+    qint64 m_offset;
+};
+
+#endif // NETWORKREPLYMOCK_H
diff --git a/tests/testmap/testmapfetcher/testmapfetcher.cpp b/tests/testmap/testmapfetcher/testmapfetcher.cpp
new file mode 100644 (file)
index 0000000..b2008fc
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#include <QtTest/QtTest>
+#include <QUrl>
+#include <QImage>
+#include <QNetworkAccessManager>
+#include <QLabel>
+
+#include "../../../src/map/mapfetcher.h"
+#include "networkaccessmanagermock.h"
+#include "networkreplymock.h"
+
+/**
+* @brief
+*
+* @class TestMapFetcher testmapfetcher.cpp "tests/testMap/testmapfetcher.cpp"
+*/
+class TestMapFetcher : public QObject
+{
+    Q_OBJECT
+public:
+    /**
+    * @brief TestMapFetcher is a test class for MapFetcher class.
+    *
+    * @fn TestMapFetcher
+    */
+    TestMapFetcher();
+
+
+private slots:
+    /**
+    * @brief Tests fetchImage method with empty URL as parameter.
+    *
+    * @fn testFetchImageEmptyURL
+    */
+    void testFetchImageEmptyURL();
+    /**
+    * @brief Tests fetchImage method with incorrect URL as parameter.
+    *
+    * @fn testFetchImageIncorrectURL
+    */
+    void testFetchImageIncorrectURL();
+    /**
+    * @brief Tests fetchImage method with correct URL as parameter.
+    *
+    * @fn testFetchImageCorrectURL
+    */
+    void testFetchImageCorrectURL();
+
+    void testFetchCorruptedImage();
+
+    /**
+    * @brief Tests fetchImage method 20 times with correct URLs
+    * as parameters.
+    *
+    * @fn testFetchImage20URLs
+    */
+    void testFetchImage20URLs();
+    /**
+    * @brief Tests fetchImage method 50 times with correct URLs
+    * as parameters.
+    *
+    * @fn testFetchImage50URLs
+    */
+    void testFetchImage50URLs();
+
+private:
+    MapFetcher *mapFetcher;
+    NetworkAccessManagerMock *managerMock;
+};
+
+TestMapFetcher::TestMapFetcher()
+{
+    QNetworkAccessManager *manager = new QNetworkAccessManager();
+    managerMock = new NetworkAccessManagerMock(manager, this);
+    mapFetcher = new MapFetcher(this, managerMock);
+}
+
+void TestMapFetcher::testFetchImageEmptyURL()
+{
+    QUrl url("");
+    mapFetcher->fetchMapImage(url);
+}
+
+void TestMapFetcher::testFetchImageIncorrectURL()
+{
+    managerMock->setMode(NetworkAccessManagerMock::INCORRECT);
+
+    QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+    QVERIFY(imageReceivedErrorSpy.isValid());
+
+    //Incorrect URL
+    QUrl url1("http://tile.openstreetmap.org/7/63/22.gi");
+    mapFetcher->fetchMapImage(url1);
+    QTest::qWait(1000);
+    QCOMPARE(imageReceivedErrorSpy.count(), 1);
+}
+
+void TestMapFetcher::testFetchImageCorrectURL()
+{
+    managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+    QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+
+    QVERIFY(imageReceivedSpy.isValid());
+
+    //Correct URL
+    QUrl url2("http://tile.openstreetmap.org/7/63/42.png");
+    mapFetcher->fetchMapImage(url2);
+    QTest::qWait(2000);
+    QCOMPARE(imageReceivedSpy.count(), 1);
+    QList<QVariant> signalArgs2 = imageReceivedSpy.takeLast();
+    QCOMPARE(url2, signalArgs2.at(0).toUrl());
+}
+
+void TestMapFetcher::testFetchCorruptedImage()
+{
+    QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+
+    QVERIFY(imageReceivedSpy.isValid());
+
+    //Correct URL
+    QUrl url2("http://tile.openstreetmap.org/7/63/1.png");
+    mapFetcher->fetchMapImage(url2);
+    QTest::qWait(1000);
+    QCOMPARE(imageReceivedSpy.count(), 1);
+    QList<QVariant> signalArgs2 = imageReceivedSpy.takeLast();
+    QCOMPARE(url2, signalArgs2.at(0).toUrl());
+}
+
+void TestMapFetcher::testFetchImage20URLs()
+{
+    managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+    QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+    QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+    QVERIFY(imageReceivedSpy.isValid());
+
+    //20 requests
+    for (int i = 1; i < 3; ++i) {
+        for (int j = 0; j < 10; ++j) {
+            QUrl url(QString("http://tile.openstreetmap.org/18/23/%1%2.png").arg(i).arg(j));
+            mapFetcher->fetchMapImage(url);
+        }
+    }
+    QTest::qWait(2000);
+    int totalCount = imageReceivedSpy.count() + imageReceivedErrorSpy.count();
+    QCOMPARE(totalCount, 20);
+}
+
+void TestMapFetcher::testFetchImage50URLs()
+{
+    managerMock->setMode(NetworkAccessManagerMock::CORRECT);
+
+    QSignalSpy imageReceivedSpy(mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)));
+    QSignalSpy imageReceivedErrorSpy(mapFetcher, SIGNAL(error(QString)));
+
+    QVERIFY(imageReceivedSpy.isValid());
+
+    //50 requests
+    for (int i = 1; i < 6; ++i) {
+        for (int j = 0; j < 10; ++j) {
+            QUrl url(QString("http://tile.openstreetmap.org/18/24/%1%2.png").arg(i).arg(j));
+            mapFetcher->fetchMapImage(url);
+        }
+    }
+
+    QTest::qWait(5000);
+    int totalCount = imageReceivedSpy.count() + imageReceivedErrorSpy.count();
+    QCOMPARE(totalCount, 50);
+}
+
+QTEST_MAIN(TestMapFetcher)
+#include "testmapfetcher.moc"
diff --git a/tests/testmap/testmapfetcher/testmapfetcher.pro b/tests/testmap/testmapfetcher/testmapfetcher.pro
new file mode 100644 (file)
index 0000000..d0044d1
--- /dev/null
@@ -0,0 +1,10 @@
+QT += network testlib
+
+HEADERS += networkreplymock.h \
+    networkaccessmanagermock.h \
+    ../../../src/map/mapfetcher.h
+SOURCES += testmapfetcher.cpp \
+    networkreplymock.cpp \
+    networkreplydummy.cpp \
+    networkaccessmanagermock.cpp \
+    ../../../src/map/mapfetcher.cpp