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