]> git.sur5r.net Git - glabels/commitdiff
2005-10-24 Jim Evins <evins@snaught.com>
authorJim Evins <evins@snaught.com>
Tue, 25 Oct 2005 03:01:56 +0000 (03:01 +0000)
committerJim Evins <evins@snaught.com>
Tue, 25 Oct 2005 03:01:56 +0000 (03:01 +0000)
* 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.

git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@557 f5e0f49d-192f-0410-a22d-a8d8700d0965

glabels2/AUTHORS
glabels2/ChangeLog
glabels2/configure.in
glabels2/src/Makefile.am
glabels2/src/merge-evolution.c [new file with mode: 0644]
glabels2/src/merge-evolution.h [new file with mode: 0644]
glabels2/src/merge-init.c
glabels2/src/merge-properties-dialog.c
glabels2/src/merge-vcard.c [new file with mode: 0644]
glabels2/src/merge-vcard.h [new file with mode: 0644]
glabels2/src/ui-commands.c

index b3a63e1dddd2e2ebaf952334e938607eb26ac523..21a47bb063cfc1ee78643517a0c24d1cf7c32a12 100644 (file)
@@ -43,6 +43,7 @@ Glabels includes contributions from:
        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:
index bd2eaa6e74e5c96a48e63fb0958a19c72b848a8f..ce58c1630671df98774e81844c783dcf9d134c37 100644 (file)
@@ -1,3 +1,20 @@
+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:
index fa0542e1028e21cbe4e4e857c26732522d59463b..851b7bc86e67639cbaacb9fd388a373921558fb1 100644 (file)
@@ -59,6 +59,7 @@ LIBGNOMEPRINT_REQUIRED=2.10.0
 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)
@@ -70,6 +71,25 @@ AC_SUBST(LIBGNOMEPRINT_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 ---------------------------------------------------------------------------
@@ -85,6 +105,7 @@ libgnomeprint-2.2 >= $LIBGNOMEPRINT_REQUIRED \
 libgnomeprintui-2.2 >= $LIBGNOMEPRINTUI_REQUIRED \
 libgnomecanvas-2.0 >= $LIBGNOMECANVAS_REQUIRED \
 libglade-2.0 >= $LIBGLADE_REQUIRED \
+$OPTIONAL_MODULES \
 )
 
 AC_SUBST(GLABELS_CFLAGS)
@@ -190,10 +211,11 @@ dnl ---------------------------------------------------------------------------
 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}
 
 "
 
index fb9d6e9da6baee824bed07d83655ab7601af7aba..fb4cf2f18f33bd0ea52dcd841678bf1e73466cc3 100644 (file)
@@ -144,6 +144,10 @@ glabels_SOURCES =                  \
        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             \
@@ -210,6 +214,10 @@ glabels_batch_SOURCES =            \
        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                         \
diff --git a/glabels2/src/merge-evolution.c b/glabels2/src/merge-evolution.c
new file mode 100644 (file)
index 0000000..77d73de
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ *  (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 */
diff --git a/glabels2/src/merge-evolution.h b/glabels2/src/merge-evolution.h
new file mode 100644 (file)
index 0000000..32c8a9c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  (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__ */
index cb6f2632573ffb4c7efc4b4cae0dde5ea88eaeda..d44d3c074a2084f0197561a2e0063918b37d59b8 100644 (file)
 
 #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"
 
@@ -69,4 +73,20 @@ gl_merge_init (void)
                                   "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 */
+
 }
index 10efabd426cdc7ed3f9239b5acd7c9a6083c5d8f..7f4c34fecfdccf609af9a8ac16c675bd3ddc7ffe 100644 (file)
@@ -445,6 +445,13 @@ type_changed_cb (GtkWidget               *widget,
                                  "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);
diff --git a/glabels2/src/merge-vcard.c b/glabels2/src/merge-vcard.c
new file mode 100644 (file)
index 0000000..65834dd
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ *  (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 */
diff --git a/glabels2/src/merge-vcard.h b/glabels2/src/merge-vcard.h
new file mode 100644 (file)
index 0000000..b6712e3
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  (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__ */
index 6a9802ed6771300fd1e6203d0d7f03ec0c7e5dd1..ac93d95c5dec04b73c377515c6948e4b4c38a4d5 100644 (file)
@@ -1090,12 +1090,13 @@ gl_ui_cmd_help_about (GtkAction *action,
        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/"),
@@ -1103,8 +1104,8 @@ gl_ui_cmd_help_about (GtkAction *action,
        };
        
        const gchar *artists[] = {
-               "Nestor Di <nestordi@usuarios.retecal.es>",
-               "Jim Evins <evins@snaught.com>",
+               "Nestor Di",
+               "Jim Evins",
                NULL
        };