[evolution-data-server/wip/mcrha/libical-glib] Add ECalComponentPropertyBag to store ICalProperty objects
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/wip/mcrha/libical-glib] Add ECalComponentPropertyBag to store ICalProperty objects
- Date: Thu, 28 Feb 2019 17:53:21 +0000 (UTC)
commit 2c86edb925e8aa7c37247b1bc9962ff90462c3e0
Author: Milan Crha <mcrha redhat com>
Date: Thu Feb 28 18:53:41 2019 +0100
Add ECalComponentPropertyBag to store ICalProperty objects
.../evolution-data-server-docs.sgml.in | 1 +
src/calendar/libecal/CMakeLists.txt | 2 +
src/calendar/libecal/e-cal-component-alarm.c | 30 ++
src/calendar/libecal/e-cal-component-alarm.h | 4 +
.../libecal/e-cal-component-property-bag.c | 354 +++++++++++++++++++++
.../libecal/e-cal-component-property-bag.h | 97 ++++++
src/calendar/libecal/libecal.h | 1 +
tests/libecal/test-cal-component.c | 270 +++++++++++++++-
8 files changed, 750 insertions(+), 9 deletions(-)
---
diff --git a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
index 68d276800..c0ef85e2a 100644
--- a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
+++ b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
@@ -158,6 +158,7 @@
<xi:include href="xml/e-cal-component-id.xml"/>
<xi:include href="xml/e-cal-component-organizer.xml"/>
<xi:include href="xml/e-cal-component-period.xml"/>
+ <xi:include href="xml/e-cal-component-property-bag.xml"/>
<xi:include href="xml/e-cal-component-range.xml"/>
<xi:include href="xml/e-cal-component-text.xml"/>
</chapter>
diff --git a/src/calendar/libecal/CMakeLists.txt b/src/calendar/libecal/CMakeLists.txt
index 83ad92bb5..e2b318931 100644
--- a/src/calendar/libecal/CMakeLists.txt
+++ b/src/calendar/libecal/CMakeLists.txt
@@ -21,6 +21,7 @@ set(SOURCES
e-cal-component-id.c
e-cal-component-organizer.c
e-cal-component-period.c
+ e-cal-component-property-bag.c
e-cal-component-range.c
e-cal-component-text.c
e-cal-recur.c
@@ -48,6 +49,7 @@ set(HEADERS
e-cal-component-id.h
e-cal-component-organizer.h
e-cal-component-period.h
+ e-cal-component-property-bag.h
e-cal-component-range.h
e-cal-component-text.h
e-cal-enums.h
diff --git a/src/calendar/libecal/e-cal-component-alarm.c b/src/calendar/libecal/e-cal-component-alarm.c
index 0e7ca3609..cb9de1b98 100644
--- a/src/calendar/libecal/e-cal-component-alarm.c
+++ b/src/calendar/libecal/e-cal-component-alarm.c
@@ -46,6 +46,7 @@ struct _ECalComponentAlarm {
ECalComponentAlarmTrigger *trigger;
GSList *attendees; /* ECalComponentAttendee * */
GSList *attachments; /* ICalAttach * */
+ ECalComponentPropertyBag *property_bag;
};
/**
@@ -66,6 +67,7 @@ e_cal_component_alarm_new (void)
alarm = g_new0 (ECalComponentAlarm, 1);
alarm->uid = e_util_generate_uid ();
alarm->action = E_CAL_COMPONENT_ALARM_UNKNOWN;
+ alarm->property_bag = e_cal_component_property_bag_new ();
return alarm;
}
@@ -178,6 +180,8 @@ e_cal_component_alarm_copy (const ECalComponentAlarm *alarm)
alrm->attachments = g_slist_reverse (alrm->attachments);
}
+ e_cal_component_property_bag_assign (alrm->property_bag, alarm->property_bag);
+
return alrm;
}
@@ -202,6 +206,7 @@ e_cal_component_alarm_free (gpointer alarm)
e_cal_component_text_free (alrm->description);
e_cal_component_alarm_repeat_free (alrm->repeat);
e_cal_component_alarm_trigger_free (alrm->trigger);
+ e_cal_component_property_bag_free (alrm->property_bag);
g_slist_free_full (alrm->attendees, e_cal_component_attendee_free);
g_slist_free_full (alrm->attachments, g_object_unref);
g_free (alrm);
@@ -245,6 +250,8 @@ e_cal_component_alarm_set_from_component (ECalComponentAlarm *alarm,
alarm->attendees = NULL;
alarm->attachments = NULL;
+ e_cal_component_property_bag_clear (alarm->property_bag);
+
for (prop = i_cal_component_get_first_property (comp, I_CAL_ANY_PROPERTY);
prop;
g_object_unref (prop), prop = i_cal_component_get_next_property (comp, I_CAL_ANY_PROPERTY)) {
@@ -323,10 +330,13 @@ e_cal_component_alarm_set_from_component (ECalComponentAlarm *alarm,
if (g_strcmp0 (xname, E_CAL_EVOLUTION_ALARM_UID_PROPERTY) == 0) {
g_free (alarm->uid);
alarm->uid = g_strdup (i_cal_property_get_x (prop));
+ } else {
+ e_cal_component_property_bag_add (alarm->property_bag, prop);
}
break;
default:
+ e_cal_component_property_bag_add (alarm->property_bag, prop);
break;
}
}
@@ -535,6 +545,8 @@ e_cal_component_alarm_fill_component (ECalComponentAlarm *alarm,
if (prop)
i_cal_component_take_property (component, prop);
}
+
+ e_cal_component_property_bag_fill_component (alarm->property_bag, component);
}
/**
@@ -987,3 +999,21 @@ e_cal_component_alarm_take_attachments (ECalComponentAlarm *alarm,
alarm->attachments = attachments;
}
}
+
+/**
+ * e_cal_component_alarm_get_property_bag:
+ * @alarm: an #ECalComponentAlarm
+ *
+ * Returns: (transfer none): an #ECalComponentPropertyBag with additional
+ * properties stored with an alarm component, other than those accessible
+ * with the other functions of the @alarm.
+ *
+ * Since: 3.36
+ **/
+ECalComponentPropertyBag *
+e_cal_component_alarm_get_property_bag (const ECalComponentAlarm *alarm)
+{
+ g_return_val_if_fail (alarm != NULL, NULL);
+
+ return alarm->property_bag;
+}
diff --git a/src/calendar/libecal/e-cal-component-alarm.h b/src/calendar/libecal/e-cal-component-alarm.h
index 21299d839..f65c1f7b9 100644
--- a/src/calendar/libecal/e-cal-component-alarm.h
+++ b/src/calendar/libecal/e-cal-component-alarm.h
@@ -29,6 +29,7 @@
#include <libecal/e-cal-component-alarm-repeat.h>
#include <libecal/e-cal-component-alarm-trigger.h>
#include <libecal/e-cal-component-attendee.h>
+#include <libecal/e-cal-component-property-bag.h>
#include <libecal/e-cal-component-text.h>
#include <libecal/e-cal-enums.h>
@@ -120,6 +121,9 @@ void e_cal_component_alarm_set_attachments
void e_cal_component_alarm_take_attachments
(ECalComponentAlarm *alarm,
GSList *attachments); /* ICalAttach * */
+ECalComponentPropertyBag *
+ e_cal_component_alarm_get_property_bag
+ (const ECalComponentAlarm *alarm);
G_END_DECLS
diff --git a/src/calendar/libecal/e-cal-component-property-bag.c
b/src/calendar/libecal/e-cal-component-property-bag.c
new file mode 100644
index 000000000..8a7107e69
--- /dev/null
+++ b/src/calendar/libecal/e-cal-component-property-bag.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "evolution-data-server-config.h"
+
+/**
+ * SECTION:e-cal-component-property-bag
+ * @short_description: An ECalComponentPropertyBag structure
+ * @include: libecal/libecal.h
+ *
+ * Contains functions to work with the #ECalComponentPropertyBag structure.
+ **/
+
+#include "e-cal-component-property-bag.h"
+
+G_DEFINE_BOXED_TYPE (ECalComponentPropertyBag, e_cal_component_property_bag,
e_cal_component_property_bag_copy, e_cal_component_property_bag_free)
+
+struct _ECalComponentPropertyBag {
+ GPtrArray *properties; /* ICalProperty * */
+};
+
+/**
+ * e_cal_component_property_bag_new:
+ *
+ * Creates a new #ECalComponentPropertyBag. Free the structure
+ * with e_cal_component_property_bag_free(), when no longer needed.
+ *
+ * Returns: (transfer full): a newly allocated #ECalComponentPropertyBag
+ *
+ * Since: 3.36
+ **/
+ECalComponentPropertyBag *
+e_cal_component_property_bag_new (void)
+{
+ ECalComponentPropertyBag *bag;
+
+ bag = g_new0 (ECalComponentPropertyBag, 1);
+ bag->properties = g_ptr_array_new_with_free_func (g_object_unref);
+
+ return bag;
+}
+
+/**
+ * e_cal_component_property_bag_new_from_component:
+ * @component: an #ICalComponent containing the properties to fill the bag with
+ * @func: (nullable) (scope call): an optional %ECalComponentPropertyBagFilterFunc callback
+ * @user_data: (closure func): user data for the @func
+ *
+ * Created a new #ECalComponentPropertyBag, filled with properties
+ * from the @component, for which the @func returned %TRUE. When
+ * the @func is %NULL, all the properties are included.
+ *
+ * Free the structure with e_cal_component_property_bag_free(), when no longer needed.
+ *
+ * Returns: (transfer full): a newly allocated #ECalComponentPropertyBag
+ *
+ * Since: 3.36
+ **/
+ECalComponentPropertyBag *
+e_cal_component_property_bag_new_from_component (const ICalComponent *component,
+ ECalComponentPropertyBagFilterFunc func,
+ gpointer user_data)
+{
+ ECalComponentPropertyBag *bag;
+
+ bag = e_cal_component_property_bag_new ();
+
+ e_cal_component_property_bag_set_from_component (bag, component, func, user_data);
+
+ return bag;
+}
+
+/**
+ * e_cal_component_property_bag_copy:
+ * @bag: (not nullable): an #ECalComponentPropertyBag
+ *
+ * Returns a newly allocated copy of @bag, which should be freed with
+ * e_cal_component_property_bag_free(), when no longer needed.
+ *
+ * Returns: (transfer full): a newly allocated copy of @bag
+ *
+ * Since: 3.36
+ **/
+ECalComponentPropertyBag *
+e_cal_component_property_bag_copy (const ECalComponentPropertyBag *bag)
+{
+ ECalComponentPropertyBag *copy;
+
+ g_return_val_if_fail (bag != NULL, NULL);
+
+ copy = e_cal_component_property_bag_new ();
+
+ e_cal_component_property_bag_assign (copy, bag);
+
+ return copy;
+}
+
+/**
+ * e_cal_component_property_bag_free: (skip)
+ * @bag: (type ECalComponentPropertyBag) (nullable): an #ECalComponentPropertyBag to free
+ *
+ * Free @bag, previously created by e_cal_component_property_bag_new(),
+ * e_cal_component_property_bag_new_from_component() or
+ * e_cal_component_property_bag_copy(). The function does nothing, if @bag
+ * is %NULL.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_free (gpointer bag)
+{
+ ECalComponentPropertyBag *bg = bag;
+
+ if (bg) {
+ g_ptr_array_unref (bg->properties);
+ g_free (bg);
+ }
+}
+
+/**
+ * e_cal_component_property_bag_set_from_component:
+ * @bag: an #ECalComponentPropertyBag
+ * @component: an #ICalComponent containing the properties to fill the @bag with
+ * @func: (nullable) (scope call): an optional %ECalComponentPropertyBagFilterFunc callback
+ * @user_data: (closure func): user data for the @func
+ *
+ * Fills the @bag with properties from the @component, for which the @func
+ * returned %TRUE. When the @func is %NULL, all the properties are included.
+ * The @bag content is cleared before any property is added.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_set_from_component (ECalComponentPropertyBag *bag,
+ const ICalComponent *component,
+ ECalComponentPropertyBagFilterFunc func,
+ gpointer user_data)
+{
+ ICalComponent *comp = (ICalComponent *) component;
+ ICalProperty *prop;
+
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (I_CAL_IS_COMPONENT (component));
+
+ e_cal_component_property_bag_clear (bag);
+
+ for (prop = i_cal_component_get_first_property (comp, I_CAL_ANY_PROPERTY);
+ prop;
+ g_object_unref (prop), prop = i_cal_component_get_next_property (comp, I_CAL_ANY_PROPERTY)) {
+ if (!func || func (prop, user_data)) {
+ e_cal_component_property_bag_add (bag, prop);
+ }
+ }
+}
+
+/**
+ * e_cal_component_property_bag_fill_component:
+ * @bag: an #ECalComponentPropertyBag
+ * @component: an #ICalComponent
+ *
+ * Adds all the stores properties in the @bag to the @component.
+ * The function doesn't verify whether the @component contains
+ * the same property already.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_fill_component (const ECalComponentPropertyBag *bag,
+ ICalComponent *component)
+{
+ guint ii;
+
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (I_CAL_IS_COMPONENT (component));
+
+ for (ii = 0; ii < bag->properties->len; ii++) {
+ ICalProperty *prop = g_ptr_array_index (bag->properties, ii);
+
+ if (prop)
+ i_cal_component_take_property (component, i_cal_property_new_clone (prop));
+ }
+}
+
+/**
+ * e_cal_component_property_bag_assign:
+ * @bag: a destination #ECalComponentPropertyBag
+ * @src_bag: a source #ECalComponentPropertyBag
+ *
+ * Assigns content of the @src_bag into the @bag.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_assign (ECalComponentPropertyBag *bag,
+ const ECalComponentPropertyBag *src_bag)
+{
+ guint count, ii;
+
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (src_bag != NULL);
+
+ e_cal_component_property_bag_clear (bag);
+ count = e_cal_component_property_bag_get_count (src_bag);
+
+ if (count) {
+ for (ii = 0; ii < count; ii++) {
+ ICalProperty *prop;
+
+ prop = e_cal_component_property_bag_get (src_bag, ii);
+
+ e_cal_component_property_bag_add (bag, prop);
+ }
+ }
+}
+
+/**
+ * e_cal_component_property_bag_add:
+ * @bag: an #ECalComponentPropertyBag
+ * @prop: an #ICalProperty
+ *
+ * Adds a copy of the @prop into the @bag.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_add (ECalComponentPropertyBag *bag,
+ const ICalProperty *prop)
+{
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (I_CAL_IS_PROPERTY (prop));
+
+ e_cal_component_property_bag_take (bag,
+ i_cal_property_new_clone ((ICalProperty *) prop));
+}
+
+/**
+ * e_cal_component_property_bag_take:
+ * @bag: an #ECalComponentPropertyBag
+ * @prop: an #ICalProperty
+ *
+ * Adds the @prop into the @bag and assumes ownership of the @prop.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_take (ECalComponentPropertyBag *bag,
+ ICalProperty *prop)
+{
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (I_CAL_IS_PROPERTY (prop));
+
+ g_ptr_array_add (bag->properties, prop);
+}
+
+/**
+ * e_cal_component_property_bag_get_count:
+ * @bag: an #ECalComponentPropertyBag
+ *
+ * Returns: how many properties are stored in the @bag
+ *
+ * Since: 3.36
+ **/
+guint
+e_cal_component_property_bag_get_count (const ECalComponentPropertyBag *bag)
+{
+ g_return_val_if_fail (bag != NULL, 0);
+ g_return_val_if_fail (bag->properties != NULL, 0);
+
+ return bag->properties->len;
+}
+
+/**
+ * e_cal_component_property_bag_get:
+ * @bag: an #ECalComponentPropertyBag
+ * @index: an index of the property to get
+ *
+ * Returns the #ICalProperty at the given @index. If the @index is
+ * out of bounds (not lower than e_cal_component_property_bag_get_count()),
+ * then %NULL is returned.
+ *
+ * The returned property is owned by the @bag and should not be freed
+ * by the caller.
+ *
+ * Returns: (transfer none) (nullable): the #ICalProperty at the given @index,
+ * or %NULL on error
+ *
+ * Since: 3.36
+ **/
+ICalProperty *
+e_cal_component_property_bag_get (const ECalComponentPropertyBag *bag,
+ guint index)
+{
+ g_return_val_if_fail (bag != NULL, NULL);
+ g_return_val_if_fail (bag->properties != NULL, NULL);
+
+ if (index >= bag->properties->len)
+ return NULL;
+
+ return g_ptr_array_index (bag->properties, index);
+}
+
+/**
+ * e_cal_component_property_bag_remove:
+ * @bag: an #ECalComponentPropertyBag
+ * @index: an index of the property to remove
+ *
+ * Removes the #ICalProperty at the given @index. If the @index is
+ * out of bounds (not lower than e_cal_component_property_bag_get_count()),
+ * then the function does nothing.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_remove (ECalComponentPropertyBag *bag,
+ guint index)
+{
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (bag->properties != NULL);
+
+ if (index < bag->properties->len)
+ g_ptr_array_remove_index (bag->properties, index);
+}
+
+/**
+ * e_cal_component_property_bag_clear:
+ * @bag: an #ECalComponentPropertyBag
+ *
+ * Removes all properties from the @bag, thus it doesn't contain any
+ * property after this function returns.
+ *
+ * Since: 3.36
+ **/
+void
+e_cal_component_property_bag_clear (ECalComponentPropertyBag *bag)
+{
+ g_return_if_fail (bag != NULL);
+ g_return_if_fail (bag->properties != NULL);
+
+ g_ptr_array_set_size (bag->properties, 0);
+}
diff --git a/src/calendar/libecal/e-cal-component-property-bag.h
b/src/calendar/libecal/e-cal-component-property-bag.h
new file mode 100644
index 000000000..c029e2dcd
--- /dev/null
+++ b/src/calendar/libecal/e-cal-component-property-bag.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if !defined (__LIBECAL_H_INSIDE__) && !defined (LIBECAL_COMPILATION)
+#error "Only <libecal/libecal.h> should be included directly."
+#endif
+
+#ifndef E_CAL_COMPONENT_PROPERTY_BAG_H
+#define E_CAL_COMPONENT_PROPERTY_BAG_H
+
+#include <glib-object.h>
+#include <libical-glib/libical-glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ECalComponentPropertyBag:
+ *
+ * Opaque structure, which represents a bad (list) of #ICalProperty objects.
+ * Use the functions below to work with it.
+ **/
+typedef struct _ECalComponentPropertyBag ECalComponentPropertyBag;
+
+/**
+ * ECalComponentPropertyBagFilterFunc:
+ * @property: an #ICalProperty
+ * @user_data: user data for the callback
+ *
+ * A function used to filter which properties should be added to the bag,
+ * when filling it with e_cal_component_property_bag_new_from_component()
+ * and e_cal_component_property_bag_set_from_component().
+ *
+ * Returns: %TRUE, to add the property to the bag; %FALSE, to not add it to the bag
+ *
+ * Since: 3.36
+ **/
+typedef gboolean (* ECalComponentPropertyBagFilterFunc)
+ (ICalProperty *property,
+ gpointer user_data);
+
+GType e_cal_component_property_bag_get_type
+ (void);
+ECalComponentPropertyBag *
+ e_cal_component_property_bag_new(void);
+ECalComponentPropertyBag *
+ e_cal_component_property_bag_new_from_component
+ (const ICalComponent *component,
+ ECalComponentPropertyBagFilterFunc func,
+ gpointer user_data);
+ECalComponentPropertyBag *
+ e_cal_component_property_bag_copy
+ (const ECalComponentPropertyBag *bag);
+void e_cal_component_property_bag_free
+ (gpointer bag); /* ECalComponentPropertyBag * */
+void e_cal_component_property_bag_set_from_component
+ (ECalComponentPropertyBag *bag,
+ const ICalComponent *component,
+ ECalComponentPropertyBagFilterFunc func,
+ gpointer user_data);
+void e_cal_component_property_bag_fill_component
+ (const ECalComponentPropertyBag *bag,
+ ICalComponent *component);
+void e_cal_component_property_bag_assign
+ (ECalComponentPropertyBag *bag,
+ const ECalComponentPropertyBag *src_bag);
+void e_cal_component_property_bag_add(ECalComponentPropertyBag *bag,
+ const ICalProperty *prop);
+void e_cal_component_property_bag_take
+ (ECalComponentPropertyBag *bag,
+ ICalProperty *prop);
+guint e_cal_component_property_bag_get_count
+ (const ECalComponentPropertyBag *bag);
+ICalProperty * e_cal_component_property_bag_get(const ECalComponentPropertyBag *bag,
+ guint index);
+void e_cal_component_property_bag_remove
+ (ECalComponentPropertyBag *bag,
+ guint index);
+void e_cal_component_property_bag_clear
+ (ECalComponentPropertyBag *bag);
+
+G_END_DECLS
+
+#endif /* E_CAL_COMPONENT_PROPERTY_BAG_H */
diff --git a/src/calendar/libecal/libecal.h b/src/calendar/libecal/libecal.h
index f3abf2bb8..7af321a04 100644
--- a/src/calendar/libecal/libecal.h
+++ b/src/calendar/libecal/libecal.h
@@ -39,6 +39,7 @@
#include <libecal/e-cal-component-id.h>
#include <libecal/e-cal-component-organizer.h>
#include <libecal/e-cal-component-period.h>
+#include <libecal/e-cal-component-property-bag.h>
#include <libecal/e-cal-component-range.h>
#include <libecal/e-cal-component-text.h>
#include <libecal/e-cal-enums.h>
diff --git a/tests/libecal/test-cal-component.c b/tests/libecal/test-cal-component.c
index 143d78db1..9ea8d5c51 100644
--- a/tests/libecal/test-cal-component.c
+++ b/tests/libecal/test-cal-component.c
@@ -321,6 +321,43 @@ verify_struct_alarm_trigger_equal (const ECalComponentAlarmTrigger *expected,
}
}
+static void
+verify_property_bag_equal (const ECalComponentPropertyBag *expected,
+ const ECalComponentPropertyBag *received)
+{
+ gint ii, count;
+
+ if (!expected) {
+ g_assert_null (received);
+ return;
+ }
+
+ g_assert_nonnull (received);
+
+ g_assert_cmpint (e_cal_component_property_bag_get_count (expected), ==,
e_cal_component_property_bag_get_count (received));
+
+ count = e_cal_component_property_bag_get_count (expected);
+ for (ii = 0; ii < count; ii++) {
+ ICalProperty *prop_expected, *prop_received;
+ gchar *value_expected, *value_received;
+
+ prop_expected = e_cal_component_property_bag_get (expected, ii);
+ prop_received = e_cal_component_property_bag_get (received, ii);
+
+ g_assert_nonnull (prop_expected);
+ g_assert_nonnull (prop_received);
+ g_assert_cmpint (i_cal_property_isa (prop_expected), ==, i_cal_property_isa (prop_received));
+
+ value_expected = i_cal_property_as_ical_string_r (prop_expected);
+ value_received = i_cal_property_as_ical_string_r (prop_received);
+
+ g_assert_cmpstr (value_expected, ==, value_received);
+
+ g_free (value_expected);
+ g_free (value_received);
+ }
+}
+
static void
verify_struct_alarm_equal (const ECalComponentAlarm *expected,
const ECalComponentAlarm *received)
@@ -353,6 +390,9 @@ verify_struct_alarm_equal (const ECalComponentAlarm *expected,
verify_ical_attach_list_equal (e_cal_component_alarm_get_attachments (expected),
e_cal_component_alarm_get_attachments (received));
+
+ verify_property_bag_equal (e_cal_component_alarm_get_property_bag (expected),
+ e_cal_component_alarm_get_property_bag (received));
}
static void
@@ -420,17 +460,18 @@ test_component_struct_alarm (void)
gboolean with_trigger;
gboolean with_attendees;
gboolean with_attachments;
+ gboolean with_properties;
} values[] = {
- { "1", E_CAL_COMPONENT_ALARM_AUDIO, NULL, FALSE, FALSE, FALSE, FALSE },
- { "2", E_CAL_COMPONENT_ALARM_DISPLAY, "display text", FALSE, FALSE, FALSE, FALSE },
- { "3", E_CAL_COMPONENT_ALARM_EMAIL, NULL, TRUE, FALSE, FALSE, FALSE },
- { "4", E_CAL_COMPONENT_ALARM_PROCEDURE, "procedure", FALSE, TRUE, FALSE, FALSE },
- { "5", E_CAL_COMPONENT_ALARM_AUDIO, NULL, FALSE, FALSE, TRUE, FALSE },
- { "6", E_CAL_COMPONENT_ALARM_DISPLAY, "display text", FALSE, FALSE, FALSE, TRUE },
- { "7", E_CAL_COMPONENT_ALARM_EMAIL, NULL, TRUE, FALSE, TRUE, FALSE },
- { "8", E_CAL_COMPONENT_ALARM_PROCEDURE, "procedure", TRUE, TRUE, TRUE, TRUE }
+ { "1", E_CAL_COMPONENT_ALARM_AUDIO, NULL, FALSE, FALSE, FALSE, FALSE, FALSE },
+ { "2", E_CAL_COMPONENT_ALARM_DISPLAY, "display text", FALSE, FALSE, FALSE, FALSE, FALSE },
+ { "3", E_CAL_COMPONENT_ALARM_EMAIL, NULL, TRUE, FALSE, FALSE, FALSE, FALSE },
+ { "4", E_CAL_COMPONENT_ALARM_PROCEDURE, "procedure", FALSE, TRUE, FALSE, FALSE, TRUE },
+ { "5", E_CAL_COMPONENT_ALARM_AUDIO, NULL, FALSE, FALSE, TRUE, FALSE, TRUE },
+ { "6", E_CAL_COMPONENT_ALARM_DISPLAY, "display text", FALSE, FALSE, FALSE, TRUE, TRUE },
+ { "7", E_CAL_COMPONENT_ALARM_EMAIL, NULL, TRUE, FALSE, TRUE, FALSE, TRUE },
+ { "8", E_CAL_COMPONENT_ALARM_PROCEDURE, "procedure", TRUE, TRUE, TRUE, TRUE, TRUE }
};
- gint ii, nth_description = 0, nth_repeat = 0, nth_trigger = 0, nth_attendees = 0, nth_attachments = 0;
+ gint ii, nth_description = 0, nth_repeat = 0, nth_trigger = 0, nth_attendees = 0, nth_attachments =
0, nth_properties = 0;
for (ii = 0; ii < G_N_ELEMENTS (values); ii++) {
ECalComponentAlarm *expected, *received;
@@ -554,6 +595,40 @@ test_component_struct_alarm (void)
}
}
+ if (values[ii].with_properties) {
+ ECalComponentPropertyBag *bag;
+ gint ii;
+
+ nth_properties++;
+
+ bag = e_cal_component_alarm_get_property_bag (expected);
+
+ g_assert_nonnull (bag);
+
+ for (ii = nth_properties; ii > 0; ii--) {
+ ICalProperty *prop;
+
+ if (ii == 0) {
+ prop = i_cal_property_new_url ("https://www.gnome.org");
+ } else if (ii == 1) {
+ prop = i_cal_property_new_voter ("MAILTO:user@no.where");
+ } else {
+ gchar *x_name;
+
+ x_name = g_strdup_printf ("X-CUSTOM-PROP-%d", ii);
+ prop = i_cal_property_new_x (x_name + 2);
+ i_cal_property_set_x_name (prop, x_name);
+ g_free (x_name);
+ }
+
+ g_assert_nonnull (prop);
+
+ e_cal_component_property_bag_take (bag, prop);
+ }
+
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, nth_properties);
+ }
+
received = e_cal_component_alarm_copy (expected);
verify_struct_alarm_equal (expected, received);
e_cal_component_alarm_free (received);
@@ -582,6 +657,7 @@ test_component_struct_alarm (void)
g_assert_cmpint (nth_trigger, >, 1);
g_assert_cmpint (nth_attendees, >, 1);
g_assert_cmpint (nth_attachments, >, 1);
+ g_assert_cmpint (nth_properties, >, 1);
}
static void
@@ -1382,6 +1458,181 @@ test_component_struct_period (void)
g_assert_cmpint (flipflop2, >, 2);
}
+#define X_PROP_NAME "X-PROP"
+#define X_PROP_VALUE "xVaLuE"
+
+static gboolean
+test_property_bag_filter_cb (ICalProperty *prop,
+ gpointer user_data)
+{
+ ICalPropertyKind *expected = user_data, kind;
+ gint ii;
+
+ g_return_val_if_fail (expected != NULL, FALSE);
+
+ kind = i_cal_property_isa (prop);
+
+ for (ii = 0; expected[ii] != I_CAL_ANY_PROPERTY; ii++) {
+ if (kind == expected[ii])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+test_check_property_bag (const ECalComponentPropertyBag *bag,
+ const ICalPropertyKind *expected)
+{
+ ICalProperty *prop;
+ gint ii;
+
+ g_assert_nonnull (bag);
+ g_assert_nonnull (expected);
+
+ for (ii = 0; expected[ii] != I_CAL_ANY_PROPERTY; ii++) {
+ prop = e_cal_component_property_bag_get (bag, ii);
+
+ g_assert_nonnull (prop);
+ g_assert_cmpint (i_cal_property_isa (prop), ==, expected[ii]);
+ if (i_cal_property_isa (prop) == I_CAL_X_PROPERTY) {
+ g_assert_cmpstr (i_cal_property_get_x_name (prop), ==, X_PROP_NAME);
+ g_assert_cmpstr (i_cal_property_get_x (prop), ==, X_PROP_VALUE);
+ }
+ }
+
+ /* Out of bounds */
+ prop = e_cal_component_property_bag_get (bag, ii);
+ g_assert_null (prop);
+}
+
+static void
+test_component_struct_property_bag (void)
+{
+ const gchar *comp_str =
+ "BEGIN:VTODO\r\n"
+ "UID:1\r\n"
+ "STATUS:CANCELLED\r\n"
+ X_PROP_NAME ":" X_PROP_VALUE "\r\n"
+ "END:VTODO\r\n";
+ ICalPropertyKind expected_unfiltered[] = {
+ I_CAL_UID_PROPERTY,
+ I_CAL_STATUS_PROPERTY,
+ I_CAL_X_PROPERTY,
+ I_CAL_ANY_PROPERTY /* sentinel */
+ },
+ expected_filtered[] = {
+ I_CAL_STATUS_PROPERTY,
+ I_CAL_X_PROPERTY,
+ I_CAL_ANY_PROPERTY /* sentinel */
+ };
+ ICalComponent *icomp;
+ ICalProperty *prop;
+ ECalComponentPropertyBag *bag, *bag2;
+ gint ii;
+
+ icomp = i_cal_component_new_from_string (comp_str);
+ g_assert_nonnull (icomp);
+
+ bag = e_cal_component_property_bag_new ();
+ g_assert_nonnull (bag);
+ e_cal_component_property_bag_set_from_component (bag, icomp, NULL, NULL);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, G_N_ELEMENTS (expected_unfiltered)
- 1);
+ test_check_property_bag (bag, expected_unfiltered);
+
+ bag2 = e_cal_component_property_bag_copy (bag);
+ g_assert_nonnull (bag2);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag2), ==, G_N_ELEMENTS
(expected_unfiltered) - 1);
+ test_check_property_bag (bag2, expected_unfiltered);
+ e_cal_component_property_bag_free (bag2);
+ e_cal_component_property_bag_free (bag);
+
+ bag = e_cal_component_property_bag_new_from_component (icomp, NULL, NULL);
+ g_assert_nonnull (bag);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, G_N_ELEMENTS (expected_unfiltered)
- 1);
+ test_check_property_bag (bag, expected_unfiltered);
+ e_cal_component_property_bag_free (bag);
+
+ bag = e_cal_component_property_bag_new ();
+ g_assert_nonnull (bag);
+ e_cal_component_property_bag_set_from_component (bag, icomp, test_property_bag_filter_cb,
expected_filtered);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, G_N_ELEMENTS (expected_filtered) -
1);
+ test_check_property_bag (bag, expected_filtered);
+ e_cal_component_property_bag_free (bag);
+
+ bag = e_cal_component_property_bag_new_from_component (icomp, test_property_bag_filter_cb,
expected_filtered);
+ g_assert_nonnull (bag);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, G_N_ELEMENTS (expected_filtered) -
1);
+ test_check_property_bag (bag, expected_filtered);
+
+ g_object_unref (icomp);
+
+ icomp = i_cal_component_new_vevent ();
+ g_assert_nonnull (icomp);
+ e_cal_component_property_bag_fill_component (bag, icomp);
+ g_assert_cmpint (i_cal_component_count_properties (icomp, I_CAL_ANY_PROPERTY), ==,
e_cal_component_property_bag_get_count (bag));
+ g_object_unref (icomp);
+
+ bag2 = e_cal_component_property_bag_copy (bag);
+
+ while (e_cal_component_property_bag_get_count (bag) > 1) {
+ e_cal_component_property_bag_remove (bag, 1);
+ }
+
+ e_cal_component_property_bag_assign (bag2, bag);
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==,
e_cal_component_property_bag_get_count (bag2));
+ e_cal_component_property_bag_free (bag2);
+
+ icomp = i_cal_component_new_vevent ();
+ g_assert_nonnull (icomp);
+ e_cal_component_property_bag_fill_component (bag, icomp);
+ g_assert_cmpint (i_cal_component_count_properties (icomp, I_CAL_ANY_PROPERTY), ==, 1);
+ g_object_unref (icomp);
+
+ e_cal_component_property_bag_clear (bag);
+
+ icomp = i_cal_component_new_vevent ();
+ g_assert_nonnull (icomp);
+ e_cal_component_property_bag_fill_component (bag, icomp);
+ g_assert_cmpint (i_cal_component_count_properties (icomp, I_CAL_ANY_PROPERTY), ==, 0);
+ g_object_unref (icomp);
+
+ prop = i_cal_property_new_uid ("234");
+ e_cal_component_property_bag_add (bag, prop);
+ g_object_unref (prop);
+
+ prop = i_cal_property_new_status (I_CAL_STATUS_CANCELLED);
+ e_cal_component_property_bag_take (bag, prop);
+
+ g_assert_cmpint (e_cal_component_property_bag_get_count (bag), ==, 2);
+
+ for (ii = 0; ii < 2; ii++) {
+ ICalProperty *prop2;
+
+ prop2 = e_cal_component_property_bag_get (bag, ii);
+ if (ii == 0) {
+ g_assert (prop != prop2);
+ g_assert_cmpint (i_cal_property_isa (prop2), ==, I_CAL_UID_PROPERTY);
+ g_assert_cmpstr (i_cal_property_get_uid (prop2), ==, "234");
+ } else {
+ g_assert (prop == prop2);
+ g_assert_cmpint (i_cal_property_isa (prop2), ==, I_CAL_STATUS_PROPERTY);
+ g_assert_cmpint (i_cal_property_get_status (prop2), ==, I_CAL_STATUS_CANCELLED);
+ }
+ }
+
+ icomp = i_cal_component_new_vevent ();
+ g_assert_nonnull (icomp);
+ e_cal_component_property_bag_fill_component (bag, icomp);
+ g_assert_cmpint (i_cal_component_count_properties (icomp, I_CAL_ANY_PROPERTY), ==,
e_cal_component_property_bag_get_count (bag));
+ g_object_unref (icomp);
+
+ e_cal_component_property_bag_free (bag);
+}
+
+#undef X_PROP_NAME
+#undef X_PROP_VALUE
+
static void
test_component_struct_range (void)
{
@@ -3367,6 +3618,7 @@ main (gint argc,
g_test_add_func ("/ECalComponent/struct/Id", test_component_struct_id);
g_test_add_func ("/ECalComponent/struct/Organizer", test_component_struct_organizer);
g_test_add_func ("/ECalComponent/struct/Period", test_component_struct_period);
+ g_test_add_func ("/ECalComponent/struct/PropertyBag", test_component_struct_property_bag);
g_test_add_func ("/ECalComponent/struct/Range", test_component_struct_range);
g_test_add_func ("/ECalComponent/struct/Text", test_component_struct_text);
g_test_add_func ("/ECalComponent/vtype", test_component_vtype);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]