[balsa] Implement VCalendar stuff using G_*_TYPE()



commit fd2f689fcc7b91ccb0fa42c3692fb7d9bdb50254
Author: Albrecht Dreß <albrecht dress arcor de>
Date:   Mon Jun 10 13:17:28 2019 -0400

    Implement VCalendar stuff using G_*_TYPE()
    
    * libbalsa/rfc2445.[ch]: implement LibBalsaVCal and LibBalsaVEvent
      using G_DECLARE_FINAL_TYPE() and G_DEFINE_TYPE(); make the data
      fields private; implement private member getters required for
      display and printing
    * src/balsa-mime-widget-vcalendar.c: use new LibBalsaVCal and
      LibBalsaVEvent getters; add missing “Created” DTSTAMP item
    * src/balsa-print-object-text.c: use new LibBalsaVCal and
      LibBalsaVEvent getters; add missing “Created” DTSTAMP item;
      use same labels as for screen display

 ChangeLog                         |  14 ++
 libbalsa/rfc2445.c                | 298 +++++++++++++++++++++++++-------------
 libbalsa/rfc2445.h                |  82 +++--------
 src/balsa-mime-widget-vcalendar.c |  69 ++++-----
 src/balsa-print-object-text.c     |  63 ++++----
 5 files changed, 302 insertions(+), 224 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c916ae3a0..fefdc7024 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2019-06-10  Albrecht Dreß  <albrecht dress arcor de>
+
+       Implement VCalendar stuff using G_*_TYPE()
+
+       * libbalsa/rfc2445.[ch]: implement LibBalsaVCal and LibBalsaVEvent
+         using G_DECLARE_FINAL_TYPE() and G_DEFINE_TYPE(); make the data
+         fields private; implement private member getters required for
+         display and printing
+       * src/balsa-mime-widget-vcalendar.c: use new LibBalsaVCal and
+         LibBalsaVEvent getters; add missing “Created” DTSTAMP item
+       * src/balsa-print-object-text.c: use new LibBalsaVCal and
+         LibBalsaVEvent getters; add missing “Created” DTSTAMP item;
+         use same labels as for screen display
+
 2019-06-08  Peter Bloomfield  <pbloomfield bellsouth net>
 
        Use G_DECLARE_FINAL_TYPE to declare LibBalsaVfs
diff --git a/libbalsa/rfc2445.c b/libbalsa/rfc2445.c
index d59c48662..42e68ac6a 100644
--- a/libbalsa/rfc2445.c
+++ b/libbalsa/rfc2445.c
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /*
  * VCalendar (RFC 2445) stuff
- * Copyright (C) 2009 Albrecht Dreß <albrecht dress arcor de>
+ * Copyright (C) 2009-2019 Albrecht Dreß <albrecht dress arcor de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,8 +42,36 @@ typedef enum {
 } LibBalsaVCalRole;
 
 
-static GObjectClass *libbalsa_vcal_parent_class = NULL;
-static GObjectClass *libbalsa_vevent_parent_class = NULL;
+struct _LibBalsaVCal {
+    GObject parent;
+
+    /* method */
+    LibBalsaVCalMethod method;
+
+    /* linked list of VEVENT entries */
+    GList *vevent;
+};
+
+G_DEFINE_TYPE(LibBalsaVCal, libbalsa_vcal, G_TYPE_OBJECT)
+
+
+struct _LibBalsaVEvent {
+    GObject parent;
+
+    LibBalsaAddress *organizer;
+    GList *attendee;
+    time_t stamp;
+    time_t start;
+    gboolean start_date_only;
+    time_t end;
+    gboolean end_date_only;
+    gchar *uid;
+    gchar *summary;
+    gchar *location;
+    gchar *description;
+};
+
+G_DEFINE_TYPE(LibBalsaVEvent, libbalsa_vevent, G_TYPE_OBJECT)
 
 
 /* LibBalsaAddress extra object data */
@@ -52,13 +80,13 @@ static GObjectClass *libbalsa_vevent_parent_class = NULL;
 #define RFC2445_RSVP            "RFC2445:RSVP"
 
 
-static void libbalsa_vcal_class_init(LibBalsaVCalClass * klass);
-static void libbalsa_vcal_init(LibBalsaVCal * self);
-static void libbalsa_vcal_finalize(LibBalsaVCal * self);
+static void libbalsa_vcal_class_init(LibBalsaVCalClass *klass);
+static void libbalsa_vcal_init(LibBalsaVCal *self);
+static void libbalsa_vcal_finalize(GObject *self);
 
