Initial version
[gpssportsniffer] / windowMap.cpp
1 /****************************************************************************
2 **
3 **  Copyright (C) 2011  Tito Eritja Real <jtitoo@gmail.com>
4 **
5 **  This program is free software: you can redistribute it and/or modify
6 **  it under the terms of the GNU General Public License as published by
7 **  the Free Software Foundation, either version 3 of the License, or
8 **  (at your option) any later version.
9 **
10 **  This program is distributed in the hope that it will be useful,
11 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 **  GNU General Public License for more details.
14 **
15 **  You should have received a copy of the GNU General Public License
16 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 **
18 ****************************************************************************/
19
20 #include "windowMap.h"
21
22 #include <QAction>
23 #include <QMenu>
24 #include <QMenuBar>
25 #include <QCloseEvent>
26 #include <QLineEdit>
27 #include <QAbstractItemView>
28 #include <QAbstractItemModel>
29 #include <QFileDialog>
30 #include <QtNetwork>
31 #include <QMessageBox>
32 #include <QProgressBar>
33
34 //#include "satellitedialog.h"
35
36
37
38 WindowMap::WindowMap(QWidget *parent, Settings* settings_p, Log *log)
39     : QMainWindow(parent),
40       //satelliteInfo(satelliteInfo),
41       //satelliteDialog(0),
42       log(log),pressed(false),snapped(false), settings(settings_p),track(0),trackToSniff(0),network(false),slippyMap(0),
43       //waitingForFix(false),
44       isDisplayInit(false),
45       validPositions(0),invalidPositions(0),mode(Mode_NewActivityMode),possitionPaint(true),nSession(0),location(0){
46
47     track = new Track();
48     trackToSniff = new Track();
49     trackToSimulate = QList<GpsPoint*>();
50     settings->setIsConfigured(false);
51
52     settingsWindow = new SettingsWindow(this,settings,log);
53     settingsWindow->hide();
54
55     loadTracksWindow = new LoadTracksWindow(this,settings,log);
56     loadTracksWindow->hide();
57
58     infoWindow = new ActivityInfo(this,settings,log);
59     infoWindow->hide();
60
61     //log->debug("tracks created");
62     simulateGPS=false;
63
64     autosaveTimer = new QTimer(this);
65     sPossitioningTimer = new QTimer(this);
66     simulatePossitioningTimer = new QTimer(this);
67
68     zoom=DEFAULT_ZOOM;
69
70     zoomInButton = new QToolButton(this);
71     zoomInButton->setIcon(QIcon(":/images/Zoom-In-icon.png"));
72     zoomInButton->adjustSize();
73     //log->debug(QString("width():%1, zoomInButton.width():%2").arg(width()).arg(zoomInButton->width()));
74
75     zoomOutButton = new QToolButton(this);
76     zoomOutButton->setIcon(QIcon(":/images/Zoom-Out-icon.png"));
77     zoomOutButton->adjustSize();
78
79     zoomInButton->hide();
80     zoomOutButton->hide();
81
82     connect(zoomInButton,SIGNAL(clicked()),this,SLOT(onZoomIn()));
83     connect(zoomOutButton,SIGNAL(clicked()),this,SLOT(onZoomOut()));
84
85     connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
86     connect(sPossitioningTimer, SIGNAL(timeout()), this, SLOT(activatePossitionPaint()));
87     connect(simulatePossitioningTimer, SIGNAL(timeout()), this,SLOT(simulatedPossitionUpdated()));
88
89     sPossitioningTimer->setInterval(1000*TIME_SECONDS_POSSITIONING_PAN);
90
91     // menus
92
93     //log->debug("going to create actions");
94
95     loadTrackAction = new QAction(tr("Load track"),this);
96     downloadMapsTrackAction = new QAction(tr("Download maps from track"),this);
97     newActivityAction = new QAction(tr("New activity"),this);
98     simulatedActivityAction = new QAction(tr("Activity simulation"),this);
99     infoAction = new QAction(tr("Activity info"),this);
100     quitAction = new QAction(tr("Quit"), this);
101
102     lapAction = new QAction(tr("New lap"), this);
103     settingsAction = new QAction(tr("Settings"), this);
104     stopAction = new QAction(tr("Stop"), this);
105     startAction = new QAction(tr("Start"), this);
106     startAction->setEnabled(false);
107     tracksAction = new QAction(tr("Load track"), this);
108     //satelliteAction = new QAction(tr("Satellite info."), this);
109     startNetworkAction = new QAction(tr("Start Networking"),this);
110     startNetworkAction->setEnabled(false);
111
112     //log->debug("done, connecting");
113
114     connect(loadTrackAction, SIGNAL(triggered()),SLOT(loadTrack()));
115     connect(downloadMapsTrackAction, SIGNAL(triggered()),SLOT(downloadMapTrack()));
116     connect(newActivityAction, SIGNAL(triggered()),SLOT(newActivityTrack()));
117     connect(simulatedActivityAction, SIGNAL(triggered()), SLOT(newSimulation()));
118     connect(stopAction, SIGNAL(triggered()), SLOT(stopActivity()));
119     connect(startAction, SIGNAL(triggered()), SLOT(startActivity()));
120     connect(quitAction, SIGNAL(triggered()), SLOT(quit()));
121     connect(lapAction, SIGNAL(triggered()), SLOT(lapActivity()));
122     connect(settingsAction, SIGNAL(triggered()), SLOT(configureSettings()));
123     connect(tracksAction, SIGNAL(triggered()), SLOT(tracksActivity()));
124     //connect(satelliteAction, SIGNAL(triggered()), SLOT(satellite()));
125     connect(startNetworkAction,SIGNAL(triggered()), SLOT(networkStart()));
126     connect(infoAction, SIGNAL(triggered()), SLOT(info()));
127
128
129      //log->debug("done!");
130
131      //log->debug("going to show buttons...");
132      //log->debug("done?");
133
134     this->setFixedSize(WIDTH_DEFAULT,HEIGHT_DEFAULT);
135      //parent->window()->setFixedSize(WIDTH_DEFAULT,HEIGHT_DEFAULT);
136     downloadingStatus = new DownloadingStatus(this);
137     downloadingStatus->hide();
138
139
140 }
141
142
143
144 WindowMap::~WindowMap()
145 {
146     //log->debug("windowMap destructor");
147     if(nSession){
148         nSession->close();
149     }
150     //log->debug("session closed");
151     if (location){
152         location->stopUpdates();
153     }
154     //log->debug("location closed");
155
156 }
157
158 void WindowMap::setTrack(QString fileName,QString activity){
159
160     track = new Track(fileName,activity);
161     //log->debug(QString("track created!!!:%1").arg(track->toString()));
162 }
163
164 void WindowMap::setMenuLoadTracks(){
165
166     //log->debug("MenuLoadTracks!!!!");
167
168     menuBar()->clear();
169 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
170
171     menuBar()->addAction(loadTrackAction);
172     menuBar()->addAction(downloadMapsTrackAction);
173     menuBar()->addAction(newActivityAction);
174     menuBar()->addAction(simulatedActivityAction);
175     menuBar()->addAction(startNetworkAction);
176     menuBar()->addAction(infoAction);
177     menuBar()->addAction(quitAction);
178
179 #else
180
181     QMenu *menu = menuBar()->addMenu("&Options");
182     menu->clear();
183     menu->addAction(loadTrackAction);
184     menu->addAction(downloadMapsTrackAction);
185     menu->addAction(newActivityAction);
186     menu->addAction(simulatedActivityAction);
187     menu->addAction(startNetworkAction);
188     menu->addAction(infoAction);
189     menu->addAction(quitAction);
190
191 #endif
192 }
193
194 void WindowMap::setMenuActivity(){
195
196     menuBar()->clear();
197 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
198     menuBar()->addAction(lapAction);
199     menuBar()->addAction(settingsAction);
200     menuBar()->addAction(startAction);
201     menuBar()->addAction(stopAction);
202     menuBar()->addAction(startNetworkAction);
203     menuBar()->addAction(tracksAction);
204     menuBar()->addAction(infoAction);
205     menuBar()->addAction(quitAction);
206
207
208     //menuBar()->addAction(satelliteAction);
209
210 #else
211     QMenu *menu = menuBar()->addMenu("&Options");
212     menu->clear();
213     menu->addAction(lapAction);
214     menu->addAction(settingsAction);
215     menu->addAction(stopAction);
216     menu->addAction(startAction);
217     menu->addAction(tracksAction);
218     menu->addAction(startNetworkAction);
219     //menu->addAction(satelliteAction);
220     menu->addAction(infoAction);
221     menu->addAction(quitAction);
222
223
224 #endif
225 }
226
227 void WindowMap::activatePossitionPaint(){
228     //log->debug("activating possitionPaint");
229     possitionPaint=true;
230     sPossitioningTimer->stop();
231 }
232 void WindowMap::desactivatePossitionPaint(){
233     //log->debug("desactivating possition paint, and starting timer");
234     possitionPaint=false;
235     sPossitioningTimer->start();
236 }
237
238 void WindowMap::clearAllMaps(){
239     if(slippyMap){
240        slippyMap->clearAllMaps();
241     }
242 }
243
244
245 void WindowMap::startServices(){
246
247     startGPS();
248     //log->debug("--- startServices ---");
249     if(settings->getIsOnline()){
250         //log->debug("Is online?" + settings->getIsOnline());
251         //log->debug("going to start networking...");
252         startNetworking();
253
254     }else{
255         //log->debug("going offline");
256         startNetworkAction->setEnabled(true);
257     }
258     startMaps();
259 }
260
261 /*
262 void WindowMap::showSatelliteInfo(){
263
264     if(!satelliteInfo)
265         satelliteInfo = QGeoSatelliteInfoSource::createDefaultSource(this);
266
267     if (satelliteInfo) {
268         SatelliteDialog *dialog = new SatelliteDialog(this,
269                 30,
270                 SatelliteDialog::ExitOnCancel,
271                 SatelliteDialog::OrderByPrnNumber,
272                 SatelliteDialog::ScaleToMaxPossible);
273
274         dialog->connectSources(location, satelliteInfo);
275
276         //location->startUpdates();
277         satelliteInfo->startUpdates();
278
279         dialog->exec();
280
281         //satelliteInfo->stopUpdates();
282
283         delete dialog;
284         //delete satelliteInfo;
285     }
286
287 }
288 */
289
290 /*
291 void WindowMap::waitForFix() {
292     if (waitingForFix)
293         return;
294
295     waitingForFix = true;
296
297     satelliteInfo = QGeoSatelliteInfoSource::createDefaultSource(this);
298
299     if (satelliteInfo) {
300         satelliteDialog = new SatelliteDialog(this,
301                 30,
302                 SatelliteDialog::ExitOnCancel,
303                 SatelliteDialog::OrderByPrnNumber,
304                 SatelliteDialog::ScaleToMaxPossible);
305
306         connect(satelliteDialog,SIGNAL(rejected()),satelliteDialog,SLOT(hide()));
307
308         satelliteDialog->connectSources(location, satelliteInfo);
309
310         satelliteInfo->startUpdates();
311
312         satelliteDialog->exec();
313
314         //satelliteInfo->stopUpdates();
315
316         //delete dialog;
317         //delete satelliteInfo;
318     }
319
320     waitingForFix = false;
321 }
322
323 */
324
325 void WindowMap::stopNetworking(){
326     network=false;
327     if(nSession)
328         nSession->close();
329     if(slippyMap)
330         slippyMap->setNetwork(false);
331 }
332
333 void WindowMap::startNetworking(){
334
335     if(!network && ((mode==Mode_NewActivityMode && settings->getIsOnline()) || (mode==Mode_LoadTracksWindow))){
336
337
338         // Set Internet Access Point
339         QNetworkConfigurationManager manager;
340         const bool canStartIAP = (manager.capabilities()
341                                   & QNetworkConfigurationManager::CanStartAndStopInterfaces);
342
343 #ifdef BEARER_IN_QTNETWORK
344         QNetworkConfiguration cfg = manager.defaultConfiguration();
345         if (!cfg.isValid() || (!canStartIAP && cfg.state() != QNetworkConfiguration::Active)) {
346 #else
347         QTM_PREPEND_NAMESPACE(QNetworkConfiguration) cfg = manager.defaultConfiguration();
348         if (!cfg.isValid() || (!canStartIAP && cfg.state() != QTM_PREPEND_NAMESPACE(QNetworkConfiguration)::Active)) {
349 #endif
350
351             QMessageBox::information(this, tr("Network"), tr(
352                                          "No Access Point found."));
353             network=false;
354             return;
355         }
356
357         nSession = new QNetworkSession(cfg, this);
358         connect(nSession,SIGNAL(error(QNetworkSession::SessionError)),this,SLOT(error(QNetworkSession::SessionError)));
359
360         nSession->open();
361         if(nSession->waitForOpened(-1)){
362             log->info("session connected");
363
364             connect(nSession, SIGNAL(opened()), this, SLOT(networkSessionOpened()));
365             //connect(nSession,SIGNAL(error(QNetworkSession::SessionError)),this,SLOT(error(QNetworkSession::SessionError)));
366
367             network=true;
368             if(slippyMap){
369                 slippyMap->setNetwork(true);
370             }
371         }else{
372             log->err(nSession->errorString());
373             network=false;
374         }
375
376     }
377
378 }
379
380 void WindowMap::networkSessionOpened(){
381
382     //log->debug("--- signal recived of sesson opened ---");
383     network=true;
384     if(slippyMap){
385         //log->debug("invalidating map");
386         slippyMap->setNetwork(true);
387         slippyMap->updateTiles();
388     }
389
390 }
391
392 void WindowMap::error(QNetworkSession::SessionError error)
393 {
394     //log->debug("--- Error in Networking!!! ---");
395     //log->debug(QString("settings is configured?%1").arg(settings->getIsConfigured()));
396
397     if(mode==Mode_NewActivityMode && (!settings->getIsOnline() || !settings->getIsConfigured()))
398         return;
399
400     QMessageBox msgBox(this);
401
402     msgBox.setText(tr("Downloading maps requires network access!."));
403     msgBox.setInformativeText(tr("Try to connect or cancel to disable maps."));
404     msgBox.setIcon(QMessageBox::Information);
405     msgBox.setStandardButtons(QMessageBox::Retry | QMessageBox::Cancel);
406     msgBox.setDefaultButton(QMessageBox::Retry);
407
408     int ret = msgBox.exec();
409     if (ret == QMessageBox::Retry) {
410         QTimer::singleShot(0, nSession, SLOT(open()));
411     } else if (ret == QMessageBox::Cancel) {
412         if(mode==Mode_NewActivityMode){
413
414             settings->setIsOnline(false);
415             //log->debug("enabling startNetworking");
416             startNetworkAction->setEnabled(true);
417             stopNetworking();
418         }
419         //else{
420         //    QTimer::singleShot(60000, nSession, SLOT(open()));
421         //}
422         network=false;
423         if(slippyMap)
424             slippyMap->setNetwork(false);
425     }
426 }
427
428 void WindowMap::startMaps(){
429
430     if(!slippyMap){
431         //log->debug(QString("network:%1").arg(network));
432         slippyMap = new TilesMap(nSession, this, log, zoom,settings->getMapType());
433         connect(slippyMap, SIGNAL(updated(QRect)), SLOT(updateMap(QRect)));
434         slippyMap->setWidth(width());
435         slippyMap->setHeight(height());
436         slippyMap->setNetwork(network);
437         //log->debug(QString("START MAPS!!! slippy.network:%1").arg(slippyMap->network));
438     }
439 }
440 void WindowMap::changeUpdateInterval(int millis){
441
442     if(!simulateGPS)
443         location->setUpdateInterval(millis);
444     else
445         simulatePossitioningTimer->setInterval(millis);
446 }
447
448 void WindowMap::changeMapType(MapType map){
449     slippyMap->setMapType(map);
450 }
451
452 bool WindowMap::checkGPS(){
453
454 //#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
455     location = QGeoPositionInfoSource::createDefaultSource(this);
456
457 //#else
458     //With maemo simulator doesn't work, I've to change this.
459 //    location=0;
460 //#endif
461
462     if (!location) {
463         if(!simulateGPS)
464             QMessageBox::information(this, tr("No GPS detected"),
465                                      tr("No GPS support detected, going to simulate mode"));
466         simulateGPS=true;
467     }
468
469 }
470
471 void WindowMap::startGPS(){
472
473
474    if(location && !simulateGPS){
475         location->setUpdateInterval(settings->getGpsInterval());
476         connect(location,SIGNAL(positionUpdated(QGeoPositionInfo)),this,SLOT(positionUpdated(QGeoPositionInfo)));
477         if(!settings->getIsOnline())
478             location->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
479         location->startUpdates();
480         //waitForFix();
481         //log->debug("setting signal updateTimeout...");
482         //connect(location, SIGNAL(updateTimeout()), this, SLOT(waitForFix()));
483         //log->debug("start positioning...");
484     }
485     startPositioning();
486 }
487
488
489 void WindowMap::positionUpdated(const QGeoPositionInfo &pos){
490
491     //log->info("ACTIVITYMAP-POSSITIONUPDATED!!!");
492     //setCenter(pos.coordinate().latitude(), pos.coordinate().longitude());
493
494     if(pos.isValid() &&
495             pos.attribute(QGeoPositionInfo::HorizontalAccuracy)<=settings->getHorizontalAccuracy() &&
496             pos.attribute(QGeoPositionInfo::VerticalAccuracy)<=settings->getVerticalAccuracy()){
497
498         GpsPoint* point = new GpsPoint(pos.coordinate().latitude(),pos.coordinate().longitude(),pos.coordinate().altitude(),pos.timestamp(),
499                                        pos.attribute(QGeoPositionInfo::GroundSpeed),pos.attribute(QGeoPositionInfo::Direction),
500                                        pos.attribute(QGeoPositionInfo::MagneticVariation),
501                                        pos.attribute(QGeoPositionInfo::HorizontalAccuracy),
502                                        pos.attribute(QGeoPositionInfo::VerticalAccuracy));
503
504
505        // log->debug(point->toString());
506         //log->debug("going to add point...");
507         track->addPoint(point);
508         emit(infoWindow->updateSummary());
509         validPositions++;
510
511         if(possitionPaint)
512             setCenter(point->getLatitude(),point->getLongitude());
513
514         //if(satelliteDialog)
515         //    satelliteDialog->hide();
516
517
518     }else{
519         log->debug("position not updated:");
520
521         log->debug("Horizontal accuracy (meters):" + QString::number(pos.attribute(QGeoPositionInfo::HorizontalAccuracy)));
522         log->debug("Vertical accuracy (meters):" + QString::number(pos.attribute(QGeoPositionInfo::VerticalAccuracy)));
523         invalidPositions++;
524     }
525
526 }
527
528 void WindowMap::simulatedPossitionUpdated(){
529     log->info("simulated possition!!!");
530     //log->info(QString("num points to simulate:%1").arg(trackToSimulate.size()));
531     GpsPoint* point= new GpsPoint(0,0,0);
532
533
534     if(trackToSimulate.size()>0){
535
536         point = trackToSimulate.first();
537
538         log->debug(QString("point to simulate:%1").arg(point->toString()));
539         track->addPoint(point);
540         log->debug("going to emit updateSummary!!!");
541         emit(infoWindow->updateSummary());
542         log->debug("point added to track and updated");
543         //log->debug(QString("track num points:%1").arg(track->getNumPoints()));
544
545         trackToSimulate.removeFirst();
546         validPositions++;
547         //log->info(QString("num points to simulate:%1").arg(trackToSimulate.size()));
548
549         //log->debug(QString("Possition paint???????????%1").arg(possitionPaint));
550         if(possitionPaint)
551             setCenter(point->getLatitude(),point->getLongitude());
552     }
553
554
555
556 }
557
558
559 void WindowMap::setTopLeft(qreal lat, qreal lng){
560
561     //log->debug("----setTopLeft----");
562     QPointF ct = slippyMap->coordinate2tile(lat, lng, zoom);
563
564     qreal tx = ct.x()-static_cast<qreal>(width())/(2.0*static_cast<qreal>(tdim));
565     qreal ty = ct.y()-static_cast<qreal>(height())/(2.0*static_cast<qreal>(tdim));
566     topLeft=QPointF(tx,ty);
567 }
568
569 void WindowMap::setCenter(qreal lat, qreal lng) {
570
571     //log->debug("--- set Center function ---!");
572
573     if (!slippyMap) {
574         log->err("slippyMap not created!");
575         firstLat = lat;
576         firstLong = lng;
577         return;
578     }
579
580     setTopLeft(lat, lng);
581     slippyMap->updateTiles(lat,lng);
582 }
583
584 void WindowMap::updateMap(const QRect &r) {
585     update(r);
586 }
587
588 void WindowMap::closeEvent(QCloseEvent *event){
589
590     //log->debug("---- WindowMap quit, going to show parent and hide this ----");
591     //log->debug(QString("mode:==Mode_NewActivityMode?:%1, mode:%2").arg(mode==Mode_NewActivityMode).arg(mode));
592     if(mode==Mode_NewActivityMode && !simulateGPS){
593         QMessageBox msgBox(this);
594
595         msgBox.setText(tr("Do you want to close activity?, it will be saved."));
596         msgBox.setInformativeText(tr("Closing Activity"));
597         msgBox.setIcon(QMessageBox::Information);
598         msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
599         msgBox.setDefaultButton(QMessageBox::Cancel);
600         int ret = msgBox.exec();
601
602         if (ret == QMessageBox::Cancel){
603             event->ignore();
604         }else{
605             disconnect(nSession,SIGNAL(error(QNetworkSession::SessionError)),this,SLOT(error(QNetworkSession::SessionError)));
606             stopPositioning();
607             autosave();
608             settings->setIsConfigured(false);
609
610             this->parentWidget()->showFullScreen();
611             //this->hide();
612
613         }
614     }else{
615
616         if(mode==Mode_NewActivityMode && simulateGPS){
617             settings->setIsConfigured(false);
618             //log->debug("exit from simulating GPS");
619             //log->debug("setting isconfigured to false and stopping timer");
620             simulatePossitioningTimer->stop();
621             simulateGPS=false;
622         }
623
624         this->parentWidget()->showFullScreen();
625         //this->hide();
626         //log->debug("done");
627     }
628 }
629
630 void WindowMap::chooseDisplay(){
631
632     if(mode==Mode_NewActivityMode && !settings->getIsConfigured()){
633         checkGPS();
634         settingsWindow->show();
635         //setWindowTitle(settings->getActivity());
636     }else if(mode==Mode_LoadTracksWindow && !settings->getIsConfigured()){
637         setWindowTitle(QString("Load Tracks ->").append(trackToSniff->getName()));
638         loadTracksWindow->show();
639     }
640 }
641
642  void WindowMap::showEvent(QShowEvent *){
643      chooseDisplay();
644  }
645
646  void WindowMap::networkStart(){
647      startNetworkAction->setEnabled(false);
648      QTimer::singleShot(0, nSession, SLOT(open()));
649  }
650
651  void WindowMap::configureSettings(){
652     settingsWindow->show();
653  }
654
655  void WindowMap::tracksActivity(){
656      //mode=Mode_LoadTracksWindow;
657      possitionPaint=false;
658      //setMenuLoadTracks();
659      loadTracksWindow->show();
660  }
661
662  void WindowMap::loadTrack(){
663      loadTracksWindow->show();
664  }
665  void WindowMap::downloadMapTrack(){
666
667
668      if(slippyMap){
669         qreal lat = slippyMap->getLatitude();
670         qreal lng = slippyMap->getLongitude();
671         tilesToDownload=0;
672         startNetworking();
673
674         downloadingStatus->show();
675
676         //downloadingStatus->move(pos);
677         QProgressBar* pb = downloadingStatus->getProgressBar();
678         int numPoints = trackToSniff->getNumPoints();
679         int zoomsToDown = (MAX_ZOOM_DOWNL - slippyMap->getZoom());
680         if(zoomsToDown>=0){
681             pb->setRange(0,numPoints*zoomsToDown);
682         }
683         pb->setValue(0);
684         downloadingStatus->setText(QString(tr("Making map requests")));
685
686         connect(slippyMap,SIGNAL(pointsRequested(int)),pb,SLOT(setValue(int)));
687         tilesToDownload = slippyMap->downloadMaps(trackToSniff);
688         disconnect(slippyMap,SIGNAL(pointsRequested(int)),pb,SLOT(setValue(int)));
689
690         if(tilesToDownload>0){
691             downloadingStatus->setText(QString(tr("Getting map tiles")));
692             pb->setRange(0,tilesToDownload);
693             pb->setValue(0);
694             connect(slippyMap,SIGNAL(tilesDownloaded(int)),this,SLOT(updateProgress(int)));
695         }else{
696             downloadingStatus->hide();
697         }
698
699         slippyMap->updateTiles(lat,lng);
700      }
701  }
702
703  void WindowMap::updateProgress(int val){
704
705      downloadingStatus->getProgressBar()->setValue(val);
706      if(val==tilesToDownload){
707          downloadingStatus->hide();
708      }
709  }
710  void WindowMap::newActivityTrack(){
711      mode=Mode_NewActivityMode;
712      settings->setIsConfigured(false);
713      setMenuActivity();
714      chooseDisplay();
715  }
716
717  void WindowMap::newSimulation(){
718      mode=Mode_NewActivityMode;
719      simulateGPS=true;
720      settings->setIsConfigured(false);
721      setMenuActivity();
722      chooseDisplay();
723  }
724
725  void WindowMap::info(){
726     infoWindow->show();
727  }
728
729  void WindowMap::startActivity(){
730
731      stopAction->setEnabled(true);
732      startAction->setEnabled(false);
733      startPositioning();
734      //log->debug("stopStart enabled");
735 }
736 void WindowMap::stopActivity(){
737
738     stopAction->setEnabled(false);
739     startAction->setEnabled(true);
740
741     stopPositioning();
742
743 }
744
745 /*
746 void WindowMap::settings(){
747     settingsWindow->show();
748 }
749 */
750
751 void WindowMap::lapActivity(){
752     if(track)
753         track->addLap();
754 }
755
756 void WindowMap::quit(){
757     QCloseEvent *event = new QCloseEvent();
758     emit closeEvent(event);
759 }
760 /*
761 void WindowMap::tracks(){
762
763 }
764 */
765
766 /*
767 void WindowMap::satellite(){
768
769 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
770     showSatelliteInfo();
771 #endif
772 }
773 */
774
775 void WindowMap::stopPositioning() {
776    if(simulateGPS){
777     simulatePossitioningTimer->stop();
778    }else{
779     if (location)
780         location->stopUpdates();
781    }
782 }
783
784 void WindowMap::startPositioning() {
785     if(simulateGPS){
786         simulatePossitioningTimer->start();
787     }else{
788         if (location)
789             location->startUpdates();
790     }
791 }
792
793 void WindowMap::onZoomOut(){
794
795     int minzoom=0;
796     if(settings->getMapType()==MapTypeICC)
797         minzoom=MIN_ICC_ZOOM;
798
799     if (zoom > minzoom) {
800         --(zoom);
801         zoomOutButton->setEnabled(zoom > minzoom);
802         zoomInButton->setEnabled(true);
803
804         if (!slippyMap)
805             return;
806         slippyMap->setZoom(zoom);
807
808         setTopLeft(slippyMap->getLatitude(), slippyMap->getLongitude());
809         slippyMap->updateTiles();
810     }
811
812 }
813
814 void WindowMap::onZoomIn(){
815     if (zoom < MAX_ZOOM - 1) {
816         ++(zoom);
817         zoomInButton->setEnabled(zoom < MAX_ZOOM - 1);
818         zoomOutButton->setEnabled(true);
819
820         if (!slippyMap)
821             return;
822         slippyMap->setZoom(zoom);
823         setTopLeft(slippyMap->getLatitude(), slippyMap->getLongitude());
824         slippyMap->updateTiles();
825     }
826
827 }
828
829 void WindowMap::updateSummary(){
830     emit(infoWindow->updateSummary());
831 }
832
833
834
835 void WindowMap::autosave(){
836
837     if(track!=0 && track->getNumPoints()>0 && !simulateGPS){
838         log->debug("going to save the TCX file...");
839         track->saveToXML();
840         log->debug("done!");
841     }
842     log->info("done...");
843 }
844
845 void WindowMap::setOrientation(ScreenOrientation orientation)
846 {
847     /*
848 #if defined(Q_OS_SYMBIAN)
849     // If the version of Qt on the device is < 4.7.2, that attribute won't work
850     if (orientation != ScreenOrientationAuto) {
851         const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
852         if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
853             qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
854             return;
855         }
856     }
857 #endif // Q_OS_SYMBIAN
858
859     Qt::WidgetAttribute attribute;
860     switch (orientation) {
861 #if QT_VERSION < 0x040702
862     // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
863     case ScreenOrientationLockPortrait:
864         attribute = static_cast<Qt::WidgetAttribute>(128);
865         break;
866     case ScreenOrientationLockLandscape:
867         attribute = static_cast<Qt::WidgetAttribute>(129);
868         break;
869     default:
870     case ScreenOrientationAuto:
871         attribute = static_cast<Qt::WidgetAttribute>(130);
872         break;
873 #else // QT_VERSION < 0x040702
874     case ScreenOrientationLockPortrait:
875         attribute = Qt::WA_LockPortraitOrientation;
876         break;
877     case ScreenOrientationLockLandscape:
878         attribute = Qt::WA_LockLandscapeOrientation;
879         break;
880     default:
881     case ScreenOrientationAuto:
882         attribute = Qt::WA_AutoOrientation;
883         break;
884 #endif // QT_VERSION < 0x040702
885     };
886     setAttribute(attribute, true);
887     */
888 }
889
890 void WindowMap::showExpanded()
891 {
892 #ifdef Q_OS_SYMBIAN
893     showFullScreen();
894 #elif defined(Q_WS_MAEMO_5)
895     showMaximized();
896 #else
897     show();
898 #endif
899 }
900
901
902 void WindowMap::paintEvent(QPaintEvent *event) {
903
904
905     fixZoomButtons();
906     log->debug("---- paint Event ----!");
907
908     QPainter p;
909     p.begin(this);
910
911     p.setPen(Qt::black);
912
913 #if defined(Q_OS_SYMBIAN)
914     QFont font = p.font();
915     font.setPixelSize(13);
916     p.setFont(font);
917 #endif
918
919     if (!slippyMap){
920         log->debug("slippyMap not created!");
921         displayInit(&p);
922
923     }else{
924
925         slippyMap->render(&p, event->rect());
926
927         //log->info("going to draw tracking route...");
928         drawTrack(trackToSniff,&p, settings->getTrackToSniffColor());
929
930         if(mode==Mode_NewActivityMode){
931             //log->info("going to draw actual route...");
932             //log->debug(QString("num points track:%1").arg(track->getNumPoints()));
933             //log->debug("entering to drawTrack");
934             drawTrack(track,&p,settings->getTrackColor(),true);
935             //log->info("done");
936         }
937     }
938
939
940     //log->info("done");
941     //p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap,"OpenStreetMap maps");
942     //log->debug("ending Paint event...");
943     p.end();
944     //log->debug("done... and now?");
945
946 }
947
948 void WindowMap::displayInit(QPainter *p){
949
950     QPixmap emptyTile = QPixmap(tdim,tdim);
951     emptyTile.fill(Qt::lightGray);
952
953     int numWidth = floor(width()/tdim)+1;
954     int numHeight = floor(height()/tdim)+1;
955     qreal tempx = static_cast<qreal>(width())/tdim;
956     qreal tempy = static_cast<qreal>(height())/tdim;
957
958     int width_offset=(tempx-numWidth)*tdim/2;
959     int height_offset=(tempy-numHeight)*tdim/2;
960
961     QPoint topLeft = QPoint(width_offset,height_offset);
962
963     for (int x = 0; x <= numWidth; ++x){
964         for (int y = 0; y <= numHeight; ++y) {
965             QRect box = QRect(topLeft.x()+x*tdim, topLeft.y()+y*tdim, tdim, tdim);
966
967             p->drawPixmap(box,emptyTile);
968         }
969     }
970
971
972
973 }
974
975 void WindowMap::drawFullTrackMaps(Track* track_p){
976
977     QList<GpsPoint*> gpsPoints = track_p->getGpsPoints();
978     //log->debug(QString("number of points to draw:%1").arg(gpsPoints.size()));
979
980     int zoomToTrack=18;
981     bool found=false;
982     bool changeZoom;
983     bool firstZoom;
984     int border=0;
985
986     qreal min_x;
987     qreal max_x;
988     qreal min_y;
989     qreal max_y;
990
991     while(zoomToTrack>0 && !found){
992         changeZoom=false;
993         firstZoom=true;
994         //log->debug(QString("zoomToTrack:%1").arg(zoomToTrack));
995         for (int i = 0;!changeZoom && i < gpsPoints.size(); ++i) {
996             GpsPoint* point = gpsPoints.at(i);
997             QPointF ct = slippyMap->coordinate2tile(point->getLatitude(), point->getLongitude(), zoomToTrack);
998
999             //log->debug(QString("point %1: x=%2,y=%3").arg(i).arg(ct.x()).arg(ct.y()));
1000             if(firstZoom){
1001                 min_x=ct.x();
1002                 max_x=ct.x();
1003                 min_y=ct.y();
1004                 max_y=ct.y();
1005                 firstZoom=false;
1006             }else{
1007                 min_x = min(min_x,ct.x());
1008                 max_x = max(max_x,ct.x());
1009                 min_y = min(min_y,ct.y());
1010                 max_y = max(max_y,ct.y());
1011             }
1012             //log->debug(QString("min_x:%1, max_x:%2, min_y:%3, max_y:%4").arg(min_x).arg(max_x).arg(min_y).arg(max_y));
1013
1014             // if point is outside screen change zoom
1015             qreal d_x=(max_x-min_x)*tdim;
1016             qreal d_y=(max_y-min_y)*tdim;
1017             //log->debug(QString("x distance:%1, y distance:%2").arg(d_x).arg(d_y));
1018             //log->debug(QString("width-border*2=%1, height-border*2=%2").arg(width()-border*2).arg(height()-border*2));
1019             if(d_x>(width()-border*2) || d_y>(height()-border*2)){
1020                 //log->debug("point outside screen, changezoom");
1021                 changeZoom=true;
1022                 zoomToTrack--;
1023             }
1024         }
1025         if(!changeZoom){
1026             found=true;
1027             //log->debug(QString("all points are inside screen, zoom found: %1").arg(zoomToTrack));
1028         }
1029     }
1030
1031     qreal med_x=qreal(min_x+static_cast<qreal>(width())/(2.0*static_cast<qreal>(tdim)));
1032     qreal med_y=qreal(min_y+static_cast<qreal>(height())/(2.0*static_cast<qreal>(tdim)));
1033
1034     qreal lng=slippyMap->tilex2long(med_x,zoomToTrack);
1035     qreal lat=slippyMap->tiley2lat(med_y,zoomToTrack);
1036
1037     zoom=zoomToTrack;
1038     slippyMap->setZoom(zoom);
1039     //log->debug(QString("changing zoom to:%1").arg(zoom));
1040     //log->debug(QString("centering with x_med:%1,y_med:%2 ").arg(med_x).arg(med_y));
1041     //log->debug(QString("centering with lat:%1,lng:%2 ").arg(lat).arg(lng));
1042
1043
1044     //log->debug(QString("minx:%1, miny:%2").arg(min_x).arg(min_y));
1045     topLeft=QPointF(min_x,min_y);
1046     slippyMap->updateTiles(lat,lng);
1047
1048
1049 }
1050 bool WindowMap::drawTrack(Track* track_p, QPainter* p, QString color_s){
1051     drawTrack(track_p,p,color_s,false);
1052 }
1053
1054 bool WindowMap::drawTrack(Track* track_p, QPainter* p, QString color_s,bool lastPoint){
1055
1056     if (track_p!=NULL && track_p->getNumPoints()<=0){
1057         log->debug("no points to draw...");
1058         return false;
1059     }
1060     QColor color = QColor(color_s);
1061     p->setBrush(QBrush(color));
1062     QPen pen(color, 5, Qt::SolidLine);
1063
1064     p->setPen(pen);
1065     qreal border=0;
1066
1067     QPointF previous=QPointF(0,0);
1068
1069     log->debug("going to get points...");
1070     //log->debug(QString("num:%1").arg(track_p->getNumPoints()));
1071     QList<GpsPoint*> points = track_p->getGpsPoints();
1072     log->debug(QString("drawing with zoom:%1").arg(zoom));
1073     //log->debug(QString("TopLeft x:%1, y:%2").arg(topLeft.x()).arg(topLeft.y()));
1074     for(int i = 0; i < points.size(); ++i){
1075
1076         GpsPoint* point = points.at(i);
1077         QPointF ct = slippyMap->coordinate2tile(point->getLatitude(), point->getLongitude(), zoom);
1078
1079         //log->debug(QString("point %1: x=%2,y=%3").arg(i).arg(ct.x()).arg(ct.y()));
1080         //log->debug(QString("topLeft.x:%1, topLeft.y:%2").arg(topLeft.x()).arg(topLeft.y()));
1081         qreal x_resized = (ct.x() - topLeft.x())*tdim + border;
1082         qreal y_resized = (ct.y() - topLeft.y())*tdim + border;
1083         QPointF resized = QPoint(x_resized,y_resized);
1084         //log->debug(QString("point resized: x=%1,y=%2").arg(resized.x()).arg(resized.y()));
1085         if(!previous.isNull() && previous!=ct &&
1086                 (resized.x()>= 0 && resized.x()<=width() &&  resized.y()>=0 && resized.y() <= height())){
1087              //log->debug(QString("drawing line from: %1,%2 to %3,%4").arg(previous.x()).arg(previous.y()).arg(resized.x()).arg(resized.y()));
1088              p->drawLine(previous,resized);
1089         }
1090         previous=resized;
1091     }
1092
1093     if(lastPoint){
1094         p->setBrush(QBrush(QColor(color_s)));
1095         p->drawEllipse(previous,10,10);
1096         p->setBrush(QBrush(Qt::black));
1097         p->drawEllipse(previous,7,7);
1098     }
1099 }
1100
1101
1102
1103 void WindowMap::mousePressEvent(QMouseEvent *event) {
1104     if (!slippyMap)
1105         return;
1106
1107     if (event->buttons() != Qt::LeftButton)
1108         return;
1109     pressed = snapped = true;
1110     pressPos = dragPos = event->pos();
1111
1112     possitionPaint=false;
1113
1114     //tapTimer.stop();
1115     //tapTimer.start(HOLD_TIME, this);
1116 }
1117
1118 void WindowMap::mouseMoveEvent(QMouseEvent *event) {
1119     if (!slippyMap)
1120         return;
1121
1122     if (!event->buttons())
1123         return;
1124
1125     //possitionPaint=false;
1126
1127     if (!pressed || !snapped) {
1128         QPoint delta = event->pos() - pressPos;
1129         pressPos = event->pos();
1130         QPointF dx = QPointF(delta);
1131
1132         //log->debug(QString("Changing topleft, from %1,%2").arg(topLeft.x()).arg(topLeft.y()));
1133         //log->debug(QString("distance changed: x=%1,y=%2").arg(dx.x()).arg(dx.y()));
1134         topLeft = topLeft -dx/tdim;
1135         //log->debug(QString("to %1,%2").arg(topLeft.x()).arg(topLeft.y()));
1136         //topLeft = QPoint(delta.x()-width()/2,delta.y()-height()/2);
1137         slippyMap->pan(delta);
1138
1139         return;
1140     } else {
1141         const int threshold = 10;
1142         QPoint delta = event->pos() - pressPos;
1143         if (snapped) {
1144             snapped &= delta.x() < threshold;
1145             snapped &= delta.y() < threshold;
1146             snapped &= delta.x() > -threshold;
1147             snapped &= delta.y() > -threshold;
1148         }
1149
1150     }
1151
1152 }
1153
1154 void WindowMap::mouseReleaseEvent(QMouseEvent *) {
1155     if (!slippyMap)
1156         return;
1157     desactivatePossitionPaint();
1158     update();
1159
1160 }
1161
1162 void WindowMap::fixZoomButtons(){
1163
1164     int x_in=(width()-zoomInButton->width());
1165     int y_in=(height()/2-zoomInButton->height()/2);
1166     //log->debug(QString("ZoomIn possition: x=%1,y=%2").arg(x_in).arg(y_in));
1167
1168     int x_out=0;
1169     int y_out=(height()/2-zoomOutButton->height()/2);
1170     //log->debug(QString("ZoomOut possition: x=%1,y=%2").arg(x_out).arg(y_out));
1171
1172     zoomInButton->move(x_in,y_in);
1173     zoomOutButton->move(x_out,y_out);
1174     zoomInButton->show();
1175     zoomOutButton->show();
1176 }
1177
1178 void WindowMap::resizeEvent(QResizeEvent * /* event */)
1179 {
1180
1181     fixZoomButtons();
1182
1183     /*
1184     int x = width() - (zoomInButton->width()
1185                        + zoomOutButton->width() + 10);
1186     zoomInButton->move(x, 5);
1187     zoomOutButton->move(x + zoomInButton->width() + 5, 5);
1188
1189     */
1190 }
1191
1192
1193 /* QString activity;
1194     int gpsInterval;
1195     QString mapType;
1196     bool isOnline;
1197     QFile gpxFile;
1198     */
1199
1200
1201
1202
1203
1204