[Planner Dev] More steps in e-d-s resource importer



Hi guys!

This morning I have been testing the e-d-s resource importer for Planner
taking the data from a LDAP server, and it works!

I need to code async queries because LDAP queries spend more time and
the UI is freeze if the query is sync. I will use async queries for all
our communications with the e-d-s.

Here goes a little screenshot and the code for the plugin, that it will
need to be upgraded to GtkUIManager.

Cheers

-- Alvaro


Attachment: planner-ldap.jpg
Description: JPEG image

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Copyright (C) 2004 Alvaro del Castillo <acs barrapunto com>
 *
 * 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>
#include <glib.h> 
#include <string.h>
#include <bonobo/bonobo-ui-component.h>
#include <bonobo/bonobo-ui-util.h>
#include <glade/glade.h>
#include <gtk/gtklist.h>
#include <gtk/gtkcombobox.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtktreemodel.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcellrenderertoggle.h>
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkcelllayout.h>
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-file-entry.h>
#include <gconf/gconf-client.h>
#include "planner-window.h"
#include "planner-plugin.h"

/* Evolution Data Server sources */
#include <libedataserver/e-source-list.h>
#include <libedataserver/e-source-group.h>
/* Calendar */
#include <libecal/e-cal.h>
/* Addressbook */
#include <libebook/e-book.h>

struct _PlannerPluginPriv {
	PlannerWindow *main_window;
	MrpProject    *project;
	/* Manage groups of source from e-d-s */
	ESourceList   *source_list;
	GtkComboBox   *select_group;
	GSList        *groups;
	GtkTreeModel  *groups_model;
	/* Manage resource from a group */
	GtkTreeView   *resources_tree_view;
	GtkTreeModel  *resources_model;
	/* Main widgets */
	GladeXML      *glade;
	GtkWidget     *dialog_get_resources;
	GtkWidget     *dialog_load_resources;
};

enum {
	COL_RESOURCE_NAME,
	COL_RESOURCE_EMAIL,
	COL_RESOURCE_SELECTED,
	COL_RESOURCE_PHOTO,
	COL_RESOURCE_OBJECT,
	NUM_RESOURCE_COLS
};

enum {
	COL_GROUP_NAME,
	COL_GROUP_OBJECT,
	NUM_GROUP_COLS
};

static void eds_plugin_import         (BonoboUIComponent     *component,
				       gpointer               user_data,
				       const gchar           *cname);
static void eds_create_groups_model   (GSList                *groups,
				       PlannerPlugin         *plugin);
static void eds_ok_button_clicked     (GtkButton             *button,
				       PlannerPlugin         *plugin);
static void eds_cancel_button_clicked (GtkButton             *button,
				       PlannerPlugin         *plugin);
static void eds_group_selected        (GtkComboBox           *select_group, 
				       PlannerPlugin         *plugin);
static void eds_resource_selected     (GtkCellRendererToggle *toggle, 
				       const gchar           *path_str,
				       PlannerPlugin         *plugin);
static void eds_import_resource       (gchar                 *name,
				       gchar                 *email,
				       PlannerPlugin         *plugin);

void        plugin_init               (PlannerPlugin         *plugin,
				       PlannerWindow         *main_window);
void        plugin_exit               (PlannerPlugin         *plugin);


static BonoboUIVerb verbs[] = {
	BONOBO_UI_VERB ("EDS Import", eds_plugin_import),
	BONOBO_UI_VERB_END
};

static void
eds_plugin_import (BonoboUIComponent *component,
		   gpointer           user_data,
		   const gchar       *cname)
{
	PlannerPlugin     *plugin;
	PlannerPluginPriv *priv;
	GtkWidget         *ok_button;
	GtkWidget         *cancel_button;
	GtkCellRenderer   *renderer;
	GConfClient       *gconf_client;
	ESourceList       *source_list;
	GSList            *groups;

	plugin = PLANNER_PLUGIN (user_data);
	priv = plugin->priv;

	priv->glade = glade_xml_new (GLADEDIR"/evolution-data-server.glade",
				     NULL, NULL);

	priv->dialog_get_resources = glade_xml_get_widget (priv->glade, "resources_get");

	gtk_window_set_transient_for (GTK_WINDOW (priv->dialog_get_resources),
				      GTK_WINDOW (priv->main_window));
	priv->select_group = (GtkComboBox *) glade_xml_get_widget (priv->glade,
								   "select_group");
	g_signal_connect (priv->select_group, "changed",
			  G_CALLBACK (eds_group_selected),
			  user_data);

	priv->resources_tree_view = (GtkTreeView *) glade_xml_get_widget (priv->glade,
									  "resources");
	
	ok_button = glade_xml_get_widget (priv->glade, "ok_button");
	cancel_button = glade_xml_get_widget (priv->glade, "cancel_button");
	
	g_signal_connect (ok_button, "clicked",
			  G_CALLBACK (eds_ok_button_clicked),
			  user_data);
	
	g_signal_connect (cancel_button, "clicked",
			  G_CALLBACK (eds_cancel_button_clicked),
			  user_data);
	
	gtk_widget_show (priv->dialog_get_resources);

	
	gconf_client = gconf_client_get_default ();
	source_list = e_source_list_new_for_gconf (gconf_client,
						   "/apps/evolution/addressbook/sources");
	/* List with addressbook groups */
	groups = e_source_list_peek_groups (source_list);
	eds_create_groups_model (groups, plugin);
	gtk_combo_box_set_model (priv->select_group, priv->groups_model);
	renderer = gtk_cell_renderer_text_new ();
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->select_group), 
				    renderer, TRUE);
	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->select_group), 
					renderer, "text", 0, NULL);
	g_slist_free (groups);
}

