• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Engines

ion_noaa.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Shawn Starr <shawn.starr@rogers.com>            *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program; if not, write to the                         *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
00018  ***************************************************************************/
00019 
00020 /* Ion for NOAA's National Weather Service XML data */
00021 
00022 #include "ion_noaa.h"
00023 
00024 class NOAAIon::Private : public QObject
00025 {
00026 public:
00027     Private() { m_url=0; }
00028     ~Private() { delete m_url; }
00029 
00030 private:
00031     struct XMLMapInfo {
00032         QString stateName;
00033         QString stationName;
00034         QString XMLurl;
00035         QString sourceOptions;
00036     };
00037 
00038 public:
00039     // Key dicts
00040     QHash<QString, NOAAIon::Private::XMLMapInfo> m_place;
00041     QHash<QString, QString> m_locations;
00042     QString m_state;
00043     QString m_station_name;
00044     QString m_xmlurl;
00045 
00046     // Weather information
00047     QHash<QString, WeatherData> m_weatherData;
00048 
00049     // Store KIO jobs
00050     QMap<KJob *, QXmlStreamReader*> m_jobXml;
00051     QMap<KJob *, QString> m_jobList;
00052     QXmlStreamReader m_xmlSetup;
00053     KUrl *m_url;
00054     KIO::TransferJob *m_job;
00055 
00056     int m_timezoneType;  // Ion option: Timezone may be local time or UTC time
00057     int m_measureType; // Ion option: Units may be Metric or Imperial
00058     bool m_windInMeters; // Ion option: Display wind format in meters per second only
00059     bool m_windInKnots; // Ion option: Display wind format in knots
00060     bool m_windInBft; // ion option: Display wind by the beaufort scale model
00061 };
00062 
00063 
00064 // ctor, dtor
00065 NOAAIon::NOAAIon(QObject *parent, const QVariantList &args)
00066         : IonInterface(parent, args), d(new Private())
00067 {
00068     Q_UNUSED(args)
00069 }
00070 
00071 NOAAIon::~NOAAIon()
00072 {
00073     // Destroy dptr
00074     delete d;
00075 }
00076 
00077 // Get the master list of locations to be parsed
00078 void NOAAIon::init()
00079 {
00080     // Get the real city XML URL so we can parse this
00081     getXMLSetup();
00082 }
00083 
00084 QStringList NOAAIon::validate(const QString& source) const
00085 {
00086     QStringList placeList;
00087     QHash<QString, QString>::const_iterator it = d->m_locations.constBegin();
00088     while (it != d->m_locations.constEnd()) {
00089         if (it.value().toLower().contains(source.toLower())) {
00090             placeList.append(QString("place|%1").arg(it.value().split("|")[1]));
00091         }
00092         ++it;
00093     }
00094 
00095     // Check if placeList is empty if so, return nothing.
00096     if (placeList.isEmpty()) {
00097         return QStringList();
00098     }
00099 
00100     placeList.sort();
00101     return placeList;
00102 }
00103 
00104 bool NOAAIon::updateIonSource(const QString& source)
00105 {
00106     // We expect the applet to send the source in the following tokenization:
00107     // ionname:validate:place_name - Triggers validation of place
00108     // ionname:weather:place_name - Triggers receiving weather of place
00109 
00110     kDebug() << "updateIonSource() SOURCE: " << source;
00111     QStringList sourceAction = source.split('|');
00112     if (sourceAction[1] == QString("validate")) {
00113         kDebug() << "Initiate Validating of place: " << sourceAction[2];
00114         QStringList result = validate(QString("%1|%2").arg(sourceAction[0]).arg(sourceAction[2]));
00115 
00116         if (result.size() == 1) {
00117             setData(source, "validate", QString("noaa|valid|single|%1").arg(result.join("|")));
00118             return true;
00119         } else if (result.size() > 1) {
00120             setData(source, "validate", QString("noaa|valid|multiple|%1").arg(result.join("|")));
00121             return true;
00122         } else if (result.size() == 0) {
00123             setData(source, "validate", QString("noaa|invalid|single|%1").arg(sourceAction[2]));
00124             return true;
00125         }
00126 
00127     } else if (sourceAction[1] == QString("weather")) {
00128         getXMLData(source);
00129         return true;
00130     }
00131     return false;
00132 }
00133 
00134 // Parses city list and gets the correct city based on ID number
00135 void NOAAIon::getXMLSetup()
00136 {
00137     d->m_url = new KUrl("http://www.weather.gov/data/current_obs/index.xml");
00138 
00139     KIO::TransferJob *job = KIO::get(d->m_url->url(), KIO::NoReload, KIO::HideProgressInfo);
00140 
00141     if (job) {
00142         connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00143                 SLOT(setup_slotDataArrived(KIO::Job *, const QByteArray &)));
00144         connect(job, SIGNAL(result(KJob *)), this, SLOT(setup_slotJobFinished(KJob *)));
00145     }
00146 }
00147 
00148 // Gets specific city XML data
00149 void NOAAIon::getXMLData(const QString& source)
00150 {
00151     KUrl url;
00152 
00153     QString dataKey = source;
00154     dataKey.replace("|weather", "");
00155     url = d->m_place[dataKey].XMLurl;
00156 
00157     kDebug() << "URL Location: " << url.url();
00158 
00159     d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00160     d->m_jobXml.insert(d->m_job, new QXmlStreamReader);
00161     d->m_jobList.insert(d->m_job, source);
00162 
00163     if (d->m_job) {
00164         connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00165                 SLOT(slotDataArrived(KIO::Job *, const QByteArray &)));
00166         connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(slotJobFinished(KJob *)));
00167     }
00168 }
00169 
00170 void NOAAIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data)
00171 {
00172     Q_UNUSED(job)
00173 
00174     if (data.isEmpty()) {
00175         return;
00176     }
00177 
00178     // Send to xml.
00179     d->m_xmlSetup.addData(data);
00180 }
00181 
00182 void NOAAIon::slotDataArrived(KIO::Job *job, const QByteArray &data)
00183 {
00184 
00185     if (data.isEmpty() || !d->m_jobXml.contains(job)) {
00186         return;
00187     }
00188 
00189     // Send to xml.
00190     d->m_jobXml[job]->addData(data);
00191 }
00192 
00193 void NOAAIon::slotJobFinished(KJob *job)
00194 {
00195     // Dual use method, if we're fetching location data to parse we need to do this first
00196     setData(d->m_jobList[job], Data());
00197     readXMLData(d->m_jobList[job], *d->m_jobXml[job]);
00198     d->m_jobList.remove(job);
00199     delete d->m_jobXml[job];
00200     d->m_jobXml.remove(job);
00201 }
00202 
00203 void NOAAIon::setup_slotJobFinished(KJob *job)
00204 {
00205     Q_UNUSED(job)
00206     readXMLSetup();
00207     setInitialized(true);
00208 }
00209 
00210 void NOAAIon::parseStationID()
00211 {
00212     QString tmp;
00213     while (!d->m_xmlSetup.atEnd()) {
00214         d->m_xmlSetup.readNext();
00215 
00216         if (d->m_xmlSetup.isEndElement() && d->m_xmlSetup.name() == "station") {
00217             break;
00218         }
00219 
00220         if (d->m_xmlSetup.isStartElement()) {
00221             if (d->m_xmlSetup.name() == "state") {
00222                 d->m_state = d->m_xmlSetup.readElementText();
00223             } else if (d->m_xmlSetup.name() == "station_name") {
00224                 d->m_station_name = d->m_xmlSetup.readElementText();
00225             } else if (d->m_xmlSetup.name() == "xml_url") {
00226                 d->m_xmlurl = d->m_xmlSetup.readElementText();
00227 
00228                 tmp = "noaa|" + d->m_station_name + ", " + d->m_state; // Build the key name.
00229                 d->m_place[tmp].stateName = d->m_state;
00230                 d->m_place[tmp].stationName = d->m_station_name;
00231                 d->m_place[tmp].XMLurl = d->m_xmlurl.replace("http://", "http://www.");
00232 
00233                 d->m_locations[tmp] = tmp;
00234             } else {
00235                 parseUnknownElement(d->m_xmlSetup);
00236             }
00237         }
00238     }
00239 }
00240 
00241 void NOAAIon::parseStationList()
00242 {
00243     while (!d->m_xmlSetup.atEnd()) {
00244         d->m_xmlSetup.readNext();
00245 
00246         if (d->m_xmlSetup.isEndElement()) {
00247             break;
00248         }
00249 
00250         if (d->m_xmlSetup.isStartElement()) {
00251             if (d->m_xmlSetup.name() == "station") {
00252                 parseStationID();
00253             } else {
00254                 parseUnknownElement(d->m_xmlSetup);
00255             }
00256         }
00257     }
00258 }
00259 
00260 // Parse the city list and store into a QMap
00261 bool NOAAIon::readXMLSetup()
00262 {
00263     while (!d->m_xmlSetup.atEnd()) {
00264         d->m_xmlSetup.readNext();
00265 
00266         if (d->m_xmlSetup.isStartElement()) {
00267             if (d->m_xmlSetup.name() == "wx_station_index") {
00268                 parseStationList();
00269             }
00270         }
00271     }
00272     return !d->m_xmlSetup.error();
00273 }
00274 
00275 WeatherData NOAAIon::parseWeatherSite(WeatherData& data, QXmlStreamReader& xml)
00276 {
00277     data.temperature_C = "N/A";
00278     data.temperature_F = "N/A";
00279     data.dewpoint_C = "N/A";
00280     data.dewpoint_F = "N/A";
00281     data.weather = "N/A";
00282     data.stationID = "N/A";
00283     data.pressure = "N/A";
00284     data.visibility = "N/A";
00285     data.humidity = "N/A";
00286     data.windSpeed = "N/A";
00287     data.windGust = "N/A";
00288     data.windchill_F = "N/A";
00289     data.windchill_C = "N/A";
00290     data.heatindex_F = "N/A";
00291     data.heatindex_C = "N/A";
00292 
00293     while (!xml.atEnd()) {
00294         xml.readNext();
00295 
00296         if (xml.isStartElement()) {
00297             if (xml.name() == "location") {
00298                 data.locationName = xml.readElementText();
00299             } else if (xml.name() == "station_id") {
00300                 data.stationID = xml.readElementText();
00301             } else if (xml.name() == "observation_time") {
00302                 data.observationTime = xml.readElementText();
00303             } else if (xml.name() == "weather") {
00304                 data.weather = xml.readElementText();
00305             } else if (xml.name() == "temp_f") {
00306                 data.temperature_F = xml.readElementText();
00307             } else if (xml.name() == "temp_c") {
00308                 data.temperature_C = xml.readElementText();
00309             } else if (xml.name() == "relative_humidity") {
00310                 data.humidity = xml.readElementText();
00311             } else if (xml.name() == "wind_dir") {
00312                 data.windDirection = xml.readElementText();
00313             } else if (xml.name() == "wind_mph") {
00314                 data.windSpeed = xml.readElementText();
00315             } else if (xml.name() == "wind_gust_mph") {
00316                 data.windGust = xml.readElementText();
00317             } else if (xml.name() == "pressure_in") {
00318                 data.pressure = xml.readElementText();
00319             } else if (xml.name() == "dewpoint_f") {
00320                 data.dewpoint_F = xml.readElementText();
00321             } else if (xml.name() == "dewpoint_c") {
00322                 data.dewpoint_C = xml.readElementText();
00323             } else if (xml.name() == "heat_index_f") {
00324                 data.heatindex_F = xml.readElementText();
00325             } else if (xml.name() == "heat_index_c") {
00326                 data.heatindex_C = xml.readElementText();
00327             } else if (xml.name() == "windchill_f") {
00328                 data.windchill_F = xml.readElementText();
00329             } else if (xml.name() == "windchill_c") {
00330                 data.windchill_C = xml.readElementText();
00331             } else if (xml.name() == "visibility_mi") {
00332                 data.visibility = xml.readElementText();
00333             } else {
00334                 parseUnknownElement(xml);
00335             }
00336         }
00337     }
00338     return data;
00339 }
00340 
00341 // Parse Weather data main loop, from here we have to decend into each tag pair
00342 bool NOAAIon::readXMLData(const QString& source, QXmlStreamReader& xml)
00343 {
00344     WeatherData data;
00345 
00346     while (!xml.atEnd()) {
00347         xml.readNext();
00348 
00349         if (xml.isEndElement()) {
00350             break;
00351         }
00352 
00353         if (xml.isStartElement()) {
00354             if (xml.name() == "current_observation") {
00355                 data = parseWeatherSite(data, xml);
00356             } else {
00357                 parseUnknownElement(xml);
00358             }
00359         }
00360     }
00361 
00362     d->m_weatherData[source] = data;
00363     updateWeather(source);
00364     return !xml.error();
00365 }
00366 
00367 // handle when no XML tag is found
00368 void NOAAIon::parseUnknownElement(QXmlStreamReader& xml)
00369 {
00370 
00371     while (!xml.atEnd()) {
00372         xml.readNext();
00373 
00374         if (xml.isEndElement()) {
00375             break;
00376         }
00377 
00378         if (xml.isStartElement()) {
00379             parseUnknownElement(xml);
00380         }
00381     }
00382 }
00383 
00384 void NOAAIon::setMeasureUnit(const QString& unitType)
00385 {
00386     d->m_measureType = unitType.toInt();
00387 }
00388 
00389 // Not used in this ion yet.
00390 void NOAAIon::setTimezoneFormat(const QString& tz)
00391 {
00392     d->m_timezoneType = tz.toInt(); // Boolean
00393 }
00394 
00395 bool NOAAIon::metricUnit()
00396 {
00397     if (d->m_measureType == KLocale::Metric) {
00398         return true;
00399     }
00400 
00401     // Imperial units
00402     return false;
00403 }
00404 
00405 // Not used in this ion yet.
00406 bool NOAAIon::timezone()
00407 {
00408     if (d->m_timezoneType) {
00409         return true;
00410     }
00411 
00412     // Not UTC, local time
00413     return false;
00414 }
00415 
00416 void NOAAIon::updateWeather(const QString& source)
00417 {
00418     QMap<QString, QString> dataFields;
00419     QStringList fieldList;
00420 
00421     setData(source, "Country", country(source));
00422     setData(source, "Place", place(source));
00423     setData(source, "Station", station(source));
00424 
00425     // Real weather - Current conditions
00426     setData(source, "Observation Period", observationTime(source));
00427     setData(source, "Current Conditions", condition(source));
00428     dataFields = temperature(source);
00429     setData(source, "Temperature", dataFields["temperature"]);
00430 
00431     if (dataFields["temperature"] != "N/A") {
00432         setData(source, "Temperature Unit", dataFields["temperatureUnit"]);
00433     }
00434 
00435     // Do we have a comfort temperature? if so display it
00436     if (dataFields["comfortTemperature"] != "N/A") {
00437         if (d->m_weatherData[source].windchill_F != "NA") {
00438             setData(source, "Windchill", QString("%1%2").arg(dataFields["comfortTemperature"]).arg(QChar(176)));
00439             setData(source, "Humidex", "N/A");
00440         }
00441         if (d->m_weatherData[source].heatindex_F != "NA" && d->m_weatherData[source].temperature_F.toInt() != d->m_weatherData[source].heatindex_F.toInt()) {
00442             setData(source, "Humidex", QString("%1%2").arg(dataFields["comfortTemperature"]).arg(QChar(176)));
00443             setData(source, "Windchill", "N/A");
00444         }
00445     } else {
00446         setData(source, "Windchill", "N/A");
00447         setData(source, "Humidex", "N/A");
00448     }
00449 
00450     setData(source, "Dewpoint", dewpoint(source));
00451     if (dewpoint(source) != "N/A") {
00452         setData(source, "Dewpoint Unit", dataFields["temperatureUnit"]);
00453     }
00454 
00455     dataFields = pressure(source);
00456     setData(source, "Pressure", dataFields["pressure"]);
00457 
00458     if (dataFields["pressure"] != "N/A") {
00459         setData(source, "Pressure Unit", dataFields["pressureUnit"]);
00460     }
00461 
00462     dataFields = visibility(source);
00463     setData(source, "Visibility", dataFields["visibility"]);
00464 
00465     if (dataFields["visibility"] != "N/A") {
00466         setData(source, "Visibility Unit", dataFields["visibilityUnit"]);
00467     }
00468 
00469     setData(source, "Humidity", humidity(source));
00470 
00471     dataFields = wind(source);
00472     setData(source, "Wind Speed", dataFields["windSpeed"]);
00473 
00474     if (dataFields["windSpeed"] != "Calm") {
00475         setData(source, "Wind Speed Unit", dataFields["windUnit"]);
00476     }
00477 
00478     setData(source, "Wind Gust", dataFields["windGust"]);
00479     setData(source, "Wind Gust Unit", dataFields["windGustUnit"]);
00480     setData(source, "Wind Direction", dataFields["windDirection"]);
00481     setData(source, "Credit", "Data provided by NOAA National Weather Service");
00482 }
00483 
00484 QString NOAAIon::country(const QString& source)
00485 {
00486     Q_UNUSED(source);
00487     return QString("USA");
00488 }
00489 QString NOAAIon::place(const QString& source)
00490 {
00491     return d->m_weatherData[source].locationName;
00492 }
00493 QString NOAAIon::station(const QString& source)
00494 {
00495     return d->m_weatherData[source].stationID;
00496 }
00497 
00498 QString NOAAIon::observationTime(const QString& source)
00499 {
00500     return d->m_weatherData[source].observationTime;
00501 }
00502 QString NOAAIon::condition(const QString& source)
00503 {
00504     if (d->m_weatherData[source].weather.isEmpty() || d->m_weatherData[source].weather == "NA") {
00505         d->m_weatherData[source].weather = "N/A";
00506     }
00507     return d->m_weatherData[source].weather;
00508 }
00509 
00510 QString NOAAIon::dewpoint(const QString& source)
00511 {
00512     if (metricUnit()) {
00513         return d->m_weatherData[source].dewpoint_C;
00514     }
00515     return d->m_weatherData[source].dewpoint_F;
00516 }
00517 
00518 QString NOAAIon::humidity(const QString& source)
00519 {
00520     if (d->m_weatherData[source].humidity == "NA") {
00521         return QString("N/A");
00522     } else {
00523         return QString("%1%").arg(d->m_weatherData[source].humidity);
00524     }
00525 }
00526 
00527 QMap<QString, QString> NOAAIon::visibility(const QString& source)
00528 {
00529     QMap<QString, QString> visibilityInfo;
00530     if (d->m_weatherData[source].visibility.isEmpty()) {
00531         visibilityInfo.insert("visibility", QString("N/A"));
00532         return visibilityInfo;
00533     }
00534     if (metricUnit()) {
00535         visibilityInfo.insert("visibility", QString::number(WeatherFormula::milesToKM(d->m_weatherData[source].visibility.toFloat()), 'f', 1));
00536         visibilityInfo.insert("visibilityUnit", "km");
00537         return visibilityInfo;
00538     }
00539     visibilityInfo.insert("visibility", d->m_weatherData[source].visibility);
00540     visibilityInfo.insert("visibilityUnit", "mi");
00541     return visibilityInfo;
00542 }
00543 
00544 QMap<QString, QString> NOAAIon::temperature(const QString& source)
00545 {
00546     QMap<QString, QString> temperatureInfo;
00547     if (metricUnit()) {
00548         temperatureInfo.insert("temperature", d->m_weatherData[source].temperature_C);
00549         temperatureInfo.insert("temperatureUnit", QString("%1C").arg(QChar(176)));
00550     } else {
00551         temperatureInfo.insert("temperature", d->m_weatherData[source].temperature_F);
00552         temperatureInfo.insert("temperatureUnit", QString("%1F").arg(QChar(176)));
00553     }
00554     temperatureInfo.insert("comfortTemperature", "N/A");
00555 
00556     if (d->m_weatherData[source].heatindex_F != "NA" && d->m_weatherData[source].windchill_F == "NA") {
00557         if (metricUnit()) {
00558             temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].heatindex_C);
00559         } else {
00560             temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].heatindex_F);
00561         }
00562     }
00563     if (d->m_weatherData[source].windchill_F != "NA" && d->m_weatherData[source].heatindex_F == "NA") {
00564         if (metricUnit()) {
00565             temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].windchill_C);
00566         } else {
00567             temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].windchill_F);
00568         }
00569     }
00570 
00571     return temperatureInfo;
00572 }
00573 
00574 QMap<QString, QString> NOAAIon::pressure(const QString& source)
00575 {
00576     QMap<QString, QString> pressureInfo;
00577     if (d->m_weatherData[source].pressure.isEmpty()) {
00578         pressureInfo.insert("pressure", "N/A");
00579         return pressureInfo;
00580     }
00581     if (metricUnit()) {
00582         pressureInfo.insert("pressure", QString::number(WeatherFormula::inchesToKilopascals(d->m_weatherData[source].pressure.toFloat()), 'f', 1));
00583         pressureInfo.insert("pressureUnit", "kPa");
00584     } else {
00585         pressureInfo.insert("pressure", d->m_weatherData[source].pressure);
00586         pressureInfo.insert("pressureUnit", "in");
00587     }
00588     return pressureInfo;
00589 }
00590 
00591 QMap<QString, QString> NOAAIon::wind(const QString& source)
00592 {
00593     QMap<QString, QString> windInfo;
00594 
00595     // May not have any winds
00596     if (d->m_weatherData[source].windSpeed == "NA") {
00597         windInfo.insert("windSpeed", "Calm");
00598         windInfo.insert("windUnit", "N/A");
00599     } else {
00600         if (metricUnit()) {
00601                 windInfo.insert("windSpeed", QString::number(WeatherFormula::milesToKM(d->m_weatherData[source].windSpeed.toFloat()), 'f', 1));
00602                 windInfo.insert("windUnit", "km/h");
00603         } else {
00604                 windInfo.insert("windSpeed", QString::number(d->m_weatherData[source].windSpeed.toFloat(), 'f', 1));
00605                 windInfo.insert("windUnit", "mph");
00606         }
00607     }
00608 
00609     // May not always have gusty winds
00610     if (d->m_weatherData[source].windGust == "NA") {
00611         windInfo.insert("windGust", "N/A");
00612         windInfo.insert("windGustUnit", "N/A");
00613     } else {
00614         if (metricUnit()) {
00615                 windInfo.insert("windGust", QString::number(WeatherFormula::milesToKM(d->m_weatherData[source].windGust.toFloat()), 'f', 1));
00616                 windInfo.insert("windGustUnit", "km/h");
00617         } else {
00618                 windInfo.insert("windGust", QString::number(d->m_weatherData[source].windGust.toFloat(), 'f', 1));
00619                 windInfo.insert("windGustUnit", "mph");
00620           }
00621     }
00622 
00623     if (d->m_weatherData[source].windDirection.isEmpty()) {
00624         windInfo.insert("windDirection", "N/A");
00625     } else {
00626         windInfo.insert("windDirection", d->m_weatherData[source].windDirection);
00627     }
00628     return windInfo;
00629 }
00630 
00631 #include "ion_noaa.moc"

Engines

Skip menu "Engines"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal