OSDN Git Service

fc27faf038a575a55b16e100e655d908be84c2c9
[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 #include <KMessageBox>
29
30 #include "weatherlocation.h"
31 #include "weathervalidator.h"
32 #include "weatheri18ncatalog.h"
33 #include "ui_weatherconfig.h"
34
35 class WeatherConfig::Private
36 {
37 public:
38     Private(WeatherConfig *weatherconfig)
39         : q(weatherconfig),
40         location(nullptr),
41         validator(nullptr),
42         ion("wettercom"),
43         dlg(nullptr),
44         busyWidget(nullptr)
45     {
46     }
47
48     void setSource(int index)
49     {
50         QString text = ui.locationCombo->itemData(index).toString();
51         if (!text.isEmpty()) {
52             source = text;
53             emit q->settingsChanged();
54         }
55     }
56
57     void changePressed()
58     {
59         QString text = ui.locationCombo->currentText();
60
61         if (text.isEmpty()) {
62             return;
63         }
64
65         if (location) {
66             delete location;
67             location = nullptr;
68         }
69
70         searchLocation = text;
71         ui.locationCombo->clear();
72
73         if (!busyWidget) {
74             busyWidget = new KPixmapSequenceWidget(q);
75             KPixmapSequence seq(QLatin1String("process-working"), 22);
76             busyWidget->setSequence(seq);
77             ui.locationSearchLayout->insertWidget(1, busyWidget);
78         }
79
80         validator->validate(text, true);
81     }
82
83     void enableOK()
84     {
85         if (dlg) {
86             dlg->enableButton(KDialog::Ok, !source.isEmpty());
87         }
88     }
89
90     void addSource(const QString &sources);
91     void addSources(const QMap<QString, QString> &sources);
92     void validatorError(const QString &error);
93
94     WeatherConfig* q;
95     QString searchLocation;
96     WeatherLocation* location;
97     WeatherValidator* validator;
98     QString ion;
99     QString source;
100     Ui::WeatherConfig ui;
101     KDialog *dlg;
102     KPixmapSequenceWidget *busyWidget;
103 };
104
105 WeatherConfig::WeatherConfig(QWidget *parent)
106     : QWidget(parent)
107     , d(new Private(this))
108 {
109     Weatheri18nCatalog::loadCatalog();
110
111     d->dlg = qobject_cast<KDialog*>(parent);
112     d->ui.setupUi(this);
113     for (int i = 0; i < KTemperature::UnitCount; i++) {
114         KTemperature::KTempUnit unit = static_cast<KTemperature::KTempUnit>(i);
115         d->ui.temperatureComboBox->addItem(KTemperature::unitDescription(unit), unit);
116     }
117     for (int i = 0; i < KPressure::UnitCount; i++) {
118         KPressure::KPresUnit unit = static_cast<KPressure::KPresUnit>(i);
119         d->ui.pressureComboBox->addItem(KPressure::unitDescription(unit), unit);
120     }
121     for (int i = 0; i < KVelocity::UnitCount; i++) {
122         KVelocity::KVeloUnit unit = static_cast<KVelocity::KVeloUnit>(i);
123         d->ui.speedComboBox->addItem(KVelocity::unitDescription(unit), unit);
124     }
125     for (int i = 0; i < KLength::UnitCount; i++) {
126         KLength::KLengUnit unit = static_cast<KLength::KLengUnit>(i);
127         d->ui.visibilityComboBox->addItem(KLength::unitDescription(unit), unit);
128     }
129
130     connect(d->ui.locationCombo, SIGNAL(returnPressed()), this, SLOT(changePressed()));
131     connect(d->ui.changeButton, SIGNAL(clicked()), this, SLOT(changePressed()));
132
133     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)),
134             this, SLOT(setUpdateInterval(int)));
135
136     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)),
137             this, SIGNAL(settingsChanged()));
138     connect(d->ui.temperatureComboBox, SIGNAL(currentIndexChanged(int)),
139             this, SIGNAL(settingsChanged()));
140     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)),
141             this, SIGNAL(settingsChanged()));
142     connect(d->ui.speedComboBox, SIGNAL(currentIndexChanged(int)),
143             this, SIGNAL(settingsChanged()));
144     connect(d->ui.visibilityComboBox, SIGNAL(currentIndexChanged(int)),
145             this, SIGNAL(settingsChanged()));
146     connect(d->ui.locationCombo, SIGNAL(currentIndexChanged(int)),
147             this, SLOT(setSource(int)));
148     
149     connect(d->ui.locationCombo, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
150     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
151     connect(d->ui.updateIntervalSpinBox, SIGNAL(valueChanged(int)) , this , SIGNAL(configValueChanged()));
152     connect(d->ui.temperatureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
153     connect(d->ui.pressureComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
154     connect(d->ui.speedComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
155     connect(d->ui.visibilityComboBox, SIGNAL(currentIndexChanged(int)) , this , SIGNAL(configValueChanged()));
156 }
157
158 WeatherConfig::~WeatherConfig()
159 {
160     delete d;
161 }
162
163 void WeatherConfig::setDataEngines(Plasma::DataEngine *location, Plasma::DataEngine *weather)
164 {
165     delete d->validator;
166     d->validator = nullptr;
167     if (weather) {
168         d->validator = new WeatherValidator(this);
169         connect(d->validator, SIGNAL(error(QString)), this, SLOT(validatorError(QString)));
170         connect(d->validator, SIGNAL(finished(QMap<QString,QString>)), this, SLOT(addSources(QMap<QString,QString>)));
171         d->validator->setDataEngine(weather);
172         d->validator->setIon(d->ion);
173     }
174     if (location && weather) {
175         d->location = new WeatherLocation(this);
176         connect(d->location, SIGNAL(valid(QString)), this, SLOT(addSource(QString)));
177         d->location->setDataEngines(location, weather);
178     }
179 }
180
181 void WeatherConfig::Private::validatorError(const QString &error)
182 {
183     kDebug() << error;
184 }
185
186 void WeatherConfig::Private::addSource(const QString &source)
187 {
188     QStringList list = source.split(QLatin1Char('|'), QString::SkipEmptyParts);
189     if (list.count() > 2) {
190         // kDebug() << list;
191         QString result = i18nc("A weather station location and the weather service it comes from",
192                                 "%1 (%2)", list[2], list[0]); // the names are too looong ions.value(list[0]));
193         const int resultIndex = ui.locationCombo->findText(result);
194         if (resultIndex < 0) {
195             ui.locationCombo->addItem(result, source);
196         }
197     }
198 }
199
200 void WeatherConfig::Private::addSources(const QMap<QString, QString> &sources)
201 {
202     QMapIterator<QString, QString> it(sources);
203
204     while (it.hasNext()) {
205         it.next();
206         addSource(it.value());
207     }
208
209     delete busyWidget;
210     busyWidget = nullptr;
211     kDebug() << ui.locationCombo->count();
212     if (ui.locationCombo->count() == 0) {
213         KMessageBox::information(
214             q,
215             i18n("No weather stations found for '%1'", searchLocation),
216             i18n("No weather stations found"),
217             QString::fromLatin1("WeatherConfig")
218         );
219     } else {
220         ui.locationCombo->showPopup();
221     }
222 }
223
224 void WeatherConfig::setUpdateInterval(int interval)
225 {
226     d->ui.updateIntervalSpinBox->setValue(interval);
227     d->ui.updateIntervalSpinBox->setSuffix(ki18np(" minute", " minutes"));
228 }
229
230 void WeatherConfig::setTemperatureUnit(const QString &unit)
231 {
232     KTemperature temp(0.0, unit);
233     if (temp.unitEnum() != KTemperature::Invalid) {
234         d->ui.temperatureComboBox->setCurrentIndex(static_cast<int>(temp.unitEnum()));
235     }
236 }
237
238 void WeatherConfig::setPressureUnit(const QString &unit)
239 {
240     KPressure pres(0.0, unit);
241     if (pres.unitEnum() != KPressure::Invalid) {
242         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(pres.unitEnum()));
243     }
244 }
245
246 void WeatherConfig::setSpeedUnit(const QString &unit)
247 {
248     KVelocity velo(0.0, unit);
249     if (velo.unitEnum() != KVelocity::Invalid) {
250         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(velo.unitEnum()));
251     }
252 }
253
254 void WeatherConfig::setVisibilityUnit(const QString &unit)
255 {
256     KLength leng(0.0, unit);
257     if (leng.unitEnum() != KLength::Invalid) {
258         d->ui.pressureComboBox->setCurrentIndex(static_cast<int>(leng.unitEnum()));
259     }
260 }
261
262 void WeatherConfig::setSource(const QString &source)
263 {
264     // kDebug() << "source set to" << source;
265     d->addSource(source);
266     d->source = source;
267 }
268
269 QString WeatherConfig::source() const
270 {
271     return d->source;
272 }
273
274 int WeatherConfig::updateInterval() const
275 {
276     return d->ui.updateIntervalSpinBox->value();
277 }
278
279 QString WeatherConfig::temperatureUnit() const
280 {
281     KTemperature temp(0.0, static_cast<KTemperature::KTempUnit>(d->ui.temperatureComboBox->currentIndex()));
282     return temp.unit();
283 }
284
285 QString WeatherConfig::pressureUnit() const
286 {
287     KPressure pres(0.0, static_cast<KPressure::KPresUnit>(d->ui.pressureComboBox->currentIndex()));
288     return pres.unit();
289 }
290
291 QString WeatherConfig::speedUnit() const
292 {
293     KVelocity velo(0.0, static_cast<KVelocity::KVeloUnit>(d->ui.speedComboBox->currentIndex()));
294     return velo.unit();
295 }
296
297 QString WeatherConfig::visibilityUnit() const
298 {
299     KLength leng(0.0, static_cast<KLength::KLengUnit>(d->ui.visibilityComboBox->currentIndex()));
300     return leng.unit();
301 }
302
303 void WeatherConfig::setConfigurableUnits(const ConfigurableUnits units)
304 {
305     d->ui.unitsLabel->setVisible(units != None);
306     d->ui.temperatureLabel->setVisible(units & Temperature);
307     d->ui.temperatureComboBox->setVisible(units & Temperature);
308     d->ui.pressureLabel->setVisible(units & Pressure);
309     d->ui.pressureComboBox->setVisible(units & Pressure);
310     d->ui.speedLabel->setVisible(units & Speed);
311     d->ui.speedComboBox->setVisible(units & Speed);
312     d->ui.visibilityLabel->setVisible(units & Visibility);
313     d->ui.visibilityComboBox->setVisible(units & Visibility);
314 }
315
316 void WeatherConfig::setHeadersVisible(bool visible)
317 {
318     d->ui.locationLabel->setVisible(visible);
319     d->ui.unitsLabel->setVisible(visible);
320 }
321
322 void WeatherConfig::setIon(const QString &ion)
323 {
324     d->ion = ion;
325     if (d->validator) {
326         d->validator->setIon(ion);
327     }
328     if (d->location) {
329         d->location->getDefault(ion);
330     }
331 }
332
333 #include "moc_weatherconfig.cpp"