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