Added spacing between map and navigation.
[medard] / src / mainwindow.cpp
1 /*
2  *  Medard for Maemo.
3  *  Copyright (C) 2011 Roman Moravcik
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #ifdef MEEGO_EDITION_HARMATTAN
21 #include <MLayout>
22 #include <MAction>
23 #include <MWidgetAction>
24 #include <MComboBox>
25 #endif
26
27 #include <QtGui>
28 #include <QSettings>
29
30 #include "aboutdialog.h"
31 #include "mainwindow.h"
32
33 #ifdef MEEGO_EDITION_HARMATTAN
34 MainWindow::MainWindow(QGraphicsItem *parent) : MApplicationPage(parent)
35 {
36     m_downloader = new MedardDownloader();
37
38     connect(m_downloader, SIGNAL(downloadFinished(const QString &, const QDateTime &)), this,
39             SLOT(downloadedFinished(const QString &, const QDateTime &)));
40     connect(m_downloader, SIGNAL(downloadFailed()), this, SLOT(downloadFailed()));
41
42     m_forecast = new ForecastWidget();
43     m_forecast->setPreferredSize(m_downloader->imageSize());
44
45     m_forecastTypeLabel = new MLabel();
46     m_forecastTypeLabel->setAlignment(Qt::AlignCenter);
47     m_forecastTypeLabel->setPreferredSize(220, 80);
48
49     m_forecastInitialDateLabel = new MLabel();
50     m_forecastInitialDateLabel->setAlignment(Qt::AlignCenter);
51     m_forecastInitialDateLabel->setWordWrap(true);
52     m_forecastInitialDateLabel->setEnabled(false);
53
54     m_forecastDateLabel = new MLabel();
55     m_forecastDateLabel->setAlignment(Qt::AlignCenter);
56     m_forecastDateLabel->setWordWrap(true);
57
58     m_downloadRetryButton = new MButton(tr("Download again"));
59     m_downloadRetryButton->setPreferredWidth(220);
60
61     connect(m_downloadRetryButton, SIGNAL(clicked()), this, SLOT(downloadAgainClicked()));
62
63     m_minusDayButton = new MButton(tr("-1 d"));
64     m_minusDayButton->setPreferredWidth(50);
65     m_plusDayButton = new MButton(tr("+1 d"));
66     m_plusDayButton->setPreferredWidth(50);
67     m_minusHourButton = new MButton(tr("-1 h"));
68     m_minusHourButton->setPreferredWidth(50);
69     m_plusHourButton = new MButton(tr("+1 h"));
70     m_plusHourButton->setPreferredWidth(50);
71
72     connect(m_minusDayButton, SIGNAL(clicked()), this, SLOT(minusDayClicked()));
73     connect(m_plusDayButton, SIGNAL(clicked()), this, SLOT(plusDayClicked()));
74     connect(m_minusHourButton, SIGNAL(clicked()), this, SLOT(minusHourClicked()));
75     connect(m_plusHourButton, SIGNAL(clicked()), this, SLOT(plusHourClicked()));
76
77     setupUi();
78     setupMenu();
79
80     loadSettings();
81 }
82 #else
83 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
84 {
85     m_downloader = new MedardDownloader();
86
87     connect(m_downloader, SIGNAL(downloadFinished(const QString &, const QDateTime &)), this,
88             SLOT(downloadedFinished(const QString &, const QDateTime &)));
89     connect(m_downloader, SIGNAL(downloadFailed()), this, SLOT(downloadFailed()));
90
91     m_forecast = new ForecastWidget();
92     m_forecast->setFixedSize(m_downloader->imageSize());
93
94     m_forecastTypeLabel = new QLabel();
95     m_forecastTypeLabel->setAlignment(Qt::AlignCenter);
96     m_forecastTypeLabel->setFixedSize(220, 80);
97
98     m_forecastInitialDateLabel = new QLabel();
99     m_forecastInitialDateLabel->setAlignment(Qt::AlignCenter);
100     m_forecastInitialDateLabel->setDisabled(true);
101
102     m_forecastDateLabel = new QLabel();
103     m_forecastDateLabel->setAlignment(Qt::AlignCenter);
104
105     m_downloadRetryButton = new QPushButton(tr("Download again"));
106
107     connect(m_downloadRetryButton, SIGNAL(clicked()), this, SLOT(downloadAgainClicked()));
108
109     m_minusDayButton = new QPushButton(tr("-1 d"));
110     m_plusDayButton = new QPushButton(tr("+1 d"));
111     m_minusHourButton = new QPushButton(tr("-1 h"));
112     m_plusHourButton = new QPushButton(tr("+1 h"));
113
114     connect(m_minusDayButton, SIGNAL(clicked()), this, SLOT(minusDayClicked()));
115     connect(m_plusDayButton, SIGNAL(clicked()), this, SLOT(plusDayClicked()));
116     connect(m_minusHourButton, SIGNAL(clicked()), this, SLOT(minusHourClicked()));
117     connect(m_plusHourButton, SIGNAL(clicked()), this, SLOT(plusHourClicked()));
118
119     setupUi();
120     setupMenu();
121
122     loadSettings();
123 }
124 #endif
125
126 MainWindow::~MainWindow()
127 {
128     delete m_downloader;
129 }
130
131 #ifdef MEEGO_EDITION_HARMATTAN
132 void MainWindow::setupUi()
133 {
134     setWindowTitle(tr("Medard"));
135     setPannable(false);
136
137     QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(Qt::Horizontal);
138     mainLayout->setSpacing(8);
139     centralWidget()->setLayout(mainLayout);
140
141     mainLayout->addItem(m_forecast);
142
143     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
144     mainLayout->addItem(layout);
145
146     layout->addItem(m_forecastTypeLabel);
147     layout->addItem(m_forecastDateLabel);
148     layout->addItem(m_forecastInitialDateLabel);
149     layout->addItem(m_downloadRetryButton);
150
151     QGraphicsLinearLayout *dayNavigationBox = new QGraphicsLinearLayout(Qt::Horizontal);
152     dayNavigationBox->addItem(m_minusDayButton);
153     dayNavigationBox->addItem(m_plusDayButton);
154     layout->addItem(dayNavigationBox);
155
156     QGraphicsLinearLayout *hourNavigationBox = new QGraphicsLinearLayout(Qt::Horizontal);
157     hourNavigationBox->addItem(m_minusHourButton);
158     hourNavigationBox->addItem(m_plusHourButton);
159     layout->addItem(hourNavigationBox);
160
161     hideNavigationButtons(false);
162 }
163 #else
164 void MainWindow::setupUi()
165 {
166 #ifdef Q_WS_MAEMO_5
167     setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
168 #endif
169     setWindowTitle(tr("Medard"));
170
171     QWidget *widget = new QWidget;
172     setCentralWidget(widget);
173
174     QHBoxLayout *mainLayout = new QHBoxLayout();
175     mainLayout->setMargin(8);
176     mainLayout->setSpacing(4);
177     widget->setLayout(mainLayout);
178
179     mainLayout->addWidget(m_forecast);
180     mainLayout->addSpacing(4);
181
182     QVBoxLayout *layout = new QVBoxLayout();
183     mainLayout->addLayout(layout);
184
185     layout->addWidget(m_forecastTypeLabel);
186     layout->addWidget(m_forecastDateLabel);
187     layout->addSpacing(20);
188     layout->addWidget(m_forecastInitialDateLabel);
189     layout->addSpacing(20);
190     layout->addWidget(m_downloadRetryButton);
191
192     QHBoxLayout *dayNavigationBox = new QHBoxLayout();
193     dayNavigationBox->addWidget(m_minusDayButton);
194     dayNavigationBox->addWidget(m_plusDayButton);
195     layout->addLayout(dayNavigationBox);
196
197     QHBoxLayout *hourNavigationBox = new QHBoxLayout();
198     hourNavigationBox->addWidget(m_minusHourButton);
199     hourNavigationBox->addWidget(m_plusHourButton);
200     layout->addLayout(hourNavigationBox);
201
202     hideNavigationButtons(false);
203 }
204 #endif
205
206 #ifdef MEEGO_EDITION_HARMATTAN
207 void MainWindow::setupMenu()
208 {
209     QStringList forecastDomainList;
210     forecastDomainList << tr("Europe") 
211                        << tr("Czech Republic");
212
213     MWidgetAction *forecastDomainAction = new MWidgetAction(centralWidget());
214     forecastDomainAction->setLocation(MAction::ApplicationMenuLocation);
215
216     m_forecastDomainComboBox = new MComboBox;
217     m_forecastDomainComboBox->setTitle(tr("Domain"));
218     m_forecastDomainComboBox->setStyleName ("CommonComboBox");
219     m_forecastDomainComboBox->setIconVisible(false);
220     m_forecastDomainComboBox->addItems(forecastDomainList);
221     forecastDomainAction->setWidget(m_forecastDomainComboBox);
222     addAction(forecastDomainAction);
223     connect(m_forecastDomainComboBox, SIGNAL(activated(int)), this, SLOT(forecastDomainChanged(int)));
224
225     QStringList forecastTypeList;
226     forecastTypeList << tr("Sea Level Pressure")
227                      << tr("Precipitation")
228                      << tr("Wind Velocity")
229                      << tr("Cloudiness")
230                      << tr("Temperature");
231
232     MWidgetAction *forecastTypeAction = new MWidgetAction(centralWidget());
233     forecastTypeAction->setLocation(MAction::ApplicationMenuLocation);
234
235     m_forecastTypeComboBox = new MComboBox;
236     m_forecastTypeComboBox->setTitle(tr("Forecast"));
237     m_forecastTypeComboBox->setStyleName ("CommonComboBox");
238     m_forecastTypeComboBox->setIconVisible(false);
239     m_forecastTypeComboBox->addItems(forecastTypeList);
240     forecastTypeAction->setWidget(m_forecastTypeComboBox);
241     addAction(forecastTypeAction);
242     connect(m_forecastTypeComboBox, SIGNAL(activated(int)), this, SLOT(forecastTypeChanged(int)));
243
244     MAction *seaLevelPreasureAction = new MAction("icon-m-weather-cloudy", "", this);
245     seaLevelPreasureAction->setLocation(MAction::ToolBarLocation);
246     addAction(seaLevelPreasureAction);
247     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
248
249     MAction *precipitationAction = new MAction("icon-m-weather-rain", "", this);
250     precipitationAction->setLocation(MAction::ToolBarLocation);
251     addAction(precipitationAction);
252     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
253
254     MAction *cloudinessAction = new MAction("icon-m-weather-partly-sunny", "", this);
255     cloudinessAction->setLocation(MAction::ToolBarLocation);
256     addAction(cloudinessAction);
257     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
258
259     MAction *temperatureAction = new MAction("icon-m-weather-hot", "", this);
260     temperatureAction->setLocation(MAction::ToolBarLocation);
261     addAction(temperatureAction);
262     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
263
264     MAction *aboutAction = new MAction(this);
265     aboutAction->setText(tr("About"));
266     aboutAction->setLocation(MAction::ApplicationMenuLocation);
267     addAction(aboutAction);
268     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
269 }
270 #else
271 void MainWindow::setupMenu()
272 {
273     QMenuBar *menu = new QMenuBar();
274     setMenuBar(menu);
275
276     m_domainActionGroup = new QActionGroup(this);
277     m_domainActionGroup->setExclusive(true);
278
279     QAction *domainAction;
280     domainAction = new QAction(tr("Europe"), m_domainActionGroup);
281     domainAction->setCheckable(true);
282     domainAction = new QAction(tr("Czech Republic"), m_domainActionGroup);
283     domainAction ->setCheckable(true);
284     menu->addActions(m_domainActionGroup->actions());
285     connect(m_domainActionGroup, SIGNAL(triggered(QAction *)), this, SLOT(forecastDomainChanged(QAction *)));
286
287     QAction *seaLevelPreasureAction = new QAction(tr("Sea Level Pressure"), this);
288     menu->addAction(seaLevelPreasureAction);
289     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
290
291     QAction *precipitationAction = new QAction(tr("Precipitation"), this);
292     menu->addAction(precipitationAction);
293     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
294
295     QAction *windVelocityAction = new QAction(tr("Wind Velocity"), this);
296     menu->addAction(windVelocityAction);
297     connect(windVelocityAction, SIGNAL(triggered()), this, SLOT(windVelocityMenuClicked()));
298
299     QAction *cloudinessAction = new QAction(tr("Cloudiness"), this);
300     menu->addAction(cloudinessAction);
301     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
302
303     QAction *temperatureAction = new QAction(tr("Temperature"), this);
304     menu->addAction(temperatureAction);
305     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
306
307     QAction *aboutAction = new QAction(tr("About"), this);
308     menu->addAction(aboutAction);
309     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
310 }
311 #endif
312
313 void MainWindow::loadSettings()
314 {
315     QSettings settings;
316
317     int forecastDomain = settings.value("ForecastDomain").toInt();
318     int forecastType = settings.value("ForecastType").toInt();
319
320     m_downloader->setForecastDomain((MedardDownloader::ForecastDomain) forecastDomain);
321 #ifdef MEEGO_EDITION_HARMATTAN
322     m_forecastDomainComboBox->setCurrentIndex(forecastDomain);
323 #else
324     m_domainActionGroup->actions().at(forecastDomain)->setChecked(true);
325 #endif
326
327     switch ((MedardDownloader::ForecastType) forecastType) {
328         case MedardDownloader::SeaLevelPressure:
329             seaLevelPreasureMenuClicked();
330             break;
331
332         case MedardDownloader::Precipitation:
333             precipitationMenuClicked();
334             break;
335
336         case MedardDownloader::WindVelocity:
337             windVelocityMenuClicked();
338             break;
339
340         case MedardDownloader::Cloudiness:
341             cloudinessMenuClicked();
342             break;
343
344         case MedardDownloader::Temperature:
345             temperatureMenuClicked();
346             break;
347     }
348 }
349
350 void MainWindow::showNavigationButtons()
351 {
352     m_downloadRetryButton->hide();
353
354     m_minusDayButton->show();
355     m_plusDayButton->show();
356     m_minusHourButton->show();
357     m_plusHourButton->show();
358 }
359
360 void MainWindow::hideNavigationButtons(bool showRetryButton)
361 {
362     if (showRetryButton)
363         m_downloadRetryButton->show();
364     else
365         m_downloadRetryButton->hide();
366
367     m_minusDayButton->hide();
368     m_plusDayButton->hide();
369     m_minusHourButton->hide();
370     m_plusHourButton->hide();
371 }
372
373 void MainWindow::updateNavigationButtons()
374 {
375     if ((m_downloader->forecastDateOffset() - 24) < m_downloader->minForecastDateOffset()) {
376 #ifdef MEEGO_EDITION_HARMATTAN
377         m_minusDayButton->setEnabled(false);
378         m_plusDayButton->setEnabled(true);
379 #else
380         m_minusDayButton->setDisabled(true);
381         m_plusDayButton->setDisabled(false);
382 #endif
383     } else if ((m_downloader->forecastDateOffset() + 24) > m_downloader->maxForecastDateOffset()) {
384 #ifdef MEEGO_EDITION_HARMATTAN
385         m_minusDayButton->setEnabled(true);
386         m_plusDayButton->setEnabled(false);
387 #else
388         m_minusDayButton->setDisabled(false);
389         m_plusDayButton->setDisabled(true);
390 #endif
391     } else {
392 #ifdef MEEGO_EDITION_HARMATTAN
393         m_minusDayButton->setEnabled(true);
394         m_plusDayButton->setEnabled(true);
395 #else
396         m_minusDayButton->setDisabled(false);
397         m_plusDayButton->setDisabled(false);
398 #endif
399     }
400
401     if ((m_downloader->forecastDateOffset() - 1) < m_downloader->minForecastDateOffset()) {
402 #ifdef MEEGO_EDITION_HARMATTAN
403         m_minusHourButton->setEnabled(false);
404         m_plusHourButton->setEnabled(true);
405 #else
406         m_minusHourButton->setDisabled(true);
407         m_plusHourButton->setDisabled(false);
408 #endif
409     } else if ((m_downloader->forecastDateOffset() + 1) > m_downloader->maxForecastDateOffset()) {
410 #ifdef MEEGO_EDITION_HARMATTAN
411         m_minusHourButton->setEnabled(true);
412         m_plusHourButton->setEnabled(false);
413 #else
414         m_minusHourButton->setDisabled(false);
415         m_plusHourButton->setDisabled(true);
416 #endif
417     } else {
418 #ifdef MEEGO_EDITION_HARMATTAN
419         m_minusHourButton->setEnabled(true);
420         m_plusHourButton->setEnabled(true);
421 #else
422         m_minusHourButton->setDisabled(false);
423         m_plusHourButton->setDisabled(false);
424 #endif
425     }
426 }
427
428 void MainWindow::setForecastType(const QString label, MedardDownloader::ForecastType type)
429 {
430     m_forecastTypeLabel->setText(label);
431     m_forecast->clearImage(false);
432     m_downloader->setForecastType(type);
433     m_downloader->downloadImage();
434
435     QSettings settings;
436     settings.setValue("ForecastType", type);
437 }
438
439 void MainWindow::setForecastDateOffset(int offset)
440 {
441     m_forecast->clearImage(false);
442     m_downloader->setForecastDateOffset(m_downloader->forecastDateOffset() + offset);
443     m_downloader->downloadImage();
444 }
445
446 void MainWindow::seaLevelPreasureMenuClicked()
447 {
448 #ifdef MEEGO_EDITION_HARMATTAN
449     m_forecastTypeComboBox->setCurrentIndex(MedardDownloader::SeaLevelPressure);
450 #endif
451     setForecastType(tr("Sea Level Pressure"), MedardDownloader::SeaLevelPressure);
452 }
453
454 void MainWindow::precipitationMenuClicked()
455 {
456 #ifdef MEEGO_EDITION_HARMATTAN
457     m_forecastTypeComboBox->setCurrentIndex(MedardDownloader::Precipitation);
458 #endif
459     setForecastType(tr("Precipitation"), MedardDownloader::Precipitation);
460 }
461
462 void MainWindow::windVelocityMenuClicked()
463 {
464 #ifdef MEEGO_EDITION_HARMATTAN
465     m_forecastTypeComboBox->setCurrentIndex(MedardDownloader::WindVelocity);
466 #endif
467     setForecastType(tr("Wind Velocity"), MedardDownloader::WindVelocity);
468 }
469
470 void MainWindow::cloudinessMenuClicked()
471 {
472 #ifdef MEEGO_EDITION_HARMATTAN
473     m_forecastTypeComboBox->setCurrentIndex(MedardDownloader::Cloudiness);
474 #endif
475     setForecastType(tr("Cloudiness"), MedardDownloader::Cloudiness);
476 }
477
478 void MainWindow::temperatureMenuClicked()
479 {
480 #ifdef MEEGO_EDITION_HARMATTAN
481     m_forecastTypeComboBox->setCurrentIndex(MedardDownloader::Temperature);
482 #endif
483     setForecastType(tr("Temperature"), MedardDownloader::Temperature);
484 }
485
486 void MainWindow::aboutMenuClicked()
487 {
488     AboutDialog *dialog = new AboutDialog();
489 #ifdef MEEGO_EDITION_HARMATTAN
490     dialog->appear(MSceneWindow::DestroyWhenDismissed);
491 #else
492     dialog->exec();
493 #endif
494 }
495
496 void MainWindow::downloadAgainClicked()
497 {
498     m_forecast->clearImage(false);
499     m_downloader->downloadImage();
500
501     hideNavigationButtons(false);
502 }
503
504 void MainWindow::plusDayClicked()
505 {
506     setForecastDateOffset(+24);
507 }
508
509 void MainWindow::minusDayClicked()
510 {
511     setForecastDateOffset(-24);
512 }
513
514 void MainWindow::plusHourClicked()
515 {
516     setForecastDateOffset(+1);
517 }
518
519 void MainWindow::minusHourClicked()
520 {
521     setForecastDateOffset(-1);
522 }
523
524 #ifdef MEEGO_EDITION_HARMATTAN
525 void MainWindow::forecastDomainChanged(int index)
526 {
527     m_forecast->clearImage(false);
528
529     if (index == 0)
530         m_downloader->setForecastDomain(MedardDownloader::Europe);
531     else
532         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
533
534     m_downloader->downloadImage();
535
536     QSettings settings;
537     settings.setValue("ForecastDomain", index);
538 }
539
540 void MainWindow::forecastTypeChanged(int index)
541 {
542     switch ((MedardDownloader::ForecastType) index) {
543         case MedardDownloader::SeaLevelPressure:
544             setForecastType(tr("Sea Level Pressure"), MedardDownloader::SeaLevelPressure);
545             break;
546
547         case MedardDownloader::Precipitation:
548             setForecastType(tr("Precipitation"), MedardDownloader::Precipitation);
549             break;
550
551         case MedardDownloader::WindVelocity:
552             setForecastType(tr("Wind Velocity"), MedardDownloader::WindVelocity);
553             break;
554
555         case MedardDownloader::Cloudiness:
556             setForecastType(tr("Cloudiness"), MedardDownloader::Cloudiness);
557             break;
558
559         case MedardDownloader::Temperature:
560             setForecastType(tr("Temperature"), MedardDownloader::Temperature);
561             break;
562     }
563 }
564
565 #else
566 void MainWindow::forecastDomainChanged(QAction *action)
567 {
568     int forecastDomain = m_domainActionGroup->actions().indexOf(action);
569
570     m_forecast->clearImage(false);
571
572     if (forecastDomain == 0)
573         m_downloader->setForecastDomain(MedardDownloader::Europe);
574     else
575         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
576
577     m_downloader->downloadImage();
578
579     QSettings settings;
580     settings.setValue("ForecastDomain", forecastDomain);
581 }
582 #endif
583
584 void MainWindow::downloadedFinished(const QString &filename, const QDateTime &date)
585 {
586     m_forecast->setImage(filename);
587     m_forecastInitialDateLabel->setText(tr("Forecast from:\n") +
588                                           m_downloader->forecastInitialDate().toString("dd.MM.yyyy, hh:mm"));
589
590     /* upcase the first letter of name of day */
591     QString temp = date.toString("dddd\ndd.MM.yyyy, hh:mm");
592     m_forecastDateLabel->setText(temp.replace(0, 1, temp.at(0).toUpper()));
593
594     showNavigationButtons();
595     updateNavigationButtons();
596 }
597
598 void MainWindow::downloadFailed()
599 {
600     m_forecast->clearImage(true);
601     m_forecastInitialDateLabel->setText("");
602     m_forecastDateLabel->setText("");
603
604     hideNavigationButtons(true);
605 }