![]() |
Home · All Namespaces · All Classes |
00001 /**************************************************************************** 00002 ** 00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 00004 ** All rights reserved. 00005 ** Contact: Nokia Corporation (directui@nokia.com) 00006 ** 00007 ** This file is part of systemui. 00008 ** 00009 ** If you have questions regarding the use of this file, please contact 00010 ** Nokia at directui@nokia.com. 00011 ** 00012 ** This library is free software; you can redistribute it and/or 00013 ** modify it under the terms of the GNU Lesser General Public 00014 ** License version 2.1 as published by the Free Software Foundation 00015 ** and appearing in the file LICENSE.LGPL included in the packaging 00016 ** of this file. 00017 ** 00018 ****************************************************************************/ 00019 00020 #include <MApplication> 00021 #include "statusindicator.h" 00022 #include "statusindicatormodel.h" 00023 #include "inputmethodstatusindicatoradaptor.h" 00024 #include "applicationcontext.h" 00025 00026 // keep these in sync with the context framework! 00027 static const QString CONTEXT_CALLSTATE_ALERTING = "alerting"; 00028 static const QString CONTEXT_CALLSTATE_KNOCKING = "knocking"; 00029 static const QString CONTEXT_CALLSTATE_ACTIVE = "active"; 00030 00031 static const QString BATTERY_MODE_NORMAL = "Level"; 00032 static const QString BATTERY_MODE_CHARGING = "Charging"; 00033 static const QString BATTERY_MODE_POWERSAVE = "PowerSave"; 00034 static const QString BATTERY_MODE_POWERSAVE_AND_CHARGING = "PowerSaveCharging"; 00035 00036 static const QString NETWORK_NAME_START_DELIMITER = "("; 00037 static const QString NETWORK_NAME_END_DELIMITER = ")"; 00038 00039 const QString TransferStatusIndicator::TRANSFER_UI_DBUS_PATH="/com/nokia/transferui"; 00040 const QString TransferStatusIndicator::TRANSFER_UI_DBUS_INTERFACE="com.nokia.transferui"; 00041 const QString TransferStatusIndicator::TRANSFER_UI_DBUS_SIGNAL="stateChanged"; 00042 const QString TransferStatusIndicator::TRANSFER_UI_STATE_IDLE = "idle"; 00043 const QString TransferStatusIndicator::TRANSFER_UI_STATE_LIVE = "live"; 00044 const QString TransferStatusIndicator::TRANSFER_UI_STATE_FAIL = "fail"; 00045 const QString TransferStatusIndicator::TRANSFER_UI_STATE_PENDING = "pending"; 00046 const QString TransferStatusIndicator::TRANSFER_UI_SUFFIX_FAIL = "Fail"; 00047 const QString TransferStatusIndicator::TRANSFER_UI_SUFFIX_LIVE = "Live"; 00048 const QString TransferStatusIndicator::TRANSFER_UI_SUFFIX_PENDING = "Pending"; 00049 00050 StatusIndicator::StatusIndicator(QGraphicsItem *parent) : 00051 MWidgetController(new StatusIndicatorModel, parent), 00052 animateIfPossible(false), 00053 modelUpdatesEnabled(true), 00054 currentValue(QVariant()) 00055 { 00056 } 00057 00058 StatusIndicator::~StatusIndicator() 00059 { 00060 foreach(ContextItem* item, contextItems) { 00061 delete item; 00062 } 00063 } 00064 00065 void StatusIndicator::updateGeometry() 00066 { 00067 MWidgetController::updateGeometry(); 00068 } 00069 00070 void StatusIndicator::setValue(QVariant v) 00071 { 00072 currentValue = v; 00073 if (modelUpdatesEnabled) { 00074 model()->setValue(v); 00075 } 00076 } 00077 00078 QVariant StatusIndicator::value() const 00079 { 00080 return currentValue; 00081 } 00082 00083 void StatusIndicator::enterDisplayEvent() 00084 { 00085 setModelUpdatesEnabled(true); 00086 foreach(ContextItem* item, contextItems) { 00087 item->subscribe(); 00088 } 00089 } 00090 00091 void StatusIndicator::exitDisplayEvent() 00092 { 00093 setModelUpdatesEnabled(false); 00094 foreach(ContextItem* item, contextItems) { 00095 item->unsubscribe(); 00096 } 00097 } 00098 00099 void StatusIndicator::setModelUpdatesEnabled(bool modelUpdatesEnabled) 00100 { 00101 this->modelUpdatesEnabled = modelUpdatesEnabled; 00102 if (modelUpdatesEnabled) { 00103 model()->setValue(currentValue); 00104 } 00105 updateAnimationStatus(); 00106 } 00107 00108 void StatusIndicator::updateAnimationStatus() 00109 { 00110 if (modelUpdatesEnabled) { 00111 model()->setAnimate(animateIfPossible); 00112 } else { 00113 model()->setAnimate(false); 00114 } 00115 } 00116 00117 ContextItem *StatusIndicator::createContextItem(ApplicationContext& context, const QString& key) 00118 { 00119 ContextItem *item = context.createContextItem(key); 00120 contextItems.append(item); 00121 return item; 00122 } 00123 00124 PhoneNetworkSignalStrengthStatusIndicator::PhoneNetworkSignalStrengthStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00125 StatusIndicator(parent) 00126 { 00127 setObjectName(metaObject()->className()); 00128 00129 signalStrength = createContextItem(context, "Cellular.SignalBars"); 00130 connect(signalStrength, SIGNAL(contentsChanged()), this, SLOT(signalStrengthChanged())); 00131 00132 setValue(0); 00133 setDisplay(false); 00134 } 00135 00136 PhoneNetworkSignalStrengthStatusIndicator::~PhoneNetworkSignalStrengthStatusIndicator() 00137 { 00138 } 00139 00140 void PhoneNetworkSignalStrengthStatusIndicator::signalStrengthChanged() 00141 { 00142 setValue(signalStrength->value().toDouble() * 0.2f ); 00143 } 00144 00145 void PhoneNetworkSignalStrengthStatusIndicator::setDisplay(bool display) 00146 { 00147 if(display) { 00148 setObjectName(metaObject()->className()); 00149 } else { 00150 setObjectName(""); 00151 } 00152 } 00153 00154 00155 PhoneNetworkTypeStatusIndicator::PhoneNetworkTypeStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00156 StatusIndicator(parent), networkAvailable(false) 00157 { 00158 cellularDataTechnology = createContextItem(context, "Cellular.DataTechnology"); 00159 connect(cellularDataTechnology, SIGNAL(contentsChanged()), this, SLOT(setNetworkType())); 00160 00161 cellularRegistrationStatus = createContextItem(context, "Cellular.RegistrationStatus"); 00162 connect(cellularRegistrationStatus, SIGNAL(contentsChanged()), this, SLOT(setNetworkType())); 00163 00164 setNetworkType(); 00165 } 00166 00167 PhoneNetworkTypeStatusIndicator::~PhoneNetworkTypeStatusIndicator() 00168 { 00169 } 00170 00171 void PhoneNetworkTypeStatusIndicator::setNetworkType() 00172 { 00173 QString postFix = "NoNetwork"; 00174 00175 QString dataTechnology = cellularDataTechnology->value().toString(); // gprs egprs umts hspa 00176 QString status = cellularRegistrationStatus->value().toString(); // home roam no-sim offline forbidden 00177 00178 setValue(0); 00179 00180 if(status == "no-sim") { 00181 postFix = "NoSIM"; 00182 } else if(status == "" || status == "offline" || status == "forbidden") { 00183 postFix = "Offline"; 00184 } else { 00185 if(dataTechnology == "gprs") { 00186 postFix = "2G"; 00187 } else if(dataTechnology == "egprs") { 00188 postFix = "25G"; 00189 } else if(dataTechnology == "umts") { 00190 postFix = "3G"; 00191 } else if(dataTechnology == "hspa") { 00192 postFix = "35G"; 00193 } 00194 } 00195 00196 bool n = !(postFix == "NoNetwork" || postFix == "Offline" || postFix == "NoSIM"); 00197 if(n != networkAvailable) { 00198 networkAvailable = n; 00199 emit networkAvailabilityChanged(n); 00200 } 00201 00202 setObjectName(metaObject()->className() + postFix); 00203 } 00204 00205 BatteryStatusIndicator::BatteryStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00206 StatusIndicator(parent) 00207 { 00208 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_NORMAL); 00209 00210 batteryLevel = createContextItem(context, "Battery.ChargeBars"); 00211 connect(batteryLevel, SIGNAL(contentsChanged()), this, SLOT(batteryLevelChanged())); 00212 00213 batteryCharging = createContextItem(context, "Battery.IsCharging"); 00214 connect(batteryCharging, SIGNAL(contentsChanged()), this, SLOT(batteryChargingChanged())); 00215 00216 batterySaveMode = createContextItem(context, "System.PowerSaveMode"); 00217 connect(batterySaveMode, SIGNAL(contentsChanged()), this, SLOT(batteryChargingChanged())); 00218 00219 // Set the initial power save mode (in case it has been switched on before reboot, etc) 00220 if (batterySaveMode->value().toBool()) { 00221 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_POWERSAVE); 00222 } 00223 00224 batteryLevelChanged (); 00225 } 00226 00227 BatteryStatusIndicator::~BatteryStatusIndicator() 00228 { 00229 } 00230 00231 void BatteryStatusIndicator::batteryLevelChanged() 00232 { 00233 QList<QVariant> chargeBars = batteryLevel->value().toList(); 00234 if(chargeBars.count() == 2 ) { 00235 double remainingBars = chargeBars.at(0).toDouble(); 00236 double maximumBars = chargeBars.at(1).toDouble(); 00237 00238 // Smoke test - check that charge bar values are valid 00239 if((maximumBars > 0) && (remainingBars >= 0) && (maximumBars >= remainingBars)) { 00240 //simple mapping to percentage value 00241 double chargeValue = remainingBars/maximumBars; 00242 setValue(chargeValue); 00243 } else { 00244 // Error situation 00245 setValue(0.0); 00246 } 00247 } 00248 } 00249 00250 void BatteryStatusIndicator::batteryChargingChanged() 00251 { 00252 if (batteryCharging->value().toBool()) { 00253 if (batterySaveMode->value().toBool()) { 00254 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_POWERSAVE_AND_CHARGING); 00255 } else { 00256 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_CHARGING); 00257 } 00258 animateIfPossible = true; 00259 } else { 00260 if (batterySaveMode->value().toBool()) { 00261 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_POWERSAVE); 00262 } else { 00263 setObjectName(QString(metaObject()->className()) + BATTERY_MODE_NORMAL); 00264 } 00265 animateIfPossible = false; 00266 } 00267 00268 updateAnimationStatus(); 00269 batteryLevelChanged (); 00270 } 00271 00272 AlarmStatusIndicator::AlarmStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00273 StatusIndicator(parent) 00274 { 00275 setObjectName(metaObject()->className()); 00276 00277 alarm = createContextItem(context, "Alarm.Present"); 00278 connect(alarm, SIGNAL(contentsChanged()), this, SLOT(alarmChanged())); 00279 alarmChanged(); 00280 } 00281 00282 AlarmStatusIndicator::~AlarmStatusIndicator() 00283 { 00284 } 00285 00286 void AlarmStatusIndicator::alarmChanged() 00287 { 00288 bool isSet = alarm->value().toBool(); 00289 00290 if (isSet) { 00291 setObjectName(QString(metaObject()->className()) + "Set"); 00292 } else { 00293 setObjectName(QString(metaObject()->className())); 00294 } 00295 00296 emit alarmSettingChanged(isSet); 00297 } 00298 00299 BluetoothStatusIndicator::BluetoothStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00300 StatusIndicator(parent) 00301 { 00302 setObjectName(metaObject()->className()); 00303 00304 bluetoothEnabled = createContextItem(context, "Bluetooth.Enabled"); 00305 connect(bluetoothEnabled, SIGNAL(contentsChanged()), this, SLOT(bluetoothChanged())); 00306 bluetoothConnected = createContextItem(context, "Bluetooth.Connected"); 00307 connect(bluetoothConnected, SIGNAL(contentsChanged()), this, SLOT(bluetoothChanged())); 00308 } 00309 00310 BluetoothStatusIndicator::~BluetoothStatusIndicator() 00311 { 00312 } 00313 00314 void BluetoothStatusIndicator::bluetoothChanged() 00315 { 00316 bool enabled = bluetoothEnabled->value().toBool(); 00317 bool connected = bluetoothConnected->value().toBool(); 00318 00319 if (enabled) { 00320 if (connected) { 00321 setObjectName(QString(metaObject()->className()) + "Active"); 00322 } else { 00323 setObjectName(QString(metaObject()->className()) + "On"); 00324 } 00325 } else { 00326 setObjectName(QString(metaObject()->className())); 00327 } 00328 } 00329 00330 PresenceStatusIndicator::PresenceStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00331 StatusIndicator(parent) 00332 { 00333 setObjectName(metaObject()->className()); 00334 00335 presence = createContextItem(context, "Presence.State"); 00336 connect(presence, SIGNAL(contentsChanged()), this, SLOT(presenceChanged())); 00337 presenceChanged(); 00338 } 00339 00340 PresenceStatusIndicator::~PresenceStatusIndicator() 00341 { 00342 } 00343 00344 void PresenceStatusIndicator::presenceChanged() 00345 { 00346 QString status = presence->value().toString(); 00347 QString suffix; 00348 00349 if (status == "busy" || status == "available" || status == "away") { 00350 // Capitalize the status 00351 status.replace(0, 1, status[0].toUpper()); 00352 setObjectName(QString(metaObject()->className()) + status); 00353 } else if (status == "offline" || status == "") { 00354 // No presence information is treated as "offline" 00355 setObjectName(QString(metaObject()->className())); 00356 } 00357 } 00358 00359 InternetConnectionStatusIndicator::InternetConnectionStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00360 StatusIndicator(parent) 00361 { 00362 connectionType = createContextItem(context, "Internet.NetworkType"); 00363 connect(connectionType, SIGNAL(contentsChanged()), this, SLOT(updateStatus())); 00364 00365 connectionState = createContextItem(context, "Internet.NetworkState"); 00366 connect(connectionState, SIGNAL(contentsChanged()), this, SLOT(updateStatus())); 00367 00368 trafficIn = createContextItem(context, "Internet.TrafficIn"); 00369 connect(trafficIn, SIGNAL(contentsChanged()), this, SLOT(updateStatus())); 00370 00371 trafficOut = createContextItem(context, "Internet.TrafficOut"); 00372 connect(trafficOut, SIGNAL(contentsChanged()), this, SLOT(updateStatus())); 00373 00374 updateStatus(); 00375 } 00376 00377 InternetConnectionStatusIndicator::~InternetConnectionStatusIndicator() 00378 { 00379 } 00380 00381 void InternetConnectionStatusIndicator::updateStatus() 00382 { 00383 QString postFix = ""; 00384 00385 QString state = connectionState->value().toString(); // disconnected connecting connected 00386 QString connection = connectionType->value().toString(); // GPRS WLAN 00387 00388 uint trafficInPercentage = trafficIn->value().toInt(); 00389 uint trafficOutPercentage = trafficOut->value().toInt(); 00390 00391 setValue(0); 00392 00393 if(connection == "WLAN") { 00394 postFix = "WLAN"; 00395 } else if(connection == "GPRS") { 00396 postFix = "PacketData"; 00397 if(state == "connected" && (trafficInPercentage > 0 || trafficOutPercentage > 0)) { 00398 postFix += "Active"; 00399 } 00400 } 00401 00402 if(state == "connecting") { 00403 postFix += "Connecting"; 00404 animateIfPossible = true; 00405 } else if(state == "connected") { 00406 animateIfPossible = false; 00407 } else { 00408 postFix = ""; 00409 animateIfPossible = false; 00410 } 00411 00412 setObjectName(metaObject()->className() + postFix); 00413 00414 updateAnimationStatus(); 00415 } 00416 00417 PhoneNetworkStatusIndicator::PhoneNetworkStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00418 StatusIndicator(parent) 00419 { 00420 setObjectName(metaObject()->className()); 00421 00422 networkName = createContextItem(context, "Cellular.NetworkName"); 00423 connect(networkName, SIGNAL(contentsChanged()), this, SLOT(phoneNetworkChanged())); 00424 connect(&networkChangeShowVisitorTimer, SIGNAL(timeout()), this, SLOT(showVisitorNetworkName())); 00425 networkChangeShowVisitorTimer.setSingleShot(true); 00426 networkChangeShowVisitorTimer.setInterval(3*1000); 00427 phoneNetworkChanged(); 00428 } 00429 00430 QString PhoneNetworkStatusIndicator::homeNetwork() const { 00431 QStringList netNames(QString(networkName->value().toString()).split(NETWORK_NAME_START_DELIMITER)); 00432 if (netNames.count() >= 1) { 00433 return netNames.first().trimmed(); 00434 } else { 00435 return QString(); 00436 } 00437 } 00438 00439 QString PhoneNetworkStatusIndicator::visitorNetwork() const { 00440 QString networkString = networkName->value().toString().trimmed(); 00441 if (networkString.contains(NETWORK_NAME_START_DELIMITER) && 00442 networkString.endsWith(NETWORK_NAME_END_DELIMITER)) { 00443 // separates networkString into pieces divided by "(" 00444 QStringList netNames(networkString.split(NETWORK_NAME_START_DELIMITER)); 00445 // removes first string before "(" which is home network 00446 netNames.removeFirst(); 00447 // returns remaining string as it was, by joining the separated strings 00448 QString visitor = netNames.join(QString(NETWORK_NAME_START_DELIMITER)); 00449 // removes end delimiter ")" 00450 visitor.chop(1); 00451 return visitor.trimmed(); 00452 } else { 00453 return QString(); 00454 } 00455 } 00456 00457 PhoneNetworkStatusIndicator::~PhoneNetworkStatusIndicator() 00458 { 00459 } 00460 00461 void PhoneNetworkStatusIndicator::phoneNetworkChanged() 00462 { 00463 if (networkChangeShowVisitorTimer.isActive()) { 00464 networkChangeShowVisitorTimer.stop(); 00465 } 00466 QString home(homeNetwork()); 00467 QString visitor(visitorNetwork()); 00468 setValue(home); 00469 if (!visitor.isEmpty() && !home.isEmpty() && (home != visitor)) { 00470 networkChangeShowVisitorTimer.start(); 00471 } 00472 } 00473 00474 void PhoneNetworkStatusIndicator::showVisitorNetworkName() { 00475 setValue(visitorNetwork()); 00476 } 00477 00478 InputMethodStatusIndicator::InputMethodStatusIndicator(QGraphicsItem *parent) : 00479 StatusIndicator(parent) 00480 { 00481 setObjectName(metaObject()->className()); 00482 new InputMethodStatusIndicatorAdaptor(this); 00483 } 00484 00485 InputMethodStatusIndicator::~InputMethodStatusIndicator() 00486 { 00487 } 00488 00489 void InputMethodStatusIndicator::setIconID(const QString &iconID) 00490 { 00491 setValue(iconID); 00492 } 00493 00494 CallStatusIndicator::CallStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00495 StatusIndicator(parent) 00496 { 00497 setObjectName(metaObject()->className()); 00498 00499 call = createContextItem(context, "Phone.Call"); 00500 connect(call, SIGNAL(contentsChanged()), this, SLOT(callOrMutedChanged())); 00501 00502 muted = createContextItem(context, "Phone.Muted"); 00503 connect(muted, SIGNAL(contentsChanged()), this, SLOT(callOrMutedChanged())); 00504 } 00505 00506 CallStatusIndicator::~CallStatusIndicator() 00507 { 00508 } 00509 00510 void CallStatusIndicator::callOrMutedChanged() 00511 { 00512 QString callState = call->value().toString(); 00513 if (callState == CONTEXT_CALLSTATE_ALERTING 00514 || callState == CONTEXT_CALLSTATE_KNOCKING) { 00515 setObjectName(QString(metaObject()->className()) + "Ringing"); 00516 setValue(0); 00517 animateIfPossible = true; 00518 } else if (callState == CONTEXT_CALLSTATE_ACTIVE) { 00519 setObjectName(QString(metaObject()->className()) + "Ongoing"); 00520 setValue(muted->value().toBool() ? 1 : 0); 00521 animateIfPossible = false; 00522 } else { 00523 setObjectName(metaObject()->className()); 00524 setValue(0); 00525 animateIfPossible = false; 00526 } 00527 00528 updateAnimationStatus(); 00529 } 00530 00531 ProfileStatusIndicator::ProfileStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00532 StatusIndicator(parent) 00533 { 00534 setObjectName(metaObject()->className()); 00535 00536 profile = createContextItem(context, "Profile.Name"); 00537 connect(profile, SIGNAL(contentsChanged()), this, SLOT(profileChanged())); 00538 } 00539 00540 ProfileStatusIndicator::~ProfileStatusIndicator() 00541 { 00542 } 00543 00544 void ProfileStatusIndicator::profileChanged() 00545 { 00546 if (profile->value().toString() == "silent") { 00547 setObjectName(QString(metaObject()->className()) + "Silent"); 00548 } else { 00549 setObjectName(metaObject()->className()); 00550 } 00551 } 00552 00553 GPSStatusIndicator::GPSStatusIndicator(ApplicationContext &context, QGraphicsItem *parent) : 00554 StatusIndicator(parent) 00555 { 00556 setObjectName(metaObject()->className()); 00557 00558 gpsState = createContextItem(context, "Location.SatPositioningState"); 00559 connect(gpsState, SIGNAL(contentsChanged()), this, SLOT(gpsStateChanged())); 00560 } 00561 00562 GPSStatusIndicator::~GPSStatusIndicator() 00563 { 00564 } 00565 00566 void GPSStatusIndicator::gpsStateChanged() 00567 { 00568 if (gpsState->value().toString() == "on") { 00569 setObjectName(QString(metaObject()->className()) + "On"); 00570 animateIfPossible = false; 00571 } 00572 else if (gpsState->value().toString() == "search") { 00573 setObjectName(QString(metaObject()->className()) + "Search"); 00574 animateIfPossible = true; 00575 } 00576 else { 00577 setObjectName(QString(metaObject()->className())); 00578 animateIfPossible = false; 00579 } 00580 updateAnimationStatus(); 00581 } 00582 00583 TransferStatusIndicator::TransferStatusIndicator(QGraphicsItem *parent) : 00584 StatusIndicator(parent), 00585 connectionSessionBus(QDBusConnection::sessionBus()) 00586 { 00587 setStyleName(metaObject()->className()); 00588 00589 connectionSessionBus.connect(QString(),TRANSFER_UI_DBUS_PATH, TRANSFER_UI_DBUS_INTERFACE, TRANSFER_UI_DBUS_SIGNAL, 00590 this, SLOT(transferStateChanged(const QString&))); 00591 00592 } 00593 00594 TransferStatusIndicator::~TransferStatusIndicator() 00595 { 00596 } 00597 00598 void TransferStatusIndicator::transferStateChanged(const QString &state) 00599 { 00600 if (state == TRANSFER_UI_STATE_LIVE) { 00601 setStyleName(QString(metaObject()->className()) + TRANSFER_UI_SUFFIX_LIVE); 00602 } else if (state == TRANSFER_UI_STATE_FAIL) { 00603 setStyleName(QString(metaObject()->className()) + TRANSFER_UI_SUFFIX_FAIL); 00604 } else if (state == TRANSFER_UI_STATE_PENDING) { 00605 setStyleName(QString(metaObject()->className()) + TRANSFER_UI_SUFFIX_PENDING); 00606 } else { 00607 setStyleName(metaObject()->className()); 00608 } 00609 00610 updateAnimationStatus(); 00611 } 00612
| Copyright © 2010 Nokia Corporation | Generated on Thu Nov 4 2010 18:19:34 Doxygen 1.7.1 |
MeeGo Touch |
