PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/contour-0.1.2/contourd/recommendation/RecommendationScriptEngine.cpp

#
C++ | 236 lines | 157 code | 55 blank | 24 comment | 10 complexity | c31f67ab795fde2a589d645498e2e433 MD5 | raw file
  1. /*
  2. * Copyright (C) 2011 Ivan Cukic <ivan.cukic(at)kde.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2,
  6. * or (at your option) any later version, as published by the Free
  7. * Software Foundation
  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 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. #include "RecommendationScriptEngine.h"
  20. #include "RecommendationScriptEngine_p.h"
  21. #include <QScriptEngine>
  22. #include <QScriptValue>
  23. #include <QTextStream>
  24. #include <QFile>
  25. #include <QTimer>
  26. #include <QDesktopServices>
  27. #include <QUrl>
  28. #include <QtSensors/QSensor>
  29. #include <KDebug>
  30. #include <KStandardDirs>
  31. #include "sensors/dbus/DBusSensor.h"
  32. namespace Contour {
  33. RecommendationScriptEngineConfig::RecommendationScriptEngineConfig(QObject * parent, KConfigGroup * config)
  34. : QObject(parent), m_config(config)
  35. {
  36. }
  37. RecommendationScriptEngineConfig::~RecommendationScriptEngineConfig()
  38. {
  39. delete m_config;
  40. }
  41. #define CREATE_CONFIG_METHODS(TYPE, TYPECASE) \
  42. TYPE RecommendationScriptEngineConfig::TYPECASE##Value(const QString & field, TYPE defaultValue) const \
  43. { return m_config->readEntry(field, defaultValue); } \
  44. void RecommendationScriptEngineConfig::Set##TYPECASE##Value(const QString & field, TYPE newValue) const \
  45. { kDebug() << field << newValue; m_config->writeEntry(field, newValue); m_config->sync(); }
  46. CREATE_CONFIG_METHODS(bool, Bool)
  47. CREATE_CONFIG_METHODS(int, Int)
  48. CREATE_CONFIG_METHODS(QString, String)
  49. CREATE_CONFIG_METHODS(QStringList, StringList)
  50. #undef CREATE_CONFIG_METHODS
  51. /**
  52. *
  53. */
  54. RecommendationScriptEngine::RecommendationScriptEngine(QObject * parent, const QString & script)
  55. : RecommendationEngine(parent), d(new Private())
  56. {
  57. d->script = script;
  58. kDebug() << "RecommendationScriptEngine()" << script << name();
  59. d->delay.setInterval(300);
  60. d->delay.setSingleShot(true);
  61. connect(&(d->delay), SIGNAL(timeout()),
  62. this, SLOT(sendUpdateNotification()));
  63. }
  64. RecommendationScriptEngine::~RecommendationScriptEngine()
  65. {
  66. delete d;
  67. }
  68. void RecommendationScriptEngine::init()
  69. {
  70. Contour::RecommendationEngine::init();
  71. QFile file(KStandardDirs::locate("data", "contour/scripts/" + d->script + "/main.js"));
  72. if (!file.open(QIODevice::ReadOnly)) {
  73. kDebug() << "Failed to open main.js for" << d->script;
  74. return;
  75. }
  76. d->engine = new QScriptEngine(this);
  77. connect(d->engine, SIGNAL(signalHandlerException(QScriptValue)),
  78. this, SLOT(signalHandlerException(QScriptValue)));
  79. d->engine->globalObject().setProperty("self",
  80. d->engine->newQObject(this));
  81. const QScriptValue & result = d->engine->evaluate(QTextStream(&file).readAll());
  82. if (d->engine->hasUncaughtException()) {
  83. int line = d->engine->uncaughtExceptionLineNumber();
  84. kDebug() << "uncaught exception at line" << line << ":" << result.toString();
  85. }
  86. }
  87. void RecommendationScriptEngine::activate(const QString & id, const QString & action)
  88. {
  89. if (d->autoremove)
  90. removeRecommendation(id);
  91. emit activationRequested(id, action);
  92. }
  93. QString RecommendationScriptEngine::name() const
  94. {
  95. kDebug() << d->script;
  96. return d->script;
  97. }
  98. QScriptValue RecommendationScriptEngine::getSensor(const QString & sensor)
  99. {
  100. kDebug() << "sensor" << sensor;
  101. QObject * result = NULL;
  102. if (sensor == "DBus") {
  103. kDebug() << "Returning the D-Bus sensor. This is not in QtMobility";
  104. result = new DBusSensor();
  105. } else {
  106. result = new QtMobility::QSensor(sensor.toAscii());
  107. }
  108. return d->engine->newQObject(result, QScriptEngine::AutoOwnership);
  109. }
  110. QScriptValue RecommendationScriptEngine::getConfig()
  111. {
  112. return d->engine->newQObject(new RecommendationScriptEngineConfig(this, config()));
  113. }
  114. QScriptValue RecommendationScriptEngine::getTimer(int msec)
  115. {
  116. kDebug() << "timer" << msec;
  117. QTimer * timer = new QTimer();
  118. timer->setSingleShot(false);
  119. timer->setInterval(msec);
  120. timer->start();
  121. return d->engine->newQObject(timer, QScriptEngine::AutoOwnership);
  122. }
  123. void RecommendationScriptEngine::openUrl(const QString & url)
  124. {
  125. QDesktopServices::openUrl(QUrl(url));
  126. }
  127. void RecommendationScriptEngine::signalHandlerException(const QScriptValue & exception)
  128. {
  129. kDebug() << "exception" << exception.toVariant();
  130. }
  131. void RecommendationScriptEngine::addRecommendation(
  132. double score,
  133. const QString & id,
  134. const QString & title,
  135. const QString & description,
  136. const QString & icon
  137. )
  138. {
  139. // kDebug() << d->script << score << id << title;
  140. int i = 0;
  141. while (d->recommendations.size() > i &&
  142. d->recommendations[i].score > score) {
  143. ++i;
  144. }
  145. RecommendationItem ri;
  146. ri.score = score;
  147. ri.id = id;
  148. ri.title = title;
  149. ri.description = description;
  150. ri.icon = icon;
  151. d->recommendations.insert(i, ri);
  152. delayedUpdateNotification();
  153. }
  154. void RecommendationScriptEngine::removeRecommendation(const QString & id)
  155. {
  156. QMutableListIterator < RecommendationItem > i(d->recommendations);
  157. while (i.hasNext()) {
  158. RecommendationItem ri = i.next();
  159. if (ri.id == id) {
  160. i.remove();
  161. }
  162. }
  163. delayedUpdateNotification();
  164. }
  165. void RecommendationScriptEngine::removeRecommendations()
  166. {
  167. d->recommendations.clear();
  168. delayedUpdateNotification();
  169. }
  170. void RecommendationScriptEngine::delayedUpdateNotification()
  171. {
  172. d->delay.start();
  173. }
  174. void RecommendationScriptEngine::sendUpdateNotification()
  175. {
  176. // just in case, although it is a single-shot
  177. d->delay.stop();
  178. emit recommendationsUpdated(d->recommendations);
  179. }
  180. } // namespace Contour
  181. // class RecommendationScriptEngine