static void
eds_create_groups_model (GSList        *groups,
			 PlannerPlugin *plugin)
{
	GtkListStore *model;
	GtkTreeIter   iter;
	GSList       *sl;
	const gchar  *name;
	
	if (groups == NULL) {
		return;
	}

	model = gtk_list_store_new (NUM_GROUP_COLS, G_TYPE_STRING, G_TYPE_OBJECT);

	for (sl = groups; sl; sl = sl->next) {
		name = e_source_group_peek_name (sl->data);
		gtk_list_store_append (model, &iter);
		gtk_list_store_set (model, &iter, 
				    COL_GROUP_NAME, name, 
				    COL_GROUP_OBJECT, sl->data, -1);
	}
	plugin->priv->groups_model = (GtkTreeModel *) model;
}

/* For now we show all the sources from a group in a List.
   Later we will us a Tree to show them usings groups. */
static void 
eds_load_resources (ESourceGroup  *group, 
		    PlannerPlugin *plugin)
{
	GtkListStore      *model;
	GtkTreeIter        iter;
	GSList            *sources, *sl;
	PlannerPluginPriv *priv;

	g_return_if_fail (E_IS_SOURCE_GROUP (group));
	sources = e_source_group_peek_sources (group);
	if (sources == NULL) {
		return;
	}

	priv = plugin->priv;

	model = (GtkListStore *) priv->resources_model;
	/* We will show the only te resource name for now */
	if (model) {
		gtk_list_store_clear (model);
	} else {
		GtkCellRenderer *toggle;

		model = gtk_list_store_new (NUM_RESOURCE_COLS, 
					    G_TYPE_STRING,   /* name */
					    G_TYPE_STRING,   /* email */
					    G_TYPE_BOOLEAN,  /* import */
					    GDK_TYPE_PIXBUF, /* photo */
					    G_TYPE_OBJECT);  /* full contact */	
		priv->resources_model = (GtkTreeModel *) model;
		gtk_tree_view_set_model (priv->resources_tree_view,
					 priv->resources_model);

		gtk_tree_view_insert_column_with_attributes 
			(priv->resources_tree_view,
			 -1, _("Name"),
			 gtk_cell_renderer_text_new (), "text", COL_RESOURCE_NAME,
			 NULL);

		gtk_tree_view_insert_column_with_attributes 
			(priv->resources_tree_view,
			 -1, _("Email"),
			 gtk_cell_renderer_text_new (), "text", COL_RESOURCE_EMAIL,
			 NULL);

		toggle = gtk_cell_renderer_toggle_new ();		
		gtk_tree_view_insert_column_with_attributes 
			(priv->resources_tree_view,
			 -1, _("Import"),
			 toggle, "active", COL_RESOURCE_SELECTED,
			 NULL);
		g_signal_connect (toggle, "toggled",
				  G_CALLBACK (eds_resource_selected),
				  plugin);

		gtk_tree_view_insert_column_with_attributes 
			(priv->resources_tree_view,
			 -1, _("Photo"),
			 gtk_cell_renderer_pixbuf_new (), "pixbuf", COL_RESOURCE_PHOTO,
			 NULL);
	}

	for (sl = sources; sl; sl = sl->next) {
		EBook      *client;
		EBookQuery *query;
		GError     *error = NULL;
		GList      *l, *contacts;
		GdkPixbuf  *pixbuf;
		
		pixbuf = gdk_pixbuf_new_from_file (IMAGEDIR"/resources.png", NULL);
		client = e_book_new (sl->data, NULL);
		if (!e_book_open (client, TRUE, NULL)) {
			continue;
		}
		/* query = e_book_query_field_exists (E_CONTACT_FULL_NAME); */
		/* query = e_book_query_any_field_contains ("John"); */
		
		/* query = e_book_query_from_string ("#t"); */
		query = e_book_query_any_field_contains ("");
		e_book_get_contacts (client, query, &contacts, &error);
		e_book_query_unref (query);
		for (l = contacts; l; l = l->next) {
			gchar *name, *email;
			name = e_contact_get (l->data, E_CONTACT_GIVEN_NAME);
			email = e_contact_get (l->data, E_CONTACT_EMAIL_1);
			gtk_list_store_append (model, &iter);
			gtk_list_store_set (model, &iter, 
					    COL_RESOURCE_NAME, name,
					    COL_RESOURCE_EMAIL, email,
					    COL_RESOURCE_SELECTED, FALSE,
					    COL_RESOURCE_PHOTO, pixbuf,
					    COL_RESOURCE_OBJECT, l->data, -1);
		}
	}
}


