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