Added spanish translation
[timedsilencer] / alarmd_backend.h
index fe77b53..4d9f272 100644 (file)
 #include <QTime>
 #include <QString>
 #include <QSettings>
+#include <QPair>
 #include <alarmd/libalarm.h>
 #include <dbus-1.0/dbus/dbus-protocol.h>
 #include <time.h>
 
 #include "phone_profile.h"
+#include "dbus_backend.h"
+#include "profileevent.h"
 
 // Alarmd documentation found at:
 // http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Generic_Platform_Components/Alarm_Framework
 class AlarmdBackend : public QObject {
   Q_OBJECT
 private:
-  static time_t toTime_t(QTime t) {
+  static time_t toTime_t(const QTime &t) {
     int time_diff = QTime::currentTime().secsTo(t);
     if(time_diff < 0) {
       // Add 24 hours
@@ -42,45 +45,135 @@ private:
     return (time_t) time(0) + time_diff;
   }
 
+  static uint32_t daysToMask(QList<int> days) {
+    uint32_t mask = 0;
+    foreach(const int& d, days) {
+      switch(d) {
+      case MON:
+        mask |= ALARM_RECUR_WDAY_MON;
+        break;
+      case TUE:
+        mask |= ALARM_RECUR_WDAY_TUE;
+        break;
+      case WED:
+        mask |= ALARM_RECUR_WDAY_WED;
+        break;
+      case THU:
+        mask |= ALARM_RECUR_WDAY_THU;
+        break;
+      case FRI:
+        mask |= ALARM_RECUR_WDAY_FRI;
+        break;
+      case SAT:
+        mask |= ALARM_RECUR_WDAY_SAT;
+        break;
+      case SUN:
+        mask |= ALARM_RECUR_WDAY_SUN;
+        break;
+      default:
+        Q_ASSERT(0); // Should never go here
+        mask |= ALARM_RECUR_WDAY_ALL;
+        break;
+      }
+    }
+    return mask;
+  }
+
 public:
-  static void deleteEvents() {
-    // Get events cookies
+  // Is only called on program uninstall
+  static void deleteAllEvents() {
     QSettings settings("TimedSilencer", "TimedSilencer");
-    cookie_t silent_cookie = settings.value("silencing_cookie", 0).toLongLong();
-    if(silent_cookie != 0) {
-      qDebug("Deleting silent profile event with cookie %ld", (long) silent_cookie);
-      alarmd_event_del(silent_cookie);
+    QHash<QString, QVariant> events = settings.value("events").toHash();
+    foreach(QVariant var_ev, events) {
+      ProfileEvent *pe = ProfileEvent::load(var_ev);
+      foreach(const long &cookie, pe->alarmd_cookies) {
+        qDebug("Unregistering event with cookie %ld", cookie);
+        alarmd_event_del(cookie);
+      }
+      delete pe;
     }
-    cookie_t general_cookie = settings.value("unsilencing_cookie", 0).toLongLong();
-    if(general_cookie != 0) {
-      qDebug("Deleting general profile event with cookie %ld", (long) general_cookie);
-      alarmd_event_del(general_cookie);
+    // Delete possible orphan events
+    cookie_t *orphan_cookies = alarmd_event_query(0,0,0,0, "TimedSilencer");
+    int i = 0;
+    while(orphan_cookies && orphan_cookies[i] != 0) {
+      alarmd_event_del(orphan_cookies[i]);
+      ++i;
     }
+    // Save in QSettings
+    events.clear();
+    settings.setValue("events", events);
   }
 
-  static void setProfileEvent(Profile p, QTime event_time) {
-    // Get event cookie
-    QSettings settings("TimedSilencer", "TimedSilencer");
-    cookie_t cookie;
-    if(p == SILENT)
-      cookie = settings.value("silencing_cookie", 0).toLongLong();
-    else
-      cookie = settings.value("unsilencing_cookie", 0).toLongLong();
-    alarm_event_t *eve = 0;
-    if(cookie == 0 || (eve = alarmd_event_get(cookie)) == 0) {
-      qDebug("Profile event does not exist yet, creating it...");
-      // The event does not exist yet
-      newProfileEvent(p, event_time);
-      return;
+  static void deleteOrphanEvents(QList<long> known_cookies) {
+    cookie_t *orphan_cookies = alarmd_event_query(0,0,0,0, "TimedSilencer");
+    int i = 0;
+    while(orphan_cookies && orphan_cookies[i] != 0) {
+      if(!known_cookies.contains(orphan_cookies[i]))
+        alarmd_event_del(orphan_cookies[i]);
+      ++i;
     }
-    // Update existing event
-    qDebug("Updating profile event with cookie %ld", (long)cookie);
-    eve->alarm_time = toTime_t(event_time);
-    alarmd_event_update(eve);
+  }
+
+  static void deleteEvents(QByteArray event_id) {
+    deleteEvents(ProfileEvent::findByID(event_id));
+  }
+
+  static void deleteEvents(ProfileEvent *pe) {
+    // unregistering events
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      qDebug("Unregistering event with cookie %ld", cookie);
+      alarmd_event_del(cookie);
+    }
+    pe->alarmd_cookies.clear();
+    ProfileEvent::clearCookies(pe->getID());
+  }
+
+  static void setProfileEvents(QByteArray event_id) {
+    setProfileEvents(ProfileEvent::findByID(event_id));
+  }
+
+  static bool checkIfStillActive(ProfileEvent *pe) {
+    Q_ASSERT(pe->activated);
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      alarm_event_t *eve = 0;
+      if((eve = alarmd_event_get(cookie)) != 0) {
+        // Free all dynamic memory associated with the alarm event
+        alarm_event_delete(eve);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static void setProfileEvents(ProfileEvent *pe) {
+    Q_ASSERT(pe->activated);
+    // First clear old alarmd events
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      qDebug("Unregistering event with cookie %ld", cookie);
+      alarmd_event_del(cookie);
+    }
+    pe->alarmd_cookies.clear();
+    // Then setting new events
+    long c1 = newProfileEvent(SILENT, pe->from_time, pe->days);
+    Q_ASSERT(c1 > 0);
+    if(c1 > 0)
+      pe->alarmd_cookies << c1;
+    long c2 = newProfileEvent(GENERAL, pe->to_time, pe->days);
+    Q_ASSERT(c2 > 0);
+    if(c2 > 0)
+      pe->alarmd_cookies << c2;
+    // Save in QSettings
+    ProfileEvent::setCookies(pe->getID(), pe->alarmd_cookies);
+    // Set Profile to SILENT if we are currently in the silent time slot
+    if(pe->affectsCurrentTime())
+      DBusBackend::setProfile(SILENT);
   }
 
 protected:
-  static void newProfileEvent(Profile p, QTime event_time) {
+  static long newProfileEvent(Profile p, const QTime &event_time, QList<int> days) {
+    Q_ASSERT(!days.empty());
+    qDebug("Registering an event");
+    if(days.empty()) days << NEVER;
     // Create the default alarm struct.
     alarm_event_t *newEvent = alarm_event_create();
     // Set the APP ID
@@ -91,9 +184,28 @@ protected:
     else
       alarm_event_set_title(newEvent, "general_profile");
     // Timing
-    newEvent->recur_secs = 86400; // 24 hours interval
-    newEvent->recur_count = -1; // Reoccur infinitely
-    newEvent->alarm_time = toTime_t(event_time);
+    if(days.first() == EVERY_DAY) {
+      newEvent->recur_secs = 86400; // 24 hours
+      newEvent->recur_count = -1; // Reoccur infinitely
+      newEvent->alarm_time = toTime_t(event_time); // Set event time
+    } else {
+      if(days.first() == NEVER) {
+        newEvent->alarm_time = toTime_t(event_time); // Set event time
+      } else {
+        qDebug("Using the new recurrence API");
+        newEvent->recur_count = -1;
+        newEvent->recur_secs = 0; // We re not using this way for recurrence
+        alarm_recur_t* recur = alarm_event_add_recurrences(newEvent, 1);
+        // Set event time
+        recur->special = ALARM_RECUR_SPECIAL_NONE;
+        recur->mask_mon = ALARM_RECUR_MON_ALL;
+        recur->mask_mday = ALARM_RECUR_MDAY_ALL;
+        recur->mask_hour = (1ul << event_time.hour());
+        recur->mask_min = (1ull << event_time.minute());
+        recur->mask_wday = daysToMask(days);
+        Q_ASSERT(newEvent->recurrence_cnt == 1);
+      }
+    }
     //Add 1 action to our alarm event, and assign it to the "act" variable
     alarm_action_t *act = alarm_event_add_actions(newEvent, 1);
     // Actions are documented here:
@@ -116,20 +228,10 @@ protected:
     }
 
     // Finally with everything setup, try to add your event to the alarm queue
-    cookie_t cookie = alarmd_event_add(newEvent);
-    if(cookie != 0) {
-      // Save cookie
-      QSettings settings("TimedSilencer", "TimedSilencer");
-      if(p == SILENT) {
-        qDebug("Saving silent profile event cookie: %ld", (long)cookie);
-        settings.setValue("silencing_cookie", static_cast<qlonglong>(cookie));
-      } else {
-        qDebug("Saving silent general event cookie: %ld", (long)cookie);
-        settings.setValue("unsilencing_cookie", static_cast<qlonglong>(cookie));
-      }
-      return;
-    }
-    qDebug("ERROR: Failed to add profile event to the queue!");
+    long cookie = alarmd_event_add(newEvent);
+    // Free all dynamic memory associated with the alarm event
+    alarm_event_delete(newEvent);
+    return cookie;
   }
 };