-static void libbalsa_vevent_class_init(LibBalsaVEventClass * klass);
-static void libbalsa_vevent_init(LibBalsaVEvent * self);
-static void libbalsa_vevent_finalize(LibBalsaVEvent * self);
+static void libbalsa_vevent_class_init(LibBalsaVEventClass *klass);
+static void libbalsa_vevent_init(LibBalsaVEvent *self);
+static void libbalsa_vevent_finalize(GObject *self);
 
 static LibBalsaAddress *cal_address_2445_to_lbaddress(const gchar * uri,
                                                      gchar ** attributes,
@@ -97,46 +125,18 @@ static struct {
 
 
 /* --- VCal GObject stuff --- */
-GType
-libbalsa_vcal_get_type(void)
-{
-    static GType libbalsa_vcal_type = 0;
-
-    if (!libbalsa_vcal_type) {
-       static const GTypeInfo libbalsa_vcal_type_info = {
-           sizeof(LibBalsaVCalClass),  /* class_size */
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) libbalsa_vcal_class_init,  /* class_init */
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(LibBalsaVCal),       /* instance_size */
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) libbalsa_vcal_init,     /* instance_init */
-           /* no value_table */
-       };
-
-       libbalsa_vcal_type =
-           g_type_register_static(G_TYPE_OBJECT, "LibBalsaVCal",
-                                  &libbalsa_vcal_type_info, 0);
-    }
-
-    return libbalsa_vcal_type;
-}
-
 
 static void
-libbalsa_vcal_class_init(LibBalsaVCalClass * klass)
+libbalsa_vcal_class_init(LibBalsaVCalClass *klass)
 {
     GObjectClass *gobject_klass = G_OBJECT_CLASS(klass);
 
-    libbalsa_vcal_parent_class = g_type_class_peek(G_TYPE_OBJECT);
-    gobject_klass->finalize = (GObjectFinalizeFunc) libbalsa_vcal_finalize;
+    gobject_klass->finalize = libbalsa_vcal_finalize;
 }
 
 
 static void
-libbalsa_vcal_init(LibBalsaVCal * self)
+libbalsa_vcal_init(LibBalsaVCal *self)
 {
     self->method = ITIP_UNKNOWN;
     self->vevent = NULL;
@@ -144,15 +144,17 @@ libbalsa_vcal_init(LibBalsaVCal * self)
 
 
 static void
-libbalsa_vcal_finalize(LibBalsaVCal * self)
+libbalsa_vcal_finalize(GObject *self)
 {
-    g_return_if_fail(self != NULL);
-    if (self->vevent) {
-       g_list_foreach(self->vevent, (GFunc) g_object_unref, NULL);
-       g_list_free(self->vevent);
+       LibBalsaVCal *vcal = LIBBALSA_VCAL(self);
+       const GObjectClass *parent_class = G_OBJECT_CLASS(libbalsa_vcal_parent_class);
+
+    if (vcal->vevent != NULL) {
+       g_list_foreach(vcal->vevent, (GFunc) g_object_unref, NULL);
+       g_list_free(vcal->vevent);
     }
 
-    libbalsa_vcal_parent_class->finalize(G_OBJECT(self));
+    (*parent_class->finalize)(self);
 }
 
 
@@ -164,69 +166,41 @@ libbalsa_vcal_new(void)
 
 
 /* --- VEvent GObject stuff --- */
-GType
-libbalsa_vevent_get_type(void)
-{
-    static GType libbalsa_vevent_type = 0;
-
-    if (!libbalsa_vevent_type) {
-       static const GTypeInfo libbalsa_vevent_type_info = {
-           sizeof(LibBalsaVEventClass),        /* class_size */
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) libbalsa_vevent_class_init,        /* class_init */
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(LibBalsaVEvent),     /* instance_size */
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) libbalsa_vevent_init,   /* instance_init */
-           /* no value_table */
-       };
-
-       libbalsa_vevent_type =
-           g_type_register_static(G_TYPE_OBJECT, "LibBalsaVEvent",
-                                  &libbalsa_vevent_type_info, 0);
-    }
-
-    return libbalsa_vevent_type;
-}
-
-
 static void
 libbalsa_vevent_class_init(LibBalsaVEventClass * klass)
 {
     GObjectClass *gobject_klass = G_OBJECT_CLASS(klass);
 
-    libbalsa_vevent_parent_class = g_type_class_peek(G_TYPE_OBJECT);
-    gobject_klass->finalize =
-       (GObjectFinalizeFunc) libbalsa_vevent_finalize;
+    gobject_klass->finalize = libbalsa_vevent_finalize;
 }
 
 
 static void
