00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00301 ALARMD_OBJECT_CLASS(g_type_class_peek(g_type_parent(ALARMD_TYPE_EVENT_RECURRING)))->time_changed(object);
00302
00303 LEAVE_FUNC;
00304 }
00305