forgot the attachment this time... -- Stéphane Konstantaropoulos - Research Student, Computer Science -- University of York, http://www-users.cs.york.ac.uk/~stephane
--- Begin Message ---
- From: Stéphane Konstantaropoulos <stephane cs york ac uk>
- To: evolution-patches lists ximian com
- Subject: ical publishing patch
- Date: Tue, 29 Mar 2005 22:15:19 +0100
Hello All, There is a (preview) patch that allows to publish the evolution calendars and task lists into an ical file, remotely (http, https, ftp, ssh) or locally to a file. This aims at solving the related bounty. Could you perhaps give it a quick go at testing, I have not tested the FTP or HTTPS for example. Notice, that this patch breaks the free/busy publishing code, as I was modifying it to give it gnome-vfs functionnality too. soup is still used for http/https as http/put does not seem to work with gnome-vfs. You can try www.icalx.com for publishing your calendars. This is incomplete as it lacks testing and I need to implement the alarms publishing or not. Hope you like it, -- Stéphane Konstantaropoulos - Research Student, Computer Science -- University of York, http://www-users.cs.york.ac.uk/~stephaneAttachment: signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=
--- End Message ---
Index: calendar/gui/apps_evolution_calendar.schemas.in.in =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/apps_evolution_calendar.schemas.in.in,v retrieving revision 1.7 diff -u -u -r1.7 apps_evolution_calendar.schemas.in.in --- calendar/gui/apps_evolution_calendar.schemas.in.in 8 Feb 2005 00:35:55 -0000 1.7 +++ calendar/gui/apps_evolution_calendar.schemas.in.in 24 Mar 2005 20:54:57 -0000 @@ -394,8 +394,8 @@ <list_type>string</list_type> <default>[]</default> <locale name="C"> - <short>Free/busy server urls</short> - <long>List of server urls for free/busy publishing.</long> + <short>List of urls for online publishing</short> + <long>List of server urls for publishing.</long> </locale> </schema> @@ -405,9 +405,31 @@ <owner>evolution-calendar</owner> <type>string</type> <locale name="C"> - <short>Free/busy template url</short> + <short>The url template to use as an online publishing data fallback</short> + </locale> + </schema> + <schema> + <key>/schemas/apps/evolution/calendar/publish/fb-uris</key> + <applyto>/apps/evolution/calendar/publish/fb-uris</applyto> + <owner>evolution-calendar</owner> + <type>list</type> + <list_type>string</list_type> + <default>[]</default> + <locale name="C"> + <short>List of urls for free/busy publishing</short> + </locale> + </schema> + + <schema> + <key>/schemas/apps/evolution/calendar/publish/fb-template</key> + <applyto>/apps/evolution/calendar/publish/fb-template</applyto> + <owner>evolution-calendar</owner> + <type>string</type> + <locale name="C"> + <short>The url template to use as a free/busy data fallback</short> <long>The url template to use as a free/busy data fallback, %u is replaced by the user part of the mail address and %d is replaced by the domain.</long> </locale> </schema> + </schemalist> </gconfschemafile> Index: calendar/gui/calendar-commands.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/calendar-commands.c,v retrieving revision 1.159 diff -u -u -r1.159 calendar-commands.c --- calendar/gui/calendar-commands.c 1 Feb 2005 11:46:33 -0000 1.159 +++ calendar/gui/calendar-commands.c 24 Mar 2005 20:54:57 -0000 @@ -333,7 +333,13 @@ static void publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { - e_pub_publish (TRUE); + e_pub_publish (PUB_FREE_BUSY, TRUE); +} + +static void +publish_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) +{ + e_pub_publish (PUB_ONLINE, TRUE); } static void @@ -617,6 +623,7 @@ BONOBO_UI_VERB ("ShowListView", show_list_view_clicked), BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd), + BONOBO_UI_VERB ("Publish", publish_cmd), BONOBO_UI_VERB ("CalendarPurge", purge_cmd), BONOBO_UI_VERB_END Index: calendar/gui/calendar-component.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/calendar-component.c,v retrieving revision 1.201 diff -u -u -r1.201 calendar-component.c --- calendar/gui/calendar-component.c 22 Mar 2005 15:09:10 -0000 1.201 +++ calendar/gui/calendar-component.c 24 Mar 2005 20:54:57 -0000 @@ -111,6 +111,7 @@ GConfClient *gconf_client; int gconf_notify_id; + int gconf_notify_fb_id; ESourceList *source_list; ESourceList *task_source_list; @@ -743,7 +744,8 @@ init_calendar_publishing_cb (gpointer data) { /* Publish if it is time to publish again */ - e_pub_publish (FALSE); + e_pub_publish (PUB_ONLINE, FALSE); + e_pub_publish (PUB_FREE_BUSY, FALSE); return FALSE; } @@ -755,7 +757,17 @@ void *user_data) { /* publish config changed, so publish */ - e_pub_publish (TRUE); + e_pub_publish (PUB_ONLINE, TRUE); +} + +static void +conf_fb_changed_callback (GConfClient *client, + unsigned int connection_id, + GConfEntry *entry, + void *user_data) +{ + /* publish config changed, so publish */ + e_pub_publish (PUB_FREE_BUSY, TRUE); } /* Evolution::Component CORBA methods. */ @@ -1674,7 +1686,11 @@ = gconf_client_notify_add (priv->gconf_client, CALENDAR_CONFIG_PUBLISH, (GConfClientNotifyFunc) conf_changed_callback, NULL, NULL, NULL); - + priv->gconf_notify_fb_id + = gconf_client_notify_add (priv->gconf_client, CALENDAR_CONFIG_FB_PUBLISH, + (GConfClientNotifyFunc) conf_fb_changed_callback, NULL, + NULL, NULL); + idle_id = g_idle_add ((GSourceFunc) init_calendar_publishing_cb, GINT_TO_POINTER (idle_id)); } Index: calendar/gui/calendar-config-keys.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config-keys.h,v retrieving revision 1.6 diff -u -u -r1.6 calendar-config-keys.h --- calendar/gui/calendar-config-keys.h 18 Dec 2004 13:01:17 -0000 1.6 +++ calendar/gui/calendar-config-keys.h 24 Mar 2005 20:54:57 -0000 @@ -71,6 +71,10 @@ #define CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/default_reminder_units" /* Free/Busy settings */ +#define CALENDAR_CONFIG_FB_PUBLISH CALENDAR_CONFIG_PREFIX"/publish/fb-uris" +#define CALENDAR_CONFIG_FB_TEMPLATE CALENDAR_CONFIG_PREFIX"/publish/fb-template" + +/* Online publish settings */ #define CALENDAR_CONFIG_PUBLISH CALENDAR_CONFIG_PREFIX"/publish/uris" #define CALENDAR_CONFIG_TEMPLATE CALENDAR_CONFIG_PREFIX"/publish/template" Index: calendar/gui/calendar-config.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.c,v retrieving revision 1.72 diff -u -u -r1.72 calendar-config.c --- calendar/gui/calendar-config.c 31 Dec 2004 16:59:18 -0000 1.72 +++ calendar/gui/calendar-config.c 24 Mar 2005 20:54:57 -0000 @@ -1107,13 +1107,27 @@ GSList * calendar_config_get_free_busy (void) { - return gconf_client_get_list (config, CALENDAR_CONFIG_PUBLISH, + return gconf_client_get_list (config, CALENDAR_CONFIG_FB_PUBLISH, GCONF_VALUE_STRING, NULL); } void calendar_config_set_free_busy (GSList *url_list) { + gconf_client_set_list (config, CALENDAR_CONFIG_FB_PUBLISH, + GCONF_VALUE_STRING, url_list, NULL); +} + +GSList * +calendar_config_get_publish (void) +{ + return gconf_client_get_list (config, CALENDAR_CONFIG_PUBLISH, + GCONF_VALUE_STRING, NULL); +} + +void +calendar_config_set_publish (GSList *url_list) +{ gconf_client_set_list (config, CALENDAR_CONFIG_PUBLISH, GCONF_VALUE_STRING, url_list, NULL); } @@ -1121,12 +1135,24 @@ gchar * calendar_config_get_free_busy_template (void) { - return gconf_client_get_string (config, CALENDAR_CONFIG_TEMPLATE, NULL); + return gconf_client_get_string (config, CALENDAR_CONFIG_FB_TEMPLATE, NULL); } void calendar_config_set_free_busy_template (const gchar *template) { + gconf_client_set_string (config, CALENDAR_CONFIG_FB_TEMPLATE, template, NULL); +} + +gchar * +calendar_config_get_publish_template (void) +{ + return gconf_client_get_string (config, CALENDAR_CONFIG_TEMPLATE, NULL); +} + +void +calendar_config_set_publish_template (const gchar *template) +{ gconf_client_set_string (config, CALENDAR_CONFIG_TEMPLATE, template, NULL); } @@ -1136,6 +1162,18 @@ { guint id; + id = gconf_client_notify_add (config, CALENDAR_CONFIG_FB_TEMPLATE, func, data, + NULL, NULL); + + return id; +} + +guint +calendar_config_add_notification_publish_template (GConfClientNotifyFunc func, + gpointer data) +{ + guint id; + id = gconf_client_notify_add (config, CALENDAR_CONFIG_TEMPLATE, func, data, NULL, NULL); Index: calendar/gui/calendar-config.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.h,v retrieving revision 1.36 diff -u -u -r1.36 calendar-config.h --- calendar/gui/calendar-config.h 31 Dec 2004 16:59:18 -0000 1.36 +++ calendar/gui/calendar-config.h 24 Mar 2005 20:54:57 -0000 @@ -206,6 +206,14 @@ void calendar_config_set_free_busy_template (const gchar *template); guint calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func, gpointer data); +/* online publishing settings */ +GSList * calendar_config_get_publish (void); +void calendar_config_set_publish (GSList * url_list); + +gchar *calendar_config_get_publish_template (void); +void calendar_config_set_publish_template (const gchar *template); +guint calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func, + gpointer data); /* Shows the timezone dialog if the user hasn't set a default timezone. */ void calendar_config_check_timezone_set (void); Index: calendar/gui/e-calendar-view.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-calendar-view.c,v retrieving revision 1.77 diff -u -u -r1.77 e-calendar-view.c --- calendar/gui/e-calendar-view.c 21 Mar 2005 14:29:15 -0000 1.77 +++ calendar/gui/e-calendar-view.c 24 Mar 2005 20:54:57 -0000 @@ -1251,7 +1251,13 @@ static void on_publish (EPopup *ep, EPopupItem *pitem, void *data) { - e_pub_publish (TRUE); + e_pub_publish (PUB_ONLINE, TRUE); +} + +static void +on_publish_fb (EPopup *ep, EPopupItem *pitem, void *data) +{ + e_pub_publish (PUB_FREE_BUSY, TRUE); } static void @@ -1390,7 +1396,8 @@ { E_POPUP_BAR, "70." }, /* TODO: Why is this in a context menu when it applies globally? */ - { E_POPUP_ITEM, "70.publish", N_("_Publish Free/Busy Information"), on_publish, }, + { E_POPUP_ITEM, "70.publish", N_("_Publish Calendars"), on_publish, }, + { E_POPUP_ITEM, "71.publish", N_("_Publish Free/Busy Information"), on_publish_fb, }, }; static EPopupItem ecv_child_items [] = { Index: calendar/gui/e-pub-utils.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-pub-utils.c,v retrieving revision 1.7 diff -u -u -r1.7 e-pub-utils.c --- calendar/gui/e-pub-utils.c 23 Feb 2005 18:56:56 -0000 1.7 +++ calendar/gui/e-pub-utils.c 24 Mar 2005 20:54:57 -0000 @@ -28,6 +28,7 @@ #include <libedataserver/e-source-list.h> #include <libedataserverui/e-passwords.h> #include <libecal/e-cal-time-util.h> +#include <libecal/e-cal-listener.h> #include <libgnome/gnome-i18n.h> #include "calendar-config.h" #include "common/authentication.h" @@ -35,16 +36,52 @@ #include "e-pub-utils.h" void -e_pub_uri_from_xml (EPublishUri *uri, const gchar *xml) +e_pub_uri_free(EPublishUri *uri) +{ + GSList *l = NULL; + g_return_if_fail(uri != NULL); + + if(uri->location){ + xmlFree(uri->location); + uri->location = NULL; + } + if(uri->username){ + xmlFree(uri->username); + uri->location = NULL; + } + if(uri->last_pub_time){ + xmlFree(uri->last_pub_time); + uri->last_pub_time = NULL; + } + if((l = uri->calendars)){ + for(; l != NULL; l = l->next) + xmlFree(l->data); + g_slist_free(uri->calendars); + uri->calendars = NULL; + } + if((l = uri->tasks)){ + for(; l != NULL; l = l->next) + xmlFree(l->data); + g_slist_free(uri->tasks); + uri->tasks = NULL; + } +} + +void +e_pub_uri_from_xml (EPublishUri *uri, const guchar *xml) { xmlDocPtr doc; xmlNodePtr root, p; - xmlChar *location, *enabled, *frequency; + xmlChar *location, *type, *enabled, *frequency; xmlChar *username, *publish_time; - GSList *l = NULL; + xmlChar *remember_pw, *no_pw; + xmlChar *alarm_publish; + xmlChar *auto_publish; uri->location = NULL; - doc = xmlParseDoc ((char *)xml); + uri->calendars = NULL; + uri->tasks = NULL; + doc = xmlParseDoc ((guchar *)xml); if (doc == NULL) { uri->location = NULL; return; @@ -54,48 +91,87 @@ if (strcmp (root->name, "uri") != 0) { return; } + location = xmlGetProp (root, "location"); + type = xmlGetProp (root, "type"); enabled = xmlGetProp (root, "enabled"); - frequency = xmlGetProp (root, "frequency"); username = xmlGetProp (root, "username"); publish_time = xmlGetProp (root, "publish_time"); + remember_pw = xmlGetProp (root, "remember_pw"); + no_pw = xmlGetProp (root, "no_password"); if (location != NULL) - uri->location = g_strdup (location); - if (enabled != NULL) + uri->location = location; + + if (type != NULL) { + uri->type = atoi (type); + xmlFree(type); + } + if (enabled != NULL) { uri->enabled = atoi (enabled); - if (frequency != NULL) - uri->publish_freq = atoi (frequency); + xmlFree(enabled); + } if (username != NULL) - uri->username = g_strdup (username); + uri->username = username; + if(no_pw != NULL) { + uri->no_pw = atoi(no_pw); + xmlFree(no_pw); + } + if(remember_pw != NULL) { + uri->remember_pw = atoi(remember_pw); + xmlFree(remember_pw); + } + if (publish_time != NULL) - uri->last_pub_time = g_strdup (publish_time); + uri->last_pub_time = publish_time; - uri->password = g_strdup (""); + if(uri->type == PUB_ONLINE) { + auto_publish = xmlGetProp (root, "auto_publish"); + alarm_publish = xmlGetProp (root, "alarm_publish"); + + if (auto_publish != NULL) { + uri->auto_publish = atoi(auto_publish); + xmlFree(auto_publish); + } + if (alarm_publish != NULL) { + uri->alarm_publish = atoi(alarm_publish); + xmlFree(alarm_publish); + } + for (p = root->children; p != NULL; p = p->next) { + xmlChar *uid = xmlGetProp (p, "uid_task"); + if(uid) + uri->tasks = g_slist_append (uri->tasks, uid); + } + } + + if(uri->type == PUB_FREE_BUSY) { + frequency = xmlGetProp (root, "frequency"); + if (frequency != NULL) { + uri->publish_freq = atoi (frequency); + xmlFree(frequency); + } + } for (p = root->children; p != NULL; p = p->next) { xmlChar *uid = xmlGetProp (p, "uid"); - - l = g_slist_append (l, uid); + if(uid) + uri->calendars = g_slist_append (uri->calendars, uid); } - uri->calendars = l; - - xmlFree(location); - xmlFree(enabled); + xmlFreeDoc(doc); return; } -gchar * +guchar * e_pub_uri_to_xml (EPublishUri *uri) { xmlDocPtr doc; xmlNodePtr root; - gchar *enabled, *frequency; GSList *cals = NULL; xmlChar *xml_buffer; char *returned_buffer; int xml_buffer_size; + gchar *str; /* temporary string from value to xml */ g_return_val_if_fail (uri != NULL, NULL); g_return_val_if_fail (uri->location != NULL, NULL); @@ -103,13 +179,43 @@ doc = xmlNewDoc ("1.0"); root = xmlNewDocNode (doc, NULL, "uri", NULL); - enabled = g_strdup_printf ("%d", uri->enabled); - frequency = g_strdup_printf ("%d", uri->publish_freq); + str = g_strdup_printf ("%d", uri->type); + xmlSetProp (root, "type", str); + g_free(str); + str = g_strdup_printf ("%d", uri->enabled); + xmlSetProp (root, "enabled", str); + g_free(str); xmlSetProp (root, "location", uri->location); - xmlSetProp (root, "enabled", enabled); - xmlSetProp (root, "frequency", frequency); xmlSetProp (root, "username", uri->username); + xmlSetProp (root, "username", uri->username); + str = g_strdup_printf ("%d", uri->no_pw); + xmlSetProp (root, "no_password", str); + g_free(str); + str = g_strdup_printf ("%d", uri->remember_pw); + xmlSetProp (root, "remember_pw", str); + g_free(str); + xmlSetProp (root, "publish_time", uri->last_pub_time); + + if(uri->type == PUB_FREE_BUSY) { + str = g_strdup_printf ("%d", uri->publish_freq); + xmlSetProp (root, "frequency", str); + g_free(str); + } + + if(uri->type == PUB_ONLINE) { + str = g_strdup_printf ("%d", uri->auto_publish); + xmlSetProp (root, "auto_publish", str); + g_free(str); + str = g_strdup_printf ("%d", uri->alarm_publish); + xmlSetProp (root, "alarm_publish", str); + g_free(str); + for (cals = uri->tasks; cals != NULL; cals = cals->next) { + xmlNodePtr node; + node = xmlNewChild (root, NULL, "source", NULL); + xmlSetProp (node, "uid_task", cals->data); + } + } for (cals = uri->calendars; cals != NULL; cals = cals->next) { xmlNodePtr node; @@ -126,7 +232,6 @@ memcpy (returned_buffer, xml_buffer, xml_buffer_size); returned_buffer [xml_buffer_size] = '\0'; xmlFree (xml_buffer); - g_free (enabled); return returned_buffer; } @@ -167,6 +272,8 @@ return TRUE; } break; + case URI_PUBLISH_USER: + return TRUE; } } @@ -188,150 +295,236 @@ else return FALSE; } - return TRUE; } +static void +e_pub_uri_calendar_modified_cb(ECalListener *listener, + ECalendarStatus status, + const char *id, gpointer data){ /* not used */ + g_return_if_fail(listener != NULL); + g_return_if_fail(E_IS_CAL_LISTENER(listener)); + if(status != E_CALENDAR_STATUS_OK) + return; + e_pub_publish(PUB_ONLINE, TRUE); +} + void -e_pub_publish (gboolean publish) { - icaltimezone *utc; +e_pub_publish (EPublishUriType type, gboolean publish) { + icaltimezone *utc = NULL; time_t start = time (NULL), end; - GSList *uri_config_list, *l, *uri_list = NULL; - ESourceList *source_list; - GConfClient *gconf_client; + GSList *uri_config_list = NULL, *l = NULL, *uri_list = NULL; + ESourceList *source_list_cal, *source_list_tasks; gboolean published = FALSE; - - gconf_client = gconf_client_get_default (); - source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/calendar/sources"); - + + source_list_cal = e_source_list_new_for_gconf_default( + "/apps/evolution/calendar/sources"); + source_list_tasks = e_source_list_new_for_gconf_default( + "/apps/evolution/tasks/sources"); + utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); end = time_add_week_with_zone (start, 6, utc); - - uri_config_list = calendar_config_get_free_busy (); - + + switch(type) { + case PUB_ONLINE: + uri_config_list = calendar_config_get_publish (); + break; + case PUB_FREE_BUSY: + uri_config_list = calendar_config_get_free_busy (); + break; + } + + /* loop URIs */ for (l = uri_config_list; l != NULL; l = l->next) { GSList *p =NULL; - EPublishUri *uri; - ECalComponent *clone = NULL; - gboolean cloned = FALSE; + EPublishUri uri; ECal *client = NULL; - char *prompt; + gchar *prompt; gboolean remember = FALSE; - gchar *password; + gchar *password = NULL; gchar *xml = (gchar *)l->data; - uri = g_new0 (EPublishUri, 1); - e_pub_uri_from_xml (uri, xml); + e_pub_uri_from_xml (&uri, xml); /* kludge to safeguard against loop from gconf update */ - if (!just_published (uri->last_pub_time)) - return; +// if (just_published (uri->last_pub_time)) +// continue; - /* TODO: make sure we're online */ /* skip this url if it isn't enabled or if it is manual */ - if (!uri->enabled) { - uri_config_list = g_slist_next (uri_config_list); + if (!uri.enabled) continue; - } if (!publish) { /* a g_idle publish, make sure we are not set to user only */ - if (uri->publish_freq == URI_PUBLISH_USER) { - uri_config_list = g_slist_next (uri_config_list); + if (uri.publish_freq == URI_PUBLISH_USER) continue; - } /* If not is it time to publish again? */ - publish = is_publish_time (uri); - + publish = is_publish_time (&uri); + + /* TODO: register the notifiers for calendars + * marked auto_publish */ } /* User published or config change */ if (publish) { + icalcomponent *toplevel; /* new toplevel component that will hold all the data */ + ECalComponent *e_toplevel; /* We still need to set the last_pub_time */ - uri->last_pub_time = 0; - is_publish_time (uri); + uri.last_pub_time = 0; + is_publish_time (&uri); + + toplevel = e_cal_util_new_top_level (); + e_toplevel = e_cal_component_new(); + e_cal_component_set_icalcomponent(e_toplevel, toplevel); + icalcomponent_set_method (toplevel, ICAL_METHOD_PUBLISH); - for (p = uri->calendars; p != NULL; p = p->next) { - GList *comp_list = NULL; + /* loop calendars */ + for (p = uri.calendars; p != NULL; p = p->next) { + GList *comp_list = NULL; /* list of icalcomponents for this calendar */ + GList *tmp; gchar *source_uid; ESource * source; + gboolean ret = FALSE; source_uid = g_strdup (p->data); - source = e_source_list_peek_source_by_uid (source_list, source_uid); + source = e_source_list_peek_source_by_uid (source_list_cal, source_uid); if (source) client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); if (!client) { - g_warning (G_STRLOC ": Could not publish Free/Busy: Calendar backend no longer exists"); + g_warning (G_STRLOC ": Could not publish calendar: Calendar backend no longer exists."); continue; } - - e_cal_open (client, TRUE, NULL); - - if (e_cal_get_free_busy ((ECal *) client, NULL, + if(!e_cal_open (client, TRUE, NULL)){ + g_warning (G_STRLOC ": Could not publish calendar: could not open calendar."); + continue; + } + + switch(type) { + case PUB_ONLINE: + ret = e_cal_get_object_list (client, "#t", + &comp_list, NULL); + break; + case PUB_FREE_BUSY: + /* TODO fix this, it no longer works!!! */ + { + gboolean cloned = FALSE; + ECalComponent *clone = NULL; + ret = e_cal_get_free_busy (client, NULL, start, end, - &comp_list, NULL)) { + &tmp, NULL); + for (; tmp; tmp = tmp->next) { + ECalComponent *comp = E_CAL_COMPONENT (tmp->data); + cloned = itip_publish_begin (comp, cloned, &clone); + g_object_unref (comp); + } + comp_list = g_list_append(comp_list, itip_comp_fb_normalize( + e_cal_component_get_icalcomponent(clone))); + ret = cloned; + break; + } + } + + if (ret) { GList *l; - for (l = comp_list; l; l = l->next) { - ECalComponent *comp = E_CAL_COMPONENT (l->data); - - cloned = itip_publish_begin (comp, (ECal *) client, cloned, &clone); - g_object_unref (comp); + /* TODO check against alarm_publish and todo_publish */ + icalcomponent_add_component(toplevel, l->data); } g_list_free (comp_list); } +// offline |= e_source_get_property (source, "offline"); g_object_unref (client); + client = NULL; g_free (source_uid); - } + } /* end loop calendars */ - /* add password to the uri */ - password = e_passwords_get_password ("Calendar", - (gchar *)uri->location); + /* loop task lists */ + for (p = uri.tasks; type == PUB_ONLINE && p != NULL; p = p->next) { + GList *comp_list = NULL; /* list of icalcomponents for this task list */ + gchar *source_uid; + ESource * source; + gboolean ret = FALSE; + + source_uid = g_strdup (p->data); + source = e_source_list_peek_source_by_uid (source_list_tasks, source_uid); + if (source) + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); + + if (!client) { + g_warning (G_STRLOC ": Could not publish task list: backend no longer exists."); + continue; + } + if(!e_cal_open (client, TRUE, NULL)){ + g_warning (G_STRLOC ": Could not publish task list: could not open it."); + continue; + } + + ret = e_cal_get_object_list (client, "#t", + &comp_list, NULL); + + if (ret) { + GList *l; + for (l = comp_list; l; l = l->next) { + icalcomponent_add_component(toplevel, l->data); + } + g_list_free (comp_list); + } + + g_object_unref (client); - if (!password) { - prompt = g_strdup_printf (_("Enter the password for %s"), (gchar *)uri->location); - password = e_passwords_ask_password (_("Enter password"), - "Calendar", (gchar *)uri->location, - prompt, - E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE, - &remember, NULL); + g_free (source_uid); + } /* end loop tasks */ - g_free (prompt); - + /* add password to the uri */ + if(!uri.no_pw) { + password = e_passwords_get_password ("Calendar", + (gchar *)uri.location); if (!password) { - g_slist_free (p); - continue; + prompt = g_strdup_printf ( + _("Enter the password for %s"), (gchar *)uri.location); + password = e_passwords_ask_password (_("Enter password"), + "Calendar", (gchar *)uri.location, + prompt, + E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE, + &remember, NULL); + g_free (prompt); } } - - if (cloned && clone) - published = itip_publish_comp ((ECal *) client, - uri->location, - uri->username, - password, &clone); - + e_cal_component_set_url(e_toplevel, uri.location); + published = itip_publish_comp (toplevel, TRUE,//offline, + uri.location, + uri.username, + password); g_slist_free (p); - } - xml = e_pub_uri_to_xml (uri); + } /* end if(publish) */ + + xml = e_pub_uri_to_xml (&uri); if (xml != NULL) { uri_list = g_slist_append (uri_list, xml); } - g_free (uri); - } + e_pub_uri_free(&uri); + } /* end loop URIs */ if (published) { /* Update gconf so we have the last_pub_time */ - calendar_config_set_free_busy (uri_list); + switch (type) { + case PUB_ONLINE: + calendar_config_set_publish (uri_list); + break; + case PUB_FREE_BUSY: + calendar_config_set_free_busy (uri_list); + break; + } } - + g_slist_free (uri_config_list); g_slist_free (uri_list); } Index: calendar/gui/e-pub-utils.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-pub-utils.h,v retrieving revision 1.1 diff -u -u -r1.1 e-pub-utils.h --- calendar/gui/e-pub-utils.h 13 Jan 2004 01:59:28 -0000 1.1 +++ calendar/gui/e-pub-utils.h 24 Mar 2005 20:54:57 -0000 @@ -28,11 +28,11 @@ G_BEGIN_DECLS -enum publish_frequency{ +typedef enum { URI_PUBLISH_DAILY, URI_PUBLISH_WEEKLY, - URI_PUBLISH_USER -}; + URI_PUBLISH_USER, +} EPublishFreq; static const int pub_frequency_type_map[] = { URI_PUBLISH_DAILY, @@ -41,21 +41,33 @@ -1 }; -struct _EPublishUri { +typedef enum { + PUB_FREE_BUSY, + PUB_ONLINE +} EPublishUriType; + +typedef struct { + /* for both types */ + EPublishUriType type; gint enabled; gchar *location; - gint publish_freq; gchar *username; - gchar *password; + gboolean no_pw; + gboolean remember_pw; GSList *calendars; gchar *last_pub_time; -}; - -typedef struct _EPublishUri EPublishUri; - -void e_pub_uri_from_xml (EPublishUri *uri, const gchar *xml); -gchar *e_pub_uri_to_xml (EPublishUri *uri); -void e_pub_publish (gboolean publish) ; + /* only for PUB_FREE_BUSY */ + EPublishFreq publish_freq; + /* only for PUB_ONLINE */ + GSList *tasks; + gboolean auto_publish; + gboolean alarm_publish; +} EPublishUri; + +void e_pub_uri_free(EPublishUri *uri); +void e_pub_uri_from_xml (EPublishUri *uri, const guchar *xml); +guchar *e_pub_uri_to_xml (EPublishUri *uri); +void e_pub_publish (EPublishUriType type, gboolean publish) ; G_END_DECLS Index: calendar/gui/itip-utils.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/itip-utils.c,v retrieving revision 1.98 diff -u -u -r1.98 itip-utils.c --- calendar/gui/itip-utils.c 15 Mar 2005 16:05:07 -0000 1.98 +++ calendar/gui/itip-utils.c 24 Mar 2005 20:54:57 -0000 @@ -36,9 +36,11 @@ #include <e-util/e-time-utils.h> #include <libecal/e-cal-time-util.h> #include <libecal/e-cal-util.h> +#include <libedataserverui/e-passwords.h> #include <libsoup/soup-session-async.h> #include <libsoup/soup-message.h> #include <libsoup/soup-uri.h> +#include <libgnomevfs/gnome-vfs.h> #include "calendar-config.h" #include "itip-utils.h" #include "dialogs/cal-attachment.h" @@ -1052,36 +1054,32 @@ } gboolean -itip_publish_begin (ECalComponent *pub_comp, ECal *client, +itip_publish_begin (ECalComponent *pub_comp, gboolean cloned, ECalComponent **clone) { icalcomponent *icomp =NULL, *icomp_clone = NULL; icalproperty *prop; - - if (e_cal_component_get_vtype (pub_comp) == E_CAL_COMPONENT_FREEBUSY) { - + if (e_cal_component_get_vtype (pub_comp) == E_CAL_COMPONENT_FREEBUSY) { if (!cloned) { *clone = e_cal_component_clone (pub_comp); - cloned = TRUE; } else { - icomp = e_cal_component_get_icalcomponent (pub_comp); icomp_clone = e_cal_component_get_icalcomponent (*clone); for (prop = icalcomponent_get_first_property (icomp, ICAL_FREEBUSY_PROPERTY); prop != NULL; - prop = icalcomponent_get_next_property (icomp, + prop = icalcomponent_get_next_property (icomp, ICAL_FREEBUSY_PROPERTY)) { icalproperty *p; - + p = icalproperty_new_clone (prop); icalcomponent_add_property (icomp_clone, p); } - } + } + return TRUE; } - - return TRUE; + return FALSE; } static void @@ -1111,8 +1109,8 @@ } } -static icalcomponent * -comp_fb_normalize (icalcomponent *icomp) +icalcomponent * +itip_comp_fb_normalize (icalcomponent *icomp) { icalcomponent *iclone; icalproperty *prop, *p; @@ -1197,64 +1195,133 @@ } gboolean -itip_publish_comp (ECal *client, gchar *uri, gchar *username, - gchar *password, ECalComponent **pub_comp) +itip_publish_comp (icalcomponent *toplevel, gboolean offline, + gchar *uri, gchar *username, gchar *password) { - icalcomponent *toplevel = NULL, *icalcomp = NULL; - icalcomponent *icomp = NULL; - SoupSession *session; - SoupMessage *msg; - SoupUri *real_uri; + icalcomponent *icalcomp = NULL; char *ical_string; + gboolean http; + GnomeVFSURI *vfs_uri; + GnomeVFSHandle *handle = NULL; + GnomeVFSResult result; + GnomeVFSFileSize bytes; + GnomeVFSFileSize bytes_written = 0; + + /* for URIs that need password input, like ssh */ + gnome_authentication_manager_init(); + + if(strncasecmp(uri, "http", 4) == 0){ + /* Publish the component with SOAP */ + SoupSession *session; + SoupUri *real_uri; + SoupMessage *msg; + session = soup_session_async_new (); + real_uri = soup_uri_new (uri); + if (!real_uri || !real_uri->host) { + g_warning (G_STRLOC ": Invalid URL: %s", uri); + g_object_unref (session); + return FALSE; + } + + real_uri->user = g_strdup (username); + real_uri->passwd = g_strdup (password); + + /* build the SOAP message */ + msg = soup_message_new_from_uri (SOUP_METHOD_PUT, real_uri); + if (!msg) { + g_warning (G_STRLOC ": Could not build SOAP message"); + g_object_unref (session); + return FALSE; + } + soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); + ical_string = icalcomponent_as_ical_string (toplevel); + soup_message_set_request (msg, "text/calendar", SOUP_BUFFER_USER_OWNED, + ical_string, strlen (ical_string)); + + /* send message to server */ + soup_session_send_message (session, msg); + if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { + g_warning(G_STRLOC ": Could not publish calendars: %d: %s", + msg->status_code, + soup_status_get_phrase (msg->status_code)); + g_object_unref (session); + return FALSE; + } + + soup_uri_free (real_uri); + g_object_unref (session); + return TRUE; + } - toplevel = e_cal_util_new_top_level (); - icalcomponent_set_method (toplevel, ICAL_METHOD_PUBLISH); - - e_cal_component_set_url (*pub_comp, uri); - - icalcomp = e_cal_component_get_icalcomponent (*pub_comp); + if((vfs_uri = gnome_vfs_uri_new(uri)) == NULL){ + g_warning (G_STRLOC ": Invalid URL: %s", uri); + return FALSE; + } + if(!gnome_vfs_uri_is_local(vfs_uri)){ + /* TODO: if this is not a local uri. make sure we're online */ + /* + GNOME_Evolution_Offline offline_obj; + CORBA_Environment ev; + CORBA_boolean offline = FALSE; + + CORBA_exception_init (&ev); + interface = Bonobo_Unknown_queryInterface( + objref, "IDL:GNOME/Evolution/Offline:1.0", &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + return; + } + + offline = GNOME_Evolution_Offline__get_isOffline(offline_obj, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + //error querying CORBA object + return; + } + + if (offline) { + //error... we are offline + CORBA_exception_free (&ev); + return; + } - icomp = comp_fb_normalize (icalcomp); - - icalcomponent_add_component (toplevel, icomp); - ical_string = icalcomponent_as_ical_string (toplevel); + CORBA_exception_free (&ev); + */ + } - /* Publish the component */ - session = soup_session_async_new (); + gnome_vfs_uri_set_user_name(vfs_uri, username); + gnome_vfs_uri_set_password(vfs_uri, password); + if(!gnome_vfs_uri_exists(vfs_uri)) { + result = gnome_vfs_create_uri(&handle, vfs_uri, + GNOME_VFS_OPEN_WRITE, + FALSE, GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ); + } else { + result = gnome_vfs_open_uri(&handle, vfs_uri, GNOME_VFS_OPEN_WRITE); + } - real_uri = soup_uri_new (uri); - if (!real_uri || !real_uri->host) { - g_warning (G_STRLOC ": Invalid URL: %s", uri); - g_object_unref (session); + if(result != GNOME_VFS_OK){ + g_warning("Publish: Cannot open uri: %s, %s", uri, gnome_vfs_result_to_string(result)); return FALSE; } - real_uri->user = g_strdup (username); - real_uri->passwd = g_strdup (password); - - /* build the SOAP message */ - msg = soup_message_new_from_uri (SOUP_METHOD_PUT, real_uri); - if (!msg) { - g_warning (G_STRLOC ": Could not build SOAP message"); - g_object_unref (session); - return FALSE; + ical_string = icalcomponent_as_ical_string (toplevel); + bytes = strlen (ical_string); + while(bytes > bytes_written) { + bytes = bytes - bytes_written; + ical_string = ical_string + bytes_written; + result = gnome_vfs_write(handle, ical_string, bytes, &bytes_written); + if(result != GNOME_VFS_OK){ + g_warning(gnome_vfs_result_to_string(result)); + return FALSE; + } } - soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); - soup_message_set_request (msg, "text/calendar", SOUP_BUFFER_USER_OWNED, - ical_string, strlen (ical_string)); - - /* send message to server */ - soup_session_send_message (session, msg); - if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { - g_warning(G_STRLOC ": Could not publish Free/Busy: %d: %s", - msg->status_code, - soup_status_get_phrase (msg->status_code)); - g_object_unref (session); + + result = gnome_vfs_close(handle); + if(result != GNOME_VFS_OK){ + g_warning("Publish: Cannot close uri: %s, %s", uri, gnome_vfs_result_to_string(result)); return FALSE; } - soup_uri_free (real_uri); - g_object_unref (session); - return TRUE; } Index: calendar/gui/itip-utils.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/itip-utils.h,v retrieving revision 1.17 diff -u -u -r1.17 itip-utils.h --- calendar/gui/itip-utils.h 8 Jan 2005 10:53:53 -0000 1.17 +++ calendar/gui/itip-utils.h 24 Mar 2005 20:54:57 -0000 @@ -31,10 +31,11 @@ gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, icalcomponent *zones, GSList *attachments_list); -gboolean itip_publish_comp (ECal *client, gchar* uri, gchar* username, - gchar* password, ECalComponent **pub_comp); +gboolean itip_publish_comp (icalcomponent *toplevel, gboolean offline, + gchar* uri, gchar* username, gchar* password); -gboolean itip_publish_begin (ECalComponent *pub_comp, ECal *client, +gboolean itip_publish_begin (ECalComponent *pub_comp, gboolean cloned, ECalComponent **clone); +icalcomponent *itip_comp_fb_normalize (icalcomponent *icomp); #endif Index: calendar/gui/dialogs/Makefile.am =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/Makefile.am,v retrieving revision 1.69 diff -u -u -r1.69 Makefile.am --- calendar/gui/dialogs/Makefile.am 8 Jan 2005 10:53:52 -0000 1.69 +++ calendar/gui/dialogs/Makefile.am 24 Mar 2005 20:54:57 -0000 @@ -62,6 +62,8 @@ event-page.h \ meeting-page.c \ meeting-page.h \ + publish-editor-dialog.c \ + publish-editor-dialog.h \ recurrence-page.c \ recurrence-page.h \ recur-comp.c \ @@ -91,6 +93,7 @@ e-delegate-dialog.glade \ event-page.glade \ meeting-page.glade \ + publish-editor-dialog.glade \ recurrence-page.glade \ schedule-page.glade \ task-details-page.glade \ Index: calendar/gui/dialogs/cal-prefs-dialog.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.c,v retrieving revision 1.41 diff -u -u -r1.41 cal-prefs-dialog.c --- calendar/gui/dialogs/cal-prefs-dialog.c 31 Dec 2004 16:59:18 -0000 1.41 +++ calendar/gui/dialogs/cal-prefs-dialog.c 24 Mar 2005 20:54:57 -0000 @@ -35,6 +35,7 @@ #include "cal-prefs-dialog.h" #include "../calendar-config.h" #include "url-editor-dialog.h" +#include "publish-editor-dialog.h" #include <gtk/gtk.h> #include <gtk/gtkmain.h> @@ -87,6 +88,18 @@ GtkTreeViewColumn *column, DialogData *dialog_data); static void show_fb_config (DialogData *dialog_data); +static void show_publish_config (DialogData *dialog_data); + +static void cal_prefs_dialog_pub_url_add_clicked (GtkWidget *button, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_edit_clicked (GtkWidget *button, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_remove_clicked (GtkWidget *button, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_enable_clicked (GtkWidget *button, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_list_change (GtkTreeSelection *selection, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_list_enable_toggled (GtkCellRendererToggle *renderer, const char *path_string, DialogData *dialog_data); +static void cal_prefs_dialog_pub_url_list_double_click(GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + DialogData *dialog_data); GtkWidget *cal_prefs_dialog_create_time_edit (void); @@ -356,7 +369,7 @@ char *xml; gtk_tree_model_get ((GtkTreeModel *) model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, &url, + URL_LIST_URL_COLUMN, &url, -1); if ((xml = e_pub_uri_to_xml (url))) @@ -371,12 +384,50 @@ } static void +pub_url_list_changed (DialogData *dialog_data) +{ + GtkListStore *model = NULL; + GSList *url_list = NULL; + GtkTreeIter iter; + gboolean valid; + + url_list = NULL; + + model = (GtkListStore *) gtk_tree_view_get_model (dialog_data->pub_url_list); + + valid = gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter); + while (valid) { + EPublishUri *url; + char *xml; + + gtk_tree_model_get ((GtkTreeModel *) model, &iter, + URL_LIST_URL_COLUMN, &url, + -1); + + if ((xml = e_pub_uri_to_xml (url))) + url_list = g_slist_append (url_list, xml); + + valid = gtk_tree_model_iter_next ((GtkTreeModel *) model, &iter); + } + + calendar_config_set_publish (url_list); + + g_slist_free (url_list); +} + +static void template_url_changed (GtkEntry *entry, DialogData *dialog_data) { calendar_config_set_free_busy_template (gtk_entry_get_text (entry)); } static void +pub_template_url_changed (GtkEntry *entry, DialogData *dialog_data) +{ + calendar_config_set_publish_template (gtk_entry_get_text (entry)); +} + +static void setup_changes (DialogData *dialog_data) { int i; @@ -420,6 +471,7 @@ G_CALLBACK (default_reminder_units_changed), dialog_data); g_signal_connect (dialog_data->template_url, "changed", G_CALLBACK (template_url_changed), dialog_data); + g_signal_connect (dialog_data->pub_template_url, "changed", G_CALLBACK (pub_template_url_changed), dialog_data); } /* Gets the widgets from the XML file and returns if they are all available. @@ -473,6 +525,12 @@ data->template_url = GW("template_url"); + data->pub_url_add = GW ("pub_url_add"); + data->pub_url_edit = GW ("pub_url_edit"); + data->pub_url_remove = GW ("pub_url_remove"); + data->pub_url_enable = GW ("pub_url_enable"); + data->pub_url_list = GTK_TREE_VIEW (GW ("pub_url_list")); + data->pub_template_url = GW("pub_template_url"); #undef GW return (data->page @@ -506,7 +564,12 @@ && data->url_edit && data->url_remove && data->url_enable - && data->url_list); + && data->url_list + && data->pub_url_add + && data->pub_url_edit + && data->pub_url_remove + && data->pub_url_enable + && data->pub_url_list); } @@ -596,6 +659,66 @@ g_signal_connect (dialog_data->url_list, "row-activated", G_CALLBACK (cal_prefs_dialog_url_list_double_click), dialog_data); + g_signal_connect (selection, "changed", + G_CALLBACK (cal_prefs_dialog_url_list_change), + dialog_data); + + /* Online Publishing */ + g_signal_connect (dialog_data->pub_url_add, "clicked", + G_CALLBACK (cal_prefs_dialog_pub_url_add_clicked), + dialog_data); + + g_signal_connect (dialog_data->pub_url_edit, "clicked", + G_CALLBACK (cal_prefs_dialog_pub_url_edit_clicked), + dialog_data); + + g_signal_connect (dialog_data->pub_url_remove, "clicked", + G_CALLBACK (cal_prefs_dialog_pub_url_remove_clicked), + dialog_data); + + g_signal_connect (dialog_data->pub_url_enable, "clicked", + G_CALLBACK (cal_prefs_dialog_pub_url_enable_clicked), + dialog_data); + + /* Online Publishing Listview */ + renderer = gtk_cell_renderer_toggle_new(); + g_object_set ((GObject *) renderer, "activatable", TRUE, NULL); + + model = gtk_list_store_new (URL_LIST_N_COLUMNS, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model (dialog_data->pub_url_list, + (GtkTreeModel *) model); + + gtk_tree_view_insert_column_with_attributes (dialog_data->pub_url_list, -1, + _("Enabled"), renderer, + "active", + URL_LIST_ENABLED_COLUMN, + NULL); + + g_signal_connect (renderer, "toggled", + G_CALLBACK (cal_prefs_dialog_pub_url_list_enable_toggled), + dialog_data); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes(dialog_data->pub_url_list, -1, + _("Location"), renderer, + "text", + URL_LIST_LOCATION_COLUMN, + NULL); + + selection = gtk_tree_view_get_selection ( + (GtkTreeView *) dialog_data->pub_url_list); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + gtk_tree_view_set_headers_visible ( + (GtkTreeView *) dialog_data->pub_url_list, TRUE); + + g_signal_connect (dialog_data->pub_url_list, "row-activated", + G_CALLBACK (cal_prefs_dialog_pub_url_list_double_click), + dialog_data); + g_signal_connect (selection, "changed", + G_CALLBACK (cal_prefs_dialog_pub_url_list_change), + dialog_data); } /* Sets the color in a color picker from an X color spec */ @@ -638,7 +761,7 @@ url->enabled, URL_LIST_LOCATION_COLUMN, g_strdup (url->location), - URL_LIST_FREE_BUSY_URL_COLUMN, url, + URL_LIST_URL_COLUMN, url, -1); url_list_changed (dialog_data); @@ -669,7 +792,7 @@ selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->url_list); if (gtk_tree_selection_get_selected (selection, &model, &iter)){ gtk_tree_model_get (model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, + URL_LIST_URL_COLUMN, &url, -1); @@ -683,7 +806,7 @@ g_strdup (url->location), URL_LIST_ENABLED_COLUMN, url->enabled, - URL_LIST_FREE_BUSY_URL_COLUMN, url, + URL_LIST_URL_COLUMN, url, -1); url_list_changed (dialog_data); @@ -715,7 +838,7 @@ selection = gtk_tree_view_get_selection (dialog_data->url_list); if (gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, &url, + URL_LIST_URL_COLUMN, &url, -1); /* make sure we have a valid account selected and that @@ -757,7 +880,7 @@ gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->url_remove), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->url_enable), FALSE); } - g_free (url); + g_free(url); url_list_changed (dialog_data); } } @@ -773,7 +896,7 @@ selection = gtk_tree_view_get_selection (dialog_data->url_list); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { gtk_tree_model_get (model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, &url, + URL_LIST_URL_COLUMN, &url, -1); url->enabled = !url->enabled; @@ -807,7 +930,7 @@ if (gtk_tree_model_get_iter (model, &iter, path)) { gtk_tree_model_get (model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, &url, + URL_LIST_URL_COLUMN, &url, -1); url->enabled = !url->enabled; @@ -846,7 +969,7 @@ state = gtk_tree_selection_get_selected (selection, &model, &iter); if (state) { gtk_tree_model_get (model, &iter, - URL_LIST_FREE_BUSY_URL_COLUMN, &url, + URL_LIST_URL_COLUMN, &url, -1); if (url->location && url->enabled) @@ -902,6 +1025,7 @@ gchar *xml = (gchar *)url_config_list->data; EPublishUri *url; url = g_new0 (EPublishUri, 1); + url->type = PUB_FREE_BUSY; e_pub_uri_from_xml (url, xml); if (url->location) { @@ -911,7 +1035,7 @@ url->enabled, URL_LIST_LOCATION_COLUMN, url->location, - URL_LIST_FREE_BUSY_URL_COLUMN, url, + URL_LIST_URL_COLUMN, url, -1); } @@ -928,6 +1052,323 @@ g_free (template_url); } +/* Shows the current Online Publishing settings in the dialog */ +static void +show_publish_config (DialogData *dialog_data) +{ + GSList *url_config_list = NULL; + GtkListStore *model; + GtkTreeIter iter; + gchar *template_url; + + model = (GtkListStore *) gtk_tree_view_get_model (dialog_data->pub_url_list); + gtk_list_store_clear (model); + + /* restore urls from gconf */ + url_config_list = calendar_config_get_publish(); + + if (!url_config_list) { + /* list is empty-disable edit, remove, and enable buttons */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_edit), + FALSE); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_remove), + FALSE); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_enable), + FALSE); + } else { + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_edit), + TRUE); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_remove), + TRUE); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_enable), + TRUE); + } + + while (url_config_list) { + gchar *xml = (gchar *)url_config_list->data; + EPublishUri *url; + url = g_new0 (EPublishUri, 1); + url->type = PUB_ONLINE; + + e_pub_uri_from_xml (url, xml); + if (url->location) { + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + URL_LIST_ENABLED_COLUMN, + url->enabled, + URL_LIST_LOCATION_COLUMN, + url->location, + URL_LIST_URL_COLUMN, url, + -1); + } + + url_config_list = g_slist_next (url_config_list); + g_free (xml); + } + + g_slist_foreach (url_config_list, (GFunc) g_free, NULL); + g_slist_free (url_config_list); + + template_url = calendar_config_get_publish_template (); + gtk_entry_set_text (GTK_ENTRY (dialog_data->pub_template_url), template_url); + + g_free (template_url); +} + +static void +cal_prefs_dialog_pub_url_add_clicked (GtkWidget *button, DialogData *dialog_data) +{ + EPublishUri *url = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreeSelection *selection; + + model = gtk_tree_view_get_model (dialog_data->pub_url_list); + url = g_new0 (EPublishUri, 1); + url->enabled = TRUE; + url->location = ""; + + if (!dialog_data->publish_editor) { + dialog_data->publish_editor = publish_editor_dialog_new (dialog_data, + url); + + if (url->location != "") { + gtk_list_store_append(GTK_LIST_STORE (model), &iter); + gtk_list_store_set (GTK_LIST_STORE(model), &iter, + URL_LIST_ENABLED_COLUMN, + url->enabled, + URL_LIST_LOCATION_COLUMN, + g_strdup (url->location), + URL_LIST_URL_COLUMN, url, + -1); + + pub_url_list_changed (dialog_data); + + if (!GTK_WIDGET_SENSITIVE ( + (GtkWidget *) dialog_data->pub_url_remove)) { + selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->pub_url_list); + gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter); + gtk_widget_set_sensitive ((GtkWidget*) dialog_data->pub_url_remove, TRUE); + gtk_tree_selection_select_iter (selection, &iter); + } + } + dialog_data->publish_editor = FALSE; + dialog_data->publish_editor_dlg = NULL; + } else { + gdk_window_raise (dialog_data->publish_editor_dlg->window); + } +} + +static void +cal_prefs_dialog_pub_url_edit_clicked (GtkWidget *button, DialogData *dialog_data) +{ + if (!dialog_data->publish_editor) { + GtkTreeSelection *selection; + EPublishUri *url = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->pub_url_list); + if (gtk_tree_selection_get_selected (selection, &model, &iter)){ + gtk_tree_model_get (model, &iter, + URL_LIST_URL_COLUMN, + &url, + -1); + + } + + if (url) { + dialog_data->publish_editor = publish_editor_dialog_new (dialog_data, url); + + gtk_list_store_set ((GtkListStore *) model, &iter, + URL_LIST_LOCATION_COLUMN, + g_strdup (url->location), + URL_LIST_ENABLED_COLUMN, + url->enabled, + URL_LIST_URL_COLUMN, url, + -1); + + pub_url_list_changed (dialog_data); + + if (!GTK_WIDGET_SENSITIVE ((GtkWidget *) dialog_data->pub_url_remove)) { + selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->pub_url_list); + gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter); + gtk_widget_set_sensitive ((GtkWidget*) dialog_data->pub_url_remove, TRUE); + gtk_tree_selection_select_iter (selection, &iter); + } + dialog_data->publish_editor = FALSE; + dialog_data->publish_editor_dlg = NULL; + } + } else { + gdk_window_raise (dialog_data->publish_editor_dlg->window); + } +} + +static void +cal_prefs_dialog_pub_url_remove_clicked (GtkWidget *button, DialogData *dialog_data) +{ + EPublishUri *url = NULL; + GtkTreeSelection * selection; + GtkTreeModel *model; + GtkWidget *confirm; + GtkTreeIter iter; + int ans; + + selection = gtk_tree_view_get_selection (dialog_data->pub_url_list); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, + URL_LIST_URL_COLUMN, &url, + -1); + + /* make sure we have a valid account selected and that + we aren't editing anything... */ + if (url == NULL || dialog_data->publish_editor) + return; + + confirm = gtk_message_dialog_new (PREFS_WINDOW (dialog_data), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("Are you sure you want to remove this URL?")); + + button = gtk_button_new_from_stock (GTK_STOCK_YES); + gtk_button_set_label ((GtkButton *) button, _("Remove")); + gtk_dialog_add_action_widget ((GtkDialog *) confirm, (GtkWidget *) button, GTK_RESPONSE_YES); + gtk_widget_show ((GtkWidget *) button); + + button = gtk_button_new_from_stock (GTK_STOCK_NO); + gtk_button_set_label ((GtkButton *) button, _("Don't Remove")); + gtk_dialog_add_action_widget ((GtkDialog *) confirm, + (GtkWidget *) button, GTK_RESPONSE_NO); + + gtk_widget_show ((GtkWidget *) button); + + ans = gtk_dialog_run ((GtkDialog *) confirm); + gtk_widget_destroy (confirm); + + if (ans == GTK_RESPONSE_YES) { + int len; + + gtk_list_store_remove ((GtkListStore *) model, &iter); + + len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL); + if (len > 0) { + gtk_tree_selection_select_iter (selection, &iter); + } else { + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_edit), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_remove), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_enable), FALSE); + } + g_free(url); + pub_url_list_changed (dialog_data); + } +} + +static void +cal_prefs_dialog_pub_url_enable_clicked (GtkWidget *button, DialogData *dialog_data) +{ + EPublishUri *url = NULL; + GtkTreeSelection * selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection (dialog_data->pub_url_list); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, + URL_LIST_URL_COLUMN, &url, + -1); + url->enabled = !url->enabled; + + gtk_tree_selection_select_iter (selection, &iter); + + gtk_list_store_set ((GtkListStore *) model, &iter, + URL_LIST_ENABLED_COLUMN, url->enabled, + -1); + + gtk_button_set_label ((GtkButton *) dialog_data->pub_url_enable, + url->enabled ? _("Disable") : _("Enable")); + + pub_url_list_changed (dialog_data); + } +} + +static void +cal_prefs_dialog_pub_url_list_enable_toggled (GtkCellRendererToggle *renderer, + const char *path_string, + DialogData *dialog_data) +{ + GtkTreeSelection * selection; + EPublishUri *url = NULL; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_string (path_string); + model = gtk_tree_view_get_model (dialog_data->pub_url_list); + selection = gtk_tree_view_get_selection (dialog_data->pub_url_list); + + if (gtk_tree_model_get_iter (model, &iter, path)) { + gtk_tree_model_get (model, &iter, + URL_LIST_URL_COLUMN, &url, + -1); + + url->enabled = !url->enabled; + gtk_list_store_set((GtkListStore *) model, &iter, + URL_LIST_ENABLED_COLUMN, + url->enabled, -1); + + if (gtk_tree_selection_iter_is_selected (selection, &iter)) + gtk_button_set_label ((GtkButton *) dialog_data->pub_url_enable, + url->enabled ? _("Disable") : _("Enable")); + + pub_url_list_changed (dialog_data); + } + + gtk_tree_path_free (path); +} + +static void +cal_prefs_dialog_pub_url_list_double_click (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + DialogData *dialog_data) +{ + cal_prefs_dialog_pub_url_edit_clicked (NULL, dialog_data); +} + +static void +cal_prefs_dialog_pub_url_list_change (GtkTreeSelection *selection, + DialogData *dialog_data) +{ + EPublishUri *url = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + int state; + + state = gtk_tree_selection_get_selected (selection, &model, &iter); + if (state) { + gtk_tree_model_get (model, &iter, + URL_LIST_URL_COLUMN, &url, + -1); + + if (url->location && url->enabled) + gtk_button_set_label ((GtkButton *) dialog_data->pub_url_enable, _("Disable")); + else + gtk_button_set_label ((GtkButton *) dialog_data->pub_url_enable, _("Enable")); + } else { + gtk_widget_grab_focus (GTK_WIDGET (dialog_data->pub_url_add)); + } + + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_edit), state); + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_remove), state); + gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->pub_url_enable), state); +} + + /* Shows the current task list settings in the dialog */ static void show_task_list_config (DialogData *dialog_data) @@ -1027,6 +1468,9 @@ /* Free/Busy */ show_fb_config (dialog_data); + /* Online Publishing */ + show_publish_config (dialog_data); + /* Other page */ e_dialog_toggle_set (dialog_data->confirm_delete, calendar_config_get_confirm_delete ()); Index: calendar/gui/dialogs/cal-prefs-dialog.glade =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.glade,v retrieving revision 1.31 diff -u -u -r1.31 cal-prefs-dialog.glade --- calendar/gui/dialogs/cal-prefs-dialog.glade 26 Jan 2005 11:48:21 -0000 1.31 +++ calendar/gui/dialogs/cal-prefs-dialog.glade 24 Mar 2005 20:54:57 -0000 @@ -2012,6 +2012,479 @@ <property name="type">tab</property> </packing> </child> + + <child> + <widget class="GtkVBox" id="vbox19"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="label_yalign">0.5</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + + <child> + <widget class="GtkAlignment" id="alignment9"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">12</property> + <property name="bottom_padding">0</property> + <property name="left_padding">12</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox31"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="pub_url_list"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox20"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox5"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_START</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="pub_url_add"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment10"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox32"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="stock">gtk-add</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label64"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Add URL</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="pub_url_edit"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment11"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox33"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="stock">gtk-properties</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label65"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Edit</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="pub_url_remove"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="pub_url_enable"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">E_nable</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox6"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_START</property> + <property name="spacing">3</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label66"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkLabel" id="label67"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Publishing</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkFrame" id="frame4"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="label_yalign">0.5</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + + <child> + <widget class="GtkAlignment" id="alignment12"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">12</property> + <property name="bottom_padding">0</property> + <property name="left_padding">12</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkVBox" id="vbox21"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="hbox34"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label68"> + <property name="visible">True</property> + <property name="label" translatable="yes">Template:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="pub_template_url"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label69"> + <property name="visible">True</property> + <property name="label" translatable="yes"><i>%u and %d will be replaced by user and domain from the email address.</i></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">True</property> + <property name="selectable">False</property> + <property name="xalign">0.49</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkLabel" id="label70"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Default Server</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label63"> + <property name="visible">True</property> + <property name="label" translatable="yes">Online Publishing</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> </widget> <packing> <property name="padding">0</property> Index: calendar/gui/dialogs/cal-prefs-dialog.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.h,v retrieving revision 1.11 diff -u -u -r1.11 cal-prefs-dialog.h --- calendar/gui/dialogs/cal-prefs-dialog.h 18 Dec 2004 13:01:17 -0000 1.11 +++ calendar/gui/dialogs/cal-prefs-dialog.h 24 Mar 2005 20:54:57 -0000 @@ -42,7 +42,7 @@ enum { URL_LIST_ENABLED_COLUMN, URL_LIST_LOCATION_COLUMN, - URL_LIST_FREE_BUSY_URL_COLUMN, + URL_LIST_URL_COLUMN, URL_LIST_N_COLUMNS }; @@ -82,11 +82,20 @@ GtkTreeView *url_list; gboolean url_editor; GtkWidget* url_editor_dlg; - guint destroyed : 1; /* widgets for the Free/Busy template */ GtkWidget *template_url; - + + /* Widgets for the Online Publishing options */ + GtkWidget *pub_url_add; + GtkWidget *pub_url_edit; + GtkWidget *pub_url_remove; + GtkWidget *pub_url_enable; + GtkTreeView *pub_url_list; + gboolean publish_editor; + GtkWidget* publish_editor_dlg; + GtkWidget *pub_template_url; + /* Other page options */ GtkWidget *confirm_delete; GtkWidget *default_reminder; Index: calendar/gui/dialogs/url-editor-dialog.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/url-editor-dialog.c,v retrieving revision 1.7 diff -u -u -r1.7 url-editor-dialog.c --- calendar/gui/dialogs/url-editor-dialog.c 23 Feb 2005 18:56:57 -0000 1.7 +++ calendar/gui/dialogs/url-editor-dialog.c 24 Mar 2005 20:54:57 -0000 @@ -66,6 +66,7 @@ url_editor_dialog_new (DialogData *dialog_data, EPublishUri *uri) { int b; + char *password; UrlDialogData *url_dlg_data = g_new0 (UrlDialogData, 1); url_dlg_data->xml = glade_xml_new (EVOLUTION_GLADEDIR "/url-editor-dialog.glade", NULL, NULL); @@ -95,17 +96,19 @@ } } - uri->password = e_passwords_get_password ("Calendar", url_dlg_data->url_data->location); + password = e_passwords_get_password ("Calendar", url_dlg_data->url_data->location); - if (uri->password) { - if (strlen(uri->password) != 0) { + if (password) { + if (strlen(password) != 0) { gtk_entry_set_text (url_dlg_data->password_entry, - uri->password); + password); e_dialog_toggle_set (url_dlg_data->remember_pw, TRUE); } else { e_dialog_toggle_set (url_dlg_data->remember_pw, FALSE); } + g_free(password); + password = NULL; } switch (uri->publish_freq) { @@ -136,9 +139,9 @@ if ((GtkEntry *) url_dlg_data->url_entry) { url_editor_dialog_fb_url_activated (url_dlg_data->url_entry, url_dlg_data); url_dlg_data->url_data->username = g_strdup (gtk_entry_get_text ((GtkEntry *) url_dlg_data->username_entry)); - url_dlg_data->url_data->password = g_strdup (gtk_entry_get_text ((GtkEntry *) url_dlg_data->password_entry)); + password = g_strdup (gtk_entry_get_text ((GtkEntry *) url_dlg_data->password_entry)); if (e_dialog_toggle_get (url_dlg_data->remember_pw)) { - e_passwords_add_password (url_dlg_data->url_data->location, url_dlg_data->url_data->password); + e_passwords_add_password (url_dlg_data->url_data->location, password); e_passwords_remember_password ("Calendar", url_dlg_data->url_data->location); } else { e_passwords_forget_password ("Calendar", url_dlg_data->url_data->location); @@ -306,11 +309,10 @@ void *data) { UrlDialogData *url_dlg_data = (UrlDialogData *) data; - enum publish_frequency frequency; - frequency = e_dialog_radio_get (url_dlg_data->daily, + url_dlg_data->url_data->publish_freq = + e_dialog_radio_get (url_dlg_data->daily, pub_frequency_type_map); - url_dlg_data->url_data->publish_freq = frequency; gtk_widget_set_sensitive ((GtkWidget *) url_dlg_data->ok, TRUE); } Index: ui/evolution-calendar.xml =================================================================== RCS file: /cvs/gnome/evolution/ui/evolution-calendar.xml,v retrieving revision 1.69 diff -u -u -r1.69 evolution-calendar.xml --- ui/evolution-calendar.xml 16 Dec 2004 18:26:54 -0000 1.69 +++ ui/evolution-calendar.xml 24 Mar 2005 20:54:57 -0000 @@ -24,6 +24,7 @@ <cmd name="DeleteOccurrence" _tip="Delete this occurrence" pixtype="stock" pixname="gtk-delete"/> <cmd name="DeleteAllOccurrences" _tip="Delete All Occurrences" pixtype="stock" pixname="gtk-delete"/> + <cmd name="Publish" _tip="Publish this calendar to a remote server"/> <cmd name="PublishFreeBusy" _tip="Publish Free/Busy information for this calendar"/> <cmd name="CalendarPurge" _label="Purg_e" _tip="Purge old appointments and meetings" accel="*Control*e"/> </commands> @@ -70,6 +71,7 @@ <submenu name="Actions" _label="_Actions"> <placeholder name="ComponentActionsPlaceholder"> <separator/> + <menuitem name="Publish" verb="" _label="Publish this calendar to a remote server"/> <menuitem name="PublishFreeBusy" verb="" _label="_Publish Free/Busy Information"/> <menuitem name="CalendarPurge" verb=""/> </placeholder> --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ calendar/gui/dialogs/publish-editor-dialog.h 2005-03-24 14:52:34.828539816 +0000 @@ -0,0 +1,47 @@ +/* + * PublishDialog - a GObject that handles a libglade-loaded dialog to + * edit the online publishing settings of calendars. + */ + +#ifndef _PUBLISH_EDITOR_DIALOG_H_ +#define _PUBLISH_EDITOR_DIALOG_H_ + +G_BEGIN_DECLS + +#include <gtk/gtk.h> +#include <glade/glade.h> + +#include "cal-prefs-dialog.h" +#include <libedataserverui/e-source-selector.h> + +struct _PublishEditorDialogData { + GladeXML *xml; + DialogData *url_dialog; + GtkWidget *publish_editor; + + GtkEntry *url_entry; + GtkWidget *auto_publish; + GtkWidget *alarm_publish; + GtkWidget *scheme_combo; + + GtkWidget *calendar_list_label; + GtkWidget *scrolled_window; + GtkWidget *scrolled_window_todo; + + GtkEntry *username_entry; + GtkEntry *password_entry; + GtkWidget *no_pw; + GtkWidget *remember_pw; + + GtkWidget *cancel; + GtkWidget *ok; + EPublishUri *url_data; +}; +typedef struct _PublishEditorDialogData PublishEditorDialogData; + +gboolean +publish_editor_dialog_new (DialogData *dialog_data, EPublishUri *pub_uri); + +G_END_DECLS + +#endif /* _PUBLISH_EDITOR_DIALOG_H_ */ --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ calendar/gui/dialogs/publish-editor-dialog.c 2005-03-24 20:05:20.756685104 +0000 @@ -0,0 +1,472 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "cal-prefs-dialog.h" +#include "publish-editor-dialog.h" + +#include <libedataserverui/e-passwords.h> +#include <gtk/gtk.h> +#include <gtk/gtksignal.h> +#include <gtk/gtkoptionmenu.h> +#include <gtk/gtktogglebutton.h> +#include <libgnomeui/gnome-color-picker.h> +#include <libgnomevfs/gnome-vfs.h> +#include <glade/glade.h> +#include <e-util/e-dialog-widgets.h> +#include <e-util/e-icon-factory.h> +#include <widgets/misc/e-dateedit.h> +#include <stdlib.h> +#include <string.h> + +enum scheme { + LOCAL, HTTP, HTTPS, FTP, SSH +}; + +static gboolean get_widgets (PublishEditorDialogData *); +static void init_widgets (PublishEditorDialogData *); + +static void scheme_combo_changed (GtkComboBox *, gpointer); +static void url_changed (GtkEntry *, gpointer); +static void url_activated (GtkEntry *, gpointer); +static void ok_enable (GtkWidget *, gpointer); +static void auto_toggled(GtkWidget *, gpointer); +static void alarm_toggled(GtkWidget *, gpointer); +static void no_pw_toggled(GtkWidget *, gpointer); +static void selection_changed_callback (ESourceSelector *, gpointer); +static void selection_todo_changed_callback (ESourceSelector *, gpointer); + +/** + * publish_editor_dialog_new: + **/ +gboolean +publish_editor_dialog_new (DialogData *dialog_data, EPublishUri *uri) +{ + int b; + gboolean remember_pw = uri->remember_pw; + char *password; + + PublishEditorDialogData self; + self.xml = glade_xml_new(EVOLUTION_GLADEDIR "/publish-editor-dialog.glade", NULL, NULL); + if (!self.xml) { + g_message("publish_editor_dialog_new(): Could not load the .glade file!"); + return FALSE; + } + + if (!get_widgets(&self)) { + g_message ("publish_editor_dialog_new(): Could not find all the widgets in the .glade file!"); + return FALSE; + } + + self.url_dialog = dialog_data; + self.url_data = uri; + + if (self.url_data->type != PUB_ONLINE) + self.url_data->type = PUB_ONLINE; + + init_widgets(&self); + + /* check whether the URL is local or remote + * then update the combobox, which should update + * the url_entry and show/hide the authentication box */ + if (self.url_data->location) { + GnomeVFSURI *uri = gnome_vfs_uri_new(self.url_data->location); + + if(uri == NULL) { + g_message ("publish_editor_dialog_new(): " + "Malformed URI: %s", self.url_data->location); + goto next; + } + + if(gnome_vfs_uri_is_local(uri)) { + gtk_combo_box_set_active(GTK_COMBO_BOX(self.scheme_combo), + LOCAL); + } else { + const char *scheme_str = gnome_vfs_uri_get_scheme(uri); + if(strncasecmp(scheme_str, "http", 4) == 0) + gtk_combo_box_set_active( + GTK_COMBO_BOX(self.scheme_combo), + HTTP); + else if(strncasecmp(scheme_str, "https", 5) == 0) + gtk_combo_box_set_active( + GTK_COMBO_BOX(self.scheme_combo), + HTTPS); + else if(strncasecmp(scheme_str, "ftp", 3) == 0) + gtk_combo_box_set_active( + GTK_COMBO_BOX(self.scheme_combo), + FTP); + else if(strncasecmp(scheme_str, "sftp", 4) == 0) + gtk_combo_box_set_active( + GTK_COMBO_BOX(self.scheme_combo), + SSH); + + if (self.url_data->username && + (strlen(self.url_data->username) != 0)){ + gtk_entry_set_text(self.username_entry, + self.url_data->username); + } + /* passwords make sense only for a remote URL + * and only if no_pw was not set + */ + if (!self.url_data->no_pw) { + password = + e_passwords_get_password ("Calendar", + self.url_data->location); + if (password && (strlen(password) != 0)) { + gtk_entry_set_text(self.password_entry, password); + e_dialog_toggle_set(self.remember_pw, + self.url_data->remember_pw); + e_dialog_toggle_set(self.no_pw, FALSE); + } else { + e_dialog_toggle_set(self.remember_pw, FALSE); + e_dialog_toggle_set(self.no_pw, TRUE); + } + if(password) + g_free(password); + } + } + + if (strlen(self.url_data->location) != 0) { + gtk_entry_set_text (self.url_entry, + self.url_data->location); + } + + gnome_vfs_uri_unref(uri); + } +next: + dialog_data->publish_editor = TRUE; + dialog_data->publish_editor_dlg = (GtkWidget *) &self; + gtk_widget_set_sensitive ((GtkWidget *) self.ok, FALSE); + + b = gtk_dialog_run ((GtkDialog *) self.publish_editor); + + if (b == GTK_RESPONSE_OK) { + if ((GtkEntry *) self.url_entry) { + url_activated(self.url_entry, &self); + self.url_data->username = g_strdup(gtk_entry_get_text( + (GtkEntry *) self.username_entry)); + if((self.url_data->no_pw = + e_dialog_toggle_get(self.no_pw))) + ; + else { + password = gtk_entry_get_text(GTK_ENTRY(self.password_entry)); + if(password && (strlen(password) > 0)){ + e_passwords_add_password(self.url_data->location, password); + if (e_dialog_toggle_get(self.remember_pw)) + e_passwords_remember_password ("Calendar", self.url_data->location); + } + if (remember_pw ==TRUE && self.url_data->remember_pw == FALSE) + e_passwords_forget_password ("Calendar", self.url_data->location); + } + self.url_data->auto_publish = + e_dialog_toggle_get(self.auto_publish); + self.url_data->alarm_publish = + e_dialog_toggle_get(self.alarm_publish); + } + } + + gtk_widget_destroy (self.publish_editor); + g_object_unref (self.xml); + return FALSE; +} + +static gboolean +get_widgets (PublishEditorDialogData *data) +{ +#define GW(name) glade_xml_get_widget (data->xml, name) + + data->publish_editor = GW ("publish_editor"); + data->url_entry = GTK_ENTRY (GW ("url_entry_local")); + data->auto_publish = GW ("auto_publish"); + data->alarm_publish = GW ("alarm_publish"); + data->scheme_combo = GW ("scheme_combo"); + data->calendar_list_label = GW ("calendar_list_label"); + data->scrolled_window = GW ("scrolled_window"); + data->scrolled_window_todo = GW ("scrolled_window_todo"); + data->username_entry = GTK_ENTRY (GW ("username_entry")); + data->password_entry = GTK_ENTRY (GW ("password_entry")); + data->no_pw = GW ("no_pw"); + data->remember_pw = GW ("remember_pw"); + data->cancel = GW ("cancel"); + data->ok = GW ("ok"); + +#undef GW + + return (data ->publish_editor + && data->url_entry + && data->auto_publish + && data->alarm_publish + && data->scheme_combo + && data->calendar_list_label + && data->scrolled_window + && data->scrolled_window_todo + && data->username_entry + && data->password_entry + && data->no_pw + && data->remember_pw + && data->cancel + && data->ok); +} + +static void +selection_changed_callback (ESourceSelector *selector, + gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + GSList *selection = e_source_selector_get_selection (selector); + + if (selection != NULL) { + GSList *p, *l = NULL; + + for (p = selection; p != NULL; p = p->next) { + ESource *source = E_SOURCE(p->data); + gchar* source_uid = g_strdup(e_source_peek_uid(source)); + + l = g_slist_append(l, source_uid); + } + self->url_data->calendars = l; + } + + e_source_selector_free_selection(selection); + gtk_widget_set_sensitive ((GtkWidget *) self->ok, TRUE); +} + +static void +selection_todo_changed_callback (ESourceSelector *selector, + gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + GSList *selection = e_source_selector_get_selection (selector); + + if (selection != NULL) { + GSList *p, *l = NULL; + + for (p = selection; p != NULL; p = p->next) { + ESource *source = E_SOURCE(p->data); + gchar* source_uid = g_strdup(e_source_peek_uid(source)); + + l = g_slist_append(l, source_uid); + } + self->url_data->tasks = l; + } + + e_source_selector_free_selection(selection); + gtk_widget_set_sensitive ((GtkWidget *) self->ok, TRUE); +} + +/* Connects any necessary signal handlers. */ +static void +init_widgets (PublishEditorDialogData *self) +{ + ESourceList *source_list = e_source_list_new_for_gconf_default( + "/apps/evolution/calendar/sources"); + ESourceList *source_list_todo = e_source_list_new_for_gconf_default( + "/apps/evolution/tasks/sources"); + GtkWidget *selector = e_source_selector_new (source_list); + GtkWidget *selector_todo = e_source_selector_new (source_list_todo); + GList *icon_list; + + gtk_widget_ensure_style(self->publish_editor); + gtk_container_set_border_width(GTK_CONTAINER( + GTK_DIALOG(self->publish_editor)->vbox), 0); + gtk_container_set_border_width(GTK_CONTAINER( + GTK_DIALOG(self->publish_editor)->action_area), 12); + g_object_set(G_OBJECT(glade_xml_get_widget(self->xml, "gnome_entry")), + "filechooser-action", GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL); + g_signal_connect(self->scheme_combo, "changed", + G_CALLBACK(scheme_combo_changed), self); + g_signal_connect (glade_xml_get_widget(self->xml, "url_entry_local"), "changed", + G_CALLBACK(url_changed), self); + g_signal_connect (glade_xml_get_widget(self->xml, "url_entry_remote"), "changed", + G_CALLBACK(url_changed), self); + g_signal_connect (self->username_entry, "changed", + G_CALLBACK (ok_enable), self); + g_signal_connect (self->password_entry, "changed", + G_CALLBACK (ok_enable), self); + g_signal_connect (self->remember_pw, "toggled", + G_CALLBACK (ok_enable), self); + g_signal_connect (self->url_entry, "activate", + G_CALLBACK (url_activated), self); + g_signal_connect (self->auto_publish, "toggled", + G_CALLBACK (auto_toggled), self); + g_signal_connect (self->alarm_publish, "toggled", + G_CALLBACK (alarm_toggled), self); + g_signal_connect (self->no_pw, "toggled", + G_CALLBACK (no_pw_toggled), self); + + gtk_combo_box_set_active(GTK_COMBO_BOX(self->scheme_combo), HTTP); + + if (self->url_data->calendars) { + ESource *source; + GSList *p; + + for(p = self->url_data->calendars; p != NULL; p = p->next) { +#warning FIX this extra allocation + gchar *source_uid = g_strdup (p->data); + source = e_source_list_peek_source_by_uid(source_list, + source_uid); + e_source_selector_select_source( + (ESourceSelector *)selector, source); + g_free (source_uid); + } + } + + if (self->url_data->tasks) { + ESource *source; + GSList *p; + + for(p = self->url_data->tasks; p != NULL; p = p->next) { +#warning FIX this extra allocation + gchar *source_uid = g_strdup (p->data); + source = e_source_list_peek_source_by_uid(source_list_todo, + source_uid); + e_source_selector_select_source( + (ESourceSelector *)selector_todo, source); + g_free (source_uid); + } + } + + e_source_selector_show_selection ((ESourceSelector *) selector, TRUE); + g_signal_connect (selector, "selection_changed", + G_CALLBACK (selection_changed_callback), self); + + gtk_label_set_mnemonic_widget (GTK_LABEL(self->calendar_list_label), + selector); + gtk_widget_show (selector); + gtk_container_add (GTK_CONTAINER(self->scrolled_window), + selector); + + e_source_selector_show_selection ((ESourceSelector *) selector_todo, TRUE); + g_signal_connect (selector_todo, "selection_changed", + G_CALLBACK (selection_todo_changed_callback), self); + + gtk_label_set_mnemonic_widget (GTK_LABEL(self->calendar_list_label), + selector_todo); + gtk_widget_show (selector_todo); + gtk_container_add (GTK_CONTAINER(self->scrolled_window_todo), + selector_todo); + + icon_list = e_icon_factory_get_icon_list ("stock_calendar"); + if (icon_list) { + gtk_window_set_icon_list (GTK_WINDOW(self->publish_editor), icon_list); + g_list_foreach (icon_list, (GFunc) g_object_unref, NULL); + g_list_free (icon_list); + } + gtk_widget_show (self->scrolled_window); + gtk_widget_show (self->scrolled_window_todo); +} + +static void scheme_combo_changed (GtkComboBox *box, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + enum scheme i = gtk_combo_box_get_active(box); + GtkWidget *auth_box = glade_xml_get_widget(self->xml, "auth_box"); + GtkWidget *gnome_entry = glade_xml_get_widget(self->xml, "gnome_entry"); + GtkEntry *url_entry_remote = GTK_ENTRY(glade_xml_get_widget(self->xml, "url_entry_remote")); + switch(i) { + case LOCAL: + if(GTK_WIDGET_VISIBLE(GTK_WIDGET(url_entry_remote))) + gtk_widget_hide(GTK_WIDGET(url_entry_remote)); + if(!GTK_WIDGET_VISIBLE(gnome_entry)) + gtk_widget_show(gnome_entry); + if(GTK_WIDGET_VISIBLE(auth_box)) + gtk_widget_hide(auth_box); + self->url_entry = GTK_ENTRY(glade_xml_get_widget( + self->xml, "url_entry_local")); + e_dialog_toggle_set(self->no_pw, TRUE); + return; + break; + case HTTP: + gtk_entry_set_text(url_entry_remote, "http://"); + break; + case HTTPS: + gtk_entry_set_text(url_entry_remote, "https://"); + break; + case FTP: + gtk_entry_set_text(url_entry_remote, "ftp://"); + break; + case SSH: + gtk_entry_set_text(url_entry_remote, "sftp://"); + e_dialog_toggle_set(self->no_pw, TRUE); + break; + } + if(GTK_WIDGET_VISIBLE(gnome_entry)) + gtk_widget_hide(gnome_entry); + if(!GTK_WIDGET_VISIBLE(GTK_WIDGET(url_entry_remote))) + gtk_widget_show(GTK_WIDGET(url_entry_remote)); + if(!GTK_WIDGET_VISIBLE(auth_box)) + gtk_widget_show(auth_box); + self->url_entry = url_entry_remote; +} +static void +url_activated (GtkEntry *url_entry, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + + self->url_data->location = g_strdup (gtk_entry_get_text ((GtkEntry *) url_entry)); +} + +static void +url_changed (GtkEntry *url_entry, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + + const gchar *entry_contents; + GtkListStore *model; + GtkTreeIter iter; + gboolean valid; + + model = (GtkListStore *) gtk_tree_view_get_model (self->url_dialog->url_list); + + entry_contents = gtk_entry_get_text ((GtkEntry *) url_entry); + /* duplicate check */ + valid = gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter); + while (valid) { + gchar *url_name; + gtk_tree_model_get ((GtkTreeModel *) model, &iter, + URL_LIST_LOCATION_COLUMN, &url_name, + -1); + + if (!strcasecmp (url_name, entry_contents)) { + gtk_widget_set_sensitive ((GtkWidget *) self->ok, FALSE); + return; + } + valid = gtk_tree_model_iter_next ((GtkTreeModel *) model, &iter); + } + /* valid and unique */ + gtk_widget_set_sensitive (GTK_WIDGET (self->ok), TRUE); + gtk_widget_grab_default (GTK_WIDGET (self->ok)); + gtk_entry_set_activates_default ((GtkEntry*) self->url_entry, TRUE); +} + +static void ok_enable (GtkWidget *widget, gpointer data) { + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + + gtk_widget_set_sensitive (GTK_WIDGET(self->ok), TRUE); +} + +/* ToggleButtons callbacks, can do better than repeating the same function + * 5 times, no? Later + */ +static void auto_toggled(GtkWidget *button, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + self->url_data->auto_publish = e_dialog_toggle_get (button); + gtk_widget_set_sensitive (GTK_WIDGET(self->ok), TRUE); +} + +static void alarm_toggled(GtkWidget *button, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + self->url_data->alarm_publish = e_dialog_toggle_get (button); + gtk_widget_set_sensitive (GTK_WIDGET(self->ok), TRUE); +} + +static void no_pw_toggled(GtkWidget *button, gpointer data) +{ + PublishEditorDialogData *self = (PublishEditorDialogData *) data; + self->url_data->no_pw = e_dialog_toggle_get (button); + gtk_widget_set_sensitive(GTK_WIDGET(self->password_entry), !self->url_data->no_pw); + gtk_widget_set_sensitive(self->remember_pw , !self->url_data->no_pw); + gtk_widget_set_sensitive (GTK_WIDGET(self->ok), TRUE); +} --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ calendar/gui/dialogs/publish-editor-dialog.glade 2005-03-24 15:33:56.320295728 +0000 @@ -0,0 +1,694 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> +<requires lib="gnome"/> + +<widget class="GtkDialog" id="publish_editor"> + <property name="visible">True</property> + <property name="title" translatable="yes">Online Publishing Settings</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> + <property name="modal">False</property> + <property name="default_width">380</property> + <property name="default_height">508</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="has_separator">False</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="publish"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child internal-child="action_area"> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + + <child> + <widget class="GtkButton" id="cancel"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-cancel</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-6</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="ok"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-ok</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-5</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">GTK_PACK_END</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox2"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="calendar_list_label"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Calendars to publish:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="height_request">100</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolled_window"> + <property name="height_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label17"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Task lists to publish:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox10"> + <property name="height_request">90</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolled_window_todo"> + <property name="height_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox3"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkCheckButton" id="auto_publish"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Automatically publish changes</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox8"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkCheckButton" id="alarm_publish"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Publish calendar alarms</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox9"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="label" translatable="yes">Publish my calendar with</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBox" id="scheme_combo"> + <property name="visible">True</property> + <property name="items" translatable="yes">local +http +https +ftp +ssh</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Publishing URL:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkEntry" id="url_entry_remote"> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GnomeFileEntry" id="gnome_entry"> + <property name="visible">True</property> + <property name="history_id">publish_editor_dialog</property> + <property name="max_saved">10</property> + <property name="browse_dialog_title" translatable="yes">Choose a file to publish to</property> + <property name="directory_entry">False</property> + <property name="modal">True</property> + <property name="use_filechooser">True</property> + + <child internal-child="entry"> + <widget class="GtkEntry" id="url_entry_local"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="auth_box"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Authentication:</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="homogeneous">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + + <child> + <widget class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Username:</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">username_entry</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Password:</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">password_entry</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="username_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="password_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">False</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="remember_pw"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Remember password</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="no_pw"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">No password</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_padding">2</property> + <property name="x_options"></property> + <property name="y_options">fill</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface>
Attachment:
signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=