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