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