diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-19 09:39:19 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-19 09:39:19 +0800 |
commit | b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab (patch) | |
tree | 854d94e177216f4f6f2b2e9f2c150b7ec5d32e3d | |
parent | c3471bfaaad0a94b6f05b678c1eacbc55e72e2dc (diff) | |
download | gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar.gz gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar.bz2 gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar.lz gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar.xz gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.tar.zst gsoc2013-evolution-b06cdfab92313ca7b1ce9a88ccb0ffba33cb17ab.zip |
Progress update:
- Tighter integration of GalViewInstance and EShellView.
- EBinding. Stolen from ExoBinding. Lets you bind GObject properties
together to automatically keep their values in sync. This is a godsend.
Added to e-util, but might even deserve a place in libedataserver.
- EShellSettings. This is the concept I blogged about. Already
started ripping apart em-mailer-prefs.c. Others to follow. Any
place where we're monitoring GConf keys is a target.
- Incremental progress on the calender and mailer. Got EMFolderView
somewhat working, but I think I'll be killing off EMFolderBrowser.
svn path=/branches/kill-bonobo/; revision=36795
33 files changed, 1868 insertions, 911 deletions
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c index f7c506ee78..216a7c77a6 100644 --- a/addressbook/gui/widgets/e-addressbook-view.c +++ b/addressbook/gui/widgets/e-addressbook-view.c @@ -365,19 +365,6 @@ addressbook_view_create_minicard_view (EAddressbookView *view) } static void -addressbook_view_changed_cb (EAddressbookView *view, - GalViewInstance *view_instance) -{ - EShellView *shell_view; - gchar *view_id; - - shell_view = e_addressbook_view_get_shell_view (view); - view_id = gal_view_instance_get_current_view_id (view_instance); - e_shell_view_set_view_id (shell_view, view_id); - g_free (view_id); -} - -static void addressbook_view_display_view_cb (EAddressbookView *view, GalView *gal_view) { @@ -608,24 +595,16 @@ static void addressbook_view_constructed (GObject *object) { EAddressbookView *view = E_ADDRESSBOOK_VIEW (object); - EShellView *shell_view; - EShellViewClass *shell_view_class; - GalViewCollection *view_collection; GalViewInstance *view_instance; + EShellView *shell_view; ESource *source; gchar *uri; shell_view = e_addressbook_view_get_shell_view (view); - shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); - view_collection = shell_view_class->view_collection; - source = e_addressbook_view_get_source (view); uri = e_source_get_uri (source); - view_instance = gal_view_instance_new (view_collection, uri); - g_signal_connect_swapped ( - view_instance, "changed", - G_CALLBACK (addressbook_view_changed_cb), view); + view_instance = e_shell_view_new_view_instance (shell_view, uri); g_signal_connect_swapped ( view_instance, "display-view", G_CALLBACK (addressbook_view_display_view_cb), view); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 3e31e39240..ca6fbe9721 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -96,9 +96,9 @@ static GHashTable *non_intrusive_error_table = NULL; struct _GnomeCalendarPrivate { /* The clients for display */ - GHashTable *clients[E_CAL_SOURCE_TYPE_LAST]; - GList *clients_list[E_CAL_SOURCE_TYPE_LAST]; - ECal *default_client[E_CAL_SOURCE_TYPE_LAST]; + GHashTable *clients; + GList *clients_list; + ECal *default_client; /* * Fields for the calendar view @@ -186,9 +186,6 @@ struct _GnomeCalendarPrivate { enum { DATES_SHOWN_CHANGED, CALENDAR_SELECTION_CHANGED, - MEMOPAD_SELECTION_CHANGED, - CALENDAR_FOCUS_CHANGE, - MEMOPAD_FOCUS_CHANGE, GOTO_DATE, SOURCE_ADDED, SOURCE_REMOVED, @@ -292,16 +289,6 @@ gnome_calendar_class_init (GnomeCalendarClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] = - g_signal_new ("calendar_focus_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GnomeCalendarClass, calendar_focus_change), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - gnome_calendar_signals[SOURCE_ADDED] = g_signal_new ("source_added", G_TYPE_FROM_CLASS (object_class), @@ -309,9 +296,8 @@ gnome_calendar_class_init (GnomeCalendarClass *class) G_STRUCT_OFFSET (GnomeCalendarClass, source_added), NULL, NULL, e_calendar_marshal_VOID__INT_OBJECT, - G_TYPE_NONE, - 2, - G_TYPE_INT, G_TYPE_OBJECT); + G_TYPE_NONE, 1, + G_TYPE_OBJECT); gnome_calendar_signals[SOURCE_REMOVED] = g_signal_new ("source_removed", @@ -320,9 +306,8 @@ gnome_calendar_class_init (GnomeCalendarClass *class) G_STRUCT_OFFSET (GnomeCalendarClass, source_removed), NULL, NULL, e_calendar_marshal_VOID__INT_OBJECT, - G_TYPE_NONE, - 2, - G_TYPE_INT, G_TYPE_OBJECT); + G_TYPE_NONE, 1, + G_TYPE_OBJECT); gnome_calendar_signals[GOTO_DATE] = g_signal_new ("goto_date", @@ -350,7 +335,6 @@ gnome_calendar_class_init (GnomeCalendarClass *class) class->dates_shown_changed = NULL; class->calendar_selection_changed = NULL; - class->calendar_focus_change = NULL; class->source_added = NULL; class->source_removed = NULL; class->goto_date = gnome_calendar_goto_date; @@ -758,7 +742,7 @@ update_query_async (struct _date_query_msg *msg) } /* create queries for each loaded client */ - for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) { + for (l = priv->clients_list; l != NULL; l = l->next) { GError *error = NULL; gint tries = 0; @@ -981,60 +965,6 @@ user_created_cb (GtkWidget *view, GnomeCalendar *gcal) } -static gint -calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals [CALENDAR_FOCUS_CHANGE], 0, - event->in ? TRUE : FALSE); - - return FALSE; -} - -/* Connects to the focus change signals of a day view widget */ -static void -connect_day_view_focus (GnomeCalendar *gcal, EDayView *dv) -{ - g_signal_connect_after (dv->top_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect_after (dv->top_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - - g_signal_connect_after (dv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect_after (dv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -/* Connects to the focus change signals of a week view widget */ -static void -connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv) -{ - if (!E_IS_WEEK_VIEW (wv)) - return; - - g_signal_connect (wv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (wv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -static void -connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv) -{ - ETable *etable; - - etable = e_table_scrolled_get_table (lv->table_scrolled); - - g_signal_connect (etable->table_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (etable->table_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - static void set_week_start (GnomeCalendar *calendar) { @@ -1087,29 +1017,25 @@ static void set_timezone (GnomeCalendar *calendar) { GnomeCalendarPrivate *priv; - int i; + GList *l; priv = calendar->priv; priv->zone = calendar_config_get_icaltimezone (); - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) { - GList *l; - - for (l = priv->clients_list[i]; l != NULL; l = l->next) { - ECal *client = l->data; - - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (client, priv->zone, NULL); - } + for (l = priv->clients_list; l != NULL; l = l->next) { + ECal *client = l->data; - if (priv->default_client[i] - && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED) + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) /* FIXME Error checking */ - e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL); + e_cal_set_default_timezone (client, priv->zone, NULL); } + if (priv->default_client[i] + && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED) + /* FIXME Error checking */ + e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL); + if (priv->views [priv->current_view_type]) e_calendar_view_set_timezone (priv->views [priv->current_view_type], priv->zone); } @@ -1473,7 +1399,6 @@ setup_widgets (GnomeCalendar *gcal) e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->day_view), priv->zone); g_signal_connect (priv->day_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view)); /* The Work Week View. */ priv->work_week_view = e_day_view_new (cal_model); @@ -1482,7 +1407,6 @@ setup_widgets (GnomeCalendar *gcal) e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5); e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->work_week_view), gcal); e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->work_week_view), priv->zone); - connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view)); /* The Marcus Bains line */ priv->update_marcus_bains_line_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_marcus_bains_line_cb, gcal, NULL); @@ -1494,8 +1418,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->week_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view)); - adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->week_view)->vscrollbar)); g_signal_connect (adjustment, "value_changed", G_CALLBACK (week_view_adjustment_changed_cb), @@ -1515,8 +1437,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->month_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view)); - adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->month_view)->vscrollbar)); g_signal_connect (adjustment, "value_changed", G_CALLBACK (month_view_adjustment_changed_cb), @@ -1530,8 +1450,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->list_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view)); - priv->views[GNOME_CAL_DAY_VIEW] = E_CALENDAR_VIEW (priv->day_view); priv->configs[GNOME_CAL_DAY_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_DAY_VIEW]))); priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CALENDAR_VIEW (priv->work_week_view); @@ -1571,13 +1489,11 @@ static void gnome_calendar_init (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - int i; priv = g_new0 (GnomeCalendarPrivate, 1); gcal->priv = priv; - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) - priv->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); if (non_intrusive_error_table == NULL) non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); @@ -1626,26 +1542,24 @@ gnome_calendar_destroy (GtkObject *object) e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), gcal); /* Clean up the clients */ - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) { - for (l = priv->clients_list[i]; l != NULL; l = l->next) { - g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - } + for (l = priv->clients_list; l != NULL; l = l->next) { + g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + } - g_hash_table_destroy (priv->clients[i]); - g_list_free (priv->clients_list[i]); + g_hash_table_destroy (priv->clients); + g_list_free (priv->clients_list); - priv->clients[i] = NULL; - priv->clients_list[i] = NULL; + priv->clients = NULL; + priv->clients_list = NULL; - if (priv->default_client[i]) { - g_signal_handlers_disconnect_matched (priv->default_client[i], - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - g_object_unref (priv->default_client[i]); - } - priv->default_client[i] = NULL; + if (priv->default_client) { + g_signal_handlers_disconnect_matched (priv->default_client, + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + g_object_unref (priv->default_client); } + priv->default_client = NULL; for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { if (priv->configs[i]) @@ -2178,7 +2092,6 @@ static void client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; ECalModel *model; ECalLoadState state; @@ -2188,19 +2101,10 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) priv = gcal->priv; - source_type = e_cal_get_source_type (ecal); source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; - default: - break; - } - - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED && source_type == E_CAL_SOURCE_TYPE_EVENT) + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED) auth_cal_forget_password (ecal); switch (status) { @@ -2238,30 +2142,27 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) return; } case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: - if (source_type == E_CAL_SOURCE_TYPE_EVENT) - { - /* check to see if we have dialog already running for this operation */ - id = g_strdup ("calendar:unable-to-load-the-calendar"); + /* check to see if we have dialog already running for this operation */ + id = g_strdup ("calendar:unable-to-load-the-calendar"); - if (g_hash_table_lookup(non_intrusive_error_table, id)) { - /* We already have it */ - g_message("Error occurred while existing dialog active:\n"); - return; - } - - w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL); - e_calendar_utils_show_error_silent (w); - g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w)); - g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id); + if (g_hash_table_lookup(non_intrusive_error_table, id)) { + /* We already have it */ + g_message("Error occurred while existing dialog active:\n"); + return; } + + w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL); + e_calendar_utils_show_error_silent (w); + g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w)); + g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id); default: /* Make sure the source doesn't disappear on us */ g_object_ref (source); - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status)); @@ -2271,49 +2172,32 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT : - msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal)); - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); - g_free (msg); - - /* add client to the views */ - model = e_calendar_view_get_model (priv->views[priv->current_view_type]); - add_mclient (model, ecal); + msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal)); + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); + g_free (msg); - /* update date navigator query */ - update_query (gcal); + /* add client to the views */ + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); + add_mclient (model, ecal); - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; + /* update date navigator query */ + update_query (gcal); - default: - g_return_if_reached (); - } + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); } static void default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; ECalLoadState state; priv = gcal->priv; - source_type = e_cal_get_source_type (ecal); source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; - default: - break; - } - switch (status) { case E_CALENDAR_STATUS_OK: break; @@ -2329,15 +2213,15 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar g_object_ref (source); /* FIXME should we do this to prevent multiple error dialogs? */ - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); /* FIXME Is there a better way to handle this? */ - if (priv->default_client[source_type]) - g_object_unref (priv->default_client[source_type]); - priv->default_client[source_type] = NULL; + if (priv->default_client) + g_object_unref (priv->default_client); + priv->default_client = NULL; - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status)); @@ -2348,16 +2232,10 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_cal_model_set_default_client ( - e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[priv->current_view_type])), - ecal); - break; - - default: - break; - } + e_cal_model_set_default_client ( + e_calendar_view_get_model ( + E_CALENDAR_VIEW (priv->views[priv->current_view_type])), + ecal); } typedef void (*open_func) (ECal *, ECalendarStatus, GnomeCalendar *); @@ -2375,14 +2253,7 @@ open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of e_cal_set_default_timezone (cal, zone, NULL); msg = g_strdup_printf (_("Opening %s"), e_cal_get_uri (cal)); - switch (e_cal_get_source_type (cal)) { - case E_CAL_SOURCE_TYPE_EVENT : - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); - break; - default: - g_free (msg); - g_return_val_if_reached (FALSE); - } + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); g_free (msg); @@ -2427,7 +2298,6 @@ backend_died_cb (ECal *ecal, gpointer data) { GnomeCalendar *gcal; GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; const char *id; GtkWidget *w = NULL; @@ -2438,24 +2308,16 @@ backend_died_cb (ECal *ecal, gpointer data) /* FIXME What about default sources? */ /* Make sure the source doesn't go away on us since we use it below */ - source_type = e_cal_get_source_type (ecal); source = g_object_ref (e_cal_get_source (ecal)); - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - id = g_strdup ("calendar:calendar-crashed"); + id = g_strdup ("calendar:calendar-crashed"); - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); - break; - - default: - g_return_if_reached (); - } + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); @@ -2547,7 +2409,7 @@ gnome_calendar_get_default_client (GnomeCalendar *gcal) * Returns: TRUE if successful, FALSE if error. */ gboolean -gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_add_source (GnomeCalendar *gcal, ESource *source) { GnomeCalendarPrivate *priv; ECal *client; @@ -2558,7 +2420,7 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source)); + client = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); if (client) { /* We already have it */ @@ -2566,18 +2428,18 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou } else { ESource *default_source; - if (priv->default_client[source_type]) { - default_source = e_cal_get_source (priv->default_client[source_type]); + if (priv->default_client) { + default_source = e_cal_get_source (priv->default_client); g_message ("Check if default client matches (%s %s)", e_source_peek_uid (default_source), e_source_peek_uid (source)); /* We don't have it but the default client is it */ if (!strcmp (e_source_peek_uid (default_source), e_source_peek_uid (source))) - client = g_object_ref (priv->default_client[source_type]); + client = g_object_ref (priv->default_client); } /* Create a new one */ if (!client) { - client = auth_new_cal_from_source (source, source_type); + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); if (!client) return FALSE; } @@ -2587,10 +2449,10 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal); /* add the client to internal structure */ - g_hash_table_insert (priv->clients[source_type], g_strdup (e_source_peek_uid (source)), client); - priv->clients_list[source_type] = g_list_prepend (priv->clients_list[source_type], client); + g_hash_table_insert (priv->clients, g_strdup (e_source_peek_uid (source)), client); + priv->clients_list = g_list_prepend (priv->clients_list, client); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source); open_ecal (gcal, client, FALSE, client_cal_opened_cb); @@ -2608,7 +2470,7 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou * Returns: TRUE if successful, FALSE otherwise. */ gboolean -gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_remove_source (GnomeCalendar *gcal, ESource *source) { gboolean result; @@ -2616,15 +2478,15 @@ gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, E g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - result = gnome_calendar_remove_source_by_uid (gcal, source_type, e_source_peek_uid (source)); + result = gnome_calendar_remove_source_by_uid (gcal, e_source_peek_uid (source)); if (result) - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); return result; } gboolean -gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const char *uid) +gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, const char *uid) { GnomeCalendarPrivate *priv; ECal *client; @@ -2637,41 +2499,34 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_ priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], uid); + client = g_hash_table_lookup (priv->clients, uid); if (!client) return TRUE; - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], client); + priv->clients_list = g_list_remove (priv->clients_list, client); g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - /* remove the query for this client */ - for (l = priv->dn_queries; l != NULL; l = l->next) { - ECalView *query = l->data; + /* remove the query for this client */ + for (l = priv->dn_queries; l != NULL; l = l->next) { + ECalView *query = l->data; - if (query && (client == e_cal_view_get_client (query))) { - g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - priv->dn_queries = g_list_remove (priv->dn_queries, query); - g_object_unref (query); - break; - } + if (query && (client == e_cal_view_get_client (query))) { + g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + priv->dn_queries = g_list_remove (priv->dn_queries, query); + g_object_unref (query); + break; } + } - model = e_calendar_view_get_model (priv->views[priv->current_view_type]); - e_cal_model_remove_client (model, client); - - /* update date navigator query */ - update_query (gcal); - break; + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); + e_cal_model_remove_client (model, client); - default: - g_return_val_if_reached (TRUE); - } + /* update date navigator query */ + update_query (gcal); - g_hash_table_remove (priv->clients[source_type], uid); + g_hash_table_remove (priv->clients, uid); return TRUE; } @@ -2689,7 +2544,7 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_ * otherwise **/ gboolean -gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_set_default_source (GnomeCalendar *gcal, ESource *source) { GnomeCalendarPrivate *priv; ECal *client; @@ -2700,21 +2555,21 @@ gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_ty priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source)); + client = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); - if (priv->default_client[source_type]) - g_object_unref (priv->default_client[source_type]); + if (priv->default_client) + g_object_unref (priv->default_client); if (client) { - priv->default_client[source_type] = g_object_ref (client); + priv->default_client = g_object_ref (client); } else { - priv->default_client[source_type] = auth_new_cal_from_source (source, source_type); - if (!priv->default_client[source_type]) + priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); + if (!priv->default_client) return FALSE; } - open_ecal (gcal, priv->default_client[source_type], FALSE, default_client_cal_opened_cb); + open_ecal (gcal, priv->default_client, FALSE, default_client_cal_opened_cb); return TRUE; } diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 7d354381bc..92fe2cba70 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -87,17 +87,13 @@ struct _GnomeCalendarClass { void (* dates_shown_changed) (GnomeCalendar *gcal); void (* calendar_selection_changed) (GnomeCalendar *gcal); - void (* taskpad_selection_changed) (GnomeCalendar *gcal); - void (* memopad_selection_changed) (GnomeCalendar *gcal); void (* calendar_focus_change) (GnomeCalendar *gcal, gboolean in); - void (* taskpad_focus_change) (GnomeCalendar *gcal, gboolean in); - void (* memopad_focus_change) (GnomeCalendar *gcal, gboolean in); - void (* change_view) (GnomeCalendar *gcal, - GnomeCalendarViewType view_type); + void (* change_view) (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); - void (* source_added) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); - void (* source_removed) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); + void (* source_added) (GnomeCalendar *gcal, ESource *source); + void (* source_removed) (GnomeCalendar *gcal, ESource *source); /* Action signals */ void (* goto_date) (GnomeCalendar *gcal, GnomeCalendarGotoDateType date); @@ -114,10 +110,10 @@ ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal); ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal); ECal *gnome_calendar_get_default_client (GnomeCalendar *gcal); -gboolean gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); -gboolean gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); -gboolean gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const char *uid); -gboolean gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); +gboolean gnome_calendar_add_source (GnomeCalendar *gcal, ESource *source); +gboolean gnome_calendar_remove_source (GnomeCalendar *gcal, ESource *source); +gboolean gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, const char *uid); +gboolean gnome_calendar_set_default_source (GnomeCalendar *gcal, ESource *source); void gnome_calendar_next (GnomeCalendar *gcal); void gnome_calendar_previous (GnomeCalendar *gcal); diff --git a/calendar/modules/e-cal-shell-content.c b/calendar/modules/e-cal-shell-content.c index 8356b2e679..80b989f64d 100644 --- a/calendar/modules/e-cal-shell-content.c +++ b/calendar/modules/e-cal-shell-content.c @@ -81,24 +81,10 @@ typedef enum { static gpointer parent_class; static void -cal_shell_content_changed_cb (ECalShellContent *cal_shell_content, - GalViewInstance *view_instance) -{ - EShellView *shell_view; - EShellContent *shell_content; - gchar *view_id; - - shell_content = E_SHELL_CONTENT (cal_shell_content); - shell_view = e_shell_content_get_shell_view (shell_content); - view_id = gal_view_instance_get_current_view_id (view_instance); - e_shell_view_set_view_id (shell_view, view_id); - g_free (view_id); -} - -static void cal_shell_content_display_view_cb (ECalShellContent *cal_shell_content, GalView *gal_view) { + /* FIXME */ } static void @@ -343,10 +329,8 @@ cal_shell_content_constructed (GObject *object) EShellModule *shell_module; EShellView *shell_view; EShellWindow *shell_window; - EShellViewClass *shell_view_class; EShellContent *foreign_content; EShellView *foreign_view; - GalViewCollection *view_collection; GalViewInstance *view_instance; GConfBridge *bridge; GtkWidget *container; @@ -365,8 +349,6 @@ cal_shell_content_constructed (GObject *object) shell_content = E_SHELL_CONTENT (object); shell_view = e_shell_content_get_shell_view (shell_content); shell_window = e_shell_view_get_shell_window (shell_view); - shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); - view_collection = shell_view_class->view_collection; shell_module = e_shell_view_get_shell_module (shell_view); config_dir = e_shell_module_get_config_dir (shell_module); @@ -557,11 +539,7 @@ cal_shell_content_constructed (GObject *object) /* Load the view instance. */ - view_instance = gal_view_instance_new (view_collection, NULL); - g_signal_connect_swapped ( - view_instance, "changed", - G_CALLBACK (cal_shell_content_changed_cb), - object); + view_instance = e_shell_view_new_view_instance (shell_view, NULL); g_signal_connect_swapped ( view_instance, "display-view", G_CALLBACK (cal_shell_content_display_view_cb), diff --git a/calendar/modules/e-memo-shell-content.c b/calendar/modules/e-memo-shell-content.c index f3d0d5bcbd..82495f836b 100644 --- a/calendar/modules/e-memo-shell-content.c +++ b/calendar/modules/e-memo-shell-content.c @@ -75,21 +75,6 @@ static GtkTargetEntry drag_types[] = { static gpointer parent_class; static void -memo_shell_content_changed_cb (EMemoShellContent *memo_shell_content, - GalViewInstance *view_instance) -{ - EShellView *shell_view; - EShellContent *shell_content; - gchar *view_id; - - shell_content = E_SHELL_CONTENT (memo_shell_content); - shell_view = e_shell_content_get_shell_view (shell_content); - view_id = gal_view_instance_get_current_view_id (view_instance); - e_shell_view_set_view_id (shell_view, view_id); - g_free (view_id); -} - -static void memo_shell_content_display_view_cb (EMemoShellContent *memo_shell_content, GalView *gal_view) { @@ -309,8 +294,6 @@ memo_shell_content_constructed (GObject *object) EMemoShellContentPrivate *priv; EShellContent *shell_content; EShellView *shell_view; - EShellViewClass *shell_view_class; - GalViewCollection *view_collection; GalViewInstance *view_instance; ETable *table; GConfBridge *bridge; @@ -325,8 +308,6 @@ memo_shell_content_constructed (GObject *object) shell_content = E_SHELL_CONTENT (object); shell_view = e_shell_content_get_shell_view (shell_content); - shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); - view_collection = shell_view_class->view_collection; /* Build content widgets. */ @@ -405,11 +386,7 @@ memo_shell_content_constructed (GObject *object) /* Load the view instance. */ - view_instance = gal_view_instance_new (view_collection, NULL); - g_signal_connect_swapped ( - view_instance, "changed", - G_CALLBACK (memo_shell_content_changed_cb), - object); + view_instance = e_shell_view_new_view_instance (shell_view, NULL); g_signal_connect_swapped ( view_instance, "display-view", G_CALLBACK (memo_shell_content_display_view_cb), diff --git a/calendar/modules/e-task-shell-content.c b/calendar/modules/e-task-shell-content.c index dec1760151..febd0c9ef2 100644 --- a/calendar/modules/e-task-shell-content.c +++ b/calendar/modules/e-task-shell-content.c @@ -76,21 +76,6 @@ static GtkTargetEntry drag_types[] = { static gpointer parent_class; static void -task_shell_content_changed_cb (ETaskShellContent *task_shell_content, - GalViewInstance *view_instance) -{ - EShellView *shell_view; - EShellContent *shell_content; - gchar *view_id; - - shell_content = E_SHELL_CONTENT (task_shell_content); - shell_view = e_shell_content_get_shell_view (shell_content); - view_id = gal_view_instance_get_current_view_id (view_instance); - e_shell_view_set_view_id (shell_view, view_id); - g_free (view_id); -} - -static void task_shell_content_display_view_cb (ETaskShellContent *task_shell_content, GalView *gal_view) { @@ -308,8 +293,6 @@ task_shell_content_constructed (GObject *object) ETaskShellContentPrivate *priv; EShellContent *shell_content; EShellView *shell_view; - EShellViewClass *shell_view_class; - GalViewCollection *view_collection; GalViewInstance *view_instance; ETable *table; GConfBridge *bridge; @@ -324,8 +307,6 @@ task_shell_content_constructed (GObject *object) shell_content = E_SHELL_CONTENT (object); shell_view = e_shell_content_get_shell_view (shell_content); - shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); - view_collection = shell_view_class->view_collection; /* Build content widgets. */ @@ -404,11 +385,7 @@ task_shell_content_constructed (GObject *object) /* Load the view instance. */ - view_instance = gal_view_instance_new (view_collection, NULL); - g_signal_connect_swapped ( - view_instance, "changed", - G_CALLBACK (task_shell_content_changed_cb), - object); + view_instance = e_shell_view_new_view_instance (shell_view, NULL); g_signal_connect_swapped ( view_instance, "display-view", G_CALLBACK (task_shell_content_display_view_cb), diff --git a/doc/reference/shell/Makefile.am b/doc/reference/shell/Makefile.am index 6489b92840..fb2533f0a0 100644 --- a/doc/reference/shell/Makefile.am +++ b/doc/reference/shell/Makefile.am @@ -74,6 +74,7 @@ GTKDOC_LIBS= \ $(top_builddir)/shell/es-event.o \ $(top_builddir)/shell/.libs/e-shell-content.o \ $(top_builddir)/shell/.libs/e-shell-module.o \ + $(top_builddir)/shell/.libs/e-shell-settings.o \ $(top_builddir)/shell/.libs/e-shell-sidebar.o \ $(top_builddir)/shell/.libs/e-shell-switcher.o \ $(top_builddir)/shell/.libs/e-shell-taskbar.o \ diff --git a/doc/reference/shell/tmpl/e-shell.sgml b/doc/reference/shell/tmpl/e-shell.sgml index c747834f4e..2b1b292778 100644 --- a/doc/reference/shell/tmpl/e-shell.sgml +++ b/doc/reference/shell/tmpl/e-shell.sgml @@ -69,6 +69,11 @@ EShell </para> +<!-- ##### ARG EShell:settings ##### --> +<para> + +</para> + <!-- ##### ENUM EShellLineStatus ##### --> <para> diff --git a/e-util/Makefile.am b/e-util/Makefile.am index c182105e49..834466bbc9 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -41,6 +41,7 @@ privsolib_LTLIBRARIES = libeutil.la libeconduit.la eutilinclude_HEADERS = \ e-bconf-map.h \ + e-binding.h \ e-categories-config.h \ e-config.h \ e-config-listener.h \ @@ -82,6 +83,7 @@ eutilinclude_HEADERS = \ libeutil_la_SOURCES = \ $(eutilinclude_HEADERS) \ e-bconf-map.c \ + e-binding.c \ e-categories-config.c \ e-config-listener.c \ e-config.c \ diff --git a/e-util/e-binding.c b/e-util/e-binding.c new file mode 100644 index 0000000000..26e62c6a23 --- /dev/null +++ b/e-util/e-binding.c @@ -0,0 +1,482 @@ +/* + * e-binding.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-binding.h" + +static gboolean +e_binding_transform_negate (const GValue *src_value, + GValue *dst_value) +{ + if (!g_value_transform (src_value, dst_value)) + return FALSE; + + g_value_set_boolean (dst_value, !g_value_get_boolean (dst_value)); + + return TRUE; +} + +static void +e_bind_properties_transfer (GObject *src_object, + GParamSpec *src_pspec, + GObject *dst_object, + GParamSpec *dst_pspec, + EBindingTransform transform, + gpointer user_data) +{ + const gchar *src_name; + const gchar *dst_name; + gboolean result; + GValue src_value = { 0, }; + GValue dst_value = { 0, }; + + src_name = g_param_spec_get_name (src_pspec); + dst_name = g_param_spec_get_name (dst_pspec); + + g_value_init (&src_value, G_PARAM_SPEC_VALUE_TYPE (src_pspec)); + g_object_get_property (src_object, src_name, &src_value); + + g_value_init (&dst_value, G_PARAM_SPEC_VALUE_TYPE (dst_pspec)); + result = (*transform) (&src_value, &dst_value, user_data); + + g_value_unset (&src_value); + + g_return_if_fail (result); + + g_param_value_validate (dst_pspec, &dst_value); + g_object_set_property (dst_object, dst_name, &dst_value); + g_value_unset (&dst_value); +} + +static void +e_bind_properties_notify (GObject *src_object, + GParamSpec *src_pspec, + gpointer data) +{ + EBindingLink *link = data; + + /* Block the destination handler for mutual bindings, + * so we don't recurse here. */ + if (link->dst_handler != 0) + g_signal_handler_block (link->dst_object, link->dst_handler); + + e_bind_properties_transfer ( + src_object, src_pspec, + link->dst_object, link->dst_pspec, + link->transform, link->user_data); + + /* Unblock destination handler. */ + if (link->dst_handler != 0) + g_signal_handler_unblock (link->dst_object, link->dst_handler); +} + +static void +e_binding_on_dst_object_destroy (gpointer data, + GObject *object) +{ + EBinding *binding = data; + + binding->link.dst_object = NULL; + + /* Calls e_binding_on_disconnect() */ + g_signal_handler_disconnect ( + binding->src_object, binding->link.handler); +} + +static void +e_binding_on_disconnect (gpointer data, + GClosure *closure) +{ + EBindingLink *link = data; + EBinding *binding; + + binding = (EBinding *) + (((gchar *) link) - G_STRUCT_OFFSET (EBinding, link)); + + if (binding->base.destroy != NULL) + binding->base.destroy (link->user_data); + + if (link->dst_object != NULL) + g_object_weak_unref ( + link->dst_object, + e_binding_on_dst_object_destroy, binding); + + g_slice_free (EBinding, binding); +} + +/* Recursively calls e_mutual_binding_on_disconnect_object2() */ +static void +e_mutual_binding_on_disconnect_object1 (gpointer data, + GClosure *closure) +{ + EMutualBinding *binding; + EBindingLink *link = data; + GObject *object2; + + binding = (EMutualBinding *) + (((gchar *) link) - G_STRUCT_OFFSET (EMutualBinding, direct)); + binding->reverse.dst_object = NULL; + + object2 = binding->direct.dst_object; + if (object2 != NULL) { + if (binding->base.destroy != NULL) + binding->base.destroy (binding->direct.user_data); + binding->direct.dst_object = NULL; + g_signal_handler_disconnect (object2, binding->reverse.handler); + g_slice_free (EMutualBinding, binding); + } +} + +/* Recursively calls e_mutual_binding_on_disconnect_object1() */ +static void +e_mutual_binding_on_disconnect_object2 (gpointer data, + GClosure *closure) +{ + EMutualBinding *binding; + EBindingLink *link = data; + GObject *object1; + + binding = (EMutualBinding *) + (((gchar *) link) - G_STRUCT_OFFSET (EMutualBinding, reverse)); + binding->direct.dst_object = NULL; + + object1 = binding->reverse.dst_object; + if (object1 != NULL) { + binding->reverse.dst_object = NULL; + g_signal_handler_disconnect (object1, binding->direct.handler); + } +} + +static void +e_binding_link_init (EBindingLink *link, + GObject *src_object, + const gchar *src_property, + GObject *dst_object, + GParamSpec *dst_pspec, + EBindingTransform transform, + GClosureNotify destroy_notify, + gpointer user_data) +{ + gchar *signal_name; + + link->dst_object = dst_object; + link->dst_pspec = dst_pspec; + link->dst_handler = 0; + link->transform = transform; + link->user_data = user_data; + + signal_name = g_strconcat ("notify::", src_property, NULL); + link->handler = g_signal_connect_data ( + src_object, signal_name, + G_CALLBACK (e_bind_properties_notify), + link, destroy_notify, 0); + g_free (signal_name); +} + +/** + * e_binding_new: + * @src_object: The source #GObject. + * @src_property: The name of the property to bind from. + * @dst_object: The destination #GObject. + * @dst_property: The name of the property to bind to. + * + * One-way binds @src_property in @src_object to @dst_property + * in @dst_object. + * + * Before binding the value of @dst_property is set to the + * value of @src_property. + * + * Returns: The descriptor of the binding. It is automatically + * removed if one of the objects is finalized. + **/ +EBinding * +e_binding_new (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property) +{ + return e_binding_new_full ( + src_object, src_property, + dst_object, dst_property, + NULL, NULL, NULL); +} + +/** + * e_binding_new_full: + * @src_object: The source #GObject. + * @src_property: The name of the property to bind from. + * @dst_object: The destination #GObject. + * @dst_property: The name of the property to bind to. + * @transform: Transformation function or %NULL. + * @destroy_notify: Callback function that is called on + * disconnection with @user_data or %NULL. + * @user_data: User data associated with the binding. + * + * One-way binds @src_property in @src_object to @dst_property + * in @dst_object. + * + * Before binding the value of @dst_property is set to the + * value of @src_property. + * + * Returns: The descriptor of the binding. It is automatically + * removed if one of the objects is finalized. + **/ +EBinding * +e_binding_new_full (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property, + EBindingTransform transform, + GDestroyNotify destroy_notify, + gpointer user_data) +{ + EBinding *binding; + GParamSpec *src_pspec; + GParamSpec *dst_pspec; + + g_return_val_if_fail (G_IS_OBJECT (src_object), NULL); + g_return_val_if_fail (G_IS_OBJECT (dst_object), NULL); + + src_pspec = g_object_class_find_property ( + G_OBJECT_GET_CLASS (src_object), src_property); + dst_pspec = g_object_class_find_property ( + G_OBJECT_GET_CLASS (dst_object), dst_property); + + if (transform == NULL) + transform = (EBindingTransform) g_value_transform; + + e_bind_properties_transfer ( + src_object, src_pspec, + dst_object, dst_pspec, + transform, user_data); + + binding = g_slice_new (EBinding); + binding->src_object = src_object; + binding->base.destroy = destroy_notify; + + e_binding_link_init ( + &binding->link, src_object, src_property, dst_object, + dst_pspec, transform, e_binding_on_disconnect, user_data); + + g_object_weak_ref ( + dst_object, e_binding_on_dst_object_destroy, binding); + + return binding; +} + +/** + * e_binding_new_with_negation: + * @src_object: The source #GObject. + * @src_property: The name of the property to bind from. + * @dst_object: The destination #GObject. + * @dst_property: The name of the property to bind to. + * + * Convenience function for binding with boolean negation of value. + * + * Return: The descriptor of the binding. It is automatically + * removed if one of the objects is finalized. + **/ +EBinding * +e_binding_new_with_negation (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property) +{ + EBindingTransform transform; + + transform = (EBindingTransform) e_binding_transform_negate; + + return e_binding_new_full ( + src_object, src_property, + dst_object, dst_property, + transform, NULL, NULL); +} + +/** + * e_binding_unbind: + * @binding: An #EBinding to unbind. + * + * Disconnects the binding between two properties. Should be + * rarely used by applications. + * + * This functions also calls the @destroy_notify function that + * was specified when @binding was created. + **/ +void +e_binding_unbind (EBinding *binding) +{ + g_signal_handler_disconnect ( + binding->src_object, binding->link.handler); +} + +/** + * e_mutual_binding_new: + * @object1 : The first #GObject. + * @property1: The first property to bind. + * @object2 : The second #GObject. + * @property2: The second property to bind. + * + * Mutually binds values of two properties. + * + * Before binding the value of @property2 is set to the value + * of @property1. + * + * Returns: The descriptor of the binding. It is automatically + * removed if one of the objects is finalized. + **/ +EMutualBinding * +e_mutual_binding_new (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2) +{ + return e_mutual_binding_new_full ( + object1, property1, + object2, property2, + NULL, NULL, NULL, NULL); +} + +/** + * e_mutual_binding_new_full: + * @object1: The first #GObject. + * @property1: The first property to bind. + * @object2: The second #GObject. + * @property2: The second property to bind. + * @transform: Transformation function or %NULL. + * @reverse_transform: The inverse transformation function or %NULL. + * @destroy_notify: Callback function called on disconnection with + * @user_data as argument or %NULL. + * @user_data: User data associated with the binding. + * + * Mutually binds values of two properties. + * + * Before binding the value of @property2 is set to the value of + * @property1. + * + * Both @transform and @reverse_transform should simultaneously be + * %NULL or non-%NULL. If they are non-%NULL, they should be reverse + * in each other. + * + * Returns: The descriptor of the binding. It is automatically + * removed if one of the objects is finalized. + **/ +EMutualBinding * +e_mutual_binding_new_full (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2, + EBindingTransform transform, + EBindingTransform reverse_transform, + GDestroyNotify destroy_notify, + gpointer user_data) +{ + EMutualBinding *binding; + GParamSpec *pspec1; + GParamSpec *pspec2; + + g_return_val_if_fail (G_IS_OBJECT (object1), NULL); + g_return_val_if_fail (G_IS_OBJECT (object2), NULL); + + pspec1 = g_object_class_find_property ( + G_OBJECT_GET_CLASS (object1), property1); + pspec2 = g_object_class_find_property ( + G_OBJECT_GET_CLASS (object2), property2); + + if (transform == NULL) + transform = (EBindingTransform) g_value_transform; + + if (reverse_transform == NULL) + reverse_transform = (EBindingTransform) g_value_transform; + + e_bind_properties_transfer ( + object1, pspec1, object2, + pspec2, transform, user_data); + + binding = g_slice_new (EMutualBinding); + binding->base.destroy = destroy_notify; + + e_binding_link_init ( + &binding->direct, + object1, property1, object2, pspec2, transform, + e_mutual_binding_on_disconnect_object1, user_data); + + e_binding_link_init ( + &binding->reverse, + object2, property2, object1, pspec1, reverse_transform, + e_mutual_binding_on_disconnect_object2, user_data); + + /* Tell each link about the reverse link for mutual bindings, + * to make sure that we do not ever recurse in notify (yeah, + * the GObject notify dispatching is really weird!). */ + binding->direct.dst_handler = binding->reverse.handler; + binding->reverse.dst_handler = binding->direct.handler; + + return binding; +} + +/** + * e_mutual_binding_new_with_negation: + * @object1: The first #GObject. + * @property1: The first property to bind. + * @object2: The second #GObject. + * @property2: The second property to bind. + * + * Convenience function for binding with boolean negation of value. + * + * Returns: The descriptor of the binding. It is automatically removed + * if one of the objects if finalized. + **/ +EMutualBinding* +e_mutual_binding_new_with_negation (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2) +{ + EBindingTransform transform; + + transform = (EBindingTransform) e_binding_transform_negate; + + return e_mutual_binding_new_full ( + object1, property1, + object2, property2, + transform, transform, + NULL, NULL); +} + +/** + * e_mutual_binding_unbind: + * @binding: An #EMutualBinding to unbind. + * + * Disconnects the binding between two properties. Should be + * rarely used by applications. + * + * This functions also calls the @destroy_notify function that + * was specified when @binding was created. + **/ +void +e_mutual_binding_unbind (EMutualBinding *binding) +{ + g_signal_handler_disconnect ( + binding->reverse.dst_object, binding->direct.handler); +} diff --git a/e-util/e-binding.h b/e-util/e-binding.h new file mode 100644 index 0000000000..2cced75920 --- /dev/null +++ b/e-util/e-binding.h @@ -0,0 +1,107 @@ +/* + * e-binding.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* This is a direct rip-off of Xfce's excellent ExoBinding API, + * which binds two GObject properties together. ExoBinding was + * written by Benedikt Meurer <benny@xfce.org>. */ + +#ifndef E_BINDING_H +#define E_BINDING_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +typedef struct _EBinding EBinding; +typedef struct _EBindingBase EBindingBase; +typedef struct _EBindingLink EBindingLink; +typedef struct _EMutualBinding EMutualBinding; + +typedef gboolean (*EBindingTransform) (const GValue *src_value, + GValue *dst_value, + gpointer user_data); + +struct _EBindingBase { + GDestroyNotify destroy; +}; + +struct _EBindingLink { + GObject *dst_object; + GParamSpec *dst_pspec; + gulong dst_handler; /* only set for mutual bindings */ + gulong handler; + EBindingTransform transform; + gpointer user_data; +}; + +struct _EBinding { + /*< private >*/ + GObject *src_object; + EBindingBase base; + EBindingLink link; +}; + +struct _EMutualBinding { + /*< private >*/ + EBindingBase base; + EBindingLink direct; + EBindingLink reverse; +}; + +EBinding * e_binding_new (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property); +EBinding * e_binding_new_full (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property, + EBindingTransform transform, + GDestroyNotify destroy_notify, + gpointer user_data); +EBinding * e_binding_new_with_negation (GObject *src_object, + const gchar *src_property, + GObject *dst_object, + const gchar *dst_property); +void e_binding_unbind (EBinding *binding); + +EMutualBinding *e_mutual_binding_new (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2); +EMutualBinding *e_mutual_binding_new_full (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2, + EBindingTransform transform, + EBindingTransform reverse_transform, + GDestroyNotify destroy_notify, + gpointer user_data); +EMutualBinding *e_mutual_binding_new_with_negation + (GObject *object1, + const gchar *property1, + GObject *object2, + const gchar *property2); +void e_mutual_binding_unbind (EMutualBinding *binding); + +G_END_DECLS + +#endif /* E_BINDING_H */ diff --git a/mail/Makefile.am b/mail/Makefile.am index 09f26f5d56..d3ed2750f8 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -85,6 +85,8 @@ libevolution_module_mail_la_SOURCES = \ em-folder-tree.h \ em-folder-tree-model.c \ em-folder-tree-model.h \ + em-folder-view.c \ + em-folder-view.h \ em-folder-utils.c \ em-folder-utils.h \ em-format.c \ @@ -109,6 +111,10 @@ libevolution_module_mail_la_SOURCES = \ em-junk-hook.h \ em-mailer-prefs.c \ em-mailer-prefs.h \ + em-menu.c \ + em-menu.h \ + em-message-browser.c \ + em-message-browser.h \ em-network-prefs.c \ em-network-prefs.h \ em-popup.c \ @@ -149,6 +155,8 @@ libevolution_module_mail_la_SOURCES = \ mail-tools.h \ mail-vfolder.c \ mail-vfolder.h \ + message-list.c \ + message-list.h \ message-tag-editor.c \ message-tag-editor.h \ message-tag-followup.c \ diff --git a/mail/e-mail-shell-content.c b/mail/e-mail-shell-content.c index 144d70d671..6d1ffc0a08 100644 --- a/mail/e-mail-shell-content.c +++ b/mail/e-mail-shell-content.c @@ -22,11 +22,16 @@ #include "e-mail-shell-content.h" #include <glib/gi18n.h> +#include <libedataserver/e-data-server-util.h> #include "e-util/gconf-bridge.h" +#include "widgets/menus/gal-view-etable.h" +#include "widgets/menus/gal-view-instance.h" -#include "em-folder-browser.h" +#include "em-folder-view.h" #include "em-search-context.h" +#include "em-utils.h" +#include "mail-config.h" #define E_MAIL_SHELL_CONTENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -34,9 +39,11 @@ struct _EMailShellContentPrivate { GtkWidget *paned; - GtkWidget *msglist; + GtkWidget *folder_view; GtkWidget *preview; + GalViewInstance *view_instance; + guint paned_binding_id; guint preview_visible : 1; @@ -52,6 +59,20 @@ enum { static gpointer parent_class; static void +mail_shell_content_display_view_cb (EMailShellContent *mail_shell_content, + GalView *gal_view) +{ + EMFolderView *folder_view; + + folder_view = e_mail_shell_content_get_folder_view (mail_shell_content); + + if (GAL_IS_VIEW_ETABLE (gal_view)) + gal_view_etable_attach_tree ( + GAL_VIEW_ETABLE (gal_view), + folder_view->list->tree); +} + +static void mail_shell_content_set_property (GObject *object, guint property_id, const GValue *value, @@ -110,9 +131,9 @@ mail_shell_content_dispose (GObject *object) priv->paned = NULL; } - if (priv->msglist != NULL) { - g_object_unref (priv->msglist); - priv->msglist = NULL; + if (priv->folder_view != NULL) { + g_object_unref (priv->folder_view); + priv->folder_view = NULL; } if (priv->preview != NULL) { @@ -120,6 +141,11 @@ mail_shell_content_dispose (GObject *object) priv->preview = NULL; } + if (priv->view_instance != NULL) { + g_object_unref (priv->view_instance); + priv->view_instance = NULL; + } + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -139,9 +165,13 @@ static void mail_shell_content_constructed (GObject *object) { EMailShellContentPrivate *priv; + EShellContent *shell_content; + EShellView *shell_view; + EShellViewClass *shell_view_class; GConfBridge *bridge; GtkWidget *container; GtkWidget *widget; + GalViewCollection *view_collection; const gchar *key; priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (object); @@ -149,6 +179,11 @@ mail_shell_content_constructed (GObject *object) /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (parent_class)->constructed (object); + shell_content = E_SHELL_CONTENT (object); + shell_view = e_shell_content_get_shell_view (shell_content); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + view_collection = shell_view_class->view_collection; + /* Build content widgets. */ container = GTK_WIDGET (object); @@ -160,10 +195,9 @@ mail_shell_content_constructed (GObject *object) container = widget; - /*widget = em_folder_browser_new ();*/ - widget = gtk_label_new ("Message List"); + widget = em_folder_view_new (); gtk_paned_add1 (GTK_PANED (container), widget); - priv->msglist = g_object_ref (widget); + priv->folder_view = g_object_ref (widget); gtk_widget_show (widget); widget = gtk_scrolled_window_new (NULL, NULL); @@ -175,6 +209,11 @@ mail_shell_content_constructed (GObject *object) gtk_paned_add2 (GTK_PANED (container), widget); gtk_widget_show (widget); + /* Load the view instance. */ + + e_mail_shell_content_update_view_instance ( + E_MAIL_SHELL_CONTENT (object)); + /* Bind GObject properties to GConf keys. */ bridge = gconf_bridge_get (); @@ -190,6 +229,8 @@ mail_shell_content_check_state (EShellContent *shell_content) EMailShellContent *mail_shell_content; guint32 state = 0; + /* FIXME */ + mail_shell_content = E_MAIL_SHELL_CONTENT (shell_content); return state; @@ -284,6 +325,15 @@ e_mail_shell_content_new (EShellView *shell_view) "shell-view", shell_view, NULL); } +EMFolderView * +e_mail_shell_content_get_folder_view (EMailShellContent *mail_shell_content) +{ + g_return_val_if_fail ( + E_IS_MAIL_SHELL_CONTENT (mail_shell_content), NULL); + + return EM_FOLDER_VIEW (mail_shell_content->priv->folder_view); +} + gboolean e_mail_shell_content_get_preview_visible (EMailShellContent *mail_shell_content) { @@ -378,3 +428,140 @@ e_mail_shell_content_set_vertical_view (EMailShellContent *mail_shell_content, g_object_notify (G_OBJECT (mail_shell_content), "vertical-view"); } + +void +e_mail_shell_content_update_view_instance (EMailShellContent *mail_shell_content) +{ + EShellContent *shell_content; + EShellView *shell_view; + EShellViewClass *shell_view_class; + GalViewCollection *view_collection; + GalViewInstance *view_instance; + EMFolderView *folder_view; + gboolean outgoing_folder; + gboolean show_vertical_view; + gchar *view_id; + + g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content)); + + shell_content = E_SHELL_CONTENT (mail_shell_content); + shell_view = e_shell_content_get_shell_view (shell_content); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + view_collection = shell_view_class->view_collection; + + folder_view = e_mail_shell_content_get_folder_view (mail_shell_content); + g_return_if_fail (folder_view->folder != NULL); + g_return_if_fail (folder_view->folder_uri != NULL); + + if (mail_shell_content->priv->view_instance != NULL) { + g_object_unref (mail_shell_content->priv->view_instance); + mail_shell_content->priv->view_instance = NULL; + } + + /* TODO: Should this go through the mail-config API? */ + view_id = mail_config_folder_to_safe_url (folder_view->folder); + view_instance = e_shell_view_new_view_instance (shell_view, view_id); + mail_shell_content->priv->view_instance = view_instance; + + show_vertical_view = folder_view->list_active && + e_mail_shell_content_get_vertical_view (mail_shell_content); + + if (show_vertical_view) { + gchar *filename; + gchar *safe_view_id; + + /* Force the view instance into vertical view. */ + + g_free (view_instance->custom_filename); + g_free (view_instance->current_view_filename); + + safe_view_id = g_strdup (view_id); + e_filename_make_safe (safe_view_id); + + filename = g_strdup_printf ( + "custom_wide_view-%s.xml", safe_view_id); + view_instance->custom_filename = g_build_filename ( + view_collection->local_dir, filename, NULL); + g_free (filename); + + filename = g_strdup_printf ( + "current_wide_view-%s.xml", safe_view_id); + view_instance->current_view_filename = g_build_filename ( + view_collection->local_dir, filename, NULL); + g_free (filename); + + g_free (safe_view_id); + } + + g_free (view_id); + + outgoing_folder = + em_utils_folder_is_drafts ( + folder_view->folder, folder_view->folder_uri) || + em_utils_folder_is_outbox ( + folder_view->folder, folder_view->folder_uri) || + em_utils_folder_is_sent ( + folder_view->folder, folder_view->folder_uri); + + if (outgoing_folder) { + if (show_vertical_view) + gal_view_instance_set_default_view ( + view_instance, "Wide_View_Sent"); + else + gal_view_instance_set_default_view ( + view_instance, "As_Sent_Folder"); + } else if (show_vertical_view) { + gal_view_instance_set_default_view ( + view_instance, "Wide_View_Normal"); + } + + gal_view_instance_load (view_instance); + + if (!gal_view_instance_exists (view_instance)) { + gchar *state_filename; + + state_filename = mail_config_folder_to_cachename ( + folder_view->folder, "et-header-"); + + if (g_file_test (state_filename, G_FILE_TEST_IS_REGULAR)) { + ETableSpecification *spec; + ETableState *state; + GalView *view; + gchar *spec_filename; + + spec = e_table_specification_new (); + spec_filename = g_build_filename ( + EVOLUTION_ETSPECDIR, + "message-list.etspec", + NULL); + e_table_specification_load_from_file ( + spec, spec_filename); + g_free (spec_filename); + + state = e_table_state_new (); + view = gal_view_etable_new (spec, ""); + + e_table_state_load_from_file ( + state, state_filename); + gal_view_etable_set_state ( + GAL_VIEW_ETABLE (view), state); + gal_view_instance_set_custom_view ( + view_instance, view); + + g_object_unref (state); + g_object_unref (view); + g_object_unref (spec); + } + + g_free (state_filename); + } + + g_signal_connect ( + view_instance, "display-view", + G_CALLBACK (mail_shell_content_display_view_cb), + mail_shell_content); + + mail_shell_content_display_view_cb ( + mail_shell_content, + gal_view_instance_get_current_view (view_instance)); +} diff --git a/mail/e-mail-shell-content.h b/mail/e-mail-shell-content.h index 09ab5c8fda..a15dd0309b 100644 --- a/mail/e-mail-shell-content.h +++ b/mail/e-mail-shell-content.h @@ -25,6 +25,8 @@ #include <shell/e-shell-content.h> #include <shell/e-shell-view.h> +#include "em-folder-view.h" + /* Standard GObject macros */ #define E_TYPE_MAIL_SHELL_CONTENT \ (e_mail_shell_content_get_type ()) @@ -83,6 +85,8 @@ struct _EMailShellContentClass { GType e_mail_shell_content_get_type (void); GtkWidget * e_mail_shell_content_new (EShellView *shell_view); +EMFolderView * e_mail_shell_content_get_folder_view + (EMailShellContent *mail_shell_content); gboolean e_mail_shell_content_get_preview_visible (EMailShellContent *mail_shell_content); void e_mail_shell_content_set_preview_visible @@ -93,6 +97,8 @@ gboolean e_mail_shell_content_get_vertical_view void e_mail_shell_content_set_vertical_view (EMailShellContent *mail_shell_content, gboolean vertical_view); +void e_mail_shell_content_update_view_instance + (EMailShellContent *mail_shell_content); G_END_DECLS diff --git a/mail/e-mail-shell-module.c b/mail/e-mail-shell-module.c index 493cbfff63..51d109e1e1 100644 --- a/mail/e-mail-shell-module.c +++ b/mail/e-mail-shell-module.c @@ -373,15 +373,14 @@ mail_shell_module_load_accounts (EShellModule *shell_module) } static void -mail_shell_module_new_mail_cb (EShellWindow *shell_window) +mail_shell_module_mail_icon_cb (EShellWindow *shell_window, + const gchar *icon_name) { GtkAction *action; action = e_shell_window_get_shell_view_action ( shell_window, MODULE_NAME); - g_object_set (action, "icon-name", "mail-unread", NULL); - - g_print ("Shell Event: new-mail\n"); + g_object_set (action, "icon-name", icon_name, NULL); } static void @@ -419,7 +418,7 @@ static GtkActionEntry source_entries[] = { }; static void -mail_shell_module_init_preferences (void) +mail_shell_module_init_preferences (EShell *shell) { GtkWidget *preferences_window; @@ -438,7 +437,7 @@ mail_shell_module_init_preferences (void) "mail", "preferences-mail", _("Mail Preferences"), - em_mailer_prefs_new (), + em_mailer_prefs_new (shell), 300); e_preferences_window_add_page ( @@ -458,6 +457,267 @@ mail_shell_module_init_preferences (void) 500); } +static void +mail_shell_module_init_settings (EShell *shell) +{ + EShellSettings *shell_settings; + + shell_settings = e_shell_get_settings (shell); + + /* XXX Default values should match the GConf schema. + * Yes it's redundant, but we're stuck with GConf. */ + + /*** Mail Preferences ***/ + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-address-compress", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_int ( + "mail-address-count", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_string ( + "mail-citation-color", + NULL, + NULL, + "#737373", + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-check-for-junk", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-confirm-expunge", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-confirm-unwanted-html", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-empty-trash-on-exit", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-enable-search-folders", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_string ( + "mail-font-monospace", + NULL, + NULL, + "", + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_string ( + "mail-font-variable", + NULL, + NULL, + "", + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-force-message-limit", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-magic-spacebar", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-mark-citations", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-mark-seen", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_int ( + "mail-mark-seen-timeout", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_int ( + "mail-message-text-part-limit", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-only-local-photos", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-show-animated-images", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-show-sender-photo", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "mail-use-custom-fonts", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + + /* Bind shell settings to GConf keys. */ + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-address-compress", + "/apps/evolution/mail/display/address_compress"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-address-count", + "/apps/evolution/mail/display/address_count"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-citation-color", + "/apps/evolution/mail/display/citation_colour"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-check-for-junk", + "/apps/evolution/mail/junk/check_incoming"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-confirm-expunge", + "/apps/evolution/mail/prompts/expunge"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-confirm-unwanted-html", + "/apps/evolution/mail/prompts/unwanted_html"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-empty-trash-on-exit", + "/apps/evolution/mail/trash/empty_on_exit"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-enable-search-folders", + "/apps/evolution/mail/display/enable_vfolders"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-font-monospace", + "/apps/evolution/mail/display/fonts/monospace"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-font-variable", + "/apps/evolution/mail/display/fonts/variable"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-force-message-limit", + "/apps/evolution/mail/display/force_message_limit"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-magic-spacebar", + "/apps/evolution/mail/display/magic_spacebar"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-mark-citations", + "/apps/evolution/mail/display/mark_citations"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-mark-seen", + "/apps/evolution/mail/display/mark_seen"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-mark-seen-timeout", + "/apps/evolution/mail/display/mark_seen_timeout"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-message-text-part-limit", + "/apps/evolution/mail/display/message_text_part_limit"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-only-local-photos", + "/apps/evolution/mail/display/photo_local"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-show-animated-images", + "/apps/evolution/mail/display/animated_images"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-show-sender-photo", + "/apps/evolution/mail/display/sender_photo"); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-use-custom-fonts", + "/apps/evolution/mail/display/fonts/use_custom"); +} + static gboolean mail_shell_module_handle_uri_cb (EShell *shell, const gchar *uri, @@ -472,7 +732,7 @@ mail_shell_module_window_weak_notify_cb (EShell *shell, GObject *where_the_object_was) { g_signal_handlers_disconnect_by_func ( - shell, mail_shell_module_new_mail_cb, + shell, mail_shell_module_mail_icon_cb, where_the_object_was); } @@ -494,8 +754,8 @@ mail_shell_module_window_created_cb (EShell *shell, source_entries, G_N_ELEMENTS (source_entries)); g_signal_connect_swapped ( - shell, "event::new-mail", - G_CALLBACK (mail_shell_module_new_mail_cb), shell_window); + shell, "event::mail-icon", + G_CALLBACK (mail_shell_module_mail_icon_cb), shell_window); g_object_weak_ref ( G_OBJECT (shell_window), (GWeakNotify) @@ -560,7 +820,11 @@ e_shell_module_init (GTypeModule *type_module) mail_shell_module_init_local_store (shell_module); mail_shell_module_load_accounts (shell_module); - mail_shell_module_init_preferences (); + + /* Initialize settings before initializing preferences, + * since the preferences bind to the shell settings. */ + mail_shell_module_init_settings (shell); + mail_shell_module_init_preferences (shell); } /******************************** Public API *********************************/ @@ -665,3 +929,20 @@ e_mail_shell_module_remove_store_by_uri (EShellModule *shell_module, { /* FIXME */ } + +void +e_mail_shell_module_stores_foreach (EShellModule *shell_module, + GHFunc func, + gpointer user_data) +{ + GHashTableIter iter; + gpointer key, value; + + g_return_if_fail (E_IS_SHELL_MODULE (shell_module)); + g_return_if_fail (func != NULL); + + g_hash_table_iter_init (&iter, store_hash); + + while (g_hash_table_iter_next (&iter, &key, &value)) + func (key, ((StoreInfo *) value)->name, user_data); +} diff --git a/mail/e-mail-shell-module.h b/mail/e-mail-shell-module.h index b15c8ed8c8..567e5f2778 100644 --- a/mail/e-mail-shell-module.h +++ b/mail/e-mail-shell-module.h @@ -69,6 +69,10 @@ CamelStore * e_mail_shell_module_load_store_by_uri void e_mail_shell_module_remove_store_by_uri (EShellModule *shell_module, const gchar *uri); +void e_mail_shell_module_stores_foreach + (EShellModule *shell_module, + GHFunc func, + gpointer user_data); G_END_DECLS diff --git a/mail/e-mail-shell-view-actions.c b/mail/e-mail-shell-view-actions.c index 02607e5531..3c7a5fdf7f 100644 --- a/mail/e-mail-shell-view-actions.c +++ b/mail/e-mail-shell-view-actions.c @@ -1788,16 +1788,21 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view) bridge = gconf_bridge_get (); + object = G_OBJECT (ACTION (MAIL_CARET_MODE)); + key = "/apps/evolution/mail/display/caret_mode"; + gconf_bridge_bind_property (bridge, key, object, "active"); + object = G_OBJECT (ACTION (MAIL_PREVIEW)); key = "/apps/evolution/mail/display/show_preview"; gconf_bridge_bind_property (bridge, key, object, "active"); - /* XXX This is ugly. We're binding an integer property to a - * boolean GConf key. But since there's only two possible - * mail views (for now, anyway), it happens to work. */ - object = G_OBJECT (ACTION (MAIL_VIEW_CLASSIC)); + object = G_OBJECT (ACTION (MAIL_VIEW_VERTICAL)); key = "/apps/evolution/mail/display/show_wide"; - gconf_bridge_bind_property (bridge, key, object, "current-value"); + gconf_bridge_bind_property (bridge, key, object, "active"); + + object = G_OBJECT (ACTION (MAIL_THREADS_GROUP_BY)); + key = "/apps/evolution/mail/display/thread_list"; + gconf_bridge_bind_property (bridge, key, object, "active"); /* Fine tuning. */ diff --git a/mail/e-mail-shell-view-private.c b/mail/e-mail-shell-view-private.c index 9287ed777e..21521fd0f9 100644 --- a/mail/e-mail-shell-view-private.c +++ b/mail/e-mail-shell-view-private.c @@ -24,6 +24,32 @@ #include <widgets/menus/gal-view-factory-etable.h> static void +mail_shell_view_folder_tree_selected_cb (EMailShellView *mail_shell_view, + const gchar *full_name, + const gchar *uri, + guint32 flags, + EMFolderTree *folder_tree) +{ + EMailShellContent *mail_shell_content; + EMFolderView *folder_view; + + mail_shell_content = mail_shell_view->priv->mail_shell_content; + folder_view = e_mail_shell_content_get_folder_view (mail_shell_content); + + if ((flags & CAMEL_FOLDER_NOSELECT) || full_name == NULL) + em_folder_view_set_folder (folder_view, NULL, NULL); + else { + EMFolderTreeModel *model; + + model = em_folder_tree_get_model (folder_tree); + em_folder_tree_model_set_selected (model, uri); + em_folder_tree_model_save_state (model); + + em_folder_view_set_folder_uri (folder_view, uri); + } +} + +static void mail_shell_view_folder_tree_popup_event_cb (EShellView *shell_view, GdkEventButton *event) { @@ -121,6 +147,11 @@ e_mail_shell_view_private_constructed (EMailShellView *mail_shell_view) folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar); g_signal_connect_swapped ( + folder_tree, "folder-selected", + G_CALLBACK (mail_shell_view_folder_tree_selected_cb), + mail_shell_view); + + g_signal_connect_swapped ( folder_tree, "popup-event", G_CALLBACK (mail_shell_view_folder_tree_popup_event_cb), mail_shell_view); diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 87d5196dcc..77c74125d6 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -27,6 +27,7 @@ #include <sys/stat.h> #include <unistd.h> +#include <glib/gi18n.h> #include <glib/gstdio.h> #include <gdk/gdkkeysyms.h> #include <libgnome/gnome-util.h> @@ -57,13 +58,6 @@ #include <camel/camel-offline-store.h> #include <camel/camel-vee-store.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-component.h> -#include <bonobo/bonobo-ui-util.h> - #include <gtkhtml/gtkhtml.h> #include <gtkhtml/gtkhtml-embedded.h> #include <gtkhtml/gtkhtml-stream.h> @@ -74,10 +68,8 @@ #include "menus/gal-view-etable.h" #include "menus/gal-view-factory-etable.h" #include "menus/gal-view-instance.h" -#include "menus/gal-view-menus.h" #include "misc/e-charset-picker.h" -#include <misc/e-filter-bar.h> #include <misc/e-spinner.h> #include "e-util/e-error.h" @@ -87,6 +79,7 @@ #include "e-util/e-profile-event.h" #include "e-util/e-util-private.h" #include "e-util/e-util-labels.h" +#include "shell/e-shell.h" #include "filter/filter-rule.h" @@ -101,20 +94,17 @@ #include "message-list.h" #include "em-utils.h" #include "em-composer-utils.h" -#include "em-marshal.h" #include "em-menu.h" #include "em-event.h" +#include "e-mail-shell-module.h" #include "mail-mt.h" #include "mail-ops.h" #include "mail-config.h" #include "mail-autofilter.h" #include "mail-vfolder.h" -#include "mail-component.h" #include "mail-tools.h" -#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */ - #ifdef HAVE_XFREE #include <X11/XF86keysym.h> #endif @@ -231,9 +221,6 @@ struct _EMFolderViewPrivate { GtkWidget *invisible; char *selection_uri; - GalViewInstance *view_instance; - GalViewMenus *view_menus; - char *selected_uid; }; @@ -415,7 +402,7 @@ emfv_class_init(GObjectClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EMFolderViewClass, on_url), NULL, NULL, - em_marshal_VOID__STRING_STRING, + e_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); @@ -573,157 +560,6 @@ em_folder_view_open_selected(EMFolderView *emfv) return i; } -/* ******************************************************************************** */ -static void -emfv_list_display_view(GalViewInstance *instance, GalView *view, EMFolderView *emfv) -{ - if (GAL_IS_VIEW_ETABLE(view)) - gal_view_etable_attach_tree(GAL_VIEW_ETABLE(view), emfv->list->tree); -} - -static void -emfv_setup_view_instance(EMFolderView *emfv) -{ - static GalViewCollection *collection = NULL; - struct _EMFolderViewPrivate *p = emfv->priv; - gboolean outgoing, show_wide=FALSE; - char *id; - - g_return_if_fail (emfv->folder); - g_return_if_fail (emfv->folder_uri); - - if (collection == NULL) { - ETableSpecification *spec; - GalViewFactory *factory; - const char *evolution_dir; - char *dir; - char *galviewsmaildir; - char *etspecfile; - - collection = gal_view_collection_new (); - - gal_view_collection_set_title (collection, _("Mail")); - - evolution_dir = mail_component_peek_base_directory (mail_component_peek ()); - galviewsmaildir = g_build_filename (EVOLUTION_GALVIEWSDIR, - "mail", - NULL); - dir = g_build_filename (evolution_dir, "views", NULL); - gal_view_collection_set_storage_directories (collection, galviewsmaildir, dir); - g_free (dir); - g_free (galviewsmaildir); - - spec = e_table_specification_new (); - etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, - "message-list.etspec", - NULL); - if (!e_table_specification_load_from_file (spec, etspecfile)) - g_error ("Unable to load ETable specification file " - "for mail"); - g_free (etspecfile); - - factory = gal_view_factory_etable_new (spec); - g_object_unref (spec); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - - gal_view_collection_load (collection); - } - - if (p->view_instance) { - g_object_unref(p->view_instance); - p->view_instance = NULL; - } - - if (p->view_menus) { - g_object_unref(p->view_menus); - p->view_menus = NULL; - } - - /* TODO: should this go through mail-config api? */ - id = mail_config_folder_to_safe_url (emfv->folder); - p->view_instance = gal_view_instance_new (collection, id); - - show_wide = emfv->list_active ? em_folder_browser_get_wide ((EMFolderBrowser *) emfv):FALSE; - if (show_wide) { - char *safe_id, *filename; - - /* Force to use the wide view */ - g_free (p->view_instance->custom_filename); - g_free (p->view_instance->current_view_filename); - safe_id = g_strdup (id); - e_filename_make_safe (safe_id); - filename = g_strdup_printf ("custom_wide_view-%s.xml", safe_id); - p->view_instance->custom_filename = g_build_filename (collection->local_dir, filename, NULL); - g_free (filename); - filename = g_strdup_printf ("current_wide_view-%s.xml", safe_id); - p->view_instance->current_view_filename = g_build_filename (collection->local_dir, filename, NULL); - g_free (filename); - g_free (safe_id); - } - g_free (id); - - outgoing = em_utils_folder_is_drafts (emfv->folder, emfv->folder_uri) - || em_utils_folder_is_sent (emfv->folder, emfv->folder_uri) - || em_utils_folder_is_outbox (emfv->folder, emfv->folder_uri); - - if (outgoing) { - if (show_wide) - gal_view_instance_set_default_view(p->view_instance, "Wide_View_Sent"); - else - gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder"); - } else if (show_wide) { - gal_view_instance_set_default_view(p->view_instance, "Wide_View_Normal"); - } - - gal_view_instance_load(p->view_instance); - - if (!gal_view_instance_exists(p->view_instance)) { - struct stat st; - char *path; - - path = mail_config_folder_to_cachename (emfv->folder, "et-header-"); - if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { - ETableSpecification *spec; - ETableState *state; - GalView *view; - char *etspecfile; - - spec = e_table_specification_new (); - etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, - "message-list.etspec", - NULL); - e_table_specification_load_from_file (spec, etspecfile); - g_free (etspecfile); - view = gal_view_etable_new (spec, ""); - g_object_unref (spec); - - state = e_table_state_new (); - e_table_state_load_from_file (state, path); - gal_view_etable_set_state (GAL_VIEW_ETABLE (view), state); - g_object_unref (state); - - gal_view_instance_set_custom_view(p->view_instance, view); - g_object_unref (view); - } - - g_free (path); - } - - g_signal_connect(p->view_instance, "display_view", G_CALLBACK(emfv_list_display_view), emfv); - emfv_list_display_view(p->view_instance, gal_view_instance_get_current_view(p->view_instance), emfv); - - if (emfv->list_active && emfv->uic) { - p->view_menus = gal_view_menus_new(p->view_instance); - gal_view_menus_apply(p->view_menus, emfv->uic, NULL); - } -} - -void em_folder_view_setup_view_instance (EMFolderView *emfv) -{ - emfv_setup_view_instance (emfv); -} - /* ********************************************************************** */ static void @@ -757,7 +593,9 @@ emfv_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri) if (folder) { /* We need to set this up to get the right view options for the message-list, * even if we're not showing it */ +#if 0 /* KILL-BONOBO */ emfv_setup_view_instance(emfv); +#endif camel_object_ref(folder); } @@ -1567,7 +1405,8 @@ prepare_offline(void *key, void *value, void *data) static void emfv_prepare_offline(BonoboUIComponent *uid, void *data, const char *path) { - mail_component_stores_foreach(mail_component_peek(), prepare_offline, NULL); + e_mail_shell_module_stores_foreach ( + mail_shell_module, prepare_offline, NULL); } static void @@ -1820,6 +1659,7 @@ emfv_message_reply(EMFolderView *emfv, int mode) static void emfv_message_search(BonoboUIComponent *uic, void *data, const char *path) { +#if 0 /* KILL-BONOBO */ EMFolderView *emfv = data; if (!emfv->list_active) /* We are in new mail window */ @@ -1829,6 +1669,7 @@ emfv_message_search(BonoboUIComponent *uic, void *data, const char *path) gtk_widget_grab_focus (((ESearchBar *)((EMFolderBrowser *) emfv)->search)->entry); gtk_option_menu_set_history (GTK_OPTION_MENU (((ESearchBar *)((EMFolderBrowser *) emfv)->search)->scopeoption), 3); } +#endif } static void @@ -2108,52 +1949,6 @@ static BonoboUIVerb emfv_message_verbs[] = { BONOBO_UI_VERB_END }; -static EPixmap emfv_message_pixmaps[] = { - - E_PIXMAP ("/commands/EditCopy", "edit-copy", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/EditCut", "edit-cut", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/EditPaste", "edit-paste", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MailCompose", "mail-message-new", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageApplyFilters", "stock_mail-filters-apply", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageCopy", "mail-copy", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageDelete", "user-trash", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageFilterJunk", "mail-mark-junk", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageFollowUpFlag", "stock_mail-flag-for-followup", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageForward", "mail-forward", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMarkAsImportant", "mail-mark-important", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMarkAsJunk", "mail-mark-junk", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMarkAsNotJunk", "mail-mark-notjunk", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMarkAsRead", "mail-mark-read", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMarkAsUnRead", "mail-mark-unread", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageMove", "mail-move", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageReplyAll", "mail-reply-all", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageReplySender", "mail-reply-sender", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageSaveAs", "document-save-as", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MessageSearch", "edit-find", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/PrintMessage", "document-print", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/PrintPreviewMessage", "document-print-preview", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TextZoomIn", "zoom-in", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TextZoomOut", "zoom-out", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TextZoomReset", "zoom-original", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ViewLoadImages", "image-x-generic", E_ICON_SIZE_MENU), - - E_PIXMAP ("/menu/MessagePlaceholder/Message/MessageNavigation/GoTo", "go-jump", E_ICON_SIZE_MENU), - - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplySender", "mail-reply-sender", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplyAll", "mail-reply-all", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageForward", "mail-forward", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/PrintMessage", "document-print", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMove", "mail-move", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageCopy", "mail-copy", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageDelete", "edit-delete", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsJunk", "mail-mark-junk", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsNotJunk", "mail-mark-notjunk", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailNextButtons/MailNext", "go-next", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MailNextButtons/MailPrevious", "go-previous", E_ICON_SIZE_LARGE_TOOLBAR), - - E_PIXMAP_END -}; - static void emfv_enable_menus(EMFolderView *emfv) @@ -2262,7 +2057,6 @@ emfv_charset_changed(BonoboUIComponent *uic, const char *path, Bonobo_UIComponen static void emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) { - struct _EMFolderViewPrivate *p = emfv->priv; if (act) { em_format_mode_t style; @@ -2275,8 +2069,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) bonobo_ui_util_set_ui(uic, PREFIX, (char *)l->data, emfv->ui_app_name, NULL); bonobo_ui_component_add_verb_list_with_data(uic, emfv_message_verbs, emfv); - e_pixmaps_update(uic, emfv_message_pixmaps); - /* must do plugin menu's after main ones because of bonobo bustedness */ if (emfv->menu) e_menu_activate((EMenu *)emfv->menu, uic, act); @@ -2302,8 +2094,10 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) bonobo_ui_component_set_translate (uic, "/", "<status><item name=\"main\"/></status>", NULL); /* We need to set this up to get the right view options for the message-list, even if we're not showing it */ +#if 0 /* KILL-BONOBO */ if (emfv->folder) emfv_setup_view_instance(emfv); +#endif } else { const BonoboUIVerb *v; @@ -2314,16 +2108,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) for (v = &emfv_message_verbs[0]; v->cname; v++) bonobo_ui_component_remove_verb(uic, v->cname); - if (p->view_instance) { - g_object_unref(p->view_instance); - p->view_instance = NULL; - } - - if (p->view_menus) { - g_object_unref(p->view_menus); - p->view_menus = NULL; - } - if (emfv->folder) mail_sync_folder(emfv->folder, NULL, NULL); @@ -2464,6 +2248,7 @@ emfv_list_done_message_selected(CamelFolder *folder, const char *uid, CamelMimeM EMFolderView *emfv = data; EMEvent *eme; EMEventTargetMessage *target; + EShell *shell; if (emfv->preview == NULL) { emfv->priv->nomarkseen = FALSE; @@ -2475,7 +2260,8 @@ emfv_list_done_message_selected(CamelFolder *folder, const char *uid, CamelMimeM e_profile_event_emit("goto.loaded", emfv->displayed_uid, 0); - mail_indicate_new_mail (FALSE); + shell = e_shell_module_get_shell (mail_shell_module); + e_shell_event (shell, "mail-icon", "evolution-mail"); /** @Event: message.reading * @Title: Viewing a message @@ -3056,6 +2842,7 @@ static GHashTable *emfv_setting_key; static void emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFolderView *emfv) { +#if 0 /* KILL-BONOBO */ GConfValue *value; char *tkey; @@ -3223,6 +3010,7 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size); break; } } +#endif } static void diff --git a/mail/em-folder-view.h b/mail/em-folder-view.h index 42ef20d296..71fe1b97fe 100644 --- a/mail/em-folder-view.h +++ b/mail/em-folder-view.h @@ -25,6 +25,7 @@ #include <gtk/gtk.h> #include "mail/em-popup.h" +#include "message-list.h" /* Standard GObject macros */ #define EM_TYPE_FOLDER_VIEW \ @@ -47,7 +48,6 @@ G_BEGIN_DECLS -struct _MessageList; struct _EMFormatHTMLDisplay; struct _CamelFolder; struct _CamelMedium; @@ -80,7 +80,7 @@ struct _EMFolderView { struct _EMFolderViewPrivate *priv; - struct _MessageList *list; + MessageList *list; struct _EMFormatHTMLDisplay *preview; diff --git a/mail/em-mailer-prefs.c b/mail/em-mailer-prefs.c index ef9aa94aa5..e1f512ee57 100644 --- a/mail/em-mailer-prefs.c +++ b/mail/em-mailer-prefs.c @@ -41,6 +41,7 @@ #include "libedataserverui/e-cell-renderer-color.h" +#include "e-util/e-binding.h" #include "e-util/e-util-private.h" #include "e-util/e-util-labels.h" @@ -51,7 +52,8 @@ static void em_mailer_prefs_class_init (EMMailerPrefsClass *class); static void em_mailer_prefs_init (EMMailerPrefs *dialog); -static void em_mailer_prefs_finalise (GObject *obj); +static void em_mailer_prefs_dispose (GObject *object); +static void em_mailer_prefs_finalize (GObject *object); static GtkVBoxClass *parent_class = NULL; @@ -127,7 +129,8 @@ em_mailer_prefs_class_init (EMMailerPrefsClass *klass) object_class = (GObjectClass *) klass; parent_class = g_type_class_ref (gtk_vbox_get_type ()); - object_class->finalize = em_mailer_prefs_finalise; + object_class->dispose = em_mailer_prefs_dispose; + object_class->finalize = em_mailer_prefs_finalize; } static void @@ -137,7 +140,21 @@ em_mailer_prefs_init (EMMailerPrefs *preferences) } static void -em_mailer_prefs_finalise (GObject *obj) +em_mailer_prefs_dispose (GObject *object) +{ + EMMailerPrefs *prefs = (EMMailerPrefs *) object; + + if (prefs->shell != NULL) { + g_object_unref (prefs->shell); + prefs->shell = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +em_mailer_prefs_finalize (GObject *obj) { EMMailerPrefs *prefs = (EMMailerPrefs *) obj; @@ -152,29 +169,64 @@ em_mailer_prefs_finalise (GObject *obj) ((GObjectClass *)(parent_class))->finalize (obj); } +static gboolean +mark_seen_timeout_transform (const GValue *src_value, + GValue *dst_value, + gpointer user_data) +{ + gdouble v_double; -static void -color_button_set_color (GtkColorButton *color_button, const gchar *spec) + /* Shell Settings (int) -> Spin Button (double) */ + v_double = (gdouble) g_value_get_int (src_value); + g_value_set_double (dst_value, v_double / 1000.0); + + return TRUE; +} + +static gboolean +mark_seen_timeout_reverse_transform (const GValue *src_value, + GValue *dst_value, + gpointer user_data) { - GdkColor color; + gdouble v_double; - if (gdk_color_parse (spec, &color)) - gtk_color_button_set_color (color_button, &color); + /* Spin Button (double) -> Shell Settings (int) */ + v_double = g_value_get_double (src_value); + g_value_set_int (dst_value, v_double * 1000); + + return TRUE; } -static void -citation_color_set (GtkColorButton *color_button, EMMailerPrefs *prefs) +static gboolean +transform_color_to_string (const GValue *src_value, + GValue *dst_value, + gpointer user_data) +{ + const GdkColor *color; + gchar *string; + + color = g_value_get_boxed (src_value); + string = gdk_color_to_string (color); + g_value_set_string (dst_value, string); + g_free (string); + + return TRUE; +} + +static gboolean +transform_string_to_color (const GValue *src_value, + GValue *dst_value, + gpointer user_data) { GdkColor color; - gchar spec[16]; + const gchar *string; + gboolean success; - gtk_color_button_get_color (color_button, &color); - g_snprintf (spec, sizeof (spec), "#%04x%04x%04x", - color.red, color.green, color.blue); + string = g_value_get_string (src_value); + if (gdk_color_parse (string, &color)) + g_value_set_boxed (dst_value, &color); - gconf_client_set_string (prefs->gconf, - "/apps/evolution/mail/display/citation_colour", - spec, NULL); + return success; } enum { @@ -718,80 +770,6 @@ emmp_header_entry_changed (GtkWidget *entry, gpointer user_data) } static void -mark_seen_timeout_changed (GtkSpinButton *spin, EMMailerPrefs *prefs) -{ - int timeout; - - timeout = (int) (gtk_spin_button_get_value (prefs->timeout) * 1000.0); - gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/mark_seen_timeout", timeout, NULL); -} - -static void -address_compress_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs) -{ - int count; - - count = (int) gtk_spin_button_get_value (prefs->address_count); - - gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/address_count", count, NULL); -} - -static void -mlimit_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs) -{ - int count; - - count = (int) gtk_spin_button_get_value (prefs->mlimit_count); - - gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/message_text_part_limit", count, NULL); -} - -static void -spin_button_init (EMMailerPrefs *prefs, GtkSpinButton *spin, const char *key, float div, GCallback value_changed) -{ - GError *err = NULL; - double min, max; - char *mkey, *p; - int val; - - gtk_spin_button_get_range (spin, &min, &max); - - mkey = g_alloca (strlen (key) + 5); - p = g_stpcpy (mkey, key); - *p++ = '_'; - - /* see if the admin locked down the min value */ - strcpy (p, "min"); - val = gconf_client_get_int (prefs->gconf, mkey, &err); - if (err == NULL) - g_clear_error (&err); - else - min = (1.0 * val) / div; - - /* see if the admin locked down the max value */ - strcpy (p, "max"); - val = gconf_client_get_int (prefs->gconf, mkey, &err); - if (err == NULL) - g_clear_error (&err); - else - max = (1.0 * val) / div; - - gtk_spin_button_set_range (spin, min, max); - - /* get the value */ - val = gconf_client_get_int (prefs->gconf, key, NULL); - gtk_spin_button_set_value (spin, (1.0 * val) / div); - - if (value_changed) { - g_object_set_data ((GObject *) spin, "key", (void *) key); - g_signal_connect (spin, "value-changed", value_changed, prefs); - } - - if (!gconf_client_key_is_writable (prefs->gconf, key, NULL)) - gtk_widget_set_sensitive ((GtkWidget *) spin, FALSE); -} - -static void toggle_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs) { const char *key; @@ -801,16 +779,6 @@ toggle_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs) } static void -photo_toggle_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs) -{ - toggle_button_toggled (toggle, prefs); - if (gtk_toggle_button_get_active (toggle)) - gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, TRUE); - else - gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE); -} - -static void junk_book_lookup_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs) { toggle_button_toggled (toggle, prefs); @@ -834,42 +802,6 @@ custom_junk_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs) } -#if 0 -// not used at the moment, commenting out -static void -toggle_button_toggled_not (GtkToggleButton *toggle, EMMailerPrefs *prefs) -{ - const char *key; - - key = g_object_get_data ((GObject *) toggle, "key"); - gconf_client_set_bool (prefs->gconf, key, !gtk_toggle_button_get_active (toggle), NULL); -} -#endif - -static void -custom_font_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs) -{ - gboolean use_custom; - - use_custom = !gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_fixed), use_custom); - gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_variable), use_custom); - - gconf_client_set_bool (prefs->gconf, "/apps/evolution/mail/display/fonts/use_custom", use_custom, NULL); -} - -static void -font_changed (GtkFontButton *font_button, EMMailerPrefs *prefs) -{ - const gchar *key; - const gchar *font_name; - - key = g_object_get_data (G_OBJECT (font_button), "key"); - font_name = gtk_font_button_get_font_name (font_button); - gconf_client_set_string (prefs->gconf, key, font_name, NULL); -} - static void toggle_button_init (EMMailerPrefs *prefs, GtkToggleButton *toggle, int not, const char *key, GCallback toggled) { @@ -939,10 +871,6 @@ emmp_empty_trash_init (EMMailerPrefs *prefs) int locked, days, hist = 0, i; GtkWidget *menu, *item; - toggle_button_init (prefs, prefs->empty_trash, FALSE, - "/apps/evolution/mail/trash/empty_on_exit", - G_CALLBACK (toggle_button_toggled)); - days = gconf_client_get_int(prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL); menu = gtk_menu_new(); for (i = 0; i < G_N_ELEMENTS (empty_trash_frequency); i++) { @@ -1160,15 +1088,17 @@ create_combo_text_widget (void) { } static void -em_mailer_prefs_construct (EMMailerPrefs *prefs) +em_mailer_prefs_construct (EMMailerPrefs *prefs, + EShell *shell) { GSList *header_config_list, *header_add_list, *p; + EShellSettings *shell_settings; GHashTable *default_header_hash; GtkWidget *toplevel; + GtkWidget *widget; GtkTreeSelection *selection; GtkCellRenderer *renderer; GtkTreeIter iter; - char *font, *buf; GladeXML *gui; gboolean locked; int val, i; @@ -1177,6 +1107,9 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) GSList *l; char *gladefile; + prefs->shell = g_object_ref (shell); + shell_settings = e_shell_get_settings (shell); + gladefile = g_build_filename (EVOLUTION_GLADEDIR, "mail-config.glade", NULL); @@ -1202,96 +1135,119 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) /* General tab */ /* Message Display */ - prefs->timeout_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkMarkTimeout")); - toggle_button_init (prefs, prefs->timeout_toggle, FALSE, - "/apps/evolution/mail/display/mark_seen", - G_CALLBACK (toggle_button_toggled)); - - prefs->timeout = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spinMarkTimeout")); - spin_button_init (prefs, prefs->timeout, - "/apps/evolution/mail/display/mark_seen_timeout", - 1000.0, G_CALLBACK (mark_seen_timeout_changed)); - - prefs->mlimit_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "mlimit_checkbutton")); - toggle_button_init (prefs, prefs->mlimit_toggle, FALSE, - "/apps/evolution/mail/display/force_message_limit", - G_CALLBACK (toggle_button_toggled)); - - prefs->magic_spacebar = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "magic_spacebar_checkbox")); - toggle_button_init (prefs, prefs->magic_spacebar, FALSE, - "/apps/evolution/mail/display/magic_spacebar", - G_CALLBACK (toggle_button_toggled)); - - prefs->mlimit_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "mlimit_spin")); - spin_button_init (prefs, prefs->mlimit_count, - "/apps/evolution/mail/display/message_text_part_limit", - 1, G_CALLBACK (mlimit_count_changed)); - - prefs->address_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "address_checkbox")); - toggle_button_init (prefs, prefs->address_toggle, FALSE, - "/apps/evolution/mail/display/address_compress", - G_CALLBACK (toggle_button_toggled)); - - prefs->address_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "address_spin")); - spin_button_init (prefs, prefs->address_count, - "/apps/evolution/mail/display/address_count", - 1, G_CALLBACK (address_compress_count_changed)); + widget = glade_xml_get_widget (gui, "chkMarkTimeout"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-mark-seen", + G_OBJECT (widget), "active"); + + /* The "mark seen" timeout requires special transform functions + * because we display the timeout value to the user in seconds + * but store the settings value in milliseconds. */ + widget = glade_xml_get_widget (gui, "spinMarkTimeout"); + prefs->timeout = GTK_SPIN_BUTTON (widget); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-mark-seen", + G_OBJECT (widget), "sensitive"); + e_mutual_binding_new_full ( + G_OBJECT (shell_settings), "mail-mark-seen-timeout", + G_OBJECT (widget), "value", + mark_seen_timeout_transform, + mark_seen_timeout_reverse_transform, + NULL, NULL); + + widget = glade_xml_get_widget (gui, "mlimit_checkbutton"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-force-message-limit", + G_OBJECT (widget), "active"); + + widget = glade_xml_get_widget (gui, "mlimit_spin"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-force-message-limit", + G_OBJECT (widget), "sensitive"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-message-text-part-limit", + G_OBJECT (widget), "value"); + + widget = glade_xml_get_widget (gui, "address_checkbox"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-address-compress", + G_OBJECT (widget), "active"); + + widget = glade_xml_get_widget (gui, "address_spin"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-address-compress", + G_OBJECT (widget), "sensitive"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-address-count", + G_OBJECT (widget), "value"); + + widget = glade_xml_get_widget (gui, "magic_spacebar_checkbox"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-magic-spacebar", + G_OBJECT (widget), "active"); prefs->charset = GTK_OPTION_MENU (glade_xml_get_widget (gui, "omenuCharset")); charset_menu_init (prefs); - prefs->citation_highlight = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkHighlightCitations")); - toggle_button_init (prefs, prefs->citation_highlight, FALSE, - "/apps/evolution/mail/display/mark_citations", - G_CALLBACK (toggle_button_toggled)); - - prefs->citation_color = GTK_COLOR_BUTTON (glade_xml_get_widget (gui, "colorButtonHighlightCitations")); - buf = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL); - color_button_set_color (prefs->citation_color, buf ? buf : "#737373"); - g_signal_connect (prefs->citation_color, "color-set", G_CALLBACK (citation_color_set), prefs); - if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL)) - gtk_widget_set_sensitive ((GtkWidget *) prefs->citation_color, FALSE); - g_free (buf); - - prefs->enable_search_folders = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEnableSearchFolders")); - toggle_button_init (prefs, prefs->enable_search_folders, FALSE, - "/apps/evolution/mail/display/enable_vfolders", - G_CALLBACK (toggle_button_toggled)); + widget = glade_xml_get_widget (gui, "chkHighlightCitations"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-mark-citations", + G_OBJECT (widget), "active"); + + widget = glade_xml_get_widget (gui, "colorButtonHighlightCitations"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-mark-citations", + G_OBJECT (widget), "sensitive"); + e_mutual_binding_new_full ( + G_OBJECT (shell_settings), "mail-citation-color", + G_OBJECT (widget), "color", + transform_string_to_color, + transform_color_to_string, + NULL, NULL); + + widget = glade_xml_get_widget (gui, "chkEnableSearchFolders"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-enable-search-folders", + G_OBJECT (widget), "active"); /* Deleting Mail */ - prefs->empty_trash = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEmptyTrashOnExit")); + widget = glade_xml_get_widget (gui, "chkEmptyTrashOnExit"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-empty-trash-on-exit", + G_OBJECT (widget), "active"); + prefs->empty_trash_days = GTK_OPTION_MENU (glade_xml_get_widget (gui, "omenuEmptyTrashDays")); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-empty-trash-on-exit", + G_OBJECT (prefs->empty_trash_days), "sensitive"); emmp_empty_trash_init (prefs); - prefs->confirm_expunge = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkConfirmExpunge")); - toggle_button_init (prefs, prefs->confirm_expunge, FALSE, - "/apps/evolution/mail/prompts/expunge", - G_CALLBACK (toggle_button_toggled)); - - /* Mail Fonts */ - font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL); - prefs->font_fixed = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontFixed")); - gtk_font_button_set_font_name (prefs->font_fixed, font); - g_free (font); - g_object_set_data ((GObject *) prefs->font_fixed, "key", "/apps/evolution/mail/display/fonts/monospace"); - g_signal_connect (prefs->font_fixed, "font-set", G_CALLBACK (font_changed), prefs); - if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL)) - gtk_widget_set_sensitive ((GtkWidget *) prefs->font_fixed, FALSE); - - font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL); - prefs->font_variable = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontVariable")); - gtk_font_button_set_font_name (prefs->font_variable, font); - g_free (font); - g_object_set_data ((GObject *) prefs->font_variable, "key", "/apps/evolution/mail/display/fonts/variable"); - g_signal_connect (prefs->font_variable, "font-set", G_CALLBACK (font_changed), prefs); - if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL)) - gtk_widget_set_sensitive ((GtkWidget *) prefs->font_variable, FALSE); - - prefs->font_share = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radFontUseSame")); - toggle_button_init (prefs, prefs->font_share, TRUE, - "/apps/evolution/mail/display/fonts/use_custom", - G_CALLBACK (custom_font_changed)); - custom_font_changed (prefs->font_share, prefs); + widget = glade_xml_get_widget (gui, "chkConfirmExpunge"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-confirm-expunge", + G_OBJECT (widget), "active"); + + /* Mail Fonts */ + widget = glade_xml_get_widget (gui, "radFontUseSame"); + e_mutual_binding_new_with_negation ( + G_OBJECT (shell_settings), "mail-use-custom-fonts", + G_OBJECT (widget), "active"); + + widget = glade_xml_get_widget (gui, "FontFixed"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-font-monospace", + G_OBJECT (widget), "font-name"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-use-custom-fonts", + G_OBJECT (widget), "sensitive"); + + widget = glade_xml_get_widget (gui, "FontVariable"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-font-variable", + G_OBJECT (widget), "font-name"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-use-custom-fonts", + G_OBJECT (widget), "sensitive"); /* HTML Mail tab */ @@ -1318,15 +1274,15 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) g_signal_connect (prefs->images_sometimes, "toggled", G_CALLBACK (http_images_changed), prefs); g_signal_connect (prefs->images_always, "toggled", G_CALLBACK (http_images_changed), prefs); - prefs->show_animated = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkShowAnimatedImages")); - toggle_button_init (prefs, prefs->show_animated, FALSE, - "/apps/evolution/mail/display/animate_images", - G_CALLBACK (toggle_button_toggled)); + widget = glade_xml_get_widget (gui, "chkShowAnimatedImages"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-show-animated-images", + G_OBJECT (widget), "active"); - prefs->prompt_unwanted_html = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkPromptWantHTML")); - toggle_button_init (prefs, prefs->prompt_unwanted_html, FALSE, - "/apps/evolution/mail/prompts/unwanted_html", - G_CALLBACK (toggle_button_toggled)); + widget = glade_xml_get_widget (gui, "chkPromptWantHTML"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-confirm-unwanted-html", + G_OBJECT (widget), "active"); /* Labels... */ locked = !gconf_client_key_is_writable (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, NULL); @@ -1351,16 +1307,18 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) /* headers */ locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/headers", NULL); - prefs->photo_show= GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_show")); - toggle_button_init (prefs, prefs->photo_show, FALSE, - "/apps/evolution/mail/display/sender_photo", - G_CALLBACK (photo_toggle_changed)); - prefs->photo_local = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_local")); - toggle_button_init (prefs, prefs->photo_local, FALSE, - "/apps/evolution/mail/display/photo_local", - G_CALLBACK (toggle_button_toggled)); - if (!gtk_toggle_button_get_active (prefs->photo_show)) - gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE); + widget = glade_xml_get_widget (gui, "photo_show"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-show-sender-photo", + G_OBJECT (widget), "active"); + + widget = glade_xml_get_widget (gui, "photo_local"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-show-sender-photo", + G_OBJECT (widget), "sensitive"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-only-local-photos", + G_OBJECT (widget), "active"); /* always de-sensitised until the user types something in the entry */ prefs->add_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersAdd")); @@ -1467,10 +1425,10 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) g_slist_free (header_add_list); /* Junk prefs */ - prefs->check_incoming = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkCheckIncomingMail")); - toggle_button_init (prefs, prefs->check_incoming, FALSE, - "/apps/evolution/mail/junk/check_incoming", - G_CALLBACK (toggle_button_toggled)); + widget = glade_xml_get_widget (gui, "chkCheckIncomingMail"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "mail-check-for-junk", + G_OBJECT (widget), "active"); prefs->empty_junk = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "junk_empty_check")); prefs->empty_junk_days = GTK_OPTION_MENU (glade_xml_get_widget (gui, "junk_empty_combo")); @@ -1515,12 +1473,14 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs) } GtkWidget * -em_mailer_prefs_new (void) +em_mailer_prefs_new (EShell *shell) { EMMailerPrefs *new; + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + new = (EMMailerPrefs *) g_object_new (em_mailer_prefs_get_type (), NULL); - em_mailer_prefs_construct (new); + em_mailer_prefs_construct (new, shell); return (GtkWidget *) new; } diff --git a/mail/em-mailer-prefs.h b/mail/em-mailer-prefs.h index 4073725dda..89f361133a 100644 --- a/mail/em-mailer-prefs.h +++ b/mail/em-mailer-prefs.h @@ -26,6 +26,7 @@ #include <gtk/gtk.h> #include <glade/glade.h> #include <gconf/gconf-client.h> +#include <shell/e-shell.h> /* Standard GObject macros */ #define EM_TYPE_MAILER_PREFS \ @@ -61,42 +62,25 @@ struct _EMMailerPrefsHeader { struct _EMMailerPrefs { GtkVBox parent_object; + EShell *shell; GladeXML *gui; GConfClient *gconf; /* General tab */ /* Message Display */ - GtkToggleButton *timeout_toggle; GtkSpinButton *timeout; - GtkToggleButton *address_toggle; - GtkSpinButton *address_count; - GtkToggleButton *mlimit_toggle; - GtkSpinButton *mlimit_count; GtkOptionMenu *charset; - GtkToggleButton *citation_highlight; - GtkColorButton *citation_color; - GtkToggleButton *enable_search_folders; - GtkToggleButton *magic_spacebar; /* Deleting Mail */ - GtkToggleButton *empty_trash; GtkOptionMenu *empty_trash_days; - GtkToggleButton *confirm_expunge; - - /* HTML Mail tab */ - GtkFontButton *font_variable; - GtkFontButton *font_fixed; - GtkToggleButton *font_share; /* Loading Images */ GtkToggleButton *images_always; GtkToggleButton *images_sometimes; GtkToggleButton *images_never; - GtkToggleButton *show_animated; GtkToggleButton *autodetect_links; - GtkToggleButton *prompt_unwanted_html; /* Labels and Colours tab */ GtkWidget *label_add; @@ -112,11 +96,8 @@ struct _EMMailerPrefs { GtkEntry *entry_header; GtkTreeView *header_list; GtkListStore *header_list_store; - GtkToggleButton *photo_show; - GtkToggleButton *photo_local; /* Junk prefs */ - GtkToggleButton *check_incoming; GtkToggleButton *empty_junk; GtkOptionMenu *empty_junk_days; @@ -142,7 +123,7 @@ struct _EMMailerPrefsClass { GType em_mailer_prefs_get_type (void); GtkWidget * create_combo_text_widget (void); -GtkWidget * em_mailer_prefs_new (void); +GtkWidget * em_mailer_prefs_new (EShell *shell); EMMailerPrefsHeader * em_mailer_prefs_header_from_xml (const gchar *xml); diff --git a/mail/em-message-browser.c b/mail/em-message-browser.c index 728b27ec43..8b3ff99152 100644 --- a/mail/em-message-browser.c +++ b/mail/em-message-browser.c @@ -52,8 +52,6 @@ #include "em-message-browser.h" #include "em-menu.h" -#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */ - #define EM_MESSAGE_BROWSER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserPrivate)) diff --git a/mail/mail-component.c b/mail/mail-component.c index e210a2613a..56a6a6ebd2 100644 --- a/mail/mail-component.c +++ b/mail/mail-component.c @@ -1571,26 +1571,6 @@ mail_component_stores_foreach (MailComponent *component, GHFunc func, void *user // return mc_default_folders[id].uri; //} -/** - * mail_indicate_new_mail - * Indicates new mail in a shell window. - * @param have_new_mail TRUE when have new mail, false otherwise. - **/ -//void -//mail_indicate_new_mail (gboolean have_new_mail) -//{ -// const char *icon = NULL; -// MailComponent *mc = mail_component_peek (); -// -// g_return_if_fail (mc != NULL); -// -// if (have_new_mail) -// icon = "mail-unread"; -// -// if (mc->priv->component_view) -// e_component_view_set_button_icon (mc->priv->component_view, icon); -//} - void mail_component_show_logger (gpointer top) { diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c index 49479faa7a..f46b22850c 100644 --- a/mail/mail-folder-cache.c +++ b/mail/mail-folder-cache.c @@ -198,7 +198,8 @@ real_flush_updates (EShellModule *shell_module) t->name = em_folder_tree_model_get_folder_name (model, up->store, up->full_name); if (t->new > 0) - e_shell_event (shell, "new-mail", NULL); + e_shell_event ( + shell, "mail-icon", "mail-unread"); /** @Event: folder.changed * @Title: Folder changed diff --git a/mail/message-list.h b/mail/message-list.h index 47be897fd2..34e971482f 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -28,6 +28,8 @@ #include <table/e-table-simple.h> #include <table/e-tree-scrolled.h> +#include <camel/camel-folder.h> + #ifdef __cplusplus extern "C" { #pragma } diff --git a/shell/Makefile.am b/shell/Makefile.am index 7b54607d10..79ed87c880 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -62,6 +62,7 @@ eshellinclude_HEADERS = \ e-shell-common.h \ e-shell-content.h \ e-shell-module.h \ + e-shell-settings.h \ e-shell-sidebar.h \ e-shell-switcher.h \ e-shell-taskbar.h \ @@ -74,6 +75,7 @@ libeshell_la_SOURCES = \ $(IDL_GENERATED) \ e-shell-content.c \ e-shell-module.c \ + e-shell-settings.c \ e-shell-sidebar.c \ e-shell-switcher.c \ e-shell-taskbar.c \ diff --git a/shell/e-shell-settings.c b/shell/e-shell-settings.c new file mode 100644 index 0000000000..d0c678baa9 --- /dev/null +++ b/shell/e-shell-settings.c @@ -0,0 +1,201 @@ +/* + * e-shell-settings.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-shell-settings.h" + +#include "e-util/gconf-bridge.h" + +#define E_SHELL_SETTINGS_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsPrivate)) + +struct _EShellSettingsPrivate { + GArray *value_array; +}; + +static GList *instances; +static guint property_count; +static gpointer parent_class; + +static void +shell_settings_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EShellSettingsPrivate *priv; + GValue *dest_value; + + priv = E_SHELL_SETTINGS_GET_PRIVATE (object); + + dest_value = &g_array_index ( + priv->value_array, GValue, property_id - 1); + + g_value_copy (value, dest_value); + g_object_notify (object, pspec->name); +} + +static void +shell_settings_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EShellSettingsPrivate *priv; + GValue *src_value; + + priv = E_SHELL_SETTINGS_GET_PRIVATE (object); + + src_value = &g_array_index ( + priv->value_array, GValue, property_id - 1); + + g_value_copy (src_value, value); +} + +static void +shell_settings_finalize (GObject *object) +{ + EShellSettingsPrivate *priv; + guint ii; + + priv = E_SHELL_SETTINGS_GET_PRIVATE (object); + + for (ii = 0; ii < priv->value_array->len; ii++) + g_value_unset (&g_array_index (priv->value_array, GValue, ii)); + + g_array_free (priv->value_array, TRUE); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +shell_settings_class_init (EShellSettingsClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EShellSettingsPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = shell_settings_set_property; + object_class->get_property = shell_settings_get_property; + object_class->finalize = shell_settings_finalize; +} + +static void +shell_settings_init (EShellSettings *shell_settings, + GObjectClass *object_class) +{ + GArray *value_array; + + instances = g_list_prepend (instances, shell_settings); + + value_array = g_array_new (FALSE, TRUE, sizeof (GValue)); + g_array_set_size (value_array, property_count); + + shell_settings->priv = E_SHELL_SETTINGS_GET_PRIVATE (shell_settings); + shell_settings->priv->value_array = value_array; +} + +GType +e_shell_settings_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EShellSettingsClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) shell_settings_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EShellSettings), + 0, /* n_preallocs */ + (GInstanceInitFunc) shell_settings_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EShellSettings", &type_info, 0); + } + + return type; +} + +void +e_shell_settings_install_property (GParamSpec *pspec) +{ + static GObjectClass *class = NULL; + GList *iter, *next; + + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + if (G_UNLIKELY (class == NULL)) + class = g_type_class_ref (E_TYPE_SHELL_SETTINGS); + + if (g_object_class_find_property (class, pspec->name) != NULL) { + g_warning ( + "Settings property \"%s\" already exists", + pspec->name); + return; + } + + for (iter = instances; iter != NULL; iter = iter->next) + g_object_freeze_notify (iter->data); + + g_object_class_install_property (class, ++property_count, pspec); + + for (iter = instances; iter != NULL; iter = iter->next) { + EShellSettings *shell_settings = iter->data; + GArray *value_array; + GValue *value; + + value_array = shell_settings->priv->value_array; + g_array_set_size (value_array, property_count); + + value = &g_array_index ( + value_array, GValue, property_count - 1); + g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_param_value_set_default (pspec, value); + g_object_notify (G_OBJECT (shell_settings), pspec->name); + } + + for (iter = instances; iter != NULL; iter = next) { + next = iter->next; + g_object_thaw_notify (iter->data); + } +} + +void +e_shell_settings_bind_to_gconf (EShellSettings *shell_settings, + const gchar *property_name, + const gchar *gconf_key) +{ + g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings)); + g_return_if_fail (property_name != NULL); + g_return_if_fail (gconf_key != NULL); + + gconf_bridge_bind_property ( + gconf_bridge_get (), gconf_key, + G_OBJECT (shell_settings), property_name); +} diff --git a/shell/e-shell-settings.h b/shell/e-shell-settings.h new file mode 100644 index 0000000000..b01d7fe327 --- /dev/null +++ b/shell/e-shell-settings.h @@ -0,0 +1,82 @@ +/* + * e-shell-settings.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/** + * SECTION: e-shell-settings + * @short_description: settings management + * @include: shell/e-shell-settings.h + **/ + +#ifndef E_SHELL_SETTINGS_H +#define E_SHELL_SETTINGS_H + +#include <shell/e-shell-common.h> + +/* Standard GObject macros */ +#define E_TYPE_SHELL_SETTINGS \ + (e_shell_settings_get_type ()) +#define E_SHELL_SETTINGS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SHELL_SETTINGS, EShellSettings)) +#define E_SHELL_SETTINGS_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SHELL_SETTINGS, EShellSettingsClass)) +#define E_IS_SHELL_SETTINGS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SHELL_SETTINGS)) +#define E_IS_SHELL_SETTINGS_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SHELL_SETTINGS)) +#define E_SHELL_SETTINGS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsClass)) + +G_BEGIN_DECLS + +typedef struct _EShellSettings EShellSettings; +typedef struct _EShellSettingsClass EShellSettingsClass; +typedef struct _EShellSettingsPrivate EShellSettingsPrivate; + +/** + * EShellSettings: + * + * Contains only private data that should be read and manipulated using the + * functions below. + **/ +struct _EShellSettings { + GObject parent; + EShellSettingsPrivate *priv; +}; + +struct _EShellSettingsClass { + GObjectClass parent_class; +}; + +GType e_shell_settings_get_type (void); +void e_shell_settings_install_property + (GParamSpec *pspec); +void e_shell_settings_bind_to_gconf (EShellSettings *shell_settings, + const gchar *property_name, + const gchar *gconf_key); + +G_END_DECLS + +#endif /* E_SHELL_SETTINGS_H */ diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 3ab67b6ab0..9c5ff2b8bb 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -111,6 +111,17 @@ shell_view_init_view_collection (EShellViewClass *shell_view_class) } static void +shell_view_update_view_id (EShellView *shell_view, + GalViewInstance *view_instance) +{ + gchar *view_id; + + view_id = gal_view_instance_get_current_view_id (view_instance); + e_shell_view_set_view_id (shell_view, view_id); + g_free (view_id); +} + +static void shell_view_emit_toggled (EShellView *shell_view) { g_signal_emit (shell_view, signals[TOGGLED], 0); @@ -967,3 +978,35 @@ e_shell_view_show_popup_menu (EShellView *shell_view, GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); } + +/** + * e_shell_view_new_view_instance: + * @shell_view: an #EShellView + * @instance_id: a name for the #GalViewInstance + * + * Creates a new #GalViewInstance and configures it to keep + * @shell_view<!-- -->'s #EShellView:view-id property up-to-date. + * + * Returns: a new #GalViewInstance + **/ +GalViewInstance * +e_shell_view_new_view_instance (EShellView *shell_view, + const gchar *instance_id) +{ + EShellViewClass *shell_view_class; + GalViewCollection *view_collection; + GalViewInstance *view_instance; + + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + + view_collection = shell_view_class->view_collection; + view_instance = gal_view_instance_new (view_collection, instance_id); + + g_signal_connect_swapped ( + view_instance, "changed", + G_CALLBACK (shell_view_update_view_id), shell_view); + + return view_instance; +} diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 1b1fffd87d..3159b5a71b 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -36,6 +36,7 @@ #include <shell/e-shell-window.h> #include <widgets/menus/gal-view-collection.h> +#include <widgets/menus/gal-view-instance.h> /* Standard GObject macros */ #define E_TYPE_SHELL_VIEW \ @@ -174,6 +175,9 @@ void e_shell_view_update_actions (EShellView *shell_view); void e_shell_view_show_popup_menu (EShellView *shell_view, const gchar *widget_path, GdkEventButton *event); +GalViewInstance * + e_shell_view_new_view_instance (EShellView *shell_view, + const gchar *instance_id); G_END_DECLS diff --git a/shell/e-shell.c b/shell/e-shell.c index d6884b0a69..1840571767 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -37,6 +37,7 @@ struct _EShellPrivate { GList *active_windows; + EShellSettings *settings; EShellLineStatus line_status; /* Shell Modules */ @@ -50,7 +51,8 @@ struct _EShellPrivate { enum { PROP_0, - PROP_ONLINE_MODE + PROP_ONLINE_MODE, + PROP_SETTINGS }; enum { @@ -261,6 +263,12 @@ shell_get_property (GObject *object, value, e_shell_get_online_mode ( E_SHELL (object))); return; + + case PROP_SETTINGS: + g_value_set_object ( + value, e_shell_get_settings ( + E_SHELL (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -273,6 +281,11 @@ shell_dispose (GObject *object) priv = E_SHELL_GET_PRIVATE (object); + if (priv->settings != NULL) { + g_object_unref (priv->settings); + priv->settings = NULL; + } + g_list_foreach ( priv->loaded_modules, (GFunc) g_type_module_unuse, NULL); @@ -358,6 +371,16 @@ shell_class_init (EShellClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property ( + object_class, + PROP_SETTINGS, + g_param_spec_object ( + "settings", + _("Settings"), + _("Application settings"), + E_TYPE_SHELL_SETTINGS, + G_PARAM_READABLE)); + signals[EVENT] = g_signal_new ( "event", G_OBJECT_CLASS_TYPE (object_class), @@ -415,6 +438,7 @@ shell_init (EShell *shell) modules_by_name = g_hash_table_new (g_str_hash, g_str_equal); modules_by_scheme = g_hash_table_new (g_str_hash, g_str_equal); + shell->priv->settings = g_object_new (E_TYPE_SHELL_SETTINGS, NULL); shell->priv->modules_by_name = modules_by_name; shell->priv->modules_by_scheme = modules_by_scheme; shell->priv->safe_mode = e_file_lock_exists (); @@ -517,6 +541,14 @@ e_shell_get_module_by_scheme (EShell *shell, return g_hash_table_lookup (hash_table, scheme); } +EShellSettings * +e_shell_get_settings (EShell *shell) +{ + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + return shell->priv->settings; +} + GtkWidget * e_shell_create_window (EShell *shell) { diff --git a/shell/e-shell.h b/shell/e-shell.h index 2c942097c5..79ff9c1783 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -30,6 +30,7 @@ #include <shell/e-shell-common.h> #include <shell/e-shell-module.h> +#include <shell/e-shell-settings.h> /* Standard GObject macros */ #define E_TYPE_SHELL \ @@ -89,6 +90,7 @@ EShellModule * e_shell_get_module_by_name (EShell *shell, const gchar *name); EShellModule * e_shell_get_module_by_scheme (EShell *shell, const gchar *scheme); +EShellSettings *e_shell_get_settings (EShell *shell); GtkWidget * e_shell_create_window (EShell *shell); GtkWidget * e_shell_get_focused_window (EShell *shell); gboolean e_shell_handle_uri (EShell *shell, |