-libbalsa_vevent_init(LibBalsaVEvent * self)
+libbalsa_vevent_init(LibBalsaVEvent *self)
 {
-    self->start = self->end = self->stamp = (time_t) - 1;
+    self->start = self->end = self->stamp = (time_t) (-1);
 }
 
 
 static void
-libbalsa_vevent_finalize(LibBalsaVEvent * self)
+libbalsa_vevent_finalize(GObject *self)
 {
-    g_return_if_fail(self != NULL);
+       LibBalsaVEvent *vevent = LIBBALSA_VEVENT(self);
+       const GObjectClass *parent_class = G_OBJECT_CLASS(libbalsa_vevent_parent_class);
 
-    if (self->organizer)
-       g_object_unref(self->organizer);
-    if (self->attendee) {
-       g_list_foreach(self->attendee, (GFunc) g_object_unref, NULL);
-       g_list_free(self->attendee);
-    }
-    g_free(self->uid);
-    g_free(self->summary);
-    g_free(self->location);
-    g_free(self->description);
+       if (vevent->organizer) {
+               g_object_unref(vevent->organizer);
+       }
+       if (vevent->attendee) {
+               g_list_foreach(vevent->attendee, (GFunc) g_object_unref, NULL);
+               g_list_free(vevent->attendee);
+       }
+       g_free(vevent->uid);
+       g_free(vevent->summary);
+       g_free(vevent->location);
+       g_free(vevent->description);
 
-    libbalsa_vevent_parent_class->finalize(G_OBJECT(self));
+       (*parent_class->finalize)(self);
 }
 
 
@@ -461,6 +435,102 @@ libbalsa_vcal_attendee_rsvp(LibBalsaAddress * person)
 }
 
 
+LibBalsaAddress *
+libbalsa_vevent_organizer(LibBalsaVEvent *event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event), NULL);
+       return event->organizer;
+}
+
+
+const gchar *
+libbalsa_vevent_summary(LibBalsaVEvent *event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event), NULL);
+       return event->summary;
+}
+
+
+const gchar *
+libbalsa_vevent_location(LibBalsaVEvent *event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event), NULL);
+       return event->location;
+}
+
+
+const gchar *
+libbalsa_vevent_description(LibBalsaVEvent *event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event), NULL);
+       return event->description;
+}
+
+
+time_t
+libbalsa_vevent_timestamp(LibBalsaVEvent *event, LibBalsaVEventTimestamp which)
+{
+       time_t result;
+
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event) &&
+               (which >= VEVENT_DATETIME_STAMP) && (VEVENT_DATETIME_END), (time_t) -1);
+       switch (which) {
+       case VEVENT_DATETIME_STAMP:
+               result = event->stamp;
+               break;
+       case VEVENT_DATETIME_START:
+               result = event->start;
+               break;
+       case VEVENT_DATETIME_END:
+               result = event->end;
+               break;
+       default:
+               g_assert_not_reached();
+       }
+       return result;
+}
+
+
+gboolean
+libbalsa_vevent_timestamp_date_only(LibBalsaVEvent *event, LibBalsaVEventTimestamp which)
+{
+       gboolean result;
+
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event) &&
+               (which >= VEVENT_DATETIME_STAMP) && (VEVENT_DATETIME_END), FALSE);
+       switch (which) {
+       case VEVENT_DATETIME_STAMP:
+               result = FALSE;
+               break;
+       case VEVENT_DATETIME_START:
+               result = event->start_date_only;
+               break;
+       case VEVENT_DATETIME_END:
+               result = event->end_date_only;
+               break;
+       default:
+               g_assert_not_reached();
+       }
+       return result;
+}
+
+
+guint
+libbalsa_vevent_attendees(LibBalsaVEvent *event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event), 0U);
+       return g_list_length(event->attendee);
+}
+
+
+LibBalsaAddress *
+libbalsa_vevent_attendee(LibBalsaVEvent *event, guint nth_attendee)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VEVENT(event) && (nth_attendee < g_list_length(event->attendee)), 
NULL);
+       return (LibBalsaAddress *) g_list_nth_data(event->attendee, nth_attendee);
+}
+
+
 /* return a new buffer containing a proper reply to an event for a new
  * participant status */
 gchar *
