~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/generic/dataengines/weather/weatherengine.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2007-2009 by Shawn Starr <shawn.starr@rogers.com>       *
 
3
 *   Copyright (C) 2009 by Aaron Seigo <aseigo@kde.org>                    *
 
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                         *
 
17
 *   Free Software Foundation, Inc.,                                       *
 
18
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
 
19
 ***************************************************************************/
 
20
 
 
21
#include "weatherengine.h"
 
22
 
 
23
#include <QCoreApplication>
 
24
#include <QTimer>
 
25
 
 
26
#include <KDebug>
 
27
#include <KLocale>
 
28
#include <KSycoca>
 
29
 
 
30
#include <Plasma/DataEngineManager>
 
31
#include <Plasma/DataContainer>
 
32
 
 
33
#include "ions/ion.h"
 
34
 
 
35
// Constructor
 
36
WeatherEngine::WeatherEngine(QObject *parent, const QVariantList& args)
 
37
        :  Plasma::DataEngine(parent, args),
 
38
           m_networkAvailable(false)
 
39
{
 
40
    Q_UNUSED(args)
 
41
 
 
42
    m_reconnectTimer.setSingleShot(true);
 
43
    connect(&m_reconnectTimer, SIGNAL(timeout()), this, SLOT(startReconnect()));
 
44
 
 
45
    // Globally notify all plugins to remove their sources (and unload plugin)
 
46
    connect(this, SIGNAL(sourceRemoved(QString)), this, SLOT(removeIonSource(QString)));
 
47
    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(unloadIons()));
 
48
}
 
49
 
 
50
// Destructor
 
51
WeatherEngine::~WeatherEngine()
 
52
{
 
53
    // Cleanup all private data.
 
54
    unloadIons();
 
55
}
 
56
 
 
57
/**
 
58
 * Loads an ion plugin given a plugin name found via KService.
 
59
 */
 
60
Plasma::DataEngine *WeatherEngine::loadIon(const QString& plugName)
 
61
{
 
62
    KPluginInfo foundPlugin;
 
63
 
 
64
    foreach(const KPluginInfo &info, Plasma::DataEngineManager::listEngineInfo("weatherengine")) {
 
65
        if (info.pluginName() == plugName) {
 
66
            foundPlugin = info;
 
67
            break;
 
68
        }
 
69
    }
 
70
 
 
71
    if (!foundPlugin.isValid()) {
 
72
        return NULL;
 
73
    }
 
74
 
 
75
    // Load the Ion plugin, store it into a QMap to handle multiple ions.
 
76
    Plasma::DataEngine *ion = Plasma::DataEngineManager::self()->loadEngine(foundPlugin.pluginName());
 
77
    ion->setObjectName(plugName);
 
78
    connect(ion, SIGNAL(sourceAdded(QString)), this, SLOT(newIonSource(QString)));
 
79
    connect(ion, SIGNAL(forceUpdate(IonInterface*,QString)), this, SLOT(forceUpdate(IonInterface*,QString)));
 
80
 
 
81
    m_ions << plugName;
 
82
 
 
83
    return ion;
 
84
}
 
85
 
 
86
/* FIXME: Q_PROPERTY functions to update the list of available plugins */
 
87
 
 
88
/**
 
89
 * Unload an Ion plugin given a Ion plugin name.
 
90
 */
 
91
void WeatherEngine::unloadIon(const QString &name)
 
92
{
 
93
    Plasma::DataEngineManager::self()->unloadEngine(name);
 
94
    m_ions.removeOne(name);
 
95
}
 
96
 
 
97
void WeatherEngine::init()
 
98
{
 
99
    // Get the list of available plugins but don't load them
 
100
    Solid::Networking::Status status = Solid::Networking::status();
 
101
    m_networkAvailable = (status == Solid::Networking::Connected ||
 
102
                             status == Solid::Networking::Unknown);
 
103
    connect(Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)),
 
104
            this, SLOT(networkStatusChanged(Solid::Networking::Status)));
 
105
    connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(updateIonList()));
 
106
 
 
107
    updateIonList();
 
108
    kDebug() << "init()";
 
109
}
 
110
 
 
111
void WeatherEngine::updateIonList(const QStringList &changedResources)
 
112
{
 
113
    if (changedResources.isEmpty() || changedResources.contains("services")) {
 
114
        removeAllData("ions");
 
115
        foreach (const KPluginInfo &info, Plasma::DataEngineManager::listEngineInfo("weatherengine")) {
 
116
            setData("ions", info.pluginName(),
 
117
                    QString("%1|%2").arg(info.property("Name").toString()).arg(info.pluginName()));
 
118
        }
 
119
    }
 
120
}
 
121
 
 
122
/**
 
123
 * SLOT: Get data from a new source
 
124
 */
 
125
void WeatherEngine::newIonSource(const QString& source)
 
126
{
 
127
    IonInterface *ion = qobject_cast<IonInterface*>(sender());
 
128
 
 
129
    if (!ion) {
 
130
        return;
 
131
    }
 
132
 
 
133
    kDebug() << "newIonSource()";
 
134
    ion->connectSource(source, this);
 
135
}
 
