From 2d75a701029288c953a84ba0a696675f5a7eb77f Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Tue, 4 Apr 2000 19:30:28 +0000 Subject: Fixed an incorrect function. 2000-04-04 Christopher James Lahey * addressbook/backend/ebook/e-book-view.c: Fixed an incorrect function. * addressbook/backend/ebook/e-book-view.h, addressbook/backend/ebook/e-book.h: Fixed some incorrect function pointer declarations. * addressbook/backend/ebook/e-card-iterator.c, addressbook/backend/ebook/e-card-iterator.h, addressbook/backend/ebook/e-card-list-iterator.c, addressbook/backend/ebook/e-card-list-iterator.h, addressbook/backend/ebook/e-card-list.c, addressbook/backend/ebook/e-card-list.h, addressbook/backend/ebook/e-card.c, addressbook/backend/ebook/e-card.h, addressbook/backend/ebook/test-card.c: Built new iterator system for getting fields with multiple entries. * addressbook/backend/ebook/Makefile.am: Added new files addressbook/backend/ebook/e-card-iterator.c, addressbook/backend/ebook/e-card-iterator.h, addressbook/backend/ebook/e-card-list-iterator.c, addressbook/backend/ebook/e-card-list-iterator.h, addressbook/backend/ebook/e-card-list.c, and addressbook/backend/ebook/e-card-list.h. svn path=/trunk/; revision=2286 --- addressbook/backend/ebook/Makefile.am | 6 + addressbook/backend/ebook/e-book-view.c | 2 +- addressbook/backend/ebook/e-book-view.h | 6 +- addressbook/backend/ebook/e-book.h | 7 +- addressbook/backend/ebook/e-card-iterator.c | 169 +++++++++++++++++++ addressbook/backend/ebook/e-card-iterator.h | 61 +++++++ addressbook/backend/ebook/e-card-list-iterator.c | 199 +++++++++++++++++++++++ addressbook/backend/ebook/e-card-list-iterator.h | 44 +++++ addressbook/backend/ebook/e-card-list.c | 134 +++++++++++++++ addressbook/backend/ebook/e-card-list.h | 59 +++++++ addressbook/backend/ebook/e-card.c | 138 +++++++++++----- addressbook/backend/ebook/e-card.h | 7 +- addressbook/backend/ebook/test-card.c | 25 ++- 13 files changed, 791 insertions(+), 66 deletions(-) create mode 100644 addressbook/backend/ebook/e-card-iterator.c create mode 100644 addressbook/backend/ebook/e-card-iterator.h create mode 100644 addressbook/backend/ebook/e-card-list-iterator.c create mode 100644 addressbook/backend/ebook/e-card-list-iterator.h create mode 100644 addressbook/backend/ebook/e-card-list.c create mode 100644 addressbook/backend/ebook/e-card-list.h (limited to 'addressbook') diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am index 05d07458bf..217c4dfafd 100644 --- a/addressbook/backend/ebook/Makefile.am +++ b/addressbook/backend/ebook/Makefile.am @@ -45,6 +45,9 @@ libebook_la_SOURCES = \ e-book-view.c \ e-book.c \ e-card-cursor.c \ + e-card-iterator.c \ + e-card-list-iterator.c \ + e-card-list.c \ e-card.c libebookincludedir = $(includedir)/backend @@ -55,6 +58,9 @@ libebookinclude_HEADERS = \ e-book-view.h \ e-book.h \ e-card-cursor.h \ + e-card-iterator.h \ + e-card-list-iterator.h \ + e-card-list.h \ e-card.h test_client_SOURCES = \ diff --git a/addressbook/backend/ebook/e-book-view.c b/addressbook/backend/ebook/e-book-view.c index e2e9dc2693..fa8deff67c 100644 --- a/addressbook/backend/ebook/e-book-view.c +++ b/addressbook/backend/ebook/e-book-view.c @@ -63,7 +63,7 @@ e_book_view_do_removed_event (EBookView *book_view, gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [CARD_REMOVED], resp->cards); - g_list_foreach (resp->cards, (GFunc) g_free, NULL); + g_list_foreach (resp->cards, (GFunc) gtk_object_unref, NULL); g_list_free (resp->cards); } diff --git a/addressbook/backend/ebook/e-book-view.h b/addressbook/backend/ebook/e-book-view.h index bb042e76f0..a286e50665 100644 --- a/addressbook/backend/ebook/e-book-view.h +++ b/addressbook/backend/ebook/e-book-view.h @@ -33,9 +33,9 @@ struct _EBookViewClass { /* * Signals. */ - void (* card_changed) (const GList *id); - void (* card_removed) (const char *id); - void (* card_added) (const GList *id); + void (* card_changed) (EBookView *book_view, const GList *cards); + void (* card_removed) (EBookView *book_view, const char *id); + void (* card_added) (EBookView *book_view, const GList *cards); }; /* Creating a new addressbook. */ diff --git a/addressbook/backend/ebook/e-book.h b/addressbook/backend/ebook/e-book.h index ae4839ce29..f45fd1cd1d 100644 --- a/addressbook/backend/ebook/e-book.h +++ b/addressbook/backend/ebook/e-book.h @@ -35,11 +35,8 @@ struct _EBookClass { /* * Signals. */ - void (* open_progress) (const char *msg, short percent); - void (* link_status) (gboolean connected); - void (* card_changed) (const char *id); - void (* card_removed) (const char *id); - void (* card_added) (const char *id); + void (* open_progress) (EBook *book, const char *msg, short percent); + void (* link_status) (EBook *book, gboolean connected); }; /* Callbacks for asynchronous functions. */ diff --git a/addressbook/backend/ebook/e-card-iterator.c b/addressbook/backend/ebook/e-card-iterator.c new file mode 100644 index 0000000000..df4cb5a4a4 --- /dev/null +++ b/addressbook/backend/ebook/e-card-iterator.c @@ -0,0 +1,169 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Christopher James Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#include +#include + +#include + +#define ECI_CLASS(object) (E_CARD_ITERATOR_CLASS(GTK_OBJECT((object))->klass)) + +static void e_card_iterator_init (ECardIterator *card); +static void e_card_iterator_class_init (ECardIteratorClass *klass); + +#define PARENT_TYPE (gtk_object_get_type ()) + +static GtkObjectClass *parent_class; + +enum { + INVALIDATE, + LAST_SIGNAL +}; + +static guint e_card_iterator_signals [LAST_SIGNAL] = { 0, }; + +/** + * e_card_iterator_get_type: + * @void: + * + * Registers the &ECardIterator class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &ECardIterator class. + **/ +GtkType +e_card_iterator_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + GtkTypeInfo info = { + "ECardIterator", + sizeof (ECardIterator), + sizeof (ECardIteratorClass), + (GtkClassInitFunc) e_card_iterator_class_init, + (GtkObjectInitFunc) e_card_iterator_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +static void +e_card_iterator_class_init (ECardIteratorClass *klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS(klass); + + parent_class = gtk_type_class (PARENT_TYPE); + + e_card_iterator_signals [INVALIDATE] = + gtk_signal_new ("invalidate", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ECardIteratorClass, invalidate), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, e_card_iterator_signals, LAST_SIGNAL); + + klass->invalidate = NULL; + klass->get = NULL; + klass->reset = NULL; + klass->next = NULL; + klass->prev = NULL; + klass->delete = NULL; + klass->set = NULL; + klass->is_valid = NULL; +} + +/** + * e_card_iterator_init: + */ +static void +e_card_iterator_init (ECardIterator *card) +{ +} + +/* + * Virtual functions: + */ +void * +e_card_iterator_get (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->get) + return ECI_CLASS(iterator)->get(iterator); + else + return NULL; +} + +void +e_card_iterator_reset (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->reset) + ECI_CLASS(iterator)->reset(iterator); +} + +gboolean +e_card_iterator_next (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->next) + return ECI_CLASS(iterator)->next(iterator); + else + return FALSE; +} + +gboolean +e_card_iterator_prev (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->prev) + return ECI_CLASS(iterator)->prev(iterator); + else + return FALSE; +} + +void +e_card_iterator_delete (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->delete) + ECI_CLASS(iterator)->delete(iterator); +} + +void +e_card_iterator_set (ECardIterator *iterator, + void *object) +{ + if (ECI_CLASS(iterator)->set) + ECI_CLASS(iterator)->set(iterator, object); +} + +gboolean +e_card_iterator_is_valid (ECardIterator *iterator) +{ + if (ECI_CLASS(iterator)->is_valid) + return ECI_CLASS(iterator)->is_valid(iterator); + else + return FALSE; +} + +void +e_card_iterator_invalidate (ECardIterator *iterator) +{ + g_return_if_fail (iterator != NULL); + g_return_if_fail (E_IS_CARD_ITERATOR (iterator)); + + gtk_signal_emit (GTK_OBJECT (iterator), + e_card_iterator_signals [INVALIDATE]); +} diff --git a/addressbook/backend/ebook/e-card-iterator.h b/addressbook/backend/ebook/e-card-iterator.h new file mode 100644 index 0000000000..4b5aaf55b7 --- /dev/null +++ b/addressbook/backend/ebook/e-card-iterator.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Chris Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#ifndef __E_CARD_ITERATOR_H__ +#define __E_CARD_ITERATOR_H__ + +#include +#include +#include + +#define E_TYPE_CARD_ITERATOR (e_card_iterator_get_type ()) +#define E_CARD_ITERATOR(obj) (GTK_CHECK_CAST ((obj), E_TYPE_CARD_ITERATOR, ECardIterator)) +#define E_CARD_ITERATOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_ITERATOR, ECardIteratorClass)) +#define E_IS_CARD_ITERATOR(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_CARD_ITERATOR)) +#define E_IS_CARD_ITERATOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_ITERATOR)) + +typedef struct _ECardIterator ECardIterator; +typedef struct _ECardIteratorClass ECardIteratorClass; + +struct _ECardIterator { + GtkObject object; +}; + +struct _ECardIteratorClass { + GtkObjectClass parent_class; + + /* Signals */ + void (*invalidate) (ECardIterator *iterator); + + /* Virtual functions */ + void * (*get) (ECardIterator *iterator); + void (*reset) (ECardIterator *iterator); + gboolean (*next) (ECardIterator *iterator); + gboolean (*prev) (ECardIterator *iterator); + void (*delete) (ECardIterator *iterator); + void (*set) (ECardIterator *iterator, + void *object); + gboolean (*is_valid) (ECardIterator *iterator); +}; + +void *e_card_iterator_get (ECardIterator *iterator); +void e_card_iterator_reset (ECardIterator *iterator); +gboolean e_card_iterator_next (ECardIterator *iterator); +gboolean e_card_iterator_prev (ECardIterator *iterator); +void e_card_iterator_delete (ECardIterator *iterator); +void e_card_iterator_set (ECardIterator *iterator, + void *object); +gboolean e_card_iterator_is_valid (ECardIterator *iterator); + +void e_card_iterator_invalidate (ECardIterator *iterator); + +/* Standard Gtk function */ +GtkType e_card_iterator_get_type (void); + +#endif /* ! __E_CARD_ITERATOR_H__ */ diff --git a/addressbook/backend/ebook/e-card-list-iterator.c b/addressbook/backend/ebook/e-card-list-iterator.c new file mode 100644 index 0000000000..e6d9a9c040 --- /dev/null +++ b/addressbook/backend/ebook/e-card-list-iterator.c @@ -0,0 +1,199 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Christopher James Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#include +#include + +#include +#include + +static void e_card_list_iterator_init (ECardListIterator *card); +static void e_card_list_iterator_class_init (ECardListIteratorClass *klass); + +static void e_card_list_iterator_invalidate (ECardIterator *iterator); +static gboolean e_card_list_iterator_is_valid (ECardIterator *iterator); +static void e_card_list_iterator_set (ECardIterator *iterator, + void *object); +static void e_card_list_iterator_delete (ECardIterator *iterator); +static gboolean e_card_list_iterator_prev (ECardIterator *iterator); +static gboolean e_card_list_iterator_next (ECardIterator *iterator); +static void e_card_list_iterator_reset (ECardIterator *iterator); +static void *e_card_list_iterator_get (ECardIterator *iterator); +static void e_card_list_iterator_destroy (GtkObject *object); + +#define PARENT_TYPE (e_card_iterator_get_type ()) + +static GtkObjectClass *parent_class; +#define PARENT_CLASS (E_CARD_LIST_ITERATOR_CLASS(parent_class)) + +/** + * e_card_list_iterator_get_type: + * @void: + * + * Registers the &ECardListIterator class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &ECardListIterator class. + **/ +GtkType +e_card_list_iterator_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + GtkTypeInfo info = { + "ECardListIterator", + sizeof (ECardListIterator), + sizeof (ECardListIteratorClass), + (GtkClassInitFunc) e_card_list_iterator_class_init, + (GtkObjectInitFunc) e_card_list_iterator_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +static void +e_card_list_iterator_class_init (ECardListIteratorClass *klass) +{ + GtkObjectClass *object_class; + ECardIteratorClass *iterator_class; + + object_class = GTK_OBJECT_CLASS(klass); + iterator_class = E_CARD_ITERATOR_CLASS(klass); + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = e_card_list_iterator_destroy; + + iterator_class->invalidate = e_card_list_iterator_invalidate; + iterator_class->get = e_card_list_iterator_get; + iterator_class->reset = e_card_list_iterator_reset; + iterator_class->next = e_card_list_iterator_next; + iterator_class->prev = e_card_list_iterator_prev; + iterator_class->delete = e_card_list_iterator_delete; + iterator_class->set = e_card_list_iterator_set; + iterator_class->is_valid = e_card_list_iterator_is_valid; +} + + + +/** + * e_card_list_iterator_init: + */ +static void +e_card_list_iterator_init (ECardListIterator *card) +{ +} + +ECardIterator * +e_card_list_iterator_new (ECardList *list) +{ + ECardListIterator *iterator = gtk_type_new(e_card_list_iterator_get_type()); + + iterator->list = list; + gtk_object_ref(GTK_OBJECT(list)); + iterator->iterator = list->list; + + return E_CARD_ITERATOR(iterator); +} + +/* + * Virtual functions: + */ +static void +e_card_list_iterator_destroy (GtkObject *object) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(object); + e_card_list_remove_iterator(iterator->list, E_CARD_ITERATOR(iterator)); + gtk_object_unref(GTK_OBJECT(iterator->list)); +} + +static void * +e_card_list_iterator_get (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + if (iterator->iterator) + return iterator->iterator->data; + else + return NULL; +} + +static void +e_card_list_iterator_reset (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + iterator->iterator = iterator->list->list; +} + +static gboolean +e_card_list_iterator_next (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + if (iterator->iterator) + iterator->iterator = g_list_next(iterator->iterator); + return (iterator->iterator != NULL); +} + +static gboolean +e_card_list_iterator_prev (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + if (iterator->iterator) + iterator->iterator = g_list_previous(iterator->iterator); + return (iterator->iterator != NULL); +} + +static void +e_card_list_iterator_delete (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + if (iterator->iterator) { + GList *temp = iterator->iterator->next; + if (iterator->list->free) + iterator->list->free(iterator->iterator->data, iterator->list->closure); + iterator->list->list = g_list_remove_link(iterator->list->list, iterator->iterator); + iterator->iterator = temp; + e_card_list_invalidate_iterators(iterator->list, E_CARD_ITERATOR(iterator)); + } +} + +static void +e_card_list_iterator_set (ECardIterator *_iterator, + void *object) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + if (iterator->iterator) { + if (iterator->list->free) + iterator->list->free(iterator->iterator->data, iterator->list->closure); + if (iterator->list->copy) + iterator->iterator->data = iterator->list->copy(object, iterator->list->closure); + else + iterator->iterator->data = object; + } +} + +static gboolean +e_card_list_iterator_is_valid (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + return iterator->iterator != NULL; +} + +static void +e_card_list_iterator_invalidate (ECardIterator *_iterator) +{ + ECardListIterator *iterator = E_CARD_LIST_ITERATOR(_iterator); + iterator->iterator = NULL; +} diff --git a/addressbook/backend/ebook/e-card-list-iterator.h b/addressbook/backend/ebook/e-card-list-iterator.h new file mode 100644 index 0000000000..cdc7a312b1 --- /dev/null +++ b/addressbook/backend/ebook/e-card-list-iterator.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Chris Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#ifndef __E_CARD_LIST_ITERATOR_H__ +#define __E_CARD_LIST_ITERATOR_H__ + +#include +#include +#include +#include +#include + +#define E_TYPE_CARD_LIST_ITERATOR (e_card_list_iterator_get_type ()) +#define E_CARD_LIST_ITERATOR(obj) (GTK_CHECK_CAST ((obj), E_TYPE_CARD_LIST_ITERATOR, ECardListIterator)) +#define E_CARD_LIST_ITERATOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_LIST_ITERATOR, ECardListIteratorClass)) +#define E_IS_CARD_LIST_ITERATOR(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_CARD_LIST_ITERATOR)) +#define E_IS_CARD_LIST_ITERATOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_LIST_ITERATOR)) + +typedef struct _ECardListIterator ECardListIterator; +typedef struct _ECardListIteratorClass ECardListIteratorClass; + +struct _ECardListIterator { + GtkObject object; + + ECardList *list; + GList *iterator; +}; + +struct _ECardListIteratorClass { + GtkObjectClass parent_class; +}; + +ECardIterator *e_card_list_iterator_new (ECardList *list); + +/* Standard Gtk function */ +GtkType e_card_list_iterator_get_type (void); + +#endif /* ! __E_CARD_LIST_ITERATOR_H__ */ diff --git a/addressbook/backend/ebook/e-card-list.c b/addressbook/backend/ebook/e-card-list.c new file mode 100644 index 0000000000..641f5b1f0a --- /dev/null +++ b/addressbook/backend/ebook/e-card-list.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Christopher James Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#include +#include + +#include +#include + +#define ECL_CLASS(object) (E_CARD_LIST_CLASS(GTK_OBJECT((object))->klass)) + +static void e_card_list_init (ECardList *card); +static void e_card_list_class_init (ECardListClass *klass); +static void e_card_list_destroy (GtkObject *object); + +#define PARENT_TYPE (gtk_object_get_type ()) + +static GtkObjectClass *parent_class; + +/** + * e_card_list_get_type: + * @void: + * + * Registers the &ECardList class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &ECardList class. + **/ +GtkType +e_card_list_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + GtkTypeInfo info = { + "ECardList", + sizeof (ECardList), + sizeof (ECardListClass), + (GtkClassInitFunc) e_card_list_class_init, + (GtkObjectInitFunc) e_card_list_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +static void +e_card_list_class_init (ECardListClass *klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS(klass); + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = e_card_list_destroy; +} + +/** + * e_card_list_init: + */ +static void +e_card_list_init (ECardList *list) +{ + list->list = NULL; + list->iterators = NULL; +} + +ECardList * +e_card_list_new (ECardListCopyFunc copy, ECardListFreeFunc free, void *closure) +{ + ECardList *list = gtk_type_new(e_card_list_get_type()); + list->copy = copy; + list->free = free; + list->closure = closure; + return list; +} + +ECardIterator * +e_card_list_get_iterator (ECardList *list) +{ + ECardIterator *iterator = e_card_list_iterator_new(list); + list->iterators = g_list_append(list->iterators, iterator); + return iterator; +} + +void +e_card_list_append (ECardList *list, void *data) +{ + e_card_list_invalidate_iterators(list, NULL); + if (list->copy) + list->list = g_list_append(list->list, list->copy(data, list->closure)); + else + list->list = g_list_append(list->list, data); +} + +void +e_card_list_invalidate_iterators (ECardList *list, ECardIterator *skip) +{ + GList *iterators = list->iterators; + for (; iterators; iterators = iterators->next) { + if (iterators->data != skip) { + e_card_iterator_invalidate(E_CARD_ITERATOR(iterators->data)); + } + } +} + +void +e_card_list_remove_iterator (ECardList *list, ECardIterator *iterator) +{ + list->iterators = g_list_remove(list->iterators, iterator); +} + +/* + * Virtual functions + */ +static void +e_card_list_destroy (GtkObject *object) +{ + ECardList *list = E_CARD_LIST(object); + g_list_foreach(list->list, (GFunc) list->free, list->closure); + g_list_free(list->list); +} diff --git a/addressbook/backend/ebook/e-card-list.h b/addressbook/backend/ebook/e-card-list.h new file mode 100644 index 0000000000..123d890e88 --- /dev/null +++ b/addressbook/backend/ebook/e-card-list.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: + * Chris Lahey + * + * Copyright (C) 2000 Helix Code, Inc. + * Copyright (C) 1999 The Free Software Foundation + */ + +#ifndef __E_CARD_LIST_H__ +#define __E_CARD_LIST_H__ + +#include +#include +#include +#include + +#define E_TYPE_CARD_LIST (e_card_list_get_type ()) +#define E_CARD_LIST(obj) (GTK_CHECK_CAST ((obj), E_TYPE_CARD_LIST, ECardList)) +#define E_CARD_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_LIST, ECardListClass)) +#define E_IS_CARD_LIST(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_CARD_LIST)) +#define E_IS_CARD_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_LIST)) + +typedef void *(*ECardListCopyFunc) (void *data, void *closure); +typedef void *(*ECardListFreeFunc) (void *data, void *closure); + +typedef struct _ECardList ECardList; +typedef struct _ECardListClass ECardListClass; + +struct _ECardList { + GtkObject object; + GList *list; + GList *iterators; + ECardListCopyFunc copy; + ECardListFreeFunc free; + void *closure; +}; + +struct _ECardListClass { + GtkObjectClass parent_class; +}; + +ECardList *e_card_list_new (ECardListCopyFunc copy, + ECardListFreeFunc free, + void *closure); +ECardIterator *e_card_list_get_iterator (ECardList *list); +void e_card_list_append (ECardList *list, + void *data); + +/* For iterators to call. */ +void e_card_list_invalidate_iterators (ECardList *list, + ECardIterator *skip); +void e_card_list_remove_iterator (ECardList *list, + ECardIterator *iterator); + +/* Standard Gtk function */ +GtkType e_card_list_get_type (void); + +#endif /* ! __E_CARD_LIST_H__ */ diff --git a/addressbook/backend/ebook/e-card.c b/addressbook/backend/ebook/e-card.c index eb5c315b0f..ba55ffc2f7 100644 --- a/addressbook/backend/ebook/e-card.c +++ b/addressbook/backend/ebook/e-card.c @@ -62,6 +62,11 @@ static void set_phone_flags (VObject *vobj, ECardPhoneFlags flags); static ECardAddressFlags get_address_flags (VObject *vobj); static void set_address_flags (VObject *vobj, ECardAddressFlags flags); +static void e_card_phone_free (ECardPhone *phone); +static ECardPhone *e_card_phone_copy (ECardPhone *phone); +static void e_card_delivery_address_free (ECardDeliveryAddress *addr); +static ECardDeliveryAddress *e_card_delivery_address_copy (ECardDeliveryAddress *addr); + typedef void (* ParsePropertyFunc) (ECard *card, VObject *object); struct { @@ -193,10 +198,10 @@ char if ( card->address ) { - GList *list = card->address; - for ( ; list; list = list->next ) { + ECardIterator *iterator = e_card_list_get_iterator(card->address); + for ( ; e_card_iterator_is_valid(iterator) ;e_card_iterator_next(iterator) ) { VObject *addressprop; - ECardDeliveryAddress *address = (ECardDeliveryAddress *) list->data; + ECardDeliveryAddress *address = (ECardDeliveryAddress *) e_card_iterator_get(iterator); addressprop = addProp(vobj, VCAdrProp); set_address_flags (addressprop, address->flags); @@ -215,26 +220,29 @@ char if ( address->country ) addPropValue(addressprop, VCCountryNameProp, address->country); } + gtk_object_unref(GTK_OBJECT(iterator)); } if ( card->phone ) { - GList *list = card->phone; - for ( ; list; list = list->next ) { + ECardIterator *iterator = e_card_list_get_iterator(card->phone); + for ( ; e_card_iterator_is_valid(iterator) ;e_card_iterator_next(iterator) ) { VObject *phoneprop; - ECardPhone *phone = (ECardPhone *) list->data; + ECardPhone *phone = (ECardPhone *) e_card_iterator_get(iterator); phoneprop = addPropValue(vobj, VCTelephoneProp, phone->number); set_phone_flags (phoneprop, phone->flags); } + gtk_object_unref(GTK_OBJECT(iterator)); } if ( card->email ) { - GList *list = card->email; - for ( ; list; list = list->next ) { + ECardIterator *iterator = e_card_list_get_iterator(card->address); + for ( ; e_card_iterator_is_valid(iterator) ;e_card_iterator_next(iterator) ) { VObject *emailprop; - emailprop = addPropValue(vobj, VCEmailAddressProp, (char *) list->data); + emailprop = addPropValue(vobj, VCEmailAddressProp, (char *) e_card_iterator_get(iterator)); addProp (emailprop, VCInternetProp); } + gtk_object_unref(GTK_OBJECT(iterator)); } if ( card->bday ) { @@ -382,8 +390,14 @@ static void parse_email(ECard *card, VObject *vobj) { char *next_email; + ECardList *list; + assign_string(vobj, &next_email); - card->email = g_list_append(card->email, next_email); + gtk_object_get(GTK_OBJECT(card), + "email", &list, + NULL); + e_card_list_append(list, next_email); + g_free (next_email); } static void @@ -403,15 +417,23 @@ static void parse_phone(ECard *card, VObject *vobj) { ECardPhone *next_phone = g_new(ECardPhone, 1); + ECardList *list; + assign_string(vobj, &(next_phone->number)); next_phone->flags = get_phone_flags(vobj); - card->phone = g_list_append(card->phone, next_phone); + + gtk_object_get(GTK_OBJECT(card), + "phone", &list, + NULL); + e_card_list_append(list, next_phone); + e_card_phone_free (next_phone); } static void parse_address(ECard *card, VObject *vobj) { ECardDeliveryAddress *next_addr = g_new(ECardDeliveryAddress, 1); + ECardList *list; next_addr->flags = get_address_flags (vobj); next_addr->po = e_v_object_get_child_value (vobj, VCPostalBoxProp); @@ -422,7 +444,11 @@ parse_address(ECard *card, VObject *vobj) next_addr->code = e_v_object_get_child_value (vobj, VCPostalCodeProp); next_addr->country = e_v_object_get_child_value (vobj, VCCountryNameProp); - card->address = g_list_append(card->address, next_addr); + gtk_object_get(GTK_OBJECT(card), + "address", &list, + NULL); + e_card_list_append(list, next_addr); + e_card_delivery_address_free (next_addr); } static void @@ -462,11 +488,11 @@ e_card_class_init (ECardClass *klass) gtk_object_add_arg_type ("ECard::name", GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_NAME); gtk_object_add_arg_type ("ECard::address", - GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_ADDRESS); + GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_ADDRESS); gtk_object_add_arg_type ("ECard::phone", - GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_PHONE); + GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_PHONE); gtk_object_add_arg_type ("ECard::email", - GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_EMAIL); + GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_EMAIL); gtk_object_add_arg_type ("ECard::birth_date", GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_BIRTH_DATE); @@ -486,6 +512,18 @@ e_card_phone_free (ECardPhone *phone) } } +static ECardPhone * +e_card_phone_copy (ECardPhone *phone) +{ + if ( phone ) { + ECardPhone *phone_copy = g_new(ECardPhone, 1); + phone_copy->number = g_strdup(phone->number); + phone_copy->flags = phone->flags; + return phone_copy; + } else + return NULL; +} + static void e_card_delivery_address_free (ECardDeliveryAddress *addr) { @@ -508,6 +546,24 @@ e_card_delivery_address_free (ECardDeliveryAddress *addr) } } +static ECardDeliveryAddress * +e_card_delivery_address_copy (ECardDeliveryAddress *addr) +{ + if ( addr ) { + ECardDeliveryAddress *addr_copy = g_new(ECardDeliveryAddress, 1); + addr_copy->po = g_strdup(addr->po ); + addr_copy->ext = g_strdup(addr->ext ); + addr_copy->street = g_strdup(addr->street ); + addr_copy->city = g_strdup(addr->city ); + addr_copy->region = g_strdup(addr->region ); + addr_copy->code = g_strdup(addr->code ); + addr_copy->country = g_strdup(addr->country); + addr_copy->flags = addr->flags; + return addr_copy; + } else + return NULL; +} + /* * ECard lifecycle management and vCard loading/saving. */ @@ -525,14 +581,12 @@ e_card_destroy (GtkObject *object) if ( card->bday ) g_free(card->bday); - g_list_foreach(card->email, (GFunc)g_free, NULL); - g_list_free(card->email); - - g_list_foreach(card->phone, (GFunc)e_card_phone_free, NULL); - g_list_free(card->phone); - - g_list_foreach(card->address, (GFunc)e_card_delivery_address_free, NULL); - g_list_free(card->address); + if (card->email) + gtk_object_unref(GTK_OBJECT(card->email)); + if (card->phone) + gtk_object_unref(GTK_OBJECT(card->phone)); + if (card->address) + gtk_object_unref(GTK_OBJECT(card->address)); } @@ -555,21 +609,6 @@ e_card_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) e_card_name_free(card->name); card->name = GTK_VALUE_POINTER(*arg); break; - case ARG_ADDRESS: - g_list_foreach(card->address, (GFunc)e_card_delivery_address_free, NULL); - g_list_free(card->address); - card->address = GTK_VALUE_POINTER(*arg); - break; - case ARG_PHONE: - g_list_foreach(card->phone, (GFunc)e_card_phone_free, NULL); - g_list_free(card->phone); - card->phone = GTK_VALUE_POINTER(*arg); - break; - case ARG_EMAIL: - g_list_foreach(card->email, (GFunc)g_free, NULL); - g_list_free(card->email); - card->email = GTK_VALUE_POINTER(*arg); - break; case ARG_BIRTH_DATE: if ( card->bday ) g_free(card->bday); @@ -590,22 +629,31 @@ e_card_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) switch (arg_id) { case ARG_FULL_NAME: - if ( card->fname ) - GTK_VALUE_STRING (*arg) = g_strdup (card->fname); - else - GTK_VALUE_STRING (*arg) = NULL; + GTK_VALUE_STRING (*arg) = card->fname; break; case ARG_NAME: GTK_VALUE_POINTER(*arg) = card->name; break; case ARG_ADDRESS: - GTK_VALUE_POINTER(*arg) = card->address; + if (!card->address) + card->address = e_card_list_new((ECardListCopyFunc) e_card_delivery_address_copy, + (ECardListFreeFunc) e_card_delivery_address_free, + NULL); + GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->address); break; case ARG_PHONE: - GTK_VALUE_POINTER(*arg) = card->phone; + if (!card->address) + card->address = e_card_list_new((ECardListCopyFunc) e_card_phone_copy, + (ECardListFreeFunc) e_card_phone_free, + NULL); + GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->phone); break; case ARG_EMAIL: - GTK_VALUE_POINTER(*arg) = card->email; + if (!card->address) + card->address = e_card_list_new((ECardListCopyFunc) g_strdup, + (ECardListFreeFunc) g_free, + NULL); + GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->email); break; case ARG_BIRTH_DATE: GTK_VALUE_POINTER(*arg) = card->bday; diff --git a/addressbook/backend/ebook/e-card.h b/addressbook/backend/ebook/e-card.h index 200d4c3b3e..3d2af18c55 100644 --- a/addressbook/backend/ebook/e-card.h +++ b/addressbook/backend/ebook/e-card.h @@ -16,6 +16,7 @@ #include #include #include +#include #define E_TYPE_CARD (e_card_get_type ()) #define E_CARD(obj) (GTK_CHECK_CAST ((obj), E_TYPE_CARD, ECard)) @@ -32,13 +33,13 @@ struct _ECard { char *fname; /* The full name. */ ECardName *name; /* The structured name. */ - GList *address; /* Delivery addresses (ECardDeliveryAddress *) */ + ECardList *address; /* Delivery addresses (ECardDeliveryAddress *) */ #if 0 GList *del_labels; /* Delivery address labels * (ECardAddrLabel *) */ #endif - GList *phone; /* Phone numbers (ECardPhone *) */ - GList *email; /* Email addresses (char *) */ + ECardList *phone; /* Phone numbers (ECardPhone *) */ + ECardList *email; /* Email addresses (char *) */ #if 0 char *url; /* The person's web page. */ diff --git a/addressbook/backend/ebook/test-card.c b/addressbook/backend/ebook/test-card.c index d032dfe707..70ced1a8d5 100644 --- a/addressbook/backend/ebook/test-card.c +++ b/addressbook/backend/ebook/test-card.c @@ -61,9 +61,10 @@ main (int argc, char **argv) /* Fields */ char *fname; ECardName *name; - GList *address; - GList *phone; - GList *email; + ECardList *address; + ECardList *phone; + ECardList *email; + ECardIterator *iterator; ECardDate *bday; gnome_init ("TestCard", "0.0", argc, argv); @@ -114,19 +115,24 @@ main (int argc, char **argv) printf("BDay : %4d-%02d-%02d\n", bday->year, bday->month, bday->day); } if ( email ) { - for ( ; email; email = email->next ) { - printf("Email : %s\n", (char *) email->data); + iterator = e_card_list_get_iterator(address); + for (; e_card_iterator_is_valid(iterator); e_card_iterator_next(iterator)) { + printf("Email : %s\n", (char *) e_card_iterator_get(iterator)); } + gtk_object_unref(GTK_OBJECT(iterator)); } if ( phone ) { - for ( ; phone; phone = phone->next ) { - ECardPhone *e_card_phone = (ECardPhone *) phone->data; + iterator = e_card_list_get_iterator(address); + for (; e_card_iterator_is_valid(iterator); e_card_iterator_next(iterator)) { + ECardPhone *e_card_phone = (ECardPhone *) e_card_iterator_get(iterator); printf("Phone ; %d : %s\n", e_card_phone->flags, e_card_phone->number); } + gtk_object_unref(GTK_OBJECT(iterator)); } if ( address ) { - for ( ; address; address = address->next ) { - ECardDeliveryAddress *del_address = (ECardDeliveryAddress *) address->data; + iterator = e_card_list_get_iterator(address); + for (; e_card_iterator_is_valid(iterator); e_card_iterator_next(iterator)) { + ECardDeliveryAddress *del_address = (ECardDeliveryAddress *) e_card_iterator_get(iterator); printf("Address ; %d:\n", del_address->flags); if ( del_address->po ) printf(" Po : %s\n", del_address->po); @@ -143,6 +149,7 @@ main (int argc, char **argv) if ( del_address->country ) printf(" Country : %s\n", del_address->country); } + gtk_object_unref(GTK_OBJECT(iterator)); } printf("%s", e_card_get_vcard(card)); gtk_object_unref (GTK_OBJECT (card)); -- cgit v1.2.3