Fixed bug 5709. Now result dialog shows only two decimals in time labels.
[speedfreak] / Client / routesavedialog.cpp
1 /*
2  * Route save dialog class
3  *
4  * @author     Toni Jussila <toni.jussila@fudeco.com>
5  * @copyright  (c) 2010 Speed Freak team
6  * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
7  */
8
9 #include "routesavedialog.h"
10 #include "ui_routesavedialog.h"
11 #include <QDebug>
12 #include <QPainter>
13 #include <QFileDialog>
14 #include <QDir>
15
16 const QPoint arrowStartEast(100, 100);
17 const QPoint arrowEndEast(140, 100);
18
19 const QPoint arrowStartNorth(120, 120);
20 const QPoint arrowEndNorth(120, 80);
21
22 const QPoint arrowStartNortheast(100, 120);
23 const QPoint arrowEndNortheast(140, 80);
24
25 const QPoint arrowStartNorthwest(140, 120);
26 const QPoint arrowEndNorthwest(100, 80);
27
28 /**
29   * Constructor of this class.
30   * @param QWidget pointer to parent object. By default the value is NULL.
31   */
32 RouteSaveDialog::RouteSaveDialog(QWidget *parent) :
33     QDialog(parent), ui(new Ui::RouteSaveDialog){
34
35     qDebug() << "__RouteSaveDialog";
36     ui->setupUi(this);
37     this->setWindowTitle("Tracking");
38
39     routeDialog = NULL;
40     location = NULL;
41     gpsData = NULL;
42     helpRoutingDialog = NULL;
43     calibrateDialog = NULL;
44
45     //Clear variables
46     averageSpeed = 0.0;
47     speed = 0.0;
48     allSpeeds = 0.0;
49     speedCount = 0;
50     direction = 0.0;
51
52     //Button settings
53     buttonStatus = true;
54     pixmapRouteStop = new QPixmap("Graphics/route_stop.png");
55     pixmapRouteStart = new QPixmap("Graphics/route_start.png");
56     iconRouteStop = new QIcon(*pixmapRouteStop);
57     iconRouteStart = new QIcon(*pixmapRouteStart);
58     QSize iconSize(125, 125);
59     ui->buttonRouteStartStop->setIconSize(iconSize);
60     ui->buttonRouteStartStop->setIcon(*iconRouteStart);
61     ui->buttonRouteStartStop->setAutoFillBackground(true);
62     ui->buttonRouteStartStop->setStyleSheet("background-color: rgb(0, 0, 0); color: rgb(255, 255, 255)");
63     ui->pushButtonInfo->setAutoFillBackground(true);
64     ui->pushButtonInfo->setStyleSheet("background-color: rgb(0, 0, 0); color: rgb(255, 255, 255)");
65     ui->buttonLoadRoute->setAutoFillBackground(true);
66     ui->buttonLoadRoute->setStyleSheet("background-color: rgb(0, 0, 0); color: rgb(255, 255, 255)");
67
68     //Satellite picture and label
69     ui->labelRouteSatelliteStatus->setVisible(0);
70     ui->labelRouteSatellitePicture->setVisible(0);
71     //ui->labelRouteSatellitePicture->setPixmap(QPixmap("Graphics/satellite_vista.png"));
72     timerSatellitePicture = new QTimer();
73     timerSatellitePicture->setInterval(400);
74     connect(timerSatellitePicture, SIGNAL(timeout()),this, SLOT(timerSatellitePictureTimeout()));
75     ui->labelUserInfo->setText("Push start button");  //User info label
76
77     //Invisible or clear labels
78     ui->labelRouteStatus->setVisible(0);
79     ui->labelRoutePicture->setVisible(0);
80     ui->labelGpsSpeed->setVisible(0); //GPS speed label
81     ui->labelGpsAvgSpeed->setVisible(0); //GPS average speed label
82     ui->labelDistance->setVisible(0); //GPS distance label
83     ui->labelSignalStrength->setText(""); //GPS signal strength label
84
85     // Timer
86     timerRoutePicture = new QTimer();
87     timerRoutePicture->setInterval(400);
88     connect(timerRoutePicture, SIGNAL(timeout()),this, SLOT(timerRoutePictureTimeout()));
89
90     //GPS
91     location = new Maemo5Location(this);
92     gpsData = new GPSData(location);
93     connect(location,SIGNAL(agnss()),this,SLOT(gpsStatus()));
94
95     // Route folder
96     QString folder = "/home/user/MyDocs/speedfreak";
97     if(!QDir(folder).exists())
98     {
99         QDir().mkdir(folder);
100     }
101     if(!QDir(folder + "/route").exists())
102     {
103         QDir().mkdir(folder + "/route");
104     }
105 }
106
107 /**
108   * Destructor of this class. Deletes all dynamic objects and sets them to NULL.
109   */
110 RouteSaveDialog::~RouteSaveDialog()
111 {
112     qDebug() << "__~RouteSaveDialog";
113     if(ui)
114         delete ui;
115     if(gpsData)
116         delete gpsData;
117     if(location)
118         delete location;
119     if(routeDialog)
120         delete routeDialog;
121     if(calibrateDialog)
122     {
123         delete calibrateDialog;
124         calibrateDialog = NULL;
125     }
126
127     delete timerSatellitePicture;
128     delete timerRoutePicture;
129     delete pixmapRouteStop;
130     delete pixmapRouteStart;
131     delete iconRouteStop;
132     delete iconRouteStart;
133 }
134
135 /**
136   *
137   */
138 void RouteSaveDialog::changeEvent(QEvent *e)
139 {
140     QDialog::changeEvent(e);
141     switch (e->type()) {
142     case QEvent::LanguageChange:
143         ui->retranslateUi(this);
144         break;
145     default:
146         break;
147     }
148 }
149
150 /**
151   * Draws compass to the UI
152   * @param QPaintEvent
153  */
154 void RouteSaveDialog::paintEvent(QPaintEvent *)
155 {
156     QPainter painter(this);
157
158     painter.setRenderHint(QPainter::Antialiasing, true);
159     painter.setPen(QPen((Qt::gray),2));
160
161     painter.drawEllipse(arrowStartEast.x() - 30, arrowStartEast.y() - 50, 100, 100);
162
163     QFont font;
164     font.setPixelSize(26);
165     painter.setFont(font);
166     painter.drawText(arrowStartNorth.x() - 10, arrowEndNorth.y() - 45, "N");
167     painter.drawText(arrowStartEast.x() - 65, arrowStartEast.y() + 5, "W");
168     painter.drawText(arrowStartNorth.x()-10, arrowStartNorth.y()+55, "S");
169     painter.drawText(arrowEndEast.x() + 40, arrowEndEast.y() + 5, "E");
170
171     font.setPixelSize(12);
172     painter.setFont(font);
173     painter.drawText(arrowStartNorth.x() + 40, arrowEndNorth.y() - 25, "NE");
174     painter.drawText(arrowStartNorth.x() + 40, arrowStartEast.y() + 45, "SE");
175     painter.drawText(arrowStartEast.x() - 45, arrowStartEast.y() + 45, "SW");
176     painter.drawText(arrowStartEast.x() - 45, arrowEndNorth.y() - 25, "NW");
177
178     if (direction >= 67.5 && direction <= 112.5)
179     {
180         // East arrow
181         painter.drawLine(arrowStartEast, arrowEndEast);
182         painter.drawLine(arrowEndEast.x(), arrowEndEast.y(), arrowEndEast.x()-10, arrowEndEast.y()-5);
183         painter.drawLine(arrowEndEast.x(), arrowEndEast.y(), arrowEndEast.x()-10, arrowEndEast.y()+5);
184     }
185
186     else if (direction <= 292.5 && direction >= 247.5)
187     {
188         // West arrow
189         painter.drawLine(arrowStartEast, arrowEndEast);
190         painter.drawLine(arrowStartEast.x(), arrowStartEast.y(), arrowStartEast.x()+10, arrowEndEast.y()-5);
191         painter.drawLine(arrowStartEast.x(), arrowStartEast.y(), arrowStartEast.x()+10, arrowStartEast.y()+5);
192     }
193
194     else if (direction <= 202.5 && direction >= 157.5)
195     {
196         // South arrow
197         painter.drawLine(arrowStartNorth, arrowEndNorth);
198         painter.drawLine(arrowStartNorth.x(), arrowStartNorth.y(), arrowStartNorth.x()-5, arrowStartNorth.y()-10);
199         painter.drawLine(arrowStartNorth.x(), arrowStartNorth.y(), arrowStartNorth.x()+5, arrowStartNorth.y()-10);
200     }
201
202     else if (direction > 22.5 && direction < 67.5)
203     {
204         // Northeast arrow
205         painter.drawLine(arrowStartNortheast, arrowEndNortheast);
206         painter.drawLine(arrowEndNortheast.x(), arrowEndNortheast.y(), arrowEndNortheast.x()-10, arrowEndNortheast.y());
207         painter.drawLine(arrowEndNortheast.x(), arrowEndNortheast.y(), arrowEndNortheast.x(), arrowEndNortheast.y()+10);
208     }
209
210     else if (direction > 202.5 && direction < 247.5)
211     {
212         // Southwest arrow
213         painter.drawLine(arrowStartNortheast, arrowEndNortheast);
214         painter.drawLine(arrowStartNortheast.x(), arrowStartNortheast.y(), arrowStartNortheast.x(), arrowStartNortheast.y() - 10);
215         painter.drawLine(arrowStartNortheast.x(), arrowStartNortheast.y(), arrowStartNortheast.x() + 10, arrowStartNortheast.y());
216     }
217
218     else if (direction > 292.5 && direction < 336.5)
219     {
220         // Northwest arrow
221         painter.drawLine(arrowStartNorthwest, arrowEndNorthwest);
222         painter.drawLine(arrowEndNorthwest.x(), arrowEndNorthwest.y(), arrowEndNorthwest.x(), arrowEndNorthwest.y()+10);
223         painter.drawLine(arrowEndNorthwest.x(), arrowEndNorthwest.y(), arrowEndNorthwest.x()+10, arrowEndNorthwest.y());
224     }
225
226     else if (direction > 112.5 && direction < 157.5)
227     {
228         // Southeast arrow
229         painter.drawLine(arrowStartNorthwest, arrowEndNorthwest);
230         painter.drawLine(arrowStartNorthwest.x(), arrowStartNorthwest.y(), arrowStartNorthwest.x(), arrowStartNorthwest.y()-10);
231         painter.drawLine(arrowStartNorthwest.x(), arrowStartNorthwest.y(), arrowStartNorthwest.x()-10, arrowStartNorthwest.y());
232     }
233
234     else
235     {
236         // North arrow
237         painter.drawLine(arrowStartNorth, arrowEndNorth);
238         painter.drawLine(arrowEndNorth.x(), arrowEndNorth.y(), arrowEndNorth.x()-5, arrowEndNorth.y()+10);
239         painter.drawLine(arrowEndNorth.x(), arrowEndNorth.y(), arrowEndNorth.x()+5, arrowEndNorth.y()+10);
240     }
241 }
242
243 /**
244   *This slot function is called when route start/stop button clicked.
245   */
246 void RouteSaveDialog::on_buttonRouteStartStop_clicked()
247 {
248     if ( buttonStatus == true )//If start button clicked
249     {
250         qDebug() << "__start button clicked";
251
252         //Clear variables
253         averageSpeed = 0.0;
254         speed = 0.0;
255         allSpeeds = 0.0;
256         speedCount = 1;
257
258         buttonStatus = false;
259         ui->buttonRouteStartStop->setIcon(*iconRouteStop);
260         location->startPollingGPS();
261         gpsStatus();
262     }
263     else //If stop button clicked
264     {
265         qDebug() << "__stop button clicked";
266         buttonStatus = true;
267         ui->buttonRouteStartStop->setIcon(*iconRouteStart);
268
269         //Satellite picture and label
270         ui->labelRouteSatelliteStatus->setText("Searching satellite");
271         ui->labelRouteSatelliteStatus->setVisible(0);
272         ui->labelRouteSatellitePicture->setVisible(0);
273         timerSatellitePicture->stop();
274
275         //Route picture and label
276         ui->labelRouteStatus->setVisible(0);
277         ui->labelRoutePicture->setVisible(0);
278         timerRoutePicture->stop();
279         location->stopPollingGPS();
280
281         //Set GPS speed labels in visible
282         ui->labelGpsSpeed->setVisible(0);
283         ui->labelGpsAvgSpeed->setVisible(0);
284
285         //GPS distance label
286         ui->labelDistance->setVisible(0);
287
288         //Stop route recording
289         gpsData->stopRouteRecording();
290
291         //User info label
292         ui->labelUserInfo->setText("Push start button");
293
294         fileName = "/home/user/MyDocs/speedfreak/route/routetemp.xml";
295         openRouteDialog();
296     }
297 }
298
299 /**
300   * This slot function is called when satellite picture timer timeout(400ms).
301   */
302 void RouteSaveDialog::timerSatellitePictureTimeout()
303 {
304     //If satellite picture visible.
305     if (ui->labelRouteSatellitePicture->isVisible() == 1)
306     {
307         ui->labelRouteSatelliteStatus->setVisible(0);
308         ui->labelRouteSatellitePicture->setVisible(0);
309     }
310     else
311     {
312         ui->labelRouteSatelliteStatus->setVisible(1);
313         ui->labelRouteSatellitePicture->setVisible(1);
314     }
315     timerSatellitePicture->start();
316 }
317
318 /**
319   * This slot function is called when route picture timer timeout(400ms).
320   */
321 void RouteSaveDialog::timerRoutePictureTimeout()
322 {
323     //If route picture visible.
324     if (ui->labelRoutePicture->isVisible() == 1)
325     {
326         ui->labelRouteStatus->setVisible(0);
327         ui->labelRoutePicture->setVisible(0);
328     }
329     else
330     {
331         ui->labelRouteStatus->setVisible(1);
332         ui->labelRoutePicture->setVisible(1);
333     }
334     timerRoutePicture->start();
335 }
336
337 /**
338   * This slot function is called when GPS update location.
339   */
340 void RouteSaveDialog::gpsStatus()
341 {
342     //IF GPS start button clicked
343     if (buttonStatus == false)
344     {
345         //ui->labelSignalStrength->setText(QString::number(location->getSignalStrength()));    //Returns average signal strength of satellites which are in use.
346
347         //If GPS find 4 or more satellite and signal stregth is 30 or more.
348         if (location->getSatellitesInUse() >= 4 && location->getSignalStrength() >= 30)
349         {
350             //Satellite picture and label
351             ui->labelRouteSatelliteStatus->setText("GPS Ready");
352             ui->labelRouteSatelliteStatus->setVisible(1);
353             ui->labelRouteSatellitePicture->setVisible(1);
354             timerSatellitePicture->stop();
355
356             //Route picture and label
357             ui->labelRouteStatus->setText("Recorded " + QString::number(gpsData->roundCounter) + " route point");
358             ui->labelUserInfo->setText("Recorded " + QString::number(gpsData->roundCounter) + " route point");
359             ui->labelRouteStatus->setVisible(1);
360             ui->labelRoutePicture->setVisible(1);
361             timerRoutePicture->start();
362
363             //Get GPS speed
364             speed = location->getSpeed();
365
366             //Get GPS track means direction
367             direction = gpsData->getDirection();
368             repaint();
369
370             //Set GPS speed
371             gpsSpeed.sprintf("%.0f", speed);
372             ui->labelGpsSpeed->setText(gpsSpeed + " km/h");
373             ui->labelGpsSpeed->setVisible(1);
374
375             //Set GPS average speed
376             allSpeeds += speed;
377             averageSpeed = allSpeeds/speedCount;
378             gpsSpeed.sprintf("%.0f",averageSpeed);
379             ui->labelGpsAvgSpeed->setText("Avg: " + gpsSpeed + " km/h");
380             ui->labelGpsAvgSpeed->setVisible(1);
381             speedCount++;
382
383             //Set distance traveled.
384             distanceString.sprintf("%.3f", gpsData->getDistanceTraveled());
385             ui->labelDistance->setText(distanceString + " km");
386             ui->labelDistance->setVisible(1);
387
388             //Start route recording
389             gpsData->startRouteRecording();
390         }
391         else //If GPS find less than 4 satellite or signal strength is poor.
392         {
393             //Satellite picture and label
394             ui->labelRouteSatelliteStatus->setText("Searching satellite");
395             ui->labelUserInfo->setText("Searching satellite");
396             ui->labelRouteSatelliteStatus->setVisible(1);
397             ui->labelRouteSatellitePicture->setVisible(1);
398             timerSatellitePicture->start();
399
400             //Route picture and label
401             ui->labelRouteStatus->setVisible(0);
402             ui->labelRoutePicture->setVisible(0);
403             timerRoutePicture->stop();
404
405             //Set GPS speed labels in visible
406             ui->labelGpsSpeed->setVisible(0);
407             ui->labelGpsAvgSpeed->setVisible(0);
408
409             //GPS distance label
410             ui->labelDistance->setVisible(0);
411         }
412     }
413     else //If stop button clicked
414     {
415         //Satellite picture and label
416         ui->labelRouteSatelliteStatus->setText("Searching satellite");
417         ui->labelUserInfo->setText("Push start button");
418         ui->labelRouteSatelliteStatus->setVisible(0);
419         ui->labelRouteSatellitePicture->setVisible(0);
420         timerSatellitePicture->stop();
421
422         //Route picture and label
423         ui->labelRouteStatus->setVisible(0);
424         ui->labelRoutePicture->setVisible(0);
425         timerRoutePicture->stop();
426
427         //Set GPS speed labels in visible
428         ui->labelGpsSpeed->setVisible(0);
429         ui->labelGpsAvgSpeed->setVisible(0);
430
431         //GPS distance label
432         ui->labelDistance->setVisible(0);
433     }
434 }
435
436 /**
437   * This slot function is called when routeDialog emit sendroute (sendPushButton).
438   */
439 void RouteSaveDialog::sendRoute(QString newName, int i)
440 {
441     emit sendroute(fileName, newName, i); //Emit mainwindow clientSendRoute
442 }
443
444 /**
445   * This slot function called when ever info button clicked.
446   */
447 void RouteSaveDialog::on_pushButtonInfo_clicked()
448 {
449     if(!helpRoutingDialog)
450     {
451         helpRoutingDialog = new HelpRoutingDialog;
452     }
453     connect(helpRoutingDialog, SIGNAL(rejected()), this, SLOT(killHelpDialog()));
454     helpRoutingDialog->show();
455 }
456
457 /**
458   * This slot function called when ever dialog rejected.
459   */
460 void RouteSaveDialog::killHelpDialog()
461 {
462     if(helpRoutingDialog)
463     {
464         qDebug() << "__Route save kill: helpRoutingDialog";
465         delete helpRoutingDialog;
466         helpRoutingDialog = NULL;
467     }
468 }
469
470 /**
471   * This slot function called when ever route dialog rejected.
472   */
473 void RouteSaveDialog::killRouteDialog()
474 {
475     if(routeDialog)
476     {
477         qDebug() << "__Route save kill: routeDialog";
478         delete routeDialog;
479         routeDialog = NULL;
480     }
481     if(calibrateDialog)
482     {
483         qDebug() << "__Route save kill: calibrateDialog";
484         delete calibrateDialog;
485         calibrateDialog = NULL;
486     }
487 }
488
489 /**
490   * This function return speed average.
491   * @return double average speed
492   */
493 double RouteSaveDialog::getAverageSpeed()
494 {
495     return averageSpeed;
496 }
497
498 /**
499   * This function return distance traveled in QString.
500   * @return QString distance traveled
501   */
502 QString RouteSaveDialog::getDistanceTraveled()
503 {
504     return distanceString;
505 }
506
507 /**
508   * This function
509   */
510 void RouteSaveDialog::setProgressbar(int i)
511 {
512     qDebug() << "__setProgressbar: " + QString::number(i);
513     //qDebug() << i;
514     calibrateDialog->setProgressValue(i);
515     progressbarIteration++;
516 }
517
518 /**
519   * This slot function called when ever load route button clicked.
520   */
521 void RouteSaveDialog::on_buttonLoadRoute_clicked()
522 {
523     fileName = QFileDialog::getOpenFileName(this, tr("Open route"), "/home/user/MyDocs/speedfreak/route", "XML (*.xml)");
524     qDebug() << "__Opening: " + fileName;
525     openRouteDialog();//fileName);
526 }
527
528 /**
529   * This function open and show route.
530   * @param QString file name
531   */
532 void RouteSaveDialog::openRouteDialog()
533 {
534     if(fileName != "")
535     {
536         // Progress bar
537         if(!calibrateDialog)
538         {
539             calibrateDialog = new CalibrateDialog();
540         }
541
542         progressbarPoints = 100;
543         progressbarIteration = 0;
544         calibrateDialog->resetProgressValue();
545         calibrateDialog->setMaxValue( progressbarPoints );
546         calibrateDialog->setTitle("Calculating route...");
547         calibrateDialog->show();
548
549         if(!routeDialog)
550         {
551             routeDialog = new RouteDialog(this);
552         }
553
554         connect(routeDialog, SIGNAL(sendroute(QString, int)), this, SLOT(sendRoute(QString, int)));
555         connect(routeDialog, SIGNAL(progressbar(int)), this, SLOT(setProgressbar(int)));
556         connect(routeDialog, SIGNAL(rejected()), this, SLOT(killRouteDialog()));
557
558         if (routeDialog->readRouteFromFile( fileName ) == true)
559         {
560             calibrateDialog->close();
561             routeDialog->show();
562         }
563         else
564         {
565             calibrateDialog->close();
566         }
567     }
568 }