Main Page | Data Structures | File List | Data Fields | Globals

eventrecurring.c

Go to the documentation of this file.
00001 /**
00002  * This file is part of alarmd
00003  *
00004  * Contact Person: David Weinehall <david.weinehall@nokia.com>
00005  *
00006  * Copyright (C) 2006 Nokia Corporation
00007  * alarmd and libalarm are free software; you can redistribute them
00008  * and/or modify them under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  *
00011  * alarmd and libalarm are distributed in the hope that they will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this software; if not, write to the Free
00018  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
00020  */
00021 
00022 #include <glib.h>
00023 #include <glib-object.h>
00024 #include "include/alarm_event.h"
00025 #include "eventrecurring.h"
00026 #include "debug.h"
00027 
00028 static void alarmd_event_recurring_init(AlarmdEventRecurring *event_recurring);
00029 static void alarmd_event_recurring_class_init(AlarmdEventRecurringClass *klass);
00030 static void _alarmd_event_recurring_set_property(GObject *object,
00031                 guint param_id,
00032                 const GValue *value,
00033                 GParamSpec *pspec);
00034 static void _alarmd_event_recurring_get_property(GObject *object,
00035                 guint param_id,
00036                 GValue *value,
00037                 GParamSpec *pspec);
00038 
00039 static void _alarmd_event_recurring_real_acknowledge(AlarmdEvent *event);
00040 static void _alarmd_event_recurring_changed(AlarmdObject *object);
00041 static GSList *_alarmd_event_recurring_get_saved_properties(void);
00042 static void _alarmd_event_recurring_time_changed(AlarmdObject *object);
00043 
00044 enum saved_props {
00045         S_RECURR_INTERVAL,
00046         S_RECURR_COUNT,
00047         S_REAL_TIME,
00048         S_COUNT
00049 };
00050 enum properties {
00051         PROP_RECURR_INTERVAL = 1,
00052         PROP_RECURR_COUNT,
00053         PROP_REAL_TIME
00054 };
00055 
00056 static const gchar * const saved_properties[S_COUNT] =
00057 {
00058         "recurr_interval",
00059         "recurr_count",
00060         "real_time"
00061 };
00062 
00063 typedef struct _AlarmdEventRecurringPrivate AlarmdEventRecurringPrivate;
00064 struct _AlarmdEventRecurringPrivate {
00065         gint recurr_interval;
00066         gint recurr_count;
00067         guint64 real_time;
00068 };
00069 
00070 
00071 #define ALARMD_EVENT_RECURRING_GET_PRIVATE(obj) \
00072 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
00073                               ALARMD_TYPE_EVENT_RECURRING, AlarmdEventRecurringPrivate));
00074 
00075 
00076 GType alarmd_event_recurring_get_type(void)
00077 {
00078         static GType event_recurring_type = 0;
00079 
00080         if (!event_recurring_type)
00081         {
00082                 static const GTypeInfo event_recurring_info =
00083                 {
00084                         sizeof (AlarmdEventRecurringClass),
00085                         NULL,
00086                         NULL,
00087                         (GClassInitFunc) alarmd_event_recurring_class_init,
00088                         NULL,
00089                         NULL,
00090                         sizeof (AlarmdEventRecurring),
00091                         0,
00092                         (GInstanceInitFunc) alarmd_event_recurring_init,
00093                         NULL
00094                 };
00095 
00096                 event_recurring_type = g_type_register_static(ALARMD_TYPE_EVENT,
00097                                 "AlarmdEventRecurring",
00098                                 &event_recurring_info, 0);
00099         }
00100 
00101         return event_recurring_type;
00102 }
00103 
00104 AlarmdEventRecurring *alarmd_event_recurring_new(void)
00105 {
00106         AlarmdEventRecurring *retval;
00107         ENTER_FUNC;
00108         retval = g_object_new(ALARMD_TYPE_EVENT_RECURRING, NULL);
00109         LEAVE_FUNC;
00110         return retval;
00111 }
00112 
00113 static void alarmd_event_recurring_init(AlarmdEventRecurring *event_recurring)
00114 {
00115         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(event_recurring);
00116         ENTER_FUNC;
00117 
00118         priv->recurr_interval = 0;
00119         priv->recurr_count = 0;
00120         priv->real_time = 0;
00121 
00122         LEAVE_FUNC;
00123 }
00124 
00125 static void alarmd_event_recurring_class_init(AlarmdEventRecurringClass *klass)
00126 {
00127         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
00128         AlarmdObjectClass *aobject_class = ALARMD_OBJECT_CLASS(klass);
00129         AlarmdEventClass *event_class = ALARMD_EVENT_CLASS(klass);
00130 
00131         ENTER_FUNC;
00132         g_type_class_add_private(klass, sizeof(AlarmdEventRecurringPrivate));
00133 
00134         gobject_class->set_property = _alarmd_event_recurring_set_property;
00135         gobject_class->get_property = _alarmd_event_recurring_get_property;
00136 
00137         aobject_class->get_saved_properties = _alarmd_event_recurring_get_saved_properties;
00138         aobject_class->changed = _alarmd_event_recurring_changed;
00139         aobject_class->time_changed = _alarmd_event_recurring_time_changed;
00140 
00141         event_class->acknowledge = _alarmd_event_recurring_real_acknowledge;
00142 
00143         g_object_class_install_property(gobject_class,
00144                         PROP_REAL_TIME,
00145                         g_param_spec_uint64("real_time",
00146                                 "The time without snooze time.",
00147                                 "The time without snooze.",
00148                                 0,
00149                                 G_MAXUINT64,
00150                                 0,
00151                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
00152         g_object_class_install_property(gobject_class,
00153                         PROP_RECURR_INTERVAL,
00154                         g_param_spec_uint("recurr_interval",
00155                                 "Postponing interval.",
00156                                 "Amount of time the event_recurring is postponed when acknowledged.",
00157                                 0,
00158                                 G_MAXUINT,
00159                                 0,
00160                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
00161         g_object_class_install_property(gobject_class,
00162                         PROP_RECURR_COUNT,
00163                         g_param_spec_int("recurr_count",
00164                                 "EventRecurring's id.",
00165                                 "Unique ID for the event_recurring.",
00166                                 -1,
00167                                 G_MAXINT,
00168                                 0,
00169                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
00170 
00171         LEAVE_FUNC;
00172 }
00173 
00174 static void _alarmd_event_recurring_real_acknowledge(AlarmdEvent *event)
00175 {
00176         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(event);
00177         guint64 diff = time(NULL) - priv->real_time;
00178         glong count = diff / (priv->recurr_interval * 60) + 1;
00179         ENTER_FUNC;
00180         DEBUG("old time: %llu, count: %u", priv->real_time, priv->recurr_count);
00181 
00182         if (priv->recurr_count != -1) {
00183                 if (priv->recurr_count < count) {
00184                         alarmd_event_cancel(event);
00185                         LEAVE_FUNC;
00186                         return;
00187                 }
00188                 priv->recurr_count -= count;
00189         }
00190 
00191         priv->real_time += count * priv->recurr_interval * 60;
00192         g_object_set(event, "time", priv->real_time, "snooze", 0, NULL);
00193 
00194         LEAVE_FUNC;
00195 }
00196 
00197 static void _alarmd_event_recurring_set_property(GObject *object,
00198                 guint param_id,
00199                 const GValue *value,
00200                 GParamSpec *pspec)
00201 {
00202         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(object);
00203         ENTER_FUNC;
00204 
00205         switch (param_id) {
00206         case PROP_RECURR_INTERVAL:
00207                 priv->recurr_interval = g_value_get_uint(value);
00208                 break;
00209         case PROP_RECURR_COUNT:
00210                 priv->recurr_count = g_value_get_int(value);
00211                 break;
00212         case PROP_REAL_TIME:
00213                 priv->real_time = g_value_get_uint64(value);
00214                 break;
00215         default:
00216                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
00217                 LEAVE_FUNC;
00218                 return;
00219                 break;
00220         }
00221         alarmd_object_changed(ALARMD_OBJECT(object));
00222         LEAVE_FUNC;
00223 }
00224 
00225 static void _alarmd_event_recurring_get_property(GObject *object,
00226                 guint param_id,
00227                 GValue *value,
00228                 GParamSpec *pspec)
00229 {
00230         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(object);
00231         ENTER_FUNC;
00232         switch (param_id) {
00233         case PROP_RECURR_INTERVAL:
00234                 g_value_set_uint(value, priv->recurr_interval);
00235                 break;
00236         case PROP_RECURR_COUNT:
00237                 g_value_set_int(value, priv->recurr_count);
00238                 break;
00239         case PROP_REAL_TIME:
00240                 g_value_set_uint64(value, priv->real_time);
00241                 break;
00242         default:
00243                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
00244                 LEAVE_FUNC;
00245                 return;
00246                 break;
00247         }
00248         LEAVE_FUNC;
00249 }
00250 
00251 static GSList *_alarmd_event_recurring_get_saved_properties()
00252 {
00253         guint i;
00254         GSList *retval = NULL;
00255         ENTER_FUNC;
00256         retval = ALARMD_OBJECT_CLASS(g_type_class_peek(g_type_parent(ALARMD_TYPE_EVENT_RECURRING)))->get_saved_properties();
00257         for (i = 0; i < S_COUNT; i++) {
00258                 retval = g_slist_append(retval, (gpointer)saved_properties[i]);
00259         }
00260         LEAVE_FUNC;
00261         return retval;
00262 }
00263 
00264 static void _alarmd_event_recurring_changed(AlarmdObject *object)
00265 {
00266         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(object);
00267         ENTER_FUNC;
00268         if (priv->real_time == 0) {
00269                 g_object_get(object, "time", &priv->real_time, NULL);
00270         }
00271         LEAVE_FUNC;
00272 }
00273 
00274 static void _alarmd_event_recurring_time_changed(AlarmdObject *object)
00275 {
00276         AlarmdEventRecurring *event = ALARMD_EVENT_RECURRING(object);
00277         AlarmdEventRecurringPrivate *priv = ALARMD_EVENT_RECURRING_GET_PRIVATE(event);
00278         time_t alarm_time;
00279         time_t now_time = time(NULL);
00280         GObject *action;
00281         gint flags;
00282 
00283         ENTER_FUNC;
00284         g_object_get(event, "action", &action, NULL);
00285         g_object_get(action, "flags", &flags, NULL);
00286 
00287         alarm_time = alarmd_event_get_time(ALARMD_EVENT(event));
00288 
00289         if ((flags & ALARM_EVENT_BACK_RESCHEDULE)) {
00290 
00291                 if (alarm_time > now_time + priv->recurr_interval * 60) {
00292                         glong count = (alarm_time - now_time) / (priv->recurr_interval * 60);
00293                         priv->real_time = alarm_time - count * priv->recurr_interval * 60;
00294                         DEBUG("Rescheduling to %d", priv->real_time);
00295                         g_object_set(event, "time", priv->real_time, "snooze", 0, NULL);
00296                         LEAVE_FUNC;
00297                         return;
00298                 }
00299         }
00300         /* If we're on timer, the timer plugin will take care of us. */
00301         ALARMD_OBJECT_CLASS(g_type_class_peek(g_type_parent(ALARMD_TYPE_EVENT_RECURRING)))->time_changed(object);
00302         
00303         LEAVE_FUNC;
00304 }
00305 

Generated on Thu Dec 21 18:23:30 2006 for Alarmd by  doxygen 1.4.2