aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/google-account-setup
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-08-08 12:26:12 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-08-08 12:26:12 +0800
commitcea054cd54d84479352a43bbabc19c9ce9af5efb (patch)
treeba02763209ba0f22989024004f57689071603ec5 /plugins/google-account-setup
parent91a6b6899e5568ed34f913bedb538dd6c9e35b32 (diff)
downloadgsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar.gz
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar.bz2
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar.lz
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar.xz
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.tar.zst
gsoc2013-evolution-cea054cd54d84479352a43bbabc19c9ce9af5efb.zip
Merge revisions 35747:35930 from trunk.
svn path=/branches/kill-bonobo/; revision=35931
Diffstat (limited to 'plugins/google-account-setup')
-rw-r--r--plugins/google-account-setup/ChangeLog38
-rw-r--r--plugins/google-account-setup/Makefile.am5
-rw-r--r--plugins/google-account-setup/google-contacts-source.c269
-rw-r--r--plugins/google-account-setup/google-contacts-source.h30
-rw-r--r--plugins/google-account-setup/google-source.c394
-rw-r--r--plugins/google-account-setup/org-gnome-evolution-google.eplug.xml14
6 files changed, 728 insertions, 22 deletions
diff --git a/plugins/google-account-setup/ChangeLog b/plugins/google-account-setup/ChangeLog
index a1019c05e7..037aa01a3c 100644
--- a/plugins/google-account-setup/ChangeLog
+++ b/plugins/google-account-setup/ChangeLog
@@ -1,3 +1,41 @@
+2008-08-07 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #535745
+
+ * google-source.c: (sanitize_user_mail), (construct_default_uri),
+ (is_default_uri), (init_combo_values), (user_changed),
+ (cal_combo_changed), (claim_error), (retrieve_list_clicked),
+ (plugin_google): New widgets and functionality to retrieve list
+ of subscribed calendars from the Google account and let user choose
+ which one would be shown.
+
+2008-08-01 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes bug #544860
+
+ * google-contacts-source.c (plugin_google_contacts):
+ Add translator comments for split "update every" sentence.
+
+2008-07-31 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes part of bug #545568
+
+ * org-gnome-evolution-google.eplug.xml:
+ Add "system_plugin=true" so it's not shown in the Plugin Manager.
+ This plugin is not designed to be disabled by the user.
+
+2008-05-24 Jörgen Scheibengruber <mfcn@gmx.de>
+
+ * Makefile.am:
+ * google-contacts-source.c (ensure_google_contacts_source_group),
+ (remove_google_contacts_source_group), (on_username_entry_changed),
+ (on_update_cb_toggled), (on_interval_sb_value_changed),
+ (plugin_google_contacts):
+ * google-contacts-source.h:
+ * google-source.c (e_plugin_lib_enable):
+ * org-gnome-evolution-google.eplug.xml:
+ Added a UI for the addressbook part
+
2008-03-31 Suman Manjunath <msuman@novell.com>
** Fix for bug #346555
diff --git a/plugins/google-account-setup/Makefile.am b/plugins/google-account-setup/Makefile.am
index 898083c65a..d1c385b172 100644
--- a/plugins/google-account-setup/Makefile.am
+++ b/plugins/google-account-setup/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = \
$(EVOLUTION_CALENDAR_CFLAGS) \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
-I . \
-I$(top_srcdir) \
-DCALDAV_GLADEDIR=\""$(gladedir)"\"
@@ -10,7 +11,9 @@ plugin_DATA = org-gnome-evolution-google.eplug
plugin_LTLIBRARIES = liborg-gnome-evolution-google.la
liborg_gnome_evolution_google_la_SOURCES = \
- google-source.c
+ google-source.c \
+ google-contacts-source.h \
+ google-contacts-source.c
liborg_gnome_evolution_google_la_LIBADD = \
$(EVOLUTION_CALENDAR_LIBS) \
diff --git a/plugins/google-account-setup/google-contacts-source.c b/plugins/google-account-setup/google-contacts-source.c
new file mode 100644
index 0000000000..d0c8e71e63
--- /dev/null
+++ b/plugins/google-account-setup/google-contacts-source.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2008, Joergen Scheibengruber <joergen.scheibengruber@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <glib/gi18n-lib.h>
+#include <glib.h>
+
+#include <gtk/gtk.h>
+
+#include <e-util/e-config.h>
+#include <e-util/e-plugin.h>
+#include <addressbook/gui/widgets/eab-config.h>
+
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-account-list.h>
+
+#include "google-contacts-source.h"
+
+
+void
+ensure_google_contacts_source_group (void)
+{
+ ESourceList *source_list;
+ ESourceGroup *group;
+
+ source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources");
+
+ if (source_list == NULL) {
+ return;
+ }
+
+ group = e_source_list_peek_group_by_name (source_list, _("Google"));
+
+ if (group == NULL) {
+ gboolean res;
+
+ group = e_source_group_new (_("Google"), "google://");
+ res = e_source_list_add_group (source_list, group, -1);
+
+ if (res == FALSE) {
+ g_warning ("Could not add Google source group!");
+ } else {
+ e_source_list_sync (source_list, NULL);
+ }
+
+ g_object_unref (group);
+ }
+ g_object_unref (source_list);
+}
+
+void
+remove_google_contacts_source_group (void)
+{
+ ESourceList *source_list;
+ ESourceGroup *group;
+
+ source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources");
+
+ if (source_list == NULL) {
+ return;
+ }
+
+ group = e_source_list_peek_group_by_name (source_list, _("Google"));
+
+ if (group) {
+ GSList *sources;
+
+ sources = e_source_group_peek_sources (group);
+
+ if (NULL == sources) {
+ e_source_list_remove_group (source_list, group);
+ e_source_list_sync (source_list, NULL);
+ }
+ }
+ g_object_unref (source_list);
+}
+
+static void
+on_username_entry_changed (GtkEntry *entry, gpointer user_data)
+{
+ ESource *source = user_data;
+ const char *text;
+ char *username;
+
+ text = gtk_entry_get_text (entry);
+
+ if (strstr (text, "@")) {
+ username = g_strdup (text);
+ } else {
+ username = g_strdup_printf ("%s@gmail.com", text);
+ }
+
+ e_source_set_relative_uri (source, username);
+ e_source_set_property (source, "username", username);
+ e_source_set_property (source, "auth", "plain/password");
+ g_free (username);
+}
+
+static void
+on_update_cb_toggled (GtkToggleButton *tb, gpointer user_data)
+{
+ ESource *source = user_data;
+ GtkWidget *sb = g_object_get_data (G_OBJECT (tb), "sb");
+
+ gtk_widget_set_sensitive (sb, gtk_toggle_button_get_active (tb));
+ if (gtk_toggle_button_get_active (tb)) {
+ gdouble value;
+ char *value_string;
+
+ value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (sb));
+ value_string = g_strdup_printf ("%d", (int)(value * 60.0));
+ e_source_set_property (source, "refresh-interval", value_string);
+ g_free (value_string);
+ } else {
+ e_source_set_property (source, "refresh-interval", "-1");
+ }
+}
+
+static void
+on_interval_sb_value_changed (GtkSpinButton *sb, gpointer user_data)
+{
+ ESource *source = user_data;
+ gdouble value;
+ char *value_string;
+
+ value = gtk_spin_button_get_value (sb);
+ value_string = g_strdup_printf ("%d", (int)(value * 60.0));
+ e_source_set_property (source, "refresh-interval", value_string);
+ g_free (value_string);
+}
+
+GtkWidget *
+plugin_google_contacts (EPlugin *epl,
+ EConfigHookItemFactoryData *data)
+{
+ EABConfigTargetSource *t = (EABConfigTargetSource *) data->target;
+ ESource *source;
+ ESourceGroup *group;
+ const char *base_uri;
+ const char *username;
+ const char *refresh_interval_str;
+ int refresh_interval;
+ GtkWidget *parent;
+ GtkWidget *vbox;
+
+ GtkWidget *section;
+ GtkWidget *vbox2;
+
+ GtkWidget *hbox;
+ GtkWidget *spacer;
+ GtkWidget *label;
+ GtkWidget *username_entry;
+
+ GtkWidget *update_cb;
+ GtkWidget *interval_sb;
+
+
+ source = t->source;
+ group = e_source_peek_group (source);
+
+ base_uri = e_source_group_peek_base_uri (group);
+
+ g_object_set_data_full (G_OBJECT (epl), "widget", NULL,
+ (GDestroyNotify)gtk_widget_destroy);
+
+ if (strcmp (base_uri, "google://")) {
+ return NULL;
+ }
+
+ /* Build up the UI */
+ parent = data->parent;
+ vbox = gtk_widget_get_ancestor (gtk_widget_get_parent (parent), GTK_TYPE_VBOX);
+
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+ section = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (section), _("<b>Server</b>"));
+ gtk_misc_set_alignment (GTK_MISC (section), 0.0, 0.0);
+ gtk_box_pack_start (GTK_BOX (vbox2), section, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 10);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
+
+ spacer = gtk_label_new (" ");
+ gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Username:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ username_entry = gtk_entry_new ();
+ username = e_source_get_property (source, "username");
+ if (username) {
+ gtk_entry_set_text (GTK_ENTRY (username_entry), username);
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), username_entry, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 10);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
+
+ spacer = gtk_label_new (" ");
+ gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
+
+ refresh_interval_str = e_source_get_property (source, "refresh-interval");
+ if (refresh_interval_str &&
+ (1 == sscanf (refresh_interval_str, "%d", &refresh_interval))) {
+ } else {
+ refresh_interval = -1;
+ }
+
+ /* Translators: This is the first half of the sentence "Update
+ * every NNN minute(s)", where NNN is a spin button widget. */
+ update_cb = gtk_check_button_new_with_label (_("Update every"));
+ gtk_box_pack_start (GTK_BOX (hbox), update_cb, FALSE, FALSE, 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (update_cb),
+ refresh_interval > 0);
+
+ interval_sb = gtk_spin_button_new_with_range (1, 60, 1);
+ gtk_widget_set_sensitive (interval_sb,
+ refresh_interval > 0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (interval_sb),
+ refresh_interval > 0 ? refresh_interval / 60 : 30);
+ gtk_box_pack_start (GTK_BOX (hbox), interval_sb, FALSE, FALSE, 0);
+
+ /* Translators: This is the second half of the sentence "Update
+ * every NNN minute(s)", where NNN is a spin button widget. */
+ label = gtk_label_new (_("minute(s)"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (vbox2);
+
+ g_object_set_data (G_OBJECT (update_cb), "sb", interval_sb);
+ g_object_set_data_full (G_OBJECT (epl), "widget", vbox2,
+ (GDestroyNotify)gtk_widget_destroy);
+
+ g_signal_connect (G_OBJECT (username_entry), "changed",
+ G_CALLBACK (on_username_entry_changed),
+ source);
+ g_signal_connect (G_OBJECT (update_cb), "toggled",
+ G_CALLBACK (on_update_cb_toggled),
+ source);
+ g_signal_connect (G_OBJECT (interval_sb), "value-changed",
+ G_CALLBACK (on_interval_sb_value_changed),
+ source);
+
+ return NULL;
+}
+
+
diff --git a/plugins/google-account-setup/google-contacts-source.h b/plugins/google-account-setup/google-contacts-source.h
new file mode 100644
index 0000000000..17421fb232
--- /dev/null
+++ b/plugins/google-account-setup/google-contacts-source.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008, Joergen Scheibengruber <joergen.scheibengruber@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __GOOGLE_CONTACTS_SOURCE_H__
+#define __GOOGLE_CONTACTS_SOURCE_H__
+
+GtkWidget *plugin_google_contacts (EPlugin *epl,
+ EConfigHookItemFactoryData *data);
+
+void ensure_google_contacts_source_group (void);
+
+void remove_google_contacts_source_group (void);
+
+#endif
diff --git a/plugins/google-account-setup/google-source.c b/plugins/google-account-setup/google-source.c
index d586b3027e..57727c6122 100644
--- a/plugins/google-account-setup/google-source.c
+++ b/plugins/google-account-setup/google-source.c
@@ -40,8 +40,18 @@
#include <libedataserver/e-url.h>
#include <libedataserver/e-account-list.h>
#include <libecal/e-cal.h>
+#include <libedataserverui/e-cell-renderer-color.h>
+#include <libedataserverui/e-passwords.h>
+
+#include <google/libgdata/gdata-service-iface.h>
+#include <google/libgdata/gdata-feed.h>
+#include <google/libgdata-google/gdata-google-service.h>
+
+#include "google-contacts-source.h"
#define CALENDAR_LOCATION "http://www.google.com/calendar/feeds/"
+#define CALENDAR_DEFAULT_PATH "/private/full"
+#define URL_GET_SUBSCRIBED_CALENDARS "http://www.google.com/calendar/feeds/default/allcalendars/full"
#define d(x)
@@ -56,6 +66,8 @@ GtkWidget * plugin_google (EPlugin *epl,
/*****************************************************************************/
/* plugin intialization */
+
+
static void
ensure_google_source_group ()
{
@@ -96,6 +108,9 @@ e_plugin_lib_enable (EPluginLib *ep, int enable)
if (enable) {
d(printf ("\n Google Eplugin starting up ...\n"));
ensure_google_source_group ();
+ ensure_google_contacts_source_group ();
+ } else {
+ remove_google_contacts_source_group ();
}
return 0;
@@ -169,6 +184,83 @@ is_email (const char *address)
return TRUE;
}
+static char *
+sanitize_user_mail (const char *user)
+{
+ if (!user)
+ return NULL;
+
+ if (!is_email (user)) {
+ return g_strconcat (user, "%40gmail.com", NULL);
+ } else {
+ char *tmp = g_malloc0 (sizeof (char) * (1 + strlen (user) + 2));
+ char *at = strchr (user, '@');
+
+ strncpy (tmp, user, at - user);
+ strcat (tmp, "%40");
+ strcat (tmp, at + 1);
+
+ return tmp;
+ }
+}
+
+static char *
+construct_default_uri (const char *username)
+{
+ char *user, *uri;
+
+ user = sanitize_user_mail (username);
+ uri = g_strconcat (CALENDAR_LOCATION, user, CALENDAR_DEFAULT_PATH, NULL);
+ g_free (user);
+
+ return uri;
+}
+
+/* checks whether the given_uri is pointing to the default user's calendar or not */
+static gboolean
+is_default_uri (const char *given_uri, const char *username)
+{
+ char *uri, *at;
+ int ats;
+ gboolean res;
+
+ if (!given_uri)
+ return TRUE;
+
+ uri = construct_default_uri (username);
+
+ /* count number of '@' in given_uri to know how much memory will be required */
+ ats = 0;
+ for (at = strchr (given_uri, '@'); at; at = strchr (at + 1, '@')) {
+ ats++;
+ }
+
+ if (!ats)
+ res = g_ascii_strcasecmp (given_uri, uri) == 0;
+ else {
+ const char *last;
+ char *tmp = g_malloc0 (sizeof (char) * (1 + strlen (given_uri) + (2 * ats)));
+
+ last = given_uri;
+ for (at = strchr (last, '@'); at; at = strchr (at + 1, '@')) {
+ strncat (tmp, last, at - last);
+ strcat (tmp, "%40");
+ last = at + 1;
+ }
+ strcat (tmp, last);
+
+ res = g_ascii_strcasecmp (tmp, uri) == 0;
+
+ g_free (tmp);
+ }
+
+ g_free (uri);
+
+ return res;
+}
+
+static void init_combo_values (GtkComboBox *combo, const char *deftitle, const char *defuri);
+
static void
user_changed (GtkEntry *editable, ESource *source)
{
@@ -176,10 +268,8 @@ user_changed (GtkEntry *editable, ESource *source)
char *uri;
char *ruri;
const char *user;
- char *projection;
uri = e_source_get_uri (source);
- user = gtk_entry_get_text (GTK_ENTRY (editable));
if (uri == NULL) {
g_free (uri);
@@ -188,24 +278,27 @@ user_changed (GtkEntry *editable, ESource *source)
euri = e_uri_new (uri);
g_free (euri->user);
+ euri->user = NULL;
- if (user != NULL) {
- euri->user = g_strdup (user);
- e_source_set_property (source, "auth", "1");
- } else {
- e_source_set_property (source, "auth", NULL);
- }
-
- projection = g_strdup ("/private/full");
+ /* two reasons why set readonly to FALSE:
+ a) the e_source_set_relative_uri does nothing for readonly sources
+ b) we are going to set default uri, which should be always writeable */
+ e_source_set_readonly (source, FALSE);
- if (!is_email (user)) {
- user = g_strconcat (user, "@gmail.com", NULL);
- }
+ user = gtk_entry_get_text (GTK_ENTRY (editable));
+ uri = construct_default_uri (user);
+ e_source_set_relative_uri (source, uri);
+ g_free (uri);
- e_source_set_relative_uri (source, g_strconcat (CALENDAR_LOCATION, g_strdup(user), g_strdup (projection), NULL));
- e_source_set_property (source, "username", euri->user);
+ e_source_set_property (source, "username", gtk_entry_get_text (GTK_ENTRY (editable)));
e_source_set_property (source, "protocol", "google");
e_source_set_property (source, "auth-domain", "google");
+ e_source_set_property (source, "auth", (user && *user) ? "1" : NULL);
+ e_source_set_property (source, "googlename", NULL);
+
+ /* we changed user, thus reset the chosen calendar combo too, because
+ other user means other calendars subscribed */
+ init_combo_values (GTK_COMBO_BOX (g_object_get_data (G_OBJECT (editable), "CalendarCombo")), _("Default"), NULL);
ruri = print_uri_noproto (euri);
g_free (ruri);
@@ -291,6 +384,229 @@ set_refresh_time (ESource *source, GtkWidget *spin, GtkWidget *option)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), time);
}
+enum {
+ COL_COLOR = 0, /* GDK_TYPE_COLOR */
+ COL_TITLE, /* G_TYPE_STRING */
+ COL_URL_PATH, /* G_TYPE_STRING */
+ COL_READ_ONLY, /* G_TYPE_BOOLEAN */
+ NUM_COLUMNS
+};
+
+static void
+init_combo_values (GtkComboBox *combo, const char *deftitle, const char *defuri)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+
+ if (!combo)
+ return;
+
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+
+ gtk_list_store_clear (store);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_COLOR, NULL,
+ COL_TITLE, deftitle,
+ COL_URL_PATH, defuri,
+ COL_READ_ONLY, FALSE,
+ -1);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+}
+
+static void
+cal_combo_changed (GtkComboBox *combo, ESource *source)
+{
+ GtkListStore *store;
+ GtkTreeIter iter;
+
+ g_return_if_fail (combo != NULL);
+ g_return_if_fail (source != NULL);
+
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+
+ if (gtk_combo_box_get_active_iter (combo, &iter)) {
+ char *uri = NULL, *title = NULL;
+ gboolean readonly = FALSE;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_TITLE, &title, COL_URL_PATH, &uri, COL_READ_ONLY, &readonly, -1);
+
+ if (!uri)
+ uri = construct_default_uri (e_source_get_property (source, "username"));
+
+ if (is_default_uri (uri, e_source_get_property (source, "username"))) {
+ /* do not store title when we use default uri */
+ g_free (title);
+ title = NULL;
+ }
+
+ /* first set readonly to FALSE, otherwise if TRUE, then e_source_set_readonly does nothing */
+ e_source_set_readonly (source, FALSE);
+ e_source_set_relative_uri (source, uri);
+ e_source_set_readonly (source, readonly);
+ e_source_set_property (source, "googlename", title);
+ e_source_set_property (source, "protocol", "google");
+ e_source_set_property (source, "auth-domain", "google");
+
+ g_free (title);
+ g_free (uri);
+ }
+}
+
+static void
+claim_error (GtkWindow *parent, const char *error)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ error);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+static void
+retrieve_list_clicked (GtkButton *button, GtkComboBox *combo)
+{
+ ESource *source;
+ GDataGoogleService *service;
+ GDataFeed *feed;
+ char *password, *tmp;
+ const char *username;
+ GError *error = NULL;
+ GtkWindow *parent;
+
+ g_return_if_fail (button != NULL);
+ g_return_if_fail (combo != NULL);
+
+ parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button)));
+
+ source = g_object_get_data (G_OBJECT (button), "ESource");
+ g_return_if_fail (source != NULL);
+
+ username = e_source_get_property (source, "username");
+ if (!username || !*username) {
+ claim_error (parent, _("Please enter user name first."));
+ return;
+ }
+
+ tmp = g_strdup_printf (_("Enter password for user %s to access list of subscribed calendars."), username);
+ password = e_passwords_ask_password (_("Enter password"), "Calendar", "", tmp,
+ E_PASSWORDS_REMEMBER_NEVER | E_PASSWORDS_REPROMPT | E_PASSWORDS_SECRET | E_PASSWORDS_DISABLE_REMEMBER,
+ NULL, parent);
+ g_free (tmp);
+
+ if (!password)
+ return;
+
+ service = gdata_google_service_new ("cl", "evolution-client-0.0.1");
+ gdata_service_set_credentials (GDATA_SERVICE (service), username, password);
+ /* privacy... maybe... */
+ memset (password, 0, strlen (password));
+ g_free (password);
+
+ feed = gdata_service_get_feed (GDATA_SERVICE (service), URL_GET_SUBSCRIBED_CALENDARS, &error);
+
+ if (feed) {
+ GSList *l;
+ char *old_selected = NULL;
+ int idx, active = -1, default_idx = -1;
+ GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_URL_PATH, &old_selected, -1);
+
+ gtk_list_store_clear (store);
+
+ for (l = gdata_feed_get_entries (feed), idx = 1; l != NULL; l = l->next) {
+ const char *uri, *title, *color, *access;
+ GSList *links;
+ GDataEntry *entry = (GDataEntry *) l->data;
+
+ if (!entry || !GDATA_IS_ENTRY (entry))
+ continue;
+
+ /* skip hidden entries */
+ if (gdata_entry_get_custom (entry, "hidden") && g_ascii_strcasecmp (gdata_entry_get_custom (entry, "hidden"), "true") == 0)
+ continue;
+
+ uri = NULL;
+ for (links = gdata_entry_get_links (entry); links && !uri; links = links->next) {
+ GDataEntryLink *link = (GDataEntryLink *)links->data;
+
+ if (!link || !link->href || !link->rel)
+ continue;
+
+ if (g_ascii_strcasecmp (link->rel, "alternate") == 0)
+ uri = link->href;
+ }
+
+ title = gdata_entry_get_title (entry);
+ color = gdata_entry_get_custom (entry, "color");
+ access = gdata_entry_get_custom (entry, "accesslevel");
+
+ if (uri && title) {
+ GdkColor gdkcolor;
+
+ if (old_selected && g_str_equal (old_selected, uri))
+ active = idx;
+
+ if (color)
+ gdk_color_parse (color, &gdkcolor);
+
+ if (default_idx == -1 && is_default_uri (uri, username)) {
+ /* have the default uri always NULL and first in the combo */
+ uri = NULL;
+ gtk_list_store_insert (store, &iter, 0);
+ default_idx = idx;
+ } else {
+ gtk_list_store_append (store, &iter);
+ }
+
+ gtk_list_store_set (store, &iter,
+ COL_COLOR, color ? &gdkcolor : NULL,
+ COL_TITLE, title,
+ COL_URL_PATH, uri,
+ COL_READ_ONLY, access && !g_str_equal (access, "owner") && !g_str_equal (access, "contributor"),
+ -1);
+ idx++;
+ }
+ }
+
+ if (default_idx == -1) {
+ /* Hey, why we didn't find the default uri? Did something go so wrong or what? */
+ gtk_list_store_insert (store, &iter, 0);
+ gtk_list_store_set (store, &iter,
+ COL_COLOR, NULL,
+ COL_TITLE, _("Default"),
+ COL_URL_PATH, NULL,
+ COL_READ_ONLY, FALSE,
+ -1);
+ }
+
+ gtk_combo_box_set_active (combo, active == -1 ? 0 : active);
+
+ g_free (old_selected);
+ g_object_unref (feed);
+ } else {
+ tmp = g_strdup_printf (_("Cannot read data from Google server.\n%s"), (error && error->message) ? error->message : _("Unknown error."));
+ claim_error (parent, tmp);
+ g_free (tmp);
+
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+ }
+
+ g_object_unref (service);
+}
+
GtkWidget *
plugin_google (EPlugin *epl,
EConfigHookItemFactoryData *data)
@@ -305,11 +621,14 @@ plugin_google (EPlugin *epl,
GtkWidget *luser;
GtkWidget *user;
GtkWidget *label;
+ GtkWidget *combo;
char *uri;
char *username;
const char *ssl_prop;
gboolean ssl_enabled;
int row;
+ GtkCellRenderer *renderer;
+ GtkListStore *store;
GtkWidget *option, *spin, *menu, *hbox;
GtkWidget *times [4];
@@ -425,7 +744,48 @@ plugin_google (EPlugin *epl,
g_free (uri);
g_free (username);
- return widget;
-}
+ label = gtk_label_new_with_mnemonic (_("Cal_endar:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_table_attach (GTK_TABLE (parent), label, 0, 1, row + 4, row + 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+
+ store = gtk_list_store_new (
+ NUM_COLUMNS,
+ GDK_TYPE_COLOR, /* COL_COLOR */
+ G_TYPE_STRING, /* COL_TITLE */
+ G_TYPE_STRING, /* COL_URL_PATH */
+ G_TYPE_BOOLEAN); /* COL_READ_ONLY */
+
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+
+ renderer = e_cell_renderer_color_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "color", COL_COLOR, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", COL_TITLE, NULL);
+
+ init_combo_values (GTK_COMBO_BOX (combo),
+ e_source_get_property (source, "googlename") ? e_source_get_property (source, "googlename") : _("Default"),
+ e_source_get_property (source, "googlename") ? e_source_peek_relative_uri (source) : NULL);
+ g_signal_connect (combo, "changed", G_CALLBACK (cal_combo_changed), source);
+ g_object_set_data (G_OBJECT (user), "CalendarCombo", combo);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+
+ gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
+ label = gtk_button_new_with_mnemonic (_("Retrieve _list"));
+ g_signal_connect (label, "clicked", G_CALLBACK (retrieve_list_clicked), combo);
+ g_object_set_data (G_OBJECT (label), "ESource", source);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (hbox);
+ gtk_table_attach (GTK_TABLE (parent), hbox, 1, 2, row + 4, row + 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+
+ return widget;
+}
diff --git a/plugins/google-account-setup/org-gnome-evolution-google.eplug.xml b/plugins/google-account-setup/org-gnome-evolution-google.eplug.xml
index d6087ad748..93a8aeee2d 100644
--- a/plugins/google-account-setup/org-gnome-evolution-google.eplug.xml
+++ b/plugins/google-account-setup/org-gnome-evolution-google.eplug.xml
@@ -1,13 +1,19 @@
<?xml version="1.0"?>
<e-plugin-list>
<e-plugin id="org.gnome.evolution.google" type="shlib" _name="Google sources"
- location="@PLUGINDIR@/liborg-gnome-evolution-google@SOEXT@" load-on-startup="false" localedir = "@LOCALEDIR@">
+ location="@PLUGINDIR@/liborg-gnome-evolution-google@SOEXT@" load-on-startup="false" localedir = "@LOCALEDIR@" system_plugin="true">
<author name="Ebby Wiselyn" email="ebbywiselyn@gmail.com"/>
- <_description>A plugin to setup google calendar.</_description>
-
+ <author name="Joergen Scheibengruber" email="joergen.scheibengruber@googlemail.com"/>
+ <_description>A plugin to setup google calendar and contacts.</_description>
+
<hook class="org.gnome.evolution.calendar.config:1.0">
<group target="source" id="org.gnome.evolution.calendar.calendarProperties">
- <item type="item_table" path="00.general/00.source/15.google" factory="plugin_google"/>
+ <item type="item_table" path="00.general/00.source/15.google" factory="plugin_google"/>
+ </group>
+ </hook>
+ <hook class="org.gnome.evolution.addressbook.config:1.0">
+ <group target="source" id="com.novell.evolution.addressbook.config.accountEditor">
+ <item type="item" path="00.general/10.display/00.google" factory="plugin_google_contacts"/>
</group>
</hook>
</e-plugin>