Frederic Ruaudel <grumz@users.sf.net>
Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
Wayne Schuller <k_wayne@linuxpower.org>
+ Austin Henry <ahenry@users.sourceforge.net> -- EDS and vcard backends
nestor di <nestordi@usuarios.retecal.es> -- excellent splash screen
that first appeared in
0.4.3:
+2005-10-24 Jim Evins <evins@snaught.com>
+
+ * AUTHORS:
+ * src/Makefile.am:
+ * src/merge-evolution.c:
+ * src/merge-evolution.h:
+ * src/merge-init.c: (gl_merge_init):
+ * src/merge-properties-dialog.c: (type_changed_cb):
+ * src/merge-vcard.c:
+ * src/merge-vcard.h:
+ * src/ui-commands.c: (gl_ui_cmd_help_about):
+ Added Evolution Data Server and VCard merge backends. Original patch
+ provided by Austin Henry <ahenry@users.sourceforge.net>.
+ * configure.in:
+ Only support EDS and VCard backends if libebook is installed. Allow
+ user to disable support, even if installed.
+
2005-10-24 Jim Evins <evins@snaught.com>
* AUTHORS:
LIBGNOMEPRINTUI_REQUIRED=2.10.0
LIBGNOMECANVAS_REQUIRED=2.10.0
LIBGLADE_REQUIRED=2.5.0
+LIBEBOOK_REQUIRED=1.2.0
dnl Make above strings available for packaging files (e.g. rpm spec files)
AC_SUBST(GLIB_REQUIRED)
AC_SUBST(LIBGNOMEPRINTUI_REQUIRED)
AC_SUBST(LIBGNOMECANVAS_REQUIRED)
AC_SUBST(LIBGLADE_REQUIRED)
+AC_SUBST(LIBEBOOK_REQUIRED)
+
+
+dnl ---------------------------------------------------------------------------
+dnl - Check for evolution data server
+dnl ---------------------------------------------------------------------------
+AC_ARG_WITH(libebook,
+ [AC_HELP_STRING([--without-libebook],
+ [build without Evolution Data Server support])])
+have_libebook=no
+if test "x$with_libebook" != xno; then
+ PKG_CHECK_MODULES(LIBEBOOK, libebook-1.2 >= $LIBEBOOK_REQUIRED,
+ [have_libebook=yes], [have_libebook=no])
+fi
+
+if test "x$have_libebook" = "xyes"; then
+ AC_DEFINE(HAVE_LIBEBOOK,1,[Define to 1 for EDS support])
+ OPTIONAL_MODULES="$OPTIONAL_MODULES libebook-1.2 >= $LIBEBOOK_REQUIRED"
+fi
dnl ---------------------------------------------------------------------------
libgnomeprintui-2.2 >= $LIBGNOMEPRINTUI_REQUIRED \
libgnomecanvas-2.0 >= $LIBGNOMECANVAS_REQUIRED \
libglade-2.0 >= $LIBGLADE_REQUIRED \
+$OPTIONAL_MODULES \
)
AC_SUBST(GLABELS_CFLAGS)
echo "
Configuration:
- Package: ${PACKAGE}-${VERSION}:
- Installation prefix ${prefix}
- Source code location: ${srcdir}
- Compiler: ${CC}
+ Package: ${PACKAGE}-${VERSION}:
+ Installation prefix ${prefix}
+ Source code location: ${srcdir}
+ Compiler: ${CC}
+ Evolution Data Server support: ${have_libebook}
"
merge-init.h \
merge-text.c \
merge-text.h \
+ merge-evolution.c \
+ merge-evolution.h \
+ merge-vcard.c \
+ merge-vcard.h \
text-node.c \
text-node.h \
wdgt-print-copies.c \
merge-init.h \
merge-text.c \
merge-text.h \
+ merge-evolution.c \
+ merge-evolution.h \
+ merge-vcard.c \
+ merge-vcard.h \
text-node.c \
text-node.h \
prefs.c \
--- /dev/null
+/*
+ * (GLABELS) Label and Business Card Creation program for GNOME
+ *
+ * merge_evolution.c: evolution merge backend module
+ *
+ * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
+ * and
+ * Copyright (C) 2005 Austin Henry <ahenry@users.sourceforge.net>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LIBEBOOK
+
+
+#include "merge-evolution.h"
+#include <libebook/e-book.h>
+
+#include <stdio.h>
+
+#include "debug.h"
+
+#define DEFAULT_QUERY "(exists \"full_name\")"
+
+/*===========================================*/
+/* Private types */
+/*===========================================*/
+
+struct _glMergeEvolutionPrivate {
+ gchar *query;
+ EBook *book;
+ GList *contacts;
+ GList *error_list; /* list of error strings */
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_QUERY,
+};
+
+/*===========================================*/
+/* Private globals */
+/*===========================================*/
+
+static glMergeClass *parent_class = NULL;
+
+
+/*===========================================*/
+/* Local function prototypes */
+/*===========================================*/
+
+static void gl_merge_evolution_class_init (glMergeEvolutionClass *klass);
+static void gl_merge_evolution_instance_init (glMergeEvolution *object);
+static void gl_merge_evolution_finalize (GObject *object);
+
+static void gl_merge_evolution_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void gl_merge_evolution_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GList *gl_merge_evolution_get_key_list (glMerge *merge);
+static gchar *gl_merge_evolution_get_primary_key (glMerge *merge);
+static void gl_merge_evolution_open (glMerge *merge);
+static void gl_merge_evolution_close (glMerge *merge);
+static glMergeRecord *gl_merge_evolution_get_record (glMerge *merge);
+static void gl_merge_evolution_copy (glMerge *dst_merge,
+ glMerge *src_merge);
+
+/* utility function prototypes go here */
+\f
+/*****************************************************************************/
+/* Boilerplate object stuff. */
+/*****************************************************************************/
+GType
+gl_merge_evolution_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (glMergeEvolutionClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gl_merge_evolution_class_init,
+ NULL,
+ NULL,
+ sizeof (glMergeEvolution),
+ 0,
+ (GInstanceInitFunc) gl_merge_evolution_instance_init,
+ NULL
+ };
+
+ type = g_type_register_static (GL_TYPE_MERGE,
+ "glMergeEvolution", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+gl_merge_evolution_class_init (glMergeEvolutionClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ glMergeClass *merge_class = (glMergeClass *) klass;
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = gl_merge_evolution_set_property;
+ object_class->get_property = gl_merge_evolution_get_property;
+
+ g_object_class_install_property
+ (object_class,
+ ARG_QUERY,
+ g_param_spec_string ("query", NULL,
+ "Query used to select records from the addressbook",
+ "(exists \"full_name\")",
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+ object_class->finalize = gl_merge_evolution_finalize;
+
+ merge_class->get_key_list = gl_merge_evolution_get_key_list;
+ merge_class->get_primary_key = gl_merge_evolution_get_primary_key;
+ merge_class->open = gl_merge_evolution_open;
+ merge_class->close = gl_merge_evolution_close;
+ merge_class->get_record = gl_merge_evolution_get_record;
+ merge_class->copy = gl_merge_evolution_copy;
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_evolution_instance_init (glMergeEvolution *merge_evolution)
+{
+ gl_debug (DEBUG_MERGE, "START");
+
+ merge_evolution->private = g_new0 (glMergeEvolutionPrivate, 1);
+ merge_evolution->private->query = g_strdup(DEFAULT_QUERY);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_evolution_finalize (GObject *object)
+{
+ glMergeEvolution *merge_evolution;
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ g_return_if_fail (object && GL_IS_MERGE_EVOLUTION (object));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ merge_evolution = GL_MERGE_EVOLUTION (object);
+ g_free (merge_evolution->private->query);
+ g_free (merge_evolution->private);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Set argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_evolution_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeEvolution *merge_evolution;
+
+ merge_evolution = GL_MERGE_EVOLUTION (object);
+
+ switch (param_id) {
+
+ case ARG_QUERY:
+ g_free (merge_evolution->private->query);
+ merge_evolution->private->query = g_value_dup_string (value);
+ gl_debug (DEBUG_MERGE, "ARG \"query\" = \"%s\"",
+ merge_evolution->private->query);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+
+ }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_evolution_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeEvolution *merge_evolution;
+
+ merge_evolution = GL_MERGE_EVOLUTION (object);
+
+ switch (param_id) {
+
+ case ARG_QUERY:
+ g_value_set_string (value, merge_evolution->private->query);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+
+ }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get key list. */
+/*--------------------------------------------------------------------------*/
+static GList *
+gl_merge_evolution_get_key_list (glMerge *merge)
+{
+ glMergeEvolution *merge_evolution;
+ GList *key_list;
+
+ gl_debug (DEBUG_MERGE, "BEGIN");
+
+ merge_evolution = GL_MERGE_EVOLUTION (merge);
+
+ /* extremely simple approach until I can list the available keys from the
+ * server, and return them. */
+ key_list = NULL;
+ key_list = g_list_append (key_list, g_strdup ("record_key"));
+ key_list = g_list_append (key_list, g_strdup ("full_name"));
+ key_list = g_list_append (key_list, g_strdup ("home_address"));
+ key_list = g_list_append (key_list, g_strdup ("work_address"));
+
+ gl_debug (DEBUG_MERGE, "END");
+
+ return key_list;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get "primary" key. */
+/*--------------------------------------------------------------------------*/
+static gchar *
+gl_merge_evolution_get_primary_key (glMerge *merge)
+{
+ return g_strdup ("record_key");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Open merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_evolution_open (glMerge *merge)
+{
+ glMergeEvolution *merge_evolution;
+ EBookQuery *query;
+ gboolean status;
+ GError *error;
+ GList **error_list;
+
+ merge_evolution = GL_MERGE_EVOLUTION (merge);
+ error_list = &merge_evolution->private->error_list;
+
+ query = e_book_query_from_string(merge_evolution->private->query);
+ if (!query) {
+ merge_evolution->private->error_list =
+ g_list_append(merge_evolution->private->error_list,
+ g_strdup("Couldn't construct query"));
+ g_error_free (error);
+ return;
+ }
+
+ merge_evolution->private->book = e_book_new_system_addressbook(&error);
+ if (!merge_evolution->private->book) {
+ *error_list = g_list_append(*error_list,
+ g_strdup_printf("Couldn't open addressbook: %s",
+ error->message));
+ e_book_query_unref(query);
+ g_error_free (error);
+ return;
+ }
+
+ if (!e_book_open(merge_evolution->private->book, TRUE, &error)) {
+ *error_list = g_list_append(*error_list,
+ g_strdup_printf("Couldn't open addressbook: %s",
+ error->message));
+ g_error_free (error);
+ e_book_query_unref(query);
+ g_object_unref(merge_evolution->private->book);
+ merge_evolution->private->book = NULL;
+
+ return;
+ }
+
+ status = e_book_get_contacts (merge_evolution->private->book,
+ query,
+ &merge_evolution->private->contacts,
+ &error);
+ if (status == FALSE) {
+ *error_list = g_list_append(*error_list,
+ g_strdup_printf("Couldn't get contacts: %s",
+ error->message));
+ g_error_free (error);
+ e_book_query_unref(query);
+ g_object_unref(merge_evolution->private->book);
+ merge_evolution->private->book = NULL;
+
+ return;
+ }
+
+ e_book_query_unref(query);
+ return;
+ /* XXX I should probably sort the list by name (or the file-as element)*/
+}
+
+/*--------------------------------------------------------------------------*/
+/* Close merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_evolution_close (glMerge *merge)
+{
+ glMergeEvolution *merge_evolution;
+ GList *iter;
+
+ merge_evolution = GL_MERGE_EVOLUTION (merge);
+
+ /* unref all of the objects created in _open */
+ g_object_unref(merge_evolution->private->book);
+ merge_evolution->private->book = NULL;
+
+ for (iter = merge_evolution->private->contacts;
+ iter != NULL;
+ iter = g_list_next(iter))
+ {
+ EContact *contact = E_CONTACT (iter->data);
+
+ g_object_unref(contact);
+ }
+ g_list_free(merge_evolution->private->contacts);
+ merge_evolution->private->contacts = NULL;
+
+ for (iter = merge_evolution->private->error_list;
+ iter != NULL;
+ iter = g_list_next(iter))
+ {
+ g_free(iter->data);
+ }
+ merge_evolution->private->error_list = NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get next record from merge source, NULL if no records left (i.e EOF) */
+/*--------------------------------------------------------------------------*/
+static glMergeRecord *
+gl_merge_evolution_get_record (glMerge *merge)
+{
+ glMergeEvolution *merge_evolution;
+ glMergeRecord *record;
+ glMergeField *field;
+
+ GList *head;
+ EContact *contact;
+
+ merge_evolution = GL_MERGE_EVOLUTION (merge);
+
+ /* we're in an error state */
+ if (merge_evolution->private->error_list) {
+ head = merge_evolution->private->error_list;
+ char *error_str = head->data;
+
+ /* a yucky hack to make the errors show up in the record list */
+ record = g_new0 (glMergeRecord, 1);
+ record->select_flag = TRUE;
+
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("full_name");
+ field->value = g_strdup (error_str);
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* do a destructive read */
+ g_free (error_str);
+ merge_evolution->private->error_list =
+ g_list_remove_link (merge_evolution->private->error_list, head);
+ g_list_free_1 (head);
+
+ return record;
+ }
+
+ head = merge_evolution->private->contacts;
+ if (head == NULL) {
+ return NULL; /* past the last record */
+ }
+ contact = E_CONTACT(head->data);
+
+ record = g_new0 (glMergeRecord, 1);
+ record->select_flag = TRUE;
+
+ /* Take the interesting fields one by one from the contact, and put them
+ * into the glMergeRecord structure. When done, free up the resources for
+ * that contact */
+
+ /* get the record key */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("record_key");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_FILE_AS));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the full name */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("full_name");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_FULL_NAME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the home address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("home_address");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_ADDRESS_LABEL_HOME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the work address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("work_address");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_ADDRESS_LABEL_WORK));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* do a destructive read */
+ g_object_unref (contact);
+ merge_evolution->private->contacts =
+ g_list_remove_link (merge_evolution->private->contacts, head);
+ g_list_free_1 (head);
+
+ return record;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Copy merge_evolution specific fields. */
+/*---------------------------------------------------------------------------*/
+static void
+gl_merge_evolution_copy (glMerge *dst_merge,
+ glMerge *src_merge)
+{
+ glMergeEvolution *dst_merge_evolution;
+ glMergeEvolution *src_merge_evolution;
+
+ dst_merge_evolution = GL_MERGE_EVOLUTION (dst_merge);
+ src_merge_evolution = GL_MERGE_EVOLUTION (src_merge);
+
+ dst_merge_evolution->private->query = g_strdup(src_merge_evolution->private->query);
+ /* I don't know that there's a good way to do a deep copy of the various
+ * libebook structures/objects, so I'm just going to leave them out. They
+ * are all regenerated on gl_merge_evolution_open, anyway */
+}
+
+
+
+#endif /* HAVE_LIBEBOOK */
--- /dev/null
+/*
+ * (GLABELS) Label and Business Card Creation program for GNOME
+ *
+ * merge_evolution.h: evolution merge backend module header file
+ *
+ * Copyright (C) 2002 Jim Evins <evins@snaught.com>.
+ * and
+ * Copyright (C) 2005 Austin Henry <ahenry@users.sourceforge.net>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __MERGE_EVOLUTION_H__
+#define __MERGE_EVOLUTION_H__
+
+#include "merge.h"
+
+G_BEGIN_DECLS
+
+/* The following object arguments are available:
+ *
+ * name type description
+ * --------------------------------------------------------------------------------
+ * query gchar* The query used to select records
+ *
+ */
+
+#define GL_TYPE_MERGE_EVOLUTION (gl_merge_evolution_get_type ())
+#define GL_MERGE_EVOLUTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_MERGE_EVOLUTION, glMergeEvolution))
+#define GL_MERGE_EVOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_MERGE_EVOLUTION, glMergeEvolutionClass))
+#define GL_IS_MERGE_EVOLUTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_MERGE_EVOLUTION))
+#define GL_IS_MERGE_EVOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_MERGE_EVOLUTION))
+#define GL_MERGE_EVOLUTION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GL_TYPE_MERGE_EVOLUTION, glMergeEvolutionClass))
+
+
+typedef struct _glMergeEvolution glMergeEvolution;
+typedef struct _glMergeEvolutionClass glMergeEvolutionClass;
+
+typedef struct _glMergeEvolutionPrivate glMergeEvolutionPrivate;
+
+
+struct _glMergeEvolution {
+ glMerge object;
+
+ glMergeEvolutionPrivate *private;
+};
+
+struct _glMergeEvolutionClass {
+ glMergeClass parent_class;
+};
+
+
+GType gl_merge_evolution_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __MERGE_EVOLUTION_H__ */
#include "merge-init.h"
#include "merge-text.h"
+#ifdef HAVE_LIBEBOOK
+#include "merge-evolution.h"
+#include "merge-vcard.h"
+#endif /* HAVE_LIBEBOOK */
#include "debug.h"
"delim", '\t',
NULL);
+#ifdef HAVE_LIBEBOOK
+
+ gl_merge_register_backend (GL_TYPE_MERGE_EVOLUTION,
+ "ebook/eds",
+ _("Data from default Evolution Addressbook"),
+ GL_MERGE_SRC_IS_FIXED,
+ NULL);
+
+ gl_merge_register_backend (GL_TYPE_MERGE_VCARD,
+ "ebook/vcard",
+ _("Data from a file containing VCards"),
+ GL_MERGE_SRC_IS_FILE,
+ NULL);
+
+#endif /* HAVE_LIBEBOOK */
+
}
"selection-changed",
G_CALLBACK (src_changed_cb), dialog);
break;
+ case GL_MERGE_SRC_IS_FIXED:
+ dialog->priv->src_entry = gtk_label_new (_("Fixed"));
+ gtk_misc_set_alignment (GTK_MISC (dialog->priv->src_entry), 0.0, 0.5);
+
+ gl_debug (DEBUG_MERGE, "Setting src = \"%s\"", dialog->priv->saved_src);
+ gl_merge_set_src (dialog->priv->merge, "Fixed");
+ break;
default:
dialog->priv->src_entry = gtk_label_new (_("N/A"));
gtk_misc_set_alignment (GTK_MISC (dialog->priv->src_entry), 0.0, 0.5);
--- /dev/null
+/*
+ * (GLABELS) Label and Business Card Creation program for GNOME
+ *
+ * merge_vcard.c: vcard merge backend module
+ *
+ * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
+ * and
+ * Copyright (C) 2005 Austin Henry <ahenry@users.sourceforge.net>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LIBEBOOK
+
+
+#include "merge-vcard.h"
+#include <libebook/e-contact.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "debug.h"
+
+/*===========================================*/
+/* Private types */
+/*===========================================*/
+
+struct _glMergeVCardPrivate {
+ FILE *fp;
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+};
+
+/*===========================================*/
+/* Private globals */
+/*===========================================*/
+
+static glMergeClass *parent_class = NULL;
+
+
+/*===========================================*/
+/* Local function prototypes */
+/*===========================================*/
+
+static void gl_merge_vcard_class_init (glMergeVCardClass *klass);
+static void gl_merge_vcard_instance_init (glMergeVCard *object);
+static void gl_merge_vcard_finalize (GObject *object);
+
+static void gl_merge_vcard_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void gl_merge_vcard_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GList *gl_merge_vcard_get_key_list (glMerge *merge);
+static gchar *gl_merge_vcard_get_primary_key (glMerge *merge);
+static void gl_merge_vcard_open (glMerge *merge);
+static void gl_merge_vcard_close (glMerge *merge);
+static glMergeRecord *gl_merge_vcard_get_record (glMerge *merge);
+static void gl_merge_vcard_copy (glMerge *dst_merge,
+ glMerge *src_merge);
+static char * parse_next_vcard (FILE *fp);
+
+/* utility function prototypes go here */
+\f
+/*****************************************************************************/
+/* Boilerplate object stuff. */
+/*****************************************************************************/
+GType
+gl_merge_vcard_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (glMergeVCardClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gl_merge_vcard_class_init,
+ NULL,
+ NULL,
+ sizeof (glMergeVCard),
+ 0,
+ (GInstanceInitFunc) gl_merge_vcard_instance_init,
+ NULL
+ };
+
+ type = g_type_register_static (GL_TYPE_MERGE,
+ "glMergeVCard", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+gl_merge_vcard_class_init (glMergeVCardClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ glMergeClass *merge_class = (glMergeClass *) klass;
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = gl_merge_vcard_set_property;
+ object_class->get_property = gl_merge_vcard_get_property;
+
+ object_class->finalize = gl_merge_vcard_finalize;
+
+ merge_class->get_key_list = gl_merge_vcard_get_key_list;
+ merge_class->get_primary_key = gl_merge_vcard_get_primary_key;
+ merge_class->open = gl_merge_vcard_open;
+ merge_class->close = gl_merge_vcard_close;
+ merge_class->get_record = gl_merge_vcard_get_record;
+ merge_class->copy = gl_merge_vcard_copy;
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_vcard_instance_init (glMergeVCard *merge_vcard)
+{
+ gl_debug (DEBUG_MERGE, "START");
+
+ merge_vcard->private = g_new0 (glMergeVCardPrivate, 1);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_vcard_finalize (GObject *object)
+{
+ glMergeVCard *merge_vcard;
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ g_return_if_fail (object && GL_IS_MERGE_VCARD (object));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ merge_vcard = GL_MERGE_VCARD (object);
+ g_free (merge_vcard->private);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Set argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (object);
+
+ switch (param_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (object);
+
+ switch (param_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+
+}
+
+/* TODO */
+/*--------------------------------------------------------------------------*/
+/* Get key list. */
+/*--------------------------------------------------------------------------*/
+static GList *
+gl_merge_vcard_get_key_list (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ GList *key_list;
+
+ gl_debug (DEBUG_MERGE, "BEGIN");
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ /* extremely simple approach until I can list the available keys from the
+ * server, and return them. */
+ key_list = NULL;
+ key_list = g_list_append (key_list, g_strdup ("full_name"));
+ key_list = g_list_append (key_list, g_strdup ("home_address"));
+ key_list = g_list_append (key_list, g_strdup ("work_address"));
+
+ gl_debug (DEBUG_MERGE, "END");
+
+ return key_list;
+}
+
+/* TODO? */
+/*--------------------------------------------------------------------------*/
+/* Get "primary" key. */
+/*--------------------------------------------------------------------------*/
+static gchar *
+gl_merge_vcard_get_primary_key (glMerge *merge)
+{
+ /* For now, let's always assume the full name is the primary key. */
+ return g_strdup ("full_name");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Open merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_open (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ gchar *src;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ src = gl_merge_get_src (merge);
+
+ if (src != NULL) {
+ merge_vcard->private->fp = fopen (src, "r");
+ }
+
+ g_free (src);
+
+ return;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Close merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_close (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ if (merge_vcard->private->fp != NULL) {
+ fclose (merge_vcard->private->fp);
+ merge_vcard->private->fp = NULL;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get next record from merge source, NULL if no records left (i.e EOF) */
+/*--------------------------------------------------------------------------*/
+static glMergeRecord *
+gl_merge_vcard_get_record (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ glMergeRecord *record;
+ glMergeField *field;
+
+ char *vcard;
+ EContact *contact;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ vcard = parse_next_vcard(merge_vcard->private->fp);
+ if (vcard[0] == '\0') {
+ return NULL; /* EOF */
+ }
+ contact = e_contact_new_from_vcard(vcard);
+ if (contact == NULL) {
+ return NULL; /* invalid vcard */
+ }
+
+ record = g_new0 (glMergeRecord, 1);
+ record->select_flag = TRUE;
+
+ /* Take the interesting fields one by one from the contact, and put them
+ * into the glMergeRecord structure. When done, free up the resources for
+ * that contact */
+
+ /* get the full name */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("full_name");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_FULL_NAME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the home address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("home_address");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_ADDRESS_LABEL_HOME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the work address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("work_address");
+ field->value = g_strdup (e_contact_get(contact, E_CONTACT_ADDRESS_LABEL_WORK));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* free the contact */
+ g_object_unref (contact);
+ g_free(vcard);
+
+ return record;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Copy merge_vcard specific fields. */
+/*---------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_copy (glMerge *dst_merge,
+ glMerge *src_merge)
+{
+ glMergeVCard *dst_merge_vcard;
+ glMergeVCard *src_merge_vcard;
+
+ dst_merge_vcard = GL_MERGE_VCARD (dst_merge);
+ src_merge_vcard = GL_MERGE_VCARD (src_merge);
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE: pull out a full VCard from the open file */
+/* Arguments: */
+/* fp - an open stream to parse in put from */
+/* Returns: */
+/* a pointer to the buffer containing the vcard, the empty string on */
+/* end-of-file or error, this buffer needs to be free by the caller */
+/*---------------------------------------------------------------------------*/
+static char *
+parse_next_vcard (FILE *fp)
+{
+ gboolean found_begin = FALSE, found_end = FALSE;
+ char *vcard;
+ char line[512];
+ int size = 2048, cursize = 0;
+
+ vcard = g_malloc0(size);
+
+ while (fgets(line, sizeof(line), fp) && found_end == FALSE) {
+ if (found_begin == TRUE) {
+ if (g_str_has_prefix(line, "END:VCARD")) { found_end = TRUE; }
+ } else {
+ if (g_str_has_prefix(line, "BEGIN:VCARD")) { found_begin = TRUE; }
+ else { continue; }/* skip lines not in a vcard */
+ }
+
+ /* if the buffer passed us isn't big enough, reallocate it */
+ cursize += strlen(line);
+ if (cursize >= size) {
+ size *= 2;
+ vcard = (char *)g_realloc(vcard, size); /* aborts program on error */
+ }
+
+ /* add the line (or portion thereof) to the vcard */
+ strncat(vcard, line, size);
+ }
+
+ return vcard;
+}
+
+
+
+#endif /* HAVE_LIBEBOOK */
--- /dev/null
+/*
+ * (GLABELS) Label and Business Card Creation program for GNOME
+ *
+ * merge_vcard.h: vcard merge backend module header file
+ *
+ * Copyright (C) 2002 Jim Evins <evins@snaught.com>.
+ * and
+ * Copyright (C) 2005 Austin Henry <ahenry@users.sourceforge.net>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __MERGE_VCARD_H__
+#define __MERGE_VCARD_H__
+
+#include "merge.h"
+
+G_BEGIN_DECLS
+
+/* The following object arguments are available:
+ *
+ * name type description
+ * --------------------------------------------------------------------------------
+ *
+ */
+
+#define GL_TYPE_MERGE_VCARD (gl_merge_vcard_get_type ())
+#define GL_MERGE_VCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_MERGE_VCARD, glMergeVCard))
+#define GL_MERGE_VCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GL_TYPE_MERGE_VCARD, glMergeVCardClass))
+#define GL_IS_MERGE_VCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GL_TYPE_MERGE_VCARD))
+#define GL_IS_MERGE_VCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GL_TYPE_MERGE_VCARD))
+#define GL_MERGE_VCARD_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GL_TYPE_MERGE_VCARD, glMergeVCardClass))
+
+
+typedef struct _glMergeVCard glMergeVCard;
+typedef struct _glMergeVCardClass glMergeVCardClass;
+
+typedef struct _glMergeVCardPrivate glMergeVCardPrivate;
+
+
+struct _glMergeVCard {
+ glMerge object;
+
+ glMergeVCardPrivate *private;
+};
+
+struct _glMergeVCardClass {
+ glMergeClass parent_class;
+};
+
+
+GType gl_merge_vcard_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+
+#endif /* __MERGE_VCARD_H__ */
GdkPixbuf *pixbuf = NULL;
const gchar *authors[] = {
- "Jim Evins <evins@snaught.com>",
+ "Jim Evins",
" ",
_("Glabels includes contributions from:"),
- "Frederic Ruaudel <grumz@users.sf.net>",
- "Wayne Schuller <k_wayne@linuxpower.org>",
- "Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>",
+ "Frederic Ruaudel",
+ "Wayne Schuller",
+ "Emmanuel Pacaud",
+ "Austin Henry",
" ",
_("See the file AUTHORS for additional credits,"),
_("or visit http://glabels.sourceforge.net/"),
};
const gchar *artists[] = {
- "Nestor Di <nestordi@usuarios.retecal.es>",
- "Jim Evins <evins@snaught.com>",
+ "Nestor Di",
+ "Jim Evins",
NULL
};