Re: [evolution-patches] Free/Busy Bounty rev 2
- From: Gary Ekker <gekker novell com>
- To: Rodrigo Moya <rodrigo ximian com>
- Cc: evolution-patches lists ximian com
- Subject: Re: [evolution-patches] Free/Busy Bounty rev 2
- Date: Mon, 12 Jan 2004 11:34:34 -0700
On Mon, 2004-01-12 at 16:29 +0100, Rodrigo Moya wrote:
> On Sun, 2004-01-11 at 21:38 -0700, Gary Ekker wrote:
> > I have attached a new revision of the patch to the bug:
> >
> > http://bugzilla.gnome.org/show_bug.cgi?id=127539
> >
> > My ISP's ftp server is down, so I didn't post any screenshots. Hopefully
> > this is the final revision. It will now check to see if it needs to
> > publish, and do so if it has been more than a day or week depending on
> > what the user has set. It will also publish after the the settings have
> > been changed. Additionaly you can arbitrarily publish with the Actions
> > menu or the pop-up menu.
> >
> > Automatic publishing is set up in calendar-component.c: createControls.
> > It occured to me that it may be good to only check to publish on the
> > initial creation of the component and then remove the callback with
> > g_idle_remove rather than have it continue to try, the code to do this
> > is there, but commented out. This would especially be good if the server
> > to which the user is publishing is down. Thoughts?
> >
> but if you remove the g_idle handler, how would you publish again, in
> the next hour or day?
After further thought on this, i agree, it should not be removed.
Fixed.
> more comments below
>
> > +static gboolean
> > +init_calendar_publishing_cb (gpointer data)
> > +{
> > +#if 0
> > + guint *idle_id = (guint *) data;
> > +
> > + /* remove the idle function--We could do this so that it runs
> once
> > + on each startup */
> > + g_source_remove (*idle_id);
> > + g_free (idle_id);
> > +#endif
> >
> returning FALSE on the callback will disable calling it again, so there
> is no need to g_source_remove it.
>
> > + idle_id = g_new0 (guint, 1);
> > + *idle_id = g_idle_add ((GSourceFunc)
> init_calendar_publishing_cb, idle_id);
> >
> instead of allocating memory, you can pass the integer as 'user_data' by
> using GINT_TO_POINTER. Then, you can retrieve it with GPOINTER_TO_INT,
> in the callback.
>
> > + 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,
> > +
> ICAL_FREEBUSY_PROPERTY))
> > + {
> > + icalproperty *p;
> > +
> > + p = icalproperty_new_clone (prop);
> > + icalcomponent_add_property
> (icomp_clone, p);
> > + }
> >
> what is this 'for' loop for? You are adding the properties from the
> component you already cloned.
>
There are two components here. What this function does it aggregate the
data. So if we are getting Free/Busy from multiple calendars, this is
called once for each ESource and the FB properties are all added to one
component. If there still seems to be a problem here given that
information, let me know. I can't think of another way to accomplish
this right now.
> > + /* Publish the component */
> > + session = soup_session_async_new ();
> >
> you should probably free the session before returning from
> itip_publish_comp. There are a few places where the function returns
> that needs memory to be freed.
>
Done. Thanks for the suggestions. Attached is the latest revision.
> cheers
? free-busy.diff
? free-busy2.diff
? free-busy3.diff
? name
? common/Makefile
? common/Makefile.in
? gui/apps_evolution_calendar-1.5.schemas
? gui/e-pub-utils.c
? gui/e-pub-utils.h
? gui/fb-utils.c
? gui/fb-utils.h
? gui/dialogs/cal-prefs-dialog.gladep
? gui/dialogs/fb-editor.glade
? gui/dialogs/fb-editor.gladep
? gui/dialogs/url-editor-dialog.c
? gui/dialogs/url-editor-dialog.glade
? gui/dialogs/url-editor-dialog.gladep
? gui/dialogs/url-editor-dialog.h
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2058
diff -u -r1.2058 ChangeLog
--- ChangeLog 9 Jan 2004 20:49:37 -0000 1.2058
+++ ChangeLog 12 Jan 2004 18:27:08 -0000
@@ -1,3 +1,66 @@
+2004-01-11 Gary Ekker <gekker novell com>
+
+ * gui/Makefile.am: add SOUP_CFLAGS, SOUP_LIBS, and fb-utils.[ch]
+ for Free/Busy publishing
+
+ * gui/apps_evolution_calendar.schemas.in.in: add schema for
+ /apps/evo/calendar/free_busy key
+
+ * gui/calendar-commands.c (publish_freebusy_cmd): change to
+ publish component rather than attach as email
+
+ * gui/calendar-config-keys.h: add free_busy/urls key definition
+
+ * gui/calendar-config.[ch] (calendar_config_get_free_busy): new
+ method for retrieving FB gconf key
+ (calendar_config_set_free_busy): new method for saving FB
+ gconf key
+
+ * gui/e-cal-view.c (on_publish): change to publish component
+ rather than attach as email
+
+ * gui/itip-utils.[ch] (itip_publish_begin): new method to process
+ e_cal_components and aggregate the data if we are publishing
+ for multiple calendars
+ (itip_publish_comp): new method to publish the ical data to an
+ http server via libsoup
+ (comp_fb_normalize): new static method to ensure rfc 2446 compliant
+ data before publishing icalcomponent_get_uid
+ (fb_sort): new static method to sort FB properties in ascending order
+
+ * gui/dialogs/Makefile.am: add url-editor-dialog.[ch] and
+ url-editor-dialog.glade for configure FB publishing
+
+ * gui/dialogs/cal-prefs-dialog.[ch] (cal_prefs_dialog_url_add_clicked):
+ (cal_prefs_dialog_url_edit_clicked):new method for events in FB tab
+ of cal-prefs-dialog
+ (cal_prefs_dialog_url_remove_clicked): ditto
+ (cal_prefs_dialog_url_enable_clicked): ditto
+ (cal_prefs_dialog_url_url_list_change): ditto
+ (cal_prefs_dialog_url_url_list_enable_toggled): ditto
+ (cal_prefs_dialog_url_url_list_double_click): ditto
+ (show_fb_config): new method for updating dialog with FB specific
+ data in gconf
+ (update_fb_config): new method for updating gconf with FB specific
+ data from dialogs
+ (setup_changes): detect changes in url_list gtk_tree_view
+ (get_widgets): include new dialog widgets for FB config
+ (init_widgets): connect signals for new FB config widgets
+
+ * gui/dialogs/cal-prefs-dialog.glade: add new widgets for FB config
+
+ * gui/dialogs/url-editor-dialog.[ch]: add files for FB url-editor dialog
+
+ * gui/dialogs/url-editor-dialog.glade: ditto
+
+ * gui/e-pub-utils.[ch]: add files with FB publishing utilities
+
+ * gui/calendar-component.c (init_calendar_publishing): sets up
+ listeners to publish calendar, g_idle_add, and on gconf change
+ (init_calendar_publishing_cb): ditto
+ (conf_changed_callback): ditto
+ (impl_createControls): ditto
+
2004-01-09 Hans Petter Jansson <hpj ximian com>
* gui/calendar-component.c (new_calendar_cb): calendar_config ->
Index: gui/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/Makefile.am,v
retrieving revision 1.290
diff -u -r1.290 Makefile.am
--- gui/Makefile.am 22 Dec 2003 15:57:20 -0000 1.290
+++ gui/Makefile.am 12 Jan 2004 18:27:08 -0000
@@ -166,6 +166,8 @@
e-meeting-utils.h \
e-mini-calendar-config.c \
e-mini-calendar-config.h \
+ e-pub-utils.c \
+ e-pub-utils.h \
e-select-names-editable.c \
e-select-names-editable.h \
e-select-names-renderer.c \
Index: gui/apps_evolution_calendar.schemas.in.in
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/apps_evolution_calendar.schemas.in.in,v
retrieving revision 1.1
diff -u -r1.1 apps_evolution_calendar.schemas.in.in
--- gui/apps_evolution_calendar.schemas.in.in 2 Dec 2003 15:55:45 -0000 1.1
+++ gui/apps_evolution_calendar.schemas.in.in 12 Jan 2004 18:27:08 -0000
@@ -355,5 +355,17 @@
<short>Programs that can run as part of alarms</short>
</locale>
</schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/publish/uris</key>
+ <applyto>/apps/evolution/calendar/publish/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>
</schemalist>
</gconfschemafile>
Index: gui/calendar-commands.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-commands.c,v
retrieving revision 1.141
diff -u -r1.141 calendar-commands.c
--- gui/calendar-commands.c 9 Jan 2004 19:50:08 -0000 1.141
+++ gui/calendar-commands.c 12 Jan 2004 18:27:08 -0000
@@ -60,6 +60,7 @@
#include "print.h"
#include "dialogs/cal-prefs-dialog.h"
#include "itip-utils.h"
+#include "e-pub-utils.h"
#include "evolution-shell-component-utils.h"
/* Focusing information for the calendar view. We have to keep track of this
@@ -319,36 +320,7 @@
static void
publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
{
- GnomeCalendar *gcal;
- GList *client_list, *cl;
- GList *comp_list = NULL;
- icaltimezone *utc;
- time_t start = time (NULL), end;
-
- gcal = GNOME_CALENDAR (data);
-
- utc = icaltimezone_get_utc_timezone ();
- start = time_day_begin_with_zone (start, utc);
- end = time_add_week_with_zone (start, 6, utc);
-
- /* FIXME Should we aggregate the data? */
- client_list = e_cal_model_get_client_list (gnome_calendar_get_calendar_model (gcal));
- for (cl = client_list; cl != NULL; cl = cl->next) {
- if (e_cal_get_free_busy ((ECal *) cl->data, NULL, start, end, &comp_list, NULL)) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- ECalComponent *comp = E_CAL_COMPONENT (l->data);
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, (ECal *) cl->data, NULL);
-
- g_object_unref (comp);
- }
-
- g_list_free (comp_list);
- }
- }
-
- g_list_free (client_list);
+ e_pub_publish (TRUE);
}
static void
Index: gui/calendar-component.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-component.c,v
retrieving revision 1.130
diff -u -r1.130 calendar-component.c
--- gui/calendar-component.c 9 Jan 2004 20:49:38 -0000 1.130
+++ gui/calendar-component.c 12 Jan 2004 18:27:09 -0000
@@ -30,6 +30,8 @@
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-i18n.h>
#include <bonobo/bonobo-exception.h>
+#include "e-pub-utils.h"
+#include "calendar-config-keys.h"
#include "calendar-config.h"
#include "calendar-component.h"
#include "calendar-commands.h"
@@ -59,6 +61,7 @@
char *config_directory;
GConfClient *gconf_client;
+ int gconf_notify_id;
ESourceList *source_list;
GSList *source_selection;
@@ -436,6 +439,25 @@
update_primary_selection (data);
}
+static gboolean
+init_calendar_publishing_cb (gpointer data)
+{
+ /* Publish if it is time to publish again */
+ e_pub_publish (FALSE);
+
+ return TRUE;
+}
+
+static void
+conf_changed_callback (GConfClient *client,
+ unsigned int connection_id,
+ GConfEntry *entry,
+ void *user_data)
+{
+ /* publish config changed, so publish */
+ e_pub_publish (TRUE);
+}
+
/* GObject methods. */
static void
@@ -589,6 +611,25 @@
}
static void
+init_calendar_publishing (CalendarComponent *calendar_component)
+{
+ guint *idle_id;
+ CalendarComponentPrivate *priv;
+
+ priv = calendar_component->priv;
+
+ gconf_client_add_dir (priv->gconf_client, CALENDAR_CONFIG_PUBLISH, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
+ priv->gconf_notify_id
+ = gconf_client_notify_add (priv->gconf_client, CALENDAR_CONFIG_PUBLISH,
+ (GConfClientNotifyFunc) conf_changed_callback, NULL,
+ NULL, NULL);
+
+ idle_id = g_new0 (guint, 1);
+ *idle_id = g_idle_add ((GSourceFunc) init_calendar_publishing_cb, GINT_TO_POINTER (idle_id));
+}
+
+static void
impl_createControls (PortableServer_Servant servant,
Bonobo_Control *corba_sidebar_control,
Bonobo_Control *corba_view_control,
@@ -636,6 +677,9 @@
e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget));
statusbar_control = bonobo_control_new (statusbar_widget);
+ /* Initialize Calendar Publishing */
+ init_calendar_publishing(calendar_component);
+
/* connect after setting the initial selections, or we'll get unwanted calls
to calendar_control_sensitize_calendar_commands */
g_signal_connect_object (priv->source_selector, "selection_changed",
Index: gui/calendar-config-keys.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config-keys.h,v
retrieving revision 1.4
diff -u -r1.4 calendar-config-keys.h
--- gui/calendar-config-keys.h 3 Dec 2003 16:37:22 -0000 1.4
+++ gui/calendar-config-keys.h 12 Jan 2004 18:27:09 -0000
@@ -70,6 +70,9 @@
#define CALENDAR_CONFIG_DEFAULT_REMINDER_INTERVAL CALENDAR_CONFIG_PREFIX "/other/default_reminder_interval"
#define CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/default_reminder_units"
+/* Free/Busy settings */
+#define CALENDAR_CONFIG_PUBLISH CALENDAR_CONFIG_PREFIX"/publish/uris"
+
G_END_DECLS
#endif
Index: gui/calendar-config.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.c,v
retrieving revision 1.65
diff -u -r1.65 calendar-config.c
--- gui/calendar-config.c 14 Dec 2003 23:57:08 -0000 1.65
+++ gui/calendar-config.c 12 Jan 2004 18:27:09 -0000
@@ -1025,3 +1025,16 @@
return sexp;
}
+GSList *
+calendar_config_get_free_busy(void)
+{
+ return gconf_client_get_list (config, CALENDAR_CONFIG_PUBLISH,
+ GCONF_VALUE_STRING, NULL);
+}
+
+void
+calendar_config_set_free_busy (GSList *url_list)
+{
+ gconf_client_set_list (config, CALENDAR_CONFIG_PUBLISH,
+ GCONF_VALUE_STRING, url_list, NULL);
+}
Index: gui/calendar-config.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.h,v
retrieving revision 1.30
diff -u -r1.30 calendar-config.h
--- gui/calendar-config.h 19 Nov 2003 03:55:31 -0000 1.30
+++ gui/calendar-config.h 12 Jan 2004 18:27:09 -0000
@@ -202,6 +202,9 @@
CalUnits calendar_config_get_default_reminder_units (void);
void calendar_config_set_default_reminder_units (CalUnits units);
+/* Free/Busy Settings */
+GSList * calendar_config_get_free_busy(void);
+void calendar_config_set_free_busy(GSList * url_list);
/* Convenience functions to configure common properties of ECalendar,
EDateEdit & ECalendarTable widgets, and the ECellDateEdit ETable cell. */
Index: gui/e-cal-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-view.c,v
retrieving revision 1.29
diff -u -r1.29 e-cal-view.c
--- gui/e-cal-view.c 9 Jan 2004 07:48:29 -0000 1.29
+++ gui/e-cal-view.c 12 Jan 2004 18:27:11 -0000
@@ -41,6 +41,7 @@
#include "e-cal-view.h"
#include "e-comp-editor-registry.h"
#include "itip-utils.h"
+#include "e-pub-utils.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
#include "dialogs/event-editor.h"
@@ -1127,34 +1128,7 @@
static void
on_publish (GtkWidget *widget, gpointer user_data)
{
- ECalendarView *cal_view;
- icaltimezone *utc;
- time_t start = time (NULL), end;
- GList *comp_list = NULL, *client_list, *cl;
-
- cal_view = E_CALENDAR_VIEW (user_data);
-
- utc = icaltimezone_get_utc_timezone ();
- start = time_day_begin_with_zone (start, utc);
- end = time_add_week_with_zone (start, 6, utc);
-
- client_list = e_cal_model_get_client_list (cal_view->priv->model);
- for (cl = client_list; cl != NULL; cl = cl->next) {
- if (e_cal_get_free_busy ((ECal *) cl->data, NULL, start, end, &comp_list, NULL)) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- ECalComponent *comp = E_CAL_COMPONENT (l->data);
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, (ECal *) cl->data, NULL);
-
- g_object_unref (comp);
- }
-
- g_list_free (comp_list);
- }
- }
-
- g_list_free (client_list);
+ e_pub_publish (TRUE);
}
static void
Index: gui/itip-utils.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/itip-utils.c,v
retrieving revision 1.84
diff -u -r1.84 itip-utils.c
--- gui/itip-utils.c 1 Dec 2003 22:14:20 -0000 1.84
+++ gui/itip-utils.c 12 Jan 2004 18:27:12 -0000
@@ -37,6 +37,10 @@
#include <e-util/e-time-utils.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-util.h>
+#include <libsoup/soup-session-async.h>
+#include <libsoup/soup-message.h>
+#include <libsoup/soup-uri.h>
+#include "e-util/e-passwords.h"
#include "calendar-config.h"
#include "itip-utils.h"
@@ -977,3 +981,217 @@
return retval;
}
+gboolean
+itip_publish_begin (ECalComponent *pub_comp, ECal *client,
+ 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 (!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,
+ ICAL_FREEBUSY_PROPERTY))
+ {
+ icalproperty *p;
+
+ p = icalproperty_new_clone (prop);
+ icalcomponent_add_property (icomp_clone, p);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+fb_sort (struct icalperiodtype *ipt, int fb_count)
+{
+ int i,j;
+
+ if (ipt == NULL || fb_count == 0)
+ return;
+
+ for (i = 0; i < fb_count-1; i++) {
+ for (j = i+1; j < fb_count; j++) {
+ struct icalperiodtype temp;
+
+ if (icaltime_compare(ipt[i].start, ipt[j].start) < 0)
+ continue;
+
+ if (icaltime_compare(ipt[i].start, ipt[j].start) == 0){
+ if (icaltime_compare(ipt[i].end,
+ ipt[j].start) < 0)
+ continue;
+ }
+ temp = ipt[i];
+ ipt[i] = ipt[j];
+ ipt[j] = temp;
+ }
+ }
+}
+
+static icalcomponent *
+comp_fb_normalize (icalcomponent *icomp)
+{
+ icalcomponent *iclone;
+ icalproperty *prop, *p;
+ const char *uid, *comment;
+ struct icaltimetype itt;
+ int fb_count, i = 0, j;
+ struct icalperiodtype *ipt;
+
+ iclone = icalcomponent_new (ICAL_VFREEBUSY_COMPONENT);
+
+ prop = icalcomponent_get_first_property (icomp,
+ ICAL_ORGANIZER_PROPERTY);
+ p = icalproperty_new_clone (prop);
+ icalcomponent_add_property (iclone, p);
+
+ itt = icalcomponent_get_dtstart (icomp);
+ icalcomponent_set_dtstart(iclone, itt);
+
+ itt = icalcomponent_get_dtend (icomp);
+ icalcomponent_set_dtend (iclone, itt);
+
+ fb_count = icalcomponent_count_properties (icomp,
+ ICAL_FREEBUSY_PROPERTY);
+ ipt = g_new0(struct icalperiodtype, fb_count+1);
+
+ for (prop = icalcomponent_get_first_property (icomp,
+ ICAL_FREEBUSY_PROPERTY);
+ prop != NULL;
+ prop = icalcomponent_get_next_property (icomp,
+ ICAL_FREEBUSY_PROPERTY))
+ {
+ ipt[i] = icalproperty_get_freebusy(prop);
+ i++;
+ }
+
+ fb_sort (ipt, fb_count);
+
+ for (j = 0; j <= fb_count-1; j++) {
+ icalparameter *param;
+
+ prop = icalproperty_new_freebusy (ipt[j]);
+ param = icalparameter_new_fbtype (ICAL_FBTYPE_BUSY);
+ icalproperty_add_parameter (prop, param);
+ icalcomponent_add_property (iclone, prop);
+ }
+ g_free (ipt);
+
+ /* Should I strip this RFC 2446 says there must not be a UID
+ if the METHOD is PUBLISH?? */
+ uid = icalcomponent_get_uid(icomp);
+ if (uid)
+ icalcomponent_set_uid (iclone, uid);
+
+ itt = icaltime_from_timet_with_zone (time (NULL), FALSE,
+ icaltimezone_get_utc_timezone ());
+ icalcomponent_set_dtstamp (iclone, itt);
+
+ prop = icalcomponent_get_first_property (icomp, ICAL_URL_PROPERTY);
+ p = icalproperty_new_clone (prop);
+ icalcomponent_add_property (iclone, p);
+
+ comment = icalcomponent_get_comment(icomp);
+ if (comment)
+ icalcomponent_set_comment(iclone, comment);
+
+ for (prop = icalcomponent_get_first_property (icomp, ICAL_X_PROPERTY);
+ prop != NULL;
+ prop = icalcomponent_get_next_property (icomp, ICAL_X_PROPERTY))
+ {
+ p = icalproperty_new_clone (prop);
+ icalcomponent_add_property (iclone, p);
+ }
+
+ return iclone;
+
+ g_object_unref (iclone);
+ return NULL;
+}
+
+gboolean
+itip_publish_comp (ECal *client, gchar *uri, gchar *username,
+ gchar *password, ECalComponent **pub_comp)
+{
+ icalcomponent *toplevel = NULL, *icalcomp = NULL;
+ icalcomponent *icomp = NULL;
+ SoupSession *session;
+ SoupMessage *msg;
+ SoupUri *real_uri;
+ char *ical_string;
+ char *prompt;
+ gboolean remember = FALSE;
+
+ 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);
+
+ icomp = comp_fb_normalize (icalcomp);
+
+ icalcomponent_add_component (toplevel, icomp);
+ ical_string = icalcomponent_as_ical_string (toplevel);
+
+ /* Publish the component */
+ session = soup_session_async_new ();
+
+ /* add username and password to the uri */
+ if (strlen(password) == 0) {
+ prompt = g_strdup_printf (_("Enter the password for %s"), uri);
+ password = e_passwords_ask_password (_("Enter password"),
+ "Calendar", NULL,
+ prompt, TRUE,
+ E_PASSWORDS_DO_NOT_REMEMBER,
+ &remember, NULL);
+
+ g_free (prompt);
+ }
+
+ real_uri = soup_uri_new(uri);
+ if (!real_uri) {
+ g_warning (G_STRLOC ": Invalid URL: %s", uri);
+ 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");
+ 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));
+ return FALSE;
+ }
+
+ soup_uri_free (real_uri);
+ g_object_unref (session);
+
+ return TRUE;
+}
Index: gui/itip-utils.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/itip-utils.h,v
retrieving revision 1.15
diff -u -r1.15 itip-utils.h
--- gui/itip-utils.h 7 Nov 2003 05:52:00 -0000 1.15
+++ gui/itip-utils.h 12 Jan 2004 18:27:12 -0000
@@ -31,5 +31,10 @@
gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *comp,
ECal *client, icalcomponent *zones);
+gboolean itip_publish_comp (ECal *client, gchar* uri, gchar* username,
+ gchar* password, ECalComponent **pub_comp);
+
+gboolean itip_publish_begin (ECalComponent *pub_comp, ECal *client,
+ gboolean cloned, ECalComponent **clone);
#endif
Index: gui/dialogs/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/Makefile.am,v
retrieving revision 1.58
diff -u -r1.58 Makefile.am
--- gui/dialogs/Makefile.am 9 Jan 2004 20:49:39 -0000 1.58
+++ gui/dialogs/Makefile.am 12 Jan 2004 18:27:12 -0000
@@ -78,7 +78,9 @@
task-details-page.c \
task-details-page.h \
task-page.c \
- task-page.h
+ task-page.h \
+ url-editor-dialog.c \
+ url-editor-dialog.h
glade_DATA = \
alarm-options.glade \
@@ -91,8 +93,8 @@
recurrence-page.glade \
schedule-page.glade \
task-details-page.glade \
- task-page.glade
-
+ task-page.glade \
+ url-editor-dialog.glade
CLEANFILES = $(BUILT_SOURCES)
Index: gui/dialogs/cal-prefs-dialog.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.c,v
retrieving revision 1.31
diff -u -r1.31 cal-prefs-dialog.c
--- gui/dialogs/cal-prefs-dialog.c 18 Nov 2003 04:24:25 -0000 1.31
+++ gui/dialogs/cal-prefs-dialog.c 12 Jan 2004 18:27:13 -0000
@@ -34,10 +34,16 @@
#include "../e-timezone-entry.h"
#include "cal-prefs-dialog.h"
#include "../calendar-config.h"
+#include "url-editor-dialog.h"
+#include <gtk/gtk.h>
+#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkoptionmenu.h>
#include <gtk/gtktogglebutton.h>
+#include <libxml/tree.h>
+#include <string.h>
+#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-color-picker.h>
#include <glade/glade.h>
#include <gal/util/e-util.h>
@@ -45,40 +51,6 @@
#include <widgets/misc/e-dateedit.h>
-struct _DialogData {
- /* Glade XML data */
- GladeXML *xml;
-
- GtkWidget *page;
-
- GtkWidget *timezone;
- GtkWidget *working_days[7];
- GtkWidget *week_start_day;
- GtkWidget *start_of_day;
- GtkWidget *end_of_day;
- GtkWidget *use_12_hour;
- GtkWidget *use_24_hour;
- GtkWidget *time_divisions;
- GtkWidget *show_end_times;
- GtkWidget *compress_weekend;
- GtkWidget *dnav_show_week_no;
-
- /* Widgets for the task list options */
- GtkWidget *tasks_due_today_color;
- GtkWidget *tasks_overdue_color;
-
- GtkWidget *tasks_hide_completed_checkbutton;
- GtkWidget *tasks_hide_completed_spinbutton;
- GtkWidget *tasks_hide_completed_optionmenu;
-
- /* Other page options */
- GtkWidget *confirm_delete;
- GtkWidget *default_reminder;
- GtkWidget *default_reminder_interval;
- GtkWidget *default_reminder_units;
-};
-typedef struct _DialogData DialogData;
-
static const int week_start_day_map[] = {
1, 2, 3, 4, 5, 6, 0, -1
};
@@ -96,7 +68,6 @@
CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1
};
-
static gboolean get_widgets (DialogData *data);
static void widget_changed_callback (GtkWidget *, void *data);
@@ -115,8 +86,23 @@
static void cal_prefs_dialog_start_of_day_changed (GtkWidget *button, void *data);
static void cal_prefs_dialog_hide_completed_tasks_toggled (GtkWidget *button, void *data);
+static void cal_prefs_dialog_url_add_clicked(GtkWidget *button, void *data);
+static void cal_prefs_dialog_url_edit_clicked(GtkWidget *button, void *data);
+static void cal_prefs_dialog_url_remove_clicked(GtkWidget *button, void *data);
+static void cal_prefs_dialog_url_enable_clicked(GtkWidget *button, void *data);
+static void cal_prefs_dialog_url_list_change (GtkTreeSelection *selection,
+ DialogData *dialog_data);
+static void cal_prefs_dialog_url_list_enable_toggled (GtkCellRendererToggle *renderer, const char *path_string, void *data);
+static void cal_prefs_dialog_url_list_double_click(GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ DialogData *dialog_data);
+static void show_fb_config (DialogData *dialog_data);
+static void update_fb_config (DialogData *dialog_data);
+
GtkWidget *cal_prefs_dialog_create_time_edit (void);
+#define PREFS_WINDOW(dialog_data) GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (dialog_data), GTK_TYPE_WINDOW))
/**
* cal_prefs_dialog_new:
@@ -233,6 +219,8 @@
connect_changed (dialog_data->default_reminder_interval, "changed", config_control);
connect_changed (GTK_OPTION_MENU (dialog_data->default_reminder_units)->menu, "selection_done", config_control);
+ connect_changed ((GtkWidget *) gtk_tree_view_get_selection (dialog_data->url_list), "changed", config_control);
+
/* These use GnomeColorPicker so we have to use a different signal. */
g_signal_connect((dialog_data->tasks_due_today_color), "color_set",
G_CALLBACK (color_set_callback), config_control);
@@ -282,6 +270,12 @@
data->default_reminder = GW ("default-reminder");
data->default_reminder_interval = GW ("default-reminder-interval");
data->default_reminder_units = GW ("default-reminder-units");
+
+ data->url_add = GW ("url_add");
+ data->url_edit = GW ("url_edit");
+ data->url_remove = GW ("url_remove");
+ data->url_enable = GW ("url_enable");
+ data->url_list = GTK_TREE_VIEW (GW ("url_list"));
#undef GW
@@ -311,7 +305,12 @@
&& data->confirm_delete
&& data->default_reminder
&& data->default_reminder_interval
- && data->default_reminder_units);
+ && data->default_reminder_units
+ && data->url_add
+ && data->url_edit
+ && data->url_remove
+ && data->url_enable
+ && data->url_list);
}
@@ -361,6 +360,13 @@
static void
init_widgets (DialogData *dialog_data)
{
+ GtkCellRenderer *renderer = NULL;
+ GtkTreeSelection *selection;
+ GtkListStore *model;
+
+ dialog_data->url_editor = FALSE;
+ dialog_data->url_editor_dlg =NULL;
+
g_signal_connect((dialog_data->use_24_hour), "toggled",
G_CALLBACK (cal_prefs_dialog_use_24_hour_toggled),
dialog_data);
@@ -377,8 +383,65 @@
"toggled",
G_CALLBACK (cal_prefs_dialog_hide_completed_tasks_toggled),
dialog_data);
-}
+
+ /* Free/Busy ... */
+ g_signal_connect((dialog_data->url_add), "clicked",
+ G_CALLBACK (cal_prefs_dialog_url_add_clicked),
+ dialog_data);
+
+ g_signal_connect((dialog_data->url_edit), "clicked",
+ G_CALLBACK (cal_prefs_dialog_url_edit_clicked),
+ dialog_data);
+ g_signal_connect((dialog_data->url_remove), "clicked",
+ G_CALLBACK (cal_prefs_dialog_url_remove_clicked),
+ dialog_data);
+
+ g_signal_connect((dialog_data->url_enable), "clicked",
+ G_CALLBACK (cal_prefs_dialog_url_enable_clicked),
+ dialog_data);
+
+ /* Free/Busy 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->url_list,
+ (GtkTreeModel *) model);
+
+ gtk_tree_view_insert_column_with_attributes (dialog_data->url_list, -1,
+ _("Enabled"), renderer,
+ "active",
+ URL_LIST_ENABLED_COLUMN,
+ NULL);
+
+ g_signal_connect(renderer, "toggled",
+ G_CALLBACK (cal_prefs_dialog_url_list_enable_toggled),
+ dialog_data);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(dialog_data->url_list, -1,
+ _("Location"), renderer,
+ "text",
+ URL_LIST_LOCATION_COLUMN,
+ NULL);
+
+ selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->url_list);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ gtk_tree_view_set_headers_visible ((GtkTreeView *) dialog_data->url_list, TRUE);
+
+
+ g_signal_connect (gtk_tree_view_get_selection (dialog_data->url_list),
+ "changed",
+ G_CALLBACK (cal_prefs_dialog_url_list_change),
+ dialog_data);
+
+ g_signal_connect(dialog_data->url_list, "row-activated",
+ G_CALLBACK (cal_prefs_dialog_url_list_double_click),
+ dialog_data);
+}
static void
cal_prefs_dialog_use_24_hour_toggled (GtkWidget *button,
@@ -479,6 +542,300 @@
65535);
}
+static void
+cal_prefs_dialog_url_add_clicked (GtkWidget *button, void *data)
+{
+ DialogData *dialog_data = (DialogData *) data;
+ EPublishUri *url = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+
+ model = gtk_tree_view_get_model (dialog_data->url_list);
+ url = g_new0 (EPublishUri, 1);
+ url->enabled = TRUE;
+ url->location = "";
+
+ if (!dialog_data->url_editor) {
+
+ dialog_data->url_editor = url_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_FREE_BUSY_URL_COLUMN, url,
+ -1);
+
+ if (!GTK_WIDGET_SENSITIVE((GtkWidget *) dialog_data->url_remove)) {
+ selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->url_list);
+ gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter);
+ gtk_widget_set_sensitive ((GtkWidget*) dialog_data->url_remove, TRUE);
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+ }
+ dialog_data->url_editor = FALSE;
+ dialog_data->url_editor_dlg = NULL;
+ } else {
+ gdk_window_raise (dialog_data->url_editor_dlg->window);
+ }
+}
+
+static void
+cal_prefs_dialog_url_edit_clicked (GtkWidget *button, void *data)
+{
+ DialogData *dialog_data = (DialogData *) data;
+
+ if (!dialog_data->url_editor) {
+ GtkTreeSelection *selection;
+ EPublishUri *url = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ 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,
+ -1);
+
+ }
+
+ if (url) {
+
+ dialog_data->url_editor = url_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_FREE_BUSY_URL_COLUMN, url,
+ -1);
+
+ if (!GTK_WIDGET_SENSITIVE((GtkWidget *) dialog_data->url_remove)) {
+ selection = gtk_tree_view_get_selection ((GtkTreeView *) dialog_data->url_list);
+ gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter);
+ gtk_widget_set_sensitive ((GtkWidget*) dialog_data->url_remove, TRUE);
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+ dialog_data->url_editor = FALSE;
+ dialog_data->url_editor_dlg = NULL;
+ }
+ } else {
+ gdk_window_raise (dialog_data->url_editor_dlg->window);
+ }
+}
+
+static void
+cal_prefs_dialog_url_remove_clicked (GtkWidget *button, void *data)
+{
+ DialogData *dialog_data = (DialogData *) data;
+ EPublishUri *url = NULL;
+ GtkTreeSelection * selection;
+ GtkTreeModel *model;
+ GtkWidget *confirm;
+ GtkTreeIter iter;
+ int ans;
+
+ 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,
+ -1);
+
+ /* make sure we have a valid account selected and that
+ we aren't editing anything... */
+ if (url == NULL || dialog_data->url_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?"));
+
+ (GtkButton *) 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);
+
+ (GtkButton *) 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->url_edit), FALSE);
+ 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);
+ }
+}
+
+static void
+cal_prefs_dialog_url_enable_clicked (GtkWidget *button, void *data)
+{
+ DialogData *dialog_data = (DialogData *) data;
+ EPublishUri *url = NULL;
+ GtkTreeSelection * selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ 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,
+ -1);
+ url->enabled = !url->enabled;
+ gtk_list_store_set ((GtkListStore *) model, &iter,
+ URL_LIST_ENABLED_COLUMN, url->enabled,
+ -1);
+
+ gtk_button_set_label ((GtkButton *) dialog_data->url_enable,
+ url->enabled ? _("Disable") : _("Enable"));
+ }
+}
+
+static void
+cal_prefs_dialog_url_list_enable_toggled (GtkCellRendererToggle *renderer,
+ const char *path_string,
+ void *data)
+{
+ DialogData *dialog_data = (DialogData *) 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->url_list);
+ selection = gtk_tree_view_get_selection (dialog_data->url_list);
+
+ if (gtk_tree_model_get_iter (model, &iter, path)) {
+ gtk_tree_model_get (model, &iter,
+ URL_LIST_FREE_BUSY_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->url_enable,
+ url->enabled ? _("Disable") : _("Enable"));
+ }
+
+ gtk_tree_path_free(path);
+}
+
+static void
+cal_prefs_dialog_url_list_double_click (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ DialogData *dialog_data)
+{
+ cal_prefs_dialog_url_edit_clicked (NULL, dialog_data);
+}
+
+static void
+cal_prefs_dialog_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_FREE_BUSY_URL_COLUMN, &url,
+ -1);
+
+ if (url->location && url->enabled)
+ gtk_button_set_label ((GtkButton *) dialog_data->url_enable, _("Disable"));
+ else
+ gtk_button_set_label ((GtkButton *) dialog_data->url_enable, _("Enable"));
+ } else {
+ gtk_widget_grab_focus (GTK_WIDGET (dialog_data->url_add));
+ }
+
+ gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->url_edit), state);
+ gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->url_remove), state);
+ gtk_widget_set_sensitive (GTK_WIDGET (dialog_data->url_enable), state);
+}
+
+/* Shows the current Free/Busy settings in the dialog */
+static void
+show_fb_config (DialogData *dialog_data)
+{
+ GSList *url_config_list;
+ GtkListStore *model;
+ GtkTreeIter iter;
+
+ model = (GtkListStore *) gtk_tree_view_get_model (dialog_data->url_list);
+ gtk_list_store_clear (model);
+
+ /* restore urls from gconf */
+ url_config_list = calendar_config_get_free_busy();
+
+ while (url_config_list) {
+ gchar *xml = (gchar *)url_config_list->data;
+ EPublishUri *url;
+ url = g_new0 (EPublishUri, 1);
+
+ 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_FREE_BUSY_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);
+ if (!gtk_tree_model_get_iter_first((GtkTreeModel *) model, &iter)) {
+ /* list is empty-disable edit, remove, and enable buttons */
+ gtk_widget_set_sensitive(GTK_WIDGET(dialog_data->url_edit),
+ FALSE);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(dialog_data->url_remove),
+ FALSE);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(dialog_data->url_enable),
+ FALSE);
+ }
+}
+
/* Shows the current task list settings in the dialog */
static void
show_task_list_config (DialogData *dialog_data)
@@ -576,6 +933,9 @@
/* Task list */
show_task_list_config (dialog_data);
+
+ /* Free/Busy */
+ show_fb_config (dialog_data);
/* Other page */
@@ -605,6 +965,41 @@
return spec;
}
+/* Updates the Free/Busy config values from the settings in the dialog*/
+static void
+update_fb_config (DialogData *dialog_data)
+{
+ GtkTreeIter iter;
+ GtkListStore *model = NULL;
+ gboolean valid;
+ GSList *url_list;
+
+ url_list = NULL;
+
+ model = (GtkListStore *) gtk_tree_view_get_model (dialog_data->url_list);
+
+ valid = gtk_tree_model_get_iter_first ((GtkTreeModel *) model, &iter);
+ while (valid) {
+ EPublishUri *url;
+ gchar *xml;
+
+ gtk_tree_model_get ((GtkTreeModel *) model, &iter,
+ URL_LIST_FREE_BUSY_URL_COLUMN, &url,
+ -1);
+
+ xml = e_pub_uri_to_xml (url);
+ if (xml != NULL) {
+ url_list = g_slist_append(url_list, xml);
+ }
+ g_free (url);
+
+ valid = gtk_tree_model_iter_next((GtkTreeModel *) model, &iter);
+ }
+ calendar_config_set_free_busy(url_list);
+
+ g_slist_free (url_list);
+}
+
/* Updates the task list config values from the settings in the dialog */
static void
update_task_list_config (DialogData *dialog_data)
@@ -671,6 +1066,9 @@
/* Task list */
update_task_list_config (dialog_data);
+
+ /* Free/Busy */
+ update_fb_config (dialog_data);
/* Other page */
Index: gui/dialogs/cal-prefs-dialog.glade
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.glade,v
retrieving revision 1.24
diff -u -r1.24 cal-prefs-dialog.glade
--- gui/dialogs/cal-prefs-dialog.glade 19 Dec 2003 17:49:01 -0000 1.24
+++ gui/dialogs/cal-prefs-dialog.glade 12 Jan 2004 18:27:14 -0000
@@ -1005,7 +1005,6 @@
<child>
<widget class="GtkVBox" id="vbox8">
- <property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
@@ -1444,6 +1443,369 @@
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="label" translatable="yes">_Display</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>
+
+ <child>
+ <widget class="GtkVBox" id="vbox14">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox18">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label49">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span weight="bold">Free/Busy URLs</span></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="hbox24">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label50">
+ <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="vbox19">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox20">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <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="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="vbox15">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label44">
+ <property name="height_request">34</property>
+ <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_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="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkButton" id="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>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment5">
+ <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>
+
+ <child>
+ <widget class="GtkHBox" id="hbox22">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image1">
+ <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="labeladd">
+ <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="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="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="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>
+ </widget>
+ </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="label45">
+ <property name="height_request">34</property>
+ <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="GtkVButtonBox" id="vbuttonbox4">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkButton" id="url_enable">
+ <property name="width_request">91</property>
+ <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" translatable="yes">E_nable</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</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="GtkLabel" id="label46">
+ <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>
+ <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>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label42">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Free/Busy</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
Index: gui/dialogs/cal-prefs-dialog.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.h,v
retrieving revision 1.9
diff -u -r1.9 cal-prefs-dialog.h
--- gui/dialogs/cal-prefs-dialog.h 7 Nov 2002 02:00:56 -0000 1.9
+++ gui/dialogs/cal-prefs-dialog.h 12 Jan 2004 18:27:14 -0000
@@ -30,9 +30,68 @@
#ifndef _CAL_PREFS_DIALOG_H_
#define _CAL_PREFS_DIALOG_H_
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
+#include "../e-pub-utils.h"
#include "evolution-config-control.h"
G_BEGIN_DECLS
+
+enum {
+ URL_LIST_ENABLED_COLUMN,
+ URL_LIST_LOCATION_COLUMN,
+ URL_LIST_FREE_BUSY_URL_COLUMN,
+ URL_LIST_N_COLUMNS
+};
+
+struct _DialogData {
+ /* Glade XML data */
+ GladeXML *xml;
+
+ GConfClient *gconf;
+
+ GtkWidget *page;
+
+ GtkWidget *timezone;
+ GtkWidget *working_days[7];
+ GtkWidget *week_start_day;
+ GtkWidget *start_of_day;
+ GtkWidget *end_of_day;
+ GtkWidget *use_12_hour;
+ GtkWidget *use_24_hour;
+ GtkWidget *time_divisions;
+ GtkWidget *show_end_times;
+ GtkWidget *compress_weekend;
+ GtkWidget *dnav_show_week_no;
+
+ /* Widgets for the task list options */
+ GtkWidget *tasks_due_today_color;
+ GtkWidget *tasks_overdue_color;
+
+ GtkWidget *tasks_hide_completed_checkbutton;
+ GtkWidget *tasks_hide_completed_spinbutton;
+ GtkWidget *tasks_hide_completed_optionmenu;
+
+ /* Widgets for the Free/Busy options */
+ GtkWidget *url_add;
+ GtkWidget *url_edit;
+ GtkWidget *url_remove;
+ GtkWidget *url_enable;
+ GtkTreeView *url_list;
+ gboolean url_editor;
+ GtkWidget* url_editor_dlg;
+ guint destroyed : 1;
+
+
+ /* Other page options */
+ GtkWidget *confirm_delete;
+ GtkWidget *default_reminder;
+ GtkWidget *default_reminder_interval;
+ GtkWidget *default_reminder_units;
+};
+typedef struct _DialogData DialogData;
EvolutionConfigControl *cal_prefs_dialog_new (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]