136
 
 
137
/**
 
138
 * SLOT: Remove the datasource from the ion and unload plugin if needed
 
139
 */
 
140
void WeatherEngine::removeIonSource(const QString& source)
 
141
{
 
142
    IonInterface *ion = ionForSource(source);
 
143
    if (ion) {
 
144
        ion->removeSource(source);
 
145
        // If plugin has no more sources let's unload the plugin
 
146
        if (ion->isEmpty()) {
 
147
            unloadIon(ionNameForSource(source));
 
148
        }
 
149
    }
 
150
    kDebug() << "removeIonSource()";
 
151
}
 
152
 
 
153
/**
 
154
 * SLOT: Push out new data to applet
 
155
 */
 
156
void WeatherEngine::dataUpdated(const QString& source, Plasma::DataEngine::Data data)
 
157
{
 
158
    kDebug() << "dataUpdated()";
 
159
    setData(source, data);
 
160
}
 
161
 
 
162
void WeatherEngine::unloadIons()
 
163
{
 
164
    foreach (const QString &ion, m_ions) {
 
165
        Plasma::DataEngineManager::self()->unloadEngine(ion);
 
166
    }
 
167
 
 
168
    m_ions.clear();
 
169
}
 
170
 
 
171
/**
 
172
 * SLOT: Set up each Ion for the first time and get any data
 
173
 */
 
174
bool WeatherEngine::sourceRequestEvent(const QString &source)
 
175
{
 
176
    Plasma::DataEngine *ion = ionForSource(source);
 
177
 
 
178
    if (!ion) {
 
179
        ion = loadIon(ionNameForSource(source));
 
180
        if (!ion) {
 
181
            return false;
 
182
        }
 
183
    }
 
184
 
 
185
    // we should connect to the ion anyway, even if the network
 
186
    // is down. when it comes up again, then it will be refreshed
 
187
    ion->connectSource(source, this);
 
188
 
 
189
    kDebug() << "sourceRequestEvent(): Network is: " << m_networkAvailable;
 
190
    if (!m_networkAvailable) {
 
191
        setData(source, Data());
 
192
        return true;
 
193
    }
 
194
 
 
195
    if (!containerForSource(source)) {
 
196
        // it is an async reply, we need to set up the data anyways
 
197
        setData(source, Data());
 
198
    }
 
199
    return true;
 
200
}
 
201
 
 
202
/**
 
203
 * SLOT: update the Applet with new data from all ions loaded.
 
204
 */
 
205
bool WeatherEngine::updateSourceEvent(const QString& source)
 
206
{
 
207
    IonInterface *ion = ionForSource(source);
 
208
    if (!ion) {
 
209
        return false;
 
210
    }
 
211
 
 
212
    kDebug() << "updateSourceEvent(): Network is: " << m_networkAvailable;
 
213
    if (!m_networkAvailable) {
 
214
        return false;
 
215
    }
 
216
 
 
217
    return ion->updateSourceEvent(source);
 
218
}
 
219
 
 
220
void WeatherEngine::networkStatusChanged(Solid::Networking::Status status)
 
221
{
 
222
    kDebug();
 
223
    m_networkAvailable = status == Solid::Networking::Connected || status == Solid::Networking::Unknown;
 
224
    if (m_networkAvailable) {
 
225
        // allow the network to settle down and actually come up
 
226
        m_reconnectTimer.start(5000);
 
227
    }
 
228
}
 
229
 
 
230
void WeatherEngine::startReconnect()
 
231
{
 
232
    foreach (const QString &i, m_ions) {
 
233
        IonInterface * ion = qobject_cast<IonInterface *>(Plasma::DataEngineManager::self()->engine(i));
 
234
        kDebug() << "resetting" << ion;
 
235
        if (ion) {
 
236
            ion->reset();
 
237
        }
 
238
    }
 
239
}
 
240
 
 
241
void WeatherEngine::forceUpdate(IonInterface *i, const QString &source)
 
242
{
 
243
    const QString actualSource(i->pluginName() + '|' + source);
 
244
    Plasma::DataContainer *container = containerForSource(source);
 
245
    if (container) {
 
246
        kDebug() << "immediate update of" << source;
 
247
        container->forceImmediateUpdate();
 
248
    } else {
 
249
        kDebug() << "innexplicable failure of" << source;
 
250
    }
 
251
}
 
252
 
 
253
IonInterface* WeatherEngine::ionForSource(const QString& name) const
 
254
{
 
255
    int offset = name.indexOf('|');
 
256
 
 
257
    if (offset < 1) {
 
258
        return NULL;
 
259
    }
 
260
 
 
261
    QString ionName = name.left(offset);
 
262
    return qobject_cast<IonInterface *>(Plasma::DataEngineManager::self()->engine(ionName));
 
263
}
 
264
 
 
265
QString WeatherEngine::ionNameForSource(const QString& source) const
 
266
{
 
267
    int offset = source.indexOf('|');
 
268
    if (offset < 1) {
 
269
        return QString();
 
270
    }
 
271
 
 
272
    return QString(source.left(offset));
 
273
}
 
274
 
 
275
#include "weatherengine.moc"