Added First version of MeeGo Harmattan port from pure QT to MTF.
[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 Q_WS_MAEMO_6
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 Q_WS_MAEMO_6
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->setDisabled(true);
52
53     m_forecastDateLabel = new MLabel();
54     m_forecastDateLabel->setAlignment(Qt::AlignCenter);
55
56     m_downloadRetryButton = new MButton(tr("Download again"));
57     m_downloadRetryButton->setPreferredWidth(220);
58
59     connect(m_downloadRetryButton, SIGNAL(clicked()), this, SLOT(downloadAgainClicked()));
60
61     m_minusDayButton = new MButton(tr("-1 d"));
62     m_minusDayButton->setPreferredWidth(50);
63     m_plusDayButton = new MButton(tr("+1 d"));
64     m_plusDayButton->setPreferredWidth(50);
65     m_minusHourButton = new MButton(tr("-1 h"));
66     m_minusHourButton->setPreferredWidth(50);
67     m_plusHourButton = new MButton(tr("+1 h"));
68     m_plusHourButton->setPreferredWidth(50);
69
70     connect(m_minusDayButton, SIGNAL(clicked()), this, SLOT(minusDayClicked()));
71     connect(m_plusDayButton, SIGNAL(clicked()), this, SLOT(plusDayClicked()));
72     connect(m_minusHourButton, SIGNAL(clicked()), this, SLOT(minusHourClicked()));
73     connect(m_plusHourButton, SIGNAL(clicked()), this, SLOT(plusHourClicked()));
74
75     setupUi();
76     setupMenu();
77
78     loadSettings();
79 }
80 #else
81 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
82 {
83     m_downloader = new MedardDownloader();
84
85     connect(m_downloader, SIGNAL(downloadFinished(const QString &, const QDateTime &)), this,
86             SLOT(downloadedFinished(const QString &, const QDateTime &)));
87     connect(m_downloader, SIGNAL(downloadFailed()), this, SLOT(downloadFailed()));
88
89     m_forecast = new ForecastWidget();
90     m_forecast->setFixedSize(m_downloader->imageSize());
91
92     m_forecastTypeLabel = new QLabel();
93     m_forecastTypeLabel->setAlignment(Qt::AlignCenter);
94     m_forecastTypeLabel->setFixedSize(220, 80);
95
96     m_forecastInitialDateLabel = new QLabel();
97     m_forecastInitialDateLabel->setAlignment(Qt::AlignCenter);
98     m_forecastInitialDateLabel->setDisabled(true);
99
100     m_forecastDateLabel = new QLabel();
101     m_forecastDateLabel->setAlignment(Qt::AlignCenter);
102
103     m_downloadRetryButton = new QPushButton(tr("Download again"));
104
105     connect(m_downloadRetryButton, SIGNAL(clicked()), this, SLOT(downloadAgainClicked()));
106
107     m_minusDayButton = new QPushButton(tr("-1 d"));
108     m_plusDayButton = new QPushButton(tr("+1 d"));
109     m_minusHourButton = new QPushButton(tr("-1 h"));
110     m_plusHourButton = new QPushButton(tr("+1 h"));
111
112     connect(m_minusDayButton, SIGNAL(clicked()), this, SLOT(minusDayClicked()));
113     connect(m_plusDayButton, SIGNAL(clicked()), this, SLOT(plusDayClicked()));
114     connect(m_minusHourButton, SIGNAL(clicked()), this, SLOT(minusHourClicked()));
115     connect(m_plusHourButton, SIGNAL(clicked()), this, SLOT(plusHourClicked()));
116
117     setupUi();
118     setupMenu();
119
120     loadSettings();
121 }
122 #endif
123
124 MainWindow::~MainWindow()
125 {
126     delete m_downloader;
127 }
128
129 #ifdef Q_WS_MAEMO_6
130 void MainWindow::setupUi()
131 {
132     setAttribute(Qt::WA_LockPortraitOrientation, true);
133     setWindowTitle(tr("Medard"));
134     setPannable(false);
135
136     QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(Qt::Horizontal);
137     centralWidget()->setLayout(mainLayout);
138
139     mainLayout->addItem(m_forecast);
140
141     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
142     mainLayout->addItem(layout);
143
144     layout->addItem(m_forecastTypeLabel);
145     layout->addItem(m_forecastDateLabel);
146     layout->addItem(m_forecastInitialDateLabel);
147     layout->addItem(m_downloadRetryButton);
148
149     QGraphicsLinearLayout *dayNavigationBox = new QGraphicsLinearLayout(Qt::Horizontal);
150     dayNavigationBox->addItem(m_minusDayButton);
151     dayNavigationBox->addItem(m_plusDayButton);
152     layout->addItem(dayNavigationBox);
153
154     QGraphicsLinearLayout *hourNavigationBox = new QGraphicsLinearLayout(Qt::Horizontal);
155     hourNavigationBox->addItem(m_minusHourButton);
156     hourNavigationBox->addItem(m_plusHourButton);
157     layout->addItem(hourNavigationBox);
158
159     hideNavigationButtons(false);
160 }
161 #else
162 void MainWindow::setupUi()
163 {
164 #ifdef Q_WS_MAEMO_5
165     setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
166 #endif
167     setWindowTitle(tr("Medard"));
168
169     QWidget *widget = new QWidget;
170     setCentralWidget(widget);
171
172     QHBoxLayout *mainLayout = new QHBoxLayout();
173     mainLayout->setMargin(8);
174     mainLayout->setSpacing(4);
175     widget->setLayout(mainLayout);
176
177     mainLayout->addWidget(m_forecast);
178     mainLayout->addSpacing(4);
179
180     QVBoxLayout *layout = new QVBoxLayout();
181     mainLayout->addLayout(layout);
182
183     layout->addWidget(m_forecastTypeLabel);
184     layout->addWidget(m_forecastDateLabel);
185     layout->addSpacing(20);
186     layout->addWidget(m_forecastInitialDateLabel);
187     layout->addSpacing(20);
188     layout->addWidget(m_downloadRetryButton);
189
190     QHBoxLayout *dayNavigationBox = new QHBoxLayout();
191     dayNavigationBox->addWidget(m_minusDayButton);
192     dayNavigationBox->addWidget(m_plusDayButton);
193     layout->addLayout(dayNavigationBox);
194
195     QHBoxLayout *hourNavigationBox = new QHBoxLayout();
196     hourNavigationBox->addWidget(m_minusHourButton);
197     hourNavigationBox->addWidget(m_plusHourButton);
198     layout->addLayout(hourNavigationBox);
199
200     hideNavigationButtons(false);
201 }
202 #endif
203
204 #ifdef Q_WS_MAEMO_6
205 void MainWindow::setupMenu()
206 {
207     QStringList domainsList;
208     domainsList << tr("Europe") << tr("Czech Republic");
209
210     MWidgetAction *domainAction = new MWidgetAction(centralWidget());
211     domainAction->setLocation(MAction::ApplicationMenuLocation);
212
213     m_domainComboBox = new MComboBox;
214     m_domainComboBox->setTitle(tr("Domain"));
215     m_domainComboBox->setIconVisible(false);
216     m_domainComboBox->addItems(domainsList);
217     domainAction->setWidget(m_domainComboBox);
218     addAction(domainAction);
219     connect(m_domainComboBox, SIGNAL(activated(int)), this, SLOT(forecastDomainChanged(int)));
220
221     MAction *seaLevelPreasureAction = new MAction("icon-m-weather-cloudy", tr("Sea Level Pressure"), this);
222     seaLevelPreasureAction->setLocation(MAction::ToolBarLocation);
223     addAction(seaLevelPreasureAction);
224     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
225
226     MAction *precipitationAction = new MAction("icon-m-weather-rain", tr("Precipitation"), this);
227     precipitationAction->setLocation(MAction::ToolBarLocation);
228     addAction(precipitationAction);
229     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
230
231     MAction *windVelocityAction = new MAction("icon-m-weather-stormy", tr("Wind Velocity"), this);
232     windVelocityAction->setLocation(MAction::ToolBarLocation);
233     addAction(windVelocityAction);
234     connect(windVelocityAction, SIGNAL(triggered()), this, SLOT(windVelocityMenuClicked()));
235
236     MAction *cloudinessAction = new MAction("icon-m-weather-partly-sunny", tr("Cloudinese"), this);
237     cloudinessAction->setLocation(MAction::ToolBarLocation);
238     addAction(cloudinessAction);
239     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
240
241     MAction *temperatureAction = new MAction("icon-m-weather-hot", tr("Temperature"), this);
242     temperatureAction->setLocation(MAction::ToolBarLocation);
243     addAction(temperatureAction);
244     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
245
246     MAction *aboutAction = new MAction(this);
247     aboutAction->setText(tr("About"));
248     aboutAction->setLocation(MAction::ApplicationMenuLocation);
249     addAction(aboutAction);
250     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
251 }
252 #else
253 void MainWindow::setupMenu()
254 {
255     QMenuBar *menu = new QMenuBar();
256     setMenuBar(menu);
257
258     m_domainActionGroup = new QActionGroup(this);
259     m_domainActionGroup->setExclusive(true);
260
261     QAction *domainAction;
262     domainAction = new QAction(tr("Europe"), m_domainActionGroup);
263     domainAction->setCheckable(true);
264     domainAction = new QAction(tr("Czech Republic"), m_domainActionGroup);
265     domainAction ->setCheckable(true);
266     menu->addActions(m_domainActionGroup->actions());
267     connect(m_domainActionGroup, SIGNAL(triggered(QAction *)), this, SLOT(forecastDomainChanged(QAction *)));
268
269     QAction *seaLevelPreasureAction = new QAction(tr("Sea Level Pressure"), this);
270     menu->addAction(seaLevelPreasureAction);
271     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
272
273     QAction *precipitationAction = new QAction(tr("Precipitation"), this);
274     menu->addAction(precipitationAction);
275     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
276
277     QAction *windVelocityAction = new QAction(tr("Wind Velocity"), this);
278     menu->addAction(windVelocityAction);
279     connect(windVelocityAction, SIGNAL(triggered()), this, SLOT(windVelocityMenuClicked()));
280
281     QAction *cloudinessAction = new QAction(tr("Cloudiness"), this);
282     menu->addAction(cloudinessAction);
283     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
284
285     QAction *temperatureAction = new QAction(tr("Temperature"), this);
286     menu->addAction(temperatureAction);
287     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
288
289     QAction *aboutAction = new QAction(tr("About"), this);
290     menu->addAction(aboutAction);
291     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
292 }
293 #endif
294
295 void MainWindow::loadSettings()
296 {
297     QSettings settings;
298
299     int forecastDomain = settings.value("ForecastDomain").toInt();
300     int forecastType = settings.value("ForecastType").toInt();
301
302     m_downloader->setForecastDomain((MedardDownloader::ForecastDomain) forecastDomain);
303 #ifdef Q_WS_MAEMO_6
304     m_domainComboBox->setCurrentIndex(forecastDomain);
305 #else
306     m_domainActionGroup->actions().at(forecastDomain)->setChecked(true);
307 #endif
308
309     switch ((MedardDownloader::ForecastType) forecastType) {
310         case MedardDownloader::SeaLevelPressure:
311             seaLevelPreasureMenuClicked();
312             break;
313
314         case MedardDownloader::Precipitation:
315             precipitationMenuClicked();
316             break;
317
318         case MedardDownloader::WindVelocity:
319             windVelocityMenuClicked();
320             break;
321
322         case MedardDownloader::Cloudiness:
323             cloudinessMenuClicked();
324             break;
325
326         case MedardDownloader::Temperature:
327             temperatureMenuClicked();
328             break;
329     }
330 }
331
332 void MainWindow::showNavigationButtons()
333 {
334     m_downloadRetryButton->hide();
335
336     m_minusDayButton->show();
337     m_plusDayButton->show();
338     m_minusHourButton->show();
339     m_plusHourButton->show();
340 }
341
342 void MainWindow::hideNavigationButtons(bool showRetryButton)
343 {
344     if (showRetryButton)
345         m_downloadRetryButton->show();
346     else
347         m_downloadRetryButton->hide();
348
349     m_minusDayButton->hide();
350     m_plusDayButton->hide();
351     m_minusHourButton->hide();
352     m_plusHourButton->hide();
353 }
354
355 void MainWindow::updateNavigationButtons()
356 {
357     if ((m_downloader->forecastDateOffset() - 24) < m_downloader->minForecastDateOffset()) {
358 //        m_minusDayButton->setDisabled(true);
359 //        m_plusDayButton->setDisabled(false);
360     } else if ((m_downloader->forecastDateOffset() + 24) > m_downloader->maxForecastDateOffset()) {
361 //        m_minusDayButton->setDisabled(false);
362 //        m_plusDayButton->setDisabled(true);
363     } else {
364 //        m_minusDayButton->setDisabled(false);
365 //        m_plusDayButton->setDisabled(false);
366     }
367
368     if ((m_downloader->forecastDateOffset() - 1) < m_downloader->minForecastDateOffset()) {
369 //        m_minusHourButton->setDisabled(true);
370 //        m_plusHourButton->setDisabled(false);
371     } else if ((m_downloader->forecastDateOffset() + 1) > m_downloader->maxForecastDateOffset()) {
372 //        m_minusHourButton->setDisabled(false);
373 //        m_plusHourButton->setDisabled(true);
374     } else {
375 //        m_minusHourButton->setDisabled(false);
376 //        m_plusHourButton->setDisabled(false);
377     }
378 }
379
380 void MainWindow::seaLevelPreasureMenuClicked()
381 {
382     forecastTypeChanged(tr("Sea Level Pressure"), MedardDownloader::SeaLevelPressure);
383 }
384
385 void MainWindow::precipitationMenuClicked()
386 {
387     forecastTypeChanged(tr("Precipitation"), MedardDownloader::Precipitation);
388 }
389
390 void MainWindow::windVelocityMenuClicked()
391 {
392     forecastTypeChanged(tr("Wind Velocity"), MedardDownloader::WindVelocity);
393 }
394
395 void MainWindow::cloudinessMenuClicked()
396 {
397     forecastTypeChanged(tr("Cloudiness"), MedardDownloader::Cloudiness);
398 }
399
400 void MainWindow::temperatureMenuClicked()
401 {
402     forecastTypeChanged(tr("Temperature"), MedardDownloader::Temperature);
403 }
404
405 void MainWindow::aboutMenuClicked()
406 {
407     AboutDialog *dialog = new AboutDialog();
408 #ifdef Q_WS_MAEMO_6
409     dialog->appear(scene(), MSceneWindow::DestroyWhenDismissed);
410 #else
411     dialog->exec();
412 #endif
413 }
414
415 void MainWindow::downloadAgainClicked()
416 {
417     m_forecast->clearImage(false);
418     m_downloader->downloadImage();
419
420     hideNavigationButtons(false);
421 }
422
423 void MainWindow::plusDayClicked()
424 {
425     forecastDateOffsetChanged(+24);
426 }
427
428 void MainWindow::minusDayClicked()
429 {
430     forecastDateOffsetChanged(-24);
431 }
432
433 void MainWindow::plusHourClicked()
434 {
435     forecastDateOffsetChanged(+1);
436 }
437
438 void MainWindow::minusHourClicked()
439 {
440     forecastDateOffsetChanged(-1);
441 }
442
443 void MainWindow::forecastTypeChanged(const QString label, MedardDownloader::ForecastType type)
444 {
445     m_forecastTypeLabel->setText(label);
446     m_forecast->clearImage(false);
447     m_downloader->setForecastType(type);
448     m_downloader->downloadImage();
449
450     QSettings settings;
451     settings.setValue("ForecastType", type);
452 }
453
454 void MainWindow::forecastDateOffsetChanged(int offset)
455 {
456     m_forecast->clearImage(false);
457     m_downloader->setForecastDateOffset(m_downloader->forecastDateOffset() + offset);
458     m_downloader->downloadImage();
459 }
460
461 #ifdef Q_WS_MAEMO_6
462 void MainWindow::forecastDomainChanged(int index)
463 {
464     m_forecast->clearImage(false);
465
466     if (index == 0)
467         m_downloader->setForecastDomain(MedardDownloader::Europe);
468     else
469         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
470
471     m_downloader->downloadImage();
472
473     QSettings settings;
474     settings.setValue("ForecastDomain", index);
475 }
476 #else
477 void MainWindow::forecastDomainChanged(QAction *action)
478 {
479     int forecastDomain = m_domainActionGroup->actions().indexOf(action);
480
481     m_forecast->clearImage(false);
482
483     if (forecastDomain == 0)
484         m_downloader->setForecastDomain(MedardDownloader::Europe);
485     else
486         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
487
488     m_downloader->downloadImage();
489
490     QSettings settings;
491     settings.setValue("ForecastDomain", forecastDomain);
492 }
493 #endif
494
495 void MainWindow::downloadedFinished(const QString &filename, const QDateTime &date)
496 {
497     m_forecast->setImage(filename);
498     m_forecastInitialDateLabel->setText(tr("Forecast from:\n") +
499                                           m_downloader->forecastInitialDate().toString("dd.MM.yyyy hh:mm"));
500
501     /* upcase the first letter of name of day */
502     QString temp = date.toString("dddd\ndd.MM.yyyy hh:mm");
503     m_forecastDateLabel->setText(temp.replace(0, 1, temp.at(0).toUpper()));
504
505     showNavigationButtons();
506     updateNavigationButtons();
507 }
508
509 void MainWindow::downloadFailed()
510 {
511     m_forecast->clearImage(true);
512     m_forecastInitialDateLabel->setText("");
513     m_forecastDateLabel->setText("");
514
515     hideNavigationButtons(true);
516 }