ee146ffe0055a1ea45b3e1f4a0f7cf01297d2571
[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
51     ui->labelMeasureTabResult->hide();
52
53 }
54
55 /**
56   *Destructor of this class. Should be used to release all allocated resources.
57   */
58 CarMainWindow::~CarMainWindow()
59 {
60     delete ui;
61     //delete result;
62     //delete measure;
63     delete xmlreader;
64     delete xmlwriter;
65     delete manager;
66 }
67
68 /**
69   *This function is used to .
70   *@param
71   */
72 void CarMainWindow::changeEvent(QEvent *e)
73 {
74     QMainWindow::changeEvent(e);
75     switch (e->type()) {
76     case QEvent::LanguageChange:
77         ui->retranslateUi(this);
78         break;
79     default:
80         break;
81     }
82 }
83
84 /**
85   *This slot function is called when ever list view is update. Start-tab view.
86   */
87 void CarMainWindow::on_listViewStartTabAccelerationCategories_clicked(QModelIndex index)
88 {
89     QString str = index.data().toString();
90     QStringList list = str.split("-");
91     QStringList list2 = list[1].split(" ");
92
93     ui->lineEditStartTabMin->setText(list[0]);
94     ui->lineEditStartTabMax->setText(list2[0]);
95     updateComboBoxStartTabUnits(list2[1]);
96 }
97
98 /**
99   *This slot function is called when ever auto start button clicked. Start-tab view.
100   */
101 void CarMainWindow::on_autoStartButton_clicked()
102 {
103
104     //delete measure;
105     //measure = NULL;
106     //measure = new MeasureDialog();
107    // connect(measure, SIGNAL(speedAchieved()), this, SLOT(openResultView()));
108     accelerometer->start();
109     timer->start();
110     // Show measure dialog.
111     //measure->show();
112     ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
113 }
114
115 /**
116   *This slot function is called when ever list view is update. Start-tab view.
117   *@param QString unit.
118   */
119 void CarMainWindow::updateComboBoxStartTabUnits(QString unit)
120 {
121     ui->comboBoxStartTabUnits->setCurrentIndex(ui->comboBoxStartTabUnits->findText(unit, Qt::MatchExactly));
122 }
123
124 /**
125   *This function is used to init unit combobox. Start-tab view.
126   */
127 void CarMainWindow::initComboBoxStartTabUnits()
128 {
129     units << "km/h" << "km" << "h" << "m" << "min" << "Mile" << "Mph" << "in" << "ft" << "yrd";
130     ui->comboBoxStartTabUnits->addItems(units);
131 }
132
133 /**
134   *This function is used to set items to unit combobox. Start-tab view.
135   *@param QStringlist units
136   */
137 void CarMainWindow::setComboBoxStartTabUnits(QStringList units)
138 {
139     ui->comboBoxStartTabUnits->addItems(units);
140 }
141
142 /**
143   *This function is used to init listViewStartTabAccelerationCategories. Start-tab view.
144   */
145 void CarMainWindow::initListViewStartTabAccelerationCategories()
146 {
147     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";
148     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
149     ui->listViewStartTabAccelerationCategories->setModel(model);
150 }
151
152 /**
153   *This function is used to set items to listViewStartTabAccelerationCategories. Start-tab view.
154   *@param QStringlist accelerationCategoriesStartTab
155   */
156 void CarMainWindow::setListViewStartTabAccelerationCategories(QStringList accelerationCategoriesStartTab)
157 {
158     QAbstractItemModel *model = new StringListModel(accelerationCategoriesStartTab);
159     ui->listViewStartTabAccelerationCategories->setModel(model);
160 }
161
162 /**
163   *This function is used to set items to category combobox. Top-tab view.
164   *@param
165   */
166 void CarMainWindow::setCategoryCompoBox()
167 {
168     ui->comboBoxTopCategory->addItems(xmlreader->getTop10List());
169 }
170
171 /**
172   *This function is used to set items to labelTopList. Top-tab view.
173   *@param QString category
174   */
175 void CarMainWindow::setListViewTopList(QString category)
176 {
177     QString topList;
178
179     if (category == "acceleration-0-100")
180     {
181         topList.append(xmlreader->getTop10AccelerationList());
182     }
183
184     else if (category == "Speed")
185     {
186         topList.append(xmlreader->getTop10SpeedList());
187     }
188
189     else if (category == "G-force")
190     {
191         topList.append(xmlreader->getTop10GforceList());
192     }
193     ui->labelTopList->setText(topList);
194 }
195
196 /**
197   *This slot function is called when speed is achieved in measure dialog. Opens result dialog.
198   */
199 void CarMainWindow::openResultView()
200 {
201     //result->saveMeasuresToArray(measure->measures);
202     // Show result dialog.
203     //result->show();
204     QString timeInteger;
205     timeInteger.setNum(this->measures->getTime40kmh());
206     //time = "0 - 40 km/h: ";
207     //time.append(timeInteger);
208     //ui->labelResult40kmh->setText(time);
209     ui->labelMeasureTabResult->show();
210     ui->labelMeasureTabResult->setText(timeInteger);
211     //ui->tabWidget->setCurrentWidget(this->ui->tabMeasureResult);
212 }
213
214 /**
215   *This slot function is called when the server has finished guery.
216   */
217 void CarMainWindow::networkResponse(QNetworkReply *reply)
218 {
219
220 }
221
222 /**
223   *This slot function is called when the user will to send data to server.
224   *@todo Where is this callback connected?
225   */
226 void CarMainWindow::on_pushButton_clicked()
227 {
228      sendXml();
229 }
230
231 /**
232   *This slot function is called when login/logout button is clicked.
233   */
234 void CarMainWindow::on_loginLogoutButton_clicked()
235 {
236     //LoginWindow myLogin;
237
238     myLogin->show();
239     //ui->loginLogoutButton->setText("logout");
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 }