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