Re: [evolution-patches] Patch for bug #127541 - Default Free Busy URI
- From: James Bowes <bowes cs dal ca>
- To: JP Rosevear <jpr novell com>
- Cc: evolution-patches ximian com, dobey ximian com, Benjamin Kahn <xkahn ximian com>
- Subject: Re: [evolution-patches] Patch for bug #127541 - Default Free Busy URI
- Date: Sat, 27 Nov 2004 19:21:58 -0400
On Fri, 2004-26-11 at 18:37 -0400, James Bowes wrote:
> On Wed, 2004-24-11 at 13:34 -0500, JP Rosevear wrote:
> > For the actual operation, perhaps you should add a notification in
> > calendar-config.[hc] that is listened to in e-meeting-store (or some
> > "controller") and issues a refresh call to rebuild the data.
> >
>
> I set up e-meeting-time-sel to watch for changes to to the gconf
> setting, since it has the start and end times that are needed for
> rebuilding the data.
>
I've attached a new version of the patch. This one listens for focus-out
events on the gtk-entry used to set the template uri in the prefs
window. This way, the setting is only saved once, rather than after
every key press, which also reduces the number gnome-vfs reads while
refreshing the meeting-store.
James
? depcomp
? help/C/evolution-2.2-C.omf
? help/C/evolution-2.2.xml
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2568
diff -u -r1.2568 ChangeLog
--- calendar/ChangeLog 26 Nov 2004 13:58:56 -0000 1.2568
+++ calendar/ChangeLog 27 Nov 2004 23:14:44 -0000
@@ -1,3 +1,41 @@
+2004-11-26 James Bowes <bowes cs dal ca>
+
+ * gui/apps_evolution_calendar.schemas.in.in: Add schema for Free/Busy
+ template uri.
+ * gui/calendar-config-keys.h:
+ * gui/calendar-config.c: (calendar_config_get_free_busy_template),
+ (calendar_config_set_free_busy_template),
+ (calendar_config_add_notification_free_busy_template):
+ * gui/calendar-config.h: Functions to get, set and monitor the
+ Free/Busy template uri gconf setting.
+ * gui/dialogs/cal-prefs-dialog.c: (template_url_changed),
+ (setup_changes), (get_widgets), (show_fb_config):
+ * gui/dialogs/cal-prefs-dialog.glade:
+ * gui/dialogs/cal-prefs-dialog.h: Change 'Free/Busy Publish' tab to
+ 'Free/Busy'. Add an entry for setting the default Free/Busy uri.
+ Only change the gconf setting on 'focus out' event
+ * gui/e-meeting-store.c: (refresh_queue_remove): Check the hash using
+ the attendee's mailto: address, rather than the memory address of the
+ attendee object as the key.
+ (e_meeting_store_get_fb_uri), (e_meeting_store_set_fb_uri): Get and set
+ the EMeetingStore's Free/Busy template string.
+ (process_callbacks_main_thread), (process_callbacks): Process callbacks
+ in the main thread, so that widgets can be redrawn properly.
+ (replace_string): Utility function for replacing wildcards in the
+ default Free/Busy uri.
+ (ems_finalize), (ems_init), (freebusy_async), (refresh_busy_periods),
+ (refresh_queue_add), (e_meeting_store_refresh_busy_periods): Add the
+ ability to check for Free/Busy information from a default location,
+ if all else fails.
+ (start_async_read): Use gnome-vfs to read the Free/Busy information.
+ * gui/e-meeting-store.h: Add function prototypes for get and set fb_uri
+ * gui/e-meeting-time-sel.c: (e_meeting_time_selector_init),
+ (e_meeting_time_selector_destroy), (free_busy_template_changed_cb):
+ Watch for a change in the Free/Busy template gconf setting, and check
+ for new Free/Busy data if it occurs.
+ * gui/e-meeting-time-sel.h: Include variable for notification function
+ id on changes to the Free/Busy uri in the EMeetingTimeSelector .
+
2004-11-26 JP Rosevear <jpr novell com>
* gui/alarm-notify/alarm-queue.c (display_notification): ditto
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.5
diff -u -r1.5 apps_evolution_calendar.schemas.in.in
--- calendar/gui/apps_evolution_calendar.schemas.in.in 26 May 2004 19:51:49 -0000 1.5
+++ calendar/gui/apps_evolution_calendar.schemas.in.in 27 Nov 2004 23:14:44 -0000
@@ -367,5 +367,16 @@
<short>List of urls for free/busy publishing</short>
</locale>
</schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/publish/template</key>
+ <applyto>/apps/evolution/calendar/publish/template</applyto>
+ <owner>evolution-calendar</owner>
+ <type>string</type>
+ <default>http://<DOMAIN>/<USER>.ifb</default>
+ <locale name="C">
+ <short>The url template to use as a free/busy data fallback</short>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
Index: calendar/gui/calendar-config-keys.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config-keys.h,v
retrieving revision 1.5
diff -u -r1.5 calendar-config-keys.h
--- calendar/gui/calendar-config-keys.h 13 Jan 2004 01:59:27 -0000 1.5
+++ calendar/gui/calendar-config-keys.h 27 Nov 2004 23:14:44 -0000
@@ -72,6 +72,7 @@
/* Free/Busy settings */
#define CALENDAR_CONFIG_PUBLISH CALENDAR_CONFIG_PREFIX"/publish/uris"
+#define CALENDAR_CONFIG_TEMPLATE CALENDAR_CONFIG_PREFIX"/publish/template"
G_END_DECLS
Index: calendar/gui/calendar-config.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.c,v
retrieving revision 1.70
diff -u -r1.70 calendar-config.c
--- calendar/gui/calendar-config.c 7 Oct 2004 21:03:36 -0000 1.70
+++ calendar/gui/calendar-config.c 27 Nov 2004 23:14:45 -0000
@@ -1063,3 +1063,27 @@
gconf_client_set_list (config, CALENDAR_CONFIG_PUBLISH,
GCONF_VALUE_STRING, url_list, NULL);
}
+
+gchar *
+calendar_config_get_free_busy_template (void)
+{
+ return gconf_client_get_string (config, CALENDAR_CONFIG_TEMPLATE, NULL);
+}
+
+void
+calendar_config_set_free_busy_template (const gchar *template)
+{
+ gconf_client_set_string (config, CALENDAR_CONFIG_TEMPLATE, template, NULL);
+}
+
+guint
+calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func,
+ gpointer data)
+{
+ guint id;
+
+ id = gconf_client_notify_add (config, CALENDAR_CONFIG_TEMPLATE, func, data,
+ NULL, NULL);
+
+ return id;
+}
Index: calendar/gui/calendar-config.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.h,v
retrieving revision 1.34
diff -u -r1.34 calendar-config.h
--- calendar/gui/calendar-config.h 30 Apr 2004 21:33:11 -0000 1.34
+++ calendar/gui/calendar-config.h 27 Nov 2004 23:14:45 -0000
@@ -206,6 +206,11 @@
GSList * calendar_config_get_free_busy (void);
void calendar_config_set_free_busy (GSList * url_list);
+gchar *calendar_config_get_free_busy_template (void);
+void calendar_config_set_free_busy_template (const gchar *template);
+guint calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func,
+ gpointer data);
+
/* Convenience functions to configure common properties of ECalendar,
EDateEdit & ECalendarTable widgets, and the ECellDateEdit ETable cell. */
void calendar_config_configure_e_calendar (ECalendar *cal);
Index: calendar/gui/e-meeting-store.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-meeting-store.c,v
retrieving revision 1.8
diff -u -r1.8 e-meeting-store.c
--- calendar/gui/e-meeting-store.c 19 Oct 2004 03:51:01 -0000 1.8
+++ calendar/gui/e-meeting-store.c 27 Nov 2004 23:14:45 -0000
@@ -48,12 +48,18 @@
ECal *client;
icaltimezone *zone;
+ char *fb_uri;
+
EBook *ebook;
GPtrArray *refresh_queue;
GHashTable *refresh_data;
GMutex *mutex;
guint refresh_idle_id;
+
+ guint callback_idle_id;
+ guint num_threads;
+ GAsyncQueue *async_queue;
};
#define BUF_SIZE 1024
@@ -78,6 +84,8 @@
static GObjectClass *parent_class = NULL;
+static void start_async_read (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data);
+
static void
start_addressbook_server (EMeetingStore *store)
{
@@ -553,9 +561,8 @@
priv = store->priv;
/* Free the queue data */
- qdata = g_hash_table_lookup (priv->refresh_data, attendee);
+ qdata = g_hash_table_lookup (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
if (qdata) {
- g_hash_table_remove (priv->refresh_data, attendee);
g_mutex_lock (priv->mutex);
g_hash_table_remove (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
g_mutex_unlock (priv->mutex);
@@ -596,7 +603,14 @@
if (priv->refresh_idle_id)
g_source_remove (priv->refresh_idle_id);
+ if (priv->callback_idle_id)
+ g_source_remove (priv->callback_idle_id);
+
+ g_free (priv->fb_uri);
+
g_mutex_free (priv->mutex);
+
+ g_async_queue_unref (priv->async_queue);
g_free (priv);
@@ -625,12 +639,16 @@
priv->attendees = g_ptr_array_new ();
priv->zone = calendar_config_get_icaltimezone ();
+
+ priv->fb_uri = calendar_config_get_free_busy_template ();
priv->refresh_queue = g_ptr_array_new ();
priv->refresh_data = g_hash_table_new (g_str_hash, g_str_equal);
priv->mutex = g_mutex_new ();
+ priv->async_queue = g_async_queue_new ();
+
start_addressbook_server (store);
}
@@ -708,6 +726,23 @@
store->priv->zone = zone;
}
+gchar *
+e_meeting_store_get_fb_uri (EMeetingStore *store)
+{
+ g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL);
+
+ return g_strdup (store->priv->fb_uri);
+}
+
+void
+e_meeting_store_set_fb_uri (EMeetingStore *store, const gchar *fb_uri)
+{
+ g_return_if_fail (E_IS_MEETING_STORE (store));
+
+ g_free (store->priv->fb_uri);
+ store->priv->fb_uri = g_strdup (fb_uri);
+}
+
static void
attendee_changed_cb (EMeetingAttendee *attendee, gpointer data)
{
@@ -947,24 +982,60 @@
return NULL;
}
+typedef struct {
+ EMeetingStoreRefreshCallback call_back;
+ gpointer *data;
+} QueueCbData;
+
+/* Process the callbacks in the main thread. Avoids widget redrawing issues. */
+static gboolean
+process_callbacks_main_thread (EMeetingStore *store)
+{
+ EMeetingStorePrivate *priv;
+ QueueCbData *aqueue_data;
+ gboolean threads_done = FALSE;
+
+ priv = store->priv;
+
+ g_mutex_lock (priv->mutex);
+ if (priv->num_threads == 0) {
+ threads_done = TRUE;
+ priv->callback_idle_id = 0;
+ }
+ g_mutex_unlock (priv->mutex);
+
+ while ((aqueue_data = g_async_queue_try_pop (priv->async_queue)) != NULL) {
+ aqueue_data->call_back (aqueue_data->data);
+
+ g_free (aqueue_data);
+ }
+
+ return !threads_done;
+}
+
static void
process_callbacks (EMeetingStoreQueueData *qdata)
{
EMeetingStore *store;
int i;
+ store = qdata->store;
+
for (i = 0; i < qdata->call_backs->len; i++) {
- EMeetingStoreRefreshCallback call_back;
- gpointer *data;
+ QueueCbData *aqueue_data = g_new0 (QueueCbData, 1);
- call_back = g_ptr_array_index (qdata->call_backs, i);
- data = g_ptr_array_index (qdata->data, i);
+ aqueue_data->call_back = g_ptr_array_index (qdata->call_backs, i);
+ aqueue_data->data = g_ptr_array_index (qdata->data, i);
- call_back (data);
+ g_async_queue_push (store->priv->async_queue, aqueue_data);
}
- store = qdata->store;
+ g_mutex_lock (store->priv->mutex);
+ store->priv->num_threads--;
+ g_mutex_unlock (store->priv->mutex);
+
refresh_queue_remove (qdata->store, qdata->attendee);
+ g_async_queue_unref (store->priv->async_queue);
g_object_unref (store);
}
@@ -1116,22 +1187,45 @@
process_callbacks (qdata);
}
+/*
+ * Replace all instances of from_value in string with to_value
+ * In the returned newly allocated string.
+*/
+static gchar *
+replace_string (gchar *string, gchar *from_value, gchar *to_value)
+{
+ gchar *replaced;
+ gchar **split_uri;
+
+ split_uri = g_strsplit (string, from_value, 0);
+ replaced = g_strjoinv (to_value, split_uri);
+ g_strfreev (split_uri);
+
+ return replaced;
+}
+
typedef struct {
ECal *client;
time_t startt;
time_t endt;
GList *users;
GList *fb_data;
+ char *fb_uri;
+ char *email;
EMeetingAttendee *attendee;
EMeetingStoreQueueData *qdata;
} FreeBusyAsyncData;
+#define USER_SUB "%u"
+#define DOMAIN_SUB "%d"
+
static gboolean
freebusy_async (gpointer data)
{
FreeBusyAsyncData *fbd = data;
EMeetingAttendee *attendee = fbd->attendee;
-
+ gchar *default_fb_uri;
+
if (fbd->client) {
e_cal_get_free_busy (fbd->client, fbd->users, fbd->startt, fbd->endt, &(fbd->fb_data), NULL);
@@ -1145,22 +1239,53 @@
comp_str = e_cal_component_get_as_string (comp);
process_free_busy (fbd->qdata, comp_str);
g_free (comp_str);
+
+ return TRUE;
}
- return TRUE;
}
-
/* Look for fburl's of attendee with no free busy info on server */
if (!e_meeting_attendee_is_set_address (attendee)) {
process_callbacks (fbd->qdata);
return TRUE;
}
+
+
+ /* Check for free busy info on the default server */
+ default_fb_uri = g_strdup (fbd->fb_uri);
+
+ if (default_fb_uri != NULL) {
+ GnomeVFSAsyncHandle *handle;
+ gchar *tmp_fb_uri;
+ gchar **split_email;
+
+ split_email = g_strsplit (fbd->email, "@", 2);
+
+ tmp_fb_uri = replace_string (default_fb_uri, USER_SUB, split_email[0]);
+ g_free (default_fb_uri);
+ default_fb_uri = replace_string (tmp_fb_uri, DOMAIN_SUB, split_email[1]);
+
+ gnome_vfs_async_open (&handle, default_fb_uri, GNOME_VFS_OPEN_READ,
+ GNOME_VFS_PRIORITY_DEFAULT, start_async_read,
+ fbd->qdata);
+
+ g_free (tmp_fb_uri);
+ g_strfreev (split_email);
+ g_free (default_fb_uri);
+ } else {
+ process_callbacks (fbd->qdata);
+ }
+
return TRUE;
}
+#undef USER_SUB
+#undef DOMAIN_SUB
+
+
static gboolean
refresh_busy_periods (gpointer data)
{
@@ -1202,13 +1327,16 @@
fbd = g_new0 (FreeBusyAsyncData, 1);
fbd->client = priv->client;
+ fbd->attendee = attendee;
fbd->users = NULL;
fbd->fb_data = NULL;
+ fbd->qdata = qdata;
+ fbd->fb_uri = priv->fb_uri;
+ fbd->email = g_strdup (itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
/* Check the server for free busy data */
if (priv->client) {
struct icaltimetype itt;
- const char *user;
itt = icaltime_null_time ();
itt.year = g_date_year (&qdata->start.date);
@@ -1226,19 +1354,36 @@
itt.minute = qdata->end.minute;
fbd->endt = icaltime_as_timet_with_zone (itt, priv->zone);
fbd->qdata = qdata;
- fbd->attendee = attendee;
- user = itip_strip_mailto (e_meeting_attendee_get_address (attendee));
- fbd->users = g_list_append (fbd->users, g_strdup (user));
+ fbd->users = g_list_append (fbd->users, g_strdup (fbd->email));
}
-
+
+
+ g_async_queue_ref (priv->async_queue);
+
+ g_mutex_lock (store->priv->mutex);
+ store->priv->num_threads++;
+ g_mutex_unlock (store->priv->mutex);
+
thread = g_thread_create ((GThreadFunc) freebusy_async, fbd, FALSE, &error);
if (!thread) {
/* do clean up stuff here */
g_list_foreach (fbd->users, (GFunc)g_free, NULL);
g_list_free (fbd->users);
+ g_free (fbd->email);
+ priv->refresh_idle_id = 0;
+
+ g_async_queue_unref (priv->async_queue);
+
+ g_mutex_lock (store->priv->mutex);
+ store->priv->num_threads--;
+ g_mutex_unlock (store->priv->mutex);
+
return FALSE;
+ } else if (priv->callback_idle_id == 0) {
+ priv->callback_idle_id = g_idle_add (process_callbacks_main_thread,
+ store);
}
return TRUE;
}
@@ -1256,16 +1401,18 @@
int i;
priv = store->priv;
-
+
attendee = g_ptr_array_index (priv->attendees, row);
if ((attendee == NULL) || !strcmp (itip_strip_mailto (e_meeting_attendee_get_address (attendee)), ""))
return;
+
/* check the queue if the attendee is already in there*/
for (i = 0; i < priv->refresh_queue->len; i++) {
if (attendee == g_ptr_array_index (priv->refresh_queue, i))
return;
+
if (!strcmp (e_meeting_attendee_get_address (attendee), e_meeting_attendee_get_address (g_ptr_array_index (priv->refresh_queue, i))))
- return;
+ return;
}
g_mutex_lock (priv->mutex);
@@ -1343,6 +1490,24 @@
gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
}
+static void
+start_async_read (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer data)
+{
+ EMeetingStoreQueueData *qdata = data;
+ GnomeVFSFileSize buf_size = BUF_SIZE - 1;
+
+ if (result != GNOME_VFS_OK) {
+ g_warning ("Unable to access free/busy url: %s",
+ gnome_vfs_result_to_string (result));
+ process_callbacks (qdata);
+ return;
+ }
+
+ gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
+}
+
void
e_meeting_store_refresh_all_busy_periods (EMeetingStore *store,
EMeetingTime *start,
@@ -1370,4 +1535,3 @@
refresh_queue_add (store, row, start, end, call_back, data);
}
-
Index: calendar/gui/e-meeting-store.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-meeting-store.h,v
retrieving revision 1.3
diff -u -r1.3 e-meeting-store.h
--- calendar/gui/e-meeting-store.h 24 Dec 2003 17:39:03 -0000 1.3
+++ calendar/gui/e-meeting-store.h 27 Nov 2004 23:14:45 -0000
@@ -78,6 +78,9 @@
icaltimezone *e_meeting_store_get_zone (EMeetingStore *im);
void e_meeting_store_set_zone (EMeetingStore *im, icaltimezone *zone);
+gchar *e_meeting_store_get_fb_uri (EMeetingStore *im);
+void e_meeting_store_set_fb_uri (EMeetingStore *im, const gchar *fb_uri);
+
void e_meeting_store_add_attendee (EMeetingStore *im, EMeetingAttendee *ia);
EMeetingAttendee *e_meeting_store_add_attendee_with_defaults (EMeetingStore *im);
Index: calendar/gui/e-meeting-time-sel.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-meeting-time-sel.c,v
retrieving revision 1.65
diff -u -r1.65 e-meeting-time-sel.c
--- calendar/gui/e-meeting-time-sel.c 14 Oct 2004 15:53:29 -0000 1.65
+++ calendar/gui/e-meeting-time-sel.c 27 Nov 2004 23:14:46 -0000
@@ -207,6 +207,9 @@
static void row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
static void row_deleted_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data);
+static void free_busy_template_changed_cb (GConfClient *client, guint cnxn_id,
+ GConfEntry *entry, gpointer user_data);
+
G_DEFINE_TYPE (EMeetingTimeSelector, e_meeting_time_selector, GTK_TYPE_TABLE);
static void
@@ -252,6 +255,10 @@
mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE;
mts->list_view = NULL;
+
+ mts->fb_uri_not =
+ calendar_config_add_notification_free_busy_template ((GConfClientNotifyFunc) free_busy_template_changed_cb,
+ mts);
}
@@ -825,6 +832,8 @@
mts->display_top = NULL;
mts->display_main = NULL;
+
+ calendar_config_remove_notification (mts->fb_uri_not);
if (GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)
(*GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)(object);
@@ -2877,3 +2886,20 @@
gtk_widget_queue_draw (mts->display_main);
}
+static void
+free_busy_template_changed_cb (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer data)
+{
+ char *fb_uri;
+
+ EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data);
+
+ fb_uri = calendar_config_get_free_busy_template ();
+ e_meeting_store_set_fb_uri (mts->model, fb_uri);
+ g_free (fb_uri);
+
+ /* Update all free/busy info, so we use the new template uri */
+ e_meeting_time_selector_refresh_free_busy (mts, 0, TRUE);
+}
Index: calendar/gui/e-meeting-time-sel.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-meeting-time-sel.h,v
retrieving revision 1.10
diff -u -r1.10 e-meeting-time-sel.h
--- calendar/gui/e-meeting-time-sel.h 15 Jun 2004 11:57:17 -0000 1.10
+++ calendar/gui/e-meeting-time-sel.h 27 Nov 2004 23:14:46 -0000
@@ -252,6 +252,9 @@
/* This is used to determine the delay between scrolls. */
gint scroll_count;
+
+ /* The notification function id for Free/Busy template uri changes */
+ guint fb_uri_not;
};
Index: calendar/gui/dialogs/cal-prefs-dialog.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.c,v
retrieving revision 1.39
diff -u -r1.39 cal-prefs-dialog.c
--- calendar/gui/dialogs/cal-prefs-dialog.c 7 Oct 2004 21:08:25 -0000 1.39
+++ calendar/gui/dialogs/cal-prefs-dialog.c 27 Nov 2004 23:14:46 -0000
@@ -370,6 +370,14 @@
g_slist_free (url_list);
}
+static gboolean
+template_url_changed (GtkEntry *entry, DialogData *dialog_data)
+{
+ calendar_config_set_free_busy_template (gtk_entry_get_text (entry));
+
+ return FALSE;
+}
+
static void
setup_changes (DialogData *dialog_data)
{
@@ -412,6 +420,8 @@
G_CALLBACK (default_reminder_interval_changed), dialog_data);
g_signal_connect (GTK_OPTION_MENU (dialog_data->default_reminder_units)->menu, "selection-done",
G_CALLBACK (default_reminder_units_changed), dialog_data);
+
+ g_signal_connect (dialog_data->template_url, "focus-out-event", G_CALLBACK (template_url_changed), dialog_data);
}
/* Gets the widgets from the XML file and returns if they are all available.
@@ -463,6 +473,8 @@
data->url_enable = GW ("url_enable");
data->url_list = GTK_TREE_VIEW (GW ("url_list"));
+ data->template_url = GW("template_url");
+
#undef GW
return (data->page
@@ -859,6 +871,7 @@
GSList *url_config_list = NULL;
GtkListStore *model;
GtkTreeIter iter;
+ gchar *template_url;
model = (GtkListStore *) gtk_tree_view_get_model (dialog_data->url_list);
gtk_list_store_clear (model);
@@ -910,6 +923,11 @@
g_slist_foreach (url_config_list, (GFunc) g_free, NULL);
g_slist_free (url_config_list);
+
+ template_url = calendar_config_get_free_busy_template ();
+ gtk_entry_set_text (GTK_ENTRY (dialog_data->template_url), template_url);
+
+ g_free (template_url);
}
/* Shows the current task list settings in the dialog */
Index: calendar/gui/dialogs/cal-prefs-dialog.glade
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.glade,v
retrieving revision 1.29
diff -u -r1.29 cal-prefs-dialog.glade
--- calendar/gui/dialogs/cal-prefs-dialog.glade 12 Oct 2004 06:58:11 -0000 1.29
+++ calendar/gui/dialogs/cal-prefs-dialog.glade 27 Nov 2004 23:14:46 -0000
@@ -1520,247 +1520,433 @@
</child>
<child>
- <widget class="GtkHBox" id="hbox20">
+ <widget class="GtkVBox" id="vbox17">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
- <property name="spacing">6</property>
+ <property name="spacing">12</property>
<child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <widget class="GtkFrame" id="frame2">
<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>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
- <widget class="GtkTreeView" id="url_list">
+ <widget class="GtkAlignment" id="alignment8">
<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">6</property>
-
- <child>
- <widget class="GtkVButtonBox" id="vbuttonbox3">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">6</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="GtkButton" id="url_add">
+ <widget class="GtkHBox" id="hbox20">
<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>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
<child>
- <widget class="GtkAlignment" id="alignment5">
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
<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>
+ <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">6</property>
<child>
- <widget class="GtkHBox" id="hbox22">
+ <widget class="GtkVButtonBox" id="vbuttonbox3">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">6</property>
<child>
- <widget class="GtkImage" id="image1">
+ <widget class="GtkButton" id="url_add">
<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>
+ <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="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>
+ <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="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>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
<child>
- <widget class="GtkLabel" id="labeladd">
+ <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">_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>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment6">
+ <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="hbox23">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image2">
+ <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="label47">
+ <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>
- <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="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment6">
- <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="hbox23">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
<child>
- <widget class="GtkImage" id="image2">
+ <widget class="GtkButton" id="url_remove">
<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>
+ <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>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
<child>
- <widget class="GtkLabel" id="label47">
+ <widget class="GtkButton" id="url_enable">
<property name="visible">True</property>
- <property name="label" translatable="yes">_Edit</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="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>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</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>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox4">
+ <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="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>
</child>
+ </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>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="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>
+ <child>
+ <widget class="GtkLabel" id="label60">
+ <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="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <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="frame1">
+ <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="GtkVButtonBox" id="vbuttonbox4">
+ <widget class="GtkAlignment" id="alignment7">
<property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">3</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="vbox18">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox30">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="label61">
+ <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="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">*</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="label62">
+ <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>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
<child>
- <widget class="GtkLabel" id="label46">
+ <widget class="GtkLabel" id="label59">
<property name="visible">True</property>
- <property name="label" translatable="yes"></property>
+ <property name="label" translatable="yes"><b>Default Free/Busy Server</b></property>
<property name="use_underline">False</property>
- <property name="use_markup">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>
@@ -1770,16 +1956,14 @@
<property name="ypad">0</property>
</widget>
<packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="fill">True</property>
</packing>
</child>
</widget>
@@ -1792,7 +1976,7 @@
<child>
<widget class="GtkLabel" id="label42">
<property name="visible">True</property>
- <property name="label" translatable="yes">Free/Busy Publishing</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: calendar/gui/dialogs/cal-prefs-dialog.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/cal-prefs-dialog.h,v
retrieving revision 1.10
diff -u -r1.10 cal-prefs-dialog.h
--- calendar/gui/dialogs/cal-prefs-dialog.h 13 Jan 2004 01:59:28 -0000 1.10
+++ calendar/gui/dialogs/cal-prefs-dialog.h 27 Nov 2004 23:14:46 -0000
@@ -83,7 +83,9 @@
gboolean url_editor;
GtkWidget* url_editor_dlg;
guint destroyed : 1;
-
+
+ /* widgets for the Free/Busy template */
+ GtkWidget *template_url;
/* Other page options */
GtkWidget *confirm_delete;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]