OSDN Git Service

kdeplasma-addons: use KMessageWidget instead of KMessageBox for the weather configura...
[kde/kde-extraapps.git] / kdeplasma-addons / libs / plasmaweather / weatherconfig.cpp
1 /*
2  *   Copyright (C) 2009 Petri Damstén <damu@iki.fi>
3  *
4  *   This program is free software; you can redistribute it and/or modify
5  *   it under the terms of the GNU Library General Public License as
6  *   published by the Free Software Foundation; either version 2, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details
13  *
14  *   You should have received a copy of the GNU Library General Public
15  *   License along with this program; if not, write to the
16  *   Free Software Foundation, Inc.,
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include "weatherconfig.h"
21
22 #include <KDebug>
23 #include <KDialog>
24 #include <KInputDialog>
25 #include <KPixmapSequence>
26 #include <KPixmapSequenceWidget>
27 #include <KUnitConversion>
28
29 #include "weatherlocation.h"
30 #include "weathervalidator.h"
31 #include "weatheri18ncatalog.h"
32 #include "ui_weatherconfig.h"
33
34 class WeatherConfig::Private
35 {
36 public:
37     Private(WeatherConfig *weatherconfig)
38         : q(weatherconfig),
39         location(nullptr),
40         validator(nullptr),
41         ion("wettercom"),
42         dlg(nullptr),
43         busyWidget(nullptr)
44     {
45     }
46
47     void setSource(int index)
48     {
49         // do not emit the signals when searching, valid source may not even be found
50         if (!searchLocation.isEmpty()) {
51             return;
52         }
53
54         QString text = ui.locationCombo->itemData(index).toString();
55         if (!text.isEmpty()) {
56             source = text;
57             emit q->settingsChanged();
58             emit q->configValueChanged();
59         }
60     }
61
62     void changePressed()
63     {
64         if (!validator) {
65             kWarning() << "No validator";
66             return;
67         }
68
69         QString text = ui.locationCombo->currentText();
70
71         if (text.isEmpty()) {
72             return;
73         }
74
75         if (location) {
76             delete location;
77             location = nullptr;
78         }
79
80         searchLocation = text;
81         ui.locationCombo->clear();
82
83         if (!busyWidget) {
84             busyWidget = new KPixmapSequenceWidget(q);
85             KPixmapSequence seq(QLatin1String("process-working"), 22);
86             busyWidget->setSequence(seq);
87             ui.locationSearchLayout->insertWidget(1, busyWidget);
88         }
89
90         validator->validate(text, true);
91     }
92
93     void enableOK()
94     {
95         if (dlg) {
96             dlg->enableButton(KDialog::Ok, !source.isEmpty());
97         }
98     }
99
100     void addSource(const QString &sources);
101     void addSources(const QMap<QString, QString> &sources);
102     void validatorError(const QString &error);
103
104     WeatherConfig* q;
105     QString searchLocation;
106     WeatherLocation* location;
107     WeatherValidator* validator;
108     QString ion;
109     QString source;
110     Ui::WeatherConfig ui;
111     KDialog *dlg;
112     KPixmapSequenceWidget *busyWidget;
113 };
114
115 WeatherConfig::WeatherConfig(QWidget *parent)
116     : QWidget(parent)
117     , d(new Private(this))
118 {
119     Weatheri18nCatalog::loadCatalog();
120
121     d->dlg = qobject_cast<KDialog*>(parent);
122     d->ui.setupUi(this);
123     for (int i = 0; i < KTemperature::UnitCount; i++) {
124         KTemperature::KTempUnit unit = static_cast<KTemperature::KTempUnit>(i);
125         d->ui.temperatureComboBox->addItem(KTemperature::unitDescription(unit), unit);
126     }
127     for (int i = 0; i < KPressure::UnitCount; i++) {
128         KPressure::KPresUnit unit = static_cast<KPressure::KPresUnit>(i);
129         d->ui.pressureComboBox->addItem(KPressure::unitDescription(unit), unit);
130     }
131     for (int i = 0; i < KVelocity::UnitCount; i++) {
132         KVelocity::KVeloUnit unit = static_cast<KVelocity::KVeloUnit>(i);
133         d->ui.speedComboBox->addItem(KVelocity::unitDescription(unit), unit);
134     }
135     for (int i = 0; i < KLength::UnitCount; i++) {
136         KLength::KLengUnit unit = static_cast<KLength::KLengUnit>(i);
137         d->ui.visibilityComboBox->addItem(KLength::unitDescription(unit), unit);
138     }
139
140     d->ui.locationMessage->hide();
141     d->ui.locationMessage->setMessageType(KMessageWidget::Error);
142
143     connect(d->ui.locationCombo, SIGNAL(returnPressed()), this, SLOT(changePressed()));
144     connect(d->ui.changeButton, SIGNAL(clicked()), this, SLOT(changePressed()));
145
146     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)),
147             this, SLOT(setUpdateInterval(int)));
148
149     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)),
150             this, SIGNAL(settingsChanged()));
151     connect(d->ui.temperatureComboBox, SIGNAL(currentIndexChanged(int)),
152             this, SIGNAL(settingsChanged()));
153     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)),
154             this, SIGNAL(settingsChanged()));
155     connect(d->ui.speedComboBox, SIGNAL(currentIndexChanged(int)),
156             this, SIGNAL(settingsChanged()));
157     connect(d->ui.visibilityComboBox, SIGNAL(currentIndexChanged(int)),
158             this, SIGNAL(settingsChanged()));
159     connect(d->ui.locationCombo, SIGNAL(currentIndexChanged(int)),
160             this, SLOT(setSource(int)));
161
162     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
163     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)) , this , SIGNAL(configValueChanged()));
164     connect(d->ui.temperatureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
165     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
166     connect(d->ui.speedComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
167     connect(d->ui.visibilityComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
168 }
169
170 WeatherConfig::~WeatherConfig()
171 {
172     delete d;
173 }
174
175 void WeatherConfig::setDataEngines(Plasma::DataEngine *location, Plasma::DataEngine *weather)
176 {
177     delete d->validator;
178     d->validator = nullptr;
179     if (weather) {
180         d->validator = new WeatherValidator(this);
181         connect(d->validator, SIGNAL(error(QString)), this, SLOT(validatorError(QString)));
182         connect(d->validator, SIGNAL(finished(QMap<QString,QString>)), this, SLOT(addSources(QMap<QString,QString>)));
183         d->validator->setDataEngine(weather);
184         d->validator->setIon(d->ion);
185     }
186     if (location && weather) {
187         d->location = new WeatherLocation(this);
188         connect(d->location, SIGNAL(valid(QString)), this, SLOT(addSource(QString)));
189         d->location->setDataEngines(location, weather);
190     }
191 }
192
193 void WeatherConfig::Private::validatorError(const QString &error)
194 {
195     kDebug() << error;
196 }
197
198 void WeatherConfig::Private::addSource(const QString &source)
199 {
200     QStringList list = source.split(QLatin1Char('|'), QString::SkipEmptyParts);
201     if (list.count() > 2) {
202         // kDebug() << list;
203         QString result = i18nc("A weather station location and the weather service it comes from",
204                                 "%1 (%2)", list[2], list[0]); // the names are too looong ions.value(list[0]));
205         const int resultIndex = ui.locationCombo->findText(result);
206         if (resultIndex < 0) {
207             ui.locationCombo->addItem(result, source);
208         }
209     }
210 }
211
212 void WeatherConfig::Private::addSources(const QMap<QString, QString> &sources)
213 {
214     QMapIterator<QString, QString> it(sources);
215
216     while (it.hasNext()) {
217         it.next();
218         addSource(it.value());
219     }
220
221     delete busyWidget;
222     busyWidget = nullptr;
223     kDebug() << ui.locationCombo->count();
224     if (ui.locationCombo->count() == 0) {
225         ui.locationMessage->setText(i18n("No weather stations found for '%1'", searchLocation));
226         ui.locationMessage->animatedShow();
227     } else {
228         ui.locationCombo->showPopup();
229     }
230     searchLocation.clear();
231 }
232
233 void WeatherConfig::setUpdateInterval(int interval)
234 {
235     d->ui.updateIntervalSpinBox->setValue(interval);
236     d->ui.updateIntervalSpinBox->setSuffix(ki18np(" minute", " minutes"));
237 }
238
239 void WeatherConfig::setTemperatureUnit(const QString &unit)
240 {
241     KTemperature temp(0.0, unit);
242     if (temp.unitEnum() != KTemperature::Invalid) {
243         d->ui.temperatureComboBox->setCurrentIndex(static_cast<int>(temp.unitEnum()));
244     }
245 }
246
247 void WeatherConfig::setPressureUnit(const QString &unit)
248 {
249     KPressure pres(0.0, unit);
250     if (pres.unitEnum() != KPressure::Invalid) {
251         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(pres.unitEnum()));
252     }
253 }
254
255 void WeatherConfig::setSpeedUnit(const QString &unit)
256 {
257     KVelocity velo(0.0, unit);
258     if (velo.unitEnum() != KVelocity::Invalid) {
259         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(velo.unitEnum()));
260     }
261 }
262
263 void WeatherConfig::setVisibilityUnit(const QString &unit)
264 {
265     KLength leng(0.0, unit);
266     if (leng.unitEnum() != KLength::Invalid) {
267         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(leng.unitEnum()));
268     }
269 }
270
271 void WeatherConfig::setSource(const QString &source)
272 {
273     // kDebug() << "source set to" << source;
274     d->addSource(source);
275     d->source = source;
276 }
277
278 QString WeatherConfig::source() const
279 {
280     return d->source;
281 }
282
283 int WeatherConfig::updateInterval() const
284 {
285     return d->ui.updateIntervalSpinBox->value();
286 }
287
288 QString WeatherConfig::temperatureUnit() const
289 {
290     KTemperature temp(0.0, static_cast<KTemperature::KTempUnit>(d->ui.temperatureComboBox->currentIndex()));
291     return temp.unit();
292 }
293
294 QString WeatherConfig::pressureUnit() const
295 {
296     KPressure pres(0.0, static_cast<KPressure::KPresUnit>(d->ui.pressureComboBox->currentIndex()));
297     return pres.unit();
298 }
299
300 QString WeatherConfig::speedUnit() const
301 {
302     KVelocity velo(0.0, static_cast<KVelocity::KVeloUnit>(d->ui.speedComboBox->currentIndex()));
303     return velo.unit();
304 }
305
306 QString WeatherConfig::visibilityUnit() const
307 {
308     KLength leng(0.0, static_cast<KLength::KLengUnit>(d->ui.visibilityComboBox->currentIndex()));
309     return leng.unit();
310 }
311
312 void WeatherConfig::setConfigurableUnits(const ConfigurableUnits units)
313 {
314     d->ui.unitsLabel->setVisible(units != None);
315     d->ui.temperatureLabel->setVisible(units & Temperature);
316     d->ui.temperatureComboBox->setVisible(units & Temperature);
317     d->ui.pressureLabel->setVisible(units & Pressure);
318     d->ui.pressureComboBox->setVisible(units & Pressure);
319     d->ui.speedLabel->setVisible(units & Speed);
320     d->ui.speedComboBox->setVisible(units & Speed);
321     d->ui.visibilityLabel->setVisible(units & Visibility);
322     d->ui.visibilityComboBox->setVisible(units & Visibility);
323 }
324
325 void WeatherConfig::setHeadersVisible(bool visible)
326 {
327     d->ui.locationLabel->setVisible(visible);
328     d->ui.unitsLabel->setVisible(visible);
329 }
330
331 void WeatherConfig::setIon(const QString &ion)
332 {
333     d->ion = ion;
334     if (d->validator) {
335         d->validator->setIon(ion);
336     }
337     if (d->location) {
338         d->location->getDefault(ion);
339     }
340 }
341
342 #include "moc_weatherconfig.cpp"