Bug fixing and added new scale for time axis.
[speedfreak] / Client / resultdialog.cpp
1 /*
2  * CarMainWindow main class
3  *
4  * @author     Janne Änäkkälä <janne.anakkala@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 "resultdialog.h"
10 #include "ui_resultdialog.h"
11 #include "usersettings.h"
12 #include "math.h"
13 #include <QPainter>
14 #include <QPicture>
15
16 const int DIAGRAM_WIDTH = 400;
17 const int DIAGRAM_HEIGHT = 300;
18
19 const int DIAGRAMGAP10KMH = 300;
20 const int DIAGRAMGAP20KMH = 150;
21 const int DIAGRAMGAP30KMH = 100;
22 const int DIAGRAMGAP40KMH = 75;
23 const int DIAGRAMGAP50KMH = 60;
24 const int DIAGRAMGAP60KMH = 50;
25 const double DIAGRAMGAP70KMH = 42.86;
26 const double DIAGRAMGAP80KMH = 37.5;
27 const double DIAGRAMGAP90KMH = 33.33;
28 const int DIAGRAMGAP100KMH = 30;
29
30 const int DIAGRAMGAP5S = 80;
31 const int DIAGRAMGAP10S = 40;
32 const int DIAGRAMGAP16S = 25;
33 const int DIAGRAMGAP20S = 20;
34
35 const QPoint diagramStemStart(70, 330);
36 const QPoint diagramStemEnd(70, 30);
37
38 const QPoint diagramHorizontalStart(70, 330);
39 const QPoint diagramHorizontalEnd(470, 330);
40
41 const int diagramGap = 30;
42
43 // Test arrays for changing speeds and times to the points in diagram
44 static const int speedArray[11] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
45 //static const int timeArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 10, 12};
46
47 // Test point array for the diagram.
48 QPoint points[11];
49
50 /**
51   * Constructor of this class.
52   * @param QWidget pointer to parent object. By default the value is NULL.
53   */
54 ResultDialog::ResultDialog(QWidget *parent) :
55     QDialog(parent),
56     ui(new Ui::ResultDialog)
57 {
58     ui->setupUi(this);
59     timeAxelLength = 10;
60     resultString = "";
61     speedList << "0" << "10" << "20" << "30" << "40" << "50" << "60" << "70" << "80" << "90" << "100" ;
62     timeList << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9" << "10" << "11"
63             << "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20";
64     this->diagramGapStem = DIAGRAMGAP100KMH;
65     this->diagramGapHorizontal = DIAGRAMGAP20S;
66     for (int i = 0; i < 11; i++)
67     {
68         timeArray[i] = 0;
69     }
70
71     if (loginSaved())
72     {
73         ui->pushButtonSend->setEnabled(true);
74     }
75     else
76     {
77         ui->pushButtonSend->setEnabled(false);
78     }
79 }
80
81 /**
82   * Destructor of this class.  Should be used to release all allocated resources.
83   */
84 ResultDialog::~ResultDialog()
85 {
86     delete ui;
87 }
88
89 void ResultDialog::changeEvent(QEvent *e)
90 {
91     QDialog::changeEvent(e);
92     switch (e->type()) {
93     case QEvent::LanguageChange:
94         ui->retranslateUi(this);
95         break;
96     default:
97         break;
98     }
99 }
100
101 /**
102   * Draws speed diagram to the UI
103   * @param QPaintEvent
104  */
105 void ResultDialog::paintEvent(QPaintEvent *)
106 {
107     setHeaders();
108     QPainter painter(this);
109
110     painter.setRenderHint(QPainter::Antialiasing, true);
111     painter.setPen(QPen((Qt::gray),2));
112     QFont font;
113     QFont fontForResult;
114     font.setPixelSize(12);
115     painter.setFont(font);
116     painter.setBrush(QBrush((Qt::yellow), Qt::SolidPattern));
117
118     fontForResult.setPixelSize(50);
119     painter.setFont(fontForResult);
120     painter.drawText(diagramStemStart.x() + 50, diagramStemStart.y() - 150, resultString);
121     painter.setFont(font);
122
123     painter.setPen(QPen((Qt::darkCyan),2));
124     painter.drawLine(diagramStemStart, diagramStemEnd);
125     painter.drawLine(diagramHorizontalStart, diagramHorizontalEnd);
126     painter.drawText(diagramStemStart.x() - 50, diagramStemEnd.y() + 100, "S");
127     painter.drawText(diagramStemStart.x() - 50, diagramStemEnd.y() + 115, "P");
128     painter.drawText(diagramStemStart.x() - 50, diagramStemEnd.y() + 130, "E");
129     painter.drawText(diagramStemStart.x() - 50, diagramStemEnd.y() + 145, "E");
130     painter.drawText(diagramStemStart.x() - 50, diagramStemEnd.y() + 160, "D");
131     painter.drawText(diagramStemStart.x() - 65, diagramStemEnd.y() + 180, "(km/h)");
132
133     painter.drawText(diagramStemStart.x() + 140, diagramStemStart.y() + 40, "T");
134     painter.drawText(diagramStemStart.x() + 150, diagramStemStart.y() + 40, "I");
135     painter.drawText(diagramStemStart.x() + 155, diagramStemStart.y() + 40, "M");
136     painter.drawText(diagramStemStart.x() + 165, diagramStemStart.y() + 40, "E");
137     painter.drawText(diagramStemStart.x() + 180, diagramStemStart.y() + 40, "(s)");
138
139     int currentX = 0;
140     int currentY = diagramStemStart.y();
141
142     painter.setPen(QPen((Qt::darkCyan),1));
143
144     int i = 0;
145     // Draws diagram's X-axel
146     while (currentX <= DIAGRAM_WIDTH)
147     {
148         painter.drawLine(currentX + diagramStemStart.x(), currentY, currentX + diagramStemStart.x(), currentY - 300);
149         painter.drawText(currentX + diagramStemStart.x() - 3, currentY + 20, timeList[i]);
150         currentX += this->diagramGapHorizontal;
151         i++;
152     }
153
154     currentX = diagramStemStart.x();
155     currentY = 0;
156
157     i = 0;
158     // Draws diagram's Y-axel
159     while (currentY >= -(DIAGRAM_HEIGHT))
160     {
161         painter.drawLine(currentX, diagramStemStart.y() + currentY, currentX+400, diagramStemStart.y() + currentY);
162         painter.drawText(currentX - 25, diagramStemStart.y() + currentY + 3, speedList[i]);
163         currentY -= this->diagramGapStem;
164         i++;
165     }
166
167     painter.setPen(QPen((Qt::red),2));
168
169     int pointsToShow = 0;
170     bool pointsUnderDiagramWidth = true;
171
172     for (i = 0; i < 11 ; i++)
173     {
174         if (points[i].x() > diagramHorizontalEnd.x())
175         {
176             pointsToShow = i;
177             pointsUnderDiagramWidth = false;
178             i = 10;
179         }
180     }
181
182     // Draws result line to the diagram
183     if (pointsUnderDiagramWidth)
184     {
185         painter.drawPolyline(points, this->getTargetChoice() + 1);
186     }
187
188     else
189     {
190         painter.drawPolyline(points, pointsToShow);
191     }
192 }
193
194 /**
195   * Change the given speed and time to the point for the diagram.
196   * @param aSpeed is speed which need to change, aTime is time in seconds which need to change.
197   * @return point is calculated from aSpeed and aTime.
198   */
199 QPoint ResultDialog::changeMeasuresToDiagramPoint(int aSpeed, qreal aTime)
200 {
201     QPoint point;
202
203     int speedAsPixels;
204     int timeAsPixels;
205
206     // Calculate speed and time to the point which can be drawn to the diagram
207     speedAsPixels = (DIAGRAM_HEIGHT*aSpeed) / (this->getTargetChoice() * 10);
208     timeAsPixels = DIAGRAM_WIDTH*aTime/timeAxelLength;
209
210     point.setY(diagramStemStart.y()-speedAsPixels);
211     point.setX(diagramStemStart.x()+timeAsPixels);
212
213     return point;
214 }
215
216 /**
217   * Sets result times in to the labels.
218   */
219 void ResultDialog::setTimesIntoLabels()
220 {
221     QString time, timeInteger;
222     timeInteger.setNum(timeArray[4]);
223     time = "0 - 40 km/h: ";
224     time.append(timeInteger);
225     ui->labelResult40kmh->setText(time);
226
227     timeInteger.setNum(timeArray[3]);
228     time = "0 - 30 km/h: ";
229     time.append(timeInteger);
230     ui->labelResult30kmh->setText(time);
231
232     timeInteger.setNum(timeArray[2]);
233     time = "0 - 20 km/h: ";
234     time.append(timeInteger);
235     ui->labelResult20kmh->setText(time);
236
237     timeInteger.setNum(timeArray[1]);
238     time = "0 - 10 km/h: ";
239     time.append(timeInteger);
240     ui->labelResult10kmh->setText(time);
241
242     timeInteger.setNum(timeArray[6]);
243     time = "0 - 60 km/h: ";
244     time.append(timeInteger);
245     ui->labelResult60kmh->setText(time);
246
247     timeInteger.setNum(timeArray[5]);
248     time = "0 - 50 km/h: ";
249     time.append(timeInteger);
250     ui->labelResult50kmh->setText(time);
251
252     timeInteger.setNum(timeArray[7]);
253     time = "0 - 70 km/h: ";
254     time.append(timeInteger);
255     ui->labelResult70kmh->setText(time);
256
257     timeInteger.setNum(timeArray[8]);
258     time = "0 - 80 km/h: ";
259     time.append(timeInteger);
260     ui->labelResult80kmh->setText(time);
261
262     timeInteger.setNum(timeArray[9]);
263     time = "0 - 90 km/h: ";
264     time.append(timeInteger);
265     ui->labelResult90kmh->setText(time);
266
267     timeInteger.setNum(timeArray[10]);
268     time = "0 - 100 km/h: ";
269     time.append(timeInteger);
270     ui->labelResult100kmh->setText(time);
271
272     showOrHideLabels();
273 }
274
275 /**
276   * Sets right timeAxelLength value depending the time which
277   * has spent to reach target speed.
278   */
279 void ResultDialog::setTimeAxelLength(int pChoice)
280 {
281     if (timeArray[pChoice] <= 5)
282     {
283         timeAxelLength = 5;
284     }
285
286     else if (timeArray[pChoice] <= 10)
287     {
288         timeAxelLength = 10;
289     }
290
291     else if (timeArray[pChoice] <= 15)
292     {
293         timeAxelLength = 15;
294     }
295
296     else
297     {
298         timeAxelLength = 20;
299     }
300 }
301
302 /**
303   * This slot function close result dialog when new run -button has been clicked.
304   */
305 void ResultDialog::on_pushButtonNew_clicked()
306 {
307     for (int i = 0; i < 11; i++)
308     {
309         timeArray[i] = 0;
310     }
311     resultString = "";
312     this->close();
313 }
314
315 /**
316   * This slot function emits sendresult signal for sending results to server when
317   * send results -button has been clicked.
318   */
319 void ResultDialog::on_pushButtonSend_clicked()
320 {
321     emit sendresult(timeArray[this->getTargetChoice()]);
322 }
323
324 /**
325   * This public function sets diagram's stem gap
326   * @param pValue is the speed value which determines diagram gap's value
327   */
328 void ResultDialog::setEnd(int pValue)
329 {
330     for (int i = 0; i < 11; i++)
331     {
332         timeArray[i] = 0;
333     }
334     resultString = "";
335
336     switch (pValue)
337     {
338     case 10:
339         this->diagramGapStem = DIAGRAMGAP10KMH;
340         break;
341
342     case 20:
343         this->diagramGapStem = DIAGRAMGAP20KMH;
344         break;
345
346     case 30:
347         this->diagramGapStem = DIAGRAMGAP30KMH;
348         break;
349
350     case 40:
351         this->diagramGapStem = DIAGRAMGAP40KMH;
352         break;
353
354     case 50:
355         this->diagramGapStem = DIAGRAMGAP50KMH;
356         break;
357
358     case 60:
359         this->diagramGapStem = DIAGRAMGAP60KMH;
360         break;
361
362     case 70:
363         this->diagramGapStem = DIAGRAMGAP70KMH;
364         break;
365
366     case 80:
367         this->diagramGapStem = DIAGRAMGAP80KMH;
368         break;
369
370     case 90:
371         this->diagramGapStem = DIAGRAMGAP90KMH;
372         break;
373
374     case 100:
375         this->diagramGapStem = DIAGRAMGAP100KMH;
376         break;
377
378     default:
379         this->diagramGapStem = DIAGRAMGAP100KMH;
380         break;
381     }
382 }
383
384 /**
385   * This public function stores time in timeArray
386   * @param pSpeed is the speed value at the time so we know where store time
387   * @param pTime is the result which needs to be store in timeArray
388   */
389 void ResultDialog::setValue(int pSpeed, double pTime)
390 {
391     //timeArray[0] = 0;
392     if (pTime <= 5.0)
393     {
394         this->diagramGapHorizontal = DIAGRAMGAP5S;
395     }
396
397     else if (pTime <= 10.0)
398     {
399        this->diagramGapHorizontal = DIAGRAMGAP10S;
400     }
401
402     else if (pTime <= 16.0)
403     {
404         this->diagramGapHorizontal = DIAGRAMGAP16S;
405     }
406
407     else
408     {
409         this->diagramGapHorizontal = DIAGRAMGAP20S;
410     }
411
412     switch (pSpeed)
413     {
414     case 10:
415         timeArray[1] = pTime;
416         break;
417     case 20:
418         timeArray[2] = pTime;
419         break;
420     case 30:
421         timeArray[3] = pTime;
422         break;
423     case 40:
424         timeArray[4] = pTime;
425         break;
426     case 50:
427         timeArray[5] = pTime;
428         break;
429     case 60:
430         timeArray[6] = pTime;
431         break;
432     case 70:
433         timeArray[7] = pTime;
434         break;
435     case 80:
436         timeArray[8] = pTime;
437         break;
438     case 90:
439         timeArray[9] = pTime;
440         break;
441     case 100:
442         timeArray[10] = pTime;
443         break;
444     }
445
446     setTimeAxelLength(getTargetChoice());
447
448     for (int i = 0; i < 11; i++)
449     {
450         points[i] = changeMeasuresToDiagramPoint(speedArray[i], timeArray[i]);
451     }
452
453     setTimesIntoLabels();
454     this->repaint();
455 }
456
457 /**
458   * Sets dialog's heading and result text
459   */
460 void ResultDialog::setHeaders()
461 {
462     //QString resultString;
463     resultString.append("Time was ");
464
465     QString time;
466
467     if (this->diagramGapStem == DIAGRAMGAP100KMH)
468     {
469         time.sprintf("%.2f", timeArray[10]);
470         resultString.append(time);
471         this->setWindowTitle("Result for accelerating 100 km/h");
472     }
473
474     else if (this->diagramGapStem == DIAGRAMGAP90KMH)
475     {
476         time.sprintf("%.2f", timeArray[9]);
477         resultString.append(time);
478         this->setWindowTitle("Result for accelerating 90 km/h");
479     }
480
481     else if (this->diagramGapStem == DIAGRAMGAP80KMH)
482     {
483         time.sprintf("%.2f", timeArray[8]);
484         resultString.append(time);
485         this->setWindowTitle("Result for accelerating 80 km/h");
486     }
487
488     else if (this->diagramGapStem == DIAGRAMGAP70KMH)
489     {
490         time.sprintf("%.2f", timeArray[7]);
491         resultString.append(time);
492         this->setWindowTitle("Result for accelerating 70 km/h");
493     }
494
495     else if (this->diagramGapStem == DIAGRAMGAP60KMH)
496     {
497         time.sprintf("%.2f", timeArray[6]);
498         resultString.append(time);
499         this->setWindowTitle("Result for accelerating 60 km/h");
500     }
501
502     else if (this->diagramGapStem == DIAGRAMGAP50KMH)
503     {
504         time.sprintf("%.2f", timeArray[5]);
505         resultString.append(time);
506         this->setWindowTitle("Result for accelerating 50 km/h");
507     }
508
509     else if (this->diagramGapStem == DIAGRAMGAP40KMH)
510     {
511         time.sprintf("%.2f", timeArray[4]);
512         resultString.append(time);
513         this->setWindowTitle("Result for accelerating 40 km/h");
514     }
515
516     else if (this->diagramGapStem == DIAGRAMGAP30KMH)
517     {
518         time.sprintf("%.2f", timeArray[3]);
519         resultString.append(time);
520         this->setWindowTitle("Result for accelerating 30 km/h");
521     }
522
523     else if (this->diagramGapStem == DIAGRAMGAP20KMH)
524     {
525         time.sprintf("%.2f", timeArray[2]);
526         resultString.append(time);
527         this->setWindowTitle("Result for accelerating 20 km/h");
528     }
529
530     else
531     {
532         time.sprintf("%.2f", timeArray[1]);
533         resultString.append(time);
534         this->setWindowTitle("Result for accelerating 10 km/h");
535     }
536 }
537
538 /**
539   * Shows only wanted results and hides
540   * unwanted
541   */
542 void ResultDialog::showOrHideLabels()
543 {
544     if (this->diagramGapStem == DIAGRAMGAP10KMH)
545     {
546         ui->labelResult20kmh->hide();
547         ui->labelResult30kmh->hide();
548         ui->labelResult40kmh->hide();
549         ui->labelResult50kmh->hide();
550         ui->labelResult60kmh->hide();
551         ui->labelResult70kmh->hide();
552         ui->labelResult80kmh->hide();
553         ui->labelResult90kmh->hide();
554         ui->labelResult100kmh->hide();
555     }
556
557     else if (this->diagramGapStem == DIAGRAMGAP20KMH)
558     {
559         ui->labelResult10kmh->show();
560         ui->labelResult20kmh->show();
561         ui->labelResult30kmh->hide();
562         ui->labelResult40kmh->hide();
563         ui->labelResult50kmh->hide();
564         ui->labelResult60kmh->hide();
565         ui->labelResult70kmh->hide();
566         ui->labelResult80kmh->hide();
567         ui->labelResult90kmh->hide();
568         ui->labelResult100kmh->hide();
569     }
570
571     else if (this->diagramGapStem == DIAGRAMGAP30KMH)
572     {
573         ui->labelResult10kmh->show();
574         ui->labelResult20kmh->show();
575         ui->labelResult30kmh->show();
576         ui->labelResult40kmh->hide();
577         ui->labelResult50kmh->hide();
578         ui->labelResult60kmh->hide();
579         ui->labelResult70kmh->hide();
580         ui->labelResult80kmh->hide();
581         ui->labelResult90kmh->hide();
582         ui->labelResult100kmh->hide();
583     }
584
585     else if (this->diagramGapStem == DIAGRAMGAP40KMH)
586     {
587         ui->labelResult10kmh->show();
588         ui->labelResult20kmh->show();
589         ui->labelResult30kmh->show();
590         ui->labelResult40kmh->show();
591         ui->labelResult50kmh->hide();
592         ui->labelResult60kmh->hide();
593         ui->labelResult70kmh->hide();
594         ui->labelResult80kmh->hide();
595         ui->labelResult90kmh->hide();
596         ui->labelResult100kmh->hide();
597     }
598
599     else if (this->diagramGapStem == DIAGRAMGAP50KMH)
600     {
601         ui->labelResult10kmh->show();
602         ui->labelResult20kmh->show();
603         ui->labelResult30kmh->show();
604         ui->labelResult40kmh->show();
605         ui->labelResult50kmh->show();
606         ui->labelResult60kmh->hide();
607         ui->labelResult70kmh->hide();
608         ui->labelResult80kmh->hide();
609         ui->labelResult90kmh->hide();
610         ui->labelResult100kmh->hide();
611     }
612
613     else if (this->diagramGapStem == DIAGRAMGAP60KMH)
614     {
615         ui->labelResult10kmh->show();
616         ui->labelResult20kmh->show();
617         ui->labelResult30kmh->show();
618         ui->labelResult40kmh->show();
619         ui->labelResult50kmh->show();
620         ui->labelResult60kmh->show();
621         ui->labelResult70kmh->hide();
622         ui->labelResult80kmh->hide();
623         ui->labelResult90kmh->hide();
624         ui->labelResult100kmh->hide();
625     }
626
627     else if (this->diagramGapStem == DIAGRAMGAP70KMH)
628     {
629         ui->labelResult10kmh->show();
630         ui->labelResult20kmh->show();
631         ui->labelResult30kmh->show();
632         ui->labelResult40kmh->show();
633         ui->labelResult50kmh->show();
634         ui->labelResult60kmh->show();
635         ui->labelResult70kmh->show();
636         ui->labelResult80kmh->hide();
637         ui->labelResult90kmh->hide();
638         ui->labelResult100kmh->hide();
639     }
640
641     else if (this->diagramGapStem == DIAGRAMGAP80KMH)
642     {
643         ui->labelResult10kmh->show();
644         ui->labelResult20kmh->show();
645         ui->labelResult30kmh->show();
646         ui->labelResult40kmh->show();
647         ui->labelResult50kmh->show();
648         ui->labelResult60kmh->show();
649         ui->labelResult70kmh->show();
650         ui->labelResult80kmh->show();
651         ui->labelResult90kmh->hide();
652         ui->labelResult100kmh->hide();
653     }
654
655     else if (this->diagramGapStem == DIAGRAMGAP90KMH)
656     {
657         ui->labelResult10kmh->show();
658         ui->labelResult20kmh->show();
659         ui->labelResult30kmh->show();
660         ui->labelResult40kmh->show();
661         ui->labelResult50kmh->show();
662         ui->labelResult60kmh->show();
663         ui->labelResult70kmh->show();
664         ui->labelResult80kmh->show();
665         ui->labelResult90kmh->show();
666         ui->labelResult100kmh->hide();
667     }
668
669     else
670     {
671         ui->labelResult10kmh->show();
672         ui->labelResult20kmh->show();
673         ui->labelResult30kmh->show();
674         ui->labelResult40kmh->show();
675         ui->labelResult50kmh->show();
676         ui->labelResult60kmh->show();
677         ui->labelResult70kmh->show();
678         ui->labelResult80kmh->show();
679         ui->labelResult90kmh->show();
680         ui->labelResult100kmh->show();
681     }
682 }
683
684 /**
685   * Checks which target speed has been choosed
686   * @return targetChoice which tells to caller integer value about the target speed
687   * e.g. 20 km/h is value 2 and 60 km/h is value 6
688   */
689 int ResultDialog::getTargetChoice()
690 {
691
692     int targetChoice = 0;
693
694     if (this->diagramGapStem == DIAGRAMGAP10KMH)
695     {
696        targetChoice = 1;
697     }
698
699     else if (this->diagramGapStem == DIAGRAMGAP20KMH)
700     {
701         targetChoice = 2;
702     }
703
704     else if (this->diagramGapStem == DIAGRAMGAP30KMH)
705     {
706         targetChoice = 3;
707     }
708
709     else if (this->diagramGapStem == DIAGRAMGAP40KMH)
710     {
711         targetChoice = 4;
712     }
713
714     else if (this->diagramGapStem == DIAGRAMGAP50KMH)
715     {
716         targetChoice = 5;
717     }
718
719     else if (this->diagramGapStem == DIAGRAMGAP60KMH)
720     {
721         targetChoice = 6;
722     }
723
724     else if (this->diagramGapStem == DIAGRAMGAP70KMH)
725     {
726         targetChoice = 7;
727     }
728
729     else if (this->diagramGapStem == DIAGRAMGAP80KMH)
730     {
731         targetChoice = 8;
732     }
733
734     else if (this->diagramGapStem == DIAGRAMGAP90KMH)
735     {
736         targetChoice = 9;
737     }
738
739     else
740     {
741         targetChoice = 10;
742     }
743     return targetChoice;
744 }