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