@@ -705,22 +775,29 @@ vcal_str_to_method(const gchar * method)
 }
 
 
+LibBalsaVCalMethod
+libbalsa_vcal_method(LibBalsaVCal *vcal)
+{
+    g_return_val_if_fail(LIBBALSA_IS_VCAL(vcal) &&
+       (vcal->method >= ITIP_UNKNOWN) && (vcal->method <= ITIP_CANCEL), ITIP_UNKNOWN);
+    return vcal->method;
+}
+
 /* return a rfc 2445 method as human-readable string */
 const gchar *
-libbalsa_vcal_method_to_str(LibBalsaVCalMethod method)
+libbalsa_vcal_method_str(LibBalsaVCal *vcal)
 {
-    static gchar *methods[] = {
-        N_("unknown"),
-       N_("Event Notification"),
-       N_("Event Request"),
-       N_("Reply to Event Request"),
-       N_("Event Cancellation"),
-    };
-
-    g_return_val_if_fail(method >= ITIP_UNKNOWN && method <= ITIP_CANCEL,
-                        NULL);
-    return methods[(int) method];
+       static gchar *methods[] = {
+               N_("unknown"),
+               N_("Event Notification"),
+               N_("Event Request"),
+               N_("Reply to Event Request"),
+               N_("Event Cancellation"),
+       };
 
+    g_return_val_if_fail(LIBBALSA_IS_VCAL(vcal) &&
+       (vcal->method >= ITIP_UNKNOWN) && (vcal->method <= ITIP_CANCEL), NULL);
+    return methods[(int) vcal->method];
 }
 
 
@@ -777,6 +854,19 @@ libbalsa_vcal_part_stat_to_str(LibBalsaVCalPartStat pstat)
 
 }
 
+guint
+libbalsa_vcal_vevents(LibBalsaVCal *vcal)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VCAL(vcal), 0U);
+       return g_list_length(vcal->vevent);
+}
+
+LibBalsaVEvent *
+libbalsa_vcal_vevent(LibBalsaVCal *vcal, guint nth_event)
+{
+       g_return_val_if_fail(LIBBALSA_IS_VCAL(vcal) && (nth_event < g_list_length(vcal->vevent)), NULL);
+       return (LibBalsaVEvent *) g_list_nth_data(vcal->vevent, nth_event);
+}
 
 /* convert the passed participant status string into the enumeration */
 static LibBalsaVCalPartStat
diff --git a/libbalsa/rfc2445.h b/libbalsa/rfc2445.h
index dca5d6cf1..d9676e44a 100644
--- a/libbalsa/rfc2445.h
+++ b/libbalsa/rfc2445.h
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /*
  * VCalendar (RFC 2445) stuff
- * Copyright (C) 2009 Albrecht Dreß <albrecht dress arcor de>
+ * Copyright (C) 2009-2019 Albrecht Dreß <albrecht dress arcor de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,27 +31,13 @@
 G_BEGIN_DECLS
 
 /* a VCalendar object description as GObject */
-#define LIBBALSA_TYPE_VCAL            (libbalsa_vcal_get_type())
-#define LIBBALSA_VCAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), LIBBALSA_TYPE_VCAL, LibBalsaVCal))
-#define LIBBALSA_VCAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), LIBBALSA_TYPE_VCAL, 
LibBalsaVCalClass))
-#define LIBBALSA_IS_VCAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIBBALSA_TYPE_VCAL))
-#define LIBBALSA_IS_VCAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LIBBALSA_TYPE_VCAL))
-#define LIBBALSA_VCAL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), LIBBALSA_TYPE_VCAL, 
LibBalsaVCalClass))
-
-typedef struct _LibBalsaVCal LibBalsaVCal;
-typedef struct _LibBalsaVCalClass LibBalsaVCalClass;
+#define LIBBALSA_TYPE_VCAL                     (libbalsa_vcal_get_type())
+G_DECLARE_FINAL_TYPE(LibBalsaVCal, libbalsa_vcal, LIBBALSA, VCAL, GObject)
 
 
 /* a VEvent object description as GObject */
