Maemo package folder added.
[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   *
153   * @param QPaintEvent
154  */
155 void RouteSaveDialog::paintEvent(QPaintEvent *)
156 {
157     QPainter painter(this);
158
159     painter.setRenderHint(QPainter::Antialiasing, true);
160     painter.setPen(QPen((Qt::gray),2));
161
162     painter.drawEllipse(arrowStartEast.x() - 30, arrowStartEast.y() - 50, 100, 100);
163
164     QFont font;
165     font.setPixelSize(26);
166     painter.setFont(font);
167     painter.drawText(arrowStartNorth.x() - 10, arrowEndNorth.y() - 45, "N");
168     painter.drawText(arrowStartEast.x() - 65, arrowStartEast.y() + 5, "W");
169     painter.drawText(arrowStartNorth.x()-10, arrowStartNorth.y()+55, "S");
170     painter.drawText(arrowEndEast.x() + 40, arrowEndEast.y() + 5, "E");
171
172     font.setPixelSize(12);
173     painter.setFont(font);
174     painter.drawText(arrowStartNorth.x() + 40, arrowEndNorth.y() - 25, "NE");
175     painter.drawText(arrowStartNorth.x() + 40, arrowStartEast.y() + 45, "SE");
176     painter.drawText(arrowStartEast.x() - 45, arrowStartEast.y() + 45, "SW");
177     painter.drawText(arrowStartEast.x() - 45, arrowEndNorth.y() - 25, "NW");
178
179     if (direction >= 67.5 && direction <= 112.5)
180     {
181         // East arrow
182         painter.drawLine(arrowStartEast, arrowEndEast);
183         painter.drawLine(arrowEndEast.x(), arrowEndEast.y(), arrowEndEast.x()-10, arrowEndEast.y()-5);
184         painter.drawLine(arrowEndEast.x(), arrowEndEast.y(), arrowEndEast.x()-10, arrowEndEast.y()+5);
185     }
186
187     else if (direction <= 292.5 && direction >= 247.5)
188     {
189         // West arrow
190         painter.drawLine(arrowStartEast, arrowEndEast);
191         painter.drawLine(arrowStartEast.x(), arrowStartEast.y(), arrowStartEast.x()+10, arrowEndEast.y()-5);
192         painter.drawLine(arrowStartEast.x(), arrowStartEast.y(), arrowStartEast.x()+10, arrowStartEast.y()+5);
193     }
194
195     else if (direction <= 202.5 && direction >= 157.5)
196     {
197         // South arrow
198         painter.drawLine(arrowStartNorth, arrowEndNorth);
199         painter.drawLine(arrowStartNorth.x(), arrowStartNorth.y(), arrowStartNorth.x()-5, arrowStartNorth.y()-10);
200         painter.drawLine(arrowStartNorth.x(), arrowStartNorth.y(), arrowStartNorth.x()+5, arrowStartNorth.y()-10);
201     }
202
203     else if (direction > 22.5 && direction < 67.5)
204     {
205         // Northeast arrow
206         painter.drawLine(arrowStartNortheast, arrowEndNortheast);
207         painter.drawLine(arrowEndNortheast.x(), arrowEndNortheast.y(), arrowEndNortheast.x()-10, arrowEndNortheast.y());
208         painter.drawLine(arrowEndNortheast.x(), arrowEndNortheast.y(), arrowEndNortheast.x(), arrowEndNortheast.y()+10);
209     }
210
211     else if (direction > 202.5 && direction < 247.5)
212     {
213         // Southwest arrow
214         painter.drawLine(arrowStartNortheast, arrowEndNortheast);
215         painter.drawLine(arrowStartNortheast.x(), arrowStartNortheast.y(), arrowStartNortheast.x(), arrowStartNortheast.y() - 10);
216         painter.drawLine(arrowStartNortheast.x(), arrowStartNortheast.y(), arrowStartNortheast.x() + 10, arrowStartNortheast.y());
217     }
218
219     else if (direction > 292.5 && direction < 336.5)
220     {
221         // Northwest arrow
222         painter.drawLine(arrowStartNorthwest, arrowEndNorthwest);
223         painter.drawLine(arrowEndNorthwest.x(), arrowEndNorthwest.y(), arrowEndNorthwest.x(), arrowEndNorthwest.y()+10);
224         painter.drawLine(arrowEndNorthwest.x(), arrowEndNorthwest.y(), arrowEndNorthwest.x()+10, arrowEndNorthwest.y());
225     }
226
227     else if (direction > 112.5 && direction < 157.5)
228     {
229         // Southeast arrow
230         painter.drawLine(arrowStartNorthwest, arrowEndNorthwest);
231         painter.drawLine(arrowStartNorthwest.x(), arrowStartNorthwest.y(), arrowStartNorthwest.x(), arrowStartNorthwest.y()-10);
232         painter.drawLine(arrowStartNorthwest.x(), arrowStartNorthwest.y(), arrowStartNorthwest.x()-10, arrowStartNorthwest.y());
233     }
234
235     else
236     {
237         // North arrow
238         painter.drawLine(arrowStartNorth, arrowEndNorth);
239         painter.drawLine(arrowEndNorth.x(), arrowEndNorth.y(), arrowEndNorth.x()-5, arrowEndNorth.y()+10);
240         painter.drawLine(arrowEndNorth.x(), arrowEndNorth.y(), arrowEndNorth.x()+5, arrowEndNorth.y()+10);
241     }
242 }
243
244 /**
245   *This slot function is called when route start/stop button clicked.
246   */
247 void RouteSaveDialog::on_buttonRouteStartStop_clicked()
248 {
249     if ( buttonStatus == true )//If start button clicked
250     {
251         qDebug() << "__start button clicked";
252
253         //Clear variables
254         averageSpeed = 0.0;
255         speed = 0.0;
256         allSpeeds = 0.0;
257         speedCount = 1;
258
259         buttonStatus = false;
260         ui->buttonRouteStartStop->setIcon(*iconRouteStop);
261         location->startPollingGPS();
262         gpsStatus();
263     }
264     else //If stop button clicked
265     {
266         qDebug() << "__stop button clicked";
267         buttonStatus = true;
268         ui->buttonRouteStartStop->setIcon(*iconRouteStart);
269
270         //Satellite picture and label
271         ui->labelRouteSatelliteStatus->setText("Searching satellite");
272         ui->labelRouteSatelliteStatus->setVisible(0);
273         ui->labelRouteSatellitePicture->setVisible(0);
274         timerSatellitePicture->stop();
275
276         //Route picture and label
277         ui->labelRouteStatus->setVisible(0);
278         ui->labelRoutePicture->setVisible(0);
279         timerRoutePicture->stop();
280         location->stopPollingGPS();
281
282         //Set GPS speed labels in visible
283         ui->labelGpsSpeed->setVisible(0);
284         ui->labelGpsAvgSpeed->setVisible(0);
285
286         //GPS distance label
287         ui->labelDistance->setVisible(0);
288
289         //Stop route recording
290         gpsData->stopRouteRecording();
291
292         //User info label
293         ui->labelUserInfo->setText("Push start button");
294
295         fileName = "/home/user/MyDocs/speedfreak/route/routetemp.xml";
296         openRouteDialog();
297     }
298 }
299
300 /**
301   * This slot function is called when satellite picture timer timeout(400ms).
302   */
303 void RouteSaveDialog::timerSatellitePictureTimeout()
304 {
305     //If satellite picture visible.
306     if (ui->labelRouteSatellitePicture->isVisible() == 1)
307     {
308         ui->labelRouteSatelliteStatus->setVisible(0);
309         ui->labelRouteSatellitePicture->setVisible(0);
310     }
311     else
312     {
313         ui->labelRouteSatelliteStatus->setVisible(1);
314         ui->labelRouteSatellitePicture->setVisible(1);
315     }
316     timerSatellitePicture->start();
317 }
318
319 /**
320   * This slot function is called when route picture timer timeout(400ms).
321   */
322 void RouteSaveDialog::timerRoutePictureTimeout()
323 {
324     //If route picture visible.
325     if (ui->labelRoutePicture->isVisible() == 1)
326     {
327         ui->labelRouteStatus->setVisible(0);
328         ui->labelRoutePicture->setVisible(0);
329     }
330     else
331     {
332         ui->labelRouteStatus->setVisible(1);
333         ui->labelRoutePicture->setVisible(1);
334     }
335     timerRoutePicture->start();
336 }
337
338 /**
339   * This slot function is called when GPS update location.
340   */
341 void RouteSaveDialog::gpsStatus()
342 {
343     //IF GPS start button clicked
344     if (buttonStatus == false)
345     {
346         //ui->labelSignalStrength->setText(QString::number(location->getSignalStrength()));    //Returns average signal strength of satellites which are in use.
347
348         //If GPS find 4 or more satellite and signal stregth is 30 or more.
349         if (location->getSatellitesInUse() >= 4 && location->getSignalStrength() >= 30)
350         {
351             //Satellite picture and label
352             ui->labelRouteSatelliteStatus->setText("GPS Ready");
353             ui->labelRouteSatelliteStatus->setVisible(1);
354             ui->labelRouteSatellitePicture->setVisible(1);
355             timerSatellitePicture->stop();
356
357             //Route picture and label
358             ui->labelRouteStatus->setText("Recorded " + QString::number(gpsData->roundCounter) + " route point");
359             ui->labelUserInfo->setText("Recorded " + QString::number(gpsData->roundCounter) + " route point");
360             ui->labelRouteStatus->setVisible(1);
361             ui->labelRoutePicture->setVisible(1);
362             timerRoutePicture->start();
363
364             //Get GPS speed
365             speed = location->getSpeed();
366
367             //Get GPS track means direction
368             direction = gpsData->getDirection();
369             repaint();
370
371             //Set GPS speed
372             gpsSpeed.sprintf("%.0f", speed);
373             ui->labelGpsSpeed->setText(gpsSpeed + " km/h");
374             ui->labelGpsSpeed->setVisible(1);
375
376             //Set GPS average speed
377             allSpeeds += speed;
378             averageSpeed = allSpeeds/speedCount;
379             gpsSpeed.sprintf("%.0f",averageSpeed);
380             ui->labelGpsAvgSpeed->setText("Avg: " + gpsSpeed + " km/h");
381             ui->labelGpsAvgSpeed->setVisible(1);
382             speedCount++;
383
384             //Set distance traveled.
385             distanceString.sprintf("%.3f", gpsData->getDistanceTraveled());
386             ui->labelDistance->setText(distanceString + " km");
387             ui->labelDistance->setVisible(1);
388
389             //Start route recording
390             gpsData->startRouteRecording();
391         }
392         else //If GPS find less than 4 satellite or signal strength is poor.
393         {
394             //Satellite picture and label
395             ui->labelRouteSatelliteStatus->setText("Searching satellite");
396             ui->labelUserInfo->setText("Searching satellite");
397             ui->labelRouteSatelliteStatus->setVisible(1);
398             ui->labelRouteSatellitePicture->setVisible(1);
399             timerSatellitePicture->start();
400
401             //Route picture and label
402             ui->labelRouteStatus->setVisible(0);
403             ui->labelRoutePicture->setVisible(0);
404             timerRoutePicture->stop();
405
406             //Set GPS speed labels in visible
407             ui->labelGpsSpeed->setVisible(0);
408             ui->labelGpsAvgSpeed->setVisible(0);
409
410             //GPS distance label
411             ui->labelDistance->setVisible(0);
412         }
413     }
414     else //If stop button clicked
415     {
416         //Satellite picture and label
417         ui->labelRouteSatelliteStatus->setText("Searching satellite");
418         ui->labelUserInfo->setText("Push start button");
419         ui->labelRouteSatelliteStatus->setVisible(0);
420         ui->labelRouteSatellitePicture->setVisible(0);
421         timerSatellitePicture->stop();
422
423         //Route picture and label
424         ui->labelRouteStatus->setVisible(0);
425         ui->labelRoutePicture->setVisible(0);
426         timerRoutePicture->stop();
427
428         //Set GPS speed labels in visible
429         ui->labelGpsSpeed->setVisible(0);
430         ui->labelGpsAvgSpeed->setVisible(0);
431
432         //GPS distance label
433         ui->labelDistance->setVisible(0);
434     }
435 }
436
437 /**
438   * This slot function is called when routeDialog emit sendroute (sendPushButton).
439   *
440   * @param QString new name
441   * @param int i
442   */
443 void RouteSaveDialog::sendRoute(QString newName, int i)
444 {
445     emit sendroute(fileName, newName, i); //Emit mainwindow clientSendRoute
446 }
447
448 /**
449   * This slot function called when ever info button clicked.
450   */
451 void RouteSaveDialog::on_pushButtonInfo_clicked()
452 {
453     if(!helpRoutingDialog)
454     {
455         helpRoutingDialog = new HelpRoutingDialog;
456     }
457     connect(helpRoutingDialog, SIGNAL(rejected()), this, SLOT(killHelpDialog()));
458     helpRoutingDialog->show();
459 }
460
461 /**
462   * This slot function called when ever dialog rejected.
463   */
464 void RouteSaveDialog::killHelpDialog()
465 {
466     if(helpRoutingDialog)
467     {
468         qDebug() << "__Route save kill: helpRoutingDialog";
469         delete helpRoutingDialog;
470         helpRoutingDialog = NULL;
471     }
472 }
473
474 /**
475   * This slot function called when ever route dialog rejected.
476   */
477 void RouteSaveDialog::killRouteDialog()
478 {
479     if(routeDialog)
480     {
481         qDebug() << "__Route save kill: routeDialog";
482         delete routeDialog;
483         routeDialog = NULL;
484     }
485     if(calibrateDialog)
486     {
487         qDebug() << "__Route save kill: calibrateDialog";
488         delete calibrateDialog;
489         calibrateDialog = NULL;
490     }
491 }
492
493 /**
494   * This function return speed average.
495   *
496   * @return double average speed
497   */
498 double RouteSaveDialog::getAverageSpeed()
499 {
500     return averageSpeed;
501 }
502
503 /**
504   * This function return distance traveled in QString.
505   *
506   * @return QString distance traveled
507   */
508 QString RouteSaveDialog::getDistanceTraveled()
509 {
510     return distanceString;
511 }
512
513 /**
514   * This function set progressbar
515   *
516   * @param int i
517   */
518 void RouteSaveDialog::setProgressbar(int i)
519 {
520     qDebug() << "__setProgressbar: " + QString::number(i);
521     //qDebug() << i;
522     calibrateDialog->setProgressValue(i);
523     progressbarIteration++;
524 }
525
526 /**
527   * This slot function called when ever load route button clicked.
528   */
529 void RouteSaveDialog::on_buttonLoadRoute_clicked()
530 {
531     fileName = QFileDialog::getOpenFileName(this, tr("Open route"), "/home/user/MyDocs/speedfreak/route", "XML (*.xml)");
532     qDebug() << "__Opening: " + fileName;
533     openRouteDialog();//fileName);
534 }
535
536 /**
537   * This function open and show route.
538   */
539 void RouteSaveDialog::openRouteDialog()
540 {
541     if(fileName != "")
542     {
543         // Progress bar
544         if(!calibrateDialog)
545         {
546             calibrateDialog = new CalibrateDialog();
547         }
548
549         progressbarPoints = 100;
550         progressbarIteration = 0;
551         calibrateDialog->resetProgressValue();
552         calibrateDialog->setMaxValue( progressbarPoints );
553         calibrateDialog->setTitle("Calculating route...");
554         calibrateDialog->show();
555
556         if(!routeDialog)
557         {
558             routeDialog = new RouteDialog(this);
559         }
560
561         connect(routeDialog, SIGNAL(sendroute(QString, int)), this, SLOT(sendRoute(QString, int)));
562         connect(routeDialog, SIGNAL(progressbar(int)), this, SLOT(setProgressbar(int)));
563         connect(routeDialog, SIGNAL(rejected()), this, SLOT(killRouteDialog()));
564
565         if (routeDialog->readRouteFromFile( fileName ) == true)
566         {
567             calibrateDialog->close();
568             routeDialog->show();
569         }
570         else
571         {
572             calibrateDialog->close();
573         }
574     }
575 }