[gnome-calendar] recurrence: Add recurrence struct to parse recurrence-rules
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar] recurrence: Add recurrence struct to parse recurrence-rules
- Date: Tue, 4 Jul 2017 13:45:09 +0000 (UTC)
commit 27bb337f5400e45f377d824d4b6924e99a03389b
Author: Yash Singh <yashdev10p gmail com>
Date: Mon Jul 3 00:06:11 2017 +0530
recurrence: Add recurrence struct to parse recurrence-rules
Currently, gnome-calendar has no component to deal
with recurrence-rules of events. This missing component
is however required to create and modify recurring events.
This patch adds the required GcalRecurrence component
which parses the recurrence-rules with details like:
* Frequency of the recurring event
* Duration of the recurrences:
** If they repeat until a particular date
** If they repeat a fixed number of times
** If they repeat forever
and then stores these details in a suitable format
in the GcalRecurrence structure. The gcal-recurrence
functions simplify the task of handling and editing
recurrences. This structure is the first step towards
creating a new 'recurrence' property of an event.
https://bugzilla.gnome.org/show_bug.cgi?id=782755
src/Makefile.am | 2 +
src/gcal-recurrence.c | 264 +++++++++++++++++++++++++++++++++++++++++++++++++
src/gcal-recurrence.h | 76 ++++++++++++++
3 files changed, 342 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index d63f545..967e03e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,6 +67,8 @@ gnome_calendar_SOURCES = \
gcal-multi-choice.h \
gcal-quick-add-popover.c \
gcal-quick-add-popover.h \
+ gcal-recurrence.c \
+ gcal-recurrence.h \
gcal-search-view.h \
gcal-search-view.c \
gcal-shell-search-provider.h \
diff --git a/src/gcal-recurrence.c b/src/gcal-recurrence.c
new file mode 100644
index 0000000..04603e7
--- /dev/null
+++ b/src/gcal-recurrence.c
@@ -0,0 +1,264 @@
+/* -*- mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * gcal-recurrence.c
+ * Copyright (C) 2017 Yash Singh <yashdev10p gmail com>
+ *
+ * gnome-calendar is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-calendar is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gcal-recurrence.h"
+#include "gcal-utils.h"
+#include "gcal-event.h"
+
+#include <glib.h>
+
+G_DEFINE_BOXED_TYPE (GcalRecurrence, gcal_recurrence, gcal_recurrence_copy, gcal_recurrence_free)
+
+/**
+ * gcal_recurrence_new:
+ *
+ * Creates a new #GcalRecurrence
+ *
+ * Returns: (transfer full): a #GcalRecurrence
+ */
+GcalRecurrence*
+gcal_recurrence_new (void)
+{
+ GcalRecurrence *new_recur;
+
+ new_recur = g_slice_new (GcalRecurrence);
+
+ new_recur->frequency = GCAL_RECURRENCE_NO_REPEAT;
+ new_recur->limit_type = GCAL_RECURRENCE_FOREVER;
+
+ new_recur->limit.until = NULL;
+ new_recur->limit.count = 0;
+
+ return new_recur;
+}
+
+/**
+ * gcal_recurrence_copy:
+ * @recur: a #GcalRecurrence
+ *
+ * Creates a copy of @recur
+ *
+ * Returns: (transfer full): a #GcalRecurrence
+ */
+GcalRecurrence*
+gcal_recurrence_copy (GcalRecurrence *recur)
+{
+ GcalRecurrence *new_recur;
+
+ g_return_val_if_fail (recur != NULL, NULL);
+
+ new_recur = gcal_recurrence_new ();
+
+ new_recur->frequency = recur->frequency;
+ new_recur->limit_type = recur->limit_type;
+
+ if (recur->limit_type == GCAL_RECURRENCE_UNTIL && recur->limit.until)
+ new_recur->limit.until = g_date_time_ref (recur->limit.until);
+
+ new_recur->limit.count = recur->limit.count;
+
+ return new_recur;
+}
+
+/**
+ * gcal_recurrence_free:
+ * @recur: a #GcalRecurrence.
+ *
+ * Frees @recur
+ */
+void
+gcal_recurrence_free (GcalRecurrence *recur)
+{
+ gcal_clear_datetime (&recur->limit.until);
+ g_slice_free (GcalRecurrence, recur);
+}
+
+/**
+ * gcal_recurrence_parse_recurrence_rules:
+ * @comp: an #ECalComponent
+ *
+ * Parses the rrule of the @comp and
+ * sets the GcalRecurrence struct accordingly.
+ *
+ * Returns: (transfer full): a #GcalRecurrence
+ */
+GcalRecurrence*
+gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
+{
+ GcalRecurrence *recur;
+ icalproperty *prop;
+ icalcomponent *icalcomp;
+ struct icalrecurrencetype rrule;
+
+ if (!e_cal_component_has_recurrences (comp))
+ return NULL;
+
+ recur = gcal_recurrence_new ();
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ g_return_val_if_fail (prop != NULL, NULL);
+
+ rrule = icalproperty_get_rrule (prop);
+
+ switch (rrule.freq)
+ {
+ case ICAL_DAILY_RECURRENCE:
+ recur->frequency = GCAL_RECURRENCE_DAILY;
+ break;
+
+ case ICAL_WEEKLY_RECURRENCE:
+ {
+ if (rrule.by_day[0] == ICAL_MONDAY_WEEKDAY &&
+ rrule.by_day[1] == ICAL_TUESDAY_WEEKDAY &&
+ rrule.by_day[2] == ICAL_WEDNESDAY_WEEKDAY &&
+ rrule.by_day[3] == ICAL_THURSDAY_WEEKDAY &&
+ rrule.by_day[4] == ICAL_FRIDAY_WEEKDAY &&
+ rrule.by_day[5] != ICAL_SATURDAY_WEEKDAY &&
+ rrule.by_day[6] != ICAL_SUNDAY_WEEKDAY)
+ {
+ recur->frequency = GCAL_RECURRENCE_MON_FRI;
+ }
+ else
+ {
+ recur->frequency = GCAL_RECURRENCE_WEEKLY;
+ }
+ break;
+ }
+
+ case ICAL_MONTHLY_RECURRENCE:
+ recur->frequency = GCAL_RECURRENCE_MONTHLY;
+ break;
+
+ case ICAL_YEARLY_RECURRENCE:
+ recur->frequency = GCAL_RECURRENCE_YEARLY;
+ break;
+
+ default:
+ recur->frequency = GCAL_RECURRENCE_OTHER;
+ }
+
+ if (rrule.count > 0)
+ {
+ recur->limit_type = GCAL_RECURRENCE_COUNT;
+ recur->limit.count = rrule.count;
+ }
+ else if (rrule.until.year != 0)
+ {
+ recur->limit_type = GCAL_RECURRENCE_UNTIL;
+ recur->limit.until = icaltime_to_datetime (&rrule.until);
+ }
+ else
+ {
+ recur->limit_type = GCAL_RECURRENCE_FOREVER;
+ }
+
+ return recur;
+}
+
+/**
+ * gcal_recurrence_to_rrule:
+ * @recur: a #GcalRecurrence
+ *
+ * Converts @recur into corresponding rrule.
+ *
+ * Returns: (transfer full): a #struct icalrecurrencetype
+ */
+struct icalrecurrencetype*
+gcal_recurrence_to_rrule (GcalRecurrence *recur)
+{
+ struct icalrecurrencetype *rrule;
+
+ if (!recur)
+ return NULL;
+
+ /* Initialize and clear the rrule to get rid of unwanted fields */
+ rrule = g_new0 (struct icalrecurrencetype, 1);
+ icalrecurrencetype_clear (rrule);
+
+ rrule->until.second = 0;
+ rrule->until.minute = 0;
+ rrule->until.hour = 0;
+ rrule->until.is_date = TRUE;
+ rrule->until.is_utc = FALSE;
+
+ switch (recur->frequency)
+ {
+ case GCAL_RECURRENCE_DAILY:
+ rrule->freq = ICAL_DAILY_RECURRENCE;
+ break;
+
+ case GCAL_RECURRENCE_WEEKLY:
+ rrule->freq = ICAL_WEEKLY_RECURRENCE;
+ break;
+
+ case GCAL_RECURRENCE_MONTHLY:
+ rrule->freq = ICAL_MONTHLY_RECURRENCE;
+ break;
+
+ case GCAL_RECURRENCE_YEARLY:
+ rrule->freq = ICAL_YEARLY_RECURRENCE;
+ break;
+
+ case GCAL_RECURRENCE_NO_REPEAT:
+ rrule->freq = ICAL_NO_RECURRENCE;
+ break;
+
+ case GCAL_RECURRENCE_MON_FRI:
+ {
+ rrule->freq = ICAL_WEEKLY_RECURRENCE;
+ rrule->by_day[0] = ICAL_MONDAY_WEEKDAY;
+ rrule->by_day[1] = ICAL_TUESDAY_WEEKDAY;
+ rrule->by_day[2] = ICAL_WEDNESDAY_WEEKDAY;
+ rrule->by_day[3] = ICAL_THURSDAY_WEEKDAY;
+ rrule->by_day[4] = ICAL_FRIDAY_WEEKDAY;
+ break;
+ }
+
+ default:
+ rrule->freq = ICAL_NO_RECURRENCE;
+ break;
+ }
+
+ switch (recur->limit_type)
+ {
+ case GCAL_RECURRENCE_COUNT:
+ rrule->count = recur->limit.count;
+ break;
+
+ case GCAL_RECURRENCE_UNTIL:
+ {
+ rrule->until.second = g_date_time_get_second (recur->limit.until);
+ rrule->until.minute = g_date_time_get_minute (recur->limit.until);
+ rrule->until.hour = g_date_time_get_hour (recur->limit.until);
+ rrule->until.day = g_date_time_get_day_of_month (recur->limit.until);
+ rrule->until.month = g_date_time_get_year (recur->limit.until);
+ rrule->until.year = g_date_time_get_month (recur->limit.until);
+ break;
+ }
+
+ case GCAL_RECURRENCE_FOREVER:
+ break;
+
+ default:
+ break;
+ }
+
+ return rrule;
+}
diff --git a/src/gcal-recurrence.h b/src/gcal-recurrence.h
new file mode 100644
index 0000000..737b27b
--- /dev/null
+++ b/src/gcal-recurrence.h
@@ -0,0 +1,76 @@
+/* -*- mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * gcal-recurrence.h
+ * Copyright (C) 2017 Yash Singh <yashdev10p gmail com>
+ *
+ * gnome-calendar is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-calendar is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCAL_RECURRENCE_H
+#define GCAL_RECURRENCE_H
+
+#include <glib-object.h>
+#include <libecal/libecal.h>
+
+G_BEGIN_DECLS
+
+#define GCAL_TYPE_RECURRENCE (gcal_recurrence_get_type())
+
+typedef struct _GcalRecurrence GcalRecurrence;
+
+typedef enum
+{
+ GCAL_RECURRENCE_NO_REPEAT,
+ GCAL_RECURRENCE_DAILY,
+ GCAL_RECURRENCE_MON_FRI,
+ GCAL_RECURRENCE_WEEKLY,
+ GCAL_RECURRENCE_MONTHLY,
+ GCAL_RECURRENCE_YEARLY,
+ GCAL_RECURRENCE_OTHER
+} GcalRecurrenceFrequency;
+
+typedef enum
+{
+ GCAL_RECURRENCE_FOREVER,
+ GCAL_RECURRENCE_COUNT,
+ GCAL_RECURRENCE_UNTIL
+} GcalRecurrenceLimitType;
+
+struct _GcalRecurrence
+{
+ GcalRecurrenceFrequency frequency;
+ GcalRecurrenceLimitType limit_type;
+
+ struct {
+ GDateTime *until;
+ guint count;
+ } limit;
+
+};
+
+GType gcal_recurrence_get_type (void) G_GNUC_CONST;
+
+GcalRecurrence* gcal_recurrence_new (void);
+
+GcalRecurrence* gcal_recurrence_copy (GcalRecurrence *recur);
+
+void gcal_recurrence_free (GcalRecurrence *recur);
+
+GcalRecurrence* gcal_recurrence_parse_recurrence_rules (ECalComponent *comp);
+
+struct icalrecurrencetype* gcal_recurrence_to_rrule (GcalRecurrence *recur);
+
+G_END_DECLS
+
+#endif /* GCAL_RECURRENCE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]