-#define LIBBALSA_TYPE_VEVENT            (libbalsa_vevent_get_type())
-#define LIBBALSA_VEVENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), LIBBALSA_TYPE_VEVENT, 
LibBalsaVEvent))
-#define LIBBALSA_VEVENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), LIBBALSA_TYPE_VEVENT, 
LibBalsaVEventClass))
-#define LIBBALSA_IS_VEVENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIBBALSA_TYPE_VEVENT))
-#define LIBBALSA_IS_VEVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LIBBALSA_TYPE_VEVENT))
-#define LIBBALSA_VEVENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), LIBBALSA_TYPE_VEVENT, 
LibBalsaVEventClass))
-
-typedef struct _LibBalsaVEvent LibBalsaVEvent;
-typedef struct _LibBalsaVEventClass LibBalsaVEventClass;
+#define LIBBALSA_TYPE_VEVENT           (libbalsa_vevent_get_type())
+G_DECLARE_FINAL_TYPE(LibBalsaVEvent, libbalsa_vevent, LIBBALSA, VEVENT, GObject)
 
 
 /* methods as defined by RFC 2446 */
@@ -76,50 +62,16 @@ typedef enum {
     VCAL_PSTAT_IN_PROCESS
 } LibBalsaVCalPartStat;
 
-
-struct _LibBalsaVCal {
-    GObject parent;
-
-    /* method */
-    LibBalsaVCalMethod method;
-
-    /* linked list of VEVENT entries */
-    GList *vevent;
-};
-
-
-struct _LibBalsaVEvent {
-    GObject parent;
-
-    LibBalsaAddress *organizer;
-    GList *attendee;
-    time_t stamp;
-    time_t start;
-    gboolean start_date_only;
-    time_t end;
-    gboolean end_date_only;
-    gchar *uid;
-    gchar *summary;
-    gchar *location;
-    gchar *description;
-};
-
-
-struct _LibBalsaVCalClass {
-    GObjectClass parent;
-};
-
-
-struct _LibBalsaVEventClass {
-    GObjectClass parent;
-};
+typedef enum {
+       VEVENT_DATETIME_STAMP,
+       VEVENT_DATETIME_START,
+       VEVENT_DATETIME_END
+} LibBalsaVEventTimestamp;
 
 
-GType libbalsa_vcal_get_type(void);
 LibBalsaVCal *libbalsa_vcal_new(void);
 LibBalsaVCal *libbalsa_vcal_new_from_body(LibBalsaMessageBody * body);
 
