Added wrapping of labels.
[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->setWordWrap(true);
52 //    m_forecastInitialDateLabel->setDisabled(true);
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 Q_WS_MAEMO_6
132 void MainWindow::setupUi()
133 {
134     setAttribute(Qt::WA_LockPortraitOrientation, true);
135     setWindowTitle(tr("Medard"));
136     setPannable(false);
137
138     QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(Qt::Horizontal);
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 Q_WS_MAEMO_6
207 void MainWindow::setupMenu()
208 {
209     QStringList domainsList;
210     domainsList << tr("Europe") << tr("Czech Republic");
211
212     MWidgetAction *domainAction = new MWidgetAction(centralWidget());
213     domainAction->setLocation(MAction::ApplicationMenuLocation);
214
215     m_domainComboBox = new MComboBox;
216     m_domainComboBox->setTitle(tr("Domain"));
217     m_domainComboBox->setIconVisible(false);
218     m_domainComboBox->addItems(domainsList);
219     domainAction->setWidget(m_domainComboBox);
220     addAction(domainAction);
221     connect(m_domainComboBox, SIGNAL(activated(int)), this, SLOT(forecastDomainChanged(int)));
222
223     MAction *seaLevelPreasureAction = new MAction("icon-m-weather-cloudy", tr("Sea Level Pressure"), this);
224     seaLevelPreasureAction->setLocation(MAction::ToolBarLocation);
225     addAction(seaLevelPreasureAction);
226     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
227
228     MAction *precipitationAction = new MAction("icon-m-weather-rain", tr("Precipitation"), this);
229     precipitationAction->setLocation(MAction::ToolBarLocation);
230     addAction(precipitationAction);
231     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
232
233     MAction *windVelocityAction = new MAction("icon-m-weather-stormy", tr("Wind Velocity"), this);
234     windVelocityAction->setLocation(MAction::ToolBarLocation);
235     addAction(windVelocityAction);
236     connect(windVelocityAction, SIGNAL(triggered()), this, SLOT(windVelocityMenuClicked()));
237
238     MAction *cloudinessAction = new MAction("icon-m-weather-partly-sunny", tr("Cloudinese"), this);
239     cloudinessAction->setLocation(MAction::ToolBarLocation);
240     addAction(cloudinessAction);
241     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
242
243     MAction *temperatureAction = new MAction("icon-m-weather-hot", tr("Temperature"), this);
244     temperatureAction->setLocation(MAction::ToolBarLocation);
245     addAction(temperatureAction);
246     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
247
248     MAction *aboutAction = new MAction(this);
249     aboutAction->setText(tr("About"));
250     aboutAction->setLocation(MAction::ApplicationMenuLocation);
251     addAction(aboutAction);
252     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
253 }
254 #else
255 void MainWindow::setupMenu()
256 {
257     QMenuBar *menu = new QMenuBar();
258     setMenuBar(menu);
259
260     m_domainActionGroup = new QActionGroup(this);
261     m_domainActionGroup->setExclusive(true);
262
263     QAction *domainAction;
264     domainAction = new QAction(tr("Europe"), m_domainActionGroup);
265     domainAction->setCheckable(true);
266     domainAction = new QAction(tr("Czech Republic"), m_domainActionGroup);
267     domainAction ->setCheckable(true);
268     menu->addActions(m_domainActionGroup->actions());
269     connect(m_domainActionGroup, SIGNAL(triggered(QAction *)), this, SLOT(forecastDomainChanged(QAction *)));
270
271     QAction *seaLevelPreasureAction = new QAction(tr("Sea Level Pressure"), this);
272     menu->addAction(seaLevelPreasureAction);
273     connect(seaLevelPreasureAction, SIGNAL(triggered()), this, SLOT(seaLevelPreasureMenuClicked()));
274
275     QAction *precipitationAction = new QAction(tr("Precipitation"), this);
276     menu->addAction(precipitationAction);
277     connect(precipitationAction, SIGNAL(triggered()), this, SLOT(precipitationMenuClicked()));
278
279     QAction *windVelocityAction = new QAction(tr("Wind Velocity"), this);
280     menu->addAction(windVelocityAction);
281     connect(windVelocityAction, SIGNAL(triggered()), this, SLOT(windVelocityMenuClicked()));
282
283     QAction *cloudinessAction = new QAction(tr("Cloudiness"), this);
284     menu->addAction(cloudinessAction);
285     connect(cloudinessAction, SIGNAL(triggered()), this, SLOT(cloudinessMenuClicked()));
286
287     QAction *temperatureAction = new QAction(tr("Temperature"), this);
288     menu->addAction(temperatureAction);
289     connect(temperatureAction, SIGNAL(triggered()), this, SLOT(temperatureMenuClicked()));
290
291     QAction *aboutAction = new QAction(tr("About"), this);
292     menu->addAction(aboutAction);
293     connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutMenuClicked()));
294 }
295 #endif
296
297 void MainWindow::loadSettings()
298 {
299     QSettings settings;
300
301     int forecastDomain = settings.value("ForecastDomain").toInt();
302     int forecastType = settings.value("ForecastType").toInt();
303
304     m_downloader->setForecastDomain((MedardDownloader::ForecastDomain) forecastDomain);
305 #ifdef Q_WS_MAEMO_6
306     m_domainComboBox->setCurrentIndex(forecastDomain);
307 #else
308     m_domainActionGroup->actions().at(forecastDomain)->setChecked(true);
309 #endif
310
311     switch ((MedardDownloader::ForecastType) forecastType) {
312         case MedardDownloader::SeaLevelPressure:
313             seaLevelPreasureMenuClicked();
314             break;
315
316         case MedardDownloader::Precipitation:
317             precipitationMenuClicked();
318             break;
319
320         case MedardDownloader::WindVelocity:
321             windVelocityMenuClicked();
322             break;
323
324         case MedardDownloader::Cloudiness:
325             cloudinessMenuClicked();
326             break;
327
328         case MedardDownloader::Temperature:
329             temperatureMenuClicked();
330             break;
331     }
332 }
333
334 void MainWindow::showNavigationButtons()
335 {
336     m_downloadRetryButton->hide();
337
338     m_minusDayButton->show();
339     m_plusDayButton->show();
340     m_minusHourButton->show();
341     m_plusHourButton->show();
342 }
343
344 void MainWindow::hideNavigationButtons(bool showRetryButton)
345 {
346     if (showRetryButton)
347         m_downloadRetryButton->show();
348     else
349         m_downloadRetryButton->hide();
350
351     m_minusDayButton->hide();
352     m_plusDayButton->hide();
353     m_minusHourButton->hide();
354     m_plusHourButton->hide();
355 }
356
357 void MainWindow::updateNavigationButtons()
358 {
359     if ((m_downloader->forecastDateOffset() - 24) < m_downloader->minForecastDateOffset()) {
360 //        m_minusDayButton->setDisabled(true);
361 //        m_plusDayButton->setDisabled(false);
362     } else if ((m_downloader->forecastDateOffset() + 24) > m_downloader->maxForecastDateOffset()) {
363 //        m_minusDayButton->setDisabled(false);
364 //        m_plusDayButton->setDisabled(true);
365     } else {
366 //        m_minusDayButton->setDisabled(false);
367 //        m_plusDayButton->setDisabled(false);
368     }
369
370     if ((m_downloader->forecastDateOffset() - 1) < m_downloader->minForecastDateOffset()) {
371 //        m_minusHourButton->setDisabled(true);
372 //        m_plusHourButton->setDisabled(false);
373     } else if ((m_downloader->forecastDateOffset() + 1) > m_downloader->maxForecastDateOffset()) {
374 //        m_minusHourButton->setDisabled(false);
375 //        m_plusHourButton->setDisabled(true);
376     } else {
377 //        m_minusHourButton->setDisabled(false);
378 //        m_plusHourButton->setDisabled(false);
379     }
380 }
381
382 void MainWindow::seaLevelPreasureMenuClicked()
383 {
384     forecastTypeChanged(tr("Sea Level Pressure"), MedardDownloader::SeaLevelPressure);
385 }
386
387 void MainWindow::precipitationMenuClicked()
388 {
389     forecastTypeChanged(tr("Precipitation"), MedardDownloader::Precipitation);
390 }
391
392 void MainWindow::windVelocityMenuClicked()
393 {
394     forecastTypeChanged(tr("Wind Velocity"), MedardDownloader::WindVelocity);
395 }
396
397 void MainWindow::cloudinessMenuClicked()
398 {
399     forecastTypeChanged(tr("Cloudiness"), MedardDownloader::Cloudiness);
400 }
401
402 void MainWindow::temperatureMenuClicked()
403 {
404     forecastTypeChanged(tr("Temperature"), MedardDownloader::Temperature);
405 }
406
407 void MainWindow::aboutMenuClicked()
408 {
409     AboutDialog *dialog = new AboutDialog();
410 #ifdef Q_WS_MAEMO_6
411     dialog->appear(scene(), MSceneWindow::DestroyWhenDismissed);
412 #else
413     dialog->exec();
414 #endif
415 }
416
417 void MainWindow::downloadAgainClicked()
418 {
419     m_forecast->clearImage(false);
420     m_downloader->downloadImage();
421
422     hideNavigationButtons(false);
423 }
424
425 void MainWindow::plusDayClicked()
426 {
427     forecastDateOffsetChanged(+24);
428 }
429
430 void MainWindow::minusDayClicked()
431 {
432     forecastDateOffsetChanged(-24);
433 }
434
435 void MainWindow::plusHourClicked()
436 {
437     forecastDateOffsetChanged(+1);
438 }
439
440 void MainWindow::minusHourClicked()
441 {
442     forecastDateOffsetChanged(-1);
443 }
444
445 void MainWindow::forecastTypeChanged(const QString label, MedardDownloader::ForecastType type)
446 {
447     m_forecastTypeLabel->setText(label);
448     m_forecast->clearImage(false);
449     m_downloader->setForecastType(type);
450     m_downloader->downloadImage();
451
452     QSettings settings;
453     settings.setValue("ForecastType", type);
454 }
455
456 void MainWindow::forecastDateOffsetChanged(int offset)
457 {
458     m_forecast->clearImage(false);
459     m_downloader->setForecastDateOffset(m_downloader->forecastDateOffset() + offset);
460     m_downloader->downloadImage();
461 }
462
463 #ifdef Q_WS_MAEMO_6
464 void MainWindow::forecastDomainChanged(int index)
465 {
466     m_forecast->clearImage(false);
467
468     if (index == 0)
469         m_downloader->setForecastDomain(MedardDownloader::Europe);
470     else
471         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
472
473     m_downloader->downloadImage();
474
475     QSettings settings;
476     settings.setValue("ForecastDomain", index);
477 }
478 #else
479 void MainWindow::forecastDomainChanged(QAction *action)
480 {
481     int forecastDomain = m_domainActionGroup->actions().indexOf(action);
482
483     m_forecast->clearImage(false);
484
485     if (forecastDomain == 0)
486         m_downloader->setForecastDomain(MedardDownloader::Europe);
487     else
488         m_downloader->setForecastDomain(MedardDownloader::CzechRepublic);
489
490     m_downloader->downloadImage();
491
492     QSettings settings;
493     settings.setValue("ForecastDomain", forecastDomain);
494 }
495 #endif
496
497 void MainWindow::downloadedFinished(const QString &filename, const QDateTime &date)
498 {
499     m_forecast->setImage(filename);
500     m_forecastInitialDateLabel->setText(tr("Forecast from:\n") +
501                                           m_downloader->forecastInitialDate().toString("dd.MM.yyyy hh:mm"));
502
503     /* upcase the first letter of name of day */
504     QString temp = date.toString("dddd\ndd.MM.yyyy hh:mm");
505     m_forecastDateLabel->setText(temp.replace(0, 1, temp.at(0).toUpper()));
506
507     showNavigationButtons();
508     updateNavigationButtons();
509 }
510
511 void MainWindow::downloadFailed()
512 {
513     m_forecast->clearImage(true);
514     m_forecastInitialDateLabel->setText("");
515     m_forecastDateLabel->setText("");
516
517     hideNavigationButtons(true);
518 }