Some bugs fixed.
[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         setWindowTitle(track->getName());
635         settingsWindow->show();
636
637     }else if(mode==Mode_LoadTracksWindow && !settings->getIsConfigured()){
638         setWindowTitle(QString("Load Tracks ->").append(trackToSniff->getName()));
639         loadTracksWindow->show();
640     }
641 }
642
643  void WindowMap::showEvent(QShowEvent *){
644      chooseDisplay();
645  }
646
647  void WindowMap::networkStart(){
648      startNetworkAction->setEnabled(false);
649      QTimer::singleShot(0, nSession, SLOT(open()));
650  }
651
652  void WindowMap::configureSettings(){
653     settingsWindow->show();
654  }
655
656  void WindowMap::tracksActivity(){
657      //mode=Mode_LoadTracksWindow;
658      possitionPaint=false;
659      //setMenuLoadTracks();
660      loadTracksWindow->show();
661  }
662
663  void WindowMap::loadTrack(){
664      loadTracksWindow->show();
665  }
666  void WindowMap::downloadMapTrack(){
667
668
669      if(slippyMap){
670         qreal lat = slippyMap->getLatitude();
671         qreal lng = slippyMap->getLongitude();
672         tilesToDownload=0;
673         startNetworking();
674
675         downloadingStatus->show();
676
677         //downloadingStatus->move(pos);
678         QProgressBar* pb = downloadingStatus->getProgressBar();
679         int numPoints = trackToSniff->getNumPoints();
680         int zoomsToDown = (MAX_ZOOM_DOWNL - slippyMap->getZoom());
681         if(zoomsToDown>=0){
682             pb->setRange(0,numPoints*zoomsToDown);
683         }
684         pb->setValue(0);
685         downloadingStatus->setText(QString(tr("Making map requests")));
686
687         connect(slippyMap,SIGNAL(pointsRequested(int)),pb,SLOT(setValue(int)));
688         tilesToDownload = slippyMap->downloadMaps(trackToSniff);
689         disconnect(slippyMap,SIGNAL(pointsRequested(int)),pb,SLOT(setValue(int)));
690
691         if(tilesToDownload>0){
692             downloadingStatus->setText(QString(tr("Getting map tiles")));
693             pb->setRange(0,tilesToDownload);
694             pb->setValue(0);
695             connect(slippyMap,SIGNAL(tilesDownloaded(int)),this,SLOT(updateProgress(int)));
696         }else{
697             downloadingStatus->hide();
698         }
699
700         slippyMap->updateTiles(lat,lng);
701      }
702  }
703
704  void WindowMap::updateProgress(int val){
705
706      downloadingStatus->getProgressBar()->setValue(val);
707      if(val==tilesToDownload){
708          downloadingStatus->hide();
709      }
710  }
711  void WindowMap::newActivityTrack(){
712      mode=Mode_NewActivityMode;
713      settings->setIsConfigured(false);
714      setMenuActivity();
715      chooseDisplay();
716  }
717
718  void WindowMap::newSimulation(){
719      mode=Mode_NewActivityMode;
720      simulateGPS=true;
721      settings->setIsConfigured(false);
722      setMenuActivity();
723      chooseDisplay();
724  }
725
726  void WindowMap::info(){
727     infoWindow->show();
728  }
729
730  void WindowMap::startActivity(){
731
732      stopAction->setEnabled(true);
733      startAction->setEnabled(false);
734      startPositioning();
735      //log->debug("stopStart enabled");
736 }
737 void WindowMap::stopActivity(){
738
739     stopAction->setEnabled(false);
740     startAction->setEnabled(true);
741
742     stopPositioning();
743
744 }
745
746 /*
747 void WindowMap::settings(){
748     settingsWindow->show();
749 }
750 */
751
752 void WindowMap::lapActivity(){
753     if(track)
754         track->addLap();
755 }
756
757 void WindowMap::quit(){
758     QCloseEvent *event = new QCloseEvent();
759     emit closeEvent(event);
760 }
761 /*
762 void WindowMap::tracks(){
763
764 }
765 */
766
767 /*
768 void WindowMap::satellite(){
769
770 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
771     showSatelliteInfo();
772 #endif
773 }
774 */
775
776 void WindowMap::stopPositioning() {
777    if(simulateGPS){
778     simulatePossitioningTimer->stop();
779    }else{
780     if (location)
781         location->stopUpdates();
782    }
783 }
784
785 void WindowMap::startPositioning() {
786     if(simulateGPS){
787         simulatePossitioningTimer->start();
788     }else{
789         if (location)
790             location->startUpdates();
791     }
792 }
793
794 void WindowMap::onZoomOut(){
795
796     int minzoom=0;
797     if(settings->getMapType()==MapTypeICC)
798         minzoom=MIN_ICC_ZOOM;
799
800     if (zoom > minzoom) {
801         --(zoom);
802         zoomOutButton->setEnabled(zoom > minzoom);
803         zoomInButton->setEnabled(true);
804
805         if (!slippyMap)
806             return;
807         slippyMap->setZoom(zoom);
808
809         setTopLeft(slippyMap->getLatitude(), slippyMap->getLongitude());
810         slippyMap->updateTiles();
811     }
812
813 }
814
815 void WindowMap::onZoomIn(){
816     if (zoom < MAX_ZOOM - 1) {
817         ++(zoom);
818         zoomInButton->setEnabled(zoom < MAX_ZOOM - 1);
819         zoomOutButton->setEnabled(true);
820
821         if (!slippyMap)
822             return;
823         slippyMap->setZoom(zoom);
824         setTopLeft(slippyMap->getLatitude(), slippyMap->getLongitude());
825         slippyMap->updateTiles();
826     }
827
828 }
829
830 void WindowMap::updateSummary(){
831     emit(infoWindow->updateSummary());
832 }
833
834
835
836 void WindowMap::autosave(){
837
838     if(track!=0 && track->getNumPoints()>0 && !simulateGPS){
839         log->debug("going to save the TCX file...");
840         track->saveToXML();
841         log->debug("done!");
842     }
843     log->info("done...");
844 }
845
846 void WindowMap::setOrientation(ScreenOrientation orientation)
847 {
848     /*
849 #if defined(Q_OS_SYMBIAN)
850     // If the version of Qt on the device is < 4.7.2, that attribute won't work
851     if (orientation != ScreenOrientationAuto) {
852         const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
853         if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
854             qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
855             return;
856         }
857     }
858 #endif // Q_OS_SYMBIAN
859
860     Qt::WidgetAttribute attribute;
861     switch (orientation) {
862 #if QT_VERSION < 0x040702
863     // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
864     case ScreenOrientationLockPortrait:
865         attribute = static_cast<Qt::WidgetAttribute>(128);
866         break;
867     case ScreenOrientationLockLandscape:
868         attribute = static_cast<Qt::WidgetAttribute>(129);
869         break;
870     default:
871     case ScreenOrientationAuto:
872         attribute = static_cast<Qt::WidgetAttribute>(130);
873         break;
874 #else // QT_VERSION < 0x040702
875     case ScreenOrientationLockPortrait:
876         attribute = Qt::WA_LockPortraitOrientation;
877         break;
878     case ScreenOrientationLockLandscape:
879         attribute = Qt::WA_LockLandscapeOrientation;
880         break;
881     default:
882     case ScreenOrientationAuto:
883         attribute = Qt::WA_AutoOrientation;
884         break;
885 #endif // QT_VERSION < 0x040702
886     };
887     setAttribute(attribute, true);
888     */
889 }
890
891 void WindowMap::showExpanded()
892 {
893 #ifdef Q_OS_SYMBIAN
894     showFullScreen();
895 #elif defined(Q_WS_MAEMO_5)
896     showMaximized();
897 #else
898     show();
899 #endif
900 }
901
902
903 void WindowMap::paintEvent(QPaintEvent *event) {
904
905
906     fixZoomButtons();
907     log->debug("---- paint Event ----!");
908
909     QPainter p;
910     p.begin(this);
911
912     p.setPen(Qt::black);
913
914 #if defined(Q_OS_SYMBIAN)
915     QFont font = p.font();
916     font.setPixelSize(13);
917     p.setFont(font);
918 #endif
919
920     if (!slippyMap){
921         log->debug("slippyMap not created!");
922         displayInit(&p);
923
924     }else{
925
926         slippyMap->render(&p, event->rect());
927
928         //log->info("going to draw tracking route...");
929         drawTrack(trackToSniff,&p, settings->getTrackToSniffColor());
930
931         if(mode==Mode_NewActivityMode){
932             //log->info("going to draw actual route...");
933             //log->debug(QString("num points track:%1").arg(track->getNumPoints()));
934             //log->debug("entering to drawTrack");
935             drawTrack(track,&p,settings->getTrackColor(),true);
936             //log->info("done");
937         }
938     }
939
940
941     //log->info("done");
942     //p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap,"OpenStreetMap maps");
943     //log->debug("ending Paint event...");
944     p.end();
945     //log->debug("done... and now?");
946
947 }
948
949 void WindowMap::displayInit(QPainter *p){
950
951     QPixmap emptyTile = QPixmap(tdim,tdim);
952     emptyTile.fill(Qt::lightGray);
953
954     int numWidth = floor(width()/tdim)+1;
955     int numHeight = floor(height()/tdim)+1;
956     qreal tempx = static_cast<qreal>(width())/tdim;
957     qreal tempy = static_cast<qreal>(height())/tdim;
958
959     int width_offset=(tempx-numWidth)*tdim/2;
960     int height_offset=(tempy-numHeight)*tdim/2;
961
962     QPoint topLeft = QPoint(width_offset,height_offset);
963
964     for (int x = 0; x <= numWidth; ++x){
965         for (int y = 0; y <= numHeight; ++y) {
966             QRect box = QRect(topLeft.x()+x*tdim, topLeft.y()+y*tdim, tdim, tdim);
967
968             p->drawPixmap(box,emptyTile);
969         }
970     }
971
972
973
974 }
975
976 void WindowMap::drawFullTrackMaps(Track* track_p){
977
978     QList<GpsPoint*> gpsPoints = track_p->getGpsPoints();
979     //log->debug(QString("number of points to draw:%1").arg(gpsPoints.size()));
980
981     int zoomToTrack=18;
982     bool found=false;
983     bool changeZoom;
984     bool firstZoom;
985     int border=0;
986
987     qreal min_x;
988     qreal max_x;
989     qreal min_y;
990     qreal max_y;
991
992     while(zoomToTrack>0 && !found){
993         changeZoom=false;
994         firstZoom=true;
995         //log->debug(QString("zoomToTrack:%1").arg(zoomToTrack));
996         for (int i = 0;!changeZoom && i < gpsPoints.size(); ++i) {
997             GpsPoint* point = gpsPoints.at(i);
998             QPointF ct = slippyMap->coordinate2tile(point->getLatitude(), point->getLongitude(), zoomToTrack);
999
1000             //log->debug(QString("point %1: x=%2,y=%3").arg(i).arg(ct.x()).arg(ct.y()));
1001             if(firstZoom){
1002                 min_x=ct.x();
1003                 max_x=ct.x();
1004                 min_y=ct.y();
1005                 max_y=ct.y();
1006                 firstZoom=false;
1007             }else{
1008                 min_x = min(min_x,ct.x());
1009                 max_x = max(max_x,ct.x());
1010                 min_y = min(min_y,ct.y());
1011                 max_y = max(max_y,ct.y());
1012             }
1013             //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));
1014
1015             // if point is outside screen change zoom
1016             qreal d_x=(max_x-min_x)*tdim;
1017             qreal d_y=(max_y-min_y)*tdim;
1018             //log->debug(QString("x distance:%1, y distance:%2").arg(d_x).arg(d_y));
1019             //log->debug(QString("width-border*2=%1, height-border*2=%2").arg(width()-border*2).arg(height()-border*2));
1020             if(d_x>(width()-border*2) || d_y>(height()-border*2)){
1021                 //log->debug("point outside screen, changezoom");
1022                 changeZoom=true;
1023                 zoomToTrack--;
1024             }
1025         }
1026         if(!changeZoom){
1027             found=true;
1028             //log->debug(QString("all points are inside screen, zoom found: %1").arg(zoomToTrack));
1029         }
1030     }
1031
1032     qreal med_x=qreal(min_x+static_cast<qreal>(width())/(2.0*static_cast<qreal>(tdim)));
1033     qreal med_y=qreal(min_y+static_cast<qreal>(height())/(2.0*static_cast<qreal>(tdim)));
1034
1035     qreal lng=slippyMap->tilex2long(med_x,zoomToTrack);
1036     qreal lat=slippyMap->tiley2lat(med_y,zoomToTrack);
1037
1038     zoom=zoomToTrack;
1039     slippyMap->setZoom(zoom);
1040     //log->debug(QString("changing zoom to:%1").arg(zoom));
1041     //log->debug(QString("centering with x_med:%1,y_med:%2 ").arg(med_x).arg(med_y));
1042     //log->debug(QString("centering with lat:%1,lng:%2 ").arg(lat).arg(lng));
1043
1044
1045     //log->debug(QString("minx:%1, miny:%2").arg(min_x).arg(min_y));
1046     topLeft=QPointF(min_x,min_y);
1047     slippyMap->updateTiles(lat,lng);
1048
1049
1050 }
1051 bool WindowMap::drawTrack(Track* track_p, QPainter* p, QString color_s){
1052     drawTrack(track_p,p,color_s,false);
1053 }
1054
1055 bool WindowMap::drawTrack(Track* track_p, QPainter* p, QString color_s,bool lastPoint){
1056
1057     if (track_p!=NULL && track_p->getNumPoints()<=0){
1058         log->debug("no points to draw...");
1059         return false;
1060     }
1061     QColor color = QColor(color_s);
1062     p->setBrush(QBrush(color));
1063     QPen pen(color, 5, Qt::SolidLine);
1064
1065     p->setPen(pen);
1066     qreal border=0;
1067
1068     QPointF previous=QPointF(0,0);
1069
1070     log->debug("going to get points...");
1071     //log->debug(QString("num:%1").arg(track_p->getNumPoints()));
1072     QList<GpsPoint*> points = track_p->getGpsPoints();
1073     log->debug(QString("drawing with zoom:%1").arg(zoom));
1074     //log->debug(QString("TopLeft x:%1, y:%2").arg(topLeft.x()).arg(topLeft.y()));
1075     for(int i = 0; i < points.size(); ++i){
1076
1077         GpsPoint* point = points.at(i);
1078         QPointF ct = slippyMap->coordinate2tile(point->getLatitude(), point->getLongitude(), zoom);
1079
1080         //log->debug(QString("point %1: x=%2,y=%3").arg(i).arg(ct.x()).arg(ct.y()));
1081         //log->debug(QString("topLeft.x:%1, topLeft.y:%2").arg(topLeft.x()).arg(topLeft.y()));
1082         qreal x_resized = (ct.x() - topLeft.x())*tdim + border;
1083         qreal y_resized = (ct.y() - topLeft.y())*tdim + border;
1084         QPointF resized = QPoint(x_resized,y_resized);
1085         //log->debug(QString("point resized: x=%1,y=%2").arg(resized.x()).arg(resized.y()));
1086         if(!previous.isNull() && previous!=ct &&
1087                 (resized.x()>= 0 && resized.x()<=width() &&  resized.y()>=0 && resized.y() <= height())){
1088              //log->debug(QString("drawing line from: %1,%2 to %3,%4").arg(previous.x()).arg(previous.y()).arg(resized.x()).arg(resized.y()));
1089              p->drawLine(previous,resized);
1090         }
1091         previous=resized;
1092     }
1093
1094     if(lastPoint){
1095         p->setBrush(QBrush(QColor(color_s)));
1096         p->drawEllipse(previous,10,10);
1097         p->setBrush(QBrush(Qt::black));
1098         p->drawEllipse(previous,7,7);
1099     }
1100 }
1101
1102
1103
1104 void WindowMap::mousePressEvent(QMouseEvent *event) {
1105     if (!slippyMap)
1106         return;
1107
1108     if (event->buttons() != Qt::LeftButton)
1109         return;
1110     pressed = snapped = true;
1111     pressPos = dragPos = event->pos();
1112
1113     possitionPaint=false;
1114
1115     //tapTimer.stop();
1116     //tapTimer.start(HOLD_TIME, this);
1117 }
1118
1119 void WindowMap::mouseMoveEvent(QMouseEvent *event) {
1120     if (!slippyMap)
1121         return;
1122
1123     if (!event->buttons())
1124         return;
1125
1126     //possitionPaint=false;
1127
1128     if (!pressed || !snapped) {
1129         QPoint delta = event->pos() - pressPos;
1130         pressPos = event->pos();
1131         QPointF dx = QPointF(delta);
1132
1133         //log->debug(QString("Changing topleft, from %1,%2").arg(topLeft.x()).arg(topLeft.y()));
1134         //log->debug(QString("distance changed: x=%1,y=%2").arg(dx.x()).arg(dx.y()));
1135         topLeft = topLeft -dx/tdim;
1136         //log->debug(QString("to %1,%2").arg(topLeft.x()).arg(topLeft.y()));
1137         //topLeft = QPoint(delta.x()-width()/2,delta.y()-height()/2);
1138         slippyMap->pan(delta);
1139
1140         return;
1141     } else {
1142         const int threshold = 10;
1143         QPoint delta = event->pos() - pressPos;
1144         if (snapped) {
1145             snapped &= delta.x() < threshold;
1146             snapped &= delta.y() < threshold;
1147             snapped &= delta.x() > -threshold;
1148             snapped &= delta.y() > -threshold;
1149         }
1150
1151     }
1152
1153 }
1154
1155 void WindowMap::mouseReleaseEvent(QMouseEvent *) {
1156     if (!slippyMap)
1157         return;
1158     desactivatePossitionPaint();
1159     update();
1160
1161 }
1162
1163 void WindowMap::fixZoomButtons(){
1164
1165     int x_in=(width()-zoomInButton->width());
1166     int y_in=(height()/2-zoomInButton->height()/2);
1167     //log->debug(QString("ZoomIn possition: x=%1,y=%2").arg(x_in).arg(y_in));
1168
1169     int x_out=0;
1170     int y_out=(height()/2-zoomOutButton->height()/2);
1171     //log->debug(QString("ZoomOut possition: x=%1,y=%2").arg(x_out).arg(y_out));
1172
1173     zoomInButton->move(x_in,y_in);
1174     zoomOutButton->move(x_out,y_out);
1175     zoomInButton->show();
1176     zoomOutButton->show();
1177 }
1178
1179 void WindowMap::resizeEvent(QResizeEvent * /* event */)
1180 {
1181
1182     fixZoomButtons();
1183
1184     /*
1185     int x = width() - (zoomInButton->width()
1186                        + zoomOutButton->width() + 10);
1187     zoomInButton->move(x, 5);
1188     zoomOutButton->move(x + zoomInButton->width() + 5, 5);
1189
1190     */
1191 }
1192
1193
1194 /* QString activity;
1195     int gpsInterval;
1196     QString mapType;
1197     bool isOnline;
1198     QFile gpxFile;
1199     */
1200
1201
1202
1203
1204
1205