-GType libbalsa_vevent_get_type(void);
 LibBalsaVEvent *libbalsa_vevent_new(void);
 gchar *libbalsa_vevent_reply(const LibBalsaVEvent * event,
                             const gchar * sender,
@@ -127,8 +79,20 @@ gchar *libbalsa_vevent_reply(const LibBalsaVEvent * event,
 
 gchar *libbalsa_vcal_attendee_to_str(LibBalsaAddress * person);
 gboolean libbalsa_vcal_attendee_rsvp(LibBalsaAddress * person);
-const gchar *libbalsa_vcal_method_to_str(LibBalsaVCalMethod method);
+LibBalsaVCalMethod libbalsa_vcal_method(LibBalsaVCal *vcal);
+const gchar *libbalsa_vcal_method_str(LibBalsaVCal *vcal);
 const gchar *libbalsa_vcal_part_stat_to_str(LibBalsaVCalPartStat pstat);
+guint libbalsa_vcal_vevents(LibBalsaVCal *vcal);
+LibBalsaVEvent *libbalsa_vcal_vevent(LibBalsaVCal *vcal, guint nth_event);
+
+LibBalsaAddress *libbalsa_vevent_organizer(LibBalsaVEvent *event);
+const gchar *libbalsa_vevent_summary(LibBalsaVEvent *event);
+const gchar *libbalsa_vevent_location(LibBalsaVEvent *event);
+const gchar *libbalsa_vevent_description(LibBalsaVEvent *event);
+time_t libbalsa_vevent_timestamp(LibBalsaVEvent *event, LibBalsaVEventTimestamp which);
+gboolean libbalsa_vevent_timestamp_date_only(LibBalsaVEvent *event, LibBalsaVEventTimestamp which);
+guint libbalsa_vevent_attendees(LibBalsaVEvent *event);
+LibBalsaAddress *libbalsa_vevent_attendee(LibBalsaVEvent *event, guint nth_attendee);
 
 G_END_DECLS
 
diff --git a/src/balsa-mime-widget-vcalendar.c b/src/balsa-mime-widget-vcalendar.c
index c50912b97..0ee021fe7 100644
--- a/src/balsa-mime-widget-vcalendar.c
+++ b/src/balsa-mime-widget-vcalendar.c
@@ -46,7 +46,7 @@ balsa_mime_widget_new_vcalendar(BalsaMessage * bm,
     BalsaMimeWidget *mw;
     GtkWidget *label;
     gchar *text;
-    GList *l;
+    guint event_no;
     LibBalsaMessage *lbm = bm->message;
     gboolean may_reply = FALSE;
     InternetAddress *sender = NULL;;
@@ -63,7 +63,7 @@ balsa_mime_widget_new_vcalendar(BalsaMessage * bm,
     mw->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
 
     text = g_strdup_printf(_("This is an iTIP calendar “%s” message."),
-                          libbalsa_vcal_method_to_str(vcal_obj->method));
+                          libbalsa_vcal_method_str(vcal_obj));
     label = gtk_label_new(text);
     g_free(text);
     gtk_widget_set_halign(label, GTK_ALIGN_START);
@@ -71,7 +71,7 @@ balsa_mime_widget_new_vcalendar(BalsaMessage * bm,
     gtk_container_add(GTK_CONTAINER(mw->widget), label);
 
     /* a reply may be created only for unread requests */
-    if ((vcal_obj->method == ITIP_REQUEST) &&
+    if ((libbalsa_vcal_method(vcal_obj) == ITIP_REQUEST) &&
        LIBBALSA_MESSAGE_IS_UNREAD(lbm)) {
        may_reply = TRUE;
        if (lbm->headers) {
@@ -88,11 +88,11 @@ balsa_mime_widget_new_vcalendar(BalsaMessage * bm,
     }
 
     /* add events */
-    for (l = vcal_obj->vevent; l; l = g_list_next(l)) {
-       GtkWidget *event =
-           balsa_vevent_widget((LibBalsaVEvent *) l->data, may_reply,
-                               sender);
-       gtk_container_add(GTK_CONTAINER(mw->widget), event);
+    for (event_no = 0U; event_no < libbalsa_vcal_vevents(vcal_obj); event_no++) {
+       GtkWidget *event;
+
+       event = balsa_vevent_widget(libbalsa_vcal_vevent(vcal_obj, event_no), may_reply, sender);
+       gtk_container_add(GTK_CONTAINER(mw->widget), event);
     }
 
     g_object_unref(vcal_obj);
@@ -118,16 +118,18 @@ balsa_mime_widget_new_vcalendar(BalsaMessage * bm,
         }                                                               \
     } while (0)
 
-#define GRID_ATTACH_DATE(g,date,date_only,label)                        \
-    do {                                                                \
-        if (date != (time_t) -1) {                                      \
-            gchar * _dstr =                                             \
-                libbalsa_date_to_utf8(date,                                                    \
-                       date_only ? "%x" : balsa_app.date_string);              \
-            GRID_ATTACH(g, _dstr, label);                               \
-            g_free(_dstr);                                              \
-        }                                                               \
-    } while (0)
+#define GRID_ATTACH_DATE(g,event,date_id,label)                                                        \
+       G_STMT_START {                                                                  \
+       time_t _date = libbalsa_vevent_timestamp(event, date_id);                                       \
+        if (_date != (time_t) -1) {                                                            \
+               gboolean _d_only = libbalsa_vevent_timestamp_date_only(event, date_id); \
+            gchar * _dstr =                                                                    \
+                libbalsa_date_to_utf8(_date,                                                                 
          \
+                       _d_only ? "%x" : balsa_app.date_string);                                        \
+            GRID_ATTACH(g, _dstr, label);                                                      \
+            g_free(_dstr);                                                                     \
+        }                                                                                      \
+    } G_STMT_END
 
 #define GRID_ATTACH_ADDRESS(g,addr,label)                               \
     do {                                                                \
@@ -165,21 +167,20 @@ balsa_vevent_widget(LibBalsaVEvent * event, gboolean may_reply,
     GtkGrid *grid;
     int row = 0;
     LibBalsaIdentity *vevent_ident = NULL;
+    guint attendee;
+       GString *all_atts = NULL;
 
     grid = GTK_GRID(gtk_grid_new());
     gtk_grid_set_row_spacing(grid, 6);
     gtk_grid_set_column_spacing(grid, 12);
-    GRID_ATTACH(grid, event->summary, _("Summary:"));
-    GRID_ATTACH_ADDRESS(grid, event->organizer, _("Organizer:"));
-    GRID_ATTACH_DATE(grid, event->start, event->start_date_only, _("Start:"));
-    GRID_ATTACH_DATE(grid, event->end, event->end_date_only, _("End:"));
-    GRID_ATTACH(grid, event->location, _("Location:"));
-    if (event->attendee) {
-       GList *att;
-       GString *all_atts = NULL;
-
-       for (att = event->attendee; att; att = att->next) {
-           LibBalsaAddress *lba = LIBBALSA_ADDRESS(att->data);
+    GRID_ATTACH(grid, libbalsa_vevent_summary(event), _("Summary:"));
+    GRID_ATTACH_ADDRESS(grid, libbalsa_vevent_organizer(event), _("Organizer:"));
+    GRID_ATTACH_DATE(grid, event, VEVENT_DATETIME_STAMP, _("Created:"));
+    GRID_ATTACH_DATE(grid, event, VEVENT_DATETIME_START, _("Start:"));
+    GRID_ATTACH_DATE(grid, event, VEVENT_DATETIME_END, _("End:"));
+    GRID_ATTACH(grid, libbalsa_vevent_location(event), _("Location:"));
+    for (attendee = 0U; attendee < libbalsa_vevent_attendees(event); attendee++) {
+           LibBalsaAddress *lba = libbalsa_vevent_attendee(event, attendee);
            gchar *this_att = libbalsa_vcal_attendee_to_str(lba);
 
            if (all_atts)
@@ -204,12 +205,12 @@ balsa_vevent_widget(LibBalsaVEvent * event, gboolean may_reply,
                g_object_unref(ia);
            }
        }
+    if (all_atts != NULL) {
        GRID_ATTACH(grid, all_atts->str,
-                    ngettext("Attendee:", "Attendees:",
-                             g_list_length(event->attendee)));
+                    ngettext("Attendee:", "Attendees:", libbalsa_vevent_attendees(event)));
        g_string_free(all_atts, TRUE);
     }
-    GRID_ATTACH_TEXT(grid, event->description, _("Description:"));
+    GRID_ATTACH_TEXT(grid, libbalsa_vevent_description(event), _("Description:"));
 
     if (sender && vevent_ident) {
        GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
@@ -277,6 +278,7 @@ vevent_reply(GObject * button, GtkWidget * box)
     gchar *rcpt;
     LibBalsaMessage *message;
     LibBalsaMessageBody *body;
+    const gchar *summary;
     gchar *dummy;
     gchar **params;
     GError *error = NULL;
@@ -302,8 +304,9 @@ vevent_reply(GObject * button, GtkWidget * box)
     message->headers->date = time(NULL);
 
     /* create the message subject */
+    summary = libbalsa_vevent_summary(event);
     dummy = g_strdup_printf("%s: %s",
-                           event->summary ? event->summary : _("iTIP Calendar Request"),
+                           (summary != NULL) ? summary : _("iTIP Calendar Request"),
                            libbalsa_vcal_part_stat_to_str(pstat));
     libbalsa_message_set_subject(message, dummy);
     g_free(dummy);
diff --git a/src/balsa-print-object-text.c b/src/balsa-print-object-text.c
index 0815f1b92..9a1373959 100644
--- a/src/balsa-print-object-text.c
+++ b/src/balsa-print-object-text.c
@@ -555,16 +555,18 @@ balsa_print_object_text_vcard(GList * list,
        }                                                               \
     } while(0)
 
-#define ADD_VCAL_DATE(buf, labwidth, layout, date, date_only, descr)   \
-    do {                                                                \
-        if (date != (time_t) -1) {                                      \
-            gchar * _dstr =                                             \
-                libbalsa_date_to_utf8(date,                                                            \
-                       date_only ? "%x" : balsa_app.date_string);              \
-            ADD_VCAL_FIELD(buf, labwidth, layout, _dstr, descr);        \
-            g_free(_dstr);                                              \
-        }                                                               \
-    } while (0)
+#define ADD_VCAL_DATE(buf, labwidth, layout, event, date_id, descr)                                    \
+       G_STMT_START {                                                                  \
+       time_t _date = libbalsa_vevent_timestamp(event, date_id);                                       \
+        if (_date != (time_t) -1) {                                                            \
+               gboolean _d_only = libbalsa_vevent_timestamp_date_only(event, date_id); \
+            gchar * _dstr =                                                                    \
+                libbalsa_date_to_utf8(_date,                                                                 
          \
+                       _d_only ? "%x" : balsa_app.date_string);                                        \
+            ADD_VCAL_FIELD(buf, labwidth, layout, _dstr, descr);                               \
+            g_free(_dstr);                                                                     \
+        }                                                                                      \
+    } G_STMT_END
 
 #define ADD_VCAL_ADDRESS(buf, labwidth, layout, addr, descr)            \
     do {                                                                \
@@ -589,7 +591,7 @@ balsa_print_object_text_calendar(GList * list,
     PangoTabArray *tabs;
     GString *desc_buf;
     LibBalsaVCal * vcal_obj;
-    GList * this_ev;
+    guint event_no;
     guint first_page;
     GList *par_parts;
     GList *this_par_part;
@@ -641,44 +643,49 @@ balsa_print_object_text_calendar(GList * list,
     /* add fields from the events*/
     desc_buf = g_string_new("");
     pod->p_label_width = 0;
-    for (this_ev = vcal_obj->vevent; this_ev; this_ev = g_list_next(this_ev)) {
-        LibBalsaVEvent * event = (LibBalsaVEvent *) this_ev->data;
+    for (event_no = 0U; event_no < libbalsa_vcal_vevents(vcal_obj); event_no++) {
+        LibBalsaVEvent * event = libbalsa_vcal_vevent(vcal_obj, event_no);
+        const gchar *description;
+        guint attendees;
 
         if (desc_buf->len > 0)
             g_string_append_c(desc_buf, '\n');
         ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                       event->summary, _("Summary"));
+               libbalsa_vevent_summary(event), _("Summary:"));
         ADD_VCAL_ADDRESS(desc_buf, pod->p_label_width, test_layout,
-                         event->organizer, _("Organizer"));
+               libbalsa_vevent_organizer(event), _("Organizer:"));
+        ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
+                      event, VEVENT_DATETIME_STAMP, _("Created:"));
         ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
-                      event->start, event->start_date_only, _("Start"));
+                      event, VEVENT_DATETIME_START, _("Start:"));
         ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
-                      event->end, event->end_date_only, _("End"));
+                      event, VEVENT_DATETIME_END, _("End:"));
         ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                       event->location, _("Location"));
-        if (event->attendee) {
-            GList * att = event->attendee;
+               libbalsa_vevent_location(event), _("Location:"));
+        attendees = libbalsa_vevent_attendees(event);
+        if (attendees > 0U) {
             gchar * this_att;
+            guint n;
 
             this_att =
-                libbalsa_vcal_attendee_to_str(LIBBALSA_ADDRESS(att->data));
-            att = g_list_next(att);
+                libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, 0U));
             ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                           this_att, att ? _("Attendees") : _("Attendee"));
+                           this_att, (attendees > 1U) ? _("Attendees:") : _("Attendee:"));
             g_free(this_att);
-            for (; att; att = g_list_next(att)) {
+            for (n = 1U; n < attendees; n++) {
                 this_att =
-                    libbalsa_vcal_attendee_to_str(LIBBALSA_ADDRESS(att->data));
+                    libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, n));
                 g_string_append_printf(desc_buf, "\n\t%s", this_att);
                 g_free(this_att);
             }
         }
-        if (event->description) {
-            gchar ** desc_lines = g_strsplit(event->description, "\n", -1);
+        description = libbalsa_vevent_description(event);
+        if (description != NULL) {
+            gchar ** desc_lines = g_strsplit(description, "\n", -1);
             gint i;
 
             ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                           desc_lines[0], _("Description"));
+                           desc_lines[0], _("Description:"));
             for (i = 1; desc_lines[i]; i++)
                 g_string_append_printf(desc_buf, "\n\t%s", desc_lines[i]);
             g_strfreev(desc_lines);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]