static void
eds_import_resource (gchar         *name,
		     gchar         *email,
		     PlannerPlugin *plugin) 
{
	MrpResource *resource = mrp_resource_new ();	

	mrp_project_add_resource  (plugin->priv->project, resource);	
	mrp_object_set (resource, "name", name, NULL);
	mrp_object_set (resource, "email", email, NULL);
}

static void
eds_group_selected (GtkComboBox   *select_group, 
		    PlannerPlugin *plugin)
{
	GtkTreeIter        iter;
	PlannerPluginPriv *priv = plugin->priv;
	ESourceGroup      *group;

	if (gtk_combo_box_get_active_iter (select_group, &iter)) {
		gtk_tree_model_get (priv->groups_model, &iter, COL_GROUP_OBJECT, &group, -1);
		eds_load_resources (group, plugin);
	}
}

static void
eds_resource_selected (GtkCellRendererToggle *toggle, 
		       const gchar           *path_str,
		       PlannerPlugin         *plugin)
{
	GtkTreePath  *path;
	GtkTreeModel *model;
	GtkTreeIter   iter;
	gboolean      selected;
	EContact     *contact;

	path = gtk_tree_path_new_from_string (path_str);

	model = plugin->priv->resources_model;
	
	gtk_tree_model_get_iter (model, &iter, path);

	gtk_tree_model_get (model,
			    &iter,
			    COL_RESOURCE_SELECTED, &selected,
			    COL_RESOURCE_OBJECT, &contact,
			    -1);

	gtk_list_store_set ((GtkListStore *) model,
			    &iter,
			    COL_RESOURCE_SELECTED, !selected,
			    -1);

	gtk_tree_path_free (path);
}

static void 
eds_ok_button_clicked (GtkButton     *button, 
		       PlannerPlugin *plugin)
{
	GtkTreeIter        iter;
	PlannerPluginPriv *priv = plugin->priv;

	gtk_tree_model_get_iter_first (priv->resources_model, &iter);

	do {
		EContact *contact;
		gboolean  selected;

		gtk_tree_model_get (priv->resources_model, &iter, 
				    COL_RESOURCE_SELECTED, &selected,
				    COL_RESOURCE_OBJECT, &contact,
				    -1);

		if (selected) {
			gchar *name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
			gchar *email = e_contact_get (contact, E_CONTACT_EMAIL_1);
			eds_import_resource (name, email, plugin);
		} 
	} while (gtk_tree_model_iter_next (priv->resources_model, &iter));
}

static void
eds_cancel_button_clicked (GtkButton *button, 
			   PlannerPlugin *plugin)
{
	PlannerPluginPriv *priv = plugin->priv;
	
	gtk_widget_destroy (priv->dialog_get_resources);
}

/* FIXME: Undo support */
G_MODULE_EXPORT void 
plugin_init (PlannerPlugin *plugin, 
	     PlannerWindow *main_window)
{
	PlannerPluginPriv *priv;
	BonoboUIContainer *ui_container;
	BonoboUIComponent *ui_component;
	
	priv = g_new0 (PlannerPluginPriv, 1);
	plugin->priv = priv;
	priv->main_window = main_window;
	priv->project = planner_window_get_project (plugin->main_window);
	
	ui_container = planner_window_get_ui_container (main_window);
	ui_component = bonobo_ui_component_new_default ();
	
	bonobo_ui_component_set_container (ui_component, 
					   BONOBO_OBJREF (ui_container),
					   NULL);
	bonobo_ui_component_freeze (ui_component, NULL);
	bonobo_ui_component_add_verb_list_with_data (ui_component, 
						     verbs,
						     plugin);
	bonobo_ui_util_set_ui (ui_component,
			       DATADIR,
			       "/planner/ui/eds-plugin.ui",
			       "edsplugin",
			       NULL);
	
	bonobo_ui_component_thaw (ui_component, NULL);
}

G_MODULE_EXPORT void 
plugin_exit (PlannerPlugin *plugin) 
{
	/*g_message ("Test exit");*/
}

Attachment: signature.asc
Description: Esta parte del mensaje =?ISO-8859-1?Q?est=E1?= firmada digitalmente



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