85282b5addeb1a89a5594e15a3369ed2059e0984
[speedfreak] / Client / carmainwindow.cpp
1 /*
2  * CarMainWindow main class
3  *
4  * @author     Toni Jussila <toni.jussila@fudeco.com>
5  * @author     Janne Änäkkälä <janne.anakkala@fudeco.com>
6  * @author     Tiina Kivilinna-Korhola <tiina.kivilinna-korhola@fudeco.com>
7  * @author     Olavi Pulkkinen <olavi.pulkkinen@fudeco.com>
8  * @copyright  (c) 2010 Speed Freak team
9  * @license    http://opensource.org/licenses/gpl-license.php GNU Public License
10  */
11
12 #include "carmainwindow.h"
13 #include "math.h"
14
15 /**
16   *Constructor of this class.
17   *@param QWidget pointer to parent object. By default the value is NULL.
18   */
19 CarMainWindow::CarMainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::CarMainWindow)
20 {
21     ui->setupUi(this);
22     ui->tabWidget->setCurrentWidget(this->ui->StartTab);
23     //result = new ResultDialog();
24     //measure = new MeasureDialog();
25     xmlreader = new XmlReader();
26
27     initComboBoxStartTabUnits();
28     initListViewStartTabAccelerationCategories();
29
30     myLogin = new LoginWindow(this);
31     myRegistration = new Registration(this);
32     xmlwriter = new XmlWriter();
33     manager = new QNetworkAccessManager(this);
34     connect(myRegistration,SIGNAL(sendregistration()),this,SLOT(registrate()));
35
36     time = 0;
37     speed = 0;
38     timer = new QTimer();
39
40     accelerometer = new Accelerometer();
41     accelerometer->setSampleRate(100);
42
43     measures = new Measures();
44     this->initializeMeasures();
45
46     timer->setInterval(300);
47
48     connect(this->timer, SIGNAL(timeout()), this, SLOT(after_timeout()));
49     connect(myLogin, SIGNAL( userNameChanged()), this, SLOT(updateUserName()));
50
51     ui->labelMeasureTabResult->hide();
52
53     this->setWindowTitle("Speed Freak");
54
55 }
56
57 /**
58   *Destructor of this class. Should be used to release all allocated resources.
59   */
60 CarMainWindow::~CarMainWindow()
61 {
62     delete ui;
63     //delete result;
64     //delete measure;
65     delete xmlreader;
66     delete xmlwriter;
67     delete manager;
68 }
69
70 /**
71   *This function is used to .
72   *@param
73   */
74 void CarMainWindow::changeEvent(QEvent *e)
75 {
76     QMainWindow::changeEvent(e);
77     switch (e->type()) {
78     case QEvent::LanguageChange:
79         ui->retranslateUi(this);
80         break;
81     default:
82         break;
83     }
84 }
85
86 /**
87   *This slot function is called when ever list view is update. Start-tab view.
88   */
89 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
90 {
91     QString str = index.data().toString();
92     QStringList list = str.split("-");
93     QStringList list2 = list[1].split(" ");
94
95     ui->lineEditStartTabMin->setText(list[0]);
96     ui->lineEditStartTabMax->setText(list2[0]);
97     updateComboBoxStartTabUnits(list2[1]);
98 }
99
100 /**
101   *This slot function is called when ever auto start button clicked. Start-tab view.
102   */
103 void CarMainWindow::on_autoStartButton_clicked()
104 {
105
106     //delete measure;
107     //measure = NULL;
108     //measure = new MeasureDialog();
109    // connect(measure, SIGNAL(speedAchieved()), this, SLOT(openResultView()));
110     accelerometer->start();
111     timer->start();
112     // Show measure dialog.
113     //measure->show();
114     ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
115 }
116
117 /**
118   *This slot function is called when ever list view is update. Start-tab view.
119   *@param QString unit.
120   */
121 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
122 {
123     ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
124 }
125
126 /**
127   *This function is used to init unit combobox. Start-tab view.
128   */
129 void CarMainWindow::initComboBoxStartTabUnits()
130 {
131     units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
132     ui->comboBoxStartTabUnits->addItems(units);
133 }
134
135 /**
136   *This function is used to set items to unit combobox. Start-tab view.
137   *@param QStringlist units
138   */
139 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
140 {
141     ui->comboBoxStartTabUnits->addItems(units);
142 }
143
144 /**
145   *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
146   */
147 void CarMainWindow::initListViewStartTabAccelerationCategories()
148 {
149     accelerationCategoriesStartTab << "0-40 km/h" << "0-100 km/h"; //<< "0-1/4 Mile" << "0-1/8 Mile" << "0-50 km" << "50-100 Mile" << "0-60 Mph" << "0-100 m" << "0-50 ft" << "0-50 yrd" << "0-500 in";
150     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
151     ui->listViewStartTabAccelerationCategories->setModel(model);
152 }
153
154 /**
155   *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
156   *@param QStringlist accelerationCategoriesStartTab
157   */
158 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
159 {
160     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
161     ui->listViewStartTabAccelerationCategories->setModel(model);
162 }
163
164 /**
165   *This function is used to set items to category combobox. Top-tab view.
166   *@param
167   */
168 void CarMainWindow::setCategoryCompoBox()
169 {
170     ui->comboBoxTopCategory->addItems(xmlreader->getCategoryList());
171 }
172
173 /**
174   *This function is used to set items to labelTopList. Top-tab view.
175   *@param QString category
176   */
177 void CarMainWindow::setListViewTopList(QString category, int size)
178 {
179     QString topList;
180     topList.append( xmlreader->getTopList(category, size));
181     ui->labelTopList->setText(topList);
182 }
183
184 /**
185   *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
186   */
187 void CarMainWindow::openResultView()
188 {
189     //result->saveMeasuresToArray(measure->measures);
190     // Show result dialog.
191     //result->show();
192     ui->pushButtonSendResult->setEnabled(true);
193     QString timeInteger;
194     timeInteger.setNum(this->measures->getTime40kmh());
195     //time = "0 - 40 km/h: ";
196     //time.append(timeInteger);
197     //ui->labelResult40kmh->setText(time);
198     ui->labelMeasureTabResult->show();
199     ui->labelMeasureTabResult->setText(timeInteger);
200     //ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
201 }
202
203 /**
204   *This slot function is called when registrate button is clicked.
205   */
206 void CarMainWindow::on_registratePushButton_clicked()
207 {
208     myRegistration->show();
209 }
210
211 /**
212   *This slot function is called when ever refresh button clicked. Top-tab view.
213   */
214 void CarMainWindow::on_buttonTopRefresh_clicked()
215 {
216     requestCategories();
217     setCategoryCompoBox();
218 }
219
220 /**
221   *This slot function is called when ever category combobox current index changed. Top-tab view.
222   *@param QString category
223   *@todo Check where limitNr is taken.
224   */
225 void CarMainWindow::on_comboBoxTopCategory_currentIndexChanged(QString category)
226 {
227     int limitNr = 5;                    //replace with real value?
228     QString limit = QString::number(limitNr);
229     category = "acceleration-0-100";    //replace with real value from category list/top window
230     requestTopList(category, limit);
231     setListViewTopList(category,10);
232 }
233
234 /**
235   *This slot function is called when ever category combobox activated. Top-tab view.
236   *@param QString category
237   */
238 void CarMainWindow::on_comboBoxTopCategory_activated(QString category)
239 {
240     setListViewTopList(category,10);
241 }
242
243 /**
244   *This slot function is called when set/change user button is clicked.
245   */
246 void CarMainWindow::on_setUserPushButton_clicked()
247 {
248     myLogin->show();
249 }
250
251 /**
252   *@brief Sends registration information to the server in xml format.
253   *Reads user name, password and emaol address from resuldialogs internal variables.
254   *@todo Replace msg box with better reaction to server`s responce.
255   */
256 void CarMainWindow::registrate()
257 {
258     qDebug() << "_registrate" ;
259     qDebug() << this->myRegistration->getUserName() << "+" << this->myRegistration->getPassword() << "+" << this->myRegistration->getEmail();
260
261     QBuffer *regbuffer = new QBuffer();
262     QUrl qurl("http://api.speedfreak-app.com/api/register");
263     QNetworkRequest request(qurl);
264     qDebug() << qurl.toString();
265     QNetworkReply *currentDownload;
266
267     regbuffer->open(QBuffer::ReadWrite);
268     xmlwriter->writeRegistering(regbuffer,
269                       this->myRegistration->getUserName(),
270                       this->myRegistration->getPassword(),
271                       this->myRegistration->getEmail());
272     //Tmp msgbox - later server responce
273     QMessageBox::about(this,"Registrate",this->myRegistration->getUserName() + this->myRegistration->getPassword() + this->myRegistration->getEmail());
274
275     currentDownload = manager->post(request, ("xml=" + regbuffer->data()));
276     qDebug() << "carmainwindow: regbuffer->data(): " << regbuffer->data();
277
278     connect(currentDownload,SIGNAL(finished()),this,SLOT(ackOfRegistration()));
279     connect(currentDownload,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(errorFromServer(QNetworkReply::NetworkError)));
280
281     regbuffer->close();
282 }
283
284
285 /**
286   *@brief Sends result(s) to the server in xml format.
287   *Send authentication information in the header.
288   *@todo Read category elsewhere.
289   */
290 void CarMainWindow::sendResultXml()
291 {
292     qDebug() << "_sendResultXml";
293
294     QBuffer *xmlbuffer = new QBuffer();
295     QString category_name = "acceleration-0-100";    //replace with real value from category list
296
297     QUrl qurl("http://api.speedfreak-app.com/api/update/" + category_name);
298     qDebug() << qurl.toString();
299     QNetworkRequest request(qurl);
300     QNetworkReply *currentDownload;
301
302     xmlbuffer->open(QBuffer::ReadWrite);
303     xmlwriter->writeResult(xmlbuffer);
304     qDebug() << "carmainwindow: xmlbuffer->data(): " << xmlbuffer->data();
305
306     QString credentials = this->myRegistration->getUserName() + ":" + this->myRegistration->getPassword();
307     credentials = "Basic " + credentials.toAscii().toBase64();
308     request.setRawHeader(QByteArray("Authorization"),credentials.toAscii());
309
310     currentDownload = manager->post(request, ("xml=" + xmlbuffer->data()));
311     connect(currentDownload,SIGNAL(finished()),this,SLOT(ackOfResult()));
312     connect(currentDownload,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(errorFromServer(QNetworkReply::NetworkError)));
313
314     xmlbuffer->close();
315 }
316
317 /**
318   *@brief Request the Top10List of certain category from the server.
319   *Send authentication information in the header.
320   *@param Category of results.
321   *@param Limit, the number of results.
322   */
323 void CarMainWindow::requestTopList(QString category, QString limit)
324 {
325     qDebug() << "_requestTopList" ;
326
327     QString urlBase = "http://api.speedfreak-app.com/api/results/";
328     QUrl qurl(urlBase + category + "/" + limit);
329     qDebug() << qurl.toString();
330     QNetworkRequest request(qurl);
331     QNetworkReply *currentDownload;
332
333     QString credentials = this->myRegistration->getUserName() + ":" + this->myRegistration->getPassword();
334     credentials = "Basic " + credentials.toAscii().toBase64();
335     request.setRawHeader(QByteArray("Authorization"),credentials.toAscii());
336
337     currentDownload = manager->post(request, ("data=" ));
338     connect(currentDownload,SIGNAL(finished()),this,SLOT(ackOfToplist()));
339     connect(currentDownload,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(errorFromServer(QNetworkReply::NetworkError)));
340 }
341
342
343 /**
344   *@brief Request categories list from the server.
345   *Send authentication information in the header.
346   */
347 void CarMainWindow::requestCategories()
348 {
349     qDebug() << "_requestCategories" ;
350
351     QUrl qurl("http://api.speedfreak-app.com/api/categories/");
352     qDebug() << qurl.toString();
353     QNetworkRequest request(qurl);
354     QNetworkReply *currentDownload;
355
356     QString credentials = this->myRegistration->getUserName() + ":" + this->myRegistration->getPassword();
357     credentials = "Basic " + credentials.toAscii().toBase64();
358     request.setRawHeader(QByteArray("Authorization"),credentials.toAscii());
359
360     currentDownload = manager->post(request, ("data=" ));
361     connect(currentDownload,SIGNAL(finished()),this,SLOT(ackOfCategories()));
362     connect(currentDownload,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(errorFromServer(QNetworkReply::NetworkError)));
363 }
364
365
366 /**
367   *@brief React to servers responce after result has been sent.
368   *@todo Implement consequencies of reply.
369   */
370 void CarMainWindow::ackOfResult()
371 {
372     qDebug() << "_ackOfResult";
373
374     QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
375     qDebug() << reply->readAll();
376     QNetworkReply::NetworkError errorcode;
377     errorcode = reply->error();
378     if(errorcode != 0) {
379         qDebug() << errorcode << reply->errorString();
380     }
381     else {
382         qDebug() << "errorcode=0";
383     }
384 }
385
386
387 /**
388   *@brief React to servers responce after registration has been sent.
389   *@todo Implement consequencies of reply.
390   */
391 void CarMainWindow::ackOfRegistration()
392 {
393     qDebug() << "_ackOfRegistration";
394
395     QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
396     qDebug() << reply->readAll();
397     QNetworkReply::NetworkError errorcode;
398     errorcode = reply->error();
399     if(errorcode != 0) {
400         qDebug() <<  "errorcode:" << errorcode << reply->errorString();
401     }
402     else {
403         qDebug() << "errorcode=0";
404     }
405 }
406
407
408 /**
409   *@brief React to servers responce after request for categories has been sent.
410   *@todo Implement reply`s feeding to categories list.
411   */
412 void CarMainWindow::ackOfCategories()
413 {
414     qDebug() << "_ackOfCategories";
415
416     QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
417     qDebug() << reply->readAll();
418     QNetworkReply::NetworkError errorcode;
419     errorcode = reply->error();
420     if(errorcode != 0) {
421         qDebug() <<  "errorcode:" << errorcode << reply->errorString();
422     }
423     else {
424         qDebug() << "errorcode=0";
425     }
426 }
427
428 /**
429   *@brief Reports errors, when server has sent error signal.
430   */
431 void CarMainWindow::errorFromServer(QNetworkReply::NetworkError errorcode)
432 {
433     qDebug() << "_errorFromServer";
434
435     if(errorcode != 0) {
436         qDebug() << errorcode;
437     }
438     else {
439         qDebug() << errorcode;
440     }
441 }
442
443
444 /**
445   *@brief React to servers responce after request of TopList in certain category has been sent.
446   *@todo Implement routing reply`s contents to UI.
447   */
448 void CarMainWindow::ackOfToplist()
449 {
450     qDebug() << "_ackOfToplist";
451
452     QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
453     xmlreader->xmlRead(reply);
454     qDebug() << reply->readAll();
455     QNetworkReply::NetworkError errorcode;
456     errorcode = reply->error();
457     if(errorcode != 0) {
458         qDebug() << errorcode << reply->errorString();
459     }
460     else {
461         qDebug() << "errorcode=0";
462     }
463 }
464
465
466 /**
467   *@brief Just for development, for the real button is not shown until
468   *measurin started and there are results.
469   *@todo Implement with real code and yet leave sendXml in the bottom in use.
470   */
471 void CarMainWindow::on_manualStartButton_clicked()
472 {
473
474 }
475
476 /**
477   * This slot function is called when timer gives timeout signal. Checks current speed
478   * and stores times in measure class.
479   */
480 void CarMainWindow::after_timeout()
481 {
482     QString timeString, speedString;
483     //time++;
484     time = accelerometer->getTotalTime();
485     speed = accelerometer->getCurrentSpeed();
486     //speed = speed +10;
487
488     if (floor(speed) == 10)
489     {
490         measures->setTime10kmh(time);
491     }
492
493     else if (floor(speed) == 20)
494     {
495         measures->setTime20kmh(time);
496     }
497
498     else if (floor(speed) == 30)
499     {
500         measures->setTime30kmh(time);
501     }
502
503     else if (floor(speed) == 40)
504     {
505         measures->setTime40kmh(time);
506     }
507
508     else if (floor(speed) == 50)
509     {
510         measures->setTime50kmh(time);
511     }
512
513     else if (floor(speed) == 60)
514     {
515         measures->setTime60kmh(time);
516     }
517
518     else if (floor(speed) == 70)
519     {
520         measures->setTime70kmh(time);
521     }
522
523     else if (floor(speed) == 80)
524     {
525         measures->setTime80kmh(time);
526     }
527
528     else if (floor(speed) == 90)
529     {
530         measures->setTime90kmh(time);
531     }
532
533     else if (floor(speed) == 100)
534     {
535         measures->setTime100kmh(time);
536     }
537
538     else
539     {
540
541     }
542
543     // If speed is over 40 km/h emits speedAchieved() signal and close this dialog.
544     if (speed >= 40.0)
545     {
546         timer->stop();
547         accelerometer->stop();
548         time = 0;
549         speed = 0;
550         //emit this->speedAchieved();
551         this->openResultView();
552         //this->close();
553
554     }
555
556     // Updates speed and time.
557     else
558     {
559         timeString.setNum(time);
560         speedString.setNum(speed);
561         ui->labelMeasureTabTime->setText(timeString);
562         ui->labelMeasureTabSpeed->setText(speedString);
563
564         timer->start();
565     }
566
567 }
568
569 /**
570   * Initializes measures class's member variables.
571   */
572 void CarMainWindow::initializeMeasures()
573 {
574     measures->setTime10kmh(0);
575     measures->setTime20kmh(0);
576     measures->setTime30kmh(0);
577     measures->setTime40kmh(0);
578     measures->setTime50kmh(0);
579     measures->setTime60kmh(0);
580     measures->setTime70kmh(0);
581     measures->setTime80kmh(0);
582     measures->setTime90kmh(0);
583     measures->setTime100kmh(0);
584 }
585
586 /**
587   * This slot function is called when Abort button is clicked.
588   */
589 void CarMainWindow::on_pushButtonMeasureTabAbort_clicked()
590 {
591     measures->setTime10kmh(0);
592     measures->setTime20kmh(0);
593     measures->setTime30kmh(0);
594     measures->setTime40kmh(0);
595     measures->setTime50kmh(0);
596     measures->setTime60kmh(0);
597     measures->setTime70kmh(0);
598     measures->setTime80kmh(0);
599     measures->setTime90kmh(0);
600     measures->setTime100kmh(0);
601     timer->stop();
602     accelerometer->stop();
603     time = 0;
604     speed = 0;
605     ui->tabWidget->setCurrentWidget(this->ui->StartTab);
606     //this->close();
607 }
608
609 void CarMainWindow::on_pushButtonSendResult_clicked()
610 {
611     sendResultXml();
612     ui->pushButtonSendResult->setEnabled(false);
613 }
614
615 void CarMainWindow::updateUserName()
616 {
617     QString newUserName;
618
619     newUserName = myLogin->getUserName();
620     ui->userNameLabel->setText( "User: " + newUserName);
621
622     if (newUserName.length())
623     {
624        ui->setUserPushButton->setText( "Change User");
625        this->setWindowTitle("Speed freak - " + newUserName);
626     }
627     else
628     {
629         ui->setUserPushButton->setText( "Set User");
630         this->setWindowTitle("Speed freak");
631     }
632 }