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