From 03a3e6f84638c62c7848eee4d6f71cc4b1a7c1b8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 16 Jul 2008 19:37:02 +0000 Subject: Disable all components and plugins. Begin rewriting the shell. svn path=/branches/kill-bonobo/; revision=35748 --- widgets/misc/Makefile.am | 2 + widgets/misc/e-online-button.c | 194 +++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-online-button.h | 68 +++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 widgets/misc/e-online-button.c create mode 100644 widgets/misc/e-online-button.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index bb3d131ffb..95acd8b929 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -57,6 +57,7 @@ widgetsinclude_HEADERS = \ e-info-label.h \ e-map.h \ e-multi-config-dialog.h \ + e-online-button.h \ e-search-bar.h \ e-task-bar.h \ e-task-widget.h \ @@ -104,6 +105,7 @@ libemiscwidgets_la_SOURCES = \ e-info-label.c \ e-map.c \ e-multi-config-dialog.c \ + e-online-button.c \ e-search-bar.c \ e-task-bar.c \ e-task-widget.c \ diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c new file mode 100644 index 0000000000..7391384950 --- /dev/null +++ b/widgets/misc/e-online-button.c @@ -0,0 +1,194 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-offline-button.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-online-button.h" + +#include + +#define ONLINE_IMAGE "online.png" +#define OFFLINE_IMAGE "offline.png" + +#define E_ONLINE_BUTTON_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate)) + +struct _EOnlineButtonPrivate { + GtkWidget *image; + gboolean online; +}; + +enum { + PROP_0, + PROP_ONLINE +}; + +static gpointer parent_class; + +static void +online_button_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ONLINE: + e_online_button_set_online ( + E_ONLINE_BUTTON (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +online_button_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ONLINE: + g_value_set_boolean ( + value, e_online_button_get_online ( + E_ONLINE_BUTTON (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +online_button_dispose (GObject *object) +{ + EOnlineButtonPrivate *priv; + + priv = E_ONLINE_BUTTON_GET_PRIVATE (object); + + if (priv->image != NULL) { + g_object_unref (priv->image); + priv->image = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +online_button_class_init (EOnlineButtonClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EOnlineButtonPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = online_button_set_property; + object_class->get_property = online_button_get_property; + object_class->dispose = online_button_dispose; + + g_object_class_install_property ( + object_class, + PROP_ONLINE, + g_param_spec_boolean ( + "online", + _("Online"), + _("The button state is online"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); +} + +static void +online_button_init (EOnlineButton *button) +{ + GtkWidget *widget; + + button->priv = E_ONLINE_BUTTON_GET_PRIVATE (button); + + GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + + widget = gtk_image_new (); + gtk_container_add (GTK_CONTAINER (button), widget); + button->priv->image = g_object_ref (widget); + gtk_widget_show (widget); +} + +GType +e_online_button_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EOnlineButtonClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) online_button_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EOnlineButton), + 0, /* n_preallocs */ + (GInstanceInitFunc) online_button_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_BUTTON, "EOnlineButton", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_online_button_new (void) +{ + return g_object_new (E_TYPE_ONLINE_BUTTON, NULL); +} + +gboolean +e_online_button_get_online (EOnlineButton *button) +{ + g_return_val_if_fail (E_IS_ONLINE_BUTTON (button), FALSE); + + return button->priv->online; +} + +void +e_online_button_set_online (EOnlineButton *button, + gboolean online) +{ + GtkImage *image; + gchar *filename; + const gchar *image_name; + + g_return_if_fail (E_IS_ONLINE_BUTTON (button)); + + button->priv->online = online; + image_name = online ? ONLINE_IMAGE : OFFLINE_IMAGE; + + image = GTK_IMAGE (button->priv->image); + filename = g_build_filename (EVOLUTION_IMAGES, image_name, NULL); + gtk_image_set_from_file (image, filename); + g_free (filename); + + g_object_notify (G_OBJECT (button), "online"); +} diff --git a/widgets/misc/e-online-button.h b/widgets/misc/e-online-button.h new file mode 100644 index 0000000000..b9b03e1ffc --- /dev/null +++ b/widgets/misc/e-online-button.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-online-button.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef E_ONLINE_BUTTON_H +#define E_ONLINE_BUTTON_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ONLINE_BUTTON \ + (e_online_button_get_type ()) +#define E_ONLINE_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButton)) +#define E_ONLINE_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ONLINE_BUTTON, EOnlineButtonClass)) +#define E_IS_ONLINE_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ONLINE_BUTTON)) +#define E_IS_ONLINE_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ONLINE_BUTTON)) +#define E_ONLINE_BUTTON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonClass)) + +G_BEGIN_DECLS + +typedef struct _EOnlineButton EOnlineButton; +typedef struct _EOnlineButtonClass EOnlineButtonClass; +typedef struct _EOnlineButtonPrivate EOnlineButtonPrivate; + +struct _EOnlineButton { + GtkButton parent; + EOnlineButtonPrivate *priv; +}; + +struct _EOnlineButtonClass { + GtkButtonClass parent_class; +}; + +GType e_online_button_get_type (void); +GtkWidget * e_online_button_new (void); +gboolean e_online_button_get_online (EOnlineButton *button); +void e_online_button_set_online (EOnlineButton *button, + gboolean online); + +G_END_DECLS + +#endif /* E_ONLINE_BUTTON_H */ -- cgit v1.2.3 From cea054cd54d84479352a43bbabc19c9ce9af5efb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 8 Aug 2008 04:26:12 +0000 Subject: Merge revisions 35747:35930 from trunk. svn path=/branches/kill-bonobo/; revision=35931 --- widgets/misc/ChangeLog | 18 ++++++++++++++++++ widgets/misc/e-activity-handler.c | 1 + widgets/misc/e-task-bar.c | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 3649c5b274..6833cf44d6 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,21 @@ +2008-07-23 Milan Crha + + ** Part of fix for bug #543943 + + * e-activity-handler.c: (e_activity_handler_operation_set_error): + * e-task-bar.c: (e_task_bar_class_init), (impl_finalize): + Leak fix. + +2008-07-20 Matthew Barnes + + ** Fixes part of bug #542587 + + * e-online-button.c: + * e-online-button.h: + New widget implements the online/offline button used in the main + window. The button just maintains an "online" flag and displays + the appropriate button image for the flag. + 2008-17-14 Paolo Borelli ** Fix for bug #542889 diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c index 8500f72f61..04861b1b8f 100644 --- a/widgets/misc/e-activity-handler.c +++ b/widgets/misc/e-activity-handler.c @@ -612,6 +612,7 @@ e_activity_handler_operation_set_error(EActivityHandler *activity_handler, activity_info->error = error; activity_info->error_time = time (NULL); activity_info->error_type = E_LOG_ERROR; + g_free (activity_info->information); activity_info->information = g_strdup (g_object_get_data ((GObject *) error, "primary")); for (sp = priv->task_bars; sp != NULL; sp = sp->next) { ETaskBar *task_bar; diff --git a/widgets/misc/e-task-bar.c b/widgets/misc/e-task-bar.c index c05c7d8999..9093f89d58 100644 --- a/widgets/misc/e-task-bar.c +++ b/widgets/misc/e-task-bar.c @@ -82,9 +82,15 @@ reduce_displayed_activities_per_component (ETaskBar *task_bar) } #endif + +static void impl_finalize (GObject *object); + static void e_task_bar_class_init (ETaskBarClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = impl_finalize; } static void @@ -114,6 +120,20 @@ e_task_bar_init (ETaskBar *task_bar) gtk_widget_set_size_request (GTK_WIDGET (task_bar), -1, height * 2); } +static void +impl_finalize (GObject *object) +{ + ETaskBar *task_bar; + ETaskBarPrivate *priv; + + task_bar = E_TASK_BAR (object); + priv = task_bar->priv; + + g_free (priv); + + (* G_OBJECT_CLASS (e_task_bar_parent_class)->finalize) (object); +} + void e_task_bar_construct (ETaskBar *task_bar) -- cgit v1.2.3 From 278c1fa77ba74f70a8d55e6d679f73372034fb14 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 8 Aug 2008 23:12:59 +0000 Subject: Work through more compilation errors. Rewrite EMultiConfigDialog to not use ETable. svn path=/branches/kill-bonobo/; revision=35942 --- widgets/misc/e-multi-config-dialog.c | 486 ++++++++++++++++---------------- widgets/misc/e-multi-config-dialog.h | 64 +++-- widgets/misc/test-multi-config-dialog.c | 8 +- 3 files changed, 280 insertions(+), 278 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-multi-config-dialog.c b/widgets/misc/e-multi-config-dialog.c index 159b14561c..bb9c0e6f79 100644 --- a/widgets/misc/e-multi-config-dialog.c +++ b/widgets/misc/e-multi-config-dialog.c @@ -16,69 +16,33 @@ * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include "e-multi-config-dialog.h" -#include -#include
-#include
-#include
-#include
- #include #define SWITCH_PAGE_INTERVAL 250 -struct _EMultiConfigDialogPrivate { - GSList *pages; - - GtkWidget *list_e_table; - ETableModel *list_e_table_model; +#define E_MULTI_CONFIG_DIALOG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogPrivate)) +struct _EMultiConfigDialogPrivate { + GtkWidget *icon_view; GtkWidget *notebook; + guint timeout_id; +}; - int set_page_timeout_id; - int set_page_timeout_page; +enum { + COLUMN_TEXT, /* G_TYPE_STRING */ + COLUMN_PIXBUF /* GDK_TYPE_PIXBUF */ }; -G_DEFINE_TYPE (EMultiConfigDialog, e_multi_config_dialog, GTK_TYPE_DIALOG) - - -/* ETable stuff. */ - -static char *list_e_table_spec = - "" - " " - " " - " " - " " - " " - " " - ""; - -/* Page handling. */ +static gpointer parent_class; static GtkWidget * -create_page_container (const char *description, - GtkWidget *widget) +create_page_container (GtkWidget *widget) { GtkWidget *vbox; @@ -92,290 +56,328 @@ create_page_container (const char *description, return vbox; } -/* Timeout for switching pages (so it's more comfortable navigating with the - keyboard). */ - -static int -set_page_timeout_callback (void *data) +static GdkPixbuf * +multi_config_dialog_load_pixbuf (const gchar *icon_name) { - EMultiConfigDialog *multi_config_dialog; - EMultiConfigDialogPrivate *priv; + GtkIconTheme *icon_theme; + GtkIconInfo *icon_info; + GdkPixbuf *pixbuf; + const gchar *filename; + gint size; + GError *error = NULL; - multi_config_dialog = E_MULTI_CONFIG_DIALOG (data); - priv = multi_config_dialog->priv; + icon_theme = gtk_icon_theme_get_default (); - gtk_notebook_set_current_page ( - GTK_NOTEBOOK (priv->notebook), priv->set_page_timeout_page); + if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, 0)) + return NULL; - priv->set_page_timeout_id = 0; - gtk_widget_grab_focus(priv->list_e_table); - return FALSE; + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, icon_name, size, 0); + + if (icon_info == NULL) + return NULL; + + filename = gtk_icon_info_get_filename (icon_info); + + pixbuf = gdk_pixbuf_new_from_file (filename, &error); + + gtk_icon_info_free (icon_info); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + return pixbuf; } +static gboolean +multi_config_dialog_timeout_cb (EMultiConfigDialog *dialog) +{ + GtkIconView *icon_view; + GtkNotebook *notebook; + GList *list; -/* Button handling. */ + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + notebook = GTK_NOTEBOOK (dialog->priv->notebook); + + list = gtk_icon_view_get_selected_items (icon_view); + + if (list != NULL) { + GtkTreePath *path = list->data; + gint page; + + page = gtk_tree_path_get_indices (path)[0]; + gtk_notebook_set_current_page (notebook, page); + } + + g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (list); + + dialog->priv->timeout_id = 0; + gtk_widget_grab_focus (GTK_WIDGET (icon_view)); + + return FALSE; +} static void -do_close (EMultiConfigDialog *dialog) +multi_config_dialog_selection_changed_cb (EMultiConfigDialog *dialog) { - gtk_widget_destroy (GTK_WIDGET (dialog)); + if (dialog->priv->timeout_id == 0) + dialog->priv->timeout_id = g_timeout_add ( + SWITCH_PAGE_INTERVAL, (GSourceFunc) + multi_config_dialog_timeout_cb, dialog); } - -/* ETable signals. */ - static void -table_cursor_change_callback (ETable *etable, - int row, - void *data) +multi_config_dialog_dispose (GObject *object) { - EMultiConfigDialog *dialog; EMultiConfigDialogPrivate *priv; - dialog = E_MULTI_CONFIG_DIALOG (data); - priv = dialog->priv; - - if (priv->set_page_timeout_id == 0) - priv->set_page_timeout_id = g_timeout_add (SWITCH_PAGE_INTERVAL, - set_page_timeout_callback, - dialog); + priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (object); - priv->set_page_timeout_page = row; -} + if (priv->icon_view != NULL) { + g_object_unref (priv->icon_view); + priv->icon_view = NULL; + } + if (priv->notebook != NULL) { + g_object_unref (priv->notebook); + priv->notebook = NULL; + } -/* GObject methods. */ + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} static void -impl_finalize (GObject *object) +multi_config_dialog_finalize (GObject *object) { - EMultiConfigDialog *dialog; EMultiConfigDialogPrivate *priv; - dialog = E_MULTI_CONFIG_DIALOG (object); - priv = dialog->priv; - - if (priv->set_page_timeout_id != 0) - g_source_remove (priv->set_page_timeout_id); - - g_slist_free (priv->pages); + priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (object); - g_free (priv); + if (priv->timeout_id != 0) + g_source_remove (priv->timeout_id); - (* G_OBJECT_CLASS (e_multi_config_dialog_parent_class)->finalize) (object); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +multi_config_dialog_map (GtkWidget *widget) +{ + GtkDialog *dialog; -/* GtkDialog methods. */ + /* Chain up to parent's map() method. */ + GTK_WIDGET_CLASS (parent_class)->map (widget); + + /* Override those stubborn style properties. */ + dialog = GTK_DIALOG (widget); + gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); + gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0); +} static void -impl_response (GtkDialog *dialog, int response_id) +multi_config_dialog_response (GtkDialog *dialog, + gint response_id) { - EMultiConfigDialog *multi_config_dialog; GError *error = NULL; - multi_config_dialog = E_MULTI_CONFIG_DIALOG (dialog); - switch (response_id) { - case GTK_RESPONSE_HELP: - gnome_help_display ( - "evolution.xml", "config-prefs", &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - break; - case GTK_RESPONSE_CLOSE: - default: - do_close (multi_config_dialog); - break; + case GTK_RESPONSE_HELP: + gnome_help_display ( + "evolution.xml", "config-prefs", &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + break; + + case GTK_RESPONSE_CLOSE: + default: + gtk_widget_destroy (GTK_WIDGET (dialog)); + break; } } - -/* GObject ctors. */ - static void -e_multi_config_dialog_class_init (EMultiConfigDialogClass *class) +multi_config_dialog_class_init (EMultiConfigDialogClass *class) { GObjectClass *object_class; + GtkWidgetClass *widget_class; GtkDialogClass *dialog_class; - object_class = G_OBJECT_CLASS (class); - object_class->finalize = impl_finalize; + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMultiConfigDialogPrivate)); - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = impl_response; -} + object_class = G_OBJECT_CLASS (class); + object_class->dispose = multi_config_dialog_dispose; + object_class->finalize = multi_config_dialog_finalize; -#define RGB_COLOR(color) (((color).red & 0xff00) << 8 | \ - ((color).green & 0xff00) | \ - ((color).blue & 0xff00) >> 8) + widget_class = GTK_WIDGET_CLASS (class); + widget_class->map = multi_config_dialog_map; -static void -canvas_realize (GtkWidget *widget, EMultiConfigDialog *dialog) -{ + dialog_class = GTK_DIALOG_CLASS (class); + dialog_class->response = multi_config_dialog_response; } - -static ETableMemoryStoreColumnInfo columns[] = { - E_TABLE_MEMORY_STORE_STRING, - E_TABLE_MEMORY_STORE_PIXBUF, - E_TABLE_MEMORY_STORE_PIXBUF, - E_TABLE_MEMORY_STORE_PIXBUF, - E_TABLE_MEMORY_STORE_PIXBUF, - E_TABLE_MEMORY_STORE_TERMINATOR -}; - static void -e_multi_config_dialog_init (EMultiConfigDialog *multi_config_dialog) +multi_config_dialog_init (EMultiConfigDialog *dialog) { - EMultiConfigDialogPrivate *priv; - ETableModel *list_e_table_model; - GtkWidget *dialog_vbox; + GtkListStore *store; + GtkWidget *container; GtkWidget *hbox; - GtkWidget *notebook; - GtkWidget *list_e_table; - ETableExtras *extras; - ECell *pixbuf; - ECell *text; - ECell *vbox; + GtkWidget *widget; - gtk_dialog_set_has_separator (GTK_DIALOG (multi_config_dialog), FALSE); - gtk_widget_realize (GTK_WIDGET (multi_config_dialog)); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (multi_config_dialog)->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (multi_config_dialog)->action_area), 12); + dialog->priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (dialog); - hbox = gtk_hbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); - dialog_vbox = GTK_DIALOG (multi_config_dialog)->vbox; + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - gtk_container_add (GTK_CONTAINER (dialog_vbox), hbox); + /* XXX Remove this once we kill Bonobo. */ + gtk_widget_realize (GTK_WIDGET (dialog)); - list_e_table_model = e_table_memory_store_new (columns); + container = GTK_DIALOG (dialog)->vbox; - vbox = e_cell_vbox_new (); - - pixbuf = e_cell_pixbuf_new(); - g_object_set (G_OBJECT (pixbuf), - "focused_column", 2, - "selected_column", 3, - "unselected_column", 4, - NULL); - e_cell_vbox_append (E_CELL_VBOX (vbox), pixbuf, 1); - g_object_unref (pixbuf); - - text = e_cell_text_new (NULL, GTK_JUSTIFY_CENTER); - e_cell_vbox_append (E_CELL_VBOX (vbox), text, 0); - g_object_unref (text); + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_add (GTK_CONTAINER (container), hbox); + gtk_widget_show (hbox); - extras = e_table_extras_new (); - e_table_extras_add_cell (extras, "vbox", vbox); + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, TRUE, 0); + gtk_widget_show (widget); - list_e_table = e_table_scrolled_new (list_e_table_model, extras, list_e_table_spec, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (list_e_table), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (list_e_table)), - "cursor_change", G_CALLBACK (table_cursor_change_callback), multi_config_dialog); + container = widget; + + store = gtk_list_store_new (2, G_TYPE_STRING, GDK_TYPE_PIXBUF); + widget = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_icon_view_set_columns (GTK_ICON_VIEW (widget), 1); + gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COLUMN_TEXT); + gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF); + g_signal_connect_swapped ( + widget, "selection-changed", + G_CALLBACK (multi_config_dialog_selection_changed_cb), dialog); + gtk_container_add (GTK_CONTAINER (container), widget); + dialog->priv->icon_view = g_object_ref (widget); + gtk_widget_show (widget); + g_object_unref (store); - g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (list_e_table))->table_canvas, - "realize", G_CALLBACK (canvas_realize), multi_config_dialog); + widget = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); + dialog->priv->notebook = g_object_ref (widget); + gtk_widget_show (widget); - g_object_unref (extras); + gtk_dialog_add_buttons ( + GTK_DIALOG (dialog), + GTK_STOCK_HELP, GTK_RESPONSE_HELP, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); - gtk_box_pack_start (GTK_BOX (hbox), list_e_table, FALSE, TRUE, 0); + gtk_dialog_set_default_response ( + GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); +} - notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE); - gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0); +GType +e_multi_config_dialog_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EMultiConfigDialogClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) multi_config_dialog_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMultiConfigDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) multi_config_dialog_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_DIALOG, "EMultiConfigDialog", &type_info, 0); + } - gtk_widget_show (hbox); - gtk_widget_show (notebook); - gtk_widget_show (list_e_table); - - gtk_dialog_add_buttons (GTK_DIALOG (multi_config_dialog), - GTK_STOCK_HELP, GTK_RESPONSE_HELP, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - gtk_dialog_set_default_response (GTK_DIALOG (multi_config_dialog), GTK_RESPONSE_OK); - - gtk_window_set_resizable (GTK_WINDOW (multi_config_dialog), TRUE); - - priv = g_new (EMultiConfigDialogPrivate, 1); - priv->pages = NULL; - priv->list_e_table = list_e_table; - priv->list_e_table_model = list_e_table_model; - priv->notebook = notebook; - priv->set_page_timeout_id = 0; - priv->set_page_timeout_page = 0; - - multi_config_dialog->priv = priv; + return type; } - GtkWidget * e_multi_config_dialog_new (void) { return g_object_new (e_multi_config_dialog_get_type (), NULL); } - void e_multi_config_dialog_add_page (EMultiConfigDialog *dialog, - const char *title, - const char *description, - GdkPixbuf *icon, + const gchar *caption, + const gchar *icon_name, EConfigPage *page_widget) { - EMultiConfigDialogPrivate *priv; - AtkObject *a11y; - AtkObject *a11yPage; - gint page_no; + GtkIconView *icon_view; + GtkNotebook *notebook; + GtkTreeModel *model; + GdkPixbuf *pixbuf; + GtkTreeIter iter; g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); - g_return_if_fail (title != NULL); - g_return_if_fail (description != NULL); + g_return_if_fail (caption != NULL); + g_return_if_fail (icon_name != NULL); g_return_if_fail (E_IS_CONFIG_PAGE (page_widget)); - priv = dialog->priv; + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + notebook = GTK_NOTEBOOK (dialog->priv->notebook); - priv->pages = g_slist_append (priv->pages, page_widget); + model = gtk_icon_view_get_model (icon_view); + pixbuf = multi_config_dialog_load_pixbuf (icon_name); - e_table_memory_store_insert (E_TABLE_MEMORY_STORE (priv->list_e_table_model), -1, NULL, title, icon, NULL, NULL, NULL); + gtk_list_store_append (GTK_LIST_STORE (model), &iter); - page_no = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - create_page_container (description, GTK_WIDGET (page_widget)), - NULL); + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + COLUMN_TEXT, caption, COLUMN_PIXBUF, pixbuf, -1); - a11y = gtk_widget_get_accessible (GTK_WIDGET(priv->notebook)); - a11yPage = atk_object_ref_accessible_child (a11y, page_no); - if (a11yPage != NULL) { - if (atk_object_get_role (a11yPage) == ATK_ROLE_PAGE_TAB) - atk_object_set_name (a11yPage, title); - g_object_unref (a11yPage); - } - if (priv->pages->next == NULL) { - ETable *table; - - /* FIXME: This is supposed to select the first entry by default - but it doesn't seem to work at all. */ - table = e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->list_e_table)); - e_table_set_cursor_row (table, 0); - e_selection_model_select_all (e_table_get_selection_model (table)); + if (gtk_tree_model_iter_n_children (model, NULL) == 1) { + GtkTreePath *path; + + path = gtk_tree_path_new_first (); + gtk_icon_view_select_path (icon_view, path); + gtk_tree_path_free (path); } + + gtk_notebook_append_page ( + notebook, create_page_container ( + GTK_WIDGET (page_widget)), NULL); } void -e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, int page) +e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, + gint page) { - EMultiConfigDialogPrivate *priv; + GtkIconView *icon_view; + GtkNotebook *notebook; + GtkTreePath *path; - g_return_if_fail (dialog != NULL); g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); - priv = dialog->priv; + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + notebook = GTK_NOTEBOOK (dialog->priv->notebook); - e_table_set_cursor_row (e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->list_e_table)), page); - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page); -} + path = gtk_tree_path_new_from_indices (page, -1); + gtk_icon_view_select_path (icon_view, path); + gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + gtk_notebook_set_current_page (notebook, page); +} diff --git a/widgets/misc/e-multi-config-dialog.h b/widgets/misc/e-multi-config-dialog.h index f39c900573..f636f0d37d 100644 --- a/widgets/misc/e-multi-config-dialog.h +++ b/widgets/misc/e-multi-config-dialog.h @@ -16,12 +16,10 @@ * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli */ -#ifndef _E_MULTI_CONFIG_DIALOG_H_ -#define _E_MULTI_CONFIG_DIALOG_H_ +#ifndef E_MULTI_CONFIG_DIALOG_H +#define E_MULTI_CONFIG_DIALOG_H #ifdef HAVE_CONFIG_H #include @@ -31,25 +29,33 @@ #include -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS -#define E_TYPE_MULTI_CONFIG_DIALOG (e_multi_config_dialog_get_type ()) -#define E_MULTI_CONFIG_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialog)) -#define E_MULTI_CONFIG_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass)) -#define E_IS_MULTI_CONFIG_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) -#define E_IS_MULTI_CONFIG_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) +/* Standard GObject macros */ +#define E_TYPE_MULTI_CONFIG_DIALOG \ + (e_multi_config_dialog_get_type ()) +#define E_MULTI_CONFIG_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialog)) +#define E_MULTI_CONFIG_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass)) +#define E_IS_MULTI_CONFIG_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) +#define E_IS_MULTI_CONFIG_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) +#define E_MULTI_CONFIG_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_TYPE \ + ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass)) - -typedef struct _EMultiConfigDialog EMultiConfigDialog; +typedef struct _EMultiConfigDialog EMultiConfigDialog; +typedef struct _EMultiConfigDialogClass EMultiConfigDialogClass; typedef struct _EMultiConfigDialogPrivate EMultiConfigDialogPrivate; -typedef struct _EMultiConfigDialogClass EMultiConfigDialogClass; struct _EMultiConfigDialog { GtkDialog parent; - EMultiConfigDialogPrivate *priv; }; @@ -57,20 +63,16 @@ struct _EMultiConfigDialogClass { GtkDialogClass parent_class; }; - -GType e_multi_config_dialog_get_type (void); -GtkWidget *e_multi_config_dialog_new (void); +GType e_multi_config_dialog_get_type (void); +GtkWidget * e_multi_config_dialog_new (void); -void e_multi_config_dialog_add_page (EMultiConfigDialog *dialog, - const char *title, - const char *description, - GdkPixbuf *icon, - EConfigPage *page); -void e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, - int page); +void e_multi_config_dialog_add_page (EMultiConfigDialog *dialog, + const gchar *caption, + const gchar *icon_name, + EConfigPage *page); +void e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, + gint page); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS -#endif /* _E_MULTI_CONFIG_DIALOG_H_ */ +#endif /* E_MULTI_CONFIG_DIALOG_H */ diff --git a/widgets/misc/test-multi-config-dialog.c b/widgets/misc/test-multi-config-dialog.c index 187f1d4ab3..b9439722e9 100644 --- a/widgets/misc/test-multi-config-dialog.c +++ b/widgets/misc/test-multi-config-dialog.c @@ -41,10 +41,8 @@ add_pages (EMultiConfigDialog *multi_config_dialog) GtkWidget *page; char *string; char *title; - char *description; string = g_strdup_printf ("This is page %d", i); - description = g_strdup_printf ("Description of page %d", i); title = g_strdup_printf ("Title of page %d", i); widget = gtk_label_new (string); @@ -53,12 +51,12 @@ add_pages (EMultiConfigDialog *multi_config_dialog) page = e_config_page_new (); gtk_container_add (GTK_CONTAINER (page), widget); - e_multi_config_dialog_add_page (multi_config_dialog, title, description, NULL, - E_CONFIG_PAGE (page)); + e_multi_config_dialog_add_page ( + multi_config_dialog, title, "gtk-properties", + E_CONFIG_PAGE (page)); g_free (string); g_free (title); - g_free (description); } } -- cgit v1.2.3 From 558de407c4afe0d3d42a6a67687f78d31404ade8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 9 Aug 2008 02:24:46 +0000 Subject: Kill EShellSettingsDialog. Rename EMultiConfigDialog to EPreferencesWindow and improve the API. svn path=/branches/kill-bonobo/; revision=35944 --- widgets/misc/Makefile.am | 14 +- widgets/misc/e-multi-config-dialog.c | 383 -------------------------------- widgets/misc/e-multi-config-dialog.h | 78 ------- widgets/misc/e-preferences-window.c | 377 +++++++++++++++++++++++++++++++ widgets/misc/e-preferences-window.h | 73 ++++++ widgets/misc/test-multi-config-dialog.c | 96 -------- widgets/misc/test-preferences-window.c | 86 +++++++ 7 files changed, 543 insertions(+), 564 deletions(-) delete mode 100644 widgets/misc/e-multi-config-dialog.c delete mode 100644 widgets/misc/e-multi-config-dialog.h create mode 100644 widgets/misc/e-preferences-window.c create mode 100644 widgets/misc/e-preferences-window.h delete mode 100644 widgets/misc/test-multi-config-dialog.c create mode 100644 widgets/misc/test-preferences-window.c (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 95acd8b929..c7258e14a5 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -56,7 +56,7 @@ widgetsinclude_HEADERS = \ e-image-chooser.h \ e-info-label.h \ e-map.h \ - e-multi-config-dialog.h \ + e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ e-task-bar.h \ @@ -104,7 +104,7 @@ libemiscwidgets_la_SOURCES = \ e-image-chooser.c \ e-info-label.c \ e-map.c \ - e-multi-config-dialog.c \ + e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ e-task-bar.c \ @@ -158,7 +158,7 @@ noinst_PROGRAMS = \ test-calendar \ test-dateedit \ test-dropdown-button \ - test-multi-config-dialog \ + test-preferences-window \ test-info-label # test-calendar @@ -191,12 +191,12 @@ test_dropdown_button_LDADD = \ $(top_builddir)/e-util/libeutil.la \ $(E_WIDGETS_LIBS) -# test-multi-config-dialog +# test-preferences-window -test_multi_config_dialog_SOURCES = \ - test-multi-config-dialog.c +test_preferences_window_SOURCES = \ + test-preferences-window.c -test_multi_config_dialog_LDADD = \ +test_preferences_window_LDADD = \ libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ $(E_WIDGETS_LIBS) diff --git a/widgets/misc/e-multi-config-dialog.c b/widgets/misc/e-multi-config-dialog.c deleted file mode 100644 index bb9c0e6f79..0000000000 --- a/widgets/misc/e-multi-config-dialog.c +++ /dev/null @@ -1,383 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-multi-config-dialog.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "e-multi-config-dialog.h" - -#include - -#define SWITCH_PAGE_INTERVAL 250 - -#define E_MULTI_CONFIG_DIALOG_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogPrivate)) - -struct _EMultiConfigDialogPrivate { - GtkWidget *icon_view; - GtkWidget *notebook; - guint timeout_id; -}; - -enum { - COLUMN_TEXT, /* G_TYPE_STRING */ - COLUMN_PIXBUF /* GDK_TYPE_PIXBUF */ -}; - -static gpointer parent_class; - -static GtkWidget * -create_page_container (GtkWidget *widget) -{ - GtkWidget *vbox; - - vbox = gtk_vbox_new (FALSE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0); - - gtk_widget_show (widget); - gtk_widget_show (vbox); - - return vbox; -} - -static GdkPixbuf * -multi_config_dialog_load_pixbuf (const gchar *icon_name) -{ - GtkIconTheme *icon_theme; - GtkIconInfo *icon_info; - GdkPixbuf *pixbuf; - const gchar *filename; - gint size; - GError *error = NULL; - - icon_theme = gtk_icon_theme_get_default (); - - if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, 0)) - return NULL; - - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, icon_name, size, 0); - - if (icon_info == NULL) - return NULL; - - filename = gtk_icon_info_get_filename (icon_info); - - pixbuf = gdk_pixbuf_new_from_file (filename, &error); - - gtk_icon_info_free (icon_info); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - - return pixbuf; -} - -static gboolean -multi_config_dialog_timeout_cb (EMultiConfigDialog *dialog) -{ - GtkIconView *icon_view; - GtkNotebook *notebook; - GList *list; - - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); - notebook = GTK_NOTEBOOK (dialog->priv->notebook); - - list = gtk_icon_view_get_selected_items (icon_view); - - if (list != NULL) { - GtkTreePath *path = list->data; - gint page; - - page = gtk_tree_path_get_indices (path)[0]; - gtk_notebook_set_current_page (notebook, page); - } - - g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (list); - - dialog->priv->timeout_id = 0; - gtk_widget_grab_focus (GTK_WIDGET (icon_view)); - - return FALSE; -} - -static void -multi_config_dialog_selection_changed_cb (EMultiConfigDialog *dialog) -{ - if (dialog->priv->timeout_id == 0) - dialog->priv->timeout_id = g_timeout_add ( - SWITCH_PAGE_INTERVAL, (GSourceFunc) - multi_config_dialog_timeout_cb, dialog); -} - -static void -multi_config_dialog_dispose (GObject *object) -{ - EMultiConfigDialogPrivate *priv; - - priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (object); - - if (priv->icon_view != NULL) { - g_object_unref (priv->icon_view); - priv->icon_view = NULL; - } - - if (priv->notebook != NULL) { - g_object_unref (priv->notebook); - priv->notebook = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -multi_config_dialog_finalize (GObject *object) -{ - EMultiConfigDialogPrivate *priv; - - priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (object); - - if (priv->timeout_id != 0) - g_source_remove (priv->timeout_id); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -multi_config_dialog_map (GtkWidget *widget) -{ - GtkDialog *dialog; - - /* Chain up to parent's map() method. */ - GTK_WIDGET_CLASS (parent_class)->map (widget); - - /* Override those stubborn style properties. */ - dialog = GTK_DIALOG (widget); - gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0); -} - -static void -multi_config_dialog_response (GtkDialog *dialog, - gint response_id) -{ - GError *error = NULL; - - switch (response_id) { - case GTK_RESPONSE_HELP: - gnome_help_display ( - "evolution.xml", "config-prefs", &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } - break; - - case GTK_RESPONSE_CLOSE: - default: - gtk_widget_destroy (GTK_WIDGET (dialog)); - break; - } -} - -static void -multi_config_dialog_class_init (EMultiConfigDialogClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkDialogClass *dialog_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EMultiConfigDialogPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = multi_config_dialog_dispose; - object_class->finalize = multi_config_dialog_finalize; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->map = multi_config_dialog_map; - - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = multi_config_dialog_response; -} - -static void -multi_config_dialog_init (EMultiConfigDialog *dialog) -{ - GtkListStore *store; - GtkWidget *container; - GtkWidget *hbox; - GtkWidget *widget; - - dialog->priv = E_MULTI_CONFIG_DIALOG_GET_PRIVATE (dialog); - - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - - /* XXX Remove this once we kill Bonobo. */ - gtk_widget_realize (GTK_WIDGET (dialog)); - - container = GTK_DIALOG (dialog)->vbox; - - hbox = gtk_hbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (container), hbox); - gtk_widget_show (hbox); - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (widget), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - container = widget; - - store = gtk_list_store_new (2, G_TYPE_STRING, GDK_TYPE_PIXBUF); - widget = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store)); - gtk_icon_view_set_columns (GTK_ICON_VIEW (widget), 1); - gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COLUMN_TEXT); - gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF); - g_signal_connect_swapped ( - widget, "selection-changed", - G_CALLBACK (multi_config_dialog_selection_changed_cb), dialog); - gtk_container_add (GTK_CONTAINER (container), widget); - dialog->priv->icon_view = g_object_ref (widget); - gtk_widget_show (widget); - g_object_unref (store); - - widget = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - dialog->priv->notebook = g_object_ref (widget); - gtk_widget_show (widget); - - gtk_dialog_add_buttons ( - GTK_DIALOG (dialog), - GTK_STOCK_HELP, GTK_RESPONSE_HELP, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - gtk_dialog_set_default_response ( - GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); -} - -GType -e_multi_config_dialog_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - const GTypeInfo type_info = { - sizeof (EMultiConfigDialogClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) multi_config_dialog_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EMultiConfigDialog), - 0, /* n_preallocs */ - (GInstanceInitFunc) multi_config_dialog_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - GTK_TYPE_DIALOG, "EMultiConfigDialog", &type_info, 0); - } - - return type; -} - -GtkWidget * -e_multi_config_dialog_new (void) -{ - return g_object_new (e_multi_config_dialog_get_type (), NULL); -} - -void -e_multi_config_dialog_add_page (EMultiConfigDialog *dialog, - const gchar *caption, - const gchar *icon_name, - EConfigPage *page_widget) -{ - GtkIconView *icon_view; - GtkNotebook *notebook; - GtkTreeModel *model; - GdkPixbuf *pixbuf; - GtkTreeIter iter; - - g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); - g_return_if_fail (caption != NULL); - g_return_if_fail (icon_name != NULL); - g_return_if_fail (E_IS_CONFIG_PAGE (page_widget)); - - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); - notebook = GTK_NOTEBOOK (dialog->priv->notebook); - - model = gtk_icon_view_get_model (icon_view); - pixbuf = multi_config_dialog_load_pixbuf (icon_name); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - COLUMN_TEXT, caption, COLUMN_PIXBUF, pixbuf, -1); - - if (gtk_tree_model_iter_n_children (model, NULL) == 1) { - GtkTreePath *path; - - path = gtk_tree_path_new_first (); - gtk_icon_view_select_path (icon_view, path); - gtk_tree_path_free (path); - } - - gtk_notebook_append_page ( - notebook, create_page_container ( - GTK_WIDGET (page_widget)), NULL); -} - -void -e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, - gint page) -{ - GtkIconView *icon_view; - GtkNotebook *notebook; - GtkTreePath *path; - - g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); - - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); - notebook = GTK_NOTEBOOK (dialog->priv->notebook); - - path = gtk_tree_path_new_from_indices (page, -1); - gtk_icon_view_select_path (icon_view, path); - gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - gtk_notebook_set_current_page (notebook, page); -} diff --git a/widgets/misc/e-multi-config-dialog.h b/widgets/misc/e-multi-config-dialog.h deleted file mode 100644 index f636f0d37d..0000000000 --- a/widgets/misc/e-multi-config-dialog.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-multi-config-dialog.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef E_MULTI_CONFIG_DIALOG_H -#define E_MULTI_CONFIG_DIALOG_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-config-page.h" - -#include - -G_BEGIN_DECLS - -/* Standard GObject macros */ -#define E_TYPE_MULTI_CONFIG_DIALOG \ - (e_multi_config_dialog_get_type ()) -#define E_MULTI_CONFIG_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialog)) -#define E_MULTI_CONFIG_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass)) -#define E_IS_MULTI_CONFIG_DIALOG(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) -#define E_IS_MULTI_CONFIG_DIALOG_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_MULTI_CONFIG_DIALOG)) -#define E_MULTI_CONFIG_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_TYPE \ - ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass)) - -typedef struct _EMultiConfigDialog EMultiConfigDialog; -typedef struct _EMultiConfigDialogClass EMultiConfigDialogClass; -typedef struct _EMultiConfigDialogPrivate EMultiConfigDialogPrivate; - -struct _EMultiConfigDialog { - GtkDialog parent; - EMultiConfigDialogPrivate *priv; -}; - -struct _EMultiConfigDialogClass { - GtkDialogClass parent_class; -}; - -GType e_multi_config_dialog_get_type (void); -GtkWidget * e_multi_config_dialog_new (void); - -void e_multi_config_dialog_add_page (EMultiConfigDialog *dialog, - const gchar *caption, - const gchar *icon_name, - EConfigPage *page); -void e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, - gint page); - -G_END_DECLS - -#endif /* E_MULTI_CONFIG_DIALOG_H */ diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c new file mode 100644 index 0000000000..1f2d38345f --- /dev/null +++ b/widgets/misc/e-preferences-window.c @@ -0,0 +1,377 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-preferences-window.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-preferences-window.h" + +#include + +#define SWITCH_PAGE_INTERVAL 250 + +#define E_PREFERENCES_WINDOW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowPrivate)) + +struct _EPreferencesWindowPrivate { + GtkWidget *icon_view; + GtkWidget *notebook; + GHashTable *index; +}; + +enum { + COLUMN_TEXT, /* G_TYPE_STRING */ + COLUMN_PIXBUF, /* GDK_TYPE_PIXBUF */ + COLUMN_PAGE, /* G_TYPE_INT */ + COLUMN_SORT /* G_TYPE_INT */ +}; + +static gpointer parent_class; + +static GdkPixbuf * +preferences_window_load_pixbuf (const gchar *icon_name) +{ + GtkIconTheme *icon_theme; + GtkIconInfo *icon_info; + GdkPixbuf *pixbuf; + const gchar *filename; + gint size; + GError *error = NULL; + + icon_theme = gtk_icon_theme_get_default (); + + if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, 0)) + return NULL; + + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, icon_name, size, 0); + + if (icon_info == NULL) + return NULL; + + filename = gtk_icon_info_get_filename (icon_info); + + pixbuf = gdk_pixbuf_new_from_file (filename, &error); + + gtk_icon_info_free (icon_info); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + return pixbuf; +} + +static void +preferences_window_selection_changed_cb (EPreferencesWindow *dialog) +{ + GtkIconView *icon_view; + GtkNotebook *notebook; + GtkTreeModel *model; + GtkTreeIter iter; + GList *list; + gint page; + + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + list = gtk_icon_view_get_selected_items (icon_view); + if (list == NULL) + return; + + model = gtk_icon_view_get_model (icon_view); + gtk_tree_model_get_iter (model, &iter, list->data); + gtk_tree_model_get (model, &iter, COLUMN_PAGE, &page, -1); + + notebook = GTK_NOTEBOOK (dialog->priv->notebook); + gtk_notebook_set_current_page (notebook, page); + + g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (list); + + gtk_widget_grab_focus (GTK_WIDGET (icon_view)); +} + +static void +preferences_window_dispose (GObject *object) +{ + EPreferencesWindowPrivate *priv; + + priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object); + + if (priv->icon_view != NULL) { + g_object_unref (priv->icon_view); + priv->icon_view = NULL; + } + + if (priv->notebook != NULL) { + g_object_unref (priv->notebook); + priv->notebook = NULL; + } + + g_hash_table_remove_all (priv->index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +preferences_window_finalize (GObject *object) +{ + EPreferencesWindowPrivate *priv; + + priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object); + + g_hash_table_destroy (priv->index); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +preferences_window_map (GtkWidget *widget) +{ + GtkDialog *dialog; + + /* Chain up to parent's map() method. */ + GTK_WIDGET_CLASS (parent_class)->map (widget); + + /* Override those stubborn style properties. */ + dialog = GTK_DIALOG (widget); + gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); + gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0); +} + +static void +preferences_window_response (GtkDialog *dialog, + gint response_id) +{ + GError *error = NULL; + + switch (response_id) { + case GTK_RESPONSE_HELP: + gnome_help_display ( + "evolution.xml", "config-prefs", &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + break; + + case GTK_RESPONSE_CLOSE: + default: + gtk_widget_destroy (GTK_WIDGET (dialog)); + break; + } +} + +static void +preferences_window_class_init (EPreferencesWindowClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkDialogClass *dialog_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EPreferencesWindowPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = preferences_window_dispose; + object_class->finalize = preferences_window_finalize; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->map = preferences_window_map; + + dialog_class = GTK_DIALOG_CLASS (class); + dialog_class->response = preferences_window_response; +} + +static void +preferences_window_init (EPreferencesWindow *dialog) +{ + GtkListStore *store; + GtkWidget *container; + GtkWidget *hbox; + GtkWidget *widget; + GHashTable *index; + + index = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) gtk_tree_row_reference_free); + + dialog->priv = E_PREFERENCES_WINDOW_GET_PRIVATE (dialog); + dialog->priv->index = index; + + store = gtk_list_store_new ( + 4, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_INT); + gtk_tree_sortable_set_sort_column_id ( + GTK_TREE_SORTABLE (store), COLUMN_SORT, GTK_SORT_ASCENDING); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); + + container = GTK_DIALOG (dialog)->vbox; + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_add (GTK_CONTAINER (container), hbox); + gtk_widget_show (hbox); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, TRUE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_icon_view_set_columns (GTK_ICON_VIEW (widget), 1); + gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COLUMN_TEXT); + gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF); + g_signal_connect_swapped ( + widget, "selection-changed", + G_CALLBACK (preferences_window_selection_changed_cb), dialog); + gtk_container_add (GTK_CONTAINER (container), widget); + dialog->priv->icon_view = g_object_ref (widget); + gtk_widget_show (widget); + g_object_unref (store); + + widget = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); + dialog->priv->notebook = g_object_ref (widget); + gtk_widget_show (widget); + + gtk_dialog_add_buttons ( + GTK_DIALOG (dialog), + GTK_STOCK_HELP, GTK_RESPONSE_HELP, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + gtk_dialog_set_default_response ( + GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); +} + +GType +e_preferences_window_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EPreferencesWindowClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) preferences_window_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EPreferencesWindow), + 0, /* n_preallocs */ + (GInstanceInitFunc) preferences_window_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_DIALOG, "EPreferencesWindow", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_preferences_window_new (void) +{ + return g_object_new (E_TYPE_PREFERENCES_WINDOW, NULL); +} + +void +e_preferences_window_add_page (EPreferencesWindow *dialog, + const gchar *page_name, + const gchar *icon_name, + const gchar *caption, + gint sort_order, + GtkWidget *widget) +{ + GtkTreeRowReference *reference; + GtkIconView *icon_view; + GtkNotebook *notebook; + GtkTreeModel *model; + GtkTreePath *path; + GHashTable *index; + GdkPixbuf *pixbuf; + GtkTreeIter iter; + gint page; + + g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); + g_return_if_fail (page_name != NULL); + g_return_if_fail (icon_name != NULL); + g_return_if_fail (caption != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + notebook = GTK_NOTEBOOK (dialog->priv->notebook); + + page = gtk_notebook_get_n_pages (notebook); + model = gtk_icon_view_get_model (icon_view); + pixbuf = preferences_window_load_pixbuf (icon_name); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + COLUMN_TEXT, caption, COLUMN_PIXBUF, pixbuf, + COLUMN_PAGE, page, COLUMN_SORT, sort_order, -1); + + index = dialog->priv->index; + path = gtk_tree_model_get_path (model, &iter); + reference = gtk_tree_row_reference_new (model, path); + g_hash_table_insert (index, g_strdup (page_name), reference); + gtk_tree_path_free (path); + + gtk_notebook_append_page (notebook, widget, NULL); + + if (page == 0) + e_preferences_window_show_page (dialog, page_name); +} + +void +e_preferences_window_show_page (EPreferencesWindow *dialog, + const gchar *page_name) +{ + GtkTreeRowReference *reference; + GtkIconView *icon_view; + GtkTreePath *path; + + g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); + g_return_if_fail (page_name != NULL); + + icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + reference = g_hash_table_lookup (dialog->priv->index, page_name); + g_return_if_fail (reference != NULL); + + path = gtk_tree_row_reference_get_path (reference); + gtk_icon_view_select_path (icon_view, path); + gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); + gtk_tree_path_free (path); +} diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h new file mode 100644 index 0000000000..133bf8cdb3 --- /dev/null +++ b/widgets/misc/e-preferences-window.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-preferences-window.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef E_PREFERENCES_WINDOW_H +#define E_PREFERENCES_WINDOW_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_PREFERENCES_WINDOW \ + (e_preferences_window_get_type ()) +#define E_PREFERENCES_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindow)) +#define E_PREFERENCES_WINDOW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass)) +#define E_IS_MULTI_CONFIG_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_PREFERENCES_WINDOW)) +#define E_IS_MULTI_CONFIG_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((obj), E_TYPE_PREFERENCES_WINDOW)) +#define E_PREFERENCES_WINDOW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_TYPE \ + ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass)) + +G_BEGIN_DECLS + +typedef struct _EPreferencesWindow EPreferencesWindow; +typedef struct _EPreferencesWindowClass EPreferencesWindowClass; +typedef struct _EPreferencesWindowPrivate EPreferencesWindowPrivate; + +struct _EPreferencesWindow { + GtkDialog parent; + EPreferencesWindowPrivate *priv; +}; + +struct _EPreferencesWindowClass { + GtkDialogClass parent_class; +}; + +GType e_preferences_window_get_type (void); +GtkWidget * e_preferences_window_new (void); +void e_preferences_window_add_page (EPreferencesWindow *window, + const gchar *page_name, + const gchar *icon_name, + const gchar *caption, + gint sort_order, + GtkWidget *widget); +void e_preferences_window_show_page (EPreferencesWindow *window, + const gchar *page_name); + +G_END_DECLS + +#endif /* E_PREFERENCES_WINDOW_H */ diff --git a/widgets/misc/test-multi-config-dialog.c b/widgets/misc/test-multi-config-dialog.c deleted file mode 100644 index b9439722e9..0000000000 --- a/widgets/misc/test-multi-config-dialog.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* test-multi-config-dialog.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: - * Ettore Perazzoli - */ - -#include "e-multi-config-dialog.c" - -#include -#include -#include - - -#define NUM_PAGES 10 - - -static void -add_pages (EMultiConfigDialog *multi_config_dialog) -{ - int i; - - for (i = 0; i < NUM_PAGES; i ++) { - GtkWidget *widget; - GtkWidget *page; - char *string; - char *title; - - string = g_strdup_printf ("This is page %d", i); - title = g_strdup_printf ("Title of page %d", i); - - widget = gtk_label_new (string); - gtk_widget_show (widget); - - page = e_config_page_new (); - gtk_container_add (GTK_CONTAINER (page), widget); - - e_multi_config_dialog_add_page ( - multi_config_dialog, title, "gtk-properties", - E_CONFIG_PAGE (page)); - - g_free (string); - g_free (title); - } -} - -static int -delete_event_callback (GtkWidget *widget, - GdkEventAny *event, - void *data) -{ - gtk_main_quit (); - - return TRUE; -} - - -int -main (int argc, char **argv) -{ - GtkWidget *dialog; - - gnome_program_init ( - "test-multi-config-dialog", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); - - dialog = e_multi_config_dialog_new (); - - gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300); - g_signal_connect((dialog), "delete_event", - G_CALLBACK (delete_event_callback), NULL); - - add_pages (E_MULTI_CONFIG_DIALOG (dialog)); - - gtk_widget_show (dialog); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c new file mode 100644 index 0000000000..ddc99ff3ba --- /dev/null +++ b/widgets/misc/test-preferences-window.c @@ -0,0 +1,86 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-preferences-window.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-preferences-window.c" + +#include +#include +#include + +#define NUM_PAGES 10 + +static void +add_pages (EPreferencesWindow *preferences_window) +{ + int i; + + for (i = 0; i < NUM_PAGES; i ++) { + GtkWidget *widget; + char *caption; + char *page_name; + + caption = g_strdup_printf ("Title of page %d", i); + page_name = g_strdup_printf ("page-%d", i); + + widget = gtk_label_new (caption); + gtk_widget_show (widget); + + e_preferences_window_add_page ( + preferences_window, page_name, + "gtk-properties", caption, i, widget); + + g_free (caption); + g_free (page_name); + } +} + +static int +delete_event_callback (GtkWidget *widget, + GdkEventAny *event, + void *data) +{ + gtk_main_quit (); + + return TRUE; +} + +int +main (int argc, char **argv) +{ + GtkWidget *dialog; + + gnome_program_init ( + "test-preferences-window", "0.0", LIBGNOMEUI_MODULE, + argc, argv, GNOME_PARAM_NONE); + + dialog = e_preferences_window_new (); + + gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300); + g_signal_connect((dialog), "delete_event", + G_CALLBACK (delete_event_callback), NULL); + + add_pages (E_PREFERENCES_WINDOW (dialog)); + + gtk_widget_show (dialog); + + gtk_main (); + + return 0; +} -- cgit v1.2.3 From 2351455697b4b31d41e9d2fa6fe86e3c1cb864fb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 9 Aug 2008 02:31:24 +0000 Subject: Kill EConfigPage. svn path=/branches/kill-bonobo/; revision=35945 --- widgets/misc/Makefile.am | 2 -- widgets/misc/e-config-page.c | 50 --------------------------------- widgets/misc/e-config-page.h | 67 -------------------------------------------- 3 files changed, 119 deletions(-) delete mode 100644 widgets/misc/e-config-page.c delete mode 100644 widgets/misc/e-config-page.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index c7258e14a5..03f3e803ca 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -47,7 +47,6 @@ widgetsinclude_HEADERS = \ e-cell-renderer-combo.h \ e-charset-picker.h \ e-combo-cell-editable.h \ - e-config-page.h \ e-combo-button.h \ e-dateedit.h \ e-dropdown-button.h \ @@ -95,7 +94,6 @@ libemiscwidgets_la_SOURCES = \ e-cell-renderer-combo.c \ e-charset-picker.c \ e-combo-cell-editable.c \ - e-config-page.c \ e-combo-button.c \ e-dateedit.c \ e-dropdown-button.c \ diff --git a/widgets/misc/e-config-page.c b/widgets/misc/e-config-page.c deleted file mode 100644 index d495a01591..0000000000 --- a/widgets/misc/e-config-page.c +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-config-page.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-config-page.h" - -G_DEFINE_TYPE (EConfigPage, e_config_page, GTK_TYPE_EVENT_BOX) - -/* GObject methods. */ - -static void -e_config_page_class_init (EConfigPageClass *class) -{ -} - -static void -e_config_page_init (EConfigPage *page) -{ -} - -GtkWidget * -e_config_page_new (void) -{ - return g_object_new (e_config_page_get_type (), NULL); -} - - diff --git a/widgets/misc/e-config-page.h b/widgets/misc/e-config-page.h deleted file mode 100644 index 118c163783..0000000000 --- a/widgets/misc/e-config-page.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-config-page.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef _E_CONFIG_PAGE_H_ -#define _E_CONFIG_PAGE_H_ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_CONFIG_PAGE (e_config_page_get_type ()) -#define E_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONFIG_PAGE, EConfigPage)) -#define E_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONFIG_PAGE, EConfigPageClass)) -#define E_IS_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONFIG_PAGE)) -#define E_IS_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONFIG_PAGE)) - - -typedef struct _EConfigPage EConfigPage; -typedef struct _EConfigPagePrivate EConfigPagePrivate; -typedef struct _EConfigPageClass EConfigPageClass; - -struct _EConfigPage { - GtkEventBox parent; - - EConfigPagePrivate *priv; -}; - -struct _EConfigPageClass { - GtkEventBoxClass parent_class; - -}; - - -GType e_config_page_get_type (void); -GtkWidget *e_config_page_new (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CONFIG_PAGE_H_ */ -- cgit v1.2.3 From 7ade227e6409c98a4010992450e111cf7bb10520 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 14 Aug 2008 20:19:12 +0000 Subject: Merge revisions 35951:35992 from trunk. svn path=/branches/kill-bonobo/; revision=35994 --- widgets/misc/ChangeLog | 21 +++++++++++ widgets/misc/e-activity-handler.c | 22 +++++------- widgets/misc/e-activity-handler.h | 2 -- widgets/misc/e-combo-button.c | 7 ++-- widgets/misc/e-info-label.c | 6 +--- widgets/misc/e-search-bar.c | 1 - widgets/misc/e-send-options.c | 12 +++---- widgets/misc/e-task-widget.c | 73 ++++++++++++++------------------------- widgets/misc/e-task-widget.h | 49 +++++++++++--------------- widgets/misc/e-url-entry.c | 3 +- widgets/misc/test-info-label.c | 3 -- 11 files changed, 85 insertions(+), 114 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 6833cf44d6..15f82821c4 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,24 @@ +2008-08-14 Matthew Barnes + + * e-multi-config-dialog.c: + * e-send-options.c: + Use e_display_help() for displaying help. + +2008-08-11 Matthew Barnes + + ** Fixes part of bug #546892 + + * e-combo-button.c: + * e-info-label.c: + * e-url-entry.c: + * e-task-widget.c: + Prefer gtk_image_new_from_stock() over e_icon_factory_get_image(). + + * e-activity-handler.c: + * e-task-widget.c: + Purge the GdkPixbuf arguments from the API. We've been ignoring + them since the spinner icon was added. + 2008-07-23 Milan Crha ** Part of fix for bug #543943 diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c index 04861b1b8f..d7972ac336 100644 --- a/widgets/misc/e-activity-handler.c +++ b/widgets/misc/e-activity-handler.c @@ -39,7 +39,6 @@ struct _ActivityInfo { char *component_id; - GdkPixbuf *icon_pixbuf; int error_type; guint id; char *information; @@ -131,7 +130,6 @@ task_widget_button_press_event_callback (GtkWidget *widget, static ActivityInfo * activity_info_new (const char *component_id, guint id, - GdkPixbuf *icon, const char *information, gboolean cancellable) { @@ -140,7 +138,6 @@ activity_info_new (const char *component_id, info = g_new (ActivityInfo, 1); info->component_id = g_strdup (component_id); info->id = id; - info->icon_pixbuf = icon ? g_object_ref (icon): NULL; info->information = g_strdup (information); info->cancellable = cancellable; info->progress = -1.0; /* (Unknown) */ @@ -155,9 +152,6 @@ static void activity_info_free (ActivityInfo *info) { g_free (info->component_id); - - if (info->icon_pixbuf) - g_object_unref (info->icon_pixbuf); g_free (info->information); if (info->menu != NULL) @@ -172,9 +166,11 @@ task_widget_new_from_activity_info (ActivityInfo *activity_info) GtkWidget *widget; ETaskWidget *etw; - widget = e_task_widget_new_with_cancel (activity_info->icon_pixbuf, - activity_info->component_id, - activity_info->information, activity_info->cancel_func, activity_info->data); + widget = e_task_widget_new_with_cancel ( + activity_info->component_id, + activity_info->information, + activity_info->cancel_func, + activity_info->data); etw = (ETaskWidget *) widget; etw->id = activity_info->id; gtk_widget_show (widget); @@ -411,7 +407,6 @@ cancel_wrapper (gpointer pdata) /* CORBA methods. */ guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, const char *component_id, - GdkPixbuf *icon_pixbuf, const char *information, gboolean cancellable, void (*cancel_func)(gpointer), @@ -426,7 +421,7 @@ guint e_activity_handler_cancelable_operation_started (EActivityHandler *activ priv = activity_handler->priv; activity_id = get_new_activity_id (activity_handler); - activity_info = activity_info_new (component_id, activity_id, icon_pixbuf, information, cancellable); + activity_info = activity_info_new (component_id, activity_id, information, cancellable); data = g_new(struct _cancel_wdata, 1); data->handler = activity_handler; @@ -457,7 +452,6 @@ guint e_activity_handler_cancelable_operation_started (EActivityHandler *activ guint e_activity_handler_operation_started (EActivityHandler *activity_handler, const char *component_id, - GdkPixbuf *icon_pixbuf, const char *information, gboolean cancellable) { @@ -470,7 +464,7 @@ e_activity_handler_operation_started (EActivityHandler *activity_handler, activity_id = get_new_activity_id (activity_handler); - activity_info = activity_info_new (component_id, activity_id, icon_pixbuf, information, cancellable); + activity_info = activity_info_new (component_id, activity_id, information, cancellable); for (p = priv->task_bars; p != NULL; p = p->next) { ETaskWidget *tw = task_widget_new_from_activity_info (activity_info); @@ -558,7 +552,7 @@ e_activity_handler_make_error (EActivityHandler *activity_handler, priv = activity_handler->priv; activity_id = get_new_activity_id (activity_handler); - activity_info = activity_info_new (component_id, activity_id, NULL, information, TRUE); + activity_info = activity_info_new (component_id, activity_id, information, TRUE); activity_info->error = error; activity_info->error_time = time (NULL); activity_info->error_type = error_type; diff --git a/widgets/misc/e-activity-handler.h b/widgets/misc/e-activity-handler.h index 49f7742026..8b6a857569 100644 --- a/widgets/misc/e-activity-handler.h +++ b/widgets/misc/e-activity-handler.h @@ -71,12 +71,10 @@ void e_activity_handler_unset_message (EActivityHandler *activity_handler); guint e_activity_handler_operation_started (EActivityHandler *activity_handler, const char *component_id, - GdkPixbuf *icon_pixbuf, const char *information, gboolean cancellable); guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, const char *component_id, - GdkPixbuf *icon_pixbuf, const char *information, gboolean cancellable, void (*cancel_func)(gpointer), diff --git a/widgets/misc/e-combo-button.c b/widgets/misc/e-combo-button.c index 65014900c6..6fc0fec57e 100644 --- a/widgets/misc/e-combo-button.c +++ b/widgets/misc/e-combo-button.c @@ -26,7 +26,6 @@ #include "e-combo-button.h" #include "ea-widgets.h" -#include struct _EComboButtonPrivate { GdkPixbuf *icon; @@ -461,7 +460,8 @@ e_combo_button_pack_hbox (EComboButton *combo_button) gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox); gtk_widget_show (priv->hbox); - priv->icon_image = e_icon_factory_get_image (NULL, E_ICON_SIZE_MENU); + priv->icon_image = gtk_image_new_from_stock ( + GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->icon_image, TRUE, TRUE, 0); gtk_widget_show (priv->icon_image); @@ -498,7 +498,8 @@ e_combo_button_pack_vbox (EComboButton *combo_button) priv->vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (priv->vbox); - priv->icon_image = e_icon_factory_get_image (NULL, E_ICON_SIZE_MENU); + priv->icon_image = gtk_image_new_from_stock ( + GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU); gtk_box_pack_start (GTK_BOX (priv->vbox), priv->icon_image, TRUE, TRUE, 0); gtk_widget_show (priv->icon_image); diff --git a/widgets/misc/e-info-label.c b/widgets/misc/e-info-label.c index 3e8691972d..4c3c04069f 100644 --- a/widgets/misc/e-info-label.c +++ b/widgets/misc/e-info-label.c @@ -27,8 +27,6 @@ #include "e-info-label.h" -#include - static GtkHBoxClass *el_parent; static void @@ -184,10 +182,8 @@ e_info_label_new(const char *icon) { EInfoLabel *el = g_object_new(e_info_label_get_type(), NULL); GtkWidget *image; - char *name = e_icon_factory_get_icon_filename (icon, E_ICON_SIZE_MENU); - image = gtk_image_new_from_file(name); - g_free(name); + image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); gtk_misc_set_padding((GtkMisc *)image, 6, 6); gtk_box_pack_start((GtkBox *)el, image, FALSE, TRUE, 0); gtk_widget_show(image); diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index ffef719f17..bd8ba20072 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -45,7 +45,6 @@ #include "e-search-bar.h" #include "e-util/e-util.h" #include "e-util/e-util-marshal.h" -#include "e-util/e-icon-factory.h" enum { diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index 32eb33b484..33c80d6917 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -23,11 +23,11 @@ #endif #include -#include #include #include #include +#include "e-util/e-util.h" #include "e-util/e-util-private.h" #include "e-dateedit.h" @@ -586,7 +586,6 @@ static void e_send_options_cb (GtkDialog *dialog, gint state, gpointer func_data { ESendOptionsDialogPrivate *priv; ESendOptionsDialog *sod; - GError *error = NULL; sod = func_data; priv = sod->priv; @@ -600,12 +599,9 @@ static void e_send_options_cb (GtkDialog *dialog, gint state, gpointer func_data g_object_unref (priv->xml); break; case GTK_RESPONSE_HELP: - gnome_help_display ( - "evolution.xml", priv->help_section, &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } + e_display_help ( + GTK_WINDOW (priv->main), + priv->help_section); break; } diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c index 74b0ba6891..bb2ec2747e 100644 --- a/widgets/misc/e-task-widget.c +++ b/widgets/misc/e-task-widget.c @@ -26,7 +26,6 @@ #include "e-task-widget.h" #include "e-spinner.h" -#include #include @@ -36,7 +35,6 @@ struct _ETaskWidgetPrivate { char *component_id; - GdkPixbuf *icon_pixbuf; GtkWidget *label; GtkWidget *box; GtkWidget *image; @@ -49,24 +47,6 @@ G_DEFINE_TYPE (ETaskWidget, e_task_widget, GTK_TYPE_EVENT_BOX) /* GObject methods. */ -static void -impl_dispose (GObject *object) -{ - ETaskWidget *task_widget; - ETaskWidgetPrivate *priv; - - task_widget = E_TASK_WIDGET (object); - - priv = task_widget->priv; - - if (priv->icon_pixbuf != NULL) { - g_object_unref (priv->icon_pixbuf); - priv->icon_pixbuf = NULL; - } - - (* G_OBJECT_CLASS (e_task_widget_parent_class)->dispose) (object); -} - static void impl_finalize (GObject *object) { @@ -88,7 +68,6 @@ e_task_widget_class_init (ETaskWidgetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = impl_dispose; object_class->finalize = impl_finalize; } @@ -100,7 +79,6 @@ e_task_widget_init (ETaskWidget *task_widget) priv = g_new (ETaskWidgetPrivate, 1); priv->component_id = NULL; - priv->icon_pixbuf = NULL; priv->label = NULL; priv->image = NULL; priv->box = NULL; @@ -137,15 +115,12 @@ prepare_popup (ETaskWidget *widget, GdkEventButton *event) void e_task_widget_construct (ETaskWidget *task_widget, - GdkPixbuf *icon_pixbuf, const char *component_id, const char *information, void (*cancel_func) (gpointer data), gpointer data) { ETaskWidgetPrivate *priv; - /*GdkPixmap *pixmap; - GdkBitmap *mask;*/ GtkWidget *box; GtkWidget *frame; @@ -169,15 +144,10 @@ e_task_widget_construct (ETaskWidget *task_widget, gtk_widget_set_size_request (box, 1, -1); - /* FIXME: Experimenting Spinner widget instead of an image. REWORK THIS */ - /* priv->icon_pixbuf = g_object_ref (icon_pixbuf); */ - - /* gdk_pixbuf_render_pixmap_and_mask (icon_pixbuf, &pixmap, &mask, 128); */ priv->box = gtk_hbox_new (FALSE, 0); priv->image = e_spinner_new (); e_spinner_set_size (E_SPINNER (priv->image), GTK_ICON_SIZE_SMALL_TOOLBAR); e_spinner_start (E_SPINNER (priv->image)); - /* gtk_image_new_from_pixmap (pixmap, mask); */ gtk_widget_show (priv->image); gtk_widget_show (priv->box); gtk_box_pack_start (GTK_BOX (priv->box), priv->image, FALSE, TRUE, 0); @@ -187,9 +157,16 @@ e_task_widget_construct (ETaskWidget *task_widget, gtk_widget_show (priv->label); gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0); if (cancel_func) { - GtkWidget *image = e_icon_factory_get_image ("gtk-stop", E_ICON_SIZE_MENU); + GdkPixbuf *pixbuf; + GtkWidget *image; GtkWidget *tool; + pixbuf = gtk_icon_theme_load_icon ( + gtk_icon_theme_get_default (), + "gtk-stop", 16, 0, NULL); + image = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (pixbuf); + tool = (GtkWidget *) gtk_tool_button_new (image, NULL); gtk_box_pack_end (GTK_BOX (box), tool, FALSE, TRUE, 0); gtk_widget_show_all (tool); @@ -198,9 +175,6 @@ e_task_widget_construct (ETaskWidget *task_widget, priv->cancel_func = cancel_func; priv->data = data; g_signal_connect (tool, "clicked", G_CALLBACK (button_press_event_cb), task_widget); - /* g_object_unref (pixmap); - if (mask) - g_object_unref (mask); */ g_signal_connect (task_widget, "button-press-event", G_CALLBACK (prepare_popup), task_widget); } @@ -209,34 +183,31 @@ e_task_widget_construct (ETaskWidget *task_widget, } GtkWidget * -e_task_widget_new_with_cancel (GdkPixbuf *icon_pixbuf, - const char *component_id, - const char *information, - void (*cancel_func) (gpointer data), - gpointer data) +e_task_widget_new_with_cancel (const char *component_id, + const char *information, + void (*cancel_func) (gpointer data), + gpointer data) { ETaskWidget *task_widget; g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, icon_pixbuf, component_id, information, cancel_func, data); + e_task_widget_construct (task_widget, component_id, information, cancel_func, data); return GTK_WIDGET (task_widget); } GtkWidget * -e_task_widget_new (GdkPixbuf *icon_pixbuf, - const char *component_id, +e_task_widget_new (const char *component_id, const char *information) { ETaskWidget *task_widget; - g_return_val_if_fail (icon_pixbuf != NULL, NULL); g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, icon_pixbuf, component_id, information, NULL, NULL); + e_task_widget_construct (task_widget, component_id, information, NULL, NULL); return GTK_WIDGET (task_widget); } @@ -245,14 +216,20 @@ GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget, const char *stock, const char *text) { - GtkWidget *img, *tool; + GtkWidget *image, *tool; + GdkPixbuf *pixbuf; + + pixbuf = gtk_icon_theme_load_icon ( + gtk_icon_theme_get_default (), + stock, 16, 0, NULL); + image = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (pixbuf); - img = e_icon_factory_get_image (stock, E_ICON_SIZE_MENU); - tool = (GtkWidget *) gtk_tool_button_new (img, NULL); + tool = (GtkWidget *) gtk_tool_button_new (image, NULL); gtk_box_pack_start (GTK_BOX(task_widget->priv->box), tool, FALSE, TRUE, 0); gtk_widget_show_all (task_widget->priv->box); gtk_widget_hide (task_widget->priv->image); - task_widget->priv->image = img; + task_widget->priv->image = image; gtk_label_set_text (GTK_LABEL (task_widget->priv->label), text); return tool; diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h index d82d053b8a..cb63b27379 100644 --- a/widgets/misc/e-task-widget.h +++ b/widgets/misc/e-task-widget.h @@ -53,34 +53,27 @@ struct _ETaskWidgetClass { }; -GType e_task_widget_get_type (void); -void e_task_widget_construct (ETaskWidget *task_widget, - GdkPixbuf *icon_pixbuf, - const char *component_id, - const char *information, - void (*cancel_func) (gpointer data), - gpointer data); -GtkWidget *e_task_widget_new (GdkPixbuf *icon_pixbuf, - const char *component_id, - const char *information); -GtkWidget * -e_task_widget_new_with_cancel (GdkPixbuf *icon_pixbuf, - const char *component_id, - const char *information, - void (*cancel_func) (gpointer data), - gpointer data); - -void e_task_widget_update (ETaskWidget *task_widget, - const char *information, - double completion); -GtkWidget * -e_task_widget_update_image (ETaskWidget *task_widget, - const char *stock, const char *text); - -void e_task_wiget_alert (ETaskWidget *task_widget); -void e_task_wiget_unalert (ETaskWidget *task_widget); - -const char *e_task_widget_get_component_id (ETaskWidget *task_widget); +GType e_task_widget_get_type (void); +void e_task_widget_construct (ETaskWidget *task_widget, + const char *component_id, + const char *information, + void (*cancel_func) (gpointer data), + gpointer data); +GtkWidget * e_task_widget_new (const char *component_id, + const char *information); +GtkWidget * e_task_widget_new_with_cancel (const char *component_id, + const char *information, + void (*cancel_func) (gpointer data), + gpointer data); +void e_task_widget_update (ETaskWidget *task_widget, + const char *information, + double completion); +GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget, + const char *stock, + const char *text); +void e_task_wiget_alert (ETaskWidget *task_widget); +void e_task_wiget_unalert (ETaskWidget *task_widget); +const char * e_task_widget_get_component_id (ETaskWidget *task_widget); #ifdef __cplusplus } diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index f0ae7c5c4a..9db87b3ecd 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -29,7 +29,6 @@ #include #include #include "e-url-entry.h" -#include struct _EUrlEntryPrivate { GtkWidget *entry; @@ -105,7 +104,7 @@ init (EUrlEntry *url_entry) gtk_widget_set_sensitive (priv->button, FALSE); gtk_box_pack_start (GTK_BOX (url_entry), priv->button, FALSE, FALSE, 0); atk_object_set_name (gtk_widget_get_accessible (priv->button), _("Click here to go to URL")); - pixmap = e_icon_factory_get_image ("go-jump", E_ICON_SIZE_BUTTON); + pixmap = gtk_image_new_from_icon_name ("go-jump", GTK_ICON_SIZE_BUTTON); gtk_container_add (GTK_CONTAINER (priv->button), pixmap); gtk_widget_show (pixmap); diff --git a/widgets/misc/test-info-label.c b/widgets/misc/test-info-label.c index 70b47f9488..890dfc2082 100644 --- a/widgets/misc/test-info-label.c +++ b/widgets/misc/test-info-label.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "e-info-label.h" static void @@ -36,7 +35,6 @@ delete_event_cb (GtkWidget *widget, gpointer data) { gtk_main_quit (); - e_icon_factory_shutdown (); } int @@ -50,7 +48,6 @@ main (int argc, char **argv) gnome_program_init ( "test-title-bar", "0.0", LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_NONE); - e_icon_factory_init (); app = gnome_app_new ("Test", "Test"); gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); -- cgit v1.2.3 From 4187293731274274e4283d9039f6e30c95578118 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 18 Aug 2008 16:18:42 +0000 Subject: Merge revisions 35993:36015 from trunk. Adapt recent "crash recovery" changes to new architecture. svn path=/branches/kill-bonobo/; revision=36018 --- widgets/misc/ChangeLog | 8 ++++++++ widgets/misc/e-online-button.c | 20 ++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 15f82821c4..7f8567f96b 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,11 @@ +2008-08-14 Matthew Barnes + + ** Fixes part of bug #547411 + + * e-online-button.c (e_online_button_set_online): + The button icons are themed now but still oblong. + Load the icons by filename so GTK+ doesn't scale them. + 2008-08-14 Matthew Barnes * e-multi-config-dialog.c: diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c index 7391384950..346aec2857 100644 --- a/widgets/misc/e-online-button.c +++ b/widgets/misc/e-online-button.c @@ -22,9 +22,6 @@ #include -#define ONLINE_IMAGE "online.png" -#define OFFLINE_IMAGE "offline.png" - #define E_ONLINE_BUTTON_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate)) @@ -177,18 +174,25 @@ e_online_button_set_online (EOnlineButton *button, gboolean online) { GtkImage *image; - gchar *filename; - const gchar *image_name; + GtkIconInfo *icon_info; + GtkIconTheme *icon_theme; + const gchar *filename; + const gchar *icon_name; g_return_if_fail (E_IS_ONLINE_BUTTON (button)); button->priv->online = online; - image_name = online ? ONLINE_IMAGE : OFFLINE_IMAGE; image = GTK_IMAGE (button->priv->image); - filename = g_build_filename (EVOLUTION_IMAGES, image_name, NULL); + icon_name = online ? "online" : "offline"; + icon_theme = gtk_icon_theme_get_default (); + + /* Prevent GTK+ from scaling these rectangular icons. */ + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, icon_name, GTK_ICON_SIZE_BUTTON, 0); + filename = gtk_icon_info_get_filename (icon_info); gtk_image_set_from_file (image, filename); - g_free (filename); + gtk_icon_info_free (icon_info); g_object_notify (G_OBJECT (button), "online"); } -- cgit v1.2.3 From 2ef1b5bf42b5d429e00f94710458f237d18315b2 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 24 Aug 2008 13:17:11 +0000 Subject: Progress update: - Get the "New" button and menu working. - Add a GtkMenuToolButton subclass called EMenuToolButton, which does some behind-the-scenes stuff to make the "New" button work properly. - Kill EComboButton and its associated a11y widget. svn path=/branches/kill-bonobo/; revision=36045 --- widgets/misc/Makefile.am | 4 +- widgets/misc/e-combo-button.c | 623 ------------------------------------ widgets/misc/e-combo-button.h | 83 ----- widgets/misc/e-menu-tool-button.c | 148 +++++++++ widgets/misc/e-menu-tool-button.h | 67 ++++ widgets/misc/e-preferences-window.c | 11 +- 6 files changed, 219 insertions(+), 717 deletions(-) delete mode 100644 widgets/misc/e-combo-button.c delete mode 100644 widgets/misc/e-combo-button.h create mode 100644 widgets/misc/e-menu-tool-button.c create mode 100644 widgets/misc/e-menu-tool-button.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 03f3e803ca..2365fe668d 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -47,7 +47,6 @@ widgetsinclude_HEADERS = \ e-cell-renderer-combo.h \ e-charset-picker.h \ e-combo-cell-editable.h \ - e-combo-button.h \ e-dateedit.h \ e-dropdown-button.h \ e-expander.h \ @@ -55,6 +54,7 @@ widgetsinclude_HEADERS = \ e-image-chooser.h \ e-info-label.h \ e-map.h \ + e-menu-tool-button.h \ e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ @@ -94,7 +94,6 @@ libemiscwidgets_la_SOURCES = \ e-cell-renderer-combo.c \ e-charset-picker.c \ e-combo-cell-editable.c \ - e-combo-button.c \ e-dateedit.c \ e-dropdown-button.c \ e-expander.c \ @@ -102,6 +101,7 @@ libemiscwidgets_la_SOURCES = \ e-image-chooser.c \ e-info-label.c \ e-map.c \ + e-menu-tool-button.c \ e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ diff --git a/widgets/misc/e-combo-button.c b/widgets/misc/e-combo-button.c deleted file mode 100644 index 6fc0fec57e..0000000000 --- a/widgets/misc/e-combo-button.c +++ /dev/null @@ -1,623 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-combo-button.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-combo-button.h" -#include "ea-widgets.h" - -struct _EComboButtonPrivate { - GdkPixbuf *icon; - - GtkWidget *icon_image; - GtkWidget *label; - GtkWidget *arrow_image; - GtkWidget *hbox; - GtkWidget *vbox; - - GtkMenu *menu; - - gboolean menu_popped_up; - gboolean is_already_packed; -}; - -#define SPACING 2 - -enum { - ACTIVATE_DEFAULT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (EComboButton, e_combo_button, GTK_TYPE_BUTTON) - -/* Utility functions. */ - -static void -set_icon (EComboButton *combo_button, - GdkPixbuf *pixbuf) -{ - EComboButtonPrivate *priv; - - priv = combo_button->priv; - - if (priv->icon != NULL) - g_object_unref (priv->icon); - - if (pixbuf == NULL) { - priv->icon = NULL; - gtk_widget_hide (priv->icon_image); - return; - } - - priv->icon = g_object_ref (pixbuf); - - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->icon_image), priv->icon); - - gtk_widget_show (priv->icon_image); -} - - -/* Paint the borders. */ - -static void -paint (EComboButton *combo_button, - GdkRectangle *area) -{ - EComboButtonPrivate *priv = combo_button->priv; - GtkWidget *widget = GTK_WIDGET (combo_button); - GtkButton *button = GTK_BUTTON (combo_button); - GtkShadowType shadow_type; - gboolean interior_focus; - int separator_x; - int focus_width, focus_pad; - int x, y, width, height; - int border_width; - - if (GTK_BUTTON (widget)->depressed || priv->menu_popped_up) { - shadow_type = GTK_SHADOW_IN; - gtk_widget_set_state (widget, GTK_STATE_ACTIVE); - } else if (GTK_BUTTON (widget)->relief == GTK_RELIEF_NONE && - (GTK_WIDGET_STATE (widget) == GTK_STATE_NORMAL || - GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE)) - shadow_type = GTK_SHADOW_NONE; - else - shadow_type = GTK_SHADOW_OUT; - - border_width = GTK_CONTAINER (widget)->border_width; - - x = widget->allocation.x + border_width; - y = widget->allocation.y + border_width; - width = widget->allocation.width - border_width * 2; - height = widget->allocation.height - border_width * 2; - - separator_x = (priv->label->allocation.width - + priv->label->allocation.x - + priv->arrow_image->allocation.x) / 2; - - gtk_widget_style_get (GTK_WIDGET (widget), - "focus-line-width", &focus_width, - "focus-padding", &focus_pad, - "interior-focus", &interior_focus, - NULL); - - if (GTK_WIDGET_HAS_DEFAULT (widget) - && GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL) - gtk_paint_box (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - area, widget, "buttondefault", - x, y, width, height); - - if (!interior_focus && GTK_WIDGET_HAS_FOCUS (widget)) { - x += focus_width + focus_pad; - y += focus_width + focus_pad; - width -= 2 * (focus_width + focus_pad); - height -= 2 * (focus_width + focus_pad); - } - - if (button->relief != GTK_RELIEF_NONE || button->depressed || - priv->menu_popped_up || - GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) { - - gtk_paint_box (widget->style, widget->window, - GTK_WIDGET_STATE (widget), shadow_type, - area, widget, "button", - x, y, separator_x, height); - - if (width - separator_x > 0) - gtk_paint_box (widget->style, widget->window, - GTK_WIDGET_STATE (widget), shadow_type, - area, widget, "button", - separator_x, y, width - separator_x, height); - } - - if (GTK_WIDGET_HAS_FOCUS (widget)) { - if (interior_focus) { - x += widget->style->xthickness + focus_pad; - y += widget->style->ythickness + focus_pad; - width -= 2 * (widget->style->xthickness + focus_pad); - height -= 2 * (widget->style->xthickness + focus_pad); - } else { - x -= focus_width + focus_pad; - y -= focus_width + focus_pad; - width += 2 * (focus_width + focus_pad); - height += 2 * (focus_width + focus_pad); - } - - gtk_paint_focus (widget->style, widget->window, - GTK_WIDGET_STATE (widget), - area, widget, "button", - x, y, width, height); - } -} - - -/* Callbacks for the associated menu. */ - -static void -menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (widget); - priv = combo_button->priv; - g_signal_handlers_disconnect_matched (menu, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - combo_button); - priv->menu = NULL; -} - -static void -menu_deactivate_callback (GtkMenuShell *menu_shell, - void *data) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (data); - priv = combo_button->priv; - - priv->menu_popped_up = FALSE; - - GTK_BUTTON (combo_button)->button_down = FALSE; - GTK_BUTTON (combo_button)->in_button = FALSE; - gtk_button_leave (GTK_BUTTON (combo_button)); - gtk_button_clicked (GTK_BUTTON (combo_button)); -} - -static void -menu_position_func (GtkMenu *menu, - gint *x_return, - gint *y_return, - gboolean *push_in, - void *data) -{ - EComboButton *combo_button; - GtkAllocation *allocation; - - combo_button = E_COMBO_BUTTON (data); - allocation = & (GTK_WIDGET (combo_button)->allocation); - - gdk_window_get_origin (GTK_WIDGET (combo_button)->window, x_return, y_return); - - *y_return += allocation->height; -} - - -/* GtkObject methods. */ - -static void -impl_destroy (GtkObject *object) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (object); - priv = combo_button->priv; - - if (priv) { - if (priv->arrow_image != NULL) { - gtk_widget_destroy (priv->arrow_image); - priv->arrow_image = NULL; - } - - if (priv->icon != NULL) { - g_object_unref (priv->icon); - priv->icon = NULL; - } - - g_free (priv); - combo_button->priv = NULL; - } - - (* GTK_OBJECT_CLASS (e_combo_button_parent_class)->destroy) (object); -} - - - -static gboolean -e_combo_button_popup (EComboButton *combo_button, GdkEventButton *event) -{ - EComboButtonPrivate *priv; - - g_return_val_if_fail (combo_button != NULL, FALSE); - g_return_val_if_fail (E_IS_COMBO_BUTTON (combo_button), FALSE); - - priv = combo_button->priv; - - priv->menu_popped_up = TRUE; - - if (event) - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_func, combo_button, - event->button, event->time); - else - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_func, combo_button, - 0, gtk_get_current_event_time()); - - return TRUE; -} -/* GtkWidget methods. */ - -static int -impl_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (widget); - priv = combo_button->priv; - - if (event->type == GDK_BUTTON_PRESS && - (event->button == 1 || event->button == 3)) { - GTK_BUTTON (widget)->button_down = TRUE; - - if (event->button == 3 || - event->x >= priv->arrow_image->allocation.x) { - /* User clicked on the right side: pop up the menu. */ - gtk_button_pressed (GTK_BUTTON (widget)); - - e_combo_button_popup (combo_button, event); - } else { - /* User clicked on the left side: just behave like a - normal button (i.e. not a toggle). */ - gtk_button_pressed (GTK_BUTTON (widget)); - } - } - - return TRUE; -} - -static int -impl_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (widget); - priv = combo_button->priv; - - /* This is to override the standard behavior of deactivating the button - when the pointer gets out of the widget, in the case in which we - have just popped up the menu. Otherwise, the button would look as - inactive when the menu is popped up. */ - if (! priv->menu_popped_up) - return (* GTK_WIDGET_CLASS (e_combo_button_parent_class)->leave_notify_event) (widget, event); - - return FALSE; -} - -static int -impl_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkBin *bin; - GdkEventExpose child_event; - - if (! GTK_WIDGET_DRAWABLE (widget)) - return FALSE; - - bin = GTK_BIN (widget); - - paint (E_COMBO_BUTTON (widget), &event->area); - - child_event = *event; - if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) && - gtk_widget_intersect (bin->child, &event->area, &child_event.area)) - gtk_container_propagate_expose (GTK_CONTAINER (widget), bin->child, &child_event); - - return FALSE; -} - - -/* GtkButton methods. */ - -static void -impl_released (GtkButton *button) -{ - EComboButton *combo_button; - EComboButtonPrivate *priv; - - combo_button = E_COMBO_BUTTON (button); - priv = combo_button->priv; - - /* Massive cut & paste from GtkButton here... The only change in - behavior here is that we want to emit ::activate_default when not - the menu hasn't been popped up. */ - - if (button->button_down) { - int new_state; - - button->button_down = FALSE; - - if (button->in_button) { - gtk_button_clicked (button); - - if (! priv->menu_popped_up) - g_signal_emit (button, signals[ACTIVATE_DEFAULT], 0); - } - - new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL); - - if (GTK_WIDGET_STATE (button) != new_state) { - gtk_widget_set_state (GTK_WIDGET (button), new_state); - - /* We _draw () instead of queue_draw so that if the - operation blocks, the label doesn't vanish. */ - /* XXX gtk_widget_draw() is deprecated. - * Replace it with GTK's implementation. */ - gtk_widget_queue_draw (GTK_WIDGET (button)); - gdk_window_process_updates ( - GTK_WIDGET (button)->window, TRUE); - } - } -} - - -static void -e_combo_button_class_init (EComboButtonClass *combo_button_class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkButtonClass *button_class; - - object_class = GTK_OBJECT_CLASS (combo_button_class); - object_class->destroy = impl_destroy; - - widget_class = GTK_WIDGET_CLASS (object_class); - widget_class->button_press_event = impl_button_press_event; - widget_class->leave_notify_event = impl_leave_notify_event; - widget_class->expose_event = impl_expose_event; - - button_class = GTK_BUTTON_CLASS (object_class); - button_class->released = impl_released; - - signals[ACTIVATE_DEFAULT] = g_signal_new ("activate_default", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EComboButtonClass, activate_default), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_combo_button_a11y_init (); -} - -static void -e_combo_button_init (EComboButton *combo_button) -{ - EComboButtonPrivate *priv; - - priv = g_new (EComboButtonPrivate, 1); - combo_button->priv = priv; - - priv->icon = NULL; - priv->menu = NULL; - priv->menu_popped_up = FALSE; - priv->is_already_packed = FALSE; -} - -void -e_combo_button_pack_hbox (EComboButton *combo_button) -{ - EComboButtonPrivate *priv; - - priv = combo_button->priv; - - if(priv->is_already_packed){ - gtk_widget_destroy (priv->hbox); - } - - priv->hbox = gtk_hbox_new (FALSE, SPACING); - gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox); - gtk_widget_show (priv->hbox); - - priv->icon_image = gtk_image_new_from_stock ( - GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (priv->hbox), priv->icon_image, TRUE, TRUE, 0); - gtk_widget_show (priv->icon_image); - - priv->label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE, - 0); - gtk_widget_show (priv->label); - - priv->arrow_image = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_box_pack_end (GTK_BOX (priv->hbox), priv->arrow_image, TRUE, TRUE, - GTK_WIDGET (combo_button)->style->xthickness); - gtk_widget_show (priv->arrow_image); - - gtk_widget_show (priv->hbox); - - priv->is_already_packed = TRUE; -} - -void -e_combo_button_pack_vbox (EComboButton *combo_button) -{ - EComboButtonPrivate *priv; - - priv = combo_button->priv; - - if(priv->is_already_packed){ - gtk_widget_destroy (priv->hbox); - } - - priv->hbox = gtk_hbox_new (FALSE, SPACING); - gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox); - gtk_widget_show (priv->hbox); - - priv->vbox = gtk_vbox_new (FALSE, 0); - gtk_widget_show (priv->vbox); - - priv->icon_image = gtk_image_new_from_stock ( - GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU); - gtk_box_pack_start (GTK_BOX (priv->vbox), priv->icon_image, TRUE, TRUE, 0); - gtk_widget_show (priv->icon_image); - - priv->label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (priv->vbox), priv->label, TRUE, TRUE, - 0); - gtk_widget_show (priv->label); - - gtk_box_pack_start (GTK_BOX(priv->hbox),priv->vbox, TRUE, TRUE, 0); - - priv->arrow_image = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_box_pack_end (GTK_BOX (priv->hbox), priv->arrow_image, TRUE, TRUE, - GTK_WIDGET (combo_button)->style->xthickness); - gtk_widget_show (priv->arrow_image); - - gtk_widget_show (priv->hbox); - - priv->is_already_packed = TRUE; -} - - -void -e_combo_button_construct (EComboButton *combo_button) -{ - EComboButtonPrivate *priv; - - g_return_if_fail (combo_button != NULL); - g_return_if_fail (E_IS_COMBO_BUTTON (combo_button)); - - priv = combo_button->priv; - g_return_if_fail (priv->menu == NULL); - - GTK_WIDGET_UNSET_FLAGS (combo_button, GTK_CAN_FOCUS); - - gtk_button_set_relief (GTK_BUTTON (combo_button), GTK_RELIEF_NONE); -} - -GtkWidget * -e_combo_button_new (void) -{ - EComboButton *new; - - new = g_object_new (e_combo_button_get_type (), NULL); - e_combo_button_construct (new); - - return GTK_WIDGET (new); -} - - -void -e_combo_button_set_icon (EComboButton *combo_button, - GdkPixbuf *pixbuf) -{ - g_return_if_fail (combo_button != NULL); - g_return_if_fail (E_IS_COMBO_BUTTON (combo_button)); - - set_icon (combo_button, pixbuf); -} - -void -e_combo_button_set_label (EComboButton *combo_button, - const char *label) -{ - EComboButtonPrivate *priv; - - g_return_if_fail (combo_button != NULL); - g_return_if_fail (E_IS_COMBO_BUTTON (combo_button)); - - priv = combo_button->priv; - - if (label == NULL) - label = ""; - - gtk_label_parse_uline (GTK_LABEL (priv->label), label); -} - -void -e_combo_button_set_menu (EComboButton *combo_button, - GtkMenu *menu) -{ - EComboButtonPrivate *priv; - - g_return_if_fail (combo_button != NULL); - g_return_if_fail (E_IS_COMBO_BUTTON (combo_button)); - g_return_if_fail (menu != NULL); - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = combo_button->priv; - - if (priv->menu != NULL) - gtk_menu_detach (priv->menu); - - priv->menu = menu; - if (menu == NULL) - return; - - gtk_menu_attach_to_widget (menu, GTK_WIDGET (combo_button), menu_detacher); - - g_signal_connect((menu), "deactivate", - G_CALLBACK (menu_deactivate_callback), - combo_button); -} - -GtkWidget * -e_combo_button_get_label (EComboButton *combo_button) -{ - EComboButtonPrivate *priv; - - g_return_val_if_fail (combo_button != NULL, NULL); - g_return_val_if_fail (E_IS_COMBO_BUTTON (combo_button), NULL); - - priv = combo_button->priv; - - return priv->label; -} - -gboolean -e_combo_button_popup_menu (EComboButton *combo_button) -{ - return e_combo_button_popup (combo_button, NULL); -} diff --git a/widgets/misc/e-combo-button.h b/widgets/misc/e-combo-button.h deleted file mode 100644 index 1167ff633d..0000000000 --- a/widgets/misc/e-combo-button.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-combo-button.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef _E_COMBO_BUTTON_H_ -#define _E_COMBO_BUTTON_H_ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_COMBO_BUTTON (e_combo_button_get_type ()) -#define E_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMBO_BUTTON, EComboButton)) -#define E_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMBO_BUTTON, EComboButtonClass)) -#define E_IS_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMBO_BUTTON)) -#define E_IS_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMBO_BUTTON)) - - -typedef struct _EComboButton EComboButton; -typedef struct _EComboButtonPrivate EComboButtonPrivate; -typedef struct _EComboButtonClass EComboButtonClass; - -struct _EComboButton { - GtkButton parent; - - EComboButtonPrivate *priv; -}; - -struct _EComboButtonClass { - GtkButtonClass parent_class; - - /* Signals. */ - void (* activate_default) (EComboButton *combo_button); -}; - - -GType e_combo_button_get_type (void); -void e_combo_button_construct (EComboButton *combo_button); -GtkWidget *e_combo_button_new (void); - -void e_combo_button_set_icon (EComboButton *combo_button, - GdkPixbuf *pixbuf); -void e_combo_button_set_label (EComboButton *combo_button, - const char *label); -void e_combo_button_set_menu (EComboButton *combo_button, - GtkMenu *menu); -void e_combo_button_pack_vbox (EComboButton *combo_button); -void e_combo_button_pack_hbox (EComboButton *combo_button); - -GtkWidget *e_combo_button_get_label (EComboButton *combo_button); - -gboolean e_combo_button_popup_menu (EComboButton *combo_button); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_COMBO_BUTTON_H_ */ diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c new file mode 100644 index 0000000000..be77895fbe --- /dev/null +++ b/widgets/misc/e-menu-tool-button.c @@ -0,0 +1,148 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-menu-tool-button.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-menu-tool-button.h" + +static gpointer parent_class; + +static GtkWidget * +menu_tool_button_clone_image (GtkWidget *source) +{ + GtkIconSize size; + GtkImageType image_type; + const gchar *icon_name; + + /* XXX This isn't general purpose because it requires that the + * source image be using a named icon. Somewhat surprised + * GTK+ doesn't offer something like this. */ + image_type = gtk_image_get_storage_type (GTK_IMAGE (source)); + g_return_val_if_fail (image_type == GTK_IMAGE_ICON_NAME, NULL); + gtk_image_get_icon_name (GTK_IMAGE (source), &icon_name, &size); + + return gtk_image_new_from_icon_name (icon_name, size); +} + +static GtkMenuItem * +menu_tool_button_get_first_menu_item (GtkMenuToolButton *menu_tool_button) +{ + GtkWidget *menu; + GList *children; + + menu = gtk_menu_tool_button_get_menu (menu_tool_button); + if (!GTK_IS_MENU (menu)) + return NULL; + + /* XXX GTK+ 2.12 provides no accessor function. */ + children = GTK_MENU_SHELL (menu)->children; + if (children == NULL || children->next == NULL) + return NULL; + + /* Return the /second/ menu item, which turns out to be the first + * visible item. The first menu item is some kind of placeholder? */ + return GTK_MENU_ITEM (children->next->data); +} + +static void +menu_tool_button_update_icon (GtkToolButton *tool_button) +{ + GtkMenuItem *menu_item; + GtkMenuToolButton *menu_tool_button; + GtkImageMenuItem *image_menu_item; + GtkWidget *image; + + menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button); + menu_item = menu_tool_button_get_first_menu_item (menu_tool_button); + if (!GTK_IS_IMAGE_MENU_ITEM (menu_item)) + return; + + image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item); + image = gtk_image_menu_item_get_image (image_menu_item); + if (!GTK_IS_IMAGE (image)) + return; + + image = menu_tool_button_clone_image (image); + gtk_tool_button_set_icon_widget (tool_button, image); + gtk_widget_show (image); +} + +static void +menu_tool_button_clicked (GtkToolButton *tool_button) +{ + GtkMenuItem *menu_item; + GtkMenuToolButton *menu_tool_button; + + menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button); + menu_item = menu_tool_button_get_first_menu_item (menu_tool_button); + + if (GTK_IS_MENU_ITEM (menu_item)) + gtk_menu_item_activate (menu_item); +} + +static void +menu_tool_button_class_init (EMenuToolButtonClass *class) +{ + GtkToolButtonClass *tool_button_class; + + parent_class = g_type_class_peek_parent (class); + + tool_button_class = GTK_TOOL_BUTTON_CLASS (class); + tool_button_class->clicked = menu_tool_button_clicked; +} + +static void +menu_tool_button_init (EMenuToolButton *button) +{ + g_signal_connect ( + button, "notify::menu", + G_CALLBACK (menu_tool_button_update_icon), NULL); +} + +GType +e_menu_tool_button_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EMenuToolButtonClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) menu_tool_button_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMenuToolButton), + 0, /* n_preallocs */ + (GInstanceInitFunc) menu_tool_button_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_MENU_TOOL_BUTTON, "EMenuToolButton", + &type_info, 0); + } + + return type; +} + +GtkToolItem * +e_menu_tool_button_new (const gchar *label) +{ + return g_object_new (E_TYPE_MENU_TOOL_BUTTON, "label", label, NULL); +} diff --git a/widgets/misc/e-menu-tool-button.h b/widgets/misc/e-menu-tool-button.h new file mode 100644 index 0000000000..110c9af9d1 --- /dev/null +++ b/widgets/misc/e-menu-tool-button.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-menu-tool-button.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* EMenuToolButton is a variation of GtkMenuToolButton where the + * button icon always reflects the first menu item, and clicking + * the button activates the first menu item. */ + +#ifndef E_MENU_TOOL_BUTTON_H +#define E_MENU_TOOL_BUTTON_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_MENU_TOOL_BUTTON \ + (e_menu_tool_button_get_type ()) +#define E_MENU_TOOL_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButton)) +#define E_MENU_TOOL_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass)) +#define E_IS_MENU_TOOL_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MENU_TOOL_BUTTON)) +#define E_IS_MENU_TOOL_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MENU_TOOL_BUTTON)) +#define E_MENU_TOOL_BUTTON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass)) + +G_BEGIN_DECLS + +typedef struct _EMenuToolButton EMenuToolButton; +typedef struct _EMenuToolButtonClass EMenuToolButtonClass; + +struct _EMenuToolButton { + GtkMenuToolButton parent; +}; + +struct _EMenuToolButtonClass { + GtkMenuToolButtonClass parent_class; +}; + +GType e_menu_tool_button_get_type (void); +GtkToolItem * e_menu_tool_button_new (const gchar *label); + +G_END_DECLS + +#endif /* E_MENU_TOOL_BUTTON_H */ diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 1f2d38345f..883d6df280 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -20,7 +20,7 @@ #include "e-preferences-window.h" -#include +#include #define SWITCH_PAGE_INTERVAL 250 @@ -162,16 +162,9 @@ static void preferences_window_response (GtkDialog *dialog, gint response_id) { - GError *error = NULL; - switch (response_id) { case GTK_RESPONSE_HELP: - gnome_help_display ( - "evolution.xml", "config-prefs", &error); - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } + e_display_help (GTK_WINDOW (dialog), "config-prefs"); break; case GTK_RESPONSE_CLOSE: -- cgit v1.2.3 From e0c501b7018f12d37b10e32923f95b7a01c7982c Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 29 Aug 2008 22:32:46 +0000 Subject: Progress update: - Contacts module partially working! - Implement UI merging. Also merge EInfoLabel into ESidebar. The shell window now manages the icon and labels and keeps them up-to-date via EShellView properties. svn path=/branches/kill-bonobo/; revision=36214 --- widgets/misc/Makefile.am | 15 +-- widgets/misc/e-info-label.c | 245 ------------------------------------ widgets/misc/e-info-label.h | 57 --------- widgets/misc/e-preferences-window.c | 6 +- widgets/misc/e-preferences-window.h | 4 +- widgets/misc/test-info-label.c | 76 ----------- 6 files changed, 7 insertions(+), 396 deletions(-) delete mode 100644 widgets/misc/e-info-label.c delete mode 100644 widgets/misc/e-info-label.h delete mode 100644 widgets/misc/test-info-label.c (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 2365fe668d..a59e16a811 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -52,7 +52,6 @@ widgetsinclude_HEADERS = \ e-expander.h \ e-icon-entry.h \ e-image-chooser.h \ - e-info-label.h \ e-map.h \ e-menu-tool-button.h \ e-preferences-window.h \ @@ -99,7 +98,6 @@ libemiscwidgets_la_SOURCES = \ e-expander.c \ e-icon-entry.c \ e-image-chooser.c \ - e-info-label.c \ e-map.c \ e-menu-tool-button.c \ e-preferences-window.c \ @@ -156,8 +154,7 @@ noinst_PROGRAMS = \ test-calendar \ test-dateedit \ test-dropdown-button \ - test-preferences-window \ - test-info-label + test-preferences-window # test-calendar @@ -199,16 +196,6 @@ test_preferences_window_LDADD = \ $(top_builddir)/e-util/libeutil.la \ $(E_WIDGETS_LIBS) -# test-info-label - -test_info_label_SOURCES = \ - test-info-label.c - -test_info_label_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(E_WIDGETS_LIBS) - EXTRA_DIST = \ $(glade_DATA) \ diff --git a/widgets/misc/e-info-label.c b/widgets/misc/e-info-label.c deleted file mode 100644 index 4c3c04069f..0000000000 --- a/widgets/misc/e-info-label.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "e-info-label.h" - -static GtkHBoxClass *el_parent; - -static void -el_init(GObject *o) -{ - /*EInfoLabel *el = (EInfoLabel *)o;*/ -} - -static void -el_finalise(GObject *o) -{ - ((GObjectClass *)el_parent)->finalize(o); -} - -static void -el_destroy (GtkObject *o) -{ - ((EInfoLabel *)o)->location = NULL; - ((EInfoLabel *)o)->info = NULL; - - ((GtkObjectClass *)el_parent)->destroy(o); -} - -static int -el_expose_event(GtkWidget *w, GdkEventExpose *event) -{ - int x = ((GtkContainer *)w)->border_width; - - /* This seems a hack to me, but playing with styles wouldn't affect the background */ - gtk_paint_flat_box(w->style, w->window, - GTK_STATE_ACTIVE, GTK_SHADOW_NONE, - &event->area, w, "EInfoLabel", - w->allocation.x+x, w->allocation.y+x, - w->allocation.width-x*2, w->allocation.height-x*2); - - return ((GtkWidgetClass *)el_parent)->expose_event(w, event); -} - -static int -get_text_full_width (GtkWidget *label) -{ - PangoLayout *layout; - PangoRectangle rect; - int width; - - g_return_val_if_fail (GTK_IS_LABEL (label), 0); - - layout = gtk_label_get_layout (GTK_LABEL (label)); - - if (!layout) - return 0; - - width = pango_layout_get_width (layout); - pango_layout_set_width (layout, -1); - pango_layout_get_extents (layout, NULL, &rect); - pango_layout_set_width (layout, width); - - return PANGO_PIXELS (rect.width); -} - -static void -el_size_allocate (GtkWidget *widget, GtkAllocation *pallocation) -{ - EInfoLabel *el; - GtkAllocation allocation; - int full_loc, full_nfo; - gint diff; - - /* let calculate parent class first, and then just make it not divide evenly */ - ((GtkWidgetClass *)el_parent)->size_allocate (widget, pallocation); - - g_return_if_fail (widget!= NULL); - - el = (EInfoLabel*) widget; - - if (!el->location) - return; - - full_loc = get_text_full_width (el->location) + 1; - full_nfo = get_text_full_width (el->info) + 1; - - /* do not know the width of text, thus return */ - if (full_loc == 1 && full_nfo == 1) - return; - - if (el->location->allocation.width + el->info->allocation.width >= full_loc + full_nfo) { - /* allocate for location only as many pixels as it requires to not ellipsize - and keep rest for the info part */ - diff = el->location->allocation.width - full_loc; - } else { - /* make both shorter, but based on the ratio of its full widths */ - gint total_have = el->location->allocation.width + el->info->allocation.width; - gint total_full = full_loc + full_nfo; - - diff = el->location->allocation.width - full_loc * total_have / total_full; - } - - if (!diff) - return; - - allocation = el->location->allocation; - allocation.width -= diff; - gtk_widget_size_allocate (el->location, &allocation); - - allocation = el->info->allocation; - allocation.x -= diff; - allocation.width += diff; - gtk_widget_size_allocate (el->info, &allocation); -} - -static void -el_class_init(GObjectClass *klass) -{ - klass->finalize = el_finalise; - - ((GtkObjectClass *)klass)->destroy = el_destroy; - ((GtkWidgetClass *)klass)->expose_event = el_expose_event; - ((GtkWidgetClass *)klass)->size_allocate = el_size_allocate; -} - -GType -e_info_label_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof(EInfoLabelClass), - NULL, NULL, - (GClassInitFunc)el_class_init, - NULL, NULL, - sizeof(EInfoLabel), 0, - (GInstanceInitFunc)el_init - }; - el_parent = g_type_class_ref(gtk_hbox_get_type()); - type = g_type_register_static(gtk_hbox_get_type(), "EInfoLabel", &info, 0); - } - - return type; -} - -/** - * e_info_label_new: - * @icon: - * - * Create a new info label widget. @icon is the name of the icon - * (from the icon theme) to use for the icon image. - * - * Return value: - **/ -GtkWidget * -e_info_label_new(const char *icon) -{ - EInfoLabel *el = g_object_new(e_info_label_get_type(), NULL); - GtkWidget *image; - - image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); - gtk_misc_set_padding((GtkMisc *)image, 6, 6); - gtk_box_pack_start((GtkBox *)el, image, FALSE, TRUE, 0); - gtk_widget_show(image); - - gtk_container_set_border_width((GtkContainer *)el, 3); - - return (GtkWidget *)el; -} - -/** - * e_info_label_set_info: - * @el: - * @location: - * @info: - * - * Set the information to show on the label. @location is some - * context about the current view. e.g. the folder name. If the - * label is too wide, this will be truncated. - * - * @info is some info about this location. - **/ -void -e_info_label_set_info(EInfoLabel *el, const char *location, const char *info) -{ - gchar *markup; - - if (el->location == NULL) { - el->location = gtk_label_new (NULL); - el->info = gtk_label_new (NULL); - - gtk_label_set_ellipsize (GTK_LABEL (el->location), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment (GTK_MISC (el->location), 0.0, 0.0); - gtk_misc_set_padding (GTK_MISC (el->location), 0, 6); - - gtk_label_set_ellipsize (GTK_LABEL (el->info), PANGO_ELLIPSIZE_MIDDLE); - gtk_misc_set_alignment (GTK_MISC (el->info), 1.0, 1.0); - gtk_misc_set_padding (GTK_MISC (el->info), 0, 6); - - gtk_widget_show (el->location); - gtk_widget_show (el->info); - - gtk_box_pack_start ( - GTK_BOX (el), GTK_WIDGET (el->location), - TRUE, TRUE, 0); - gtk_box_pack_end ( - GTK_BOX (el), GTK_WIDGET (el->info), - TRUE, TRUE, 6); - gtk_widget_set_state (GTK_WIDGET (el), GTK_STATE_ACTIVE); - } - - markup = g_markup_printf_escaped ("%s", location); - gtk_label_set_markup (GTK_LABEL (el->location), markup); - g_free (markup); - - markup = g_markup_printf_escaped ("%s", info); - gtk_label_set_markup (GTK_LABEL (el->info), markup); - g_free (markup); -} - diff --git a/widgets/misc/e-info-label.h b/widgets/misc/e-info-label.h deleted file mode 100644 index 7122138cf8..0000000000 --- a/widgets/misc/e-info-label.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * - * Authors: Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef _E_INFO_LABEL_H -#define _E_INFO_LABEL_H - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_INFO_LABEL_GET_CLASS(emfv) ((EInfoLabelClass *) G_OBJECT_GET_CLASS (emfv)) - -typedef struct _EInfoLabel EInfoLabel; -typedef struct _EInfoLabelClass EInfoLabelClass; - -struct _EInfoLabel { - GtkHBox parent; - - struct _GtkWidget *location; - struct _GtkWidget *info; -}; - -struct _EInfoLabelClass { - GtkHBoxClass parent_class; -}; - -GType e_info_label_get_type(void); - -GtkWidget *e_info_label_new(const char *icon); -void e_info_label_set_info(EInfoLabel *, const char *loc, const char *info); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! _E_INFO_LABEL_H */ diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 883d6df280..988d065d76 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -303,8 +303,8 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, const gchar *page_name, const gchar *icon_name, const gchar *caption, - gint sort_order, - GtkWidget *widget) + GtkWidget *widget, + gint sort_order) { GtkTreeRowReference *reference; GtkIconView *icon_view; @@ -346,6 +346,8 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, if (page == 0) e_preferences_window_show_page (dialog, page_name); + + gtk_widget_queue_resize (GTK_WIDGET (dialog)); } void diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h index 133bf8cdb3..379d41a977 100644 --- a/widgets/misc/e-preferences-window.h +++ b/widgets/misc/e-preferences-window.h @@ -63,8 +63,8 @@ void e_preferences_window_add_page (EPreferencesWindow *window, const gchar *page_name, const gchar *icon_name, const gchar *caption, - gint sort_order, - GtkWidget *widget); + GtkWidget *widget, + gint sort_order); void e_preferences_window_show_page (EPreferencesWindow *window, const gchar *page_name); diff --git a/widgets/misc/test-info-label.c b/widgets/misc/test-info-label.c deleted file mode 100644 index 890dfc2082..0000000000 --- a/widgets/misc/test-info-label.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-title-bar.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include "e-info-label.h" - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); -} - -int -main (int argc, char **argv) -{ - GtkWidget *app; - GtkWidget *info_label; - GtkWidget *label; - GtkWidget *vbox; - - gnome_program_init ( - "test-title-bar", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); - - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); - gtk_window_set_resizable (GTK_WINDOW (app), TRUE); - - g_signal_connect (app, "delete_event", G_CALLBACK (delete_event_cb), NULL); - - info_label = e_info_label_new ("stock_default-folder"); - e_info_label_set_info ((EInfoLabel *) info_label, "Component Name", "An annoyingly long component message"); - gtk_widget_show (info_label); - - label = gtk_label_new ("boo"); - gtk_widget_show (label); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), info_label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - gnome_app_set_contents (GNOME_APP (app), vbox); - gtk_widget_show (app); - - gtk_main (); - - return 0; -} -- cgit v1.2.3 From 3843185df1e71e14e4f2e5d34aca34724090b496 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 30 Aug 2008 04:42:02 +0000 Subject: Preferences window awesomeness. svn path=/branches/kill-bonobo/; revision=36215 --- widgets/misc/e-preferences-window.c | 143 ++++++++++++++++++++---------------- widgets/misc/e-preferences-window.h | 8 +- 2 files changed, 83 insertions(+), 68 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 988d065d76..c18d975c1d 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -20,6 +20,7 @@ #include "e-preferences-window.h" +#include #include #define SWITCH_PAGE_INTERVAL 250 @@ -79,7 +80,13 @@ preferences_window_load_pixbuf (const gchar *icon_name) } static void -preferences_window_selection_changed_cb (EPreferencesWindow *dialog) +preferences_window_help_clicked_cb (GtkWindow *window) +{ + e_display_help (window, "config-prefs"); +} + +static void +preferences_window_selection_changed_cb (EPreferencesWindow *window) { GtkIconView *icon_view; GtkNotebook *notebook; @@ -88,7 +95,7 @@ preferences_window_selection_changed_cb (EPreferencesWindow *dialog) GList *list; gint page; - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); + icon_view = GTK_ICON_VIEW (window->priv->icon_view); list = gtk_icon_view_get_selected_items (icon_view); if (list == NULL) return; @@ -97,7 +104,7 @@ preferences_window_selection_changed_cb (EPreferencesWindow *dialog) gtk_tree_model_get_iter (model, &iter, list->data); gtk_tree_model_get (model, &iter, COLUMN_PAGE, &page, -1); - notebook = GTK_NOTEBOOK (dialog->priv->notebook); + notebook = GTK_NOTEBOOK (window->priv->notebook); gtk_notebook_set_current_page (notebook, page); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); @@ -143,35 +150,16 @@ preferences_window_finalize (GObject *object) } static void -preferences_window_map (GtkWidget *widget) +preferences_window_show (GtkWidget *widget) { - GtkDialog *dialog; + EPreferencesWindowPrivate *priv; - /* Chain up to parent's map() method. */ - GTK_WIDGET_CLASS (parent_class)->map (widget); + priv = E_PREFERENCES_WINDOW_GET_PRIVATE (widget); - /* Override those stubborn style properties. */ - dialog = GTK_DIALOG (widget); - gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0); -} + gtk_widget_grab_focus (priv->icon_view); -static void -preferences_window_response (GtkDialog *dialog, - gint response_id) -{ - switch (response_id) { - case GTK_RESPONSE_HELP: - e_display_help (GTK_WINDOW (dialog), "config-prefs"); - break; - - case GTK_RESPONSE_CLOSE: - default: - gtk_widget_destroy (GTK_WIDGET (dialog)); - break; - } + /* Chain up to parent's show() method. */ + GTK_WIDGET_CLASS (parent_class)->show (widget); } static void @@ -179,7 +167,6 @@ preferences_window_class_init (EPreferencesWindowClass *class) { GObjectClass *object_class; GtkWidgetClass *widget_class; - GtkDialogClass *dialog_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EPreferencesWindowPrivate)); @@ -189,42 +176,53 @@ preferences_window_class_init (EPreferencesWindowClass *class) object_class->finalize = preferences_window_finalize; widget_class = GTK_WIDGET_CLASS (class); - widget_class->map = preferences_window_map; - - dialog_class = GTK_DIALOG_CLASS (class); - dialog_class->response = preferences_window_response; + widget_class->show = preferences_window_show; } static void -preferences_window_init (EPreferencesWindow *dialog) +preferences_window_init (EPreferencesWindow *window) { GtkListStore *store; GtkWidget *container; GtkWidget *hbox; + GtkWidget *vbox; GtkWidget *widget; GHashTable *index; + const gchar *title; index = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) gtk_tree_row_reference_free); - dialog->priv = E_PREFERENCES_WINDOW_GET_PRIVATE (dialog); - dialog->priv->index = index; + window->priv = E_PREFERENCES_WINDOW_GET_PRIVATE (window); + window->priv->index = index; store = gtk_list_store_new ( 4, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_INT); gtk_tree_sortable_set_sort_column_id ( GTK_TREE_SORTABLE (store), COLUMN_SORT, GTK_SORT_ASCENDING); - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); + title = _("Evolution Preferences"); + gtk_window_set_title (GTK_WINDOW (window), title); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (window), 12); + + g_signal_connect ( + window, "delete-event", + G_CALLBACK (gtk_widget_hide_on_delete), NULL); - container = GTK_DIALOG (dialog)->vbox; + widget = gtk_vbox_new (FALSE, 12); + gtk_container_add (GTK_CONTAINER (window), widget); + gtk_widget_show (widget); - hbox = gtk_hbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (container), hbox); - gtk_widget_show (hbox); + vbox = widget; + + widget = gtk_hbox_new (FALSE, 12); + gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0); + gtk_widget_show (widget); + + hbox = widget; widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy ( @@ -243,9 +241,9 @@ preferences_window_init (EPreferencesWindow *dialog) gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF); g_signal_connect_swapped ( widget, "selection-changed", - G_CALLBACK (preferences_window_selection_changed_cb), dialog); + G_CALLBACK (preferences_window_selection_changed_cb), window); gtk_container_add (GTK_CONTAINER (container), widget); - dialog->priv->icon_view = g_object_ref (widget); + window->priv->icon_view = g_object_ref (widget); gtk_widget_show (widget); g_object_unref (store); @@ -253,17 +251,34 @@ preferences_window_init (EPreferencesWindow *dialog) gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - dialog->priv->notebook = g_object_ref (widget); + window->priv->notebook = g_object_ref (widget); gtk_widget_show (widget); - gtk_dialog_add_buttons ( - GTK_DIALOG (dialog), - GTK_STOCK_HELP, GTK_RESPONSE_HELP, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); + widget = gtk_hbutton_box_new (); + gtk_button_box_set_layout ( + GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_END); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; - gtk_dialog_set_default_response ( - GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); + widget = gtk_button_new_from_stock (GTK_STOCK_HELP); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (preferences_window_help_clicked_cb), window); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_button_box_set_child_secondary ( + GTK_BUTTON_BOX (container), widget, TRUE); + gtk_widget_show (widget); + + widget = gtk_button_new_from_stock (GTK_STOCK_CLOSE); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (gtk_widget_hide), window); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_grab_default (widget); + gtk_widget_show (widget); } GType @@ -286,7 +301,7 @@ e_preferences_window_get_type (void) }; type = g_type_register_static ( - GTK_TYPE_DIALOG, "EPreferencesWindow", &type_info, 0); + GTK_TYPE_WINDOW, "EPreferencesWindow", &type_info, 0); } return type; @@ -299,7 +314,7 @@ e_preferences_window_new (void) } void -e_preferences_window_add_page (EPreferencesWindow *dialog, +e_preferences_window_add_page (EPreferencesWindow *window, const gchar *page_name, const gchar *icon_name, const gchar *caption, @@ -316,14 +331,14 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, GtkTreeIter iter; gint page; - g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); + g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); g_return_if_fail (page_name != NULL); g_return_if_fail (icon_name != NULL); g_return_if_fail (caption != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); - notebook = GTK_NOTEBOOK (dialog->priv->notebook); + icon_view = GTK_ICON_VIEW (window->priv->icon_view); + notebook = GTK_NOTEBOOK (window->priv->notebook); page = gtk_notebook_get_n_pages (notebook); model = gtk_icon_view_get_model (icon_view); @@ -336,7 +351,7 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, COLUMN_TEXT, caption, COLUMN_PIXBUF, pixbuf, COLUMN_PAGE, page, COLUMN_SORT, sort_order, -1); - index = dialog->priv->index; + index = window->priv->index; path = gtk_tree_model_get_path (model, &iter); reference = gtk_tree_row_reference_new (model, path); g_hash_table_insert (index, g_strdup (page_name), reference); @@ -345,24 +360,24 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, gtk_notebook_append_page (notebook, widget, NULL); if (page == 0) - e_preferences_window_show_page (dialog, page_name); + e_preferences_window_show_page (window, page_name); - gtk_widget_queue_resize (GTK_WIDGET (dialog)); + gtk_widget_queue_resize (GTK_WIDGET (window)); } void -e_preferences_window_show_page (EPreferencesWindow *dialog, +e_preferences_window_show_page (EPreferencesWindow *window, const gchar *page_name) { GtkTreeRowReference *reference; GtkIconView *icon_view; GtkTreePath *path; - g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog)); + g_return_if_fail (E_IS_PREFERENCES_WINDOW (window)); g_return_if_fail (page_name != NULL); - icon_view = GTK_ICON_VIEW (dialog->priv->icon_view); - reference = g_hash_table_lookup (dialog->priv->index, page_name); + icon_view = GTK_ICON_VIEW (window->priv->icon_view); + reference = g_hash_table_lookup (window->priv->index, page_name); g_return_if_fail (reference != NULL); path = gtk_tree_row_reference_get_path (reference); diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h index 379d41a977..2a1ec921c8 100644 --- a/widgets/misc/e-preferences-window.h +++ b/widgets/misc/e-preferences-window.h @@ -32,10 +32,10 @@ #define E_PREFERENCES_WINDOW_CLASS(cls) \ (G_TYPE_CHECK_CLASS_CAST \ ((cls), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass)) -#define E_IS_MULTI_CONFIG_DIALOG(obj) \ +#define E_IS_PREFERENCES_WINDOW(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE \ ((obj), E_TYPE_PREFERENCES_WINDOW)) -#define E_IS_MULTI_CONFIG_DIALOG_CLASS(cls) \ +#define E_IS_PREFERENCES_WINDOW_CLASS(cls) \ (G_TYPE_CHECK_CLASS_TYPE \ ((obj), E_TYPE_PREFERENCES_WINDOW)) #define E_PREFERENCES_WINDOW_GET_CLASS(obj) \ @@ -49,12 +49,12 @@ typedef struct _EPreferencesWindowClass EPreferencesWindowClass; typedef struct _EPreferencesWindowPrivate EPreferencesWindowPrivate; struct _EPreferencesWindow { - GtkDialog parent; + GtkWindow parent; EPreferencesWindowPrivate *priv; }; struct _EPreferencesWindowClass { - GtkDialogClass parent_class; + GtkWindowClass parent_class; }; GType e_preferences_window_get_type (void); -- cgit v1.2.3 From 0ad2c0cf65f5769856e9359ec3d0c8d48676c171 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 30 Aug 2008 14:38:37 +0000 Subject: Figured out why the switcher buttons have no relief. GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=549943 svn path=/branches/kill-bonobo/; revision=36221 --- widgets/misc/e-preferences-window.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index c18d975c1d..1ccd07d91e 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -361,8 +361,6 @@ e_preferences_window_add_page (EPreferencesWindow *window, if (page == 0) e_preferences_window_show_page (window, page_name); - - gtk_widget_queue_resize (GTK_WIDGET (window)); } void -- cgit v1.2.3 From 06c449751cab10e94281911a4dba703616754c52 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 30 Aug 2008 22:11:55 +0000 Subject: ** Fixes bug #549968 2008-08-30 Matthew Barnes ** Fixes bug #549968 * calendar/gui/dialogs/comp-editor.c (comp_editor_init): * widgets/misc/e-attachment-bar.c (e_attachment_bar_bonobo_ui_populate_with): Use the same mnemonic for "Recent Documents" as composer. svn path=/branches/kill-bonobo/; revision=36226 --- widgets/misc/ChangeLog | 7 +++++++ widgets/misc/e-attachment-bar.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 7f8567f96b..2d100b24ce 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,10 @@ +2008-08-30 Matthew Barnes + + ** Fixes part of bug #549968 + + * e-attachment-bar.c (e_attachment_bar_bonobo_ui_populate_with): + Use the same mnemonic for "Recent Documents" as composer. + 2008-08-14 Matthew Barnes ** Fixes part of bug #547411 diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 3da833b7ec..4536ab0233 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -1378,7 +1378,7 @@ e_attachment_bar_bonobo_ui_populate_with_recent (BonoboUIComponent *uic, const c menuitems = g_string_new ("\n"); for (l = g_list_first (items), i = 1; l && i <= limit; l = l->next, ++i) { -- cgit v1.2.3 From 8bbf952350c37970e8947b807513e58e91435998 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 31 Aug 2008 12:29:42 +0000 Subject: Fix some bugs related to the New menu and toolbar button. svn path=/branches/kill-bonobo/; revision=36232 --- widgets/misc/e-menu-tool-button.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c index be77895fbe..f2ff6ded44 100644 --- a/widgets/misc/e-menu-tool-button.c +++ b/widgets/misc/e-menu-tool-button.c @@ -51,12 +51,10 @@ menu_tool_button_get_first_menu_item (GtkMenuToolButton *menu_tool_button) /* XXX GTK+ 2.12 provides no accessor function. */ children = GTK_MENU_SHELL (menu)->children; - if (children == NULL || children->next == NULL) + if (children == NULL) return NULL; - /* Return the /second/ menu item, which turns out to be the first - * visible item. The first menu item is some kind of placeholder? */ - return GTK_MENU_ITEM (children->next->data); + return GTK_MENU_ITEM (children->data); } static void -- cgit v1.2.3 From eca687589d106ff87cd4fca7bf581cb0532caf96 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 5 Sep 2008 15:47:38 +0000 Subject: Saving progress. Lots of changes. Things are a bit broken at the moment. svn path=/branches/kill-bonobo/; revision=36260 --- widgets/misc/Makefile.am | 26 +- widgets/misc/e-action-combo-box.c | 479 ++++++++ widgets/misc/e-action-combo-box.h | 79 ++ widgets/misc/e-filter-bar.h | 8 +- widgets/misc/e-icon-entry.c | 369 +++--- widgets/misc/e-icon-entry.h | 65 +- widgets/misc/e-search-bar.c | 2072 ++++++++++++-------------------- widgets/misc/e-search-bar.h | 213 +--- widgets/misc/test-preferences-window.c | 2 +- 9 files changed, 1666 insertions(+), 1647 deletions(-) create mode 100644 widgets/misc/e-action-combo-box.c create mode 100644 widgets/misc/e-action-combo-box.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index a59e16a811..ee91224f5e 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -15,8 +15,8 @@ INCLUDES = \ privsolib_LTLIBRARIES = \ - libemiscwidgets.la \ - libefilterbar.la + libemiscwidgets.la +# libefilterbar.la widgetsincludedir = $(privincludedir)/misc @@ -35,6 +35,7 @@ glade_DATA = e-send-options.glade \ widgetsinclude_HEADERS = \ $(pilot_headers) \ e-account-combo-box.h \ + e-action-combo-box.h \ e-activity-handler.h \ e-attachment.h \ e-attachment-bar.h \ @@ -83,6 +84,7 @@ libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ $(pilot_sources) \ e-account-combo-box.c \ + e-action-combo-box.c \ e-activity-handler.c \ e-calendar.c \ e-attachment.c \ @@ -139,16 +141,16 @@ libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ $(EVOLUTON_MAIL_LIBS) \ $(ICONV_LIBS) -libefilterbar_la_SOURCES = \ - e-filter-bar.c \ - e-filter-bar.h - -libefilterbar_la_LDFLAGS = $(NO_UNDEFINED) - -libefilterbar_la_LIBADD = \ - $(WIN32_BOOTSTRAP_LIBS) \ - libemiscwidgets.la \ - $(E_WIDGETS_LIBS) +#libefilterbar_la_SOURCES = \ +# e-filter-bar.c \ +# e-filter-bar.h +# +#libefilterbar_la_LDFLAGS = $(NO_UNDEFINED) +# +#libefilterbar_la_LIBADD = \ +# $(WIN32_BOOTSTRAP_LIBS) \ +# libemiscwidgets.la \ +# $(E_WIDGETS_LIBS) noinst_PROGRAMS = \ test-calendar \ diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c new file mode 100644 index 0000000000..5e32268431 --- /dev/null +++ b/widgets/misc/e-action-combo-box.c @@ -0,0 +1,479 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-action-combo-box.c + * + * Copyright (C) 2008 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "e-action-combo-box.h" + +#include + +#define E_ACTION_COMBO_BOX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxPrivate)) + +enum { + COLUMN_ACTION, + COLUMN_SORT +}; + +enum { + PROP_0, + PROP_ACTION +}; + +struct _EActionComboBoxPrivate { + GtkRadioAction *action; + GtkActionGroup *action_group; + GHashTable *index; + guint changed_handler_id; /* action::changed */ + guint group_sensitive_handler_id; /* action-group::sensitive */ + guint group_visible_handler_id; /* action-group::visible */ +}; + +static gpointer parent_class; + +static void +action_combo_box_action_changed_cb (GtkRadioAction *action, + GtkRadioAction *current, + EActionComboBox *combo_box) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gboolean valid; + + reference = g_hash_table_lookup ( + combo_box->priv->index, GINT_TO_POINTER ( + gtk_radio_action_get_current_value (current))); + g_return_if_fail (reference != NULL); + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + valid = gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + g_return_if_fail (valid); + + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); +} + +static void +action_combo_box_action_group_notify_cb (GtkActionGroup *action_group, + GParamSpec *pspec, + EActionComboBox *combo_box) +{ + g_object_set ( + combo_box, "sensitive", + gtk_action_group_get_sensitive (action_group), "visible", + gtk_action_group_get_visible (action_group), NULL); +} + +static void +action_combo_box_render_pixbuf (GtkCellLayout *layout, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + EActionComboBox *combo_box) +{ + GtkRadioAction *action; + gchar *icon_name; + gchar *stock_id; + gboolean sensitive; + gboolean visible; + + gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + + g_object_get ( + G_OBJECT (action), + "icon-name", &icon_name, + "sensitive", &sensitive, + "stock-id", &stock_id, + "visible", &visible, + NULL); + + g_object_set ( + G_OBJECT (renderer), + "icon-name", icon_name, + "sensitive", sensitive, + "stock-id", stock_id, + "stock-size", GTK_ICON_SIZE_MENU, + "visible", visible, + NULL); + + g_free (icon_name); + g_free (stock_id); +} + +static void +action_combo_box_render_text (GtkCellLayout *layout, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + EActionComboBox *combo_box) +{ + GtkRadioAction *action; + gchar **strv; + gchar *label; + gboolean sensitive; + gboolean visible; + + gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + + g_object_get ( + G_OBJECT (action), + "label", &label, + "sensitive", &sensitive, + "visible", &visible, + NULL); + + /* Strip out underscores. */ + strv = g_strsplit (label, "_", -1); + g_free (label); + label = g_strjoinv (NULL, strv); + g_strfreev (strv); + + g_object_set ( + G_OBJECT (renderer), + "sensitive", sensitive, + "text", label, + "visible", visible, + NULL); + + g_free (label); +} + +static void +action_combo_box_update_model (EActionComboBox *combo_box) +{ + GtkListStore *list_store; + GSList *list; + + g_hash_table_remove_all (combo_box->priv->index); + + if (combo_box->priv->action == NULL) { + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL); + return; + } + + list_store = gtk_list_store_new ( + 2, GTK_TYPE_RADIO_ACTION, G_TYPE_INT); + + list = gtk_radio_action_get_group (combo_box->priv->action); + + while (list != NULL) { + GtkTreeRowReference *reference; + GtkRadioAction *action = list->data; + GtkTreePath *path; + GtkTreeIter iter; + gint value; + + gtk_list_store_append (list_store, &iter); + g_object_get (G_OBJECT (action), "value", &value, NULL); + gtk_list_store_set ( + list_store, &iter, COLUMN_ACTION, + list->data, COLUMN_SORT, value, -1); + + path = gtk_tree_model_get_path ( + GTK_TREE_MODEL (list_store), &iter); + reference = gtk_tree_row_reference_new ( + GTK_TREE_MODEL (list_store), path); + g_hash_table_insert ( + combo_box->priv->index, + GINT_TO_POINTER (value), reference); + gtk_tree_path_free (path); + + list = g_slist_next (list); + } + + gtk_tree_sortable_set_sort_column_id ( + GTK_TREE_SORTABLE (list_store), + COLUMN_SORT, GTK_SORT_ASCENDING); + gtk_combo_box_set_model ( + GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (list_store)); + + action_combo_box_action_changed_cb ( + combo_box->priv->action, + combo_box->priv->action, + combo_box); +} + +static void +action_combo_box_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTION: + e_action_combo_box_set_action ( + E_ACTION_COMBO_BOX (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +action_combo_box_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTION: + g_value_set_object ( + value, e_action_combo_box_get_action ( + E_ACTION_COMBO_BOX (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +action_combo_box_dispose (GObject *object) +{ + EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); + + if (priv->action != NULL) { + g_object_unref (priv->action); + priv->action = NULL; + } + + if (priv->action_group != NULL) { + g_object_unref (priv->action_group); + priv->action_group = NULL; + } + + g_hash_table_remove_all (priv->index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +action_combo_box_finalize (GObject *object) +{ + EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object); + + g_hash_table_destroy (priv->index); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +action_combo_box_changed (GtkComboBox *combo_box) +{ + GtkRadioAction *action; + GtkTreeModel *model; + GtkTreeIter iter; + gint value; + + /* This method is virtual, so no need to chain up. */ + + if (!gtk_combo_box_get_active_iter (combo_box, &iter)) + return; + + model = gtk_combo_box_get_model (combo_box); + gtk_tree_model_get (model, &iter, COLUMN_ACTION, &action, -1); + g_object_get (G_OBJECT (action), "value", &value, NULL); + gtk_radio_action_set_current_value (action, value); +} + +static void +action_combo_box_class_init (EActionComboBoxClass *class) +{ + GObjectClass *object_class; + GtkComboBoxClass *combo_box_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EActionComboBoxPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = action_combo_box_set_property; + object_class->get_property = action_combo_box_get_property; + object_class->dispose = action_combo_box_dispose; + object_class->finalize = action_combo_box_finalize; + + combo_box_class = GTK_COMBO_BOX_CLASS (class); + combo_box_class->changed = action_combo_box_changed; + + g_object_class_install_property ( + object_class, + PROP_ACTION, + g_param_spec_object ( + "action", + _("Action"), + _("A GtkRadioAction"), + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); +} + +static void +action_combo_box_init (EActionComboBox *combo_box) +{ + GtkCellRenderer *renderer; + + combo_box->priv = E_ACTION_COMBO_BOX_GET_PRIVATE (combo_box); + + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_cell_layout_pack_start ( + GTK_CELL_LAYOUT (combo_box), renderer, FALSE); + gtk_cell_layout_set_cell_data_func ( + GTK_CELL_LAYOUT (combo_box), renderer, + (GtkCellLayoutDataFunc) action_combo_box_render_pixbuf, + combo_box, NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start ( + GTK_CELL_LAYOUT (combo_box), renderer, TRUE); + gtk_cell_layout_set_cell_data_func ( + GTK_CELL_LAYOUT (combo_box), renderer, + (GtkCellLayoutDataFunc) action_combo_box_render_text, + combo_box, NULL); + + combo_box->priv->index = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) gtk_tree_row_reference_free); +} + +GType +e_action_combo_box_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EActionComboBoxClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) action_combo_box_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EActionComboBox), + 0, /* n_preallocs */ + (GInstanceInitFunc) action_combo_box_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_COMBO_BOX, "EActionComboBox", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_action_combo_box_new (void) +{ + return e_action_combo_box_new_with_action (NULL); +} + +GtkWidget * +e_action_combo_box_new_with_action (GtkRadioAction *action) +{ + return g_object_new (E_ACTION_TYPE_COMBO_BOX, "action", action, NULL); +} + +GtkRadioAction * +e_action_combo_box_get_action (EActionComboBox *combo_box) +{ + g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), NULL); + + return combo_box->priv->action; +} + +void +e_action_combo_box_set_action (EActionComboBox *combo_box, + GtkRadioAction *action) +{ + g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); + + if (action != NULL) + g_return_if_fail (GTK_IS_RADIO_ACTION (action)); + + if (combo_box->priv->action != NULL) { + g_signal_handler_disconnect ( + combo_box->priv->action, + combo_box->priv->changed_handler_id); + g_object_unref (combo_box->priv->action); + } + + if (combo_box->priv->action_group != NULL) { + g_signal_handler_disconnect ( + combo_box->priv->action_group, + combo_box->priv->group_sensitive_handler_id); + g_signal_handler_disconnect ( + combo_box->priv->action_group, + combo_box->priv->group_visible_handler_id); + g_object_unref (combo_box->priv->action_group); + combo_box->priv->action_group = NULL; + } + + if (action != NULL) + g_object_get ( + g_object_ref (action), "action-group", + &combo_box->priv->action_group, NULL); + combo_box->priv->action = action; + action_combo_box_update_model (combo_box); + + if (combo_box->priv->action != NULL) + combo_box->priv->changed_handler_id = g_signal_connect ( + combo_box->priv->action, "changed", + G_CALLBACK (action_combo_box_action_changed_cb), + combo_box); + + if (combo_box->priv->action_group != NULL) { + combo_box->priv->group_sensitive_handler_id = + g_signal_connect ( + combo_box->priv->action_group, + "notify::sensitive", G_CALLBACK ( + action_combo_box_action_group_notify_cb), + combo_box); + combo_box->priv->group_visible_handler_id = + g_signal_connect ( + combo_box->priv->action_group, + "notify::visible", G_CALLBACK ( + action_combo_box_action_group_notify_cb), + combo_box); + } +} + +gint +e_action_combo_box_get_current_value (EActionComboBox *combo_box) +{ + g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), 0); + g_return_val_if_fail (combo_box->priv->action != NULL, 0); + + return gtk_radio_action_get_current_value (combo_box->priv->action); +} + +void +e_action_combo_box_set_current_value (EActionComboBox *combo_box, + gint current_value) +{ + g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); + g_return_if_fail (combo_box->priv->action != NULL); + + gtk_radio_action_set_current_value ( + combo_box->priv->action, current_value); +} diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h new file mode 100644 index 0000000000..452c3fa265 --- /dev/null +++ b/widgets/misc/e-action-combo-box.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-action-combo-box.h + * + * Copyright (C) 2008 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef E_ACTION_COMBO_BOX_H +#define E_ACTION_COMBO_BOX_H + +/* This is a GtkComboBox that is driven by a group of GtkRadioActions. + * Just plug in a GtkRadioAction and the widget will handle the rest. + * (Based on GtkhtmlComboBox.) */ + +#include + +/* Standard GObject macros */ +#define E_ACTION_TYPE_COMBO_BOX \ + (e_action_combo_box_get_type ()) +#define E_ACTION_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBox)) +#define E_ACTION_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxClass)) +#define E_ACTION_IS_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_ACTION_TYPE_COMBO_BOX)) +#define E_ACTION_IS_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_ACTION_TYPE_COMBO_BOX)) +#define E_ACTION_COMBO_BOX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxClass)) + +G_BEGIN_DECLS + +typedef struct _EActionComboBox EActionComboBox; +typedef struct _EActionComboBoxClass EActionComboBoxClass; +typedef struct _EActionComboBoxPrivate EActionComboBoxPrivate; + +struct _EActionComboBox { + GtkComboBox parent; + EActionComboBoxPrivate *priv; +}; + +struct _EActionComboBoxClass { + GtkComboBoxClass parent_class; +}; + +GType e_action_combo_box_get_type (void); +GtkWidget * e_action_combo_box_new (void); +GtkWidget * e_action_combo_box_new_with_action + (GtkRadioAction *action); +GtkRadioAction *e_action_combo_box_get_action (EActionComboBox *combo_box); +void e_action_combo_box_set_action (EActionComboBox *combo_box, + GtkRadioAction *action); +gint e_action_combo_box_get_current_value + (EActionComboBox *combo_box); +void e_action_combo_box_set_current_value + (EActionComboBox *combo_box, + gint current_value); + +G_END_DECLS + +#endif /* E_ACTION_COMBO_BOX_H */ diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index dfc033f1fc..5caf803485 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -101,10 +101,10 @@ enum { #define E_FILTERBAR_SAVE { N_("_Save Search..."), E_FILTERBAR_SAVE_ID, 0 } #define E_FILTERBAR_EDIT { N_("_Edit Saved Searches..."), E_FILTERBAR_EDIT_ID, 0 } #define E_FILTERBAR_ADVANCED { N_("_Advanced Search..."), E_FILTERBAR_ADVANCED_ID, 0 } -#define E_FILTERBAR_ALL_ACCOUNTS { N_("All Accounts"), E_FILTERBAR_ALL_ACCOUNTS_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_CURRENT_ACCOUNT { N_("Current Account"), E_FILTERBAR_CURRENT_ACCOUNT_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_CURRENT_FOLDER { N_("Current Folder"), E_FILTERBAR_CURRENT_FOLDER_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_CURRENT_MESSAGE { N_("Current Message"), E_FILTERBAR_CURRENT_MESSAGE_ID, ESB_ITEMTYPE_RADIO } +#define E_FILTERBAR_ALL_ACCOUNTS { N_("All Accounts"), E_FILTERBAR_ALL_ACCOUNTS_ID } +#define E_FILTERBAR_CURRENT_ACCOUNT { N_("Current Account"), E_FILTERBAR_CURRENT_ACCOUNT_ID } +#define E_FILTERBAR_CURRENT_FOLDER { N_("Current Folder"), E_FILTERBAR_CURRENT_FOLDER_ID } +#define E_FILTERBAR_CURRENT_MESSAGE { N_("Current Message"), E_FILTERBAR_CURRENT_MESSAGE_ID } #define E_FILTERBAR_SEPARATOR { NULL, 0, 0 } #ifdef JUST_FOR_TRANSLATORS diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index 7f0dbaaaee..500b27e6db 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -32,25 +32,65 @@ * */ -#include "config.h" - #include "e-icon-entry.h" -#define E_ICON_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), E_TYPE_ICON_ENTRY, EIconEntryPrivate)) +#define E_ICON_ENTRY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ICON_ENTRY, EIconEntryPrivate)) -struct _EIconEntryPrivate -{ +struct _EIconEntryPrivate { + GtkWidget *entry; GtkWidget *hbox; }; -static GtkWidgetClass *parent_class = NULL; +static gpointer parent_class; -/* private helper functions */ +static void +icon_entry_proxy_set_cursor (GtkWidget *widget, + GdkEventCrossing *event) +{ + if (event->type == GDK_ENTER_NOTIFY) { + GdkCursor *cursor; + + cursor = gdk_cursor_new (GDK_HAND1); + gdk_window_set_cursor (widget->window, cursor); + gdk_cursor_unref (cursor); + } else + gdk_window_set_cursor (widget->window, NULL); +} +static GtkWidget * +icon_entry_create_proxy (GtkAction *action) +{ + GtkWidget *proxy; + GtkWidget *widget; + + proxy = gtk_event_box_new (); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (proxy), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (proxy), 2); + gtk_action_connect_proxy (action, proxy); + gtk_widget_show (widget); + + widget = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU); + gtk_container_add (GTK_CONTAINER (proxy), widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + proxy, "button-press-event", + G_CALLBACK (gtk_action_activate), action); + g_signal_connect_after ( + proxy, "enter-notify-event", + G_CALLBACK (icon_entry_proxy_set_cursor), NULL); + g_signal_connect_after ( + proxy, "leave-notify-event", + G_CALLBACK (icon_entry_proxy_set_cursor), NULL); + + return proxy; +} static gboolean -entry_focus_change_cb (GtkWidget *widget, - GdkEventFocus *event, - GtkWidget *entry) +icon_entry_focus_change_cb (GtkWidget *widget, + GdkEventFocus *event, + GtkWidget *entry) { gtk_widget_queue_draw (entry); @@ -58,37 +98,35 @@ entry_focus_change_cb (GtkWidget *widget, } static void -e_icon_entry_get_borders (GtkWidget *widget, - GtkWidget *entry, - int *xborder, - int *yborder) +icon_entry_get_borders (GtkWidget *widget, + GtkWidget *entry, + gint *xborder, + gint *yborder) { - int focus_width; + gint focus_width; gboolean interior_focus; g_return_if_fail (entry->style != NULL); - gtk_widget_style_get (entry, - "focus-line-width", &focus_width, - "interior-focus", &interior_focus, - NULL); + gtk_widget_style_get ( + entry, "focus-line-width", &focus_width, + "interior-focus", &interior_focus, NULL); *xborder = entry->style->xthickness; *yborder = entry->style->ythickness; - if (!interior_focus) - { + if (!interior_focus) { *xborder += focus_width; *yborder += focus_width; } } static void -e_icon_entry_paint (GtkWidget *widget, +icon_entry_paint (GtkWidget *widget, GdkEventExpose *event) { EIconEntry *entry = E_ICON_ENTRY (widget); - GtkWidget *entry_widget = entry->entry; + GtkWidget *entry_widget = entry->priv->entry; int x = 0, y = 0, width, height, focus_width; gboolean interior_focus; @@ -133,36 +171,29 @@ e_icon_entry_paint (GtkWidget *widget, } } -/* Class implementation */ - static void -e_icon_entry_init (EIconEntry *entry) +icon_entry_dispose (GObject *object) { EIconEntryPrivate *priv; - GtkWidget *widget = (GtkWidget *) entry; - - priv = entry->priv = E_ICON_ENTRY_GET_PRIVATE (entry); - GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW); + priv = E_ICON_ENTRY_GET_PRIVATE (object); - priv->hbox = gtk_hbox_new (FALSE, /* FIXME */ 0); - gtk_container_add (GTK_CONTAINER (entry), priv->hbox); + if (priv->entry != NULL) { + g_object_unref (priv->entry); + priv->entry = NULL; + } - entry->entry = gtk_entry_new (); - gtk_entry_set_has_frame (GTK_ENTRY (entry->entry), FALSE); - gtk_box_pack_start (GTK_BOX (priv->hbox), entry->entry, TRUE, TRUE, /* FIXME */ 0); + if (priv->hbox != NULL) { + g_object_unref (priv->hbox); + priv->hbox = NULL; + } - /* We need to queue a redraw when focus changes, to comply with themes - * (like Clearlooks) which draw focused and unfocused entries differently. - */ - g_signal_connect_after (entry->entry, "focus-in-event", - G_CALLBACK (entry_focus_change_cb), entry); - g_signal_connect_after (entry->entry, "focus-out-event", - G_CALLBACK (entry_focus_change_cb), entry); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -e_icon_entry_realize (GtkWidget *widget) +icon_entry_realize (GtkWidget *widget) { GdkWindowAttr attributes; gint attributes_mask; @@ -185,34 +216,41 @@ e_icon_entry_realize (GtkWidget *widget) attributes.wclass = GDK_INPUT_OUTPUT; attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); + widget->window = gdk_window_new ( + gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + gtk_style_set_background ( + widget->style, widget->window, GTK_STATE_NORMAL); } static void -e_icon_entry_size_request (GtkWidget *widget, - GtkRequisition *requisition) +icon_entry_size_request (GtkWidget *widget, + GtkRequisition *requisition) { - EIconEntry *entry = E_ICON_ENTRY (widget); - GtkContainer *container = GTK_CONTAINER (widget); - GtkBin *bin = GTK_BIN (widget); - int xborder, yborder; + EIconEntryPrivate *priv; + GtkContainer *container; + GtkWidget *child; + gint xborder, yborder; - requisition->width = requisition->height = container->border_width * 2; + priv = E_ICON_ENTRY_GET_PRIVATE (widget); + container = GTK_CONTAINER (widget); - gtk_widget_ensure_style (entry->entry); - e_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder); + requisition->width = container->border_width * 2; + requisition->height = container->border_width * 2; - if (GTK_WIDGET_VISIBLE (bin->child)) - { + gtk_widget_ensure_style (priv->entry); + icon_entry_get_borders (widget, priv->entry, &xborder, &yborder); + + child = GTK_BIN (widget)->child; + if (GTK_WIDGET_VISIBLE (child)) { GtkRequisition child_requisition; - gtk_widget_size_request (bin->child, &child_requisition); + gtk_widget_size_request (child, &child_requisition); requisition->width += child_requisition.width; requisition->height += child_requisition.height; } @@ -222,68 +260,112 @@ e_icon_entry_size_request (GtkWidget *widget, } static void -e_icon_entry_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +icon_entry_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { - EIconEntry *entry = E_ICON_ENTRY (widget); - GtkContainer *container = GTK_CONTAINER (widget); - GtkBin *bin = GTK_BIN (widget); + EIconEntryPrivate *priv; + GtkContainer *container; GtkAllocation child_allocation; - int xborder, yborder; + gint xborder, yborder; + gint width, height; + + priv = E_ICON_ENTRY_GET_PRIVATE (widget); + container = GTK_CONTAINER (widget); widget->allocation = *allocation; - e_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder); + icon_entry_get_borders (widget, priv->entry, &xborder, &yborder); + + if (GTK_WIDGET_REALIZED (widget)) { + width = allocation->width - container->border_width * 2; + height = allocation->height - container->border_width * 2; - if (GTK_WIDGET_REALIZED (widget)) - { child_allocation.x = container->border_width; child_allocation.y = container->border_width; - child_allocation.width = MAX (allocation->width - container->border_width * 2, 0); - child_allocation.height = MAX (allocation->height - container->border_width * 2, 0); - - gdk_window_move_resize (widget->window, - allocation->x + child_allocation.x, - allocation->y + child_allocation.y, - child_allocation.width, - child_allocation.height); + child_allocation.width = MAX (width, 0); + child_allocation.height = MAX (height, 0); + + gdk_window_move_resize ( + widget->window, + allocation->x + child_allocation.x, + allocation->y + child_allocation.y, + child_allocation.width, + child_allocation.height); } + width = allocation->width - (container->border_width + xborder) * 2; + height = allocation->height - (container->border_width + yborder) * 2; + child_allocation.x = container->border_width + xborder; child_allocation.y = container->border_width + yborder; - child_allocation.width = MAX (allocation->width - (container->border_width + xborder) * 2, 0); - child_allocation.height = MAX (allocation->height - (container->border_width + yborder) * 2, 0); + child_allocation.width = MAX (width, 0); + child_allocation.height = MAX (height, 0); - gtk_widget_size_allocate (bin->child, &child_allocation); + gtk_widget_size_allocate (GTK_BIN (widget)->child, &child_allocation); } static gboolean -e_icon_entry_expose (GtkWidget *widget, - GdkEventExpose *event) +icon_entry_expose (GtkWidget *widget, + GdkEventExpose *event) { - if (GTK_WIDGET_DRAWABLE (widget) && - event->window == widget->window) - { - e_icon_entry_paint (widget, event); - } + if (GTK_WIDGET_DRAWABLE (widget) && event->window == widget->window) + icon_entry_paint (widget, event); - return parent_class->expose_event (widget, event); + /* Chain up to parent's expose() method. */ + return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); } static void -e_icon_entry_class_init (EIconEntryClass *klass) +icon_entry_class_init (EIconEntryClass *class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class; + GtkWidgetClass *widget_class; - parent_class = GTK_WIDGET_CLASS (g_type_class_peek_parent (klass)); + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EIconEntryPrivate)); - widget_class->realize = e_icon_entry_realize; - widget_class->size_request = e_icon_entry_size_request; - widget_class->size_allocate = e_icon_entry_size_allocate; - widget_class->expose_event = e_icon_entry_expose; + object_class = G_OBJECT_CLASS (class); + object_class->dispose = icon_entry_dispose; - g_type_class_add_private (object_class, sizeof (EIconEntryPrivate)); + widget_class = GTK_WIDGET_CLASS (class); + widget_class->realize = icon_entry_realize; + widget_class->size_request = icon_entry_size_request; + widget_class->size_allocate = icon_entry_size_allocate; + widget_class->expose_event = icon_entry_expose; +} + +static void +icon_entry_init (EIconEntry *icon_entry) +{ + GtkWidget *widget; + GtkWidget *container; + + icon_entry->priv = E_ICON_ENTRY_GET_PRIVATE (icon_entry); + + GTK_WIDGET_UNSET_FLAGS (icon_entry, GTK_NO_WINDOW); + + widget = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (icon_entry), widget); + icon_entry->priv->hbox = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_entry_new (); + gtk_entry_set_has_frame (GTK_ENTRY (widget), FALSE); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + icon_entry->priv->entry = g_object_ref (widget); + gtk_widget_show (widget); + + /* We need to queue a redraw when focus changes, to comply with + * themes (like Clearlooks) which draw focused and unfocused + * entries differently. */ + g_signal_connect_after ( + widget, "focus-in-event", + G_CALLBACK (icon_entry_focus_change_cb), icon_entry); + g_signal_connect_after ( + widget, "focus-out-event", + G_CALLBACK (icon_entry_focus_change_cb), icon_entry); } GType @@ -293,92 +375,67 @@ e_icon_entry_get_type (void) if (G_UNLIKELY (type == 0)) { - static const GTypeInfo our_info = - { + static const GTypeInfo type_info = { sizeof (EIconEntryClass), - NULL, - NULL, - (GClassInitFunc) e_icon_entry_class_init, - NULL, - NULL, + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) icon_entry_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ sizeof (EIconEntry), - 0, - (GInstanceInitFunc) e_icon_entry_init + 0, /* n_preallocs */ + (GInstanceInitFunc) icon_entry_init, + NULL /* value_table */ }; - type = g_type_register_static (GTK_TYPE_BIN, - "EIconEntry", - &our_info, 0); + type = g_type_register_static ( + GTK_TYPE_BIN, "EIconEntry", &type_info, 0); } return type; } -/* public functions */ - GtkWidget * e_icon_entry_new (void) { return GTK_WIDGET (g_object_new (E_TYPE_ICON_ENTRY, NULL)); } -void -e_icon_entry_pack_widget (EIconEntry *entry, - GtkWidget *widget, - gboolean start) +GtkWidget * +e_icon_entry_get_entry (EIconEntry *icon_entry) { - EIconEntryPrivate *priv; - - g_return_if_fail (E_IS_ICON_ENTRY (entry)); - - priv = entry->priv; + g_return_val_if_fail (E_IS_ICON_ENTRY (icon_entry), NULL); - if (start) - { - gtk_box_pack_start (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2); - gtk_box_reorder_child (GTK_BOX (priv->hbox), widget, 0); - } - else - { - gtk_box_pack_end (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2); - } + return icon_entry->priv->entry; } -static void -set_cursor (GtkWidget *widget, GdkEventCrossing *event, gpointer dummy) +void +e_icon_entry_add_action_start (EIconEntry *icon_entry, + GtkAction *action) { + GtkWidget *proxy; + GtkBox *box; - if (event->type == GDK_ENTER_NOTIFY) - gdk_window_set_cursor (widget->window, gdk_cursor_new (GDK_HAND1)); - else - gdk_window_set_cursor (widget->window, gdk_cursor_new (GDK_LEFT_PTR)); - + g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); + g_return_if_fail (GTK_IS_ACTION (action)); + box = GTK_BOX (icon_entry->priv->hbox); + proxy = icon_entry_create_proxy (action); + gtk_box_pack_start (box, proxy, FALSE, FALSE, 2); + gtk_box_reorder_child (box, proxy, 0); } -GtkWidget * -e_icon_entry_create_button (const char *stock) +void +e_icon_entry_add_action_end (EIconEntry *icon_entry, + GtkAction *action) { - GtkWidget *eventbox; - GtkWidget *image; - - eventbox = gtk_event_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (eventbox), 2); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (eventbox), FALSE); + GtkWidget *proxy; + GtkBox *box; - image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (eventbox), image); - - g_signal_connect_after (eventbox, "enter-notify-event", (GCallback) set_cursor, NULL); - g_signal_connect_after (eventbox, "leave-notify-event", (GCallback) set_cursor, NULL); - - return eventbox; -} - -GtkWidget * -e_icon_entry_get_entry (EIconEntry *entry) -{ - g_return_val_if_fail (E_IS_ICON_ENTRY (entry), NULL); + g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); + g_return_if_fail (GTK_IS_ACTION (action)); - return entry->entry; + box = GTK_BOX (icon_entry->priv->hbox); + proxy = icon_entry_create_proxy (action); + gtk_box_pack_end (box, proxy, FALSE, FALSE, 2); } diff --git a/widgets/misc/e-icon-entry.h b/widgets/misc/e-icon-entry.h index 894cb16c4f..110720ab19 100644 --- a/widgets/misc/e-icon-entry.h +++ b/widgets/misc/e-icon-entry.h @@ -41,44 +41,47 @@ G_BEGIN_DECLS -#define E_TYPE_ICON_ENTRY (e_icon_entry_get_type()) -#define E_ICON_ENTRY(object) (G_TYPE_CHECK_INSTANCE_CAST((object), E_TYPE_ICON_ENTRY, EIconEntry)) -#define E_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), E_TYPE_ICON_ENTRY, EIconEntryClass)) -#define E_IS_ICON_ENTRY(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), E_TYPE_ICON_ENTRY)) -#define E_IS_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), E_TYPE_ICON_ENTRY)) -#define E_ICON_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), E_TYPE_ICON_ENTRY, EIconEntryClass)) - +/* Standard GObject macros */ +#define E_TYPE_ICON_ENTRY \ + (e_icon_entry_get_type()) +#define E_ICON_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ICON_ENTRY, EIconEntry)) +#define E_ICON_ENTRY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ICON_ENTRY, EIconEntryClass)) +#define E_IS_ICON_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ICON_ENTRY)) +#define E_IS_ICON_ENTRY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ICON_ENTRY)) +#define E_ICON_ENTRY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ICON_ENTRY, EIconEntryClass)) + +typedef struct _EIconEntry EIconEntry; typedef struct _EIconEntryClass EIconEntryClass; -typedef struct _EIconEntry EIconEntry; -typedef struct _EIconEntryPrivate EIconEntryPrivate; - -struct _EIconEntryClass -{ - GtkBinClass parent_class; -}; - +typedef struct _EIconEntryPrivate EIconEntryPrivate; + struct _EIconEntry { - GtkBin parent_object; - - /*< public >*/ - GtkWidget *entry; - - /*< private >*/ + GtkBin parent; EIconEntryPrivate *priv; }; -GType e_icon_entry_get_type (void); - -GtkWidget *e_icon_entry_new (void); - -void e_icon_entry_pack_widget (EIconEntry *entry, - GtkWidget *widget, - gboolean start); - -GtkWidget *e_icon_entry_get_entry (EIconEntry *entry); +struct _EIconEntryClass +{ + GtkBinClass parent_class; +}; -GtkWidget *e_icon_entry_create_button (const char *stock); +GType e_icon_entry_get_type (void); +GtkWidget * e_icon_entry_new (void); +GtkWidget * e_icon_entry_get_entry (EIconEntry *entry); +void e_icon_entry_add_action_start (EIconEntry *entry, + GtkAction *action); +void e_icon_entry_add_action_end (EIconEntry *entry, + GtkAction *action); G_END_DECLS diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index bd8ba20072..fcfe002843 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -24,306 +24,159 @@ * Boston, MA 02110-1301, USA. */ +#include "e-search-bar.h" -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include - -#include - -#include +#include "config.h" #include #include - -#include "e-icon-entry.h" -#include "e-search-bar.h" -#include "e-util/e-util.h" -#include "e-util/e-util-marshal.h" - - -enum { - QUERY_CHANGED, - MENU_ACTIVATED, - SEARCH_ACTIVATED, - SEARCH_CLEARED, - LAST_SIGNAL +#include +#include +#include +#include + +#include +#include +#include +#include + +#define E_SEARCH_BAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate)) + +struct _ESearchBarPrivate { + GtkWidget *filter_label; + GtkWidget *filter_combo_box; + GtkWidget *search_label; + GtkWidget *search_entry; + GtkWidget *scope_label; + GtkWidget *scope_combo_box; + + GtkRadioAction *search_action; + GtkWidget *search_popup_menu; + + GtkActionGroup *action_group; }; -static gint esb_signals [LAST_SIGNAL] = { 0, }; - -static GtkHBoxClass *parent_class = NULL; - -/* The arguments we take */ enum { PROP_0, - PROP_ITEM_ID, - PROP_SUBITEM_ID, - PROP_TEXT, + PROP_FILTER_ACTION, + PROP_FILTER_VALUE, + PROP_FILTER_VISIBLE, + PROP_SEARCH_ACTION, + PROP_SEARCH_TEXT, + PROP_SEARCH_VALUE, + PROP_SEARCH_VISIBLE, + PROP_SCOPE_ACTION, + PROP_SCOPE_VALUE, + PROP_SCOPE_VISIBLE }; - -/* Forward decls. */ - -static int find_id (GtkWidget *menu, int idin, const char *type, GtkWidget **widget); - -static void emit_search_activated (ESearchBar *esb); -static void emit_query_changed (ESearchBar *esb); - - -/* Utility functions. */ - -static void -set_find_now_sensitive (ESearchBar *search_bar, - gboolean sensitive) -{ - if (search_bar->ui_component != NULL) - bonobo_ui_component_set_prop (search_bar->ui_component, - "/commands/ESearchBar:FindNow", - "sensitive", sensitive ? "1" : "0", NULL); -} +static gpointer parent_class; static void -update_clear_menuitem_sensitive (ESearchBar *search_bar) +action_search_clear_cb (GtkAction *action, + ESearchBar *search_bar) { - if (search_bar->ui_component != NULL) { - gboolean sensitive = GTK_WIDGET_SENSITIVE (search_bar->clear_button) || search_bar->viewitem_id != 0; - - bonobo_ui_component_set_prop (search_bar->ui_component, - "/commands/ESearchBar:Clear", - "sensitive", sensitive ? "1" : "0", NULL); - } + e_search_bar_set_search_text (search_bar, ""); + gtk_action_set_sensitive (action, FALSE); } static void -clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearchBar *search_bar) -{ - g_return_if_fail (clear_button != NULL && search_bar != NULL); - - update_clear_menuitem_sensitive (search_bar); -} - -static char * -verb_name_from_id (int id) +action_search_find_cb (GtkAction *action, + ESearchBar *search_bar) { - return g_strdup_printf ("ESearchBar:Activate:%d", id); + gtk_action_set_sensitive (action, FALSE); } -/* This implements the "clear" action, i.e. clears the text and then emits - * ::search_activated. */ - static void -clear_search (ESearchBar *esb) -{ - e_search_bar_set_text (esb, ""); - esb->block_search = TRUE; - if (esb->item_id < 0) - e_search_bar_set_item_id (esb, esb->last_search_option); - e_search_bar_set_viewitem_id (esb, 0); - esb->block_search = FALSE; - emit_search_activated (esb); -} +action_search_type_cb (GtkAction *action, + ESearchBar *search_bar) +{ + gtk_menu_popup ( + GTK_MENU (search_bar->priv->search_popup_menu), + NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); +} + +static GtkActionEntry search_entries[] = { + + { "search-clear", + GTK_STOCK_CLEAR, + NULL, + "q", + N_("Clear the most recent search"), + G_CALLBACK (action_search_clear_cb) }, + + { "search-find", + GTK_STOCK_FIND, + N_("_Find Now"), + NULL, + N_("Execute the search"), + G_CALLBACK (action_search_find_cb) }, + + { "search-type", + GTK_STOCK_FIND, + NULL, + NULL, + NULL, + G_CALLBACK (action_search_type_cb) } +}; static void -free_menu_items (ESearchBar *esb) +search_bar_update_search_popup (ESearchBar *search_bar) { - GSList *p; - - if (esb->menu_items == NULL) - return; + GtkAction *action; + GtkMenuShell *menu_shell; + GSList *list, *iter; - for (p = esb->menu_items; p != NULL; p = p->next) { - ESearchBarItem *item; + action = gtk_action_group_get_action ( + search_bar->priv->action_group, "search-type"); - item = (ESearchBarItem *) p->data; - - /* (No submitems for the menu_items, so no need to free that - member.) */ - - g_free (item->text); - g_free (item); + if (search_bar->priv->search_popup_menu != NULL) { + g_object_unref (search_bar->priv->search_popup_menu); + search_bar->priv->search_popup_menu = NULL; } - g_slist_free (esb->menu_items); - esb->menu_items = NULL; -} - - -/* Signals. */ - -static void -emit_query_changed (ESearchBar *esb) -{ - g_signal_emit (esb, esb_signals [QUERY_CHANGED], 0); - update_clear_menuitem_sensitive (esb); -} - -static void -emit_search_activated(ESearchBar *esb) -{ - if (esb->pending_activate) { - g_source_remove (esb->pending_activate); - esb->pending_activate = 0; + if (search_bar->priv->search_action == NULL) { + gtk_action_set_sensitive (action, FALSE); + return; } - g_signal_emit (esb, esb_signals [SEARCH_ACTIVATED], 0); - - set_find_now_sensitive (esb, FALSE); - update_clear_menuitem_sensitive (esb); -} - -static void -emit_menu_activated (ESearchBar *esb, int item) -{ - g_signal_emit (esb, - esb_signals [MENU_ACTIVATED], 0, - item); -} - - -/* Callbacks -- Standard verbs. */ - -static void -search_now_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - GtkStyle *style = gtk_widget_get_default_style (); - char *text; + search_bar->priv->search_popup_menu = gtk_menu_new (); + menu_shell = GTK_MENU_SHELL (search_bar->priv->search_popup_menu); + list = gtk_radio_action_get_group (search_bar->priv->search_action); - esb = E_SEARCH_BAR (data); - text = e_search_bar_get_text (esb); + for (iter = list; iter != NULL; iter = iter->next) { + GtkAction *action = iter->data; + GtkWidget *widget; - if (text && *text) { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - } else { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - gtk_widget_set_sensitive (esb->clear_button, FALSE); + widget = gtk_action_create_menu_item (action); + gtk_menu_shell_append (menu_shell, widget); + gtk_widget_show (widget); } - g_free (text); - emit_search_activated (esb); -} - -static void -clear_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - esb = E_SEARCH_BAR (data); - - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - gtk_widget_set_sensitive (esb->clear_button, FALSE); - - clear_search (esb); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_grab_focus (esb->entry); -} - -static void -setup_standard_verbs (ESearchBar *search_bar) -{ - bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:Clear", - clear_verb_cb, search_bar); - bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:FindNow", - search_now_verb_cb, search_bar); - - bonobo_ui_component_set (search_bar->ui_component, "/", - ("" - " " - " " - ""), - NULL); - - /* Make sure the entries are created with the correct sensitivity. */ - set_find_now_sensitive (search_bar, FALSE); - update_clear_menuitem_sensitive (search_bar); -} - -/* Callbacks -- The verbs for all the definable items. */ - -static void -search_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - const char *p; - int id; - - esb = E_SEARCH_BAR (data); - - p = strrchr (verb_name, ':'); - g_return_if_fail (p != NULL); - - id = atoi (p + 1); - - emit_menu_activated (esb, id); -} - -/* Get the selected menu item's label */ -static const gchar * -get_selected_item_label (GtkWidget *menu) -{ - GtkWidget *label, *item; - const gchar *text = NULL; - - item = gtk_menu_get_active ((GtkMenu *)menu); - label = gtk_bin_get_child ((GtkBin *)item); - - if (GTK_IS_LABEL (label)) - text = gtk_label_get_text ((GtkLabel *)label); - - return text; + gtk_action_set_sensitive (action, TRUE); } static gboolean -entry_focus_in_cb (GtkWidget *widget, - GdkEventFocus *event, - ESearchBar *esb) -{ - GtkStyle *entry_style, *default_style; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); - - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - } - - return FALSE; -} - -static gboolean -paint_search_text (GtkWidget *widget, ESearchBar *esb) +paint_search_text (GtkWidget *widget, + ESearchBar *search_bar) { +#if 0 GtkStyle *style = gtk_widget_get_default_style (); - const gchar *text = NULL; - GtkWidget *menu_widget = esb->option_menu; + const gchar *text; + GtkWidget *menu_widget = search_bar->option_menu; text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text && *text) return FALSE; - if (!GTK_WIDGET_SENSITIVE (esb->option_button)) { - menu_widget = esb->scopeoption_menu; - text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (esb->scopeoption_menu))),"string"); - } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu)))) + style = gtk_widget_get_default_style (); + + if (!GTK_WIDGET_SENSITIVE (search_bar->option_button)) { + menu_widget = search_bar->scopeoption_menu; + text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (search_bar->scopeoption_menu))),"string"); + } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (search_bar->option_menu)))) return FALSE; else /* no query in search entry .. so set the current option */ text = get_selected_item_label (menu_widget); @@ -332,1263 +185,894 @@ paint_search_text (GtkWidget *widget, ESearchBar *esb) if (text && *text) { gchar *t; - if (!GTK_WIDGET_HAS_FOCUS(esb->entry)) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), text); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE])); + if (!GTK_WIDGET_HAS_FOCUS(search_bar->entry)) { + gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text); + gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE])); } t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type")); - gtk_widget_set_tooltip_text (esb->option_button, t); + gtk_widget_set_tooltip_text (search_bar->option_button, t); g_free (t); - gtk_widget_set_sensitive (esb->clear_button, FALSE); + gtk_widget_set_sensitive (search_bar->clear_button, FALSE); } + return FALSE; +#endif + return FALSE; } void e_search_bar_paint (ESearchBar *search_bar) { - paint_search_text (search_bar->entry, search_bar); -} + EIconEntry *icon_entry; + GtkWidget *entry; -static gboolean -entry_focus_out_cb (GtkWidget *widget, - GdkEventFocus *event, - ESearchBar *esb) -{ - return paint_search_text (widget, esb); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); + paint_search_text (entry, search_bar); } static void -entry_activated_cb (GtkWidget *widget, - ESearchBar *esb) +search_bar_entry_activated_cb (ESearchBar *search_bar, + GtkWidget *entry) { - const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); - GtkStyle *style = gtk_widget_get_default_style (); + GtkStyle *style; + GtkAction *action; + GtkActionGroup *action_group; + gboolean sensitive; + const gchar *text; - if (text && *text) { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - } else { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - gtk_widget_set_sensitive (esb->clear_button, FALSE); - } - - emit_search_activated (esb); -} - -static void -entry_changed_cb (GtkWidget *widget, - ESearchBar *esb) -{ - const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); - GtkStyle *entry_style, *default_style; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); + style = gtk_widget_get_default_style (); + text = gtk_entry_get_text (GTK_ENTRY (entry)); + action_group = e_search_bar_get_action_group (search_bar); if (text && *text) { - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) - gtk_widget_set_sensitive (esb->clear_button, FALSE); - else - gtk_widget_set_sensitive (esb->clear_button, TRUE); + gtk_widget_modify_base ( + entry, GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text ( + entry, GTK_STATE_NORMAL, + &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base ( + search_bar->priv->search_entry, + GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_base ( + search_bar->priv->filter_combo_box, + GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + sensitive = TRUE; } else { - /* selected color means some search text is active */ - gtk_widget_set_sensitive (esb->clear_button, gdk_color_equal (&(entry_style->base[GTK_STATE_NORMAL]), &(default_style->base[GTK_STATE_SELECTED]))); + gtk_widget_modify_base ( + entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text ( + entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base ( + search_bar->priv->search_entry, + GTK_STATE_NORMAL, NULL); + sensitive = FALSE; } -} -static void -viewitem_activated_cb(GtkWidget *widget, ESearchBar *esb) -{ - gint viewid; - GtkStyle *entry_style, *default_style; - - widget = gtk_menu_get_active (GTK_MENU (esb->viewoption_menu)); - - viewid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); - esb->viewitem_id = viewid; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); - - /* If the text is grayed, Its not the query string */ - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - } + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + gtk_action_set_sensitive (action, sensitive); - esb->block_search = TRUE; - emit_search_activated (esb); - esb->block_search = FALSE; + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_FIND); + gtk_action_activate (action); } static void -scopeitem_activated_cb(GtkWidget *widget, ESearchBar *esb) -{ - gint scopeid; - GtkStyle *entry_style, *default_style; - - widget = gtk_menu_get_active (GTK_MENU (esb->scopeoption_menu)); - - scopeid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); - esb->scopeitem_id = scopeid; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); - - /* If the text is grayed, Its not the query string */ - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_widget_grab_focus (esb->entry); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); +search_bar_entry_changed_cb (ESearchBar *search_bar, + GtkWidget *entry) +{ + GtkActionGroup *action_group; + GtkAction *action; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; + gboolean sensitive; + const gchar *text; + + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); + + text = gtk_entry_get_text (GTK_ENTRY (entry)); + + if (text != NULL && *text != '\0') { + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; + sensitive = !gdk_color_equal (color1, color2); + } else { + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_SELECTED]; + sensitive = gdk_color_equal (color1, color2); } - esb->block_search = TRUE; - emit_search_activated (esb); - esb->block_search = FALSE; + action_group = search_bar->priv->action_group; + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + gtk_action_set_sensitive (action, sensitive); } -static void -option_activated_cb (GtkWidget *widget, - ESearchBar *esb) +static gboolean +search_bar_entry_focus_in_cb (ESearchBar *search_bar, + GdkEventFocus *event, + GtkWidget *entry) { - int id; - const char *text; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; - id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); - e_search_bar_set_item_id (esb, id); + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; - if (GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu)))) { - gchar *t; - text = get_selected_item_label (esb->option_menu); - if (text && *text) - t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type")); - else - t = g_strdup_printf ("%s: %s", _("Search"), _("Click here to change the search type")); - - gtk_widget_set_tooltip_text (esb->option_button, t); - g_free (t); + if (gdk_color_equal (color1, color2)) { + gtk_entry_set_text (GTK_ENTRY (entry), ""); + gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL); } - if (!esb->block_search) { - emit_query_changed (esb); - } - if (!esb->block_search && id > 0) { - emit_search_activated (esb); - } -} - -static void -option_button_clicked_cb (GtkWidget *widget, GdkEventButton *event, - ESearchBar *esb) -{ - gtk_menu_popup (GTK_MENU (esb->option_menu), NULL, NULL, NULL, NULL,1,gtk_get_current_event_time()); - - gtk_widget_grab_focus (esb->entry); -} - -static void -clear_button_clicked_cb (GtkWidget *widget, GdkEventButton *event, - ESearchBar *esb) -{ - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - gtk_widget_set_sensitive (esb->clear_button, FALSE); - - clear_search (esb); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_grab_focus (esb->entry); + return FALSE; } static gboolean -entry_key_press_cb (GtkWidget *widget, - GdkEventKey *key_event, - ESearchBar *esb) +search_bar_entry_focus_out_cb (ESearchBar *search_bar, + GdkEventFocus *event, + GtkWidget *entry) { - if (((key_event->state & gtk_accelerator_get_default_mod_mask ()) == - GDK_MOD1_MASK) && (key_event->keyval == GDK_Down)) { - option_button_clicked_cb (NULL, NULL, esb); - return TRUE; - } - - return FALSE; + return paint_search_text (entry, search_bar); } -#if 0 -static void -scopeoption_changed_cb (GtkWidget *option_menu, ESearchBar *search_bar) +static gboolean +search_bar_entry_key_press_cb (ESearchBar *search_bar, + GdkEventKey *key_event, + GtkWidget *entry) { - char *text = NULL; - - text = e_search_bar_get_text (search_bar); - if (!(text && *text)) - gtk_widget_grab_focus (search_bar->entry); - - if(!search_bar->block_search) - emit_query_changed (search_bar); + guint state; - g_free (text); -} +#if 0 /* FIXME */ + state = key_event->state & gtk_accelerator_get_default_mod_mask (); + if (state == GDK_MOD1_MASK && key_event->keyval == GDK_Down) { + search_bar_option_clicked_cb (search_bar, NULL, NULL); + return TRUE; + } #endif - -/* Widgetry creation. */ -#if 0 -/* This function exists to fix the irreparable GtkOptionMenu stupidity. In - fact, this lame-ass widget adds a 1-pixel-wide empty border around the - button for no reason. So we have add a 1-pixel-wide border around the the - buttons we have in the search bar to make things look right. This is done - through an event box. */ -static GtkWidget * -put_in_spacer_widget (GtkWidget *widget) -{ - GtkWidget *holder; - - holder = gtk_event_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (holder), 1); - gtk_container_add (GTK_CONTAINER (holder), widget); - - return holder; + return FALSE; } -#endif static void -append_xml_menu_item (GString *xml, - const char *name, - const char *label, - const char *stock, - const char *verb, - const char *accelerator) -{ - char *encoded_label; - - encoded_label = bonobo_ui_util_encode_str (label); - g_string_append_printf (xml, ""); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -remove_bonobo_menus (ESearchBar *esb) -{ - if (bonobo_ui_component_get_container (esb->ui_component) == CORBA_OBJECT_NIL) - return; +search_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_FILTER_ACTION: + g_value_set_object ( + value, e_search_bar_get_filter_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_FILTER_VALUE: + g_value_set_int ( + value, e_search_bar_get_filter_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_FILTER_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_filter_visible ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_ACTION: + g_value_set_object ( + value, e_search_bar_get_search_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_TEXT: + g_value_set_string ( + value, e_search_bar_get_search_text ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_VALUE: + g_value_set_int ( + value, e_search_bar_get_search_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_search_visible ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_ACTION: + g_value_set_object ( + value, e_search_bar_get_scope_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_VALUE: + g_value_set_int ( + value, e_search_bar_get_scope_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_scope_visible ( + E_SEARCH_BAR (object))); + return; + } - bonobo_ui_component_rm (esb->ui_component, "/menu/SearchPlaceholder", NULL); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -setup_bonobo_menus (ESearchBar *esb) +search_bar_dispose (GObject *object) { - GString *xml; - GSList *p; - char *verb_name; - char *encoded_title; - - xml = g_string_new (""); - - encoded_title = bonobo_ui_util_encode_str (_("_Search")); - g_string_append_printf (xml, "", encoded_title); - g_free (encoded_title); - - g_string_append (xml, ""); - - append_xml_menu_item (xml, "FindNow", _("_Find Now"), "gtk-find", "ESearchBar:FindNow", NULL); - append_xml_menu_item (xml, "Clear", _("_Clear"), "gtk-clear", "ESearchBar:Clear", "*Control**Shift*q"); + ESearchBarPrivate *priv; - for (p = esb->menu_items; p != NULL; p = p->next) { - const ESearchBarItem *item; + priv = E_SEARCH_BAR_GET_PRIVATE (object); - item = (const ESearchBarItem *) p->data; - - verb_name = verb_name_from_id (item->id); - bonobo_ui_component_add_verb (esb->ui_component, verb_name, search_verb_cb, esb); - - if (item->text == NULL) - g_string_append (xml, ""); - else - append_xml_menu_item (xml, verb_name, item->text, NULL, verb_name, NULL); - - g_free (verb_name); + if (priv->filter_label != NULL) { + g_object_unref (priv->filter_label); + priv->filter_label = NULL; } - g_string_append (xml, ""); - g_string_append (xml, ""); - - remove_bonobo_menus (esb); - bonobo_ui_component_set (esb->ui_component, "/menu/SearchPlaceholder", xml->str, NULL); - - g_string_free (xml, TRUE); - - if (esb->clear_button) { - g_signal_connect (esb->clear_button, "state-changed", G_CALLBACK (clear_button_state_changed), esb); + if (priv->filter_combo_box != NULL) { + g_object_unref (priv->filter_combo_box); + priv->filter_combo_box = NULL; } -} - -static void -update_bonobo_menus (ESearchBar *esb) -{ - setup_bonobo_menus (esb); -} -static void -set_menu (ESearchBar *esb, - ESearchBarItem *items) -{ - int i; - - free_menu_items (esb); - - if (items == NULL) - return; - - for (i = 0; items[i].id != -1; i++) { - ESearchBarItem *new_item; - - new_item = g_new (ESearchBarItem, 1); - new_item->text = items[i].text ? g_strdup (_(items[i].text)) : NULL; - new_item->id = items[i].id; - new_item->type = items[i].type; - - esb->menu_items = g_slist_append (esb->menu_items, new_item); + if (priv->search_label != NULL) { + g_object_unref (priv->search_label); + priv->search_label = NULL; } - if (esb->ui_component != NULL) - update_bonobo_menus (esb); -} - -/* /\* Callback used when an option item is destroyed. We have to destroy its */ -/* * suboption items. */ -/* *\/ */ -/* static void */ -/* option_item_destroy_cb (GtkObject *object, gpointer data) */ -/* { */ -/* /\* ESearchBarSubitem *subitems; *\/ */ - -/* /\* subitems = data; *\/ */ - -/* /\* g_assert (subitems != NULL); *\/ */ -/* /\* free_subitems (subitems); *\/ */ -/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */ -/* } */ - -static void -set_option (ESearchBar *esb, ESearchBarItem *items) -{ - GtkWidget *menu; - GSList *group = NULL; - int i; - - if (esb->option_menu) - gtk_widget_destroy (esb->option_menu); - - esb->option_menu = menu = gtk_menu_new (); - for (i = 0; items[i].id != -1; i++) { - GtkWidget *item; - - /* Create a new group */ - if (items[i].id == 0) - group = NULL; - - if (items[i].text) { - char *str; - str = e_str_without_underscores (_(items[i].text)); - switch (items[i].type) { - case ESB_ITEMTYPE_NORMAL: - item = gtk_menu_item_new_with_label (str); - break; - case ESB_ITEMTYPE_CHECK: - item = gtk_check_menu_item_new_with_label (str); - break; - case ESB_ITEMTYPE_RADIO: - item = gtk_radio_menu_item_new_with_label (group, str); - group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); - break; - default: - /* Fixme : this should be a normal item */ - item = gtk_radio_menu_item_new_with_label (group, str); - group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); - break; - } - g_free (str); - } else { - item = gtk_menu_item_new (); - gtk_widget_set_sensitive (item, FALSE); - } - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + if (priv->search_entry != NULL) { + g_object_unref (priv->search_entry); + priv->search_entry = NULL; + } - g_object_set_data (G_OBJECT (item), "EsbItemId", GINT_TO_POINTER(items[i].id)); + if (priv->scope_label != NULL) { + g_object_unref (priv->scope_label); + priv->scope_label = NULL; + } - g_signal_connect (item, "activate", - G_CALLBACK (option_activated_cb), - esb); + if (priv->scope_combo_box != NULL) { + g_object_unref (priv->scope_combo_box); + priv->scope_combo_box = NULL; } - gtk_widget_show_all (menu); - g_object_set_data (G_OBJECT(esb->option_menu), "group", group); - entry_focus_out_cb (esb->entry, NULL, esb); -} + if (priv->search_action != NULL) { + g_object_unref (priv->search_action); + priv->search_action = NULL; + } -static int -find_id (GtkWidget *menu, int idin, const char *type, GtkWidget **widget) -{ - GList *l = GTK_MENU_SHELL (menu)->children; - int row = -1, i = 0, id; - - if (widget) - *widget = NULL; - while (l) { - id = GPOINTER_TO_INT (g_object_get_data (l->data, type)); - if (id == idin) { - row = i; - if (widget) - *widget = l->data; - break; - } - i++; - l = l->next; + if (priv->action_group != NULL) { + g_object_unref (priv->action_group); + priv->action_group = NULL; } - return row; -} - -/* GtkObject methods. */ + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} static void -impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +search_bar_class_init (ESearchBarClass *class) { - ESearchBar *esb = E_SEARCH_BAR (object); - - switch (prop_id) { - case PROP_ITEM_ID: - g_value_set_int (value, e_search_bar_get_item_id (esb)); - break; - - case PROP_TEXT: - g_value_take_string (value, e_search_bar_get_text (esb)); - break; + GObjectClass *object_class; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESearchBarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = search_bar_set_property; + object_class->get_property = search_bar_get_property; + object_class->dispose = search_bar_dispose; + + g_object_class_install_property ( + object_class, + PROP_FILTER_ACTION, + g_param_spec_object ( + "filter-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VALUE, + g_param_spec_int ( + "filter-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VISIBLE, + g_param_spec_boolean ( + "filter-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_ACTION, + g_param_spec_object ( + "search-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_TEXT, + g_param_spec_string ( + "search-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VALUE, + g_param_spec_int ( + "search-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VISIBLE, + g_param_spec_boolean ( + "search-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_ACTION, + g_param_spec_object ( + "scope-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VALUE, + g_param_spec_int ( + "scope-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VISIBLE, + g_param_spec_boolean ( + "scope-visible", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); } static void -impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +search_bar_init (ESearchBar *search_bar) { - ESearchBar *esb = E_SEARCH_BAR(object); + EIconEntry *icon_entry; + GtkActionGroup *action_group; + GtkAction *action; + GtkLabel *label; + GtkWidget *mnemonic; + GtkWidget *widget; - switch (prop_id) { - case PROP_ITEM_ID: - e_search_bar_set_item_id (esb, g_value_get_int (value)); - break; + search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar); - case PROP_TEXT: - e_search_bar_set_text (esb, g_value_get_string (value)); - break; + gtk_box_set_spacing (GTK_BOX (search_bar), 3); + gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE); - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + /*** Filter Widgets ***/ + + /* Translators: The "Show: " label is followed by the Quick Search + * Dropdown Menu where you can choose to display "All Messages", + * "Unread Messages", "Message with 'Important' Label" and so on... */ + widget = gtk_label_new_with_mnemonic (_("Sho_w: ")); + gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->filter_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_action_combo_box_new (); + gtk_label_set_mnemonic_widget (label, widget); + gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, TRUE, 0); + search_bar->priv->filter_combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + /*** Scope Widgets ***/ + + widget = e_action_combo_box_new (); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->scope_combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + mnemonic = widget; + + /* Translators: The " in " label is part of the Quick Search Bar, + * example: Search: [_________________] in [ Current Folder ] */ + widget = gtk_label_new_with_mnemonic (_(" i_n ")); + gtk_label_set_mnemonic_widget (GTK_LABEL (widget), mnemonic); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->scope_label = g_object_ref (widget); + gtk_widget_show (widget); + + /*** Search Widgets ***/ + + widget = e_icon_entry_new (); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->search_entry = g_object_ref (widget); + gtk_widget_show (widget); + + icon_entry = E_ICON_ENTRY (widget); + + /* Translators: The "Search: " label is followed by the Quick Search + * Text input field where one enters the term to search for. */ + widget = gtk_label_new_with_mnemonic (_("Sear_ch: ")); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->search_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_icon_entry_get_entry (icon_entry); + gtk_label_set_mnemonic_widget (label, widget); + g_signal_connect_swapped ( + widget, "activate", + G_CALLBACK (search_bar_entry_activated_cb), search_bar); + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (search_bar_entry_changed_cb), search_bar); + g_signal_connect_swapped ( + widget, "focus-in-event", + G_CALLBACK (search_bar_entry_focus_in_cb), search_bar); + g_signal_connect_swapped ( + widget, "focus-out-event", + G_CALLBACK (search_bar_entry_focus_out_cb), search_bar); + g_signal_connect_swapped ( + widget, "key-press-event", + G_CALLBACK (search_bar_entry_key_press_cb), search_bar); + + action_group = gtk_action_group_new ("search"); + gtk_action_group_set_translation_domain ( + action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions ( + action_group, search_entries, + G_N_ELEMENTS (search_entries), search_bar); + search_bar->priv->action_group = action_group; + + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_TYPE); + e_icon_entry_add_action_start (icon_entry, action); + gtk_action_set_sensitive (action, FALSE); + + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + e_icon_entry_add_action_end (icon_entry, action); + gtk_action_set_sensitive (action, FALSE); } -static void -impl_dispose (GObject *object) +GType +e_search_bar_get_type (void) { - ESearchBar *esb = E_SEARCH_BAR (object); - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (object)); - - /* These three we do need to unref, because we explicitly hold - references to them. */ + static GType type = 0; - if (esb->ui_component != NULL) { - bonobo_object_unref (BONOBO_OBJECT (esb->ui_component)); - esb->ui_component = NULL; - } -/* if (esb->entry) { */ -/* g_object_unref (esb->entry); */ -/* esb->entry = NULL; */ -/* } */ - if (esb->suboption) { - g_object_unref (esb->suboption); - esb->suboption = NULL; - } + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESearchBarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) search_bar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESearchBar), + 0, /* n_preallocs */ + (GInstanceInitFunc) search_bar_init, + NULL /* value_table */ + }; - if (esb->pending_activate) { - g_source_remove (esb->pending_activate); - esb->pending_activate = 0; + type = g_type_register_static ( + GTK_TYPE_HBOX, "ESearchBar", &type_info, 0); } - free_menu_items (esb); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); + return type; } - -static void -class_init (ESearchBarClass *klass) +GtkWidget * +e_search_bar_new (void) { - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (gtk_hbox_get_type ()); - - object_class->set_property = impl_set_property; - object_class->get_property = impl_get_property; - object_class->dispose = impl_dispose; - - klass->set_menu = set_menu; - klass->set_option = set_option; - - g_object_class_install_property (object_class, PROP_ITEM_ID, - g_param_spec_int ("item_id", - _("Item ID"), - /*_( */"XXX blurb" /*)*/, - 0, 0, 0, - G_PARAM_READWRITE | G_PARAM_LAX_VALIDATION)); - - g_object_class_install_property (object_class, PROP_TEXT, - g_param_spec_string ("text", - _("Text"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - esb_signals [QUERY_CHANGED] = - g_signal_new ("query_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, query_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - esb_signals [MENU_ACTIVATED] = - g_signal_new ("menu_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, menu_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - esb_signals [SEARCH_ACTIVATED] = - g_signal_new ("search_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, search_activated), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - esb_signals [SEARCH_CLEARED] = - g_signal_new ("search_cleared", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, search_cleared), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + return g_object_new (E_TYPE_SEARCH_BAR, NULL); } -static void -init (ESearchBar *esb) +GtkActionGroup * +e_search_bar_get_action_group (ESearchBar *search_bar) { - esb->ui_component = NULL; - esb->menu_items = NULL; - - esb->option = NULL; - esb->entry = NULL; - esb->suboption = NULL; - - esb->option_menu = NULL; - esb->suboption_menu = NULL; - esb->option_button = NULL; - esb->clear_button = NULL; - esb->entry_box = NULL; - - esb->scopeoption_menu = NULL; - esb->scopeoption = NULL; - esb->scopeoption_box = NULL; - - esb->pending_activate = 0; - - esb->item_id = 0; - esb->scopeitem_id = 0; - esb->last_search_option = 0; - esb->block_search = FALSE; -} - - -/* Object construction. */ + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); -static gint -idle_activate_hack (gpointer ptr) -{ - ESearchBar *esb = E_SEARCH_BAR (ptr); - esb->pending_activate = 0; - emit_search_activated (esb); - return FALSE; + return search_bar->priv->action_group; } -void -e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items) +GtkRadioAction * +e_search_bar_get_filter_action (ESearchBar *search_bar) { - GtkWidget *label, *hbox, *bighbox; - - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (option_items != NULL); + EActionComboBox *combo_box; - gtk_box_set_spacing (GTK_BOX (search_bar), 3); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - bighbox = gtk_hbox_new (FALSE, 0); - search_bar->entry_box = gtk_hbox_new (0, FALSE); - search_bar->icon_entry = e_icon_entry_new (); - search_bar->entry = e_icon_entry_get_entry (E_ICON_ENTRY (search_bar->icon_entry)); - - g_signal_connect (search_bar->entry, "changed", - G_CALLBACK (entry_changed_cb), search_bar); - g_signal_connect (search_bar->entry, "activate", - G_CALLBACK (entry_activated_cb), search_bar); - g_signal_connect (search_bar->entry, "focus-in-event", - G_CALLBACK (entry_focus_in_cb), search_bar); - g_signal_connect (search_bar->entry, "focus-out-event", - G_CALLBACK (entry_focus_out_cb), search_bar); - g_signal_connect (search_bar->entry, "key-press-event", - G_CALLBACK (entry_key_press_cb), search_bar); - - search_bar->clear_button = e_icon_entry_create_button ("gtk-clear"); - g_signal_connect (G_OBJECT (search_bar->clear_button), "button-press-event", G_CALLBACK(clear_button_clicked_cb), search_bar); - e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->clear_button, FALSE); - - search_bar->option_button = e_icon_entry_create_button ("gtk-find"); - g_signal_connect (G_OBJECT (search_bar->option_button), "button-press-event", G_CALLBACK(option_button_clicked_cb), search_bar); - e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->option_button, TRUE); - - gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, FALSE, FALSE, 0); - - gtk_widget_show_all (search_bar->entry_box); - gtk_widget_set_sensitive (search_bar->clear_button, FALSE); - - /* Current View filter */ - search_bar->viewoption_box = gtk_hbox_new (0, FALSE); - - /* To Translators: The "Show: " label is followed by the Quick Search Dropdown Menu where you can choose - to display "All Messages", "Unread Messages", "Message with 'Important' Label" and so on... */ - label = gtk_label_new_with_mnemonic (_("Sho_w: ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), label, FALSE, FALSE, 0); - - search_bar->viewoption = gtk_option_menu_new (); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->viewoption); - gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), search_bar->viewoption, FALSE, TRUE, 0); - gtk_widget_show_all (search_bar->viewoption_box); - gtk_box_pack_start (GTK_BOX(search_bar), search_bar->viewoption_box, FALSE, FALSE, 0); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); - - /* Search entry */ - hbox = gtk_hbox_new (FALSE, 0); - /* To Translators: The "Show: " label is followed by the Quick Search Text input field where one enters - the term to search for */ - label = gtk_label_new_with_mnemonic (_("Sear_ch: ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, FALSE, FALSE, 0); - gtk_widget_show (search_bar->entry_box); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->entry); - - /* Search Scope Widgets */ - search_bar->scopeoption_box = gtk_hbox_new (0, FALSE); - gtk_box_set_spacing (GTK_BOX (search_bar->scopeoption_box), 3); - /* To Translators: The " in " label is part of the Quick Search Bar, example: - Search: | | in | Current Folder/All Accounts/Current Account */ - label = gtk_label_new_with_mnemonic (_(" i_n ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0); - - search_bar->scopeoption = gtk_option_menu_new (); -/* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ - gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0); - gtk_widget_show_all (search_bar->scopeoption_box); - gtk_widget_hide (hbox); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->scopeoption); - - gtk_box_pack_end (GTK_BOX(hbox), search_bar->scopeoption_box, FALSE, FALSE, 0); - gtk_widget_hide (search_bar->scopeoption_box); - - gtk_box_pack_end (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - /* Set the menu */ - e_search_bar_set_menu (search_bar, menu_items); - e_search_bar_set_option (search_bar, option_items); - - /* - * If the default choice for the option menu has subitems, then we need to - * activate the search immediately. However, the developer won't have - * connected to the activated signal until after the object is constructed, - * so we can't emit here. Thus we launch a one-shot idle function that will - * emit the changed signal, so that the proper callback will get invoked. - */ - - search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar); + return e_action_combo_box_get_action (combo_box); } void -e_search_bar_set_menu (ESearchBar *search_bar, ESearchBarItem *menu_items) +e_search_bar_set_filter_action (ESearchBar *search_bar, + GtkRadioAction *action) { - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + EActionComboBox *combo_box; - ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_menu (search_bar, menu_items); -} - -void -e_search_bar_add_menu (ESearchBar *search_bar, ESearchBarItem *menu_item) -{ - g_return_if_fail (search_bar != NULL); g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - set_menu (search_bar, menu_item); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); + + e_action_combo_box_set_action (combo_box, action); + g_object_notify (G_OBJECT (search_bar), "filter-action"); } -void -e_search_bar_set_option (ESearchBar *search_bar, ESearchBarItem *option_items) +gint +e_search_bar_get_filter_value (ESearchBar *search_bar) { - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (option_items != NULL); + EActionComboBox *combo_box; - ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_option (search_bar, option_items); -} + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); -void -e_search_bar_set_viewoption_menufunc (ESearchBar *search_bar, ESearchBarMenuFunc *menu_gen_func, void *data) -{ - g_signal_connect (search_bar->viewoption, "button_press_event", G_CALLBACK (menu_gen_func), data); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); + + return e_action_combo_box_get_current_value (combo_box); } -/** - * e_search_bar_set_viewoption_menu: - * @search_bar: A search bar. - * @option_id: Identifier of the main option menu item under which the subitems - * are to be set. - * @subitems: Array of subitem information. - * - * Sets the items for the secondary option menu of a search bar. - **/ void -e_search_bar_set_viewoption_menu (ESearchBar *search_bar, GtkWidget *menu) +e_search_bar_set_filter_value (ESearchBar *search_bar, + gint value) { + EActionComboBox *combo_box; - if (search_bar->viewoption_menu != NULL) - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption)); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - search_bar->viewoption_menu = menu; - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), search_bar->viewoption_menu); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - g_signal_connect (search_bar->viewoption_menu, - "selection-done", - G_CALLBACK (viewitem_activated_cb), - search_bar); + e_action_combo_box_set_current_value (combo_box, value); + g_object_notify (G_OBJECT (search_bar), "filter-value"); } -GtkWidget * -e_search_bar_get_selected_viewitem (ESearchBar *search_bar) +gboolean +e_search_bar_get_filter_visible (ESearchBar *search_bar) { - GtkWidget *widget = NULL; - - widget = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu)); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - return widget; + return GTK_WIDGET_VISIBLE (search_bar->priv->filter_combo_box); } -/** - * e_search_bar_set_viewoption: - * @search_bar: A search bar. - * @option_id: Identifier of the main option menu item under which the subitems - * are to be set. - * @subitems: Array of subitem information. - * - * Sets the items for the secondary option menu of a search bar. - **/ void -e_search_bar_set_viewoption (ESearchBar *search_bar, int option_id, ESearchBarItem *subitems) +e_search_bar_set_filter_visible (ESearchBar *search_bar, + gboolean visible) { - GtkWidget *menu; - GtkWidget *menu_item; - gint i; - - /* Create the menu if it is not there. right scenario ????*/ + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - if (search_bar->viewoption_menu == NULL) { - search_bar->viewoption_menu = menu = gtk_menu_new (); + if (visible) { + gtk_widget_show (search_bar->priv->filter_label); + gtk_widget_show (search_bar->priv->filter_combo_box); } else { - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption)); - search_bar->viewoption_menu = menu = gtk_menu_new (); + gtk_widget_hide (search_bar->priv->filter_label); + gtk_widget_hide (search_bar->priv->filter_combo_box); } - /* Create the items */ - - for (i = 0; subitems[i].id != -1; ++i) { - if (subitems[i].text) { - char *str = NULL; - str = e_str_without_underscores (subitems[i].text); - menu_item = gtk_menu_item_new_with_label (str); - g_free (str); - } else { - menu_item = gtk_menu_item_new (); - gtk_widget_set_sensitive (menu_item, FALSE); - } - - g_object_set_data (G_OBJECT (menu_item), "EsbItemId", - GINT_TO_POINTER (subitems[i].id)); - - g_signal_connect (menu_item, - "activate", - G_CALLBACK (viewitem_activated_cb), - search_bar); - - gtk_widget_show (menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), menu); - + g_object_notify (G_OBJECT (search_bar), "filter-visible"); } -/** - * e_search_bar_set_scopeoption: - * @search_bar: A search bar. - * are to be set. - * @scopeitems: Array of scope information. - * - * Sets the items for the search scope option menu of a search bar. - **/ -void -e_search_bar_set_scopeoption (ESearchBar *search_bar, ESearchBarItem *scopeitems) +GtkRadioAction * +e_search_bar_get_search_action (ESearchBar *search_bar) { - GtkWidget *menu; - GtkWidget *menu_item; - gint i; - - gtk_widget_show (search_bar->scopeoption_box); - if (search_bar->scopeoption_menu != NULL) { - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption)); - } - - search_bar->scopeoption_menu = menu = gtk_menu_new (); - - /* Generate items */ - for (i = 0; scopeitems[i].id != -1; ++i) { - if (scopeitems[i].text) { - char *str; - str = e_str_without_underscores (_(scopeitems[i].text)); - menu_item = gtk_menu_item_new_with_label (str); - g_object_set_data_full (G_OBJECT (menu_item), "string",str, g_free); - } else { - menu_item = gtk_menu_item_new (); - gtk_widget_set_sensitive (menu_item, FALSE); - } - - g_object_set_data (G_OBJECT (menu_item), "EsbItemId", - GINT_TO_POINTER (scopeitems[i].id)); - - g_signal_connect (menu_item, - "activate", - G_CALLBACK (scopeitem_activated_cb), - search_bar); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - gtk_widget_show (menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), menu); + return search_bar->priv->search_action; } -/** - * e_search_bar_set_scopeoption_menu: - * @search_bar: A search bar. - * @menu: the scope option menu - * - * Sets the items for the secondary option menu of a search bar. - **/ void -e_search_bar_set_scopeoption_menu (ESearchBar *search_bar, GtkMenu *menu) +e_search_bar_set_search_action (ESearchBar *search_bar, + GtkRadioAction *action) { + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - if (search_bar->scopeoption_menu != NULL) - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption)); + if (action != NULL) { + g_return_if_fail (GTK_IS_RADIO_ACTION (action)); + g_object_ref (action); + } - search_bar->scopeoption_menu = GTK_WIDGET (menu); - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), search_bar->scopeoption_menu); + search_bar->priv->search_action = action; + search_bar_update_search_popup (search_bar); - g_signal_connect (search_bar->scopeoption_menu, - "selection-done", - G_CALLBACK (scopeitem_activated_cb), - search_bar); + g_object_notify (G_OBJECT (search_bar), "search-action"); } -GtkWidget * -e_search_bar_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items) +const gchar * +e_search_bar_get_search_text (ESearchBar *search_bar) { - GtkWidget *widget; + EIconEntry *icon_entry; + GtkWidget *entry; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; - g_return_val_if_fail (option_items != NULL, NULL); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - widget = g_object_new (e_search_bar_get_type (), NULL); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); - e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); - return widget; -} + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; -void -e_search_bar_set_ui_component (ESearchBar *search_bar, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (search_bar->ui_component != NULL) { - remove_bonobo_menus (search_bar); - bonobo_object_unref (BONOBO_OBJECT (search_bar->ui_component)); - } + if (gdk_color_equal (color1, color2)) + return ""; - search_bar->ui_component = ui_component; - if (ui_component != NULL) { - bonobo_object_ref (BONOBO_OBJECT (ui_component)); - setup_standard_verbs (search_bar); - setup_bonobo_menus (search_bar); - } + return gtk_entry_get_text (GTK_ENTRY (entry)); } void -e_search_bar_set_menu_sensitive (ESearchBar *search_bar, int id, gboolean state) +e_search_bar_set_search_text (ESearchBar *search_bar, + const gchar *text) { - char *verb_name; - char *path; + EIconEntry *icon_entry; + GtkWidget *entry; - verb_name = verb_name_from_id (id); - path = g_strconcat ("/commands/", verb_name, NULL); - g_free (verb_name); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - bonobo_ui_component_set_prop (search_bar->ui_component, path, - "sensitive", state ? "1" : "0", - NULL); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); - g_free (path); + gtk_entry_set_text (GTK_ENTRY (entry), text); + g_object_notify (G_OBJECT (search_bar), "search-text"); } -GType -e_search_bar_get_type (void) +gint +e_search_bar_get_search_value (ESearchBar *search_bar) { - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (ESearchBarClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ESearchBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) init, - }; - - type = g_type_register_static (gtk_hbox_get_type (), "ESearchBar", &info, 0); - } + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - return type; + /* FIXME */ + return 0; } void -e_search_bar_set_viewitem_id (ESearchBar *search_bar, int id) +e_search_bar_set_search_value (ESearchBar *search_bar, + gint value) { - int row; - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - row = find_id (search_bar->viewoption_menu, id, "EsbItemId", NULL); - if (row == -1) - return; - search_bar->viewitem_id = id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->viewoption), row); + /* FIXME */ - emit_query_changed (search_bar); + g_object_notify (G_OBJECT (search_bar), "search-value"); } -/** - * e_search_bar_set_item_id: - * @search_bar: A search bar. - * @id: Identifier of the item to set. - * - * Sets the active item in the options menu of a search bar. - **/ -void -e_search_bar_set_item_id (ESearchBar *search_bar, int id) +gboolean +e_search_bar_get_search_visible (ESearchBar *search_bar) { - int row; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - row = find_id (search_bar->option_menu, id, "EsbItemId", NULL); - if (row == -1) - return; - - if (id>=0) - search_bar->last_search_option = id; - search_bar->item_id = id; - gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row); - - if (!search_bar->block_search) - emit_query_changed (search_bar); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - update_clear_menuitem_sensitive (search_bar); + return GTK_WIDGET_VISIBLE (search_bar->priv->search_entry); } void -e_search_bar_set_item_menu (ESearchBar *search_bar, int id) +e_search_bar_set_search_visible (ESearchBar *search_bar, + gboolean visible) { - int row; - GtkWidget *item; g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - row = find_id (search_bar->option_menu, id, "EsbItemId", &item); - if (row == -1) - return; + if (visible) { + gtk_widget_show (search_bar->priv->search_label); + gtk_widget_show (search_bar->priv->search_entry); + } else { + gtk_widget_hide (search_bar->priv->search_label); + gtk_widget_hide (search_bar->priv->search_entry); + } - gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row); - if (id>=0) - gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE); + g_object_notify (G_OBJECT (search_bar), "search-visible"); } -/** - * e_search_bar_set_search_scope: - * @search_bar: A search bar. - * @id: Identifier of the item to set. - * - * Sets the active item in the options menu of a search bar. - **/ -void -e_search_bar_set_search_scope (ESearchBar *search_bar, int id) +GtkRadioAction * +e_search_bar_get_scope_action (ESearchBar *search_bar) { - int row; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + EActionComboBox *combo_box; - row = find_id (search_bar->scopeoption_menu, id, "EsbItemId", NULL); - if (row == -1) - return; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - search_bar->scopeitem_id = id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->scopeoption), row); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - if (!search_bar->block_search) - emit_query_changed (search_bar); + return e_action_combo_box_get_action (combo_box); } - -/** - * e_search_bar_get_item_id: - * @search_bar: A search bar. - * - * Queries the currently selected item in the options menu of a search bar. - * - * Return value: Identifier of the selected item in the options menu. - **/ -int -e_search_bar_get_item_id (ESearchBar *search_bar) +void +e_search_bar_set_scope_action (ESearchBar *search_bar, + GtkRadioAction *action) { - GtkWidget *menu_item; - gint item_id; + EActionComboBox *combo_box; - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_if_fail (GTK_IS_RADIO_ACTION (action)); - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->option_menu)); - item_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); - search_bar->item_id = item_id; + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - return search_bar->item_id; + e_action_combo_box_set_action (combo_box, action); + g_object_notify (G_OBJECT (search_bar), "scope-action"); } -/** - * e_search_bar_get_search_scope: - * @search_bar: A search bar. - * - * Queries the currently selected search type in the options menu of a search bar. - * - * Return value: Identifier of the selected item in the options menu. - **/ -int -e_search_bar_get_search_scope (ESearchBar *search_bar) +gint +e_search_bar_get_scope_value (ESearchBar *search_bar) { - GtkWidget *menu_item; - gint scopeitem_id; - - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + EActionComboBox *combo_box; - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->scopeoption_menu)); - scopeitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - search_bar->scopeitem_id = scopeitem_id; + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - return search_bar->scopeitem_id; + return e_action_combo_box_get_current_value (combo_box); } -/** - * e_search_bar_get_viewitem_id: - * @search_bar: A search bar. - * - * Queries the currently selected item in the viewoptions menu of a search bar. - * - * Return value: Identifier of the selected item in the viewoptions menu. - * If the search bar currently contains an entry rather than a a viewoption menu, - * a value less than zero is returned. - **/ -int -e_search_bar_get_viewitem_id (ESearchBar *search_bar) +void +e_search_bar_set_scope_value (ESearchBar *search_bar, + gint value) { - GtkWidget *menu_item; - gint viewitem_id; - - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + EActionComboBox *combo_box; - if (!search_bar->viewoption_menu) - return -1; - - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu)); - viewitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - search_bar->viewitem_id = viewitem_id; + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - return search_bar->viewitem_id; + e_action_combo_box_set_current_value (combo_box, value); + g_object_notify (G_OBJECT (search_bar), "scope-value"); } -/** - * e_search_bar_set_ids: - * @search_bar: A search bar. - * @item_id: Identifier of the item to set. - * @subitem_id: Identifier of the subitem to set. - * - * Sets the item and subitem ids for a search bar. This is intended to switch - * to an item that has subitems. - **/ -void -e_search_bar_set_ids (ESearchBar *search_bar, int item_id, int subitem_id) +gboolean +e_search_bar_get_scope_visible (ESearchBar *search_bar) { - int item_row; - GtkWidget *item_widget; - - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - item_row = find_id (search_bar->option_menu, item_id, "EsbChoiceId", &item_widget); - if (item_row == -1 || !item_widget) - return; - - search_bar->item_id = item_id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->option), item_row); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); + return GTK_WIDGET_VISIBLE (search_bar->priv->scope_combo_box); } -/** - * e_search_bar_set_text: - * @search_bar: A search bar. - * @text: Text to set in the search bar's entry line. - * - * Sets the text string inside the entry line of a search bar. - **/ void -e_search_bar_set_text (ESearchBar *search_bar, const char *text) +e_search_bar_set_scope_visible (ESearchBar *search_bar, + gboolean visible) { g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text); -} - -/** - * e_search_bar_get_text: - * @search_bar: A search bar. - * - * Queries the text of the entry line in a search bar. - * - * Return value: The text string that is in the entry line of the search bar. - * This must be freed using g_free(). If a suboption menu is active instead - * of an entry, NULL is returned. - **/ -char * -e_search_bar_get_text (ESearchBar *search_bar) -{ - GtkStyle *entry_style, *default_style; - - g_return_val_if_fail (search_bar != NULL, NULL); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - entry_style = gtk_widget_get_style (search_bar->entry); - default_style = gtk_widget_get_default_style (); - - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) - return g_strdup (""); - return g_strdup (gtk_entry_get_text (GTK_ENTRY (search_bar->entry))); -} - -void e_search_bar_scope_enable (ESearchBar *esb, int did, gboolean state) -{ - GtkWidget *widget=NULL; - GList *l ; - int id; - gpointer *pointer; - - g_return_if_fail (esb != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (esb)); - - l = GTK_MENU_SHELL (esb->scopeoption_menu)->children; - while (l) { - pointer = g_object_get_data (l->data, "EsbItemId"); - if (pointer) { - id = GPOINTER_TO_INT (pointer); - if (id == did) { - widget = l->data; - break; - } - } - l = l->next; + if (visible) { + gtk_widget_show (search_bar->priv->scope_label); + gtk_widget_show (search_bar->priv->scope_combo_box); + } else { + gtk_widget_hide (search_bar->priv->scope_label); + gtk_widget_hide (search_bar->priv->scope_combo_box); } - if (widget) - gtk_widget_set_sensitive (widget, state); + g_object_notify (G_OBJECT (search_bar), "scope-visible"); } diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index f4a8ec93c2..56883e27bc 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -17,172 +17,87 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ -#ifndef __E_SEARCH_BAR_H__ -#define __E_SEARCH_BAR_H__ + +#ifndef E_SEARCH_BAR_H +#define E_SEARCH_BAR_H #include -#include +/* Standard GObject macros */ +#define E_TYPE_SEARCH_BAR \ + (e_search_bar_get_type ()) +#define E_SEARCH_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SEARCH_BAR, ESearchBar)) +#define E_SEARCH_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SEARCH_BAR, ESearchBarClass)) +#define E_IS_SEARCH_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SEARCH_BAR)) +#define E_IS_SEARCH_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SEARCH_BAR)) +#define E_SEARCH_BAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SEARCH_BAR, ESearchBarClass)) + +/* Action Names */ +#define E_SEARCH_BAR_ACTION_CLEAR "search-clear" +#define E_SEARCH_BAR_ACTION_FIND "search-find" +#define E_SEARCH_BAR_ACTION_TYPE "search-type" G_BEGIN_DECLS -/* ESearchBar - A card displaying information about a contact. - * - * The following arguments are available: - * - * name type read/write description - * --------------------------------------------------------------------------------- - * item_id int RW Which option item is currently selected. - * subitem_id int RW Which option subitem is currently selected. - * text string RW Text in the entry box. - */ - -#define E_SEARCH_BAR_TYPE (e_search_bar_get_type ()) -#define E_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_SEARCH_BAR_TYPE, ESearchBar)) -#define E_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_SEARCH_BAR_TYPE, ESearchBarClass)) -#define E_IS_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_SEARCH_BAR_TYPE)) -#define E_IS_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_SEARCH_BAR_TYPE)) - -enum _ESearchBarItemType { - ESB_ITEMTYPE_NORMAL, - ESB_ITEMTYPE_CHECK, - ESB_ITEMTYPE_RADIO, -}; -typedef enum _ESearchBarItemType ESearchBarItemType; - -typedef struct { - char *text; - int id; - int type; -} ESearchBarItem; - -typedef struct _ESearchBar ESearchBar; -typedef struct _ESearchBarClass ESearchBarClass; - -typedef void (*ESearchBarMenuFunc)(ESearchBar *esb, ESearchBarItem *menu_items); +typedef struct _ESearchBar ESearchBar; +typedef struct _ESearchBarClass ESearchBarClass; +typedef struct _ESearchBarPrivate ESearchBarPrivate; struct _ESearchBar { GtkHBox parent; - - BonoboUIComponent *ui_component; - - GSList *menu_items; - - /* item specific fields */ - GtkWidget *option; - GtkWidget *entry; - GtkWidget *suboption; /* an option menu for the choices associated with some options */ - - /* PRIVATE */ - GtkWidget *dropdown_holder; /* holds the dropdown */ - GtkWidget *option_menu; - GtkWidget *suboption_menu; - GtkWidget *option_button; - GtkWidget *clear_button; - GtkWidget *entry_box; - GtkWidget *icon_entry; - - /* show option widgets */ - GtkWidget *viewoption_box; - GtkWidget *viewoption; /* an option menu for the choices associated with some search options */ - GtkWidget *viewoption_menu; - - /* search scope widgets */ - GtkWidget *scopeoption_box; - GtkWidget *scopeoption; /* an option menu for the choices associated with scope search */ - GtkWidget *scopeoption_menu; - - guint pending_activate; - - /* The currently-selected item & subitem */ - int item_id; - int viewitem_id; /* Current View Id */ - int scopeitem_id; /* Scope of search */ - int last_search_option; - - gboolean block_search; + ESearchBarPrivate *priv; }; struct _ESearchBarClass { GtkHBoxClass parent_class; - - void (*set_menu) (ESearchBar *, ESearchBarItem *); - void (*set_option) (ESearchBar *, ESearchBarItem *); - - /* signals */ - void (*search_activated) (ESearchBar *search); - void (*search_cleared) (ESearchBar *search); - void (*query_changed) (ESearchBar *search); - void (*menu_activated) (ESearchBar *search, int item); -}; - -enum { - E_SEARCHBAR_FIND_NOW_ID = -1, - E_SEARCHBAR_CLEAR_ID = -2 }; - -GType e_search_bar_get_type (void); -void e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items); -GtkWidget *e_search_bar_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items); - -void e_search_bar_set_ui_component (ESearchBar *search_bar, - BonoboUIComponent *ui_component); - -void e_search_bar_set_menu (ESearchBar *search_bar, - ESearchBarItem *menu_items); -void e_search_bar_add_menu (ESearchBar *search_bar, - ESearchBarItem *menu_item); - -void e_search_bar_set_option (ESearchBar *search_bar, - ESearchBarItem *option_items); -void e_search_bar_paint (ESearchBar *search_bar); -void e_search_bar_set_viewoption (ESearchBar *search_bar, - int option_id, - ESearchBarItem *subitems); - -void e_search_bar_set_menu_sensitive (ESearchBar *search_bar, - int id, - gboolean state); - -void e_search_bar_set_item_id (ESearchBar *search_bar, - int id); -void e_search_bar_set_item_menu (ESearchBar *search_bar, - int id); -int e_search_bar_get_item_id (ESearchBar *search_bar); - -int e_search_bar_get_viewitem_id (ESearchBar *search_bar); - -void e_search_bar_set_viewitem_id (ESearchBar *search_bar, int id); +GType e_search_bar_get_type (void); +GtkWidget * e_search_bar_new (void); +GtkActionGroup *e_search_bar_get_action_group (ESearchBar *search_bar); +GtkRadioAction *e_search_bar_get_filter_action (ESearchBar *search_bar); +void e_search_bar_set_filter_action (ESearchBar *search_bar, + GtkRadioAction *action); +gint e_search_bar_get_filter_value (ESearchBar *search_bar); +void e_search_bar_set_filter_value (ESearchBar *search_bar, + gint value); +gboolean e_search_bar_get_filter_visible (ESearchBar *search_bar); +void e_search_bar_set_filter_visible (ESearchBar *search_bar, + gboolean visible); +GtkRadioAction *e_search_bar_get_search_action (ESearchBar *search_bar); +void e_search_bar_set_search_action (ESearchBar *search_bar, + GtkRadioAction *action); +const gchar * e_search_bar_get_search_text (ESearchBar *search_bar); +void e_search_bar_set_search_text (ESearchBar *search_bar, + const gchar *text); +gint e_search_bar_get_search_value (ESearchBar *search_bar); +void e_search_bar_set_search_value (ESearchBar *search_bar, + gint value); +gboolean e_search_bar_get_search_visible (ESearchBar *search_bar); +void e_search_bar_set_search_visible (ESearchBar *search_bar, + gboolean visible); +GtkRadioAction *e_search_bar_get_scope_action (ESearchBar *search_bar); +void e_search_bar_set_scope_action (ESearchBar *search_bar, + GtkRadioAction *action); +gint e_search_bar_get_scope_value (ESearchBar *search_bar); +void e_search_bar_set_scope_value (ESearchBar *search_bar, + gint value); +gboolean e_search_bar_get_scope_visible (ESearchBar *search_bar); +void e_search_bar_set_scope_visible (ESearchBar *search_bar, + gboolean visible); -void e_search_bar_set_ids (ESearchBar *search_bar, - int item_id, - int subitem_id); - -void e_search_bar_set_scopeoption (ESearchBar *search_bar, ESearchBarItem *scopeitems); - -void e_search_bar_set_scopeoption_menu (ESearchBar *search_bar, GtkMenu *menu); - -void e_search_bar_set_search_scope (ESearchBar *search_bar, int id); - -void e_search_bar_set_viewoption_menu (ESearchBar *search_bar, GtkWidget *menu); - -void e_search_bar_set_viewoption_menufunc (ESearchBar *search_bar, ESearchBarMenuFunc *menu_gen_func, void *data); - -GtkWidget *e_search_bar_get_selected_viewitem (ESearchBar *search_bar); - -int e_search_bar_get_search_scope (ESearchBar *search_bar); - -void e_search_bar_set_text (ESearchBar *search_bar, - const char *text); -char *e_search_bar_get_text (ESearchBar *search_bar); -void e_search_bar_scope_enable (ESearchBar *search_bar, int did, gboolean state); G_END_DECLS - -#endif /* __E_SEARCH_BAR_H__ */ +#endif /* E_SEARCH_BAR_H */ diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c index ddc99ff3ba..dc3d40be59 100644 --- a/widgets/misc/test-preferences-window.c +++ b/widgets/misc/test-preferences-window.c @@ -44,7 +44,7 @@ add_pages (EPreferencesWindow *preferences_window) e_preferences_window_add_page ( preferences_window, page_name, - "gtk-properties", caption, i, widget); + "gtk-properties", caption, widget, i); g_free (caption); g_free (page_name); -- cgit v1.2.3 From 52d683e48cf1103a9806da95c72abce2db3ae1f4 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 7 Sep 2008 04:02:27 +0000 Subject: Progress update: - Contacts module mostly working now. - View and search UI not yet working. - Still refining shell design. svn path=/branches/kill-bonobo/; revision=36268 --- widgets/misc/Makefile.am | 6 + widgets/misc/e-filter-bar.c | 652 ++++++++++++++++++-------------------------- widgets/misc/e-filter-bar.h | 69 +++-- widgets/misc/e-icon-entry.c | 1 - widgets/misc/e-search-bar.c | 142 ++++++++++ widgets/misc/e-search-bar.h | 6 + 6 files changed, 448 insertions(+), 428 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ee91224f5e..138d102295 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -5,6 +5,7 @@ endif INCLUDES = \ -I$(top_srcdir) \ -I$(top_srcdir)/a11y/widgets \ + -I$(top_srcdir)/filter \ -I$(top_srcdir)/widgets \ -DEVOLUTION_IMAGES=\""$(imagesdir)"\" \ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ @@ -132,6 +133,7 @@ libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ $(top_builddir)/widgets/table/libetable.la \ $(top_builddir)/widgets/text/libetext.la \ $(top_builddir)/a11y/widgets/libevolution-widgets-a11y.la \ @@ -166,6 +168,7 @@ test_calendar_SOURCES = \ test_calendar_LDADD = \ libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ $(E_WIDGETS_LIBS) # test-dateedit @@ -176,6 +179,7 @@ test_dateedit_SOURCES = \ test_dateedit_LDADD = \ libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ $(E_WIDGETS_LIBS) # test-dropdown-button @@ -186,6 +190,7 @@ test_dropdown_button_SOURCES = \ test_dropdown_button_LDADD = \ libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ $(E_WIDGETS_LIBS) # test-preferences-window @@ -196,6 +201,7 @@ test_preferences_window_SOURCES = \ test_preferences_window_LDADD = \ libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ $(E_WIDGETS_LIBS) diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 37f508c9f6..dc9863a8f5 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -29,26 +29,15 @@ #endif #include +#include #include #include -#include - #include "e-dropdown-button.h" #include "e-filter-bar.h" #include "filter/rule-editor.h" -#define d(x) - -enum { - LAST_SIGNAL -}; - -/*static gint esb_signals [LAST_SIGNAL] = { 0, };*/ - -static ESearchBarClass *parent_class = NULL; - /* The arguments we take */ enum { PROP_0, @@ -56,59 +45,26 @@ enum { PROP_STATE, }; +static gpointer parent_class; /* Callbacks. */ static void rule_changed (FilterRule *rule, gpointer user_data); - /* rule editor thingy */ static void -rule_editor_destroyed (EFilterBar *efb, GObject *deadbeef) -{ - efb->save_dialog = NULL; - e_search_bar_set_menu_sensitive (E_SEARCH_BAR (efb), E_FILTERBAR_SAVE_ID, TRUE); -} - -/* FIXME: need to update the popup menu to match any edited rules, sigh */ -static void -full_rule_editor_response (GtkWidget *dialog, int response, void *data) -{ - EFilterBar *efb = data; - - if (response == GTK_RESPONSE_OK) - rule_context_save (efb->context, efb->userrules); - - gtk_widget_destroy (dialog); -} - -static void -rule_editor_response (GtkWidget *dialog, int response, void *data) +rule_editor_destroyed (EFilterBar *filter_bar, GObject *deadbeef) { - EFilterBar *efb = data; - FilterRule *rule; - - if (response == GTK_RESPONSE_OK) { - rule = g_object_get_data (G_OBJECT (dialog), "rule"); - if (rule) { - if (!filter_rule_validate (rule)) - return; - - rule_context_add_rule (efb->context, rule); - /* FIXME: check return */ - rule_context_save (efb->context, efb->userrules); - } - } - - gtk_widget_destroy (dialog); + filter_bar->save_dialog = NULL; + e_search_bar_set_menu_sensitive (E_SEARCH_BAR (filter_bar), E_FILTERBAR_SAVE_ID, TRUE); } static void rule_advanced_response (GtkWidget *dialog, int response, void *data) { - EFilterBar *efb = data; + EFilterBar *filter_bar = data; /* the below generates a compiler warning about incompatible pointer types */ - ESearchBar *esb = (ESearchBar *)efb; + ESearchBar *search_bar = (ESearchBar *)filter_bar; FilterRule *rule; if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) { @@ -119,26 +75,26 @@ rule_advanced_response (GtkWidget *dialog, int response, void *data) if (!filter_rule_validate (rule)) return; - efb->current_query = rule; + filter_bar->current_query = rule; g_object_ref (rule); - g_signal_emit_by_name (efb, "search_activated"); + g_signal_emit_by_name (filter_bar, "search_activated"); - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - e_search_bar_set_text (esb,_("Advanced Search")); - gtk_widget_set_sensitive (esb->clear_button, TRUE); + gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_base (search_bar->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + e_search_bar_set_text (search_bar,_("Advanced Search")); + gtk_widget_set_sensitive (search_bar->clear_button, TRUE); if (response == GTK_RESPONSE_APPLY) { - if (!rule_context_find_rule (efb->context, rule->name, rule->source)) - rule_context_add_rule (efb->context, rule); + if (!rule_context_find_rule (filter_bar->context, rule->name, rule->source)) + rule_context_add_rule (filter_bar->context, rule); /* FIXME: check return */ - rule_context_save (efb->context, efb->userrules); + rule_context_save (filter_bar->context, filter_bar->userrules); } } } else { - e_search_bar_set_item_id (esb, esb->last_search_option); + e_search_bar_set_item_id (search_bar, search_bar->last_search_option); } if (response != GTK_RESPONSE_APPLY) @@ -148,34 +104,26 @@ rule_advanced_response (GtkWidget *dialog, int response, void *data) static void dialog_rule_changed (FilterRule *fr, GtkWidget *dialog) { - gboolean sensitive; - - g_return_if_fail (dialog != NULL); - - sensitive = fr && fr->parts; - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY, sensitive); + /* mbarnes: converted */ } static void -do_advanced (ESearchBar *esb) +do_advanced (ESearchBar *search_bar) { - EFilterBar *efb = (EFilterBar *)esb; - - d(printf("Advanced search!\n")); + EFilterBar *filter_bar = (EFilterBar *)search_bar; - if (!efb->save_dialog && !efb->setquery) { + if (!filter_bar->save_dialog && !filter_bar->setquery) { GtkWidget *dialog, *w; FilterRule *rule; - if (efb->current_query) - rule = filter_rule_clone (efb->current_query); + if (filter_bar->current_query) + rule = filter_rule_clone (filter_bar->current_query); else { rule = filter_rule_new (); - efb->current_query = rule; + filter_bar->current_query = rule; } - w = filter_rule_get_widget (rule, efb->context); + w = filter_rule_get_widget (rule, filter_bar->context); filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); gtk_container_set_border_width (GTK_CONTAINER (w), 12); @@ -185,7 +133,7 @@ do_advanced (ESearchBar *esb) GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - efb->save_dialog = dialog; + filter_bar->save_dialog = dialog; gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); @@ -201,166 +149,105 @@ do_advanced (ESearchBar *esb) g_signal_connect (rule, "changed", G_CALLBACK (dialog_rule_changed), dialog); dialog_rule_changed (rule, dialog); - g_signal_connect (dialog, "response", G_CALLBACK (rule_advanced_response), efb); - g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb); + g_signal_connect (dialog, "response", G_CALLBACK (rule_advanced_response), filter_bar); + g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, filter_bar); - e_search_bar_set_menu_sensitive (esb, E_FILTERBAR_SAVE_ID, FALSE); + e_search_bar_set_menu_sensitive (search_bar, E_FILTERBAR_SAVE_ID, FALSE); gtk_widget_show (dialog); } } static void -save_search_dialog (ESearchBar *esb) +save_search_dialog (ESearchBar *search_bar) { - FilterRule *rule; - char *name, *text; - GtkWidget *dialog, *w; - - EFilterBar *efb = (EFilterBar *)esb; - - rule = filter_rule_clone (efb->current_query); - text = e_search_bar_get_text (esb); - name = g_strdup_printf ("%s %s", rule->name, text && text[0] ? text : "''"); - filter_rule_set_name (rule, name); - g_free (text); - g_free (name); - - w = filter_rule_get_widget (rule, efb->context); - filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); - gtk_container_set_border_width (GTK_CONTAINER (w), 12); - - /* FIXME: get the toplevel window... */ - dialog = gtk_dialog_new_with_buttons (_("Save Search"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - efb->save_dialog = dialog; - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); - - gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300); - - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 0); - - g_object_ref (rule); - g_object_set_data_full ((GObject *) dialog, "rule", rule, (GDestroyNotify) g_object_unref); - g_signal_connect (dialog, "response", G_CALLBACK (rule_editor_response), efb); - g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb); - - g_signal_connect (rule, "changed", G_CALLBACK (dialog_rule_changed), dialog); - dialog_rule_changed (rule, dialog); - - e_search_bar_set_menu_sensitive (esb, E_FILTERBAR_SAVE_ID, FALSE); - - gtk_widget_show (dialog); + /* mbarnes: converted */ } static void -menubar_activated (ESearchBar *esb, int id, void *data) +menubar_activated (ESearchBar *search_bar, int id, void *data) { - EFilterBar *efb = (EFilterBar *)esb; + EFilterBar *filter_bar = (EFilterBar *)search_bar; GtkWidget *dialog; GtkStyle *style; - d(printf ("menubar activated!\n")); - switch (id) { case E_FILTERBAR_EDIT_ID: - if (!efb->save_dialog) { - efb->save_dialog = dialog = (GtkWidget *) rule_editor_new (efb->context, FILTER_SOURCE_INCOMING, _("_Searches")); - - gtk_window_set_title (GTK_WINDOW (dialog), _("Searches")); - g_signal_connect (dialog, "response", G_CALLBACK (full_rule_editor_response), efb); - g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb); - gtk_widget_show (dialog); - } + /* mbarnes: converted */ break; case E_FILTERBAR_SAVE_ID: - if (efb->current_query && !efb->save_dialog) - save_search_dialog (esb); + if (filter_bar->current_query && !filter_bar->save_dialog) + save_search_dialog (search_bar); - d(printf("Save menu\n")); break; case E_FILTERBAR_ADVANCED_ID: - e_search_bar_set_item_id (esb, E_FILTERBAR_ADVANCED_ID); + e_search_bar_set_item_id (search_bar, E_FILTERBAR_ADVANCED_ID); break; default: - if (id >= efb->menu_base && id < efb->menu_base + efb->menu_rules->len) { -#if d(!)0 - GString *out = g_string_new (""); - - printf("Selected rule: %s\n", ((FilterRule *)efb->menu_rules->pdata[id - efb->menu_base])->name); - filter_rule_build_code (efb->menu_rules->pdata[id - efb->menu_base], out); - printf("query: '%s'\n", out->str); - g_string_free (out, TRUE); -#endif - efb->current_query = (FilterRule *)efb->menu_rules->pdata[id - efb->menu_base]; + if (id >= filter_bar->menu_base && id < filter_bar->menu_base + filter_bar->menu_rules->len) { + filter_bar->current_query = (FilterRule *)filter_bar->menu_rules->pdata[id - filter_bar->menu_base]; - efb->setquery = TRUE; - e_search_bar_set_item_id (esb, E_FILTERBAR_ADVANCED_ID); - efb->setquery = FALSE; + filter_bar->setquery = TRUE; + e_search_bar_set_item_id (search_bar, E_FILTERBAR_ADVANCED_ID); + filter_bar->setquery = FALSE; /* saved searches activated */ style = gtk_widget_get_default_style (); - efb->setquery = TRUE; - gtk_widget_modify_base (esb->entry , GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED] )); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text [GTK_STATE_SELECTED] )); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); - gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); - e_search_bar_set_text (esb,_("Advanced Search")); - g_signal_emit_by_name (efb, "search_activated", NULL); - efb->setquery = FALSE; + filter_bar->setquery = TRUE; + gtk_widget_modify_base (search_bar->entry , GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED] )); + gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text [GTK_STATE_SELECTED] )); + gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); + gtk_widget_modify_base (search_bar->viewoption, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); + e_search_bar_set_text (search_bar,_("Advanced Search")); + g_signal_emit_by_name (filter_bar, "search_activated", NULL); + filter_bar->setquery = FALSE; } else { return; } } - g_signal_stop_emission_by_name (esb, "menu_activated"); + g_signal_stop_emission_by_name (search_bar, "menu_activated"); } static void -option_changed (ESearchBar *esb, void *data) +option_changed (ESearchBar *search_bar, void *data) { - EFilterBar *efb = (EFilterBar *)esb; - int id = e_search_bar_get_item_id (esb); + EFilterBar *filter_bar = (EFilterBar *)search_bar; + int id = e_search_bar_get_item_id (search_bar); char *query; - d(printf("option changed, id = %d, setquery = %s %d\n", id, efb->setquery ? "true" : "false", esb->block_search)); - - if (esb->scopeitem_id == E_FILTERBAR_CURRENT_MESSAGE_ID) { - gtk_widget_set_sensitive (esb->option_button, FALSE); + if (search_bar->scopeitem_id == E_FILTERBAR_CURRENT_MESSAGE_ID) { + gtk_widget_set_sensitive (search_bar->option_button, FALSE); } else { - gtk_widget_set_sensitive (esb->option_button, TRUE); + gtk_widget_set_sensitive (search_bar->option_button, TRUE); } - if (efb->setquery) + if (filter_bar->setquery) return; switch (id) { case E_FILTERBAR_SAVE_ID: /* Fixme */ - /* save_search_dialog (esb); */ + /* save_search_dialog (search_bar); */ break; case E_FILTERBAR_ADVANCED_ID: - d(printf ("do_advanced\n")); - if (!esb->block_search) - do_advanced (esb); + if (!search_bar->block_search) + do_advanced (search_bar); break; default: - if (id >= efb->option_base && id < efb->option_base + efb->option_rules->len) { - efb->current_query = (FilterRule *)efb->option_rules->pdata[id - efb->option_base]; - if (efb->config && efb->current_query) { - query = e_search_bar_get_text (esb); - efb->config (efb, efb->current_query, id, query, efb->config_data); + if (id >= filter_bar->option_base && id < filter_bar->option_base + filter_bar->option_rules->len) { + filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[id - filter_bar->option_base]; + if (filter_bar->config && filter_bar->current_query) { + query = e_search_bar_get_text (search_bar); + filter_bar->config (filter_bar, filter_bar->current_query, id, query, filter_bar->config_data); g_free (query); } } else { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - efb->current_query = NULL; - gtk_entry_set_text ((GtkEntry *)esb->entry, ""); + gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, NULL); + filter_bar->current_query = NULL; + gtk_entry_set_text ((GtkEntry *)search_bar->entry, ""); } } } @@ -375,10 +262,10 @@ dup_item_no_subitems (ESearchBarItem *dest, } static GArray * -build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrArray *rules) +build_items (ESearchBar *search_bar, ESearchBarItem *items, int type, int *start, GPtrArray *rules) { FilterRule *rule = NULL; - EFilterBar *efb = (EFilterBar *)esb; + EFilterBar *filter_bar = (EFilterBar *)search_bar; int id = 0, i; GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem)); ESearchBarItem item = { NULL, -1, 2 }; @@ -410,7 +297,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA source = FILTER_SOURCE_INCOMING; /* Add a separator if there is at least one custom rule. */ - if (rule_context_next_rule (efb->context, rule, source) != NULL) { + if (rule_context_next_rule (filter_bar->context, rule, source) != NULL) { item.id = 0; item.text = NULL; item.type = 0; @@ -421,7 +308,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA } num = 1; - while ((rule = rule_context_next_rule (efb->context, rule, source))) { + while ((rule = rule_context_next_rule (filter_bar->context, rule, source))) { item.id = id++; if (type == 0 && num <= 10) { @@ -434,7 +321,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA if (g_slist_find(gtksux, rule) == NULL) { g_object_ref (rule); - g_signal_connect (rule, "changed", G_CALLBACK (rule_changed), efb); + g_signal_connect (rule, "changed", G_CALLBACK (rule_changed), filter_bar); } else { gtksux = g_slist_remove(gtksux, rule); } @@ -448,7 +335,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA next = gtksux->next; rule = gtksux->data; - g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), efb); + g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), filter_bar); g_object_unref (rule); g_slist_free_1(gtksux); @@ -491,13 +378,13 @@ free_built_items (GArray *menu) } static void -generate_menu (ESearchBar *esb, ESearchBarItem *items) +generate_menu (ESearchBar *search_bar, ESearchBarItem *items) { - EFilterBar *efb = (EFilterBar *)esb; + EFilterBar *filter_bar = (EFilterBar *)search_bar; GArray *menu; - menu = build_items (esb, items, 0, &efb->menu_base, efb->menu_rules); - ((ESearchBarClass *)parent_class)->set_menu (esb, (ESearchBarItem *)menu->data); + menu = build_items (search_bar, items, 0, &filter_bar->menu_base, filter_bar->menu_rules); + ((ESearchBarClass *)parent_class)->set_menu (search_bar, (ESearchBarItem *)menu->data); free_built_items (menu); } @@ -515,14 +402,14 @@ free_items (ESearchBarItem *items) /* Virtual methods */ static void -set_menu (ESearchBar *esb, ESearchBarItem *items) +set_menu (ESearchBar *search_bar, ESearchBarItem *items) { - EFilterBar *efb = E_FILTER_BAR (esb); + EFilterBar *filter_bar = E_FILTER_BAR (search_bar); ESearchBarItem *default_items; int i, num; - if (efb->default_items) - free_items (efb->default_items); + if (filter_bar->default_items) + free_items (filter_bar->default_items); for (num = 0; items[num].id != -1; num++) ; @@ -534,72 +421,72 @@ set_menu (ESearchBar *esb, ESearchBarItem *items) default_items[i].type = items[i].type; } - efb->default_items = default_items; + filter_bar->default_items = default_items; - generate_menu (esb, default_items); + generate_menu (search_bar, default_items); } static void -set_option (ESearchBar *esb, ESearchBarItem *items) +set_option (ESearchBar *search_bar, ESearchBarItem *items) { GArray *menu; - EFilterBar *efb = (EFilterBar *)esb; + EFilterBar *filter_bar = (EFilterBar *)search_bar; - menu = build_items (esb, items, 1, &efb->option_base, efb->option_rules); - ((ESearchBarClass *)parent_class)->set_option (esb, (ESearchBarItem *)menu->data); + menu = build_items (search_bar, items, 1, &filter_bar->option_base, filter_bar->option_rules); + ((ESearchBarClass *)parent_class)->set_option (search_bar, (ESearchBarItem *)menu->data); free_built_items (menu); - e_search_bar_set_item_id (esb, efb->option_base); + e_search_bar_set_item_id (search_bar, filter_bar->option_base); } static void context_changed (RuleContext *context, gpointer user_data) { - EFilterBar *efb = E_FILTER_BAR (user_data); - ESearchBar *esb = E_SEARCH_BAR (user_data); + EFilterBar *filter_bar = E_FILTER_BAR (user_data); + ESearchBar *search_bar = E_SEARCH_BAR (user_data); /* just generate whole menu again */ - generate_menu (esb, efb->default_items); + generate_menu (search_bar, filter_bar->default_items); } static void context_rule_removed (RuleContext *context, FilterRule *rule, gpointer user_data) { - EFilterBar *efb = E_FILTER_BAR (user_data); - ESearchBar *esb = E_SEARCH_BAR (user_data); + EFilterBar *filter_bar = E_FILTER_BAR (user_data); + ESearchBar *search_bar = E_SEARCH_BAR (user_data); /* just generate whole menu again */ - generate_menu (esb, efb->default_items); + generate_menu (search_bar, filter_bar->default_items); } static void rule_changed (FilterRule *rule, gpointer user_data) { - EFilterBar *efb = E_FILTER_BAR (user_data); - ESearchBar *esb = E_SEARCH_BAR (user_data); + EFilterBar *filter_bar = E_FILTER_BAR (user_data); + ESearchBar *search_bar = E_SEARCH_BAR (user_data); /* just generate whole menu again */ - generate_menu (esb, efb->default_items); + generate_menu (search_bar, filter_bar->default_items); } - -/* GtkObject methods. */ - static void -get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +filter_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - EFilterBar *efb = (EFilterBar *) object; - ESearchBar *esb = E_SEARCH_BAR (object); + EFilterBar *filter_bar = (EFilterBar *) object; + ESearchBar *search_bar = E_SEARCH_BAR (object); switch (property_id) { case PROP_QUERY: { - char *text = e_search_bar_get_text (E_SEARCH_BAR (efb)); + char *text = e_search_bar_get_text (E_SEARCH_BAR (filter_bar)); /* empty search text means searching turned off */ - if (efb->current_query && text && *text) { + if (filter_bar->current_query && text && *text) { GString *out = g_string_new (""); - filter_rule_build_code (efb->current_query, out); + filter_rule_build_code (filter_bar->current_query, out); g_value_take_string (value, out->str); g_string_free (out, FALSE); } else { @@ -616,32 +503,32 @@ get_property (GObject *object, guint property_id, GValue *value, GParamSpec *psp xmlNodePtr root, node; xmlDocPtr doc; - item_id = e_search_bar_get_item_id ((ESearchBar *) efb); + item_id = e_search_bar_get_item_id ((ESearchBar *) filter_bar); doc = xmlNewDoc ((const unsigned char *)"1.0"); root = xmlNewDocNode (doc, NULL, (const unsigned char *)"state", NULL); xmlDocSetRootElement (doc, root); - searchscope = e_search_bar_get_search_scope ((ESearchBar *) efb); - view_id = e_search_bar_get_viewitem_id ((ESearchBar *) efb); + searchscope = e_search_bar_get_search_scope ((ESearchBar *) filter_bar); + view_id = e_search_bar_get_viewitem_id ((ESearchBar *) filter_bar); if (searchscope < E_FILTERBAR_CURRENT_FOLDER_ID) - item_id = esb->last_search_option; + item_id = search_bar->last_search_option; if (item_id == E_FILTERBAR_ADVANCED_ID) { /* advanced query, save the filterbar state */ node = xmlNewChild (root, NULL, (const unsigned char *)"filter-bar", NULL); - sprintf (buf, "%d", esb->last_search_option); + sprintf (buf, "%d", search_bar->last_search_option); xmlSetProp (node, (const unsigned char *)"item_id", (unsigned char *)buf); sprintf (buf, "%d", searchscope); xmlSetProp (node, (const unsigned char *)"searchscope", (unsigned char *)buf); sprintf (buf, "%d", view_id); xmlSetProp (node, (const unsigned char *)"view_id", (unsigned char *)buf); - xmlAddChild (node, filter_rule_xml_encode (efb->current_query)); + xmlAddChild (node, filter_rule_xml_encode (filter_bar->current_query)); } else { /* simple query, save the searchbar state */ - text = e_search_bar_get_text ((ESearchBar *) efb); + text = e_search_bar_get_text ((ESearchBar *) filter_bar); node = xmlNewChild (root, NULL, (const unsigned char *)"search-bar", NULL); xmlSetProp (node, (const unsigned char *)"text", (unsigned char *)(text ? text : "")); @@ -689,10 +576,13 @@ xml_get_prop_int (xmlNodePtr node, const char *prop) } static void -set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +filter_bar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - EFilterBar *efb = (EFilterBar *) object; - ESearchBar *esb = E_SEARCH_BAR (object); + EFilterBar *filter_bar = (EFilterBar *) object; + ESearchBar *search_bar = E_SEARCH_BAR (object); xmlNodePtr root, node; const char *state; xmlDocPtr doc; @@ -730,43 +620,43 @@ set_property (GObject *object, guint property_id, const GValue *value, GParamSpe GtkStyle *style = gtk_widget_get_default_style (); rule = filter_rule_new (); - if (filter_rule_xml_decode (rule, node, efb->context) != 0) { - gtk_widget_modify_base (E_SEARCH_BAR (efb)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, NULL); + if (filter_rule_xml_decode (rule, node, filter_bar->context) != 0) { + gtk_widget_modify_base (E_SEARCH_BAR (filter_bar)->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, NULL); g_object_unref (rule); rule = NULL; } else { rule_set = TRUE; - gtk_widget_set_sensitive (esb->clear_button, TRUE); - gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)efb)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_set_sensitive (search_bar->clear_button, TRUE); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); g_object_set_data_full (object, "rule", rule, (GDestroyNotify) g_object_unref); } } if (rule_set) { - esb->block_search = TRUE; - e_search_bar_set_text (esb, _("Advanced Search")); - e_search_bar_set_item_menu ((ESearchBar *) efb, item_id); - e_search_bar_set_search_scope ((ESearchBar *) efb, scope); - esb->block_search = FALSE; - efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base]; - if (efb->config && efb->current_query) { - char *query = e_search_bar_get_text (esb); - efb->config (efb, efb->current_query, item_id, query, efb->config_data); + search_bar->block_search = TRUE; + e_search_bar_set_text (search_bar, _("Advanced Search")); + e_search_bar_set_item_menu ((ESearchBar *) filter_bar, item_id); + e_search_bar_set_search_scope ((ESearchBar *) filter_bar, scope); + search_bar->block_search = FALSE; + filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; + if (filter_bar->config && filter_bar->current_query) { + char *query = e_search_bar_get_text (search_bar); + filter_bar->config (filter_bar, filter_bar->current_query, item_id, query, filter_bar->config_data); g_free (query); } } - e_search_bar_set_viewitem_id ((ESearchBar *) efb, view_id); - efb->current_query = rule; - efb->setquery = TRUE; - e_search_bar_set_item_id ((ESearchBar *) efb, E_FILTERBAR_ADVANCED_ID); - efb->setquery = FALSE; + e_search_bar_set_viewitem_id ((ESearchBar *) filter_bar, view_id); + filter_bar->current_query = rule; + filter_bar->setquery = TRUE; + e_search_bar_set_item_id ((ESearchBar *) filter_bar, E_FILTERBAR_ADVANCED_ID); + filter_bar->setquery = FALSE; break; } else if (!strcmp ((char *)node->name, "search-bar")) { @@ -781,36 +671,36 @@ set_property (GObject *object, guint property_id, const GValue *value, GParamSpe item_id = xml_get_prop_int (node, "item_id"); subitem_id = xml_get_prop_int (node, "subitem_id"); - esb->block_search = TRUE; + search_bar->block_search = TRUE; if (subitem_id >= 0) - e_search_bar_set_ids (E_SEARCH_BAR (efb), item_id, subitem_id); + e_search_bar_set_ids (E_SEARCH_BAR (filter_bar), item_id, subitem_id); else - e_search_bar_set_item_menu (E_SEARCH_BAR (efb), item_id); - esb->block_search = FALSE; + e_search_bar_set_item_menu (E_SEARCH_BAR (filter_bar), item_id); + search_bar->block_search = FALSE; view_id = xml_get_prop_int (node, "view_id"); - e_search_bar_set_viewitem_id (E_SEARCH_BAR (efb), view_id); + e_search_bar_set_viewitem_id (E_SEARCH_BAR (filter_bar), view_id); scope = xml_get_prop_int (node, "searchscope"); - e_search_bar_set_search_scope (E_SEARCH_BAR (efb), scope); + e_search_bar_set_search_scope (E_SEARCH_BAR (filter_bar), scope); text = (char *)xmlGetProp (node, (const unsigned char *)"text"); - e_search_bar_set_text (E_SEARCH_BAR (efb), text); + e_search_bar_set_text (E_SEARCH_BAR (filter_bar), text); if (text && *text) { - efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base]; - if (efb->config && efb->current_query) - efb->config (efb, efb->current_query, item_id, text, efb->config_data); - gtk_widget_set_sensitive (esb->clear_button, TRUE); - gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)efb)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; + if (filter_bar->config && filter_bar->current_query) + filter_bar->config (filter_bar, filter_bar->current_query, item_id, text, filter_bar->config_data); + gtk_widget_set_sensitive (search_bar->clear_button, TRUE); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); } else { - gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, NULL); - e_search_bar_paint (esb); - efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base]; - if (efb->config && efb->current_query) - efb->config (efb, efb->current_query, item_id, "", efb->config_data); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, NULL); + e_search_bar_paint (search_bar); + filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; + if (filter_bar->config && filter_bar->current_query) + filter_bar->config (filter_bar, filter_bar->current_query, item_id, "", filter_bar->config_data); } xmlFree (text); @@ -825,15 +715,15 @@ set_property (GObject *object, guint property_id, const GValue *value, GParamSpe xmlFreeDoc (doc); } else { /* set default state */ - e_search_bar_set_item_id ((ESearchBar *) efb, 0); - e_search_bar_set_viewitem_id ((ESearchBar *) efb, 0); - e_search_bar_set_search_scope ((ESearchBar *) efb, E_FILTERBAR_CURRENT_FOLDER_ID); + e_search_bar_set_item_id ((ESearchBar *) filter_bar, 0); + e_search_bar_set_viewitem_id ((ESearchBar *) filter_bar, 0); + e_search_bar_set_search_scope ((ESearchBar *) filter_bar, E_FILTERBAR_CURRENT_FOLDER_ID); } /* we don't want to run option_changed */ - efb->setquery = TRUE; - g_signal_emit_by_name (efb, "search_activated", NULL); - efb->setquery = FALSE; + filter_bar->setquery = TRUE; + g_signal_emit_by_name (filter_bar, "search_activated", NULL); + filter_bar->setquery = FALSE; break; default: @@ -842,22 +732,27 @@ set_property (GObject *object, guint property_id, const GValue *value, GParamSpe } } -static void clear_rules(EFilterBar *efb, GPtrArray *rules) +static void +filter_bar_clear_rules (EFilterBar *filter_bar, + GPtrArray *rules) { - int i; FilterRule *rule; + gint ii; + + /* Clear out any data on old rules. */ + for (ii = 0; ii < rules->len; ii++) { + FilterRule *rule = rules->pdata[ii]; - /* clear out any data on old rules */ - for (i=0;ilen;i++) { - rule = rules->pdata[i]; - g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), efb); + g_signal_handlers_disconnect_by_func ( + rule, G_CALLBACK (rule_changed), filter_bar); g_object_unref(rule); } + g_ptr_array_set_size (rules, 0); } static void -dispose (GObject *object) +filter_bar_dispose (GObject *object) { EFilterBar *bar; @@ -870,8 +765,8 @@ dispose (GObject *object) rule_context_save (bar->context, bar->userrules); if (bar->menu_rules != NULL) { - clear_rules(bar, bar->menu_rules); - clear_rules(bar, bar->option_rules); + filter_bar_clear_rules (bar, bar->menu_rules); + filter_bar_clear_rules (bar, bar->option_rules); g_ptr_array_free (bar->menu_rules, TRUE); g_ptr_array_free (bar->option_rules, TRUE); @@ -898,97 +793,97 @@ dispose (GObject *object) bar->default_items = NULL; } - (* G_OBJECT_CLASS (parent_class)->dispose) (object); + G_OBJECT_CLASS (parent_class)->dispose (object); } - static void -class_init (EFilterBarClass *klass) +class_init (EFilterBarClass *class) { - GObjectClass *object_class = (GObjectClass *) klass; - ESearchBarClass *esb_class = (ESearchBarClass *) klass; + GObjectClass *object_class; + ESearchBarClass *search_bar_class; GParamSpec *pspec; - parent_class = g_type_class_ref (e_search_bar_get_type ()); - - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; - - esb_class->set_menu = set_menu; - esb_class->set_option = set_option; - - pspec = g_param_spec_string ("query", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property (object_class, PROP_QUERY, pspec); - - pspec = g_param_spec_string ("state", NULL, NULL, NULL, G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_STATE, pspec); - - /*gtk_object_add_arg_type ("EFilterBar::query", G_TYPE_STRING, GTK_ARG_READABLE, ARG_QUERY);*/ - -#if 0 - esb_signals [QUERY_CHANGED] = - g_signal_new ("query_changed", - G_SIGNAL_RUN_LAST, - object_class->type, - G_STRUCT_OFFSET (EFilterBarClass, query_changed), - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - esb_signals [MENU_ACTIVATED] = - g_signal_new ("menu_activated", - G_SIGNAL_RUN_LAST, - object_class->type, - G_STRUCT_OFFSET (EFilterBarClass, menu_activated), - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - gtk_object_class_add_signals (object_class, esb_signals, LAST_SIGNAL); -#endif + parent_class = g_type_class_peek_parent (class); + + object_class = G_OBJECT_CLASS (object_class); + object_class->set_property = filter_bar_set_property; + object_class->get_property = filter_bar_get_property; + object_class->dispose = filter_bar_dispose; + + search_bar_class = E_SEARCH_BAR_CLASS (class); + search_bar_class->set_menu = set_menu; + search_bar_class->set_option = set_option; + + g_object_class_install_property ( + object_class, + PROP_QUERY, + g_param_spec_string ( + "query", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_STATE, + g_param_spec_string ( + "state", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); } static void -init (EFilterBar *efb) +filter_bar_init (EFilterBar *filter_bar) { - g_signal_connect (efb, "menu_activated", G_CALLBACK (menubar_activated), NULL); - g_signal_connect (efb, "query_changed", G_CALLBACK (option_changed), NULL); - g_signal_connect (efb, "search_activated", G_CALLBACK (option_changed), NULL); + g_signal_connect (filter_bar, "menu_activated", G_CALLBACK (menubar_activated), NULL); + g_signal_connect (filter_bar, "query_changed", G_CALLBACK (option_changed), NULL); + g_signal_connect (filter_bar, "search_activated", G_CALLBACK (option_changed), NULL); - efb->menu_rules = g_ptr_array_new (); - efb->option_rules = g_ptr_array_new (); + filter_bar->menu_rules = g_ptr_array_new (); + filter_bar->option_rules = g_ptr_array_new (); } - -/* Object construction. */ - -EFilterBar * -e_filter_bar_new (RuleContext *context, - const char *systemrules, - const char *userrules, - EFilterBarConfigRule config, - void *data) +GType +e_filter_bar_get_type (void) { - EFilterBar *bar; + static GType type = 0; - bar = g_object_new (e_filter_bar_get_type (), NULL); + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EFilterBarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) filter_bar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EFilterBar), + 0, /* n_preallocs */ + (GInstanceInitFunc) filter_bar_init, + NULL /* value_table */ + }; - e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar); + type = g_type_register_static ( + E_TYPE_SEARCH_BAR, "EFilterBar", &type_info, 0); + } - return bar; + return type; } - -void -e_filter_bar_new_construct (RuleContext *context, - const char *systemrules, - const char *userrules, +EFilterBar * +e_filter_bar_new (RuleContext *context, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, - void *data ,EFilterBar *bar ) + gpointer data) { - ESearchBarItem item = { NULL, -1, 0 }; + EFilterBar *bar; + + bar = g_object_new (E_TYPE_FILTER_BAR, NULL); - bar->context = context; - g_object_ref (context); + bar->context = g_object_ref (context); bar->config = config; bar->config_data = data; @@ -1000,35 +895,8 @@ e_filter_bar_new_construct (RuleContext *context, bar->account_search_vf = NULL; bar->account_search_cancel = NULL; - e_search_bar_construct ((ESearchBar *)bar, &item, &item); - g_signal_connect (context, "changed", G_CALLBACK (context_changed), bar); g_signal_connect (context, "rule_removed", G_CALLBACK (context_rule_removed), bar); -} - -GType -e_filter_bar_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EFilterBarClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EFilterBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - e_search_bar_get_type (), "EFilterBar", &type_info, 0); - } - - return type; + return bar; } diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index 5caf803485..ca53f3aeb0 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -17,8 +17,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ -#ifndef __E_FILTER_BAR_H__ -#define __E_FILTER_BAR_H__ +#ifndef E_FILTER_BAR_H +#define E_FILTER_BAR_H #include #include @@ -29,11 +29,6 @@ #include "filter/rule-context.h" #include "filter/filter-rule.h" -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - /* EFilterBar - A filter rule driven search bar. * * The following arguments are available: @@ -44,14 +39,29 @@ extern "C" { * state string RW XML string representing the state. */ -#define E_FILTER_BAR_TYPE (e_filter_bar_get_type ()) -#define E_FILTER_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_FILTER_BAR_TYPE, EFilterBar)) -#define E_FILTER_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_FILTER_BAR_TYPE, EFilterBarClass)) -#define E_IS_FILTER_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_FILTER_BAR_TYPE)) -#define E_IS_FILTER_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_FILTER_BAR_TYPE)) - -typedef struct _EFilterBar EFilterBar; -typedef struct _EFilterBarClass EFilterBarClass; +/* Standard GObject macros */ +#define E_TYPE_FILTER_BAR \ + (e_filter_bar_get_type ()) +#define E_FILTER_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_FILTER_BAR, EFilterBar)) +#define E_FILTER_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_FILTER_BAR, EFilterBarClass)) +#define E_IS_FILTER_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_FILTER_BAR)) +#define E_IS_FILTER_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((obj), E_TYPE_FILTER_BAR)) +#define E_FILTER_BAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_FILTER_BAR, EFilterBarClass)) + +G_BEGIN_DECLS + +typedef struct _EFilterBar EFilterBar; +typedef struct _EFilterBarClass EFilterBarClass; typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, int id, const char *query, void *data); @@ -79,8 +89,7 @@ struct _EFilterBar { CamelOperation *account_search_cancel; }; -struct _EFilterBarClass -{ +struct _EFilterBarClass { ESearchBarClass parent_class; }; @@ -116,23 +125,13 @@ const char * strings[] = { #endif -GType e_filter_bar_get_type (void); - -EFilterBar *e_filter_bar_new (RuleContext *context, - const char *systemrules, - const char *userrules, - EFilterBarConfigRule config, - void *data); -void -e_filter_bar_new_construct (RuleContext *context, - const char *systemrules, - const char *userrules, - EFilterBarConfigRule config, - void *data ,EFilterBar *bar ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ +GType e_filter_bar_get_type (void); +EFilterBar * e_filter_bar_new (RuleContext *context, + const gchar *systemrules, + const gchar *userrules, + EFilterBarConfigRule config, + gpointer data); +G_END_DECLS -#endif /* __E_FILTER_BAR_H__ */ +#endif /* E_FILTER_BAR_H */ diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index 500b27e6db..1c9ed12d96 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -69,7 +69,6 @@ icon_entry_create_proxy (GtkAction *action) gtk_event_box_set_visible_window (GTK_EVENT_BOX (proxy), FALSE); gtk_container_set_border_width (GTK_CONTAINER (proxy), 2); gtk_action_connect_proxy (action, proxy); - gtk_widget_show (widget); widget = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU); gtk_container_add (GTK_CONTAINER (proxy), widget); diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index fcfe002843..fa8b099569 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -45,6 +45,9 @@ ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate)) struct _ESearchBarPrivate { + RuleContext *context; + FilterRule *current_query; + GtkWidget *filter_label; GtkWidget *filter_combo_box; GtkWidget *search_label; @@ -60,6 +63,7 @@ struct _ESearchBarPrivate { enum { PROP_0, + PROP_CONTEXT, PROP_FILTER_ACTION, PROP_FILTER_VALUE, PROP_FILTER_VISIBLE, @@ -122,6 +126,20 @@ static GtkActionEntry search_entries[] = { G_CALLBACK (action_search_type_cb) } }; +static void +search_bar_rule_changed (FilterRule *rule, + GtkDialog *dialog) +{ + gboolean sensitive; + + sensitive = (rule != NULL && rule->parts != NULL); + + gtk_dialog_set_response_sensitive ( + dialog, GTK_RESPONSE_OK, sensitive); + gtk_dialog_set_response_sensitive ( + dialog, GTK_RESPONSE_APPLY, sensitive); +} + static void search_bar_update_search_popup (ESearchBar *search_bar) { @@ -355,6 +373,12 @@ search_bar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_CONTEXT: + e_search_bar_set_context ( + E_SEARCH_BAR (object), + g_value_get_object (value)); + return; + case PROP_FILTER_ACTION: e_search_bar_set_filter_action ( E_SEARCH_BAR (object), @@ -426,6 +450,12 @@ search_bar_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_CONTEXT: + g_value_set_object ( + value, e_search_bar_get_context ( + E_SEARCH_BAR (object))); + return; + case PROP_FILTER_ACTION: g_value_set_object ( value, e_search_bar_get_filter_action ( @@ -497,6 +527,11 @@ search_bar_dispose (GObject *object) priv = E_SEARCH_BAR_GET_PRIVATE (object); + if (priv->context != NULL) { + g_object_unref (priv->context); + priv->context = NULL; + } + if (priv->filter_label != NULL) { g_object_unref (priv->filter_label); priv->filter_label = NULL; @@ -554,6 +589,16 @@ search_bar_class_init (ESearchBarClass *class) object_class->get_property = search_bar_get_property; object_class->dispose = search_bar_dispose; + g_object_class_install_property ( + object_class, + PROP_CONTEXT, + g_param_spec_object ( + "context", + NULL, + NULL, + RULE_TYPE_CONTEXT, + G_PARAM_READWRITE)); + g_object_class_install_property ( object_class, PROP_FILTER_ACTION, @@ -809,6 +854,28 @@ e_search_bar_get_action_group (ESearchBar *search_bar) return search_bar->priv->action_group; } +RuleContext * +e_search_bar_get_context (ESearchBar *search_bar) +{ + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); + + return search_bar->priv->context; +} + +void +e_search_bar_set_context (ESearchBar *search_bar, + RuleContext *context) +{ + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_if_fail (IS_RULE_CONTEXT (context)); + + if (search_bar->priv->context != NULL) + g_object_unref (search_bar->priv->context); + + search_bar->priv->context = g_object_ref (context); + g_object_notify (G_OBJECT (search_bar), "context"); +} + GtkRadioAction * e_search_bar_get_filter_action (ESearchBar *search_bar) { @@ -950,6 +1017,7 @@ e_search_bar_set_search_text (ESearchBar *search_bar, icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); entry = e_icon_entry_get_entry (icon_entry); + text = (text != NULL) ? text : ""; gtk_entry_set_text (GTK_ENTRY (entry), text); g_object_notify (G_OBJECT (search_bar), "search-text"); } @@ -1076,3 +1144,77 @@ e_search_bar_set_scope_visible (ESearchBar *search_bar, g_object_notify (G_OBJECT (search_bar), "scope-visible"); } + +static void +search_bar_rule_changed_cb (FilterRule *rule, + GtkDialog *dialog) +{ + /* FIXME Think this does something with sensitivity. */ +} + +void +e_search_bar_save_search_dialog (ESearchBar *search_bar, + const gchar *filename) +{ + RuleContext *context; + FilterRule *rule; + GtkWidget *dialog; + GtkWidget *parent; + GtkWidget *widget; + const gchar *search_text; + gchar *rule_name; + + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_if_fail (filename != NULL); + + g_return_if_fail (search_bar->priv->current_query != NULL); + + rule = filter_rule_clone (search_bar->priv->current_query); + search_text = e_search_bar_get_search_text (search_bar); + if (search_text == NULL || *search_text == '\0') + search_text = "''"; + + rule_name = g_strdup_printf ("%s %s", rule->name, search_text); + filter_rule_set_name (rule, rule_name); + g_free (rule_name); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (search_bar)); + + dialog = gtk_dialog_new_with_buttons ( + _("Save Search"), GTK_WINDOW (parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300); + gtk_container_set_border_width ( + GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); + gtk_container_set_border_width ( + GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); + + context = search_bar->priv->context; + widget = filter_rule_get_widget (rule, context); + filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + gtk_box_pack_start ( + GTK_BOX (GTK_DIALOG (dialog)->vbox), + widget, TRUE, TRUE, 0); + + g_signal_connect ( + rule, "changed", + G_CALLBACK (search_bar_rule_changed_cb), + dialog); + + search_bar_rule_changed_cb (rule, GTK_DIALOG (dialog)); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { + if (filter_rule_validate (rule)) { + rule_context_add_rule (context, rule); + rule_context_save (context, filename); + } + } + + gtk_widget_destroy (dialog); +} diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index 56883e27bc..dd51edd698 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -22,6 +22,7 @@ #define E_SEARCH_BAR_H #include +#include /* Standard GObject macros */ #define E_TYPE_SEARCH_BAR \ @@ -67,6 +68,9 @@ struct _ESearchBarClass GType e_search_bar_get_type (void); GtkWidget * e_search_bar_new (void); GtkActionGroup *e_search_bar_get_action_group (ESearchBar *search_bar); +RuleContext * e_search_bar_get_context (ESearchBar *search_bar); +void e_search_bar_set_context (ESearchBar *search_bar, + RuleContext *context); GtkRadioAction *e_search_bar_get_filter_action (ESearchBar *search_bar); void e_search_bar_set_filter_action (ESearchBar *search_bar, GtkRadioAction *action); @@ -97,6 +101,8 @@ void e_search_bar_set_scope_value (ESearchBar *search_bar, gboolean e_search_bar_get_scope_visible (ESearchBar *search_bar); void e_search_bar_set_scope_visible (ESearchBar *search_bar, gboolean visible); +void e_search_bar_save_search_dialog (ESearchBar *search_bar, + const gchar *filename); G_END_DECLS -- cgit v1.2.3 From 5350eebb5ef8c07e69110616ce1662e0e92bea16 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 8 Sep 2008 20:37:00 +0000 Subject: Progress update: - Merge ETaskBar into EShellTaskbar. - Remember the last view, and make --component work. svn path=/branches/kill-bonobo/; revision=36278 --- widgets/misc/Makefile.am | 4 - widgets/misc/e-activity-handler.c | 697 -------------------------------------- widgets/misc/e-activity-handler.h | 108 ------ widgets/misc/e-task-bar.c | 302 ----------------- widgets/misc/e-task-bar.h | 81 ----- widgets/misc/e-task-widget.c | 29 +- widgets/misc/e-task-widget.h | 8 +- 7 files changed, 6 insertions(+), 1223 deletions(-) delete mode 100644 widgets/misc/e-activity-handler.c delete mode 100644 widgets/misc/e-activity-handler.h delete mode 100644 widgets/misc/e-task-bar.c delete mode 100644 widgets/misc/e-task-bar.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 138d102295..0b7eca1f12 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -37,7 +37,6 @@ widgetsinclude_HEADERS = \ $(pilot_headers) \ e-account-combo-box.h \ e-action-combo-box.h \ - e-activity-handler.h \ e-attachment.h \ e-attachment-bar.h \ e-spinner.c \ @@ -59,7 +58,6 @@ widgetsinclude_HEADERS = \ e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ - e-task-bar.h \ e-task-widget.h \ e-send-options.h \ e-url-entry.h \ @@ -86,7 +84,6 @@ libemiscwidgets_la_SOURCES = \ $(pilot_sources) \ e-account-combo-box.c \ e-action-combo-box.c \ - e-activity-handler.c \ e-calendar.c \ e-attachment.c \ e-attachment-bar.c \ @@ -106,7 +103,6 @@ libemiscwidgets_la_SOURCES = \ e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ - e-task-bar.c \ e-task-widget.c \ e-send-options.c \ e-url-entry.c \ diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c deleted file mode 100644 index d7972ac336..0000000000 --- a/widgets/misc/e-activity-handler.c +++ /dev/null @@ -1,697 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-activity-handler.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-activity-handler.h" - -#include -#include - -#include -#include - -#include - -#define ICON_SIZE 16 - - -struct _ActivityInfo { - char *component_id; - int error_type; - guint id; - char *information; - gboolean cancellable; - double progress; - GtkWidget *menu; - void (*cancel_func) (gpointer data); - gpointer data; - gpointer error; - time_t error_time; -}; -typedef struct _ActivityInfo ActivityInfo; - -struct _EActivityHandlerPrivate { - guint next_activity_id; - GList *activity_infos; - GSList *task_bars; - ELogger *logger; - guint error_timer; - guint error_flush_interval; - -}; - -/* In the status bar, we show only errors and info. Errors are pictured as warnings. */ -const char *icon_data [] = {"stock_dialog-warning", "stock_dialog-info"}; - -G_DEFINE_TYPE (EActivityHandler, e_activity_handler, G_TYPE_OBJECT) - -/* Utility functions. */ - -static void handle_error (ETaskWidget *task); - -static unsigned int -get_new_activity_id (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - - priv = activity_handler->priv; - - return priv->next_activity_id ++; -} - -static GList * -lookup_activity (GList *list, - guint activity_id, - int *order_number_return) -{ - GList *p; - int i; - - for (p = list, i = 0; p != NULL; p = p->next, i ++) { - ActivityInfo *activity_info; - - activity_info = (ActivityInfo *) p->data; - if (activity_info->id == activity_id) { - *order_number_return = i; - return p; - } - } - - *order_number_return = -1; - return NULL; -} - - -/* ETaskWidget actions. */ - -static int -task_widget_button_press_event_callback (GtkWidget *widget, - GdkEventButton *button_event, - void *data) -{ - ActivityInfo *activity_info; - - activity_info = (ActivityInfo *) data; - - if (button_event->button == 3) - return activity_info->cancellable; - - if (button_event->button != 1) - return FALSE; - - return TRUE; -} - - -/* Creating and destroying ActivityInfos. */ - -static ActivityInfo * -activity_info_new (const char *component_id, - guint id, - const char *information, - gboolean cancellable) -{ - ActivityInfo *info; - - info = g_new (ActivityInfo, 1); - info->component_id = g_strdup (component_id); - info->id = id; - info->information = g_strdup (information); - info->cancellable = cancellable; - info->progress = -1.0; /* (Unknown) */ - info->menu = NULL; - info->error = NULL; - info->cancel_func = NULL; - - return info; -} - -static void -activity_info_free (ActivityInfo *info) -{ - g_free (info->component_id); - g_free (info->information); - - if (info->menu != NULL) - gtk_widget_destroy (info->menu); - - g_free (info); -} - -static ETaskWidget * -task_widget_new_from_activity_info (ActivityInfo *activity_info) -{ - GtkWidget *widget; - ETaskWidget *etw; - - widget = e_task_widget_new_with_cancel ( - activity_info->component_id, - activity_info->information, - activity_info->cancel_func, - activity_info->data); - etw = (ETaskWidget *) widget; - etw->id = activity_info->id; - gtk_widget_show (widget); - - g_signal_connect (widget, "button_press_event", - G_CALLBACK (task_widget_button_press_event_callback), - activity_info); - - return E_TASK_WIDGET (widget); -} - - -/* Task Bar handling. */ - -static void -setup_task_bar (EActivityHandler *activity_handler, - ETaskBar *task_bar) -{ - EActivityHandlerPrivate *priv; - GList *p; - - priv = activity_handler->priv; - - for (p = g_list_last (priv->activity_infos); p != NULL; p = p->prev) { - ActivityInfo *info = p->data; - ETaskWidget *task_widget = task_widget_new_from_activity_info (info); - task_widget->id = info->id; - e_task_bar_prepend_task (task_bar, task_widget); - if (info->error) { - /* Prepare to handle existing errors*/ - GtkWidget *tool; - const char *stock; - - stock = info->error_type ? icon_data [1] : icon_data[0]; - tool = e_task_widget_update_image (task_widget, (char *)stock, info->information); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", info->error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(info->id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(info->error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - } -} - -static void -task_bar_destroy_notify (void *data, - GObject *task_bar_instance) -{ - EActivityHandler *activity_handler; - EActivityHandlerPrivate *priv; - - activity_handler = E_ACTIVITY_HANDLER (data); - priv = activity_handler->priv; - - priv->task_bars = g_slist_remove (priv->task_bars, task_bar_instance); -} - - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - EActivityHandler *handler; - EActivityHandlerPrivate *priv; - GList *p; - GSList *sp; - - handler = E_ACTIVITY_HANDLER (object); - priv = handler->priv; - - for (p = priv->activity_infos; p != NULL; p = p->next) { - ActivityInfo *info; - - info = (ActivityInfo *) p->data; - activity_info_free (info); - } - - g_list_free (priv->activity_infos); - priv->activity_infos = NULL; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) - g_object_weak_unref (G_OBJECT (sp->data), task_bar_destroy_notify, handler); - priv->task_bars = NULL; - - (* G_OBJECT_CLASS (e_activity_handler_parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - EActivityHandler *handler; - EActivityHandlerPrivate *priv; - - handler = E_ACTIVITY_HANDLER (object); - priv = handler->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_activity_handler_parent_class)->finalize) (object); -} - -static void -e_activity_handler_class_init (EActivityHandlerClass *activity_handler_class) -{ - GObjectClass *object_class = (GObjectClass *) activity_handler_class; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; -} - -static void -e_activity_handler_init (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - - priv = g_new (EActivityHandlerPrivate, 1); - priv->next_activity_id = 1; - priv->activity_infos = NULL; - priv->task_bars = NULL; - priv->logger = NULL; - priv->error_timer = 0; - priv->error_flush_interval = 0; - activity_handler->priv = priv; -} - - -EActivityHandler * -e_activity_handler_new (void) -{ - return g_object_new (e_activity_handler_get_type (), NULL); -} - -void -e_activity_handler_set_error_flush_time (EActivityHandler *handler, int time) -{ - handler->priv->error_flush_interval = time; -} -void -e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger) -{ - handler->priv->logger = logger; -} - -void -e_activity_handler_set_message (EActivityHandler *activity_handler, - const char *message) -{ - EActivityHandlerPrivate *priv; - GSList *i; - - priv = activity_handler->priv; - - for (i = priv->task_bars; i; i = i->next) - e_task_bar_set_message (E_TASK_BAR (i->data), message); -} - -void -e_activity_handler_unset_message (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - GSList *i; - - priv = activity_handler->priv; - - for (i = priv->task_bars; i; i = i->next) - e_task_bar_unset_message (E_TASK_BAR (i->data)); -} - -void -e_activity_handler_attach_task_bar (EActivityHandler *activity_handler, - ETaskBar *task_bar) -{ - EActivityHandlerPrivate *priv; - - g_return_if_fail (activity_handler != NULL); - g_return_if_fail (E_IS_ACTIVITY_HANDLER (activity_handler)); - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - priv = activity_handler->priv; - - g_object_weak_ref (G_OBJECT (task_bar), task_bar_destroy_notify, activity_handler); - - priv->task_bars = g_slist_prepend (priv->task_bars, task_bar); - - setup_task_bar (activity_handler, task_bar); -} - -struct _cancel_wdata { - EActivityHandler *handler; - ActivityInfo *info; - guint id; - void (*cancel)(gpointer); - gpointer data; -}; - -static void -cancel_wrapper (gpointer pdata) -{ - struct _cancel_wdata *data = (struct _cancel_wdata *) pdata; - /* This can be invoked in two scenario. Either to cancel or to hide error */ - if (data->info->error) { - /* Hide the error */ - EActivityHandler *handler = data->handler; - ActivityInfo *info; - int order, len; - GSList *sp; - GList *p = lookup_activity (handler->priv->activity_infos, data->id, &order); - e_logger_log (handler->priv->logger, E_LOG_ERROR, g_object_get_data (data->info->error, "primary"), - g_object_get_data (data->info->error, "secondary")); - gtk_widget_destroy (data->info->error); - data->info->error = NULL; - info = data->info; - for (sp = handler->priv->task_bars; sp != NULL; sp = sp->next) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, info->id); - } - activity_info_free (info); - len = g_list_length (handler->priv->activity_infos); - handler->priv->activity_infos = g_list_remove_link (handler->priv->activity_infos, p); - if (len == 1) - handler->priv->activity_infos = NULL; - } else { - /* Cancel the operation */ - data->cancel (data->data); - } - /* No need to free the data. It will be freed as part of the task widget destroy */ -} - -/* CORBA methods. */ -guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, - const char *component_id, - const char *information, - gboolean cancellable, - void (*cancel_func)(gpointer), - gpointer user_data) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - struct _cancel_wdata *data; - gboolean bfree = FALSE; - priv = activity_handler->priv; - - activity_id = get_new_activity_id (activity_handler); - activity_info = activity_info_new (component_id, activity_id, information, cancellable); - - data = g_new(struct _cancel_wdata, 1); - data->handler = activity_handler; - data->id = activity_id; - data->info = activity_info; - data->cancel = cancel_func; - data->data = user_data; - - activity_info->cancel_func = cancel_wrapper; - activity_info->data = data; - for (p = priv->task_bars; p != NULL; p = p->next) { - ETaskWidget *tw = task_widget_new_from_activity_info (activity_info); - tw->id = activity_id; - if (!bfree) { - /* The data will be freed part of the widget destroy */ - g_object_set_data_full ((GObject *) tw, "free-data", data, g_free); - bfree = TRUE; - } - e_task_bar_prepend_task (E_TASK_BAR (p->data), tw); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - return activity_id; - -} - -guint -e_activity_handler_operation_started (EActivityHandler *activity_handler, - const char *component_id, - const char *information, - gboolean cancellable) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - - priv = activity_handler->priv; - - activity_id = get_new_activity_id (activity_handler); - - activity_info = activity_info_new (component_id, activity_id, information, cancellable); - - for (p = priv->task_bars; p != NULL; p = p->next) { - ETaskWidget *tw = task_widget_new_from_activity_info (activity_info); - tw->id = activity_id; - e_task_bar_prepend_task (E_TASK_BAR (p->data), tw); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - return activity_id; -} - -static void -handle_error (ETaskWidget *task) -{ - GtkWidget *tool, *error; - EActivityHandler *activity_handler; - guint id; - int error_type = GPOINTER_TO_INT((g_object_get_data ((GObject *) task, "error-type"))); - tool = g_object_get_data ((GObject *) task, "tool"); - error = g_object_get_data ((GObject *) task, "error"); - activity_handler = g_object_get_data ((GObject *) task, "activity-handler"); - id = GPOINTER_TO_UINT (g_object_get_data ((GObject *) task, "activity")); - e_activity_handler_operation_finished (activity_handler, id); - gtk_widget_show (error); - e_logger_log (activity_handler->priv->logger, error_type, - g_object_get_data ((GObject *) error, "primary"), - g_object_get_data ((GObject *) error, "secondary")); -} - -static gboolean -error_cleanup (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - GList *p, *node; - GSList *sp; - int i; - time_t now = time (NULL); - gboolean berror = FALSE; - - for (p = priv->activity_infos, i = 0; p != NULL; i++) { - ActivityInfo *info; - - info = (ActivityInfo *) p->data; - if (info->error) - berror = TRUE; - if (info->error && info->error_time && (now - info->error_time) > 5 ) { - /* Error older than wanted time. So cleanup */ - e_logger_log (priv->logger, info->error_type, g_object_get_data (info->error, "primary"), - g_object_get_data (info->error, "secondary")); - gtk_widget_destroy (info->error); - node = p; - p = p->next; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, info->id); - } - activity_info_free (info); - priv->activity_infos = g_list_remove_link (priv->activity_infos, node); - - } else - p = p->next; - } - if (!berror) - priv->error_timer = 0; - return berror; -} - -guint -e_activity_handler_make_error (EActivityHandler *activity_handler, - const char *component_id, - int error_type, - GtkWidget *error) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - char *information = g_object_get_data((GObject *) error, "primary"); - const char *img; - - priv = activity_handler->priv; - activity_id = get_new_activity_id (activity_handler); - - activity_info = activity_info_new (component_id, activity_id, information, TRUE); - activity_info->error = error; - activity_info->error_time = time (NULL); - activity_info->error_type = error_type; - - img = error_type ? icon_data[1] : icon_data[0]; - for (p = priv->task_bars; p != NULL; p = p->next) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_TASK_BAR (p->data); - task_widget = task_widget_new_from_activity_info (activity_info); - task_widget->id = activity_id; - e_task_bar_prepend_task (E_TASK_BAR (p->data), task_widget); - - tool = e_task_widget_update_image (task_widget, (char *)img, information); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - if (!activity_handler->priv->error_timer) - activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc)error_cleanup, activity_handler); - - return activity_id; -} - -void -e_activity_handler_operation_set_error(EActivityHandler *activity_handler, - guint activity_id, - GtkWidget *error) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - ActivityInfo *activity_info; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("EActivityHandler: unknown operation %d", activity_id); - return; - } - - activity_info = (ActivityInfo *) p->data; - activity_info->error = error; - activity_info->error_time = time (NULL); - activity_info->error_type = E_LOG_ERROR; - g_free (activity_info->information); - activity_info->information = g_strdup (g_object_get_data ((GObject *) error, "primary")); - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_TASK_BAR (sp->data); - task_widget = e_task_bar_get_task_widget_from_id (task_bar, activity_info->id); - if (!task_widget) - continue; - - tool = e_task_widget_update_image (task_widget, (char *)icon_data[0], g_object_get_data ((GObject *) error, "primary")); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(E_LOG_ERROR)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - - if (!activity_handler->priv->error_timer) - activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc) error_cleanup, activity_handler); -} - -void -e_activity_handler_operation_progressing (EActivityHandler *activity_handler, - guint activity_id, - const char *information, - double progress) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - ActivityInfo *activity_info; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("EActivityHandler: unknown operation %d", activity_id); - return; - } - - activity_info = (ActivityInfo *) p->data; - - g_free (activity_info->information); - activity_info->information = g_strdup (information); - - activity_info->progress = progress; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - - task_bar = E_TASK_BAR (sp->data); - task_widget = e_task_bar_get_task_widget_from_id (task_bar, activity_info->id); - if (!task_widget) - continue; - - e_task_widget_update (task_widget, information, progress); - } -} - -void -e_activity_handler_operation_finished (EActivityHandler *activity_handler, - guint activity_id) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("e_activity_handler_operation_finished: Unknown activity %d\n", activity_id); - return; - } - - activity_info_free ((ActivityInfo *) p->data); - priv->activity_infos = g_list_remove_link (priv->activity_infos, p); - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, activity_id); - } -} - diff --git a/widgets/misc/e-activity-handler.h b/widgets/misc/e-activity-handler.h deleted file mode 100644 index 8b6a857569..0000000000 --- a/widgets/misc/e-activity-handler.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-activity-handler.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef _E_ACTIVITY_HANDLER_H_ -#define _E_ACTIVITY_HANDLER_H_ - -#include "e-task-bar.h" -#include "e-util/e-logger.h" -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_ACTIVITY_HANDLER (e_activity_handler_get_type ()) -#define E_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ACTIVITY_HANDLER, EActivityHandler)) -#define E_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ACTIVITY_HANDLER, EActivityHandlerClass)) -#define E_IS_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER)) -#define E_IS_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER)) - - -typedef struct _EActivityHandler EActivityHandler; -typedef struct _EActivityHandlerPrivate EActivityHandlerPrivate; -typedef struct _EActivityHandlerClass EActivityHandlerClass; - -#define EAH_ICON_INFO "stock_dialog-info" -#define EAH_ICON_ERROR "stock_dialog-warning" - -struct _EActivityHandler { - GObject parent; - - EActivityHandlerPrivate *priv; -}; - -struct _EActivityHandlerClass { - GObjectClass parent_class; -}; - - -GType e_activity_handler_get_type (void); - -EActivityHandler *e_activity_handler_new (void); - -void e_activity_handler_attach_task_bar (EActivityHandler *activity_hanlder, - ETaskBar *task_bar); - -void e_activity_handler_set_message (EActivityHandler *activity_handler, - const char *message); - -void e_activity_handler_unset_message (EActivityHandler *activity_handler); - -guint e_activity_handler_operation_started (EActivityHandler *activity_handler, - const char *component_id, - const char *information, - gboolean cancellable); -guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, - const char *component_id, - const char *information, - gboolean cancellable, - void (*cancel_func)(gpointer), - gpointer user_data); - -void e_activity_handler_operation_progressing (EActivityHandler *activity_handler, - guint activity_id, - const char *information, - double progress); - -void e_activity_handler_operation_finished (EActivityHandler *activity_handler, - guint activity_id); - -void e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger); -guint e_activity_handler_make_error (EActivityHandler *activity_handler, - const char *component_id, - int error_type, - GtkWidget *error); -void -e_activity_handler_operation_set_error (EActivityHandler *activity_handler, - guint activity_id, - GtkWidget *error); - -void -e_activity_handler_set_error_flush_time (EActivityHandler *handler, int time); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ACTIVITY_HANDLER_H_ */ diff --git a/widgets/misc/e-task-bar.c b/widgets/misc/e-task-bar.c deleted file mode 100644 index 9093f89d58..0000000000 --- a/widgets/misc/e-task-bar.c +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-bar.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-task-bar.h" - -struct _ETaskBarPrivate -{ - GtkWidget *message_label; - GtkHBox *hbox; -}; - -/* WARNING: Ugly hack starts here. */ -#define MAX_ACTIVITIES_PER_COMPONENT 2 - -G_DEFINE_TYPE (ETaskBar, e_task_bar, GTK_TYPE_HBOX) - -#if 0 -static void -reduce_displayed_activities_per_component (ETaskBar *task_bar) -{ - GHashTable *component_ids_hash; - GtkBox *box; - GList *p; - - component_ids_hash = g_hash_table_new (g_str_hash, g_str_equal); - - box = GTK_BOX (task_bar->priv->hbox); - - for (p = box->children; p != NULL; p = p->next) { - GtkBoxChild *child; - const char *component_id; - void *hash_item; - - child = (GtkBoxChild *) p->data; - component_id = e_task_widget_get_component_id (E_TASK_WIDGET (child->widget)); - - hash_item = g_hash_table_lookup (component_ids_hash, component_id); - - if (hash_item == NULL) { - gtk_widget_show (child->widget); - g_hash_table_insert (component_ids_hash, (void *) component_id, GINT_TO_POINTER (1)); - } else { - int num_items; - - num_items = GPOINTER_TO_INT (hash_item); - g_return_if_fail (num_items <= MAX_ACTIVITIES_PER_COMPONENT); - - if (num_items == MAX_ACTIVITIES_PER_COMPONENT) { - gtk_widget_hide (child->widget); - } else { - num_items ++; - gtk_widget_show (child->widget); - g_hash_table_insert (component_ids_hash, (void *) component_id, GINT_TO_POINTER (num_items)); - } - } - } - - g_hash_table_destroy (component_ids_hash); -} -#endif - - -static void impl_finalize (GObject *object); - -static void -e_task_bar_class_init (ETaskBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = impl_finalize; -} - -static void -e_task_bar_init (ETaskBar *task_bar) -{ - GtkWidget *label, *hbox; - gint height; - - task_bar->priv = g_new (ETaskBarPrivate, 1); - - gtk_box_set_spacing (GTK_BOX (task_bar), 10); - - label = gtk_label_new (NULL); - gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); - gtk_box_pack_start (GTK_BOX (task_bar), label, TRUE, TRUE, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - task_bar->priv->message_label = label; - - hbox = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (task_bar), hbox); - task_bar->priv->hbox = GTK_HBOX (hbox); - - /* Make the task bar large enough to accomodate a small icon. - * XXX The "* 2" is a fudge factor to allow for some padding. - * The true value is probably buried in a style property. */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height); - gtk_widget_set_size_request (GTK_WIDGET (task_bar), -1, height * 2); -} - -static void -impl_finalize (GObject *object) -{ - ETaskBar *task_bar; - ETaskBarPrivate *priv; - - task_bar = E_TASK_BAR (object); - priv = task_bar->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_task_bar_parent_class)->finalize) (object); -} - - -void -e_task_bar_construct (ETaskBar *task_bar) -{ - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - /* Nothing to do here. */ -} - -GtkWidget * -e_task_bar_new (void) -{ - ETaskBar *task_bar; - - task_bar = g_object_new (e_task_bar_get_type (), NULL); - e_task_bar_construct (task_bar); - - return GTK_WIDGET (task_bar); -} - -void -e_task_bar_set_message (ETaskBar *task_bar, - const char *message) -{ - if (message) { - gtk_label_set_text ( - GTK_LABEL (task_bar->priv->message_label), message); - gtk_widget_show (task_bar->priv->message_label); - } else { - e_task_bar_unset_message (task_bar); - } -} - -void -e_task_bar_unset_message (ETaskBar *task_bar) -{ - gtk_widget_hide (task_bar->priv->message_label); -} - -void -e_task_bar_prepend_task (ETaskBar *task_bar, - ETaskWidget *task_widget) -{ - GtkBoxChild *child_info; - GtkBox *box; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - - /* Hah hah. GTK+ sucks. This is adapted from `gtkhbox.c'. */ - - child_info = g_new (GtkBoxChild, 1); - child_info->widget = GTK_WIDGET (task_widget); - child_info->padding = 0; - child_info->expand = TRUE; - child_info->fill = TRUE; - child_info->pack = GTK_PACK_START; - - box = GTK_BOX (task_bar->priv->hbox); - - box->children = g_list_prepend (box->children, child_info); - - gtk_widget_set_parent (GTK_WIDGET (task_widget), GTK_WIDGET (task_bar->priv->hbox)); - - if (GTK_WIDGET_REALIZED (task_bar)) - gtk_widget_realize (GTK_WIDGET (task_widget)); - - if (GTK_WIDGET_VISIBLE (task_bar) && GTK_WIDGET_VISIBLE (task_widget)) { - if (GTK_WIDGET_MAPPED (task_bar)) - gtk_widget_map (GTK_WIDGET (task_widget)); - gtk_widget_queue_resize (GTK_WIDGET (task_widget)); - } - - /* We don't restrict */ - /* reduce_displayed_activities_per_component (task_bar);*/ - - gtk_widget_show (GTK_WIDGET (task_bar->priv->hbox)); -} - -void -e_task_bar_remove_task_from_id (ETaskBar *task_bar, - guint id) -{ - ETaskWidget *task_widget; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - task_widget = e_task_bar_get_task_widget_from_id (task_bar, id); - if (!task_widget) { - printf("Failed...\n"); - return; - } - - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - /* We don't restrict here on */ - /* reduce_displayed_activities_per_component (task_bar); */ - - if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0) - gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox)); -} - -void -e_task_bar_remove_task (ETaskBar *task_bar, - int n) -{ - ETaskWidget *task_widget; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - g_return_if_fail (n >= 0); - - task_widget = e_task_bar_get_task_widget (task_bar, n); - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - /* We don't restrict here on */ - /* reduce_displayed_activities_per_component (task_bar); */ - - if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0) - gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox)); -} - -ETaskWidget * -e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, - guint id) -{ - GtkBoxChild *child_info; - ETaskWidget *w = NULL; - GList *list; - - g_return_val_if_fail (task_bar != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL); - - list = GTK_BOX (task_bar->priv->hbox)->children; - while (list) { - child_info = list->data; - w = (ETaskWidget *) child_info->widget; - if (w && w->id == id) - break; - - w = NULL; - list = list->next; - } - - return w; -} - -ETaskWidget * - -e_task_bar_get_task_widget (ETaskBar *task_bar, - int n) -{ - GtkBoxChild *child_info; - - g_return_val_if_fail (task_bar != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL); - - child_info = (GtkBoxChild *) g_list_nth (GTK_BOX (task_bar->priv->hbox)->children, n)->data; - - return E_TASK_WIDGET (child_info->widget); -} - diff --git a/widgets/misc/e-task-bar.h b/widgets/misc/e-task-bar.h deleted file mode 100644 index ccd5900712..0000000000 --- a/widgets/misc/e-task-bar.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-bar.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef _E_TASK_BAR_H_ -#define _E_TASK_BAR_H_ - -#include "e-task-widget.h" - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_TASK_BAR (e_task_bar_get_type ()) -#define E_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASK_BAR, ETaskBar)) -#define E_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TASK_BAR, ETaskBarClass)) -#define E_IS_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASK_BAR)) -#define E_IS_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_TASK_BAR)) - - -typedef struct _ETaskBar ETaskBar; -typedef struct _ETaskBarPrivate ETaskBarPrivate; -typedef struct _ETaskBarClass ETaskBarClass; - -struct _ETaskBar { - GtkHBox parent; - - ETaskBarPrivate *priv; -}; - -struct _ETaskBarClass { - GtkHBoxClass parent_class; -}; - - -GType e_task_bar_get_type (void); -void e_task_bar_construct (ETaskBar *task_bar); -GtkWidget *e_task_bar_new (void); - -void e_task_bar_set_message (ETaskBar *task_bar, - const char *message); -void e_task_bar_unset_message (ETaskBar *task_bar); - -void e_task_bar_prepend_task (ETaskBar *task_bar, - ETaskWidget *task_widget); -void e_task_bar_remove_task (ETaskBar *task_bar, - int n); -ETaskWidget * e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, - guint id); - -void e_task_bar_remove_task_from_id (ETaskBar *task_bar, - guint id); -ETaskWidget *e_task_bar_get_task_widget (ETaskBar *task_bar, - int n); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_TASK_BAR_H_ */ diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c index bb2ec2747e..fe500ae778 100644 --- a/widgets/misc/e-task-widget.c +++ b/widgets/misc/e-task-widget.c @@ -33,8 +33,6 @@ #define SPACING 2 struct _ETaskWidgetPrivate { - char *component_id; - GtkWidget *label; GtkWidget *box; GtkWidget *image; @@ -56,7 +54,6 @@ impl_finalize (GObject *object) task_widget = E_TASK_WIDGET (object); priv = task_widget->priv; - g_free (priv->component_id); g_free (priv); (* G_OBJECT_CLASS (e_task_widget_parent_class)->finalize) (object); @@ -78,7 +75,6 @@ e_task_widget_init (ETaskWidget *task_widget) priv = g_new (ETaskWidgetPrivate, 1); - priv->component_id = NULL; priv->label = NULL; priv->image = NULL; priv->box = NULL; @@ -115,7 +111,6 @@ prepare_popup (ETaskWidget *widget, GdkEventButton *event) void e_task_widget_construct (ETaskWidget *task_widget, - const char *component_id, const char *information, void (*cancel_func) (gpointer data), gpointer data) @@ -126,13 +121,10 @@ e_task_widget_construct (ETaskWidget *task_widget, g_return_if_fail (task_widget != NULL); g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - g_return_if_fail (component_id != NULL); g_return_if_fail (information != NULL); priv = task_widget->priv; - priv->component_id = g_strdup (component_id); - frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (task_widget), frame); @@ -183,8 +175,7 @@ e_task_widget_construct (ETaskWidget *task_widget, } GtkWidget * -e_task_widget_new_with_cancel (const char *component_id, - const char *information, +e_task_widget_new_with_cancel (const char *information, void (*cancel_func) (gpointer data), gpointer data) { @@ -193,21 +184,20 @@ e_task_widget_new_with_cancel (const char *component_id, g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, component_id, information, cancel_func, data); + e_task_widget_construct (task_widget, information, cancel_func, data); return GTK_WIDGET (task_widget); } GtkWidget * -e_task_widget_new (const char *component_id, - const char *information) +e_task_widget_new (const char *information) { ETaskWidget *task_widget; g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, component_id, information, NULL, NULL); + e_task_widget_construct (task_widget, information, NULL, NULL); return GTK_WIDGET (task_widget); } @@ -281,14 +271,3 @@ e_task_wiget_unalert (ETaskWidget *task_widget) g_return_if_fail (task_widget != NULL); g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); } - - -const char * -e_task_widget_get_component_id (ETaskWidget *task_widget) -{ - g_return_val_if_fail (task_widget != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_WIDGET (task_widget), NULL); - - return task_widget->priv->component_id; -} - diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h index cb63b27379..0cc4ca5e20 100644 --- a/widgets/misc/e-task-widget.h +++ b/widgets/misc/e-task-widget.h @@ -55,14 +55,11 @@ struct _ETaskWidgetClass { GType e_task_widget_get_type (void); void e_task_widget_construct (ETaskWidget *task_widget, - const char *component_id, const char *information, void (*cancel_func) (gpointer data), gpointer data); -GtkWidget * e_task_widget_new (const char *component_id, - const char *information); -GtkWidget * e_task_widget_new_with_cancel (const char *component_id, - const char *information, +GtkWidget * e_task_widget_new (const char *information); +GtkWidget * e_task_widget_new_with_cancel (const char *information, void (*cancel_func) (gpointer data), gpointer data); void e_task_widget_update (ETaskWidget *task_widget, @@ -73,7 +70,6 @@ GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget, const char *text); void e_task_wiget_alert (ETaskWidget *task_widget); void e_task_wiget_unalert (ETaskWidget *task_widget); -const char * e_task_widget_get_component_id (ETaskWidget *task_widget); #ifdef __cplusplus } -- cgit v1.2.3 From c0a255eb90769638d57ae4122932f75c46e4e531 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 11 Sep 2008 15:34:29 +0000 Subject: Merge revisions 36016:36303 from trunk. svn path=/branches/kill-bonobo/; revision=36307 --- widgets/misc/ChangeLog | 114 +++++++++++++++++++++++++++++++- widgets/misc/e-account-combo-box.c | 19 +++--- widgets/misc/e-account-combo-box.h | 19 +++--- widgets/misc/e-attachment-bar.h | 29 ++++---- widgets/misc/e-attachment.c | 33 ++++----- widgets/misc/e-attachment.h | 29 ++++---- widgets/misc/e-calendar-item.c | 34 ++++------ widgets/misc/e-calendar-item.h | 30 +++++---- widgets/misc/e-calendar.h | 30 ++++----- widgets/misc/e-canvas-background.h | 31 ++++----- widgets/misc/e-canvas-utils.c | 32 ++++----- widgets/misc/e-canvas-utils.h | 30 ++++----- widgets/misc/e-canvas-vbox.c | 31 +++++---- widgets/misc/e-canvas-vbox.h | 31 +++++---- widgets/misc/e-canvas.h | 31 +++++---- widgets/misc/e-cell-date-edit.c | 29 ++++---- widgets/misc/e-cell-date-edit.h | 28 ++++---- widgets/misc/e-cell-percent.h | 28 ++++---- widgets/misc/e-cell-renderer-combo.c | 26 ++++---- widgets/misc/e-cell-renderer-combo.h | 25 +++---- widgets/misc/e-charset-picker.c | 21 +++--- widgets/misc/e-charset-picker.h | 18 ++--- widgets/misc/e-colors.h | 31 +++++---- widgets/misc/e-combo-cell-editable.c | 26 ++++---- widgets/misc/e-combo-cell-editable.h | 25 +++---- widgets/misc/e-cursors.c | 31 ++++----- widgets/misc/e-cursors.h | 32 ++++----- widgets/misc/e-dropdown-button.c | 27 ++++---- widgets/misc/e-dropdown-button.h | 26 ++++---- widgets/misc/e-expander.h | 28 ++++---- widgets/misc/e-filter-bar.c | 32 ++++----- widgets/misc/e-filter-bar.h | 29 ++++---- widgets/misc/e-gui-utils.c | 31 +++++---- widgets/misc/e-gui-utils.h | 31 +++++---- widgets/misc/e-image-chooser.c | 28 ++++---- widgets/misc/e-image-chooser.h | 27 ++++---- widgets/misc/e-map.c | 28 ++++---- widgets/misc/e-map.h | 27 ++++---- widgets/misc/e-pilot-settings.c | 27 ++++---- widgets/misc/e-pilot-settings.h | 26 ++++---- widgets/misc/e-popup-menu.c | 35 +++++----- widgets/misc/e-popup-menu.h | 35 +++++----- widgets/misc/e-printable.c | 31 +++++---- widgets/misc/e-printable.h | 32 ++++----- widgets/misc/e-reflow-model.c | 31 +++++---- widgets/misc/e-reflow-model.h | 32 ++++----- widgets/misc/e-reflow.h | 31 +++++---- widgets/misc/e-selection-model-array.c | 32 ++++----- widgets/misc/e-selection-model-array.h | 32 ++++----- widgets/misc/e-selection-model-simple.c | 32 ++++----- widgets/misc/e-selection-model-simple.h | 32 ++++----- widgets/misc/e-selection-model.c | 31 +++++---- widgets/misc/e-selection-model.h | 32 ++++----- widgets/misc/e-send-options.c | 28 ++++---- widgets/misc/e-send-options.h | 28 ++++---- widgets/misc/e-signature-combo-box.c | 19 +++--- widgets/misc/e-signature-combo-box.h | 19 +++--- widgets/misc/e-task-widget.h | 26 ++++---- widgets/misc/e-unicode.c | 31 ++++----- widgets/misc/test-calendar.c | 29 ++++---- widgets/misc/test-charset-picker.c | 20 ++++++ widgets/misc/test-color.c | 28 ++++---- widgets/misc/test-dateedit.c | 29 ++++---- widgets/misc/test-dropdown-button.c | 27 ++++---- widgets/misc/test-error.c | 27 ++++---- 65 files changed, 1034 insertions(+), 905 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 2d100b24ce..74ad227f47 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,10 +1,122 @@ -2008-08-30 Matthew Barnes +2008-09-06 Matthew Barnes ** Fixes part of bug #549968 * e-attachment-bar.c (e_attachment_bar_bonobo_ui_populate_with): Use the same mnemonic for "Recent Documents" as composer. +2008-09-06 Michael Meeks + + * e-spinner.c: correct licensing cockup; apologies. + * e-icon-entry.h: ditto. + +2008-09-04 Sankar P + +License Changes + + * e-calendar-item.c: + * e-charset-picker.c: + * e-config-page.c: + * e-dropdown-button.c: + * e-multi-config-dialog.c: + * e-multi-config-dialog.h: + * test-multi-config-dialog.c: + +2008-09-02 Sankar P + +License Changes + + * e-activity-handler.c: + * e-activity-handler.h: + * e-attachment-bar.h: + * e-attachment.h: + * e-calendar.h: + * e-canvas-background.h: + * e-canvas-utils.h: + * e-canvas-vbox.c: + * e-canvas-vbox.h: + * e-canvas.h: + * e-cell-date-edit.c: + * e-cell-renderer-combo.c: + * e-colors.h: + * e-combo-button.h: + * e-combo-cell-editable.c: + * e-config-page.h: + * e-cursors.c: + * e-dropdown-button.h: + * e-expander.h: + * e-filter-bar.c: + * e-filter-bar.h: + * e-gui-utils.c: + * e-gui-utils.h: + * e-image-chooser.c: + * e-info-label.c: + * e-map.c: + * e-pilot-settings.c: + * e-popup-menu.c: + * e-popup-menu.h: + * e-printable.c: + * e-reflow.h: + * e-selection-model.c: + * e-send-options.c: + * e-task-bar.c: + * e-task-bar.h: + * e-task-widget.h: + * e-unicode.c: + * test-calendar.c: + * test-dateedit.c: + * test-dropdown-button.c: + +2008-09-01 Matthew Barnes + + ** Fixes bug #550334 + + * e-activity-handler.c: + Use standard icon names for warning and information. + +2008-08-30 Matthew Barnes + + * e-info-label.c (e_info_label_set_info): + Fix vertical alignment of labels. + +2008-08-27 Sankar P + +License Changes + + * e-account-combo-box.c: + * e-account-combo-box.h: + * e-attachment.c: + * e-calendar-item.h: + * e-canvas-utils.c: + * e-cell-date-edit.h: + * e-cell-percent.h: + * e-cell-renderer-combo.h: + * e-charset-picker.h: + * e-combo-cell-editable.h: + * e-cursors.h: + * e-icon-entry.h: + * e-image-chooser.h: + * e-info-label.h: + * e-map.h: + * e-pilot-settings.h: + * e-printable.h: + * e-reflow-model.c: + * e-reflow-model.h: + * e-selection-model-array.c: + * e-selection-model-array.h: + * e-selection-model-simple.c: + * e-selection-model-simple.h: + * e-selection-model.h: + * e-send-options.h: + * e-signature-combo-box.c: + * e-signature-combo-box.h: + * e-spinner.c: + * e-spinner.h: + * test-charset-picker.c: + * test-color.c: + * test-error.c: + * test-info-label.c: + 2008-08-14 Matthew Barnes ** Fixes part of bug #547411 diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c index b6f92146e0..ebde2b5c0e 100644 --- a/widgets/misc/e-account-combo-box.c +++ b/widgets/misc/e-account-combo-box.c @@ -1,20 +1,21 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU Lesser General Public - * License as published by the Free Software Foundation. + * This program is 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 - * General Public License for more details. + * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include "e-account-combo-box.h" diff --git a/widgets/misc/e-account-combo-box.h b/widgets/misc/e-account-combo-box.h index 2bf84c163a..87f7eb9704 100644 --- a/widgets/misc/e-account-combo-box.h +++ b/widgets/misc/e-account-combo-box.h @@ -1,20 +1,21 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU Lesser General Public - * License as published by the Free Software Foundation. + * This program is 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 - * General Public License for more details. + * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef E_ACCOUNT_COMBO_BOX_H diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h index 4d6f136cbe..7f8b4795d1 100644 --- a/widgets/misc/e-attachment-bar.h +++ b/widgets/misc/e-attachment-bar.h @@ -1,25 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-attachment-bar.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * published by the Free Software Foundation; either version 2 of the - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: Ettore Perazzoli - * Srinivasa Ragavan + * Authors: + * Ettore Perazzoli + * Srinivasa Ragavan + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_ATTACHMENT_BAR_H__ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 44774a0ffa..073110571a 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1,24 +1,25 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* - * Authors: Ettore Perazzoli - * Jeffrey Stedfast - * Srinivasa Ragavan * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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 free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * 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. * - * 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 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 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: + * Ettore Perazzoli + * Jeffrey Stedfast + * Srinivasa Ragavan + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 958604fe7a..7b45f24ae5 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -1,25 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-attachment.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * published by the Free Software Foundation; either version 2 of the - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: Ettore Perazzoli - * Srinivasa Ragavan + * Authors: + * Ettore Perazzoli + * Srinivasa Ragavan + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_ATTACHMENT_H__ diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 2d7a78a5eb..3bf1fe65a7 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -1,32 +1,26 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * ECalendarItem - canvas item displaying a calendar. * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -/* - * ECalendarItem - canvas item displaying a calendar. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * Authors: + * Damon Chaplin + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ - #ifdef HAVE_CONFIG_H #include #endif diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h index 42efd5358f..b93ec9518d 100644 --- a/widgets/misc/e-calendar-item.h +++ b/widgets/misc/e-calendar-item.h @@ -1,25 +1,27 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + #ifndef _E_CALENDAR_ITEM_H_ #define _E_CALENDAR_ITEM_H_ diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h index 99902a8d0d..aebc615cfc 100644 --- a/widgets/misc/e-calendar.h +++ b/widgets/misc/e-calendar.h @@ -1,25 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ + #ifndef _E_CALENDAR_H_ #define _E_CALENDAR_H_ diff --git a/widgets/misc/e-canvas-background.h b/widgets/misc/e-canvas-background.h index afa2fb771a..5d75735c12 100644 --- a/widgets/misc/e-canvas-background.h +++ b/widgets/misc/e-canvas-background.h @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-canvas-background.h - background color for canvas. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef E_CANVAS_BACKGROUND_H diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c index 2e242b1c6d..c46f64c199 100644 --- a/widgets/misc/e-canvas-utils.c +++ b/widgets/misc/e-canvas-utils.c @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-canvas-utils.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include "e-canvas-utils.h" diff --git a/widgets/misc/e-canvas-utils.h b/widgets/misc/e-canvas-utils.h index fae54472ff..fa09a86c25 100644 --- a/widgets/misc/e-canvas-utils.h +++ b/widgets/misc/e-canvas-utils.h @@ -1,23 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_CANVAS_UTILS__ diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index 9c93c15f23..dfdfaf64dc 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-canvas-vbox.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h index 4422983844..51602e77de 100644 --- a/widgets/misc/e-canvas-vbox.h +++ b/widgets/misc/e-canvas-vbox.h @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-canvas-vbox.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_CANVAS_VBOX_H__ diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index 9be02115f3..e06bed7824 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-canvas.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_CANVAS_H__ diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c index 0748cec19e..824c8a1b20 100644 --- a/widgets/misc/e-cell-date-edit.c +++ b/widgets/misc/e-cell-date-edit.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/misc/e-cell-date-edit.h index 0bcb2395f7..938d356e8d 100644 --- a/widgets/misc/e-cell-date-edit.h +++ b/widgets/misc/e-cell-date-edit.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-cell-percent.h b/widgets/misc/e-cell-percent.h index a07c3b9409..46a7ddc3e3 100644 --- a/widgets/misc/e-cell-percent.h +++ b/widgets/misc/e-cell-percent.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-cell-renderer-combo.c b/widgets/misc/e-cell-renderer-combo.c index 09f80de663..96f474d0d9 100644 --- a/widgets/misc/e-cell-renderer-combo.c +++ b/widgets/misc/e-cell-renderer-combo.c @@ -1,23 +1,23 @@ /* - * e-cell-renderer-combo.c - * - * Author: Mike Kestner - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Mike Kestner + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/e-cell-renderer-combo.h b/widgets/misc/e-cell-renderer-combo.h index 056c62eb80..547eca7e7a 100644 --- a/widgets/misc/e-cell-renderer-combo.h +++ b/widgets/misc/e-cell-renderer-combo.h @@ -1,23 +1,24 @@ /* - * e-cell-renderer-combo.h - * - * Author: Mike Kestner - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Mike Kestner + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef __E_CELL_RENDERER_COMBO_H__ diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index f83ca36aa5..03014609ae 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -1,20 +1,21 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * + * Authors: + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index 5947304392..7250b10dfb 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -1,20 +1,20 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ diff --git a/widgets/misc/e-colors.h b/widgets/misc/e-colors.h index 5afe019a76..30ddfd496a 100644 --- a/widgets/misc/e-colors.h +++ b/widgets/misc/e-colors.h @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-colors.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Miguel de Icaza (miguel@kernel.org) + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Miguel de Icaza (miguel@kernel.org) + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef GNOME_APP_LIBS_COLOR_H diff --git a/widgets/misc/e-combo-cell-editable.c b/widgets/misc/e-combo-cell-editable.c index b4921db52e..5502a83a0d 100644 --- a/widgets/misc/e-combo-cell-editable.c +++ b/widgets/misc/e-combo-cell-editable.c @@ -1,23 +1,23 @@ /* - * e-combo-cell-editable.c - * - * Author: Mike Kestner - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Mike Kestner + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include diff --git a/widgets/misc/e-combo-cell-editable.h b/widgets/misc/e-combo-cell-editable.h index 447b8a8aa3..d3f64a36d3 100644 --- a/widgets/misc/e-combo-cell-editable.h +++ b/widgets/misc/e-combo-cell-editable.h @@ -1,23 +1,24 @@ /* - * e-combo-cell-editable.h - * - * Author: Mike Kestner - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Mike Kestner + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef __E_COMBO_CELL_EDITABLE_H__ diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index 95c511ed92..ac03e18e70 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-cursors.c - cursor handling for gnumeric - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Miguel de Icaza (miguel@gnu.org) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Miguel de Icaza (miguel@gnu.org) + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include diff --git a/widgets/misc/e-cursors.h b/widgets/misc/e-cursors.h index e0d20362bd..c22e295c7b 100644 --- a/widgets/misc/e-cursors.h +++ b/widgets/misc/e-cursors.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-cursors.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Miguel de Icaza (miguel@gnu.org) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Miguel de Icaza (miguel@gnu.org) + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef GNOME_APP_LIB_CURSORS_H diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c index ce9f02127f..32785a5e8f 100644 --- a/widgets/misc/e-dropdown-button.c +++ b/widgets/misc/e-dropdown-button.c @@ -1,25 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * * Authors: - * Ettore Perazzoli - * Damon Chaplin + * Ettore Perazzoli + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/e-dropdown-button.h b/widgets/misc/e-dropdown-button.h index e52c59457f..b10fd9a670 100644 --- a/widgets/misc/e-dropdown-button.h +++ b/widgets/misc/e-dropdown-button.h @@ -1,23 +1,23 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: Ettore Perazzoli + * Authors: + * Ettore Perazzoli + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef _E_DROPDOWN_BUTTON_H_ diff --git a/widgets/misc/e-expander.h b/widgets/misc/e-expander.h index b7aa330d28..6ddb68087e 100644 --- a/widgets/misc/e-expander.h +++ b/widgets/misc/e-expander.h @@ -1,24 +1,24 @@ -/* GTK - The GIMP Toolkit - * - * Copyright (C) 2003 Sun Microsystems, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public +/* + * 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) any later version. + * version 2 of the License, or (at your option) version 3. * - * This library is distributed in the hope that it will be useful, + * 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 - * Library General Public License for more details. + * 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 * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * * Authors: - * Mark McLoughlin + * Mark McLoughlin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2003 Sun Microsystems, Inc. + * */ #ifndef _E_EXPANDER_H_ diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index dc9863a8f5..c662460aba 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -1,29 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * e-search-bar.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Michael Zucchi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Michael Zucchi + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ - #ifdef HAVE_CONFIG_H #include #endif diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index ca53f3aeb0..edc20e2fec 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -1,22 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-filter-bar.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Author: Michael Zucchi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Michael Zucchi + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ + #ifndef E_FILTER_BAR_H #define E_FILTER_BAR_H diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c index d4a7888fb8..4e0b099944 100644 --- a/widgets/misc/e-gui-utils.c +++ b/widgets/misc/e-gui-utils.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-gui-utils.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Miguel de Icaza + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Miguel de Icaza + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-gui-utils.h b/widgets/misc/e-gui-utils.h index 1682041c4c..d0a54f7c42 100644 --- a/widgets/misc/e-gui-utils.h +++ b/widgets/misc/e-gui-utils.h @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-gui-utils.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Miguel de Icaza + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Miguel de Icaza + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef GAL_GUI_UTILS_H diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index d0c626c10f..8057d23aaa 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -1,21 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-image-chooser.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Author: Chris Toshok - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Chris Toshok + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h index bbf160f1c1..0e78026683 100644 --- a/widgets/misc/e-image-chooser.h +++ b/widgets/misc/e-image-chooser.h @@ -1,21 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-image-chooser.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Author: Chris Toshok +/* * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Chris Toshok + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef _E_IMAGE_CHOOSER_H_ diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index eb518c2434..347b97ca7c 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -1,23 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Map widget. - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: Hans Petter Jansson +/* + * Map widget. * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Hans Petter Jansson + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include diff --git a/widgets/misc/e-map.h b/widgets/misc/e-map.h index 34e4d775d5..4d65c7b47b 100644 --- a/widgets/misc/e-map.h +++ b/widgets/misc/e-map.h @@ -1,23 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Map widget. - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: Hans Petter Jansson +/* * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Hans Petter Jansson + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef E_MAP_H diff --git a/widgets/misc/e-pilot-settings.c b/widgets/misc/e-pilot-settings.c index c190aaf696..80ad52d083 100644 --- a/widgets/misc/e-pilot-settings.c +++ b/widgets/misc/e-pilot-settings.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-pilot-settings.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: JP Rosevear + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/e-pilot-settings.h b/widgets/misc/e-pilot-settings.h index f98a320da2..fbba3b2f71 100644 --- a/widgets/misc/e-pilot-settings.h +++ b/widgets/misc/e-pilot-settings.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-pilot-settings.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* * * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: JP Rosevear + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef _E_PILOT_SETTINGS_H_ diff --git a/widgets/misc/e-popup-menu.c b/widgets/misc/e-popup-menu.c index 1d370f2093..1581d3e409 100644 --- a/widgets/misc/e-popup-menu.c +++ b/widgets/misc/e-popup-menu.c @@ -1,26 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-popup-menu.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Miguel de Icaza - * Jody Goldberg (jgoldberg@home.com) - * Jeffrey Stedfast + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Miguel de Icaza + * Jody Goldberg (jgoldberg@home.com) + * Jeffrey Stedfast + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-popup-menu.h b/widgets/misc/e-popup-menu.h index 195c788505..c297bde53f 100644 --- a/widgets/misc/e-popup-menu.h +++ b/widgets/misc/e-popup-menu.h @@ -1,26 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-popup-menu.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Miguel de Icaza - * Jody Goldberg (jgoldberg@home.com) - * Jeffrey Stedfast + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Miguel de Icaza + * Jody Goldberg (jgoldberg@home.com) + * Jeffrey Stedfast + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef E_POPUP_MENU_H diff --git a/widgets/misc/e-printable.c b/widgets/misc/e-printable.c index 62de9a1847..f5392cc201 100644 --- a/widgets/misc/e-printable.c +++ b/widgets/misc/e-printable.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-printable.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-printable.h b/widgets/misc/e-printable.h index 5875de4baa..d0d3223dbf 100644 --- a/widgets/misc/e-printable.h +++ b/widgets/misc/e-printable.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-printable.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_PRINTABLE_H_ diff --git a/widgets/misc/e-reflow-model.c b/widgets/misc/e-reflow-model.c index 31747e6bcc..8f206e20c6 100644 --- a/widgets/misc/e-reflow-model.c +++ b/widgets/misc/e-reflow-model.c @@ -1,26 +1,25 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-reflow-model.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ - #include #include "e-util/e-util-marshal.h" diff --git a/widgets/misc/e-reflow-model.h b/widgets/misc/e-reflow-model.h index 1322057693..7482e5079f 100644 --- a/widgets/misc/e-reflow-model.h +++ b/widgets/misc/e-reflow-model.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-reflow-model.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_REFLOW_MODEL_H_ diff --git a/widgets/misc/e-reflow.h b/widgets/misc/e-reflow.h index 93c7b1ddf8..6d67369209 100644 --- a/widgets/misc/e-reflow.h +++ b/widgets/misc/e-reflow.h @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-reflow.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_REFLOW_H__ diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index 8f3398d982..f45923c1dd 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model-array.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index 7d0d9f5a47..abbf828374 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model-array.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_SELECTION_MODEL_ARRAY_H_ diff --git a/widgets/misc/e-selection-model-simple.c b/widgets/misc/e-selection-model-simple.c index 9ec0251ddd..88fa6f857f 100644 --- a/widgets/misc/e-selection-model-simple.c +++ b/widgets/misc/e-selection-model-simple.c @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model-simple.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include diff --git a/widgets/misc/e-selection-model-simple.h b/widgets/misc/e-selection-model-simple.h index e65724649d..2cd2ecabd3 100644 --- a/widgets/misc/e-selection-model-simple.h +++ b/widgets/misc/e-selection-model-simple.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model-simple.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_SELECTION_MODEL_SIMPLE_H_ diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index e8e4e52629..4e473f80bb 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index a1b5c38aaf..18bbc2a115 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -1,24 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-selection-model.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_SELECTION_MODEL_H_ diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index 33c80d6917..6c10a60c1c 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -1,21 +1,25 @@ -/* Evolution calendar - Main page of the Groupwise send options Dialog - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: Chenthill Palanisamy +/* + * Evolution calendar - Main page of the Groupwise send options Dialog * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Chenthill Palanisamy + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301. */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/e-send-options.h b/widgets/misc/e-send-options.h index 0b4a1d8b51..9a32357358 100644 --- a/widgets/misc/e-send-options.h +++ b/widgets/misc/e-send-options.h @@ -1,24 +1,26 @@ - /* Evolution calendar - Timezone selector dialog - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: Damon Chaplin +/* * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ - + #ifndef __E_SENDOPTIONS_DIALOG_H__ #define __E_SENDOPTIONS_DIALOG_H__ diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c index 522a400801..199a3ad51a 100644 --- a/widgets/misc/e-signature-combo-box.c +++ b/widgets/misc/e-signature-combo-box.c @@ -1,20 +1,21 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU Lesser General Public - * License as published by the Free Software Foundation. + * This program is 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 - * General Public License for more details. + * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include "e-signature-combo-box.h" diff --git a/widgets/misc/e-signature-combo-box.h b/widgets/misc/e-signature-combo-box.h index 14435d12b1..ec05c2b5d7 100644 --- a/widgets/misc/e-signature-combo-box.h +++ b/widgets/misc/e-signature-combo-box.h @@ -1,20 +1,21 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU Lesser General Public - * License as published by the Free Software Foundation. + * This program is 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 - * General Public License for more details. + * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef E_SIGNATURE_COMBO_BOX_H diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h index 0cc4ca5e20..a955da4bb1 100644 --- a/widgets/misc/e-task-widget.h +++ b/widgets/misc/e-task-widget.h @@ -1,23 +1,23 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-widget.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * - * Author: Ettore Perazzoli + * Authors: + * Ettore Perazzoli + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef _E_TASK_WIDGET_H_ diff --git a/widgets/misc/e-unicode.c b/widgets/misc/e-unicode.c index 85ee8f7596..a98154dd20 100644 --- a/widgets/misc/e-unicode.c +++ b/widgets/misc/e-unicode.c @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-unicode.c - utf-8 support functions for gal - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Lauris Kaplinski * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c index 307190c85d..1906c70ede 100644 --- a/widgets/misc/test-calendar.c +++ b/widgets/misc/test-calendar.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/test-charset-picker.c b/widgets/misc/test-charset-picker.c index 889bba2600..5b49e2d0f7 100644 --- a/widgets/misc/test-charset-picker.c +++ b/widgets/misc/test-charset-picker.c @@ -1,3 +1,23 @@ +/* + * + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + #include #include "e-charset-picker.h" diff --git a/widgets/misc/test-color.c b/widgets/misc/test-color.c index 66e0081177..f86166a228 100644 --- a/widgets/misc/test-color.c +++ b/widgets/misc/test-color.c @@ -1,23 +1,21 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * test-color.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c index d2d430ac16..da6a5953b1 100644 --- a/widgets/misc/test-dateedit.c +++ b/widgets/misc/test-dateedit.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c index c572af2102..38523c47b1 100644 --- a/widgets/misc/test-dropdown-button.c +++ b/widgets/misc/test-dropdown-button.c @@ -1,25 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-dropdown-menu.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * * Authors: - * Ettore Perazzoli - * Damon Chaplin + * Ettore Perazzoli + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/test-error.c b/widgets/misc/test-error.c index 5ebdb6a93e..84abd76ce3 100644 --- a/widgets/misc/test-error.c +++ b/widgets/misc/test-error.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - * - * test-error.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Author: Michael Zucchi +/* * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Authors: + * Michael Zucchi + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -- cgit v1.2.3 From 979203663083ef89f678dc1e95bc0c9b24f55a9e Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 18 Sep 2008 03:31:42 +0000 Subject: Progress update: - Kill EABMenu. - Centralize marshallers to eliminate duplication. svn path=/branches/kill-bonobo/; revision=36368 --- widgets/misc/e-dateedit.c | 1 - widgets/misc/e-image-chooser.c | 1 - widgets/misc/e-map.c | 2 +- widgets/misc/e-printable.c | 10 ++++------ widgets/misc/e-reflow-model.c | 4 +--- widgets/misc/e-reflow.c | 3 +-- widgets/misc/e-search-bar.c | 1 - widgets/misc/e-selection-model.c | 5 ++--- 8 files changed, 9 insertions(+), 18 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 82847d729e..1ffe823f4c 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -35,7 +35,6 @@ #endif #include "e-dateedit.h" -#include "e-util/e-util-marshal.h" #include #include diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index 8057d23aaa..20252f1b92 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -28,7 +28,6 @@ #include #include "e-image-chooser.h" -#include "e-util/e-util-marshal.h" #include "e-util/e-icon-factory.h" #include "e-util/e-util.h" diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index 347b97ca7c..f9742b597f 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -183,7 +183,7 @@ e_map_class_init (EMapClass *class) G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EMapClass, set_scroll_adjustments), NULL, NULL, - e_util_marshal_NONE__OBJECT_OBJECT, + e_marshal_NONE__OBJECT_OBJECT, G_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); diff --git a/widgets/misc/e-printable.c b/widgets/misc/e-printable.c index f5392cc201..7f2db7ecc4 100644 --- a/widgets/misc/e-printable.c +++ b/widgets/misc/e-printable.c @@ -24,8 +24,6 @@ #include -#include "e-util/e-util-marshal.h" - #include "e-util/e-util.h" #include "e-printable.h" @@ -57,7 +55,7 @@ e_printable_class_init (EPrintableClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EPrintableClass, print_page), NULL, NULL, - e_util_marshal_NONE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, + e_marshal_NONE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, G_TYPE_NONE, 4, G_TYPE_OBJECT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_BOOLEAN); @@ -67,7 +65,7 @@ e_printable_class_init (EPrintableClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EPrintableClass, data_left), NULL, NULL, - e_util_marshal_BOOLEAN__NONE, + e_marshal_BOOLEAN__NONE, G_TYPE_BOOLEAN, 0, G_TYPE_NONE); e_printable_signals [RESET] = @@ -85,7 +83,7 @@ e_printable_class_init (EPrintableClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EPrintableClass, height), NULL, NULL, - e_util_marshal_DOUBLE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, + e_marshal_DOUBLE__OBJECT_DOUBLE_DOUBLE_BOOLEAN, G_TYPE_DOUBLE, 4, G_TYPE_OBJECT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_BOOLEAN); @@ -95,7 +93,7 @@ e_printable_class_init (EPrintableClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EPrintableClass, will_fit), NULL, NULL, - e_util_marshal_BOOLEAN__OBJECT_DOUBLE_DOUBLE_BOOLEAN, + e_marshal_BOOLEAN__OBJECT_DOUBLE_DOUBLE_BOOLEAN, G_TYPE_BOOLEAN, 4, G_TYPE_OBJECT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_BOOLEAN); diff --git a/widgets/misc/e-reflow-model.c b/widgets/misc/e-reflow-model.c index 8f206e20c6..eae3d43324 100644 --- a/widgets/misc/e-reflow-model.c +++ b/widgets/misc/e-reflow-model.c @@ -22,8 +22,6 @@ */ #include -#include "e-util/e-util-marshal.h" - #include "e-util/e-util.h" #include "e-reflow-model.h" @@ -178,7 +176,7 @@ e_reflow_model_class_init (EReflowModelClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EReflowModelClass, model_items_inserted), NULL, NULL, - e_util_marshal_NONE__INT_INT, + e_marshal_NONE__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); e_reflow_model_signals [MODEL_ITEM_CHANGED] = diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index 2a2725c4ef..6fd7021b54 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -31,7 +31,6 @@ #include "text/e-text.h" #include -#include "e-util/e-util-marshal.h" #include "e-util/e-util.h" #include "misc/e-unicode.h" @@ -1470,7 +1469,7 @@ e_reflow_class_init (EReflowClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EReflowClass, selection_event), NULL, NULL, - e_util_marshal_INT__OBJECT_BOXED, + e_marshal_INT__OBJECT_BOXED, G_TYPE_INT, 2, G_TYPE_OBJECT, GDK_TYPE_EVENT); diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index fa8b099569..1cd67e8459 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index 4e473f80bb..697bb68096 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -25,7 +25,6 @@ #include #include -#include "e-util/e-util-marshal.h" #include "e-util/e-util.h" #include "e-selection-model.h" @@ -151,7 +150,7 @@ e_selection_model_class_init (ESelectionModelClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ESelectionModelClass, cursor_changed), NULL, NULL, - e_util_marshal_NONE__INT_INT, + e_marshal_NONE__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); e_selection_model_signals [CURSOR_ACTIVATED] = @@ -160,7 +159,7 @@ e_selection_model_class_init (ESelectionModelClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ESelectionModelClass, cursor_activated), NULL, NULL, - e_util_marshal_NONE__INT_INT, + e_marshal_NONE__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); e_selection_model_signals [SELECTION_CHANGED] = -- cgit v1.2.3 From 3e3c13b439668945241b32cf8c1fd3d6e625f9f5 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 19 Sep 2008 16:52:08 +0000 Subject: Replace EActivityHandler with a new activity-tracking system that uses EActivity objects instead of numeric handler IDs. Create an EActivity, configure it, and (optionally) connect to its "cancelled" and "completed" signals. Then hand it to the shell view via e_shell_view_add_activity(). When finished with the activity, call e_activity_finish() and unref it. svn path=/branches/kill-bonobo/; revision=36391 --- widgets/misc/Makefile.am | 8 +- widgets/misc/e-activity-proxy.c | 313 +++++++++++++++++++++++++++ widgets/misc/e-activity-proxy.h | 68 ++++++ widgets/misc/e-activity.c | 463 ++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-activity.h | 86 ++++++++ widgets/misc/e-task-widget.c | 273 ----------------------- widgets/misc/e-task-widget.h | 78 ------- 7 files changed, 935 insertions(+), 354 deletions(-) create mode 100644 widgets/misc/e-activity-proxy.c create mode 100644 widgets/misc/e-activity-proxy.h create mode 100644 widgets/misc/e-activity.c create mode 100644 widgets/misc/e-activity.h delete mode 100644 widgets/misc/e-task-widget.c delete mode 100644 widgets/misc/e-task-widget.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 0b7eca1f12..e5ddeecc06 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -37,8 +37,10 @@ widgetsinclude_HEADERS = \ $(pilot_headers) \ e-account-combo-box.h \ e-action-combo-box.h \ - e-attachment.h \ + e-activity.h \ + e-activity-proxy.h \ e-attachment-bar.h \ + e-attachment.h \ e-spinner.c \ e-spinner.h \ e-calendar.h \ @@ -58,7 +60,6 @@ widgetsinclude_HEADERS = \ e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ - e-task-widget.h \ e-send-options.h \ e-url-entry.h \ e-canvas-background.h \ @@ -84,6 +85,8 @@ libemiscwidgets_la_SOURCES = \ $(pilot_sources) \ e-account-combo-box.c \ e-action-combo-box.c \ + e-activity.c \ + e-activity-proxy.c \ e-calendar.c \ e-attachment.c \ e-attachment-bar.c \ @@ -103,7 +106,6 @@ libemiscwidgets_la_SOURCES = \ e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ - e-task-widget.c \ e-send-options.c \ e-url-entry.c \ e-canvas-background.c \ diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c new file mode 100644 index 0000000000..9ae9143bb7 --- /dev/null +++ b/widgets/misc/e-activity-proxy.c @@ -0,0 +1,313 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + * e-activity-proxy.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-activity-proxy.h" + +#include +#include + +#define E_ACTIVITY_PROXY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyPrivate)) + +struct _EActivityProxyPrivate { + EActivity *activity; + GtkWidget *image; + GtkWidget *label; + GtkWidget *button; + GtkWidget *spinner; +}; + +enum { + PROP_0, + PROP_ACTIVITY +}; + +static gpointer parent_class; + +static void +activity_proxy_update (EActivityProxy *proxy) +{ + EActivity *activity = proxy->priv->activity; + const gchar *icon_name; + gboolean cancellable; + gboolean cancelled; + gboolean completed; + gboolean sensitive; + gchar *description; + + cancellable = e_activity_get_cancellable (activity); + cancelled = e_activity_is_cancelled (activity); + completed = e_activity_is_completed (activity); + icon_name = e_activity_get_icon_name (activity); + + description = e_activity_describe (activity); + gtk_widget_set_tooltip_text (GTK_WIDGET (proxy), description); + gtk_label_set_text (GTK_LABEL (proxy->priv->label), description); + g_free (description); + + if (icon_name != NULL) { + gtk_image_set_from_icon_name ( + GTK_IMAGE (proxy->priv->image), + icon_name, GTK_ICON_SIZE_MENU); + e_spinner_stop (E_SPINNER (proxy->priv->spinner)); + gtk_widget_show (proxy->priv->image); + gtk_widget_hide (proxy->priv->spinner); + } else { + e_spinner_start (E_SPINNER (proxy->priv->spinner)); + gtk_widget_show (proxy->priv->spinner); + gtk_widget_hide (proxy->priv->image); + } + + if (cancellable) + gtk_widget_show (proxy->priv->button); + else + gtk_widget_hide (proxy->priv->button); + + sensitive = !(cancelled || completed); + gtk_widget_set_sensitive (proxy->priv->button, sensitive); +} + +static void +activity_proxy_set_activity (EActivityProxy *proxy, + EActivity *activity) +{ + g_return_if_fail (proxy->priv->activity == NULL); + + proxy->priv->activity = g_object_ref (activity); +} + +static void +activity_proxy_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVITY: + activity_proxy_set_activity ( + E_ACTIVITY_PROXY (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +activity_proxy_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVITY: + g_value_set_object ( + value, e_activity_proxy_get_activity ( + E_ACTIVITY_PROXY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +activity_proxy_dispose (GObject *object) +{ + EActivityProxyPrivate *priv; + + priv = E_ACTIVITY_PROXY_GET_PRIVATE (object); + + if (priv->activity != NULL) { + g_object_unref (priv->activity); + priv->activity = NULL; + } + + if (priv->image != NULL) { + g_object_unref (priv->image); + priv->image = NULL; + } + + if (priv->label != NULL) { + g_object_unref (priv->label); + priv->label = NULL; + } + + if (priv->button != NULL) { + g_object_unref (priv->button); + priv->button = NULL; + } + + if (priv->spinner != NULL) { + g_object_unref (priv->spinner); + priv->spinner = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +activity_proxy_constructed (GObject *object) +{ + EActivityProxy *proxy; + + proxy = E_ACTIVITY_PROXY (object); + + g_signal_connect_swapped ( + proxy->priv->button, "clicked", + G_CALLBACK (e_activity_cancel), proxy->priv->activity); + + g_signal_connect_swapped ( + proxy->priv->activity, "cancelled", + G_CALLBACK (activity_proxy_update), proxy); + + g_signal_connect_swapped ( + proxy->priv->activity, "completed", + G_CALLBACK (activity_proxy_update), proxy); + + g_signal_connect_swapped ( + proxy->priv->activity, "notify", + G_CALLBACK (activity_proxy_update), proxy); + + activity_proxy_update (proxy); +} + +static void +activity_proxy_class_init (EActivityProxyClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EActivityProxyPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = activity_proxy_set_property; + object_class->get_property = activity_proxy_get_property; + object_class->dispose = activity_proxy_dispose; + object_class->constructed = activity_proxy_constructed; + + g_object_class_install_property ( + object_class, + PROP_ACTIVITY, + g_param_spec_object ( + "activity", + NULL, + NULL, + E_TYPE_ACTIVITY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +activity_proxy_init (EActivityProxy *proxy) +{ + GtkWidget *container; + GtkWidget *widget; + + proxy->priv = E_ACTIVITY_PROXY_GET_PRIVATE (proxy); + + container = GTK_WIDGET (proxy); + + widget = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_hbox_new (FALSE, 3); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_spinner_new (); + e_spinner_set_size (E_SPINNER (widget), GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + proxy->priv->spinner = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + proxy->priv->image = g_object_ref (widget); + gtk_widget_hide (widget); + + widget = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + proxy->priv->label = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_button_new (); + gtk_button_set_image ( + GTK_BUTTON (widget), gtk_image_new_from_stock ( + GTK_STOCK_STOP, GTK_ICON_SIZE_MENU)); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_set_tooltip_text (widget, _("Cancel")); + proxy->priv->button = g_object_ref (widget); + gtk_widget_show (widget); +} + +GType +e_activity_proxy_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EActivityProxyClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) activity_proxy_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EActivityProxy), + 0, /* n_preallocs */ + (GInstanceInitFunc) activity_proxy_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_EVENT_BOX, "EActivityProxy", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_activity_proxy_new (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); + + return g_object_new ( + E_TYPE_ACTIVITY_PROXY, + "activity", activity, NULL); +} + +EActivity * +e_activity_proxy_get_activity (EActivityProxy *proxy) +{ + g_return_val_if_fail (E_IS_ACTIVITY_PROXY (proxy), NULL); + + return proxy->priv->activity; +} diff --git a/widgets/misc/e-activity-proxy.h b/widgets/misc/e-activity-proxy.h new file mode 100644 index 0000000000..bc9e97dfeb --- /dev/null +++ b/widgets/misc/e-activity-proxy.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + * e-activity-proxy.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef E_ACTIVITY_PROXY_H +#define E_ACTIVITY_PROXY_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ACTIVITY_PROXY \ + (e_activity_proxy_get_type ()) +#define E_ACTIVITY_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxy)) +#define E_ACTIVITY_PROXY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass)) +#define E_IS_ACTIVITY_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ACTIVITY_PROXY)) +#define E_IS_ACTIVITY_PROXY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ACTIVITY_PROXY)) +#define E_ACTIVITY_PROXY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass)) + +G_BEGIN_DECLS + +typedef struct _EActivityProxy EActivityProxy; +typedef struct _EActivityProxyClass EActivityProxyClass; +typedef struct _EActivityProxyPrivate EActivityProxyPrivate; + +struct _EActivityProxy { + GtkEventBox parent; + EActivityProxyPrivate *priv; +}; + +struct _EActivityProxyClass { + GtkEventBoxClass parent_class; +}; + +GType e_activity_proxy_get_type (void); +GtkWidget * e_activity_proxy_new (EActivity *activity); +EActivity * e_activity_proxy_get_activity (EActivityProxy *proxy); + +G_END_DECLS + +#endif /* E_ACTIVITY_PROXY_H */ diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c new file mode 100644 index 0000000000..251efbb758 --- /dev/null +++ b/widgets/misc/e-activity.c @@ -0,0 +1,463 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + * e-activity.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-activity.h" + +#include + +#define E_ACTIVITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ACTIVITY, EActivityPrivate)) + +struct _EActivityPrivate { + gchar *icon_name; + gchar *primary_text; + gchar *secondary_text; + gdouble percent; + gboolean cancellable; + guint cancelled : 1; + guint completed : 1; +}; + +enum { + PROP_0, + PROP_CANCELLABLE, + PROP_ICON_NAME, + PROP_PERCENT, + PROP_PRIMARY_TEXT, + PROP_SECONDARY_TEXT +}; + +enum { + CANCELLED, + COMPLETED, + LAST_SIGNAL +}; + +static gpointer parent_class; +static gulong signals[LAST_SIGNAL]; + +static void +activity_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CANCELLABLE: + e_activity_set_cancellable ( + E_ACTIVITY (object), + g_value_get_boolean (value)); + return; + + case PROP_ICON_NAME: + e_activity_set_icon_name ( + E_ACTIVITY (object), + g_value_get_string (value)); + return; + + case PROP_PERCENT: + e_activity_set_percent ( + E_ACTIVITY (object), + g_value_get_double (value)); + return; + + case PROP_PRIMARY_TEXT: + e_activity_set_primary_text ( + E_ACTIVITY (object), + g_value_get_string (value)); + return; + + case PROP_SECONDARY_TEXT: + e_activity_set_secondary_text ( + E_ACTIVITY (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +activity_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CANCELLABLE: + g_value_set_boolean ( + value, e_activity_get_cancellable ( + E_ACTIVITY (object))); + return; + + case PROP_ICON_NAME: + g_value_set_string ( + value, e_activity_get_icon_name ( + E_ACTIVITY (object))); + return; + + case PROP_PERCENT: + g_value_set_double ( + value, e_activity_get_percent ( + E_ACTIVITY (object))); + return; + + case PROP_PRIMARY_TEXT: + g_value_set_string ( + value, e_activity_get_primary_text ( + E_ACTIVITY (object))); + return; + + case PROP_SECONDARY_TEXT: + g_value_set_string ( + value, e_activity_get_secondary_text ( + E_ACTIVITY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +activity_finalize (GObject *object) +{ + EActivityPrivate *priv; + + priv = E_ACTIVITY_GET_PRIVATE (object); + + g_free (priv->icon_name); + g_free (priv->primary_text); + g_free (priv->secondary_text); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +activity_class_init (EActivityClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EActivityPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = activity_set_property; + object_class->get_property = activity_get_property; + object_class->finalize = activity_finalize; + + g_object_class_install_property ( + object_class, + PROP_CANCELLABLE, + g_param_spec_boolean ( + "cancellable", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_ICON_NAME, + g_param_spec_string ( + "icon-name", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_PERCENT, + g_param_spec_double ( + "percent", + NULL, + NULL, + -G_MAXDOUBLE, + G_MAXDOUBLE, + -1.0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_PRIMARY_TEXT, + g_param_spec_string ( + "primary-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SECONDARY_TEXT, + g_param_spec_string ( + "secondary-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + signals[CANCELLED] = g_signal_new ( + "cancelled", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[COMPLETED] = g_signal_new ( + "completed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +activity_init (EActivity *activity) +{ + activity->priv = E_ACTIVITY_GET_PRIVATE (activity); +} + +GType +e_activity_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EActivityClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) activity_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EActivity), + 0, /* n_preallocs */ + (GInstanceInitFunc) activity_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EActivity", &type_info, 0); + } + + return type; +} + +EActivity * +e_activity_new (const gchar *primary_text) +{ + return g_object_new ( + E_TYPE_ACTIVITY, + "primary-text", primary_text, NULL); +} + +void +e_activity_cancel (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + g_return_if_fail (activity->priv->cancellable); + + if (activity->priv->cancelled) + return; + + if (activity->priv->completed) + return; + + activity->priv->cancelled = TRUE; + g_signal_emit (activity, signals[CANCELLED], 0); +} + +void +e_activity_complete (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (activity->priv->cancelled) + return; + + if (activity->priv->completed) + return; + + activity->priv->completed = TRUE; + g_signal_emit (activity, signals[COMPLETED], 0); +} + +gchar * +e_activity_describe (EActivity *activity) +{ + GString *string; + const gchar *text; + gboolean cancelled; + gboolean completed; + gdouble percent; + + g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); + + string = g_string_sized_new (256); + text = e_activity_get_primary_text (activity); + cancelled = e_activity_is_cancelled (activity); + completed = e_activity_is_completed (activity); + percent = e_activity_get_percent (activity); + + if (cancelled) { + /* Translators: This is a cancelled activity. */ + g_string_printf (string, _("%s (cancelled)"), text); + } else if (completed) { + /* Translators: This is a completed activity. */ + g_string_printf (string, _("%s (completed)"), text); + } else if (percent < 0.0) { + /* Translators: This is an activity whose percent + * complete is unknown. */ + g_string_printf (string, _("%s (...)"), text); + } else { + /* Translators: This is an activity whose percent + * complete is known. */ + g_string_printf ( + string, _("%s (%d%% complete"), text, + (gint) (percent * 100.0 + 0.5)); + } + + return g_string_free (string, FALSE); +} + +gboolean +e_activity_is_cancelled (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + return activity->priv->cancelled; +} + +gboolean +e_activity_is_completed (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + return activity->priv->completed; +} + +gboolean +e_activity_get_cancellable (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + return activity->priv->cancellable; +} + +void +e_activity_set_cancellable (EActivity *activity, + gboolean cancellable) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + activity->priv->cancellable = cancellable; + + g_object_notify (G_OBJECT (activity), "cancellable"); +} + +const gchar * +e_activity_get_icon_name (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); + + return activity->priv->icon_name; +} + +void +e_activity_set_icon_name (EActivity *activity, + const gchar *icon_name) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_free (activity->priv->icon_name); + activity->priv->icon_name = g_strdup (icon_name); + + g_object_notify (G_OBJECT (activity), "icon-name"); +} + +gdouble +e_activity_get_percent (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), -1.0); + + return activity->priv->percent; +} + +void +e_activity_set_percent (EActivity *activity, + gdouble percent) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + activity->priv->percent = percent; + + g_object_notify (G_OBJECT (activity), "percent"); +} + +const gchar * +e_activity_get_primary_text (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); + + return activity->priv->primary_text; +} + +void +e_activity_set_primary_text (EActivity *activity, + const gchar *primary_text) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_free (activity->priv->primary_text); + activity->priv->primary_text = g_strdup (primary_text); + + g_object_notify (G_OBJECT (activity), "primary-text"); +} + +const gchar * +e_activity_get_secondary_text (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); + + return activity->priv->secondary_text; +} + +void +e_activity_set_secondary_text (EActivity *activity, + const gchar *secondary_text) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_free (activity->priv->secondary_text); + activity->priv->secondary_text = g_strdup (secondary_text); + + g_object_notify (G_OBJECT (activity), "secondary-text"); +} diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h new file mode 100644 index 0000000000..b88ba58dfb --- /dev/null +++ b/widgets/misc/e-activity.h @@ -0,0 +1,86 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + * e-activity.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef E_ACTIVITY_H +#define E_ACTIVITY_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ACTIVITY \ + (e_activity_get_type ()) +#define E_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ACTIVITY, EActivity)) +#define E_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ACTIVITY, EActivityClass)) +#define E_IS_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ACTIVITY)) +#define E_IS_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ACTIVITY)) +#define E_ACTIVITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ACTIVITY, EActivityClass)) + +G_BEGIN_DECLS + +typedef struct _EActivity EActivity; +typedef struct _EActivityClass EActivityClass; +typedef struct _EActivityPrivate EActivityPrivate; + +struct _EActivity { + GObject parent; + EActivityPrivate *priv; +}; + +struct _EActivityClass { + GObjectClass parent_class; +}; + +GType e_activity_get_type (void); +EActivity * e_activity_new (const gchar *primary_text); +void e_activity_cancel (EActivity *activity); +void e_activity_complete (EActivity *activity); +gchar * e_activity_describe (EActivity *activity); +gboolean e_activity_is_cancelled (EActivity *activity); +gboolean e_activity_is_completed (EActivity *activity); +gboolean e_activity_get_cancellable (EActivity *activity); +void e_activity_set_cancellable (EActivity *activity, + gboolean cancellable); +const gchar * e_activity_get_icon_name (EActivity *activity); +void e_activity_set_icon_name (EActivity *activity, + const gchar *icon_name); +gdouble e_activity_get_percent (EActivity *activity); +void e_activity_set_percent (EActivity *activity, + gdouble percent); +const gchar * e_activity_get_primary_text (EActivity *activity); +void e_activity_set_primary_text (EActivity *activity, + const gchar *primary_text); +const gchar * e_activity_get_secondary_text (EActivity *activity); +void e_activity_set_secondary_text (EActivity *activity, + const gchar *secondary_text); + +G_END_DECLS + +#endif /* E_ACTIVITY_H */ diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c deleted file mode 100644 index fe500ae778..0000000000 --- a/widgets/misc/e-task-widget.c +++ /dev/null @@ -1,273 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-widget.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-task-widget.h" -#include "e-spinner.h" - -#include - - -#define SPACING 2 - -struct _ETaskWidgetPrivate { - GtkWidget *label; - GtkWidget *box; - GtkWidget *image; - - void (*cancel_func) (gpointer data); - gpointer data; -}; - -G_DEFINE_TYPE (ETaskWidget, e_task_widget, GTK_TYPE_EVENT_BOX) - -/* GObject methods. */ - -static void -impl_finalize (GObject *object) -{ - ETaskWidget *task_widget; - ETaskWidgetPrivate *priv; - - task_widget = E_TASK_WIDGET (object); - priv = task_widget->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_task_widget_parent_class)->finalize) (object); -} - - -static void -e_task_widget_class_init (ETaskWidgetClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = impl_finalize; -} - -static void -e_task_widget_init (ETaskWidget *task_widget) -{ - ETaskWidgetPrivate *priv; - - priv = g_new (ETaskWidgetPrivate, 1); - - priv->label = NULL; - priv->image = NULL; - priv->box = NULL; - - task_widget->priv = priv; - task_widget->id = 0; -} - -static gboolean -button_press_event_cb (GtkWidget *w, gpointer data) -{ - ETaskWidget *tw = (ETaskWidget *) data; - ETaskWidgetPrivate *priv = tw->priv; - - priv->cancel_func (priv->data); - - return TRUE; -} - -static gboolean -prepare_popup (ETaskWidget *widget, GdkEventButton *event) -{ - if (event->type != GDK_BUTTON_PRESS) - return FALSE; - - if (event->button != 3) - return FALSE; - - /* FIXME: Implement Cancel */ - - return TRUE; -} - - -void -e_task_widget_construct (ETaskWidget *task_widget, - const char *information, - void (*cancel_func) (gpointer data), - gpointer data) -{ - ETaskWidgetPrivate *priv; - GtkWidget *box; - GtkWidget *frame; - - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - g_return_if_fail (information != NULL); - - priv = task_widget->priv; - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (task_widget), frame); - gtk_widget_show (frame); - - box = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), box); - gtk_widget_show (box); - - gtk_widget_set_size_request (box, 1, -1); - - priv->box = gtk_hbox_new (FALSE, 0); - priv->image = e_spinner_new (); - e_spinner_set_size (E_SPINNER (priv->image), GTK_ICON_SIZE_SMALL_TOOLBAR); - e_spinner_start (E_SPINNER (priv->image)); - gtk_widget_show (priv->image); - gtk_widget_show (priv->box); - gtk_box_pack_start (GTK_BOX (priv->box), priv->image, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (box), priv->box, FALSE, TRUE, 0); - priv->label = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5); - gtk_widget_show (priv->label); - gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0); - if (cancel_func) { - GdkPixbuf *pixbuf; - GtkWidget *image; - GtkWidget *tool; - - pixbuf = gtk_icon_theme_load_icon ( - gtk_icon_theme_get_default (), - "gtk-stop", 16, 0, NULL); - image = gtk_image_new_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - - tool = (GtkWidget *) gtk_tool_button_new (image, NULL); - gtk_box_pack_end (GTK_BOX (box), tool, FALSE, TRUE, 0); - gtk_widget_show_all (tool); - - gtk_widget_set_sensitive (tool, cancel_func != NULL); - priv->cancel_func = cancel_func; - priv->data = data; - g_signal_connect (tool, "clicked", G_CALLBACK (button_press_event_cb), task_widget); - g_signal_connect (task_widget, "button-press-event", G_CALLBACK (prepare_popup), task_widget); - - } - - e_task_widget_update (task_widget, information, -1.0); -} - -GtkWidget * -e_task_widget_new_with_cancel (const char *information, - void (*cancel_func) (gpointer data), - gpointer data) -{ - ETaskWidget *task_widget; - - g_return_val_if_fail (information != NULL, NULL); - - task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, information, cancel_func, data); - - return GTK_WIDGET (task_widget); -} - -GtkWidget * -e_task_widget_new (const char *information) -{ - ETaskWidget *task_widget; - - g_return_val_if_fail (information != NULL, NULL); - - task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, information, NULL, NULL); - - return GTK_WIDGET (task_widget); -} - -GtkWidget * -e_task_widget_update_image (ETaskWidget *task_widget, - const char *stock, const char *text) -{ - GtkWidget *image, *tool; - GdkPixbuf *pixbuf; - - pixbuf = gtk_icon_theme_load_icon ( - gtk_icon_theme_get_default (), - stock, 16, 0, NULL); - image = gtk_image_new_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - - tool = (GtkWidget *) gtk_tool_button_new (image, NULL); - gtk_box_pack_start (GTK_BOX(task_widget->priv->box), tool, FALSE, TRUE, 0); - gtk_widget_show_all (task_widget->priv->box); - gtk_widget_hide (task_widget->priv->image); - task_widget->priv->image = image; - gtk_label_set_text (GTK_LABEL (task_widget->priv->label), text); - - return tool; -} - - -void -e_task_widget_update (ETaskWidget *task_widget, - const char *information, - double completion) -{ - ETaskWidgetPrivate *priv; - char *text; - - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - g_return_if_fail (information != NULL); - - priv = task_widget->priv; - - if (completion < 0.0) { - /* For Translator only: %s is status message that is displayed (eg "moving items", "updating objects") */ - text = g_strdup_printf (_("%s (...)"), information); - } else { - int percent_complete; - percent_complete = (int) (completion * 100.0 + .5); - /* For Translator only: %s is status message that is displayed (eg "moving items", "updating objects"); - %d is a number between 0 and 100, describing the percentage of operation complete */ - text = g_strdup_printf (_("%s (%d%% complete)"), information, percent_complete); - } - - gtk_label_set_text (GTK_LABEL (priv->label), text); - - gtk_widget_set_tooltip_text (GTK_WIDGET (task_widget), text); - - g_free (text); -} - -void -e_task_wiget_alert (ETaskWidget *task_widget) -{ - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); -} - -void -e_task_wiget_unalert (ETaskWidget *task_widget) -{ - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); -} diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h deleted file mode 100644 index a955da4bb1..0000000000 --- a/widgets/misc/e-task-widget.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_TASK_WIDGET_H_ -#define _E_TASK_WIDGET_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_TASK_WIDGET (e_task_widget_get_type ()) -#define E_TASK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASK_WIDGET, ETaskWidget)) -#define E_TASK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TASK_WIDGET, ETaskWidgetClass)) -#define E_IS_TASK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASK_WIDGET)) -#define E_IS_TASK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_TASK_WIDGET)) - - -typedef struct _ETaskWidget ETaskWidget; -typedef struct _ETaskWidgetPrivate ETaskWidgetPrivate; -typedef struct _ETaskWidgetClass ETaskWidgetClass; - -struct _ETaskWidget { - GtkEventBox parent; - - ETaskWidgetPrivate *priv; - guint id; -}; - -struct _ETaskWidgetClass { - GtkEventBoxClass parent_class; -}; - - -GType e_task_widget_get_type (void); -void e_task_widget_construct (ETaskWidget *task_widget, - const char *information, - void (*cancel_func) (gpointer data), - gpointer data); -GtkWidget * e_task_widget_new (const char *information); -GtkWidget * e_task_widget_new_with_cancel (const char *information, - void (*cancel_func) (gpointer data), - gpointer data); -void e_task_widget_update (ETaskWidget *task_widget, - const char *information, - double completion); -GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget, - const char *stock, - const char *text); -void e_task_wiget_alert (ETaskWidget *task_widget); -void e_task_wiget_unalert (ETaskWidget *task_widget); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_TASK_WIDGET_H_ */ -- cgit v1.2.3 From 6b2295c93a40f6010d94399666a8e099aded8e85 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 19 Sep 2008 18:21:06 +0000 Subject: Fix some miscellaneous address book bugs. Kill e-shell-constants.h. svn path=/branches/kill-bonobo/; revision=36392 --- widgets/misc/e-menu-tool-button.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c index f2ff6ded44..70e64d8124 100644 --- a/widgets/misc/e-menu-tool-button.c +++ b/widgets/misc/e-menu-tool-button.c @@ -58,12 +58,14 @@ menu_tool_button_get_first_menu_item (GtkMenuToolButton *menu_tool_button) } static void -menu_tool_button_update_icon (GtkToolButton *tool_button) +menu_tool_button_update_button (GtkToolButton *tool_button) { GtkMenuItem *menu_item; GtkMenuToolButton *menu_tool_button; GtkImageMenuItem *image_menu_item; + GtkAction *action; GtkWidget *image; + gchar *tooltip = NULL; menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button); menu_item = menu_tool_button_get_first_menu_item (menu_tool_button); @@ -78,6 +80,14 @@ menu_tool_button_update_icon (GtkToolButton *tool_button) image = menu_tool_button_clone_image (image); gtk_tool_button_set_icon_widget (tool_button, image); gtk_widget_show (image); + + /* If the menu item is a proxy for a GtkAction, extract + * the action's tooltip and use it as our own tooltip. */ + action = gtk_widget_get_action (GTK_WIDGET (menu_item)); + if (action != NULL) + g_object_get (action, "tooltip", &tooltip, NULL); + gtk_widget_set_tooltip_text (GTK_WIDGET (tool_button), tooltip); + g_free (tooltip); } static void @@ -109,7 +119,7 @@ menu_tool_button_init (EMenuToolButton *button) { g_signal_connect ( button, "notify::menu", - G_CALLBACK (menu_tool_button_update_icon), NULL); + G_CALLBACK (menu_tool_button_update_button), NULL); } GType -- cgit v1.2.3 From 73c370019c4de89d4c901ee8c25cc0cbb55992fb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 22 Sep 2008 21:03:28 +0000 Subject: Search UI is kinda sorta working. Still some outstanding issues. svn path=/branches/kill-bonobo/; revision=36427 --- widgets/misc/e-icon-entry.c | 149 +++++++++++++++++++++++++++++++++++++------- widgets/misc/e-icon-entry.h | 3 + 2 files changed, 129 insertions(+), 23 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index 1c9ed12d96..86e42488a7 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -39,10 +39,16 @@ ((obj), E_TYPE_ICON_ENTRY, EIconEntryPrivate)) struct _EIconEntryPrivate { + GtkStateType visual_state; GtkWidget *entry; GtkWidget *hbox; }; +enum { + PROP_0, + PROP_VISUAL_STATE +}; + static gpointer parent_class; static void @@ -64,6 +70,7 @@ icon_entry_create_proxy (GtkAction *action) { GtkWidget *proxy; GtkWidget *widget; + gchar *tooltip; proxy = gtk_event_box_new (); gtk_event_box_set_visible_window (GTK_EVENT_BOX (proxy), FALSE); @@ -74,6 +81,10 @@ icon_entry_create_proxy (GtkAction *action) gtk_container_add (GTK_CONTAINER (proxy), widget); gtk_widget_show (widget); + g_object_get (action, "tooltip", &tooltip, NULL); + gtk_widget_set_tooltip_text (proxy, tooltip); + g_free (tooltip); + g_signal_connect_swapped ( proxy, "button-press-event", G_CALLBACK (gtk_action_activate), action); @@ -122,54 +133,89 @@ icon_entry_get_borders (GtkWidget *widget, static void icon_entry_paint (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { EIconEntry *entry = E_ICON_ENTRY (widget); GtkWidget *entry_widget = entry->priv->entry; int x = 0, y = 0, width, height, focus_width; gboolean interior_focus; - gtk_widget_style_get (entry_widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - NULL); + gtk_widget_style_get ( + entry_widget, + "interior-focus", &interior_focus, + "focus-line-width", &focus_width, NULL); gdk_drawable_get_size (widget->window, &width, &height); - if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) - { + if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) { x += focus_width; y += focus_width; width -= 2 * focus_width; height -= 2 * focus_width; } - gtk_paint_flat_box (entry_widget->style, widget->window, - GTK_WIDGET_STATE (entry_widget), GTK_SHADOW_NONE, - NULL, entry_widget, "entry_bg", - /* FIXME: was 0, 0 in gtk_entry_expose, but I think this is correct: */ - x, y, width, height); + gtk_paint_flat_box ( + entry_widget->style, widget->window, + GTK_WIDGET_STATE (entry_widget), GTK_SHADOW_NONE, + NULL, entry_widget, "entry_bg", + /* FIXME: was 0, 0 in gtk_entry_expose, but I think this is correct: */ + x, y, width, height); - gtk_paint_shadow (entry_widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - NULL, entry_widget, "entry", - x, y, width, height); + gtk_paint_shadow ( + entry_widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_IN, + NULL, entry_widget, "entry", + x, y, width, height); - if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) - { + if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) { x -= focus_width; y -= focus_width; width += 2 * focus_width; height += 2 * focus_width; - gtk_paint_focus (entry_widget->style, widget->window, - GTK_WIDGET_STATE (entry_widget), - NULL, entry_widget, "entry", - /* FIXME: was 0, 0 in gtk_entry_draw_frame, but I think this is correct: */ - x, y, width, height); + gtk_paint_focus ( + entry_widget->style, widget->window, + GTK_WIDGET_STATE (entry_widget), + NULL, entry_widget, "entry", + /* FIXME: was 0, 0 in gtk_entry_draw_frame, but I think this is correct: */ + x, y, width, height); } } +static void +icon_entry_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_VISUAL_STATE: + e_icon_entry_set_visual_state ( + E_ICON_ENTRY (object), + g_value_get_enum (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +icon_entry_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_VISUAL_STATE: + g_value_set_enum ( + value, e_icon_entry_get_visual_state ( + E_ICON_ENTRY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + static void icon_entry_dispose (GObject *object) { @@ -324,6 +370,8 @@ icon_entry_class_init (EIconEntryClass *class) g_type_class_add_private (class, sizeof (EIconEntryPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = icon_entry_set_property; + object_class->get_property = icon_entry_get_property; object_class->dispose = icon_entry_dispose; widget_class = GTK_WIDGET_CLASS (class); @@ -331,6 +379,17 @@ icon_entry_class_init (EIconEntryClass *class) widget_class->size_request = icon_entry_size_request; widget_class->size_allocate = icon_entry_size_allocate; widget_class->expose_event = icon_entry_expose; + + g_object_class_install_property ( + object_class, + PROP_VISUAL_STATE, + g_param_spec_enum ( + "visual-state", + NULL, + NULL, + GTK_TYPE_STATE_TYPE, + GTK_STATE_NORMAL, + G_PARAM_READWRITE)); } static void @@ -340,6 +399,7 @@ icon_entry_init (EIconEntry *icon_entry) GtkWidget *container; icon_entry->priv = E_ICON_ENTRY_GET_PRIVATE (icon_entry); + icon_entry->priv->visual_state = GTK_STATE_NORMAL; GTK_WIDGET_UNSET_FLAGS (icon_entry, GTK_NO_WINDOW); @@ -438,3 +498,46 @@ e_icon_entry_add_action_end (EIconEntry *icon_entry, proxy = icon_entry_create_proxy (action); gtk_box_pack_end (box, proxy, FALSE, FALSE, 2); } + +GtkStateType +e_icon_entry_get_visual_state (EIconEntry *icon_entry) +{ + g_return_val_if_fail (E_IS_ICON_ENTRY (icon_entry), GTK_STATE_NORMAL); + + return icon_entry->priv->visual_state; +} + +void +e_icon_entry_set_visual_state (EIconEntry *icon_entry, + GtkStateType visual_state) +{ + GtkWidget *widget; + const GdkColor *base_color; + const GdkColor *text_color; + + g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); + + if (visual_state == GTK_STATE_NORMAL) { + base_color = NULL; + text_color = NULL; + } else { + GtkStyle *style; + + style = gtk_widget_get_default_style (); + base_color = &style->base[visual_state]; + text_color = &style->text[visual_state]; + } + + widget = GTK_WIDGET (icon_entry); + gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); + + widget = icon_entry->priv->entry; + gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); + gtk_widget_modify_text (widget, GTK_STATE_NORMAL, text_color); + + widget = icon_entry->priv->hbox; + gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); + + icon_entry->priv->visual_state = visual_state; + g_object_notify (G_OBJECT (icon_entry), "visual-state"); +} diff --git a/widgets/misc/e-icon-entry.h b/widgets/misc/e-icon-entry.h index 110720ab19..65aff61978 100644 --- a/widgets/misc/e-icon-entry.h +++ b/widgets/misc/e-icon-entry.h @@ -82,6 +82,9 @@ void e_icon_entry_add_action_start (EIconEntry *entry, GtkAction *action); void e_icon_entry_add_action_end (EIconEntry *entry, GtkAction *action); +GtkStateType e_icon_entry_get_visual_state (EIconEntry *entry); +void e_icon_entry_set_visual_state (EIconEntry *entry, + GtkStateType visual_state); G_END_DECLS -- cgit v1.2.3 From c261a99bc4765ccb99206ed6105a323698b514c7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 30 Sep 2008 03:25:23 +0000 Subject: Memos are mostly working now. Tasks to follow. svn path=/branches/kill-bonobo/; revision=36495 --- widgets/misc/e-action-combo-box.c | 52 +++++++++++++++++++++++++++++++++++++-- widgets/misc/e-action-combo-box.h | 3 +++ 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c index 5e32268431..e826fb2a54 100644 --- a/widgets/misc/e-action-combo-box.c +++ b/widgets/misc/e-action-combo-box.c @@ -98,6 +98,10 @@ action_combo_box_render_pixbuf (GtkCellLayout *layout, gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + /* A NULL action means the row is a separator. */ + if (action == NULL) + return; + g_object_get ( G_OBJECT (action), "icon-name", &icon_name, @@ -134,6 +138,10 @@ action_combo_box_render_text (GtkCellLayout *layout, gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + /* A NULL action means the row is a separator. */ + if (action == NULL) + return; + g_object_get ( G_OBJECT (action), "label", &label, @@ -157,6 +165,22 @@ action_combo_box_render_text (GtkCellLayout *layout, g_free (label); } +static gboolean +action_combo_box_is_row_separator (GtkTreeModel *model, + GtkTreeIter *iter) +{ + GtkAction *action; + gboolean separator; + + /* NULL actions are rendered as separators. */ + gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + separator = (action == NULL); + if (action != NULL) + g_object_unref (action); + + return separator; +} + static void action_combo_box_update_model (EActionComboBox *combo_box) { @@ -170,8 +194,11 @@ action_combo_box_update_model (EActionComboBox *combo_box) return; } + /* We store values in the sort column as floats so that we can + * insert separators in between consecutive integer values and + * still maintain the proper ordering. */ list_store = gtk_list_store_new ( - 2, GTK_TYPE_RADIO_ACTION, G_TYPE_INT); + 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT); list = gtk_radio_action_get_group (combo_box->priv->action); @@ -186,7 +213,7 @@ action_combo_box_update_model (EActionComboBox *combo_box) g_object_get (G_OBJECT (action), "value", &value, NULL); gtk_list_store_set ( list_store, &iter, COLUMN_ACTION, - list->data, COLUMN_SORT, value, -1); + list->data, COLUMN_SORT, (gfloat) value, -1); path = gtk_tree_model_get_path ( GTK_TREE_MODEL (list_store), &iter); @@ -349,6 +376,10 @@ action_combo_box_init (EActionComboBox *combo_box) (GtkCellLayoutDataFunc) action_combo_box_render_text, combo_box, NULL); + gtk_combo_box_set_row_separator_func ( + GTK_COMBO_BOX (combo_box), (GtkTreeViewRowSeparatorFunc) + action_combo_box_is_row_separator, NULL, NULL); + combo_box->priv->index = g_hash_table_new_full ( g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, @@ -477,3 +508,20 @@ e_action_combo_box_set_current_value (EActionComboBox *combo_box, gtk_radio_action_set_current_value ( combo_box->priv->action, current_value); } + +void +e_action_combo_box_add_separator_after (EActionComboBox *combo_box, + gint action_value) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); + + /* NULL actions are rendered as separators. */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, COLUMN_ACTION, + NULL, COLUMN_SORT, (gfloat) action_value + 0.5, -1); +} diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h index 452c3fa265..7327c4723b 100644 --- a/widgets/misc/e-action-combo-box.h +++ b/widgets/misc/e-action-combo-box.h @@ -73,6 +73,9 @@ gint e_action_combo_box_get_current_value void e_action_combo_box_set_current_value (EActionComboBox *combo_box, gint current_value); +void e_action_combo_box_add_separator_after + (EActionComboBox *combo_box, + gint action_value); G_END_DECLS -- cgit v1.2.3 From b2cda1d0c6d44f53f71bad9e256f41188677dfba Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Oct 2008 20:56:04 +0000 Subject: Merge revisions 36016:36533 from trunk. svn path=/branches/kill-bonobo/; revision=36534 --- widgets/misc/ChangeLog | 65 ++++++++++++++++++++++++++++++++++++++ widgets/misc/e-attachment-bar.c | 32 +++++++++---------- widgets/misc/e-attachment.c | 3 +- widgets/misc/e-calendar.c | 31 +++++++++--------- widgets/misc/e-canvas-background.c | 31 +++++++++--------- widgets/misc/e-canvas.c | 31 +++++++++--------- widgets/misc/e-cell-percent.c | 29 ++++++++--------- widgets/misc/e-colors.c | 31 +++++++++--------- widgets/misc/e-dateedit.c | 32 ++++++++----------- widgets/misc/e-expander.c | 28 ++++++++-------- widgets/misc/e-online-button.c | 21 ++++++------ widgets/misc/e-online-button.h | 21 ++++++------ widgets/misc/e-search-bar.c | 34 ++++++++++---------- widgets/misc/e-unicode.h | 31 +++++++++--------- 14 files changed, 237 insertions(+), 183 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 74ad227f47..57e1d25b7a 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,68 @@ +2008-10-01 Milan Crha + + ** Part of fix for bug #554418 + + * e-attachment.c: (attachment_guess_mime_type): + Allow guessing mime_type based on the file content. + +2008-10-01 Sankar P + +License Changes + + * e-canvas-background.c: + * e-dateedit.c: + +2008-09-30 Sankar P + +License Changes + + * e-expander.c: + +2008-09-29 Milan Crha + + ** Part of fix for bug #530716 + + * e-activity-handler.c: (error_cleanup): GtkDialog errors close + by the response message, not as other widgets, because creator + of the dialog waits for that signal and takes care of the widget. + +2008-09-29 Sankar P + +License Changes + + * e-colors.c: + +2008-09-24 Sankar P + +License Changes + + * e-canvas.c: + * e-combo-button.c: + +2008-09-19 Sankar P + +License Changes + + * e-attachment-bar.c: + * e-search-bar.c: + * e-search-bar.h: + * e-task-widget.c: + +2008-09-16 Sankar P + +License Changes + + * e-calendar.c: + * e-cell-percent.c: + * e-unicode.h: + +2008-09-12 Sankar P + +License Changes + + * e-online-button.c: + * e-online-button.h: + 2008-09-06 Matthew Barnes ** Fixes part of bug #549968 diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 4536ab0233..1e41a95338 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -1,24 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* - * Authors: Ettore Perazzoli - * Jeffrey Stedfast - * Srinivasa Ragavan + * 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. * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * 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 General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Authors: + * Ettore Perazzoli + * Jeffrey Stedfast + * Srinivasa Ragavan + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 073110571a..4f5e9ace34 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -229,8 +229,7 @@ attachment_guess_mime_type (const char *file_name) char *type; gchar *content = NULL; - type = e_util_guess_mime_type (file_name); - + type = e_util_guess_mime_type (file_name, TRUE); if (type && strcmp (type, "text/directory") == 0 && file_ext_is (file_name, ".vcf") && diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index 4e79343027..824a79d4e0 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -1,25 +1,24 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c index 1a3722848c..77cad661e1 100644 --- a/widgets/misc/e-canvas-background.c +++ b/widgets/misc/e-canvas-background.c @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-canvas-background.c - background color for canvas. - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 5ef3000e8d..a395197df7 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-canvas.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #include diff --git a/widgets/misc/e-cell-percent.c b/widgets/misc/e-cell-percent.c index e09e730206..ee83d60def 100644 --- a/widgets/misc/e-cell-percent.c +++ b/widgets/misc/e-cell-percent.c @@ -1,24 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-colors.c b/widgets/misc/e-colors.c index ec4f1e77ea..c9c72d06d7 100644 --- a/widgets/misc/e-colors.c +++ b/widgets/misc/e-colors.c @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-colors.c - General color allocation utilities - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Miguel de Icaza (miguel@kernel.org) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Miguel de Icaza + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* We keep our own color context, as the color allocation might take diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 1ffe823f4c..f11ecbe029 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -1,27 +1,23 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - /* - * Author : - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Based on the GnomeDateEdit, part of the Gnome Library. - * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation - * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 General Public License for more details. + * 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 + * + * + * Authors: + * Damon Chaplin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA */ /* diff --git a/widgets/misc/e-expander.c b/widgets/misc/e-expander.c index 7886e23859..771598739d 100644 --- a/widgets/misc/e-expander.c +++ b/widgets/misc/e-expander.c @@ -1,24 +1,26 @@ -/* GTK - The GIMP Toolkit +/* + * GTK - The GIMP Toolkit * - * Copyright (C) 2003 Sun Microsystems, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * 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) any later version. + * version 2 of the License, or (at your option) version 3. * - * This library is distributed in the hope that it will be useful, + * 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 - * Library General Public License for more details. + * 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 * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. * * Authors: - * Mark McLoughlin + * Mark McLoughlin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2003 Sun Microsystems, Inc. + * */ #include diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c index 346aec2857..dec24a6587 100644 --- a/widgets/misc/e-online-button.c +++ b/widgets/misc/e-online-button.c @@ -1,21 +1,18 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-offline-button.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ #include "e-online-button.h" diff --git a/widgets/misc/e-online-button.h b/widgets/misc/e-online-button.h index b9b03e1ffc..6576035a9d 100644 --- a/widgets/misc/e-online-button.h +++ b/widgets/misc/e-online-button.h @@ -1,21 +1,18 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-online-button.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ #ifndef E_ONLINE_BUTTON_H diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 1cd67e8459..050f840fa8 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -1,27 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-search-bar.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Chris Lahey - * Ettore Perazzoli - * Jon Trowbridge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Authors: + * Chris Lahey + * Ettore Perazzoli + * Jon Trowbridge + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-search-bar.h" diff --git a/widgets/misc/e-unicode.h b/widgets/misc/e-unicode.h index 9ef0578b2f..b745876b6d 100644 --- a/widgets/misc/e-unicode.h +++ b/widgets/misc/e-unicode.h @@ -1,24 +1,25 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * e-unicode.h - utf-8 support functions for gal - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Authors: - * Lauris Kaplinski * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * 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 library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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 - * Library General Public License for more details. + * 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 + * + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _E_UNICODE_H_ -- cgit v1.2.3 From 791c982c456fca453978358d2e919082419b7808 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Oct 2008 21:51:10 +0000 Subject: Update the headers on files I've created or completely rewritten to match Sankar's LGPLv3 template. svn path=/branches/kill-bonobo/; revision=36535 --- widgets/misc/e-activity-proxy.c | 16 ++++++++-------- widgets/misc/e-activity-proxy.h | 16 ++++++++-------- widgets/misc/e-activity.c | 16 ++++++++-------- widgets/misc/e-activity.h | 16 ++++++++-------- widgets/misc/e-menu-tool-button.c | 23 ++++++++++++----------- widgets/misc/e-menu-tool-button.h | 23 ++++++++++++----------- widgets/misc/e-preferences-window.c | 23 ++++++++++++----------- widgets/misc/e-preferences-window.h | 23 ++++++++++++----------- widgets/misc/test-preferences-window.c | 23 ++++++++++++----------- 9 files changed, 92 insertions(+), 87 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index 9ae9143bb7..56b8ed33d4 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -1,8 +1,6 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- +/* * e-activity-proxy.c * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * 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 @@ -11,12 +9,14 @@ * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-activity-proxy.h" diff --git a/widgets/misc/e-activity-proxy.h b/widgets/misc/e-activity-proxy.h index bc9e97dfeb..af305be4fe 100644 --- a/widgets/misc/e-activity-proxy.h +++ b/widgets/misc/e-activity-proxy.h @@ -1,8 +1,6 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- +/* * e-activity-proxy.h * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * 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 @@ -11,12 +9,14 @@ * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef E_ACTIVITY_PROXY_H diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 251efbb758..434225a5a2 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -1,8 +1,6 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- +/* * e-activity.c * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * 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 @@ -11,12 +9,14 @@ * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-activity.h" diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index b88ba58dfb..48a19ff91d 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -1,8 +1,6 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- +/* * e-activity.h * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * * 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 @@ -11,12 +9,14 @@ * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef E_ACTIVITY_H diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c index 70e64d8124..5e87de8175 100644 --- a/widgets/misc/e-menu-tool-button.c +++ b/widgets/misc/e-menu-tool-button.c @@ -1,21 +1,22 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-menu-tool-button.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* + * e-menu-tool-button.c * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-menu-tool-button.h" diff --git a/widgets/misc/e-menu-tool-button.h b/widgets/misc/e-menu-tool-button.h index 110c9af9d1..b10cf3a62f 100644 --- a/widgets/misc/e-menu-tool-button.h +++ b/widgets/misc/e-menu-tool-button.h @@ -1,21 +1,22 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-menu-tool-button.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* + * e-menu-tool-button.h * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ /* EMenuToolButton is a variation of GtkMenuToolButton where the diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 1ccd07d91e..7ae9fdf596 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -1,21 +1,22 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-preferences-window.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* + * e-preferences-window.c * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-preferences-window.h" diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h index 2a1ec921c8..39f2b82b89 100644 --- a/widgets/misc/e-preferences-window.h +++ b/widgets/misc/e-preferences-window.h @@ -1,21 +1,22 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-preferences-window.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* + * e-preferences-window.h * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef E_PREFERENCES_WINDOW_H diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c index dc3d40be59..8bd8aa8950 100644 --- a/widgets/misc/test-preferences-window.c +++ b/widgets/misc/test-preferences-window.c @@ -1,21 +1,22 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* test-preferences-window.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) +/* + * test-preferences-window.c * * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * 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 - * General Public License for more details. + * 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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #include "e-preferences-window.c" -- cgit v1.2.3 From 79aa45cfed7e87150de85869795ef0dd3be06db0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 13 Oct 2008 17:57:46 +0000 Subject: Progress update: - Calendar is kind of a mess at the moment. Doesn't compile. - Roughed in the Mail module, including all the actions. That _does_ compile. Runs, even. svn path=/branches/kill-bonobo/; revision=36611 --- widgets/misc/e-calendar.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h index aebc615cfc..1330eb4cf3 100644 --- a/widgets/misc/e-calendar.h +++ b/widgets/misc/e-calendar.h @@ -39,9 +39,24 @@ extern "C" { * to got to the current day. */ -#define E_CALENDAR(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_get_type (), ECalendar) -#define E_CALENDAR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_get_type (), ECalendarClass) -#define E_IS_CALENDAR(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_get_type ()) +/* Standard GObject macros */ +#define E_TYPE_CALENDAR \ + (e_calendar_get_type ()) +#define E_CALENDAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CALENDAR, ECalendar)) +#define E_CALENDAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CALENDAR, ECalendarClass)) +#define E_IS_CALENDAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CALENDAR)) +#define E_IS_CALENDAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CALENDAR)) +#define E_CALENDAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CALENDAR, ECalendarClass)) typedef struct _ECalendar ECalendar; -- cgit v1.2.3 From 54b80a7271e8ce1b2f3ccc68bb553940a24b80e2 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 17 Oct 2008 03:48:03 +0000 Subject: Get the mail folder tree compiling, though I'm not yet sure why it's not showing anything. Probably something stupid. Also enabled the composer. svn path=/branches/kill-bonobo/; revision=36623 --- widgets/misc/e-activity-proxy.c | 59 ++++++--- widgets/misc/e-activity.c | 264 +++++++++++++++++++++++++++++++++++++++- widgets/misc/e-activity.h | 18 ++- 3 files changed, 320 insertions(+), 21 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index 56b8ed33d4..6ce89016cd 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -30,9 +30,10 @@ struct _EActivityProxyPrivate { EActivity *activity; + GtkWidget *button; GtkWidget *image; GtkWidget *label; - GtkWidget *button; + GtkWidget *cancel; GtkWidget *spinner; }; @@ -50,12 +51,14 @@ activity_proxy_update (EActivityProxy *proxy) const gchar *icon_name; gboolean cancellable; gboolean cancelled; + gboolean clickable; gboolean completed; gboolean sensitive; gchar *description; cancellable = e_activity_get_cancellable (activity); cancelled = e_activity_is_cancelled (activity); + clickable = e_activity_get_clickable (activity); completed = e_activity_is_completed (activity); icon_name = e_activity_get_icon_name (activity); @@ -64,26 +67,39 @@ activity_proxy_update (EActivityProxy *proxy) gtk_label_set_text (GTK_LABEL (proxy->priv->label), description); g_free (description); + /* Note, an activity requires an icon name in order to + * be clickable. We don't support spinner buttons. */ if (icon_name != NULL) { gtk_image_set_from_icon_name ( GTK_IMAGE (proxy->priv->image), icon_name, GTK_ICON_SIZE_MENU); + gtk_button_set_image ( + GTK_BUTTON (proxy->priv->button), + gtk_image_new_from_icon_name ( + icon_name, GTK_ICON_SIZE_MENU)); e_spinner_stop (E_SPINNER (proxy->priv->spinner)); - gtk_widget_show (proxy->priv->image); gtk_widget_hide (proxy->priv->spinner); + if (clickable) { + gtk_widget_show (proxy->priv->button); + gtk_widget_hide (proxy->priv->image); + } else { + gtk_widget_hide (proxy->priv->button); + gtk_widget_show (proxy->priv->image); + } } else { e_spinner_start (E_SPINNER (proxy->priv->spinner)); gtk_widget_show (proxy->priv->spinner); + gtk_widget_hide (proxy->priv->button); gtk_widget_hide (proxy->priv->image); } if (cancellable) - gtk_widget_show (proxy->priv->button); + gtk_widget_show (proxy->priv->cancel); else - gtk_widget_hide (proxy->priv->button); + gtk_widget_hide (proxy->priv->cancel); sensitive = !(cancelled || completed); - gtk_widget_set_sensitive (proxy->priv->button, sensitive); + gtk_widget_set_sensitive (proxy->priv->cancel, sensitive); } static void @@ -141,6 +157,11 @@ activity_proxy_dispose (GObject *object) priv->activity = NULL; } + if (priv->button != NULL) { + g_object_unref (priv->button); + priv->image = NULL; + } + if (priv->image != NULL) { g_object_unref (priv->image); priv->image = NULL; @@ -151,9 +172,9 @@ activity_proxy_dispose (GObject *object) priv->label = NULL; } - if (priv->button != NULL) { - g_object_unref (priv->button); - priv->button = NULL; + if (priv->cancel != NULL) { + g_object_unref (priv->cancel); + priv->cancel = NULL; } if (priv->spinner != NULL) { @@ -174,6 +195,10 @@ activity_proxy_constructed (GObject *object) g_signal_connect_swapped ( proxy->priv->button, "clicked", + G_CALLBACK (e_activity_clicked), proxy->priv->activity); + + g_signal_connect_swapped ( + proxy->priv->cancel, "clicked", G_CALLBACK (e_activity_cancel), proxy->priv->activity); g_signal_connect_swapped ( @@ -240,18 +265,24 @@ activity_proxy_init (EActivityProxy *proxy) container = widget; + widget = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + proxy->priv->image = g_object_ref (widget); + gtk_widget_hide (widget); + + widget = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + proxy->priv->button = g_object_ref (widget); + gtk_widget_hide (widget); + widget = e_spinner_new (); e_spinner_set_size (E_SPINNER (widget), GTK_ICON_SIZE_MENU); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); proxy->priv->spinner = g_object_ref (widget); gtk_widget_show (widget); - widget = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - proxy->priv->image = g_object_ref (widget); - gtk_widget_hide (widget); - widget = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); proxy->priv->label = g_object_ref (widget); @@ -264,7 +295,7 @@ activity_proxy_init (EActivityProxy *proxy) gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); gtk_widget_set_tooltip_text (widget, _("Cancel")); - proxy->priv->button = g_object_ref (widget); + proxy->priv->cancel = g_object_ref (widget); gtk_widget_show (widget); } diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 434225a5a2..7905c4062f 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -32,14 +32,20 @@ struct _EActivityPrivate { gchar *primary_text; gchar *secondary_text; gdouble percent; - gboolean cancellable; - guint cancelled : 1; - guint completed : 1; + guint timeout_id; + + guint blocking : 1; + guint cancellable : 1; + guint cancelled : 1; + guint clickable : 1; + guint completed : 1; }; enum { PROP_0, + PROP_BLOCKING, PROP_CANCELLABLE, + PROP_CLICKABLE, PROP_ICON_NAME, PROP_PERCENT, PROP_PRIMARY_TEXT, @@ -48,13 +54,23 @@ enum { enum { CANCELLED, + CLICKED, COMPLETED, + TIMEOUT, LAST_SIGNAL }; static gpointer parent_class; static gulong signals[LAST_SIGNAL]; +static gboolean +activity_timeout_cb (EActivity *activity) +{ + g_signal_emit (activity, signals[TIMEOUT], 0); + + return FALSE; +} + static void activity_set_property (GObject *object, guint property_id, @@ -62,12 +78,24 @@ activity_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_BLOCKING: + e_activity_set_blocking ( + E_ACTIVITY (object), + g_value_get_boolean (value)); + return; + case PROP_CANCELLABLE: e_activity_set_cancellable ( E_ACTIVITY (object), g_value_get_boolean (value)); return; + case PROP_CLICKABLE: + e_activity_set_clickable ( + E_ACTIVITY (object), + g_value_get_boolean (value)); + return; + case PROP_ICON_NAME: e_activity_set_icon_name ( E_ACTIVITY (object), @@ -103,12 +131,24 @@ activity_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_BLOCKING: + g_value_set_boolean ( + value, e_activity_get_blocking ( + E_ACTIVITY (object))); + return; + case PROP_CANCELLABLE: g_value_set_boolean ( value, e_activity_get_cancellable ( E_ACTIVITY (object))); return; + case PROP_CLICKABLE: + g_value_set_boolean ( + value, e_activity_get_clickable ( + E_ACTIVITY (object))); + return; + case PROP_ICON_NAME: g_value_set_string ( value, e_activity_get_icon_name ( @@ -148,6 +188,9 @@ activity_finalize (GObject *object) g_free (priv->primary_text); g_free (priv->secondary_text); + if (priv->timeout_id > 0) + g_source_remove (priv->timeout_id); + /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -165,6 +208,17 @@ activity_class_init (EActivityClass *class) object_class->get_property = activity_get_property; object_class->finalize = activity_finalize; + g_object_class_install_property ( + object_class, + PROP_BLOCKING, + g_param_spec_boolean ( + "blocking", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property ( object_class, PROP_CANCELLABLE, @@ -176,6 +230,17 @@ activity_class_init (EActivityClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property ( + object_class, + PROP_CLICKABLE, + g_param_spec_boolean ( + "clickable", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property ( object_class, PROP_ICON_NAME, @@ -225,7 +290,15 @@ activity_class_init (EActivityClass *class) signals[CANCELLED] = g_signal_new ( "cancelled", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CLICKED] = g_signal_new ( + "clicked", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -233,7 +306,15 @@ activity_class_init (EActivityClass *class) signals[COMPLETED] = g_signal_new ( "completed", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[TIMEOUT] = g_signal_new ( + "timeout", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -310,6 +391,14 @@ e_activity_complete (EActivity *activity) g_signal_emit (activity, signals[COMPLETED], 0); } +void +e_activity_clicked (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_signal_emit (activity, signals[CLICKED], 0); +} + gchar * e_activity_describe (EActivity *activity) { @@ -336,7 +425,7 @@ e_activity_describe (EActivity *activity) } else if (percent < 0.0) { /* Translators: This is an activity whose percent * complete is unknown. */ - g_string_printf (string, _("%s (...)"), text); + g_string_printf (string, _("%s..."), text); } else { /* Translators: This is an activity whose percent * complete is known. */ @@ -364,6 +453,48 @@ e_activity_is_completed (EActivity *activity) return activity->priv->completed; } +void +e_activity_add_timeout (EActivity *activity, + guint seconds) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + e_activity_cancel_timeout (activity); + + activity->priv->timeout_id = g_timeout_add_seconds ( + seconds, (GSourceFunc) activity_timeout_cb, activity); +} + +void +e_activity_cancel_timeout (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (activity->priv->timeout_id > 0) { + g_source_remove (activity->priv->timeout_id); + activity->priv->timeout_id = 0; + } +} + +gboolean +e_activity_get_blocking (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + return activity->priv->blocking; +} + +void +e_activity_set_blocking (EActivity *activity, + gboolean blocking) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + activity->priv->blocking = blocking; + + g_object_notify (G_OBJECT (activity), "blocking"); +} + gboolean e_activity_get_cancellable (EActivity *activity) { @@ -383,6 +514,25 @@ e_activity_set_cancellable (EActivity *activity, g_object_notify (G_OBJECT (activity), "cancellable"); } +gboolean +e_activity_get_clickable (EActivity *activity) +{ + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + return activity->priv->clickable; +} + +void +e_activity_set_clickable (EActivity *activity, + gboolean clickable) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + activity->priv->clickable = clickable; + + g_object_notify (G_OBJECT (activity), "clickable"); +} + const gchar * e_activity_get_icon_name (EActivity *activity) { @@ -461,3 +611,105 @@ e_activity_set_secondary_text (EActivity *activity, g_object_notify (G_OBJECT (activity), "secondary-text"); } + +/************************* Error Dialog Integration **************************/ + +void +e_activity_error (EActivity *activity, + GtkWidget *error_dialog) +{ + GObject *object; + const gchar *primary_text; + const gchar *secondary_text; + + /* XXX Convert an activity to a clickable error message. + * Clicking on the activity completes it and displays + * the error dialog. Eventually I'd like to eliminate + * error dialogs altogether and show errors directly + * in the shell window. */ + + g_return_if_fail (E_IS_ACTIVITY (activity)); + g_return_if_fail (GTK_IS_DIALOG (error_dialog)); + + object = G_OBJECT (error_dialog); + primary_text = g_object_get_data (object, "primary"); + secondary_text = g_object_get_data (object, "secondary"); + + e_activity_set_primary_text (activity, primary_text); + e_activity_set_secondary_text (activity, secondary_text); + e_activity_set_icon_name (activity, "dialog-warning"); + e_activity_set_clickable (activity, TRUE); + + g_signal_connect ( + activity, "cancelled", + G_CALLBACK (e_activity_cancel_timeout), NULL); + + g_signal_connect ( + activity, "completed", + G_CALLBACK (e_activity_cancel_timeout), NULL); + + g_signal_connect ( + activity, "clicked", + G_CALLBACK (e_activity_complete), NULL); + + g_signal_connect_swapped ( + activity, "clicked", + G_CALLBACK (gtk_dialog_run), error_dialog); + + g_signal_connect ( + activity, "timeout", + G_CALLBACK (e_activity_complete), NULL); + + /* XXX Allow for a configurable timeout. */ + e_activity_add_timeout (activity, 60); +} + +void +e_activity_info (EActivity *activity, + GtkWidget *info_dialog) +{ + GObject *object; + const gchar *primary_text; + const gchar *secondary_text; + + /* XXX Convert an activity to a clickable info message. + * Clicking on the activity completes it and displays + * the info dialog. Eventually I'd like to eliminate + * info dialogs altogether and show errors directly + * in the shell window. */ + + g_return_if_fail (E_IS_ACTIVITY (activity)); + g_return_if_fail (GTK_IS_DIALOG (info_dialog)); + + object = G_OBJECT (info_dialog); + primary_text = g_object_get_data (object, "primary"); + secondary_text = g_object_get_data (object, "secondary"); + + e_activity_set_primary_text (activity, primary_text); + e_activity_set_secondary_text (activity, secondary_text); + e_activity_set_icon_name (activity, "dialog-warning"); + e_activity_set_clickable (activity, TRUE); + + g_signal_connect ( + activity, "cancelled", + G_CALLBACK (e_activity_cancel_timeout), NULL); + + g_signal_connect ( + activity, "completed", + G_CALLBACK (e_activity_cancel_timeout), NULL); + + g_signal_connect ( + activity, "clicked", + G_CALLBACK (e_activity_complete), NULL); + + g_signal_connect_swapped ( + activity, "clicked", + G_CALLBACK (gtk_dialog_run), info_dialog); + + g_signal_connect ( + activity, "timeout", + G_CALLBACK (e_activity_complete), NULL); + + /* XXX Allow for a configurable timeout. */ + e_activity_add_timeout (activity, 60); +} diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index 48a19ff91d..d949860333 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -22,7 +22,7 @@ #ifndef E_ACTIVITY_H #define E_ACTIVITY_H -#include +#include /* Standard GObject macros */ #define E_TYPE_ACTIVITY \ @@ -62,12 +62,22 @@ GType e_activity_get_type (void); EActivity * e_activity_new (const gchar *primary_text); void e_activity_cancel (EActivity *activity); void e_activity_complete (EActivity *activity); +void e_activity_clicked (EActivity *activity); gchar * e_activity_describe (EActivity *activity); gboolean e_activity_is_cancelled (EActivity *activity); gboolean e_activity_is_completed (EActivity *activity); +void e_activity_add_timeout (EActivity *activity, + guint seconds); +void e_activity_cancel_timeout (EActivity *activity); +gboolean e_activity_get_blocking (EActivity *activity); +void e_activity_set_blocking (EActivity *activity, + gboolean blocking); gboolean e_activity_get_cancellable (EActivity *activity); void e_activity_set_cancellable (EActivity *activity, gboolean cancellable); +gboolean e_activity_get_clickable (EActivity *activity); +void e_activity_set_clickable (EActivity *activity, + gboolean clickable); const gchar * e_activity_get_icon_name (EActivity *activity); void e_activity_set_icon_name (EActivity *activity, const gchar *icon_name); @@ -81,6 +91,12 @@ const gchar * e_activity_get_secondary_text (EActivity *activity); void e_activity_set_secondary_text (EActivity *activity, const gchar *secondary_text); +/* XXX Hacky integration with error dialogs. */ +void e_activity_error (EActivity *activity, + GtkWidget *error_dialog); +void e_activity_info (EActivity *activity, + GtkWidget *info_dialog); + G_END_DECLS #endif /* E_ACTIVITY_H */ -- cgit v1.2.3 From 85b2913a380c69f14ae0254ad23b10fabfb33667 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 24 Oct 2008 23:52:05 +0000 Subject: Merge revisions 36534:36684 from trunk. svn path=/branches/kill-bonobo/; revision=36685 --- widgets/misc/ChangeLog | 21 +++++++++ widgets/misc/e-dateedit.c | 14 +++--- widgets/misc/e-dateedit.h | 9 ++-- widgets/misc/e-reflow.c | 50 +++++++++------------ widgets/misc/e-spinner.c | 110 ++++++++++++++++++++++++---------------------- widgets/misc/e-spinner.h | 35 +-------------- 6 files changed, 110 insertions(+), 129 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 57e1d25b7a..85ec90411f 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,24 @@ +2008-10-21 Sankar P + + * e-spinner.c (e_spinner_stop), + (e_spinner_new_spinning_small_shown): + * e-spinner.h: + * e-task-widget.c (e_task_widget_construct): + Re-factor spinner usage. + +2008-10-17 Sankar P + +License Changes + + * e-dateedit.c: + * e-dateedit.h: + +2008-10-10 Sankar P + +License Changes + code cleanup + + * e-reflow.c (e_reflow_event), (e_reflow_init): + 2008-10-01 Milan Crha ** Part of fix for bug #554418 diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index f11ecbe029..272223025e 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -1,23 +1,21 @@ /* - * 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 library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library 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 + * You should have received a copy of the GNU Library General Public * License along with the program; if not, see * - * * Authors: * Damon Chaplin * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * */ /* diff --git a/widgets/misc/e-dateedit.h b/widgets/misc/e-dateedit.h index 587120148d..5c1e20deac 100644 --- a/widgets/misc/e-dateedit.h +++ b/widgets/misc/e-dateedit.h @@ -9,11 +9,12 @@ * Based on the GnomeDateEdit, part of the Gnome Library. * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library 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 General Public License for more details. diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index 6fd7021b54..f51a502a83 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -1,26 +1,24 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * e-reflow.c - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * 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. * - * Authors: - * Chris Lahey + * 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. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see * - * This library 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Authors: + * Chris Lahey + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ - #include #include @@ -955,14 +953,12 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case 1: { GdkEventButton *button = (GdkEventButton *) event; - double n_x, max_x; + double n_x; n_x = button->x; n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - max_x = E_REFLOW_BORDER_WIDTH; - max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count; - if ( button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > button->x ) { + if ( button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { /* don't allow to drag the first line*/ if (e_reflow_pick_line(reflow, button->x) == 0) return TRUE; @@ -1046,16 +1042,13 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) return TRUE; } else { GdkEventMotion *motion = (GdkEventMotion *) event; - double n_x, max_x; + double n_x; n_x = motion->x; n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - max_x = E_REFLOW_BORDER_WIDTH; - max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count; - - if ( motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > motion->x) { + if ( motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { if ( reflow->default_cursor_shown ) { gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor); reflow->default_cursor_shown = FALSE; @@ -1071,14 +1064,12 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_ENTER_NOTIFY: if (!reflow->column_drag) { GdkEventCrossing *crossing = (GdkEventCrossing *) event; - double n_x, max_x; + double n_x; n_x = crossing->x; n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - max_x = E_REFLOW_BORDER_WIDTH; - max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count; - if ( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > crossing->x) { + if ( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { if ( reflow->default_cursor_shown ) { gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor); reflow->default_cursor_shown = FALSE; @@ -1541,4 +1532,3 @@ e_reflow_init (EReflow *reflow) e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow); } - diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index 26a77e6126..56990d71a1 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -32,6 +32,30 @@ #include "e-spinner.h" +#define E_TYPE_SPINNER (e_spinner_get_type ()) +#define E_SPINNER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SPINNER, ESpinner)) +#define E_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_SPINNER, ESpinnerClass)) +#define E_IS_SPINNER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SPINNER)) +#define E_IS_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_SPINNER)) +#define E_SPINNER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_SPINNER, ESpinnerClass)) + +typedef struct _ESpinner ESpinner; +typedef struct _ESpinnerClass ESpinnerClass; +typedef struct _ESpinnerDetails ESpinnerDetails; + +struct _ESpinner +{ + GtkWidget parent; + + /*< private >*/ + ESpinnerDetails *details; +}; + +struct _ESpinnerClass +{ + GtkWidgetClass parent_class; +}; + #define LOG(msg, args...) #define START_PROFILER(name) #define STOP_PROFILER(name) @@ -518,7 +542,7 @@ static void e_spinner_init (ESpinner *spinner); static GObjectClass *parent_class; -GType +static GType e_spinner_get_type (void) { static GType type = 0; @@ -701,13 +725,7 @@ bump_spinner_frame_cb (ESpinner *spinner) return TRUE; } -/** - * e_spinner_start: - * @spinner: a #ESpinner - * - * Start the spinner animation. - **/ -void +static void e_spinner_start (ESpinner *spinner) { ESpinnerDetails *details = spinner->details; @@ -742,39 +760,7 @@ e_spinner_remove_update_callback (ESpinner *spinner) } } -/** - * e_spinner_stop: - * @spinner: a #ESpinner - * - * Stop the spinner animation. - **/ -void -e_spinner_stop (ESpinner *spinner) -{ - ESpinnerDetails *details = spinner->details; - - details->spinning = FALSE; - details->current_image = 0; - - if (details->timer_task != 0) - { - e_spinner_remove_update_callback (spinner); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner))) - { - gtk_widget_queue_draw (GTK_WIDGET (spinner)); - } - } -} - -/* - * e_spinner_set_size: - * @spinner: a #ESpinner - * @size: the size of type %GtkIconSize - * - * Set the size of the spinner. - **/ -void +static void e_spinner_set_size (ESpinner *spinner, GtkIconSize size) { @@ -794,6 +780,27 @@ e_spinner_set_size (ESpinner *spinner, } #if 0 + +static void +e_spinner_stop (ESpinner *spinner) +{ + ESpinnerDetails *details = spinner->details; + + details->spinning = FALSE; + details->current_image = 0; + + if (details->timer_task != 0) + { + e_spinner_remove_update_callback (spinner); + + if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner))) + { + gtk_widget_queue_draw (GTK_WIDGET (spinner)); + } + } +} + + /* * e_spinner_set_timeout: * @spinner: a #ESpinner @@ -958,17 +965,14 @@ e_spinner_class_init (ESpinnerClass *class) g_type_class_add_private (object_class, sizeof (ESpinnerDetails)); } -/* - * e_spinner_new: - * - * Create a new #ESpinner. The spinner is a widget - * that gives the user feedback about network status with - * an animated image. - * - * Return Value: the spinner #GtkWidget - **/ -GtkWidget * -e_spinner_new (void) +GtkWidget *e_spinner_new_spinning_small_shown (void) { - return GTK_WIDGET (g_object_new (E_TYPE_SPINNER, NULL)); + ESpinner *image; + image = E_SPINNER (g_object_new (E_TYPE_SPINNER, NULL)); + + e_spinner_set_size (image, GTK_ICON_SIZE_SMALL_TOOLBAR); + e_spinner_start (image); + gtk_widget_show (GTK_WIDGET(image)); + + return GTK_WIDGET (image); } diff --git a/widgets/misc/e-spinner.h b/widgets/misc/e-spinner.h index 5a1cd42c5e..0fb97d945e 100644 --- a/widgets/misc/e-spinner.h +++ b/widgets/misc/e-spinner.h @@ -32,40 +32,7 @@ G_BEGIN_DECLS -#define E_TYPE_SPINNER (e_spinner_get_type ()) -#define E_SPINNER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SPINNER, ESpinner)) -#define E_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_SPINNER, ESpinnerClass)) -#define E_IS_SPINNER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SPINNER)) -#define E_IS_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_SPINNER)) -#define E_SPINNER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_SPINNER, ESpinnerClass)) - -typedef struct _ESpinner ESpinner; -typedef struct _ESpinnerClass ESpinnerClass; -typedef struct _ESpinnerDetails ESpinnerDetails; - -struct _ESpinner -{ - GtkWidget parent; - - /*< private >*/ - ESpinnerDetails *details; -}; - -struct _ESpinnerClass -{ - GtkWidgetClass parent_class; -}; - -GType e_spinner_get_type (void); - -GtkWidget *e_spinner_new (void); - -void e_spinner_start (ESpinner *throbber); - -void e_spinner_stop (ESpinner *throbber); - -void e_spinner_set_size (ESpinner *spinner, - GtkIconSize size); +GtkWidget *e_spinner_new_spinning_small_shown (void); G_END_DECLS -- cgit v1.2.3 From 14f54991f36d5d3556af1dde53ddb7a8aceafa3a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Oct 2008 20:28:57 +0000 Subject: Disable parts of my previous calendar work, such that all modules now load! svn path=/branches/kill-bonobo/; revision=36690 --- widgets/misc/e-activity-proxy.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index 6ce89016cd..24ffa5e521 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -77,7 +77,6 @@ activity_proxy_update (EActivityProxy *proxy) GTK_BUTTON (proxy->priv->button), gtk_image_new_from_icon_name ( icon_name, GTK_ICON_SIZE_MENU)); - e_spinner_stop (E_SPINNER (proxy->priv->spinner)); gtk_widget_hide (proxy->priv->spinner); if (clickable) { gtk_widget_show (proxy->priv->button); @@ -87,7 +86,6 @@ activity_proxy_update (EActivityProxy *proxy) gtk_widget_show (proxy->priv->image); } } else { - e_spinner_start (E_SPINNER (proxy->priv->spinner)); gtk_widget_show (proxy->priv->spinner); gtk_widget_hide (proxy->priv->button); gtk_widget_hide (proxy->priv->image); @@ -275,8 +273,8 @@ activity_proxy_init (EActivityProxy *proxy) proxy->priv->button = g_object_ref (widget); gtk_widget_hide (widget); - widget = e_spinner_new (); - e_spinner_set_size (E_SPINNER (widget), GTK_ICON_SIZE_MENU); + /* XXX What's the rationale for killing the old spinner API? */ + widget = e_spinner_new_spinning_small_shown (); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); proxy->priv->spinner = g_object_ref (widget); gtk_widget_show (widget); -- cgit v1.2.3 From 80e6c5adad4e89846c004efb2029d4db9ec2e64f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 30 Oct 2008 20:51:26 +0000 Subject: Add popup menus to the calendar memopad and taskpad. Implement support for "hide completed tasks" option (not yet tested). Flesh out most of the Preferences window. Still need Certificates page. svn path=/branches/kill-bonobo/; revision=36701 --- widgets/misc/e-preferences-window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 7ae9fdf596..1235ebbad8 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -358,6 +358,7 @@ e_preferences_window_add_page (EPreferencesWindow *window, g_hash_table_insert (index, g_strdup (page_name), reference); gtk_tree_path_free (path); + gtk_widget_show (widget); gtk_notebook_append_page (notebook, widget, NULL); if (page == 0) -- cgit v1.2.3 From 9c9e85d286fe61ed11e457c737bd26e2732119ab Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 30 Oct 2008 21:23:17 +0000 Subject: Secondary checkout spotted a compilation issue. Select the first Preferences page when the window is shown. svn path=/branches/kill-bonobo/; revision=36702 --- widgets/misc/e-preferences-window.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 1235ebbad8..ecdbee1402 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -154,9 +154,18 @@ static void preferences_window_show (GtkWidget *widget) { EPreferencesWindowPrivate *priv; + GtkIconView *icon_view; + GtkTreePath *path; priv = E_PREFERENCES_WINDOW_GET_PRIVATE (widget); + icon_view = GTK_ICON_VIEW (priv->icon_view); + + path = gtk_tree_path_new_first (); + gtk_icon_view_select_path (icon_view, path); + gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + gtk_widget_grab_focus (priv->icon_view); /* Chain up to parent's show() method. */ @@ -360,9 +369,6 @@ e_preferences_window_add_page (EPreferencesWindow *window, gtk_widget_show (widget); gtk_notebook_append_page (notebook, widget, NULL); - - if (page == 0) - e_preferences_window_show_page (window, page_name); } void -- cgit v1.2.3 From d6445f8abfa78c0a9c8680a3ba7422d331391f8f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 7 Nov 2008 22:04:53 +0000 Subject: Merge revisions 36685:36729 from trunk. svn path=/branches/kill-bonobo/; revision=36763 --- widgets/misc/ChangeLog | 7 +++++++ widgets/misc/e-url-entry.c | 19 +++++++++---------- widgets/misc/e-url-entry.h | 19 +++++++++---------- 3 files changed, 25 insertions(+), 20 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 85ec90411f..e7b9460b10 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,10 @@ +2008-10-29 Sankar P + +License Changes + + * e-url-entry.c: + * e-url-entry.h: + 2008-10-21 Sankar P * e-spinner.c (e_spinner_stop), diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index 9db87b3ecd..26d081fc85 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -1,12 +1,8 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-url-entry.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * 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) any later version. + * 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 @@ -14,11 +10,14 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * Author: JP Rosevear */ #ifdef HAVE_CONFIG_H diff --git a/widgets/misc/e-url-entry.h b/widgets/misc/e-url-entry.h index f2ebf54eae..1c051ac0e8 100644 --- a/widgets/misc/e-url-entry.h +++ b/widgets/misc/e-url-entry.h @@ -1,12 +1,8 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-url-entry.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * +/* * 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) any later version. + * 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 @@ -14,11 +10,14 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * License along with the program; if not, see + * + * + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * Author: JP Rosevear */ #ifndef _E_URL_ENTRY_H_ -- cgit v1.2.3 From 076b7c45131482b87d18963d34d035435491ee8d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 21 Nov 2008 22:58:35 +0000 Subject: Fix a mistyped macro. svn path=/branches/kill-bonobo/; revision=36809 --- widgets/misc/e-action-combo-box.c | 4 ++-- widgets/misc/e-action-combo-box.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c index e826fb2a54..b3bc5a78a9 100644 --- a/widgets/misc/e-action-combo-box.c +++ b/widgets/misc/e-action-combo-box.c @@ -24,7 +24,7 @@ #define E_ACTION_COMBO_BOX_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxPrivate)) + ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxPrivate)) enum { COLUMN_ACTION, @@ -422,7 +422,7 @@ e_action_combo_box_new (void) GtkWidget * e_action_combo_box_new_with_action (GtkRadioAction *action) { - return g_object_new (E_ACTION_TYPE_COMBO_BOX, "action", action, NULL); + return g_object_new (E_TYPE_ACTION_COMBO_BOX, "action", action, NULL); } GtkRadioAction * diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h index 7327c4723b..c3e6941ca6 100644 --- a/widgets/misc/e-action-combo-box.h +++ b/widgets/misc/e-action-combo-box.h @@ -28,23 +28,23 @@ #include /* Standard GObject macros */ -#define E_ACTION_TYPE_COMBO_BOX \ +#define E_TYPE_ACTION_COMBO_BOX \ (e_action_combo_box_get_type ()) #define E_ACTION_COMBO_BOX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBox)) + ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBox)) #define E_ACTION_COMBO_BOX_CLASS(cls) \ (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxClass)) + ((cls), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass)) #define E_ACTION_IS_COMBO_BOX(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_ACTION_TYPE_COMBO_BOX)) + ((obj), E_TYPE_ACTION_COMBO_BOX)) #define E_ACTION_IS_COMBO_BOX_CLASS(cls) \ (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_ACTION_TYPE_COMBO_BOX)) + ((cls), E_TYPE_ACTION_COMBO_BOX)) #define E_ACTION_COMBO_BOX_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_ACTION_TYPE_COMBO_BOX, EActionComboBoxClass)) + ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass)) G_BEGIN_DECLS -- cgit v1.2.3 From d158af8cdfa6e4bf85c1e74769e8d61bc469494c Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 10 Dec 2008 18:30:29 +0000 Subject: Merge revisions 36811:36865 from trunk. svn path=/branches/kill-bonobo/; revision=36867 --- widgets/misc/ChangeLog | 14 ++++++++++++++ widgets/misc/e-attachment-bar.c | 3 ++- widgets/misc/e-send-options.glade | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index e7b9460b10..c519df2d47 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,17 @@ +2008-12-10 Milan Crha + + ** Fix for bug #556303 + + * e-attachment-bar.c: (eab_icon_clicked_cb): + Check whether attachment has a body already before accessing it. + +2008-12-09 Milan Crha + + ** Part of fix for bug #563669 + + * e-send-options.glade: + Use zero GtkSpinButton's PageSize, as Gtk+ requires. + 2008-10-29 Sankar P License Changes diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 1e41a95338..bdb6852e13 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -1001,7 +1001,8 @@ eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) if (E_IS_ATTACHMENT_BAR (bar) && event->type == GDK_2BUTTON_PRESS) { p = e_attachment_bar_get_selected (bar); - if (p && p->next == NULL) { + /* check if has body already, remote files can take longer to fetch */ + if (p && p->next == NULL && ((EAttachment *)p->data)->body) { attachment = p->data; /* Check if the file is stored already */ diff --git a/widgets/misc/e-send-options.glade b/widgets/misc/e-send-options.glade index fd509488da..1c1cc486d0 100644 --- a/widgets/misc/e-send-options.glade +++ b/widgets/misc/e-send-options.glade @@ -220,7 +220,7 @@ GTK_UPDATE_ALWAYS False False - 5 0 100 1 10 10 + 5 0 100 1 10 0 1 @@ -450,7 +450,7 @@ GTK_UPDATE_ALWAYS False False - 2 0 100 1 10 10 + 2 0 100 1 10 0 0 -- cgit v1.2.3 From 9d915124c28eb0772b4e1086d6988e7d56d9a04c Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 31 Dec 2008 20:24:59 +0000 Subject: Get the Character Encoding menu working. Kill e_charset_picker_bonobo_ui_populate(). svn path=/branches/kill-bonobo/; revision=36950 --- widgets/misc/e-charset-picker.c | 199 +++++++--------------------------------- widgets/misc/e-charset-picker.h | 10 +- 2 files changed, 37 insertions(+), 172 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 03014609ae..1f24397fae 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -440,6 +440,7 @@ e_charset_picker_dialog (const char *title, const char *prompt, /** * e_charset_add_radio_actions: * @action_group: a #GtkActionGroup + * @action_prefix: a prefix for action names, or %NULL * @default_charset: the default character set, or %NULL to use the * locale character set * @callback: a callback function for actions in the group, or %NULL @@ -453,8 +454,9 @@ e_charset_picker_dialog (const char *title, const char *prompt, * the default will be added next, followed by the remaining character * sets. **/ -void +GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, + const gchar *action_prefix, const gchar *default_charset, GCallback callback, gpointer user_data) @@ -464,12 +466,10 @@ e_charset_add_radio_actions (GtkActionGroup *action_group, const gchar *locale_charset; gint def, ii; - g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL); - /* XXX I could try to factor out code common to this - * function and e_charset_picker_bonobo_ui_populate() - * instead of duplicating it, but I expect the latter - * function to be obsolete in the foreseeable future. */ + if (action_prefix == NULL) + action_prefix = ""; g_get_charset (&locale_charset); if (!g_ascii_strcasecmp (locale_charset, "US-ASCII")) @@ -482,13 +482,18 @@ e_charset_add_radio_actions (GtkActionGroup *action_group, break; for (ii = 0; ii < G_N_ELEMENTS (charsets); ii++) { + const gchar *charset_name; + gchar *action_name; gchar *escaped_name; gchar *charset_label; gchar **str_array; + charset_name = charsets[ii].name; + action_name = g_strconcat (action_prefix, charset_name, NULL); + /* Escape underlines in the character set name so * they're not treated as GtkLabel mnemonics. */ - str_array = g_strsplit (charsets[ii].name, "_", -1); + str_array = g_strsplit (charset_name, "_", -1); escaped_name = g_strjoinv ("__", str_array); g_strfreev (str_array); @@ -506,8 +511,14 @@ e_charset_add_radio_actions (GtkActionGroup *action_group, else charset_label = g_strdup (escaped_name); + /* XXX Add a tooltip! */ action = gtk_radio_action_new ( - charsets[ii].name, charset_label, NULL, NULL, ii); + action_name, charset_label, NULL, NULL, ii); + + /* Character set name is static so no need to free it. */ + g_object_set_data ( + G_OBJECT (action), "charset", + (gpointer) charset_name); gtk_radio_action_set_group (action, group); group = gtk_radio_action_get_group (action); @@ -521,22 +532,34 @@ e_charset_add_radio_actions (GtkActionGroup *action_group, g_object_unref (action); + g_free (action_name); g_free (escaped_name); g_free (charset_label); } if (def == G_N_ELEMENTS (charsets)) { + const gchar *charset_name; + gchar *action_name; gchar *charset_label; gchar **str_array; + charset_name = default_charset; + action_name = g_strconcat (action_prefix, charset_name, NULL); + /* Escape underlines in the character set name so * they're not treated as GtkLabel mnemonics. */ - str_array = g_strsplit (default_charset, "_", -1); + str_array = g_strsplit (charset_name, "_", -1); charset_label = g_strjoinv ("__", str_array); g_strfreev (str_array); + /* XXX Add a tooltip! */ action = gtk_radio_action_new ( - default_charset, charset_label, NULL, NULL, def); + action_name, charset_label, NULL, NULL, def); + + /* Character set name is static so no need to free it. */ + g_object_set_data ( + G_OBJECT (action), "charset", + (gpointer) charset_name); gtk_radio_action_set_group (action, group); group = gtk_radio_action_get_group (action); @@ -550,165 +573,13 @@ e_charset_add_radio_actions (GtkActionGroup *action_group, g_object_unref (action); + g_free (action_name); g_free (charset_label); } /* Any of the actions in the action group will do. */ if (action != NULL) gtk_radio_action_set_current_value (action, def); -} - -/** - * e_charset_picker_bonobo_ui_populate: - * @uic: Bonobo UI Component - * @path: menu path - * @default_charset: the default character set, or %NULL to use the - * locale character set. - * @cb: Callback function - * @user_data: data to be passed to the callback. - * - * This creates a Bonobo UI menu and fills it in with a selection - * of available character sets. The @default_charset (or locale character - * set if @default_charset is %NULL) will be listed first, and selected - * by default (except that iso-8859-1 will always be used instead of - * US-ASCII). Any other character sets of the same language class as - * the default will be listed next, followed by the remaining character - * sets. - **/ -void -e_charset_picker_bonobo_ui_populate (BonoboUIComponent *uic, const char *path, - const char *default_charset, - BonoboUIListenerFn cb, gpointer user_data) -{ - char *encoded_label, *label; - const char *locale_charset; - GString *menuitems; - int def, i; - - g_get_charset (&locale_charset); - if (!g_ascii_strcasecmp (locale_charset, "US-ASCII")) - locale_charset = "iso-8859-1"; - - if (!default_charset) - default_charset = locale_charset; - for (def = 0; def < num_charsets; def++) { - if (!g_ascii_strcasecmp (charsets[def].name, default_charset)) - break; - } - - label = g_strdup (_("Ch_aracter Encoding")); - encoded_label = bonobo_ui_util_encode_str (label); - menuitems = g_string_new (""); - g_string_append_printf (menuitems, "\n", - encoded_label); - g_free (encoded_label); - g_free (label); - - for (i = 0; i < num_charsets; i++) { - char *command; - char *charset_name, *u; - - /* escape _'s in the charset name so that it doesn't become an underline in a GtkLabel */ - if ((u = strchr (charsets[i].name, '_'))) { - int extra = 1; - char *s, *d; - - while ((u = strchr (u + 1, '_'))) - extra++; - - d = charset_name = g_alloca (strlen (charsets[i].name) + extra + 1); - s = charsets[i].name; - while (*s != '\0') { - if (*s == '_') - *d++ = '_'; - *d++ = *s++; - } - *d = '\0'; - } else { - charset_name = charsets[i].name; - } - - if (charsets[i].subclass) { - label = g_strdup_printf ("%s, %s (%s)", - _(classnames[charsets[i].class]), - _(charsets[i].subclass), - charset_name); - } else if (charsets[i].class) { - label = g_strdup_printf ("%s (%s)", - _(classnames[charsets[i].class]), - charset_name); - } else { - label = g_strdup (charset_name); - } - - encoded_label = bonobo_ui_util_encode_str (label); - g_free (label); - - command = g_strdup_printf ("\n", - charsets[i].name, encoded_label, i == def); - - bonobo_ui_component_set (uic, "/commands", command, NULL); - g_free (command); - - g_string_append_printf (menuitems, " \n", - charsets[i].name); - - g_free (encoded_label); - - label = g_strdup_printf ("Charset-%s", charsets[i].name); - bonobo_ui_component_add_listener (uic, label, cb, user_data); - g_free (label); - } - - if (def == num_charsets) { - char *command; - char *charset_name, *u; - - /* escape _'s in the charset name so that it doesn't become an underline in a GtkLabel */ - if ((u = strchr (default_charset, '_'))) { - int extra = 1; - char *s, *d; - - while ((u = strchr (u + 1, '_'))) - extra++; - - d = charset_name = g_alloca (strlen (default_charset) + extra + 1); - s = (char *) default_charset; - while (*s != '\0') { - if (*s == '_') - *d++ = '_'; - *d++ = *s++; - } - *d = '\0'; - } else { - charset_name = (char *) default_charset; - } - - label = g_strdup (charset_name); - encoded_label = bonobo_ui_util_encode_str (label); - g_free (label); - - command = g_strdup_printf ("\n", - default_charset, encoded_label); - - bonobo_ui_component_set (uic, "/commands", command, NULL); - g_free (command); - - g_string_append (menuitems, " \n"); - g_string_append_printf (menuitems, " \n", - default_charset); - - g_free (encoded_label); - - label = g_strdup_printf ("Charset-%s", default_charset); - bonobo_ui_component_add_listener (uic, label, cb, user_data); - g_free (label); - } - - g_string_append (menuitems, "\n"); - bonobo_ui_component_set (uic, path, menuitems->str, NULL); - g_string_free (menuitems, TRUE); + return group; } diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index 7250b10dfb..21643ccf99 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -33,18 +33,12 @@ char * e_charset_picker_dialog (const char *title, const char *default_charset, GtkWindow *parent); -void e_charset_add_radio_actions (GtkActionGroup *action_group, +GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, + const gchar *action_prefix, const gchar *default_charset, GCallback callback, gpointer user_data); -void e_charset_picker_bonobo_ui_populate - (BonoboUIComponent *uic, - const char *path, - const char *default_charset, - BonoboUIListenerFn cb, - gpointer user_data); - G_END_DECLS #endif /* E_CHARSETPICKER_H */ -- cgit v1.2.3 From e0610b2e0cea191f631dc825cdc8023cdcd9433d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 11 Jan 2009 14:20:50 +0000 Subject: Continue chipping away at EMFolderView and EMFolderBrowser. Migrate from gnome_url_show() to e_show_uri(). svn path=/branches/kill-bonobo/; revision=37038 --- widgets/misc/e-attachment-bar.c | 10 ++-------- widgets/misc/e-url-entry.c | 8 ++++++-- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index bdb6852e13..2da9d3541c 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -993,7 +993,6 @@ static gboolean eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) { EAttachment *attachment; - GError *error = NULL; gboolean ret = FALSE; CamelURL *url; char *path; @@ -1015,13 +1014,8 @@ eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) g_free (path); } - /* launch the url now */ - gnome_url_show (attachment->store_uri, &error); - if (error) { - g_message ("DEBUG: Launch failed: %s\n", error->message); - g_error_free (error); - error = NULL; - } + /* FIXME Pass a parent window. */ + e_show_uri (NULL, attachment->store_uri); ret = TRUE; } diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index 26d081fc85..32490f6590 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -25,9 +25,9 @@ #endif #include -#include #include #include "e-url-entry.h" +#include "e-util/e-util.h" struct _EUrlEntryPrivate { GtkWidget *entry; @@ -170,11 +170,15 @@ button_clicked_cb (GtkWidget *widget, gpointer data) { EUrlEntry *url_entry; EUrlEntryPrivate *priv; + const gchar *uri; url_entry = E_URL_ENTRY (data); priv = url_entry->priv; - gnome_url_show (gtk_entry_get_text (GTK_ENTRY (priv->entry)), NULL); + uri = gtk_entry_get_text (GTK_ENTRY (priv->entry)); + + /* FIXME Pass a parent window. */ + e_show_uri (NULL, uri); } static void -- cgit v1.2.3 From c7d3c9f95609123035ebaa267f9d2e6ecfa8c2e8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 12 Jan 2009 04:12:01 +0000 Subject: Merge revisions 36866:37046 from trunk. svn path=/branches/kill-bonobo/; revision=37050 --- widgets/misc/ChangeLog | 34 ++++++++++++++++ widgets/misc/e-cell-date-edit.c | 1 - widgets/misc/e-cell-percent.c | 1 - widgets/misc/e-charset-picker.c | 2 +- widgets/misc/e-dropdown-button.c | 1 - widgets/misc/e-signature-combo-box.c | 6 ++- widgets/misc/test-color.c | 78 ------------------------------------ widgets/misc/test-dropdown-button.c | 1 - 8 files changed, 40 insertions(+), 84 deletions(-) delete mode 100644 widgets/misc/test-color.c (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index c519df2d47..e8c1a5023d 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,37 @@ +2009-01-11 Matthew Barnes + + * e-attachment-bar.c (eab_icon_clicked_cb): + * e-url-entry.c (button_clicked_cb): + Call e_show_uri() instead of gnome_url_show(). + +2009-01-10 Matthew Barnes + + * test-dropdown-button.c: + Remove unneeded #include . + +2009-01-10 Matthew Barnes + + ** Fixes part of bug #567281 + + * e-cell-date-edit.c: + * e-cell-percent.c: + Remove unneeded #include . + +2009-01-10 Matthew Barnes + + ** Fixes part of bug #567276 + + * test-color.c: + We don't ship this. Remove it. + +2009-01-10 Matthew Barnes + + ** Fixes part of bug #567285 + + * e-activity-handler.c: + * e-dropdown-button.c: + Remove unneeded #include . + 2008-12-10 Milan Crha ** Fix for bug #556303 diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c index 824c8a1b20..68cbbb97d4 100644 --- a/widgets/misc/e-cell-date-edit.c +++ b/widgets/misc/e-cell-date-edit.c @@ -42,7 +42,6 @@ #include
#include
-#include #include #include diff --git a/widgets/misc/e-cell-percent.c b/widgets/misc/e-cell-percent.c index ee83d60def..94e33489e5 100644 --- a/widgets/misc/e-cell-percent.c +++ b/widgets/misc/e-cell-percent.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include "e-cell-percent.h" diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 1f24397fae..ade1c186a6 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c index 32785a5e8f..aa5f84f6c8 100644 --- a/widgets/misc/e-dropdown-button.c +++ b/widgets/misc/e-dropdown-button.c @@ -28,7 +28,6 @@ #include "e-dropdown-button.h" #include -#include struct _EDropdownButtonPrivate { GtkAccelGroup *accel_group; diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c index 199a3ad51a..9ebd20a0b2 100644 --- a/widgets/misc/e-signature-combo-box.c +++ b/widgets/misc/e-signature-combo-box.c @@ -18,9 +18,13 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "e-signature-combo-box.h" -#include +#include #define E_SIGNATURE_COMBO_BOX_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/widgets/misc/test-color.c b/widgets/misc/test-color.c deleted file mode 100644 index f86166a228..0000000000 --- a/widgets/misc/test-color.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * 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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include - -#include - -#include - -#include "color-palette.h" -#include "e-colors.h" -#include "widget-color-combo.h" - -#include "pixmaps/cursor_hand_open.xpm" - -/* To compile (from src/widgets): - -gcc -I.. -I../.. -L. -Wall -o tester tester.c ../color.c `gnome-config --cflags --libs gnome gnomeui` -lwidgets - -*/ - -gint -main ( gint argc, gchar* argv[] ) -{ - GtkWidget * dialog; - GtkWidget * T; - ColorGroup *cg; - - gnome_program_init ("tester", "1.0", - LIBGNOMEUI_MODULE, - argc, argv, NULL); - - dialog = gnome_dialog_new ("TESTER", GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, NULL); - - cg = color_group_fetch ("fore_color_group", dialog); - T = color_palette_new ("Color Palette", NULL, cg); - - gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)-> vbox ), - T, TRUE, TRUE, 5); - gtk_widget_show_all (T); - - cg = color_group_fetch ("fore_color_group", dialog); - T = color_combo_new ( - gdk_pixbuf_new_from_xpm_data ((char const **)cursor_hand_open_xpm), - _("Automatic"), &e_black, cg); - gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)-> vbox ), - T, TRUE, TRUE, 5); - gtk_widget_show_all (T); - - cg = color_group_fetch ("back_color_group", dialog); - T = color_combo_new ( - gdk_pixbuf_new_from_xpm_data ((char const **)cursor_hand_open_xpm), - _("Automatic"), &e_black, cg); - gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)-> vbox ), - T, TRUE, TRUE, 5); - gtk_widget_show_all (T); - - gnome_dialog_run_and_close ( GNOME_DIALOG (dialog) ); - return 0; -} diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c index 38523c47b1..f0a7ca4d0e 100644 --- a/widgets/misc/test-dropdown-button.c +++ b/widgets/misc/test-dropdown-button.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "e-dropdown-button.h" -- cgit v1.2.3 From 4d07d219d1f18aeba2c16317ade4b4004d8934b9 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 16 Jan 2009 13:49:40 +0000 Subject: Fix a typo. svn path=/branches/kill-bonobo/; revision=37088 --- widgets/misc/e-activity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 7905c4062f..34e902f5a6 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -430,7 +430,7 @@ e_activity_describe (EActivity *activity) /* Translators: This is an activity whose percent * complete is known. */ g_string_printf ( - string, _("%s (%d%% complete"), text, + string, _("%s (%d%% complete)"), text, (gint) (percent * 100.0 + 0.5)); } -- cgit v1.2.3 From c22126d54f0cf0637e3d5ddd5d78b3ff5d111582 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 17 Jan 2009 20:06:17 +0000 Subject: Hack GtkIconTheme so we can reference category icons as named icons. Necessary for EActionComboBox, since GtkActions can only handle named or stock icons. Hopefully this is just a temporary hack. Eventually we should make the category icons themeable. Kill the "mail-account-disable" plugin and integrate it properly. More dead plugins to follow... Don't show disabled menu items in pop-up context menus. It does the user no good to see things he CAN'T do with the object he clicked on. svn path=/branches/kill-bonobo/; revision=37093 --- widgets/misc/e-action-combo-box.c | 54 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c index b3bc5a78a9..977ac06ade 100644 --- a/widgets/misc/e-action-combo-box.c +++ b/widgets/misc/e-action-combo-box.c @@ -43,6 +43,7 @@ struct _EActionComboBoxPrivate { guint changed_handler_id; /* action::changed */ guint group_sensitive_handler_id; /* action-group::sensitive */ guint group_visible_handler_id; /* action-group::visible */ + gboolean group_has_icons : 1; }; static gpointer parent_class; @@ -95,9 +96,14 @@ action_combo_box_render_pixbuf (GtkCellLayout *layout, gchar *stock_id; gboolean sensitive; gboolean visible; + gint width; gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); + /* Do any of the actions have an icon? */ + if (!combo_box->priv->group_has_icons) + return; + /* A NULL action means the row is a separator. */ if (action == NULL) return; @@ -110,14 +116,31 @@ action_combo_box_render_pixbuf (GtkCellLayout *layout, "visible", &visible, NULL); - g_object_set ( - G_OBJECT (renderer), - "icon-name", icon_name, - "sensitive", sensitive, - "stock-id", stock_id, - "stock-size", GTK_ICON_SIZE_MENU, - "visible", visible, - NULL); + /* Keep the pixbuf renderer a fixed size for proper alignment. */ + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL); + + /* We can't set both "icon-name" and "stock-id" because setting + * one unsets the other. So pick the one that has a non-NULL + * value. If both are non-NULL, "stock-id" wins. */ + + if (stock_id != NULL) + g_object_set ( + G_OBJECT (renderer), + "sensitive", sensitive, + "stock-id", stock_id, + "stock-size", GTK_ICON_SIZE_MENU, + "visible", visible, + "width", width, + NULL); + else + g_object_set ( + G_OBJECT (renderer), + "icon-name", icon_name, + "sensitive", sensitive, + "stock-size", GTK_ICON_SIZE_MENU, + "visible", visible, + "width", width, + NULL); g_free (icon_name); g_free (stock_id); @@ -135,6 +158,7 @@ action_combo_box_render_text (GtkCellLayout *layout, gchar *label; gboolean sensitive; gboolean visible; + gint xpad; gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1); @@ -155,11 +179,14 @@ action_combo_box_render_text (GtkCellLayout *layout, label = g_strjoinv (NULL, strv); g_strfreev (strv); + xpad = combo_box->priv->group_has_icons ? 3 : 0; + g_object_set ( G_OBJECT (renderer), "sensitive", sensitive, "text", label, "visible", visible, + "xpad", xpad, NULL); g_free (label); @@ -201,14 +228,25 @@ action_combo_box_update_model (EActionComboBox *combo_box) 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT); list = gtk_radio_action_get_group (combo_box->priv->action); + combo_box->priv->group_has_icons = FALSE; while (list != NULL) { GtkTreeRowReference *reference; GtkRadioAction *action = list->data; GtkTreePath *path; GtkTreeIter iter; + gchar *icon_name; + gchar *stock_id; gint value; + g_object_get ( + action, "icon-name", &icon_name, + "stock-id", &stock_id, NULL); + combo_box->priv->group_has_icons |= + (icon_name != NULL || stock_id != NULL); + g_free (icon_name); + g_free (stock_id); + gtk_list_store_append (list_store, &iter); g_object_get (G_OBJECT (action), "value", &value, NULL); gtk_list_store_set ( -- cgit v1.2.3 From 22d41a51fae2d18315887b05000cf7facc36e887 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 20 Jan 2009 00:05:40 +0000 Subject: Formalize the "no disabled items in popup menus" policy in the form of a GtkAction subclass called EPopupAction. Migrate all the modules over to using EPopupActions in their popup menus. Add sensitivity management of GtkActions to EMailReader. Not finished. svn path=/branches/kill-bonobo/; revision=37106 --- widgets/misc/Makefile.am | 2 + widgets/misc/e-popup-action.c | 285 ++++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-popup-action.h | 95 ++++++++++++++ 3 files changed, 382 insertions(+) create mode 100644 widgets/misc/e-popup-action.c create mode 100644 widgets/misc/e-popup-action.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index e5ddeecc06..ce702ec9fd 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -57,6 +57,7 @@ widgetsinclude_HEADERS = \ e-image-chooser.h \ e-map.h \ e-menu-tool-button.h \ + e-popup-action.h \ e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ @@ -103,6 +104,7 @@ libemiscwidgets_la_SOURCES = \ e-image-chooser.c \ e-map.c \ e-menu-tool-button.c \ + e-popup-action.c \ e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ diff --git a/widgets/misc/e-popup-action.c b/widgets/misc/e-popup-action.c new file mode 100644 index 0000000000..51abc01338 --- /dev/null +++ b/widgets/misc/e-popup-action.c @@ -0,0 +1,285 @@ +/* + * e-popup-action.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-popup-action.h" + +#include +#include "e-util/e-binding.h" + +#define E_POPUP_ACTION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_POPUP_ACTION, EPopupActionPrivate)) + +enum { + PROP_0, + PROP_SOURCE +}; + +struct _EPopupActionPrivate { + GtkAction *source; +}; + +static gpointer parent_class; + +static void +popup_action_set_source (EPopupAction *popup_action, + GtkAction *source) +{ + g_return_if_fail (popup_action->priv->source == NULL); + g_return_if_fail (GTK_IS_ACTION (source)); + + popup_action->priv->source = g_object_ref (source); +} + +static void +popup_action_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE: + popup_action_set_source ( + E_POPUP_ACTION (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +popup_action_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE: + g_value_set_object ( + value, e_popup_action_get_source ( + E_POPUP_ACTION (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +popup_action_dispose (GObject *object) +{ + EPopupActionPrivate *priv; + + priv = E_POPUP_ACTION_GET_PRIVATE (object); + + if (priv->source != NULL) { + g_object_unref (priv->source); + priv->source = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +popup_action_constructed (GObject *object) +{ + EPopupActionPrivate *priv; + GObject *source; + gchar *icon_name; + gchar *label; + gchar *stock_id; + gchar *tooltip; + + priv = E_POPUP_ACTION_GET_PRIVATE (object); + + source = G_OBJECT (priv->source); + + g_object_get ( + object, "icon-name", &icon_name, "label", &label, + "stock-id", &stock_id, "tooltip", &tooltip, NULL); + + if (label == NULL) + e_binding_new (source, "label", object, "label"); + + if (tooltip == NULL) + e_binding_new (source, "tooltip", object, "tooltip"); + + if (icon_name == NULL && stock_id == NULL) { + g_free (icon_name); + g_free (stock_id); + + g_object_get ( + source, "icon-name", &icon_name, + "stock-id", &stock_id, NULL); + + if (icon_name == NULL) { + e_binding_new ( + source, "icon-name", object, "icon-name"); + e_binding_new ( + source, "stock-id", object, "stock-id"); + } else { + e_binding_new ( + source, "stock-id", object, "stock-id"); + e_binding_new ( + source, "icon-name", object, "icon-name"); + } + } + + e_binding_new (source, "sensitive", object, "visible"); + + g_free (icon_name); + g_free (label); + g_free (stock_id); + g_free (tooltip); +} + +static void +popup_action_class_init (EPopupActionClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EPopupActionPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = popup_action_set_property; + object_class->get_property = popup_action_get_property; + object_class->dispose = popup_action_dispose; + + g_object_class_install_property ( + object_class, + PROP_SOURCE, + g_param_spec_object ( + "source", + _("Source Action"), + _("The source action to proxy"), + GTK_TYPE_ACTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +popup_action_init (EPopupAction *popup_action) +{ + popup_action->priv = E_POPUP_ACTION_GET_PRIVATE (popup_action); +} + +GType +e_popup_action_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EPopupActionClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) popup_action_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EPopupAction), + 0, /* n_preallocs */ + (GInstanceInitFunc) popup_action_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_ACTION, "EPopupAction", &type_info, 0); + } + + return type; +} + +EPopupAction * +e_popup_action_new (const gchar *name, + const gchar *label, + GtkAction *source) +{ + EPopupAction *popup_action; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (GTK_IS_ACTION (source), NULL); + + popup_action = g_object_new ( + E_TYPE_POPUP_ACTION, "name", name, + "label", label, "source", source, NULL); + + /* XXX This is a hack to work around the fact that GtkAction's + * "label" and "tooltip" properties are not constructor + * properties, even though they're supplied upfront. + * + * See: http://bugzilla.gnome.org/show_bug.cgi?id=568334 */ + popup_action_constructed (G_OBJECT (popup_action)); + + return popup_action; +} + +GtkAction * +e_popup_action_get_source (EPopupAction *popup_action) +{ + g_return_val_if_fail (E_IS_POPUP_ACTION (popup_action), NULL); + + return popup_action->priv->source; +} + +void +e_action_group_add_popup_actions (GtkActionGroup *action_group, + const EPopupActionEntry *entries, + guint n_entries) +{ + guint ii; + + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + + for (ii = 0; ii < n_entries; ii++) { + EPopupAction *popup_action; + GtkAction *source; + const gchar *label; + + label = gtk_action_group_translate_string ( + action_group, entries[ii].label); + + source = gtk_action_group_get_action ( + action_group, entries[ii].source); + + if (source == NULL) { + g_warning ( + "Source action '%s' not found in " + "action group '%s'", entries[ii].source, + gtk_action_group_get_name (action_group)); + continue; + } + + popup_action = e_popup_action_new ( + entries[ii].name, label, source); + + g_signal_connect_swapped ( + popup_action, "activate", + G_CALLBACK (gtk_action_activate), + popup_action->priv->source); + + gtk_action_group_add_action ( + action_group, GTK_ACTION (popup_action)); + + g_object_unref (popup_action); + } +} diff --git a/widgets/misc/e-popup-action.h b/widgets/misc/e-popup-action.h new file mode 100644 index 0000000000..6000b5a6ec --- /dev/null +++ b/widgets/misc/e-popup-action.h @@ -0,0 +1,95 @@ +/* + * e-popup-action.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* A popup action is an action that lives in a popup menu. It proxies an + * equivalent action in the main menu, with two differences: + * + * 1) If the main menu action is insensitive, the popup action is invisible. + * 2) The popup action may have a different label than the main menu action. + * + * To use: + * + * Create an array of EPopupActionEntry structs. Add the main menu actions + * that serve as "sources" for the popup actions to an action group first. + * Then pass the same action group and the EPopupActionEntry array to + * e_action_group_add_popup_actions() to add popup actions. + */ + +#ifndef E_POPUP_ACTION_H +#define E_POPUP_ACTION_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_POPUP_ACTION \ + (e_popup_action_get_type ()) +#define E_POPUP_ACTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_POPUP_ACTION, EPopupAction)) +#define E_POPUP_ACTION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_POPUP_ACTION, EPopupActionClass)) +#define E_IS_POPUP_ACTION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_POPUP_ACTION)) +#define E_IS_POPUP_ACTION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_POPUP_ACTION)) +#define E_POPUP_ACTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_POPUP_ACTION, EPopupActionClass)) + +G_BEGIN_DECLS + +typedef struct _EPopupAction EPopupAction; +typedef struct _EPopupActionClass EPopupActionClass; +typedef struct _EPopupActionPrivate EPopupActionPrivate; +typedef struct _EPopupActionEntry EPopupActionEntry; + +struct _EPopupAction { + GtkAction parent; + EPopupActionPrivate *priv; +}; + +struct _EPopupActionClass { + GtkActionClass parent_class; +}; + +struct _EPopupActionEntry { + const gchar *name; + const gchar *label; /* optional: overrides the source action */ + const gchar *source; /* name of the source action */ +}; + +GType e_popup_action_get_type (void); +EPopupAction * e_popup_action_new (const gchar *name, + const gchar *label, + GtkAction *source); +GtkAction * e_popup_action_get_source (EPopupAction *popup_action); + +void e_action_group_add_popup_actions + (GtkActionGroup *action_group, + const EPopupActionEntry *entries, + guint n_entries); + +G_END_DECLS + +#endif /* E_POPUP_ACTION_H */ -- cgit v1.2.3 From cbb3a71adc5551f4c600cfc6f53fc112f3022a78 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 24 Jan 2009 04:45:19 +0000 Subject: Get automatic message selection working. Add a tooltip to the online button. svn path=/branches/kill-bonobo/; revision=37126 --- widgets/misc/e-online-button.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c index dec24a6587..fbfb850272 100644 --- a/widgets/misc/e-online-button.c +++ b/widgets/misc/e-online-button.c @@ -23,6 +23,12 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate)) +#define ONLINE_TOOLTIP \ + "Evolution is currently online. Click this button to work offline." + +#define OFFLINE_TOOLTIP \ + "Evolution is currently offline. Click this button to work online." + struct _EOnlineButtonPrivate { GtkWidget *image; gboolean online; @@ -175,6 +181,7 @@ e_online_button_set_online (EOnlineButton *button, GtkIconTheme *icon_theme; const gchar *filename; const gchar *icon_name; + const gchar *tooltip; g_return_if_fail (E_IS_ONLINE_BUTTON (button)); @@ -191,5 +198,8 @@ e_online_button_set_online (EOnlineButton *button, gtk_image_set_from_file (image, filename); gtk_icon_info_free (icon_info); + tooltip = _(online ? ONLINE_TOOLTIP : OFFLINE_TOOLTIP); + gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip); + g_object_notify (G_OBJECT (button), "online"); } -- cgit v1.2.3 From 04024bf52cf11bffb2272e449055a2bd389bd59f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 25 Jan 2009 03:58:06 +0000 Subject: Fix a crash when cancelling a task in the task bar. Tinker with task bar padding. svn path=/branches/kill-bonobo/; revision=37131 --- widgets/misc/e-activity-proxy.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index 24ffa5e521..dc41e71f8f 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -151,6 +151,9 @@ activity_proxy_dispose (GObject *object) priv = E_ACTIVITY_PROXY_GET_PRIVATE (object); if (priv->activity != NULL) { + g_signal_handlers_disconnect_matched ( + priv->activity, G_SIGNAL_MATCH_FUNC, 0, 0, + NULL, activity_proxy_update, NULL); g_object_unref (priv->activity); priv->activity = NULL; } -- cgit v1.2.3 From bc80332460c353e391cd620f2cc51f7b56eef4de Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 26 Jan 2009 18:49:51 +0000 Subject: Miscellaneous stuff. svn path=/branches/kill-bonobo/; revision=37134 --- widgets/misc/e-attachment-bar.c | 101 ---------------------------------------- widgets/misc/e-attachment-bar.h | 8 +--- widgets/misc/e-charset-picker.c | 3 -- widgets/misc/e-charset-picker.h | 1 - 4 files changed, 1 insertion(+), 112 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 2da9d3541c..316aa85a0e 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -76,9 +76,6 @@ static GnomeIconListClass *parent_class = NULL; struct _EAttachmentBarPrivate { GtkWidget *attach; /* attachment file dialogue, if active */ - /* Recent documents. Use this widget directly when bonoboui is obsoleted */ - GtkWidget *recent; - gboolean batch_unref; GPtrArray *attachments; char *path; @@ -791,9 +788,6 @@ destroy (GtkObject *object) if (priv->attach) gtk_widget_destroy (priv->attach); - if (priv->recent) - gtk_widget_destroy (priv->recent); - if (priv->path) g_free (priv->path); @@ -1065,14 +1059,6 @@ init (EAttachmentBar *bar) priv->batch_unref = FALSE; priv->attachments = g_ptr_array_new (); - priv->recent = gtk_recent_chooser_menu_new (); - gtk_recent_chooser_menu_set_show_numbers (GTK_RECENT_CHOOSER_MENU (priv->recent), TRUE); - gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (priv->recent), GTK_RECENT_SORT_MRU); - gtk_recent_chooser_set_show_not_found (GTK_RECENT_CHOOSER (priv->recent), FALSE); - gtk_recent_chooser_set_show_private (GTK_RECENT_CHOOSER (priv->recent), FALSE); - gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (priv->recent), TRUE); - gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER (priv->recent), TRUE); - priv->path = NULL; bar->priv = priv; @@ -1297,7 +1283,6 @@ void e_attachment_bar_refresh (EAttachmentBar *bar) { update (bar); - } int @@ -1352,92 +1337,6 @@ e_attachment_bar_attach_mime_part (EAttachmentBar *bar, CamelMimePart *part) add_from_mime_part (bar, part); } -/* FIXME: Remove this API if nobody uses it */ -void -e_attachment_bar_bonobo_ui_populate_with_recent (BonoboUIComponent *uic, const char *path, - EAttachmentBar *bar, - BonoboUIVerbFn verb_cb, gpointer user_data) -{ - struct _EAttachmentBarPrivate *priv; - GList *items, *l; - gint limit, i; - GString *menuitems; - char *encoded_label, *label; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - priv = bar->priv; - limit = gtk_recent_chooser_get_limit (GTK_RECENT_CHOOSER (priv->recent)); - items = gtk_recent_chooser_get_items (GTK_RECENT_CHOOSER (priv->recent)); - - menuitems = g_string_new ("\n"); - - for (l = g_list_first (items), i = 1; l && i <= limit; l = l->next, ++i) { - GtkRecentInfo *info = ((GtkRecentInfo *)(l->data)); - const gchar *info_dn = gtk_recent_info_get_display_name (info); - char *display_name, *u; - - /* escape _'s in the display name so that it doesn't become an underline in a GtkLabel */ - if ((u = strchr (info_dn, '_'))) { - int extra = 1; - char *d; - const char *s; - - while ((u = strchr (u + 1, '_'))) - extra++; - - d = display_name = g_alloca (strlen (info_dn) + extra + 1); - s = info_dn; - while (*s != '\0') { - if (*s == '_') - *d++ = '_'; - *d++ = *s++; - } - *d = '\0'; - } else - display_name = (char *) info_dn; - - /* Add menu item */ - label = g_strdup (display_name); - encoded_label = bonobo_ui_util_encode_str (label); - g_string_append_printf (menuitems, - " \n", - i, encoded_label); - g_free (encoded_label); - g_free (label); - } - - g_string_append (menuitems, "\n"); - - bonobo_ui_component_set (uic, path, menuitems->str, NULL); - - g_string_free (menuitems, TRUE); - - /* Add uri prop */ - for (l = g_list_first (items), i = 1; l && i <= limit; l = l->next, ++i) { - GtkRecentInfo *info = ((GtkRecentInfo *)(l->data)); - const gchar *info_uri = gtk_recent_info_get_uri (info); - label = g_strdup_printf ("/commands/Recent-%d", i); - bonobo_ui_component_set_prop (uic, label, "uri", info_uri, NULL); - g_free (label); - } - - /* Add verb */ - for (l = g_list_first (items), i = 1; l && i <= limit; l = l->next, ++i) { - label = g_strdup_printf ("Recent-%d", i); - bonobo_ui_component_add_verb (uic, label, verb_cb, user_data); - g_free (label); - } - - for (l = g_list_first (items); l; l = l->next) - gtk_recent_info_unref ((GtkRecentInfo *)(l->data)); - g_list_free (items); -} - static void action_recent_cb (GtkAction *action, EAttachmentBar *attachment_bar) diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h index 7f8b4795d1..363b7f0fb8 100644 --- a/widgets/misc/e-attachment-bar.h +++ b/widgets/misc/e-attachment-bar.h @@ -24,11 +24,9 @@ #ifndef __E_ATTACHMENT_BAR_H__ #define __E_ATTACHMENT_BAR_H__ +#include #include -#include -#include - #include #include "e-attachment.h" @@ -85,10 +83,6 @@ GSList *e_attachment_bar_get_selected (EAttachmentBar *bar); void e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width); GSList * e_attachment_bar_get_all_attachments (EAttachmentBar *bar); void e_attachment_bar_create_attachment_cache (EAttachment *attachment); -void -e_attachment_bar_bonobo_ui_populate_with_recent (BonoboUIComponent *uic, const char *path, - EAttachmentBar *bar, - BonoboUIVerbFn verb_cb, gpointer user_data); GtkAction * e_attachment_bar_recent_action_new (EAttachmentBar *bar, const gchar *action_name, diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index ade1c186a6..6b30b3b11c 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -31,9 +31,6 @@ #include -#include -#include - typedef enum { E_CHARSET_UNKNOWN, E_CHARSET_ARABIC, diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index 21643ccf99..1521a2dbb0 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -22,7 +22,6 @@ #define E_CHARSETPICKER_H #include -#include G_BEGIN_DECLS -- cgit v1.2.3 From 533d59e2cd30ba79a99a71907ffdda65505e633a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 28 Jan 2009 17:19:34 +0000 Subject: Add unique-1.0 requirement (blessed external dependency). Make EShell a subclass of UniqueApp and handle single-instance negotiation. When another Evolution process is running: - Running "evolution" will simply present the existing windows. - Running "evolution -c " will open a shell window set to . - Running "evolution " will open an appropriate window for . The second process will then terminate immediately. svn path=/branches/kill-bonobo/; revision=37147 --- widgets/misc/e-activity-proxy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index dc41e71f8f..9c08a8d9a0 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -160,7 +160,7 @@ activity_proxy_dispose (GObject *object) if (priv->button != NULL) { g_object_unref (priv->button); - priv->image = NULL; + priv->button = NULL; } if (priv->image != NULL) { -- cgit v1.2.3 From fee5916b60c605ff5086d8fdc2a85c5ea21351f6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 31 Jan 2009 19:03:12 +0000 Subject: Merge revisions 37108:37199 from trunk. svn path=/branches/kill-bonobo/; revision=37200 --- widgets/misc/ChangeLog | 10 ++++++++++ widgets/misc/e-calendar-item.c | 24 +++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index e8c1a5023d..2c1046f0a6 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,13 @@ +2009-01-30 Suman Manjunath + + ** Fix for bug #342446 + + ** Committing on behalf of Behnam Esfahbod + + * e-calendar-item.c (e_calendar_item_draw_day_numbers), + (e_calendar_item_recalc_sizes), (e_calendar_item_position_menu): + Use localized digits in the calendar widget. + 2009-01-11 Matthew Barnes * e-attachment-bar.c (eab_icon_clicked_cb): diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 3bf1fe65a7..da4c063175 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -1395,7 +1395,7 @@ e_calendar_item_draw_day_numbers (ECalendarItem *calitem, gboolean today, selected, has_focus, drop_target = FALSE; gboolean bold, draw_day, finished = FALSE; gint today_year, today_month, today_mday, month_offset; - gchar buffer[2]; + gchar buffer[9]; gint day_style = 0; PangoContext *pango_context; PangoFontMetrics *font_metrics; @@ -1505,12 +1505,12 @@ e_calendar_item_draw_day_numbers (ECalendarItem *calitem, if (week_num >= 10) { digit = week_num / 10; text_x -= calitem->week_number_digit_widths[digit]; - buffer[num_chars++] = digit + '0'; + num_chars += sprintf (&buffer[num_chars], "%Id", digit); } digit = week_num % 10; text_x -= calitem->week_number_digit_widths[digit] + 6; - buffer[num_chars++] = digit + '0'; + num_chars += sprintf (&buffer[num_chars], "%Id", digit); cairo_save (cr); gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_ACTIVE]); @@ -1618,12 +1618,12 @@ e_calendar_item_draw_day_numbers (ECalendarItem *calitem, if (day_num >= 10) { digit = day_num / 10; day_x -= calitem->digit_widths[digit]; - buffer[num_chars++] = digit + '0'; + num_chars += sprintf (&buffer[num_chars], "%Id", digit); } digit = day_num % 10; day_x -= calitem->digit_widths[digit]; - buffer[num_chars++] = digit + '0'; + num_chars += sprintf (&buffer[num_chars], "%Id", digit); cairo_save (cr); if (fg_color) { @@ -1913,7 +1913,6 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) { GnomeCanvasItem *canvas_item; GtkStyle *style; - gchar *digits = "0123456789"; gint day, max_day_width, digit, max_digit_width, max_week_number_digit_width; gint char_height, width, min_cell_width, min_cell_height; PangoFontDescription *font_desc, *wkfont_desc; @@ -1956,7 +1955,12 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) max_digit_width = 0; max_week_number_digit_width = 0; for (digit = 0; digit < 10; digit++) { - pango_layout_set_text (layout, &digits [digit], 1); + gchar locale_digit[5]; + int locale_digit_len; + + locale_digit_len = sprintf (locale_digit, "%Id", digit); + + pango_layout_set_text (layout, locale_digit, locale_digit_len); pango_layout_get_pixel_size (layout, &width, NULL); calitem->digit_widths[digit] = width; @@ -1966,7 +1970,7 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) pango_context_set_font_description (pango_context, wkfont_desc); pango_layout_context_changed (layout); - pango_layout_set_text (layout, &digits [digit], 1); + pango_layout_set_text (layout, locale_digit, locale_digit_len); pango_layout_get_pixel_size (layout, &width, NULL); calitem->week_number_digit_widths[digit] = width; @@ -3352,7 +3356,9 @@ e_calendar_item_position_menu (GtkMenu *menu, gtk_widget_get_child_requisition (GTK_WIDGET (menu), &requisition); - *x -= 2; + *x -= (gtk_widget_get_direction(GTK_WIDGET(menu)) == GTK_TEXT_DIR_RTL) + ? requisition.width - 2 + : 2; *y -= requisition.height / 2; screen_width = gdk_screen_width (); -- cgit v1.2.3 From 14e8637d6b1a98b4ed6bedc70d0fca744b7b3e0f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 7 Feb 2009 20:04:52 +0000 Subject: Rewrite the mail label code from top to bottom. - Kill the e-util-labels API and read label information into a single-column GtkListStore. Use GConfBridge to automatically keep GConf synched with the list store. - The list store (a singleton instance) is stored in EShellSettings so it's available everywhere. - The list store serves as the model for EMailLabelTreeView, which itself is embedded in EMailLabelManager; a complete label management UI as seen in the preferences dialog. - EMailLabelDialog is used to add or edit a label. Avoid using a color button, instead embed a GtkColorSelection directly in the dialog so everything is in one window. Open issues: - The weird toggle/color/text menu items in the popup menu aren't there. For now they're just regular toggle items. I'll deal with it later. - Filter intergration is broken at the moment. svn path=/branches/kill-bonobo/; revision=37233 --- widgets/misc/e-action-combo-box.c | 17 +++++++++++++++++ widgets/misc/e-action-combo-box.h | 3 +++ 2 files changed, 20 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c index 977ac06ade..e8a9be51ed 100644 --- a/widgets/misc/e-action-combo-box.c +++ b/widgets/misc/e-action-combo-box.c @@ -547,6 +547,23 @@ e_action_combo_box_set_current_value (EActionComboBox *combo_box, combo_box->priv->action, current_value); } +void +e_action_combo_box_add_separator_before (EActionComboBox *combo_box, + gint action_value) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box)); + + /* NULL actions are rendered as separators. */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, COLUMN_ACTION, + NULL, COLUMN_SORT, (gfloat) action_value - 0.5, -1); +} + void e_action_combo_box_add_separator_after (EActionComboBox *combo_box, gint action_value) diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h index c3e6941ca6..300338639a 100644 --- a/widgets/misc/e-action-combo-box.h +++ b/widgets/misc/e-action-combo-box.h @@ -73,6 +73,9 @@ gint e_action_combo_box_get_current_value void e_action_combo_box_set_current_value (EActionComboBox *combo_box, gint current_value); +void e_action_combo_box_add_separator_before + (EActionComboBox *combo_box, + gint action_value); void e_action_combo_box_add_separator_after (EActionComboBox *combo_box, gint action_value); -- cgit v1.2.3 From de169b4feeeaf2013aa256ddf70276bacbd6542a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 10 Feb 2009 02:51:52 +0000 Subject: Rewrite the signature management UI from top to bottom. - Break the UI out of Glade and into small, manageable widgets: ESignatureEditor (moved from mail to widgets/misc) ESignatureManager ESignatureTreeView ESignatureScriptDialog - Move several signature utilities to e-util/e-signature-utils.c so they're accessible from widgets/misc without introducing circular dependences. - Have EMailShellModule listen for new GtkhtmlEditor windows (from which EMsgComposer and ESignatureEditor are derived) and configure the window with spelling and HTML editing user preferences. - Drastically simplifies em-composer-prefs.c. svn path=/branches/kill-bonobo/; revision=37239 --- widgets/misc/Makefile.am | 8 + widgets/misc/e-signature-combo-box.c | 1 + widgets/misc/e-signature-combo-box.h | 1 + widgets/misc/e-signature-editor.c | 503 +++++++++++++++++++++ widgets/misc/e-signature-editor.h | 70 +++ widgets/misc/e-signature-manager.c | 746 +++++++++++++++++++++++++++++++ widgets/misc/e-signature-manager.h | 100 +++++ widgets/misc/e-signature-script-dialog.c | 463 +++++++++++++++++++ widgets/misc/e-signature-script-dialog.h | 76 ++++ widgets/misc/e-signature-tree-view.c | 405 +++++++++++++++++ widgets/misc/e-signature-tree-view.h | 78 ++++ 11 files changed, 2451 insertions(+) create mode 100644 widgets/misc/e-signature-editor.c create mode 100644 widgets/misc/e-signature-editor.h create mode 100644 widgets/misc/e-signature-manager.c create mode 100644 widgets/misc/e-signature-manager.h create mode 100644 widgets/misc/e-signature-script-dialog.c create mode 100644 widgets/misc/e-signature-script-dialog.h create mode 100644 widgets/misc/e-signature-tree-view.c create mode 100644 widgets/misc/e-signature-tree-view.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ce702ec9fd..a1d555085b 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -78,6 +78,10 @@ widgetsinclude_HEADERS = \ e-selection-model-simple.h \ e-selection-model.h \ e-signature-combo-box.h \ + e-signature-editor.h \ + e-signature-manager.h \ + e-signature-script-dialog.h \ + e-signature-tree-view.h \ e-unicode.h \ e-colors.h @@ -125,6 +129,10 @@ libemiscwidgets_la_SOURCES = \ e-selection-model-simple.c \ e-selection-model.c \ e-signature-combo-box.c \ + e-signature-editor.c \ + e-signature-manager.c \ + e-signature-script-dialog.c \ + e-signature-tree-view.c \ e-unicode.c \ e-colors.c diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c index 9ebd20a0b2..40a93b7d25 100644 --- a/widgets/misc/e-signature-combo-box.c +++ b/widgets/misc/e-signature-combo-box.c @@ -1,4 +1,5 @@ /* + * e-signature-combo-box.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/widgets/misc/e-signature-combo-box.h b/widgets/misc/e-signature-combo-box.h index ec05c2b5d7..5cdd224e6b 100644 --- a/widgets/misc/e-signature-combo-box.h +++ b/widgets/misc/e-signature-combo-box.h @@ -1,4 +1,5 @@ /* + * e-signature-combo-box.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/widgets/misc/e-signature-editor.c b/widgets/misc/e-signature-editor.c new file mode 100644 index 0000000000..c7dcbdaad9 --- /dev/null +++ b/widgets/misc/e-signature-editor.c @@ -0,0 +1,503 @@ +/* + * e-signature-editor.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-signature-editor.h" + +#include +#include + +#include +#include + +#define E_SIGNATURE_EDITOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorPrivate)) + +enum { + PROP_0, + PROP_SIGNATURE +}; + +struct _ESignatureEditorPrivate { + GtkActionGroup *action_group; + ESignature *signature; + GtkWidget *entry; + gchar *original_name; +}; + +static const gchar *ui = +"\n" +" \n" +" \n" +" \n" +" \n" +" " +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +""; + +static gpointer parent_class = NULL; + +static void +handle_error (GError **error) +{ + if (*error != NULL) { + g_warning ("%s", (*error)->message); + g_clear_error (error); + } +} + +static void +action_close_cb (GtkAction *action, + ESignatureEditor *editor) +{ + gboolean something_changed = FALSE; + const gchar *original_name; + const gchar *signature_name; + + original_name = editor->priv->original_name; + signature_name = gtk_entry_get_text (GTK_ENTRY (editor->priv->entry)); + + something_changed |= gtkhtml_editor_has_undo (GTKHTML_EDITOR (editor)); + something_changed |= (strcmp (signature_name, original_name) != 0); + + if (something_changed) { + gint response; + + response = e_error_run ( + GTK_WINDOW (editor), + "mail:ask-signature-changed", NULL); + if (response == GTK_RESPONSE_YES) { + GtkActionGroup *action_group; + + action_group = editor->priv->action_group; + action = gtk_action_group_get_action ( + action_group, "save-and-close"); + gtk_action_activate (action); + return; + } else if (response == GTK_RESPONSE_CANCEL) + return; + } + + gtk_widget_destroy (GTK_WIDGET (editor)); +} + +static void +action_save_and_close_cb (GtkAction *action, + ESignatureEditor *editor) +{ + GtkWidget *entry; + ESignatureList *signature_list; + ESignature *signature; + ESignature *same_name; + const gchar *filename; + gchar *signature_name; + gboolean html; + GError *error = NULL; + + entry = editor->priv->entry; + html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor)); + + if (editor->priv->signature == NULL) { + signature = e_signature_new (); + signature->name = g_strdup (_("Unnamed")); + signature->script = FALSE; + signature->html = html; + + /* FIXME Pass a GError and deal with it. */ + signature->filename = e_create_signature_file (NULL); + } else { + signature = g_object_ref (editor->priv->signature); + signature->html = html; + } + + filename = signature->filename; + gtkhtml_editor_save (GTKHTML_EDITOR (editor), filename, html, &error); + + if (error != NULL) { + e_error_run ( + GTK_WINDOW (editor), + "mail:no-save-signature", + error->message, NULL); + g_clear_error (&error); + return; + } + + signature_list = e_get_signature_list (); + + signature_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + g_strstrip (signature_name); + + /* Make sure the signature name is not blank. */ + if (*signature_name == '\0') { + e_error_run ( + GTK_WINDOW (editor), + "mail:blank-signature", NULL); + gtk_widget_grab_focus (entry); + g_free (signature_name); + return; + } + + /* Don't overwrite an existing signature of the same name. + * XXX ESignatureList misuses const. */ + same_name = (ESignature *) e_signature_list_find ( + signature_list, E_SIGNATURE_FIND_NAME, signature_name); + if (same_name != NULL && strcmp (signature->uid, same_name->uid) != 0) { + e_error_run ( + GTK_WINDOW (editor), + "mail:signature-already-exists", + signature_name, NULL); + gtk_widget_grab_focus (entry); + g_free (signature_name); + return; + } + + g_free (signature->name); + signature->name = signature_name; + + if (editor->priv->signature != NULL) + e_signature_list_change (signature_list, signature); + else + e_signature_list_add (signature_list, signature); + e_signature_list_save (signature_list); + + gtk_widget_destroy (GTK_WIDGET (editor)); +} + +static GtkActionEntry entries[] = { + + { "close", + GTK_STOCK_CLOSE, + N_("_Close"), + "w", + NULL, + G_CALLBACK (action_close_cb) }, + + { "save-and-close", + GTK_STOCK_SAVE, + N_("_Save and Close"), + "Return", + NULL, + G_CALLBACK (action_save_and_close_cb) }, + + { "file-menu", + NULL, + N_("_File"), + NULL, + NULL, + NULL } +}; + +static gboolean +signature_editor_delete_event_cb (ESignatureEditor *editor, + GdkEvent *event) +{ + GtkActionGroup *action_group; + GtkAction *action; + + action_group = editor->priv->action_group; + action = gtk_action_group_get_action (action_group, "close"); + gtk_action_activate (action); + + return TRUE; +} + +static void +signature_editor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SIGNATURE: + e_signature_editor_set_signature ( + E_SIGNATURE_EDITOR (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +signature_editor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SIGNATURE: + g_value_set_object ( + value, e_signature_editor_get_signature ( + E_SIGNATURE_EDITOR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +signature_editor_dispose (GObject *object) +{ + ESignatureEditorPrivate *priv; + + priv = E_SIGNATURE_EDITOR_GET_PRIVATE (object); + + if (priv->action_group != NULL) { + g_object_unref (priv->action_group); + priv->action_group = NULL; + } + + if (priv->signature != NULL) { + g_object_unref (priv->signature); + priv->signature = NULL; + } + + if (priv->entry != NULL) { + g_object_unref (priv->entry); + priv->entry = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +signature_editor_finalize (GObject *object) +{ + ESignatureEditorPrivate *priv; + + priv = E_SIGNATURE_EDITOR_GET_PRIVATE (object); + + g_free (priv->original_name); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +signature_editor_class_init (ESignatureEditorClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESignatureEditorPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = signature_editor_set_property; + object_class->get_property = signature_editor_get_property; + object_class->dispose = signature_editor_dispose; + object_class->finalize = signature_editor_finalize; + + g_object_class_install_property ( + object_class, + PROP_SIGNATURE, + g_param_spec_object ( + "signature", + NULL, + NULL, + E_TYPE_SIGNATURE, + G_PARAM_READWRITE)); +} + +static void +signature_editor_init (ESignatureEditor *editor) +{ + GtkActionGroup *action_group; + GtkUIManager *manager; + GtkWidget *container; + GtkWidget *widget; + GtkWidget *vbox; + GError *error = NULL; + + editor->priv = E_SIGNATURE_EDITOR_GET_PRIVATE (editor); + vbox = GTKHTML_EDITOR (editor)->vbox; + + manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); + + gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error); + handle_error (&error); + + action_group = gtk_action_group_new ("signature"); + gtk_action_group_set_translation_domain ( + action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions ( + action_group, entries, + G_N_ELEMENTS (entries), editor); + gtk_ui_manager_insert_action_group (manager, action_group, 0); + editor->priv->action_group = g_object_ref (action_group); + + gtk_ui_manager_ensure_update (manager); + + gtk_window_set_title (GTK_WINDOW (editor), _("Edit Signature")); + + widget = gtk_hbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (widget), 6); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + /* Position 2 should be between the main and style toolbars. */ + gtk_box_reorder_child (GTK_BOX (vbox), widget, 2); + gtk_widget_show (widget); + container = widget; + + widget = gtk_entry_new (); + gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0); + editor->priv->entry = g_object_ref_sink (widget); + gtk_widget_show (widget); + + widget = gtk_label_new_with_mnemonic (_("_Signature Name:")); + gtk_label_set_mnemonic_widget (GTK_LABEL (widget), editor->priv->entry); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_signal_connect ( + editor, "delete-event", + G_CALLBACK (signature_editor_delete_event_cb), NULL); + + e_signature_editor_set_signature (editor, NULL); +} + +GType +e_signature_editor_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESignatureEditorClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) signature_editor_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESignatureEditor), + 0, /* n_preallocs */ + (GInstanceInitFunc) signature_editor_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTKHTML_TYPE_EDITOR, "ESignatureEditor", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_signature_editor_new (void) +{ + return g_object_new (E_TYPE_SIGNATURE_EDITOR, NULL); +} + +ESignature * +e_signature_editor_get_signature (ESignatureEditor *editor) +{ + g_return_val_if_fail (E_IS_SIGNATURE_EDITOR (editor), NULL); + + return editor->priv->signature; +} + +void +e_signature_editor_set_signature (ESignatureEditor *editor, + ESignature *signature) +{ + const gchar *filename; + const gchar *signature_name; + gchar *contents; + gsize length; + GError *error = NULL; + + g_return_if_fail (E_IS_SIGNATURE_EDITOR (editor)); + + if (signature != NULL) + g_return_if_fail (E_SIGNATURE (signature)); + + if (editor->priv->signature != NULL) { + g_object_unref (editor->priv->signature); + editor->priv->signature = NULL; + } + + if (signature == NULL) + goto exit; + + editor->priv->signature = g_object_ref (signature); + + /* Load signature content. */ + + filename = signature->filename; + + if (signature->html) + g_file_get_contents (filename, &contents, &length, &error); + else { + gchar *data; + + data = e_read_signature_file (signature, FALSE, &error); + if (data != NULL) + contents = g_strdup_printf ("
\n%s", data);
+		else
+			contents = NULL;
+		length = -1;
+		g_free (data);
+	}
+
+	if (error == NULL) {
+		gtkhtml_editor_set_html_mode (
+			GTKHTML_EDITOR (editor), signature->html);
+		gtkhtml_editor_set_text_html (
+			GTKHTML_EDITOR (editor), contents, length);
+		g_free (contents);
+	} else {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+exit:
+	if (signature != NULL)
+		signature_name = signature->name;
+	else
+		signature_name = _("Unnamed");
+
+	/* Set the entry text before we grab focus. */
+	g_free (editor->priv->original_name);
+	editor->priv->original_name = g_strdup (signature_name);
+	gtk_entry_set_text (GTK_ENTRY (editor->priv->entry), signature_name);
+
+	/* Set the focus appropriately.  If this is a new signature, draw
+	 * the user's attention to the signature name entry.  Otherwise go
+	 * straight to the editing area. */
+	if (signature == NULL)
+		gtk_widget_grab_focus (editor->priv->entry);
+	else {
+		GtkHTML *html;
+
+		html = gtkhtml_editor_get_html (GTKHTML_EDITOR (editor));
+		gtk_widget_grab_focus (GTK_WIDGET (html));
+	}
+
+	g_object_notify (G_OBJECT (editor), "signature");
+}
diff --git a/widgets/misc/e-signature-editor.h b/widgets/misc/e-signature-editor.h
new file mode 100644
index 0000000000..9d6c37ac87
--- /dev/null
+++ b/widgets/misc/e-signature-editor.h
@@ -0,0 +1,70 @@
+/*
+ * e-signature-editor.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_EDITOR_H
+#define E_SIGNATURE_EDITOR_H
+
+#include 
+#include 
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_EDITOR \
+	(e_signature_editor_get_type ())
+#define E_SIGNATURE_EDITOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditor))
+#define E_SIGNATURE_EDITOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorClass))
+#define E_IS_SIGNATURE_EDITOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SIGNATURE_EDITOR))
+#define E_IS_SIGNATURE_EDITOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SIGNATURE_EDITOR))
+#define E_SIGNATURE_EDITOR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureEditor ESignatureEditor;
+typedef struct _ESignatureEditorClass ESignatureEditorClass;
+typedef struct _ESignatureEditorPrivate ESignatureEditorPrivate;
+
+struct _ESignatureEditor {
+	GtkhtmlEditor parent;
+	ESignatureEditorPrivate *priv;
+};
+
+struct _ESignatureEditorClass {
+	GtkhtmlEditorClass parent_class;
+};
+
+GType		e_signature_editor_get_type	 (void);
+GtkWidget *	e_signature_editor_new		 (void);
+ESignature *	e_signature_editor_get_signature (ESignatureEditor *editor);
+void		e_signature_editor_set_signature (ESignatureEditor *editor,
+						  ESignature *signature);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_EDITOR_H */
diff --git a/widgets/misc/e-signature-manager.c b/widgets/misc/e-signature-manager.c
new file mode 100644
index 0000000000..0c145e9821
--- /dev/null
+++ b/widgets/misc/e-signature-manager.c
@@ -0,0 +1,746 @@
+/*
+ * e-signature-manager.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-manager.h"
+
+#include 
+#include 
+#include 
+#include "e-util/e-binding.h"
+#include "e-signature-tree-view.h"
+#include "e-signature-script-dialog.h"
+
+#define E_SIGNATURE_MANAGER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerPrivate))
+
+struct _ESignatureManagerPrivate {
+	ESignatureList *signature_list;
+
+	GtkWidget *tree_view;
+	GtkWidget *add_button;
+	GtkWidget *add_script_button;
+	GtkWidget *edit_button;
+	GtkWidget *remove_button;
+
+	guint allow_scripts : 1;
+	guint prefer_html   : 1;
+};
+
+enum {
+	PROP_0,
+	PROP_ALLOW_SCRIPTS,
+	PROP_PREFER_HTML,
+	PROP_SIGNATURE_LIST
+};
+
+enum {
+	ADD_SIGNATURE,
+	ADD_SIGNATURE_SCRIPT,
+	EDITOR_CREATED,
+	EDIT_SIGNATURE,
+	REMOVE_SIGNATURE,
+	LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_manager_emit_editor_created (ESignatureManager *manager,
+                                       GtkWidget *editor)
+{
+	g_return_if_fail (E_IS_SIGNATURE_EDITOR (editor));
+
+	g_signal_emit (manager, signals[EDITOR_CREATED], 0, editor);
+}
+
+static gboolean
+signature_manager_key_press_event_cb (ESignatureManager *manager,
+                                      GdkEventKey *event)
+{
+	if (event->keyval == GDK_Delete) {
+		e_signature_manager_remove_signature (manager);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+signature_manager_run_script_dialog (ESignatureManager *manager,
+                                     ESignature *signature,
+                                     const gchar *title)
+{
+	GtkWidget *dialog;
+	GFile *script_file;
+	const gchar *script_name;
+	gboolean success = FALSE;
+	gpointer parent;
+
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+	parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+	dialog = e_signature_script_dialog_new (parent);
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+
+	if (signature->filename != NULL && signature->name != NULL) {
+
+		script_file = g_file_new_for_path (signature->filename);
+		script_name = signature->name;
+
+		e_signature_script_dialog_set_script_file (
+			E_SIGNATURE_SCRIPT_DIALOG (dialog), script_file);
+		e_signature_script_dialog_set_script_name (
+			E_SIGNATURE_SCRIPT_DIALOG (dialog), script_name);
+
+		g_object_unref (script_file);
+	}
+
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+		goto exit;
+
+	script_file = e_signature_script_dialog_get_script_file (
+		E_SIGNATURE_SCRIPT_DIALOG (dialog));
+	script_name = e_signature_script_dialog_get_script_name (
+		E_SIGNATURE_SCRIPT_DIALOG (dialog));
+
+	g_free (signature->filename);
+	signature->filename = g_file_get_path (script_file);
+
+	g_free (signature->name);
+	signature->name = g_strdup (script_name);
+
+	g_object_unref (script_file);
+
+	success = TRUE;
+
+exit:
+	gtk_widget_destroy (dialog);
+
+	return success;
+}
+
+static void
+signature_manager_selection_changed_cb (ESignatureManager *manager,
+                                        GtkTreeSelection *selection)
+{
+	GtkWidget *edit_button;
+	GtkWidget *remove_button;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	edit_button = manager->priv->edit_button;
+	remove_button = manager->priv->remove_button;
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		gtk_widget_set_sensitive (edit_button, TRUE);
+		gtk_widget_set_sensitive (remove_button, TRUE);
+	} else {
+		gtk_widget_set_sensitive (edit_button, FALSE);
+		gtk_widget_set_sensitive (remove_button, FALSE);
+	}
+}
+
+static void
+signature_manager_set_property (GObject *object,
+                                guint property_id,
+                                const GValue *value,
+                                GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALLOW_SCRIPTS:
+			e_signature_manager_set_allow_scripts (
+				E_SIGNATURE_MANAGER (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_PREFER_HTML:
+			e_signature_manager_set_prefer_html (
+				E_SIGNATURE_MANAGER (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_SIGNATURE_LIST:
+			e_signature_manager_set_signature_list (
+				E_SIGNATURE_MANAGER (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_manager_get_property (GObject *object,
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALLOW_SCRIPTS:
+			g_value_set_boolean (
+				value,
+				e_signature_manager_get_allow_scripts (
+				E_SIGNATURE_MANAGER (object)));
+			return;
+
+		case PROP_PREFER_HTML:
+			g_value_set_boolean (
+				value,
+				e_signature_manager_get_prefer_html (
+				E_SIGNATURE_MANAGER (object)));
+			return;
+
+		case PROP_SIGNATURE_LIST:
+			g_value_set_object (
+				value,
+				e_signature_manager_get_signature_list (
+				E_SIGNATURE_MANAGER (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_manager_dispose (GObject *object)
+{
+	ESignatureManagerPrivate *priv;
+
+	priv = E_SIGNATURE_MANAGER_GET_PRIVATE (object);
+
+	if (priv->signature_list != NULL) {
+		g_object_unref (priv->signature_list);
+		priv->signature_list = NULL;
+	}
+
+	if (priv->tree_view != NULL) {
+		g_object_unref (priv->tree_view);
+		priv->tree_view = NULL;
+	}
+
+	if (priv->add_button != NULL) {
+		g_object_unref (priv->add_button);
+		priv->add_button = NULL;
+	}
+
+	if (priv->add_script_button != NULL) {
+		g_object_unref (priv->add_script_button);
+		priv->add_script_button = NULL;
+	}
+
+	if (priv->edit_button != NULL) {
+		g_object_unref (priv->edit_button);
+		priv->edit_button = NULL;
+	}
+
+	if (priv->remove_button != NULL) {
+		g_object_unref (priv->remove_button);
+		priv->remove_button = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_manager_add_signature (ESignatureManager *manager)
+{
+	ESignatureTreeView *tree_view;
+	GtkWidget *editor;
+
+	tree_view = e_signature_manager_get_tree_view (manager);
+
+	editor = e_signature_editor_new ();
+	gtkhtml_editor_set_html_mode (
+		GTKHTML_EDITOR (editor), manager->priv->prefer_html);
+	signature_manager_emit_editor_created (manager, editor);
+
+	gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_add_signature_script (ESignatureManager *manager)
+{
+	ESignatureTreeView *tree_view;
+	ESignatureList *signature_list;
+	ESignature *signature;
+	const gchar *title;
+
+	title = _("Add Signature Script");
+	tree_view = e_signature_manager_get_tree_view (manager);
+	signature_list = e_signature_manager_get_signature_list (manager);
+
+	signature = e_signature_new ();
+	signature->script = TRUE;
+	signature->html = TRUE;
+
+	if (signature_manager_run_script_dialog (manager, signature, title))
+		e_signature_list_add (signature_list, signature);
+
+	e_signature_list_save (signature_list);
+	g_object_unref (signature);
+
+	gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_editor_created (ESignatureManager *manager,
+                                  ESignatureEditor *editor)
+{
+	GtkWindowPosition position;
+	gpointer parent;
+
+	position = GTK_WIN_POS_CENTER_ON_PARENT;
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+	parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+	gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+	gtk_window_set_position (GTK_WINDOW (editor), position);
+	gtk_widget_show (GTK_WIDGET (editor));
+}
+
+static void
+signature_manager_edit_signature (ESignatureManager *manager)
+{
+	ESignatureTreeView *tree_view;
+	ESignatureList *signature_list;
+	ESignature *signature;
+	GtkWidget *editor;
+	const gchar *title;
+	gchar *filename;
+
+	tree_view = e_signature_manager_get_tree_view (manager);
+	signature = e_signature_tree_view_get_selected (tree_view);
+	signature_list = e_signature_manager_get_signature_list (manager);
+
+	if (signature == NULL)
+		return;
+
+	if (signature->script)
+		goto script;
+
+	filename = signature->filename;
+	if (filename == NULL || *filename == '\0') {
+		g_free (filename);
+		filename = g_strdup (_("Unnamed"));
+		signature->filename = filename;
+	}
+
+	editor = e_signature_editor_new ();
+	e_signature_editor_set_signature (
+		E_SIGNATURE_EDITOR (editor), signature);
+	signature_manager_emit_editor_created (manager, editor);
+
+	goto exit;
+
+script:
+	title = _("Edit Signature Script");
+
+	if (signature_manager_run_script_dialog (manager, signature, title))
+		e_signature_list_change (signature_list, signature);
+
+	e_signature_list_save (signature_list);
+
+exit:
+	gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+
+	g_object_unref (signature);
+}
+
+static void
+signature_manager_remove_signature (ESignatureManager *manager)
+{
+	ESignatureTreeView *tree_view;
+	ESignatureList *signature_list;
+	ESignature *signature;
+
+	tree_view = e_signature_manager_get_tree_view (manager);
+	signature = e_signature_tree_view_get_selected (tree_view);
+	signature_list = e_signature_tree_view_get_signature_list (tree_view);
+
+	if (signature == NULL)
+		return;
+
+	if (signature->filename != NULL && !signature->script)
+		g_unlink (signature->filename);
+
+	e_signature_list_remove (signature_list, signature);
+	e_signature_list_save (signature_list);
+
+	gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_class_init (ESignatureManagerClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (ESignatureManagerPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = signature_manager_set_property;
+	object_class->get_property = signature_manager_get_property;
+	object_class->dispose = signature_manager_dispose;
+
+	class->add_signature = signature_manager_add_signature;
+	class->add_signature_script = signature_manager_add_signature_script;
+	class->editor_created = signature_manager_editor_created;
+	class->edit_signature = signature_manager_edit_signature;
+	class->remove_signature = signature_manager_remove_signature;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ALLOW_SCRIPTS,
+		g_param_spec_boolean (
+			"allow-scripts",
+			"Allow Scripts",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_PREFER_HTML,
+		g_param_spec_boolean (
+			"prefer-html",
+			"Prefer HTML",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SIGNATURE_LIST,
+		g_param_spec_object (
+			"signature-list",
+			"Signature List",
+			NULL,
+			E_TYPE_SIGNATURE_LIST,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	signals[ADD_SIGNATURE] = g_signal_new (
+		"add-signature",
+		G_OBJECT_CLASS_TYPE (class),
+		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (ESignatureManagerClass, add_signature),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+
+	signals[ADD_SIGNATURE_SCRIPT] = g_signal_new (
+		"add-signature-script",
+		G_OBJECT_CLASS_TYPE (class),
+		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (ESignatureManagerClass, add_signature_script),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+
+	signals[EDITOR_CREATED] = g_signal_new (
+		"editor-created",
+		G_OBJECT_CLASS_TYPE (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (ESignatureManagerClass, editor_created),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__OBJECT,
+		G_TYPE_NONE, 1,
+		E_TYPE_SIGNATURE_EDITOR);
+
+	signals[EDIT_SIGNATURE] = g_signal_new (
+		"edit-signature",
+		G_OBJECT_CLASS_TYPE (class),
+		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (ESignatureManagerClass, edit_signature),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+
+	signals[REMOVE_SIGNATURE] = g_signal_new (
+		"remove-signature",
+		G_OBJECT_CLASS_TYPE (class),
+		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (ESignatureManagerClass, remove_signature),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+}
+
+static void
+signature_manager_init (ESignatureManager *manager)
+{
+	GtkTreeSelection *selection;
+	GtkWidget *container;
+	GtkWidget *widget;
+
+	manager->priv = E_SIGNATURE_MANAGER_GET_PRIVATE (manager);
+
+	gtk_table_resize (GTK_TABLE (manager), 1, 2);
+	gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+	gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+	container = GTK_WIDGET (manager);
+
+	widget = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (
+		GTK_SCROLLED_WINDOW (widget),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (
+		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+	gtk_table_attach (
+		GTK_TABLE (container), widget, 0, 1, 0, 1,
+		GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = e_signature_tree_view_new ();
+	gtk_container_add (GTK_CONTAINER (container), widget);
+	manager->priv->tree_view = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	e_mutual_binding_new (
+		G_OBJECT (manager), "signature-list",
+		G_OBJECT (widget), "signature-list");
+
+	g_signal_connect_swapped (
+		widget, "key-press-event",
+		G_CALLBACK (signature_manager_key_press_event_cb),
+		manager);
+
+	g_signal_connect_swapped (
+		widget, "row-activated",
+		G_CALLBACK (e_signature_manager_edit_signature),
+		manager);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+	g_signal_connect_swapped (
+		selection, "changed",
+		G_CALLBACK (signature_manager_selection_changed_cb),
+		manager);
+
+	container = GTK_WIDGET (manager);
+
+	widget = gtk_vbutton_box_new ();
+	gtk_button_box_set_layout (
+		GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+	gtk_box_set_spacing (GTK_BOX (widget), 6);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->add_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (e_signature_manager_add_signature),
+		manager);
+
+	widget = gtk_button_new_with_mnemonic (_("Add _Script"));
+	gtk_button_set_image (
+		GTK_BUTTON (widget), gtk_image_new_from_stock (
+		GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON));
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->add_script_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	e_binding_new (
+		G_OBJECT (manager), "allow-scripts",
+		G_OBJECT (widget), "sensitive");
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (e_signature_manager_add_signature_script),
+		manager);
+
+	widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->edit_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (e_signature_manager_edit_signature),
+		manager);
+
+	widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	manager->priv->remove_button = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	g_signal_connect_swapped (
+		widget, "clicked",
+		G_CALLBACK (e_signature_manager_remove_signature),
+		manager);
+}
+
+GType
+e_signature_manager_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (ESignatureManagerClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) signature_manager_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_init */
+			sizeof (ESignatureManager),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) signature_manager_init,
+			NULL   /* value_table */
+		};
+
+		type = g_type_register_static (
+			GTK_TYPE_TABLE, "ESignatureManager", &type_info, 0);
+	}
+
+	return type;
+}
+
+GtkWidget *
+e_signature_manager_new (ESignatureList *signature_list)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_LIST (signature_list), NULL);
+
+	return g_object_new (
+		E_TYPE_SIGNATURE_MANAGER,
+		"signature-list", signature_list, NULL);
+}
+
+void
+e_signature_manager_add_signature (ESignatureManager *manager)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	g_signal_emit (manager, signals[ADD_SIGNATURE], 0);
+}
+
+void
+e_signature_manager_add_signature_script (ESignatureManager *manager)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	g_signal_emit (manager, signals[ADD_SIGNATURE_SCRIPT], 0);
+}
+
+void
+e_signature_manager_edit_signature (ESignatureManager *manager)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	g_signal_emit (manager, signals[EDIT_SIGNATURE], 0);
+}
+
+void
+e_signature_manager_remove_signature (ESignatureManager *manager)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	g_signal_emit (manager, signals[REMOVE_SIGNATURE], 0);
+}
+
+gboolean
+e_signature_manager_get_allow_scripts (ESignatureManager *manager)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), FALSE);
+
+	return manager->priv->allow_scripts;
+}
+
+void
+e_signature_manager_set_allow_scripts (ESignatureManager *manager,
+                                       gboolean allow_scripts)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	manager->priv->allow_scripts = allow_scripts;
+
+	g_object_notify (G_OBJECT (manager), "allow-scripts");
+}
+
+gboolean
+e_signature_manager_get_prefer_html (ESignatureManager *manager)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), FALSE);
+
+	return manager->priv->prefer_html;
+}
+
+void
+e_signature_manager_set_prefer_html (ESignatureManager *manager,
+                                     gboolean prefer_html)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	manager->priv->prefer_html = prefer_html;
+
+	g_object_notify (G_OBJECT (manager), "prefer-html");
+}
+
+ESignatureList *
+e_signature_manager_get_signature_list (ESignatureManager *manager)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), NULL);
+
+	return manager->priv->signature_list;
+}
+
+void
+e_signature_manager_set_signature_list (ESignatureManager *manager,
+                                        ESignatureList *signature_list)
+{
+	g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+	if (signature_list != NULL) {
+		g_return_if_fail (E_IS_SIGNATURE_LIST (signature_list));
+		g_object_ref (signature_list);
+	}
+
+	if (manager->priv->signature_list != NULL)
+		g_object_unref (manager->priv->signature_list);
+
+	manager->priv->signature_list = signature_list;
+
+	g_object_notify (G_OBJECT (manager), "signature-list");
+}
+
+ESignatureTreeView *
+e_signature_manager_get_tree_view (ESignatureManager *manager)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), NULL);
+
+	return E_SIGNATURE_TREE_VIEW (manager->priv->tree_view);
+}
diff --git a/widgets/misc/e-signature-manager.h b/widgets/misc/e-signature-manager.h
new file mode 100644
index 0000000000..6c182badab
--- /dev/null
+++ b/widgets/misc/e-signature-manager.h
@@ -0,0 +1,100 @@
+/*
+ * e-signature-manager.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_MANAGER_H
+#define E_SIGNATURE_MANAGER_H
+
+#include 
+#include 
+#include 
+#include 
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_MANAGER \
+	(e_signature_manager_get_type ())
+#define E_SIGNATURE_MANAGER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManager))
+#define E_SIGNATURE_MANAGER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerClass))
+#define E_IS_SIGNATURE_MANAGER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SIGNATURE_MANAGER))
+#define E_IS_SIGNATURE_MANAGER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SIGNATURE_MANAGER))
+#define E_SIGNATURE_MANAGER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureManager ESignatureManager;
+typedef struct _ESignatureManagerClass ESignatureManagerClass;
+typedef struct _ESignatureManagerPrivate ESignatureManagerPrivate;
+
+struct _ESignatureManager {
+	GtkTable parent;
+	ESignatureManagerPrivate *priv;
+};
+
+struct _ESignatureManagerClass {
+	GtkTableClass parent_class;
+
+	void		(*add_signature)	(ESignatureManager *manager);
+	void		(*add_signature_script)	(ESignatureManager *manager);
+	void		(*editor_created)	(ESignatureManager *manager,
+						 ESignatureEditor *editor);
+	void		(*edit_signature)	(ESignatureManager *manager);
+	void		(*remove_signature)	(ESignatureManager *manager);
+};
+
+GType		e_signature_manager_get_type	(void);
+GtkWidget *	e_signature_manager_new		(ESignatureList *signature_list);
+void		e_signature_manager_add_signature
+						(ESignatureManager *manager);
+void		e_signature_manager_add_signature_script
+						(ESignatureManager *manager);
+void		e_signature_manager_edit_signature
+						(ESignatureManager *manager);
+void		e_signature_manager_remove_signature
+						(ESignatureManager *manager);
+gboolean	e_signature_manager_get_allow_scripts
+						(ESignatureManager *manager);
+void		e_signature_manager_set_allow_scripts
+						(ESignatureManager *manager,
+						 gboolean allow_scripts);
+gboolean	e_signature_manager_get_prefer_html
+						(ESignatureManager *manager);
+void		e_signature_manager_set_prefer_html
+						(ESignatureManager *manager,
+						 gboolean prefer_html);
+ESignatureList *e_signature_manager_get_signature_list
+						(ESignatureManager *manager);
+void		e_signature_manager_set_signature_list
+						(ESignatureManager *manager,
+						 ESignatureList *signature_list);
+ESignatureTreeView *
+		e_signature_manager_get_tree_view
+						(ESignatureManager *manager);
+
+#endif /* E_SIGNATURE_MANAGER_H */
diff --git a/widgets/misc/e-signature-script-dialog.c b/widgets/misc/e-signature-script-dialog.c
new file mode 100644
index 0000000000..06e021b046
--- /dev/null
+++ b/widgets/misc/e-signature-script-dialog.c
@@ -0,0 +1,463 @@
+/*
+ * e-signature-script-dialog.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-script-dialog.h"
+
+#include 
+#include "e-util/e-binding.h"
+
+#define E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogPrivate))
+
+struct _ESignatureScriptDialogPrivate {
+	GtkWidget *entry;
+	GtkWidget *file_chooser;
+	GtkWidget *alert;
+};
+
+enum {
+	PROP_0,
+	PROP_SCRIPT_FILE,
+	PROP_SCRIPT_NAME
+};
+
+static gpointer parent_class;
+
+static gboolean
+signature_script_dialog_filter_cb (const GtkFileFilterInfo *filter_info)
+{
+	const gchar *filename = filter_info->filename;
+
+	return g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
+}
+
+static void
+signature_script_dialog_update_status (ESignatureScriptDialog *dialog)
+{
+	GFile *script_file;
+	const gchar *script_name;
+	gboolean show_alert;
+	gboolean sensitive;
+
+	script_file = e_signature_script_dialog_get_script_file (dialog);
+	script_name = e_signature_script_dialog_get_script_name (dialog);
+
+	sensitive = (script_name != NULL && *script_name != '\0');
+
+	if (script_file != NULL) {
+		gboolean executable;
+		gchar *filename;
+
+		filename = g_file_get_path (script_file);
+		executable = g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
+		g_free (filename);
+
+		show_alert = !executable;
+		sensitive &= executable;
+
+		g_object_unref (script_file);
+	} else {
+		sensitive = FALSE;
+		show_alert = FALSE;
+	}
+
+	if (show_alert)
+		gtk_widget_show (dialog->priv->alert);
+	else
+		gtk_widget_hide (dialog->priv->alert);
+
+	gtk_dialog_set_response_sensitive (
+		GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+signature_script_dialog_set_property (GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SCRIPT_FILE:
+			e_signature_script_dialog_set_script_file (
+				E_SIGNATURE_SCRIPT_DIALOG (object),
+				g_value_get_object (value));
+			return;
+
+		case PROP_SCRIPT_NAME:
+			e_signature_script_dialog_set_script_name (
+				E_SIGNATURE_SCRIPT_DIALOG (object),
+				g_value_get_string (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_script_dialog_get_property (GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SCRIPT_FILE:
+			g_value_set_object (
+				value,
+				e_signature_script_dialog_get_script_file (
+				E_SIGNATURE_SCRIPT_DIALOG (object)));
+			return;
+
+		case PROP_SCRIPT_NAME:
+			g_value_set_string (
+				value,
+				e_signature_script_dialog_get_script_name (
+				E_SIGNATURE_SCRIPT_DIALOG (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_script_dialog_dispose (GObject *object)
+{
+	ESignatureScriptDialogPrivate *priv;
+
+	priv = E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
+
+	if (priv->entry != NULL) {
+		g_object_unref (priv->entry);
+		priv->entry = NULL;
+	}
+
+	if (priv->file_chooser != NULL) {
+		g_object_unref (priv->file_chooser);
+		priv->file_chooser = NULL;
+	}
+
+	if (priv->alert != NULL) {
+		g_object_unref (priv->alert);
+		priv->alert = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_script_dialog_map (GtkWidget *widget)
+{
+	GtkWidget *action_area;
+	GtkWidget *content_area;
+
+	/* Chain up to parent's map() method. */
+	GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+	/* XXX Override GtkDialog's broken style property defaults. */
+	action_area = gtk_dialog_get_action_area (GTK_DIALOG (widget));
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (widget));
+
+	gtk_box_set_spacing (GTK_BOX (content_area), 12);
+	gtk_container_set_border_width (GTK_CONTAINER (action_area), 0);
+	gtk_container_set_border_width (GTK_CONTAINER (content_area), 12);
+}
+
+static void
+signature_script_dialog_class_init (ESignatureScriptDialogClass *class)
+{
+	GObjectClass *object_class;
+	GtkWidgetClass *widget_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (ESignatureScriptDialogPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = signature_script_dialog_set_property;
+	object_class->get_property = signature_script_dialog_get_property;
+	object_class->dispose = signature_script_dialog_dispose;
+
+	widget_class = GTK_WIDGET_CLASS (class);
+	widget_class->map = signature_script_dialog_map;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SCRIPT_FILE,
+		g_param_spec_object (
+			"script-file",
+			"Script File",
+			NULL,
+			G_TYPE_FILE,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SCRIPT_NAME,
+		g_param_spec_string (
+			"script-name",
+			"Script Name",
+			NULL,
+			_("Unnamed"),
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+}
+
+static void
+signature_script_dialog_init (ESignatureScriptDialog *dialog)
+{
+	GtkFileFilter *filter;
+	GtkWidget *content_area;
+	GtkWidget *container;
+	GtkWidget *widget;
+	gchar *markup;
+
+	dialog->priv = E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog);
+
+	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+	gtk_dialog_add_button (
+		GTK_DIALOG (dialog),
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+	gtk_dialog_add_button (
+		GTK_DIALOG (dialog),
+		GTK_STOCK_SAVE, GTK_RESPONSE_OK);
+
+	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+	container = content_area;
+
+	widget = gtk_table_new (4, 2, FALSE);
+	gtk_table_set_col_spacings (GTK_TABLE (widget), 6);
+	gtk_table_set_row_spacings (GTK_TABLE (widget), 6);
+	gtk_table_set_row_spacing (GTK_TABLE (widget), 0, 12);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_image_new_from_stock (
+		GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		0, 1, 0, 1, 0, 0, 0, 0);
+	gtk_widget_show (widget);
+
+	widget = gtk_label_new (_(
+		"The output of this script will be used as your\n"
+		"signature. The name you specify will be used\n"
+		"for display purposes only."));
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+	gtk_widget_show (widget);
+
+	widget = gtk_entry_new ();
+	gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+	dialog->priv->entry = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	widget = gtk_label_new_with_mnemonic (_("_Name:"));
+	gtk_label_set_mnemonic_widget (
+		GTK_LABEL (widget), dialog->priv->entry);
+	gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		0, 1, 1, 2, GTK_FILL, 0, 0, 0);
+	gtk_widget_show (widget);
+
+	widget = gtk_file_chooser_button_new (
+		NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+	dialog->priv->file_chooser = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	/* Restrict file selection to executable files. */
+	filter = gtk_file_filter_new ();
+	gtk_file_filter_add_custom (
+		filter, GTK_FILE_FILTER_FILENAME,
+		(GtkFileFilterFunc) signature_script_dialog_filter_cb,
+		NULL, NULL);
+	gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter);
+
+	/* XXX ESignature stores a filename instead of a URI,
+	 *     so we have to restrict it to local files only. */
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+
+	widget = gtk_label_new_with_mnemonic (_("S_cript:"));
+	gtk_label_set_mnemonic_widget (
+		GTK_LABEL (widget), dialog->priv->file_chooser);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		0, 1, 2, 3, GTK_FILL, 0, 0, 0);
+	gtk_widget_show (widget);
+
+	/* This is just a placeholder. */
+	widget = gtk_label_new (NULL);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		0, 1, 3, 4, GTK_FILL, 0, 0, 0);
+	gtk_widget_show (widget);
+
+	widget = gtk_hbox_new (FALSE, 6);
+	gtk_table_attach (
+		GTK_TABLE (container), widget,
+		1, 2, 3, 4, 0, 0, 0, 0);
+	dialog->priv->alert = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_image_new_from_stock (
+		GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	gtk_widget_show (widget);
+
+	markup = g_markup_printf_escaped (
+		"%s",
+		_("Script file must be executable."));
+	widget = gtk_label_new (markup);
+	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	gtk_widget_show (widget);
+	g_free (markup);
+
+	g_signal_connect (
+		dialog, "notify::script-file",
+		G_CALLBACK (signature_script_dialog_update_status), NULL);
+
+	g_signal_connect (
+		dialog, "notify::script-name",
+		G_CALLBACK (signature_script_dialog_update_status), NULL);
+
+	g_signal_connect_swapped (
+		dialog->priv->entry, "changed",
+		G_CALLBACK (signature_script_dialog_update_status), dialog);
+
+	g_signal_connect_swapped (
+		dialog->priv->file_chooser, "file-set",
+		G_CALLBACK (signature_script_dialog_update_status), dialog);
+
+	signature_script_dialog_update_status (dialog);
+}
+
+GType
+e_signature_script_dialog_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (ESignatureScriptDialogClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) signature_script_dialog_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (ESignatureScriptDialog),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) signature_script_dialog_init,
+			NULL   /* value_table */
+		};
+
+		type = g_type_register_static (
+			GTK_TYPE_DIALOG, "ESignatureScriptDialog",
+			&type_info, 0);
+	}
+
+	return type;
+}
+
+GtkWidget *
+e_signature_script_dialog_new (GtkWindow *parent)
+{
+	return g_object_new (
+		E_TYPE_SIGNATURE_SCRIPT_DIALOG,
+		"transient-for", parent, NULL);
+}
+
+GFile *
+e_signature_script_dialog_get_script_file (ESignatureScriptDialog *dialog)
+{
+	GtkFileChooser *file_chooser;
+
+	g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
+
+	file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
+
+	return gtk_file_chooser_get_file (file_chooser);
+}
+
+void
+e_signature_script_dialog_set_script_file (ESignatureScriptDialog *dialog,
+                                           GFile *script_file)
+{
+	GtkFileChooser *file_chooser;
+	GError *error = NULL;
+
+	g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog));
+	g_return_if_fail (G_IS_FILE (script_file));
+
+	file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
+
+	if (gtk_file_chooser_set_file (file_chooser, script_file, &error))
+		g_object_notify (G_OBJECT (dialog), "script-file");
+	else {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+}
+
+const gchar *
+e_signature_script_dialog_get_script_name (ESignatureScriptDialog *dialog)
+{
+	GtkEntry *entry;
+
+	g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
+
+	entry = GTK_ENTRY (dialog->priv->entry);
+
+	return gtk_entry_get_text (entry);
+}
+
+void
+e_signature_script_dialog_set_script_name (ESignatureScriptDialog *dialog,
+                                           const gchar *script_name)
+{
+	GtkEntry *entry;
+
+	g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog));
+
+	if (script_name == NULL)
+		script_name = "";
+
+	entry = GTK_ENTRY (dialog->priv->entry);
+	gtk_entry_set_text (entry, script_name);
+
+	g_object_notify (G_OBJECT (dialog), "script-name");
+}
diff --git a/widgets/misc/e-signature-script-dialog.h b/widgets/misc/e-signature-script-dialog.h
new file mode 100644
index 0000000000..4cd7f05632
--- /dev/null
+++ b/widgets/misc/e-signature-script-dialog.h
@@ -0,0 +1,76 @@
+/*
+ * e-signature-script-dialog.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_SCRIPT_DIALOG_H
+#define E_SIGNATURE_SCRIPT_DIALOG_H
+
+#include 
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_SCRIPT_DIALOG \
+	(e_signature_script_dialog_get_type ())
+#define E_SIGNATURE_SCRIPT_DIALOG(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialog))
+#define E_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogClass))
+#define E_IS_SIGNATURE_SCRIPT_DIALOG(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG))
+#define E_IS_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SIGNATURE_SCRIPT_DIALOG))
+#define E_SIGNATURE_SCRIPT_DIALOG_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureScriptDialog ESignatureScriptDialog;
+typedef struct _ESignatureScriptDialogClass ESignatureScriptDialogClass;
+typedef struct _ESignatureScriptDialogPrivate ESignatureScriptDialogPrivate;
+
+struct _ESignatureScriptDialog {
+	GtkDialog parent;
+	ESignatureScriptDialogPrivate *priv;
+};
+
+struct _ESignatureScriptDialogClass {
+	GtkDialogClass parent_class;
+};
+
+GType		e_signature_script_dialog_get_type	(void);
+GtkWidget *	e_signature_script_dialog_new		(GtkWindow *parent);
+GFile *		e_signature_script_dialog_get_script_file
+					(ESignatureScriptDialog *dialog);
+void		e_signature_script_dialog_set_script_file
+					(ESignatureScriptDialog *dialog,
+					 GFile *script_file);
+const gchar *	e_signature_script_dialog_get_script_name
+					(ESignatureScriptDialog *dialog);
+void		e_signature_script_dialog_set_script_name
+					(ESignatureScriptDialog *dialog,
+					 const gchar *script_name);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_SCRIPT_DIALOG_H */
diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c
new file mode 100644
index 0000000000..ef1cc36b14
--- /dev/null
+++ b/widgets/misc/e-signature-tree-view.c
@@ -0,0 +1,405 @@
+/*
+ * e-signature-tree-view.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-tree-view.h"
+
+#define E_SIGNATURE_TREE_VIEW_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewPrivate))
+
+enum {
+	COLUMN_STRING,
+	COLUMN_SIGNATURE
+};
+
+enum {
+	PROP_0,
+	PROP_SIGNATURE_LIST
+};
+
+enum {
+	REFRESHED,
+	LAST_SIGNAL
+};
+
+struct _ESignatureTreeViewPrivate {
+	ESignatureList *signature_list;
+	GHashTable *index;
+};
+
+static gpointer parent_class;
+static guint signal_ids[LAST_SIGNAL];
+
+static void
+signature_tree_view_refresh_cb (ESignatureList *signature_list,
+                                ESignature *unused,
+                                ESignatureTreeView *tree_view)
+{
+	GtkListStore *store;
+	GtkTreeModel *model;
+	GtkTreeIter tree_iter;
+	EIterator *signature_iter;
+	ESignature *signature;
+	GHashTable *index;
+	GList *list = NULL;
+	GList *iter;
+
+	store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_SIGNATURE);
+	model = GTK_TREE_MODEL (store);
+	index = tree_view->priv->index;
+
+	g_hash_table_remove_all (index);
+
+	if (signature_list == NULL)
+		goto skip;
+
+	/* Build a list of ESignatures to display. */
+	signature_iter = e_list_get_iterator (E_LIST (signature_list));
+	while (e_iterator_is_valid (signature_iter)) {
+
+		/* XXX EIterator misuses const. */
+		signature = (ESignature *) e_iterator_get (signature_iter);
+		list = g_list_prepend (list, signature);
+		e_iterator_next (signature_iter);
+	}
+	g_object_unref (signature_iter);
+
+	list = g_list_reverse (list);
+
+	/* Populate the list store and index. */
+	for (iter = list; iter != NULL; iter = iter->next) {
+		GtkTreeRowReference *reference;
+		GtkTreePath *path;
+
+		signature = iter->data;
+
+		/* Skip autogenerated signatures. */
+		if (signature->autogen)
+			continue;
+
+		gtk_list_store_append (store, &tree_iter);
+		gtk_list_store_set (
+			store, &tree_iter,
+			COLUMN_STRING, signature->name,
+			COLUMN_SIGNATURE, signature, -1);
+
+		path = gtk_tree_model_get_path (model, &tree_iter);
+		reference = gtk_tree_row_reference_new (model, path);
+		g_hash_table_insert (index, signature, reference);
+		gtk_tree_path_free (path);
+	}
+
+skip:
+	/* Restore the previously selected signature. */
+	signature = e_signature_tree_view_get_selected (tree_view);
+	if (signature != NULL)
+		g_object_ref (signature);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
+	e_signature_tree_view_set_selected (tree_view, signature);
+	if (signature != NULL)
+		g_object_unref (signature);
+
+	g_signal_emit (tree_view, signal_ids[REFRESHED], 0);
+}
+
+static GObject *
+signature_tree_view_constructor (GType type,
+                                 guint n_construct_properties,
+                                 GObjectConstructParam *construct_properties)
+{
+	GObject *object;
+	GtkTreeView *tree_view;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+
+	/* Chain up to parent's constructor() method. */
+	object = G_OBJECT_CLASS (parent_class)->constructor (
+		type, n_construct_properties, construct_properties);
+
+	tree_view = GTK_TREE_VIEW (object);
+	gtk_tree_view_set_headers_visible (tree_view, FALSE);
+
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute (
+		column, renderer, "text", COLUMN_STRING);
+	gtk_tree_view_append_column (tree_view, column);
+
+	return object;
+}
+
+static void
+signature_tree_view_set_property (GObject *object,
+                                  guint property_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SIGNATURE_LIST:
+			e_signature_tree_view_set_signature_list (
+				E_SIGNATURE_TREE_VIEW (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_tree_view_get_property (GObject *object,
+                                  guint property_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SIGNATURE_LIST:
+			g_value_set_object (
+				value,
+				e_signature_tree_view_get_signature_list (
+				E_SIGNATURE_TREE_VIEW (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_tree_view_dispose (GObject *object)
+{
+	ESignatureTreeViewPrivate *priv;
+
+	priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (object);
+
+	if (priv->signature_list != NULL) {
+		g_signal_handlers_disconnect_by_func (
+			priv->signature_list,
+			signature_tree_view_refresh_cb, object);
+		g_object_unref (priv->signature_list);
+		priv->signature_list = NULL;
+	}
+
+	g_hash_table_remove_all (priv->index);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_tree_view_finalize (GObject *object)
+{
+	ESignatureTreeViewPrivate *priv;
+
+	priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (object);
+
+	g_hash_table_destroy (priv->index);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+signature_tree_view_class_init (ESignatureTreeViewClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (ESignatureTreeViewPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->constructor = signature_tree_view_constructor;
+	object_class->set_property = signature_tree_view_set_property;
+	object_class->get_property = signature_tree_view_get_property;
+	object_class->dispose = signature_tree_view_dispose;
+	object_class->finalize = signature_tree_view_finalize;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SIGNATURE_LIST,
+		g_param_spec_object (
+			"signature-list",
+			"Signature List",
+			NULL,
+			E_TYPE_SIGNATURE_LIST,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	signal_ids[REFRESHED] = g_signal_new (
+		"refreshed",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		0, NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+}
+
+static void
+signature_tree_view_init (ESignatureTreeView *tree_view)
+{
+	GHashTable *index;
+
+	/* Reverse-lookup index */
+	index = g_hash_table_new_full (
+		g_direct_hash, g_direct_equal,
+		(GDestroyNotify) g_object_unref,
+		(GDestroyNotify) gtk_tree_row_reference_free);
+
+	tree_view->priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
+	tree_view->priv->index = index;
+}
+
+GType
+e_signature_tree_view_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (ESignatureTreeViewClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) signature_tree_view_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (ESignatureTreeView),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) signature_tree_view_init,
+			NULL  /* value_table */
+		};
+
+		type = g_type_register_static (
+			GTK_TYPE_TREE_VIEW, "ESignatureTreeView",
+			&type_info, 0);
+	}
+
+	return type;
+}
+
+GtkWidget *
+e_signature_tree_view_new (void)
+{
+	return g_object_new (E_TYPE_SIGNATURE_TREE_VIEW, NULL);
+}
+
+ESignatureList *
+e_signature_tree_view_get_signature_list (ESignatureTreeView *tree_view)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), NULL);
+
+	return tree_view->priv->signature_list;
+}
+
+void
+e_signature_tree_view_set_signature_list (ESignatureTreeView *tree_view,
+                                          ESignatureList *signature_list)
+{
+	ESignatureTreeViewPrivate *priv;
+
+	g_return_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view));
+
+	if (signature_list != NULL)
+		g_return_if_fail (E_IS_SIGNATURE_LIST (signature_list));
+
+	priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
+
+	if (priv->signature_list != NULL) {
+		g_signal_handlers_disconnect_by_func (
+			priv->signature_list,
+			signature_tree_view_refresh_cb, tree_view);
+		g_object_unref (priv->signature_list);
+		priv->signature_list = NULL;
+	}
+
+	if (signature_list != NULL) {
+		priv->signature_list = g_object_ref (signature_list);
+
+		/* Listen for changes to the signature list. */
+		g_signal_connect (
+			priv->signature_list, "signature-added",
+			G_CALLBACK (signature_tree_view_refresh_cb),
+			tree_view);
+		g_signal_connect (
+			priv->signature_list, "signature-changed",
+			G_CALLBACK (signature_tree_view_refresh_cb),
+			tree_view);
+		g_signal_connect (
+			priv->signature_list, "signature-removed",
+			G_CALLBACK (signature_tree_view_refresh_cb),
+			tree_view);
+	}
+
+	signature_tree_view_refresh_cb (signature_list, NULL, tree_view);
+
+	g_object_notify (G_OBJECT (tree_view), "signature-list");
+}
+
+ESignature *
+e_signature_tree_view_get_selected (ESignatureTreeView *tree_view)
+{
+	ESignature *signature;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), NULL);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return NULL;
+
+	gtk_tree_model_get (model, &iter, COLUMN_SIGNATURE, &signature, -1);
+
+	return signature;
+}
+
+gboolean
+e_signature_tree_view_set_selected (ESignatureTreeView *tree_view,
+                                    ESignature *signature)
+{
+	GtkTreeRowReference *reference;
+	GtkTreeSelection *selection;
+	GtkTreePath *path;
+
+	g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), FALSE);
+
+	if (signature != NULL)
+		g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+	/* NULL means clear the selection. */
+	if (signature == NULL) {
+		gtk_tree_selection_unselect_all (selection);
+		return TRUE;
+	}
+
+	/* Lookup the tree row reference for the signature. */
+	reference = g_hash_table_lookup (tree_view->priv->index, signature);
+	if (reference == NULL)
+		return FALSE;
+
+	/* Select the referenced path. */
+	path = gtk_tree_row_reference_get_path (reference);
+	gtk_tree_selection_select_path (selection, path);
+	gtk_tree_path_free (path);
+
+	return TRUE;
+}
diff --git a/widgets/misc/e-signature-tree-view.h b/widgets/misc/e-signature-tree-view.h
new file mode 100644
index 0000000000..3afe569136
--- /dev/null
+++ b/widgets/misc/e-signature-tree-view.h
@@ -0,0 +1,78 @@
+/*
+ * e-signature-tree-view.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_TREE_VIEW_H
+#define E_SIGNATURE_TREE_VIEW_H
+
+#include 
+#include 
+#include 
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_TREE_VIEW \
+	(e_signature_tree_view_get_type ())
+#define E_SIGNATURE_TREE_VIEW(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeView))
+#define E_SIGNATURE_TREE_VIEW_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewClass))
+#define E_IS_SIGNATURE_TREE_VIEW(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SIGNATURE_TREE_VIEW))
+#define E_IS_SIGNATURE_TREE_VIEW_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SIGNATURE_TREE_VIEW))
+#define E_SIGNATURE_TREE_VIEW_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureTreeView ESignatureTreeView;
+typedef struct _ESignatureTreeViewClass ESignatureTreeViewClass;
+typedef struct _ESignatureTreeViewPrivate ESignatureTreeViewPrivate;
+
+struct _ESignatureTreeView {
+	GtkTreeView parent;
+	ESignatureTreeViewPrivate *priv;
+};
+
+struct _ESignatureTreeViewClass {
+	GtkTreeViewClass parent_class;
+};
+
+GType		e_signature_tree_view_get_type	(void);
+GtkWidget *	e_signature_tree_view_new	(void);
+ESignatureList *e_signature_tree_view_get_signature_list
+					(ESignatureTreeView *tree_view);
+void		e_signature_tree_view_set_signature_list
+					(ESignatureTreeView *tree_view,
+					 ESignatureList *signature_list);
+ESignature *	e_signature_tree_view_get_selected
+					(ESignatureTreeView *tree_view);
+gboolean	e_signature_tree_view_set_selected
+					(ESignatureTreeView *tree_view,
+					 ESignature *signature);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_TREE_VIEW_H */
-- 
cgit v1.2.3


From ccd8e3964f548798eb05a430b3ea81b2760069cc Mon Sep 17 00:00:00 2001
From: Matthew Barnes 
Date: Sat, 14 Feb 2009 00:30:08 +0000
Subject: Get mail search bar partially working without help from EFilterBar.
 Search scope (current folder, current account, etc.) is still ignored.

svn path=/branches/kill-bonobo/; revision=37263
---
 widgets/misc/e-search-bar.h | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'widgets/misc')

diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h
index dd51edd698..333cbabc82 100644
--- a/widgets/misc/e-search-bar.h
+++ b/widgets/misc/e-search-bar.h
@@ -54,14 +54,12 @@ typedef struct _ESearchBar ESearchBar;
 typedef struct _ESearchBarClass ESearchBarClass;
 typedef struct _ESearchBarPrivate ESearchBarPrivate;
 
-struct _ESearchBar
-{
+struct _ESearchBar {
 	GtkHBox parent;
 	ESearchBarPrivate *priv;
 };
 
-struct _ESearchBarClass
-{
+struct _ESearchBarClass {
 	GtkHBoxClass parent_class;
 };
 
-- 
cgit v1.2.3


From f7e298665b02f72890c6681e6d21ef5601beccbb Mon Sep 17 00:00:00 2001
From: Matthew Barnes 
Date: Sun, 15 Feb 2009 03:27:31 +0000
Subject: Merge revisions 37200:3266 from trunk.

svn path=/branches/kill-bonobo/; revision=37270
---
 widgets/misc/ChangeLog      | 8 ++++++++
 widgets/misc/e-filter-bar.c | 3 ++-
 widgets/misc/e-unicode.c    | 2 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

(limited to 'widgets/misc')

diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog
index 2c1046f0a6..d81e52d0a1 100644
--- a/widgets/misc/ChangeLog
+++ b/widgets/misc/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-12  Milan Crha  
+
+	** Part of fix for bug #404232
+
+	* e-filter-bar.c: (rule_advanced_response): Emit signal after
+	search bar text is set, thus the text will not be empty, which
+	is considered as "no search" these days.
+
 2009-01-30  Suman Manjunath  
 
 	** Fix for bug #342446
diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c
index c662460aba..21901b631a 100644
--- a/widgets/misc/e-filter-bar.c
+++ b/widgets/misc/e-filter-bar.c
@@ -73,7 +73,6 @@ rule_advanced_response (GtkWidget *dialog, int response, void *data)
 
 			filter_bar->current_query = rule;
 			g_object_ref (rule);
-			g_signal_emit_by_name (filter_bar, "search_activated");
 
 			gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
 			gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
@@ -82,6 +81,8 @@ rule_advanced_response (GtkWidget *dialog, int response, void *data)
 			e_search_bar_set_text (search_bar,_("Advanced Search"));
 			gtk_widget_set_sensitive (search_bar->clear_button, TRUE);
 
+			g_signal_emit_by_name (efb, "search_activated");
+
 			if (response == GTK_RESPONSE_APPLY) {
 				if (!rule_context_find_rule (filter_bar->context, rule->name, rule->source))
 					rule_context_add_rule (filter_bar->context, rule);
diff --git a/widgets/misc/e-unicode.c b/widgets/misc/e-unicode.c
index a98154dd20..9d660b6600 100644
--- a/widgets/misc/e-unicode.c
+++ b/widgets/misc/e-unicode.c
@@ -46,7 +46,7 @@
 #include 
 #include "e-unicode.h"
 
-#define d(x) x
+#define d(x)
 
 #define FONT_TESTING
 #define MAX_DECOMP 8
-- 
cgit v1.2.3


From 03d8740213e324efaf7b774b0c7497ced2fa626b Mon Sep 17 00:00:00 2001
From: Matthew Barnes 
Date: Mon, 16 Feb 2009 00:44:40 +0000
Subject: Move signature script execution to e-util/e-signature-utils.s so the
 composer can invoke it.  Composer no longer needs mail-config.h.

Split signature preview into a new widget: ESignaturePreview.


svn path=/branches/kill-bonobo/; revision=37272
---
 widgets/misc/Makefile.am             |   2 +
 widgets/misc/e-signature-preview.c   | 344 +++++++++++++++++++++++++++++++++++
 widgets/misc/e-signature-preview.h   |  81 +++++++++
 widgets/misc/e-signature-tree-view.c |  46 ++++-
 4 files changed, 470 insertions(+), 3 deletions(-)
 create mode 100644 widgets/misc/e-signature-preview.c
 create mode 100644 widgets/misc/e-signature-preview.h

(limited to 'widgets/misc')

diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index a1d555085b..589bd1083e 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -80,6 +80,7 @@ widgetsinclude_HEADERS =			\
 	e-signature-combo-box.h			\
 	e-signature-editor.h			\
 	e-signature-manager.h			\
+	e-signature-preview.h			\
 	e-signature-script-dialog.h		\
 	e-signature-tree-view.h			\
 	e-unicode.h				\
@@ -131,6 +132,7 @@ libemiscwidgets_la_SOURCES =			\
 	e-signature-combo-box.c			\
 	e-signature-editor.c			\
 	e-signature-manager.c			\
+	e-signature-preview.c			\
 	e-signature-script-dialog.c		\
 	e-signature-tree-view.c			\
 	e-unicode.c				\
diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c
new file mode 100644
index 0000000000..d618e05daa
--- /dev/null
+++ b/widgets/misc/e-signature-preview.c
@@ -0,0 +1,344 @@
+/*
+ * e-signature-preview.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   
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-preview.h"
+
+#include 
+#include 
+#include 
+#include 
+#include "e-util/e-signature-utils.h"
+
+#define E_SIGNATURE_PREVIEW_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewPrivate))
+
+enum {
+	PROP_0,
+	PROP_ALLOW_SCRIPTS,
+	PROP_SIGNATURE
+};
+
+enum {
+	REFRESH,
+	LAST_SIGNAL
+};
+
+struct _ESignaturePreviewPrivate {
+	ESignature *signature;
+	guint allow_scripts : 1;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_preview_set_property (GObject *object,
+                                guint property_id,
+                                const GValue *value,
+                                GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALLOW_SCRIPTS:
+			e_signature_preview_set_allow_scripts (
+				E_SIGNATURE_PREVIEW (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_SIGNATURE:
+			e_signature_preview_set_signature (
+				E_SIGNATURE_PREVIEW (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_get_property (GObject *object,
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALLOW_SCRIPTS:
+			g_value_set_boolean (
+				value, e_signature_preview_get_allow_scripts (
+				E_SIGNATURE_PREVIEW (object)));
+			return;
+
+		case PROP_SIGNATURE:
+			g_value_set_object (
+				value, e_signature_preview_get_signature (
+				E_SIGNATURE_PREVIEW (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_dispose (GObject *object)
+{
+	ESignaturePreviewPrivate *priv;
+
+	priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (object);
+
+	if (priv->signature != NULL) {
+		g_object_unref (priv->signature);
+		priv->signature = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_preview_url_requested (GtkHTML *html,
+                                 const gchar *url,
+                                 GtkHTMLStream *handle)
+{
+	GtkHTMLStreamStatus status;
+	gchar buffer[128];
+	gchar *filename;
+	gssize size;
+	gint fd;
+
+	/* FIXME Use GInputStream for this. */
+
+	if (g_str_has_prefix (url, "file:"))
+		filename = g_filename_from_uri (url, NULL, NULL);
+	else
+		filename = g_strdup (url);
+	fd = g_open (filename, O_RDONLY, 0);
+	g_free (filename);
+
+	status = GTK_HTML_STREAM_OK;
+	if (fd != -1) {
+		while ((size = read (fd, buffer, sizeof (buffer)))) {
+			if (size == -1) {
+				status = GTK_HTML_STREAM_ERROR;
+				break;
+			} else
+				gtk_html_write (html, handle, buffer, size);
+		}
+	} else
+		status = GTK_HTML_STREAM_ERROR;
+
+	gtk_html_end (html, handle, status);
+
+	if (fd > 0)
+		close (fd);
+}
+
+static void
+signature_preview_refresh (ESignaturePreview *preview)
+{
+	GtkHTML *html;
+	ESignature *signature;
+	gchar *content = NULL;
+	gsize length;
+
+	/* XXX We should show error messages in the preview. */
+
+	html = GTK_HTML (preview);
+	signature = e_signature_preview_get_signature (preview);
+
+	if (signature == NULL)
+		goto clear;
+
+	if (signature->script && !preview->priv->allow_scripts)
+		goto clear;
+
+	if (signature->script)
+		content = e_run_signature_script (signature->filename);
+	else
+		content = e_read_signature_file (signature, FALSE, NULL);
+
+	if (content == NULL || *content == '\0')
+		goto clear;
+
+	length = strlen (content);
+
+	if (signature->html)
+		gtk_html_load_from_string (html, content, length);
+	else {
+		GtkHTMLStream *stream;
+
+		stream = gtk_html_begin_content (
+			html, "text/html; charset=utf-8");
+		gtk_html_write (html, stream, "
", 5);
+		if (length > 0)
+			gtk_html_write (html, stream, content, length);
+		gtk_html_write (html, stream, "
", 6); + gtk_html_end (html, stream, GTK_HTML_STREAM_OK); + } + + g_free (content); + return; + +clear: + gtk_html_load_from_string (html, " ", 1); + g_free (content); +} + +static void +signature_preview_class_init (ESignaturePreviewClass *class) +{ + GObjectClass *object_class; + GtkHTMLClass *html_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESignaturePreviewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = signature_preview_set_property; + object_class->get_property = signature_preview_get_property; + object_class->dispose = signature_preview_dispose; + + html_class = GTK_HTML_CLASS (class); + html_class->url_requested = signature_preview_url_requested; + + class->refresh = signature_preview_refresh; + + g_object_class_install_property ( + object_class, + PROP_ALLOW_SCRIPTS, + g_param_spec_boolean ( + "allow-scripts", + "Allow Scripts", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SIGNATURE, + g_param_spec_object ( + "signature", + "Signature", + NULL, + E_TYPE_SIGNATURE, + G_PARAM_READWRITE)); + + signals[REFRESH] = g_signal_new ( + "refresh", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ESignaturePreviewClass, refresh), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +signature_preview_init (ESignaturePreview *preview) +{ + preview->priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (preview); +} + +GType +e_signature_preview_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESignaturePreviewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) signature_preview_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESignaturePreview), + 0, /* n_preallocs */ + (GInstanceInitFunc) signature_preview_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_HTML, "ESignaturePreview", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_signature_preview_new (void) +{ + return g_object_new (E_TYPE_SIGNATURE_PREVIEW, NULL); +} + +void +e_signature_preview_refresh (ESignaturePreview *preview) +{ + g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview)); + + g_signal_emit (preview, signals[REFRESH], 0); +} + +gboolean +e_signature_preview_get_allow_scripts (ESignaturePreview *preview) +{ + g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), FALSE); + + return preview->priv->allow_scripts; +} + +void +e_signature_preview_set_allow_scripts (ESignaturePreview *preview, + gboolean allow_scripts) +{ + g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview)); + + preview->priv->allow_scripts = allow_scripts; + g_object_notify (G_OBJECT (preview), "allow-scripts"); +} + +ESignature * +e_signature_preview_get_signature (ESignaturePreview *preview) +{ + g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), NULL); + + return preview->priv->signature; +} + +void +e_signature_preview_set_signature (ESignaturePreview *preview, + ESignature *signature) +{ + g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview)); + + if (signature != NULL) { + g_return_if_fail (E_IS_SIGNATURE (signature)); + g_object_ref (signature); + } + + if (preview->priv->signature != NULL) + g_object_unref (preview->priv->signature); + + preview->priv->signature = signature; + g_object_notify (G_OBJECT (preview), "signature"); + + e_signature_preview_refresh (preview); +} diff --git a/widgets/misc/e-signature-preview.h b/widgets/misc/e-signature-preview.h new file mode 100644 index 0000000000..2cedcc1d2f --- /dev/null +++ b/widgets/misc/e-signature-preview.h @@ -0,0 +1,81 @@ +/* + * e-signature-preview.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_SIGNATURE_PREVIEW_H +#define E_SIGNATURE_PREVIEW_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_SIGNATURE_PREVIEW \ + (e_signature_preview_get_type ()) +#define E_SIGNATURE_PREVIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview)) +#define E_SIGNATURE_PREVIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewClass)) +#define E_IS_SIGNATURE_PREVIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SIGNATURE_PREVIEW)) +#define E_IS_SIGNATURE_PREVIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SIGNATURE_PREVIEW)) +#define E_SIGNATURE_PREVIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview)) + +G_BEGIN_DECLS + +typedef struct _ESignaturePreview ESignaturePreview; +typedef struct _ESignaturePreviewClass ESignaturePreviewClass; +typedef struct _ESignaturePreviewPrivate ESignaturePreviewPrivate; + +struct _ESignaturePreview { + GtkHTML parent; + ESignaturePreviewPrivate *priv; +}; + +struct _ESignaturePreviewClass { + GtkHTMLClass parent_class; + + /* Signals */ + void (*refresh) (ESignaturePreview *preview); +}; + +GType e_signature_preview_get_type (void); +GtkWidget * e_signature_preview_new (void); +void e_signature_preview_refresh (ESignaturePreview *preview); +gboolean e_signature_preview_get_allow_scripts + (ESignaturePreview *preview); +void e_signature_preview_set_allow_scripts + (ESignaturePreview *preview, + gboolean allow_scripts); +ESignature * e_signature_preview_get_signature + (ESignaturePreview *preview); +void e_signature_preview_set_signature + (ESignaturePreview *preview, + ESignature *signature); + +G_END_DECLS + +#endif /* E_SIGNATURE_PREVIEW_H */ diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c index ef1cc36b14..1f6d75b5b5 100644 --- a/widgets/misc/e-signature-tree-view.c +++ b/widgets/misc/e-signature-tree-view.c @@ -32,6 +32,7 @@ enum { enum { PROP_0, + PROP_SELECTED, PROP_SIGNATURE_LIST }; @@ -46,7 +47,7 @@ struct _ESignatureTreeViewPrivate { }; static gpointer parent_class; -static guint signal_ids[LAST_SIGNAL]; +static guint signals[LAST_SIGNAL]; static void signature_tree_view_refresh_cb (ESignatureList *signature_list, @@ -117,7 +118,13 @@ skip: if (signature != NULL) g_object_unref (signature); - g_signal_emit (tree_view, signal_ids[REFRESHED], 0); + g_signal_emit (tree_view, signals[REFRESHED], 0); +} + +static void +signature_tree_view_selection_changed_cb (ESignatureTreeView *tree_view) +{ + g_object_notify (G_OBJECT (tree_view), "selected"); } static GObject * @@ -154,6 +161,12 @@ signature_tree_view_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_SELECTED: + e_signature_tree_view_set_selected ( + E_SIGNATURE_TREE_VIEW (object), + g_value_get_object (value)); + return; + case PROP_SIGNATURE_LIST: e_signature_tree_view_set_signature_list ( E_SIGNATURE_TREE_VIEW (object), @@ -171,6 +184,13 @@ signature_tree_view_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_SELECTED: + g_value_set_object ( + value, + e_signature_tree_view_get_selected ( + E_SIGNATURE_TREE_VIEW (object))); + return; + case PROP_SIGNATURE_LIST: g_value_set_object ( value, @@ -231,6 +251,16 @@ signature_tree_view_class_init (ESignatureTreeViewClass *class) object_class->dispose = signature_tree_view_dispose; object_class->finalize = signature_tree_view_finalize; + g_object_class_install_property ( + object_class, + PROP_SELECTED, + g_param_spec_object ( + "selected", + "Selected Signature", + NULL, + E_TYPE_SIGNATURE, + G_PARAM_READWRITE)); + g_object_class_install_property ( object_class, PROP_SIGNATURE_LIST, @@ -242,7 +272,7 @@ signature_tree_view_class_init (ESignatureTreeViewClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - signal_ids[REFRESHED] = g_signal_new ( + signals[REFRESHED] = g_signal_new ( "refreshed", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, @@ -255,6 +285,7 @@ static void signature_tree_view_init (ESignatureTreeView *tree_view) { GHashTable *index; + GtkTreeSelection *selection; /* Reverse-lookup index */ index = g_hash_table_new_full ( @@ -264,6 +295,13 @@ signature_tree_view_init (ESignatureTreeView *tree_view) tree_view->priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view); tree_view->priv->index = index; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + + g_signal_connect_swapped ( + selection, "changed", + G_CALLBACK (signature_tree_view_selection_changed_cb), + tree_view); } GType @@ -401,5 +439,7 @@ e_signature_tree_view_set_selected (ESignatureTreeView *tree_view, gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); + g_object_notify (G_OBJECT (tree_view), "selected"); + return TRUE; } -- cgit v1.2.3 From 7ed5f59771262651ee8b0d29a123e43a6ac0b6c6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 17 Feb 2009 15:59:18 +0000 Subject: Miscellaneous bug fixes. Kill e-util/e-corba-utils.[ch]. svn path=/branches/kill-bonobo/; revision=37283 --- widgets/misc/e-icon-entry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index 86e42488a7..cfcce8f8c5 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -75,7 +75,7 @@ icon_entry_create_proxy (GtkAction *action) proxy = gtk_event_box_new (); gtk_event_box_set_visible_window (GTK_EVENT_BOX (proxy), FALSE); gtk_container_set_border_width (GTK_CONTAINER (proxy), 2); - gtk_action_connect_proxy (action, proxy); + gtk_widget_show (proxy); widget = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU); gtk_container_add (GTK_CONTAINER (proxy), widget); -- cgit v1.2.3 From c3bfa60a7b27cb0cc44e134dcb9951ab9d41e6f6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 21 Feb 2009 15:02:32 +0000 Subject: Kill EDropdownButton. Migrate off of gnome_program_init(). svn path=/branches/kill-bonobo/; revision=37303 --- widgets/misc/Makefile.am | 14 -- widgets/misc/e-dropdown-button.c | 233 --------------------------------- widgets/misc/e-dropdown-button.h | 70 ---------- widgets/misc/test-calendar.c | 26 ++-- widgets/misc/test-dateedit.c | 30 ++--- widgets/misc/test-dropdown-button.c | 99 -------------- widgets/misc/test-preferences-window.c | 21 ++- 7 files changed, 35 insertions(+), 458 deletions(-) delete mode 100644 widgets/misc/e-dropdown-button.c delete mode 100644 widgets/misc/e-dropdown-button.h delete mode 100644 widgets/misc/test-dropdown-button.c (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 589bd1083e..c422ae9972 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -51,7 +51,6 @@ widgetsinclude_HEADERS = \ e-charset-picker.h \ e-combo-cell-editable.h \ e-dateedit.h \ - e-dropdown-button.h \ e-expander.h \ e-icon-entry.h \ e-image-chooser.h \ @@ -103,7 +102,6 @@ libemiscwidgets_la_SOURCES = \ e-charset-picker.c \ e-combo-cell-editable.c \ e-dateedit.c \ - e-dropdown-button.c \ e-expander.c \ e-icon-entry.c \ e-image-chooser.c \ @@ -167,7 +165,6 @@ libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ noinst_PROGRAMS = \ test-calendar \ test-dateedit \ - test-dropdown-button \ test-preferences-window # test-calendar @@ -192,17 +189,6 @@ test_dateedit_LDADD = \ $(top_builddir)/filter/libfilter.la \ $(E_WIDGETS_LIBS) -# test-dropdown-button - -test_dropdown_button_SOURCES = \ - test-dropdown-button.c - -test_dropdown_button_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(E_WIDGETS_LIBS) - # test-preferences-window test_preferences_window_SOURCES = \ diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c deleted file mode 100644 index aa5f84f6c8..0000000000 --- a/widgets/misc/e-dropdown-button.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-dropdown-button.h" - -#include - -struct _EDropdownButtonPrivate { - GtkAccelGroup *accel_group; - GtkWidget *menu; -}; - -G_DEFINE_TYPE (EDropdownButton, e_dropdown_button, GTK_TYPE_TOGGLE_BUTTON) - -/* Callback to position the pop-up menu. */ - -static void -menu_position_cb (GtkMenu *menu, - int *x, - int *y, - gboolean *push_in, - void *data) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - GtkRequisition menu_requisition; - int max_x, max_y; - - dropdown_button = E_DROPDOWN_BUTTON (data); - priv = dropdown_button->priv; - - /* Calculate our preferred position. */ - gdk_window_get_origin (GTK_WIDGET (dropdown_button)->window, x, y); - *y += GTK_WIDGET (dropdown_button)->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (GTK_WIDGET (priv->menu), &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - -/* Callback for the "deactivate" signal on the pop-up menu. This is used so - that we unset the state of the toggle button when the pop-up menu - disappears. */ - -static int -menu_deactivate_cb (GtkMenuShell *menu_shell, - void *data) -{ - EDropdownButton *dropdown_button; - - dropdown_button = E_DROPDOWN_BUTTON (data); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dropdown_button), FALSE); - return TRUE; -} - - -/* GtkObject methods. */ - -static void -impl_destroy (GtkObject *object) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - - dropdown_button = E_DROPDOWN_BUTTON (object); - priv = dropdown_button->priv; - - g_object_unref (priv->accel_group); - gtk_widget_destroy (priv->menu); - - g_free (priv); - - if (GTK_OBJECT_CLASS (e_dropdown_button_parent_class)->destroy) - (* GTK_OBJECT_CLASS (e_dropdown_button_parent_class)->destroy) (object); -} - - -/* GtkWidget methods. */ - -static void -impl_toggled (GtkToggleButton *toggle_button) -{ - EDropdownButton *dropdown_button; - EDropdownButtonPrivate *priv; - - if (GTK_TOGGLE_BUTTON_CLASS (e_dropdown_button_parent_class)->toggled) - GTK_TOGGLE_BUTTON_CLASS (e_dropdown_button_parent_class)->toggled (toggle_button); - - dropdown_button = E_DROPDOWN_BUTTON (toggle_button); - priv = dropdown_button->priv; - - if (toggle_button->active) { - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_cb, dropdown_button, - 1, GDK_CURRENT_TIME); - } else { - gtk_menu_popdown (GTK_MENU (priv->menu)); - } -} - - -static void -e_dropdown_button_class_init (EDropdownButtonClass *klass) -{ - GtkObjectClass *object_class; - GtkToggleButtonClass *toggle_class; - - object_class = GTK_OBJECT_CLASS (klass); - toggle_class = GTK_TOGGLE_BUTTON_CLASS (klass); - - object_class->destroy = impl_destroy; - toggle_class->toggled = impl_toggled; -} - - -static void -e_dropdown_button_init (EDropdownButton *dropdown_button) -{ - EDropdownButtonPrivate *priv; - - priv = g_new (EDropdownButtonPrivate, 1); - priv->accel_group = gtk_accel_group_new (); - priv->menu = NULL; - - dropdown_button->priv = priv; -} - - -/** - * e_dropdown_button_construct: - * @dropdown_button: A pointer to an %EDropdownButton object - * @label_text: Text to display in the button - * @menu: The menu to pop up when the button is pressed - * - * Construct the @dropdown_button with the specified @label_text and the - * associated @menu. - **/ -void -e_dropdown_button_construct (EDropdownButton *dropdown_button, - const char *label_text, - GtkMenu *menu) -{ - EDropdownButtonPrivate *priv; - GtkWidget *hbox; - GtkWidget *arrow; - GtkWidget *label; - unsigned int accel_key; - - g_return_if_fail (dropdown_button != NULL); - g_return_if_fail (E_IS_DROPDOWN_BUTTON (dropdown_button)); - g_return_if_fail (label_text != NULL); - g_return_if_fail (menu != NULL); - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = dropdown_button->priv; - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (dropdown_button), hbox); - gtk_widget_show (hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), label_text); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (GTK_WIDGET (dropdown_button), "clicked", - priv->accel_group, accel_key, GDK_MOD1_MASK, 0); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - priv->menu = GTK_WIDGET (menu); - - g_signal_connect_object (priv->menu, "deactivate", - G_CALLBACK (menu_deactivate_cb), - dropdown_button, 0); -} - -/** - * e_dropdown_button_new: - * @label_text: Text to display in the button - * @menu: The menu to pop up when the button is pressed - * - * Create a new dropdown button. When the button is clicked, the specified - * @menu will be popped up. - * - * Return value: A pointer to the newly created %EDropdownButton. - **/ -GtkWidget * -e_dropdown_button_new (const char *label_text, - GtkMenu *menu) -{ - GtkWidget *widget; - - g_return_val_if_fail (label_text != NULL, NULL); - g_return_val_if_fail (menu != NULL, NULL); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - widget = g_object_new (e_dropdown_button_get_type (), NULL); - - e_dropdown_button_construct (E_DROPDOWN_BUTTON (widget), label_text, menu); - return widget; -} - diff --git a/widgets/misc/e-dropdown-button.h b/widgets/misc/e-dropdown-button.h deleted file mode 100644 index b10fd9a670..0000000000 --- a/widgets/misc/e-dropdown-button.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_DROPDOWN_BUTTON_H_ -#define _E_DROPDOWN_BUTTON_H_ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_DROPDOWN_BUTTON (e_dropdown_button_get_type ()) -#define E_DROPDOWN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_DROPDOWN_BUTTON, EDropdownButton)) -#define E_DROPDOWN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_DROPDOWN_BUTTON, EDropdownButtonClass)) -#define E_IS_DROPDOWN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON)) -#define E_IS_DROPDOWN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON)) - - -typedef struct _EDropdownButton EDropdownButton; -typedef struct _EDropdownButtonPrivate EDropdownButtonPrivate; -typedef struct _EDropdownButtonClass EDropdownButtonClass; - -struct _EDropdownButton { - GtkToggleButton parent; - - EDropdownButtonPrivate *priv; -}; - -struct _EDropdownButtonClass { - GtkToggleButtonClass parent_class; -}; - - -GType e_dropdown_button_get_type (void); -void e_dropdown_button_construct (EDropdownButton *dropdown_button, - const char *label_text, - GtkMenu *menu); -GtkWidget *e_dropdown_button_new (const char *label_text, - GtkMenu *menu); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DROPDOWN_BUTTON_H_ */ diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c index 1906c70ede..f4fe6d3039 100644 --- a/widgets/misc/test-calendar.c +++ b/widgets/misc/test-calendar.c @@ -30,9 +30,6 @@ #include -#include -#include - #include "e-calendar.h" /* Drag and Drop stuff. */ @@ -61,21 +58,20 @@ delete_event_cb (GtkWidget *widget, int main (int argc, char **argv) { - GtkWidget *app; + GtkWidget *window; GtkWidget *cal; GtkWidget *vbox; ECalendarItem *calitem; - gnome_program_init ( - "test-calendar", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); + gtk_init (&argc, &argv); - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); - gtk_window_set_resizable (GTK_WINDOW (app), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (app), 8); + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "ECalendar Test"); + gtk_window_set_default_size (GTK_WINDOW (window), 400, 400); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (window), 8); - g_signal_connect (app, "delete_event", + g_signal_connect (window, "delete_event", G_CALLBACK (delete_event_cb), NULL); cal = e_calendar_new (); @@ -99,8 +95,8 @@ main (int argc, char **argv) gtk_box_pack_start (GTK_BOX (vbox), cal, TRUE, TRUE, 0); gtk_widget_show (vbox); - gnome_app_set_contents (GNOME_APP (app), vbox); - gtk_widget_show (app); + gtk_container_add (GTK_CONTAINER (window), vbox); + gtk_widget_show (window); gtk_main (); @@ -122,7 +118,7 @@ on_date_range_changed (ECalendarItem *calitem) start_day, start_month + 1, start_year, end_day, end_month + 1, end_year); - /* These days should appear bold. Remember month is 0 to 11. */ + /* These days should windowear bold. Remember month is 0 to 11. */ e_calendar_item_mark_day (calitem, 2000, 7, 26, /* 26th Aug 2000. */ E_CALENDAR_ITEM_MARK_BOLD); e_calendar_item_mark_day (calitem, 2000, 8, 13, /* 13th Sep 2000. */ diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c index da6a5953b1..8c340ed45b 100644 --- a/widgets/misc/test-dateedit.c +++ b/widgets/misc/test-dateedit.c @@ -29,13 +29,11 @@ #endif #include -#include -#include #include "e-dateedit.h" static void delete_event_cb (GtkWidget *widget, GdkEventAny *event, - GtkWidget *app); + GtkWidget *window); static void on_get_date_clicked (GtkWidget *button, EDateEdit *dedit); static void on_toggle_24_hour_clicked (GtkWidget *button, @@ -52,27 +50,29 @@ static void on_time_changed (EDateEdit *dedit, int main (int argc, char **argv) { - GtkWidget *app; + GtkWidget *window; EDateEdit *dedit; GtkWidget *table, *button; - gnome_program_init ("test-dateedit", "0.0", LIBGNOMEUI_MODULE, argc, argv, NULL); + gtk_init (&argc, &argv); puts ("here"); - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 300, 200); - gtk_window_set_resizable (GTK_WINDOW (app), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (app), 8); + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "EDateEdit Test"); + gtk_window_set_default_size (GTK_WINDOW (window), 300, 200); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (window), 8); - g_signal_connect (app, "delete_event", - G_CALLBACK (delete_event_cb), app); + g_signal_connect (window, "delete_event", + G_CALLBACK (delete_event_cb), window); table = gtk_table_new (3, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4); gtk_widget_show (table); - gnome_app_set_contents (GNOME_APP (app), table); + + gtk_container_add (GTK_CONTAINER (window), table); /* EDateEdit 1. */ dedit = E_DATE_EDIT (e_date_edit_new ()); @@ -160,7 +160,7 @@ main (int argc, char **argv) g_signal_connect (button, "clicked", G_CALLBACK (on_toggle_24_hour_clicked), dedit); - gtk_widget_show (app); + gtk_widget_show (window); gtk_main (); @@ -171,9 +171,9 @@ main (int argc, char **argv) static void delete_event_cb (GtkWidget *widget, GdkEventAny *event, - GtkWidget *app) + GtkWidget *window) { - gtk_widget_destroy (app); + gtk_widget_destroy (window); gtk_main_quit (); } diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c deleted file mode 100644 index f0a7ca4d0e..0000000000 --- a/widgets/misc/test-dropdown-button.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include -#include - -#include "e-dropdown-button.h" - - -/* (The following is shameless stolen from `testgnome.c'. */ - -static void -item_activated (GtkWidget *widget, - void *data) -{ - printf ("%s activated.\n", (char *) data); -} - -static GnomeUIInfo ui_info[] = { - { GNOME_APP_UI_ITEM, "_New", "Create a new file", item_activated, "file/new", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_NEW, 'n', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "_Open...", "Open an existing file", item_activated, "file/open", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_OPEN, 'o', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "_Save", "Save the current file", item_activated, "file/save", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_SAVE, 's', GDK_CONTROL_MASK, NULL }, - { GNOME_APP_UI_ITEM, "Save _as...", "Save the current file with a new name", item_activated, "file/save as", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_SAVE_AS, 0, 0, NULL }, - - GNOMEUIINFO_SEPARATOR, - - { GNOME_APP_UI_ITEM, "_Print...", "Print the current file", item_activated, "file/print", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_PRINT, 'p', GDK_CONTROL_MASK, NULL }, - - GNOMEUIINFO_SEPARATOR, - - { GNOME_APP_UI_ITEM, "_Close", "Close the current file", item_activated, "file/close", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_CLOSE, 0, 0, NULL }, - { GNOME_APP_UI_ITEM, "E_xit", "Exit the program", item_activated, "file/exit", NULL, - GNOME_APP_PIXMAP_STOCK, GTK_STOCK_QUIT, 'q', GDK_CONTROL_MASK, NULL }, - GNOMEUIINFO_END -}; - - -int -main (int argc, char **argv) -{ - GtkWidget *window; - GtkWidget *menu; - GtkWidget *dropdown_button; - - gnome_program_init ( - "test-dropdown-button", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 1, 1); - - menu = gtk_menu_new (); - - gnome_app_fill_menu (GTK_MENU_SHELL (menu), ui_info, NULL, TRUE, 0); - - dropdown_button = e_dropdown_button_new ("Me_nu", GTK_MENU (menu)); - gtk_container_add (GTK_CONTAINER (window), dropdown_button); - - gtk_widget_show (window); - gtk_widget_show (dropdown_button); - - gtk_main (); - - return 0; -} diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c index 8bd8aa8950..bc53f98c58 100644 --- a/widgets/misc/test-preferences-window.c +++ b/widgets/misc/test-preferences-window.c @@ -22,8 +22,6 @@ #include "e-preferences-window.c" #include -#include -#include #define NUM_PAGES 10 @@ -65,21 +63,20 @@ delete_event_callback (GtkWidget *widget, int main (int argc, char **argv) { - GtkWidget *dialog; + GtkWidget *window; - gnome_program_init ( - "test-preferences-window", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); + gtk_init (&argc, &argv); - dialog = e_preferences_window_new (); + window = e_preferences_window_new (); + gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); - gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300); - g_signal_connect((dialog), "delete_event", - G_CALLBACK (delete_event_callback), NULL); + g_signal_connect( + window, "delete-event", + G_CALLBACK (delete_event_callback), NULL); - add_pages (E_PREFERENCES_WINDOW (dialog)); + add_pages (E_PREFERENCES_WINDOW (window)); - gtk_widget_show (dialog); + gtk_widget_show (window); gtk_main (); -- cgit v1.2.3 From dd757fd3959245876364deeb2ed36f948ab31545 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 21 Feb 2009 15:12:51 +0000 Subject: Fix compilation error. svn path=/branches/kill-bonobo/; revision=37304 --- widgets/misc/e-filter-bar.c | 1 - 1 file changed, 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 21901b631a..dc69b6c269 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -30,7 +30,6 @@ #include #include -#include "e-dropdown-button.h" #include "e-filter-bar.h" #include "filter/rule-editor.h" -- cgit v1.2.3 From f963cc39a7d21f64f578dae50fd08c44181a3bf6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 9 Mar 2009 03:31:24 +0000 Subject: Cleaning up the attachment bar, centralizing its popup menu, and converting everything to GtkUIManager/GtkActions. Saving progress mid-stream... not sure about the MIME part utilities yet. Also, add some EActivity subclasses. Considering an EFileActivity subclass for asynchronous GIO operations (loading/saving attachments, etc.), but still ironing out details. svn path=/branches/kill-bonobo/; revision=37389 --- widgets/misc/Makefile.am | 90 +- widgets/misc/e-activity.c | 249 ++--- widgets/misc/e-activity.h | 17 +- widgets/misc/e-alert-activity.c | 254 +++++ widgets/misc/e-alert-activity.h | 70 ++ widgets/misc/e-attachment-bar.c | 2114 +++++++++++++++++++++++++----------- widgets/misc/e-attachment-bar.h | 135 ++- widgets/misc/e-attachment-dialog.c | 413 +++++++ widgets/misc/e-attachment-dialog.h | 73 ++ widgets/misc/e-attachment.c | 743 ++++++++----- widgets/misc/e-attachment.h | 116 +- widgets/misc/e-mime-part-utils.c | 223 ++++ widgets/misc/e-mime-part-utils.h | 46 + widgets/misc/e-timeout-activity.c | 180 +++ widgets/misc/e-timeout-activity.h | 71 ++ 15 files changed, 3515 insertions(+), 1279 deletions(-) create mode 100644 widgets/misc/e-alert-activity.c create mode 100644 widgets/misc/e-alert-activity.h create mode 100644 widgets/misc/e-attachment-dialog.c create mode 100644 widgets/misc/e-attachment-dialog.h create mode 100644 widgets/misc/e-mime-part-utils.c create mode 100644 widgets/misc/e-mime-part-utils.h create mode 100644 widgets/misc/e-timeout-activity.c create mode 100644 widgets/misc/e-timeout-activity.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index c422ae9972..ffbe7fa5fb 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -17,7 +17,6 @@ INCLUDES = \ privsolib_LTLIBRARIES = \ libemiscwidgets.la -# libefilterbar.la widgetsincludedir = $(privincludedir)/misc @@ -39,51 +38,55 @@ widgetsinclude_HEADERS = \ e-action-combo-box.h \ e-activity.h \ e-activity-proxy.h \ - e-attachment-bar.h \ + e-alert-activity.h \ e-attachment.h \ - e-spinner.c \ - e-spinner.h \ + e-attachment-bar.h \ + e-attachment-dialog.h \ e-calendar.h \ e-calendar-item.h \ + e-canvas.h \ + e-canvas-background.h \ + e-canvas-utils.h \ + e-canvas-vbox.h \ e-cell-date-edit.h \ e-cell-percent.h \ e-cell-renderer-combo.h \ e-charset-picker.h \ + e-colors.h \ e-combo-cell-editable.h \ + e-cursors.h \ e-dateedit.h \ e-expander.h \ + e-gui-utils.h \ + e-hsv-utils.h \ e-icon-entry.h \ e-image-chooser.h \ e-map.h \ e-menu-tool-button.h \ - e-popup-action.h \ - e-preferences-window.h \ + e-mime-part-utils.h \ e-online-button.h \ - e-search-bar.h \ - e-send-options.h \ - e-url-entry.h \ - e-canvas-background.h \ - e-canvas-utils.h \ - e-canvas-vbox.h \ - e-canvas.h \ - e-cursors.h \ - e-gui-utils.h \ - e-hsv-utils.h \ + e-popup-action.h \ e-popup-menu.h \ + e-preferences-window.h \ e-printable.h \ - e-reflow-model.h \ e-reflow.h \ + e-reflow-model.h \ + e-search-bar.h \ + e-selection-model.h \ e-selection-model-array.h \ e-selection-model-simple.h \ - e-selection-model.h \ + e-send-options.h \ e-signature-combo-box.h \ e-signature-editor.h \ e-signature-manager.h \ e-signature-preview.h \ e-signature-script-dialog.h \ e-signature-tree-view.h \ + e-spinner.c \ + e-spinner.h \ + e-timeout-activity.h \ e-unicode.h \ - e-colors.h + e-url-entry.h libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ @@ -92,54 +95,57 @@ libemiscwidgets_la_SOURCES = \ e-action-combo-box.c \ e-activity.c \ e-activity-proxy.c \ - e-calendar.c \ + e-alert-activity.c \ e-attachment.c \ e-attachment-bar.c \ + e-attachment-dialog.c \ + e-calendar.c \ e-calendar-item.c \ + e-canvas.c \ + e-canvas-background.c \ + e-canvas-utils.c \ + e-canvas-vbox.c \ e-cell-date-edit.c \ e-cell-percent.c \ e-cell-renderer-combo.c \ e-charset-picker.c \ + e-colors.c \ e-combo-cell-editable.c \ + e-cursors.c \ e-dateedit.c \ e-expander.c \ + e-gui-utils.c \ + e-hsv-utils.c \ e-icon-entry.c \ e-image-chooser.c \ e-map.c \ e-menu-tool-button.c \ - e-popup-action.c \ - e-preferences-window.c \ + e-mime-part-utils.c \ e-online-button.c \ - e-search-bar.c \ - e-send-options.c \ - e-url-entry.c \ - e-canvas-background.c \ - e-canvas-utils.c \ - e-canvas-vbox.c \ - e-canvas.c \ - e-cursors.c \ - e-gui-utils.c \ - e-hsv-utils.c \ + e-popup-action.c \ e-popup-menu.c \ + e-preferences-window.c \ e-printable.c \ e-reflow-model.c \ e-reflow.c \ + e-search-bar.c \ + e-selection-model.c \ e-selection-model-array.c \ e-selection-model-simple.c \ - e-selection-model.c \ + e-send-options.c \ e-signature-combo-box.c \ e-signature-editor.c \ e-signature-manager.c \ e-signature-preview.c \ e-signature-script-dialog.c \ e-signature-tree-view.c \ + e-timeout-activity.c \ e-unicode.c \ - e-colors.c - + e-url-entry.c libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) -libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ +libemiscwidgets_la_LIBADD = \ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/filter/libfilter.la \ $(top_builddir)/widgets/table/libetable.la \ @@ -148,20 +154,8 @@ libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/a11y/libevolution-a11y.la \ $(EVOLUTION_MAIL_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(EVOLUTON_MAIL_LIBS) \ $(ICONV_LIBS) -#libefilterbar_la_SOURCES = \ -# e-filter-bar.c \ -# e-filter-bar.h -# -#libefilterbar_la_LDFLAGS = $(NO_UNDEFINED) -# -#libefilterbar_la_LIBADD = \ -# $(WIN32_BOOTSTRAP_LIBS) \ -# libemiscwidgets.la \ -# $(E_WIDGETS_LIBS) - noinst_PROGRAMS = \ test-calendar \ test-dateedit \ diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 34e902f5a6..40ee0df35a 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -32,7 +32,6 @@ struct _EActivityPrivate { gchar *primary_text; gchar *secondary_text; gdouble percent; - guint timeout_id; guint blocking : 1; guint cancellable : 1; @@ -56,21 +55,12 @@ enum { CANCELLED, CLICKED, COMPLETED, - TIMEOUT, LAST_SIGNAL }; static gpointer parent_class; static gulong signals[LAST_SIGNAL]; -static gboolean -activity_timeout_cb (EActivity *activity) -{ - g_signal_emit (activity, signals[TIMEOUT], 0); - - return FALSE; -} - static void activity_set_property (GObject *object, guint property_id, @@ -188,13 +178,64 @@ activity_finalize (GObject *object) g_free (priv->primary_text); g_free (priv->secondary_text); - if (priv->timeout_id > 0) - g_source_remove (priv->timeout_id); - /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } +static gchar * +activity_describe (EActivity *activity) +{ + GString *string; + const gchar *text; + gboolean cancelled; + gboolean completed; + gdouble percent; + + string = g_string_sized_new (256); + text = e_activity_get_primary_text (activity); + cancelled = e_activity_is_cancelled (activity); + completed = e_activity_is_completed (activity); + percent = e_activity_get_percent (activity); + + if (cancelled) { + /* Translators: This is a cancelled activity. */ + g_string_printf (string, _("%s (cancelled)"), text); + } else if (completed) { + /* Translators: This is a completed activity. */ + g_string_printf (string, _("%s (completed)"), text); + } else if (percent < 0.0) { + /* Translators: This is an activity whose percent + * complete is unknown. */ + g_string_printf (string, _("%s..."), text); + } else { + /* Translators: This is an activity whose percent + * complete is known. */ + g_string_printf ( + string, _("%s (%d%% complete)"), text, + (gint) (percent * 100.0 + 0.5)); + } + + return g_string_free (string, FALSE); +} + +static void +activity_cancelled (EActivity *activity) +{ + activity->priv->cancelled = TRUE; +} + +static void +activity_completed (EActivity *activity) +{ + activity->priv->completed = TRUE; +} + +static void +activity_clicked (EActivity *activity) +{ + /* Allow subclasses to safely chain up. */ +} + static void activity_class_init (EActivityClass *class) { @@ -208,6 +249,11 @@ activity_class_init (EActivityClass *class) object_class->get_property = activity_get_property; object_class->finalize = activity_finalize; + class->describe = activity_describe; + class->cancelled = activity_cancelled; + class->completed = activity_completed; + class->clicked = activity_clicked; + g_object_class_install_property ( object_class, PROP_BLOCKING, @@ -291,7 +337,8 @@ activity_class_init (EActivityClass *class) "cancelled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - 0, NULL, NULL, + G_STRUCT_OFFSET (EActivityClass, cancelled), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -299,7 +346,8 @@ activity_class_init (EActivityClass *class) "clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - 0, NULL, NULL, + G_STRUCT_OFFSET (EActivityClass, clicked), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -307,15 +355,8 @@ activity_class_init (EActivityClass *class) "completed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[TIMEOUT] = g_signal_new ( - "timeout", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, + G_STRUCT_OFFSET (EActivityClass, completed), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } @@ -372,7 +413,6 @@ e_activity_cancel (EActivity *activity) if (activity->priv->completed) return; - activity->priv->cancelled = TRUE; g_signal_emit (activity, signals[CANCELLED], 0); } @@ -387,7 +427,6 @@ e_activity_complete (EActivity *activity) if (activity->priv->completed) return; - activity->priv->completed = TRUE; g_signal_emit (activity, signals[COMPLETED], 0); } @@ -402,39 +441,14 @@ e_activity_clicked (EActivity *activity) gchar * e_activity_describe (EActivity *activity) { - GString *string; - const gchar *text; - gboolean cancelled; - gboolean completed; - gdouble percent; + EActivityClass *class; g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL); - string = g_string_sized_new (256); - text = e_activity_get_primary_text (activity); - cancelled = e_activity_is_cancelled (activity); - completed = e_activity_is_completed (activity); - percent = e_activity_get_percent (activity); - - if (cancelled) { - /* Translators: This is a cancelled activity. */ - g_string_printf (string, _("%s (cancelled)"), text); - } else if (completed) { - /* Translators: This is a completed activity. */ - g_string_printf (string, _("%s (completed)"), text); - } else if (percent < 0.0) { - /* Translators: This is an activity whose percent - * complete is unknown. */ - g_string_printf (string, _("%s..."), text); - } else { - /* Translators: This is an activity whose percent - * complete is known. */ - g_string_printf ( - string, _("%s (%d%% complete)"), text, - (gint) (percent * 100.0 + 0.5)); - } + class = E_ACTIVITY_GET_CLASS (activity); + g_return_val_if_fail (class->describe != NULL, NULL); - return g_string_free (string, FALSE); + return class->describe (activity); } gboolean @@ -453,29 +467,6 @@ e_activity_is_completed (EActivity *activity) return activity->priv->completed; } -void -e_activity_add_timeout (EActivity *activity, - guint seconds) -{ - g_return_if_fail (E_IS_ACTIVITY (activity)); - - e_activity_cancel_timeout (activity); - - activity->priv->timeout_id = g_timeout_add_seconds ( - seconds, (GSourceFunc) activity_timeout_cb, activity); -} - -void -e_activity_cancel_timeout (EActivity *activity) -{ - g_return_if_fail (E_IS_ACTIVITY (activity)); - - if (activity->priv->timeout_id > 0) { - g_source_remove (activity->priv->timeout_id); - activity->priv->timeout_id = 0; - } -} - gboolean e_activity_get_blocking (EActivity *activity) { @@ -611,105 +602,3 @@ e_activity_set_secondary_text (EActivity *activity, g_object_notify (G_OBJECT (activity), "secondary-text"); } - -/************************* Error Dialog Integration **************************/ - -void -e_activity_error (EActivity *activity, - GtkWidget *error_dialog) -{ - GObject *object; - const gchar *primary_text; - const gchar *secondary_text; - - /* XXX Convert an activity to a clickable error message. - * Clicking on the activity completes it and displays - * the error dialog. Eventually I'd like to eliminate - * error dialogs altogether and show errors directly - * in the shell window. */ - - g_return_if_fail (E_IS_ACTIVITY (activity)); - g_return_if_fail (GTK_IS_DIALOG (error_dialog)); - - object = G_OBJECT (error_dialog); - primary_text = g_object_get_data (object, "primary"); - secondary_text = g_object_get_data (object, "secondary"); - - e_activity_set_primary_text (activity, primary_text); - e_activity_set_secondary_text (activity, secondary_text); - e_activity_set_icon_name (activity, "dialog-warning"); - e_activity_set_clickable (activity, TRUE); - - g_signal_connect ( - activity, "cancelled", - G_CALLBACK (e_activity_cancel_timeout), NULL); - - g_signal_connect ( - activity, "completed", - G_CALLBACK (e_activity_cancel_timeout), NULL); - - g_signal_connect ( - activity, "clicked", - G_CALLBACK (e_activity_complete), NULL); - - g_signal_connect_swapped ( - activity, "clicked", - G_CALLBACK (gtk_dialog_run), error_dialog); - - g_signal_connect ( - activity, "timeout", - G_CALLBACK (e_activity_complete), NULL); - - /* XXX Allow for a configurable timeout. */ - e_activity_add_timeout (activity, 60); -} - -void -e_activity_info (EActivity *activity, - GtkWidget *info_dialog) -{ - GObject *object; - const gchar *primary_text; - const gchar *secondary_text; - - /* XXX Convert an activity to a clickable info message. - * Clicking on the activity completes it and displays - * the info dialog. Eventually I'd like to eliminate - * info dialogs altogether and show errors directly - * in the shell window. */ - - g_return_if_fail (E_IS_ACTIVITY (activity)); - g_return_if_fail (GTK_IS_DIALOG (info_dialog)); - - object = G_OBJECT (info_dialog); - primary_text = g_object_get_data (object, "primary"); - secondary_text = g_object_get_data (object, "secondary"); - - e_activity_set_primary_text (activity, primary_text); - e_activity_set_secondary_text (activity, secondary_text); - e_activity_set_icon_name (activity, "dialog-warning"); - e_activity_set_clickable (activity, TRUE); - - g_signal_connect ( - activity, "cancelled", - G_CALLBACK (e_activity_cancel_timeout), NULL); - - g_signal_connect ( - activity, "completed", - G_CALLBACK (e_activity_cancel_timeout), NULL); - - g_signal_connect ( - activity, "clicked", - G_CALLBACK (e_activity_complete), NULL); - - g_signal_connect_swapped ( - activity, "clicked", - G_CALLBACK (gtk_dialog_run), info_dialog); - - g_signal_connect ( - activity, "timeout", - G_CALLBACK (e_activity_complete), NULL); - - /* XXX Allow for a configurable timeout. */ - e_activity_add_timeout (activity, 60); -} diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index d949860333..5050d9e611 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -56,6 +56,14 @@ struct _EActivity { struct _EActivityClass { GObjectClass parent_class; + + /* Methods */ + gchar * (*describe) (EActivity *activity); + + /* Signals */ + void (*cancelled) (EActivity *activity); + void (*completed) (EActivity *activity); + void (*clicked) (EActivity *activity); }; GType e_activity_get_type (void); @@ -66,9 +74,6 @@ void e_activity_clicked (EActivity *activity); gchar * e_activity_describe (EActivity *activity); gboolean e_activity_is_cancelled (EActivity *activity); gboolean e_activity_is_completed (EActivity *activity); -void e_activity_add_timeout (EActivity *activity, - guint seconds); -void e_activity_cancel_timeout (EActivity *activity); gboolean e_activity_get_blocking (EActivity *activity); void e_activity_set_blocking (EActivity *activity, gboolean blocking); @@ -91,12 +96,6 @@ const gchar * e_activity_get_secondary_text (EActivity *activity); void e_activity_set_secondary_text (EActivity *activity, const gchar *secondary_text); -/* XXX Hacky integration with error dialogs. */ -void e_activity_error (EActivity *activity, - GtkWidget *error_dialog); -void e_activity_info (EActivity *activity, - GtkWidget *info_dialog); - G_END_DECLS #endif /* E_ACTIVITY_H */ diff --git a/widgets/misc/e-alert-activity.c b/widgets/misc/e-alert-activity.c new file mode 100644 index 0000000000..d8b9d6f3f3 --- /dev/null +++ b/widgets/misc/e-alert-activity.c @@ -0,0 +1,254 @@ +/* + * e-alert-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-alert-activity.h" + +#define E_ALERT_ACTIVITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivityPrivate)) + +struct _EAlertActivityPrivate { + GtkWidget *message_dialog; +}; + +enum { + PROP_0, + PROP_MESSAGE_DIALOG +}; + +static gpointer parent_class; + +static void +alert_activity_set_message_dialog (EAlertActivity *alert_activity, + GtkWidget *message_dialog) +{ + g_return_if_fail (alert_activity->priv->message_dialog == NULL); + + alert_activity->priv->message_dialog = g_object_ref (message_dialog); +} + +static void +alert_activity_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MESSAGE_DIALOG: + alert_activity_set_message_dialog ( + E_ALERT_ACTIVITY (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +alert_activity_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MESSAGE_DIALOG: + g_value_set_object ( + value, e_alert_activity_get_message_dialog ( + E_ALERT_ACTIVITY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +alert_activity_dispose (GObject *object) +{ + EAlertActivityPrivate *priv; + + priv = E_ALERT_ACTIVITY_GET_PRIVATE (object); + + if (priv->message_dialog != NULL) { + g_object_unref (priv->message_dialog); + priv->message_dialog = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +alert_activity_constructed (GObject *object) +{ + EActivity *activity; + EAlertActivity *alert_activity; + GtkWidget *message_dialog; + const gchar *primary_text; + const gchar *secondary_text; + + alert_activity = E_ALERT_ACTIVITY (object); + message_dialog = e_alert_activity_get_message_dialog (alert_activity); + + object = G_OBJECT (message_dialog); + primary_text = g_object_get_data (object, "primary"); + secondary_text = g_object_get_data (object, "secondary"); + + activity = E_ACTIVITY (alert_activity); + e_activity_set_primary_text (activity, primary_text); + e_activity_set_secondary_text (activity, secondary_text); +} + +static void +alert_activity_clicked (EActivity *activity) +{ + EAlertActivity *alert_activity; + GtkWidget *message_dialog; + + e_activity_complete (activity); + + alert_activity = E_ALERT_ACTIVITY (activity); + message_dialog = e_alert_activity_get_message_dialog (alert_activity); + gtk_dialog_run (GTK_DIALOG (message_dialog)); + gtk_widget_hide (message_dialog); + + /* Chain up to parent's clicked() method. */ + E_ACTIVITY_CLASS (parent_class)->clicked (activity); +} + +static void +alert_activity_timeout (ETimeoutActivity *activity) +{ + e_activity_complete (E_ACTIVITY (activity)); + + /* Chain up to parent's timeout() method. */ + E_TIMEOUT_ACTIVITY_CLASS (parent_class)->timeout (activity); +} + +static void +alert_activity_class_init (EAlertActivityClass *class) +{ + GObjectClass *object_class; + EActivityClass *activity_class; + ETimeoutActivityClass *timeout_activity_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAlertActivityPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = alert_activity_set_property; + object_class->get_property = alert_activity_get_property; + object_class->dispose = alert_activity_dispose; + object_class->constructed = alert_activity_constructed; + + activity_class = E_ACTIVITY_CLASS (class); + activity_class->clicked = alert_activity_clicked; + + timeout_activity_class = E_TIMEOUT_ACTIVITY_CLASS (class); + timeout_activity_class->timeout = alert_activity_timeout; + + g_object_class_install_property ( + object_class, + PROP_MESSAGE_DIALOG, + g_param_spec_object ( + "message-dialog", + NULL, + NULL, + GTK_TYPE_DIALOG, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +alert_activity_init (EAlertActivity *alert_activity) +{ + alert_activity->priv = E_ALERT_ACTIVITY_GET_PRIVATE (alert_activity); + + e_activity_set_clickable (E_ACTIVITY (alert_activity), TRUE); + e_timeout_activity_set_timeout (E_TIMEOUT_ACTIVITY (alert_activity), 60); +} + +GType +e_alert_activity_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAlertActivityClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) alert_activity_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAlertActivity), + 0, /* n_preallocs */ + (GInstanceInitFunc) alert_activity_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_TIMEOUT_ACTIVITY, "EAlertActivity", + &type_info, 0); + } + + return type; +} + +EActivity * +e_alert_activity_new_info (GtkWidget *message_dialog) +{ + g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL); + + return g_object_new ( + E_TYPE_ALERT_ACTIVITY, + "icon-name", "dialog-information", + "message-dialog", message_dialog, NULL); +} + +EActivity * +e_alert_activity_new_error (GtkWidget *message_dialog) +{ + g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL); + + return g_object_new ( + E_TYPE_ALERT_ACTIVITY, + "icon-name", "dialog-error", + "message-dialog", message_dialog, NULL); +} + +EActivity * +e_alert_activity_new_warning (GtkWidget *message_dialog) +{ + g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL); + + return g_object_new ( + E_TYPE_ALERT_ACTIVITY, + "icon-name", "dialog-warning", + "message-dialog", message_dialog, NULL); +} + +GtkWidget * +e_alert_activity_get_message_dialog (EAlertActivity *alert_activity) +{ + g_return_val_if_fail (E_IS_ALERT_ACTIVITY (alert_activity), NULL); + + return alert_activity->priv->message_dialog; +} diff --git a/widgets/misc/e-alert-activity.h b/widgets/misc/e-alert-activity.h new file mode 100644 index 0000000000..4c5547d7fa --- /dev/null +++ b/widgets/misc/e-alert-activity.h @@ -0,0 +1,70 @@ +/* + * e-alert-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ALERT_ACTIVITY_H +#define E_ALERT_ACTIVITY_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ALERT_ACTIVITY \ + (e_alert_activity_get_type ()) +#define E_ALERT_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivity)) +#define E_ALERT_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ALERT_ACTIVITY, EAlertActivityClass)) +#define E_IS_ALERT_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ALERT_ACTIVITY)) +#define E_IS_ALERT_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ALERT_ACTIVITY)) +#define E_ALERT_ACTIVITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivityClass)) + +G_BEGIN_DECLS + +typedef struct _EAlertActivity EAlertActivity; +typedef struct _EAlertActivityClass EAlertActivityClass; +typedef struct _EAlertActivityPrivate EAlertActivityPrivate; + +struct _EAlertActivity { + ETimeoutActivity parent; + EAlertActivityPrivate *priv; +}; + +struct _EAlertActivityClass { + ETimeoutActivityClass parent_class; +}; + +GType e_alert_activity_get_type (void); +EActivity * e_alert_activity_new_info (GtkWidget *message_dialog); +EActivity * e_alert_activity_new_error (GtkWidget *message_dialog); +EActivity * e_alert_activity_new_warning (GtkWidget *message_dialog); +GtkWidget * e_alert_activity_get_message_dialog + (EAlertActivity *alert_activity); + +G_END_DECLS + +#endif /* E_ALERT_ACTIVITY_H */ diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 316aa85a0e..4608d77b9d 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -43,6 +43,7 @@ #include "e-attachment.h" #include "e-attachment-bar.h" +#include "e-mime-part-utils.h" #include @@ -56,11 +57,13 @@ #include #include -#include "e-util/e-util.h" +#include "e-util/e-binding.h" +#include "e-util/e-error.h" #include "e-util/e-gui-utils.h" #include "e-util/e-icon-factory.h" -#include "e-util/e-error.h" #include "e-util/e-mktemp.h" +#include "e-util/e-util.h" +#include "e-util/gconf-bridge.h" #define ICON_WIDTH 64 #define ICON_SEPARATORS " /-_" @@ -70,84 +73,418 @@ #define ICON_BORDER 2 #define ICON_TEXT_SPACING 2 - -static GnomeIconListClass *parent_class = NULL; +#define E_ATTACHMENT_BAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarPrivate)) struct _EAttachmentBarPrivate { - GtkWidget *attach; /* attachment file dialogue, if active */ - gboolean batch_unref; GPtrArray *attachments; + gchar *current_folder; char *path; + + GtkUIManager *ui_manager; + GtkActionGroup *standard_actions; + GtkActionGroup *editable_actions; + GtkActionGroup *open_actions; + guint merge_id; + + gchar *background_filename; + gchar *background_options; + + guint editable : 1; +}; + +enum { + PROP_0, + PROP_BACKGROUND_FILENAME, + PROP_BACKGROUND_OPTIONS, + PROP_CURRENT_FOLDER, + PROP_EDITABLE, + PROP_UI_MANAGER }; - enum { CHANGED, + UPDATE_ACTIONS, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; - -static void update (EAttachmentBar *bar); +static void +action_add_cb (GtkAction *action, + EAttachmentBar *attachment_bar) +{ + GtkWidget *dialog; + GtkWidget *option; + GSList *uris, *iter; + const gchar *disposition; + gboolean active; + gpointer parent; + gint response; + + parent = gtk_widget_get_toplevel (GTK_WIDGET (attachment_bar)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + dialog = gtk_file_chooser_dialog_new ( + _("Insert Attachment"), parent, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("A_ttach"), GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_default_response ( + GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_file_chooser_set_local_only ( + GTK_FILE_CHOOSER (dialog), FALSE); + gtk_file_chooser_set_select_multiple ( + GTK_FILE_CHOOSER (dialog), TRUE); + gtk_window_set_icon_name ( + GTK_WINDOW (dialog), "mail-attachment"); + + option = gtk_check_button_new_with_mnemonic ( + _("_Suggest automatic display of attachment")); + gtk_file_chooser_set_extra_widget ( + GTK_FILE_CHOOSER (dialog), option); + gtk_widget_show (option); + + response = e_attachment_bar_file_chooser_dialog_run ( + attachment_bar, dialog); + + if (response != GTK_RESPONSE_OK) + goto exit; + + uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog)); + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option)); + disposition = active ? "inline" : "attachment"; + + for (iter = uris; iter != NULL; iter = iter->next) { + CamelURL *url; + + url = camel_url_new (iter->data, NULL); + if (url == NULL) + continue; -/* Attachment handling functions. */ + /* XXX Do we really need two different attach functions? */ + if (g_ascii_strcasecmp (url->protocol, "file") == 0) + e_attachment_bar_attach ( + attachment_bar, url->path, disposition); + else + e_attachment_bar_attach_remote_file ( + attachment_bar, iter->data, disposition); + + camel_url_free (url); + } + + g_slist_foreach (uris, (GFunc) g_free, NULL); + g_slist_free (uris); + +exit: + gtk_widget_destroy (dialog); +} static void -attachment_destroy (EAttachmentBar *bar, EAttachment *attachment) +action_properties_cb (GtkAction *action, + EAttachmentBar *attachment_bar) { - if (bar->priv->batch_unref) - return; + GnomeIconList *icon_list; + GPtrArray *array; + GList *selection; + gpointer parent; - if (g_ptr_array_remove (bar->priv->attachments, attachment)) { - update (bar); - g_signal_emit (bar, signals[CHANGED], 0); + array = attachment_bar->priv->attachments; + + icon_list = GNOME_ICON_LIST (attachment_bar); + selection = gnome_icon_list_get_selection (icon_list); + g_return_if_fail (selection != NULL); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (icon_list)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + while (selection != NULL) { + gint index = GPOINTER_TO_INT (selection->data); + EAttachment *attachment; + + selection = g_list_next (selection); + + if (index >= array->len) + continue; + + attachment = array->pdata[index]; + e_attachment_edit (attachment, parent); } } static void -attachment_changed_cb (EAttachment *attachment, - gpointer data) +action_recent_cb (GtkAction *action, + EAttachmentBar *attachment_bar) { - update (E_ATTACHMENT_BAR (data)); + GtkRecentChooser *chooser; + GFile *file; + gchar *uri; + + chooser = GTK_RECENT_CHOOSER (action); + + /* Wish: gtk_recent_chooser_get_current_file() */ + uri = gtk_recent_chooser_get_current_uri (chooser); + file = g_file_new_for_uri (uri); + g_free (uri); + + if (g_file_is_native (file)) + e_attachment_bar_attach ( + E_ATTACHMENT_BAR (attachment_bar), + g_file_get_path (file), "attachment"); + else + e_attachment_bar_attach_remote_file ( + E_ATTACHMENT_BAR (attachment_bar), + g_file_get_uri (file), "attachment"); + + g_object_unref (file); } static void -add_common (EAttachmentBar *bar, EAttachment *attachment) +action_remove_cb (GtkAction *action, + EAttachmentBar *attachment_bar) { - g_return_if_fail (attachment != NULL); + GnomeIconList *icon_list; + GPtrArray *array; + GList *selection; + GList *trash = NULL; - g_ptr_array_add (bar->priv->attachments, attachment); - g_object_weak_ref ((GObject *) attachment, (GWeakNotify) attachment_destroy, bar); - g_signal_connect (attachment, "changed", G_CALLBACK (attachment_changed_cb), bar); + array = attachment_bar->priv->attachments; - update (bar); + icon_list = GNOME_ICON_LIST (attachment_bar); + selection = gnome_icon_list_get_selection (icon_list); + g_return_if_fail (selection != NULL); - g_signal_emit (bar, signals[CHANGED], 0); + while (selection != NULL) { + gint index = GPOINTER_TO_INT (selection->data); + + selection = g_list_next (selection); + + if (index >= array->len) + continue; + + /* We can't unref the attachment here because that may + * change the selection and invalidate the list we are + * iterating over. So move it to a trash list instead. */ + trash = g_list_prepend (trash, array->pdata[index]); + array->pdata[index] = NULL; + } + + /* Compress the attachment array. */ + while (g_ptr_array_remove (array, NULL)); + + /* Take out the trash. */ + g_list_foreach (trash, (GFunc) g_object_unref, NULL); + g_list_free (trash); + + e_attachment_bar_refresh (attachment_bar); + + g_signal_emit (attachment_bar, signals[CHANGED], 0); } static void -add_from_mime_part (EAttachmentBar *bar, CamelMimePart *part) +action_save_as_cb (GtkAction *action, + EAttachmentBar *attachment_bar) { - add_common (bar, e_attachment_new_from_mime_part (part)); } static void -add_from_file (EAttachmentBar *bar, const char *file_name, const char *disposition) +action_set_background_cb (GtkAction *action, + EAttachmentBar *attachment_bar) { + GnomeIconList *icon_list; + CamelContentType *content_type; + CamelMimePart *mime_part; EAttachment *attachment; - CamelException ex; + GPtrArray *array; + GList *selection; + gchar *basename; + gchar *filename; + gchar *dirname; + GFile *file; + gint index; + GError *error = NULL; + + icon_list = GNOME_ICON_LIST (attachment_bar); + selection = gnome_icon_list_get_selection (icon_list); + g_return_if_fail (selection != NULL); + + array = attachment_bar->priv->attachments; + index = GPOINTER_TO_INT (selection->data); + attachment = E_ATTACHMENT (array->pdata[index]); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + + content_type = camel_mime_part_get_content_type (mime_part); + basename = g_strdup (camel_mime_part_get_filename (mime_part)); + + if (basename == NULL || basename == '\0') { + g_free (basename); + basename = g_strdup_printf ( + _("untitled_image.%s"), + content_type->subtype); + } - camel_exception_init (&ex); + dirname = g_build_filename ( + g_get_home_dir (), ".gnome2", "wallpapers", NULL); - if ((attachment = e_attachment_new (file_name, disposition, &ex))) { - add_common (bar, attachment); - } else { - /* FIXME: Avoid using error from mailer */ - e_error_run ((GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) bar), "mail-composer:no-attach", - file_name, camel_exception_get_description (&ex), NULL); - camel_exception_clear (&ex); + index = 0; + filename = g_build_filename (dirname, basename, NULL); + + while (g_file_test (filename, G_FILE_TEST_EXISTS)) { + gchar *temp; + gchar *ext; + + ext = strrchr (filename, '.'); + if (ext != NULL) + *ext++ = '\0'; + + if (ext == NULL) + temp = g_strdup_printf ( + "%s (%d)", basename, index++); + else + temp = g_strdup_printf ( + "%s (%d).%s", basename, index++, ext); + + g_free (basename); + g_free (filename); + basename = temp; + + filename = g_build_filename (dirname, basename, NULL); + } + + g_free (basename); + g_free (dirname); + + file = g_file_new_for_path (filename); + + if (e_mime_part_utils_save_to_file (mime_part, file, &error)) { + const gchar *background_filename; + const gchar *background_options; + + background_filename = + e_attachment_bar_get_background_filename ( + attachment_bar); + background_options = + e_attachment_bar_get_background_options ( + attachment_bar); + + if (g_strcmp0 (background_filename, filename) == 0) + e_attachment_bar_set_background_filename ( + attachment_bar, NULL); + + e_attachment_bar_set_background_filename ( + attachment_bar, filename); + + if (g_strcmp0 (background_options, "none") == 0) + e_attachment_bar_set_background_options ( + attachment_bar, "wallpaper"); + } + + g_object_unref (file); + g_free (filename); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } +} + +static GtkActionEntry standard_entries[] = { + + { "save-as", + GTK_STOCK_SAVE_AS, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_save_as_cb) }, + + { "set-background", + NULL, + N_("Set as _Background"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_set_background_cb) } +}; + +static GtkActionEntry editable_entries[] = { + + { "add", + GTK_STOCK_ADD, + N_("A_dd Attachment..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_add_cb) }, + + { "properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_properties_cb) }, + + { "remove", + GTK_STOCK_REMOVE, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_remove_cb) } +}; + +static void +attachment_bar_show_popup_menu (EAttachmentBar *attachment_bar, + GdkEventButton *event) +{ + GtkUIManager *ui_manager; + GtkWidget *menu; + + ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); + menu = gtk_ui_manager_get_widget (ui_manager, "/attachment-popup"); + g_return_if_fail (GTK_IS_MENU (menu)); + + e_attachment_bar_update_actions (attachment_bar); + + if (event != NULL) + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + event->button, event->time); + else + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + 0, gtk_get_current_event_time ()); +} + +/* Attachment handling functions. */ + +static void +attachment_destroy (EAttachmentBar *bar, + EAttachment *attachment) +{ + if (bar->priv->batch_unref) + return; + + if (g_ptr_array_remove (bar->priv->attachments, attachment)) { + e_attachment_bar_refresh (bar); + g_signal_emit (bar, signals[CHANGED], 0); } } @@ -161,6 +498,7 @@ get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) { GdkPixbuf *pixbuf = NULL; #ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H + CamelMimePart *mime_part; struct stat file_stat; char *file_uri = NULL; gboolean is_tmp = FALSE; @@ -168,9 +506,11 @@ get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) if (!attachment || !attachment->is_available_local) return NULL; + mime_part = e_attachment_get_mime_part (attachment); + if (attachment->store_uri && g_str_has_prefix (attachment->store_uri, "file://")) file_uri = attachment->store_uri; - else if (attachment->body) { + else if (mime_part != NULL) { /* save part to the temp directory */ char *tmp_file; @@ -182,7 +522,7 @@ get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) char *mfilename = NULL; const char * filename; - filename = camel_mime_part_get_filename (attachment->body); + filename = camel_mime_part_get_filename (mime_part); if (filename == NULL) filename = "unknown"; else { @@ -202,7 +542,7 @@ get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) if (stream) { CamelDataWrapper *content; - content = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body)); + content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); if (camel_data_wrapper_decode_to_stream (content, stream) == -1 || camel_stream_flush (stream) == -1) { @@ -298,17 +638,24 @@ scale_pixbuf (GdkPixbuf *pixbuf) /* Icon list contents handling. */ static void -calculate_height_width(EAttachmentBar *bar, int *new_width, int *new_height) +calculate_height_width (EAttachmentBar *bar, + gint *new_width, + gint *new_height) { int width, height, icon_width; PangoFontMetrics *metrics; PangoContext *context; - context = gtk_widget_get_pango_context ((GtkWidget *) bar); - metrics = pango_context_get_metrics (context, ((GtkWidget *) bar)->style->font_desc, pango_context_get_language (context)); - width = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (metrics)) * 15; + context = gtk_widget_get_pango_context (GTK_WIDGET (bar)); + metrics = pango_context_get_metrics ( + context, GTK_WIDGET (bar)->style->font_desc, + pango_context_get_language (context)); + width = PANGO_PIXELS ( + pango_font_metrics_get_approximate_char_width (metrics)) * 15; /* This should be *2, but the icon list creates too much space above ... */ - height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) * 3; + height = PANGO_PIXELS ( + pango_font_metrics_get_ascent (metrics) + + pango_font_metrics_get_descent (metrics)) * 3; pango_font_metrics_unref (metrics); icon_width = ICON_WIDTH + ICON_SPACING + ICON_BORDER + ICON_TEXT_SPACING; @@ -316,21 +663,23 @@ calculate_height_width(EAttachmentBar *bar, int *new_width, int *new_height) *new_width = MAX (icon_width, width); if (new_height) - *new_height = ICON_WIDTH + ICON_SPACING + ICON_BORDER + ICON_TEXT_SPACING + height; - - return; + *new_height = ICON_WIDTH + ICON_SPACING + + ICON_BORDER + ICON_TEXT_SPACING + height; } void e_attachment_bar_create_attachment_cache (EAttachment *attachment) { - CamelContentType *content_type; + CamelMimePart *mime_part; - if (!attachment->body) + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part == NULL) return; - content_type = camel_mime_part_get_content_type (attachment->body); + content_type = camel_mime_part_get_content_type (mime_part); if (camel_content_type_is(content_type, "image", "*")) { CamelDataWrapper *wrapper; @@ -339,7 +688,7 @@ e_attachment_bar_create_attachment_cache (EAttachment *attachment) gboolean error = TRUE; GdkPixbuf *pixbuf; - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body)); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); mstream = (CamelStreamMem *) camel_stream_mem_new (); camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); @@ -350,12 +699,15 @@ e_attachment_bar_create_attachment_cache (EAttachment *attachment) gdk_pixbuf_loader_close (loader, NULL); if (!error) { + /* The loader owns the reference. */ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - attachment->pixbuf_cache = scale_pixbuf (pixbuf); - pixbuf = attachment->pixbuf_cache; - g_object_ref(pixbuf); + + /* This returns a new GdkPixbuf. */ + pixbuf = scale_pixbuf (pixbuf); + e_attachment_set_thumbnail (attachment, pixbuf); + g_object_unref (pixbuf); } else { - attachment->pixbuf_cache = NULL; + e_attachment_set_thumbnail (attachment, NULL); g_warning ("GdkPixbufLoader Error"); } @@ -366,343 +718,108 @@ e_attachment_bar_create_attachment_cache (EAttachment *attachment) } static void -update (EAttachmentBar *bar) +update_remote_file (EAttachment *attachment, EAttachmentBar *bar) { - struct _EAttachmentBarPrivate *priv; GnomeIconList *icon_list; - int bar_width, bar_height; - int i; + GnomeIconTextItem *item; + const gchar *filename; + char *msg, *base; + + if (attachment->percentage == -1) { + e_attachment_bar_refresh (bar); + return; + } + + filename = e_attachment_get_filename (attachment); + base = g_path_get_basename (filename); + msg = g_strdup_printf ("%s (%d%%)", base, attachment->percentage); + g_free (base); - priv = bar->priv; icon_list = GNOME_ICON_LIST (bar); gnome_icon_list_freeze (icon_list); - gnome_icon_list_clear (icon_list); - - /* FIXME could be faster, but we don't care. */ - for (i = 0; i < priv->attachments->len; i++) { - EAttachment *attachment; - CamelContentType *content_type; - char *size_string, *label; - GdkPixbuf *pixbuf = NULL; - const char *desc; + item = gnome_icon_list_get_icon_text_item ( + icon_list, attachment->index); + if (!item->is_text_allocated) + g_free (item->text); - attachment = priv->attachments->pdata[i]; + gnome_icon_text_item_configure ( + item, item->x, item->y, item->width, + item->fontname, msg, item->is_editable, TRUE); - if (!attachment->is_available_local || !attachment->body) { - if ((pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG))) { - attachment->index = gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, ""); - g_object_unref (pixbuf); - } - continue; - } + gnome_icon_list_thaw (icon_list); +} - content_type = camel_mime_part_get_content_type (attachment->body); - /* Get the image out of the attachment - and create a thumbnail for it */ - if ((pixbuf = attachment->pixbuf_cache)) { - g_object_ref(pixbuf); - } else if (camel_content_type_is(content_type, "image", "*")) { - CamelDataWrapper *wrapper; - CamelStreamMem *mstream; - GdkPixbufLoader *loader; - gboolean error = TRUE; +void +e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width) +{ + int per_col, rows, height, width; - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body)); - mstream = (CamelStreamMem *) camel_stream_mem_new (); + calculate_height_width(bar, &width, &height); + per_col = bar_width / width; + per_col = (per_col ? per_col : 1); + rows = (bar->priv->attachments->len + per_col - 1) / per_col; + gtk_widget_set_size_request ((GtkWidget *)bar, bar_width, rows * height); +} - camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); +/** + * e_attachment_bar_get_selected: + * @bar: an #EAttachmentBar object + * + * Returns a newly allocated #GSList of ref'd #EAttachment objects + * representing the selected items in the #EAttachmentBar Icon List. + **/ +GSList * +e_attachment_bar_get_selected (EAttachmentBar *bar) +{ + EAttachmentBarPrivate *priv; + GSList *attachments = NULL; + EAttachment *attachment; + GList *items; + int id; - /* Stream image into pixbuf loader */ - loader = gdk_pixbuf_loader_new (); - error = !gdk_pixbuf_loader_write (loader, mstream->buffer->data, mstream->buffer->len, NULL); - gdk_pixbuf_loader_close (loader, NULL); + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - if (!error) { - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - attachment->pixbuf_cache = scale_pixbuf (pixbuf); - pixbuf = attachment->pixbuf_cache; - g_object_ref (pixbuf); - } else { - pixbuf = NULL; - g_warning ("GdkPixbufLoader Error"); - } + priv = bar->priv; - /* Destroy everything */ - g_object_unref (loader); - camel_object_unref (mstream); - } else if (!bar->expand && (pixbuf = get_system_thumbnail (attachment, content_type))) { - attachment->pixbuf_cache = scale_pixbuf (pixbuf); - pixbuf = attachment->pixbuf_cache; - g_object_ref (pixbuf); - } + items = gnome_icon_list_get_selection ((GnomeIconList *) bar); - desc = camel_mime_part_get_description (attachment->body); - if (!desc || *desc == '\0') { - if (attachment->file_name) - desc = attachment->file_name; - else - desc = camel_mime_part_get_filename (attachment->body); + while (items != NULL) { + if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { + attachment = priv->attachments->pdata[id]; + attachments = g_slist_prepend (attachments, attachment); + g_object_ref (attachment); } - if (!desc) - desc = _("attachment"); + items = items->next; + } - if (attachment->size && (size_string = g_format_size_for_display (attachment->size))) { - label = g_strdup_printf ("%s (%s)", desc, size_string); - g_free (size_string); - } else - label = g_strdup (desc); + attachments = g_slist_reverse (attachments); - if (pixbuf == NULL) { - char *mime_type; + return attachments; +} - mime_type = camel_content_type_simple (content_type); - pixbuf = e_icon_for_mime_type (mime_type, 48); - if (pixbuf == NULL) { - g_warning("cannot find icon for mime type %s (installation problem?)", mime_type); - pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG); - } - g_free (mime_type); +/* FIXME: Cleanup this, since there is a api to get selected attachments */ +/** + * e_attachment_bar_get_attachment: + * @bar: an #EAttachmentBar object + * @id: Index of the desired attachment or -1 to request all selected attachments + * + * Returns a newly allocated #GSList of ref'd #EAttachment objects + * representing the requested item(s) in the #EAttachmentBar Icon + * List. + **/ +GSList * +e_attachment_bar_get_attachment (EAttachmentBar *bar, int id) +{ + EAttachmentBarPrivate *priv; + EAttachment *attachment; + GSList *attachments; - /* remember this picture and use it later again */ - if (pixbuf) - attachment->pixbuf_cache = g_object_ref (pixbuf); - } + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - if (pixbuf) { - GdkPixbuf *pixbuf_orig = pixbuf; - pixbuf = gdk_pixbuf_add_alpha (pixbuf_orig, TRUE, 255, 255, 255); - - /* gdk_pixbuf_add_alpha returns a newly allocated pixbuf, - free the original one. - */ - g_object_unref (pixbuf_orig); - - /* In case of a attachment bar, in a signed/encrypted part, display the status as a emblem*/ - if (attachment->sign) { - /* Show the signature status at the right-bottom.*/ - GdkPixbuf *sign = NULL; - int x, y; - - if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_BAD) - sign = e_icon_factory_get_icon ("stock_signature-bad", E_ICON_SIZE_MENU); - else if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_GOOD) - sign = e_icon_factory_get_icon ("stock_signature-ok", E_ICON_SIZE_MENU); - else - sign = e_icon_factory_get_icon ("stock_signature", E_ICON_SIZE_MENU); - - x = gdk_pixbuf_get_width (pixbuf) - 17; - y = gdk_pixbuf_get_height (pixbuf) - 17; - - gdk_pixbuf_copy_area (sign, 0, 0, 16, 16, pixbuf, x, y); - g_object_unref (sign); - } - - if (attachment->encrypt) { - /* Show the encryption status at the top left.*/ - GdkPixbuf *encrypt = e_icon_factory_get_icon ("stock_lock-ok", E_ICON_SIZE_MENU); - - gdk_pixbuf_copy_area (encrypt, 0, 0, 16, 16, pixbuf, 1, 1); - g_object_unref (encrypt); - } - - gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, label); - g_object_unref (pixbuf); - } - - g_free (label); - } - - gnome_icon_list_thaw (icon_list); - - /* Resize */ - if (bar->expand) { - gtk_widget_get_size_request ((GtkWidget *) bar, &bar_width, &bar_height); - - if (bar->priv->attachments->len) { - int per_col, rows, height, width; - - calculate_height_width(bar, &width, &height); - per_col = bar_width / width; - per_col = (per_col ? per_col : 1); - rows = (bar->priv->attachments->len + per_col -1) / per_col; - gtk_widget_set_size_request ((GtkWidget *) bar, bar_width, rows * height); - } - } -} - -static void -update_remote_file (EAttachment *attachment, EAttachmentBar *bar) -{ - GnomeIconList *icon_list; - GnomeIconTextItem *item; - char *msg, *base; - - if (attachment->percentage == -1) { - update (bar); - return; - } - - base = g_path_get_basename(attachment->file_name); - msg = g_strdup_printf("%s (%d%%)", base, attachment->percentage); - g_free(base); - - icon_list = GNOME_ICON_LIST (bar); - - gnome_icon_list_freeze (icon_list); - - item = gnome_icon_list_get_icon_text_item (icon_list, attachment->index); - if (!item->is_text_allocated) - g_free (item->text); - - gnome_icon_text_item_configure (item, item->x, item->y, item->width, item->fontname, msg, item->is_editable, TRUE); - - gnome_icon_list_thaw (icon_list); -} - -void -e_attachment_bar_remove_selected (EAttachmentBar *bar) -{ - struct _EAttachmentBarPrivate *priv; - EAttachment *attachment; - int id, left, nrem = 0; - GList *items; - GPtrArray *temp_arr; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - priv = bar->priv; - - if (!(items = gnome_icon_list_get_selection ((GnomeIconList *) bar))) - return; - - temp_arr = g_ptr_array_new (); - while (items != NULL) { - if ((id = GPOINTER_TO_INT (items->data) - nrem) < priv->attachments->len) { - attachment = E_ATTACHMENT(g_ptr_array_index (priv->attachments, id)); - g_ptr_array_add (temp_arr, (gpointer)attachment); - g_ptr_array_remove_index (priv->attachments, id); - nrem++; - } - - items = items->next; - } - - g_ptr_array_foreach (temp_arr, (GFunc)g_object_unref, NULL); - g_ptr_array_free (temp_arr, TRUE); - - update (bar); - - g_signal_emit (bar, signals[CHANGED], 0); - - id++; - - if ((left = gnome_icon_list_get_num_icons ((GnomeIconList *) bar)) > 0) - gnome_icon_list_focus_icon ((GnomeIconList *) bar, left > id ? id : left - 1); -} - -void -e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width) -{ - int per_col, rows, height, width; - - calculate_height_width(bar, &width, &height); - per_col = bar_width / width; - per_col = (per_col ? per_col : 1); - rows = (bar->priv->attachments->len + per_col - 1) / per_col; - gtk_widget_set_size_request ((GtkWidget *)bar, bar_width, rows * height); -} - -void -e_attachment_bar_edit_selected (EAttachmentBar *bar) -{ - struct _EAttachmentBarPrivate *priv; - EAttachment *attachment; - GList *items; - int id; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - priv = bar->priv; - - items = gnome_icon_list_get_selection ((GnomeIconList *) bar); - while (items != NULL) { - if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { - attachment = priv->attachments->pdata[id]; - e_attachment_edit (attachment, GTK_WIDGET (bar)); - } - - items = items->next; - } -} - -GtkWidget ** -e_attachment_bar_get_selector(EAttachmentBar *bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - return &bar->priv->attach; -} - -/** - * e_attachment_bar_get_selected: - * @bar: an #EAttachmentBar object - * - * Returns a newly allocated #GSList of ref'd #EAttachment objects - * representing the selected items in the #EAttachmentBar Icon List. - **/ -GSList * -e_attachment_bar_get_selected (EAttachmentBar *bar) -{ - struct _EAttachmentBarPrivate *priv; - GSList *attachments = NULL; - EAttachment *attachment; - GList *items; - int id; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; - - items = gnome_icon_list_get_selection ((GnomeIconList *) bar); - - while (items != NULL) { - if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { - attachment = priv->attachments->pdata[id]; - attachments = g_slist_prepend (attachments, attachment); - g_object_ref (attachment); - } - - items = items->next; - } - - attachments = g_slist_reverse (attachments); - - return attachments; -} - -/* FIXME: Cleanup this, since there is a api to get selected attachments */ -/** - * e_attachment_bar_get_attachment: - * @bar: an #EAttachmentBar object - * @id: Index of the desired attachment or -1 to request all selected attachments - * - * Returns a newly allocated #GSList of ref'd #EAttachment objects - * representing the requested item(s) in the #EAttachmentBar Icon - * List. - **/ -GSList * -e_attachment_bar_get_attachment (EAttachmentBar *bar, int id) -{ - struct _EAttachmentBarPrivate *priv; - EAttachment *attachment; - GSList *attachments; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; + priv = bar->priv; if (id == -1 || id > priv->attachments->len) return e_attachment_bar_get_selected (bar); @@ -724,7 +841,7 @@ e_attachment_bar_get_attachment (EAttachmentBar *bar, int id) GSList * e_attachment_bar_get_all_attachments (EAttachmentBar *bar) { - struct _EAttachmentBarPrivate *priv; + EAttachmentBarPrivate *priv; GSList *attachments = NULL; EAttachment *attachment; int i; @@ -748,7 +865,7 @@ e_attachment_bar_get_all_attachments (EAttachmentBar *bar) GSList * e_attachment_bar_get_parts (EAttachmentBar *bar) { - struct _EAttachmentBarPrivate *priv; + EAttachmentBarPrivate *priv; EAttachment *attachment; GSList *parts = NULL; int i; @@ -758,50 +875,22 @@ e_attachment_bar_get_parts (EAttachmentBar *bar) priv = bar->priv; for (i = 0; i < priv->attachments->len; i++) { + CamelMimePart *mime_part; + attachment = priv->attachments->pdata[i]; + mime_part = e_attachment_get_mime_part (attachment); + if (attachment->is_available_local) - parts = g_slist_prepend (parts, attachment->body); + parts = g_slist_prepend (parts, mime_part); } return parts; } -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EAttachmentBar *bar = (EAttachmentBar *) object; - struct _EAttachmentBarPrivate *priv = bar->priv; - EAttachment *attachment; - int i; - - if ((priv = bar->priv)) { - priv->batch_unref = TRUE; - for (i = 0; i < priv->attachments->len; i++) { - attachment = priv->attachments->pdata[i]; - g_object_weak_unref ((GObject *) attachment, (GWeakNotify) attachment_destroy, bar); - g_object_unref (attachment); - } - g_ptr_array_free (priv->attachments, TRUE); - - if (priv->attach) - gtk_widget_destroy (priv->attach); - - if (priv->path) - g_free (priv->path); - - g_free (priv); - bar->priv = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - static char * -temp_save_part (CamelMimePart *part, gboolean readonly) +temp_save_part (EAttachment *attachment, gboolean readonly) { + CamelMimePart *mime_part; const char *filename; char *tmpdir, *path, *mfilename = NULL, *utf8_mfilename = NULL; CamelStream *stream; @@ -810,7 +899,9 @@ temp_save_part (CamelMimePart *part, gboolean readonly) if (!(tmpdir = e_mkdtemp ("evolution-tmp-XXXXXX"))) return NULL; - if (!(filename = camel_mime_part_get_filename (part))) { + mime_part = e_attachment_get_mime_part (attachment); + + if (!(filename = camel_mime_part_get_filename (mime_part))) { /* This is the default filename used for temporary file creation */ filename = _("Unknown"); } else { @@ -825,7 +916,7 @@ temp_save_part (CamelMimePart *part, gboolean readonly) g_free (tmpdir); g_free (mfilename); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); if (readonly) stream = camel_stream_fs_new_with_name (path, O_RDWR|O_CREAT|O_TRUNC, 0444); else @@ -853,9 +944,344 @@ temp_save_part (CamelMimePart *part, gboolean readonly) } static void -eab_drag_data_get(EAttachmentBar *bar, GdkDragContext *drag, GtkSelectionData *data, guint info, guint time) +attachment_bar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BACKGROUND_FILENAME: + e_attachment_bar_set_background_filename ( + E_ATTACHMENT_BAR (object), + g_value_get_string (value)); + return; + + case PROP_BACKGROUND_OPTIONS: + e_attachment_bar_set_background_options ( + E_ATTACHMENT_BAR (object), + g_value_get_string (value)); + return; + + case PROP_CURRENT_FOLDER: + e_attachment_bar_set_current_folder ( + E_ATTACHMENT_BAR (object), + g_value_get_string (value)); + return; + + case PROP_EDITABLE: + e_attachment_bar_set_editable ( + E_ATTACHMENT_BAR (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BACKGROUND_FILENAME: + g_value_set_string ( + value, + e_attachment_bar_get_background_filename ( + E_ATTACHMENT_BAR (object))); + return; + + case PROP_BACKGROUND_OPTIONS: + g_value_set_string ( + value, + e_attachment_bar_get_background_options ( + E_ATTACHMENT_BAR (object))); + return; + + case PROP_CURRENT_FOLDER: + g_value_set_string ( + value, + e_attachment_bar_get_current_folder ( + E_ATTACHMENT_BAR (object))); + return; + + case PROP_EDITABLE: + g_value_set_boolean ( + value, + e_attachment_bar_get_editable ( + E_ATTACHMENT_BAR (object))); + return; + + case PROP_UI_MANAGER: + g_value_set_object ( + value, + e_attachment_bar_get_ui_manager ( + E_ATTACHMENT_BAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_bar_dispose (GObject *object) +{ + EAttachmentBarPrivate *priv; + guint ii; + + priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); + + priv->batch_unref = TRUE; + + for (ii = 0; ii < priv->attachments->len; ii++) { + EAttachment *attachment; + + attachment = priv->attachments->pdata[ii]; + g_object_weak_unref ( + G_OBJECT (attachment), (GWeakNotify) + attachment_destroy, object); + g_object_unref (attachment); + } + g_ptr_array_set_size (priv->attachments, 0); + + if (priv->ui_manager != NULL) { + g_object_unref (priv->ui_manager); + priv->ui_manager = NULL; + } + + if (priv->standard_actions != NULL) { + g_object_unref (priv->standard_actions); + priv->standard_actions = NULL; + } + + if (priv->editable_actions != NULL) { + g_object_unref (priv->editable_actions); + priv->editable_actions = NULL; + } + + if (priv->open_actions != NULL) { + g_object_unref (priv->open_actions); + priv->open_actions = NULL; + } + + /* Chain up to parent's dipose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_bar_finalize (GObject *object) +{ + EAttachmentBarPrivate *priv; + + priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); + + g_ptr_array_free (priv->attachments, TRUE); + g_free (priv->current_folder); + g_free (priv->path); + + g_free (priv->background_filename); + g_free (priv->background_options); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +attachment_bar_constructed (GObject *object) +{ + EAttachmentBarPrivate *priv; + GtkActionGroup *action_group; + GConfBridge *bridge; + const gchar *prop; + const gchar *key; + + priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); + action_group = priv->editable_actions; + bridge = gconf_bridge_get (); + + e_mutual_binding_new ( + G_OBJECT (object), "editable", + G_OBJECT (action_group), "visible"); + + prop = "background-filename"; + key = "/desktop/gnome/background/picture_filename"; + gconf_bridge_bind_property (bridge, key, object, prop); + + prop = "background-options"; + key = "/desktop/gnome/background/picture_options"; + gconf_bridge_bind_property (bridge, key, object, prop); +} + +static gboolean +attachment_bar_event (GtkWidget *widget, + GdkEvent *event) { - struct _EAttachmentBarPrivate *priv = bar->priv; + EAttachment *attachment; + gboolean ret = FALSE; + gpointer parent; + CamelURL *url; + char *path; + GSList *p; + + if (event->type != GDK_2BUTTON_PRESS) + return FALSE; + + parent = gtk_widget_get_toplevel (widget); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + p = e_attachment_bar_get_selected (E_ATTACHMENT_BAR (widget)); + /* check if has body already, remote files can take longer to fetch */ + if (p && p->next == NULL && e_attachment_get_mime_part (p->data) != NULL) { + attachment = p->data; + + /* Check if the file is stored already */ + if (!attachment->store_uri) { + path = temp_save_part (attachment, TRUE); + url = camel_url_new ("file://", NULL); + camel_url_set_path (url, path); + attachment->store_uri = camel_url_to_string (url, 0); + camel_url_free (url); + g_free (path); + } + + e_show_uri (parent, attachment->store_uri); + + ret = TRUE; + } + + g_slist_foreach (p, (GFunc) g_object_unref, NULL); + g_slist_free (p); + + return ret; +} + +static gboolean +attachment_bar_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + GnomeIconList *icon_list; + GList *selected, *tmp; + int length, icon_number; + gboolean take_selected = FALSE; + + GtkTargetEntry drag_types[] = { + { "text/uri-list", 0, 0 }, + }; + + icon_list = GNOME_ICON_LIST (widget); + selected = gnome_icon_list_get_selection (icon_list); + length = g_list_length (selected); + + icon_number = gnome_icon_list_get_icon_at ( + icon_list, event->x, event->y); + if (icon_number < 0) { + /* When nothing is selected, deselect all */ + gnome_icon_list_unselect_all (icon_list); + length = 0; + selected = NULL; + } + + if (event->button == 1) { + /* If something is selected, then allow drag or else help to select */ + if (length) + gtk_drag_source_set ( + widget, GDK_BUTTON1_MASK, drag_types, + G_N_ELEMENTS (drag_types), GDK_ACTION_COPY); + else + gtk_drag_source_unset (widget); + goto exit; + } + + /* If not r-click dont progress any more.*/ + if (event->button != 3) + goto exit; + + /* When a r-click on something, if it is in the already selected list, consider a r-click of multiple things + * or deselect all and select only this for r-click + */ + if (icon_number >= 0) { + for (tmp = selected; tmp; tmp = tmp->next) { + if (GPOINTER_TO_INT (tmp->data) == icon_number) + take_selected = TRUE; + } + + if (!take_selected) { + gnome_icon_list_unselect_all (icon_list); + gnome_icon_list_select_icon (icon_list, icon_number); + } + } + + attachment_bar_show_popup_menu (E_ATTACHMENT_BAR (widget), event); + +exit: + /* Chain up to parent's button_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_press_event (widget, event); +} + +static gboolean +attachment_bar_button_release_event (GtkWidget *widget, + GdkEventButton *event) +{ + GnomeIconList *icon_list; + GList *selected; + + GtkTargetEntry drag_types[] = { + { "text/uri-list", 0, 0 }, + }; + + if (event->button != 1) + goto exit; + + icon_list = GNOME_ICON_LIST (widget); + selected = gnome_icon_list_get_selection (icon_list); + + if (selected != NULL) + gtk_drag_source_set ( + widget, GDK_BUTTON1_MASK, drag_types, + G_N_ELEMENTS (drag_types), GDK_ACTION_COPY); + else + gtk_drag_source_unset (widget); + +exit: + /* Chain up to parent's button_release_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_release_event (widget, event); +} + +static gboolean +attachment_bar_key_press_event (GtkWidget *widget, + GdkEventKey *event) +{ + EAttachmentBar *attachment_bar; + gboolean editable; + + attachment_bar = E_ATTACHMENT_BAR (widget); + editable = e_attachment_bar_get_editable (attachment_bar); + + if (editable && event->keyval == GDK_Delete) { + GtkActionGroup *action_group; + GtkAction *action; + + action_group = attachment_bar->priv->editable_actions; + action = gtk_action_group_get_action (action_group, "remove"); + gtk_action_activate (action); + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + key_press_event (widget, event); +} + +static void +attachment_bar_drag_data_get (GtkWidget *widget, + GdkDragContext *drag, + GtkSelectionData *data, + guint info, + guint time) +{ + EAttachmentBarPrivate *priv; EAttachment *attachment; char *path, **uris; int len, n, i = 0; @@ -865,7 +1291,8 @@ eab_drag_data_get(EAttachmentBar *bar, GdkDragContext *drag, GtkSelectionData *d if (info) return; - items = gnome_icon_list_get_selection (GNOME_ICON_LIST (bar)); + priv = E_ATTACHMENT_BAR_GET_PRIVATE (widget); + items = gnome_icon_list_get_selection (GNOME_ICON_LIST (widget)); len = g_list_length (items); uris = g_malloc0 (sizeof (char *) * (len + 1)); @@ -885,7 +1312,7 @@ eab_drag_data_get(EAttachmentBar *bar, GdkDragContext *drag, GtkSelectionData *d } /* If we are not able to save, ignore it */ - if (!(path = temp_save_part (attachment->body, FALSE))) + if (!(path = temp_save_part (attachment, FALSE))) continue; url = camel_url_new ("file://", NULL); @@ -902,227 +1329,280 @@ eab_drag_data_get(EAttachmentBar *bar, GdkDragContext *drag, GtkSelectionData *d gtk_selection_data_set_uris (data, uris); g_free (uris); - - return; } static gboolean -eab_button_release_event(EAttachmentBar *bar, GdkEventButton *event, gpointer dummy) +attachment_bar_popup_menu (GtkWidget *widget) { - GnomeIconList *icon_list = GNOME_ICON_LIST(bar); - GList *selected; - int length; - GtkTargetEntry drag_types[] = { - { "text/uri-list", 0, 0 }, - }; - - if (event && event->button == 1) { - selected = gnome_icon_list_get_selection(icon_list); - length = g_list_length (selected); - if (length) - gtk_drag_source_set((GtkWidget *)bar, GDK_BUTTON1_MASK, drag_types, G_N_ELEMENTS(drag_types), GDK_ACTION_COPY); - else - gtk_drag_source_unset((GtkWidget *)bar); - } + attachment_bar_show_popup_menu (E_ATTACHMENT_BAR (widget), NULL); - return FALSE; + return TRUE; } -static gboolean -eab_button_press_event(EAttachmentBar *bar, GdkEventButton *event, gpointer dummy) +static void +attachment_bar_update_actions (EAttachmentBar *attachment_bar) { - GnomeIconList *icon_list = GNOME_ICON_LIST(bar); - GList *selected = NULL, *tmp; - int length, icon_number; - gboolean take_selected = FALSE; - GtkTargetEntry drag_types[] = { - { "text/uri-list", 0, 0 }, - }; + GnomeIconList *icon_list; + CamelMimePart *mime_part; + GtkUIManager *ui_manager; + GtkActionGroup *action_group; + GtkAction *action; + GList *selection; + guint n_selected; + gboolean is_image; + gpointer parent; + guint merge_id; - selected = gnome_icon_list_get_selection(icon_list); - length = g_list_length (selected); + icon_list = GNOME_ICON_LIST (attachment_bar); + selection = gnome_icon_list_get_selection (icon_list); + n_selected = g_list_length (selection); - if (event) { - icon_number = gnome_icon_list_get_icon_at(icon_list, event->x, event->y); - if (icon_number < 0) { - /* When nothing is selected, deselect all */ - gnome_icon_list_unselect_all (icon_list); - length = 0; - selected = NULL; - } + parent = gtk_widget_get_toplevel (GTK_WIDGET (attachment_bar)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - if (event->button == 1) { - /* If something is selected, then allow drag or else help to select */ - if (length) - gtk_drag_source_set((GtkWidget *)bar, GDK_BUTTON1_MASK, drag_types, G_N_ELEMENTS(drag_types), GDK_ACTION_COPY); - else - gtk_drag_source_unset((GtkWidget *)bar); - return FALSE; - } + is_image = FALSE; + mime_part = NULL; - /* If not r-click dont progress any more.*/ - if (event->button != 3) - return FALSE; - - /* When a r-click on something, if it is in the already selected list, consider a r-click of multiple things - * or deselect all and select only this for r-click - */ - if (icon_number >= 0) { - for (tmp = selected; tmp; tmp = tmp->next) { - if (GPOINTER_TO_INT(tmp->data) == icon_number) - take_selected = TRUE; - } + if (n_selected == 1) { + GPtrArray *array; + EAttachment *attachment; + gint index; - if (!take_selected) { - gnome_icon_list_unselect_all(icon_list); - gnome_icon_list_select_icon(icon_list, icon_number); - } - } + array = attachment_bar->priv->attachments; + index = GPOINTER_TO_INT (selection->data); + attachment = E_ATTACHMENT (array->pdata[index]); + mime_part = e_attachment_get_mime_part (attachment); + is_image = e_attachment_is_image (attachment); } - return FALSE; -} - -static gboolean -eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) -{ - EAttachment *attachment; - gboolean ret = FALSE; - CamelURL *url; - char *path; - GSList *p; + ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - if (E_IS_ATTACHMENT_BAR (bar) && event->type == GDK_2BUTTON_PRESS) { - p = e_attachment_bar_get_selected (bar); - /* check if has body already, remote files can take longer to fetch */ - if (p && p->next == NULL && ((EAttachment *)p->data)->body) { - attachment = p->data; - - /* Check if the file is stored already */ - if (!attachment->store_uri) { - path = temp_save_part (attachment->body, TRUE); - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, path); - attachment->store_uri = camel_url_to_string (url, 0); - camel_url_free (url); - g_free (path); - } + action_group = attachment_bar->priv->standard_actions; - /* FIXME Pass a parent window. */ - e_show_uri (NULL, attachment->store_uri); + action = gtk_action_group_get_action (action_group, "save-as"); + gtk_action_set_visible (action, n_selected > 0); - ret = TRUE; - } + action = gtk_action_group_get_action (action_group, "set-background"); + gtk_action_set_visible (action, is_image); - if (p) { - g_slist_foreach (p, (GFunc) g_object_unref, NULL); - g_slist_free (p); - } - } + action_group = attachment_bar->priv->editable_actions; - return ret; -} - -/* Initialization. */ + action = gtk_action_group_get_action (action_group, "properties"); + gtk_action_set_visible (action, n_selected == 1); -static void -class_init (EAttachmentBarClass *klass) -{ - GtkObjectClass *object_class; + action = gtk_action_group_get_action (action_group, "remove"); + gtk_action_set_visible (action, n_selected > 0); - object_class = GTK_OBJECT_CLASS (klass); + action_group = attachment_bar->priv->open_actions; - parent_class = g_type_class_ref (gnome_icon_list_get_type ()); + merge_id = attachment_bar->priv->merge_id; + gtk_ui_manager_remove_ui (ui_manager, merge_id); + e_action_group_remove_all_actions (action_group); - object_class->destroy = destroy; + if (mime_part == NULL) + return; - /* Setup signals. */ + e_mime_part_utils_add_open_actions ( + mime_part, ui_manager, action_group, + "/attachment-popup/open-actions", parent, merge_id); +} - signals[CHANGED] = - g_signal_new ("changed", - E_TYPE_ATTACHMENT_BAR, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EAttachmentBarClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); +static void +attachment_bar_class_init (EAttachmentBarClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentBarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_bar_set_property; + object_class->get_property = attachment_bar_get_property; + object_class->dispose = attachment_bar_dispose; + object_class->finalize = attachment_bar_finalize; + object_class->constructed = attachment_bar_constructed; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->event = attachment_bar_event; + widget_class->button_press_event = attachment_bar_button_press_event; + widget_class->button_release_event = attachment_bar_button_release_event; + widget_class->key_press_event = attachment_bar_key_press_event; + widget_class->drag_data_get = attachment_bar_drag_data_get; + widget_class->popup_menu = attachment_bar_popup_menu; + + class->update_actions = attachment_bar_update_actions; + + g_object_class_install_property ( + object_class, + PROP_BACKGROUND_FILENAME, + g_param_spec_string ( + "background-filename", + "Background Filename", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_BACKGROUND_OPTIONS, + g_param_spec_string ( + "background-options", + "Background Options", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_CURRENT_FOLDER, + g_param_spec_string ( + "current-folder", + "Current Folder", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_EDITABLE, + g_param_spec_boolean ( + "editable", + "Editable", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_UI_MANAGER, + g_param_spec_object ( + "ui-manager", + "UI Manager", + NULL, + GTK_TYPE_UI_MANAGER, + G_PARAM_READABLE)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAttachmentBarClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[UPDATE_ACTIONS] = g_signal_new ( + "update-actions", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EAttachmentBarClass, update_actions), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -init (EAttachmentBar *bar) +attachment_bar_init (EAttachmentBar *bar) { - struct _EAttachmentBarPrivate *priv; + GnomeIconList *icon_list; + GtkUIManager *ui_manager; + GtkActionGroup *action_group; + gint icon_width, window_height; + const gchar *domain = GETTEXT_PACKAGE; + GError *error = NULL; + + bar->priv = E_ATTACHMENT_BAR_GET_PRIVATE (bar); + bar->priv->attachments = g_ptr_array_new (); + + GTK_WIDGET_SET_FLAGS (bar, GTK_CAN_FOCUS); + + icon_list = GNOME_ICON_LIST (bar); - priv = g_new (struct _EAttachmentBarPrivate, 1); + calculate_height_width (bar, &icon_width, &window_height); + gnome_icon_list_construct (icon_list, icon_width, NULL, 0); - priv->attach = NULL; - priv->batch_unref = FALSE; - priv->attachments = g_ptr_array_new (); + gtk_widget_set_size_request ( + GTK_WIDGET (bar), icon_width * 4, window_height); - priv->path = NULL; + atk_object_set_name ( + gtk_widget_get_accessible (GTK_WIDGET (bar)), + _("Attachment Bar")); - bar->priv = priv; - bar->expand = FALSE; + gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS); + gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING); + gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING); + gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); + gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); + gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); + + ui_manager = gtk_ui_manager_new (); + bar->priv->ui_manager = ui_manager; + bar->priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); + + action_group = gtk_action_group_new ("standard"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), bar); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + bar->priv->standard_actions = action_group; + + action_group = gtk_action_group_new ("editable"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_action_group_add_actions ( + action_group, editable_entries, + G_N_ELEMENTS (editable_entries), bar); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + bar->priv->editable_actions = action_group; + + action_group = gtk_action_group_new ("open"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + bar->priv->open_actions = action_group; + + /* Because we are loading from a hard-coded string, there is + * no chance of I/O errors. Failure here imples a malformed + * UI definition. Full stop. */ + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + if (error != NULL) + g_error ("%s", error->message); } - GType e_attachment_bar_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { sizeof (EAttachmentBarClass), - NULL, NULL, - (GClassInitFunc) class_init, - NULL, NULL, + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_bar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ sizeof (EAttachmentBar), - 0, - (GInstanceInitFunc) init, + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_bar_init, + NULL /* value_table */ }; - type = g_type_register_static (GNOME_TYPE_ICON_LIST, "EAttachmentBar", &info, 0); + type = g_type_register_static ( + GNOME_TYPE_ICON_LIST, "EAttachmentBar", &type_info, 0); } return type; } GtkWidget * -e_attachment_bar_new (GtkAdjustment *adj) +e_attachment_bar_new (void) { - EAttachmentBar *new; - GnomeIconList *icon_list; - int icon_width, window_height; - - new = g_object_new (e_attachment_bar_get_type (), NULL); - - icon_list = GNOME_ICON_LIST (new); - - calculate_height_width (new, &icon_width, &window_height); - - gnome_icon_list_construct (icon_list, icon_width, adj, 0); - - gtk_widget_set_size_request (GTK_WIDGET (new), icon_width * 4, window_height); - - GTK_WIDGET_SET_FLAGS (new, GTK_CAN_FOCUS); - - gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS); - gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING); - gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING); - gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); - gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); - gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); - - atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (new)), - _("Attachment Bar")); - - g_signal_connect (new, "button_release_event", G_CALLBACK(eab_button_release_event), NULL); - g_signal_connect (new, "button_press_event", G_CALLBACK(eab_button_press_event), NULL); - g_signal_connect (new, "drag-data-get", G_CALLBACK(eab_drag_data_get), NULL); - g_signal_connect (icon_list, "event", G_CALLBACK (eab_icon_clicked_cb), NULL); - - return GTK_WIDGET (new); + return g_object_new (E_TYPE_ATTACHMENT_BAR, NULL); } static char * @@ -1159,12 +1639,14 @@ attach_to_multipart (CamelMultipart *multipart, { CamelContentType *content_type; CamelDataWrapper *content; + CamelMimePart *mime_part; - if (!attachment->body) + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part == NULL) return; - content_type = camel_mime_part_get_content_type (attachment->body); - content = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body)); + content_type = camel_mime_part_get_content_type (mime_part); + content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); if (!CAMEL_IS_MULTIPART (content)) { if (camel_content_type_is (content_type, "text", "*")) { @@ -1188,7 +1670,7 @@ attach_to_multipart (CamelMultipart *multipart, camel_object_unref (filter_stream); encoding = camel_mime_filter_bestenc_get_best_encoding (bestenc, CAMEL_BESTENC_8BIT); - camel_mime_part_set_encoding (attachment->body, encoding); + camel_mime_part_set_encoding (mime_part, encoding); if (encoding == CAMEL_TRANSFER_ENCODING_7BIT) { /* the text fits within us-ascii so this is safe */ @@ -1207,24 +1689,26 @@ attach_to_multipart (CamelMultipart *multipart, /* looks kinda nasty, but this is how ya have to do it */ camel_content_type_set_param (content_type, "charset", default_charset); type = camel_content_type_format (content_type); - camel_mime_part_set_content_type (attachment->body, type); + camel_mime_part_set_content_type (mime_part, type); g_free (type); g_free (buf); } camel_object_unref (bestenc); } else if (!CAMEL_IS_MIME_MESSAGE (content)) { - camel_mime_part_set_encoding (attachment->body, CAMEL_TRANSFER_ENCODING_BASE64); + camel_mime_part_set_encoding (mime_part, CAMEL_TRANSFER_ENCODING_BASE64); } } - camel_multipart_add_part (multipart, attachment->body); + camel_multipart_add_part (multipart, mime_part); } void -e_attachment_bar_to_multipart (EAttachmentBar *bar, CamelMultipart *multipart, const char *default_charset) +e_attachment_bar_to_multipart (EAttachmentBar *bar, + CamelMultipart *multipart, + const gchar *default_charset) { - struct _EAttachmentBarPrivate *priv; + EAttachmentBarPrivate *priv; EAttachment *attachment; int i; @@ -1249,32 +1733,73 @@ e_attachment_bar_get_num_attachments (EAttachmentBar *bar) } void -e_attachment_bar_attach (EAttachmentBar *bar, const char *file_name, const char *disposition) +e_attachment_bar_attach (EAttachmentBar *bar, + const gchar *filename, + const gchar *disposition) { + EAttachment *attachment; + CamelException ex; + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (file_name != NULL && disposition != NULL); + g_return_if_fail (filename != NULL); + g_return_if_fail (disposition != NULL); + + camel_exception_init (&ex); + + attachment = e_attachment_new (filename, disposition, &ex); - add_from_file (bar, file_name, disposition); + if (attachment != NULL) + e_attachment_bar_add_attachment (bar, attachment); + else { + GtkWidget *toplevel; + + /* FIXME: Avoid using error from mailer */ + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bar)); + e_error_run ( + GTK_WINDOW (toplevel), "mail-composer:no-attach", + filename, camel_exception_get_description (&ex), NULL); + camel_exception_clear (&ex); + } } void -e_attachment_bar_add_attachment (EAttachmentBar *bar, EAttachment *attachment) +e_attachment_bar_add_attachment (EAttachmentBar *bar, + EAttachment *attachment) { g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_ptr_array_add (bar->priv->attachments, attachment); - add_common (bar, attachment); + g_object_weak_ref ( + G_OBJECT (attachment), (GWeakNotify) + attachment_destroy, bar); + + g_signal_connect_swapped ( + attachment, "changed", + G_CALLBACK (e_attachment_bar_refresh), bar); + + e_attachment_bar_refresh (bar); + + g_signal_emit (bar, signals[CHANGED], 0); } void -e_attachment_bar_add_attachment_silent (EAttachmentBar *bar, EAttachment *attachment) +e_attachment_bar_add_attachment_silent (EAttachmentBar *bar, + EAttachment *attachment) { g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (attachment != NULL); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_ptr_array_add (bar->priv->attachments, attachment); - g_object_weak_ref ((GObject *) attachment, (GWeakNotify) attachment_destroy, bar); - g_signal_connect (attachment, "changed", G_CALLBACK (attachment_changed_cb), bar); + g_object_weak_ref ( + G_OBJECT (attachment), (GWeakNotify) + attachment_destroy, bar); + + g_signal_connect_swapped ( + attachment, "changed", + G_CALLBACK (e_attachment_bar_refresh), bar); g_signal_emit (bar, signals[CHANGED], 0); } @@ -1282,13 +1807,180 @@ e_attachment_bar_add_attachment_silent (EAttachmentBar *bar, EAttachment *attach void e_attachment_bar_refresh (EAttachmentBar *bar) { - update (bar); + EAttachmentBarPrivate *priv; + GnomeIconList *icon_list; + int bar_width, bar_height; + int i; + + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); + + priv = bar->priv; + icon_list = GNOME_ICON_LIST (bar); + + gnome_icon_list_freeze (icon_list); + + gnome_icon_list_clear (icon_list); + + /* FIXME could be faster, but we don't care. */ + for (i = 0; i < priv->attachments->len; i++) { + EAttachment *attachment; + CamelContentType *content_type; + CamelMimePart *mime_part; + char *size_string, *label; + GdkPixbuf *pixbuf = NULL; + const char *desc; + + attachment = priv->attachments->pdata[i]; + mime_part = e_attachment_get_mime_part (attachment); + + if (!attachment->is_available_local || mime_part == NULL) { + if ((pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG))) { + attachment->index = gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, ""); + g_object_unref (pixbuf); + } + continue; + } + + content_type = camel_mime_part_get_content_type (mime_part); + /* Get the image out of the attachment + and create a thumbnail for it */ + pixbuf = e_attachment_get_thumbnail (attachment); + if (pixbuf != NULL) + g_object_ref (pixbuf); + else if (camel_content_type_is(content_type, "image", "*")) { + CamelDataWrapper *wrapper; + CamelStreamMem *mstream; + GdkPixbufLoader *loader; + gboolean error = TRUE; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + mstream = (CamelStreamMem *) camel_stream_mem_new (); + + camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); + + /* Stream image into pixbuf loader */ + loader = gdk_pixbuf_loader_new (); + error = !gdk_pixbuf_loader_write (loader, mstream->buffer->data, mstream->buffer->len, NULL); + gdk_pixbuf_loader_close (loader, NULL); + + if (!error) { + /* The loader owns the reference. */ + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + + /* This returns a new GdkPixbuf. */ + pixbuf = scale_pixbuf (pixbuf); + e_attachment_set_thumbnail (attachment, pixbuf); + } else { + pixbuf = NULL; + g_warning ("GdkPixbufLoader Error"); + } + + /* Destroy everything */ + g_object_unref (loader); + camel_object_unref (mstream); + } else if (!bar->expand && (pixbuf = get_system_thumbnail (attachment, content_type))) { + /* This returns a new GdkPixbuf. */ + pixbuf = scale_pixbuf (pixbuf); + e_attachment_set_thumbnail (attachment, pixbuf); + } + + desc = camel_mime_part_get_description (mime_part); + if (desc == NULL || *desc == '\0') + desc = e_attachment_get_filename (attachment); + if (desc == NULL || *desc == '\0') + desc = camel_mime_part_get_filename (mime_part); + + if (!desc) + desc = _("attachment"); + + if (attachment->size && (size_string = g_format_size_for_display (attachment->size))) { + label = g_strdup_printf ("%s (%s)", desc, size_string); + g_free (size_string); + } else + label = g_strdup (desc); + + if (pixbuf == NULL) { + char *mime_type; + + mime_type = camel_content_type_simple (content_type); + pixbuf = e_icon_for_mime_type (mime_type, 48); + if (pixbuf == NULL) { + g_warning("cannot find icon for mime type %s (installation problem?)", mime_type); + pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG); + } + g_free (mime_type); + + /* remember this picture and use it later again */ + if (pixbuf) + e_attachment_set_thumbnail (attachment, pixbuf); + } + + if (pixbuf) { + GdkPixbuf *pixbuf_orig = pixbuf; + pixbuf = gdk_pixbuf_add_alpha (pixbuf_orig, TRUE, 255, 255, 255); + + /* gdk_pixbuf_add_alpha returns a newly allocated pixbuf, + free the original one. + */ + g_object_unref (pixbuf_orig); + + /* In case of a attachment bar, in a signed/encrypted part, display the status as a emblem*/ + if (attachment->sign) { + /* Show the signature status at the right-bottom.*/ + GdkPixbuf *sign = NULL; + int x, y; + + if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_BAD) + sign = e_icon_factory_get_icon ("stock_signature-bad", E_ICON_SIZE_MENU); + else if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_GOOD) + sign = e_icon_factory_get_icon ("stock_signature-ok", E_ICON_SIZE_MENU); + else + sign = e_icon_factory_get_icon ("stock_signature", E_ICON_SIZE_MENU); + + x = gdk_pixbuf_get_width (pixbuf) - 17; + y = gdk_pixbuf_get_height (pixbuf) - 17; + + gdk_pixbuf_copy_area (sign, 0, 0, 16, 16, pixbuf, x, y); + g_object_unref (sign); + } + + if (attachment->encrypt) { + /* Show the encryption status at the top left.*/ + GdkPixbuf *encrypt = e_icon_factory_get_icon ("stock_lock-ok", E_ICON_SIZE_MENU); + + gdk_pixbuf_copy_area (encrypt, 0, 0, 16, 16, pixbuf, 1, 1); + g_object_unref (encrypt); + } + + gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, label); + g_object_unref (pixbuf); + } + + g_free (label); + } + + gnome_icon_list_thaw (icon_list); + + /* Resize */ + if (bar->expand) { + gtk_widget_get_size_request ((GtkWidget *) bar, &bar_width, &bar_height); + + if (bar->priv->attachments->len) { + int per_col, rows, height, width; + + calculate_height_width(bar, &width, &height); + per_col = bar_width / width; + per_col = (per_col ? per_col : 1); + rows = (bar->priv->attachments->len + per_col -1) / per_col; + gtk_widget_set_size_request ((GtkWidget *) bar, bar_width, rows * height); + } + } } int e_attachment_bar_get_download_count (EAttachmentBar *bar) { - struct _EAttachmentBarPrivate *priv; + EAttachmentBarPrivate *priv; EAttachment *attachment; int i, n = 0; @@ -1306,68 +1998,57 @@ e_attachment_bar_get_download_count (EAttachmentBar *bar) } void -e_attachment_bar_attach_remote_file (EAttachmentBar *bar, const char *url, const char *disposition) +e_attachment_bar_attach_remote_file (EAttachmentBar *bar, + const gchar *url, + const gchar *disposition) { EAttachment *attachment; CamelException ex; - GtkWindow *parent; + GtkWidget *parent; g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - if (!bar->priv->path) + if (bar->priv->path == NULL) bar->priv->path = e_mkdtemp ("attach-XXXXXX"); - parent = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) bar); + parent = gtk_widget_get_toplevel (GTK_WIDGET (bar)); camel_exception_init (&ex); - if ((attachment = e_attachment_new_remote_file (parent, url, disposition, bar->priv->path, &ex))) { - add_common (bar, attachment); - g_signal_connect (attachment, "update", G_CALLBACK (update_remote_file), bar); + + attachment = e_attachment_new_remote_file ( + GTK_WINDOW (parent), url, disposition, bar->priv->path, &ex); + + if (attachment != NULL) { + e_attachment_bar_add_attachment (bar, attachment); + g_signal_connect ( + attachment, "update", + G_CALLBACK (update_remote_file), bar); } else { - e_error_run (parent, "mail-composer:no-attach", - url, camel_exception_get_description (&ex), NULL); + e_error_run ( + GTK_WINDOW (parent), "mail-composer:no-attach", + url, camel_exception_get_description (&ex), NULL); camel_exception_clear (&ex); } } void -e_attachment_bar_attach_mime_part (EAttachmentBar *bar, CamelMimePart *part) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - add_from_mime_part (bar, part); -} - -static void -action_recent_cb (GtkAction *action, - EAttachmentBar *attachment_bar) +e_attachment_bar_attach_mime_part (EAttachmentBar *bar, + CamelMimePart *part) { - GtkRecentChooser *chooser; - GFile *file; - gchar *uri; - - chooser = GTK_RECENT_CHOOSER (action); + EAttachment *attachment; - /* Wish: gtk_recent_chooser_get_current_file() */ - uri = gtk_recent_chooser_get_current_uri (chooser); - file = g_file_new_for_uri (uri); - g_free (uri); + /* XXX Is this function really worth keeping? */ - if (g_file_is_native (file)) - e_attachment_bar_attach ( - E_ATTACHMENT_BAR (attachment_bar), - g_file_get_path (file), "attachment"); - else - e_attachment_bar_attach_remote_file ( - E_ATTACHMENT_BAR (attachment_bar), - g_file_get_uri (file), "attachment"); + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); + g_return_if_fail (CAMEL_IS_MIME_PART (part)); - g_object_unref (file); + attachment = e_attachment_new_from_mime_part (part); + e_attachment_bar_add_attachment (bar, attachment); } GtkAction * -e_attachment_bar_recent_action_new (EAttachmentBar *bar, - const gchar *action_name, - const gchar *action_label) +e_attachment_bar_recent_action_new (EAttachmentBar *bar, + const gchar *action_name, + const gchar *action_label) { GtkAction *action; GtkRecentChooser *chooser; @@ -1392,3 +2073,148 @@ e_attachment_bar_recent_action_new (EAttachmentBar *bar, return action; } +gint +e_attachment_bar_file_chooser_dialog_run (EAttachmentBar *attachment_bar, + GtkWidget *dialog) +{ + GtkFileChooser *file_chooser; + gint response = GTK_RESPONSE_NONE; + const gchar *current_folder; + gboolean save_folder; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), response); + g_return_val_if_fail (GTK_IS_FILE_CHOOSER_DIALOG (dialog), response); + + file_chooser = GTK_FILE_CHOOSER (dialog); + current_folder = e_attachment_bar_get_current_folder (attachment_bar); + gtk_file_chooser_set_current_folder (file_chooser, current_folder); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + save_folder = + (response == GTK_RESPONSE_ACCEPT) || + (response == GTK_RESPONSE_OK) || + (response == GTK_RESPONSE_YES) || + (response == GTK_RESPONSE_APPLY); + + if (save_folder) { + gchar *folder; + + folder = gtk_file_chooser_get_current_folder (file_chooser); + e_attachment_bar_set_current_folder (attachment_bar, folder); + g_free (folder); + } + + return response; +} + +void +e_attachment_bar_update_actions (EAttachmentBar *attachment_bar) +{ + g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); + + g_signal_emit (attachment_bar, signals[UPDATE_ACTIONS], 0); +} + +const gchar * +e_attachment_bar_get_background_filename (EAttachmentBar *attachment_bar) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + + return attachment_bar->priv->background_filename; +} + +void +e_attachment_bar_set_background_filename (EAttachmentBar *attachment_bar, + const gchar *background_filename) +{ + EAttachmentBarPrivate *priv; + + g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); + + if (background_filename == NULL) + background_filename = ""; + + priv = attachment_bar->priv; + g_free (priv->background_filename); + priv->background_filename = g_strdup (background_filename); + + g_object_notify (G_OBJECT (attachment_bar), "background-filename"); +} + +const gchar * +e_attachment_bar_get_background_options (EAttachmentBar *attachment_bar) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + + return attachment_bar->priv->background_options; +} + +void +e_attachment_bar_set_background_options (EAttachmentBar *attachment_bar, + const gchar *background_options) +{ + EAttachmentBarPrivate *priv; + + g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); + + if (background_options == NULL) + background_options = "none"; + + priv = attachment_bar->priv; + g_free (priv->background_options); + priv->background_options = g_strdup (background_options); + + g_object_notify (G_OBJECT (attachment_bar), "background-options"); +} + +const gchar * +e_attachment_bar_get_current_folder (EAttachmentBar *attachment_bar) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + + return attachment_bar->priv->current_folder; +} + +void +e_attachment_bar_set_current_folder (EAttachmentBar *attachment_bar, + const gchar *current_folder) +{ + + g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); + + if (current_folder == NULL) + current_folder = g_get_home_dir (); + + g_free (attachment_bar->priv->current_folder); + attachment_bar->priv->current_folder = g_strdup (current_folder); + + g_object_notify (G_OBJECT (attachment_bar), "current-folder"); +} + +gboolean +e_attachment_bar_get_editable (EAttachmentBar *attachment_bar) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), FALSE); + + return attachment_bar->priv->editable; +} + +void +e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, + gboolean editable) +{ + g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); + + attachment_bar->priv->editable = editable; + + g_object_notify (G_OBJECT (attachment_bar), "editable"); +} + +GtkUIManager * +e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + + return attachment_bar->priv->ui_manager; +} diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h index 363b7f0fb8..a55dcb11f6 100644 --- a/widgets/misc/e-attachment-bar.h +++ b/widgets/misc/e-attachment-bar.h @@ -21,8 +21,8 @@ * */ -#ifndef __E_ATTACHMENT_BAR_H__ -#define __E_ATTACHMENT_BAR_H__ +#ifndef E_ATTACHMENT_BAR_H +#define E_ATTACHMENT_BAR_H #include #include @@ -30,70 +30,107 @@ #include #include "e-attachment.h" -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - #define E_TYPE_ATTACHMENT_BAR \ (e_attachment_bar_get_type ()) #define E_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBar)) -#define E_ATTACHMENT_BAR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBar)) +#define E_ATTACHMENT_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) #define E_IS_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ATTACHMENT_BAR)) -#define E_IS_ATTACHMENT_BAR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ATTACHMENT_BAR)) + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_BAR)) +#define E_IS_ATTACHMENT_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_BAR)) +#define E_ATTACHMENT_BAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) + +G_BEGIN_DECLS typedef struct _EAttachmentBar EAttachmentBar; typedef struct _EAttachmentBarClass EAttachmentBarClass; +typedef struct _EAttachmentBarPrivate EAttachmentBarPrivate; struct _EAttachmentBar { GnomeIconList parent; gboolean expand; - - struct _EAttachmentBarPrivate *priv; + EAttachmentBarPrivate *priv; }; struct _EAttachmentBarClass { GnomeIconListClass parent_class; - void (* changed) (EAttachmentBar *bar); + /* Signals */ + void (*changed) (EAttachmentBar *bar); + void (*update_actions) (EAttachmentBar *bar); }; +GType e_attachment_bar_get_type (void); +GtkWidget * e_attachment_bar_new (void); +void e_attachment_bar_to_multipart (EAttachmentBar *bar, + CamelMultipart *multipart, + const gchar *default_charset); +guint e_attachment_bar_get_num_attachments + (EAttachmentBar *bar); +void e_attachment_bar_attach (EAttachmentBar *bar, + const gchar *filename, + const gchar *disposition); +void e_attachment_bar_attach_mime_part + (EAttachmentBar *bar, + CamelMimePart *part); +gint e_attachment_bar_get_download_count + (EAttachmentBar *bar); +void e_attachment_bar_attach_remote_file + (EAttachmentBar *bar, + const gchar *url, + const gchar *disposition); +GSList * e_attachment_bar_get_attachment (EAttachmentBar *bar, + gint id); +void e_attachment_bar_add_attachment (EAttachmentBar *bar, + EAttachment *attachment); +GSList * e_attachment_bar_get_parts (EAttachmentBar *bar); +GSList * e_attachment_bar_get_selected (EAttachmentBar *bar); +void e_attachment_bar_set_width (EAttachmentBar *bar, + gint bar_width); +GSList * e_attachment_bar_get_all_attachments + (EAttachmentBar *bar); +void e_attachment_bar_create_attachment_cache + (EAttachment *attachment); +GtkAction * e_attachment_bar_recent_action_new + (EAttachmentBar *bar, + const gchar *action_name, + const gchar *action_label); +void e_attachment_bar_add_attachment_silent + (EAttachmentBar *bar, + EAttachment *attachment); +void e_attachment_bar_refresh (EAttachmentBar *bar); +gint e_attachment_bar_file_chooser_dialog_run + (EAttachmentBar *attachment_bar, + GtkWidget *dialog); +void e_attachment_bar_update_actions (EAttachmentBar *attachment_bar); +const gchar * e_attachment_bar_get_background_filename + (EAttachmentBar *attachment_bar); +void e_attachment_bar_set_background_filename + (EAttachmentBar *attachment_bar, + const gchar *background_filename); +const gchar * e_attachment_bar_get_background_options + (EAttachmentBar *attachment_bar); +void e_attachment_bar_set_background_options + (EAttachmentBar *attachment_bar, + const gchar *background_options); +const gchar * e_attachment_bar_get_current_folder + (EAttachmentBar *attachment_bar); +void e_attachment_bar_set_current_folder + (EAttachmentBar *attachment_bar, + const gchar *current_folder); +gboolean e_attachment_bar_get_editable (EAttachmentBar *attachment_bar); +void e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, + gboolean editable); +GtkUIManager * e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar); -GType e_attachment_bar_get_type (void); - -GtkWidget *e_attachment_bar_new (GtkAdjustment *adj); -void e_attachment_bar_to_multipart (EAttachmentBar *bar, CamelMultipart *multipart, - const char *default_charset); -guint e_attachment_bar_get_num_attachments (EAttachmentBar *bar); -void e_attachment_bar_attach (EAttachmentBar *bar, const char *file_name, const char *disposition); -void e_attachment_bar_attach_mime_part (EAttachmentBar *bar, CamelMimePart *part); -int e_attachment_bar_get_download_count (EAttachmentBar *bar); -void e_attachment_bar_attach_remote_file (EAttachmentBar *bar, const char *url, const char *disposition); -GSList *e_attachment_bar_get_attachment (EAttachmentBar *bar, int id); -void e_attachment_bar_add_attachment (EAttachmentBar *bar, EAttachment *attachment); -void e_attachment_bar_edit_selected (EAttachmentBar *bar); -void e_attachment_bar_remove_selected (EAttachmentBar *bar); -GtkWidget ** e_attachment_bar_get_selector(EAttachmentBar *bar); -GSList *e_attachment_bar_get_parts (EAttachmentBar *bar); -GSList *e_attachment_bar_get_selected (EAttachmentBar *bar); -void e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width); -GSList * e_attachment_bar_get_all_attachments (EAttachmentBar *bar); -void e_attachment_bar_create_attachment_cache (EAttachment *attachment); -GtkAction * -e_attachment_bar_recent_action_new (EAttachmentBar *bar, - const gchar *action_name, - const gchar *action_label); -void -e_attachment_bar_add_attachment_silent (EAttachmentBar *bar, EAttachment *attachment); -void -e_attachment_bar_refresh (EAttachmentBar *bar); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS -#endif /* __E_ATTACHMENT_BAR_H__ */ +#endif /* E_ATTACHMENT_BAR_H */ diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c new file mode 100644 index 0000000000..0668a7358d --- /dev/null +++ b/widgets/misc/e-attachment-dialog.c @@ -0,0 +1,413 @@ +/* + * e-attachment-dialog.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-dialog.h" + +#include + +#define E_ATTACHMENT_DIALOG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogPrivate)) + +struct _EAttachmentDialogPrivate { + EAttachment *attachment; + GtkWidget *filename_entry; + GtkWidget *description_entry; + GtkWidget *mime_type_label; + GtkWidget *disposition_checkbox; +}; + +enum { + PROP_0, + PROP_ATTACHMENT +}; + +static gpointer parent_class; + +static void +attachment_dialog_update (EAttachmentDialog *dialog) +{ + EAttachment *attachment; + CamelMimePart *mime_part; + GtkWidget *widget; + gboolean sensitive; + const gchar *text; + gboolean active; + + /* XXX This is too complex. I shouldn't have to use the + * MIME part at all. */ + + attachment = e_attachment_dialog_get_attachment (dialog); + if (attachment != NULL) + mime_part = e_attachment_get_mime_part (attachment); + else + mime_part = NULL; + + sensitive = (attachment != NULL); + gtk_dialog_set_response_sensitive ( + GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); + + text = NULL; + if (attachment != NULL) + text = e_attachment_get_filename (attachment); + text = (text != NULL) ? text : ""; + widget = dialog->priv->filename_entry; + gtk_widget_set_sensitive (widget, sensitive); + gtk_entry_set_text (GTK_ENTRY (widget), text); + + text = NULL; + if (attachment != NULL) + text = e_attachment_get_description (attachment); + text = (text != NULL) ? text : ""; + widget = dialog->priv->description_entry; + gtk_widget_set_sensitive (widget, sensitive); + gtk_entry_set_text (GTK_ENTRY (widget), text); + + text = NULL; + if (attachment != NULL) + text = e_attachment_get_mime_type (attachment); + text = (text != NULL) ? text : ""; + widget = dialog->priv->mime_type_label; + gtk_label_set_text (GTK_LABEL (widget), text); + + active = FALSE; + if (mime_part != NULL) { + const gchar *disposition; + + disposition = camel_mime_part_get_disposition (mime_part); + active = (g_ascii_strcasecmp (disposition, "inline") == 0); + } else if (attachment != NULL) + active = e_attachment_is_inline (attachment); + widget = dialog->priv->disposition_checkbox; + gtk_widget_set_sensitive (widget, sensitive); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active); +} + +static void +attachment_dialog_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ATTACHMENT: + e_attachment_dialog_set_attachment ( + E_ATTACHMENT_DIALOG (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_dialog_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ATTACHMENT: + g_value_set_object ( + value, e_attachment_dialog_get_attachment ( + E_ATTACHMENT_DIALOG (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_dialog_dispose (GObject *object) +{ + EAttachmentDialogPrivate *priv; + + priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (object); + + if (priv->attachment != NULL) { + g_object_unref (priv->attachment); + priv->attachment = NULL; + } + + if (priv->filename_entry != NULL) { + g_object_unref (priv->filename_entry); + priv->filename_entry = NULL; + } + + if (priv->description_entry != NULL) { + g_object_unref (priv->description_entry); + priv->description_entry = NULL; + } + + if (priv->mime_type_label != NULL) { + g_object_unref (priv->mime_type_label); + priv->mime_type_label = NULL; + } + + if (priv->disposition_checkbox != NULL) { + g_object_unref (priv->disposition_checkbox); + priv->disposition_checkbox = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_dialog_map (GtkWidget *widget) +{ + GtkWidget *action_area; + GtkWidget *content_area; + + /* Chain up to parent's map() method. */ + GTK_WIDGET_CLASS (parent_class)->map (widget); + + /* XXX Override GtkDialog's broken style property defaults. */ + action_area = gtk_dialog_get_action_area (GTK_DIALOG (widget)); + content_area = gtk_dialog_get_content_area (GTK_DIALOG (widget)); + + gtk_box_set_spacing (GTK_BOX (content_area), 12); + gtk_container_set_border_width (GTK_CONTAINER (action_area), 0); + gtk_container_set_border_width (GTK_CONTAINER (content_area), 12); +} + +static void +attachment_dialog_response (GtkDialog *dialog, + gint response_id) +{ + EAttachmentDialogPrivate *priv; + EAttachment *attachment; + GtkToggleButton *button; + GtkEntry *entry; + const gchar *text; + gboolean active; + + if (response_id != GTK_RESPONSE_OK) + return; + + priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (dialog); + g_return_if_fail (priv->attachment != NULL); + attachment = priv->attachment; + + entry = GTK_ENTRY (priv->filename_entry); + text = gtk_entry_get_text (entry); + e_attachment_set_filename (attachment, text); + + entry = GTK_ENTRY (priv->description_entry); + text = gtk_entry_get_text (entry); + e_attachment_set_description (attachment, text); + + button = GTK_TOGGLE_BUTTON (priv->disposition_checkbox); + active = gtk_toggle_button_get_active (button); + text = active ? "inline" : "attachment"; + e_attachment_set_disposition (attachment, text); +} + +static void +attachment_dialog_class_init (EAttachmentDialogClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkDialogClass *dialog_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentDialogPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_dialog_set_property; + object_class->get_property = attachment_dialog_get_property; + object_class->dispose = attachment_dialog_dispose; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->map = attachment_dialog_map; + + dialog_class = GTK_DIALOG_CLASS (class); + dialog_class->response = attachment_dialog_response; + + g_object_class_install_property ( + object_class, + PROP_ATTACHMENT, + g_param_spec_object ( + "attachment", + "Attachment", + NULL, + E_TYPE_ATTACHMENT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); +} + +static void +attachment_dialog_init (EAttachmentDialog *dialog) +{ + GtkWidget *container; + GtkWidget *widget; + + dialog->priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (dialog); + + gtk_dialog_add_button ( + GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button ( + GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); + gtk_window_set_icon_name ( + GTK_WINDOW (dialog), "mail-attachment"); + gtk_window_set_title ( + GTK_WINDOW (dialog), _("Attachment Properties")); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + container = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + + widget = gtk_table_new (4, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (widget), 6); + gtk_table_set_row_spacings (GTK_TABLE (widget), 6); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); + gtk_table_attach ( + GTK_TABLE (container), widget, + 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); + dialog->priv->filename_entry = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new_with_mnemonic (_("_Filename:")); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_label_set_mnemonic_widget ( + GTK_LABEL (widget), dialog->priv->filename_entry); + gtk_table_attach ( + GTK_TABLE (container), widget, + 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + widget = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); + gtk_table_attach ( + GTK_TABLE (container), widget, + 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); + dialog->priv->description_entry = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new_with_mnemonic (_("_Description:")); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_label_set_mnemonic_widget ( + GTK_LABEL (widget), dialog->priv->description_entry); + gtk_table_attach ( + GTK_TABLE (container), widget, + 0, 1, 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_selectable (GTK_LABEL (widget), TRUE); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach ( + GTK_TABLE (container), widget, + 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); + dialog->priv->mime_type_label = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new (_("MIME Type:")); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_table_attach ( + GTK_TABLE (container), widget, + 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + widget = gtk_check_button_new_with_mnemonic ( + _("_Suggest automatic display of attachment")); + gtk_table_attach ( + GTK_TABLE (container), widget, + 0, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0); + dialog->priv->disposition_checkbox = g_object_ref (widget); + gtk_widget_show (widget); +} + +GType +e_attachment_dialog_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentDialogClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_dialog_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_init */ + sizeof (EAttachmentDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_dialog_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_DIALOG, "EAttachmentDialog", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_attachment_dialog_new (GtkWindow *parent, + EAttachment *attachment) +{ + if (parent != NULL) + g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); + if (attachment != NULL) + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + return g_object_new ( + E_TYPE_ATTACHMENT_DIALOG, + "transient-for", parent, "attachment", attachment, NULL); +} + +EAttachment * +e_attachment_dialog_get_attachment (EAttachmentDialog *dialog) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_DIALOG (dialog), NULL); + + return dialog->priv->attachment; +} + +void +e_attachment_dialog_set_attachment (EAttachmentDialog *dialog, + EAttachment *attachment) +{ + g_return_if_fail (E_IS_ATTACHMENT_DIALOG (dialog)); + + if (attachment != NULL) { + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_object_ref (attachment); + } + + if (dialog->priv->attachment != NULL) + g_object_unref (dialog->priv->attachment); + + dialog->priv->attachment = attachment; + + attachment_dialog_update (dialog); + + g_object_notify (G_OBJECT (dialog), "attachment"); +} diff --git a/widgets/misc/e-attachment-dialog.h b/widgets/misc/e-attachment-dialog.h new file mode 100644 index 0000000000..8e24e1840c --- /dev/null +++ b/widgets/misc/e-attachment-dialog.h @@ -0,0 +1,73 @@ +/* + * e-attachment-dialog.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_DIALOG_H +#define E_ATTACHMENT_DIALOG_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_DIALOG \ + (e_attachment_dialog_get_type ()) +#define E_ATTACHMENT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialog)) +#define E_ATTACHMENT_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogClass)) +#define E_IS_ATTACHMENT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_DIALOG)) +#define E_IS_ATTACHMENT_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_DIALOG)) +#define E_ATTACHMENT_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_DIALOG, EAttachmentDialogClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentDialog EAttachmentDialog; +typedef struct _EAttachmentDialogClass EAttachmentDialogClass; +typedef struct _EAttachmentDialogPrivate EAttachmentDialogPrivate; + +struct _EAttachmentDialog { + GtkDialog parent; + EAttachmentDialogPrivate *priv; +}; + +struct _EAttachmentDialogClass { + GtkDialogClass parent_class; +}; + +GType e_attachment_dialog_get_type (void); +GtkWidget * e_attachment_dialog_new (GtkWindow *parent, + EAttachment *attachment); +EAttachment * e_attachment_dialog_get_attachment + (EAttachmentDialog *dialog); +void e_attachment_dialog_set_attachment + (EAttachmentDialog *dialog, + EAttachment *attachment); + +G_END_DECLS + +#endif /* E_ATTACHMENT_DIALOG_H */ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 4f5e9ace34..9bb6f09ade 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -27,6 +27,9 @@ #include #endif +#include "e-attachment.h" +#include "e-attachment-dialog.h" + #ifdef G_OS_WIN32 /* Include early (as the gio stuff below will * include it anyway, sigh) to workaround the DATADIR problem. @@ -56,7 +59,27 @@ #include "e-util/e-mktemp.h" #include "e-util/e-util-private.h" -#include "e-attachment.h" +#define E_ATTACHMENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) + +struct _EAttachmentPrivate { + gchar *filename; + gchar *description; + gchar *disposition; + gchar *mime_type; + + GdkPixbuf *thumbnail; + CamelMimePart *mime_part; +}; + +enum { + PROP_0, + PROP_DESCRIPTION, + PROP_DISPOSITION, + PROP_FILENAME, + PROP_THUMBNAIL +}; enum { CHANGED, @@ -64,112 +87,207 @@ enum { LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; - -static GObjectClass *parent_class = NULL; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static void -changed (EAttachment *attachment) +attachment_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - g_signal_emit (attachment, signals[CHANGED], 0); + switch (property_id) { + case PROP_DESCRIPTION: + e_attachment_set_description ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_DISPOSITION: + e_attachment_set_disposition ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_FILENAME: + e_attachment_set_filename ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_THUMBNAIL: + e_attachment_set_thumbnail ( + E_ATTACHMENT (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } +static void +attachment_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DESCRIPTION: + g_value_set_string ( + value, e_attachment_get_description ( + E_ATTACHMENT (object))); + return; + + case PROP_DISPOSITION: + g_value_set_string ( + value, e_attachment_get_disposition ( + E_ATTACHMENT (object))); + return; + + case PROP_FILENAME: + g_value_set_string ( + value, e_attachment_get_filename ( + E_ATTACHMENT (object))); + return; + + case PROP_THUMBNAIL: + g_value_set_object ( + value, e_attachment_get_thumbnail ( + E_ATTACHMENT (object))); + return; + } -/* GtkObject methods. */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} static void -finalise (GObject *object) +attachment_dispose (GObject *object) { - EAttachment *attachment = (EAttachment *) object; - GtkWidget *dialog; + EAttachmentPrivate *priv; - if (attachment->editor_gui != NULL) { - dialog = glade_xml_get_widget (attachment->editor_gui, "dialog"); - g_signal_emit_by_name (dialog, "response", GTK_RESPONSE_CLOSE); - } + priv = E_ATTACHMENT_GET_PRIVATE (object); - if (attachment->is_available_local) { - camel_object_unref (attachment->body); - if (attachment->pixbuf_cache != NULL) - g_object_unref (attachment->pixbuf_cache); - } else { - if (attachment->cancellable) { - /* the operation is still running, so cancel it */ - g_cancellable_cancel (attachment->cancellable); - attachment->cancellable = NULL; - } - g_free (attachment->description); + if (priv->thumbnail != NULL) { + g_object_unref (priv->thumbnail); + priv->thumbnail = NULL; } - g_free (attachment->file_name); - g_free (attachment->store_uri); + if (priv->mime_part != NULL) { + camel_object_unref (priv->mime_part); + priv->mime_part = NULL; + } - G_OBJECT_CLASS (parent_class)->finalize (object); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } - -/* Signals. */ - static void -real_changed (EAttachment *attachment) +attachment_finalize (GObject *object) { - g_return_if_fail (E_IS_ATTACHMENT (attachment)); -} + EAttachment *attachment = (EAttachment *) object; -static void -real_update_attachment (EAttachment *attachment, char *msg) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); -} + if (attachment->cancellable) { + /* the operation is still running, so cancel it */ + g_cancellable_cancel (attachment->cancellable); + attachment->cancellable = NULL; + } + + g_free (attachment->store_uri); + + g_free (attachment->priv->filename); + g_free (attachment->priv->description); + g_free (attachment->priv->disposition); + g_free (attachment->priv->mime_type); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} static void -class_init (EAttachmentClass *klass) +attachment_class_init (EAttachmentClass *class) { GObjectClass *object_class; - object_class = (GObjectClass*) klass; - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->finalize = finalise; - klass->changed = real_changed; - klass->update = real_update_attachment; - - signals[CHANGED] = g_signal_new ("changed", - E_TYPE_ATTACHMENT, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[UPDATE] = g_signal_new ("update", - E_TYPE_ATTACHMENT, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, update), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_set_property; + object_class->get_property = attachment_get_property; + object_class->dispose = attachment_dispose; + object_class->finalize = attachment_finalize; + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "description", + "Description", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "disposition", + "Disposition", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "filename", + "Filename", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_THUMBNAIL, + g_param_spec_object ( + "thumbnail", + "Thumbnail Image", + NULL, + GDK_TYPE_PIXBUF, + G_PARAM_READWRITE)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EAttachmentClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[UPDATE] = g_signal_new ( + "update", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EAttachmentClass, update), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -init (EAttachment *attachment) +attachment_init (EAttachment *attachment) { - attachment->editor_gui = NULL; - attachment->body = NULL; - attachment->size = 0; - attachment->pixbuf_cache = NULL; + attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment); + attachment->index = -1; - attachment->file_name = NULL; attachment->percentage = -1; - attachment->description = NULL; - attachment->disposition = FALSE; attachment->sign = CAMEL_CIPHER_VALIDITY_SIGN_NONE; attachment->encrypt = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; - attachment->store_uri = NULL; - attachment->cancellable = NULL; } GType @@ -177,20 +295,22 @@ e_attachment_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { sizeof (EAttachmentClass), - NULL, - NULL, - (GClassInitFunc) class_init, - NULL, - NULL, + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ sizeof (EAttachment), - 0, - (GInstanceInitFunc) init, + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_init, + NULL /* value_table */ }; - type = g_type_register_static (G_TYPE_OBJECT, "EAttachment", &info, 0); + type = g_type_register_static ( + G_TYPE_OBJECT, "EAttachment", &type_info, 0); } return type; @@ -198,42 +318,42 @@ e_attachment_get_type (void) /** * file_ext_is: - * @param file_name: path for file + * @param filename: path for file * @param ext: desired extension, with a dot - * @return if file_name has extension ext or not + * @return if filename has extension ext or not **/ static gboolean -file_ext_is (const char *file_name, const char *ext) +file_ext_is (const char *filename, const char *ext) { int i, dot = -1; - if (!file_name || !ext) + if (!filename || !ext) return FALSE; - for (i = 0; file_name[i]; i++) { - if (file_name [i] == '.') + for (i = 0; filename[i]; i++) { + if (filename [i] == '.') dot = i; } if (dot > 0) { - return 0 == g_ascii_strcasecmp (file_name + dot, ext); + return 0 == g_ascii_strcasecmp (filename + dot, ext); } return FALSE; } static char * -attachment_guess_mime_type (const char *file_name) +attachment_guess_mime_type (const char *filename) { char *type; gchar *content = NULL; - type = e_util_guess_mime_type (file_name, TRUE); + type = e_util_guess_mime_type (filename, TRUE); if (type && strcmp (type, "text/directory") == 0 && - file_ext_is (file_name, ".vcf") && - g_file_get_contents (file_name, &content, NULL, NULL) && + file_ext_is (filename, ".vcf") && + g_file_get_contents (filename, &content, NULL, NULL) && content) { EVCard *vc = e_vcard_new_from_string (content); @@ -265,30 +385,30 @@ attachment_guess_mime_type (const char *file_name) /** * e_attachment_new: - * @file_name: filename to attach + * @filename: filename to attach * @disposition: Content-Disposition of the attachment * @ex: exception * * Return value: the new attachment, or %NULL on error **/ EAttachment * -e_attachment_new (const char *file_name, const char *disposition, CamelException *ex) +e_attachment_new (const char *filename, const char *disposition, CamelException *ex) { EAttachment *new; CamelMimePart *part; CamelDataWrapper *wrapper; CamelStream *stream; struct stat statbuf; - char *mime_type; - char *filename; + gchar *mime_type; + gchar *basename; CamelURL *url; - g_return_val_if_fail (file_name != NULL, NULL); + g_return_val_if_fail (filename != NULL, NULL); - if (g_stat (file_name, &statbuf) < 0) { + if (g_stat (filename, &statbuf) < 0) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return NULL; } @@ -296,18 +416,18 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException if (!S_ISREG (statbuf.st_mode)) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: not a regular file"), - file_name); + filename); return NULL; } - if (!(stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0))) { + if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return NULL; } - if ((mime_type = attachment_guess_mime_type (file_name))) { + if ((mime_type = attachment_guess_mime_type (filename))) { if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { wrapper = (CamelDataWrapper *) camel_mime_message_new (); } else { @@ -330,8 +450,8 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException camel_object_unref (wrapper); camel_mime_part_set_disposition (part, disposition); - filename = g_path_get_basename (file_name); - camel_mime_part_set_filename (part, filename); + basename = g_path_get_basename (filename); + camel_mime_part_set_filename (part, basename); #if 0 /* Note: Outlook 2002 is broken with respect to Content-Ids on @@ -344,17 +464,15 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException g_free (content_id); #endif - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; - new->body = part; + new = g_object_new (E_TYPE_ATTACHMENT, "filename", basename, NULL); + new->priv->mime_part = part; new->size = statbuf.st_size; new->guessed_type = TRUE; new->cancellable = NULL; new->is_available_local = TRUE; - new->file_name = filename; url = camel_url_new ("file://", NULL); - camel_url_set_path (url, file_name); + camel_url_set_path (url, filename); new->store_uri = camel_url_to_string (url, 0); camel_url_free (url); @@ -364,7 +482,7 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException typedef struct { EAttachment *attachment; - char *file_name; + char *filename; char *uri; GtkWindow *parent; /* for error dialog */ @@ -394,7 +512,7 @@ download_info_free (DownloadInfo *download_info) if (download_info->cancellable) g_object_unref (download_info->cancellable); - g_free (download_info->file_name); + g_free (download_info->filename); g_free (download_info->uri); g_free (download_info->buffer); g_free (download_info); @@ -450,7 +568,7 @@ data_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) download_info->attachment->cancellable = NULL; camel_exception_init (&ex); - e_attachment_build_remote_file (download_info->file_name, download_info->attachment, "attachment", &ex); + e_attachment_build_remote_file (download_info->filename, download_info->attachment, &ex); if (camel_exception_is_set (&ex)) { download_info->was_error = TRUE; @@ -482,7 +600,7 @@ download_to_local_path (DownloadInfo *download_info, CamelException *ex) { GError *error = NULL; GFile *src = g_file_new_for_uri (download_info->uri); - GFile *des = g_file_new_for_path (download_info->file_name); + GFile *des = g_file_new_for_path (download_info->filename); gboolean res = FALSE; g_return_val_if_fail (src != NULL && des != NULL, FALSE); @@ -538,6 +656,7 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons DownloadInfo *download_info; CamelURL *url; char *base; + gchar *filename; g_return_val_if_fail (uri != NULL, NULL); @@ -545,25 +664,26 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons base = g_path_get_basename (url->path); camel_url_free (url); - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; - new->body = NULL; + filename = g_build_filename (path, base, NULL); + + new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); new->size = 0; new->guessed_type = FALSE; new->cancellable = NULL; new->is_available_local = FALSE; new->percentage = 0; - new->file_name = g_build_filename (path, base, NULL); g_free (base); download_info = g_new0 (DownloadInfo, 1); download_info->attachment = new; - download_info->file_name = g_strdup (new->file_name); + download_info->filename = g_strdup (filename); download_info->uri = g_strdup (uri); download_info->parent = error_dlg_parent; download_info->was_error = FALSE; + g_free (filename); + /* it frees all on the error, so do not free it twice */ if (!download_to_local_path (download_info, ex)) return NULL; @@ -573,23 +693,27 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons void -e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, const char *disposition, CamelException *ex) +e_attachment_build_remote_file (const gchar *filename, + EAttachment *attachment, + CamelException *ex) { CamelMimePart *part; CamelDataWrapper *wrapper; CamelStream *stream; struct stat statbuf; - char *mime_type; - char *filename; + const gchar *description; + const gchar *disposition; + gchar *mime_type; + gchar *basename; CamelURL *url; - g_return_if_fail (file_name != NULL); + g_return_if_fail (filename != NULL); - if (g_stat (file_name, &statbuf) == -1) { + if (g_stat (filename, &statbuf) == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); - g_message ("Cannot attach file %s: %s\n", file_name, g_strerror (errno)); + filename, g_strerror (errno)); + g_message ("Cannot attach file %s: %s\n", filename, g_strerror (errno)); return; } @@ -597,19 +721,19 @@ e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, if (!S_ISREG (statbuf.st_mode)) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: not a regular file"), - file_name); - g_message ("Cannot attach file %s: not a regular file", file_name); + filename); + g_message ("Cannot attach file %s: not a regular file", filename); return; } - if (!(stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0))) { + if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return; } - if ((mime_type = attachment_guess_mime_type (file_name))) { + if ((mime_type = attachment_guess_mime_type (filename))) { if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { wrapper = (CamelDataWrapper *) camel_mime_message_new (); } else { @@ -631,36 +755,34 @@ e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); camel_object_unref (wrapper); - if (attachment->disposition) - camel_mime_part_set_disposition (part, "inline"); - else - camel_mime_part_set_disposition (part, "attachment"); + disposition = e_attachment_get_disposition (attachment); + camel_mime_part_set_disposition (part, disposition); - if (!attachment->file_name) - filename = g_path_get_basename (file_name); + if (e_attachment_get_filename (attachment) == NULL) + basename = g_path_get_basename (filename); else - filename = g_path_get_basename (attachment->file_name); + basename = g_path_get_basename (e_attachment_get_filename (attachment)); camel_mime_part_set_filename (part, filename); - if (attachment->description) { - camel_mime_part_set_description (part, attachment->description); - g_free (attachment->description); - attachment->description = NULL; + description = e_attachment_get_description (attachment); + if (description != NULL) { + camel_mime_part_set_description (part, description); + e_attachment_set_description (attachment, NULL); } - attachment->editor_gui = NULL; - attachment->body = part; + attachment->priv->mime_part = part; attachment->size = statbuf.st_size; attachment->guessed_type = TRUE; - g_free (attachment->file_name); - attachment->file_name = filename; + + e_attachment_set_filename (attachment, basename); url = camel_url_new ("file://", NULL); - camel_url_set_path (url, file_name); + camel_url_set_path (url, filename); attachment->store_uri = camel_url_to_string (url, 0); camel_url_free (url); + g_free (basename); } @@ -674,210 +796,231 @@ EAttachment * e_attachment_new_from_mime_part (CamelMimePart *part) { EAttachment *new; + const gchar *filename; g_return_val_if_fail (CAMEL_IS_MIME_PART (part), NULL); - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; + filename = camel_mime_part_get_filename (part); + + new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); camel_object_ref (part); - new->body = part; + new->priv->mime_part = part; new->guessed_type = FALSE; new->is_available_local = TRUE; new->size = camel_mime_part_get_content_size (part); - new->file_name = g_strdup (camel_mime_part_get_filename(part)); return new; } - -/* The attachment property dialog. */ - -typedef struct { +void +e_attachment_edit (EAttachment *attachment, + GtkWindow *parent) +{ GtkWidget *dialog; - GtkEntry *file_name_entry; - GtkEntry *description_entry; - GtkEntry *mime_type_entry; - GtkToggleButton *disposition_checkbox; - EAttachment *attachment; -} DialogData; -static void -destroy_dialog_data (DialogData *data) + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + dialog = e_attachment_dialog_new (parent, attachment); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +const gchar * +e_attachment_get_description (EAttachment *attachment) { - g_free (data); + CamelMimePart *mime_part; + const gchar *description; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + description = camel_mime_part_get_description (mime_part); + else + description = attachment->priv->description; + + return description; } -/* - * fixme: I am converting EVERYTHING to/from UTF-8, although mime types - * are in ASCII. This is not strictly necessary, but we want to be - * consistent and possibly check for errors somewhere. - */ +void +e_attachment_set_description (EAttachment *attachment, + const gchar *description) +{ + CamelMimePart *mime_part; -static void -set_entry (GladeXML *xml, const char *widget_name, const char *value) + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_free (attachment->priv->description); + attachment->priv->description = g_strdup (description); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_description (mime_part, description); + + g_object_notify (G_OBJECT (attachment), "description"); +} + +const gchar * +e_attachment_get_disposition (EAttachment *attachment) { - GtkEntry *entry; + CamelMimePart *mime_part; + const gchar *disposition; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - entry = GTK_ENTRY (glade_xml_get_widget (xml, widget_name)); - if (entry == NULL) - g_warning ("Entry for `%s' not found.", widget_name); + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + disposition = camel_mime_part_get_disposition (mime_part); else - gtk_entry_set_text (entry, value ? value : ""); + disposition = attachment->priv->disposition; + + return disposition; } -static void -connect_widget (GladeXML *gui, const char *name, const char *signal_name, - GCallback func, gpointer data) +void +e_attachment_set_disposition (EAttachment *attachment, + const gchar *disposition) { - GtkWidget *widget; + CamelMimePart *mime_part; - widget = glade_xml_get_widget (gui, name); - g_signal_connect (widget, signal_name, func, data); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_free (attachment->priv->disposition); + attachment->priv->disposition = g_strdup (disposition); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_disposition (mime_part, disposition); + + g_object_notify (G_OBJECT (attachment), "disposition"); } -static void -close_cb (GtkWidget *widget, gpointer data) +const gchar * +e_attachment_get_filename (EAttachment *attachment) { - EAttachment *attachment; - DialogData *dialog_data; + CamelMimePart *mime_part; + const gchar *filename; - dialog_data = (DialogData *) data; - attachment = dialog_data->attachment; + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - gtk_widget_destroy (dialog_data->dialog); - g_object_unref (attachment->editor_gui); - attachment->editor_gui = NULL; + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + filename = camel_mime_part_get_filename (mime_part); + else + filename = attachment->priv->filename; - destroy_dialog_data (dialog_data); + return filename; } -static void -ok_cb (GtkWidget *widget, gpointer data) +void +e_attachment_set_filename (EAttachment *attachment, + const gchar *filename) { - DialogData *dialog_data; - EAttachment *attachment; - const char *str; + CamelMimePart *mime_part; - dialog_data = (DialogData *) data; - attachment = dialog_data->attachment; + g_return_if_fail (E_IS_ATTACHMENT (attachment)); - str = gtk_entry_get_text (dialog_data->file_name_entry); - if (attachment->is_available_local) - camel_mime_part_set_filename (attachment->body, str); - g_free (attachment->file_name); - attachment->file_name = g_strdup (str); + g_free (attachment->priv->filename); + attachment->priv->filename = g_strdup (filename); - str = gtk_entry_get_text (dialog_data->description_entry); - if (attachment->is_available_local) { - camel_mime_part_set_description (attachment->body, str); - } else { - g_free (attachment->description); - attachment->description = g_strdup (str); - } + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_filename (mime_part, filename); - str = gtk_entry_get_text (dialog_data->mime_type_entry); - if (attachment->is_available_local) { - camel_mime_part_set_content_type (attachment->body, str); - camel_data_wrapper_set_mime_type(camel_medium_get_content_object(CAMEL_MEDIUM (attachment->body)), str); - } + g_object_notify (G_OBJECT (attachment), "filename"); +} - if (attachment->is_available_local) { - switch (gtk_toggle_button_get_active (dialog_data->disposition_checkbox)) { - case 0: - camel_mime_part_set_disposition (attachment->body, "attachment"); - break; - case 1: - camel_mime_part_set_disposition (attachment->body, "inline"); - break; - default: - /* Hmmmm? */ - break; - } - } else { - attachment->disposition = gtk_toggle_button_get_active (dialog_data->disposition_checkbox); +CamelMimePart * +e_attachment_get_mime_part (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + return attachment->priv->mime_part; +} + +const gchar * +e_attachment_get_mime_type (EAttachment *attachment) +{ + CamelContentType *content_type; + CamelMimePart *mime_part; + const gchar *filename; + gchar *mime_type; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + if (attachment->priv->mime_type != NULL) + goto exit; + + mime_part = e_attachment_get_mime_part (attachment); + filename = e_attachment_get_filename (attachment); + content_type = camel_mime_part_get_content_type (mime_part); + + if (mime_part == NULL) + mime_type = attachment_guess_mime_type (filename); + else { + content_type = camel_mime_part_get_content_type (mime_part); + mime_type = camel_content_type_simple (content_type); } - changed (attachment); - close_cb (widget, data); + attachment->priv->mime_type = mime_type; + +exit: + return attachment->priv->mime_type; } -static void -response_cb (GtkWidget *widget, gint response, gpointer data) +GdkPixbuf * +e_attachment_get_thumbnail (EAttachment *attachment) { - if (response == GTK_RESPONSE_OK) - ok_cb (widget, data); - else - close_cb (widget, data); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + return attachment->priv->thumbnail; } void -e_attachment_edit (EAttachment *attachment, GtkWidget *parent) +e_attachment_set_thumbnail (EAttachment *attachment, + GdkPixbuf *thumbnail) { - CamelContentType *content_type; - const char *disposition; - DialogData *dialog_data; - GladeXML *editor_gui; - GtkWidget *window; - char *type; - char *filename; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - if (attachment->editor_gui != NULL) { - window = glade_xml_get_widget (attachment->editor_gui, "dialog"); - gdk_window_show (window->window); - return; + if (thumbnail != NULL) { + g_return_if_fail (GDK_IS_PIXBUF (thumbnail)); + g_object_ref (thumbnail); } - filename = g_build_filename (EVOLUTION_GLADEDIR, "e-attachment.glade", NULL); - editor_gui = glade_xml_new (filename, NULL, NULL); - g_free (filename); + if (attachment->priv->thumbnail != NULL) + g_object_unref (attachment->priv->thumbnail); - if (editor_gui == NULL) { - g_warning ("Cannot load `e-attachment.glade'"); - return; - } + attachment->priv->thumbnail = thumbnail; - attachment->editor_gui = editor_gui; - - gtk_window_set_transient_for (GTK_WINDOW (glade_xml_get_widget (editor_gui, "dialog")), - GTK_WINDOW (gtk_widget_get_toplevel (parent))); - - dialog_data = g_new (DialogData, 1); - dialog_data->attachment = attachment; - dialog_data->dialog = glade_xml_get_widget (editor_gui, "dialog"); - dialog_data->file_name_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "file_name_entry")); - dialog_data->description_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "description_entry")); - dialog_data->mime_type_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "mime_type_entry")); - dialog_data->disposition_checkbox = GTK_TOGGLE_BUTTON (glade_xml_get_widget (editor_gui, "disposition_checkbox")); - - if (attachment->is_available_local && attachment->body) { - set_entry (editor_gui, "file_name_entry", camel_mime_part_get_filename (attachment->body)); - set_entry (editor_gui, "description_entry", camel_mime_part_get_description (attachment->body)); - content_type = camel_mime_part_get_content_type (attachment->body); - type = camel_content_type_simple (content_type); - set_entry (editor_gui, "mime_type_entry", type); - g_free (type); - - disposition = camel_mime_part_get_disposition (attachment->body); - gtk_toggle_button_set_active (dialog_data->disposition_checkbox, - disposition && !g_ascii_strcasecmp (disposition, "inline")); - } else { - set_entry (editor_gui, "file_name_entry", attachment->file_name); - set_entry (editor_gui, "description_entry", attachment->description); - if ((type = attachment_guess_mime_type (attachment->file_name))) { - set_entry (editor_gui, "mime_type_entry", type); - g_free (type); - } else { - set_entry (editor_gui, "mime_type_entry", ""); - } + g_object_notify (G_OBJECT (attachment), "thumbnail"); +} - gtk_toggle_button_set_active (dialog_data->disposition_checkbox, attachment->disposition); - } +gboolean +e_attachment_is_image (EAttachment *attachment) +{ + CamelContentType *content_type; + CamelMimePart *mime_part; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part == NULL) + return FALSE; + + content_type = camel_mime_part_get_content_type (mime_part); + + return camel_content_type_is (content_type, "image", "*"); +} + +gboolean +e_attachment_is_inline (EAttachment *attachment) +{ + const gchar *disposition; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - connect_widget (editor_gui, "dialog", "response", (GCallback)response_cb, dialog_data); + disposition = e_attachment_get_disposition (attachment); + g_return_val_if_fail (disposition != NULL, FALSE); - /* make sure that when the parent gets hidden/closed that our windows also close */ - parent = gtk_widget_get_toplevel (parent); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog_data->dialog), TRUE); + return (g_ascii_strcasecmp (disposition, "inline") == 0); } diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 7b45f24ae5..c69189c189 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -15,14 +15,14 @@ * * Authors: * Ettore Perazzoli - * Srinivasa Ragavan + * Srinivasa Ragavan * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef __E_ATTACHMENT_H__ -#define __E_ATTACHMENT_H__ +#ifndef E_ATTACHMENT_H +#define E_ATTACHMENT_H #include #include @@ -31,73 +31,91 @@ #include #include -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_ATTACHMENT (e_attachment_get_type ()) -#define E_ATTACHMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ATTACHMENT, EAttachment)) -#define E_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ATTACHMENT, EAttachmentClass)) -#define E_IS_ATTACHMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ATTACHMENT)) -#define E_IS_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ATTACHMENT)) - - -typedef struct _EAttachment EAttachment; -typedef struct _EAttachmentClass EAttachmentClass; +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT \ + (e_attachment_get_type ()) +#define E_ATTACHMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT, EAttachment)) +#define E_ATTACHMENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT, EAttachmentClass)) +#define E_IS_ATTACHMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT)) +#define E_IS_ATTACHMENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((obj), E_TYPE_ATTACHMENT)) +#define E_ATTACHMENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT, EAttachmentClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachment EAttachment; +typedef struct _EAttachmentClass EAttachmentClass; +typedef struct _EAttachmentPrivate EAttachmentPrivate; struct _EAttachment { GObject parent; - GladeXML *editor_gui; - - CamelMimePart *body; gboolean guessed_type; gulong size; - GdkPixbuf *pixbuf_cache; - GCancellable *cancellable; gboolean is_available_local; int percentage; - char *file_name; - char *description; - gboolean disposition; int index; char *store_uri; /* Status of signed/encrypted attachments */ camel_cipher_validity_sign_t sign; camel_cipher_validity_encrypt_t encrypt; + + EAttachmentPrivate *priv; }; struct _EAttachmentClass { GObjectClass parent_class; - void (*changed) (EAttachment *attachment); - void (*update) (EAttachment *attachment, char *msg); + void (*changed) (EAttachment *attachment); + void (*update) (EAttachment *attachment, + gchar *message); }; -GType e_attachment_get_type (void); -EAttachment *e_attachment_new (const char *file_name, - const char *disposition, - CamelException *ex); -EAttachment * e_attachment_new_remote_file (GtkWindow *error_dlg_parent, - const char *url, - const char *disposition, - const char *path, - CamelException *ex); -void e_attachment_build_remote_file (const char *filename, - EAttachment *attachment, - const char *disposition, - CamelException *ex); -EAttachment *e_attachment_new_from_mime_part (CamelMimePart *part); -void e_attachment_edit (EAttachment *attachment, - GtkWidget *parent); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_ATTACHMENT_H__ */ +GType e_attachment_get_type (void); +EAttachment * e_attachment_new (const gchar *filename, + const gchar *disposition, + CamelException *ex); +EAttachment * e_attachment_new_remote_file (GtkWindow *error_dlg_parent, + const gchar *url, + const gchar *disposition, + const gchar *path, + CamelException *ex); +void e_attachment_build_remote_file (const gchar *filename, + EAttachment *attachment, + CamelException *ex); +EAttachment * e_attachment_new_from_mime_part (CamelMimePart *part); +void e_attachment_edit (EAttachment *attachment, + GtkWindow *parent); +const gchar * e_attachment_get_description (EAttachment *attachment); +void e_attachment_set_description (EAttachment *attachment, + const gchar *description); +const gchar * e_attachment_get_disposition (EAttachment *attachment); +void e_attachment_set_disposition (EAttachment *attachment, + const gchar *disposition); +const gchar * e_attachment_get_filename (EAttachment *attachment); +void e_attachment_set_filename (EAttachment *attachment, + const gchar *filename); +CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment); +const gchar * e_attachment_get_mime_type (EAttachment *attachment); +GdkPixbuf * e_attachment_get_thumbnail (EAttachment *attachment); +void e_attachment_set_thumbnail (EAttachment *attachment, + GdkPixbuf *pixbuf); +gboolean e_attachment_is_image (EAttachment *attachment); +gboolean e_attachment_is_inline (EAttachment *attachment); + +G_END_DECLS + +#endif /* E_ATTACHMENT_H */ diff --git a/widgets/misc/e-mime-part-utils.c b/widgets/misc/e-mime-part-utils.c new file mode 100644 index 0000000000..3238ca93f5 --- /dev/null +++ b/widgets/misc/e-mime-part-utils.c @@ -0,0 +1,223 @@ +/* + * e-mime-part-utils.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-mime-part-utils.h" + +#include +#include +#include +#include + +#include "e-util/e-util.h" + +static void +mime_part_utils_open_in_cb (GtkAction *action, + CamelMimePart *mime_part) +{ + GtkWindow *parent; + GFile *file; + gchar *path; + gchar *uri; + gint fd; + GError *error = NULL; + + parent = g_object_get_data (G_OBJECT (action), "parent-window"); + + fd = e_file_open_tmp (&path, &error); + if (error != NULL) + goto fail; + + close (fd); + + file = g_file_new_for_path (path); + e_mime_part_utils_save_to_file (mime_part, file, &error); + g_free (path); + + if (error != NULL) { + g_object_unref (file); + goto fail; + } + + uri = g_file_get_uri (file); + e_show_uri (parent, uri); + g_free (uri); + + g_object_unref (file); + + return; + +fail: + g_warning ("%s", error->message); + g_error_free (error); +} + +GList * +e_mime_part_utils_get_apps (CamelMimePart *mime_part) +{ + GList *app_info_list; + const gchar *filename; + gchar *content_type; + gchar *mime_type; + gchar *cp; + + g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL); + + filename = camel_mime_part_get_filename (mime_part); + mime_type = camel_content_type_simple ( + camel_mime_part_get_content_type (mime_part)); + g_return_val_if_fail (mime_type != NULL, NULL); + + /* GIO expects lowercase MIME types. */ + for (cp = mime_type; *cp != '\0'; cp++) + *cp = g_ascii_tolower (*cp); + + content_type = g_content_type_from_mime_type (mime_type); + if (content_type != NULL) + app_info_list = g_app_info_get_all_for_type (content_type); + else + app_info_list = g_app_info_get_all_for_type (mime_type); + g_free (content_type); + + if (app_info_list != NULL || filename == NULL) + goto exit; + + if (strcmp (mime_type, "application/octet-stream") != 0) + goto exit; + + content_type = g_content_type_guess (filename, NULL, 0, NULL); + app_info_list = g_app_info_get_all_for_type (content_type); + g_free (content_type); + +exit: + g_free (mime_type); + + return app_info_list; +} + +gboolean +e_mime_part_utils_save_to_file (CamelMimePart *mime_part, + GFile *file, + GError **error) +{ + GFileOutputStream *output_stream; + CamelDataWrapper *content; + CamelStream *stream; + + g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), FALSE); + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + output_stream = g_file_replace ( + file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); + if (output_stream == NULL) + return FALSE; + + /* The CamelStream takes ownership of the GFileOutputStream. */ + content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + stream = camel_stream_vfs_new_with_stream (G_OBJECT (output_stream)); + + /* XXX Camel's streams are synchronous only, so we have to write + * the whole thing in one shot and hope it doesn't block the + * main loop for too long. */ + if (camel_data_wrapper_decode_to_stream (content, stream) < 0) + goto file_error; + + if (camel_stream_flush (stream) < 0) + goto file_error; + + camel_object_unref (stream); + + return TRUE; + +file_error: + g_set_error ( + error, G_FILE_ERROR, + g_file_error_from_errno (errno), + "%s", g_strerror (errno)); + + camel_object_unref (stream); + + return FALSE; +} + +void +e_mime_part_utils_add_open_actions (CamelMimePart *mime_part, + GtkUIManager *ui_manager, + GtkActionGroup *action_group, + const gchar *widget_path, + GtkWindow *parent, + guint merge_id) +{ + GList *app_info_list; + GList *iter; + + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager)); + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent)); + g_return_if_fail (widget_path != NULL); + + app_info_list = e_mime_part_utils_get_apps (mime_part); + + for (iter = app_info_list; iter != NULL; iter = iter->next) { + GAppInfo *app_info = iter->data; + GtkAction *action; + const gchar *app_executable; + const gchar *app_name; + gchar *action_tooltip; + gchar *action_label; + gchar *action_name; + + if (!g_app_info_should_show (app_info)) + continue; + + app_executable = g_app_info_get_executable (app_info); + app_name = g_app_info_get_name (app_info); + + action_name = g_strdup_printf ("open-in-%s", app_executable); + action_label = g_strdup_printf (_("Open in %s..."), app_name); + + action_tooltip = g_strdup_printf ( + _("Open this attachment in %s"), app_name); + + action = gtk_action_new ( + action_name, action_label, action_tooltip, NULL); + + g_object_set_data ( + G_OBJECT (action), "parent-window", parent); + + g_signal_connect ( + action, "activate", + G_CALLBACK (mime_part_utils_open_in_cb), mime_part); + + gtk_action_group_add_action (action_group, action); + + gtk_ui_manager_add_ui ( + ui_manager, merge_id, widget_path, action_name, + action_name, GTK_UI_MANAGER_AUTO, FALSE); + + g_free (action_name); + g_free (action_label); + g_free (action_tooltip); + } + + g_list_foreach (app_info_list, (GFunc) g_object_unref, NULL); + g_list_free (app_info_list); +} diff --git a/widgets/misc/e-mime-part-utils.h b/widgets/misc/e-mime-part-utils.h new file mode 100644 index 0000000000..e923e07c8d --- /dev/null +++ b/widgets/misc/e-mime-part-utils.h @@ -0,0 +1,46 @@ +/* + * e-mime-part-utils.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MIME_PART_UTILS_H +#define E_MIME_PART_UTILS_H + +#include +#include +#include + +G_BEGIN_DECLS + +GList * e_mime_part_utils_get_apps (CamelMimePart *mime_part); +gboolean e_mime_part_utils_save_to_file (CamelMimePart *mime_part, + GFile *file, + GError **error); + +void e_mime_part_utils_add_open_actions + (CamelMimePart *mime_part, + GtkUIManager *ui_manager, + GtkActionGroup *action_group, + const gchar *widget_path, + GtkWindow *parent, + guint merge_id); + +G_END_DECLS + +#endif /* E_MIME_PART_UTILS_H */ diff --git a/widgets/misc/e-timeout-activity.c b/widgets/misc/e-timeout-activity.c new file mode 100644 index 0000000000..d02bcf96d2 --- /dev/null +++ b/widgets/misc/e-timeout-activity.c @@ -0,0 +1,180 @@ +/* + * e-timeout-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-timeout-activity.h" + +#define E_TIMEOUT_ACTIVITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityPrivate)) + +struct _ETimeoutActivityPrivate { + guint timeout_id; +}; + +enum { + TIMEOUT, + LAST_SIGNAL +}; + +static gpointer parent_class; +static gulong signals[LAST_SIGNAL]; + +static gboolean +timeout_activity_cb (ETimeoutActivity *timeout_activity) +{ + g_signal_emit (timeout_activity, signals[TIMEOUT], 0); + + return FALSE; +} + +static void +timeout_activity_finalize (GObject *object) +{ + ETimeoutActivityPrivate *priv; + + priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (object); + + if (priv->timeout_id > 0) + g_source_remove (priv->timeout_id); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +timeout_activity_cancelled (EActivity *activity) +{ + ETimeoutActivityPrivate *priv; + + priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (activity); + + if (priv->timeout_id > 0) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + + /* Chain up to parent's cancelled() method. */ + E_ACTIVITY_CLASS (parent_class)->cancelled (activity); +} + +static void +timeout_activity_completed (EActivity *activity) +{ + ETimeoutActivityPrivate *priv; + + priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (activity); + + if (priv->timeout_id > 0) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + + /* Chain up to parent's completed() method. */ + E_ACTIVITY_CLASS (parent_class)->completed (activity); +} + +static void +timeout_activity_timeout (ETimeoutActivity *timeout_activity) +{ + /* Allow subclasses to safely chain up. */ +} + +static void +timeout_activity_class_init (ETimeoutActivityClass *class) +{ + GObjectClass *object_class; + EActivityClass *activity_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ETimeoutActivityPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = timeout_activity_finalize; + + activity_class = E_ACTIVITY_CLASS (class); + activity_class->cancelled = timeout_activity_cancelled; + activity_class->completed = timeout_activity_completed; + + class->timeout = timeout_activity_timeout; + + signals[TIMEOUT] = g_signal_new ( + "timeout", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ETimeoutActivityClass, timeout), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +timeout_activity_init (ETimeoutActivity *timeout_activity) +{ + timeout_activity->priv = + E_TIMEOUT_ACTIVITY_GET_PRIVATE (timeout_activity); +} + +GType +e_timeout_activity_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ETimeoutActivityClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) timeout_activity_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ETimeoutActivity), + 0, /* n_preallocs */ + (GInstanceInitFunc) timeout_activity_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ACTIVITY, "ETimeoutActivity", &type_info, 0); + } + + return type; +} + +EActivity * +e_timeout_activity_new (const gchar *primary_text) +{ + return g_object_new ( + E_TYPE_TIMEOUT_ACTIVITY, + "primary-text", primary_text, NULL); +} + +void +e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity, + guint seconds) +{ + g_return_if_fail (E_IS_TIMEOUT_ACTIVITY (timeout_activity)); + + if (timeout_activity->priv->timeout_id > 0) + e_activity_cancel (E_ACTIVITY (timeout_activity)); + + timeout_activity->priv->timeout_id = g_timeout_add_seconds ( + seconds, (GSourceFunc) timeout_activity_cb, timeout_activity); +} diff --git a/widgets/misc/e-timeout-activity.h b/widgets/misc/e-timeout-activity.h new file mode 100644 index 0000000000..70aaee7dcb --- /dev/null +++ b/widgets/misc/e-timeout-activity.h @@ -0,0 +1,71 @@ +/* + * e-timeout-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TIMEOUT_ACTIVITY_H +#define E_TIMEOUT_ACTIVITY_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_TIMEOUT_ACTIVITY \ + (e_timeout_activity_get_type ()) +#define E_TIMEOUT_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivity)) +#define E_TIMEOUT_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityClass)) +#define E_IS_TIMEOUT_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TIMEOUT_ACTIVITY)) +#define E_IS_TIMEOUT_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TIMEOUT_ACTIVITY)) +#define E_TIMEOUT_ACTIVITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityClass)) + +G_BEGIN_DECLS + +typedef struct _ETimeoutActivity ETimeoutActivity; +typedef struct _ETimeoutActivityClass ETimeoutActivityClass; +typedef struct _ETimeoutActivityPrivate ETimeoutActivityPrivate; + +struct _ETimeoutActivity { + EActivity parent; + ETimeoutActivityPrivate *priv; +}; + +struct _ETimeoutActivityClass { + EActivityClass parent_class; + + /* Signals */ + void (*timeout) (ETimeoutActivity *timeout_activity); +}; + +GType e_timeout_activity_get_type (void); +EActivity * e_timeout_activity_new (const gchar *primary_text); +void e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity, + guint seconds); + +G_END_DECLS + +#endif /* E_TIMEOUT_ACTIVITY_H */ -- cgit v1.2.3 From 7a92d9cc82b7775a0f5cb1fde233119d435a79b6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 10 Mar 2009 01:06:18 +0000 Subject: Add e_lookup_action() and e_lookup_action_group() to e-util, so I don't have to keep writing the algorithm over and over again. Add EFileActivity, which provides a GCancellable for GIO operations. Cancelling the activity cancels the GIO operation, and vice versa. Also provides a handy GFileProgressCallback function which updates the activity's "percent" property. svn path=/branches/kill-bonobo/; revision=37396 --- widgets/misc/Makefile.am | 2 + widgets/misc/e-activity-proxy.c | 6 +- widgets/misc/e-activity.c | 58 +++++----- widgets/misc/e-activity.h | 6 +- widgets/misc/e-attachment-bar.c | 55 +++++++--- widgets/misc/e-attachment-bar.h | 5 + widgets/misc/e-file-activity.c | 234 ++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-file-activity.h | 75 +++++++++++++ 8 files changed, 389 insertions(+), 52 deletions(-) create mode 100644 widgets/misc/e-file-activity.c create mode 100644 widgets/misc/e-file-activity.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ffbe7fa5fb..8e79779d6d 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -57,6 +57,7 @@ widgetsinclude_HEADERS = \ e-cursors.h \ e-dateedit.h \ e-expander.h \ + e-file-activity.h \ e-gui-utils.h \ e-hsv-utils.h \ e-icon-entry.h \ @@ -114,6 +115,7 @@ libemiscwidgets_la_SOURCES = \ e-cursors.c \ e-dateedit.c \ e-expander.c \ + e-file-activity.c \ e-gui-utils.c \ e-hsv-utils.c \ e-icon-entry.c \ diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index 9c08a8d9a0..bddcc124f3 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -49,14 +49,14 @@ activity_proxy_update (EActivityProxy *proxy) { EActivity *activity = proxy->priv->activity; const gchar *icon_name; - gboolean cancellable; + gboolean allow_cancel; gboolean cancelled; gboolean clickable; gboolean completed; gboolean sensitive; gchar *description; - cancellable = e_activity_get_cancellable (activity); + allow_cancel = e_activity_get_allow_cancel (activity); cancelled = e_activity_is_cancelled (activity); clickable = e_activity_get_clickable (activity); completed = e_activity_is_completed (activity); @@ -91,7 +91,7 @@ activity_proxy_update (EActivityProxy *proxy) gtk_widget_hide (proxy->priv->image); } - if (cancellable) + if (allow_cancel) gtk_widget_show (proxy->priv->cancel); else gtk_widget_hide (proxy->priv->cancel); diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 40ee0df35a..352300f023 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -33,8 +33,8 @@ struct _EActivityPrivate { gchar *secondary_text; gdouble percent; + guint allow_cancel : 1; guint blocking : 1; - guint cancellable : 1; guint cancelled : 1; guint clickable : 1; guint completed : 1; @@ -42,8 +42,8 @@ struct _EActivityPrivate { enum { PROP_0, + PROP_ALLOW_CANCEL, PROP_BLOCKING, - PROP_CANCELLABLE, PROP_CLICKABLE, PROP_ICON_NAME, PROP_PERCENT, @@ -68,14 +68,14 @@ activity_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BLOCKING: - e_activity_set_blocking ( + case PROP_ALLOW_CANCEL: + e_activity_set_allow_cancel ( E_ACTIVITY (object), g_value_get_boolean (value)); return; - case PROP_CANCELLABLE: - e_activity_set_cancellable ( + case PROP_BLOCKING: + e_activity_set_blocking ( E_ACTIVITY (object), g_value_get_boolean (value)); return; @@ -121,15 +121,15 @@ activity_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BLOCKING: + case PROP_ALLOW_CANCEL: g_value_set_boolean ( - value, e_activity_get_blocking ( + value, e_activity_get_allow_cancel ( E_ACTIVITY (object))); return; - case PROP_CANCELLABLE: + case PROP_BLOCKING: g_value_set_boolean ( - value, e_activity_get_cancellable ( + value, e_activity_get_blocking ( E_ACTIVITY (object))); return; @@ -256,23 +256,23 @@ activity_class_init (EActivityClass *class) g_object_class_install_property ( object_class, - PROP_BLOCKING, + PROP_ALLOW_CANCEL, g_param_spec_boolean ( - "blocking", + "allow-cancel", NULL, NULL, - TRUE, + FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, - PROP_CANCELLABLE, + PROP_BLOCKING, g_param_spec_boolean ( - "cancellable", + "blocking", NULL, NULL, - FALSE, + TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); @@ -405,7 +405,7 @@ void e_activity_cancel (EActivity *activity) { g_return_if_fail (E_IS_ACTIVITY (activity)); - g_return_if_fail (activity->priv->cancellable); + g_return_if_fail (activity->priv->allow_cancel); if (activity->priv->cancelled) return; @@ -468,41 +468,41 @@ e_activity_is_completed (EActivity *activity) } gboolean -e_activity_get_blocking (EActivity *activity) +e_activity_get_allow_cancel (EActivity *activity) { g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); - return activity->priv->blocking; + return activity->priv->allow_cancel; } void -e_activity_set_blocking (EActivity *activity, - gboolean blocking) +e_activity_set_allow_cancel (EActivity *activity, + gboolean allow_cancel) { g_return_if_fail (E_IS_ACTIVITY (activity)); - activity->priv->blocking = blocking; + activity->priv->allow_cancel = allow_cancel; - g_object_notify (G_OBJECT (activity), "blocking"); + g_object_notify (G_OBJECT (activity), "allow-cancel"); } gboolean -e_activity_get_cancellable (EActivity *activity) +e_activity_get_blocking (EActivity *activity) { g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); - return activity->priv->cancellable; + return activity->priv->blocking; } void -e_activity_set_cancellable (EActivity *activity, - gboolean cancellable) +e_activity_set_blocking (EActivity *activity, + gboolean blocking) { g_return_if_fail (E_IS_ACTIVITY (activity)); - activity->priv->cancellable = cancellable; + activity->priv->blocking = blocking; - g_object_notify (G_OBJECT (activity), "cancellable"); + g_object_notify (G_OBJECT (activity), "blocking"); } gboolean diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index 5050d9e611..9a14c073a0 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -74,12 +74,12 @@ void e_activity_clicked (EActivity *activity); gchar * e_activity_describe (EActivity *activity); gboolean e_activity_is_cancelled (EActivity *activity); gboolean e_activity_is_completed (EActivity *activity); +gboolean e_activity_get_allow_cancel (EActivity *activity); +void e_activity_set_allow_cancel (EActivity *activity, + gboolean allow_cancel); gboolean e_activity_get_blocking (EActivity *activity); void e_activity_set_blocking (EActivity *activity, gboolean blocking); -gboolean e_activity_get_cancellable (EActivity *activity); -void e_activity_set_cancellable (EActivity *activity, - gboolean cancellable); gboolean e_activity_get_clickable (EActivity *activity); void e_activity_set_clickable (EActivity *activity, gboolean clickable); diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 4608d77b9d..5a1a6359de 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -1261,11 +1261,9 @@ attachment_bar_key_press_event (GtkWidget *widget, editable = e_attachment_bar_get_editable (attachment_bar); if (editable && event->keyval == GDK_Delete) { - GtkActionGroup *action_group; GtkAction *action; - action_group = attachment_bar->priv->editable_actions; - action = gtk_action_group_get_action (action_group, "remove"); + action = e_attachment_bar_get_action (attachment_bar, "remove"); gtk_action_activate (action); } @@ -1375,27 +1373,22 @@ attachment_bar_update_actions (EAttachmentBar *attachment_bar) is_image = e_attachment_is_image (attachment); } - ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - - action_group = attachment_bar->priv->standard_actions; + action = e_attachment_bar_get_action (attachment_bar, "properties"); + gtk_action_set_visible (action, n_selected == 1); - action = gtk_action_group_get_action (action_group, "save-as"); + action = e_attachment_bar_get_action (attachment_bar, "remove"); gtk_action_set_visible (action, n_selected > 0); - action = gtk_action_group_get_action (action_group, "set-background"); - gtk_action_set_visible (action, is_image); - - action_group = attachment_bar->priv->editable_actions; - - action = gtk_action_group_get_action (action_group, "properties"); - gtk_action_set_visible (action, n_selected == 1); - - action = gtk_action_group_get_action (action_group, "remove"); + action = e_attachment_bar_get_action (attachment_bar, "save-as"); gtk_action_set_visible (action, n_selected > 0); - action_group = attachment_bar->priv->open_actions; + action = e_attachment_bar_get_action (attachment_bar, "set-background"); + gtk_action_set_visible (action, is_image); + /* Clear out the "open" action group. */ merge_id = attachment_bar->priv->merge_id; + action_group = attachment_bar->priv->open_actions; + ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); gtk_ui_manager_remove_ui (ui_manager, merge_id); e_action_group_remove_all_actions (action_group); @@ -2218,3 +2211,31 @@ e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar) return attachment_bar->priv->ui_manager; } + +GtkAction * +e_attachment_bar_get_action (EAttachmentBar *attachment_bar, + const gchar *action_name) +{ + GtkUIManager *ui_manager; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + g_return_val_if_fail (action_name != NULL, NULL); + + ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); + + return e_lookup_action (ui_manager, action_name); +} + +GtkActionGroup * +e_attachment_bar_get_action_group (EAttachmentBar *attachment_bar, + const gchar *group_name) +{ + GtkUIManager *ui_manager; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); + + return e_lookup_action_group (ui_manager, group_name); +} diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h index a55dcb11f6..a9b0655276 100644 --- a/widgets/misc/e-attachment-bar.h +++ b/widgets/misc/e-attachment-bar.h @@ -130,6 +130,11 @@ gboolean e_attachment_bar_get_editable (EAttachmentBar *attachment_bar); void e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, gboolean editable); GtkUIManager * e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar); +GtkAction * e_attachment_bar_get_action (EAttachmentBar *attachment_bar, + const gchar *action_name); +GtkActionGroup *e_attachment_bar_get_action_group + (EAttachmentBar *attachment_bar, + const gchar *group_name); G_END_DECLS diff --git a/widgets/misc/e-file-activity.c b/widgets/misc/e-file-activity.c new file mode 100644 index 0000000000..38dae234df --- /dev/null +++ b/widgets/misc/e-file-activity.c @@ -0,0 +1,234 @@ +/* + * e-file-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-file-activity.h" + +#define E_FILE_ACTIVITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_FILE_ACTIVITY, EFileActivityPrivate)) + +struct _EFileActivityPrivate { + GCancellable *cancellable; + gulong handler_id; +}; + +enum { + PROP_0, + PROP_CANCELLABLE +}; + +static gpointer parent_class; + +static void +file_activity_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CANCELLABLE: + e_file_activity_set_cancellable ( + E_FILE_ACTIVITY (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +file_activity_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CANCELLABLE: + g_value_set_object ( + value, e_file_activity_get_cancellable ( + E_FILE_ACTIVITY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +file_activity_dispose (GObject *object) +{ + EFileActivityPrivate *priv; + + priv = E_FILE_ACTIVITY_GET_PRIVATE (object); + + if (priv->cancellable != NULL) { + g_signal_handler_disconnect ( + priv->cancellable, priv->handler_id); + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +file_activity_cancelled (EActivity *activity) +{ + EFileActivity *file_activity; + GCancellable *cancellable; + + file_activity = E_FILE_ACTIVITY (activity); + cancellable = e_file_activity_get_cancellable (file_activity); + g_cancellable_cancel (cancellable); + + /* Chain up to parent's cancelled() method. */ + E_ACTIVITY_CLASS (parent_class)->cancelled (activity); +} + +static void +file_activity_class_init (EFileActivityClass *class) +{ + GObjectClass *object_class; + EActivityClass *activity_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EFileActivityPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = file_activity_set_property; + object_class->get_property = file_activity_get_property; + object_class->dispose = file_activity_dispose; + + activity_class = E_ACTIVITY_CLASS (class); + activity_class->cancelled = file_activity_cancelled; + + g_object_class_install_property ( + object_class, + PROP_CANCELLABLE, + g_param_spec_object ( + "cancellable", + "Cancellable", + NULL, + G_TYPE_CANCELLABLE, + G_PARAM_READWRITE)); +} + +static void +file_activity_init (EFileActivity *file_activity) +{ + GCancellable *cancellable; + + file_activity->priv = E_FILE_ACTIVITY_GET_PRIVATE (file_activity); + + e_activity_set_allow_cancel (E_ACTIVITY (file_activity), TRUE); + + cancellable = g_cancellable_new (); + e_file_activity_set_cancellable (file_activity, cancellable); + g_object_unref (cancellable); +} + +GType +e_file_activity_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EFileActivityClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) file_activity_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EFileActivity), + 0, /* n_preallocs */ + (GInstanceInitFunc) file_activity_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ACTIVITY, "EFileActivity", &type_info, 0); + } + + return type; +} + +EActivity * +e_file_activity_new (const gchar *primary_text) +{ + return g_object_new ( + E_TYPE_FILE_ACTIVITY, + "primary-text", primary_text, NULL); +} + +GCancellable * +e_file_activity_get_cancellable (EFileActivity *file_activity) +{ + g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); + + return file_activity->priv->cancellable; +} + +void +e_file_activity_set_cancellable (EFileActivity *file_activity, + GCancellable *cancellable) +{ + g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + + if (cancellable != NULL) { + g_return_if_fail (G_IS_CANCELLABLE (cancellable)); + g_object_ref (cancellable); + } + + if (file_activity->priv->cancellable != NULL) { + g_signal_handler_disconnect ( + file_activity->priv->cancellable, + file_activity->priv->handler_id); + g_object_unref (file_activity->priv->cancellable); + file_activity->priv->handler_id = 0; + } + + file_activity->priv->cancellable = cancellable; + + if (cancellable != NULL) + file_activity->priv->handler_id = + g_signal_connect_swapped ( + cancellable, "cancelled", + G_CALLBACK (e_activity_cancel), + file_activity); + + g_object_notify (G_OBJECT (file_activity), "cancellable"); +} + +void +e_file_activity_progress (goffset current_num_bytes, + goffset total_num_bytes, + gpointer activity) +{ + gdouble percent = -1.0; + + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (current_num_bytes > 0 && total_num_bytes > 0) + percent = (gdouble) current_num_bytes / total_num_bytes; + + e_activity_set_percent (activity, percent); +} diff --git a/widgets/misc/e-file-activity.h b/widgets/misc/e-file-activity.h new file mode 100644 index 0000000000..4a57228872 --- /dev/null +++ b/widgets/misc/e-file-activity.h @@ -0,0 +1,75 @@ +/* + * e-file-activity.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_FILE_ACTIVITY_H +#define E_FILE_ACTIVITY_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_FILE_ACTIVITY \ + (e_file_activity_get_type ()) +#define E_FILE_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_FILE_ACTIVITY, EFileActivity)) +#define E_FILE_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_FILE_ACTIVITY, EFileActivityClass)) +#define E_IS_FILE_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_FILE_ACTIVITY)) +#define E_IS_FILE_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_FILE_ACTIVITY)) +#define E_FILE_ACTIVITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_FILE_ACTIVITY, EFileActivityClass)) + +G_BEGIN_DECLS + +typedef struct _EFileActivity EFileActivity; +typedef struct _EFileActivityClass EFileActivityClass; +typedef struct _EFileActivityPrivate EFileActivityPrivate; + +struct _EFileActivity { + EActivity parent; + EFileActivityPrivate *priv; +}; + +struct _EFileActivityClass { + EActivityClass parent_class; +}; + +GType e_file_activity_get_type (void); +EActivity * e_file_activity_new (const gchar *primary_text); +GCancellable * e_file_activity_get_cancellable (EFileActivity *file_activity); +void e_file_activity_set_cancellable (EFileActivity *file_activity, + GCancellable *cancellable); + +/* This can be used as a GFileProgressCallback. */ +void e_file_activity_progress (goffset current_num_bytes, + goffset total_num_bytes, + gpointer activity); + +G_END_DECLS + +#endif /* E_FILE_ACTIVITY_H */ -- cgit v1.2.3 From 4cec9fc7169dc3b810321555a70cda916720867d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 20 Mar 2009 19:06:59 +0000 Subject: Saving progress on a massive attachment handling rewrite. svn path=/branches/kill-bonobo/; revision=37465 --- widgets/misc/Makefile.am | 12 +- widgets/misc/e-activity.c | 112 ++- widgets/misc/e-activity.h | 8 + widgets/misc/e-attachment-bar.c | 445 --------- widgets/misc/e-attachment-dialog.c | 112 +-- widgets/misc/e-attachment-icon-view.c | 319 +++++++ widgets/misc/e-attachment-icon-view.h | 66 ++ widgets/misc/e-attachment-paned.c | 563 ++++++++++++ widgets/misc/e-attachment-paned.h | 79 ++ widgets/misc/e-attachment-store.c | 1073 ++++++++++++++++++++++ widgets/misc/e-attachment-store.h | 110 +++ widgets/misc/e-attachment-tree-view.c | 396 +++++++++ widgets/misc/e-attachment-tree-view.h | 66 ++ widgets/misc/e-attachment-view.c | 1041 ++++++++++++++++++++++ widgets/misc/e-attachment-view.h | 163 ++++ widgets/misc/e-attachment.c | 1584 ++++++++++++++++++++------------- widgets/misc/e-attachment.h | 98 +- widgets/misc/e-file-activity.c | 133 ++- widgets/misc/e-file-activity.h | 10 +- widgets/misc/e-timeout-activity.c | 18 + widgets/misc/e-timeout-activity.h | 2 + 21 files changed, 5213 insertions(+), 1197 deletions(-) create mode 100644 widgets/misc/e-attachment-icon-view.c create mode 100644 widgets/misc/e-attachment-icon-view.h create mode 100644 widgets/misc/e-attachment-paned.c create mode 100644 widgets/misc/e-attachment-paned.h create mode 100644 widgets/misc/e-attachment-store.c create mode 100644 widgets/misc/e-attachment-store.h create mode 100644 widgets/misc/e-attachment-tree-view.c create mode 100644 widgets/misc/e-attachment-tree-view.h create mode 100644 widgets/misc/e-attachment-view.c create mode 100644 widgets/misc/e-attachment-view.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 8e79779d6d..f6fc7ed10a 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -40,8 +40,12 @@ widgetsinclude_HEADERS = \ e-activity-proxy.h \ e-alert-activity.h \ e-attachment.h \ - e-attachment-bar.h \ e-attachment-dialog.h \ + e-attachment-icon-view.h \ + e-attachment-paned.h \ + e-attachment-store.h \ + e-attachment-tree-view.h \ + e-attachment-view.h \ e-calendar.h \ e-calendar-item.h \ e-canvas.h \ @@ -98,8 +102,12 @@ libemiscwidgets_la_SOURCES = \ e-activity-proxy.c \ e-alert-activity.c \ e-attachment.c \ - e-attachment-bar.c \ e-attachment-dialog.c \ + e-attachment-icon-view.c \ + e-attachment-paned.c \ + e-attachment-store.c \ + e-attachment-tree-view.c \ + e-attachment-view.c \ e-calendar.c \ e-calendar-item.c \ e-canvas.c \ diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index 352300f023..c65c3aaa0a 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -21,6 +21,7 @@ #include "e-activity.h" +#include #include #define E_ACTIVITY_GET_PRIVATE(obj) \ @@ -32,6 +33,8 @@ struct _EActivityPrivate { gchar *primary_text; gchar *secondary_text; gdouble percent; + guint idle_id; + GError *error; guint allow_cancel : 1; guint blocking : 1; @@ -61,6 +64,24 @@ enum { static gpointer parent_class; static gulong signals[LAST_SIGNAL]; +static gboolean +activity_idle_cancel_cb (EActivity *activity) +{ + activity->priv->idle_id = 0; + e_activity_cancel (activity); + + return FALSE; +} + +static gboolean +activity_idle_complete_cb (EActivity *activity) +{ + activity->priv->idle_id = 0; + e_activity_complete (activity); + + return FALSE; +} + static void activity_set_property (GObject *object, guint property_id, @@ -178,6 +199,12 @@ activity_finalize (GObject *object) g_free (priv->primary_text); g_free (priv->secondary_text); + if (priv->idle_id > 0) + g_source_remove (priv->idle_id); + + if (priv->error != NULL) + g_error_free (priv->error); + /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -222,12 +249,22 @@ static void activity_cancelled (EActivity *activity) { activity->priv->cancelled = TRUE; + + if (activity->priv->idle_id > 0) { + g_source_remove (activity->priv->idle_id); + activity->priv->idle_id = 0; + } } static void activity_completed (EActivity *activity) { activity->priv->completed = TRUE; + + if (activity->priv->idle_id > 0) { + g_source_remove (activity->priv->idle_id); + activity->priv->idle_id = 0; + } } static void @@ -401,11 +438,29 @@ e_activity_new (const gchar *primary_text) "primary-text", primary_text, NULL); } +EActivity * +e_activity_newv (const gchar *format, ...) +{ + EActivity *activity; + gchar *primary_text; + va_list args; + + va_start (args, format); + primary_text = g_strdup_vprintf (format, args); + activity = e_activity_new (primary_text); + g_free (primary_text); + va_end (args); + + return activity; +} + void e_activity_cancel (EActivity *activity) { g_return_if_fail (E_IS_ACTIVITY (activity)); - g_return_if_fail (activity->priv->allow_cancel); + + if (!activity->priv->allow_cancel); + return; if (activity->priv->cancelled) return; @@ -416,6 +471,18 @@ e_activity_cancel (EActivity *activity) g_signal_emit (activity, signals[CANCELLED], 0); } +void +e_activity_cancel_in_idle (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (activity->priv->idle_id > 0) + g_source_remove (activity->priv->idle_id); + + activity->priv->idle_id = g_idle_add ( + (GSourceFunc) activity_idle_cancel_cb, activity); +} + void e_activity_complete (EActivity *activity) { @@ -430,6 +497,18 @@ e_activity_complete (EActivity *activity) g_signal_emit (activity, signals[COMPLETED], 0); } +void +e_activity_complete_in_idle (EActivity *activity) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (activity->priv->idle_id > 0) + g_source_remove (activity->priv->idle_id); + + activity->priv->idle_id = g_idle_add ( + (GSourceFunc) activity_idle_complete_cb, activity); +} + void e_activity_clicked (EActivity *activity) { @@ -602,3 +681,34 @@ e_activity_set_secondary_text (EActivity *activity, g_object_notify (G_OBJECT (activity), "secondary-text"); } + +void +e_activity_set_error (EActivity *activity, + const GError *error) +{ + g_return_if_fail (E_IS_ACTIVITY (activity)); + + if (activity->priv->error != NULL) { + g_error_free (activity->priv->error); + activity->priv->error = NULL; + } + + if (error != NULL) + activity->priv->error = g_error_copy (error); +} + +gboolean +e_activity_propagate_error (EActivity *activity, + GError **destination) +{ + gboolean propagated; + + g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); + + if ((propagated = (activity->priv->error != NULL))) { + g_propagate_error (destination, activity->priv->error); + activity->priv->error = NULL; + } + + return propagated; +} diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index 9a14c073a0..68f0bf20be 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -68,8 +68,12 @@ struct _EActivityClass { GType e_activity_get_type (void); EActivity * e_activity_new (const gchar *primary_text); +EActivity * e_activity_newv (const gchar *format, + ...) G_GNUC_PRINTF (1, 2); void e_activity_cancel (EActivity *activity); +void e_activity_cancel_in_idle (EActivity *activity); void e_activity_complete (EActivity *activity); +void e_activity_complete_in_idle (EActivity *activity); void e_activity_clicked (EActivity *activity); gchar * e_activity_describe (EActivity *activity); gboolean e_activity_is_cancelled (EActivity *activity); @@ -95,6 +99,10 @@ void e_activity_set_primary_text (EActivity *activity, const gchar * e_activity_get_secondary_text (EActivity *activity); void e_activity_set_secondary_text (EActivity *activity, const gchar *secondary_text); +void e_activity_set_error (EActivity *activity, + const GError *error); +gboolean e_activity_propagate_error (EActivity *activity, + GError **destination); G_END_DECLS diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 5a1a6359de..aebc6bb423 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -80,7 +80,6 @@ struct _EAttachmentBarPrivate { gboolean batch_unref; GPtrArray *attachments; - gchar *current_folder; char *path; GtkUIManager *ui_manager; @@ -89,17 +88,11 @@ struct _EAttachmentBarPrivate { GtkActionGroup *open_actions; guint merge_id; - gchar *background_filename; - gchar *background_options; - guint editable : 1; }; enum { PROP_0, - PROP_BACKGROUND_FILENAME, - PROP_BACKGROUND_OPTIONS, - PROP_CURRENT_FOLDER, PROP_EDITABLE, PROP_UI_MANAGER }; @@ -128,78 +121,6 @@ static const gchar *ui = " " ""; -static void -action_add_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ - GtkWidget *dialog; - GtkWidget *option; - GSList *uris, *iter; - const gchar *disposition; - gboolean active; - gpointer parent; - gint response; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (attachment_bar)); - parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - - dialog = gtk_file_chooser_dialog_new ( - _("Insert Attachment"), parent, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("A_ttach"), GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_default_response ( - GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_file_chooser_set_local_only ( - GTK_FILE_CHOOSER (dialog), FALSE); - gtk_file_chooser_set_select_multiple ( - GTK_FILE_CHOOSER (dialog), TRUE); - gtk_window_set_icon_name ( - GTK_WINDOW (dialog), "mail-attachment"); - - option = gtk_check_button_new_with_mnemonic ( - _("_Suggest automatic display of attachment")); - gtk_file_chooser_set_extra_widget ( - GTK_FILE_CHOOSER (dialog), option); - gtk_widget_show (option); - - response = e_attachment_bar_file_chooser_dialog_run ( - attachment_bar, dialog); - - if (response != GTK_RESPONSE_OK) - goto exit; - - uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog)); - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option)); - disposition = active ? "inline" : "attachment"; - - for (iter = uris; iter != NULL; iter = iter->next) { - CamelURL *url; - - url = camel_url_new (iter->data, NULL); - if (url == NULL) - continue; - - /* XXX Do we really need two different attach functions? */ - if (g_ascii_strcasecmp (url->protocol, "file") == 0) - e_attachment_bar_attach ( - attachment_bar, url->path, disposition); - else - e_attachment_bar_attach_remote_file ( - attachment_bar, iter->data, disposition); - - camel_url_free (url); - } - - g_slist_foreach (uris, (GFunc) g_free, NULL); - g_slist_free (uris); - -exit: - gtk_widget_destroy (dialog); -} - static void action_properties_cb (GtkAction *action, EAttachmentBar *attachment_bar) @@ -232,33 +153,6 @@ action_properties_cb (GtkAction *action, } } -static void -action_recent_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ - GtkRecentChooser *chooser; - GFile *file; - gchar *uri; - - chooser = GTK_RECENT_CHOOSER (action); - - /* Wish: gtk_recent_chooser_get_current_file() */ - uri = gtk_recent_chooser_get_current_uri (chooser); - file = g_file_new_for_uri (uri); - g_free (uri); - - if (g_file_is_native (file)) - e_attachment_bar_attach ( - E_ATTACHMENT_BAR (attachment_bar), - g_file_get_path (file), "attachment"); - else - e_attachment_bar_attach_remote_file ( - E_ATTACHMENT_BAR (attachment_bar), - g_file_get_uri (file), "attachment"); - - g_object_unref (file); -} - static void action_remove_cb (GtkAction *action, EAttachmentBar *attachment_bar) @@ -409,47 +303,6 @@ action_set_background_cb (GtkAction *action, } } -static GtkActionEntry standard_entries[] = { - - { "save-as", - GTK_STOCK_SAVE_AS, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_save_as_cb) }, - - { "set-background", - NULL, - N_("Set as _Background"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_set_background_cb) } -}; - -static GtkActionEntry editable_entries[] = { - - { "add", - GTK_STOCK_ADD, - N_("A_dd Attachment..."), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_add_cb) }, - - { "properties", - GTK_STOCK_PROPERTIES, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_properties_cb) }, - - { "remove", - GTK_STOCK_REMOVE, - NULL, - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_remove_cb) } -}; - static void attachment_bar_show_popup_menu (EAttachmentBar *attachment_bar, GdkEventButton *event) @@ -950,24 +803,6 @@ attachment_bar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BACKGROUND_FILENAME: - e_attachment_bar_set_background_filename ( - E_ATTACHMENT_BAR (object), - g_value_get_string (value)); - return; - - case PROP_BACKGROUND_OPTIONS: - e_attachment_bar_set_background_options ( - E_ATTACHMENT_BAR (object), - g_value_get_string (value)); - return; - - case PROP_CURRENT_FOLDER: - e_attachment_bar_set_current_folder ( - E_ATTACHMENT_BAR (object), - g_value_get_string (value)); - return; - case PROP_EDITABLE: e_attachment_bar_set_editable ( E_ATTACHMENT_BAR (object), @@ -985,27 +820,6 @@ attachment_bar_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BACKGROUND_FILENAME: - g_value_set_string ( - value, - e_attachment_bar_get_background_filename ( - E_ATTACHMENT_BAR (object))); - return; - - case PROP_BACKGROUND_OPTIONS: - g_value_set_string ( - value, - e_attachment_bar_get_background_options ( - E_ATTACHMENT_BAR (object))); - return; - - case PROP_CURRENT_FOLDER: - g_value_set_string ( - value, - e_attachment_bar_get_current_folder ( - E_ATTACHMENT_BAR (object))); - return; - case PROP_EDITABLE: g_value_set_boolean ( value, @@ -1077,12 +891,8 @@ attachment_bar_finalize (GObject *object) priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); g_ptr_array_free (priv->attachments, TRUE); - g_free (priv->current_folder); g_free (priv->path); - g_free (priv->background_filename); - g_free (priv->background_options); - /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -1092,25 +902,13 @@ attachment_bar_constructed (GObject *object) { EAttachmentBarPrivate *priv; GtkActionGroup *action_group; - GConfBridge *bridge; - const gchar *prop; - const gchar *key; priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); action_group = priv->editable_actions; - bridge = gconf_bridge_get (); e_mutual_binding_new ( G_OBJECT (object), "editable", G_OBJECT (action_group), "visible"); - - prop = "background-filename"; - key = "/desktop/gnome/background/picture_filename"; - gconf_bridge_bind_property (bridge, key, object, prop); - - prop = "background-options"; - key = "/desktop/gnome/background/picture_options"; - gconf_bridge_bind_property (bridge, key, object, prop); } static gboolean @@ -1426,39 +1224,6 @@ attachment_bar_class_init (EAttachmentBarClass *class) class->update_actions = attachment_bar_update_actions; - g_object_class_install_property ( - object_class, - PROP_BACKGROUND_FILENAME, - g_param_spec_string ( - "background-filename", - "Background Filename", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_BACKGROUND_OPTIONS, - g_param_spec_string ( - "background-options", - "Background Options", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_CURRENT_FOLDER, - g_param_spec_string ( - "current-folder", - "Current Folder", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - g_object_class_install_property ( object_class, PROP_EDITABLE, @@ -1503,10 +1268,7 @@ static void attachment_bar_init (EAttachmentBar *bar) { GnomeIconList *icon_list; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; gint icon_width, window_height; - const gchar *domain = GETTEXT_PACKAGE; GError *error = NULL; bar->priv = E_ATTACHMENT_BAR_GET_PRIVATE (bar); @@ -1532,38 +1294,6 @@ attachment_bar_init (EAttachmentBar *bar) gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); - - ui_manager = gtk_ui_manager_new (); - bar->priv->ui_manager = ui_manager; - bar->priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); - - action_group = gtk_action_group_new ("standard"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), bar); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - bar->priv->standard_actions = action_group; - - action_group = gtk_action_group_new ("editable"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_action_group_add_actions ( - action_group, editable_entries, - G_N_ELEMENTS (editable_entries), bar); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - bar->priv->editable_actions = action_group; - - action_group = gtk_action_group_new ("open"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - bar->priv->open_actions = action_group; - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here imples a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); } GType @@ -2038,69 +1768,6 @@ e_attachment_bar_attach_mime_part (EAttachmentBar *bar, e_attachment_bar_add_attachment (bar, attachment); } -GtkAction * -e_attachment_bar_recent_action_new (EAttachmentBar *bar, - const gchar *action_name, - const gchar *action_label) -{ - GtkAction *action; - GtkRecentChooser *chooser; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - action = gtk_recent_action_new ( - action_name, action_label, NULL, NULL); - gtk_recent_action_set_show_numbers (GTK_RECENT_ACTION (action), TRUE); - - chooser = GTK_RECENT_CHOOSER (action); - gtk_recent_chooser_set_show_icons (chooser, TRUE); - gtk_recent_chooser_set_show_not_found (chooser, FALSE); - gtk_recent_chooser_set_show_private (chooser, FALSE); - gtk_recent_chooser_set_show_tips (chooser, TRUE); - gtk_recent_chooser_set_sort_type (chooser, GTK_RECENT_SORT_MRU); - - g_signal_connect ( - action, "item-activated", - G_CALLBACK (action_recent_cb), bar); - - return action; -} - -gint -e_attachment_bar_file_chooser_dialog_run (EAttachmentBar *attachment_bar, - GtkWidget *dialog) -{ - GtkFileChooser *file_chooser; - gint response = GTK_RESPONSE_NONE; - const gchar *current_folder; - gboolean save_folder; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), response); - g_return_val_if_fail (GTK_IS_FILE_CHOOSER_DIALOG (dialog), response); - - file_chooser = GTK_FILE_CHOOSER (dialog); - current_folder = e_attachment_bar_get_current_folder (attachment_bar); - gtk_file_chooser_set_current_folder (file_chooser, current_folder); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - save_folder = - (response == GTK_RESPONSE_ACCEPT) || - (response == GTK_RESPONSE_OK) || - (response == GTK_RESPONSE_YES) || - (response == GTK_RESPONSE_APPLY); - - if (save_folder) { - gchar *folder; - - folder = gtk_file_chooser_get_current_folder (file_chooser); - e_attachment_bar_set_current_folder (attachment_bar, folder); - g_free (folder); - } - - return response; -} - void e_attachment_bar_update_actions (EAttachmentBar *attachment_bar) { @@ -2109,82 +1776,6 @@ e_attachment_bar_update_actions (EAttachmentBar *attachment_bar) g_signal_emit (attachment_bar, signals[UPDATE_ACTIONS], 0); } -const gchar * -e_attachment_bar_get_background_filename (EAttachmentBar *attachment_bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - - return attachment_bar->priv->background_filename; -} - -void -e_attachment_bar_set_background_filename (EAttachmentBar *attachment_bar, - const gchar *background_filename) -{ - EAttachmentBarPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); - - if (background_filename == NULL) - background_filename = ""; - - priv = attachment_bar->priv; - g_free (priv->background_filename); - priv->background_filename = g_strdup (background_filename); - - g_object_notify (G_OBJECT (attachment_bar), "background-filename"); -} - -const gchar * -e_attachment_bar_get_background_options (EAttachmentBar *attachment_bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - - return attachment_bar->priv->background_options; -} - -void -e_attachment_bar_set_background_options (EAttachmentBar *attachment_bar, - const gchar *background_options) -{ - EAttachmentBarPrivate *priv; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); - - if (background_options == NULL) - background_options = "none"; - - priv = attachment_bar->priv; - g_free (priv->background_options); - priv->background_options = g_strdup (background_options); - - g_object_notify (G_OBJECT (attachment_bar), "background-options"); -} - -const gchar * -e_attachment_bar_get_current_folder (EAttachmentBar *attachment_bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - - return attachment_bar->priv->current_folder; -} - -void -e_attachment_bar_set_current_folder (EAttachmentBar *attachment_bar, - const gchar *current_folder) -{ - - g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); - - if (current_folder == NULL) - current_folder = g_get_home_dir (); - - g_free (attachment_bar->priv->current_folder); - attachment_bar->priv->current_folder = g_strdup (current_folder); - - g_object_notify (G_OBJECT (attachment_bar), "current-folder"); -} - gboolean e_attachment_bar_get_editable (EAttachmentBar *attachment_bar) { @@ -2203,39 +1794,3 @@ e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, g_object_notify (G_OBJECT (attachment_bar), "editable"); } - -GtkUIManager * -e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - - return attachment_bar->priv->ui_manager; -} - -GtkAction * -e_attachment_bar_get_action (EAttachmentBar *attachment_bar, - const gchar *action_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - g_return_val_if_fail (action_name != NULL, NULL); - - ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - - return e_lookup_action (ui_manager, action_name); -} - -GtkActionGroup * -e_attachment_bar_get_action_group (EAttachmentBar *attachment_bar, - const gchar *group_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - - return e_lookup_action_group (ui_manager, group_name); -} diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index 0668a7358d..f697df1fe9 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -29,9 +29,9 @@ struct _EAttachmentDialogPrivate { EAttachment *attachment; - GtkWidget *filename_entry; + GtkWidget *display_name_entry; GtkWidget *description_entry; - GtkWidget *mime_type_label; + GtkWidget *content_type_label; GtkWidget *disposition_checkbox; }; @@ -46,56 +46,54 @@ static void attachment_dialog_update (EAttachmentDialog *dialog) { EAttachment *attachment; - CamelMimePart *mime_part; + GFileInfo *file_info; GtkWidget *widget; + const gchar *content_type; + const gchar *display_name; + const gchar *description; + const gchar *disposition; gboolean sensitive; - const gchar *text; gboolean active; - /* XXX This is too complex. I shouldn't have to use the - * MIME part at all. */ - attachment = e_attachment_dialog_get_attachment (dialog); - if (attachment != NULL) - mime_part = e_attachment_get_mime_part (attachment); - else - mime_part = NULL; - sensitive = (attachment != NULL); + if (E_IS_ATTACHMENT (attachment)) { + file_info = e_attachment_get_file_info (attachment); + content_type = e_attachment_get_content_type (attachment); + display_name = e_attachment_get_display_name (attachment); + description = e_attachment_get_description (attachment); + disposition = e_attachment_get_disposition (attachment); + } else { + file_info = NULL; + content_type = NULL; + display_name = NULL; + description = NULL; + disposition = NULL; + } + + sensitive = G_IS_FILE_INFO (file_info); + gtk_dialog_set_response_sensitive ( GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); - text = NULL; - if (attachment != NULL) - text = e_attachment_get_filename (attachment); - text = (text != NULL) ? text : ""; - widget = dialog->priv->filename_entry; + if (display_name == NULL) + display_name = ""; + widget = dialog->priv->display_name_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), text); + gtk_entry_set_text (GTK_ENTRY (widget), display_name); - text = NULL; - if (attachment != NULL) - text = e_attachment_get_description (attachment); - text = (text != NULL) ? text : ""; + if (description == NULL) + description = ""; widget = dialog->priv->description_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), text); + gtk_entry_set_text (GTK_ENTRY (widget), description); - text = NULL; - if (attachment != NULL) - text = e_attachment_get_mime_type (attachment); - text = (text != NULL) ? text : ""; - widget = dialog->priv->mime_type_label; - gtk_label_set_text (GTK_LABEL (widget), text); - - active = FALSE; - if (mime_part != NULL) { - const gchar *disposition; - - disposition = camel_mime_part_get_disposition (mime_part); - active = (g_ascii_strcasecmp (disposition, "inline") == 0); - } else if (attachment != NULL) - active = e_attachment_is_inline (attachment); + if (content_type == NULL) + content_type = ""; + widget = dialog->priv->content_type_label; + gtk_label_set_text (GTK_LABEL (widget), content_type); + + active = (g_strcmp0 (disposition, "inline") == 0); widget = dialog->priv->disposition_checkbox; gtk_widget_set_sensitive (widget, sensitive); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active); @@ -147,9 +145,9 @@ attachment_dialog_dispose (GObject *object) priv->attachment = NULL; } - if (priv->filename_entry != NULL) { - g_object_unref (priv->filename_entry); - priv->filename_entry = NULL; + if (priv->display_name_entry != NULL) { + g_object_unref (priv->display_name_entry); + priv->display_name_entry = NULL; } if (priv->description_entry != NULL) { @@ -157,9 +155,9 @@ attachment_dialog_dispose (GObject *object) priv->description_entry = NULL; } - if (priv->mime_type_label != NULL) { - g_object_unref (priv->mime_type_label); - priv->mime_type_label = NULL; + if (priv->content_type_label != NULL) { + g_object_unref (priv->content_type_label); + priv->content_type_label = NULL; } if (priv->disposition_checkbox != NULL) { @@ -196,7 +194,8 @@ attachment_dialog_response (GtkDialog *dialog, EAttachmentDialogPrivate *priv; EAttachment *attachment; GtkToggleButton *button; - GtkEntry *entry; + GFileInfo *file_info; + const gchar *attribute; const gchar *text; gboolean active; @@ -204,16 +203,19 @@ attachment_dialog_response (GtkDialog *dialog, return; priv = E_ATTACHMENT_DIALOG_GET_PRIVATE (dialog); - g_return_if_fail (priv->attachment != NULL); + g_return_if_fail (E_IS_ATTACHMENT (priv->attachment)); attachment = priv->attachment; - entry = GTK_ENTRY (priv->filename_entry); - text = gtk_entry_get_text (entry); - e_attachment_set_filename (attachment, text); + file_info = e_attachment_get_file_info (attachment); + g_return_if_fail (G_IS_FILE_INFO (file_info)); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; + text = gtk_entry_get_text (GTK_ENTRY (priv->display_name_entry)); + g_file_info_set_attribute_string (file_info, attribute, text); - entry = GTK_ENTRY (priv->description_entry); - text = gtk_entry_get_text (entry); - e_attachment_set_description (attachment, text); + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + text = gtk_entry_get_text (GTK_ENTRY (priv->description_entry)); + g_file_info_set_attribute_string (file_info, attribute, text); button = GTK_TOGGLE_BUTTON (priv->disposition_checkbox); active = gtk_toggle_button_get_active (button); @@ -289,13 +291,13 @@ attachment_dialog_init (EAttachmentDialog *dialog) gtk_table_attach ( GTK_TABLE (container), widget, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->filename_entry = g_object_ref (widget); + dialog->priv->display_name_entry = g_object_ref (widget); gtk_widget_show (widget); widget = gtk_label_new_with_mnemonic (_("_Filename:")); gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), dialog->priv->filename_entry); + GTK_LABEL (widget), dialog->priv->display_name_entry); gtk_table_attach ( GTK_TABLE (container), widget, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); @@ -324,7 +326,7 @@ attachment_dialog_init (EAttachmentDialog *dialog) gtk_table_attach ( GTK_TABLE (container), widget, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); - dialog->priv->mime_type_label = g_object_ref (widget); + dialog->priv->content_type_label = g_object_ref (widget); gtk_widget_show (widget); widget = gtk_label_new (_("MIME Type:")); diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c new file mode 100644 index 0000000000..8d39a76d75 --- /dev/null +++ b/widgets/misc/e-attachment-icon-view.c @@ -0,0 +1,319 @@ +/* + * e-attachment-icon-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-icon-view.h" + +#include + +#include "e-attachment.h" +#include "e-attachment-store.h" +#include "e-attachment-view.h" + +#define E_ATTACHMENT_ICON_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconViewPrivate)) + +struct _EAttachmentIconViewPrivate { + EAttachmentViewPrivate view_priv; +}; + +static gpointer parent_class; + +static void +attachment_icon_view_dispose (GObject *object) +{ + e_attachment_view_dispose (E_ATTACHMENT_VIEW (object)); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_icon_view_finalize (GObject *object) +{ + e_attachment_view_finalize (E_ATTACHMENT_VIEW (object)); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +attachment_icon_view_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { + e_attachment_view_show_popup_menu (view, event); + return TRUE; + } + + /* Chain up to parent's button_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_press_event (widget, event); +} + +static gboolean +attachment_icon_view_key_press_event (GtkWidget *widget, + GdkEventKey *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (event->keyval == GDK_Delete) { + e_attachment_view_remove_selected (view, TRUE); + return TRUE; + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + key_press_event (widget, event); +} + +static gboolean +attachment_icon_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + return e_attachment_view_drag_motion (view, context, x, y, time); +} + +static void +attachment_icon_view_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_drag_data_received ( + view, context, x, y, selection, info, time); +} + +static gboolean +attachment_icon_view_popup_menu (GtkWidget *widget) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_show_popup_menu (view, NULL); + + return TRUE; +} + +static EAttachmentViewPrivate * +attachment_icon_view_get_private (EAttachmentView *view) +{ + EAttachmentIconViewPrivate *priv; + + priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (view); + + return &priv->view_priv; +} + +static EAttachmentStore * +attachment_icon_view_get_store (EAttachmentView *view) +{ + GtkIconView *icon_view; + GtkTreeModel *model; + + icon_view = GTK_ICON_VIEW (view); + model = gtk_icon_view_get_model (icon_view); + + return E_ATTACHMENT_STORE (model); +} + +static GtkTreePath * +attachment_icon_view_get_path_at_pos (EAttachmentView *view, + gint x, + gint y) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + return gtk_icon_view_get_path_at_pos (icon_view, x, y); +} + +static GList * +attachment_icon_view_get_selected_paths (EAttachmentView *view) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + return gtk_icon_view_get_selected_items (icon_view); +} + +static gboolean +attachment_icon_view_path_is_selected (EAttachmentView *view, + GtkTreePath *path) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + return gtk_icon_view_path_is_selected (icon_view, path); +} + +static void +attachment_icon_view_select_path (EAttachmentView *view, + GtkTreePath *path) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_select_path (icon_view, path); +} + +static void +attachment_icon_view_unselect_path (EAttachmentView *view, + GtkTreePath *path) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_unselect_path (icon_view, path); +} + +static void +attachment_icon_view_select_all (EAttachmentView *view) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_select_all (icon_view); +} + +static void +attachment_icon_view_unselect_all (EAttachmentView *view) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_unselect_all (icon_view); +} + +static void +attachment_icon_view_class_init (EAttachmentIconViewClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = attachment_icon_view_dispose; + object_class->finalize = attachment_icon_view_finalize; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->button_press_event = attachment_icon_view_button_press_event; + widget_class->key_press_event = attachment_icon_view_key_press_event; + widget_class->drag_motion = attachment_icon_view_drag_motion; + widget_class->drag_data_received = attachment_icon_view_drag_data_received; + widget_class->popup_menu = attachment_icon_view_popup_menu; +} + +static void +attachment_icon_view_iface_init (EAttachmentViewIface *iface) +{ + iface->get_private = attachment_icon_view_get_private; + iface->get_store = attachment_icon_view_get_store; + + iface->get_path_at_pos = attachment_icon_view_get_path_at_pos; + iface->get_selected_paths = attachment_icon_view_get_selected_paths; + iface->path_is_selected = attachment_icon_view_path_is_selected; + iface->select_path = attachment_icon_view_select_path; + iface->unselect_path = attachment_icon_view_unselect_path; + iface->select_all = attachment_icon_view_select_all; + iface->unselect_all = attachment_icon_view_unselect_all; +} + +static void +attachment_icon_view_init (EAttachmentIconView *icon_view) +{ + icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view); + + e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view)); + + gtk_icon_view_set_selection_mode ( + GTK_ICON_VIEW (icon_view), GTK_SELECTION_MULTIPLE); + + gtk_icon_view_set_pixbuf_column ( + GTK_ICON_VIEW (icon_view), + E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF); + + gtk_icon_view_set_text_column ( + GTK_ICON_VIEW (icon_view), + E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION); +} + +GType +e_attachment_icon_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentIconViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_icon_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentIconView), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_icon_view_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) attachment_icon_view_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + type = g_type_register_static ( + GTK_TYPE_ICON_VIEW, "EAttachmentIconView", + &type_info, 0); + + g_type_add_interface_static ( + type, E_TYPE_ATTACHMENT_VIEW, &iface_info); + } + + return type; +} + +GtkWidget * +e_attachment_icon_view_new (void) +{ + return g_object_new (E_TYPE_ATTACHMENT_ICON_VIEW, NULL); +} diff --git a/widgets/misc/e-attachment-icon-view.h b/widgets/misc/e-attachment-icon-view.h new file mode 100644 index 0000000000..ab9360e42e --- /dev/null +++ b/widgets/misc/e-attachment-icon-view.h @@ -0,0 +1,66 @@ +/* + * e-attachment-icon-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_ICON_VIEW_H +#define E_ATTACHMENT_ICON_VIEW_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_ICON_VIEW \ + (e_attachment_icon_view_get_type ()) +#define E_ATTACHMENT_ICON_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconView)) +#define E_ATTACHMENT_ICON_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconView)) +#define E_IS_ATTACHMENT_ICON_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_ICON_VIEW)) +#define E_IS_ATTACHMENT_ICON_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_ICON_VIEW)) +#define E_ATTACHMENT_ICON_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_ICON_VIEW)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentIconView EAttachmentIconView; +typedef struct _EAttachmentIconViewClass EAttachmentIconViewClass; +typedef struct _EAttachmentIconViewPrivate EAttachmentIconViewPrivate; + +struct _EAttachmentIconView { + GtkIconView parent; + EAttachmentIconViewPrivate *priv; +}; + +struct _EAttachmentIconViewClass { + GtkIconViewClass parent_class; +}; + +GType e_attachment_icon_view_get_type (void); +GtkWidget * e_attachment_icon_view_new (void); + +G_END_DECLS + +#endif /* E_ATTACHMENT_ICON_VIEW_H */ diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c new file mode 100644 index 0000000000..bb919e9789 --- /dev/null +++ b/widgets/misc/e-attachment-paned.c @@ -0,0 +1,563 @@ +/* + * e-attachment-paned.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-paned.h" + +#include +#include "e-util/e-binding.h" +#include "e-attachment-store.h" +#include "e-attachment-icon-view.h" +#include "e-attachment-tree-view.h" + +#define E_ATTACHMENT_PANED_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedPrivate)) + +#define NUM_VIEWS 2 + +struct _EAttachmentPanedPrivate { + GtkTreeModel *model; + GtkWidget *expander; + GtkWidget *notebook; + GtkWidget *combo_box; + GtkWidget *icon_view; + GtkWidget *tree_view; + GtkWidget *show_hide_label; + GtkWidget *status_icon; + GtkWidget *status_label; + GtkWidget *content_area; + + gint active_view; + guint expanded : 1; +}; + +enum { + PROP_0, + PROP_ACTIVE_VIEW, + PROP_EXPANDED +}; + +static gpointer parent_class; + +static void +attachment_paned_notify_cb (EAttachmentPaned *paned, + GParamSpec *pspec, + GtkExpander *expander) +{ + GtkLabel *label; + const gchar *text; + + label = GTK_LABEL (paned->priv->show_hide_label); + + /* Update the expander label. */ + if (gtk_expander_get_expanded (expander)) + text = _("Hide _Attachment Bar"); + else + text = _("Show _Attachment Bar"); + + gtk_label_set_text_with_mnemonic (label, text); +} + +static void +attachment_paned_sync_icon_view (EAttachmentPaned *paned) +{ + EAttachmentView *source; + EAttachmentView *target; + + source = E_ATTACHMENT_VIEW (paned->priv->tree_view); + target = E_ATTACHMENT_VIEW (paned->priv->icon_view); + + /* Only sync if the tree view is active. This prevents the + * two views from endlessly trying to sync with each other. */ + if (e_attachment_paned_get_active_view (paned) == 1) + e_attachment_view_sync_selection (source, target); +} + +static void +attachment_paned_sync_tree_view (EAttachmentPaned *paned) +{ + EAttachmentView *source; + EAttachmentView *target; + + source = E_ATTACHMENT_VIEW (paned->priv->icon_view); + target = E_ATTACHMENT_VIEW (paned->priv->tree_view); + + /* Only sync if the icon view is active. This prevents the + * two views from endlessly trying to sync with each other. */ + if (e_attachment_paned_get_active_view (paned) == 0) + e_attachment_view_sync_selection (source, target); +} + +static void +attachment_paned_update_status (EAttachmentPaned *paned) +{ + EAttachmentView *view; + EAttachmentStore *store; + GtkExpander *expander; + GtkLabel *label; + guint num_attachments; + guint64 total_size; + gchar *display_size; + gchar *markup; + + view = e_attachment_paned_get_view (paned); + store = e_attachment_view_get_store (view); + expander = GTK_EXPANDER (paned->priv->expander); + label = GTK_LABEL (paned->priv->status_label); + + num_attachments = e_attachment_store_get_num_attachments (store); + total_size = e_attachment_store_get_total_size (store); + display_size = g_format_size_for_display (total_size); + + markup = g_strdup_printf ( + "%d %s (%s)", num_attachments, ngettext ( + "Attachment", "Attachments", num_attachments), + display_size); + gtk_label_set_markup (label, markup); + g_free (markup); + + g_free (display_size); + + if (num_attachments > 0) { + gtk_widget_show (paned->priv->status_icon); + gtk_widget_show (paned->priv->status_label); + gtk_expander_set_expanded (expander, TRUE); + } else { + gtk_widget_hide (paned->priv->status_icon); + gtk_widget_hide (paned->priv->status_label); + gtk_expander_set_expanded (expander, FALSE); + } +} + +static void +attachment_paned_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_VIEW: + e_attachment_paned_set_active_view ( + E_ATTACHMENT_PANED (object), + g_value_get_int (value)); + return; + + case PROP_EXPANDED: + e_attachment_paned_set_expanded ( + E_ATTACHMENT_PANED (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_paned_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_VIEW: + g_value_set_int ( + value, e_attachment_paned_get_active_view ( + E_ATTACHMENT_PANED (object))); + return; + + case PROP_EXPANDED: + g_value_set_boolean ( + value, e_attachment_paned_get_expanded ( + E_ATTACHMENT_PANED (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_paned_dispose (GObject *object) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (object); + + if (priv->model != NULL) { + g_object_unref (priv->model); + priv->model = NULL; + } + + if (priv->expander != NULL) { + g_object_unref (priv->expander); + priv->expander = NULL; + } + + if (priv->notebook != NULL) { + g_object_unref (priv->notebook); + priv->notebook = NULL; + } + + if (priv->combo_box != NULL) { + g_object_unref (priv->combo_box); + priv->combo_box = NULL; + } + + if (priv->icon_view != NULL) { + g_object_unref (priv->icon_view); + priv->icon_view = NULL; + } + + if (priv->tree_view != NULL) { + g_object_unref (priv->tree_view); + priv->tree_view = NULL; + } + + if (priv->show_hide_label != NULL) { + g_object_unref (priv->show_hide_label); + priv->show_hide_label = NULL; + } + + if (priv->status_icon != NULL) { + g_object_unref (priv->status_icon); + priv->status_icon = NULL; + } + + if (priv->status_label != NULL) { + g_object_unref (priv->status_label); + priv->status_label = NULL; + } + + if (priv->content_area != NULL) { + g_object_unref (priv->content_area); + priv->content_area = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_paned_constructed (GObject *object) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (object); + + e_mutual_binding_new ( + G_OBJECT (object), "active-view", + G_OBJECT (priv->combo_box), "active"); + + e_mutual_binding_new ( + G_OBJECT (object), "active-view", + G_OBJECT (priv->notebook), "page"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->expander), "expanded"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->combo_box), "sensitive"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->notebook), "visible"); +} + +static void +attachment_paned_class_init (EAttachmentPanedClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentPanedPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_paned_set_property; + object_class->get_property = attachment_paned_get_property; + object_class->dispose = attachment_paned_dispose; + object_class->constructed = attachment_paned_constructed; + + g_object_class_install_property ( + object_class, + PROP_ACTIVE_VIEW, + g_param_spec_int ( + "active-view", + "Active View", + NULL, + 0, + NUM_VIEWS, + 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_EXPANDED, + g_param_spec_boolean ( + "expanded", + "Expanded", + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); +} + +static void +attachment_paned_init (EAttachmentPaned *paned) +{ + GtkTreeSelection *selection; + GtkSizeGroup *size_group; + GtkWidget *container; + GtkWidget *widget; + + paned->priv = E_ATTACHMENT_PANED_GET_PRIVATE (paned); + paned->priv->model = e_attachment_store_new (); + + /* Keep the expander label and combo box the same height. */ + size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + + /* Construct the Controls */ + + container = GTK_WIDGET (paned); + + widget = gtk_vbox_new (FALSE, 6); + gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE); + paned->priv->content_area = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_hbox_new (FALSE, 6); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_expander_new (NULL); + gtk_expander_set_spacing (GTK_EXPANDER (widget), 0); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + paned->priv->expander = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_combo_box_new_text (); + gtk_size_group_add_widget (size_group, widget); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Icon View")); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("List View")); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + paned->priv->combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + container = paned->priv->expander; + + widget = gtk_hbox_new (FALSE, 0); + gtk_size_group_add_widget (size_group, widget); + gtk_expander_set_label_widget (GTK_EXPANDER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_label_new_with_mnemonic (_("Show _Attachment Bar")); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 6); + paned->priv->show_hide_label = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_image_new_from_icon_name ( + "mail-attachment", GTK_ICON_SIZE_MENU); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_widget_set_size_request (widget, 100, -1); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + paned->priv->status_icon = g_object_ref (widget); + gtk_widget_hide (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6); + paned->priv->status_label = g_object_ref (widget); + gtk_widget_show (widget); + + /* Construct the Attachment Views */ + + container = GTK_WIDGET (paned); + + widget = gtk_notebook_new (); + gtk_widget_set_size_request (widget, -1, 40); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE); + paned->priv->notebook = g_object_ref (widget); + gtk_widget_hide (widget); + + container = paned->priv->notebook; + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_icon_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_icon_view_set_model (GTK_ICON_VIEW (widget), paned->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + paned->priv->icon_view = g_object_ref (widget); + gtk_widget_show (widget); + + container = paned->priv->notebook; + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_tree_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget), paned->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + paned->priv->tree_view = g_object_ref (widget); + gtk_widget_show (widget); + + selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (paned->priv->tree_view)); + + g_signal_connect_swapped ( + selection, "changed", + G_CALLBACK (attachment_paned_sync_icon_view), paned); + + g_signal_connect_swapped ( + paned->priv->icon_view, "selection-changed", + G_CALLBACK (attachment_paned_sync_tree_view), paned); + + g_signal_connect_swapped ( + paned->priv->expander, "notify::expanded", + G_CALLBACK (attachment_paned_notify_cb), paned); + + g_signal_connect_swapped ( + paned->priv->model, "notify::num-attachments", + G_CALLBACK (attachment_paned_update_status), paned); + + g_signal_connect_swapped ( + paned->priv->model, "notify::total-size", + G_CALLBACK (attachment_paned_update_status), paned); + + g_object_unref (size_group); +} + +GType +e_attachment_paned_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentPanedClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_paned_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentPaned), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_paned_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_VPANED, "EAttachmentPaned", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_attachment_paned_new (void) +{ + return g_object_new (E_TYPE_ATTACHMENT_PANED, NULL); +} + +EAttachmentView * +e_attachment_paned_get_view (EAttachmentPaned *paned) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL); + + return E_ATTACHMENT_VIEW (paned->priv->icon_view); +} + +GtkWidget * +e_attachment_paned_get_content_area (EAttachmentPaned *paned) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL); + + return paned->priv->content_area; +} + +gint +e_attachment_paned_get_active_view (EAttachmentPaned *paned) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), 0); + + return paned->priv->active_view; +} + +void +e_attachment_paned_set_active_view (EAttachmentPaned *paned, + gint active_view) +{ + g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); + g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS); + + paned->priv->active_view = active_view; + + g_object_notify (G_OBJECT (paned), "active-view"); +} + +gboolean +e_attachment_paned_get_expanded (EAttachmentPaned *paned) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), FALSE); + + return paned->priv->expanded; +} + +void +e_attachment_paned_set_expanded (EAttachmentPaned *paned, + gboolean expanded) +{ + g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); + + paned->priv->expanded = expanded; + + g_object_notify (G_OBJECT (paned), "expanded"); +} diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h new file mode 100644 index 0000000000..c6cad5226f --- /dev/null +++ b/widgets/misc/e-attachment-paned.h @@ -0,0 +1,79 @@ +/* + * e-attachment-paned.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_PANED_H +#define E_ATTACHMENT_PANED_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_PANED \ + (e_attachment_paned_get_type ()) +#define E_ATTACHMENT_PANED(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPaned)) +#define E_ATTACHMENT_PANED_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedClass)) +#define E_IS_ATTACHMENT_PANED(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_PANED)) +#define E_IS_ATTACHMENT_PANED_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_PANED)) +#define E_ATTACHMENT_PANED_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentPaned EAttachmentPaned; +typedef struct _EAttachmentPanedClass EAttachmentPanedClass; +typedef struct _EAttachmentPanedPrivate EAttachmentPanedPrivate; + +struct _EAttachmentPaned { + GtkVPaned parent; + EAttachmentPanedPrivate *priv; +}; + +struct _EAttachmentPanedClass { + GtkVPanedClass parent_class; +}; + +GType e_attachment_paned_get_type (void); +GtkWidget * e_attachment_paned_new (void); +EAttachmentView * + e_attachment_paned_get_view (EAttachmentPaned *paned); +GtkWidget * e_attachment_paned_get_content_area + (EAttachmentPaned *paned); +gint e_attachment_paned_get_active_view + (EAttachmentPaned *paned); +void e_attachment_paned_set_active_view + (EAttachmentPaned *paned, + gint active_view); +gboolean e_attachment_paned_get_expanded (EAttachmentPaned *paned); +void e_attachment_paned_set_expanded (EAttachmentPaned *paned, + gboolean expanded); + +G_END_DECLS + +#endif /* E_ATTACHMENT_PANED_H */ diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c new file mode 100644 index 0000000000..2658dd06c9 --- /dev/null +++ b/widgets/misc/e-attachment-store.c @@ -0,0 +1,1073 @@ +/* + * e-attachment-store.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-store.h" + +#include + +#include "e-util/e-util.h" +#include "e-util/gconf-bridge.h" + +#include "e-file-activity.h" + +#define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStorePrivate)) + +#define DEFAULT_ICON_NAME "mail-attachment" + +/* XXX Unfortunate that we have to define this here. Would + * prefer the attachment view classes pick their own size, + * but GtkIconView requires a dedicated pixbuf column. */ +#define LARGE_ICON_SIZE GTK_ICON_SIZE_DIALOG +#define SMALL_ICON_SIZE GTK_ICON_SIZE_MENU + +struct _EAttachmentStorePrivate { + GHashTable *activity_index; + GHashTable *attachment_index; + gchar *background_filename; + gchar *background_options; + gchar *current_folder; + + guint ignore_row_changed : 1; +}; + +enum { + PROP_0, + PROP_BACKGROUND_FILENAME, + PROP_BACKGROUND_OPTIONS, + PROP_CURRENT_FOLDER, + PROP_NUM_ATTACHMENTS, + PROP_NUM_DOWNLOADING, + PROP_TOTAL_SIZE +}; + +enum { + NEW_ACTIVITY, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static const gchar * +attachment_store_get_background_filename (EAttachmentStore *store) +{ + return store->priv->background_filename; +} + +static void +attachment_store_set_background_filename (EAttachmentStore *store, + const gchar *background_filename) +{ + if (background_filename == NULL) + background_filename = ""; + + g_free (store->priv->background_filename); + store->priv->background_filename = g_strdup (background_filename); + + g_object_notify (G_OBJECT (store), "background-filename"); +} + +static const gchar * +attachment_store_get_background_options (EAttachmentStore *store) +{ + return store->priv->background_options; +} + +static void +attachment_store_set_background_options (EAttachmentStore *store, + const gchar *background_options) +{ + if (background_options == NULL) + background_options = ""; + + g_free (store->priv->background_options); + store->priv->background_options = g_strdup (background_options); + + g_object_notify (G_OBJECT (store), "background-options"); +} + +static void +attachment_store_remove_activity (EAttachmentStore *store, + EActivity *activity) +{ + GtkTreeRowReference *reference; + GHashTable *hash_table; + + hash_table = store->priv->activity_index; + reference = g_hash_table_lookup (hash_table, activity); + + if (gtk_tree_row_reference_valid (reference)) { + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + gtk_list_store_set ( + GTK_LIST_STORE (store), &iter, + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, NULL, -1); + } + + g_hash_table_remove (hash_table, activity); + + g_object_notify (G_OBJECT (store), "num-downloading"); +} + +static void +attachment_store_copy_ready (GFile *source, + GAsyncResult *result, + GtkTreeRowReference *reference) +{ + EAttachmentStore *store; + EAttachment *attachment; + EActivity *activity; + GFile *destination; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gboolean valid; + GError *error = NULL; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + valid = gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + g_return_if_fail (valid); + + gtk_tree_model_get ( + model, &iter, + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, &activity, + E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, &attachment, -1); + + gtk_tree_row_reference_free (reference); + + store = E_ATTACHMENT_STORE (model); + + if (!g_file_copy_finish (source, result, &error)) + goto fail; + + gtk_list_store_set ( + GTK_LIST_STORE (store), &iter, + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, NULL, -1); + + destination = e_file_activity_get_file (E_FILE_ACTIVITY (activity)); + e_attachment_set_file (attachment, destination); + + e_activity_complete (activity); + + path = gtk_tree_model_get_path (model, &iter); + gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); + + g_object_unref (attachment); + g_object_unref (activity); + + return; + +fail: + e_attachment_store_remove_attachment (store, attachment); + + g_object_unref (attachment); + g_object_unref (activity); + + /* XXX Do something more useful with the error. */ + g_warning ("%s", error->message); + g_error_free (error); +} + +static void +attachment_store_copy_async (EAttachmentStore *store, + EAttachment *attachment) +{ + EActivity *activity; + GCancellable *cancellable; + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GHashTable *hash_table; + GFile *destination; + GFile *source; + gboolean valid; + gchar *filename; + gchar *uri; + gint fd; + GError *error = NULL; + + hash_table = store->priv->attachment_index; + reference = g_hash_table_lookup (hash_table, attachment); + g_return_if_fail (reference != NULL); + + fd = e_file_open_tmp (&filename, &error); + if (error != NULL) + goto fail; + + source = e_attachment_get_file (attachment); + destination = g_file_new_for_path (filename); + + g_free (filename); + close (fd); + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + valid = gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + g_return_if_fail (valid); + + uri = g_file_get_uri (source); + activity = e_file_activity_newv (_("Downloading '%s'"), uri); + g_free (uri); + + gtk_list_store_set ( + GTK_LIST_STORE (store), &iter, + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, activity, -1); + + reference = gtk_tree_row_reference_copy (reference); + + g_hash_table_insert (hash_table, g_object_ref (activity), reference); + + g_signal_connect_swapped ( + activity, "cancelled", + G_CALLBACK (attachment_store_remove_activity), store); + + g_signal_connect_swapped ( + activity, "completed", + G_CALLBACK (attachment_store_remove_activity), store); + + reference = gtk_tree_row_reference_copy (reference); + + cancellable = e_file_activity_get_cancellable ( + E_FILE_ACTIVITY (activity)); + + g_file_copy_async ( + source, destination, G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, cancellable, (GFileProgressCallback) + e_file_activity_progress, activity, (GAsyncReadyCallback) + attachment_store_copy_ready, reference); + + e_file_activity_set_file (E_FILE_ACTIVITY (activity), destination); + g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity); + + g_object_notify (G_OBJECT (store), "num-downloading"); + + g_object_unref (activity); + g_object_unref (destination); + + return; + +fail: + e_attachment_store_remove_attachment (store, attachment); + + /* XXX Do something more useful with the error. */ + g_warning ("%s", error->message); + g_error_free (error); +} + +static void +attachment_store_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BACKGROUND_FILENAME: + attachment_store_set_background_filename ( + E_ATTACHMENT_STORE (object), + g_value_get_string (value)); + return; + + case PROP_BACKGROUND_OPTIONS: + attachment_store_set_background_options ( + E_ATTACHMENT_STORE (object), + g_value_get_string (value)); + return; + + case PROP_CURRENT_FOLDER: + e_attachment_store_set_current_folder ( + E_ATTACHMENT_STORE (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_store_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BACKGROUND_FILENAME: + g_value_set_string ( + value, + attachment_store_get_background_filename ( + E_ATTACHMENT_STORE (object))); + return; + + case PROP_BACKGROUND_OPTIONS: + g_value_set_string ( + value, + attachment_store_get_background_options ( + E_ATTACHMENT_STORE (object))); + return; + + case PROP_CURRENT_FOLDER: + g_value_set_string ( + value, + e_attachment_store_get_current_folder ( + E_ATTACHMENT_STORE (object))); + return; + + case PROP_NUM_ATTACHMENTS: + g_value_set_uint ( + value, + e_attachment_store_get_num_attachments ( + E_ATTACHMENT_STORE (object))); + return; + + case PROP_NUM_DOWNLOADING: + g_value_set_uint ( + value, + e_attachment_store_get_num_downloading ( + E_ATTACHMENT_STORE (object))); + return; + + case PROP_TOTAL_SIZE: + g_value_set_uint64 ( + value, + e_attachment_store_get_total_size ( + E_ATTACHMENT_STORE (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_store_dispose (GObject *object) +{ + EAttachmentStorePrivate *priv; + + priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); + + g_hash_table_remove_all (priv->activity_index); + g_hash_table_remove_all (priv->attachment_index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_store_finalize (GObject *object) +{ + EAttachmentStorePrivate *priv; + + priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); + + g_hash_table_destroy (priv->activity_index); + g_hash_table_destroy (priv->attachment_index); + + g_free (priv->background_filename); + g_free (priv->background_options); + g_free (priv->current_folder); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +attachment_store_constructed (GObject *object) +{ + EAttachmentStorePrivate *priv; + GConfBridge *bridge; + const gchar *prop; + const gchar *key; + + priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); + bridge = gconf_bridge_get (); + + prop = "background-filename"; + key = "/desktop/gnome/background/picture_filename"; + gconf_bridge_bind_property (bridge, key, object, prop); + + prop = "background-options"; + key = "/desktop/gnome/background/picture_options"; + gconf_bridge_bind_property (bridge, key, object, prop); +} + +static void +attachment_store_row_changed (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter) +{ + EAttachmentStorePrivate *priv; + EAttachment *attachment; + GtkIconTheme *icon_theme; + GdkPixbuf *large_pixbuf; + GdkPixbuf *small_pixbuf; + GIcon *icon; + const gchar *content_type; + const gchar *display_name; + const gchar *thumbnail_path; + gchar *content_description; + gchar *display_size; + gchar *icon_caption; + gint large_icon_size; + gint small_icon_size; + guint64 size; + gint column_id; + GError *error = NULL; + + priv = E_ATTACHMENT_STORE_GET_PRIVATE (model); + + if (priv->ignore_row_changed) + return; + + icon_theme = gtk_icon_theme_get_default (); + gtk_icon_size_lookup (LARGE_ICON_SIZE, &large_icon_size, NULL); + gtk_icon_size_lookup (SMALL_ICON_SIZE, &small_icon_size, NULL); + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, iter, column_id, &attachment, -1); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + content_type = e_attachment_get_content_type (attachment); + display_name = e_attachment_get_display_name (attachment); + thumbnail_path = e_attachment_get_thumbnail_path (attachment); + icon = e_attachment_get_icon (attachment); + size = e_attachment_get_size (attachment); + + content_type = (content_type != NULL) ? content_type : ""; + content_description = g_content_type_get_description (content_type); + display_size = g_format_size_for_display ((goffset) size); + + if (size > 0) + icon_caption = g_strdup_printf ( + "%s\n(%s)", display_name, display_size); + else + icon_caption = g_strdup (display_name); + + /* Prefer the thumbnail if we have one. */ + if (thumbnail_path != NULL) { + gint width = -1; + gint height = -1; + + gdk_pixbuf_get_file_info (thumbnail_path, &width, &height); + + large_pixbuf = gdk_pixbuf_new_from_file_at_scale ( + thumbnail_path, + (width > height) ? large_icon_size : -1, + (width > height) ? -1 : large_icon_size, + TRUE, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_clear_error (&error); + } + + small_pixbuf = gdk_pixbuf_new_from_file_at_scale ( + thumbnail_path, + (width > height) ? small_icon_size : -1, + (width > height) ? -1 : small_icon_size, + TRUE, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_clear_error (&error); + } + + /* Otherwise fall back to the icon theme. */ + } else { + GtkIconInfo *icon_info = NULL; + const gchar *filename; + + if (G_IS_ICON (icon)) + icon_info = gtk_icon_theme_lookup_by_gicon ( + icon_theme, icon, large_icon_size, 0); + if (icon_info == NULL) + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, DEFAULT_ICON_NAME, + large_icon_size, 0); + g_return_if_fail (icon_info != NULL); + + filename = gtk_icon_info_get_filename (icon_info); + large_pixbuf = gdk_pixbuf_new_from_file (filename, &error); + gtk_icon_info_free (icon_info); + + if (error != NULL) { + g_warning ("%s", error->message); + g_clear_error (&error); + } + + icon_info = NULL; + + if (G_IS_ICON (icon)) + icon_info = gtk_icon_theme_lookup_by_gicon ( + icon_theme, icon, small_icon_size, 0); + if (icon_info == NULL) + icon_info = gtk_icon_theme_lookup_icon ( + icon_theme, DEFAULT_ICON_NAME, + small_icon_size, 0); + g_return_if_fail (icon_info != NULL); + + filename = gtk_icon_info_get_filename (icon_info); + small_pixbuf = gdk_pixbuf_new_from_file (filename, &error); + gtk_icon_info_free (icon_info); + + if (error != NULL) { + g_warning ("%s", error->message); + g_clear_error (&error); + } + } + + /* We're about to trigger another "row-changed" + * signal, so this prevents infinite recursion. */ + priv->ignore_row_changed = TRUE; + + gtk_list_store_set ( + GTK_LIST_STORE (model), iter, + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_description, + E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, + E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION, icon_caption, + E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF, large_pixbuf, + E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF, small_pixbuf, + E_ATTACHMENT_STORE_COLUMN_SIZE, size, + -1); + + priv->ignore_row_changed = FALSE; + + if (large_pixbuf != NULL) + g_object_unref (large_pixbuf); + + if (small_pixbuf != NULL) + g_object_unref (small_pixbuf); + + g_free (content_description); + g_free (display_size); +} + +static void +attachment_store_class_init (EAttachmentStoreClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentStorePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_store_set_property; + object_class->get_property = attachment_store_get_property; + object_class->dispose = attachment_store_dispose; + object_class->finalize = attachment_store_finalize; + object_class->constructed = attachment_store_constructed; + + g_object_class_install_property ( + object_class, + PROP_BACKGROUND_FILENAME, + g_param_spec_string ( + "background-filename", + "Background Filename", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_BACKGROUND_OPTIONS, + g_param_spec_string ( + "background-options", + "Background Options", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_CURRENT_FOLDER, + g_param_spec_string ( + "current-folder", + "Current Folder", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_NUM_ATTACHMENTS, + g_param_spec_uint ( + "num-attachments", + "Num Attachments", + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_NUM_DOWNLOADING, + g_param_spec_uint ( + "num-downloading", + "Num Downloading", + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_TOTAL_SIZE, + g_param_spec_uint64 ( + "total-size", + "Total Size", + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); +} + +static void +attachment_store_iface_init (GtkTreeModelIface *iface) +{ + iface->row_changed = attachment_store_row_changed; +} + +static void +attachment_store_init (EAttachmentStore *store) +{ + GType types[E_ATTACHMENT_STORE_NUM_COLUMNS]; + GHashTable *activity_index; + GHashTable *attachment_index; + gint column = 0; + + activity_index = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) gtk_tree_row_reference_free); + + attachment_index = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) gtk_tree_row_reference_free); + + store->priv = E_ATTACHMENT_STORE_GET_PRIVATE (store); + store->priv->activity_index = activity_index; + store->priv->attachment_index = attachment_index; + + types[column++] = E_TYPE_ACTIVITY; /* COLUMN_ACTIVITY */ + types[column++] = E_TYPE_ATTACHMENT; /* COLUMN_ATTACHMENT */ + types[column++] = G_TYPE_STRING; /* COLUMN_CONTENT_TYPE */ + types[column++] = G_TYPE_STRING; /* COLUMN_DISPLAY_NAME */ + types[column++] = G_TYPE_STRING; /* COLUMN_ICON_CAPTION */ + types[column++] = GDK_TYPE_PIXBUF; /* COLUMN_LARGE_PIXBUF */ + types[column++] = GDK_TYPE_PIXBUF; /* COLUMN_SMALL_PIXBUF */ + types[column++] = G_TYPE_UINT64; /* COLUMN_SIZE */ + + g_assert (column == E_ATTACHMENT_STORE_NUM_COLUMNS); + + gtk_list_store_set_column_types ( + GTK_LIST_STORE (store), G_N_ELEMENTS (types), types); +} + +GType +e_attachment_store_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentStoreClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_store_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentStore), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_store_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) attachment_store_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + type = g_type_register_static ( + GTK_TYPE_LIST_STORE, "EAttachmentStore", + &type_info, 0); + + g_type_add_interface_static ( + type, GTK_TYPE_TREE_MODEL, &iface_info); + } + + return type; +} + +GtkTreeModel * +e_attachment_store_new (void) +{ + return g_object_new (E_TYPE_ATTACHMENT_STORE, NULL); +} + +void +e_attachment_store_add_attachment (EAttachmentStore *store, + EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GFile *file; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + gtk_list_store_append (GTK_LIST_STORE (store), &iter); + + gtk_list_store_set ( + GTK_LIST_STORE (store), &iter, + E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, attachment, -1); + + model = GTK_TREE_MODEL (store); + path = gtk_tree_model_get_path (model, &iter); + reference = gtk_tree_row_reference_new (model, path); + gtk_tree_path_free (path); + + g_hash_table_insert ( + store->priv->attachment_index, + g_object_ref (attachment), reference); + + file = e_attachment_get_file (attachment); + + /* This lets the attachment tell us when to update. */ + _e_attachment_set_reference (attachment, reference); + + if (!g_file_is_native (file)) + attachment_store_copy_async (store, attachment); + + g_object_freeze_notify (G_OBJECT (store)); + g_object_notify (G_OBJECT (store), "num-attachments"); + g_object_notify (G_OBJECT (store), "total-size"); + g_object_thaw_notify (G_OBJECT (store)); +} + +gboolean +e_attachment_store_remove_attachment (EAttachmentStore *store, + EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GHashTable *hash_table; + EActivity *activity; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + hash_table = store->priv->attachment_index; + reference = g_hash_table_lookup (hash_table, attachment); + + if (reference == NULL) + return FALSE; + + if (!gtk_tree_row_reference_valid (reference)) { + g_hash_table_remove (hash_table, attachment); + return FALSE; + } + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + gtk_tree_model_get ( + model, &iter, + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, &activity, -1); + + if (activity != NULL) { + /* Cancel the file transfer. */ + e_activity_cancel (activity); + g_object_unref (activity); + } + + gtk_list_store_remove (GTK_LIST_STORE (store), &iter); + g_hash_table_remove (hash_table, attachment); + + g_object_freeze_notify (G_OBJECT (store)); + g_object_notify (G_OBJECT (store), "num-attachments"); + g_object_notify (G_OBJECT (store), "total-size"); + g_object_thaw_notify (G_OBJECT (store)); + + return TRUE; +} + +void +e_attachment_store_add_to_multipart (EAttachmentStore *store, + CamelMultipart *multipart, + const gchar *default_charset) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean valid; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (CAMEL_MULTIPART (multipart)); + + model = GTK_TREE_MODEL (store); + valid = gtk_tree_model_get_iter_first (model, &iter); + + while (valid) { + EAttachment *attachment; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + + e_attachment_add_to_multipart ( + attachment, multipart, default_charset); + + g_object_unref (attachment); + + valid = gtk_tree_model_iter_next (model, &iter); + } +} + +const gchar * +e_attachment_store_get_current_folder (EAttachmentStore *store) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); + + return store->priv->current_folder; +} + +void +e_attachment_store_set_current_folder (EAttachmentStore *store, + const gchar *current_folder) +{ + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + + if (current_folder == NULL) + current_folder = g_get_home_dir (); + + g_free (store->priv->current_folder); + store->priv->current_folder = g_strdup (current_folder); + + g_object_notify (G_OBJECT (store), "current-folder"); +} + +guint +e_attachment_store_get_num_attachments (EAttachmentStore *store) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); + + return g_hash_table_size (store->priv->attachment_index); +} + +guint +e_attachment_store_get_num_downloading (EAttachmentStore *store) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); + + return g_hash_table_size (store->priv->activity_index); +} + +guint64 +e_attachment_store_get_total_size (EAttachmentStore *store) +{ + GtkTreeModel *model; + GtkTreeIter iter; + guint64 total_size = 0; + gboolean valid; + + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); + + model = GTK_TREE_MODEL (store); + valid = gtk_tree_model_get_iter_first (model, &iter); + + while (valid) { + EAttachment *attachment; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + total_size += e_attachment_get_size (attachment); + g_object_unref (attachment); + + valid = gtk_tree_model_iter_next (model, &iter); + } + + return total_size; +} + +gint +e_attachment_store_run_file_chooser_dialog (EAttachmentStore *store, + GtkWidget *dialog) +{ + GtkFileChooser *file_chooser; + gint response = GTK_RESPONSE_NONE; + const gchar *current_folder; + gboolean update_folder; + + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), response); + g_return_val_if_fail (GTK_IS_FILE_CHOOSER_DIALOG (dialog), response); + + file_chooser = GTK_FILE_CHOOSER (dialog); + current_folder = e_attachment_store_get_current_folder (store); + gtk_file_chooser_set_current_folder (file_chooser, current_folder); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + update_folder = + (response == GTK_RESPONSE_ACCEPT) || + (response == GTK_RESPONSE_OK) || + (response == GTK_RESPONSE_YES) || + (response == GTK_RESPONSE_APPLY); + + if (update_folder) { + gchar *folder; + + folder = gtk_file_chooser_get_current_folder (file_chooser); + e_attachment_store_set_current_folder (store, folder); + g_free (folder); + } + + return response; +} + +void +e_attachment_store_run_load_dialog (EAttachmentStore *store, + GtkWindow *parent) +{ + GtkFileChooser *file_chooser; + GtkWidget *dialog; + GtkWidget *option; + GSList *files, *iter; + const gchar *disposition; + gboolean active; + gint response; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + + dialog = gtk_file_chooser_dialog_new ( + _("Add Attachment"), parent, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("A_ttach"), GTK_RESPONSE_OK, NULL); + + file_chooser = GTK_FILE_CHOOSER (dialog); + gtk_file_chooser_set_local_only (file_chooser, FALSE); + gtk_file_chooser_set_select_multiple (file_chooser, TRUE); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); + + option = gtk_check_button_new_with_mnemonic ( + _("_Suggest automatic display of attachment")); + gtk_file_chooser_set_extra_widget (file_chooser, option); + gtk_widget_show (option); + + response = e_attachment_store_run_file_chooser_dialog (store, dialog); + + if (response != GTK_RESPONSE_OK) + goto exit; + + files = gtk_file_chooser_get_files (file_chooser); + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option)); + disposition = active ? "inline" : "attachment"; + + for (iter = files; iter != NULL; iter = g_slist_next (iter)) { + EAttachment *attachment; + GFile *file = iter->data; + + attachment = e_attachment_new (); + e_attachment_set_file (attachment, file); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + } + + g_slist_foreach (files, (GFunc) g_object_unref, NULL); + g_slist_free (files); + +exit: + gtk_widget_destroy (dialog); +} + +void +e_attachment_store_run_save_dialog (EAttachmentStore *store, + EAttachment *attachment, + GtkWindow *parent) +{ + GtkFileChooser *file_chooser; + GtkWidget *dialog; + GFile *file; + EActivity *activity; + const gchar *display_name; + gint response; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + dialog = gtk_file_chooser_dialog_new ( + _("Save Attachment"), parent, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); + + file_chooser = GTK_FILE_CHOOSER (dialog); + gtk_file_chooser_set_local_only (file_chooser, FALSE); + gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); + + display_name = e_attachment_get_display_name (attachment); + if (display_name != NULL) + gtk_file_chooser_set_current_name (file_chooser, display_name); + + response = e_attachment_store_run_file_chooser_dialog (store, dialog); + + if (response != GTK_RESPONSE_OK) + goto exit; + + file = gtk_file_chooser_get_file (file_chooser); + activity = e_file_activity_new (_("Saving attachment")); + e_attachment_save_async ( + attachment, E_FILE_ACTIVITY (activity), file); + g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity); + g_object_unref (activity); + g_object_unref (file); + +exit: + gtk_widget_destroy (dialog); +} diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h new file mode 100644 index 0000000000..906aee6638 --- /dev/null +++ b/widgets/misc/e-attachment-store.h @@ -0,0 +1,110 @@ +/* + * e-attachment-store.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_STORE_H +#define E_ATTACHMENT_STORE_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_STORE \ + (e_attachment_store_get_type ()) +#define E_ATTACHMENT_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStore)) +#define E_ATTACHMENT_STORE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_STORE, EAttachmentStoreClass)) +#define E_IS_ATTACHMENT_STORE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_STORE)) +#define E_IS_ATTACHMENT_STORE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_STORE)) +#define E_ATTACHMENT_STORE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStoreClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentStore EAttachmentStore; +typedef struct _EAttachmentStoreClass EAttachmentStoreClass; +typedef struct _EAttachmentStorePrivate EAttachmentStorePrivate; + +struct _EAttachmentStore { + GtkListStore parent; + EAttachmentStorePrivate *priv; +}; + +struct _EAttachmentStoreClass { + GtkListStoreClass parent_class; +}; + +enum { + E_ATTACHMENT_STORE_COLUMN_ACTIVITY, /* E_TYPE_ACTIVITY */ + E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, /* E_TYPE_ATTACHMENT */ + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */ + E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, /* G_TYPE_STRING */ + E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION, /* G_TYPE_STRING */ + E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF, /* GDK_TYPE_PIXBUF */ + E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF, /* GDK_TYPE_PIXBUF */ + E_ATTACHMENT_STORE_COLUMN_SIZE, /* G_TYPE_UINT64 */ + E_ATTACHMENT_STORE_NUM_COLUMNS +}; + +GType e_attachment_store_get_type (void); +GtkTreeModel * e_attachment_store_new (void); +void e_attachment_store_add_attachment + (EAttachmentStore *store, + EAttachment *attachment); +gboolean e_attachment_store_remove_attachment + (EAttachmentStore *store, + EAttachment *attachment); +void e_attachment_store_add_to_multipart + (EAttachmentStore *store, + CamelMultipart *multipart, + const gchar *default_charset); +const gchar * e_attachment_store_get_current_folder + (EAttachmentStore *store); +void e_attachment_store_set_current_folder + (EAttachmentStore *store, + const gchar *current_folder); +guint e_attachment_store_get_num_attachments + (EAttachmentStore *store); +guint e_attachment_store_get_num_downloading + (EAttachmentStore *store); +guint64 e_attachment_store_get_total_size + (EAttachmentStore *store); +gint e_attachment_store_run_file_chooser_dialog + (EAttachmentStore *store, + GtkWidget *dialog); +void e_attachment_store_run_load_dialog + (EAttachmentStore *store, + GtkWindow *parent); +void e_attachment_store_run_save_dialog + (EAttachmentStore *store, + EAttachment *attachment, + GtkWindow *parent); + +G_END_DECLS + +#endif /* E_ATTACHMENT_STORE_H */ diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c new file mode 100644 index 0000000000..817a6c7dab --- /dev/null +++ b/widgets/misc/e-attachment-tree-view.c @@ -0,0 +1,396 @@ +/* + * e-attachment-tree-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-tree-view.h" + +#include +#include + +#include "e-attachment.h" +#include "e-attachment-store.h" +#include "e-attachment-view.h" + +#define E_ATTACHMENT_TREE_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewPrivate)) + +struct _EAttachmentTreeViewPrivate { + EAttachmentViewPrivate view_priv; +}; + +static gpointer parent_class; + +static void +attachment_tree_view_dispose (GObject *object) +{ + e_attachment_view_dispose (E_ATTACHMENT_VIEW (object)); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_tree_view_finalize (GObject *object) +{ + e_attachment_view_finalize (E_ATTACHMENT_VIEW (object)); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +attachment_tree_view_render_size (GtkTreeViewColumn *column, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter) +{ + gchar *display_size; + gint column_id; + guint64 size; + + column_id = E_ATTACHMENT_STORE_COLUMN_SIZE; + gtk_tree_model_get (model, iter, column_id, &size, -1); + + display_size = g_format_size_for_display ((goffset) size); + g_object_set (renderer, "text", display_size, NULL); + g_free (display_size); +} + +static gboolean +attachment_tree_view_button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { + e_attachment_view_show_popup_menu (view, event); + return TRUE; + } + + /* Chain up to parent's button_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_press_event (widget, event); +} + +static gboolean +attachment_tree_view_key_press_event (GtkWidget *widget, + GdkEventKey *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (event->keyval == GDK_Delete) { + e_attachment_view_remove_selected (view, TRUE); + return TRUE; + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + key_press_event (widget, event); +} + +static gboolean +attachment_tree_view_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + return e_attachment_view_drag_motion (view, context, x, y, time); +} + +static void +attachment_tree_view_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_drag_data_received ( + view, context, x, y, selection, info, time); +} + +static gboolean +attachment_tree_view_popup_menu (GtkWidget *widget) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_show_popup_menu (view, NULL); + + return TRUE; +} + +static EAttachmentViewPrivate * +attachment_tree_view_get_private (EAttachmentView *view) +{ + EAttachmentTreeViewPrivate *priv; + + priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (view); + + return &priv->view_priv; +} + +static EAttachmentStore * +attachment_tree_view_get_store (EAttachmentView *view) +{ + GtkTreeView *tree_view; + GtkTreeModel *model; + + tree_view = GTK_TREE_VIEW (view); + model = gtk_tree_view_get_model (tree_view); + + return E_ATTACHMENT_STORE (model); +} + +static GtkTreePath * +attachment_tree_view_get_path_at_pos (EAttachmentView *view, + gint x, + gint y) +{ + GtkTreeView *tree_view; + GtkTreePath *path; + gboolean row_exists; + + tree_view = GTK_TREE_VIEW (view); + + row_exists = gtk_tree_view_get_path_at_pos ( + tree_view, x, y, &path, NULL, NULL, NULL); + + return row_exists ? path : NULL; +} + +static GList * +attachment_tree_view_get_selected_paths (EAttachmentView *view) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + return gtk_tree_selection_get_selected_rows (selection, NULL); +} + +static gboolean +attachment_tree_view_path_is_selected (EAttachmentView *view, + GtkTreePath *path) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + return gtk_tree_selection_path_is_selected (selection, path); +} + +static void +attachment_tree_view_select_path (EAttachmentView *view, + GtkTreePath *path) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + gtk_tree_selection_select_path (selection, path); +} + +static void +attachment_tree_view_unselect_path (EAttachmentView *view, + GtkTreePath *path) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + gtk_tree_selection_unselect_path (selection, path); +} + +static void +attachment_tree_view_select_all (EAttachmentView *view) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + gtk_tree_selection_select_all (selection); +} + +static void +attachment_tree_view_unselect_all (EAttachmentView *view) +{ + GtkTreeView *tree_view; + GtkTreeSelection *selection; + + tree_view = GTK_TREE_VIEW (view); + selection = gtk_tree_view_get_selection (tree_view); + + gtk_tree_selection_unselect_all (selection); +} + +static void +attachment_tree_view_class_init (EAttachmentTreeViewClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = attachment_tree_view_dispose; + object_class->finalize = attachment_tree_view_finalize; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->button_press_event = attachment_tree_view_button_press_event; + widget_class->key_press_event = attachment_tree_view_key_press_event; + widget_class->drag_motion = attachment_tree_view_drag_motion; + widget_class->drag_data_received = attachment_tree_view_drag_data_received; + widget_class->popup_menu = attachment_tree_view_popup_menu; +} + +static void +attachment_tree_view_iface_init (EAttachmentViewIface *iface) +{ + iface->get_private = attachment_tree_view_get_private; + iface->get_store = attachment_tree_view_get_store; + + iface->get_path_at_pos = attachment_tree_view_get_path_at_pos; + iface->get_selected_paths = attachment_tree_view_get_selected_paths; + iface->path_is_selected = attachment_tree_view_path_is_selected; + iface->select_path = attachment_tree_view_select_path; + iface->unselect_path = attachment_tree_view_unselect_path; + iface->select_all = attachment_tree_view_select_all; + iface->unselect_all = attachment_tree_view_unselect_all; +} + +static void +attachment_tree_view_init (EAttachmentTreeView *tree_view) +{ + GtkTreeSelection *selection; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + tree_view->priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (tree_view); + + e_attachment_view_init (E_ATTACHMENT_VIEW (tree_view)); + + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_column_set_spacing (column, 3); + gtk_tree_view_column_set_title (column, _("Name")); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, FALSE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "pixbuf", + E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "text", + E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Size")); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_set_cell_data_func ( + column, renderer, (GtkTreeCellDataFunc) + attachment_tree_view_render_size, NULL, NULL); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Type")); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "text", + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE); +} + +GType +e_attachment_tree_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentTreeViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_tree_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentTreeView), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_tree_view_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) attachment_tree_view_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + type = g_type_register_static ( + GTK_TYPE_TREE_VIEW, "EAttachmentTreeView", + &type_info, 0); + + g_type_add_interface_static ( + type, E_TYPE_ATTACHMENT_VIEW, &iface_info); + } + + return type; +} + +GtkWidget * +e_attachment_tree_view_new (void) +{ + return g_object_new (E_TYPE_ATTACHMENT_TREE_VIEW, NULL); +} diff --git a/widgets/misc/e-attachment-tree-view.h b/widgets/misc/e-attachment-tree-view.h new file mode 100644 index 0000000000..7f16ba5ab2 --- /dev/null +++ b/widgets/misc/e-attachment-tree-view.h @@ -0,0 +1,66 @@ +/* + * e-attachment-tree-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_TREE_VIEW_H +#define E_ATTACHMENT_TREE_VIEW_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_TREE_VIEW \ + (e_attachment_tree_view_get_type ()) +#define E_ATTACHMENT_TREE_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeView)) +#define E_ATTACHMENT_TREE_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewClass)) +#define E_IS_ATTACHMENT_TREE_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_TREE_VIEW)) +#define E_IS_ATTACHMENT_TREE_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_TREE_VIEW)) +#define E_ATTACHMENT_TREE_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentTreeView EAttachmentTreeView; +typedef struct _EAttachmentTreeViewClass EAttachmentTreeViewClass; +typedef struct _EAttachmentTreeViewPrivate EAttachmentTreeViewPrivate; + +struct _EAttachmentTreeView { + GtkTreeView parent; + EAttachmentTreeViewPrivate *priv; +}; + +struct _EAttachmentTreeViewClass { + GtkTreeViewClass parent_class; +}; + +GType e_attachment_tree_view_get_type (void); +GtkWidget * e_attachment_tree_view_new (void); + +G_END_DECLS + +#endif /* E_ATTACHMENT_TREE_VIEW_H */ diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c new file mode 100644 index 0000000000..198ce75d31 --- /dev/null +++ b/widgets/misc/e-attachment-view.c @@ -0,0 +1,1041 @@ +/* + * e-attachment-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-view.h" + +#include +#include +#include + +#include "e-util/e-plugin-ui.h" +#include "e-util/e-util.h" +#include "e-attachment-dialog.h" + +enum { + DND_TYPE_MESSAGE_RFC822, + DND_TYPE_X_UID_LIST, + DND_TYPE_TEXT_URI_LIST, + DND_TYPE_NETSCAPE_URL, + DND_TYPE_TEXT_VCARD, + DND_TYPE_TEXT_CALENDAR +}; + +static GtkTargetEntry drop_types[] = { + { "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 }, + { "x-uid-list", 0, DND_TYPE_X_UID_LIST }, + { "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST }, + { "_NETSCAPE_URL", 0, DND_TYPE_NETSCAPE_URL }, + { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD }, + { "text/calendar", 0, DND_TYPE_TEXT_CALENDAR } +}; + +/* The atoms need initialized at runtime. */ +static struct { + const gchar *target; + GdkAtom atom; + GdkDragAction actions; +} drag_info[] = { + { "message/rfc822", NULL, GDK_ACTION_COPY }, + { "x-uid-list", NULL, GDK_ACTION_COPY | + GDK_ACTION_MOVE | + GDK_ACTION_ASK }, + { "text/uri-list", NULL, GDK_ACTION_COPY }, + { "_NETSCAPE_URL", NULL, GDK_ACTION_COPY }, + { "text/x-vcard", NULL, GDK_ACTION_COPY }, + { "text/calendar", NULL, GDK_ACTION_COPY } +}; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static void +action_add_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachmentStore *store; + gpointer parent; + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + store = e_attachment_view_get_store (view); + e_attachment_store_run_load_dialog (store, parent); +} + +static void +action_drag_cancel_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + priv = e_attachment_view_get_private (view); + gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); +} + +static void +action_drag_copy_cb (GtkAction *action, + EAttachmentView *view) +{ + e_attachment_view_drag_action (view, GDK_ACTION_COPY); +} + +static void +action_drag_move_cb (GtkAction *action, + EAttachmentView *view) +{ + e_attachment_view_drag_action (view, GDK_ACTION_MOVE); +} + +static void +action_properties_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + GtkWidget *dialog; + GList *selected; + gpointer parent; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = selected->data; + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + dialog = e_attachment_dialog_new (parent, attachment); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +action_recent_cb (GtkAction *action, + EAttachmentView *view) +{ + GtkRecentChooser *chooser; + EAttachmentStore *store; + EAttachment *attachment; + gchar *uri; + + chooser = GTK_RECENT_CHOOSER (action); + store = e_attachment_view_get_store (view); + + uri = gtk_recent_chooser_get_current_uri (chooser); + attachment = e_attachment_new_for_uri (uri); + e_attachment_store_add_attachment (store, attachment); + g_free (uri); +} + +static void +action_remove_cb (GtkAction *action, + EAttachmentView *view) +{ + e_attachment_view_remove_selected (view, FALSE); +} + +static void +action_save_as_cb (GtkAction *action, + EAttachmentView *view) +{ +} + +static void +action_set_background_cb (GtkAction *action, + EAttachmentView *view) +{ +} + +static GtkActionEntry standard_entries[] = { + + { "drag-cancel", + NULL, + N_("Cancel _Drag"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_drag_cancel_cb) }, + + { "drag-copy", + NULL, + N_("_Copy"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_drag_copy_cb) }, + + { "drag-move", + NULL, + N_("_Move"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_drag_move_cb) }, + + { "save-as", + GTK_STOCK_SAVE_AS, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_save_as_cb) }, + + { "set-background", + NULL, + N_("Set as _Background"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_set_background_cb) } +}; + +static GtkActionEntry editable_entries[] = { + + { "add", + GTK_STOCK_ADD, + N_("A_dd Attachment..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_add_cb) }, + + { "properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_properties_cb) }, + + { "remove", + GTK_STOCK_REMOVE, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_remove_cb) } +}; + +static void +drop_message_rfc822 (EAttachmentView *view, + GtkSelectionData *selection_data, + EAttachmentStore *store, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + EAttachment *attachment; + CamelMimeMessage *message; + CamelDataWrapper *wrapper; + CamelStream *stream; + const gchar *data; + gboolean success = FALSE; + gboolean delete = FALSE; + gint length; + + priv = e_attachment_view_get_private (view); + + data = (const gchar *) gtk_selection_data_get_data (selection_data); + length = gtk_selection_data_get_length (selection_data); + + stream = camel_stream_mem_new (); + camel_stream_write (stream, data, length); + camel_stream_reset (stream); + + message = camel_mime_message_new (); + wrapper = CAMEL_DATA_WRAPPER (message); + + if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1) + goto exit; + + attachment = e_attachment_new_for_message (message); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + + success = TRUE; + delete = (action == GDK_ACTION_MOVE); + +exit: + camel_object_unref (message); + camel_object_unref (stream); + + gtk_drag_finish (priv->drag_context, success, delete, priv->time); +} + +static void +drop_netscape_url (EAttachmentView *view, + GtkSelectionData *selection_data, + EAttachmentStore *store, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + EAttachment *attachment; + const gchar *data; + gchar *copied_data; + gchar **strv; + gint length; + + /* _NETSCAPE_URL is represented as "URI\nTITLE" */ + + priv = e_attachment_view_get_private (view); + + data = (const gchar *) gtk_selection_data_get_data (selection_data); + length = gtk_selection_data_get_length (selection_data); + + copied_data = g_strndup (data, length); + strv = g_strsplit (copied_data, "\n", 2); + g_free (copied_data); + + attachment = e_attachment_new_for_uri (strv[0]); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + + g_strfreev (strv); + + gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); +} + +static void +drop_text_uri_list (EAttachmentView *view, + GtkSelectionData *selection_data, + EAttachmentStore *store, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + gchar **uris; + gint ii; + + priv = e_attachment_view_get_private (view); + + uris = gtk_selection_data_get_uris (selection_data); + + for (ii = 0; uris[ii] != NULL; ii++) { + EAttachment *attachment; + + attachment = e_attachment_new_for_uri (uris[ii]); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + } + + g_strfreev (uris); + + gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); +} + +static void +drop_text_generic (EAttachmentView *view, + GtkSelectionData *selection_data, + EAttachmentStore *store, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + EAttachment *attachment; + CamelMimePart *mime_part; + GdkAtom atom; + const gchar *data; + gchar *content_type; + gint length; + + priv = e_attachment_view_get_private (view); + + data = (const gchar *) gtk_selection_data_get_data (selection_data); + length = gtk_selection_data_get_length (selection_data); + atom = gtk_selection_data_get_data_type (selection_data); + + mime_part = camel_mime_part_new (); + + content_type = gdk_atom_name (atom); + camel_mime_part_set_content (mime_part, data, length, content_type); + camel_mime_part_set_disposition (mime_part, "inline"); + g_free (content_type); + + attachment = e_attachment_new (); + e_attachment_set_mime_part (attachment, mime_part); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + + camel_object_unref (mime_part); + + gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); +} + +static void +drop_x_uid_list (EAttachmentView *view, + GtkSelectionData *selection_data, + EAttachmentStore *store, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + + /* FIXME Ugh, this looks painful. Requires mailer stuff. */ + + priv = e_attachment_view_get_private (view); + + gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); +} + +static void +attachment_view_class_init (EAttachmentViewIface *iface) +{ + gint ii; + + for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) { + const gchar *target = drag_info[ii].target; + drag_info[ii].atom = gdk_atom_intern (target, FALSE); + } +} + +GType +e_attachment_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentViewIface), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_INTERFACE, "EAttachmentView", &type_info, 0); + + g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET); + } + + return type; +} + +void +e_attachment_view_init (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + GtkUIManager *ui_manager; + GtkActionGroup *action_group; + const gchar *domain = GETTEXT_PACKAGE; + GError *error = NULL; + + priv = e_attachment_view_get_private (view); + + gtk_drag_dest_set ( + GTK_WIDGET (view), GTK_DEST_DEFAULT_ALL, + drop_types, G_N_ELEMENTS (drop_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); + + ui_manager = gtk_ui_manager_new (); + priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); + priv->ui_manager = ui_manager; + + action_group = gtk_action_group_new ("standard"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), view); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + priv->standard_actions = action_group; + + action_group = gtk_action_group_new ("editable"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_action_group_add_actions ( + action_group, editable_entries, + G_N_ELEMENTS (editable_entries), view); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + priv->editable_actions = action_group; + + action_group = gtk_action_group_new ("openwith"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + priv->openwith_actions = action_group; + + /* Because we are loading from a hard-coded string, there is + * no chance of I/O errors. Failure here implies a malformed + * UI definition. Full stop. */ + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + if (error != NULL) + g_error ("%s", error->message); + + e_plugin_ui_register_manager (ui_manager, "attachment-view", view); +} + +void +e_attachment_view_dispose (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + priv = e_attachment_view_get_private (view); + + if (priv->ui_manager != NULL) { + g_object_unref (priv->ui_manager); + priv->ui_manager = NULL; + } + + if (priv->standard_actions != NULL) { + g_object_unref (priv->standard_actions); + priv->standard_actions = NULL; + } + + if (priv->editable_actions != NULL) { + g_object_unref (priv->editable_actions); + priv->editable_actions = NULL; + } + + if (priv->openwith_actions != NULL) { + g_object_unref (priv->openwith_actions); + priv->openwith_actions = NULL; + } + + if (priv->drag_context != NULL) { + g_object_unref (priv->drag_context); + priv->drag_context = NULL; + } +} + +void +e_attachment_view_finalize (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + priv = e_attachment_view_get_private (view); + + if (priv->selection_data != NULL) + gtk_selection_data_free (priv->selection_data); +} + +EAttachmentViewPrivate * +e_attachment_view_get_private (EAttachmentView *view) +{ + EAttachmentViewIface *iface; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_val_if_fail (iface->get_private != NULL, NULL); + + return iface->get_private (view); +} + +EAttachmentStore * +e_attachment_view_get_store (EAttachmentView *view) +{ + EAttachmentViewIface *iface; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_val_if_fail (iface->get_store != NULL, NULL); + + return iface->get_store (view); +} + +GList * +e_attachment_view_get_selected_attachments (EAttachmentView *view) +{ + EAttachmentStore *store; + GtkTreeModel *model; + GList *selected, *item; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + selected = e_attachment_view_get_selected_paths (view); + store = e_attachment_view_get_store (view); + model = GTK_TREE_MODEL (store); + + /* Convert the GtkTreePaths to EAttachments. */ + for (item = selected; item != NULL; item = item->next) { + EAttachment *attachment; + GtkTreePath *path; + GtkTreeIter iter; + + path = item->data; + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + gtk_tree_path_free (path); + + item->data = attachment; + } + + return selected; +} +void +e_attachment_view_remove_selected (EAttachmentView *view, + gboolean select_next) +{ + EAttachmentStore *store; + GtkTreeModel *model; + GList *selected, *item; + gint column_id; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + selected = e_attachment_view_get_selected_paths (view); + store = e_attachment_view_get_store (view); + model = GTK_TREE_MODEL (store); + + for (item = selected; item != NULL; item = item->next) { + EAttachment *attachment; + GtkTreePath *path = item->data; + GtkTreeIter iter; + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + e_attachment_store_remove_attachment (store, attachment); + g_object_unref (attachment); + } + + /* If we only removed one attachment, try to select another. */ + if (select_next && g_list_length (selected) == 1) { + GtkTreePath *path = selected->data; + + e_attachment_view_select_path (view, path); + if (!e_attachment_view_path_is_selected (view, path)) + if (gtk_tree_path_prev (path)) + e_attachment_view_select_path (view, path); + } + + g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected); +} + +GtkTreePath * +e_attachment_view_get_path_at_pos (EAttachmentView *view, + gint x, + gint y) +{ + EAttachmentViewIface *iface; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_val_if_fail (iface->get_path_at_pos != NULL, NULL); + + return iface->get_path_at_pos (view, x, y); +} + +GList * +e_attachment_view_get_selected_paths (EAttachmentView *view) +{ + EAttachmentViewIface *iface; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_val_if_fail (iface->get_selected_paths != NULL, NULL); + + return iface->get_selected_paths (view); +} + +gboolean +e_attachment_view_path_is_selected (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentViewIface *iface; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_val_if_fail (iface->path_is_selected != NULL, FALSE); + + return iface->path_is_selected (view, path); +} + +void +e_attachment_view_select_path (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentViewIface *iface; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (path != NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_if_fail (iface->select_path != NULL); + + iface->select_path (view, path); +} + +void +e_attachment_view_unselect_path (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentViewIface *iface; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (path != NULL); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_if_fail (iface->unselect_path != NULL); + + iface->unselect_path (view, path); +} + +void +e_attachment_view_select_all (EAttachmentView *view) +{ + EAttachmentViewIface *iface; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_if_fail (iface->select_all != NULL); + + iface->select_all (view); +} + +void +e_attachment_view_unselect_all (EAttachmentView *view) +{ + EAttachmentViewIface *iface; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + iface = E_ATTACHMENT_VIEW_GET_IFACE (view); + g_return_if_fail (iface->unselect_all != NULL); + + iface->unselect_all (view); +} + +void +e_attachment_view_sync_selection (EAttachmentView *view, + EAttachmentView *target) +{ + GList *selected, *iter; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (E_IS_ATTACHMENT_VIEW (target)); + + selected = e_attachment_view_get_selected_paths (view); + e_attachment_view_unselect_all (target); + + for (iter = selected; iter != NULL; iter = iter->next) + e_attachment_view_select_path (target, iter->data); + + g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected); +} + +void +e_attachment_view_drag_action (EAttachmentView *view, + GdkDragAction action) +{ + EAttachmentViewPrivate *priv; + GtkSelectionData *selection_data; + EAttachmentStore *store; + GdkAtom atom; + gchar *name; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + priv = e_attachment_view_get_private (view); + + selection_data = priv->selection_data; + store = e_attachment_view_get_store (view); + atom = gtk_selection_data_get_data_type (selection_data); + + switch (priv->info) { + case DND_TYPE_MESSAGE_RFC822: + drop_message_rfc822 ( + view, selection_data, store, action); + return; + + case DND_TYPE_NETSCAPE_URL: + drop_netscape_url ( + view, selection_data, store, action); + return; + + case DND_TYPE_TEXT_URI_LIST: + drop_text_uri_list ( + view, selection_data, store, action); + return; + + case DND_TYPE_TEXT_VCARD: + case DND_TYPE_TEXT_CALENDAR: + drop_text_generic ( + view, selection_data, store, action); + return; + + case DND_TYPE_X_UID_LIST: + drop_x_uid_list ( + view, selection_data, store, action); + return; + + default: + name = gdk_atom_name (atom); + g_warning ("Unknown drag type: %s", name); + g_free (name); + break; + } + + gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); +} + +gboolean +e_attachment_view_drag_motion (EAttachmentView *view, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + GList *iter; + GdkDragAction actions = 0; + GdkDragAction chosen_action; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + + for (iter = context->targets; iter != NULL; iter = iter->next) { + GdkAtom atom = iter->data; + gint ii; + + for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) + if (atom == drag_info[ii].atom) + actions |= drag_info[ii].actions; + } + + actions &= context->actions; + chosen_action = context->suggested_action; + + if (chosen_action == GDK_ACTION_ASK) { + GdkDragAction mask; + + mask = GDK_ACTION_COPY | GDK_ACTION_MOVE; + if ((actions & mask) != mask) + chosen_action = GDK_ACTION_COPY; + } + + gdk_drag_status (context, chosen_action, time); + + return (chosen_action != 0); +} + +void +e_attachment_view_drag_data_received (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + EAttachmentViewPrivate *priv; + GtkUIManager *ui_manager; + GdkDragAction action; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + priv = e_attachment_view_get_private (view); + ui_manager = e_attachment_view_get_ui_manager (view); + + action = drag_context->action; + + if (gtk_selection_data_get_data (selection_data) == NULL) + return; + + if (gtk_selection_data_get_length (selection_data) == -1) + return; + + if (priv->drag_context != NULL) + g_object_unref (priv->drag_context); + + if (priv->selection_data != NULL) + gtk_selection_data_free (priv->selection_data); + + priv->drag_context = g_object_ref (drag_context); + priv->selection_data = gtk_selection_data_copy (selection_data); + priv->info = info; + priv->time = time; + + if (action == GDK_ACTION_ASK) { + GtkWidget *menu; + + menu = gtk_ui_manager_get_widget (ui_manager, "/dnd"); + g_return_if_fail (GTK_IS_MENU (menu)); + + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, time); + } else + e_attachment_view_drag_action (view, action); +} + +GtkAction * +e_attachment_view_get_action (EAttachmentView *view, + const gchar *action_name) +{ + GtkUIManager *ui_manager; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + g_return_val_if_fail (action_name != NULL, NULL); + + ui_manager = e_attachment_view_get_ui_manager (view); + + return e_lookup_action (ui_manager, action_name); +} + +GtkActionGroup * +e_attachment_view_get_action_group (EAttachmentView *view, + const gchar *group_name) +{ + GtkUIManager *ui_manager; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + ui_manager = e_attachment_view_get_ui_manager (view); + + return e_lookup_action_group (ui_manager, group_name); +} + +GtkUIManager * +e_attachment_view_get_ui_manager (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + priv = e_attachment_view_get_private (view); + + return priv->ui_manager; +} + +GtkAction * +e_attachment_view_recent_action_new (EAttachmentView *view, + const gchar *action_name, + const gchar *action_label) +{ + GtkAction *action; + GtkRecentChooser *chooser; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + g_return_val_if_fail (action_name != NULL, NULL); + + action = gtk_recent_action_new ( + action_name, action_label, NULL, NULL); + gtk_recent_action_set_show_numbers (GTK_RECENT_ACTION (action), TRUE); + + chooser = GTK_RECENT_CHOOSER (action); + gtk_recent_chooser_set_show_icons (chooser, TRUE); + gtk_recent_chooser_set_show_not_found (chooser, FALSE); + gtk_recent_chooser_set_show_private (chooser, FALSE); + gtk_recent_chooser_set_show_tips (chooser, TRUE); + gtk_recent_chooser_set_sort_type (chooser, GTK_RECENT_SORT_MRU); + + g_signal_connect ( + action, "item-activated", + G_CALLBACK (action_recent_cb), view); + + return action; +} + +void +e_attachment_view_show_popup_menu (EAttachmentView *view, + GdkEventButton *event) +{ + GtkUIManager *ui_manager; + GtkWidget *menu; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + if (event != NULL) { + GtkTreePath *path; + + path = e_attachment_view_get_path_at_pos ( + view, event->x, event->y); + if (path != NULL) { + if (!e_attachment_view_path_is_selected (view, path)) { + e_attachment_view_unselect_all (view); + e_attachment_view_select_path (view, path); + } + gtk_tree_path_free (path); + } else + e_attachment_view_unselect_all (view); + } + + e_attachment_view_update_actions (view); + + ui_manager = e_attachment_view_get_ui_manager (view); + menu = gtk_ui_manager_get_widget (ui_manager, "/context"); + g_return_if_fail (GTK_IS_MENU (menu)); + + if (event != NULL) + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + event->button, event->time); + else + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + 0, gtk_get_current_event_time ()); +} + +void +e_attachment_view_update_actions (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + GFileInfo *file_info; + GtkAction *action; + GList *selected; + guint n_selected; + gboolean is_image; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + priv = e_attachment_view_get_private (view); + selected = e_attachment_view_get_selected_attachments (view); + n_selected = g_list_length (selected); + + is_image = FALSE; + file_info = NULL; + + if (n_selected == 1) { + EAttachment *attachment = selected->data; + file_info = e_attachment_get_file_info (attachment); + is_image = e_attachment_is_image (attachment); + } + + action = e_attachment_view_get_action (view, "properties"); + gtk_action_set_visible (action, n_selected == 1); + + action = e_attachment_view_get_action (view, "remove"); + gtk_action_set_visible (action, n_selected > 0); + + action = e_attachment_view_get_action (view, "save-as"); + gtk_action_set_visible (action, n_selected > 0); + + action = e_attachment_view_get_action (view, "set-background"); + gtk_action_set_visible (action, is_image); +} diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h new file mode 100644 index 0000000000..a00308d2d5 --- /dev/null +++ b/widgets/misc/e-attachment-view.h @@ -0,0 +1,163 @@ +/* + * e-attachment-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_VIEW_H +#define E_ATTACHMENT_VIEW_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_VIEW \ + (e_attachment_view_get_type ()) +#define E_ATTACHMENT_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_VIEW, EAttachmentView)) +#define E_ATTACHMENT_VIEW_IFACE(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_VIEW, EAttachmentViewIface)) +#define E_IS_ATTACHMENT_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_VIEW)) +#define E_IS_ATTACHMENT_VIEW_IFACE(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_VIEW)) +#define E_ATTACHMENT_VIEW_GET_IFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE \ + ((obj), E_TYPE_ATTACHMENT_VIEW, EAttachmentViewIface)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentView EAttachmentView; +typedef struct _EAttachmentViewIface EAttachmentViewIface; +typedef struct _EAttachmentViewPrivate EAttachmentViewPrivate; + +struct _EAttachmentViewIface { + GTypeInterface parent_iface; + + /* General Methods */ + EAttachmentViewPrivate * + (*get_private) (EAttachmentView *view); + EAttachmentStore * + (*get_store) (EAttachmentView *view); + + /* Selection Methods */ + GtkTreePath * (*get_path_at_pos) (EAttachmentView *view, + gint x, + gint y); + GList * (*get_selected_paths) (EAttachmentView *view); + gboolean (*path_is_selected) (EAttachmentView *view, + GtkTreePath *path); + void (*select_path) (EAttachmentView *view, + GtkTreePath *path); + void (*unselect_path) (EAttachmentView *view, + GtkTreePath *path); + void (*select_all) (EAttachmentView *view); + void (*unselect_all) (EAttachmentView *view); +}; + +struct _EAttachmentViewPrivate { + + /* Popup Menu Management */ + GtkUIManager *ui_manager; + GtkActionGroup *standard_actions; + GtkActionGroup *editable_actions; + GtkActionGroup *openwith_actions; + guint merge_id; + + /* Drag and Drop State */ + GdkDragContext *drag_context; + GtkSelectionData *selection_data; + guint info; + guint time; +}; + +GType e_attachment_view_get_type (void); + +void e_attachment_view_init (EAttachmentView *view); +void e_attachment_view_dispose (EAttachmentView *view); +void e_attachment_view_finalize (EAttachmentView *view); + +EAttachmentViewPrivate * + e_attachment_view_get_private (EAttachmentView *view); +EAttachmentStore * + e_attachment_view_get_store (EAttachmentView *view); +GList * e_attachment_view_get_selected_attachments + (EAttachmentView *view); +void e_attachment_view_remove_selected + (EAttachmentView *view, + gboolean select_next); + +/* Selection Management */ +GtkTreePath * e_attachment_view_get_path_at_pos + (EAttachmentView *view, + gint x, + gint y); +GList * e_attachment_view_get_selected_paths + (EAttachmentView *view); +gboolean e_attachment_view_path_is_selected + (EAttachmentView *view, + GtkTreePath *path); +void e_attachment_view_select_path (EAttachmentView *view, + GtkTreePath *path); +void e_attachment_view_unselect_path (EAttachmentView *view, + GtkTreePath *path); +void e_attachment_view_select_all (EAttachmentView *view); +void e_attachment_view_unselect_all (EAttachmentView *view); +void e_attachment_view_sync_selection(EAttachmentView *view, + EAttachmentView *target); + +/* Drag and Drop Support */ +void e_attachment_view_drag_action (EAttachmentView *view, + GdkDragAction action); +gboolean e_attachment_view_drag_motion (EAttachmentView *view, + GdkDragContext *context, + gint x, + gint y, + guint time); +void e_attachment_view_drag_data_received + (EAttachmentView *view, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time); + +/* Popup Menu Management */ +GtkAction * e_attachment_view_get_action (EAttachmentView *view, + const gchar *action_name); +GtkActionGroup *e_attachment_view_get_action_group + (EAttachmentView *view, + const gchar *group_name); +GtkUIManager * e_attachment_view_get_ui_manager(EAttachmentView *view); +GtkAction * e_attachment_view_recent_action_new + (EAttachmentView *view, + const gchar *action_name, + const gchar *action_label); +void e_attachment_view_show_popup_menu + (EAttachmentView *view, + GdkEventButton *event); +void e_attachment_view_update_actions(EAttachmentView *view); + +G_END_DECLS + +#endif /* E_ATTACHMENT_VIEW_H */ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 9bb6f09ade..6f9e80f02b 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1,4 +1,5 @@ /* + * e-attachment.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,81 +15,275 @@ * License along with the program; if not, see * * - * Authors: - * Ettore Perazzoli - * Jeffrey Stedfast - * Srinivasa Ragavan - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include "e-attachment.h" -#include "e-attachment-dialog.h" - -#ifdef G_OS_WIN32 -/* Include early (as the gio stuff below will - * include it anyway, sigh) to workaround the DATADIR problem. - * (and the headers it includes) stomps all over the - * namespace like a baboon on crack, and especially the DATADIR enum - * in objidl.h causes problems. - */ -#undef DATADIR -#define DATADIR crap_DATADIR -#include -#undef DATADIR -#endif -#include -#include #include - -#include - #include -#include - -#include +#include +#include +#include +#include +#include +#include #include "e-util/e-util.h" -#include "e-util/e-error.h" -#include "e-util/e-mktemp.h" -#include "e-util/e-util-private.h" #define E_ATTACHMENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) +/* Attributes needed by EAttachmentStore, et al. */ +#define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*" + struct _EAttachmentPrivate { - gchar *filename; - gchar *description; + GFile *file; + GFileInfo *file_info; + GCancellable *cancellable; + CamelMimePart *mime_part; gchar *disposition; - gchar *mime_type; - GdkPixbuf *thumbnail; - CamelMimePart *mime_part; + /* This is a reference to our row in an EAttachmentStore, + * serving as a means of broadcasting "row-changed" signals. + * If we are removed from the store, we lazily free the + * reference when it is found to be to be invalid. */ + GtkTreeRowReference *reference; }; enum { PROP_0, - PROP_DESCRIPTION, PROP_DISPOSITION, - PROP_FILENAME, - PROP_THUMBNAIL -}; - -enum { - CHANGED, - UPDATE, - LAST_SIGNAL + PROP_FILE, + PROP_FILE_INFO, + PROP_MIME_PART }; static gpointer parent_class; -static guint signals[LAST_SIGNAL]; + +static void +attachment_notify_model (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + reference = attachment->priv->reference; + + if (reference == NULL) + return; + + /* Free the reference if it's no longer valid. + * It means we've been removed from the store. */ + if (!gtk_tree_row_reference_valid (reference)) { + gtk_tree_row_reference_free (reference); + attachment->priv->reference = NULL; + return; + } + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_row_changed (model, path, &iter); + g_object_notify (G_OBJECT (model), "total-size"); + + gtk_tree_path_free (path); +} + +static gchar * +attachment_get_default_charset (void) +{ + GConfClient *client; + const gchar *key; + gchar *charset; + + /* XXX This function doesn't really belong here. */ + + client = gconf_client_get_default (); + key = "/apps/evolution/mail/composer/charset"; + charset = gconf_client_get_string (client, key, NULL); + if (charset == NULL || *charset == '\0') { + g_free (charset); + key = "/apps/evolution/mail/format/charset"; + charset = gconf_client_get_string (client, key, NULL); + if (charset == NULL || *charset == '\0') { + g_free (charset); + charset = NULL; + } + } + g_object_unref (client); + + if (charset == NULL) + charset = g_strdup (camel_iconv_locale_charset ()); + + if (charset == NULL) + charset = g_strdup ("us-ascii"); + + return charset; +} + +static void +attachment_set_file_info (EAttachment *attachment, + GFileInfo *file_info) +{ + GCancellable *cancellable; + + cancellable = attachment->priv->cancellable; + + /* Cancel any query operations in progress. */ + if (!g_cancellable_is_cancelled (cancellable)) { + g_cancellable_cancel (cancellable); + g_cancellable_reset (cancellable); + } + + if (file_info != NULL) + g_object_ref (file_info); + + if (attachment->priv->file_info != NULL) + g_object_unref (attachment->priv->file_info); + + attachment->priv->file_info = file_info; + + g_object_notify (G_OBJECT (attachment), "file-info"); + + attachment_notify_model (attachment); +} + +static void +attachment_reset (EAttachment *attachment) +{ + GCancellable *cancellable; + + cancellable = attachment->priv->cancellable; + + g_object_freeze_notify (G_OBJECT (attachment)); + + /* Cancel any query operations in progress. */ + if (!g_cancellable_is_cancelled (cancellable)) { + g_cancellable_cancel (cancellable); + g_cancellable_reset (cancellable); + } + + if (attachment->priv->file != NULL) { + g_object_notify (G_OBJECT (attachment), "file"); + g_object_unref (attachment->priv->file); + attachment->priv->file = NULL; + } + + if (attachment->priv->mime_part != NULL) { + g_object_notify (G_OBJECT (attachment), "mime-part"); + g_object_unref (attachment->priv->mime_part); + attachment->priv->mime_part = NULL; + } + + attachment_set_file_info (attachment, NULL); + + g_object_thaw_notify (G_OBJECT (attachment)); +} + +static void +attachment_file_info_ready_cb (GFile *file, + GAsyncResult *result, + EAttachment *attachment) +{ + GFileInfo *file_info; + GError *error = NULL; + + /* Even if we failed to obtain a GFileInfo, we still emit a + * "notify::file-info" to signal the async operation finished. */ + file_info = g_file_query_info_finish (file, result, &error); + attachment_set_file_info (attachment, file_info); + + if (file_info != NULL) + g_object_unref (file_info); + else { + g_warning ("%s", error->message); + g_error_free (error); + } +} + +static void +attachment_file_info_to_mime_part (EAttachment *attachment, + CamelMimePart *mime_part) +{ + GFileInfo *file_info; + const gchar *attribute; + const gchar *string; + gchar *allocated; + + file_info = e_attachment_get_file_info (attachment); + + if (file_info == NULL || mime_part == NULL) + return; + + /* XXX Note that we skip "standard::size" here. */ + + attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; + string = g_file_info_get_attribute_string (file_info, attribute); + allocated = g_content_type_get_mime_type (string); + camel_mime_part_set_content_type (mime_part, allocated); + g_free (allocated); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; + string = g_file_info_get_attribute_string (file_info, attribute); + camel_mime_part_set_filename (mime_part, string); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + string = g_file_info_get_attribute_string (file_info, attribute); + camel_mime_part_set_description (mime_part, string); + + string = e_attachment_get_disposition (attachment); + camel_mime_part_set_disposition (mime_part, string); +} + +static void +attachment_mime_part_to_file_info (EAttachment *attachment) +{ + CamelContentType *content_type; + CamelMimePart *mime_part; + GFileInfo *file_info; + const gchar *attribute; + const gchar *string; + gchar *allocated; + guint64 v_uint64; + + file_info = e_attachment_get_file_info (attachment); + mime_part = e_attachment_get_mime_part (attachment); + + if (file_info == NULL || mime_part == NULL) + return; + + attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; + content_type = camel_mime_part_get_content_type (mime_part); + allocated = camel_content_type_simple (content_type); + if (allocated != NULL) + g_file_info_set_attribute_string ( + file_info, attribute, allocated); + g_free (allocated); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; + string = camel_mime_part_get_filename (mime_part); + if (string != NULL) + g_file_info_set_attribute_string ( + file_info, attribute, string); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + string = camel_mime_part_get_description (mime_part); + if (string != NULL) + g_file_info_set_attribute_string ( + file_info, attribute, string); + + attribute = G_FILE_ATTRIBUTE_STANDARD_SIZE; + v_uint64 = camel_mime_part_get_content_size (mime_part); + g_file_info_set_attribute_uint64 (file_info, attribute, v_uint64); + + string = camel_mime_part_get_disposition (mime_part); + e_attachment_set_disposition (attachment, string); +} static void attachment_set_property (GObject *object, @@ -97,28 +292,22 @@ attachment_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_DESCRIPTION: - e_attachment_set_description ( - E_ATTACHMENT (object), - g_value_get_string (value)); - return; - case PROP_DISPOSITION: e_attachment_set_disposition ( E_ATTACHMENT (object), g_value_get_string (value)); return; - case PROP_FILENAME: - e_attachment_set_filename ( + case PROP_FILE: + e_attachment_set_file ( E_ATTACHMENT (object), - g_value_get_string (value)); + g_value_get_object (value)); return; - case PROP_THUMBNAIL: - e_attachment_set_thumbnail ( + case PROP_MIME_PART: + e_attachment_set_mime_part ( E_ATTACHMENT (object), - g_value_get_object (value)); + g_value_get_boxed (value)); return; } @@ -132,27 +321,27 @@ attachment_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_DESCRIPTION: - g_value_set_string ( - value, e_attachment_get_description ( - E_ATTACHMENT (object))); - return; - case PROP_DISPOSITION: g_value_set_string ( value, e_attachment_get_disposition ( E_ATTACHMENT (object))); return; - case PROP_FILENAME: - g_value_set_string ( - value, e_attachment_get_filename ( + case PROP_FILE: + g_value_set_object ( + value, e_attachment_get_file ( E_ATTACHMENT (object))); return; - case PROP_THUMBNAIL: + case PROP_FILE_INFO: g_value_set_object ( - value, e_attachment_get_thumbnail ( + value, e_attachment_get_file_info ( + E_ATTACHMENT (object))); + return; + + case PROP_MIME_PART: + g_value_set_boxed ( + value, e_attachment_get_mime_part ( E_ATTACHMENT (object))); return; } @@ -167,9 +356,20 @@ attachment_dispose (GObject *object) priv = E_ATTACHMENT_GET_PRIVATE (object); - if (priv->thumbnail != NULL) { - g_object_unref (priv->thumbnail); - priv->thumbnail = NULL; + if (priv->cancellable != NULL) { + g_cancellable_cancel (priv->cancellable); + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + + if (priv->file != NULL) { + g_object_unref (priv->file); + priv->file = NULL; + } + + if (priv->file_info != NULL) { + g_object_unref (priv->file_info); + priv->file_info = NULL; } if (priv->mime_part != NULL) { @@ -177,6 +377,10 @@ attachment_dispose (GObject *object) priv->mime_part = NULL; } + /* This accepts NULL arguments. */ + gtk_tree_row_reference_free (priv->reference); + priv->reference = NULL; + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -184,20 +388,11 @@ attachment_dispose (GObject *object) static void attachment_finalize (GObject *object) { - EAttachment *attachment = (EAttachment *) object; - - if (attachment->cancellable) { - /* the operation is still running, so cancel it */ - g_cancellable_cancel (attachment->cancellable); - attachment->cancellable = NULL; - } + EAttachmentPrivate *priv; - g_free (attachment->store_uri); + priv = E_ATTACHMENT_GET_PRIVATE (object); - g_free (attachment->priv->filename); - g_free (attachment->priv->description); - g_free (attachment->priv->disposition); - g_free (attachment->priv->mime_type); + g_free (priv->disposition); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); @@ -219,75 +414,52 @@ attachment_class_init (EAttachmentClass *class) g_object_class_install_property ( object_class, - PROP_DESCRIPTION, + PROP_DISPOSITION, g_param_spec_string ( - "description", - "Description", - NULL, + "disposition", + "Disposition", NULL, + "attachment", G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, - PROP_DESCRIPTION, - g_param_spec_string ( - "disposition", - "Disposition", - NULL, + PROP_FILE, + g_param_spec_object ( + "file", + "File", NULL, + G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, - PROP_DESCRIPTION, - g_param_spec_string ( - "filename", - "Filename", - NULL, + PROP_FILE_INFO, + g_param_spec_object ( + "file-info", + "File Info", NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_TYPE_FILE_INFO, + G_PARAM_READABLE)); g_object_class_install_property ( object_class, - PROP_THUMBNAIL, - g_param_spec_object ( - "thumbnail", - "Thumbnail Image", + PROP_MIME_PART, + g_param_spec_boxed ( + "mime-part", + "MIME Part", NULL, - GDK_TYPE_PIXBUF, + E_TYPE_CAMEL_OBJECT, G_PARAM_READWRITE)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UPDATE] = g_signal_new ( - "update", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, update), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); } static void attachment_init (EAttachment *attachment) { attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment); - - attachment->index = -1; - attachment->percentage = -1; - attachment->sign = CAMEL_CIPHER_VALIDITY_SIGN_NONE; - attachment->encrypt = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; + attachment->priv->cancellable = g_cancellable_new (); } GType @@ -316,711 +488,845 @@ e_attachment_get_type (void) return type; } -/** - * file_ext_is: - * @param filename: path for file - * @param ext: desired extension, with a dot - * @return if filename has extension ext or not - **/ - -static gboolean -file_ext_is (const char *filename, const char *ext) +EAttachment * +e_attachment_new (void) { - int i, dot = -1; + return g_object_new (E_TYPE_ATTACHMENT, NULL); +} - if (!filename || !ext) - return FALSE; +EAttachment * +e_attachment_new_for_path (const gchar *path) +{ + EAttachment *attachment; + GFile *file; - for (i = 0; filename[i]; i++) { - if (filename [i] == '.') - dot = i; - } + g_return_val_if_fail (path != NULL, NULL); - if (dot > 0) { - return 0 == g_ascii_strcasecmp (filename + dot, ext); - } + file = g_file_new_for_path (path); + attachment = g_object_new (E_TYPE_ATTACHMENT, "file", file, NULL); + g_object_unref (file); - return FALSE; + return attachment; } -static char * -attachment_guess_mime_type (const char *filename) +EAttachment * +e_attachment_new_for_uri (const gchar *uri) { - char *type; - gchar *content = NULL; + EAttachment *attachment; + GFile *file; - type = e_util_guess_mime_type (filename, TRUE); + g_return_val_if_fail (uri != NULL, NULL); - if (type && strcmp (type, "text/directory") == 0 && - file_ext_is (filename, ".vcf") && - g_file_get_contents (filename, &content, NULL, NULL) && - content) { - EVCard *vc = e_vcard_new_from_string (content); + file = g_file_new_for_uri (uri); + attachment = g_object_new (E_TYPE_ATTACHMENT, "file", file, NULL); + g_object_unref (file); - if (vc) { - g_free (type); - g_object_unref (G_OBJECT (vc)); + return attachment; +} - type = g_strdup ("text/x-vcard"); - } +EAttachment * +e_attachment_new_for_message (CamelMimeMessage *message) +{ + CamelDataWrapper *wrapper; + CamelMimePart *mime_part; + EAttachment *attachment; + GString *description; + const gchar *subject; - } + g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - g_free (content); + mime_part = camel_mime_part_new (); + camel_mime_part_set_disposition (mime_part, "inline"); + subject = camel_mime_message_get_subject (message); - if (type) { - /* Check if returned mime_type is valid */ - CamelContentType *ctype = camel_content_type_decode (type); + description = g_string_new (_("Attached message")); + if (subject != NULL) + g_string_append_printf (description, " - %s", subject); + camel_mime_part_set_description (mime_part, description->str); + g_string_free (description, TRUE); - if (!ctype) { - g_free (type); - type = NULL; - } else - camel_content_type_unref (ctype); - } + wrapper = CAMEL_DATA_WRAPPER (message); + camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper); + camel_mime_part_set_content_type (mime_part, "message/rfc822"); - return type; + attachment = e_attachment_new (); + e_attachment_set_mime_part (attachment, mime_part); + camel_object_unref (mime_part); + + return attachment; } - -/** - * e_attachment_new: - * @filename: filename to attach - * @disposition: Content-Disposition of the attachment - * @ex: exception - * - * Return value: the new attachment, or %NULL on error - **/ -EAttachment * -e_attachment_new (const char *filename, const char *disposition, CamelException *ex) +void +e_attachment_add_to_multipart (EAttachment *attachment, + CamelMultipart *multipart, + const gchar *default_charset) { - EAttachment *new; - CamelMimePart *part; + CamelContentType *content_type; CamelDataWrapper *wrapper; - CamelStream *stream; - struct stat statbuf; - gchar *mime_type; - gchar *basename; - CamelURL *url; + CamelMimePart *mime_part; - g_return_val_if_fail (filename != NULL, NULL); + /* XXX EMsgComposer might be a better place for this function. */ - if (g_stat (filename, &statbuf) < 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: %s"), - filename, g_strerror (errno)); - return NULL; - } + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (CAMEL_IS_MULTIPART (multipart)); - /* return if it's not a regular file */ - if (!S_ISREG (statbuf.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: not a regular file"), - filename); - return NULL; - } + /* Still loading? Too bad. */ + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part == NULL) + return; - if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: %s"), - filename, g_strerror (errno)); - return NULL; - } + content_type = camel_mime_part_get_content_type (mime_part); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + + if (CAMEL_IS_MULTIPART (wrapper)) + goto exit; - if ((mime_type = attachment_guess_mime_type (filename))) { - if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { - wrapper = (CamelDataWrapper *) camel_mime_message_new (); - } else { - wrapper = camel_data_wrapper_new (); + /* For text content, determine the best encoding and character set. */ + if (camel_content_type_is (content_type, "text", "*")) { + CamelTransferEncoding encoding; + CamelStreamFilter *filtered_stream; + CamelMimeFilterBestenc *filter; + CamelStream *stream; + const gchar *charset; + + charset = camel_content_type_param (content_type, "charset"); + + /* Determine the best encoding by writing the MIME + * part to a NULL stream with a "bestenc" filter. */ + stream = camel_stream_null_new (); + filtered_stream = camel_stream_filter_new_with_stream (stream); + filter = camel_mime_filter_bestenc_new ( + CAMEL_BESTENC_GET_ENCODING); + camel_stream_filter_add ( + filtered_stream, CAMEL_MIME_FILTER (filter)); + camel_data_wrapper_decode_to_stream ( + wrapper, CAMEL_STREAM (filtered_stream)); + camel_object_unref (filtered_stream); + camel_object_unref (stream); + + /* Retrieve the best encoding from the filter. */ + encoding = camel_mime_filter_bestenc_get_best_encoding ( + filter, CAMEL_BESTENC_8BIT); + camel_mime_part_set_encoding (mime_part, encoding); + camel_object_unref (filter); + + if (encoding == CAMEL_TRANSFER_ENCODING_7BIT) { + /* The text fits within us-ascii, so this is safe. + * FIXME Check that this isn't iso-2022-jp? */ + default_charset = "us-ascii"; + + } else if (charset == NULL && default_charset == NULL) { + default_charset = attachment_get_default_charset (); + /* FIXME Check that this fits within the + * default_charset and if not, find one + * that does and/or allow the user to + * specify. */ } - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, mime_type); - g_free (mime_type); - } else { - wrapper = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, "application/octet-stream"); - } + if (charset == NULL) { + gchar *type; - camel_object_unref (stream); + camel_content_type_set_param ( + content_type, "charset", default_charset); + type = camel_content_type_format (content_type); + camel_mime_part_set_content_type (mime_part, type); + g_free (type); + } - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); - camel_object_unref (wrapper); + /* Otherwise, unless it's a message/rfc822, Base64 encode it. */ + } else if (!CAMEL_IS_MIME_MESSAGE (wrapper)) + camel_mime_part_set_encoding ( + mime_part, CAMEL_TRANSFER_ENCODING_BASE64); - camel_mime_part_set_disposition (part, disposition); - basename = g_path_get_basename (filename); - camel_mime_part_set_filename (part, basename); +exit: + camel_multipart_add_part (multipart, mime_part); +} -#if 0 - /* Note: Outlook 2002 is broken with respect to Content-Ids on - non-multipart/related parts, so as an interoperability - workaround, don't set a Content-Id on these parts. Fixes - bug #10032 */ - /* set the Content-Id */ - content_id = camel_header_msgid_generate (); - camel_mime_part_set_content_id (part, content_id); - g_free (content_id); -#endif +const gchar * +e_attachment_get_disposition (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - new = g_object_new (E_TYPE_ATTACHMENT, "filename", basename, NULL); - new->priv->mime_part = part; - new->size = statbuf.st_size; - new->guessed_type = TRUE; - new->cancellable = NULL; - new->is_available_local = TRUE; + return attachment->priv->disposition; +} + +void +e_attachment_set_disposition (EAttachment *attachment, + const gchar *disposition) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, filename); - new->store_uri = camel_url_to_string (url, 0); - camel_url_free (url); + g_free (attachment->priv->disposition); + attachment->priv->disposition = g_strdup (disposition); - return new; + g_object_notify (G_OBJECT (attachment), "disposition"); } +GFile * +e_attachment_get_file (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); -typedef struct { - EAttachment *attachment; - char *filename; - char *uri; - GtkWindow *parent; /* for error dialog */ - - guint64 file_size; /* zero indicates unknown size */ - GInputStream *istream; /* read from here ... */ - GOutputStream *ostream; /* ...and write into this. */ - gboolean was_error; + return attachment->priv->file; +} + +void +e_attachment_set_file (EAttachment *attachment, + GFile *file) +{ GCancellable *cancellable; - void *buffer; /* read into this, not more than buffer_size bytes */ - gsize buffer_size; -} DownloadInfo; + g_return_if_fail (E_IS_ATTACHMENT (attachment)); -static void -download_info_free (DownloadInfo *download_info) -{ - /* if there was an error, then free attachment too */ - if (download_info->was_error) - g_object_unref (download_info->attachment); + g_object_freeze_notify (G_OBJECT (attachment)); + + if (file != NULL) { + g_return_if_fail (G_IS_FILE (file)); + g_object_ref (file); + } + + attachment_reset (attachment); + attachment->priv->file = file; - if (download_info->ostream) - g_object_unref (download_info->ostream); + cancellable = attachment->priv->cancellable; - if (download_info->istream) - g_object_unref (download_info->istream); + if (file != NULL) + g_file_query_info_async ( + file, ATTACHMENT_QUERY, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) + attachment_file_info_ready_cb, + attachment); - if (download_info->cancellable) - g_object_unref (download_info->cancellable); + g_object_notify (G_OBJECT (attachment), "file"); - g_free (download_info->filename); - g_free (download_info->uri); - g_free (download_info->buffer); - g_free (download_info); + g_object_thaw_notify (G_OBJECT (attachment)); } -static void -data_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +GFileInfo * +e_attachment_get_file_info (EAttachment *attachment) { - DownloadInfo *download_info = (DownloadInfo *)user_data; - GError *error = NULL; - gssize read; + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - g_return_if_fail (download_info != NULL); + return attachment->priv->file_info; +} - if (g_cancellable_is_cancelled (download_info->cancellable)) { - /* finish the operation and close both streams */ - g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, NULL); +CamelMimePart * +e_attachment_get_mime_part (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - g_output_stream_close (download_info->ostream, NULL, NULL); - g_input_stream_close (download_info->istream, NULL, NULL); + return attachment->priv->mime_part; +} - /* The only way how to get this canceled is in EAttachment's finalize method, - and because the download_info_free free's the attachment on error, - then do not consider cancellation as an error. */ - download_info_free (download_info); - return; +void +e_attachment_set_mime_part (EAttachment *attachment, + CamelMimePart *mime_part) +{ + GFileInfo *file_info; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_object_freeze_notify (G_OBJECT (attachment)); + + if (mime_part != NULL) { + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + camel_object_ref (mime_part); } - read = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error); + attachment_reset (attachment); + attachment->priv->mime_part = mime_part; - if (!error) - g_output_stream_write_all (download_info->ostream, download_info->buffer, read, NULL, download_info->cancellable, &error); + file_info = g_file_info_new (); + attachment_set_file_info (attachment, file_info); + attachment_mime_part_to_file_info (attachment); + g_object_unref (file_info); - if (error) { - download_info->was_error = error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED; - if (download_info->was_error) - e_error_run (download_info->parent, "mail-composer:no-attach", download_info->uri, error->message, NULL); + g_object_notify (G_OBJECT (attachment), "mime-part"); - g_error_free (error); + g_object_thaw_notify (G_OBJECT (attachment)); +} - download_info->attachment->cancellable = NULL; - download_info_free (download_info); - return; - } +const gchar * +e_attachment_get_content_type (EAttachment *attachment) +{ + GFileInfo *file_info; + const gchar *attribute; - if (read == 0) { - CamelException ex; + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - /* done with reading */ - g_output_stream_close (download_info->ostream, NULL, NULL); - g_input_stream_close (download_info->istream, NULL, NULL); + attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; + file_info = e_attachment_get_file_info (attachment); - download_info->attachment->cancellable = NULL; + if (file_info == NULL) + return NULL; - camel_exception_init (&ex); - e_attachment_build_remote_file (download_info->filename, download_info->attachment, &ex); + return g_file_info_get_attribute_string (file_info, attribute); +} - if (camel_exception_is_set (&ex)) { - download_info->was_error = TRUE; - e_error_run (download_info->parent, "mail-composer:no-attach", download_info->uri, camel_exception_get_description (&ex), NULL); - camel_exception_clear (&ex); - } +const gchar * +e_attachment_get_display_name (EAttachment *attachment) +{ + GFileInfo *file_info; + const gchar *attribute; - download_info->attachment->percentage = -1; - download_info->attachment->is_available_local = TRUE; - g_signal_emit (download_info->attachment, signals[UPDATE], 0); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - download_info_free (download_info); - return; - } else if (download_info->file_size) { - download_info->attachment->percentage = read * 100 / download_info->file_size; - download_info->file_size -= MIN (download_info->file_size, read); - g_signal_emit (download_info->attachment, signals[UPDATE], 0); - } else { - download_info->attachment->percentage = 0; - g_signal_emit (download_info->attachment, signals[UPDATE], 0); - } + attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; + file_info = e_attachment_get_file_info (attachment); - /* read next chunk */ - g_input_stream_read_async (download_info->istream, download_info->buffer, download_info->buffer_size, G_PRIORITY_DEFAULT, download_info->cancellable, data_ready_cb, download_info); + if (file_info == NULL) + return NULL; + + return g_file_info_get_attribute_string (file_info, attribute); } -static gboolean -download_to_local_path (DownloadInfo *download_info, CamelException *ex) +const gchar * +e_attachment_get_description (EAttachment *attachment) { - GError *error = NULL; - GFile *src = g_file_new_for_uri (download_info->uri); - GFile *des = g_file_new_for_path (download_info->filename); - gboolean res = FALSE; + GFileInfo *file_info; + const gchar *attribute; - g_return_val_if_fail (src != NULL && des != NULL, FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - download_info->ostream = G_OUTPUT_STREAM (g_file_replace (des, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + file_info = e_attachment_get_file_info (attachment); - if (download_info->ostream && !error) { - GFileInfo *fi; + if (file_info == NULL) + return NULL; - fi = g_file_query_info (src, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + return g_file_info_get_attribute_string (file_info, attribute); +} - if (fi) { - download_info->file_size = g_file_info_get_attribute_uint64 (fi, G_FILE_ATTRIBUTE_STANDARD_SIZE); - g_object_unref (fi); - } else { - download_info->file_size = 0; - } +GIcon * +e_attachment_get_icon (EAttachment *attachment) +{ + GFileInfo *file_info; + const gchar *attribute; - download_info->istream = G_INPUT_STREAM (g_file_read (src, NULL, &error)); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - if (download_info->istream && !error) { - download_info->cancellable = g_cancellable_new (); - download_info->attachment->cancellable = download_info->cancellable; - download_info->buffer_size = 10240; /* max 10KB chunk */ - download_info->buffer = g_malloc (sizeof (char) * download_info->buffer_size); + attribute = G_FILE_ATTRIBUTE_STANDARD_ICON; + file_info = e_attachment_get_file_info (attachment); - g_input_stream_read_async (download_info->istream, download_info->buffer, download_info->buffer_size, G_PRIORITY_DEFAULT, download_info->cancellable, data_ready_cb, download_info); + if (file_info == NULL) + return NULL; - res = TRUE; - } - } + return (GIcon *) + g_file_info_get_attribute_object (file_info, attribute); +} + +const gchar * +e_attachment_get_thumbnail_path (EAttachment *attachment) +{ + GFileInfo *file_info; + const gchar *attribute; - if (error) { - /* propagate error */ - if (ex) - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, error->message); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - g_error_free (error); - download_info->was_error = TRUE; - download_info_free (download_info); - } + attribute = G_FILE_ATTRIBUTE_THUMBNAIL_PATH; + file_info = e_attachment_get_file_info (attachment); - g_object_unref (src); - g_object_unref (des); + if (file_info == NULL) + return NULL; - return res; + return g_file_info_get_attribute_byte_string (file_info, attribute); } -EAttachment * -e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, const char *disposition, const char *path, CamelException *ex) +guint64 +e_attachment_get_size (EAttachment *attachment) { - EAttachment *new; - DownloadInfo *download_info; - CamelURL *url; - char *base; - gchar *filename; + GFileInfo *file_info; + const gchar *attribute; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), 0); - url = camel_url_new (uri, NULL); - base = g_path_get_basename (url->path); - camel_url_free (url); + attribute = G_FILE_ATTRIBUTE_STANDARD_SIZE; + file_info = e_attachment_get_file_info (attachment); - filename = g_build_filename (path, base, NULL); + if (file_info == NULL) + return 0; - new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); - new->size = 0; - new->guessed_type = FALSE; - new->cancellable = NULL; - new->is_available_local = FALSE; - new->percentage = 0; + return g_file_info_get_attribute_uint64 (file_info, attribute); +} - g_free (base); +gboolean +e_attachment_is_image (EAttachment *attachment) +{ + const gchar *content_type; - download_info = g_new0 (DownloadInfo, 1); - download_info->attachment = new; - download_info->filename = g_strdup (filename); - download_info->uri = g_strdup (uri); - download_info->parent = error_dlg_parent; - download_info->was_error = FALSE; + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_free (filename); + content_type = e_attachment_get_content_type (attachment); - /* it frees all on the error, so do not free it twice */ - if (!download_to_local_path (download_info, ex)) - return NULL; + if (content_type == NULL) + return FALSE; - return new; + return g_content_type_is_a (content_type, "image"); } - -void -e_attachment_build_remote_file (const gchar *filename, - EAttachment *attachment, - CamelException *ex) +gboolean +e_attachment_is_rfc822 (EAttachment *attachment) { - CamelMimePart *part; - CamelDataWrapper *wrapper; - CamelStream *stream; - struct stat statbuf; - const gchar *description; - const gchar *disposition; - gchar *mime_type; - gchar *basename; - CamelURL *url; + const gchar *content_type; - g_return_if_fail (filename != NULL); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - if (g_stat (filename, &statbuf) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: %s"), - filename, g_strerror (errno)); - g_message ("Cannot attach file %s: %s\n", filename, g_strerror (errno)); - return; - } + content_type = e_attachment_get_content_type (attachment); - /* return if it's not a regular file */ - if (!S_ISREG (statbuf.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: not a regular file"), - filename); - g_message ("Cannot attach file %s: not a regular file", filename); - return; - } + if (content_type == NULL) + return FALSE; - if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot attach file %s: %s"), - filename, g_strerror (errno)); - return; - } + return g_content_type_equals (content_type, "message/rfc822"); +} - if ((mime_type = attachment_guess_mime_type (filename))) { - if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { - wrapper = (CamelDataWrapper *) camel_mime_message_new (); - } else { - wrapper = camel_data_wrapper_new (); - } +static void +attachment_save_file_cb (GFile *source, + GAsyncResult *result, + EActivity *activity) +{ + GError *error = NULL; - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, mime_type); - g_free (mime_type); - } else { - wrapper = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, "application/octet-stream"); + if (!g_file_copy_finish (source, result, &error)) { + e_activity_set_error (activity, error); + g_error_free (error); } - camel_object_unref (stream); + e_activity_complete (activity); + g_object_unref (activity); +} - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); - camel_object_unref (wrapper); +static gpointer +attachment_save_part_thread (EActivity *activity) +{ + GObject *object; + EAttachment *attachment; + GCancellable *cancellable; + GOutputStream *output_stream; + EFileActivity *file_activity; + CamelDataWrapper *wrapper; + CamelMimePart *mime_part; + CamelStream *stream; + GError *error = NULL; - disposition = e_attachment_get_disposition (attachment); - camel_mime_part_set_disposition (part, disposition); + object = G_OBJECT (activity); + attachment = g_object_get_data (object, "attachment"); + output_stream = g_object_get_data (object, "output-stream"); - if (e_attachment_get_filename (attachment) == NULL) - basename = g_path_get_basename (filename); - else - basename = g_path_get_basename (e_attachment_get_filename (attachment)); + /* Last chance to cancel. */ + file_activity = E_FILE_ACTIVITY (activity); + cancellable = e_file_activity_get_cancellable (file_activity); + if (g_cancellable_set_error_if_cancelled (cancellable, &error)) + goto exit; - camel_mime_part_set_filename (part, filename); + object = g_object_ref (output_stream); + stream = camel_stream_vfs_new_with_stream (object); + mime_part = e_attachment_get_mime_part (attachment); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - description = e_attachment_get_description (attachment); - if (description != NULL) { - camel_mime_part_set_description (part, description); - e_attachment_set_description (attachment, NULL); - } + if (camel_data_wrapper_decode_to_stream (wrapper, stream) < 0) + g_set_error ( + &error, G_IO_ERROR, + g_io_error_from_errno (errno), + g_strerror (errno)); - attachment->priv->mime_part = part; - attachment->size = statbuf.st_size; - attachment->guessed_type = TRUE; + else if (camel_stream_flush (stream) < 0) + g_set_error ( + &error, G_IO_ERROR, + g_io_error_from_errno (errno), + g_strerror (errno)); - e_attachment_set_filename (attachment, basename); + camel_object_unref (stream); - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, filename); - attachment->store_uri = camel_url_to_string (url, 0); - camel_url_free (url); +exit: + if (error != NULL) { + e_activity_set_error (activity, error); + g_error_free (error); + } - g_free (basename); -} + e_activity_complete_in_idle (activity); + g_object_unref (activity); + return NULL; +} -/** - * e_attachment_new_from_mime_part: - * @part: a CamelMimePart - * - * Return value: a new EAttachment based on the mime part - **/ -EAttachment * -e_attachment_new_from_mime_part (CamelMimePart *part) +static void +attachment_save_part_cb (GFile *destination, + GAsyncResult *result, + EActivity *activity) { - EAttachment *new; - const gchar *filename; + GFileOutputStream *output_stream; + GError *error = NULL; - g_return_val_if_fail (CAMEL_IS_MIME_PART (part), NULL); + output_stream = g_file_replace_finish (destination, result, &error); - filename = camel_mime_part_get_filename (part); + if (output_stream != NULL) { + g_object_set_data_full ( + G_OBJECT (activity), + "output-stream", output_stream, + (GDestroyNotify) g_object_unref); + g_thread_create ( + (GThreadFunc) attachment_save_part_thread, + activity, FALSE, &error); + } - new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); - camel_object_ref (part); - new->priv->mime_part = part; - new->guessed_type = FALSE; - new->is_available_local = TRUE; - new->size = camel_mime_part_get_content_size (part); + if (error != NULL) { + e_activity_set_error (activity, error); + e_activity_complete (activity); + g_object_unref (activity); + g_error_free (error); + } - return new; } void -e_attachment_edit (EAttachment *attachment, - GtkWindow *parent) +e_attachment_save_async (EAttachment *attachment, + EFileActivity *file_activity, + GFile *destination) { - GtkWidget *dialog; + GFileProgressCallback progress_callback; + GCancellable *cancellable; + CamelMimePart *mime_part; + GFile *source; g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + + /* The attachment content is either a GFile (on disk) or a + * CamelMimePart (in memory). Each is saved differently. */ - dialog = e_attachment_dialog_new (parent, attachment); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); + source = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (source != NULL || mime_part != NULL); + + cancellable = e_file_activity_get_cancellable (file_activity); + progress_callback = e_file_activity_progress; + + /* GFile is the easier, but probably less common case. The + * attachment already references an on-disk file, so we can + * just use GIO to copy it asynchronously. + * + * We use G_FILE_COPY_OVERWRITE because the user should have + * already confirmed the overwrite through the save dialog. */ + if (G_IS_FILE (source)) + g_file_copy_async ( + source, destination, + G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, cancellable, + progress_callback, file_activity, + (GAsyncReadyCallback) attachment_save_file_cb, + g_object_ref (file_activity)); + + /* CamelMimePart can only be decoded to a file synchronously, so + * we do this in two stages. Stage one asynchronously opens the + * destination file for writing. Stage two spawns a thread that + * decodes the MIME part to the destination file. This stage is + * not cancellable, unfortunately. */ + else if (CAMEL_IS_MIME_PART (mime_part)) { + g_object_set_data_full ( + G_OBJECT (file_activity), + "attachment", g_object_ref (attachment), + (GDestroyNotify) g_object_unref); + g_file_replace_async ( + destination, NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_part_cb, + g_object_ref (file_activity)); + } } -const gchar * -e_attachment_get_description (EAttachment *attachment) +#if 0 +typedef struct { + gint io_priority; + GCancellable *cancellable; + GSimpleAsyncResult *simple; + GFileInfo *file_info; +} BuildMimePartData; + +static BuildMimePartData * +attachment_build_mime_part_data_new (EAttachment *attachment, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + gpointer source_tag) { - CamelMimePart *mime_part; - const gchar *description; + BuildMimePartData *data; + GSimpleAsyncResult *simple; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + simple = g_simple_async_result_new ( + G_OBJECT (attachment), callback, user_data, source_tag); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - description = camel_mime_part_get_description (mime_part); - else - description = attachment->priv->description; + if (G_IS_CANCELLABLE (cancellable)) + g_object_ref (cancellable); - return description; + data = g_slice_new0 (BuildMimePartData); + data->io_priority = io_priority; + data->cancellable = cancellable; + data->simple = simple; + return data; } -void -e_attachment_set_description (EAttachment *attachment, - const gchar *description) +static void +attachment_build_mime_part_data_free (BuildMimePartData *data) { - CamelMimePart *mime_part; + if (data->attachment != NULL) + g_object_unref (data->attachment); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); + if (data->cancellable != NULL) + g_object_unref (data->cancellable); - g_free (attachment->priv->description); - attachment->priv->description = g_strdup (description); + if (data->simple != NULL) + g_object_unref (data->simple); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - camel_mime_part_set_description (mime_part, description); + if (data->file_info != NULL) + g_object_unref (data->file_info); - g_object_notify (G_OBJECT (attachment), "description"); + g_slice_free (BuildMimePartData, data); } -const gchar * -e_attachment_get_disposition (EAttachment *attachment) +static void +attachment_build_mime_part_splice_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) { + GSimpleAsyncResult *final_result; + GCancellable *cancellable; + EAttachment *attachment; + CamelDataWrapper *wrapper; CamelMimePart *mime_part; - const gchar *disposition; + CamelStream *stream; + const gchar *content_type; + gchar *mime_type; + gssize length; + gpointer data; + GError *error = NULL; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + final_result = G_SIMPLE_ASYNC_RESULT (user_data); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - disposition = camel_mime_part_get_disposition (mime_part); - else - disposition = attachment->priv->disposition; + cancellable = g_cancellable_get_current (); + g_cancellable_pop_current (cancellable); + g_object_unref (cancellable); - return disposition; -} + length = g_output_stream_splice_finish ( + G_OUTPUT_STREAM (source), result, &error); + if (error != NULL) + goto fail; -void -e_attachment_set_disposition (EAttachment *attachment, - const gchar *disposition) -{ - CamelMimePart *mime_part; + data = g_memory_output_stream_get_data ( + G_MEMORY_OUTPUT_STREAM (source)); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); + attachment = E_ATTACHMENT ( + g_async_result_get_source_object ( + G_ASYNC_RESULT (final_result))); - g_free (attachment->priv->disposition); - attachment->priv->disposition = g_strdup (disposition); + if (e_attachment_is_rfc822 (attachment)) + wrapper = (CamelDataWrapper *) camel_mime_message_new (); + else + wrapper = camel_data_wrapper_new (); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - camel_mime_part_set_disposition (mime_part, disposition); + content_type = e_attachment_get_content_type (attachment); + mime_type = g_content_type_get_mime_type (content_type); - g_object_notify (G_OBJECT (attachment), "disposition"); -} + stream = camel_stream_mem_new_with_buffer (data, length); + camel_data_wrapper_construct_from_stream (wrapper, stream); + camel_data_wrapper_set_mime_type (wrapper, mime_type); + camel_object_unref (stream); -const gchar * -e_attachment_get_filename (EAttachment *attachment) -{ - CamelMimePart *mime_part; - const gchar *filename; + mime_part = camel_mime_part_new (); + camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper); - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + g_simple_async_result_set_op_res_gpointer ( + final_result, mime_part, camel_object_unref); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - filename = camel_mime_part_get_filename (mime_part); - else - filename = attachment->priv->filename; + g_simple_async_result_complete (final_result); + + camel_object_unref (wrapper); + g_free (mime_type); + + return; - return filename; +fail: + g_simple_async_result_set_from_error (final_result, error); + g_simple_async_result_complete (final_result); + g_error_free (error); } -void -e_attachment_set_filename (EAttachment *attachment, - const gchar *filename) +static void +attachment_build_mime_part_read_cb (GObject *source, + GAsyncResult *result, + BuildMimePartData *data) { - CamelMimePart *mime_part; + GFileInputStream *input_stream; + GOutputStream *output_stream; + GCancellable *cancellable; + GError *error = NULL; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); + input_stream = g_file_read_finish (G_FILE (source), result, &error); + if (error != NULL) + goto fail; - g_free (attachment->priv->filename); - attachment->priv->filename = g_strdup (filename); + output_stream = g_memory_output_stream_new ( + NULL, 0, g_realloc, g_free); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part != NULL) - camel_mime_part_set_filename (mime_part, filename); + g_output_stream_splice_async ( + output_stream, G_INPUT_STREAM (input_stream), + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, cancellable, + attachment_build_mime_part_splice_cb, result); - g_object_notify (G_OBJECT (attachment), "filename"); -} + g_cancellable_push_current (cancellable); -CamelMimePart * -e_attachment_get_mime_part (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + g_object_unref (input_stream); + g_object_unref (output_stream); - return attachment->priv->mime_part; + return; + +fail: + g_simple_async_result_set_from_error (final_result, error); + g_simple_async_result_complete (final_result); + g_error_free (error); } -const gchar * -e_attachment_get_mime_type (EAttachment *attachment) +static gboolean +attachment_build_mime_part_idle_cb (BuildMimePartData *data) { - CamelContentType *content_type; - CamelMimePart *mime_part; - const gchar *filename; - gchar *mime_type; + GObject *source; + GAsyncResult *result; + GFileInfo *file_info; + GFile *file; + GError *error = NULL; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + if (g_cancellable_set_error_if_cancelled (data->cancellable, &error)) + goto cancelled; - if (attachment->priv->mime_type != NULL) - goto exit; + result = G_ASYNC_RESULT (data->simple); + source = g_async_result_get_source_object (result); + file_info = e_attachment_get_file_info (E_ATTACHMENT (source)); - mime_part = e_attachment_get_mime_part (attachment); - filename = e_attachment_get_filename (attachment); - content_type = camel_mime_part_get_content_type (mime_part); + /* Poll again on the next idle. */ + if (!G_IS_FILE_INFO (file_info)) + return TRUE; - if (mime_part == NULL) - mime_type = attachment_guess_mime_type (filename); - else { - content_type = camel_mime_part_get_content_type (mime_part); - mime_type = camel_content_type_simple (content_type); - } + /* We have a GFileInfo, so on to step 2. */ - attachment->priv->mime_type = mime_type; + data->file_info = g_file_info_dup (file_info); + file = e_attachment_get_file (E_ATTACHMENT (source)); -exit: - return attachment->priv->mime_type; -} + /* Because Camel's stream API is synchronous and not + * cancellable, we have to asynchronously read the file + * into memory and then encode it to a MIME part. That + * means double buffering the file contents in memory, + * unfortunately. */ + g_file_read_async ( + file, data->io_priority, data->cancellable, + attachment_build_mime_part_read_cb, data); -GdkPixbuf * -e_attachment_get_thumbnail (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + return FALSE; + +cancelled: + g_simple_async_result_set_op_res_gboolean (data->simple, FALSE); + g_simple_async_result_set_from_error (data->simple, error); + g_simple_async_result_complete (data->simple); - return attachment->priv->thumbnail; + build_mime_part_data_free (data); + g_error_free (error); + + return FALSE; } void -e_attachment_set_thumbnail (EAttachment *attachment, - GdkPixbuf *thumbnail) +e_attachment_build_mime_part_async (EAttachment *attachment, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + CamelMimePart *mime_part; + GSimpleAsyncResult *result; + GFile *file; + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (callback != NULL); - if (thumbnail != NULL) { - g_return_if_fail (GDK_IS_PIXBUF (thumbnail)); - g_object_ref (thumbnail); + file = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (file != NULL || mime_part != NULL); + + result = g_simple_async_result_new ( + G_OBJECT (attachment), callback, user_data, + e_attachment_build_mime_part_async); + + /* First try the easy way out. */ + if (CAMEL_IS_MIME_PART (mime_part)) { + camel_object_ref (mime_part); + g_simple_async_result_set_op_res_gpointer ( + result, mime_part, camel_object_unref); + g_simple_async_result_complete_in_idle (result); + return; } - if (attachment->priv->thumbnail != NULL) - g_object_unref (attachment->priv->thumbnail); + /* XXX g_cancellable_push_current() documentation lies. + * The function rejects NULL pointers, so create a + * dummy GCancellable if necessary. */ + if (cancellable == NULL) + cancellable = g_cancellable_new (); + else + g_object_ref (cancellable); - attachment->priv->thumbnail = thumbnail; + /* Because Camel's stream API is synchronous and not + * cancellable, we have to asynchronously read the file + * into memory and then encode it to a MIME part. That + * means it's double buffered, unfortunately. */ + g_file_read_async ( + file, G_PRIORITY_DEFAULT, cancellable, + attachment_build_mime_part_read_cb, result); - g_object_notify (G_OBJECT (attachment), "thumbnail"); + g_cancellable_push_current (cancellable); } -gboolean -e_attachment_is_image (EAttachment *attachment) +CamelMimePart * +e_attachment_build_mime_part_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error) { - CamelContentType *content_type; CamelMimePart *mime_part; + GSimpleAsyncResult *simple_result; + gboolean async_result_is_valid; + gpointer source_tag; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part == NULL) - return FALSE; + source_tag = e_attachment_build_mime_part_async; + async_result_is_valid = g_simple_async_result_is_valid ( + result, G_OBJECT (attachment), source_tag); + g_return_val_if_fail (async_result_is_valid, NULL); - content_type = camel_mime_part_get_content_type (mime_part); + simple_result = G_SIMPLE_ASYNC_RESULT (result); + g_simple_async_result_propagate_error (simple_result, error); + mime_part = g_simple_async_result_get_op_res_gpointer (simple_result); + attachment_file_info_to_mime_part (attachment, mime_part); - return camel_content_type_is (content_type, "image", "*"); -} + if (CAMEL_IS_MIME_PART (mime_part)) + camel_object_ref (mime_part); -gboolean -e_attachment_is_inline (EAttachment *attachment) -{ - const gchar *disposition; + g_object_unref (result); - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + return mime_part; +} +#endif - disposition = e_attachment_get_disposition (attachment); - g_return_val_if_fail (disposition != NULL, FALSE); +void +_e_attachment_set_reference (EAttachment *attachment, + GtkTreeRowReference *reference) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (reference != NULL); - return (g_ascii_strcasecmp (disposition, "inline") == 0); + gtk_tree_row_reference_free (attachment->priv->reference); + attachment->priv->reference = gtk_tree_row_reference_copy (reference); } diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index c69189c189..a7bb85dd75 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -1,4 +1,6 @@ /* + * e-attachment.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 @@ -13,10 +15,6 @@ * License along with the program; if not, see * * - * Authors: - * Ettore Perazzoli - * Srinivasa Ragavan - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ @@ -25,11 +23,10 @@ #define E_ATTACHMENT_H #include -#include -#include #include -#include -#include +#include +#include +#include /* Standard GObject macros */ #define E_TYPE_ATTACHMENT \ @@ -45,7 +42,7 @@ ((obj), E_TYPE_ATTACHMENT)) #define E_IS_ATTACHMENT_CLASS(cls) \ (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_ATTACHMENT)) + ((cls), E_TYPE_ATTACHMENT)) #define E_ATTACHMENT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS \ ((obj), E_TYPE_ATTACHMENT, EAttachmentClass)) @@ -58,63 +55,58 @@ typedef struct _EAttachmentPrivate EAttachmentPrivate; struct _EAttachment { GObject parent; - - gboolean guessed_type; - gulong size; - - GCancellable *cancellable; - - gboolean is_available_local; - int percentage; - int index; - char *store_uri; - - /* Status of signed/encrypted attachments */ - camel_cipher_validity_sign_t sign; - camel_cipher_validity_encrypt_t encrypt; - EAttachmentPrivate *priv; }; struct _EAttachmentClass { GObjectClass parent_class; - - void (*changed) (EAttachment *attachment); - void (*update) (EAttachment *attachment, - gchar *message); }; GType e_attachment_get_type (void); -EAttachment * e_attachment_new (const gchar *filename, - const gchar *disposition, - CamelException *ex); -EAttachment * e_attachment_new_remote_file (GtkWindow *error_dlg_parent, - const gchar *url, - const gchar *disposition, - const gchar *path, - CamelException *ex); -void e_attachment_build_remote_file (const gchar *filename, - EAttachment *attachment, - CamelException *ex); -EAttachment * e_attachment_new_from_mime_part (CamelMimePart *part); -void e_attachment_edit (EAttachment *attachment, - GtkWindow *parent); -const gchar * e_attachment_get_description (EAttachment *attachment); -void e_attachment_set_description (EAttachment *attachment, - const gchar *description); +EAttachment * e_attachment_new (void); +EAttachment * e_attachment_new_for_path (const gchar *path); +EAttachment * e_attachment_new_for_uri (const gchar *uri); +EAttachment * e_attachment_new_for_message (CamelMimeMessage *message); +void e_attachment_add_to_multipart (EAttachment *attachment, + CamelMultipart *multipart, + const gchar *default_charset); const gchar * e_attachment_get_disposition (EAttachment *attachment); void e_attachment_set_disposition (EAttachment *attachment, const gchar *disposition); -const gchar * e_attachment_get_filename (EAttachment *attachment); -void e_attachment_set_filename (EAttachment *attachment, - const gchar *filename); +GFile * e_attachment_get_file (EAttachment *attachment); +void e_attachment_set_file (EAttachment *attachment, + GFile *file); +GFileInfo * e_attachment_get_file_info (EAttachment *attachment); CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment); -const gchar * e_attachment_get_mime_type (EAttachment *attachment); -GdkPixbuf * e_attachment_get_thumbnail (EAttachment *attachment); -void e_attachment_set_thumbnail (EAttachment *attachment, - GdkPixbuf *pixbuf); +void e_attachment_set_mime_part (EAttachment *attachment, + CamelMimePart *mime_part); +const gchar * e_attachment_get_content_type (EAttachment *attachment); +const gchar * e_attachment_get_display_name (EAttachment *attachment); +const gchar * e_attachment_get_description (EAttachment *attachment); +GIcon * e_attachment_get_icon (EAttachment *attachment); +const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); +guint64 e_attachment_get_size (EAttachment *attachment); gboolean e_attachment_is_image (EAttachment *attachment); -gboolean e_attachment_is_inline (EAttachment *attachment); +gboolean e_attachment_is_rfc822 (EAttachment *attachment); +void e_attachment_save_async (EAttachment *attachment, + EFileActivity *file_activity, + GFile *destination); + +#if 0 +void e_attachment_build_mime_part_async + (EAttachment *attachment, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +CamelMimePart * e_attachment_build_mime_part_finish + (EAttachment *attachment, + GAsyncResult *result, + GError **error); +#endif + +/* For use by EAttachmentStore only. */ +void _e_attachment_set_reference (EAttachment *attachment, + GtkTreeRowReference *reference); G_END_DECLS diff --git a/widgets/misc/e-file-activity.c b/widgets/misc/e-file-activity.c index 38dae234df..1957c20282 100644 --- a/widgets/misc/e-file-activity.c +++ b/widgets/misc/e-file-activity.c @@ -21,18 +21,25 @@ #include "e-file-activity.h" +#include + #define E_FILE_ACTIVITY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_FILE_ACTIVITY, EFileActivityPrivate)) struct _EFileActivityPrivate { GCancellable *cancellable; + GAsyncResult *result; + GFile *file; + gulong handler_id; }; enum { PROP_0, - PROP_CANCELLABLE + PROP_CANCELLABLE, + PROP_FILE, + PROP_RESULT }; static gpointer parent_class; @@ -49,6 +56,18 @@ file_activity_set_property (GObject *object, E_FILE_ACTIVITY (object), g_value_get_object (value)); return; + + case PROP_FILE: + e_file_activity_set_file ( + E_FILE_ACTIVITY (object), + g_value_get_object (value)); + return; + + case PROP_RESULT: + e_file_activity_set_result ( + E_FILE_ACTIVITY (object), + g_value_get_object (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -66,6 +85,18 @@ file_activity_get_property (GObject *object, value, e_file_activity_get_cancellable ( E_FILE_ACTIVITY (object))); return; + + case PROP_FILE: + g_value_set_object ( + value, e_file_activity_get_file ( + E_FILE_ACTIVITY (object))); + return; + + case PROP_RESULT: + g_value_set_object ( + value, e_file_activity_get_result ( + E_FILE_ACTIVITY (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -85,6 +116,16 @@ file_activity_dispose (GObject *object) priv->cancellable = NULL; } + if (priv->result != NULL) { + g_object_unref (priv->result); + priv->result = NULL; + } + + if (priv->file != NULL) { + g_object_unref (priv->file); + priv->file = NULL; + } + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -129,6 +170,26 @@ file_activity_class_init (EFileActivityClass *class) NULL, G_TYPE_CANCELLABLE, G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILE, + g_param_spec_object ( + "file", + "File", + NULL, + G_TYPE_FILE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_RESULT, + g_param_spec_object ( + "result", + "Result", + NULL, + G_TYPE_ASYNC_RESULT, + G_PARAM_READWRITE)); } static void @@ -179,6 +240,22 @@ e_file_activity_new (const gchar *primary_text) "primary-text", primary_text, NULL); } +EActivity * +e_file_activity_newv (const gchar *format, ...) +{ + EActivity *activity; + gchar *primary_text; + va_list args; + + va_start (args, format); + primary_text = g_strdup_vprintf (format, args); + activity = e_file_activity_new (primary_text); + g_free (primary_text); + va_end (args); + + return activity; +} + GCancellable * e_file_activity_get_cancellable (EFileActivity *file_activity) { @@ -218,6 +295,60 @@ e_file_activity_set_cancellable (EFileActivity *file_activity, g_object_notify (G_OBJECT (file_activity), "cancellable"); } +GFile * +e_file_activity_get_file (EFileActivity *file_activity) +{ + g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); + + return file_activity->priv->file; +} + +void +e_file_activity_set_file (EFileActivity *file_activity, + GFile *file) +{ + g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + + if (file != NULL) { + g_return_if_fail (G_IS_FILE (file)); + g_object_ref (file); + } + + if (file_activity->priv->file != NULL) + g_object_unref (file_activity->priv->file); + + file_activity->priv->file = file; + + g_object_notify (G_OBJECT (file_activity), "file"); +} + +GAsyncResult * +e_file_activity_get_result (EFileActivity *file_activity) +{ + g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); + + return file_activity->priv->result; +} + +void +e_file_activity_set_result (EFileActivity *file_activity, + GAsyncResult *result) +{ + g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + + if (result != NULL) { + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_object_ref (result); + } + + if (file_activity->priv->result != NULL) + g_object_unref (file_activity->priv->result); + + file_activity->priv->result = result; + + g_object_notify (G_OBJECT (file_activity), "result"); +} + void e_file_activity_progress (goffset current_num_bytes, goffset total_num_bytes, diff --git a/widgets/misc/e-file-activity.h b/widgets/misc/e-file-activity.h index 4a57228872..acd144dec0 100644 --- a/widgets/misc/e-file-activity.h +++ b/widgets/misc/e-file-activity.h @@ -23,7 +23,7 @@ #define E_FILE_ACTIVITY_H #include -#include +#include /* Standard GObject macros */ #define E_TYPE_FILE_ACTIVITY \ @@ -61,9 +61,17 @@ struct _EFileActivityClass { GType e_file_activity_get_type (void); EActivity * e_file_activity_new (const gchar *primary_text); +EActivity * e_file_activity_newv (const gchar *format, + ...) G_GNUC_PRINTF (1, 2); GCancellable * e_file_activity_get_cancellable (EFileActivity *file_activity); void e_file_activity_set_cancellable (EFileActivity *file_activity, GCancellable *cancellable); +GFile * e_file_activity_get_file (EFileActivity *file_activity); +void e_file_activity_set_file (EFileActivity *file_activity, + GFile *file); +GAsyncResult * e_file_activity_get_result (EFileActivity *file_activity); +void e_file_activity_set_result (EFileActivity *file_activity, + GAsyncResult *result); /* This can be used as a GFileProgressCallback. */ void e_file_activity_progress (goffset current_num_bytes, diff --git a/widgets/misc/e-timeout-activity.c b/widgets/misc/e-timeout-activity.c index d02bcf96d2..878d6b87a3 100644 --- a/widgets/misc/e-timeout-activity.c +++ b/widgets/misc/e-timeout-activity.c @@ -21,6 +21,8 @@ #include "e-timeout-activity.h" +#include + #define E_TIMEOUT_ACTIVITY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityPrivate)) @@ -166,6 +168,22 @@ e_timeout_activity_new (const gchar *primary_text) "primary-text", primary_text, NULL); } +EActivity * +e_timeout_activity_newv (const gchar *format, ...) +{ + EActivity *activity; + gchar *primary_text; + va_list args; + + va_start (args, format); + primary_text = g_strdup_vprintf (format, args); + activity = e_timeout_activity_new (primary_text); + g_free (primary_text); + va_end (args); + + return activity; +} + void e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity, guint seconds) diff --git a/widgets/misc/e-timeout-activity.h b/widgets/misc/e-timeout-activity.h index 70aaee7dcb..b395f39bde 100644 --- a/widgets/misc/e-timeout-activity.h +++ b/widgets/misc/e-timeout-activity.h @@ -63,6 +63,8 @@ struct _ETimeoutActivityClass { GType e_timeout_activity_get_type (void); EActivity * e_timeout_activity_new (const gchar *primary_text); +EActivity * e_timeout_activity_newv (const gchar *format, + ...) G_GNUC_PRINTF (1, 2); void e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity, guint seconds); -- cgit v1.2.3 From 6e163b39c75dbba470d073b4f79a897aa6fb0e54 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 24 Mar 2009 02:05:26 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37470 --- widgets/misc/e-activity.c | 36 ++- widgets/misc/e-attachment-dialog.c | 25 +- widgets/misc/e-attachment-icon-view.c | 70 ++++- widgets/misc/e-attachment-paned.c | 176 +++++++++++-- widgets/misc/e-attachment-paned.h | 3 - widgets/misc/e-attachment-store.c | 170 +++++------- widgets/misc/e-attachment-store.h | 9 +- widgets/misc/e-attachment-tree-view.c | 50 +++- widgets/misc/e-attachment-view.c | 148 ++++++++++- widgets/misc/e-attachment-view.h | 5 + widgets/misc/e-attachment.c | 479 +++++++++++++++++++++++++++++++--- widgets/misc/e-attachment.h | 18 ++ 12 files changed, 985 insertions(+), 204 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index c65c3aaa0a..d40d5aacbe 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -69,6 +69,7 @@ activity_idle_cancel_cb (EActivity *activity) { activity->priv->idle_id = 0; e_activity_cancel (activity); + g_object_unref (activity); return FALSE; } @@ -78,6 +79,7 @@ activity_idle_complete_cb (EActivity *activity) { activity->priv->idle_id = 0; e_activity_complete (activity); + g_object_unref (activity); return FALSE; } @@ -474,13 +476,24 @@ e_activity_cancel (EActivity *activity) void e_activity_cancel_in_idle (EActivity *activity) { + guint old_idle_id; + g_return_if_fail (E_IS_ACTIVITY (activity)); - if (activity->priv->idle_id > 0) - g_source_remove (activity->priv->idle_id); + /* Be careful not to finalize the activity. Decrement the + * reference count only after incrementing it, in case this + * is the last reference. */ + + old_idle_id = activity->priv->idle_id; activity->priv->idle_id = g_idle_add ( - (GSourceFunc) activity_idle_cancel_cb, activity); + (GSourceFunc) activity_idle_cancel_cb, + g_object_ref (activity)); + + if (old_idle_id > 0) { + g_source_remove (old_idle_id); + g_object_unref (activity); + } } void @@ -500,13 +513,24 @@ e_activity_complete (EActivity *activity) void e_activity_complete_in_idle (EActivity *activity) { + guint old_idle_id; + g_return_if_fail (E_IS_ACTIVITY (activity)); - if (activity->priv->idle_id > 0) - g_source_remove (activity->priv->idle_id); + /* Be careful not to finalize the activity. Decrement the + * reference count only after incrementing it, in case this + * is the last reference. */ + + old_idle_id = activity->priv->idle_id; activity->priv->idle_id = g_idle_add ( - (GSourceFunc) activity_idle_complete_cb, activity); + (GSourceFunc) activity_idle_complete_cb, + g_object_ref (activity)); + + if (old_idle_id > 0) { + g_source_remove (old_idle_id); + g_object_unref (activity); + } } void diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index f697df1fe9..da3c3a855c 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -52,6 +52,7 @@ attachment_dialog_update (EAttachmentDialog *dialog) const gchar *display_name; const gchar *description; const gchar *disposition; + gchar *type_description = NULL; gboolean sensitive; gboolean active; @@ -71,32 +72,42 @@ attachment_dialog_update (EAttachmentDialog *dialog) disposition = NULL; } + if (content_type != NULL) { + gchar *comment; + gchar *mime_type; + + comment = g_content_type_get_description (content_type); + mime_type = g_content_type_get_mime_type (content_type); + + type_description = + g_strdup_printf ("%s (%s)", comment, mime_type); + + g_free (comment); + g_free (mime_type); + } + sensitive = G_IS_FILE_INFO (file_info); gtk_dialog_set_response_sensitive ( GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive); - if (display_name == NULL) - display_name = ""; widget = dialog->priv->display_name_entry; gtk_widget_set_sensitive (widget, sensitive); gtk_entry_set_text (GTK_ENTRY (widget), display_name); - if (description == NULL) - description = ""; widget = dialog->priv->description_entry; gtk_widget_set_sensitive (widget, sensitive); gtk_entry_set_text (GTK_ENTRY (widget), description); - if (content_type == NULL) - content_type = ""; widget = dialog->priv->content_type_label; - gtk_label_set_text (GTK_LABEL (widget), content_type); + gtk_label_set_text (GTK_LABEL (widget), type_description); active = (g_strcmp0 (disposition, "inline") == 0); widget = dialog->priv->disposition_checkbox; gtk_widget_set_sensitive (widget, sensitive); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active); + + g_free (type_description); } static void diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index 8d39a76d75..6d27429743 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -35,8 +35,47 @@ struct _EAttachmentIconViewPrivate { EAttachmentViewPrivate view_priv; }; +enum { + PROP_0, + PROP_EDITABLE +}; + static gpointer parent_class; +static void +attachment_icon_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EDITABLE: + e_attachment_view_set_editable ( + E_ATTACHMENT_VIEW (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_icon_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_attachment_view_get_editable ( + E_ATTACHMENT_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + static void attachment_icon_view_dispose (GObject *object) { @@ -231,6 +270,8 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class) g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_icon_view_set_property; + object_class->get_property = attachment_icon_view_get_property; object_class->dispose = attachment_icon_view_dispose; object_class->finalize = attachment_icon_view_finalize; @@ -240,6 +281,9 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class) widget_class->drag_motion = attachment_icon_view_drag_motion; widget_class->drag_data_received = attachment_icon_view_drag_data_received; widget_class->popup_menu = attachment_icon_view_popup_menu; + + g_object_class_override_property ( + object_class, PROP_EDITABLE, "editable"); } static void @@ -260,6 +304,10 @@ attachment_icon_view_iface_init (EAttachmentViewIface *iface) static void attachment_icon_view_init (EAttachmentIconView *icon_view) { + GtkCellLayout *cell_layout; + GtkCellRenderer *renderer; + + cell_layout = GTK_CELL_LAYOUT (icon_view); icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view); e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view)); @@ -267,13 +315,23 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) gtk_icon_view_set_selection_mode ( GTK_ICON_VIEW (icon_view), GTK_SELECTION_MULTIPLE); - gtk_icon_view_set_pixbuf_column ( - GTK_ICON_VIEW (icon_view), - E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF); + renderer = gtk_cell_renderer_pixbuf_new (); + g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "gicon", + E_ATTACHMENT_STORE_COLUMN_ICON); + + renderer = gtk_cell_renderer_text_new (); + g_object_set ( + renderer, "alignment", PANGO_ALIGN_CENTER, + "xalign", 0.5, NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); - gtk_icon_view_set_text_column ( - GTK_ICON_VIEW (icon_view), - E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION); + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "text", + E_ATTACHMENT_STORE_COLUMN_CAPTION); } GType diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index bb919e9789..5134282526 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -23,6 +23,7 @@ #include #include "e-util/e-binding.h" +#include "e-attachment-view.h" #include "e-attachment-store.h" #include "e-attachment-icon-view.h" #include "e-attachment-tree-view.h" @@ -52,6 +53,7 @@ struct _EAttachmentPanedPrivate { enum { PROP_0, PROP_ACTIVE_VIEW, + PROP_EDITABLE, PROP_EXPANDED }; @@ -118,7 +120,7 @@ attachment_paned_update_status (EAttachmentPaned *paned) gchar *display_size; gchar *markup; - view = e_attachment_paned_get_view (paned); + view = E_ATTACHMENT_VIEW (paned); store = e_attachment_view_get_store (view); expander = GTK_EXPANDER (paned->priv->expander); label = GTK_LABEL (paned->priv->status_label); @@ -149,9 +151,9 @@ attachment_paned_update_status (EAttachmentPaned *paned) static void attachment_paned_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { switch (property_id) { case PROP_ACTIVE_VIEW: @@ -160,6 +162,12 @@ attachment_paned_set_property (GObject *object, g_value_get_int (value)); return; + case PROP_EDITABLE: + e_attachment_view_set_editable ( + E_ATTACHMENT_VIEW (object), + g_value_get_boolean (value)); + return; + case PROP_EXPANDED: e_attachment_paned_set_expanded ( E_ATTACHMENT_PANED (object), @@ -172,9 +180,9 @@ attachment_paned_set_property (GObject *object, static void attachment_paned_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) + guint property_id, + GValue *value, + GParamSpec *pspec) { switch (property_id) { case PROP_ACTIVE_VIEW: @@ -183,6 +191,12 @@ attachment_paned_get_property (GObject *object, E_ATTACHMENT_PANED (object))); return; + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_attachment_view_get_editable ( + E_ATTACHMENT_VIEW (object))); + return; + case PROP_EXPANDED: g_value_set_boolean ( value, e_attachment_paned_get_expanded ( @@ -269,6 +283,14 @@ attachment_paned_constructed (GObject *object) G_OBJECT (object), "active-view", G_OBJECT (priv->notebook), "page"); + e_mutual_binding_new ( + G_OBJECT (object), "editable", + G_OBJECT (priv->icon_view), "editable"); + + e_mutual_binding_new ( + G_OBJECT (object), "editable", + G_OBJECT (priv->tree_view), "editable"); + e_mutual_binding_new ( G_OBJECT (object), "expanded", G_OBJECT (priv->expander), "expanded"); @@ -282,6 +304,110 @@ attachment_paned_constructed (GObject *object) G_OBJECT (priv->notebook), "visible"); } +static EAttachmentViewPrivate * +attachment_paned_get_private (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_private (view); +} + +static EAttachmentStore * +attachment_paned_get_store (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_store (view); +} + +static GtkTreePath * +attachment_paned_get_path_at_pos (EAttachmentView *view, + gint x, + gint y) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_path_at_pos (view, x, y); +} + +static GList * +attachment_paned_get_selected_paths (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_selected_paths (view); +} + +static gboolean +attachment_paned_path_is_selected (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_path_is_selected (view, path); +} + +static void +attachment_paned_select_path (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_select_path (view, path); +} + +static void +attachment_paned_unselect_path (EAttachmentView *view, + GtkTreePath *path) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_unselect_path (view, path); +} + +static void +attachment_paned_select_all (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_select_all (view); +} + +static void +attachment_paned_unselect_all (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_unselect_all (view); +} + static void attachment_paned_class_init (EAttachmentPanedClass *class) { @@ -319,6 +445,23 @@ attachment_paned_class_init (EAttachmentPanedClass *class) FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_override_property ( + object_class, PROP_EDITABLE, "editable"); +} + +static void +attachment_paned_iface_init (EAttachmentViewIface *iface) +{ + iface->get_private = attachment_paned_get_private; + iface->get_store = attachment_paned_get_store; + iface->get_path_at_pos = attachment_paned_get_path_at_pos; + iface->get_selected_paths = attachment_paned_get_selected_paths; + iface->path_is_selected = attachment_paned_path_is_selected; + iface->select_path = attachment_paned_select_path; + iface->unselect_path = attachment_paned_unselect_path; + iface->select_all = attachment_paned_select_all; + iface->unselect_all = attachment_paned_unselect_all; } static void @@ -394,7 +537,7 @@ attachment_paned_init (EAttachmentPaned *paned) gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6); paned->priv->status_label = g_object_ref (widget); - gtk_widget_show (widget); + gtk_widget_hide (widget); /* Construct the Attachment Views */ @@ -493,9 +636,18 @@ e_attachment_paned_get_type (void) NULL /* value_table */ }; + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) attachment_paned_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + type = g_type_register_static ( GTK_TYPE_VPANED, "EAttachmentPaned", &type_info, 0); + + g_type_add_interface_static ( + type, E_TYPE_ATTACHMENT_VIEW, &iface_info); } return type; @@ -507,14 +659,6 @@ e_attachment_paned_new (void) return g_object_new (E_TYPE_ATTACHMENT_PANED, NULL); } -EAttachmentView * -e_attachment_paned_get_view (EAttachmentPaned *paned) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL); - - return E_ATTACHMENT_VIEW (paned->priv->icon_view); -} - GtkWidget * e_attachment_paned_get_content_area (EAttachmentPaned *paned) { diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h index c6cad5226f..c15d642771 100644 --- a/widgets/misc/e-attachment-paned.h +++ b/widgets/misc/e-attachment-paned.h @@ -23,7 +23,6 @@ #define E_ATTACHMENT_PANED_H #include -#include /* Standard GObject macros */ #define E_TYPE_ATTACHMENT_PANED \ @@ -61,8 +60,6 @@ struct _EAttachmentPanedClass { GType e_attachment_paned_get_type (void); GtkWidget * e_attachment_paned_new (void); -EAttachmentView * - e_attachment_paned_get_view (EAttachmentPaned *paned); GtkWidget * e_attachment_paned_get_content_area (EAttachmentPaned *paned); gint e_attachment_paned_get_active_view diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 2658dd06c9..bd6cb18481 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -34,12 +34,6 @@ #define DEFAULT_ICON_NAME "mail-attachment" -/* XXX Unfortunate that we have to define this here. Would - * prefer the attachment view classes pick their own size, - * but GtkIconView requires a dedicated pixbuf column. */ -#define LARGE_ICON_SIZE GTK_ICON_SIZE_DIALOG -#define SMALL_ICON_SIZE GTK_ICON_SIZE_MENU - struct _EAttachmentStorePrivate { GHashTable *activity_index; GHashTable *attachment_index; @@ -56,7 +50,7 @@ enum { PROP_BACKGROUND_OPTIONS, PROP_CURRENT_FOLDER, PROP_NUM_ATTACHMENTS, - PROP_NUM_DOWNLOADING, + PROP_NUM_LOADING, PROP_TOTAL_SIZE }; @@ -133,7 +127,7 @@ attachment_store_remove_activity (EAttachmentStore *store, g_hash_table_remove (hash_table, activity); - g_object_notify (G_OBJECT (store), "num-downloading"); + g_object_notify (G_OBJECT (store), "num-loading"); } static void @@ -178,10 +172,6 @@ attachment_store_copy_ready (GFile *source, e_activity_complete (activity); - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); - g_object_unref (attachment); g_object_unref (activity); @@ -247,6 +237,7 @@ attachment_store_copy_async (EAttachmentStore *store, reference = gtk_tree_row_reference_copy (reference); + hash_table = store->priv->activity_index; g_hash_table_insert (hash_table, g_object_ref (activity), reference); g_signal_connect_swapped ( @@ -271,7 +262,7 @@ attachment_store_copy_async (EAttachmentStore *store, e_file_activity_set_file (E_FILE_ACTIVITY (activity), destination); g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity); - g_object_notify (G_OBJECT (store), "num-downloading"); + g_object_notify (G_OBJECT (store), "num-loading"); g_object_unref (activity); g_object_unref (destination); @@ -350,10 +341,10 @@ attachment_store_get_property (GObject *object, E_ATTACHMENT_STORE (object))); return; - case PROP_NUM_DOWNLOADING: + case PROP_NUM_LOADING: g_value_set_uint ( value, - e_attachment_store_get_num_downloading ( + e_attachment_store_get_num_loading ( E_ATTACHMENT_STORE (object))); return; @@ -427,31 +418,25 @@ attachment_store_row_changed (GtkTreeModel *model, { EAttachmentStorePrivate *priv; EAttachment *attachment; - GtkIconTheme *icon_theme; - GdkPixbuf *large_pixbuf; - GdkPixbuf *small_pixbuf; + GFile *file; GIcon *icon; + GList *list; const gchar *content_type; const gchar *display_name; const gchar *thumbnail_path; gchar *content_description; gchar *display_size; - gchar *icon_caption; - gint large_icon_size; - gint small_icon_size; + gchar *caption; + gboolean loading; + gboolean saving; guint64 size; gint column_id; - GError *error = NULL; priv = E_ATTACHMENT_STORE_GET_PRIVATE (model); if (priv->ignore_row_changed) return; - icon_theme = gtk_icon_theme_get_default (); - gtk_icon_size_lookup (LARGE_ICON_SIZE, &large_icon_size, NULL); - gtk_icon_size_lookup (SMALL_ICON_SIZE, &small_icon_size, NULL); - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; gtk_tree_model_get (model, iter, column_id, &attachment, -1); g_return_if_fail (E_IS_ATTACHMENT (attachment)); @@ -459,6 +444,8 @@ attachment_store_row_changed (GtkTreeModel *model, content_type = e_attachment_get_content_type (attachment); display_name = e_attachment_get_display_name (attachment); thumbnail_path = e_attachment_get_thumbnail_path (attachment); + loading = e_attachment_get_loading (attachment); + saving = e_attachment_get_saving (attachment); icon = e_attachment_get_icon (attachment); size = e_attachment_get_size (attachment); @@ -467,82 +454,46 @@ attachment_store_row_changed (GtkTreeModel *model, display_size = g_format_size_for_display ((goffset) size); if (size > 0) - icon_caption = g_strdup_printf ( + caption = g_strdup_printf ( "%s\n(%s)", display_name, display_size); else - icon_caption = g_strdup (display_name); + caption = g_strdup (display_name); /* Prefer the thumbnail if we have one. */ - if (thumbnail_path != NULL) { - gint width = -1; - gint height = -1; - - gdk_pixbuf_get_file_info (thumbnail_path, &width, &height); + if (thumbnail_path != NULL && *thumbnail_path != '\0') { + file = g_file_new_for_path (thumbnail_path); + icon = g_file_icon_new (file); + g_object_unref (file); - large_pixbuf = gdk_pixbuf_new_from_file_at_scale ( - thumbnail_path, - (width > height) ? large_icon_size : -1, - (width > height) ? -1 : large_icon_size, - TRUE, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } + /* Else use the standard icon for the content type. */ + } else if (icon != NULL) + g_object_ref (icon); - small_pixbuf = gdk_pixbuf_new_from_file_at_scale ( - thumbnail_path, - (width > height) ? small_icon_size : -1, - (width > height) ? -1 : small_icon_size, - TRUE, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - /* Otherwise fall back to the icon theme. */ - } else { - GtkIconInfo *icon_info = NULL; - const gchar *filename; - - if (G_IS_ICON (icon)) - icon_info = gtk_icon_theme_lookup_by_gicon ( - icon_theme, icon, large_icon_size, 0); - if (icon_info == NULL) - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, DEFAULT_ICON_NAME, - large_icon_size, 0); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - large_pixbuf = gdk_pixbuf_new_from_file (filename, &error); - gtk_icon_info_free (icon_info); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); + /* Last ditch fallback. (GFileInfo not yet loaded?) */ + else + icon = g_themed_icon_new (DEFAULT_ICON_NAME); + + /* Apply emblems. */ + list = e_attachment_list_emblems (attachment); + if (list != NULL) { + GIcon *emblemed_icon; + GEmblem *emblem; + + emblem = G_EMBLEM (list->data); + emblemed_icon = g_emblemed_icon_new (icon, emblem); + list = g_list_delete_link (list, list); + g_object_unref (emblem); + + while (list != NULL) { + emblem = G_EMBLEM (list->data); + g_emblemed_icon_add_emblem ( + G_EMBLEMED_ICON (emblemed_icon), emblem); + list = g_list_delete_link (list, list); + g_object_unref (emblem); } - icon_info = NULL; - - if (G_IS_ICON (icon)) - icon_info = gtk_icon_theme_lookup_by_gicon ( - icon_theme, icon, small_icon_size, 0); - if (icon_info == NULL) - icon_info = gtk_icon_theme_lookup_icon ( - icon_theme, DEFAULT_ICON_NAME, - small_icon_size, 0); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - small_pixbuf = gdk_pixbuf_new_from_file (filename, &error); - gtk_icon_info_free (icon_info); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } + g_object_unref (icon); + icon = emblemed_icon; } /* We're about to trigger another "row-changed" @@ -553,20 +504,16 @@ attachment_store_row_changed (GtkTreeModel *model, GTK_LIST_STORE (model), iter, E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_description, E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, - E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION, icon_caption, - E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF, large_pixbuf, - E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF, small_pixbuf, + E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, + E_ATTACHMENT_STORE_COLUMN_ICON, icon, + E_ATTACHMENT_STORE_COLUMN_LOADING, loading, + E_ATTACHMENT_STORE_COLUMN_SAVING, saving, E_ATTACHMENT_STORE_COLUMN_SIZE, size, -1); priv->ignore_row_changed = FALSE; - if (large_pixbuf != NULL) - g_object_unref (large_pixbuf); - - if (small_pixbuf != NULL) - g_object_unref (small_pixbuf); - + g_object_unref (icon); g_free (content_description); g_free (display_size); } @@ -633,10 +580,10 @@ attachment_store_class_init (EAttachmentStoreClass *class) g_object_class_install_property ( object_class, - PROP_NUM_DOWNLOADING, + PROP_NUM_LOADING, g_param_spec_uint ( - "num-downloading", - "Num Downloading", + "num-loading", + "Num Loading", NULL, 0, G_MAXUINT, @@ -686,11 +633,12 @@ attachment_store_init (EAttachmentStore *store) types[column++] = E_TYPE_ACTIVITY; /* COLUMN_ACTIVITY */ types[column++] = E_TYPE_ATTACHMENT; /* COLUMN_ATTACHMENT */ + types[column++] = G_TYPE_STRING; /* COLUMN_CAPTION */ types[column++] = G_TYPE_STRING; /* COLUMN_CONTENT_TYPE */ types[column++] = G_TYPE_STRING; /* COLUMN_DISPLAY_NAME */ - types[column++] = G_TYPE_STRING; /* COLUMN_ICON_CAPTION */ - types[column++] = GDK_TYPE_PIXBUF; /* COLUMN_LARGE_PIXBUF */ - types[column++] = GDK_TYPE_PIXBUF; /* COLUMN_SMALL_PIXBUF */ + types[column++] = G_TYPE_ICON; /* COLUMN_ICON */ + types[column++] = G_TYPE_BOOLEAN; /* COLUMN_LOADING */ + types[column++] = G_TYPE_BOOLEAN; /* COLUMN_SAVING */ types[column++] = G_TYPE_UINT64; /* COLUMN_SIZE */ g_assert (column == E_ATTACHMENT_STORE_NUM_COLUMNS); @@ -774,7 +722,7 @@ e_attachment_store_add_attachment (EAttachmentStore *store, /* This lets the attachment tell us when to update. */ _e_attachment_set_reference (attachment, reference); - if (!g_file_is_native (file)) + if (file != NULL && !g_file_is_native (file)) attachment_store_copy_async (store, attachment); g_object_freeze_notify (G_OBJECT (store)); @@ -897,7 +845,7 @@ e_attachment_store_get_num_attachments (EAttachmentStore *store) } guint -e_attachment_store_get_num_downloading (EAttachmentStore *store) +e_attachment_store_get_num_loading (EAttachmentStore *store) { g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index 906aee6638..971868258f 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -62,11 +62,12 @@ struct _EAttachmentStoreClass { enum { E_ATTACHMENT_STORE_COLUMN_ACTIVITY, /* E_TYPE_ACTIVITY */ E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, /* E_TYPE_ATTACHMENT */ + E_ATTACHMENT_STORE_COLUMN_CAPTION, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF, /* GDK_TYPE_PIXBUF */ - E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF, /* GDK_TYPE_PIXBUF */ + E_ATTACHMENT_STORE_COLUMN_ICON, /* G_TYPE_ICON */ + E_ATTACHMENT_STORE_COLUMN_LOADING, /* G_TYPE_BOOLEAN */ + E_ATTACHMENT_STORE_COLUMN_SAVING, /* G_TYPE_BOOLEAN */ E_ATTACHMENT_STORE_COLUMN_SIZE, /* G_TYPE_UINT64 */ E_ATTACHMENT_STORE_NUM_COLUMNS }; @@ -90,7 +91,7 @@ void e_attachment_store_set_current_folder const gchar *current_folder); guint e_attachment_store_get_num_attachments (EAttachmentStore *store); -guint e_attachment_store_get_num_downloading +guint e_attachment_store_get_num_loading (EAttachmentStore *store); guint64 e_attachment_store_get_total_size (EAttachmentStore *store); diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index 817a6c7dab..df01e07040 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -36,8 +36,47 @@ struct _EAttachmentTreeViewPrivate { EAttachmentViewPrivate view_priv; }; +enum { + PROP_0, + PROP_EDITABLE +}; + static gpointer parent_class; +static void +attachment_tree_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EDITABLE: + e_attachment_view_set_editable ( + E_ATTACHMENT_VIEW (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_tree_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_attachment_view_get_editable ( + E_ATTACHMENT_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + static void attachment_tree_view_dispose (GObject *object) { @@ -267,6 +306,8 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class) g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_tree_view_set_property; + object_class->get_property = attachment_tree_view_get_property; object_class->dispose = attachment_tree_view_dispose; object_class->finalize = attachment_tree_view_finalize; @@ -276,6 +317,9 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class) widget_class->drag_motion = attachment_tree_view_drag_motion; widget_class->drag_data_received = attachment_tree_view_drag_data_received; widget_class->popup_menu = attachment_tree_view_popup_menu; + + g_object_class_override_property ( + object_class, PROP_EDITABLE, "editable"); } static void @@ -318,9 +362,11 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) renderer = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); + g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL); + gtk_tree_view_column_add_attribute ( - column, renderer, "pixbuf", - E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF); + column, renderer, "gicon", + E_ATTACHMENT_STORE_COLUMN_ICON); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 198ce75d31..bdb0a0067e 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -25,6 +25,7 @@ #include #include +#include "e-util/e-binding.h" #include "e-util/e-plugin-ui.h" #include "e-util/e-util.h" #include "e-attachment-dialog.h" @@ -122,6 +123,30 @@ action_drag_move_cb (GtkAction *action, e_attachment_view_drag_action (view, GDK_ACTION_MOVE); } +static void +action_open_in_cb (GtkAction *action, + EAttachmentView *view) +{ + GAppInfo *app_info; + EActivity *activity; + EAttachment *attachment; + + app_info = g_object_get_data (G_OBJECT (action), "app-info"); + g_return_if_fail (G_IS_APP_INFO (app_info)); + + attachment = g_object_get_data (G_OBJECT (action), "attachment"); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + activity = e_file_activity_newv ( + _("Opening attachment in %s"), + g_app_info_get_name (app_info)); + + e_attachment_launch_async ( + attachment, E_FILE_ACTIVITY (activity), app_info); + + g_object_unref (activity); +} + static void action_properties_cb (GtkAction *action, EAttachmentView *view) @@ -407,6 +432,16 @@ attachment_view_class_init (EAttachmentViewIface *iface) { gint ii; + g_object_interface_install_property ( + iface, + g_param_spec_boolean ( + "editable", + "Editable", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) { const gchar *target = drag_info[ii].target; drag_info[ii].atom = gdk_atom_intern (target, FALSE); @@ -489,6 +524,10 @@ e_attachment_view_init (EAttachmentView *view) if (error != NULL) g_error ("%s", error->message); + e_mutual_binding_new ( + G_OBJECT (view), "editable", + G_OBJECT (priv->editable_actions), "visible"); + e_plugin_ui_register_manager (ui_manager, "attachment-view", view); } @@ -562,6 +601,32 @@ e_attachment_view_get_store (EAttachmentView *view) return iface->get_store (view); } +gboolean +e_attachment_view_get_editable (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + + priv = e_attachment_view_get_private (view); + + return priv->editable; +} + +void +e_attachment_view_set_editable (EAttachmentView *view, + gboolean editable) +{ + EAttachmentViewPrivate *priv; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + priv = e_attachment_view_get_private (view); + priv->editable = editable; + + g_object_notify (G_OBJECT (view), "editable"); +} + GList * e_attachment_view_get_selected_attachments (EAttachmentView *view) { @@ -1006,27 +1071,29 @@ void e_attachment_view_update_actions (EAttachmentView *view) { EAttachmentViewPrivate *priv; - GFileInfo *file_info; + EAttachment *attachment; GtkAction *action; - GList *selected; + GList *list, *iter; guint n_selected; gboolean is_image; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); priv = e_attachment_view_get_private (view); - selected = e_attachment_view_get_selected_attachments (view); - n_selected = g_list_length (selected); - - is_image = FALSE; - file_info = NULL; + list = e_attachment_view_get_selected_attachments (view); + n_selected = g_list_length (list); if (n_selected == 1) { - EAttachment *attachment = selected->data; - file_info = e_attachment_get_file_info (attachment); + attachment = g_object_ref (list->data); is_image = e_attachment_is_image (attachment); + } else { + attachment = NULL; + is_image = FALSE; } + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + action = e_attachment_view_get_action (view, "properties"); gtk_action_set_visible (action, n_selected == 1); @@ -1038,4 +1105,67 @@ e_attachment_view_update_actions (EAttachmentView *view) action = e_attachment_view_get_action (view, "set-background"); gtk_action_set_visible (action, is_image); + + /* Clear out the "openwith" action group. */ + gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); + e_action_group_remove_all_actions (priv->openwith_actions); + + if (attachment == NULL) + return; + + list = e_attachment_list_apps (attachment); + + for (iter = list; iter != NULL; iter = iter->next) { + GAppInfo *app_info = iter->data; + GtkAction *action; + const gchar *app_executable; + const gchar *app_name; + gchar *action_tooltip; + gchar *action_label; + gchar *action_name; + + if (!g_app_info_should_show (app_info)) + continue; + + app_executable = g_app_info_get_executable (app_info); + app_name = g_app_info_get_name (app_info); + + action_name = g_strdup_printf ("open-in-%s", app_executable); + action_label = g_strdup_printf (_("Open in %s..."), app_name); + + action_tooltip = g_strdup_printf ( + _("Open this attachment in %s"), app_name); + + action = gtk_action_new ( + action_name, action_label, action_tooltip, NULL); + + g_object_set_data_full ( + G_OBJECT (action), + "app-info", g_object_ref (app_info), + (GDestroyNotify) g_object_unref); + + g_object_set_data_full ( + G_OBJECT (action), + "attachment", g_object_ref (attachment), + (GDestroyNotify) g_object_unref); + + g_signal_connect ( + action, "activate", + G_CALLBACK (action_open_in_cb), view); + + gtk_action_group_add_action (priv->openwith_actions, action); + + gtk_ui_manager_add_ui ( + priv->ui_manager, priv->merge_id, + "/context/open-actions", action_name, + action_name, GTK_UI_MANAGER_AUTO, FALSE); + + g_free (action_name); + g_free (action_label); + g_free (action_tooltip); + } + + g_object_unref (attachment); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index a00308d2d5..e6e04a82a3 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -88,6 +88,8 @@ struct _EAttachmentViewPrivate { GtkSelectionData *selection_data; guint info; guint time; + + guint editable : 1; }; GType e_attachment_view_get_type (void); @@ -100,6 +102,9 @@ EAttachmentViewPrivate * e_attachment_view_get_private (EAttachmentView *view); EAttachmentStore * e_attachment_view_get_store (EAttachmentView *view); +gboolean e_attachment_view_get_editable (EAttachmentView *view); +void e_attachment_view_set_editable (EAttachmentView *view, + gboolean editable); GList * e_attachment_view_get_selected_attachments (EAttachmentView *view); void e_attachment_view_remove_selected diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 6f9e80f02b..015a706dc4 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -36,6 +36,16 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) +/* Emblems */ +#define EMBLEM_LOADING "emblem-downloads" +#define EMBLEM_SAVING "document-save" +#define EMBLEM_ENCRYPT_WEAK "security-low" +#define EMBLEM_ENCRYPT_STRONG "security-high" +#define EMBLEM_ENCRYPT_UNKNOWN "security-medium" +#define EMBLEM_SIGN_BAD "stock_signature_bad" +#define EMBLEM_SIGN_GOOD "stock_signature-ok" +#define EMBLEM_SIGN_UNKNOWN "stock_signature" + /* Attributes needed by EAttachmentStore, et al. */ #define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*" @@ -45,6 +55,11 @@ struct _EAttachmentPrivate { GCancellable *cancellable; CamelMimePart *mime_part; gchar *disposition; + guint loading : 1; + guint saving : 1; + + camel_cipher_validity_encrypt_t encrypted; + camel_cipher_validity_sign_t signed_; /* This is a reference to our row in an EAttachmentStore, * serving as a means of broadcasting "row-changed" signals. @@ -56,9 +71,12 @@ struct _EAttachmentPrivate { enum { PROP_0, PROP_DISPOSITION, + PROP_ENCRYPTED, PROP_FILE, PROP_FILE_INFO, - PROP_MIME_PART + PROP_LOADING, + PROP_MIME_PART, + PROP_SIGNED }; static gpointer parent_class; @@ -89,6 +107,8 @@ attachment_notify_model (EAttachment *attachment) gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_row_changed (model, path, &iter); + + /* XXX This doesn't really belong here. */ g_object_notify (G_OBJECT (model), "total-size"); gtk_tree_path_free (path); @@ -101,7 +121,7 @@ attachment_get_default_charset (void) const gchar *key; gchar *charset; - /* XXX This function doesn't really belong here. */ + /* XXX This doesn't really belong here. */ client = gconf_client_get_default (); key = "/apps/evolution/mail/composer/charset"; @@ -149,7 +169,26 @@ attachment_set_file_info (EAttachment *attachment, attachment->priv->file_info = file_info; g_object_notify (G_OBJECT (attachment), "file-info"); + attachment_notify_model (attachment); +} +static void +attachment_set_loading (EAttachment *attachment, + gboolean loading) +{ + attachment->priv->loading = loading; + + g_object_notify (G_OBJECT (attachment), "loading"); + attachment_notify_model (attachment); +} + +static void +attachment_set_saving (EAttachment *attachment, + gboolean saving) +{ + attachment->priv->saving = saving; + + g_object_notify (G_OBJECT (attachment), "saving"); attachment_notify_model (attachment); } @@ -162,7 +201,7 @@ attachment_reset (EAttachment *attachment) g_object_freeze_notify (G_OBJECT (attachment)); - /* Cancel any query operations in progress. */ + /* Cancel any I/O operations in progress. */ if (!g_cancellable_is_cancelled (cancellable)) { g_cancellable_cancel (cancellable); g_cancellable_reset (cancellable); @@ -220,7 +259,8 @@ attachment_file_info_to_mime_part (EAttachment *attachment, if (file_info == NULL || mime_part == NULL) return; - /* XXX Note that we skip "standard::size" here. */ + /* XXX Note that we skip "standard::size" here. + * The CamelMimePart already knows the size. */ attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; string = g_file_info_get_attribute_string (file_info, attribute); @@ -241,28 +281,55 @@ attachment_file_info_to_mime_part (EAttachment *attachment, } static void -attachment_mime_part_to_file_info (EAttachment *attachment) +attachment_populate_file_info (EAttachment *attachment, + GFileInfo *file_info) { CamelContentType *content_type; CamelMimePart *mime_part; - GFileInfo *file_info; const gchar *attribute; const gchar *string; gchar *allocated; guint64 v_uint64; - file_info = e_attachment_get_file_info (attachment); mime_part = e_attachment_get_mime_part (attachment); - if (file_info == NULL || mime_part == NULL) - return; - attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; content_type = camel_mime_part_get_content_type (mime_part); allocated = camel_content_type_simple (content_type); - if (allocated != NULL) + if (allocated != NULL) { + GIcon *icon; + gchar *cp; + + /* GIO expects lowercase MIME types. */ + for (cp = allocated; *cp != '\0'; cp++) + *cp = g_ascii_tolower (*cp); + + /* Swap the MIME type for a content type. */ + cp = g_content_type_from_mime_type (allocated); + g_free (allocated); + allocated = cp; + + /* Use the MIME part's filename if we have to. */ + if (g_content_type_is_unknown (allocated)) { + string = camel_mime_part_get_filename (mime_part); + if (string != NULL) { + g_free (allocated); + allocated = g_content_type_guess ( + string, NULL, 0, NULL); + } + } + g_file_info_set_attribute_string ( file_info, attribute, allocated); + + attribute = G_FILE_ATTRIBUTE_STANDARD_ICON; + icon = g_content_type_get_icon (allocated); + if (icon != NULL) { + g_file_info_set_attribute_object ( + file_info, attribute, G_OBJECT (icon)); + g_object_unref (icon); + } + } g_free (allocated); attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; @@ -298,6 +365,12 @@ attachment_set_property (GObject *object, g_value_get_string (value)); return; + case PROP_ENCRYPTED: + e_attachment_set_encrypted ( + E_ATTACHMENT (object), + g_value_get_int (value)); + return; + case PROP_FILE: e_attachment_set_file ( E_ATTACHMENT (object), @@ -309,6 +382,12 @@ attachment_set_property (GObject *object, E_ATTACHMENT (object), g_value_get_boxed (value)); return; + + case PROP_SIGNED: + e_attachment_set_signed ( + E_ATTACHMENT (object), + g_value_get_int (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -327,6 +406,12 @@ attachment_get_property (GObject *object, E_ATTACHMENT (object))); return; + case PROP_ENCRYPTED: + g_value_set_int ( + value, e_attachment_get_encrypted ( + E_ATTACHMENT (object))); + return; + case PROP_FILE: g_value_set_object ( value, e_attachment_get_file ( @@ -339,11 +424,23 @@ attachment_get_property (GObject *object, E_ATTACHMENT (object))); return; + case PROP_LOADING: + g_value_set_boolean ( + value, e_attachment_get_loading ( + E_ATTACHMENT (object))); + return; + case PROP_MIME_PART: g_value_set_boxed ( value, e_attachment_get_mime_part ( E_ATTACHMENT (object))); return; + + case PROP_SIGNED: + g_value_set_int ( + value, e_attachment_get_signed ( + E_ATTACHMENT (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -423,6 +520,20 @@ attachment_class_init (EAttachmentClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /* FIXME Define a GEnumClass for this. */ + g_object_class_install_property ( + object_class, + PROP_ENCRYPTED, + g_param_spec_int ( + "encrypted", + "Encrypted", + NULL, + CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE, + CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG, + CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property ( object_class, PROP_FILE, @@ -444,6 +555,16 @@ attachment_class_init (EAttachmentClass *class) G_TYPE_FILE_INFO, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_LOADING, + g_param_spec_boolean ( + "loading", + "Loading", + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property ( object_class, PROP_MIME_PART, @@ -453,6 +574,20 @@ attachment_class_init (EAttachmentClass *class) NULL, E_TYPE_CAMEL_OBJECT, G_PARAM_READWRITE)); + + /* FIXME Define a GEnumClass for this. */ + g_object_class_install_property ( + object_class, + PROP_SIGNED, + g_param_spec_int ( + "signed", + "Signed", + NULL, + CAMEL_CIPHER_VALIDITY_SIGN_NONE, + CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY, + CAMEL_CIPHER_VALIDITY_SIGN_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); } static void @@ -460,6 +595,8 @@ attachment_init (EAttachment *attachment) { attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment); attachment->priv->cancellable = g_cancellable_new (); + attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; + attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE; } GType @@ -724,8 +861,6 @@ void e_attachment_set_mime_part (EAttachment *attachment, CamelMimePart *mime_part) { - GFileInfo *file_info; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_object_freeze_notify (G_OBJECT (attachment)); @@ -738,16 +873,64 @@ e_attachment_set_mime_part (EAttachment *attachment, attachment_reset (attachment); attachment->priv->mime_part = mime_part; - file_info = g_file_info_new (); - attachment_set_file_info (attachment, file_info); - attachment_mime_part_to_file_info (attachment); - g_object_unref (file_info); + if (mime_part != NULL) { + GFileInfo *file_info; + + file_info = g_file_info_new (); + attachment_populate_file_info (attachment, file_info); + attachment_set_file_info (attachment, file_info); + g_object_unref (file_info); + } g_object_notify (G_OBJECT (attachment), "mime-part"); g_object_thaw_notify (G_OBJECT (attachment)); } +camel_cipher_validity_encrypt_t +e_attachment_get_encrypted (EAttachment *attachment) +{ + g_return_val_if_fail ( + E_IS_ATTACHMENT (attachment), + CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE); + + return attachment->priv->encrypted; +} + +void +e_attachment_set_encrypted (EAttachment *attachment, + camel_cipher_validity_encrypt_t encrypted) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + attachment->priv->encrypted = encrypted; + + g_object_notify (G_OBJECT (attachment), "encrypted"); + attachment_notify_model (attachment); +} + +camel_cipher_validity_sign_t +e_attachment_get_signed (EAttachment *attachment) +{ + g_return_val_if_fail ( + E_IS_ATTACHMENT (attachment), + CAMEL_CIPHER_VALIDITY_SIGN_NONE); + + return attachment->priv->signed_; +} + +void +e_attachment_set_signed (EAttachment *attachment, + camel_cipher_validity_sign_t signed_) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + attachment->priv->signed_ = signed_; + + g_object_notify (G_OBJECT (attachment), "signed"); + attachment_notify_model (attachment); +} + const gchar * e_attachment_get_content_type (EAttachment *attachment) { @@ -817,6 +1000,14 @@ e_attachment_get_icon (EAttachment *attachment) g_file_info_get_attribute_object (file_info, attribute); } +gboolean +e_attachment_get_loading (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->loading; +} + const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment) { @@ -834,6 +1025,14 @@ e_attachment_get_thumbnail_path (EAttachment *attachment) return g_file_info_get_attribute_byte_string (file_info, attribute); } +gboolean +e_attachment_get_saving (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->saving; +} + guint64 e_attachment_get_size (EAttachment *attachment) { @@ -881,24 +1080,225 @@ e_attachment_is_rfc822 (EAttachment *attachment) return g_content_type_equals (content_type, "message/rfc822"); } +GList * +e_attachment_list_apps (EAttachment *attachment) +{ + GList *app_info_list; + const gchar *content_type; + const gchar *display_name; + gchar *allocated; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + content_type = e_attachment_get_content_type (attachment); + display_name = e_attachment_get_display_name (attachment); + g_return_val_if_fail (content_type != NULL, NULL); + + app_info_list = g_app_info_get_all_for_type (content_type); + + if (app_info_list != NULL || display_name == NULL) + goto exit; + + if (!g_content_type_is_unknown (content_type)) + goto exit; + + allocated = g_content_type_guess (display_name, NULL, 0, NULL); + app_info_list = g_app_info_get_all_for_type (allocated); + g_free (allocated); + +exit: + return app_info_list; +} + +GList * +e_attachment_list_emblems (EAttachment *attachment) +{ + GList *list = NULL; + GIcon *icon; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + if (e_attachment_get_loading (attachment)) { + icon = g_themed_icon_new (EMBLEM_LOADING); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + } + + if (e_attachment_get_saving (attachment)) { + icon = g_themed_icon_new (EMBLEM_SAVING); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + } + + switch (e_attachment_get_encrypted (attachment)) { + case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK: + icon = g_themed_icon_new (EMBLEM_ENCRYPT_WEAK); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED: + icon = g_themed_icon_new (EMBLEM_ENCRYPT_UNKNOWN); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG: + icon = g_themed_icon_new (EMBLEM_ENCRYPT_STRONG); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + default: + break; + } + + switch (e_attachment_get_signed (attachment)) { + case CAMEL_CIPHER_VALIDITY_SIGN_GOOD: + icon = g_themed_icon_new (EMBLEM_SIGN_GOOD); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_BAD: + icon = g_themed_icon_new (EMBLEM_SIGN_BAD); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN: + case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY: + icon = g_themed_icon_new (EMBLEM_SIGN_UNKNOWN); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + break; + + default: + break; + } + + return list; +} + +/************************ e_attachment_launch_async() ************************/ + +static void +attachment_launch_file (EActivity *activity, + GAppInfo *app_info, + GFile *file) +{ + GdkAppLaunchContext *launch_context; + GList *file_list; + GError *error = NULL; + + file_list = g_list_prepend (NULL, file); + launch_context = gdk_app_launch_context_new (); + + g_app_info_launch ( + app_info, file_list, + G_APP_LAUNCH_CONTEXT (launch_context), &error); + + g_list_free (file_list); + g_object_unref (launch_context); + + if (error != NULL) { + e_activity_set_error (activity, error); + g_error_free (error); + } + + e_activity_complete (activity); + g_object_unref (activity); +} + +void +e_attachment_launch_async (EAttachment *attachment, + EFileActivity *file_activity, + GAppInfo *app_info) +{ + CamelMimePart *mime_part; + GFile *file; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + g_return_if_fail (G_IS_APP_INFO (app_info)); + + file = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (file != NULL || mime_part != NULL); + + /* If the attachment already references a GFile, we can launch + * the application directly. Otherwise we have to save the MIME + * part to a temporary file and launch the application from that. */ + if (G_IS_FILE (file)) { + EActivity *activity = g_object_ref (file_activity); + attachment_launch_file (activity, app_info, file); + + } else if (CAMEL_IS_MIME_PART (mime_part)) { + /* XXX Not done yet. */ + } +} + +/************************* e_attachment_save_async() *************************/ + +typedef struct _AttachmentSaveContext AttachmentSaveContext; + +struct _AttachmentSaveContext { + EAttachment *attachment; + EFileActivity *file_activity; + GOutputStream *output_stream; +}; + +static AttachmentSaveContext * +attachment_save_context_new (EAttachment *attachment, + EFileActivity *file_activity) +{ + AttachmentSaveContext *save_context; + + save_context = g_slice_new (AttachmentSaveContext); + save_context->attachment = g_object_ref (attachment); + save_context->file_activity = g_object_ref (file_activity); + save_context->output_stream = NULL; + + attachment_set_saving (save_context->attachment, TRUE); + + return save_context; +} + +static void +attachment_save_context_free (AttachmentSaveContext *save_context) +{ + attachment_set_saving (save_context->attachment, FALSE); + + g_object_unref (save_context->attachment); + g_object_unref (save_context->file_activity); + + if (save_context->output_stream != NULL) + g_object_unref (save_context->output_stream); + + g_slice_free (AttachmentSaveContext, save_context); +} + static void attachment_save_file_cb (GFile *source, GAsyncResult *result, - EActivity *activity) + AttachmentSaveContext *save_context) { + EActivity *activity; GError *error = NULL; + activity = E_ACTIVITY (save_context->file_activity); + if (!g_file_copy_finish (source, result, &error)) { e_activity_set_error (activity, error); g_error_free (error); } e_activity_complete (activity); - g_object_unref (activity); + attachment_save_context_free (save_context); } static gpointer -attachment_save_part_thread (EActivity *activity) +attachment_save_part_thread (AttachmentSaveContext *save_context) { GObject *object; EAttachment *attachment; @@ -910,12 +1310,11 @@ attachment_save_part_thread (EActivity *activity) CamelStream *stream; GError *error = NULL; - object = G_OBJECT (activity); - attachment = g_object_get_data (object, "attachment"); - output_stream = g_object_get_data (object, "output-stream"); + attachment = save_context->attachment; + file_activity = save_context->file_activity; + output_stream = save_context->output_stream; /* Last chance to cancel. */ - file_activity = E_FILE_ACTIVITY (activity); cancellable = e_file_activity_get_cancellable (file_activity); if (g_cancellable_set_error_if_cancelled (cancellable, &error)) goto exit; @@ -941,12 +1340,12 @@ attachment_save_part_thread (EActivity *activity) exit: if (error != NULL) { - e_activity_set_error (activity, error); + e_activity_set_error (E_ACTIVITY (file_activity), error); g_error_free (error); } - e_activity_complete_in_idle (activity); - g_object_unref (activity); + e_activity_complete_in_idle (E_ACTIVITY (file_activity)); + attachment_save_context_free (save_context); return NULL; } @@ -954,30 +1353,28 @@ exit: static void attachment_save_part_cb (GFile *destination, GAsyncResult *result, - EActivity *activity) + AttachmentSaveContext *save_context) { GFileOutputStream *output_stream; + EActivity *activity; GError *error = NULL; + activity = E_ACTIVITY (save_context->file_activity); output_stream = g_file_replace_finish (destination, result, &error); + save_context->output_stream = G_OUTPUT_STREAM (output_stream); - if (output_stream != NULL) { - g_object_set_data_full ( - G_OBJECT (activity), - "output-stream", output_stream, - (GDestroyNotify) g_object_unref); + if (output_stream != NULL) g_thread_create ( (GThreadFunc) attachment_save_part_thread, - activity, FALSE, &error); - } + save_context, FALSE, &error); if (error != NULL) { e_activity_set_error (activity, error); e_activity_complete (activity); - g_object_unref (activity); g_error_free (error); - } + attachment_save_context_free (save_context); + } } void @@ -985,14 +1382,15 @@ e_attachment_save_async (EAttachment *attachment, EFileActivity *file_activity, GFile *destination) { + AttachmentSaveContext *save_context; GFileProgressCallback progress_callback; GCancellable *cancellable; CamelMimePart *mime_part; GFile *source; g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_FILE (destination)); g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); + g_return_if_fail (G_IS_FILE (destination)); /* The attachment content is either a GFile (on disk) or a * CamelMimePart (in memory). Each is saved differently. */ @@ -1001,6 +1399,7 @@ e_attachment_save_async (EAttachment *attachment, mime_part = e_attachment_get_mime_part (attachment); g_return_if_fail (source != NULL || mime_part != NULL); + save_context = attachment_save_context_new (attachment, file_activity); cancellable = e_file_activity_get_cancellable (file_activity); progress_callback = e_file_activity_progress; @@ -1017,7 +1416,7 @@ e_attachment_save_async (EAttachment *attachment, G_PRIORITY_DEFAULT, cancellable, progress_callback, file_activity, (GAsyncReadyCallback) attachment_save_file_cb, - g_object_ref (file_activity)); + save_context); /* CamelMimePart can only be decoded to a file synchronously, so * we do this in two stages. Stage one asynchronously opens the @@ -1034,7 +1433,7 @@ e_attachment_save_async (EAttachment *attachment, G_FILE_CREATE_REPLACE_DESTINATION, G_PRIORITY_DEFAULT, cancellable, (GAsyncReadyCallback) attachment_save_part_cb, - g_object_ref (file_activity)); + save_context); } } diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index a7bb85dd75..d9ef68bf39 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -23,6 +23,7 @@ #define E_ATTACHMENT_H #include +#include #include #include #include @@ -80,14 +81,31 @@ GFileInfo * e_attachment_get_file_info (EAttachment *attachment); CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment); void e_attachment_set_mime_part (EAttachment *attachment, CamelMimePart *mime_part); +camel_cipher_validity_encrypt_t + e_attachment_get_encrypted (EAttachment *attachment); +void e_attachment_set_encrypted (EAttachment *attachment, + camel_cipher_validity_encrypt_t encrypted); +camel_cipher_validity_sign_t + e_attachment_get_signed (EAttachment *attachment); +void e_attachment_set_signed (EAttachment *attachment, + camel_cipher_validity_sign_t signed_); const gchar * e_attachment_get_content_type (EAttachment *attachment); const gchar * e_attachment_get_display_name (EAttachment *attachment); const gchar * e_attachment_get_description (EAttachment *attachment); GIcon * e_attachment_get_icon (EAttachment *attachment); +gboolean e_attachment_get_loading (EAttachment *attachment); const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); +gboolean e_attachment_get_saving (EAttachment *attachment); guint64 e_attachment_get_size (EAttachment *attachment); gboolean e_attachment_is_image (EAttachment *attachment); gboolean e_attachment_is_rfc822 (EAttachment *attachment); +GList * e_attachment_list_apps (EAttachment *attachment); +GList * e_attachment_list_emblems (EAttachment *attachment); + +/* Asynchronous Operations */ +void e_attachment_launch_async (EAttachment *attachment, + EFileActivity *file_activity, + GAppInfo *app_info); void e_attachment_save_async (EAttachment *attachment, EFileActivity *file_activity, GFile *destination); -- cgit v1.2.3 From c05c973cff53769ef575bfc5257a2a414117b323 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 26 Mar 2009 04:48:21 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37476 --- widgets/misc/e-attachment-dialog.c | 14 +- widgets/misc/e-attachment-icon-view.c | 42 +- widgets/misc/e-attachment-store.c | 303 ++--- widgets/misc/e-attachment-store.h | 4 +- widgets/misc/e-attachment-tree-view.c | 44 + widgets/misc/e-attachment-view.c | 151 ++- widgets/misc/e-attachment-view.h | 3 + widgets/misc/e-attachment.c | 1941 +++++++++++++++++++++------------ widgets/misc/e-attachment.h | 58 +- 9 files changed, 1586 insertions(+), 974 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index da3c3a855c..a844c228eb 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -58,20 +58,24 @@ attachment_dialog_update (EAttachmentDialog *dialog) attachment = e_attachment_dialog_get_attachment (dialog); - if (E_IS_ATTACHMENT (attachment)) { + if (attachment != NULL) { file_info = e_attachment_get_file_info (attachment); - content_type = e_attachment_get_content_type (attachment); - display_name = e_attachment_get_display_name (attachment); description = e_attachment_get_description (attachment); disposition = e_attachment_get_disposition (attachment); } else { file_info = NULL; - content_type = NULL; - display_name = NULL; description = NULL; disposition = NULL; } + if (file_info != NULL) { + content_type = g_file_info_get_content_type (file_info); + display_name = g_file_info_get_display_name (file_info); + } else { + content_type = NULL; + display_name = NULL; + } + if (content_type != NULL) { gchar *comment; gchar *mime_type; diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index 6d27429743..f6e42b2fbe 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -21,6 +21,7 @@ #include "e-attachment-icon-view.h" +#include #include #include "e-attachment.h" @@ -163,6 +164,15 @@ attachment_icon_view_popup_menu (GtkWidget *widget) return TRUE; } +static void +attachment_icon_view_item_activated (GtkIconView *icon_view, + GtkTreePath *path) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (icon_view); + + e_attachment_view_open_path (view, path, NULL); +} + static EAttachmentViewPrivate * attachment_icon_view_get_private (EAttachmentView *view) { @@ -265,6 +275,7 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class) { GObjectClass *object_class; GtkWidgetClass *widget_class; + GtkIconViewClass *icon_view_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); @@ -282,6 +293,9 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class) widget_class->drag_data_received = attachment_icon_view_drag_data_received; widget_class->popup_menu = attachment_icon_view_popup_menu; + icon_view_class = GTK_ICON_VIEW_CLASS (class); + icon_view_class->item_activated = attachment_icon_view_item_activated; + g_object_class_override_property ( object_class, PROP_EDITABLE, "editable"); } @@ -317,7 +331,7 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); gtk_cell_layout_add_attribute ( cell_layout, renderer, "gicon", @@ -327,11 +341,35 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) g_object_set ( renderer, "alignment", PANGO_ALIGN_CENTER, "xalign", 0.5, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); gtk_cell_layout_add_attribute ( cell_layout, renderer, "text", E_ATTACHMENT_STORE_COLUMN_CAPTION); + + renderer = gtk_cell_renderer_progress_new (); + g_object_set (renderer, "text", _("Loading"), NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "value", + E_ATTACHMENT_STORE_COLUMN_PERCENT); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "visible", + E_ATTACHMENT_STORE_COLUMN_LOADING); + + renderer = gtk_cell_renderer_progress_new (); + g_object_set (renderer, "text", _("Saving"), NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "value", + E_ATTACHMENT_STORE_COLUMN_PERCENT); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "visible", + E_ATTACHMENT_STORE_COLUMN_SAVING); } GType diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index bd6cb18481..6086ed4d2f 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -26,8 +26,6 @@ #include "e-util/e-util.h" #include "e-util/gconf-bridge.h" -#include "e-file-activity.h" - #define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStorePrivate)) @@ -35,7 +33,6 @@ #define DEFAULT_ICON_NAME "mail-attachment" struct _EAttachmentStorePrivate { - GHashTable *activity_index; GHashTable *attachment_index; gchar *background_filename; gchar *background_options; @@ -54,13 +51,7 @@ enum { PROP_TOTAL_SIZE }; -enum { - NEW_ACTIVITY, - LAST_SIGNAL -}; - static gpointer parent_class; -static guint signals[LAST_SIGNAL]; static const gchar * attachment_store_get_background_filename (EAttachmentStore *store) @@ -100,183 +91,6 @@ attachment_store_set_background_options (EAttachmentStore *store, g_object_notify (G_OBJECT (store), "background-options"); } -static void -attachment_store_remove_activity (EAttachmentStore *store, - EActivity *activity) -{ - GtkTreeRowReference *reference; - GHashTable *hash_table; - - hash_table = store->priv->activity_index; - reference = g_hash_table_lookup (hash_table, activity); - - if (gtk_tree_row_reference_valid (reference)) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - gtk_list_store_set ( - GTK_LIST_STORE (store), &iter, - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, NULL, -1); - } - - g_hash_table_remove (hash_table, activity); - - g_object_notify (G_OBJECT (store), "num-loading"); -} - -static void -attachment_store_copy_ready (GFile *source, - GAsyncResult *result, - GtkTreeRowReference *reference) -{ - EAttachmentStore *store; - EAttachment *attachment; - EActivity *activity; - GFile *destination; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean valid; - GError *error = NULL; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - valid = gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - g_return_if_fail (valid); - - gtk_tree_model_get ( - model, &iter, - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, &activity, - E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, &attachment, -1); - - gtk_tree_row_reference_free (reference); - - store = E_ATTACHMENT_STORE (model); - - if (!g_file_copy_finish (source, result, &error)) - goto fail; - - gtk_list_store_set ( - GTK_LIST_STORE (store), &iter, - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, NULL, -1); - - destination = e_file_activity_get_file (E_FILE_ACTIVITY (activity)); - e_attachment_set_file (attachment, destination); - - e_activity_complete (activity); - - g_object_unref (attachment); - g_object_unref (activity); - - return; - -fail: - e_attachment_store_remove_attachment (store, attachment); - - g_object_unref (attachment); - g_object_unref (activity); - - /* XXX Do something more useful with the error. */ - g_warning ("%s", error->message); - g_error_free (error); -} - -static void -attachment_store_copy_async (EAttachmentStore *store, - EAttachment *attachment) -{ - EActivity *activity; - GCancellable *cancellable; - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - GHashTable *hash_table; - GFile *destination; - GFile *source; - gboolean valid; - gchar *filename; - gchar *uri; - gint fd; - GError *error = NULL; - - hash_table = store->priv->attachment_index; - reference = g_hash_table_lookup (hash_table, attachment); - g_return_if_fail (reference != NULL); - - fd = e_file_open_tmp (&filename, &error); - if (error != NULL) - goto fail; - - source = e_attachment_get_file (attachment); - destination = g_file_new_for_path (filename); - - g_free (filename); - close (fd); - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - valid = gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - g_return_if_fail (valid); - - uri = g_file_get_uri (source); - activity = e_file_activity_newv (_("Downloading '%s'"), uri); - g_free (uri); - - gtk_list_store_set ( - GTK_LIST_STORE (store), &iter, - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, activity, -1); - - reference = gtk_tree_row_reference_copy (reference); - - hash_table = store->priv->activity_index; - g_hash_table_insert (hash_table, g_object_ref (activity), reference); - - g_signal_connect_swapped ( - activity, "cancelled", - G_CALLBACK (attachment_store_remove_activity), store); - - g_signal_connect_swapped ( - activity, "completed", - G_CALLBACK (attachment_store_remove_activity), store); - - reference = gtk_tree_row_reference_copy (reference); - - cancellable = e_file_activity_get_cancellable ( - E_FILE_ACTIVITY (activity)); - - g_file_copy_async ( - source, destination, G_FILE_COPY_OVERWRITE, - G_PRIORITY_DEFAULT, cancellable, (GFileProgressCallback) - e_file_activity_progress, activity, (GAsyncReadyCallback) - attachment_store_copy_ready, reference); - - e_file_activity_set_file (E_FILE_ACTIVITY (activity), destination); - g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity); - - g_object_notify (G_OBJECT (store), "num-loading"); - - g_object_unref (activity); - g_object_unref (destination); - - return; - -fail: - e_attachment_store_remove_attachment (store, attachment); - - /* XXX Do something more useful with the error. */ - g_warning ("%s", error->message); - g_error_free (error); -} - static void attachment_store_set_property (GObject *object, guint property_id, @@ -366,7 +180,6 @@ attachment_store_dispose (GObject *object) priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); - g_hash_table_remove_all (priv->activity_index); g_hash_table_remove_all (priv->attachment_index); /* Chain up to parent's dispose() method. */ @@ -380,7 +193,6 @@ attachment_store_finalize (GObject *object) priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); - g_hash_table_destroy (priv->activity_index); g_hash_table_destroy (priv->attachment_index); g_free (priv->background_filename); @@ -418,6 +230,7 @@ attachment_store_row_changed (GtkTreeModel *model, { EAttachmentStorePrivate *priv; EAttachment *attachment; + GFileInfo *file_info; GFile *file; GIcon *icon; GList *list; @@ -429,8 +242,9 @@ attachment_store_row_changed (GtkTreeModel *model, gchar *caption; gboolean loading; gboolean saving; - guint64 size; + goffset size; gint column_id; + gint percent; priv = E_ATTACHMENT_STORE_GET_PRIVATE (model); @@ -441,17 +255,24 @@ attachment_store_row_changed (GtkTreeModel *model, gtk_tree_model_get (model, iter, column_id, &attachment, -1); g_return_if_fail (E_IS_ATTACHMENT (attachment)); - content_type = e_attachment_get_content_type (attachment); - display_name = e_attachment_get_display_name (attachment); + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) { + g_object_unref (attachment); + return; + } + + content_type = g_file_info_get_content_type (file_info); + display_name = g_file_info_get_display_name (file_info); thumbnail_path = e_attachment_get_thumbnail_path (attachment); loading = e_attachment_get_loading (attachment); + percent = e_attachment_get_percent (attachment); saving = e_attachment_get_saving (attachment); - icon = e_attachment_get_icon (attachment); - size = e_attachment_get_size (attachment); + icon = g_file_info_get_icon (file_info); + size = g_file_info_get_size (file_info); content_type = (content_type != NULL) ? content_type : ""; content_description = g_content_type_get_description (content_type); - display_size = g_format_size_for_display ((goffset) size); + display_size = g_format_size_for_display (size); if (size > 0) caption = g_strdup_printf ( @@ -507,6 +328,7 @@ attachment_store_row_changed (GtkTreeModel *model, E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, E_ATTACHMENT_STORE_COLUMN_ICON, icon, E_ATTACHMENT_STORE_COLUMN_LOADING, loading, + E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, E_ATTACHMENT_STORE_COLUMN_SAVING, saving, E_ATTACHMENT_STORE_COLUMN_SIZE, size, -1); @@ -613,31 +435,24 @@ static void attachment_store_init (EAttachmentStore *store) { GType types[E_ATTACHMENT_STORE_NUM_COLUMNS]; - GHashTable *activity_index; GHashTable *attachment_index; gint column = 0; - activity_index = g_hash_table_new_full ( - g_direct_hash, g_direct_equal, - (GDestroyNotify) g_object_unref, - (GDestroyNotify) gtk_tree_row_reference_free); - attachment_index = g_hash_table_new_full ( g_direct_hash, g_direct_equal, (GDestroyNotify) g_object_unref, (GDestroyNotify) gtk_tree_row_reference_free); store->priv = E_ATTACHMENT_STORE_GET_PRIVATE (store); - store->priv->activity_index = activity_index; store->priv->attachment_index = attachment_index; - types[column++] = E_TYPE_ACTIVITY; /* COLUMN_ACTIVITY */ types[column++] = E_TYPE_ATTACHMENT; /* COLUMN_ATTACHMENT */ types[column++] = G_TYPE_STRING; /* COLUMN_CAPTION */ types[column++] = G_TYPE_STRING; /* COLUMN_CONTENT_TYPE */ types[column++] = G_TYPE_STRING; /* COLUMN_DISPLAY_NAME */ types[column++] = G_TYPE_ICON; /* COLUMN_ICON */ types[column++] = G_TYPE_BOOLEAN; /* COLUMN_LOADING */ + types[column++] = G_TYPE_INT; /* COLUMN_PERCENT */ types[column++] = G_TYPE_BOOLEAN; /* COLUMN_SAVING */ types[column++] = G_TYPE_UINT64; /* COLUMN_SIZE */ @@ -720,10 +535,7 @@ e_attachment_store_add_attachment (EAttachmentStore *store, file = e_attachment_get_file (attachment); /* This lets the attachment tell us when to update. */ - _e_attachment_set_reference (attachment, reference); - - if (file != NULL && !g_file_is_native (file)) - attachment_store_copy_async (store, attachment); + e_attachment_set_reference (attachment, reference); g_object_freeze_notify (G_OBJECT (store)); g_object_notify (G_OBJECT (store), "num-attachments"); @@ -737,7 +549,6 @@ e_attachment_store_remove_attachment (EAttachmentStore *store, { GtkTreeRowReference *reference; GHashTable *hash_table; - EActivity *activity; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; @@ -756,21 +567,14 @@ e_attachment_store_remove_attachment (EAttachmentStore *store, return FALSE; } + e_attachment_cancel (attachment); + e_attachment_set_reference (attachment, NULL); + model = gtk_tree_row_reference_get_model (reference); path = gtk_tree_row_reference_get_path (reference); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); - gtk_tree_model_get ( - model, &iter, - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, &activity, -1); - - if (activity != NULL) { - /* Cancel the file transfer. */ - e_activity_cancel (activity); - g_object_unref (activity); - } - gtk_list_store_remove (GTK_LIST_STORE (store), &iter); g_hash_table_remove (hash_table, attachment); @@ -804,8 +608,10 @@ e_attachment_store_add_to_multipart (EAttachmentStore *store, column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - e_attachment_add_to_multipart ( - attachment, multipart, default_charset); + /* Skip the attachment if it's still loading. */ + if (!e_attachment_get_loading (attachment)) + e_attachment_add_to_multipart ( + attachment, multipart, default_charset); g_object_unref (attachment); @@ -847,17 +653,38 @@ e_attachment_store_get_num_attachments (EAttachmentStore *store) guint e_attachment_store_get_num_loading (EAttachmentStore *store) { + GtkTreeModel *model; + GtkTreeIter iter; + guint num_loading = 0; + gboolean valid; + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - return g_hash_table_size (store->priv->activity_index); + model = GTK_TREE_MODEL (store); + valid = gtk_tree_model_get_iter_first (model, &iter); + + while (valid) { + EAttachment *attachment; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + if (e_attachment_get_loading (attachment)) + num_loading++; + g_object_unref (attachment); + + valid = gtk_tree_model_iter_next (model, &iter); + } + + return num_loading; } -guint64 +goffset e_attachment_store_get_total_size (EAttachmentStore *store) { GtkTreeModel *model; GtkTreeIter iter; - guint64 total_size = 0; + goffset total_size = 0; gboolean valid; g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); @@ -867,11 +694,14 @@ e_attachment_store_get_total_size (EAttachmentStore *store) while (valid) { EAttachment *attachment; + GFileInfo *file_info; gint column_id; column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - total_size += e_attachment_get_size (attachment); + file_info = e_attachment_get_file_info (attachment); + if (file_info != NULL) + total_size += g_file_info_get_size (file_info); g_object_unref (attachment); valid = gtk_tree_model_iter_next (model, &iter); @@ -928,6 +758,7 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store, gint response; g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (GTK_IS_WINDOW (parent)); dialog = gtk_file_chooser_dialog_new ( _("Add Attachment"), parent, @@ -962,6 +793,9 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store, attachment = e_attachment_new (); e_attachment_set_file (attachment, file); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_object_unref (attachment); } @@ -979,13 +813,14 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, { GtkFileChooser *file_chooser; GtkWidget *dialog; - GFile *file; - EActivity *activity; + GFile *destination; + GFileInfo *file_info; const gchar *display_name; gint response; g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (GTK_IS_WINDOW (parent)); dialog = gtk_file_chooser_dialog_new ( _("Save Attachment"), parent, @@ -999,7 +834,11 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); - display_name = e_attachment_get_display_name (attachment); + file_info = e_attachment_get_file_info (attachment); + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + else + display_name = NULL; if (display_name != NULL) gtk_file_chooser_set_current_name (file_chooser, display_name); @@ -1008,13 +847,13 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, if (response != GTK_RESPONSE_OK) goto exit; - file = gtk_file_chooser_get_file (file_chooser); - activity = e_file_activity_new (_("Saving attachment")); + destination = gtk_file_chooser_get_file (file_chooser); + e_attachment_save_async ( - attachment, E_FILE_ACTIVITY (activity), file); - g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity); - g_object_unref (activity); - g_object_unref (file); + attachment, destination, (GAsyncReadyCallback) + e_attachment_save_handle_error, parent); + + g_object_unref (destination); exit: gtk_widget_destroy (dialog); diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index 971868258f..e7f74102be 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -60,13 +60,13 @@ struct _EAttachmentStoreClass { }; enum { - E_ATTACHMENT_STORE_COLUMN_ACTIVITY, /* E_TYPE_ACTIVITY */ E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, /* E_TYPE_ATTACHMENT */ E_ATTACHMENT_STORE_COLUMN_CAPTION, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_ICON, /* G_TYPE_ICON */ E_ATTACHMENT_STORE_COLUMN_LOADING, /* G_TYPE_BOOLEAN */ + E_ATTACHMENT_STORE_COLUMN_PERCENT, /* G_TYPE_INT */ E_ATTACHMENT_STORE_COLUMN_SAVING, /* G_TYPE_BOOLEAN */ E_ATTACHMENT_STORE_COLUMN_SIZE, /* G_TYPE_UINT64 */ E_ATTACHMENT_STORE_NUM_COLUMNS @@ -93,7 +93,7 @@ guint e_attachment_store_get_num_attachments (EAttachmentStore *store); guint e_attachment_store_get_num_loading (EAttachmentStore *store); -guint64 e_attachment_store_get_total_size +goffset e_attachment_store_get_total_size (EAttachmentStore *store); gint e_attachment_store_run_file_chooser_dialog (EAttachmentStore *store, diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index df01e07040..548ed3aa4f 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -182,6 +182,16 @@ attachment_tree_view_popup_menu (GtkWidget *widget) return TRUE; } +static void +attachment_tree_view_row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (tree_view); + + e_attachment_view_open_path (view, path, NULL); +} + static EAttachmentViewPrivate * attachment_tree_view_get_private (EAttachmentView *view) { @@ -301,6 +311,7 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class) { GObjectClass *object_class; GtkWidgetClass *widget_class; + GtkTreeViewClass *tree_view_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EAttachmentViewPrivate)); @@ -318,6 +329,9 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class) widget_class->drag_data_received = attachment_tree_view_drag_data_received; widget_class->popup_menu = attachment_tree_view_popup_menu; + tree_view_class = GTK_TREE_VIEW_CLASS (class); + tree_view_class->row_activated = attachment_tree_view_row_activated; + g_object_class_override_property ( object_class, PROP_EDITABLE, "editable"); } @@ -353,6 +367,8 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + /* Name Column */ + column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_spacing (column, 3); @@ -376,6 +392,32 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) column, renderer, "text", E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME); + renderer = gtk_cell_renderer_progress_new (); + g_object_set (renderer, "text", _("Loading"), NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "value", + E_ATTACHMENT_STORE_COLUMN_PERCENT); + + gtk_tree_view_column_add_attribute ( + column, renderer, "visible", + E_ATTACHMENT_STORE_COLUMN_LOADING); + + renderer = gtk_cell_renderer_progress_new (); + g_object_set (renderer, "text", _("Saving"), NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "value", + E_ATTACHMENT_STORE_COLUMN_PERCENT); + + gtk_tree_view_column_add_attribute ( + column, renderer, "visible", + E_ATTACHMENT_STORE_COLUMN_SAVING); + + /* Size Column */ + column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Size")); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); @@ -387,6 +429,8 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) column, renderer, (GtkTreeCellDataFunc) attachment_tree_view_render_size, NULL, NULL); + /* Type Column */ + column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Type")); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index bdb0a0067e..cb735fbfec 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -67,6 +67,7 @@ static struct { static const gchar *ui = "" " " +" " " " " " " " @@ -99,6 +100,23 @@ action_add_cb (GtkAction *action, e_attachment_store_run_load_dialog (store, parent); } +static void +action_cancel_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = selected->data; + + e_attachment_cancel (attachment); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + static void action_drag_cancel_cb (GtkAction *action, EAttachmentView *view) @@ -128,23 +146,20 @@ action_open_in_cb (GtkAction *action, EAttachmentView *view) { GAppInfo *app_info; - EActivity *activity; - EAttachment *attachment; + GtkTreePath *path; + GList *selected; + + selected = e_attachment_view_get_selected_paths (view); + g_return_if_fail (g_list_length (selected) == 1); + path = selected->data; app_info = g_object_get_data (G_OBJECT (action), "app-info"); g_return_if_fail (G_IS_APP_INFO (app_info)); - attachment = g_object_get_data (G_OBJECT (action), "attachment"); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - activity = e_file_activity_newv ( - _("Opening attachment in %s"), - g_app_info_get_name (app_info)); + e_attachment_view_open_path (view, path, app_info); - e_attachment_launch_async ( - attachment, E_FILE_ACTIVITY (activity), app_info); - - g_object_unref (activity); + g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected); } static void @@ -178,14 +193,21 @@ action_recent_cb (GtkAction *action, GtkRecentChooser *chooser; EAttachmentStore *store; EAttachment *attachment; + gpointer parent; gchar *uri; chooser = GTK_RECENT_CHOOSER (action); store = e_attachment_view_get_store (view); + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + uri = gtk_recent_chooser_get_current_uri (chooser); attachment = e_attachment_new_for_uri (uri); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_free (uri); } @@ -200,16 +222,42 @@ static void action_save_as_cb (GtkAction *action, EAttachmentView *view) { + EAttachmentStore *store; + EAttachment *attachment; + GList *selected; + gpointer parent; + + store = e_attachment_view_get_store (view); + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = selected->data; + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + e_attachment_store_run_save_dialog (store, attachment, parent); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); } static void action_set_background_cb (GtkAction *action, EAttachmentView *view) { + /* FIXME */ } static GtkActionEntry standard_entries[] = { + { "cancel", + GTK_STOCK_CANCEL, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_cancel_cb) }, + { "drag-cancel", NULL, N_("Cancel _Drag"), @@ -284,6 +332,7 @@ drop_message_rfc822 (EAttachmentView *view, const gchar *data; gboolean success = FALSE; gboolean delete = FALSE; + gpointer parent; gint length; priv = e_attachment_view_get_private (view); @@ -301,8 +350,14 @@ drop_message_rfc822 (EAttachmentView *view, if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1) goto exit; + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + attachment = e_attachment_new_for_message (message); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_object_unref (attachment); success = TRUE; @@ -324,6 +379,7 @@ drop_netscape_url (EAttachmentView *view, EAttachmentViewPrivate *priv; EAttachment *attachment; const gchar *data; + gpointer parent; gchar *copied_data; gchar **strv; gint length; @@ -339,8 +395,14 @@ drop_netscape_url (EAttachmentView *view, strv = g_strsplit (copied_data, "\n", 2); g_free (copied_data); + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + attachment = e_attachment_new_for_uri (strv[0]); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_object_unref (attachment); g_strfreev (strv); @@ -355,6 +417,7 @@ drop_text_uri_list (EAttachmentView *view, GdkDragAction action) { EAttachmentViewPrivate *priv; + gpointer parent; gchar **uris; gint ii; @@ -362,11 +425,17 @@ drop_text_uri_list (EAttachmentView *view, uris = gtk_selection_data_get_uris (selection_data); + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + for (ii = 0; uris[ii] != NULL; ii++) { EAttachment *attachment; attachment = e_attachment_new_for_uri (uris[ii]); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_object_unref (attachment); } @@ -386,6 +455,7 @@ drop_text_generic (EAttachmentView *view, CamelMimePart *mime_part; GdkAtom atom; const gchar *data; + gpointer parent; gchar *content_type; gint length; @@ -402,9 +472,15 @@ drop_text_generic (EAttachmentView *view, camel_mime_part_set_disposition (mime_part, "inline"); g_free (content_type); + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + attachment = e_attachment_new (); e_attachment_set_mime_part (attachment, mime_part); e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); g_object_unref (attachment); camel_object_unref (mime_part); @@ -635,6 +711,8 @@ e_attachment_view_get_selected_attachments (EAttachmentView *view) GList *selected, *item; gint column_id; + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; selected = e_attachment_view_get_selected_paths (view); store = e_attachment_view_get_store (view); @@ -657,6 +735,39 @@ e_attachment_view_get_selected_attachments (EAttachmentView *view) return selected; } + +void +e_attachment_view_open_path (EAttachmentView *view, + GtkTreePath *path, + GAppInfo *app_info) +{ + EAttachmentStore *store; + EAttachment *attachment; + GtkTreeModel *model; + GtkTreeIter iter; + gpointer parent; + gint column_id; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (path != NULL); + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + store = e_attachment_view_get_store (view); + model = GTK_TREE_MODEL (store); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + e_attachment_open_async ( + attachment, app_info, (GAsyncReadyCallback) + e_attachment_open_handle_error, parent); + + g_object_unref (attachment); +} + void e_attachment_view_remove_selected (EAttachmentView *view, gboolean select_next) @@ -1076,6 +1187,7 @@ e_attachment_view_update_actions (EAttachmentView *view) GList *list, *iter; guint n_selected; gboolean is_image; + gboolean busy = FALSE; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); @@ -1086,6 +1198,8 @@ e_attachment_view_update_actions (EAttachmentView *view) if (n_selected == 1) { attachment = g_object_ref (list->data); is_image = e_attachment_is_image (attachment); + busy |= e_attachment_get_loading (attachment); + busy |= e_attachment_get_saving (attachment); } else { attachment = NULL; is_image = FALSE; @@ -1094,23 +1208,26 @@ e_attachment_view_update_actions (EAttachmentView *view) g_list_foreach (list, (GFunc) g_object_unref, NULL); g_list_free (list); + action = e_attachment_view_get_action (view, "cancel"); + gtk_action_set_visible (action, busy); + action = e_attachment_view_get_action (view, "properties"); - gtk_action_set_visible (action, n_selected == 1); + gtk_action_set_visible (action, !busy && n_selected == 1); action = e_attachment_view_get_action (view, "remove"); - gtk_action_set_visible (action, n_selected > 0); + gtk_action_set_visible (action, !busy && n_selected > 0); action = e_attachment_view_get_action (view, "save-as"); - gtk_action_set_visible (action, n_selected > 0); + gtk_action_set_visible (action, !busy && n_selected == 1); action = e_attachment_view_get_action (view, "set-background"); - gtk_action_set_visible (action, is_image); + gtk_action_set_visible (action, !busy && is_image); /* Clear out the "openwith" action group. */ gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); e_action_group_remove_all_actions (priv->openwith_actions); - if (attachment == NULL) + if (attachment == NULL || busy) return; list = e_attachment_list_apps (attachment); diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index e6e04a82a3..96a0f2dc16 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -107,6 +107,9 @@ void e_attachment_view_set_editable (EAttachmentView *view, gboolean editable); GList * e_attachment_view_get_selected_attachments (EAttachmentView *view); +void e_attachment_view_open_path (EAttachmentView *view, + GtkTreePath *path, + GAppInfo *app_info); void e_attachment_view_remove_selected (EAttachmentView *view, gboolean select_next); diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 015a706dc4..55b3280e87 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) /* Emblems */ +#define EMBLEM_CANCELLED "gtk-cancel" #define EMBLEM_LOADING "emblem-downloads" #define EMBLEM_SAVING "document-save" #define EMBLEM_ENCRYPT_WEAK "security-low" @@ -54,7 +56,10 @@ struct _EAttachmentPrivate { GFileInfo *file_info; GCancellable *cancellable; CamelMimePart *mime_part; + guint emblem_timeout_id; gchar *disposition; + gint percent; + guint loading : 1; guint saving : 1; @@ -76,44 +81,14 @@ enum { PROP_FILE_INFO, PROP_LOADING, PROP_MIME_PART, + PROP_PERCENT, + PROP_REFERENCE, + PROP_SAVING, PROP_SIGNED }; static gpointer parent_class; -static void -attachment_notify_model (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - reference = attachment->priv->reference; - - if (reference == NULL) - return; - - /* Free the reference if it's no longer valid. - * It means we've been removed from the store. */ - if (!gtk_tree_row_reference_valid (reference)) { - gtk_tree_row_reference_free (reference); - attachment->priv->reference = NULL; - return; - } - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_row_changed (model, path, &iter); - - /* XXX This doesn't really belong here. */ - g_object_notify (G_OBJECT (model), "total-size"); - - gtk_tree_path_free (path); -} - static gchar * attachment_get_default_charset (void) { @@ -146,19 +121,35 @@ attachment_get_default_charset (void) return charset; } +static void +attachment_notify_model (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + reference = e_attachment_get_reference (attachment); + + if (reference == NULL) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_row_changed (model, path, &iter); + + gtk_tree_path_free (path); +} + static void attachment_set_file_info (EAttachment *attachment, GFileInfo *file_info) { - GCancellable *cancellable; - - cancellable = attachment->priv->cancellable; + GtkTreeRowReference *reference; - /* Cancel any query operations in progress. */ - if (!g_cancellable_is_cancelled (cancellable)) { - g_cancellable_cancel (cancellable); - g_cancellable_reset (cancellable); - } + reference = e_attachment_get_reference (attachment); if (file_info != NULL) g_object_ref (file_info); @@ -169,6 +160,14 @@ attachment_set_file_info (EAttachment *attachment, attachment->priv->file_info = file_info; g_object_notify (G_OBJECT (attachment), "file-info"); + + /* Tell the EAttachmentStore its total size changed. */ + if (reference != NULL) { + GtkTreeModel *model; + model = gtk_tree_row_reference_get_model (reference); + g_object_notify (G_OBJECT (model), "total-size"); + } + attachment_notify_model (attachment); } @@ -176,9 +175,24 @@ static void attachment_set_loading (EAttachment *attachment, gboolean loading) { + GtkTreeRowReference *reference; + + reference = e_attachment_get_reference (attachment); + + attachment->priv->percent = 0; attachment->priv->loading = loading; + g_object_freeze_notify (G_OBJECT (attachment)); + g_object_notify (G_OBJECT (attachment), "percent"); g_object_notify (G_OBJECT (attachment), "loading"); + g_object_thaw_notify (G_OBJECT (attachment)); + + if (reference != NULL) { + GtkTreeModel *model; + model = gtk_tree_row_reference_get_model (reference); + g_object_notify (G_OBJECT (model), "num-loading"); + } + attachment_notify_model (attachment); } @@ -186,170 +200,53 @@ static void attachment_set_saving (EAttachment *attachment, gboolean saving) { + attachment->priv->percent = 0; attachment->priv->saving = saving; - g_object_notify (G_OBJECT (attachment), "saving"); - attachment_notify_model (attachment); -} - -static void -attachment_reset (EAttachment *attachment) -{ - GCancellable *cancellable; - - cancellable = attachment->priv->cancellable; - g_object_freeze_notify (G_OBJECT (attachment)); - - /* Cancel any I/O operations in progress. */ - if (!g_cancellable_is_cancelled (cancellable)) { - g_cancellable_cancel (cancellable); - g_cancellable_reset (cancellable); - } - - if (attachment->priv->file != NULL) { - g_object_notify (G_OBJECT (attachment), "file"); - g_object_unref (attachment->priv->file); - attachment->priv->file = NULL; - } - - if (attachment->priv->mime_part != NULL) { - g_object_notify (G_OBJECT (attachment), "mime-part"); - g_object_unref (attachment->priv->mime_part); - attachment->priv->mime_part = NULL; - } - - attachment_set_file_info (attachment, NULL); - + g_object_notify (G_OBJECT (attachment), "percent"); + g_object_notify (G_OBJECT (attachment), "saving"); g_object_thaw_notify (G_OBJECT (attachment)); + + attachment_notify_model (attachment); } static void -attachment_file_info_ready_cb (GFile *file, - GAsyncResult *result, - EAttachment *attachment) +attachment_progress_cb (goffset current_num_bytes, + goffset total_num_bytes, + EAttachment *attachment) { - GFileInfo *file_info; - GError *error = NULL; + attachment->priv->percent = + (current_num_bytes * 100) / total_num_bytes; - /* Even if we failed to obtain a GFileInfo, we still emit a - * "notify::file-info" to signal the async operation finished. */ - file_info = g_file_query_info_finish (file, result, &error); - attachment_set_file_info (attachment, file_info); + g_object_notify (G_OBJECT (attachment), "percent"); - if (file_info != NULL) - g_object_unref (file_info); - else { - g_warning ("%s", error->message); - g_error_free (error); - } + attachment_notify_model (attachment); } -static void -attachment_file_info_to_mime_part (EAttachment *attachment, - CamelMimePart *mime_part) +static gboolean +attachment_cancelled_timeout_cb (EAttachment *attachment) { - GFileInfo *file_info; - const gchar *attribute; - const gchar *string; - gchar *allocated; - - file_info = e_attachment_get_file_info (attachment); + attachment->priv->emblem_timeout_id = 0; + g_cancellable_reset (attachment->priv->cancellable); - if (file_info == NULL || mime_part == NULL) - return; - - /* XXX Note that we skip "standard::size" here. - * The CamelMimePart already knows the size. */ - - attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; - string = g_file_info_get_attribute_string (file_info, attribute); - allocated = g_content_type_get_mime_type (string); - camel_mime_part_set_content_type (mime_part, allocated); - g_free (allocated); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; - string = g_file_info_get_attribute_string (file_info, attribute); - camel_mime_part_set_filename (mime_part, string); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - string = g_file_info_get_attribute_string (file_info, attribute); - camel_mime_part_set_description (mime_part, string); + attachment_notify_model (attachment); - string = e_attachment_get_disposition (attachment); - camel_mime_part_set_disposition (mime_part, string); + return FALSE; } static void -attachment_populate_file_info (EAttachment *attachment, - GFileInfo *file_info) +attachment_cancelled_cb (EAttachment *attachment) { - CamelContentType *content_type; - CamelMimePart *mime_part; - const gchar *attribute; - const gchar *string; - gchar *allocated; - guint64 v_uint64; - - mime_part = e_attachment_get_mime_part (attachment); - - attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; - content_type = camel_mime_part_get_content_type (mime_part); - allocated = camel_content_type_simple (content_type); - if (allocated != NULL) { - GIcon *icon; - gchar *cp; - - /* GIO expects lowercase MIME types. */ - for (cp = allocated; *cp != '\0'; cp++) - *cp = g_ascii_tolower (*cp); - - /* Swap the MIME type for a content type. */ - cp = g_content_type_from_mime_type (allocated); - g_free (allocated); - allocated = cp; - - /* Use the MIME part's filename if we have to. */ - if (g_content_type_is_unknown (allocated)) { - string = camel_mime_part_get_filename (mime_part); - if (string != NULL) { - g_free (allocated); - allocated = g_content_type_guess ( - string, NULL, 0, NULL); - } - } - - g_file_info_set_attribute_string ( - file_info, attribute, allocated); - - attribute = G_FILE_ATTRIBUTE_STANDARD_ICON; - icon = g_content_type_get_icon (allocated); - if (icon != NULL) { - g_file_info_set_attribute_object ( - file_info, attribute, G_OBJECT (icon)); - g_object_unref (icon); - } - } - g_free (allocated); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; - string = camel_mime_part_get_filename (mime_part); - if (string != NULL) - g_file_info_set_attribute_string ( - file_info, attribute, string); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; - string = camel_mime_part_get_description (mime_part); - if (string != NULL) - g_file_info_set_attribute_string ( - file_info, attribute, string); + /* Reset the GCancellable after one second. This causes a + * cancel emblem to be briefly shown on the attachment icon + * as visual feedback that an operation was cancelled. */ - attribute = G_FILE_ATTRIBUTE_STANDARD_SIZE; - v_uint64 = camel_mime_part_get_content_size (mime_part); - g_file_info_set_attribute_uint64 (file_info, attribute, v_uint64); + if (attachment->priv->emblem_timeout_id > 0) + g_source_remove (attachment->priv->emblem_timeout_id); - string = camel_mime_part_get_disposition (mime_part); - e_attachment_set_disposition (attachment, string); + attachment->priv->emblem_timeout_id = g_timeout_add_seconds ( + 1, (GSourceFunc) attachment_cancelled_timeout_cb, attachment); } static void @@ -383,6 +280,12 @@ attachment_set_property (GObject *object, g_value_get_boxed (value)); return; + case PROP_REFERENCE: + e_attachment_set_reference ( + E_ATTACHMENT (object), + g_value_get_boxed (value)); + return; + case PROP_SIGNED: e_attachment_set_signed ( E_ATTACHMENT (object), @@ -436,6 +339,24 @@ attachment_get_property (GObject *object, E_ATTACHMENT (object))); return; + case PROP_PERCENT: + g_value_set_int ( + value, e_attachment_get_percent ( + E_ATTACHMENT (object))); + return; + + case PROP_REFERENCE: + g_value_set_boxed ( + value, e_attachment_get_reference ( + E_ATTACHMENT (object))); + return; + + case PROP_SAVING: + g_value_set_boolean ( + value, e_attachment_get_saving ( + E_ATTACHMENT (object))); + return; + case PROP_SIGNED: g_value_set_int ( value, e_attachment_get_signed ( @@ -453,12 +374,6 @@ attachment_dispose (GObject *object) priv = E_ATTACHMENT_GET_PRIVATE (object); - if (priv->cancellable != NULL) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - if (priv->file != NULL) { g_object_unref (priv->file); priv->file = NULL; @@ -469,11 +384,21 @@ attachment_dispose (GObject *object) priv->file_info = NULL; } + if (priv->cancellable != NULL) { + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + if (priv->mime_part != NULL) { camel_object_unref (priv->mime_part); priv->mime_part = NULL; } + if (priv->emblem_timeout_id > 0) { + g_source_remove (priv->emblem_timeout_id); + priv->emblem_timeout_id = 0; + } + /* This accepts NULL arguments. */ gtk_tree_row_reference_free (priv->reference); priv->reference = NULL; @@ -575,6 +500,38 @@ attachment_class_init (EAttachmentClass *class) E_TYPE_CAMEL_OBJECT, G_PARAM_READWRITE)); + g_object_class_install_property ( + object_class, + PROP_PERCENT, + g_param_spec_int ( + "percent", + "Percent", + NULL, + 0, + 100, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_REFERENCE, + g_param_spec_boxed ( + "reference", + "Reference", + NULL, + GTK_TYPE_TREE_ROW_REFERENCE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SAVING, + g_param_spec_boolean ( + "saving", + "Saving", + NULL, + FALSE, + G_PARAM_READABLE)); + /* FIXME Define a GEnumClass for this. */ g_object_class_install_property ( object_class, @@ -597,6 +554,10 @@ attachment_init (EAttachment *attachment) attachment->priv->cancellable = g_cancellable_new (); attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE; + + g_signal_connect_swapped ( + attachment->priv->cancellable, "cancelled", + G_CALLBACK (attachment_cancelled_cb), attachment); } GType @@ -779,6 +740,14 @@ exit: camel_multipart_add_part (multipart, mime_part); } +void +e_attachment_cancel (EAttachment *attachment) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_cancellable_cancel (attachment->priv->cancellable); +} + const gchar * e_attachment_get_disposition (EAttachment *attachment) { @@ -811,34 +780,19 @@ void e_attachment_set_file (EAttachment *attachment, GFile *file) { - GCancellable *cancellable; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_object_freeze_notify (G_OBJECT (attachment)); - if (file != NULL) { g_return_if_fail (G_IS_FILE (file)); g_object_ref (file); } - attachment_reset (attachment); - attachment->priv->file = file; - - cancellable = attachment->priv->cancellable; + if (attachment->priv->file != NULL) + g_object_unref (attachment->priv->file); - if (file != NULL) - g_file_query_info_async ( - file, ATTACHMENT_QUERY, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) - attachment_file_info_ready_cb, - attachment); + attachment->priv->file = file; g_object_notify (G_OBJECT (attachment), "file"); - - g_object_thaw_notify (G_OBJECT (attachment)); } GFileInfo * @@ -849,6 +803,14 @@ e_attachment_get_file_info (EAttachment *attachment) return attachment->priv->file_info; } +gboolean +e_attachment_get_loading (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->loading; +} + CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment) { @@ -863,35 +825,67 @@ e_attachment_set_mime_part (EAttachment *attachment, { g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_object_freeze_notify (G_OBJECT (attachment)); - if (mime_part != NULL) { g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); camel_object_ref (mime_part); } - attachment_reset (attachment); - attachment->priv->mime_part = mime_part; - - if (mime_part != NULL) { - GFileInfo *file_info; + if (attachment->priv->mime_part != NULL) + camel_object_unref (attachment->priv->mime_part); - file_info = g_file_info_new (); - attachment_populate_file_info (attachment, file_info); - attachment_set_file_info (attachment, file_info); - g_object_unref (file_info); - } + attachment->priv->mime_part = mime_part; g_object_notify (G_OBJECT (attachment), "mime-part"); - - g_object_thaw_notify (G_OBJECT (attachment)); } -camel_cipher_validity_encrypt_t -e_attachment_get_encrypted (EAttachment *attachment) +gint +e_attachment_get_percent (EAttachment *attachment) { - g_return_val_if_fail ( - E_IS_ATTACHMENT (attachment), + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), 0); + + return attachment->priv->percent; +} + +GtkTreeRowReference * +e_attachment_get_reference (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + /* Don't return an invalid tree row reference. */ + if (!gtk_tree_row_reference_valid (attachment->priv->reference)) + e_attachment_set_reference (attachment, NULL); + + return attachment->priv->reference; +} + +void +e_attachment_set_reference (EAttachment *attachment, + GtkTreeRowReference *reference) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + if (reference != NULL) + reference = gtk_tree_row_reference_copy (reference); + + gtk_tree_row_reference_free (attachment->priv->reference); + attachment->priv->reference = reference; + + g_object_notify (G_OBJECT (attachment), "reference"); +} + +gboolean +e_attachment_get_saving (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->saving; +} + +camel_cipher_validity_encrypt_t +e_attachment_get_encrypted (EAttachment *attachment) +{ + g_return_val_if_fail ( + E_IS_ATTACHMENT (attachment), CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE); return attachment->priv->encrypted; @@ -931,40 +925,6 @@ e_attachment_set_signed (EAttachment *attachment, attachment_notify_model (attachment); } -const gchar * -e_attachment_get_content_type (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return NULL; - - return g_file_info_get_attribute_string (file_info, attribute); -} - -const gchar * -e_attachment_get_display_name (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return NULL; - - return g_file_info_get_attribute_string (file_info, attribute); -} - const gchar * e_attachment_get_description (EAttachment *attachment) { @@ -982,32 +942,6 @@ e_attachment_get_description (EAttachment *attachment) return g_file_info_get_attribute_string (file_info, attribute); } -GIcon * -e_attachment_get_icon (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - attribute = G_FILE_ATTRIBUTE_STANDARD_ICON; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return NULL; - - return (GIcon *) - g_file_info_get_attribute_object (file_info, attribute); -} - -gboolean -e_attachment_get_loading (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->loading; -} - const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment) { @@ -1025,40 +959,19 @@ e_attachment_get_thumbnail_path (EAttachment *attachment) return g_file_info_get_attribute_byte_string (file_info, attribute); } -gboolean -e_attachment_get_saving (EAttachment *attachment) -{ - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - return attachment->priv->saving; -} - -guint64 -e_attachment_get_size (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *attribute; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), 0); - - attribute = G_FILE_ATTRIBUTE_STANDARD_SIZE; - file_info = e_attachment_get_file_info (attachment); - - if (file_info == NULL) - return 0; - - return g_file_info_get_attribute_uint64 (file_info, attribute); -} - gboolean e_attachment_is_image (EAttachment *attachment) { + GFileInfo *file_info; const gchar *content_type; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - content_type = e_attachment_get_content_type (attachment); + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + return FALSE; + content_type = g_file_info_get_content_type (file_info); if (content_type == NULL) return FALSE; @@ -1068,12 +981,16 @@ e_attachment_is_image (EAttachment *attachment) gboolean e_attachment_is_rfc822 (EAttachment *attachment) { + GFileInfo *file_info; const gchar *content_type; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - content_type = e_attachment_get_content_type (attachment); + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + return FALSE; + content_type = g_file_info_get_content_type (file_info); if (content_type == NULL) return FALSE; @@ -1084,14 +1001,18 @@ GList * e_attachment_list_apps (EAttachment *attachment) { GList *app_info_list; + GFileInfo *file_info; const gchar *content_type; const gchar *display_name; gchar *allocated; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - content_type = e_attachment_get_content_type (attachment); - display_name = e_attachment_get_display_name (attachment); + file_info = e_attachment_get_file_info (attachment); + g_return_val_if_fail (file_info != NULL, NULL); + + content_type = g_file_info_get_content_type (file_info); + display_name = g_file_info_get_display_name (file_info); g_return_val_if_fail (content_type != NULL, NULL); app_info_list = g_app_info_get_all_for_type (content_type); @@ -1113,11 +1034,20 @@ exit: GList * e_attachment_list_emblems (EAttachment *attachment) { + GCancellable *cancellable; GList *list = NULL; GIcon *icon; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + cancellable = attachment->priv->cancellable; + + if (g_cancellable_is_cancelled (cancellable)) { + icon = g_themed_icon_new (EMBLEM_CANCELLED); + list = g_list_append (list, g_emblem_new (icon)); + g_object_unref (icon); + } + if (e_attachment_get_loading (attachment)) { icon = g_themed_icon_new (EMBLEM_LOADING); list = g_list_append (list, g_emblem_new (icon)); @@ -1180,552 +1110,1179 @@ e_attachment_list_emblems (EAttachment *attachment) return list; } -/************************ e_attachment_launch_async() ************************/ +/************************* e_attachment_load_async() *************************/ + +typedef struct _AttachmentLoadContext AttachmentLoadContext; + +struct _AttachmentLoadContext { + EAttachment *attachment; + GSimpleAsyncResult *simple; + GInputStream *input_stream; + GOutputStream *output_stream; + GFileInfo *file_info; + goffset total_num_bytes; + gssize bytes_read; + gchar buffer[4096]; +}; +/* Forward Declaration */ static void -attachment_launch_file (EActivity *activity, - GAppInfo *app_info, - GFile *file) +attachment_load_stream_read_cb (GInputStream *input_stream, + GAsyncResult *result, + AttachmentLoadContext *load_context); + +static AttachmentLoadContext * +attachment_load_context_new (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data) { - GdkAppLaunchContext *launch_context; - GList *file_list; - GError *error = NULL; - - file_list = g_list_prepend (NULL, file); - launch_context = gdk_app_launch_context_new (); + AttachmentLoadContext *load_context; + GSimpleAsyncResult *simple; - g_app_info_launch ( - app_info, file_list, - G_APP_LAUNCH_CONTEXT (launch_context), &error); + simple = g_simple_async_result_new ( + G_OBJECT (attachment), callback, + user_data, e_attachment_load_async); - g_list_free (file_list); - g_object_unref (launch_context); + load_context = g_slice_new0 (AttachmentLoadContext); + load_context->attachment = g_object_ref (attachment); + load_context->simple = simple; - if (error != NULL) { - e_activity_set_error (activity, error); - g_error_free (error); - } + attachment_set_loading (load_context->attachment, TRUE); - e_activity_complete (activity); - g_object_unref (activity); + return load_context; } -void -e_attachment_launch_async (EAttachment *attachment, - EFileActivity *file_activity, - GAppInfo *app_info) +static void +attachment_load_context_free (AttachmentLoadContext *load_context) { - CamelMimePart *mime_part; - GFile *file; + /* Do not free the GSimpleAsyncResult. */ + g_object_unref (load_context->attachment); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); - g_return_if_fail (G_IS_APP_INFO (app_info)); + if (load_context->input_stream != NULL) + g_object_unref (load_context->input_stream); - file = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (file != NULL || mime_part != NULL); + if (load_context->output_stream != NULL) + g_object_unref (load_context->output_stream); - /* If the attachment already references a GFile, we can launch - * the application directly. Otherwise we have to save the MIME - * part to a temporary file and launch the application from that. */ - if (G_IS_FILE (file)) { - EActivity *activity = g_object_ref (file_activity); - attachment_launch_file (activity, app_info, file); + if (load_context->file_info != NULL) + g_object_unref (load_context->file_info); - } else if (CAMEL_IS_MIME_PART (mime_part)) { - /* XXX Not done yet. */ - } + g_slice_free (AttachmentLoadContext, load_context); } -/************************* e_attachment_save_async() *************************/ +static void +attachment_load_finish (AttachmentLoadContext *load_context) +{ + GFileInfo *file_info; + EAttachment *attachment; + GMemoryOutputStream *output_stream; + GSimpleAsyncResult *simple; + CamelDataWrapper *wrapper; + CamelMimePart *mime_part; + CamelStream *stream; + const gchar *attribute; + const gchar *content_type; + const gchar *display_name; + const gchar *description; + const gchar *disposition; + gchar *mime_type; + gpointer data; + gsize size; -typedef struct _AttachmentSaveContext AttachmentSaveContext; + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; -struct _AttachmentSaveContext { - EAttachment *attachment; - EFileActivity *file_activity; - GOutputStream *output_stream; -}; + file_info = load_context->file_info; + attachment = load_context->attachment; + output_stream = G_MEMORY_OUTPUT_STREAM (load_context->output_stream); -static AttachmentSaveContext * -attachment_save_context_new (EAttachment *attachment, - EFileActivity *file_activity) -{ - AttachmentSaveContext *save_context; + if (e_attachment_is_rfc822 (attachment)) + wrapper = (CamelDataWrapper *) camel_mime_message_new (); + else + wrapper = camel_data_wrapper_new (); - save_context = g_slice_new (AttachmentSaveContext); - save_context->attachment = g_object_ref (attachment); - save_context->file_activity = g_object_ref (file_activity); - save_context->output_stream = NULL; + content_type = g_file_info_get_content_type (file_info); + mime_type = g_content_type_get_mime_type (content_type); - attachment_set_saving (save_context->attachment, TRUE); + data = g_memory_output_stream_get_data (output_stream); + size = g_memory_output_stream_get_data_size (output_stream); - return save_context; -} + stream = camel_stream_mem_new_with_buffer (data, size); + camel_data_wrapper_construct_from_stream (wrapper, stream); + camel_data_wrapper_set_mime_type (wrapper, mime_type); + camel_stream_close (stream); + camel_object_unref (stream); -static void -attachment_save_context_free (AttachmentSaveContext *save_context) -{ - attachment_set_saving (save_context->attachment, FALSE); + mime_part = camel_mime_part_new (); + camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper); - g_object_unref (save_context->attachment); - g_object_unref (save_context->file_activity); + camel_object_unref (wrapper); + g_free (mime_type); - if (save_context->output_stream != NULL) - g_object_unref (save_context->output_stream); + display_name = g_file_info_get_display_name (file_info); + if (display_name != NULL) + camel_mime_part_set_filename (mime_part, display_name); - g_slice_free (AttachmentSaveContext, save_context); + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + description = g_file_info_get_attribute_string (file_info, attribute); + if (description != NULL) + camel_mime_part_set_description (mime_part, description); + + disposition = e_attachment_get_disposition (attachment); + if (disposition != NULL) + camel_mime_part_set_disposition (mime_part, disposition); + + g_simple_async_result_set_op_res_gpointer ( + simple, mime_part, (GDestroyNotify) camel_object_unref); + + g_simple_async_result_complete (simple); + + attachment_load_context_free (load_context); } static void -attachment_save_file_cb (GFile *source, - GAsyncResult *result, - AttachmentSaveContext *save_context) +attachment_load_write_cb (GOutputStream *output_stream, + GAsyncResult *result, + AttachmentLoadContext *load_context) { - EActivity *activity; + EAttachment *attachment; + GCancellable *cancellable; + GInputStream *input_stream; + gssize bytes_written; GError *error = NULL; - activity = E_ACTIVITY (save_context->file_activity); + bytes_written = g_output_stream_write_finish ( + output_stream, result, &error); + + if (error != NULL) { + GSimpleAsyncResult *simple; + + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; - if (!g_file_copy_finish (source, result, &error)) { - e_activity_set_error (activity, error); + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); g_error_free (error); + + attachment_load_context_free (load_context); + + return; } - e_activity_complete (activity); - attachment_save_context_free (save_context); + attachment = load_context->attachment; + cancellable = attachment->priv->cancellable; + input_stream = load_context->input_stream; + + attachment_progress_cb ( + g_seekable_tell (G_SEEKABLE (output_stream)), + load_context->total_num_bytes, attachment); + + if (bytes_written < load_context->bytes_read) { + g_memmove ( + load_context->buffer, + load_context->buffer + bytes_written, + load_context->bytes_read - bytes_written); + load_context->bytes_read -= bytes_written; + + g_output_stream_write_async ( + output_stream, + load_context->buffer, + load_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_load_write_cb, + load_context); + } else + g_input_stream_read_async ( + input_stream, + load_context->buffer, + sizeof (load_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_load_stream_read_cb, + load_context); } -static gpointer -attachment_save_part_thread (AttachmentSaveContext *save_context) +static void +attachment_load_stream_read_cb (GInputStream *input_stream, + GAsyncResult *result, + AttachmentLoadContext *load_context) { - GObject *object; EAttachment *attachment; GCancellable *cancellable; GOutputStream *output_stream; - EFileActivity *file_activity; - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - CamelStream *stream; + gssize bytes_read; GError *error = NULL; - attachment = save_context->attachment; - file_activity = save_context->file_activity; - output_stream = save_context->output_stream; + bytes_read = g_input_stream_read_finish ( + input_stream, result, &error); - /* Last chance to cancel. */ - cancellable = e_file_activity_get_cancellable (file_activity); - if (g_cancellable_set_error_if_cancelled (cancellable, &error)) - goto exit; + if (error != NULL) { + GSimpleAsyncResult *simple; - object = g_object_ref (output_stream); - stream = camel_stream_vfs_new_with_stream (object); - mime_part = e_attachment_get_mime_part (attachment); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; - if (camel_data_wrapper_decode_to_stream (wrapper, stream) < 0) - g_set_error ( - &error, G_IO_ERROR, - g_io_error_from_errno (errno), - g_strerror (errno)); + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); - else if (camel_stream_flush (stream) < 0) - g_set_error ( - &error, G_IO_ERROR, - g_io_error_from_errno (errno), - g_strerror (errno)); + attachment_load_context_free (load_context); - camel_object_unref (stream); + return; + } -exit: - if (error != NULL) { - e_activity_set_error (E_ACTIVITY (file_activity), error); - g_error_free (error); + if (bytes_read == 0) { + attachment_load_finish (load_context); + return; } - e_activity_complete_in_idle (E_ACTIVITY (file_activity)); - attachment_save_context_free (save_context); + attachment = load_context->attachment; + cancellable = attachment->priv->cancellable; + output_stream = load_context->output_stream; + load_context->bytes_read = bytes_read; - return NULL; + g_output_stream_write_async ( + output_stream, + load_context->buffer, + load_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_load_write_cb, + load_context); } static void -attachment_save_part_cb (GFile *destination, - GAsyncResult *result, - AttachmentSaveContext *save_context) +attachment_load_file_read_cb (GFile *file, + GAsyncResult *result, + AttachmentLoadContext *load_context) { - GFileOutputStream *output_stream; - EActivity *activity; + EAttachment *attachment; + GCancellable *cancellable; + GFileInputStream *input_stream; + GOutputStream *output_stream; GError *error = NULL; - activity = E_ACTIVITY (save_context->file_activity); - output_stream = g_file_replace_finish (destination, result, &error); - save_context->output_stream = G_OUTPUT_STREAM (output_stream); - - if (output_stream != NULL) - g_thread_create ( - (GThreadFunc) attachment_save_part_thread, - save_context, FALSE, &error); + input_stream = g_file_read_finish (file, result, &error); + load_context->input_stream = G_INPUT_STREAM (input_stream); if (error != NULL) { - e_activity_set_error (activity, error); - e_activity_complete (activity); + GSimpleAsyncResult *simple; + + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); g_error_free (error); - attachment_save_context_free (save_context); + attachment_load_context_free (load_context); + + return; } -} -void -e_attachment_save_async (EAttachment *attachment, - EFileActivity *file_activity, - GFile *destination) -{ - AttachmentSaveContext *save_context; - GFileProgressCallback progress_callback; + /* Load the contents into a GMemoryOutputStream. */ + output_stream = g_memory_output_stream_new ( + NULL, 0, g_realloc, g_free); + + attachment = load_context->attachment; + cancellable = attachment->priv->cancellable; + load_context->output_stream = output_stream; + + g_input_stream_read_async ( + load_context->input_stream, + load_context->buffer, + sizeof (load_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_load_stream_read_cb, + load_context); +} + +static void +attachment_load_query_info_cb (GFile *file, + GAsyncResult *result, + AttachmentLoadContext *load_context) +{ + EAttachment *attachment; GCancellable *cancellable; - CamelMimePart *mime_part; - GFile *source; + GFileInfo *file_info; + GError *error = NULL; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); - g_return_if_fail (G_IS_FILE (destination)); + attachment = load_context->attachment; + cancellable = attachment->priv->cancellable; - /* The attachment content is either a GFile (on disk) or a - * CamelMimePart (in memory). Each is saved differently. */ + file_info = g_file_query_info_finish (file, result, &error); + attachment_set_file_info (attachment, file_info); + load_context->file_info = file_info; - source = e_attachment_get_file (attachment); + if (error != NULL) { + GSimpleAsyncResult *simple; + + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_load_context_free (load_context); + + return; + } + + load_context->total_num_bytes = g_file_info_get_size (file_info); + + g_file_read_async ( + file, G_PRIORITY_DEFAULT, + cancellable, (GAsyncReadyCallback) + attachment_load_file_read_cb, load_context); +} + +static void +attachment_load_from_mime_part (AttachmentLoadContext *load_context) +{ + GFileInfo *file_info; + EAttachment *attachment; + GSimpleAsyncResult *simple; + CamelContentType *content_type; + CamelMimePart *mime_part; + const gchar *attribute; + const gchar *string; + gchar *allocated; + goffset size; + + attachment = load_context->attachment; mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (source != NULL || mime_part != NULL); - save_context = attachment_save_context_new (attachment, file_activity); - cancellable = e_file_activity_get_cancellable (file_activity); - progress_callback = e_file_activity_progress; + file_info = g_file_info_new (); + load_context->file_info = file_info; - /* GFile is the easier, but probably less common case. The - * attachment already references an on-disk file, so we can - * just use GIO to copy it asynchronously. - * - * We use G_FILE_COPY_OVERWRITE because the user should have - * already confirmed the overwrite through the save dialog. */ - if (G_IS_FILE (source)) - g_file_copy_async ( - source, destination, - G_FILE_COPY_OVERWRITE, - G_PRIORITY_DEFAULT, cancellable, - progress_callback, file_activity, - (GAsyncReadyCallback) attachment_save_file_cb, - save_context); + content_type = camel_mime_part_get_content_type (mime_part); + allocated = camel_content_type_simple (content_type); + if (allocated != NULL) { + GIcon *icon; + gchar *cp; - /* CamelMimePart can only be decoded to a file synchronously, so - * we do this in two stages. Stage one asynchronously opens the - * destination file for writing. Stage two spawns a thread that - * decodes the MIME part to the destination file. This stage is - * not cancellable, unfortunately. */ - else if (CAMEL_IS_MIME_PART (mime_part)) { - g_object_set_data_full ( - G_OBJECT (file_activity), - "attachment", g_object_ref (attachment), - (GDestroyNotify) g_object_unref); - g_file_replace_async ( - destination, NULL, FALSE, - G_FILE_CREATE_REPLACE_DESTINATION, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_part_cb, - save_context); + /* GIO expects lowercase MIME types. */ + for (cp = allocated; *cp != '\0'; cp++) + *cp = g_ascii_tolower (*cp); + + /* Swap the MIME type for a content type. */ + cp = g_content_type_from_mime_type (allocated); + g_free (allocated); + allocated = cp; + + /* Use the MIME part's filename if we have to. */ + if (g_content_type_is_unknown (allocated)) { + string = camel_mime_part_get_filename (mime_part); + if (string != NULL) { + g_free (allocated); + allocated = g_content_type_guess ( + string, NULL, 0, NULL); + } + } + + g_file_info_set_content_type (file_info, allocated); + + icon = g_content_type_get_icon (allocated); + if (icon != NULL) { + g_file_info_set_icon (file_info, icon); + g_object_unref (icon); + } } + g_free (allocated); + + string = camel_mime_part_get_filename (mime_part); + if (string != NULL) + g_file_info_set_display_name (file_info, string); + + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; + string = camel_mime_part_get_description (mime_part); + if (string != NULL) + g_file_info_set_attribute_string ( + file_info, attribute, string); + + size = (goffset) camel_mime_part_get_content_size (mime_part); + g_file_info_set_size (file_info, size); + + string = camel_mime_part_get_disposition (mime_part); + e_attachment_set_disposition (attachment, string); + + attachment_set_file_info (attachment, file_info); + + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; + + camel_object_ref (mime_part); + g_simple_async_result_set_op_res_gpointer ( + simple, mime_part, + (GDestroyNotify) camel_object_unref); + g_simple_async_result_complete_in_idle (simple); + + attachment_load_context_free (load_context); } -#if 0 -typedef struct { - gint io_priority; +void +e_attachment_load_async (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AttachmentLoadContext *load_context; GCancellable *cancellable; + CamelMimePart *mime_part; + GFile *file; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (callback != NULL); + + g_return_if_fail (!e_attachment_get_loading (attachment)); + g_return_if_fail (!e_attachment_get_saving (attachment)); + + file = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (file != NULL || mime_part != NULL); + + load_context = attachment_load_context_new ( + attachment, callback, user_data); + + cancellable = attachment->priv->cancellable; + g_cancellable_reset (cancellable); + + /* Handle the trivial case first. */ + if (mime_part != NULL) + attachment_load_from_mime_part (load_context); + + else if (file != NULL) + g_file_query_info_async ( + file, ATTACHMENT_QUERY, + G_FILE_QUERY_INFO_NONE,G_PRIORITY_DEFAULT, + cancellable, (GAsyncReadyCallback) + attachment_load_query_info_cb, load_context); +} + +gboolean +e_attachment_load_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error) +{ GSimpleAsyncResult *simple; + CamelMimePart *mime_part; + + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, + G_OBJECT (attachment), e_attachment_load_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + mime_part = g_simple_async_result_get_op_res_gpointer (simple); + if (mime_part != NULL) + e_attachment_set_mime_part (attachment, mime_part); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + attachment_set_loading (attachment, FALSE); + + return (mime_part != NULL); +} + +void +e_attachment_load_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent) +{ + GtkWidget *dialog; GFileInfo *file_info; -} BuildMimePartData; + const gchar *display_name; + const gchar *primary_text; + GError *error = NULL; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_return_if_fail (GTK_IS_WINDOW (parent)); + + if (e_attachment_load_finish (attachment, result, &error)) + return; + + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + else + display_name = NULL; + + if (display_name != NULL) + primary_text = g_strdup_printf ( + _("Could not load '%s'"), display_name); + else + primary_text = g_strdup_printf ( + _("Could not load the attachment")); + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", primary_text); -static BuildMimePartData * -attachment_build_mime_part_data_new (EAttachment *attachment, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - gpointer source_tag) + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); +} + +/************************* e_attachment_open_async() *************************/ + +typedef struct _AttachmentOpenContext AttachmentOpenContext; + +struct _AttachmentOpenContext { + EAttachment *attachment; + GSimpleAsyncResult *simple; + GAppInfo *app_info; + GFile *file; +}; + +static AttachmentOpenContext * +attachment_open_context_new (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data) { - BuildMimePartData *data; + AttachmentOpenContext *open_context; GSimpleAsyncResult *simple; simple = g_simple_async_result_new ( - G_OBJECT (attachment), callback, user_data, source_tag); + G_OBJECT (attachment), callback, + user_data, e_attachment_open_async); - if (G_IS_CANCELLABLE (cancellable)) - g_object_ref (cancellable); + open_context = g_slice_new0 (AttachmentOpenContext); + open_context->attachment = g_object_ref (attachment); + open_context->simple = simple; - data = g_slice_new0 (BuildMimePartData); - data->io_priority = io_priority; - data->cancellable = cancellable; - data->simple = simple; - return data; + return open_context; } static void -attachment_build_mime_part_data_free (BuildMimePartData *data) +attachment_open_context_free (AttachmentOpenContext *open_context) { - if (data->attachment != NULL) - g_object_unref (data->attachment); + /* Do not free the GSimpleAsyncResult. */ + g_object_unref (open_context->attachment); - if (data->cancellable != NULL) - g_object_unref (data->cancellable); + if (open_context->app_info != NULL) + g_object_unref (open_context->app_info); - if (data->simple != NULL) - g_object_unref (data->simple); + if (open_context->file != NULL) + g_object_unref (open_context->file); - if (data->file_info != NULL) - g_object_unref (data->file_info); + g_slice_free (AttachmentOpenContext, open_context); +} - g_slice_free (BuildMimePartData, data); +static void +attachment_open_file (AttachmentOpenContext *open_context) +{ + GdkAppLaunchContext *context; + GSimpleAsyncResult *simple; + GList *file_list; + gboolean success; + GError *error = NULL; + + /* Steal the reference. */ + simple = open_context->simple; + open_context->simple = NULL; + + if (open_context->app_info == NULL) + open_context->app_info = g_file_query_default_handler ( + open_context->file, NULL, &error); + + if (open_context->app_info == NULL) + goto exit; + + context = gdk_app_launch_context_new (); + file_list = g_list_prepend (NULL, open_context->file); + + success = g_app_info_launch ( + open_context->app_info, file_list, + G_APP_LAUNCH_CONTEXT (context), &error); + + g_simple_async_result_set_op_res_gboolean (simple, success); + + g_list_free (file_list); + g_object_unref (context); + +exit: + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + g_simple_async_result_complete (simple); + attachment_open_context_free (open_context); } static void -attachment_build_mime_part_splice_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +attachment_open_save_finished_cb (EAttachment *attachment, + GAsyncResult *result, + AttachmentOpenContext *open_context) { - GSimpleAsyncResult *final_result; - GCancellable *cancellable; - EAttachment *attachment; - CamelDataWrapper *wrapper; + GError *error = NULL; + + if (e_attachment_save_finish (attachment, result, &error)) + attachment_open_file (open_context); + else { + GSimpleAsyncResult *simple; + + /* Steal the reference. */ + simple = open_context->simple; + open_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_open_context_free (open_context); + } +} + +static void +attachment_open_save_temporary (AttachmentOpenContext *open_context) +{ + gchar *path; + gint fd; + GError *error = NULL; + + fd = e_file_open_tmp (&path, &error); + if (error != NULL) { + GSimpleAsyncResult *simple; + + /* Steal the reference. */ + simple = open_context->simple; + open_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_open_context_free (open_context); + return; + } + + close (fd); + + open_context->file = g_file_new_for_path (path); + + e_attachment_save_async ( + open_context->attachment, open_context->file, + (GAsyncReadyCallback) attachment_open_save_finished_cb, + open_context); +} + +void +e_attachment_open_async (EAttachment *attachment, + GAppInfo *app_info, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AttachmentOpenContext *open_context; CamelMimePart *mime_part; - CamelStream *stream; - const gchar *content_type; - gchar *mime_type; - gssize length; - gpointer data; + GFile *file; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (callback != NULL); + + g_return_if_fail (!e_attachment_get_loading (attachment)); + g_return_if_fail (!e_attachment_get_saving (attachment)); + + file = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (file != NULL || mime_part != NULL); + + open_context = attachment_open_context_new ( + attachment, callback, user_data); + + if (G_IS_APP_INFO (app_info)) + open_context->app_info = g_object_ref (app_info); + + /* If the attachment already references a GFile, we can launch + * the application directly. Otherwise we have to save the MIME + * part to a temporary file and launch the application from that. */ + if (file != NULL) { + open_context->file = g_object_ref (file); + attachment_open_file (open_context); + + } else if (mime_part != NULL) + attachment_open_save_temporary (open_context); +} + +gboolean +e_attachment_open_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gboolean success; + + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, + G_OBJECT (attachment), e_attachment_open_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + success = g_simple_async_result_get_op_res_gboolean (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + return success; +} + +void +e_attachment_open_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent) +{ + GtkWidget *dialog; + GFileInfo *file_info; + const gchar *display_name; + const gchar *primary_text; GError *error = NULL; - final_result = G_SIMPLE_ASYNC_RESULT (user_data); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_return_if_fail (GTK_IS_WINDOW (parent)); - cancellable = g_cancellable_get_current (); - g_cancellable_pop_current (cancellable); - g_object_unref (cancellable); + if (e_attachment_open_finish (attachment, result, &error)) + return; - length = g_output_stream_splice_finish ( - G_OUTPUT_STREAM (source), result, &error); - if (error != NULL) - goto fail; + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - data = g_memory_output_stream_get_data ( - G_MEMORY_OUTPUT_STREAM (source)); + file_info = e_attachment_get_file_info (attachment); - attachment = E_ATTACHMENT ( - g_async_result_get_source_object ( - G_ASYNC_RESULT (final_result))); + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + else + display_name = NULL; - if (e_attachment_is_rfc822 (attachment)) - wrapper = (CamelDataWrapper *) camel_mime_message_new (); + if (display_name != NULL) + primary_text = g_strdup_printf ( + _("Could not open '%s'"), display_name); else - wrapper = camel_data_wrapper_new (); + primary_text = g_strdup_printf ( + _("Could not open the attachment")); - content_type = e_attachment_get_content_type (attachment); - mime_type = g_content_type_get_mime_type (content_type); + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", primary_text); - stream = camel_stream_mem_new_with_buffer (data, length); - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, mime_type); - camel_object_unref (stream); + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - mime_part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper); + gtk_dialog_run (GTK_DIALOG (dialog)); - g_simple_async_result_set_op_res_gpointer ( - final_result, mime_part, camel_object_unref); + gtk_widget_destroy (dialog); + g_error_free (error); +} - g_simple_async_result_complete (final_result); +/************************* e_attachment_save_async() *************************/ - camel_object_unref (wrapper); - g_free (mime_type); +typedef struct _AttachmentSaveContext AttachmentSaveContext; - return; +struct _AttachmentSaveContext { + EAttachment *attachment; + GSimpleAsyncResult *simple; + GInputStream *input_stream; + GOutputStream *output_stream; + goffset total_num_bytes; + gssize bytes_read; + gchar buffer[4096]; +}; -fail: - g_simple_async_result_set_from_error (final_result, error); - g_simple_async_result_complete (final_result); - g_error_free (error); +/* Forward Declaration */ +static void +attachment_save_read_cb (GInputStream *input_stream, + GAsyncResult *result, + AttachmentSaveContext *save_context); + +static AttachmentSaveContext * +attachment_save_context_new (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AttachmentSaveContext *save_context; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (attachment), callback, + user_data, e_attachment_save_async); + + save_context = g_slice_new0 (AttachmentSaveContext); + save_context->attachment = g_object_ref (attachment); + save_context->simple = simple; + + attachment_set_saving (save_context->attachment, TRUE); + + return save_context; } static void -attachment_build_mime_part_read_cb (GObject *source, - GAsyncResult *result, - BuildMimePartData *data) +attachment_save_context_free (AttachmentSaveContext *save_context) { - GFileInputStream *input_stream; - GOutputStream *output_stream; + /* Do not free the GSimpleAsyncResult. */ + g_object_unref (save_context->attachment); + + if (save_context->input_stream != NULL) + g_object_unref (save_context->input_stream); + + if (save_context->output_stream != NULL) + g_object_unref (save_context->output_stream); + + g_slice_free (AttachmentSaveContext, save_context); +} + +static void +attachment_save_file_cb (GFile *source, + GAsyncResult *result, + AttachmentSaveContext *save_context) +{ + GSimpleAsyncResult *simple; + gboolean success; + GError *error = NULL; + + /* Steal the reference. */ + simple = save_context->simple; + save_context->simple = NULL; + + success = g_file_copy_finish (source, result, &error); + g_simple_async_result_set_op_res_gboolean (simple, success); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + g_simple_async_result_complete (simple); + attachment_save_context_free (save_context); +} + +static void +attachment_save_write_cb (GOutputStream *output_stream, + GAsyncResult *result, + AttachmentSaveContext *save_context) +{ + EAttachment *attachment; GCancellable *cancellable; + GInputStream *input_stream; + gssize bytes_written; GError *error = NULL; - input_stream = g_file_read_finish (G_FILE (source), result, &error); - if (error != NULL) - goto fail; + bytes_written = g_output_stream_write_finish ( + output_stream, result, &error); - output_stream = g_memory_output_stream_new ( - NULL, 0, g_realloc, g_free); + if (error != NULL) { + GSimpleAsyncResult *simple; - g_output_stream_splice_async ( - output_stream, G_INPUT_STREAM (input_stream), - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - G_PRIORITY_DEFAULT, cancellable, - attachment_build_mime_part_splice_cb, result); + /* Steal the reference. */ + simple = save_context->simple; + save_context->simple = NULL; - g_cancellable_push_current (cancellable); + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); - g_object_unref (input_stream); - g_object_unref (output_stream); + attachment_save_context_free (save_context); - return; + return; + } -fail: - g_simple_async_result_set_from_error (final_result, error); - g_simple_async_result_complete (final_result); - g_error_free (error); + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + input_stream = save_context->input_stream; + + if (bytes_written < save_context->bytes_read) { + g_memmove ( + save_context->buffer, + save_context->buffer + bytes_written, + save_context->bytes_read - bytes_written); + save_context->bytes_read -= bytes_written; + + g_output_stream_write_async ( + output_stream, + save_context->buffer, + save_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_write_cb, + save_context); + } else + g_input_stream_read_async ( + input_stream, + save_context->buffer, + sizeof (save_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_read_cb, + save_context); } -static gboolean -attachment_build_mime_part_idle_cb (BuildMimePartData *data) +static void +attachment_save_read_cb (GInputStream *input_stream, + GAsyncResult *result, + AttachmentSaveContext *save_context) { - GObject *source; - GAsyncResult *result; - GFileInfo *file_info; - GFile *file; + EAttachment *attachment; + GCancellable *cancellable; + GOutputStream *output_stream; + gssize bytes_read; GError *error = NULL; - if (g_cancellable_set_error_if_cancelled (data->cancellable, &error)) - goto cancelled; + bytes_read = g_input_stream_read_finish ( + input_stream, result, &error); - result = G_ASYNC_RESULT (data->simple); - source = g_async_result_get_source_object (result); - file_info = e_attachment_get_file_info (E_ATTACHMENT (source)); + if (error != NULL) { + GSimpleAsyncResult *simple; - /* Poll again on the next idle. */ - if (!G_IS_FILE_INFO (file_info)) - return TRUE; + /* Steal the reference. */ + simple = save_context->simple; + save_context->simple = NULL; - /* We have a GFileInfo, so on to step 2. */ + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); - data->file_info = g_file_info_dup (file_info); - file = e_attachment_get_file (E_ATTACHMENT (source)); + attachment_save_context_free (save_context); - /* Because Camel's stream API is synchronous and not - * cancellable, we have to asynchronously read the file - * into memory and then encode it to a MIME part. That - * means double buffering the file contents in memory, - * unfortunately. */ - g_file_read_async ( - file, data->io_priority, data->cancellable, - attachment_build_mime_part_read_cb, data); + return; + } - return FALSE; + if (bytes_read == 0) { + GSimpleAsyncResult *simple; -cancelled: - g_simple_async_result_set_op_res_gboolean (data->simple, FALSE); - g_simple_async_result_set_from_error (data->simple, error); - g_simple_async_result_complete (data->simple); + /* Steal the reference. */ + simple = save_context->simple; + save_context->simple = NULL; - build_mime_part_data_free (data); - g_error_free (error); + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); - return FALSE; + attachment_save_context_free (save_context); + + return; + } + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + output_stream = save_context->output_stream; + save_context->bytes_read = bytes_read; + + attachment_progress_cb ( + g_seekable_tell (G_SEEKABLE (input_stream)), + save_context->total_num_bytes, attachment); + + g_output_stream_write_async ( + output_stream, + save_context->buffer, + save_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_write_cb, + save_context); } -void -e_attachment_build_mime_part_async (EAttachment *attachment, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +static void +attachment_save_replace_cb (GFile *destination, + GAsyncResult *result, + AttachmentSaveContext *save_context) { + GCancellable *cancellable; + GInputStream *input_stream; + GFileOutputStream *output_stream; + CamelDataWrapper *wrapper; CamelMimePart *mime_part; - GSimpleAsyncResult *result; - GFile *file; + CamelStream *stream; + EAttachment *attachment; + GByteArray *buffer; + GError *error = NULL; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (callback != NULL); + output_stream = g_file_replace_finish (destination, result, &error); + save_context->output_stream = G_OUTPUT_STREAM (output_stream); - file = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (file != NULL || mime_part != NULL); + if (error != NULL) { + GSimpleAsyncResult *simple; - result = g_simple_async_result_new ( - G_OBJECT (attachment), callback, user_data, - e_attachment_build_mime_part_async); + /* Steal the reference. */ + simple = save_context->simple; + save_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_save_context_free (save_context); - /* First try the easy way out. */ - if (CAMEL_IS_MIME_PART (mime_part)) { - camel_object_ref (mime_part); - g_simple_async_result_set_op_res_gpointer ( - result, mime_part, camel_object_unref); - g_simple_async_result_complete_in_idle (result); return; } - /* XXX g_cancellable_push_current() documentation lies. - * The function rejects NULL pointers, so create a - * dummy GCancellable if necessary. */ - if (cancellable == NULL) - cancellable = g_cancellable_new (); - else - g_object_ref (cancellable); + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + mime_part = e_attachment_get_mime_part (attachment); - /* Because Camel's stream API is synchronous and not - * cancellable, we have to asynchronously read the file - * into memory and then encode it to a MIME part. That - * means it's double buffered, unfortunately. */ - g_file_read_async ( - file, G_PRIORITY_DEFAULT, cancellable, - attachment_build_mime_part_read_cb, result); + /* Decode the MIME part to an in-memory buffer. We have to do + * this because CamelStream is synchronous-only, and using threads + * is dangerous because CamelDataWrapper is not reentrant. */ + buffer = g_byte_array_new (); + stream = camel_stream_mem_new_with_byte_array (buffer); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + camel_data_wrapper_decode_to_stream (wrapper, stream); + camel_object_unref (stream); - g_cancellable_push_current (cancellable); + /* Load the buffer into a GMemoryInputStream. */ + input_stream = g_memory_input_stream_new_from_data ( + buffer->data, (gssize) buffer->len, + (GDestroyNotify) g_free); + save_context->input_stream = input_stream; + save_context->total_num_bytes = (goffset) buffer->len; + g_byte_array_free (buffer, FALSE); + + g_input_stream_read_async ( + input_stream, + save_context->buffer, + sizeof (save_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_read_cb, + save_context); } -CamelMimePart * -e_attachment_build_mime_part_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error) +void +e_attachment_save_async (EAttachment *attachment, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data) { + AttachmentSaveContext *save_context; + GCancellable *cancellable; CamelMimePart *mime_part; - GSimpleAsyncResult *simple_result; - gboolean async_result_is_valid; - gpointer source_tag; + GFile *source; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (callback != NULL); - source_tag = e_attachment_build_mime_part_async; - async_result_is_valid = g_simple_async_result_is_valid ( - result, G_OBJECT (attachment), source_tag); - g_return_val_if_fail (async_result_is_valid, NULL); + g_return_if_fail (!e_attachment_get_loading (attachment)); + g_return_if_fail (!e_attachment_get_saving (attachment)); - simple_result = G_SIMPLE_ASYNC_RESULT (result); - g_simple_async_result_propagate_error (simple_result, error); - mime_part = g_simple_async_result_get_op_res_gpointer (simple_result); - attachment_file_info_to_mime_part (attachment, mime_part); + /* The attachment content is either a GFile (on disk) or a + * CamelMimePart (in memory). Each is saved differently. */ - if (CAMEL_IS_MIME_PART (mime_part)) - camel_object_ref (mime_part); + source = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (source != NULL || mime_part != NULL); + + save_context = attachment_save_context_new ( + attachment, callback, user_data); - g_object_unref (result); + cancellable = attachment->priv->cancellable; + g_cancellable_reset (cancellable); - return mime_part; + /* GFile is the easier, but probably less common case. The + * attachment already references an on-disk file, so we can + * just use GIO to copy it asynchronously. + * + * We use G_FILE_COPY_OVERWRITE because the user should have + * already confirmed the overwrite through the save dialog. */ + if (G_IS_FILE (source)) + g_file_copy_async ( + source, destination, + G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, cancellable, + (GFileProgressCallback) attachment_progress_cb, + attachment, + (GAsyncReadyCallback) attachment_save_file_cb, + save_context); + + /* CamelMimePart can only be decoded to a file synchronously, so + * we do this in two stages. Stage one asynchronously opens the + * destination file for writing. Stage two spawns a thread that + * decodes the MIME part to the destination file. This stage is + * not cancellable, unfortunately. */ + else if (CAMEL_IS_MIME_PART (mime_part)) + g_file_replace_async ( + destination, NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_replace_cb, + save_context); +} + +gboolean +e_attachment_save_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gboolean success; + + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, + G_OBJECT (attachment), e_attachment_save_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + success = g_simple_async_result_get_op_res_gboolean (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + attachment_set_saving (attachment, FALSE); + + return success; } -#endif void -_e_attachment_set_reference (EAttachment *attachment, - GtkTreeRowReference *reference) +e_attachment_save_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent) { + GtkWidget *dialog; + GFileInfo *file_info; + const gchar *display_name; + const gchar *primary_text; + GError *error = NULL; + g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (reference != NULL); + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_return_if_fail (GTK_IS_WINDOW (parent)); - gtk_tree_row_reference_free (attachment->priv->reference); - attachment->priv->reference = gtk_tree_row_reference_copy (reference); + if (e_attachment_save_finish (attachment, result, &error)) + return; + + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + else + display_name = NULL; + + if (display_name != NULL) + primary_text = g_strdup_printf ( + _("Could not save '%s'"), display_name); + else + primary_text = g_strdup_printf ( + _("Could not save the attachment")); + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", primary_text); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); } diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index d9ef68bf39..1ca5b3121b 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -22,12 +22,11 @@ #ifndef E_ATTACHMENT_H #define E_ATTACHMENT_H -#include +#include #include #include #include #include -#include /* Standard GObject macros */ #define E_TYPE_ATTACHMENT \ @@ -71,6 +70,7 @@ EAttachment * e_attachment_new_for_message (CamelMimeMessage *message); void e_attachment_add_to_multipart (EAttachment *attachment, CamelMultipart *multipart, const gchar *default_charset); +void e_attachment_cancel (EAttachment *attachment); const gchar * e_attachment_get_disposition (EAttachment *attachment); void e_attachment_set_disposition (EAttachment *attachment, const gchar *disposition); @@ -78,9 +78,16 @@ GFile * e_attachment_get_file (EAttachment *attachment); void e_attachment_set_file (EAttachment *attachment, GFile *file); GFileInfo * e_attachment_get_file_info (EAttachment *attachment); +gboolean e_attachment_get_loading (EAttachment *attachment); CamelMimePart * e_attachment_get_mime_part (EAttachment *attachment); void e_attachment_set_mime_part (EAttachment *attachment, CamelMimePart *mime_part); +gint e_attachment_get_percent (EAttachment *attachment); +GtkTreeRowReference * + e_attachment_get_reference (EAttachment *attachment); +void e_attachment_set_reference (EAttachment *attachment, + GtkTreeRowReference *reference); +gboolean e_attachment_get_saving (EAttachment *attachment); camel_cipher_validity_encrypt_t e_attachment_get_encrypted (EAttachment *attachment); void e_attachment_set_encrypted (EAttachment *attachment, @@ -89,42 +96,45 @@ camel_cipher_validity_sign_t e_attachment_get_signed (EAttachment *attachment); void e_attachment_set_signed (EAttachment *attachment, camel_cipher_validity_sign_t signed_); -const gchar * e_attachment_get_content_type (EAttachment *attachment); -const gchar * e_attachment_get_display_name (EAttachment *attachment); const gchar * e_attachment_get_description (EAttachment *attachment); -GIcon * e_attachment_get_icon (EAttachment *attachment); -gboolean e_attachment_get_loading (EAttachment *attachment); const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); -gboolean e_attachment_get_saving (EAttachment *attachment); -guint64 e_attachment_get_size (EAttachment *attachment); gboolean e_attachment_is_image (EAttachment *attachment); gboolean e_attachment_is_rfc822 (EAttachment *attachment); GList * e_attachment_list_apps (EAttachment *attachment); GList * e_attachment_list_emblems (EAttachment *attachment); /* Asynchronous Operations */ -void e_attachment_launch_async (EAttachment *attachment, - EFileActivity *file_activity, - GAppInfo *app_info); +void e_attachment_load_async (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_attachment_load_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error); +void e_attachment_open_async (EAttachment *attachment, + GAppInfo *app_info, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_attachment_open_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error); void e_attachment_save_async (EAttachment *attachment, - EFileActivity *file_activity, - GFile *destination); - -#if 0 -void e_attachment_build_mime_part_async - (EAttachment *attachment, - GCancellable *cancellable, + GFile *destination, GAsyncReadyCallback callback, gpointer user_data); -CamelMimePart * e_attachment_build_mime_part_finish - (EAttachment *attachment, +gboolean e_attachment_save_finish (EAttachment *attachment, GAsyncResult *result, GError **error); -#endif -/* For use by EAttachmentStore only. */ -void _e_attachment_set_reference (EAttachment *attachment, - GtkTreeRowReference *reference); +/* Handy GAsyncReadyCallback Functions */ +void e_attachment_load_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent); +void e_attachment_open_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent); +void e_attachment_save_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent); G_END_DECLS -- cgit v1.2.3 From bc4f60ba176b64cc8fd8ffa47a01542f8eb25bdf Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 26 Mar 2009 19:33:16 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37478 --- widgets/misc/e-attachment-dialog.c | 6 +- widgets/misc/e-attachment-store.c | 134 -------------- widgets/misc/e-attachment.c | 345 ++++++++++++++++++++++++++++++++++--- 3 files changed, 327 insertions(+), 158 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index a844c228eb..dd39a253c9 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -97,11 +97,13 @@ attachment_dialog_update (EAttachmentDialog *dialog) widget = dialog->priv->display_name_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), display_name); + if (display_name != NULL) + gtk_entry_set_text (GTK_ENTRY (widget), display_name); widget = dialog->priv->description_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), description); + if (description != NULL) + gtk_entry_set_text (GTK_ENTRY (widget), description); widget = dialog->priv->content_type_label; gtk_label_set_text (GTK_LABEL (widget), type_description); diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 6086ed4d2f..3b273f929c 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -30,8 +30,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStorePrivate)) -#define DEFAULT_ICON_NAME "mail-attachment" - struct _EAttachmentStorePrivate { GHashTable *attachment_index; gchar *background_filename; @@ -223,123 +221,6 @@ attachment_store_constructed (GObject *object) gconf_bridge_bind_property (bridge, key, object, prop); } -static void -attachment_store_row_changed (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter) -{ - EAttachmentStorePrivate *priv; - EAttachment *attachment; - GFileInfo *file_info; - GFile *file; - GIcon *icon; - GList *list; - const gchar *content_type; - const gchar *display_name; - const gchar *thumbnail_path; - gchar *content_description; - gchar *display_size; - gchar *caption; - gboolean loading; - gboolean saving; - goffset size; - gint column_id; - gint percent; - - priv = E_ATTACHMENT_STORE_GET_PRIVATE (model); - - if (priv->ignore_row_changed) - return; - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - gtk_tree_model_get (model, iter, column_id, &attachment, -1); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) { - g_object_unref (attachment); - return; - } - - content_type = g_file_info_get_content_type (file_info); - display_name = g_file_info_get_display_name (file_info); - thumbnail_path = e_attachment_get_thumbnail_path (attachment); - loading = e_attachment_get_loading (attachment); - percent = e_attachment_get_percent (attachment); - saving = e_attachment_get_saving (attachment); - icon = g_file_info_get_icon (file_info); - size = g_file_info_get_size (file_info); - - content_type = (content_type != NULL) ? content_type : ""; - content_description = g_content_type_get_description (content_type); - display_size = g_format_size_for_display (size); - - if (size > 0) - caption = g_strdup_printf ( - "%s\n(%s)", display_name, display_size); - else - caption = g_strdup (display_name); - - /* Prefer the thumbnail if we have one. */ - if (thumbnail_path != NULL && *thumbnail_path != '\0') { - file = g_file_new_for_path (thumbnail_path); - icon = g_file_icon_new (file); - g_object_unref (file); - - /* Else use the standard icon for the content type. */ - } else if (icon != NULL) - g_object_ref (icon); - - /* Last ditch fallback. (GFileInfo not yet loaded?) */ - else - icon = g_themed_icon_new (DEFAULT_ICON_NAME); - - /* Apply emblems. */ - list = e_attachment_list_emblems (attachment); - if (list != NULL) { - GIcon *emblemed_icon; - GEmblem *emblem; - - emblem = G_EMBLEM (list->data); - emblemed_icon = g_emblemed_icon_new (icon, emblem); - list = g_list_delete_link (list, list); - g_object_unref (emblem); - - while (list != NULL) { - emblem = G_EMBLEM (list->data); - g_emblemed_icon_add_emblem ( - G_EMBLEMED_ICON (emblemed_icon), emblem); - list = g_list_delete_link (list, list); - g_object_unref (emblem); - } - - g_object_unref (icon); - icon = emblemed_icon; - } - - /* We're about to trigger another "row-changed" - * signal, so this prevents infinite recursion. */ - priv->ignore_row_changed = TRUE; - - gtk_list_store_set ( - GTK_LIST_STORE (model), iter, - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_description, - E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, - E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, - E_ATTACHMENT_STORE_COLUMN_ICON, icon, - E_ATTACHMENT_STORE_COLUMN_LOADING, loading, - E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, - E_ATTACHMENT_STORE_COLUMN_SAVING, saving, - E_ATTACHMENT_STORE_COLUMN_SIZE, size, - -1); - - priv->ignore_row_changed = FALSE; - - g_object_unref (icon); - g_free (content_description); - g_free (display_size); -} - static void attachment_store_class_init (EAttachmentStoreClass *class) { @@ -425,12 +306,6 @@ attachment_store_class_init (EAttachmentStoreClass *class) G_PARAM_READABLE)); } -static void -attachment_store_iface_init (GtkTreeModelIface *iface) -{ - iface->row_changed = attachment_store_row_changed; -} - static void attachment_store_init (EAttachmentStore *store) { @@ -481,18 +356,9 @@ e_attachment_store_get_type (void) NULL /* value_table */ }; - static const GInterfaceInfo iface_info = { - (GInterfaceInitFunc) attachment_store_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL /* interface_data */ - }; - type = g_type_register_static ( GTK_TYPE_LIST_STORE, "EAttachmentStore", &type_info, 0); - - g_type_add_interface_static ( - type, GTK_TYPE_TREE_MODEL, &iface_info); } return type; diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 55b3280e87..7044aa8cde 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -32,11 +32,15 @@ #include #include "e-util/e-util.h" +#include "e-attachment-store.h" #define E_ATTACHMENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) +/* Fallback Icon */ +#define DEFAULT_ICON_NAME "mail-attachment" + /* Emblems */ #define EMBLEM_CANCELLED "gtk-cancel" #define EMBLEM_LOADING "emblem-downloads" @@ -122,25 +126,258 @@ attachment_get_default_charset (void) } static void -attachment_notify_model (EAttachment *attachment) +attachment_update_file_info_columns (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GFileInfo *file_info; + const gchar *content_type; + const gchar *display_name; + gchar *display_size; + gchar *caption; + goffset size; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + content_type = g_file_info_get_content_type (file_info); + display_name = g_file_info_get_display_name (file_info); + size = g_file_info_get_size (file_info); + + display_size = g_format_size_for_display (size); + + if (size > 0) + caption = g_strdup_printf ( + "%s\n(%s)", display_name, display_size); + else + caption = g_strdup (display_name); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_type, + E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, + E_ATTACHMENT_STORE_COLUMN_SIZE, size, + -1); + + g_free (display_size); + g_free (caption); +} + +static void +attachment_update_icon_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GFileInfo *file_info; + GCancellable *cancellable; + GIcon *icon = NULL; + const gchar *emblem_name = NULL; + const gchar *thumbnail_path = NULL; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + cancellable = attachment->priv->cancellable; + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) { + icon = g_file_info_get_icon (file_info); + thumbnail_path = g_file_info_get_attribute_byte_string ( + file_info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + } + + /* Prefer the thumbnail if we have one. */ + if (thumbnail_path != NULL && *thumbnail_path != '\0') { + GFile *file; + + file = g_file_new_for_path (thumbnail_path); + icon = g_file_icon_new (file); + g_object_unref (file); + + /* Else use the standard icon for the content type. */ + } else if (icon != NULL) + g_object_ref (icon); + + /* Last ditch fallback. (GFileInfo not yet loaded?) */ + else + icon = g_themed_icon_new (DEFAULT_ICON_NAME); + + /* Pick an emblem, limit one. Choices listed by priority. */ + + if (g_cancellable_is_cancelled (cancellable)) + emblem_name = EMBLEM_CANCELLED; + + else if (e_attachment_get_loading (attachment)) + emblem_name = EMBLEM_LOADING; + + else if (e_attachment_get_saving (attachment)) + emblem_name = EMBLEM_SAVING; + + else if (e_attachment_get_encrypted (attachment)) + switch (e_attachment_get_encrypted (attachment)) { + case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK: + emblem_name = EMBLEM_ENCRYPT_WEAK; + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED: + emblem_name = EMBLEM_ENCRYPT_UNKNOWN; + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG: + emblem_name = EMBLEM_ENCRYPT_STRONG; + break; + + default: + g_warn_if_reached (); + break; + } + + else if (e_attachment_get_signed (attachment)) + switch (e_attachment_get_signed (attachment)) { + case CAMEL_CIPHER_VALIDITY_SIGN_GOOD: + emblem_name = EMBLEM_SIGN_GOOD; + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_BAD: + emblem_name = EMBLEM_SIGN_BAD; + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN: + case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY: + emblem_name = EMBLEM_SIGN_UNKNOWN; + break; + + default: + g_warn_if_reached (); + break; + } + + if (emblem_name != NULL) { + GIcon *emblemed_icon; + GEmblem *emblem; + + emblemed_icon = g_themed_icon_new (emblem_name); + emblem = g_emblem_new (emblemed_icon); + g_object_unref (emblemed_icon); + + emblemed_icon = g_emblemed_icon_new (icon, emblem); + g_object_unref (emblem); + g_object_unref (icon); + + icon = emblemed_icon; + } + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_ICON, icon, + -1); + + g_object_unref (icon); +} + +static void +attachment_update_loading_column (EAttachment *attachment) { GtkTreeRowReference *reference; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; + GFileInfo *file_info; + gboolean loading; reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; - if (reference == NULL) + /* Don't show progress until we have a GFileInfo. */ + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) return; model = gtk_tree_row_reference_get_model (reference); path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + loading = e_attachment_get_loading (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_LOADING, loading, + -1); +} + +static void +attachment_update_percent_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gint percent; + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); + + percent = e_attachment_get_percent (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, + -1); +} +static void +attachment_update_saving_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gboolean saving; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); + + saving = e_attachment_get_saving (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_SAVING, saving, + -1); } static void @@ -167,8 +404,6 @@ attachment_set_file_info (EAttachment *attachment, model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "total-size"); } - - attachment_notify_model (attachment); } static void @@ -192,8 +427,6 @@ attachment_set_loading (EAttachment *attachment, model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "num-loading"); } - - attachment_notify_model (attachment); } static void @@ -207,8 +440,6 @@ attachment_set_saving (EAttachment *attachment, g_object_notify (G_OBJECT (attachment), "percent"); g_object_notify (G_OBJECT (attachment), "saving"); g_object_thaw_notify (G_OBJECT (attachment)); - - attachment_notify_model (attachment); } static void @@ -220,8 +451,6 @@ attachment_progress_cb (goffset current_num_bytes, (current_num_bytes * 100) / total_num_bytes; g_object_notify (G_OBJECT (attachment), "percent"); - - attachment_notify_model (attachment); } static gboolean @@ -230,7 +459,7 @@ attachment_cancelled_timeout_cb (EAttachment *attachment) attachment->priv->emblem_timeout_id = 0; g_cancellable_reset (attachment->priv->cancellable); - attachment_notify_model (attachment); + attachment_update_icon_column (attachment); return FALSE; } @@ -247,6 +476,8 @@ attachment_cancelled_cb (EAttachment *attachment) attachment->priv->emblem_timeout_id = g_timeout_add_seconds ( 1, (GSourceFunc) attachment_cancelled_timeout_cb, attachment); + + attachment_update_icon_column (attachment); } static void @@ -555,6 +786,66 @@ attachment_init (EAttachment *attachment) attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE; + g_signal_connect ( + attachment, "notify::encrypted", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_file_info_columns), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::loading", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::loading", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::percent", + G_CALLBACK (attachment_update_percent_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_file_info_columns), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_saving_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_percent_column), NULL); + + g_signal_connect ( + attachment, "notify::saving", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::saving", + G_CALLBACK (attachment_update_saving_column), NULL); + + g_signal_connect ( + attachment, "notify::signed", + G_CALLBACK (attachment_update_icon_column), NULL); + g_signal_connect_swapped ( attachment->priv->cancellable, "cancelled", G_CALLBACK (attachment_cancelled_cb), attachment); @@ -851,10 +1142,6 @@ e_attachment_get_reference (EAttachment *attachment) { g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - /* Don't return an invalid tree row reference. */ - if (!gtk_tree_row_reference_valid (attachment->priv->reference)) - e_attachment_set_reference (attachment, NULL); - return attachment->priv->reference; } @@ -900,7 +1187,6 @@ e_attachment_set_encrypted (EAttachment *attachment, attachment->priv->encrypted = encrypted; g_object_notify (G_OBJECT (attachment), "encrypted"); - attachment_notify_model (attachment); } camel_cipher_validity_sign_t @@ -922,7 +1208,6 @@ e_attachment_set_signed (EAttachment *attachment, attachment->priv->signed_ = signed_; g_object_notify (G_OBJECT (attachment), "signed"); - attachment_notify_model (attachment); } const gchar * @@ -1695,9 +1980,24 @@ attachment_open_file (AttachmentOpenContext *open_context) simple = open_context->simple; open_context->simple = NULL; - if (open_context->app_info == NULL) - open_context->app_info = g_file_query_default_handler ( - open_context->file, NULL, &error); + /* Find a default app based on content type. */ + if (open_context->app_info == NULL) { + EAttachment *attachment; + GFileInfo *file_info; + const gchar *content_type; + + attachment = open_context->attachment; + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + goto exit; + + content_type = g_file_info_get_content_type (file_info); + if (content_type == NULL) + goto exit; + + open_context->app_info = g_app_info_get_default_for_type ( + content_type, FALSE); + } if (open_context->app_info == NULL) goto exit; @@ -2132,7 +2432,8 @@ attachment_save_replace_cb (GFile *destination, * this because CamelStream is synchronous-only, and using threads * is dangerous because CamelDataWrapper is not reentrant. */ buffer = g_byte_array_new (); - stream = camel_stream_mem_new_with_byte_array (buffer); + stream = camel_stream_mem_new (); + camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), buffer); wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); camel_data_wrapper_decode_to_stream (wrapper, stream); camel_object_unref (stream); -- cgit v1.2.3 From 8a1f639a670696e71daac8305ae0823668d29a14 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 30 Mar 2009 03:38:36 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37482 --- widgets/misc/e-attachment-icon-view.c | 139 ++++++- widgets/misc/e-attachment-paned.c | 142 ++++--- widgets/misc/e-attachment-store.c | 54 ++- widgets/misc/e-attachment-store.h | 2 +- widgets/misc/e-attachment-tree-view.c | 134 +++++- widgets/misc/e-attachment-view.c | 248 ++++++++++-- widgets/misc/e-attachment-view.h | 45 ++- widgets/misc/e-attachment.c | 740 ++++++++++++++++------------------ widgets/misc/e-attachment.h | 1 - 9 files changed, 990 insertions(+), 515 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index f6e42b2fbe..9588540f05 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -101,16 +101,28 @@ attachment_icon_view_button_press_event (GtkWidget *widget, { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { - e_attachment_view_show_popup_menu (view, event); + if (e_attachment_view_button_press_event (view, event)) return TRUE; - } /* Chain up to parent's button_press_event() method. */ return GTK_WIDGET_CLASS (parent_class)-> button_press_event (widget, event); } +static gboolean +attachment_icon_view_button_release_event (GtkWidget *widget, + GdkEventButton *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (e_attachment_view_button_release_event (view, event)) + return TRUE; + + /* Chain up to parent's button_release_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_release_event (widget, event); +} + static gboolean attachment_icon_view_key_press_event (GtkWidget *widget, GdkEventKey *event) @@ -127,6 +139,43 @@ attachment_icon_view_key_press_event (GtkWidget *widget, key_press_event (widget, event); } +static void +attachment_icon_view_drag_begin (GtkWidget *widget, + GdkDragContext *context) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + /* Chain up to parent's drag_begin() method. */ + GTK_WIDGET_CLASS (parent_class)->drag_begin (widget, context); + + e_attachment_view_drag_begin (view, context); +} + +static void +attachment_icon_view_drag_end (GtkWidget *widget, + GdkDragContext *context) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + /* Chain up to parent's drag_end() method. */ + GTK_WIDGET_CLASS (parent_class)->drag_end (widget, context); + + e_attachment_view_drag_end (view, context); +} + +static void +attachment_icon_view_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection, + guint info, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_drag_data_get ( + view, context, selection, info, time); +} + static gboolean attachment_icon_view_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -139,6 +188,23 @@ attachment_icon_view_drag_motion (GtkWidget *widget, return e_attachment_view_drag_motion (view, context, x, y, time); } +static gboolean +attachment_icon_view_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (!e_attachment_view_drag_drop (view, context, x, y, time)) + return FALSE; + + /* Chain up to parent's drag_drop() method. */ + return GTK_WIDGET_CLASS (parent_class)->drag_drop ( + widget, context, x, y, time); +} + static void attachment_icon_view_drag_data_received (GtkWidget *widget, GdkDragContext *context, @@ -270,6 +336,55 @@ attachment_icon_view_unselect_all (EAttachmentView *view) gtk_icon_view_unselect_all (icon_view); } +static void +attachment_icon_view_drag_source_set (EAttachmentView *view, + GdkModifierType start_button_mask, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_enable_model_drag_source ( + icon_view, start_button_mask, targets, n_targets, actions); +} + +static void +attachment_icon_view_drag_dest_set (EAttachmentView *view, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_enable_model_drag_dest ( + icon_view, targets, n_targets, actions); +} + +static void +attachment_icon_view_drag_source_unset (EAttachmentView *view) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_unset_model_drag_source (icon_view); +} + +static void +attachment_icon_view_drag_dest_unset (EAttachmentView *view) +{ + GtkIconView *icon_view; + + icon_view = GTK_ICON_VIEW (view); + + gtk_icon_view_unset_model_drag_dest (icon_view); +} + static void attachment_icon_view_class_init (EAttachmentIconViewClass *class) { @@ -288,8 +403,13 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->button_press_event = attachment_icon_view_button_press_event; + widget_class->button_release_event = attachment_icon_view_button_release_event; widget_class->key_press_event = attachment_icon_view_key_press_event; + widget_class->drag_begin = attachment_icon_view_drag_begin; + widget_class->drag_end = attachment_icon_view_drag_end; + widget_class->drag_data_get = attachment_icon_view_drag_data_get; widget_class->drag_motion = attachment_icon_view_drag_motion; + widget_class->drag_drop = attachment_icon_view_drag_drop; widget_class->drag_data_received = attachment_icon_view_drag_data_received; widget_class->popup_menu = attachment_icon_view_popup_menu; @@ -313,6 +433,11 @@ attachment_icon_view_iface_init (EAttachmentViewIface *iface) iface->unselect_path = attachment_icon_view_unselect_path; iface->select_all = attachment_icon_view_select_all; iface->unselect_all = attachment_icon_view_unselect_all; + + iface->drag_source_set = attachment_icon_view_drag_source_set; + iface->drag_dest_set = attachment_icon_view_drag_dest_set; + iface->drag_source_unset = attachment_icon_view_drag_source_unset; + iface->drag_dest_unset = attachment_icon_view_drag_dest_unset; } static void @@ -320,7 +445,6 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) { GtkCellLayout *cell_layout; GtkCellRenderer *renderer; - cell_layout = GTK_CELL_LAYOUT (icon_view); icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view); @@ -331,7 +455,7 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); gtk_cell_layout_add_attribute ( cell_layout, renderer, "gicon", @@ -340,8 +464,9 @@ attachment_icon_view_init (EAttachmentIconView *icon_view) renderer = gtk_cell_renderer_text_new (); g_object_set ( renderer, "alignment", PANGO_ALIGN_CENTER, - "xalign", 0.5, NULL); - gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + "wrap-mode", PANGO_WRAP_WORD, "wrap-width", 150, + "yalign", 0.0, NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); gtk_cell_layout_add_attribute ( cell_layout, renderer, "text", diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index 5134282526..42890236e9 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -467,10 +467,12 @@ attachment_paned_iface_init (EAttachmentViewIface *iface) static void attachment_paned_init (EAttachmentPaned *paned) { + EAttachmentView *view; GtkTreeSelection *selection; GtkSizeGroup *size_group; GtkWidget *container; GtkWidget *widget; + GtkAction *action; paned->priv = E_ATTACHMENT_PANED_GET_PRIVATE (paned); paned->priv->model = e_attachment_store_new (); @@ -478,6 +480,58 @@ attachment_paned_init (EAttachmentPaned *paned) /* Keep the expander label and combo box the same height. */ size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + /* Construct the Attachment Views */ + + container = GTK_WIDGET (paned); + + widget = gtk_notebook_new (); + gtk_widget_set_size_request (widget, -1, 40); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE); + paned->priv->notebook = g_object_ref (widget); + gtk_widget_hide (widget); + + container = paned->priv->notebook; + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_icon_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_icon_view_set_model (GTK_ICON_VIEW (widget), paned->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + paned->priv->icon_view = g_object_ref (widget); + gtk_widget_show (widget); + + container = paned->priv->notebook; + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_tree_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget), paned->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + paned->priv->tree_view = g_object_ref (widget); + gtk_widget_show (widget); + /* Construct the Controls */ container = GTK_WIDGET (paned); @@ -501,6 +555,16 @@ attachment_paned_init (EAttachmentPaned *paned) paned->priv->expander = g_object_ref (widget); gtk_widget_show (widget); + /* The "Add Attachment" button proxies the "add" action from + * one of the two attachment views. Doesn't matter which. */ + widget = gtk_button_new (); + view = E_ATTACHMENT_VIEW (paned->priv->icon_view); + action = e_attachment_view_get_action (view, "add"); + gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); + gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + widget = gtk_combo_box_new_text (); gtk_size_group_add_widget (size_group, widget); gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Icon View")); @@ -511,85 +575,45 @@ attachment_paned_init (EAttachmentPaned *paned) container = paned->priv->expander; - widget = gtk_hbox_new (FALSE, 0); + /* Request the width to be as large as possible, and let the + * GtkExpander allocate what space there is. This effectively + * packs the widget to expand. */ + widget = gtk_hbox_new (FALSE, 6); gtk_size_group_add_widget (size_group, widget); + gtk_widget_set_size_request (widget, G_MAXINT, -1); gtk_expander_set_label_widget (GTK_EXPANDER (container), widget); gtk_widget_show (widget); container = widget; widget = gtk_label_new_with_mnemonic (_("Show _Attachment Bar")); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 6); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); paned->priv->show_hide_label = g_object_ref (widget); gtk_widget_show (widget); - widget = gtk_image_new_from_icon_name ( - "mail-attachment", GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_widget_set_size_request (widget, 100, -1); + widget = gtk_alignment_new (0.5, 0.5, 0.0, 1.0); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - paned->priv->status_icon = g_object_ref (widget); - gtk_widget_hide (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6); - paned->priv->status_label = g_object_ref (widget); - gtk_widget_hide (widget); - - /* Construct the Attachment Views */ - - container = GTK_WIDGET (paned); - - widget = gtk_notebook_new (); - gtk_widget_set_size_request (widget, -1, 40); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE); - paned->priv->notebook = g_object_ref (widget); - gtk_widget_hide (widget); - - container = paned->priv->notebook; - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (widget), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); gtk_widget_show (widget); container = widget; - widget = e_attachment_icon_view_new (); - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); - gtk_icon_view_set_model (GTK_ICON_VIEW (widget), paned->priv->model); + widget = gtk_hbox_new (FALSE, 6); gtk_container_add (GTK_CONTAINER (container), widget); - paned->priv->icon_view = g_object_ref (widget); - gtk_widget_show (widget); - - container = paned->priv->notebook; - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (widget), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); gtk_widget_show (widget); container = widget; - widget = e_attachment_tree_view_new (); - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); - gtk_tree_view_set_model (GTK_TREE_VIEW (widget), paned->priv->model); - gtk_container_add (GTK_CONTAINER (container), widget); - paned->priv->tree_view = g_object_ref (widget); - gtk_widget_show (widget); + widget = gtk_image_new_from_icon_name ( + "mail-attachment", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + paned->priv->status_icon = g_object_ref (widget); + gtk_widget_hide (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + paned->priv->status_label = g_object_ref (widget); + gtk_widget_hide (widget); selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (paned->priv->tree_view)); diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 3b273f929c..0187d2a8c8 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -674,23 +674,34 @@ exit: void e_attachment_store_run_save_dialog (EAttachmentStore *store, - EAttachment *attachment, + GList *attachment_list, GtkWindow *parent) { GtkFileChooser *file_chooser; + GtkFileChooserAction action; GtkWidget *dialog; GFile *destination; - GFileInfo *file_info; - const gchar *display_name; + const gchar *title; gint response; + guint length; g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_return_if_fail (GTK_IS_WINDOW (parent)); + length = g_list_length (attachment_list); + + if (length == 0) + return; + + title = ngettext ("Save Attachment", "Save Attachments", length); + + if (length == 1) + action = GTK_FILE_CHOOSER_ACTION_SAVE; + else + action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; + dialog = gtk_file_chooser_dialog_new ( - _("Save Attachment"), parent, - GTK_FILE_CHOOSER_ACTION_SAVE, + title, parent, action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); @@ -700,13 +711,20 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_icon_name (GTK_WINDOW (dialog), "mail-attachment"); - file_info = e_attachment_get_file_info (attachment); - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - else - display_name = NULL; - if (display_name != NULL) - gtk_file_chooser_set_current_name (file_chooser, display_name); + if (action == GTK_FILE_CHOOSER_ACTION_SAVE) { + EAttachment *attachment; + GFileInfo *file_info; + const gchar *name = NULL; + + attachment = attachment_list->data; + file_info = e_attachment_get_file_info (attachment); + if (file_info != NULL) + name = g_file_info_get_display_name (file_info); + if (name == NULL) + /* Translators: Default attachment filename. */ + name = _("attachment.dat"); + gtk_file_chooser_set_current_name (file_chooser, name); + } response = e_attachment_store_run_file_chooser_dialog (store, dialog); @@ -715,9 +733,13 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, destination = gtk_file_chooser_get_file (file_chooser); - e_attachment_save_async ( - attachment, destination, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); + while (attachment_list != NULL) { + e_attachment_save_async ( + attachment_list->data, + destination, (GAsyncReadyCallback) + e_attachment_save_handle_error, parent); + attachment_list = g_list_next (attachment_list); + } g_object_unref (destination); diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index e7f74102be..88b2823313 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -103,7 +103,7 @@ void e_attachment_store_run_load_dialog GtkWindow *parent); void e_attachment_store_run_save_dialog (EAttachmentStore *store, - EAttachment *attachment, + GList *attachment_list, GtkWindow *parent); G_END_DECLS diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index 548ed3aa4f..5a613f4f17 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -119,16 +119,28 @@ attachment_tree_view_button_press_event (GtkWidget *widget, { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { - e_attachment_view_show_popup_menu (view, event); + if (e_attachment_view_button_press_event (view, event)) return TRUE; - } /* Chain up to parent's button_press_event() method. */ return GTK_WIDGET_CLASS (parent_class)-> button_press_event (widget, event); } +static gboolean +attachment_tree_view_button_release_event (GtkWidget *widget, + GdkEventButton *event) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (e_attachment_view_button_release_event (view, event)) + return TRUE; + + /* Chain up to parent's button_release_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + button_release_event (widget, event); +} + static gboolean attachment_tree_view_key_press_event (GtkWidget *widget, GdkEventKey *event) @@ -145,6 +157,43 @@ attachment_tree_view_key_press_event (GtkWidget *widget, key_press_event (widget, event); } +static void +attachment_tree_view_drag_begin (GtkWidget *widget, + GdkDragContext *context) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + /* Chain up to parent's drag_begin() method. */ + GTK_WIDGET_CLASS (parent_class)->drag_begin (widget, context); + + e_attachment_view_drag_begin (view, context); +} + +static void +attachment_tree_view_drag_end (GtkWidget *widget, + GdkDragContext *context) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + /* Chain up to parent's drag_end() method. */ + GTK_WIDGET_CLASS (parent_class)->drag_end (widget, context); + + e_attachment_view_drag_end (view, context); +} + +static void +attachment_tree_view_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection, + guint info, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + e_attachment_view_drag_data_get ( + view, context, selection, info, time); +} + static gboolean attachment_tree_view_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -157,6 +206,23 @@ attachment_tree_view_drag_motion (GtkWidget *widget, return e_attachment_view_drag_motion (view, context, x, y, time); } +static gboolean +attachment_tree_view_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + EAttachmentView *view = E_ATTACHMENT_VIEW (widget); + + if (!e_attachment_view_drag_drop (view, context, x, y, time)) + return FALSE; + + /* Chain up to parent's drag_drop() method. */ + return GTK_WIDGET_CLASS (parent_class)->drag_drop ( + widget, context, x, y, time); +} + static void attachment_tree_view_drag_data_received (GtkWidget *widget, GdkDragContext *context, @@ -306,6 +372,55 @@ attachment_tree_view_unselect_all (EAttachmentView *view) gtk_tree_selection_unselect_all (selection); } +static void +attachment_tree_view_drag_source_set (EAttachmentView *view, + GdkModifierType start_button_mask, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions) +{ + GtkTreeView *tree_view; + + tree_view = GTK_TREE_VIEW (view); + + gtk_tree_view_enable_model_drag_source ( + tree_view, start_button_mask, targets, n_targets, actions); +} + +static void +attachment_tree_view_drag_dest_set (EAttachmentView *view, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions) +{ + GtkTreeView *tree_view; + + tree_view = GTK_TREE_VIEW (view); + + gtk_tree_view_enable_model_drag_dest ( + tree_view, targets, n_targets, actions); +} + +static void +attachment_tree_view_drag_source_unset (EAttachmentView *view) +{ + GtkTreeView *tree_view; + + tree_view = GTK_TREE_VIEW (view); + + gtk_tree_view_unset_rows_drag_source (tree_view); +} + +static void +attachment_tree_view_drag_dest_unset (EAttachmentView *view) +{ + GtkTreeView *tree_view; + + tree_view = GTK_TREE_VIEW (view); + + gtk_tree_view_unset_rows_drag_dest (tree_view); +} + static void attachment_tree_view_class_init (EAttachmentTreeViewClass *class) { @@ -324,8 +439,13 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->button_press_event = attachment_tree_view_button_press_event; + widget_class->button_release_event = attachment_tree_view_button_release_event; widget_class->key_press_event = attachment_tree_view_key_press_event; + widget_class->drag_begin = attachment_tree_view_drag_begin; + widget_class->drag_end = attachment_tree_view_drag_end; + widget_class->drag_data_get = attachment_tree_view_drag_data_get; widget_class->drag_motion = attachment_tree_view_drag_motion; + widget_class->drag_drop = attachment_tree_view_drag_drop; widget_class->drag_data_received = attachment_tree_view_drag_data_received; widget_class->popup_menu = attachment_tree_view_popup_menu; @@ -349,6 +469,11 @@ attachment_tree_view_iface_init (EAttachmentViewIface *iface) iface->unselect_path = attachment_tree_view_unselect_path; iface->select_all = attachment_tree_view_select_all; iface->unselect_all = attachment_tree_view_unselect_all; + + iface->drag_source_set = attachment_tree_view_drag_source_set; + iface->drag_dest_set = attachment_tree_view_drag_dest_set; + iface->drag_source_unset = attachment_tree_view_drag_source_unset; + iface->drag_dest_unset = attachment_tree_view_drag_dest_unset; } static void @@ -368,7 +493,6 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); /* Name Column */ - column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_spacing (column, 3); @@ -417,7 +541,6 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) E_ATTACHMENT_STORE_COLUMN_SAVING); /* Size Column */ - column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Size")); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); @@ -430,7 +553,6 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) attachment_tree_view_render_size, NULL, NULL); /* Type Column */ - column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, _("Type")); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index cb735fbfec..e9e546e449 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -223,21 +223,16 @@ action_save_as_cb (GtkAction *action, EAttachmentView *view) { EAttachmentStore *store; - EAttachment *attachment; GList *selected; gpointer parent; store = e_attachment_view_get_store (view); - selected = e_attachment_view_get_selected_attachments (view); - g_return_if_fail (g_list_length (selected) == 1); - attachment = selected->data; - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - e_attachment_store_run_save_dialog (store, attachment, parent); - + selected = e_attachment_view_get_selected_attachments (view); + e_attachment_store_run_save_dialog (store, selected, parent); g_list_foreach (selected, (GFunc) g_object_unref, NULL); g_list_free (selected); } @@ -300,7 +295,7 @@ static GtkActionEntry editable_entries[] = { GTK_STOCK_ADD, N_("A_dd Attachment..."), NULL, - NULL, /* XXX Add a tooltip! */ + N_("Attach a file"), G_CALLBACK (action_add_cb) }, { "properties", @@ -563,10 +558,8 @@ e_attachment_view_init (EAttachmentView *view) priv = e_attachment_view_get_private (view); - gtk_drag_dest_set ( - GTK_WIDGET (view), GTK_DEST_DEFAULT_ALL, - drop_types, G_N_ELEMENTS (drop_types), - GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); + e_attachment_view_drag_source_set (view); + e_attachment_view_drag_dest_set (view); ui_manager = gtk_ui_manager_new (); priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); @@ -809,6 +802,70 @@ e_attachment_view_remove_selected (EAttachmentView *view, g_list_free (selected); } +gboolean +e_attachment_view_button_press_event (EAttachmentView *view, + GdkEventButton *event) +{ + GtkTreePath *path; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + /* If the user clicked on a selected item, retain the current + * selection. If the user clicked on an unselected item, select + * the clicked item only. If the user did not click on an item, + * clear the current selection. */ + path = e_attachment_view_get_path_at_pos (view, event->x, event->y); + if (path != NULL) { + if (!e_attachment_view_path_is_selected (view, path)) { + e_attachment_view_unselect_all (view); + e_attachment_view_select_path (view, path); + } + gtk_tree_path_free (path); + } else + e_attachment_view_unselect_all (view); + + /* Cancel drag and drop if there are no selected items, + * or if any of the selected items are loading or saving. */ + if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { + GList *selected, *iter; + gboolean busy = FALSE; + + selected = e_attachment_view_get_selected_attachments (view); + for (iter = selected; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + busy |= e_attachment_get_loading (attachment); + busy |= e_attachment_get_saving (attachment); + } + if (selected == NULL || busy) + e_attachment_view_drag_source_unset (view); + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); + } + + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { + e_attachment_view_show_popup_menu (view, event); + return TRUE; + } + + return FALSE; +} + +gboolean +e_attachment_view_button_release_event (EAttachmentView *view, + GdkEventButton *event) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + /* Restore the attachment view as a drag source, in case + * we had to cancel during a button press event. */ + if (event->button == 1) + e_attachment_view_drag_source_set (view); + + return FALSE; +} + GtkTreePath * e_attachment_view_get_path_at_pos (EAttachmentView *view, gint x, @@ -927,6 +984,118 @@ e_attachment_view_sync_selection (EAttachmentView *view, g_list_free (selected); } +void +e_attachment_view_drag_source_set (EAttachmentView *view) +{ + GtkTargetEntry *targets; + GtkTargetList *list; + gint n_targets; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + list = gtk_target_list_new (NULL, 0); + gtk_target_list_add_uri_targets (list, 0); + targets = gtk_target_table_new_from_list (list, &n_targets); + + gtk_drag_source_set ( + GTK_WIDGET (view), GDK_BUTTON1_MASK, + targets, n_targets, GDK_ACTION_COPY); + + gtk_target_table_free (targets, n_targets); + gtk_target_list_unref (list); +} + +void +e_attachment_view_drag_source_unset (EAttachmentView *view) +{ + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + gtk_drag_source_unset (GTK_WIDGET (view)); +} + +void +e_attachment_view_drag_begin (EAttachmentView *view, + GdkDragContext *context) +{ + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); +} + +void +e_attachment_view_drag_end (EAttachmentView *view, + GdkDragContext *context) +{ + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); +} + +void +e_attachment_view_drag_data_get (EAttachmentView *view, + GdkDragContext *context, + GtkSelectionData *selection, + guint info, + guint time) +{ + GList *selected, *iter; + gchar **uris; + gint ii = 0; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); + g_return_if_fail (selection != NULL); + + selected = e_attachment_view_get_selected_attachments (view); + if (selected == NULL) + return; + + uris = g_malloc0 (sizeof (gchar *) * (g_list_length (selected) + 1)); + + for (iter = selected; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + GFile *file; + + /* FIXME Need to handle attachments with no GFile. */ + file = e_attachment_get_file (attachment); + if (file == NULL) + continue; + + uris[ii++] = g_file_get_uri (file); + } + + gtk_selection_data_set_uris (selection, uris); + + g_strfreev (uris); +} + +void +e_attachment_view_drag_dest_set (EAttachmentView *view) +{ + GtkTargetEntry *targets; + GtkTargetList *list; + gint n_targets; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + list = gtk_target_list_new (NULL, 0); + /* FIXME Add targets here... */ + targets = gtk_target_table_new_from_list (list, &n_targets); + + gtk_drag_dest_set ( + GTK_WIDGET (view), GTK_DEST_DEFAULT_ALL, + targets, n_targets, GDK_ACTION_COPY); + + gtk_target_table_free (targets, n_targets); + gtk_target_list_unref (list); +} + +void +e_attachment_view_drag_dest_unset (EAttachmentView *view) +{ + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + gtk_drag_dest_unset (GTK_WIDGET (view)); +} + void e_attachment_view_drag_action (EAttachmentView *view, GdkDragAction action) @@ -994,6 +1163,11 @@ e_attachment_view_drag_motion (EAttachmentView *view, GdkDragAction chosen_action; g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE); + + /* Disallow drops if we're not editable. */ + if (!e_attachment_view_get_editable (view)) + return FALSE; for (iter = context->targets; iter != NULL; iter = iter->next) { GdkAtom atom = iter->data; @@ -1020,12 +1194,29 @@ e_attachment_view_drag_motion (EAttachmentView *view, return (chosen_action != 0); } +gboolean +e_attachment_view_drag_drop (EAttachmentView *view, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE); + + /* Disallow drops if we're not editable. */ + if (!e_attachment_view_get_editable (view)) + return FALSE; + + return TRUE; +} + void e_attachment_view_drag_data_received (EAttachmentView *view, - GdkDragContext *drag_context, + GdkDragContext *context, gint x, gint y, - GtkSelectionData *selection_data, + GtkSelectionData *selection, guint info, guint time) { @@ -1034,16 +1225,18 @@ e_attachment_view_drag_data_received (EAttachmentView *view, GdkDragAction action; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); + g_return_if_fail (selection != NULL); priv = e_attachment_view_get_private (view); ui_manager = e_attachment_view_get_ui_manager (view); - action = drag_context->action; + action = context->action; - if (gtk_selection_data_get_data (selection_data) == NULL) + if (gtk_selection_data_get_data (selection) == NULL) return; - if (gtk_selection_data_get_length (selection_data) == -1) + if (gtk_selection_data_get_length (selection) == -1) return; if (priv->drag_context != NULL) @@ -1052,8 +1245,8 @@ e_attachment_view_drag_data_received (EAttachmentView *view, if (priv->selection_data != NULL) gtk_selection_data_free (priv->selection_data); - priv->drag_context = g_object_ref (drag_context); - priv->selection_data = gtk_selection_data_copy (selection_data); + priv->drag_context = g_object_ref (context); + priv->selection_data = gtk_selection_data_copy (selection); priv->info = info; priv->time = time; @@ -1147,21 +1340,6 @@ e_attachment_view_show_popup_menu (EAttachmentView *view, g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - if (event != NULL) { - GtkTreePath *path; - - path = e_attachment_view_get_path_at_pos ( - view, event->x, event->y); - if (path != NULL) { - if (!e_attachment_view_path_is_selected (view, path)) { - e_attachment_view_unselect_all (view); - e_attachment_view_select_path (view, path); - } - gtk_tree_path_free (path); - } else - e_attachment_view_unselect_all (view); - } - e_attachment_view_update_actions (view); ui_manager = e_attachment_view_get_ui_manager (view); @@ -1218,7 +1396,7 @@ e_attachment_view_update_actions (EAttachmentView *view) gtk_action_set_visible (action, !busy && n_selected > 0); action = e_attachment_view_get_action (view, "save-as"); - gtk_action_set_visible (action, !busy && n_selected == 1); + gtk_action_set_visible (action, !busy && n_selected > 0); action = e_attachment_view_get_action (view, "set-background"); gtk_action_set_visible (action, !busy && is_image); diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 96a0f2dc16..d33ad951ac 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -72,6 +72,19 @@ struct _EAttachmentViewIface { GtkTreePath *path); void (*select_all) (EAttachmentView *view); void (*unselect_all) (EAttachmentView *view); + + /* Drag and Drop Methods */ + void (*drag_source_set) (EAttachmentView *view, + GdkModifierType start_button_mask, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions); + void (*drag_dest_set) (EAttachmentView *view, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions); + void (*drag_source_unset) (EAttachmentView *view); + void (*drag_dest_unset) (EAttachmentView *view); }; struct _EAttachmentViewPrivate { @@ -114,6 +127,13 @@ void e_attachment_view_remove_selected (EAttachmentView *view, gboolean select_next); +gboolean e_attachment_view_button_press_event + (EAttachmentView *view, + GdkEventButton *event); +gboolean e_attachment_view_button_release_event + (EAttachmentView *view, + GdkEventButton *event); + /* Selection Management */ GtkTreePath * e_attachment_view_get_path_at_pos (EAttachmentView *view, @@ -133,7 +153,25 @@ void e_attachment_view_unselect_all (EAttachmentView *view); void e_attachment_view_sync_selection(EAttachmentView *view, EAttachmentView *target); -/* Drag and Drop Support */ +/* Drag Source Support */ +void e_attachment_view_drag_source_set + (EAttachmentView *view); +void e_attachment_view_drag_source_unset + (EAttachmentView *view); +void e_attachment_view_drag_begin (EAttachmentView *view, + GdkDragContext *context); +void e_attachment_view_drag_end (EAttachmentView *view, + GdkDragContext *context); +void e_attachment_view_drag_data_get (EAttachmentView *view, + GdkDragContext *context, + GtkSelectionData *selection, + guint info, + guint time); + +/* Drag Destination Support */ +void e_attachment_view_drag_dest_set (EAttachmentView *view); +void e_attachment_view_drag_dest_unset + (EAttachmentView *view); void e_attachment_view_drag_action (EAttachmentView *view, GdkDragAction action); gboolean e_attachment_view_drag_motion (EAttachmentView *view, @@ -141,6 +179,11 @@ gboolean e_attachment_view_drag_motion (EAttachmentView *view, gint x, gint y, guint time); +gboolean e_attachment_view_drag_drop (EAttachmentView *view, + GdkDragContext *context, + gint x, + gint y, + guint time); void e_attachment_view_drag_data_received (EAttachmentView *view, GdkDragContext *context, diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 7044aa8cde..d06e49dc30 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -135,6 +135,7 @@ attachment_update_file_info_columns (EAttachment *attachment) GFileInfo *file_info; const gchar *content_type; const gchar *display_name; + gchar *content_desc; gchar *display_size; gchar *caption; goffset size; @@ -156,6 +157,7 @@ attachment_update_file_info_columns (EAttachment *attachment) display_name = g_file_info_get_display_name (file_info); size = g_file_info_get_size (file_info); + content_desc = g_content_type_get_description (content_type); display_size = g_format_size_for_display (size); if (size > 0) @@ -167,11 +169,12 @@ attachment_update_file_info_columns (EAttachment *attachment) gtk_list_store_set ( GTK_LIST_STORE (model), &iter, E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_type, + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_desc, E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, E_ATTACHMENT_STORE_COLUMN_SIZE, size, -1); + g_free (content_desc); g_free (display_size); g_free (caption); } @@ -297,44 +300,14 @@ attachment_update_icon_column (EAttachment *attachment) } static void -attachment_update_loading_column (EAttachment *attachment) +attachment_update_progress_columns (EAttachment *attachment) { GtkTreeRowReference *reference; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; - GFileInfo *file_info; gboolean loading; - - reference = e_attachment_get_reference (attachment); - if (!gtk_tree_row_reference_valid (reference)) - return; - - /* Don't show progress until we have a GFileInfo. */ - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - return; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - loading = e_attachment_get_loading (attachment); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, - E_ATTACHMENT_STORE_COLUMN_LOADING, loading, - -1); -} - -static void -attachment_update_percent_column (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; + gboolean saving; gint percent; reference = e_attachment_get_reference (attachment); @@ -346,36 +319,15 @@ attachment_update_percent_column (EAttachment *attachment) gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); + /* Don't show progress bars until we have progress to report. */ percent = e_attachment_get_percent (attachment); + loading = e_attachment_get_loading (attachment) && (percent > 0); + saving = e_attachment_get_saving (attachment) && (percent > 0); gtk_list_store_set ( GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_LOADING, loading, E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, - -1); -} - -static void -attachment_update_saving_column (EAttachment *attachment) -{ - GtkTreeRowReference *reference; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean saving; - - reference = e_attachment_get_reference (attachment); - if (!gtk_tree_row_reference_valid (reference)) - return; - - model = gtk_tree_row_reference_get_model (reference); - path = gtk_tree_row_reference_get_path (reference); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - saving = e_attachment_get_saving (attachment); - - gtk_list_store_set ( - GTK_LIST_STORE (model), &iter, E_ATTACHMENT_STORE_COLUMN_SAVING, saving, -1); } @@ -399,7 +351,7 @@ attachment_set_file_info (EAttachment *attachment, g_object_notify (G_OBJECT (attachment), "file-info"); /* Tell the EAttachmentStore its total size changed. */ - if (reference != NULL) { + if (gtk_tree_row_reference_valid (reference)) { GtkTreeModel *model; model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "total-size"); @@ -422,7 +374,7 @@ attachment_set_loading (EAttachment *attachment, g_object_notify (G_OBJECT (attachment), "loading"); g_object_thaw_notify (G_OBJECT (attachment)); - if (reference != NULL) { + if (gtk_tree_row_reference_valid (reference)) { GtkTreeModel *model; model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "num-loading"); @@ -798,21 +750,17 @@ attachment_init (EAttachment *attachment) attachment, "notify::file-info", G_CALLBACK (attachment_update_icon_column), NULL); - g_signal_connect ( - attachment, "notify::file-info", - G_CALLBACK (attachment_update_loading_column), NULL); - g_signal_connect ( attachment, "notify::loading", G_CALLBACK (attachment_update_icon_column), NULL); g_signal_connect ( attachment, "notify::loading", - G_CALLBACK (attachment_update_loading_column), NULL); + G_CALLBACK (attachment_update_progress_columns), NULL); g_signal_connect ( attachment, "notify::percent", - G_CALLBACK (attachment_update_percent_column), NULL); + G_CALLBACK (attachment_update_progress_columns), NULL); g_signal_connect ( attachment, "notify::reference", @@ -824,15 +772,7 @@ attachment_init (EAttachment *attachment) g_signal_connect ( attachment, "notify::reference", - G_CALLBACK (attachment_update_loading_column), NULL); - - g_signal_connect ( - attachment, "notify::reference", - G_CALLBACK (attachment_update_saving_column), NULL); - - g_signal_connect ( - attachment, "notify::reference", - G_CALLBACK (attachment_update_percent_column), NULL); + G_CALLBACK (attachment_update_progress_columns), NULL); g_signal_connect ( attachment, "notify::saving", @@ -840,7 +780,7 @@ attachment_init (EAttachment *attachment) g_signal_connect ( attachment, "notify::saving", - G_CALLBACK (attachment_update_saving_column), NULL); + G_CALLBACK (attachment_update_progress_columns), NULL); g_signal_connect ( attachment, "notify::signed", @@ -1294,7 +1234,8 @@ e_attachment_list_apps (EAttachment *attachment) g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); file_info = e_attachment_get_file_info (attachment); - g_return_val_if_fail (file_info != NULL, NULL); + if (file_info == NULL) + return NULL; content_type = g_file_info_get_content_type (file_info); display_name = g_file_info_get_display_name (file_info); @@ -1316,92 +1257,14 @@ exit: return app_info_list; } -GList * -e_attachment_list_emblems (EAttachment *attachment) -{ - GCancellable *cancellable; - GList *list = NULL; - GIcon *icon; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - - cancellable = attachment->priv->cancellable; - - if (g_cancellable_is_cancelled (cancellable)) { - icon = g_themed_icon_new (EMBLEM_CANCELLED); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - } - - if (e_attachment_get_loading (attachment)) { - icon = g_themed_icon_new (EMBLEM_LOADING); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - } - - if (e_attachment_get_saving (attachment)) { - icon = g_themed_icon_new (EMBLEM_SAVING); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - } - - switch (e_attachment_get_encrypted (attachment)) { - case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK: - icon = g_themed_icon_new (EMBLEM_ENCRYPT_WEAK); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED: - icon = g_themed_icon_new (EMBLEM_ENCRYPT_UNKNOWN); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG: - icon = g_themed_icon_new (EMBLEM_ENCRYPT_STRONG); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - default: - break; - } - - switch (e_attachment_get_signed (attachment)) { - case CAMEL_CIPHER_VALIDITY_SIGN_GOOD: - icon = g_themed_icon_new (EMBLEM_SIGN_GOOD); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - case CAMEL_CIPHER_VALIDITY_SIGN_BAD: - icon = g_themed_icon_new (EMBLEM_SIGN_BAD); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN: - case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY: - icon = g_themed_icon_new (EMBLEM_SIGN_UNKNOWN); - list = g_list_append (list, g_emblem_new (icon)); - g_object_unref (icon); - break; - - default: - break; - } - - return list; -} - /************************* e_attachment_load_async() *************************/ -typedef struct _AttachmentLoadContext AttachmentLoadContext; +typedef struct _LoadContext LoadContext; -struct _AttachmentLoadContext { +struct _LoadContext { EAttachment *attachment; GSimpleAsyncResult *simple; + GInputStream *input_stream; GOutputStream *output_stream; GFileInfo *file_info; @@ -1414,21 +1277,21 @@ struct _AttachmentLoadContext { static void attachment_load_stream_read_cb (GInputStream *input_stream, GAsyncResult *result, - AttachmentLoadContext *load_context); + LoadContext *load_context); -static AttachmentLoadContext * +static LoadContext * attachment_load_context_new (EAttachment *attachment, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentLoadContext *load_context; + LoadContext *load_context; GSimpleAsyncResult *simple; simple = g_simple_async_result_new ( G_OBJECT (attachment), callback, user_data, e_attachment_load_async); - load_context = g_slice_new0 (AttachmentLoadContext); + load_context = g_slice_new0 (LoadContext); load_context->attachment = g_object_ref (attachment); load_context->simple = simple; @@ -1438,7 +1301,7 @@ attachment_load_context_new (EAttachment *attachment, } static void -attachment_load_context_free (AttachmentLoadContext *load_context) +attachment_load_context_free (LoadContext *load_context) { /* Do not free the GSimpleAsyncResult. */ g_object_unref (load_context->attachment); @@ -1452,11 +1315,33 @@ attachment_load_context_free (AttachmentLoadContext *load_context) if (load_context->file_info != NULL) g_object_unref (load_context->file_info); - g_slice_free (AttachmentLoadContext, load_context); + g_slice_free (LoadContext, load_context); +} + +static gboolean +attachment_load_check_for_error (LoadContext *load_context, + GError *error) +{ + GSimpleAsyncResult *simple; + + if (error == NULL) + return FALSE; + + /* Steal the reference. */ + simple = load_context->simple; + load_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_load_context_free (load_context); + + return TRUE; } static void -attachment_load_finish (AttachmentLoadContext *load_context) +attachment_load_finish (LoadContext *load_context) { GFileInfo *file_info; EAttachment *attachment; @@ -1529,7 +1414,7 @@ attachment_load_finish (AttachmentLoadContext *load_context) static void attachment_load_write_cb (GOutputStream *output_stream, GAsyncResult *result, - AttachmentLoadContext *load_context) + LoadContext *load_context) { EAttachment *attachment; GCancellable *cancellable; @@ -1540,21 +1425,8 @@ attachment_load_write_cb (GOutputStream *output_stream, bytes_written = g_output_stream_write_finish ( output_stream, result, &error); - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = load_context->simple; - load_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_load_context_free (load_context); - + if (attachment_load_check_for_error (load_context, error)) return; - } attachment = load_context->attachment; cancellable = attachment->priv->cancellable; @@ -1591,7 +1463,7 @@ attachment_load_write_cb (GOutputStream *output_stream, static void attachment_load_stream_read_cb (GInputStream *input_stream, GAsyncResult *result, - AttachmentLoadContext *load_context) + LoadContext *load_context) { EAttachment *attachment; GCancellable *cancellable; @@ -1602,21 +1474,8 @@ attachment_load_stream_read_cb (GInputStream *input_stream, bytes_read = g_input_stream_read_finish ( input_stream, result, &error); - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = load_context->simple; - load_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_load_context_free (load_context); - + if (attachment_load_check_for_error (load_context, error)) return; - } if (bytes_read == 0) { attachment_load_finish (load_context); @@ -1640,7 +1499,7 @@ attachment_load_stream_read_cb (GInputStream *input_stream, static void attachment_load_file_read_cb (GFile *file, GAsyncResult *result, - AttachmentLoadContext *load_context) + LoadContext *load_context) { EAttachment *attachment; GCancellable *cancellable; @@ -1648,24 +1507,12 @@ attachment_load_file_read_cb (GFile *file, GOutputStream *output_stream; GError *error = NULL; + /* Input stream might be NULL, so don't use cast macro. */ input_stream = g_file_read_finish (file, result, &error); - load_context->input_stream = G_INPUT_STREAM (input_stream); - - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = load_context->simple; - load_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_load_context_free (load_context); + load_context->input_stream = (GInputStream *) input_stream; + if (attachment_load_check_for_error (load_context, error)) return; - } /* Load the contents into a GMemoryOutputStream. */ output_stream = g_memory_output_stream_new ( @@ -1687,7 +1534,7 @@ attachment_load_file_read_cb (GFile *file, static void attachment_load_query_info_cb (GFile *file, GAsyncResult *result, - AttachmentLoadContext *load_context) + LoadContext *load_context) { EAttachment *attachment; GCancellable *cancellable; @@ -1701,21 +1548,8 @@ attachment_load_query_info_cb (GFile *file, attachment_set_file_info (attachment, file_info); load_context->file_info = file_info; - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = load_context->simple; - load_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_load_context_free (load_context); - + if (attachment_load_check_for_error (load_context, error)) return; - } load_context->total_num_bytes = g_file_info_get_size (file_info); @@ -1726,7 +1560,7 @@ attachment_load_query_info_cb (GFile *file, } static void -attachment_load_from_mime_part (AttachmentLoadContext *load_context) +attachment_load_from_mime_part (LoadContext *load_context) { GFileInfo *file_info; EAttachment *attachment; @@ -1780,8 +1614,10 @@ attachment_load_from_mime_part (AttachmentLoadContext *load_context) g_free (allocated); string = camel_mime_part_get_filename (mime_part); - if (string != NULL) - g_file_info_set_display_name (file_info, string); + if (string == NULL) + /* Translators: Default attachment filename. */ + string = _("attachment.dat"); + g_file_info_set_display_name (file_info, string); attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; string = camel_mime_part_get_description (mime_part); @@ -1815,7 +1651,7 @@ e_attachment_load_async (EAttachment *attachment, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentLoadContext *load_context; + LoadContext *load_context; GCancellable *cancellable; CamelMimePart *mime_part; GFile *file; @@ -1823,8 +1659,21 @@ e_attachment_load_async (EAttachment *attachment, g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_return_if_fail (callback != NULL); - g_return_if_fail (!e_attachment_get_loading (attachment)); - g_return_if_fail (!e_attachment_get_saving (attachment)); + if (e_attachment_get_loading (attachment)) { + g_simple_async_report_error_in_idle ( + G_OBJECT (attachment), callback, user_data, + G_IO_ERROR, G_IO_ERROR_BUSY, + _("A load operation is already in progress")); + return; + } + + if (e_attachment_get_saving (attachment)) { + g_simple_async_report_error_in_idle ( + G_OBJECT (attachment), callback, user_data, + G_IO_ERROR, G_IO_ERROR_BUSY, + _("A save operation is already in progress")); + return; + } file = e_attachment_get_file (attachment); mime_part = e_attachment_get_mime_part (attachment); @@ -1836,16 +1685,16 @@ e_attachment_load_async (EAttachment *attachment, cancellable = attachment->priv->cancellable; g_cancellable_reset (cancellable); - /* Handle the trivial case first. */ - if (mime_part != NULL) - attachment_load_from_mime_part (load_context); - - else if (file != NULL) + if (file != NULL) g_file_query_info_async ( file, ATTACHMENT_QUERY, G_FILE_QUERY_INFO_NONE,G_PRIORITY_DEFAULT, cancellable, (GAsyncReadyCallback) attachment_load_query_info_cb, load_context); + + else if (mime_part != NULL) + attachment_load_from_mime_part (load_context); + } gboolean @@ -1879,6 +1728,7 @@ e_attachment_load_handle_error (EAttachment *attachment, { GtkWidget *dialog; GFileInfo *file_info; + GtkTreeRowReference *reference; const gchar *display_name; const gchar *primary_text; GError *error = NULL; @@ -1890,6 +1740,18 @@ e_attachment_load_handle_error (EAttachment *attachment, if (e_attachment_load_finish (attachment, result, &error)) return; + /* XXX Calling EAttachmentStore functions from here violates + * the abstraction, but for now it's not hurting anything. */ + reference = e_attachment_get_reference (attachment); + if (gtk_tree_row_reference_valid (reference)) { + GtkTreeModel *model; + + model = gtk_tree_row_reference_get_model (reference); + + e_attachment_store_remove_attachment ( + E_ATTACHMENT_STORE (model), attachment); + } + /* Ignore cancellations. */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; @@ -1924,28 +1786,29 @@ e_attachment_load_handle_error (EAttachment *attachment, /************************* e_attachment_open_async() *************************/ -typedef struct _AttachmentOpenContext AttachmentOpenContext; +typedef struct _OpenContext OpenContext; -struct _AttachmentOpenContext { +struct _OpenContext { EAttachment *attachment; GSimpleAsyncResult *simple; + GAppInfo *app_info; GFile *file; }; -static AttachmentOpenContext * +static OpenContext * attachment_open_context_new (EAttachment *attachment, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentOpenContext *open_context; + OpenContext *open_context; GSimpleAsyncResult *simple; simple = g_simple_async_result_new ( G_OBJECT (attachment), callback, user_data, e_attachment_open_async); - open_context = g_slice_new0 (AttachmentOpenContext); + open_context = g_slice_new0 (OpenContext); open_context->attachment = g_object_ref (attachment); open_context->simple = simple; @@ -1953,7 +1816,7 @@ attachment_open_context_new (EAttachment *attachment, } static void -attachment_open_context_free (AttachmentOpenContext *open_context) +attachment_open_context_free (OpenContext *open_context) { /* Do not free the GSimpleAsyncResult. */ g_object_unref (open_context->attachment); @@ -1964,11 +1827,33 @@ attachment_open_context_free (AttachmentOpenContext *open_context) if (open_context->file != NULL) g_object_unref (open_context->file); - g_slice_free (AttachmentOpenContext, open_context); + g_slice_free (OpenContext, open_context); +} + +static gboolean +attachment_open_check_for_error (OpenContext *open_context, + GError *error) +{ + GSimpleAsyncResult *simple; + + if (error == NULL) + return FALSE; + + /* Steal the reference. */ + simple = open_context->simple; + open_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_open_context_free (open_context); + + return TRUE; } static void -attachment_open_file (AttachmentOpenContext *open_context) +attachment_open_file (OpenContext *open_context) { GdkAppLaunchContext *context; GSimpleAsyncResult *simple; @@ -2027,49 +1912,29 @@ exit: static void attachment_open_save_finished_cb (EAttachment *attachment, GAsyncResult *result, - AttachmentOpenContext *open_context) + OpenContext *open_context) { GError *error = NULL; - if (e_attachment_save_finish (attachment, result, &error)) - attachment_open_file (open_context); - else { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = open_context->simple; - open_context->simple = NULL; + e_attachment_save_finish (attachment, result, &error); - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); + if (attachment_open_check_for_error (open_context, error)) + return; - attachment_open_context_free (open_context); - } + attachment_open_file (open_context); } static void -attachment_open_save_temporary (AttachmentOpenContext *open_context) +attachment_open_save_temporary (OpenContext *open_context) { gchar *path; gint fd; GError *error = NULL; fd = e_file_open_tmp (&path, &error); - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = open_context->simple; - open_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - attachment_open_context_free (open_context); + if (attachment_open_check_for_error (open_context, error)) return; - } close (fd); @@ -2087,16 +1952,13 @@ e_attachment_open_async (EAttachment *attachment, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentOpenContext *open_context; + OpenContext *open_context; CamelMimePart *mime_part; GFile *file; g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_return_if_fail (callback != NULL); - g_return_if_fail (!e_attachment_get_loading (attachment)); - g_return_if_fail (!e_attachment_get_saving (attachment)); - file = e_attachment_get_file (attachment); mime_part = e_attachment_get_mime_part (attachment); g_return_if_fail (file != NULL || mime_part != NULL); @@ -2190,37 +2052,40 @@ e_attachment_open_handle_error (EAttachment *attachment, /************************* e_attachment_save_async() *************************/ -typedef struct _AttachmentSaveContext AttachmentSaveContext; +typedef struct _SaveContext SaveContext; -struct _AttachmentSaveContext { +struct _SaveContext { EAttachment *attachment; GSimpleAsyncResult *simple; + + GFile *directory; GInputStream *input_stream; GOutputStream *output_stream; goffset total_num_bytes; gssize bytes_read; gchar buffer[4096]; + gint count; }; /* Forward Declaration */ static void attachment_save_read_cb (GInputStream *input_stream, GAsyncResult *result, - AttachmentSaveContext *save_context); + SaveContext *save_context); -static AttachmentSaveContext * +static SaveContext * attachment_save_context_new (EAttachment *attachment, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentSaveContext *save_context; + SaveContext *save_context; GSimpleAsyncResult *simple; simple = g_simple_async_result_new ( G_OBJECT (attachment), callback, user_data, e_attachment_save_async); - save_context = g_slice_new0 (AttachmentSaveContext); + save_context = g_slice_new0 (SaveContext); save_context->attachment = g_object_ref (attachment); save_context->simple = simple; @@ -2230,49 +2095,98 @@ attachment_save_context_new (EAttachment *attachment, } static void -attachment_save_context_free (AttachmentSaveContext *save_context) +attachment_save_context_free (SaveContext *save_context) { /* Do not free the GSimpleAsyncResult. */ g_object_unref (save_context->attachment); + if (save_context->directory != NULL) + g_object_unref (save_context->directory); + if (save_context->input_stream != NULL) g_object_unref (save_context->input_stream); if (save_context->output_stream != NULL) g_object_unref (save_context->output_stream); - g_slice_free (AttachmentSaveContext, save_context); + g_slice_free (SaveContext, save_context); } -static void -attachment_save_file_cb (GFile *source, - GAsyncResult *result, - AttachmentSaveContext *save_context) +static gboolean +attachment_save_check_for_error (SaveContext *save_context, + GError *error) { GSimpleAsyncResult *simple; - gboolean success; - GError *error = NULL; + + if (error == NULL) + return FALSE; /* Steal the reference. */ simple = save_context->simple; save_context->simple = NULL; - success = g_file_copy_finish (source, result, &error); - g_simple_async_result_set_op_res_gboolean (simple, success); + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); - if (error != NULL) { - g_simple_async_result_set_from_error (simple, error); - g_error_free (error); + attachment_save_context_free (save_context); + + return TRUE; +} + +static GFile * +attachment_save_new_candidate (SaveContext *save_context) +{ + GFile *candidate; + GFileInfo *file_info; + EAttachment *attachment; + const gchar *display_name; + gchar *basename; + + attachment = save_context->attachment; + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + if (display_name == NULL) + /* Translators: Default attachment filename. */ + display_name = _("attachment.dat"); + + if (save_context->count == 0) + basename = g_strdup (display_name); + else { + GString *string; + const gchar *ext; + gsize length; + + string = g_string_sized_new (strlen (display_name)); + ext = g_utf8_strchr (display_name, -1, '.'); + + if (ext != NULL) + length = ext - display_name; + else + length = strlen (display_name); + + g_string_append_len (string, display_name, length); + g_string_append_printf (string, " (%d)", save_context->count); + g_string_append (string, (ext != NULL) ? ext : ""); + + basename = g_string_free (string, FALSE); } - g_simple_async_result_complete (simple); - attachment_save_context_free (save_context); + save_context->count++; + + candidate = g_file_get_child (save_context->directory, basename); + + g_free (basename); + + return candidate; } static void attachment_save_write_cb (GOutputStream *output_stream, GAsyncResult *result, - AttachmentSaveContext *save_context) + SaveContext *save_context) { EAttachment *attachment; GCancellable *cancellable; @@ -2283,21 +2197,8 @@ attachment_save_write_cb (GOutputStream *output_stream, bytes_written = g_output_stream_write_finish ( output_stream, result, &error); - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = save_context->simple; - save_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_save_context_free (save_context); - + if (attachment_save_check_for_error (save_context, error)) return; - } attachment = save_context->attachment; cancellable = attachment->priv->cancellable; @@ -2330,7 +2231,7 @@ attachment_save_write_cb (GOutputStream *output_stream, static void attachment_save_read_cb (GInputStream *input_stream, GAsyncResult *result, - AttachmentSaveContext *save_context) + SaveContext *save_context) { EAttachment *attachment; GCancellable *cancellable; @@ -2341,21 +2242,8 @@ attachment_save_read_cb (GInputStream *input_stream, bytes_read = g_input_stream_read_finish ( input_stream, result, &error); - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = save_context->simple; - save_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_save_context_free (save_context); - + if (attachment_save_check_for_error (save_context, error)) return; - } if (bytes_read == 0) { GSimpleAsyncResult *simple; @@ -2391,38 +2279,15 @@ attachment_save_read_cb (GInputStream *input_stream, } static void -attachment_save_replace_cb (GFile *destination, - GAsyncResult *result, - AttachmentSaveContext *save_context) +attachment_save_got_output_stream (SaveContext *save_context) { GCancellable *cancellable; GInputStream *input_stream; - GFileOutputStream *output_stream; CamelDataWrapper *wrapper; CamelMimePart *mime_part; CamelStream *stream; EAttachment *attachment; GByteArray *buffer; - GError *error = NULL; - - output_stream = g_file_replace_finish (destination, result, &error); - save_context->output_stream = G_OUTPUT_STREAM (output_stream); - - if (error != NULL) { - GSimpleAsyncResult *simple; - - /* Steal the reference. */ - simple = save_context->simple; - save_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_save_context_free (save_context); - - return; - } attachment = save_context->attachment; cancellable = attachment->priv->cancellable; @@ -2455,30 +2320,149 @@ attachment_save_replace_cb (GFile *destination, save_context); } +static void +attachment_save_create_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GFileOutputStream *output_stream; + GError *error = NULL; + + /* Output stream might be NULL, so don't use cast macro. */ + output_stream = g_file_create_finish (destination, result, &error); + save_context->output_stream = (GOutputStream *) output_stream; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { + destination = attachment_save_new_candidate (save_context); + + g_file_create_async ( + destination, G_FILE_CREATE_NONE, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_create_cb, + save_context); + + g_object_unref (destination); + g_error_free (error); + return; + } + + if (attachment_save_check_for_error (save_context, error)) + return; + + attachment_save_got_output_stream (save_context); +} + +static void +attachment_save_replace_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + GFileOutputStream *output_stream; + GError *error = NULL; + + /* Output stream might be NULL, so don't use cast macro. */ + output_stream = g_file_replace_finish (destination, result, &error); + save_context->output_stream = (GOutputStream *) output_stream; + + if (attachment_save_check_for_error (save_context, error)) + return; + + attachment_save_got_output_stream (save_context); +} + +static void +attachment_save_query_info_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GFileInfo *file_info; + GFileType file_type; + GError *error = NULL; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + + file_info = g_file_query_info_finish (destination, result, &error); + + /* G_IO_ERROR_NOT_FOUND just means we're creating a new file. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { + g_error_free (error); + goto replace; + } + + if (attachment_save_check_for_error (save_context, error)) + return; + + file_type = g_file_info_get_file_type (file_info); + g_object_unref (file_info); + + if (file_type == G_FILE_TYPE_DIRECTORY) { + save_context->directory = g_object_ref (destination); + destination = attachment_save_new_candidate (save_context); + + g_file_create_async ( + destination, G_FILE_CREATE_NONE, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_create_cb, + save_context); + + g_object_unref (destination); + + return; + } + +replace: + g_file_replace_async ( + destination, NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_replace_cb, + save_context); +} + void e_attachment_save_async (EAttachment *attachment, GFile *destination, GAsyncReadyCallback callback, gpointer user_data) { - AttachmentSaveContext *save_context; + SaveContext *save_context; GCancellable *cancellable; - CamelMimePart *mime_part; - GFile *source; g_return_if_fail (E_IS_ATTACHMENT (attachment)); g_return_if_fail (G_IS_FILE (destination)); g_return_if_fail (callback != NULL); - g_return_if_fail (!e_attachment_get_loading (attachment)); - g_return_if_fail (!e_attachment_get_saving (attachment)); + if (e_attachment_get_loading (attachment)) { + g_simple_async_report_error_in_idle ( + G_OBJECT (attachment), callback, user_data, + G_IO_ERROR, G_IO_ERROR_BUSY, + _("A load operation is already in progress")); + return; + } - /* The attachment content is either a GFile (on disk) or a - * CamelMimePart (in memory). Each is saved differently. */ + if (e_attachment_get_saving (attachment)) { + g_simple_async_report_error_in_idle ( + G_OBJECT (attachment), callback, user_data, + G_IO_ERROR, G_IO_ERROR_BUSY, + _("A save operation is already in progress")); + return; + } - source = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (source != NULL || mime_part != NULL); + if (e_attachment_get_mime_part (attachment) == NULL) { + g_simple_async_report_error_in_idle ( + G_OBJECT (attachment), callback, user_data, + G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Attachment contents not loaded")); + return; + } save_context = attachment_save_context_new ( attachment, callback, user_data); @@ -2486,34 +2470,12 @@ e_attachment_save_async (EAttachment *attachment, cancellable = attachment->priv->cancellable; g_cancellable_reset (cancellable); - /* GFile is the easier, but probably less common case. The - * attachment already references an on-disk file, so we can - * just use GIO to copy it asynchronously. - * - * We use G_FILE_COPY_OVERWRITE because the user should have - * already confirmed the overwrite through the save dialog. */ - if (G_IS_FILE (source)) - g_file_copy_async ( - source, destination, - G_FILE_COPY_OVERWRITE, - G_PRIORITY_DEFAULT, cancellable, - (GFileProgressCallback) attachment_progress_cb, - attachment, - (GAsyncReadyCallback) attachment_save_file_cb, - save_context); - - /* CamelMimePart can only be decoded to a file synchronously, so - * we do this in two stages. Stage one asynchronously opens the - * destination file for writing. Stage two spawns a thread that - * decodes the MIME part to the destination file. This stage is - * not cancellable, unfortunately. */ - else if (CAMEL_IS_MIME_PART (mime_part)) - g_file_replace_async ( - destination, NULL, FALSE, - G_FILE_CREATE_REPLACE_DESTINATION, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_replace_cb, - save_context); + /* First we need to know if destination is a directory. */ + g_file_query_info_async ( + destination, G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, + cancellable, (GAsyncReadyCallback) + attachment_save_query_info_cb, save_context); } gboolean diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 1ca5b3121b..8a13da2909 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -101,7 +101,6 @@ const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); gboolean e_attachment_is_image (EAttachment *attachment); gboolean e_attachment_is_rfc822 (EAttachment *attachment); GList * e_attachment_list_apps (EAttachment *attachment); -GList * e_attachment_list_emblems (EAttachment *attachment); /* Asynchronous Operations */ void e_attachment_load_async (EAttachment *attachment, -- cgit v1.2.3 From 04cc4a2cb1bf87417f82d1094ddde611019c0ab8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 30 Mar 2009 22:26:35 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37486 --- widgets/misc/e-attachment-store.c | 174 +++++++++++++++++++++++++++++++++++--- widgets/misc/e-attachment-store.h | 14 ++- widgets/misc/e-attachment-view.c | 96 +++++++++++++++++++-- widgets/misc/e-attachment.c | 30 +++++-- 4 files changed, 287 insertions(+), 27 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 0187d2a8c8..1eb429b41e 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -672,7 +672,7 @@ exit: gtk_widget_destroy (dialog); } -void +GFile * e_attachment_store_run_save_dialog (EAttachmentStore *store, GList *attachment_list, GtkWindow *parent) @@ -685,13 +685,12 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, gint response; guint length; - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (GTK_IS_WINDOW (parent)); + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); length = g_list_length (attachment_list); if (length == 0) - return; + return NULL; title = ngettext ("Save Attachment", "Save Attachments", length); @@ -728,21 +727,172 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, response = e_attachment_store_run_file_chooser_dialog (store, dialog); - if (response != GTK_RESPONSE_OK) - goto exit; + if (response == GTK_RESPONSE_OK) + destination = gtk_file_chooser_get_file (file_chooser); + else + destination = NULL; + + gtk_widget_destroy (dialog); + + return destination; +} + +/******************* e_attachment_store_save_list_async() ********************/ + +typedef struct _SaveContext SaveContext; + +struct _SaveContext { + GSimpleAsyncResult *simple; + GList *attachment_list; + GError *error; +}; + +static SaveContext * +attachment_store_save_context_new (EAttachmentStore *store, + GList *attachment_list, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, user_data, + e_attachment_store_save_list_async); + + save_context = g_slice_new0 (SaveContext); + save_context->simple = simple; + save_context->attachment_list = g_list_copy (attachment_list); + + g_list_foreach ( + save_context->attachment_list, + (GFunc) g_object_ref, NULL); + + return save_context; +} + +static void +attachment_store_save_context_free (SaveContext *save_context) +{ + /* Do not free the GSimpleAsyncResult. */ + + /* The attachment list should be empty now. */ + g_warn_if_fail (save_context->attachment_list != NULL); + + /* So should the error. */ + g_warn_if_fail (save_context->error != NULL); + + g_slice_free (SaveContext, save_context); +} + +static void +attachment_store_save_list_finished_cb (EAttachment *attachment, + GAsyncResult *result, + SaveContext *save_context) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + e_attachment_save_finish (attachment, result, &error); + + /* Remove the attachment from the list. */ + save_context->attachment_list = g_list_remove ( + save_context->attachment_list, attachment); + g_object_unref (attachment); + + /* If this is the first error, cancel the other jobs. */ + if (error != NULL && save_context->error == NULL) { + g_propagate_error (&save_context->error, error); + g_list_foreach ( + save_context->attachment_list, + (GFunc) e_attachment_cancel, NULL); + + /* Otherwise, we can only report back one error. So if this is + * something other than cancellation, dump it to the terminal. */ + } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s", error->message); + + if (error != NULL) + g_error_free (error); + + /* If there's still jobs running, let them finish. */ + if (save_context->attachment_list != NULL) + return; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* Steal the error, too. */ + error = save_context->error; + save_context->error = NULL; + + if (error == NULL) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + g_simple_async_result_complete (simple); - destination = gtk_file_chooser_get_file (file_chooser); + attachment_store_save_context_free (save_context); +} + +void +e_attachment_store_save_list_async (EAttachmentStore *store, + GList *attachment_list, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (callback != NULL); + + /* Passing an empty list is silly, but we'll handle it. */ + if (attachment_list == NULL) { + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, user_data, + e_attachment_store_save_list_async); + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete_in_idle (simple); + return; + } + + save_context = attachment_store_save_context_new ( + store, attachment_list, callback, user_data); while (attachment_list != NULL) { e_attachment_save_async ( - attachment_list->data, + E_ATTACHMENT (attachment_list->data), destination, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); + attachment_store_save_list_finished_cb, + save_context); attachment_list = g_list_next (attachment_list); } +} - g_object_unref (destination); +gboolean +e_attachment_store_save_list_finish (EAttachmentStore *store, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gboolean success; -exit: - gtk_widget_destroy (dialog); + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, G_OBJECT (store), + e_attachment_store_save_list_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + success = g_simple_async_result_get_op_res_gboolean (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + return success; } diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index 88b2823313..c672cb3c34 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -101,11 +101,23 @@ gint e_attachment_store_run_file_chooser_dialog void e_attachment_store_run_load_dialog (EAttachmentStore *store, GtkWindow *parent); -void e_attachment_store_run_save_dialog +GFile * e_attachment_store_run_save_dialog (EAttachmentStore *store, GList *attachment_list, GtkWindow *parent); +/* Asynchronous Operations */ +void e_attachment_store_save_list_async + (EAttachmentStore *store, + GList *attachment_list, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean e_attachment_store_save_list_finish + (EAttachmentStore *store, + GAsyncResult *result, + GError **error); + G_END_DECLS #endif /* E_ATTACHMENT_STORE_H */ diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index e9e546e449..6d6079df21 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -218,12 +218,53 @@ action_remove_cb (GtkAction *action, e_attachment_view_remove_selected (view, FALSE); } +static void +action_save_all_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachmentStore *store; + GList *selected, *iter; + GFile *destination; + gpointer parent; + + store = e_attachment_view_get_store (view); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + /* XXX We lose the previous selection. */ + e_attachment_view_select_all (view); + selected = e_attachment_view_get_selected_attachments (view); + e_attachment_view_unselect_all (view); + + destination = e_attachment_store_run_save_dialog ( + store, selected, parent); + + if (destination == NULL) + goto exit; + + for (iter = selected; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + + e_attachment_save_async ( + attachment, destination, (GAsyncReadyCallback) + e_attachment_save_handle_error, parent); + } + + g_object_unref (destination); + +exit: + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + static void action_save_as_cb (GtkAction *action, EAttachmentView *view) { EAttachmentStore *store; - GList *selected; + GList *selected, *iter; + GFile *destination; gpointer parent; store = e_attachment_view_get_store (view); @@ -232,7 +273,24 @@ action_save_as_cb (GtkAction *action, parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; selected = e_attachment_view_get_selected_attachments (view); - e_attachment_store_run_save_dialog (store, selected, parent); + + destination = e_attachment_store_run_save_dialog ( + store, selected, parent); + + if (destination == NULL) + goto exit; + + for (iter = selected; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + + e_attachment_save_async ( + attachment, destination, (GAsyncReadyCallback) + e_attachment_save_handle_error, parent); + } + + g_object_unref (destination); + +exit: g_list_foreach (selected, (GFunc) g_object_unref, NULL); g_list_free (selected); } @@ -274,6 +332,13 @@ static GtkActionEntry standard_entries[] = { NULL, /* XXX Add a tooltip! */ G_CALLBACK (action_drag_move_cb) }, + { "save-all", + GTK_STOCK_SAVE_AS, + N_("S_ave All"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_save_all_cb) }, + { "save-as", GTK_STOCK_SAVE_AS, NULL, @@ -281,6 +346,15 @@ static GtkActionEntry standard_entries[] = { NULL, /* XXX Add a tooltip! */ G_CALLBACK (action_save_as_cb) }, + /* Alternate "save-all" label, for when + * the attachment store has one row. */ + { "save-one", + GTK_STOCK_SAVE_AS, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_save_all_cb) }, + { "set-background", NULL, N_("Set as _Background"), @@ -807,10 +881,14 @@ e_attachment_view_button_press_event (EAttachmentView *view, GdkEventButton *event) { GtkTreePath *path; + gboolean editable; + gboolean item_clicked; g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); g_return_val_if_fail (event != NULL, FALSE); + editable = e_attachment_view_get_editable (view); + /* If the user clicked on a selected item, retain the current * selection. If the user clicked on an unselected item, select * the clicked item only. If the user did not click on an item, @@ -822,8 +900,11 @@ e_attachment_view_button_press_event (EAttachmentView *view, e_attachment_view_select_path (view, path); } gtk_tree_path_free (path); - } else + item_clicked = TRUE; + } else { e_attachment_view_unselect_all (view); + item_clicked = FALSE; + } /* Cancel drag and drop if there are no selected items, * or if any of the selected items are loading or saving. */ @@ -844,8 +925,13 @@ e_attachment_view_button_press_event (EAttachmentView *view, } if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { - e_attachment_view_show_popup_menu (view, event); - return TRUE; + /* Non-editable attachment views should only show a + * popup menu when right-clicking on an attachment, + * but editable views can show the menu any time. */ + if (item_clicked || editable) { + e_attachment_view_show_popup_menu (view, event); + return TRUE; + } } return FALSE; diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index d06e49dc30..52a3d928f6 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1189,6 +1189,8 @@ e_attachment_is_image (EAttachment *attachment) { GFileInfo *file_info; const gchar *content_type; + gchar *mime_type; + gboolean is_image; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); @@ -1200,7 +1202,11 @@ e_attachment_is_image (EAttachment *attachment) if (content_type == NULL) return FALSE; - return g_content_type_is_a (content_type, "image"); + mime_type = g_content_type_get_mime_type (content_type); + is_image = (g_ascii_strncasecmp (mime_type, "image/", 6) == 0); + g_free (mime_type); + + return is_image; } gboolean @@ -1208,6 +1214,8 @@ e_attachment_is_rfc822 (EAttachment *attachment) { GFileInfo *file_info; const gchar *content_type; + gchar *mime_type; + gboolean is_rfc822; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); @@ -1219,7 +1227,11 @@ e_attachment_is_rfc822 (EAttachment *attachment) if (content_type == NULL) return FALSE; - return g_content_type_equals (content_type, "message/rfc822"); + mime_type = g_content_type_get_mime_type (content_type); + is_rfc822 = (g_ascii_strcasecmp (mime_type, "message/rfc822") == 0); + g_free (mime_type); + + return is_rfc822; } GList * @@ -1327,7 +1339,7 @@ attachment_load_check_for_error (LoadContext *load_context, if (error == NULL) return FALSE; - /* Steal the reference. */ + /* Steal the result. */ simple = load_context->simple; load_context->simple = NULL; @@ -1359,7 +1371,7 @@ attachment_load_finish (LoadContext *load_context) gpointer data; gsize size; - /* Steal the reference. */ + /* Steal the result. */ simple = load_context->simple; load_context->simple = NULL; @@ -1633,7 +1645,7 @@ attachment_load_from_mime_part (LoadContext *load_context) attachment_set_file_info (attachment, file_info); - /* Steal the reference. */ + /* Steal the result. */ simple = load_context->simple; load_context->simple = NULL; @@ -1839,7 +1851,7 @@ attachment_open_check_for_error (OpenContext *open_context, if (error == NULL) return FALSE; - /* Steal the reference. */ + /* Steal the result. */ simple = open_context->simple; open_context->simple = NULL; @@ -1861,7 +1873,7 @@ attachment_open_file (OpenContext *open_context) gboolean success; GError *error = NULL; - /* Steal the reference. */ + /* Steal the result. */ simple = open_context->simple; open_context->simple = NULL; @@ -2121,7 +2133,7 @@ attachment_save_check_for_error (SaveContext *save_context, if (error == NULL) return FALSE; - /* Steal the reference. */ + /* Steal the result. */ simple = save_context->simple; save_context->simple = NULL; @@ -2248,7 +2260,7 @@ attachment_save_read_cb (GInputStream *input_stream, if (bytes_read == 0) { GSimpleAsyncResult *simple; - /* Steal the reference. */ + /* Steal the result. */ simple = save_context->simple; save_context->simple = NULL; -- cgit v1.2.3 From 0485fb58c5beeb04f0b3d833e6b73a2d2ec1acc7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 31 Mar 2009 21:48:38 +0000 Subject: Extend EAttachmentView by subclassing EAttachmentHandler. So far it only supports extending the attachment pop-up menu, but I also plan to support extending drag and drop types. Might even end up replacing EMFormatHook. Two subclasses created so far: EAttachmentHandlerImage handles images (built-in) EAttachmentHandlerMail handles emails (defined in mail module) svn path=/branches/kill-bonobo/; revision=37487 --- widgets/misc/Makefile.am | 4 + widgets/misc/e-attachment-bar.c | 1796 ----------------------------- widgets/misc/e-attachment-bar.h | 141 --- widgets/misc/e-attachment-handler-image.c | 285 +++++ widgets/misc/e-attachment-handler-image.h | 65 ++ widgets/misc/e-attachment-handler.c | 157 +++ widgets/misc/e-attachment-handler.h | 67 ++ widgets/misc/e-attachment-icon-view.c | 5 +- widgets/misc/e-attachment-store.c | 5 +- widgets/misc/e-attachment-tree-view.c | 5 +- widgets/misc/e-attachment-view.c | 279 +++-- widgets/misc/e-attachment-view.h | 10 + widgets/misc/e-attachment.c | 90 +- widgets/misc/e-attachment.h | 3 +- 14 files changed, 796 insertions(+), 2116 deletions(-) delete mode 100644 widgets/misc/e-attachment-bar.c delete mode 100644 widgets/misc/e-attachment-bar.h create mode 100644 widgets/misc/e-attachment-handler-image.c create mode 100644 widgets/misc/e-attachment-handler-image.h create mode 100644 widgets/misc/e-attachment-handler.c create mode 100644 widgets/misc/e-attachment-handler.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index f6fc7ed10a..ad2f445eea 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -41,6 +41,8 @@ widgetsinclude_HEADERS = \ e-alert-activity.h \ e-attachment.h \ e-attachment-dialog.h \ + e-attachment-handler.h \ + e-attachment-handler-image.h \ e-attachment-icon-view.h \ e-attachment-paned.h \ e-attachment-store.h \ @@ -103,6 +105,8 @@ libemiscwidgets_la_SOURCES = \ e-alert-activity.c \ e-attachment.c \ e-attachment-dialog.c \ + e-attachment-handler.c \ + e-attachment-handler-image.c \ e-attachment-icon-view.c \ e-attachment-paned.c \ e-attachment-store.c \ diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c deleted file mode 100644 index aebc6bb423..0000000000 --- a/widgets/misc/e-attachment-bar.c +++ /dev/null @@ -1,1796 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * Jeffrey Stedfast - * Srinivasa Ragavan - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H -#include -#endif - -#include "e-attachment.h" -#include "e-attachment-bar.h" -#include "e-mime-part-utils.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "e-util/e-binding.h" -#include "e-util/e-error.h" -#include "e-util/e-gui-utils.h" -#include "e-util/e-icon-factory.h" -#include "e-util/e-mktemp.h" -#include "e-util/e-util.h" -#include "e-util/gconf-bridge.h" - -#define ICON_WIDTH 64 -#define ICON_SEPARATORS " /-_" -#define ICON_SPACING 2 -#define ICON_ROW_SPACING ICON_SPACING -#define ICON_COL_SPACING ICON_SPACING -#define ICON_BORDER 2 -#define ICON_TEXT_SPACING 2 - -#define E_ATTACHMENT_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarPrivate)) - -struct _EAttachmentBarPrivate { - gboolean batch_unref; - GPtrArray *attachments; - char *path; - - GtkUIManager *ui_manager; - GtkActionGroup *standard_actions; - GtkActionGroup *editable_actions; - GtkActionGroup *open_actions; - guint merge_id; - - guint editable : 1; -}; - -enum { - PROP_0, - PROP_EDITABLE, - PROP_UI_MANAGER -}; - -enum { - CHANGED, - UPDATE_ACTIONS, - LAST_SIGNAL -}; - -static gpointer parent_class; -static guint signals[LAST_SIGNAL]; - -static const gchar *ui = -"" -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -""; - -static void -action_properties_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ - GnomeIconList *icon_list; - GPtrArray *array; - GList *selection; - gpointer parent; - - array = attachment_bar->priv->attachments; - - icon_list = GNOME_ICON_LIST (attachment_bar); - selection = gnome_icon_list_get_selection (icon_list); - g_return_if_fail (selection != NULL); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (icon_list)); - parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - - while (selection != NULL) { - gint index = GPOINTER_TO_INT (selection->data); - EAttachment *attachment; - - selection = g_list_next (selection); - - if (index >= array->len) - continue; - - attachment = array->pdata[index]; - e_attachment_edit (attachment, parent); - } -} - -static void -action_remove_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ - GnomeIconList *icon_list; - GPtrArray *array; - GList *selection; - GList *trash = NULL; - - array = attachment_bar->priv->attachments; - - icon_list = GNOME_ICON_LIST (attachment_bar); - selection = gnome_icon_list_get_selection (icon_list); - g_return_if_fail (selection != NULL); - - while (selection != NULL) { - gint index = GPOINTER_TO_INT (selection->data); - - selection = g_list_next (selection); - - if (index >= array->len) - continue; - - /* We can't unref the attachment here because that may - * change the selection and invalidate the list we are - * iterating over. So move it to a trash list instead. */ - trash = g_list_prepend (trash, array->pdata[index]); - array->pdata[index] = NULL; - } - - /* Compress the attachment array. */ - while (g_ptr_array_remove (array, NULL)); - - /* Take out the trash. */ - g_list_foreach (trash, (GFunc) g_object_unref, NULL); - g_list_free (trash); - - e_attachment_bar_refresh (attachment_bar); - - g_signal_emit (attachment_bar, signals[CHANGED], 0); -} - -static void -action_save_as_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ -} - -static void -action_set_background_cb (GtkAction *action, - EAttachmentBar *attachment_bar) -{ - GnomeIconList *icon_list; - CamelContentType *content_type; - CamelMimePart *mime_part; - EAttachment *attachment; - GPtrArray *array; - GList *selection; - gchar *basename; - gchar *filename; - gchar *dirname; - GFile *file; - gint index; - GError *error = NULL; - - icon_list = GNOME_ICON_LIST (attachment_bar); - selection = gnome_icon_list_get_selection (icon_list); - g_return_if_fail (selection != NULL); - - array = attachment_bar->priv->attachments; - index = GPOINTER_TO_INT (selection->data); - attachment = E_ATTACHMENT (array->pdata[index]); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - - content_type = camel_mime_part_get_content_type (mime_part); - basename = g_strdup (camel_mime_part_get_filename (mime_part)); - - if (basename == NULL || basename == '\0') { - g_free (basename); - basename = g_strdup_printf ( - _("untitled_image.%s"), - content_type->subtype); - } - - dirname = g_build_filename ( - g_get_home_dir (), ".gnome2", "wallpapers", NULL); - - index = 0; - filename = g_build_filename (dirname, basename, NULL); - - while (g_file_test (filename, G_FILE_TEST_EXISTS)) { - gchar *temp; - gchar *ext; - - ext = strrchr (filename, '.'); - if (ext != NULL) - *ext++ = '\0'; - - if (ext == NULL) - temp = g_strdup_printf ( - "%s (%d)", basename, index++); - else - temp = g_strdup_printf ( - "%s (%d).%s", basename, index++, ext); - - g_free (basename); - g_free (filename); - basename = temp; - - filename = g_build_filename (dirname, basename, NULL); - } - - g_free (basename); - g_free (dirname); - - file = g_file_new_for_path (filename); - - if (e_mime_part_utils_save_to_file (mime_part, file, &error)) { - const gchar *background_filename; - const gchar *background_options; - - background_filename = - e_attachment_bar_get_background_filename ( - attachment_bar); - background_options = - e_attachment_bar_get_background_options ( - attachment_bar); - - if (g_strcmp0 (background_filename, filename) == 0) - e_attachment_bar_set_background_filename ( - attachment_bar, NULL); - - e_attachment_bar_set_background_filename ( - attachment_bar, filename); - - if (g_strcmp0 (background_options, "none") == 0) - e_attachment_bar_set_background_options ( - attachment_bar, "wallpaper"); - } - - g_object_unref (file); - g_free (filename); - - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } -} - -static void -attachment_bar_show_popup_menu (EAttachmentBar *attachment_bar, - GdkEventButton *event) -{ - GtkUIManager *ui_manager; - GtkWidget *menu; - - ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - menu = gtk_ui_manager_get_widget (ui_manager, "/attachment-popup"); - g_return_if_fail (GTK_IS_MENU (menu)); - - e_attachment_bar_update_actions (attachment_bar); - - if (event != NULL) - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button, event->time); - else - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, - 0, gtk_get_current_event_time ()); -} - -/* Attachment handling functions. */ - -static void -attachment_destroy (EAttachmentBar *bar, - EAttachment *attachment) -{ - if (bar->priv->batch_unref) - return; - - if (g_ptr_array_remove (bar->priv->attachments, attachment)) { - e_attachment_bar_refresh (bar); - g_signal_emit (bar, signals[CHANGED], 0); - } -} - -/* get_system_thumbnail: - * If filled store_uri, then creating thumbnail for it, otherwise, if is_available_local, - * and attachment is not an application, then save to temp and create a thumbnail for the body. - * Otherwise returns NULL (or if something goes wrong/library not available). - */ -static GdkPixbuf * -get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) -{ - GdkPixbuf *pixbuf = NULL; -#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H - CamelMimePart *mime_part; - struct stat file_stat; - char *file_uri = NULL; - gboolean is_tmp = FALSE; - - if (!attachment || !attachment->is_available_local) - return NULL; - - mime_part = e_attachment_get_mime_part (attachment); - - if (attachment->store_uri && g_str_has_prefix (attachment->store_uri, "file://")) - file_uri = attachment->store_uri; - else if (mime_part != NULL) { - /* save part to the temp directory */ - char *tmp_file; - - is_tmp = TRUE; - - tmp_file = e_mktemp ("tmp-XXXXXX"); - if (tmp_file) { - CamelStream *stream; - char *mfilename = NULL; - const char * filename; - - filename = camel_mime_part_get_filename (mime_part); - if (filename == NULL) - filename = "unknown"; - else { - char *utf8_mfilename; - - utf8_mfilename = g_strdup (filename); - e_filename_make_safe (utf8_mfilename); - mfilename = g_filename_from_utf8 ((const char *) utf8_mfilename, -1, NULL, NULL, NULL); - g_free (utf8_mfilename); - - filename = (const char *) mfilename; - } - - file_uri = g_strjoin (NULL, "file://", tmp_file, "-", filename, NULL); - - stream = camel_stream_fs_new_with_name (file_uri + 7, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (stream) { - CamelDataWrapper *content; - - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - - if (camel_data_wrapper_decode_to_stream (content, stream) == -1 - || camel_stream_flush (stream) == -1) { - g_free (file_uri); - file_uri = NULL; - } - - camel_object_unref (stream); - } else { - g_free (file_uri); - file_uri = NULL; - } - - g_free (mfilename); - g_free (tmp_file); - } - } - - if (!file_uri || !g_str_has_prefix (file_uri, "file://")) { - if (is_tmp) - g_free (file_uri); - - return NULL; - } - - if (stat (file_uri + 7, &file_stat) != -1 && S_ISREG (file_stat.st_mode)) { - GnomeThumbnailFactory *th_factory; - char *th_file; - - th_factory = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL); - th_file = gnome_thumbnail_factory_lookup (th_factory, file_uri, file_stat.st_mtime); - - if (th_file) { - pixbuf = gdk_pixbuf_new_from_file (th_file, NULL); - g_free (th_file); - } else if (content_type) { - char *mime = camel_content_type_simple (content_type); - - if (gnome_thumbnail_factory_can_thumbnail (th_factory, file_uri, mime, file_stat.st_mtime)) { - pixbuf = gnome_thumbnail_factory_generate_thumbnail (th_factory, file_uri, mime); - - if (pixbuf && !is_tmp) - gnome_thumbnail_factory_save_thumbnail (th_factory, pixbuf, file_uri, file_stat.st_mtime); - } - - g_free (mime); - } - - g_object_unref (th_factory); - } - - if (is_tmp) { - /* clear the temp */ - g_remove (file_uri + 7); - g_free (file_uri); - } -#endif - - return pixbuf; -} - -static GdkPixbuf * -scale_pixbuf (GdkPixbuf *pixbuf) -{ - int ratio, width, height; - - if (!pixbuf) - return NULL; - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - if (width >= height) { - if (width > 48) { - ratio = width / 48; - width = 48; - height = height / ratio; - if (height == 0) - height = 1; - } - } else { - if (height > 48) { - ratio = height / 48; - height = 48; - width = width / ratio; - if (width == 0) - width = 1; - } - } - - return e_icon_factory_pixbuf_scale (pixbuf, width, height); -} - -/* Icon list contents handling. */ - -static void -calculate_height_width (EAttachmentBar *bar, - gint *new_width, - gint *new_height) -{ - int width, height, icon_width; - PangoFontMetrics *metrics; - PangoContext *context; - - context = gtk_widget_get_pango_context (GTK_WIDGET (bar)); - metrics = pango_context_get_metrics ( - context, GTK_WIDGET (bar)->style->font_desc, - pango_context_get_language (context)); - width = PANGO_PIXELS ( - pango_font_metrics_get_approximate_char_width (metrics)) * 15; - /* This should be *2, but the icon list creates too much space above ... */ - height = PANGO_PIXELS ( - pango_font_metrics_get_ascent (metrics) + - pango_font_metrics_get_descent (metrics)) * 3; - pango_font_metrics_unref (metrics); - icon_width = ICON_WIDTH + ICON_SPACING + ICON_BORDER + ICON_TEXT_SPACING; - - if (new_width) - *new_width = MAX (icon_width, width); - - if (new_height) - *new_height = ICON_WIDTH + ICON_SPACING + - ICON_BORDER + ICON_TEXT_SPACING + height; -} - -void -e_attachment_bar_create_attachment_cache (EAttachment *attachment) -{ - CamelContentType *content_type; - CamelMimePart *mime_part; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part == NULL) - return; - - content_type = camel_mime_part_get_content_type (mime_part); - - if (camel_content_type_is(content_type, "image", "*")) { - CamelDataWrapper *wrapper; - CamelStreamMem *mstream; - GdkPixbufLoader *loader; - gboolean error = TRUE; - GdkPixbuf *pixbuf; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - mstream = (CamelStreamMem *) camel_stream_mem_new (); - - camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); - - /* Stream image into pixbuf loader */ - loader = gdk_pixbuf_loader_new (); - error = !gdk_pixbuf_loader_write (loader, mstream->buffer->data, mstream->buffer->len, NULL); - gdk_pixbuf_loader_close (loader, NULL); - - if (!error) { - /* The loader owns the reference. */ - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - - /* This returns a new GdkPixbuf. */ - pixbuf = scale_pixbuf (pixbuf); - e_attachment_set_thumbnail (attachment, pixbuf); - g_object_unref (pixbuf); - } else { - e_attachment_set_thumbnail (attachment, NULL); - g_warning ("GdkPixbufLoader Error"); - } - - /* Destroy everything */ - g_object_unref (loader); - camel_object_unref (mstream); - } -} - -static void -update_remote_file (EAttachment *attachment, EAttachmentBar *bar) -{ - GnomeIconList *icon_list; - GnomeIconTextItem *item; - const gchar *filename; - char *msg, *base; - - if (attachment->percentage == -1) { - e_attachment_bar_refresh (bar); - return; - } - - filename = e_attachment_get_filename (attachment); - base = g_path_get_basename (filename); - msg = g_strdup_printf ("%s (%d%%)", base, attachment->percentage); - g_free (base); - - icon_list = GNOME_ICON_LIST (bar); - - gnome_icon_list_freeze (icon_list); - - item = gnome_icon_list_get_icon_text_item ( - icon_list, attachment->index); - if (!item->is_text_allocated) - g_free (item->text); - - gnome_icon_text_item_configure ( - item, item->x, item->y, item->width, - item->fontname, msg, item->is_editable, TRUE); - - gnome_icon_list_thaw (icon_list); -} - -void -e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width) -{ - int per_col, rows, height, width; - - calculate_height_width(bar, &width, &height); - per_col = bar_width / width; - per_col = (per_col ? per_col : 1); - rows = (bar->priv->attachments->len + per_col - 1) / per_col; - gtk_widget_set_size_request ((GtkWidget *)bar, bar_width, rows * height); -} - -/** - * e_attachment_bar_get_selected: - * @bar: an #EAttachmentBar object - * - * Returns a newly allocated #GSList of ref'd #EAttachment objects - * representing the selected items in the #EAttachmentBar Icon List. - **/ -GSList * -e_attachment_bar_get_selected (EAttachmentBar *bar) -{ - EAttachmentBarPrivate *priv; - GSList *attachments = NULL; - EAttachment *attachment; - GList *items; - int id; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; - - items = gnome_icon_list_get_selection ((GnomeIconList *) bar); - - while (items != NULL) { - if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { - attachment = priv->attachments->pdata[id]; - attachments = g_slist_prepend (attachments, attachment); - g_object_ref (attachment); - } - - items = items->next; - } - - attachments = g_slist_reverse (attachments); - - return attachments; -} - -/* FIXME: Cleanup this, since there is a api to get selected attachments */ -/** - * e_attachment_bar_get_attachment: - * @bar: an #EAttachmentBar object - * @id: Index of the desired attachment or -1 to request all selected attachments - * - * Returns a newly allocated #GSList of ref'd #EAttachment objects - * representing the requested item(s) in the #EAttachmentBar Icon - * List. - **/ -GSList * -e_attachment_bar_get_attachment (EAttachmentBar *bar, int id) -{ - EAttachmentBarPrivate *priv; - EAttachment *attachment; - GSList *attachments; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; - - if (id == -1 || id > priv->attachments->len) - return e_attachment_bar_get_selected (bar); - - attachment = priv->attachments->pdata[id]; - attachments = g_slist_prepend (NULL, attachment); - g_object_ref (attachment); - - return attachments; -} - - -/** - * e_attachment_bar_get_all_attachments: - * @bar: an #EAttachmentBar object - * - * Returns a newly allocated #GSList of ref'd #EAttachment objects. - **/ -GSList * -e_attachment_bar_get_all_attachments (EAttachmentBar *bar) -{ - EAttachmentBarPrivate *priv; - GSList *attachments = NULL; - EAttachment *attachment; - int i; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; - - for (i = priv->attachments->len - 1; i >= 0; i--) { - attachment = priv->attachments->pdata[i]; - if (attachment->is_available_local) { - attachments = g_slist_prepend (attachments, attachment); - g_object_ref (attachment); - } - } - - return attachments; -} - -/* Just the GSList has to be freed by the caller */ -GSList * -e_attachment_bar_get_parts (EAttachmentBar *bar) -{ - EAttachmentBarPrivate *priv; - EAttachment *attachment; - GSList *parts = NULL; - int i; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); - - priv = bar->priv; - - for (i = 0; i < priv->attachments->len; i++) { - CamelMimePart *mime_part; - - attachment = priv->attachments->pdata[i]; - mime_part = e_attachment_get_mime_part (attachment); - - if (attachment->is_available_local) - parts = g_slist_prepend (parts, mime_part); - } - - return parts; -} - -static char * -temp_save_part (EAttachment *attachment, gboolean readonly) -{ - CamelMimePart *mime_part; - const char *filename; - char *tmpdir, *path, *mfilename = NULL, *utf8_mfilename = NULL; - CamelStream *stream; - CamelDataWrapper *wrapper; - - if (!(tmpdir = e_mkdtemp ("evolution-tmp-XXXXXX"))) - return NULL; - - mime_part = e_attachment_get_mime_part (attachment); - - if (!(filename = camel_mime_part_get_filename (mime_part))) { - /* This is the default filename used for temporary file creation */ - filename = _("Unknown"); - } else { - utf8_mfilename = g_strdup (filename); - e_filename_make_safe (utf8_mfilename); - mfilename = g_filename_from_utf8 ((const char *) utf8_mfilename, -1, NULL, NULL, NULL); - g_free (utf8_mfilename); - filename = (const char *) mfilename; - } - - path = g_build_filename (tmpdir, filename, NULL); - g_free (tmpdir); - g_free (mfilename); - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - if (readonly) - stream = camel_stream_fs_new_with_name (path, O_RDWR|O_CREAT|O_TRUNC, 0444); - else - stream = camel_stream_fs_new_with_name (path, O_RDWR|O_CREAT|O_TRUNC, 0644); - - if (!stream) { - /* TODO handle error conditions */ - g_message ("DEBUG: could not open the file to write\n"); - g_free (path); - return NULL; - } - - if (camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) stream) == -1) { - g_free (path); - camel_stream_close (stream); - camel_object_unref (stream); - g_message ("DEBUG: could not write to file\n"); - return NULL; - } - - camel_stream_close(stream); - camel_object_unref(stream); - - return path; -} - -static void -attachment_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EDITABLE: - e_attachment_bar_set_editable ( - E_ATTACHMENT_BAR (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EDITABLE: - g_value_set_boolean ( - value, - e_attachment_bar_get_editable ( - E_ATTACHMENT_BAR (object))); - return; - - case PROP_UI_MANAGER: - g_value_set_object ( - value, - e_attachment_bar_get_ui_manager ( - E_ATTACHMENT_BAR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -attachment_bar_dispose (GObject *object) -{ - EAttachmentBarPrivate *priv; - guint ii; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); - - priv->batch_unref = TRUE; - - for (ii = 0; ii < priv->attachments->len; ii++) { - EAttachment *attachment; - - attachment = priv->attachments->pdata[ii]; - g_object_weak_unref ( - G_OBJECT (attachment), (GWeakNotify) - attachment_destroy, object); - g_object_unref (attachment); - } - g_ptr_array_set_size (priv->attachments, 0); - - if (priv->ui_manager != NULL) { - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - } - - if (priv->standard_actions != NULL) { - g_object_unref (priv->standard_actions); - priv->standard_actions = NULL; - } - - if (priv->editable_actions != NULL) { - g_object_unref (priv->editable_actions); - priv->editable_actions = NULL; - } - - if (priv->open_actions != NULL) { - g_object_unref (priv->open_actions); - priv->open_actions = NULL; - } - - /* Chain up to parent's dipose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -attachment_bar_finalize (GObject *object) -{ - EAttachmentBarPrivate *priv; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); - - g_ptr_array_free (priv->attachments, TRUE); - g_free (priv->path); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -attachment_bar_constructed (GObject *object) -{ - EAttachmentBarPrivate *priv; - GtkActionGroup *action_group; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (object); - action_group = priv->editable_actions; - - e_mutual_binding_new ( - G_OBJECT (object), "editable", - G_OBJECT (action_group), "visible"); -} - -static gboolean -attachment_bar_event (GtkWidget *widget, - GdkEvent *event) -{ - EAttachment *attachment; - gboolean ret = FALSE; - gpointer parent; - CamelURL *url; - char *path; - GSList *p; - - if (event->type != GDK_2BUTTON_PRESS) - return FALSE; - - parent = gtk_widget_get_toplevel (widget); - parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - - p = e_attachment_bar_get_selected (E_ATTACHMENT_BAR (widget)); - /* check if has body already, remote files can take longer to fetch */ - if (p && p->next == NULL && e_attachment_get_mime_part (p->data) != NULL) { - attachment = p->data; - - /* Check if the file is stored already */ - if (!attachment->store_uri) { - path = temp_save_part (attachment, TRUE); - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, path); - attachment->store_uri = camel_url_to_string (url, 0); - camel_url_free (url); - g_free (path); - } - - e_show_uri (parent, attachment->store_uri); - - ret = TRUE; - } - - g_slist_foreach (p, (GFunc) g_object_unref, NULL); - g_slist_free (p); - - return ret; -} - -static gboolean -attachment_bar_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - GnomeIconList *icon_list; - GList *selected, *tmp; - int length, icon_number; - gboolean take_selected = FALSE; - - GtkTargetEntry drag_types[] = { - { "text/uri-list", 0, 0 }, - }; - - icon_list = GNOME_ICON_LIST (widget); - selected = gnome_icon_list_get_selection (icon_list); - length = g_list_length (selected); - - icon_number = gnome_icon_list_get_icon_at ( - icon_list, event->x, event->y); - if (icon_number < 0) { - /* When nothing is selected, deselect all */ - gnome_icon_list_unselect_all (icon_list); - length = 0; - selected = NULL; - } - - if (event->button == 1) { - /* If something is selected, then allow drag or else help to select */ - if (length) - gtk_drag_source_set ( - widget, GDK_BUTTON1_MASK, drag_types, - G_N_ELEMENTS (drag_types), GDK_ACTION_COPY); - else - gtk_drag_source_unset (widget); - goto exit; - } - - /* If not r-click dont progress any more.*/ - if (event->button != 3) - goto exit; - - /* When a r-click on something, if it is in the already selected list, consider a r-click of multiple things - * or deselect all and select only this for r-click - */ - if (icon_number >= 0) { - for (tmp = selected; tmp; tmp = tmp->next) { - if (GPOINTER_TO_INT (tmp->data) == icon_number) - take_selected = TRUE; - } - - if (!take_selected) { - gnome_icon_list_unselect_all (icon_list); - gnome_icon_list_select_icon (icon_list, icon_number); - } - } - - attachment_bar_show_popup_menu (E_ATTACHMENT_BAR (widget), event); - -exit: - /* Chain up to parent's button_press_event() method. */ - return GTK_WIDGET_CLASS (parent_class)-> - button_press_event (widget, event); -} - -static gboolean -attachment_bar_button_release_event (GtkWidget *widget, - GdkEventButton *event) -{ - GnomeIconList *icon_list; - GList *selected; - - GtkTargetEntry drag_types[] = { - { "text/uri-list", 0, 0 }, - }; - - if (event->button != 1) - goto exit; - - icon_list = GNOME_ICON_LIST (widget); - selected = gnome_icon_list_get_selection (icon_list); - - if (selected != NULL) - gtk_drag_source_set ( - widget, GDK_BUTTON1_MASK, drag_types, - G_N_ELEMENTS (drag_types), GDK_ACTION_COPY); - else - gtk_drag_source_unset (widget); - -exit: - /* Chain up to parent's button_release_event() method. */ - return GTK_WIDGET_CLASS (parent_class)-> - button_release_event (widget, event); -} - -static gboolean -attachment_bar_key_press_event (GtkWidget *widget, - GdkEventKey *event) -{ - EAttachmentBar *attachment_bar; - gboolean editable; - - attachment_bar = E_ATTACHMENT_BAR (widget); - editable = e_attachment_bar_get_editable (attachment_bar); - - if (editable && event->keyval == GDK_Delete) { - GtkAction *action; - - action = e_attachment_bar_get_action (attachment_bar, "remove"); - gtk_action_activate (action); - } - - /* Chain up to parent's key_press_event() method. */ - return GTK_WIDGET_CLASS (parent_class)-> - key_press_event (widget, event); -} - -static void -attachment_bar_drag_data_get (GtkWidget *widget, - GdkDragContext *drag, - GtkSelectionData *data, - guint info, - guint time) -{ - EAttachmentBarPrivate *priv; - EAttachment *attachment; - char *path, **uris; - int len, n, i = 0; - CamelURL *url; - GList *items; - - if (info) - return; - - priv = E_ATTACHMENT_BAR_GET_PRIVATE (widget); - items = gnome_icon_list_get_selection (GNOME_ICON_LIST (widget)); - len = g_list_length (items); - - uris = g_malloc0 (sizeof (char *) * (len + 1)); - - for ( ; items != NULL; items = items->next) { - if (!((n = GPOINTER_TO_INT (items->data)) < priv->attachments->len)) - continue; - - attachment = priv->attachments->pdata[n]; - - if (!attachment->is_available_local) - continue; - - if (attachment->store_uri) { - uris[i++] = attachment->store_uri; - continue; - } - - /* If we are not able to save, ignore it */ - if (!(path = temp_save_part (attachment, FALSE))) - continue; - - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, path); - attachment->store_uri = camel_url_to_string (url, 0); - camel_url_free (url); - g_free (path); - - uris[i++] = attachment->store_uri; - } - - uris[i] = NULL; - - gtk_selection_data_set_uris (data, uris); - - g_free (uris); -} - -static gboolean -attachment_bar_popup_menu (GtkWidget *widget) -{ - attachment_bar_show_popup_menu (E_ATTACHMENT_BAR (widget), NULL); - - return TRUE; -} - -static void -attachment_bar_update_actions (EAttachmentBar *attachment_bar) -{ - GnomeIconList *icon_list; - CamelMimePart *mime_part; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - GtkAction *action; - GList *selection; - guint n_selected; - gboolean is_image; - gpointer parent; - guint merge_id; - - icon_list = GNOME_ICON_LIST (attachment_bar); - selection = gnome_icon_list_get_selection (icon_list); - n_selected = g_list_length (selection); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (attachment_bar)); - parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - - is_image = FALSE; - mime_part = NULL; - - if (n_selected == 1) { - GPtrArray *array; - EAttachment *attachment; - gint index; - - array = attachment_bar->priv->attachments; - index = GPOINTER_TO_INT (selection->data); - attachment = E_ATTACHMENT (array->pdata[index]); - mime_part = e_attachment_get_mime_part (attachment); - is_image = e_attachment_is_image (attachment); - } - - action = e_attachment_bar_get_action (attachment_bar, "properties"); - gtk_action_set_visible (action, n_selected == 1); - - action = e_attachment_bar_get_action (attachment_bar, "remove"); - gtk_action_set_visible (action, n_selected > 0); - - action = e_attachment_bar_get_action (attachment_bar, "save-as"); - gtk_action_set_visible (action, n_selected > 0); - - action = e_attachment_bar_get_action (attachment_bar, "set-background"); - gtk_action_set_visible (action, is_image); - - /* Clear out the "open" action group. */ - merge_id = attachment_bar->priv->merge_id; - action_group = attachment_bar->priv->open_actions; - ui_manager = e_attachment_bar_get_ui_manager (attachment_bar); - gtk_ui_manager_remove_ui (ui_manager, merge_id); - e_action_group_remove_all_actions (action_group); - - if (mime_part == NULL) - return; - - e_mime_part_utils_add_open_actions ( - mime_part, ui_manager, action_group, - "/attachment-popup/open-actions", parent, merge_id); -} - -static void -attachment_bar_class_init (EAttachmentBarClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EAttachmentBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = attachment_bar_set_property; - object_class->get_property = attachment_bar_get_property; - object_class->dispose = attachment_bar_dispose; - object_class->finalize = attachment_bar_finalize; - object_class->constructed = attachment_bar_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->event = attachment_bar_event; - widget_class->button_press_event = attachment_bar_button_press_event; - widget_class->button_release_event = attachment_bar_button_release_event; - widget_class->key_press_event = attachment_bar_key_press_event; - widget_class->drag_data_get = attachment_bar_drag_data_get; - widget_class->popup_menu = attachment_bar_popup_menu; - - class->update_actions = attachment_bar_update_actions; - - g_object_class_install_property ( - object_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_UI_MANAGER, - g_param_spec_object ( - "ui-manager", - "UI Manager", - NULL, - GTK_TYPE_UI_MANAGER, - G_PARAM_READABLE)); - - signals[CHANGED] = g_signal_new ( - "changed", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EAttachmentBarClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UPDATE_ACTIONS] = g_signal_new ( - "update-actions", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EAttachmentBarClass, update_actions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -attachment_bar_init (EAttachmentBar *bar) -{ - GnomeIconList *icon_list; - gint icon_width, window_height; - GError *error = NULL; - - bar->priv = E_ATTACHMENT_BAR_GET_PRIVATE (bar); - bar->priv->attachments = g_ptr_array_new (); - - GTK_WIDGET_SET_FLAGS (bar, GTK_CAN_FOCUS); - - icon_list = GNOME_ICON_LIST (bar); - - calculate_height_width (bar, &icon_width, &window_height); - gnome_icon_list_construct (icon_list, icon_width, NULL, 0); - - gtk_widget_set_size_request ( - GTK_WIDGET (bar), icon_width * 4, window_height); - - atk_object_set_name ( - gtk_widget_get_accessible (GTK_WIDGET (bar)), - _("Attachment Bar")); - - gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS); - gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING); - gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING); - gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); - gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); - gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); -} - -GType -e_attachment_bar_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EAttachmentBarClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) attachment_bar_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EAttachmentBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) attachment_bar_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - GNOME_TYPE_ICON_LIST, "EAttachmentBar", &type_info, 0); - } - - return type; -} - -GtkWidget * -e_attachment_bar_new (void) -{ - return g_object_new (E_TYPE_ATTACHMENT_BAR, NULL); -} - -static char * -get_default_charset (void) -{ - GConfClient *gconf; - const char *locale; - char *charset; - - gconf = gconf_client_get_default (); - charset = gconf_client_get_string (gconf, "/apps/evolution/mail/composer/charset", NULL); - - if (!charset || charset[0] == '\0') { - g_free (charset); - charset = gconf_client_get_string (gconf, "/apps/evolution/mail/format/charset", NULL); - if (charset && charset[0] == '\0') { - g_free (charset); - charset = NULL; - } - } - - g_object_unref (gconf); - - if (!charset && (locale = camel_iconv_locale_charset ())) - charset = g_strdup (locale); - - return charset ? charset : g_strdup ("us-ascii"); -} - -static void -attach_to_multipart (CamelMultipart *multipart, - EAttachment *attachment, - const char *default_charset) -{ - CamelContentType *content_type; - CamelDataWrapper *content; - CamelMimePart *mime_part; - - mime_part = e_attachment_get_mime_part (attachment); - if (mime_part == NULL) - return; - - content_type = camel_mime_part_get_content_type (mime_part); - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - - if (!CAMEL_IS_MULTIPART (content)) { - if (camel_content_type_is (content_type, "text", "*")) { - CamelTransferEncoding encoding; - CamelStreamFilter *filter_stream; - CamelMimeFilterBestenc *bestenc; - CamelStream *stream; - const char *charset; - char *buf = NULL; - char *type; - - charset = camel_content_type_param (content_type, "charset"); - - stream = camel_stream_null_new (); - filter_stream = camel_stream_filter_new_with_stream (stream); - bestenc = camel_mime_filter_bestenc_new (CAMEL_BESTENC_GET_ENCODING); - camel_stream_filter_add (filter_stream, CAMEL_MIME_FILTER (bestenc)); - camel_object_unref (stream); - - camel_data_wrapper_decode_to_stream (content, CAMEL_STREAM (filter_stream)); - camel_object_unref (filter_stream); - - encoding = camel_mime_filter_bestenc_get_best_encoding (bestenc, CAMEL_BESTENC_8BIT); - camel_mime_part_set_encoding (mime_part, encoding); - - if (encoding == CAMEL_TRANSFER_ENCODING_7BIT) { - /* the text fits within us-ascii so this is safe */ - /* FIXME: check that this isn't iso-2022-jp? */ - default_charset = "us-ascii"; - } else if (!charset) { - if (!default_charset) - default_charset = buf = get_default_charset (); - - /* FIXME: We should really check that this fits within the - default_charset and if not find one that does and/or - allow the user to specify? */ - } - - if (!charset) { - /* looks kinda nasty, but this is how ya have to do it */ - camel_content_type_set_param (content_type, "charset", default_charset); - type = camel_content_type_format (content_type); - camel_mime_part_set_content_type (mime_part, type); - g_free (type); - g_free (buf); - } - - camel_object_unref (bestenc); - } else if (!CAMEL_IS_MIME_MESSAGE (content)) { - camel_mime_part_set_encoding (mime_part, CAMEL_TRANSFER_ENCODING_BASE64); - } - } - - camel_multipart_add_part (multipart, mime_part); -} - -void -e_attachment_bar_to_multipart (EAttachmentBar *bar, - CamelMultipart *multipart, - const gchar *default_charset) -{ - EAttachmentBarPrivate *priv; - EAttachment *attachment; - int i; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (CAMEL_IS_MULTIPART (multipart)); - - priv = bar->priv; - - for (i = 0; i < priv->attachments->len; i++) { - attachment = priv->attachments->pdata[i]; - if (attachment->is_available_local) - attach_to_multipart (multipart, attachment, default_charset); - } -} - -guint -e_attachment_bar_get_num_attachments (EAttachmentBar *bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - return bar->priv->attachments->len; -} - -void -e_attachment_bar_attach (EAttachmentBar *bar, - const gchar *filename, - const gchar *disposition) -{ - EAttachment *attachment; - CamelException ex; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (filename != NULL); - g_return_if_fail (disposition != NULL); - - camel_exception_init (&ex); - - attachment = e_attachment_new (filename, disposition, &ex); - - if (attachment != NULL) - e_attachment_bar_add_attachment (bar, attachment); - else { - GtkWidget *toplevel; - - /* FIXME: Avoid using error from mailer */ - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bar)); - e_error_run ( - GTK_WINDOW (toplevel), "mail-composer:no-attach", - filename, camel_exception_get_description (&ex), NULL); - camel_exception_clear (&ex); - } -} - -void -e_attachment_bar_add_attachment (EAttachmentBar *bar, - EAttachment *attachment) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - g_ptr_array_add (bar->priv->attachments, attachment); - - g_object_weak_ref ( - G_OBJECT (attachment), (GWeakNotify) - attachment_destroy, bar); - - g_signal_connect_swapped ( - attachment, "changed", - G_CALLBACK (e_attachment_bar_refresh), bar); - - e_attachment_bar_refresh (bar); - - g_signal_emit (bar, signals[CHANGED], 0); -} - -void -e_attachment_bar_add_attachment_silent (EAttachmentBar *bar, - EAttachment *attachment) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - g_ptr_array_add (bar->priv->attachments, attachment); - - g_object_weak_ref ( - G_OBJECT (attachment), (GWeakNotify) - attachment_destroy, bar); - - g_signal_connect_swapped ( - attachment, "changed", - G_CALLBACK (e_attachment_bar_refresh), bar); - - g_signal_emit (bar, signals[CHANGED], 0); -} - -void -e_attachment_bar_refresh (EAttachmentBar *bar) -{ - EAttachmentBarPrivate *priv; - GnomeIconList *icon_list; - int bar_width, bar_height; - int i; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - priv = bar->priv; - icon_list = GNOME_ICON_LIST (bar); - - gnome_icon_list_freeze (icon_list); - - gnome_icon_list_clear (icon_list); - - /* FIXME could be faster, but we don't care. */ - for (i = 0; i < priv->attachments->len; i++) { - EAttachment *attachment; - CamelContentType *content_type; - CamelMimePart *mime_part; - char *size_string, *label; - GdkPixbuf *pixbuf = NULL; - const char *desc; - - attachment = priv->attachments->pdata[i]; - mime_part = e_attachment_get_mime_part (attachment); - - if (!attachment->is_available_local || mime_part == NULL) { - if ((pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG))) { - attachment->index = gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, ""); - g_object_unref (pixbuf); - } - continue; - } - - content_type = camel_mime_part_get_content_type (mime_part); - /* Get the image out of the attachment - and create a thumbnail for it */ - pixbuf = e_attachment_get_thumbnail (attachment); - if (pixbuf != NULL) - g_object_ref (pixbuf); - else if (camel_content_type_is(content_type, "image", "*")) { - CamelDataWrapper *wrapper; - CamelStreamMem *mstream; - GdkPixbufLoader *loader; - gboolean error = TRUE; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - mstream = (CamelStreamMem *) camel_stream_mem_new (); - - camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); - - /* Stream image into pixbuf loader */ - loader = gdk_pixbuf_loader_new (); - error = !gdk_pixbuf_loader_write (loader, mstream->buffer->data, mstream->buffer->len, NULL); - gdk_pixbuf_loader_close (loader, NULL); - - if (!error) { - /* The loader owns the reference. */ - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - - /* This returns a new GdkPixbuf. */ - pixbuf = scale_pixbuf (pixbuf); - e_attachment_set_thumbnail (attachment, pixbuf); - } else { - pixbuf = NULL; - g_warning ("GdkPixbufLoader Error"); - } - - /* Destroy everything */ - g_object_unref (loader); - camel_object_unref (mstream); - } else if (!bar->expand && (pixbuf = get_system_thumbnail (attachment, content_type))) { - /* This returns a new GdkPixbuf. */ - pixbuf = scale_pixbuf (pixbuf); - e_attachment_set_thumbnail (attachment, pixbuf); - } - - desc = camel_mime_part_get_description (mime_part); - if (desc == NULL || *desc == '\0') - desc = e_attachment_get_filename (attachment); - if (desc == NULL || *desc == '\0') - desc = camel_mime_part_get_filename (mime_part); - - if (!desc) - desc = _("attachment"); - - if (attachment->size && (size_string = g_format_size_for_display (attachment->size))) { - label = g_strdup_printf ("%s (%s)", desc, size_string); - g_free (size_string); - } else - label = g_strdup (desc); - - if (pixbuf == NULL) { - char *mime_type; - - mime_type = camel_content_type_simple (content_type); - pixbuf = e_icon_for_mime_type (mime_type, 48); - if (pixbuf == NULL) { - g_warning("cannot find icon for mime type %s (installation problem?)", mime_type); - pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG); - } - g_free (mime_type); - - /* remember this picture and use it later again */ - if (pixbuf) - e_attachment_set_thumbnail (attachment, pixbuf); - } - - if (pixbuf) { - GdkPixbuf *pixbuf_orig = pixbuf; - pixbuf = gdk_pixbuf_add_alpha (pixbuf_orig, TRUE, 255, 255, 255); - - /* gdk_pixbuf_add_alpha returns a newly allocated pixbuf, - free the original one. - */ - g_object_unref (pixbuf_orig); - - /* In case of a attachment bar, in a signed/encrypted part, display the status as a emblem*/ - if (attachment->sign) { - /* Show the signature status at the right-bottom.*/ - GdkPixbuf *sign = NULL; - int x, y; - - if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_BAD) - sign = e_icon_factory_get_icon ("stock_signature-bad", E_ICON_SIZE_MENU); - else if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_GOOD) - sign = e_icon_factory_get_icon ("stock_signature-ok", E_ICON_SIZE_MENU); - else - sign = e_icon_factory_get_icon ("stock_signature", E_ICON_SIZE_MENU); - - x = gdk_pixbuf_get_width (pixbuf) - 17; - y = gdk_pixbuf_get_height (pixbuf) - 17; - - gdk_pixbuf_copy_area (sign, 0, 0, 16, 16, pixbuf, x, y); - g_object_unref (sign); - } - - if (attachment->encrypt) { - /* Show the encryption status at the top left.*/ - GdkPixbuf *encrypt = e_icon_factory_get_icon ("stock_lock-ok", E_ICON_SIZE_MENU); - - gdk_pixbuf_copy_area (encrypt, 0, 0, 16, 16, pixbuf, 1, 1); - g_object_unref (encrypt); - } - - gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, label); - g_object_unref (pixbuf); - } - - g_free (label); - } - - gnome_icon_list_thaw (icon_list); - - /* Resize */ - if (bar->expand) { - gtk_widget_get_size_request ((GtkWidget *) bar, &bar_width, &bar_height); - - if (bar->priv->attachments->len) { - int per_col, rows, height, width; - - calculate_height_width(bar, &width, &height); - per_col = bar_width / width; - per_col = (per_col ? per_col : 1); - rows = (bar->priv->attachments->len + per_col -1) / per_col; - gtk_widget_set_size_request ((GtkWidget *) bar, bar_width, rows * height); - } - } -} - -int -e_attachment_bar_get_download_count (EAttachmentBar *bar) -{ - EAttachmentBarPrivate *priv; - EAttachment *attachment; - int i, n = 0; - - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - priv = bar->priv; - - for (i = 0; i < priv->attachments->len; i++) { - attachment = priv->attachments->pdata[i]; - if (!attachment->is_available_local) - n++; - } - - return n; -} - -void -e_attachment_bar_attach_remote_file (EAttachmentBar *bar, - const gchar *url, - const gchar *disposition) -{ - EAttachment *attachment; - CamelException ex; - GtkWidget *parent; - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - - if (bar->priv->path == NULL) - bar->priv->path = e_mkdtemp ("attach-XXXXXX"); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (bar)); - camel_exception_init (&ex); - - attachment = e_attachment_new_remote_file ( - GTK_WINDOW (parent), url, disposition, bar->priv->path, &ex); - - if (attachment != NULL) { - e_attachment_bar_add_attachment (bar, attachment); - g_signal_connect ( - attachment, "update", - G_CALLBACK (update_remote_file), bar); - } else { - e_error_run ( - GTK_WINDOW (parent), "mail-composer:no-attach", - url, camel_exception_get_description (&ex), NULL); - camel_exception_clear (&ex); - } -} - -void -e_attachment_bar_attach_mime_part (EAttachmentBar *bar, - CamelMimePart *part) -{ - EAttachment *attachment; - - /* XXX Is this function really worth keeping? */ - - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (CAMEL_IS_MIME_PART (part)); - - attachment = e_attachment_new_from_mime_part (part); - e_attachment_bar_add_attachment (bar, attachment); -} - -void -e_attachment_bar_update_actions (EAttachmentBar *attachment_bar) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); - - g_signal_emit (attachment_bar, signals[UPDATE_ACTIONS], 0); -} - -gboolean -e_attachment_bar_get_editable (EAttachmentBar *attachment_bar) -{ - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar), FALSE); - - return attachment_bar->priv->editable; -} - -void -e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, - gboolean editable) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (attachment_bar)); - - attachment_bar->priv->editable = editable; - - g_object_notify (G_OBJECT (attachment_bar), "editable"); -} diff --git a/widgets/misc/e-attachment-bar.h b/widgets/misc/e-attachment-bar.h deleted file mode 100644 index a9b0655276..0000000000 --- a/widgets/misc/e-attachment-bar.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Ettore Perazzoli - * Srinivasa Ragavan - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_ATTACHMENT_BAR_H -#define E_ATTACHMENT_BAR_H - -#include -#include - -#include -#include "e-attachment.h" - -#define E_TYPE_ATTACHMENT_BAR \ - (e_attachment_bar_get_type ()) -#define E_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBar)) -#define E_ATTACHMENT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) -#define E_IS_ATTACHMENT_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ATTACHMENT_BAR)) -#define E_IS_ATTACHMENT_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ATTACHMENT_BAR)) -#define E_ATTACHMENT_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarClass)) - -G_BEGIN_DECLS - -typedef struct _EAttachmentBar EAttachmentBar; -typedef struct _EAttachmentBarClass EAttachmentBarClass; -typedef struct _EAttachmentBarPrivate EAttachmentBarPrivate; - -struct _EAttachmentBar { - GnomeIconList parent; - gboolean expand; - EAttachmentBarPrivate *priv; -}; - -struct _EAttachmentBarClass { - GnomeIconListClass parent_class; - - /* Signals */ - void (*changed) (EAttachmentBar *bar); - void (*update_actions) (EAttachmentBar *bar); -}; - -GType e_attachment_bar_get_type (void); -GtkWidget * e_attachment_bar_new (void); -void e_attachment_bar_to_multipart (EAttachmentBar *bar, - CamelMultipart *multipart, - const gchar *default_charset); -guint e_attachment_bar_get_num_attachments - (EAttachmentBar *bar); -void e_attachment_bar_attach (EAttachmentBar *bar, - const gchar *filename, - const gchar *disposition); -void e_attachment_bar_attach_mime_part - (EAttachmentBar *bar, - CamelMimePart *part); -gint e_attachment_bar_get_download_count - (EAttachmentBar *bar); -void e_attachment_bar_attach_remote_file - (EAttachmentBar *bar, - const gchar *url, - const gchar *disposition); -GSList * e_attachment_bar_get_attachment (EAttachmentBar *bar, - gint id); -void e_attachment_bar_add_attachment (EAttachmentBar *bar, - EAttachment *attachment); -GSList * e_attachment_bar_get_parts (EAttachmentBar *bar); -GSList * e_attachment_bar_get_selected (EAttachmentBar *bar); -void e_attachment_bar_set_width (EAttachmentBar *bar, - gint bar_width); -GSList * e_attachment_bar_get_all_attachments - (EAttachmentBar *bar); -void e_attachment_bar_create_attachment_cache - (EAttachment *attachment); -GtkAction * e_attachment_bar_recent_action_new - (EAttachmentBar *bar, - const gchar *action_name, - const gchar *action_label); -void e_attachment_bar_add_attachment_silent - (EAttachmentBar *bar, - EAttachment *attachment); -void e_attachment_bar_refresh (EAttachmentBar *bar); -gint e_attachment_bar_file_chooser_dialog_run - (EAttachmentBar *attachment_bar, - GtkWidget *dialog); -void e_attachment_bar_update_actions (EAttachmentBar *attachment_bar); -const gchar * e_attachment_bar_get_background_filename - (EAttachmentBar *attachment_bar); -void e_attachment_bar_set_background_filename - (EAttachmentBar *attachment_bar, - const gchar *background_filename); -const gchar * e_attachment_bar_get_background_options - (EAttachmentBar *attachment_bar); -void e_attachment_bar_set_background_options - (EAttachmentBar *attachment_bar, - const gchar *background_options); -const gchar * e_attachment_bar_get_current_folder - (EAttachmentBar *attachment_bar); -void e_attachment_bar_set_current_folder - (EAttachmentBar *attachment_bar, - const gchar *current_folder); -gboolean e_attachment_bar_get_editable (EAttachmentBar *attachment_bar); -void e_attachment_bar_set_editable (EAttachmentBar *attachment_bar, - gboolean editable); -GtkUIManager * e_attachment_bar_get_ui_manager (EAttachmentBar *attachment_bar); -GtkAction * e_attachment_bar_get_action (EAttachmentBar *attachment_bar, - const gchar *action_name); -GtkActionGroup *e_attachment_bar_get_action_group - (EAttachmentBar *attachment_bar, - const gchar *group_name); - -G_END_DECLS - -#endif /* E_ATTACHMENT_BAR_H */ diff --git a/widgets/misc/e-attachment-handler-image.c b/widgets/misc/e-attachment-handler-image.c new file mode 100644 index 0000000000..02357facc9 --- /dev/null +++ b/widgets/misc/e-attachment-handler-image.c @@ -0,0 +1,285 @@ +/* + * e-attachment-handler-image.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-handler-image.h" + +#include +#include +#include + +#define E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImagePrivate)) + +struct _EAttachmentHandlerImagePrivate { + gint placeholder; +}; + +static gpointer parent_class; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +""; + +static void +action_image_set_as_background_saved_cb (EAttachment *attachment, + GAsyncResult *result, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + GConfClient *client; + GtkWidget *dialog; + GFile *file; + const gchar *key; + gpointer parent; + gchar *value; + GError *error = NULL; + + client = gconf_client_get_default (); + view = e_attachment_handler_get_view (handler); + + file = e_attachment_save_finish (attachment, result, &error); + + if (error != NULL) + goto error; + + value = g_file_get_path (file); + g_object_unref (file); + + key = "/desktop/gnome/background/picture_filename"; + gconf_client_set_string (client, key, value, &error); + g_free (value); + + if (error != NULL) + goto error; + + /* Ignore errors for this part. */ + key = "/desktop/gnome/background/picture_options"; + value = gconf_client_get_string (client, key, NULL); + if (g_strcmp0 (value, "none") == 0) + gconf_client_set_string (client, key, "wallpaper", NULL); + g_free (value); + + goto exit; + +error: + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", + _("Could not set as background")); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); + +exit: + g_object_unref (client); + g_object_unref (handler); +} + +static void +action_image_set_as_background_cb (GtkAction *action, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + EAttachment *attachment; + GFile *destination; + GList *selected; + gchar *path; + + view = e_attachment_handler_get_view (handler); + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = E_ATTACHMENT (selected->data); + + /* Save the image under ~/.gnome2/wallpapers/. */ + path = g_build_filename ( + g_get_home_dir (), ".gnome2", "wallpapers", NULL); + destination = g_file_new_for_path (path); + g_mkdir_with_parents (path, 0755); + g_free (path); + + e_attachment_save_async ( + attachment, destination, (GAsyncReadyCallback) + action_image_set_as_background_saved_cb, + g_object_ref (handler)); + + g_object_unref (destination); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static GtkActionEntry standard_entries[] = { + + { "image-set-as-background", + NULL, + N_("Set as _Background"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_image_set_as_background_cb) } +}; + +static void +attachment_handler_image_update_actions_cb (EAttachmentView *view, + EAttachmentHandler *handler) +{ + EAttachmentHandlerImagePrivate *priv; + EAttachment *attachment; + GFileInfo *file_info; + GtkActionGroup *action_group; + const gchar *content_type; + gchar *mime_type; + GList *selected; + gboolean visible = FALSE; + + priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler); + + selected = e_attachment_view_get_selected_attachments (view); + + if (g_list_length (selected) != 1) + goto exit; + + attachment = E_ATTACHMENT (selected->data); + file_info = e_attachment_get_file_info (attachment); + + if (file_info == NULL) + goto exit; + + if (e_attachment_get_loading (attachment)) + goto exit; + + if (e_attachment_get_saving (attachment)) + goto exit; + + content_type = g_file_info_get_content_type (file_info); + + mime_type = g_content_type_get_mime_type (content_type); + visible = (g_ascii_strncasecmp (mime_type, "image/", 6) == 0); + g_free (mime_type); + +exit: + action_group = e_attachment_view_get_action_group (view, "image"); + gtk_action_group_set_visible (action_group, visible); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +attachment_handler_image_constructed (GObject *object) +{ + EAttachmentHandlerImagePrivate *priv; + EAttachmentHandler *handler; + EAttachmentView *view; + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + const gchar *domain = GETTEXT_PACKAGE; + GError *error = NULL; + + handler = E_ATTACHMENT_HANDLER (object); + priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + view = e_attachment_handler_get_view (handler); + ui_manager = e_attachment_view_get_ui_manager (view); + + action_group = gtk_action_group_new ("image"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), object); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + g_object_unref (action_group); + + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_signal_connect ( + view, "update-actions", + G_CALLBACK (attachment_handler_image_update_actions_cb), + object); +} + +static void +attachment_handler_image_class_init (EAttachmentHandlerImageClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentHandlerImagePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = attachment_handler_image_constructed; +} + +static void +attachment_handler_image_init (EAttachmentHandlerImage *handler) +{ + handler->priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler); +} + +GType +e_attachment_handler_image_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentHandlerImageClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_handler_image_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentHandlerImage), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_handler_image_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ATTACHMENT_HANDLER, + "EAttachmentHandlerImage", + &type_info, 0); + } + + return type; +} diff --git a/widgets/misc/e-attachment-handler-image.h b/widgets/misc/e-attachment-handler-image.h new file mode 100644 index 0000000000..53b076c61f --- /dev/null +++ b/widgets/misc/e-attachment-handler-image.h @@ -0,0 +1,65 @@ +/* + * e-attachment-handler-image.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_HANDLER_IMAGE_H +#define E_ATTACHMENT_HANDLER_IMAGE_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_HANDLER_IMAGE \ + (e_attachment_handler_image_get_type ()) +#define E_ATTACHMENT_HANDLER_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImage)) +#define E_ATTACHMENT_HANDLER_IMAGE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImageClass)) +#define E_IS_ATTACHMENT_HANDLER_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE)) +#define E_IS_ATTACHMENT_HANDLER_IMAGE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_IMAGE)) +#define E_ATTACHMENT_HANDLER_IMAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImageClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentHandlerImage EAttachmentHandlerImage; +typedef struct _EAttachmentHandlerImageClass EAttachmentHandlerImageClass; +typedef struct _EAttachmentHandlerImagePrivate EAttachmentHandlerImagePrivate; + +struct _EAttachmentHandlerImage { + EAttachmentHandler parent; + EAttachmentHandlerImagePrivate *priv; +}; + +struct _EAttachmentHandlerImageClass { + EAttachmentHandlerClass parent_class; +}; + +GType e_attachment_handler_image_get_type (void); + +G_END_DECLS + +#endif /* E_ATTACHMENT_HANDLER_IMAGE_H */ diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c new file mode 100644 index 0000000000..dce139f9c3 --- /dev/null +++ b/widgets/misc/e-attachment-handler.c @@ -0,0 +1,157 @@ +/* + * e-attachment-handler.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-handler.h" + +#define E_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerPrivate)) + +struct _EAttachmentHandlerPrivate { + gpointer view; /* weak pointer */ +}; + +enum { + PROP_0, + PROP_VIEW +}; + +static gpointer parent_class; + +static void +attachment_handler_set_view (EAttachmentHandler *handler, + EAttachmentView *view) +{ + g_return_if_fail (handler->priv->view == NULL); + + handler->priv->view = view; + + g_object_add_weak_pointer ( + G_OBJECT (view), &handler->priv->view); +} + +static void +attachment_handler_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_VIEW: + attachment_handler_set_view ( + E_ATTACHMENT_HANDLER (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_handler_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_VIEW: + g_value_set_object ( + value, e_attachment_handler_get_view ( + E_ATTACHMENT_HANDLER (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_handler_constructed (GObject *object) +{ + /* This allows subclasses to chain up safely since GObject + * does not implement this method, and we might want to do + * something here in the future. */ +} + +static void +attachment_handler_class_init (EAttachmentHandlerClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentHandlerPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_handler_set_property; + object_class->get_property = attachment_handler_get_property; + object_class->constructed = attachment_handler_constructed; + + g_object_class_install_property ( + object_class, + PROP_VIEW, + g_param_spec_object ( + "view", + "View", + NULL, + E_TYPE_ATTACHMENT_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +attachment_handler_init (EAttachmentHandler *handler) +{ + handler->priv = E_ATTACHMENT_HANDLER_GET_PRIVATE (handler); +} + +GType +e_attachment_handler_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentHandlerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_handler_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentHandler), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_handler_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EAttachmentHandler", + &type_info, G_TYPE_FLAG_ABSTRACT); + } + + return type; +} + +EAttachmentView * +e_attachment_handler_get_view (EAttachmentHandler *handler) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), NULL); + + return E_ATTACHMENT_VIEW (handler->priv->view); +} diff --git a/widgets/misc/e-attachment-handler.h b/widgets/misc/e-attachment-handler.h new file mode 100644 index 0000000000..8de5743ba6 --- /dev/null +++ b/widgets/misc/e-attachment-handler.h @@ -0,0 +1,67 @@ +/* + * e-attachment-handler.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_HANDLER_H +#define E_ATTACHMENT_HANDLER_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_HANDLER \ + (e_attachment_handler_get_type ()) +#define E_ATTACHMENT_HANDLER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandler)) +#define E_ATTACHMENT_HANDLER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerClass)) +#define E_IS_ATTACHMENT_HANDLER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER)) +#define E_IS_ATTACHMENT_HANDLER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_HANDLER)) +#define E_ATTACHMENT_HANDLER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_HANDLER, EAttachmentHandlerClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentHandler EAttachmentHandler; +typedef struct _EAttachmentHandlerClass EAttachmentHandlerClass; +typedef struct _EAttachmentHandlerPrivate EAttachmentHandlerPrivate; + +struct _EAttachmentHandler { + GObject parent; + EAttachmentHandlerPrivate *priv; +}; + +struct _EAttachmentHandlerClass { + GObjectClass parent_class; +}; + +GType e_attachment_handler_get_type (void); +EAttachmentView * + e_attachment_handler_get_view (EAttachmentHandler *handler); + +G_END_DECLS + +#endif /* E_ATTACHMENT_HANDLER_H */ diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index 9588540f05..e8a7db8459 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -22,7 +22,6 @@ #include "e-attachment-icon-view.h" #include -#include #include "e-attachment.h" #include "e-attachment-store.h" @@ -129,10 +128,8 @@ attachment_icon_view_key_press_event (GtkWidget *widget, { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - if (event->keyval == GDK_Delete) { - e_attachment_view_remove_selected (view, TRUE); + if (e_attachment_view_key_press_event (view, event)) return TRUE; - } /* Chain up to parent's key_press_event() method. */ return GTK_WIDGET_CLASS (parent_class)-> diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 1eb429b41e..e565d68cae 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -790,10 +790,13 @@ attachment_store_save_list_finished_cb (EAttachment *attachment, GAsyncResult *result, SaveContext *save_context) { + GFile *file; GSimpleAsyncResult *simple; GError *error = NULL; - e_attachment_save_finish (attachment, result, &error); + file = e_attachment_save_finish (attachment, result, &error); + if (file != NULL) + g_object_unref (file); /* Remove the attachment from the list. */ save_context->attachment_list = g_list_remove ( diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index 5a613f4f17..336b3225df 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -22,7 +22,6 @@ #include "e-attachment-tree-view.h" #include -#include #include "e-attachment.h" #include "e-attachment-store.h" @@ -147,10 +146,8 @@ attachment_tree_view_key_press_event (GtkWidget *widget, { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - if (event->keyval == GDK_Delete) { - e_attachment_view_remove_selected (view, TRUE); + if (e_attachment_view_key_press_event (view, event)) return TRUE; - } /* Chain up to parent's key_press_event() method. */ return GTK_WIDGET_CLASS (parent_class)-> diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 6d6079df21..b2dc62b934 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -23,12 +23,18 @@ #include #include +#include #include #include "e-util/e-binding.h" -#include "e-util/e-plugin-ui.h" #include "e-util/e-util.h" #include "e-attachment-dialog.h" +#include "e-attachment-handler-image.h" + +enum { + UPDATE_ACTIONS, + LAST_SIGNAL +}; enum { DND_TYPE_MESSAGE_RFC822, @@ -69,9 +75,9 @@ static const gchar *ui = " " " " " " -" " " " " " +" " " " " " " " @@ -86,6 +92,8 @@ static const gchar *ui = " " ""; +static gulong signals[LAST_SIGNAL]; + static void action_add_cb (GtkAction *action, EAttachmentView *view) @@ -295,13 +303,6 @@ exit: g_list_free (selected); } -static void -action_set_background_cb (GtkAction *action, - EAttachmentView *view) -{ - /* FIXME */ -} - static GtkActionEntry standard_entries[] = { { "cancel", @@ -354,13 +355,6 @@ static GtkActionEntry standard_entries[] = { NULL, NULL, /* XXX Add a tooltip! */ G_CALLBACK (action_save_all_cb) }, - - { "set-background", - NULL, - N_("Set as _Background"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_set_background_cb) } }; static GtkActionEntry editable_entries[] = { @@ -572,11 +566,115 @@ drop_x_uid_list (EAttachmentView *view, gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); } +static void +attachment_view_update_actions (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + EAttachment *attachment; + GtkAction *action; + GList *list, *iter; + guint n_selected; + gboolean busy = FALSE; + + g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); + + priv = e_attachment_view_get_private (view); + list = e_attachment_view_get_selected_attachments (view); + n_selected = g_list_length (list); + + if (n_selected == 1) { + attachment = g_object_ref (list->data); + busy |= e_attachment_get_loading (attachment); + busy |= e_attachment_get_saving (attachment); + } else + attachment = NULL; + + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + + action = e_attachment_view_get_action (view, "cancel"); + gtk_action_set_visible (action, busy); + + action = e_attachment_view_get_action (view, "properties"); + gtk_action_set_visible (action, !busy && n_selected == 1); + + action = e_attachment_view_get_action (view, "remove"); + gtk_action_set_visible (action, !busy && n_selected > 0); + + action = e_attachment_view_get_action (view, "save-as"); + gtk_action_set_visible (action, !busy && n_selected > 0); + + /* Clear out the "openwith" action group. */ + gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); + e_action_group_remove_all_actions (priv->openwith_actions); + + if (attachment == NULL || busy) + return; + + list = e_attachment_list_apps (attachment); + + for (iter = list; iter != NULL; iter = iter->next) { + GAppInfo *app_info = iter->data; + GtkAction *action; + const gchar *app_executable; + const gchar *app_name; + gchar *action_tooltip; + gchar *action_label; + gchar *action_name; + + if (!g_app_info_should_show (app_info)) + continue; + + app_executable = g_app_info_get_executable (app_info); + app_name = g_app_info_get_name (app_info); + + action_name = g_strdup_printf ("open-in-%s", app_executable); + action_label = g_strdup_printf (_("Open in %s..."), app_name); + + action_tooltip = g_strdup_printf ( + _("Open this attachment in %s"), app_name); + + action = gtk_action_new ( + action_name, action_label, action_tooltip, NULL); + + g_object_set_data_full ( + G_OBJECT (action), + "app-info", g_object_ref (app_info), + (GDestroyNotify) g_object_unref); + + g_object_set_data_full ( + G_OBJECT (action), + "attachment", g_object_ref (attachment), + (GDestroyNotify) g_object_unref); + + g_signal_connect ( + action, "activate", + G_CALLBACK (action_open_in_cb), view); + + gtk_action_group_add_action (priv->openwith_actions, action); + + gtk_ui_manager_add_ui ( + priv->ui_manager, priv->merge_id, + "/context/open-actions", action_name, + action_name, GTK_UI_MANAGER_AUTO, FALSE); + + g_free (action_name); + g_free (action_label); + g_free (action_tooltip); + } + + g_object_unref (attachment); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); +} + static void attachment_view_class_init (EAttachmentViewIface *iface) { gint ii; + iface->update_actions = attachment_view_update_actions; + g_object_interface_install_property ( iface, g_param_spec_boolean ( @@ -587,6 +685,15 @@ attachment_view_class_init (EAttachmentViewIface *iface) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + signals[UPDATE_ACTIONS] = g_signal_new ( + "update-actions", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EAttachmentViewIface, update_actions), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) { const gchar *target = drag_info[ii].target; drag_info[ii].atom = gdk_atom_intern (target, FALSE); @@ -616,6 +723,9 @@ e_attachment_view_get_type (void) G_TYPE_INTERFACE, "EAttachmentView", &type_info, 0); g_type_interface_add_prerequisite (type, GTK_TYPE_WIDGET); + + /* Register known handler types. */ + e_attachment_handler_image_get_type (); } return type; @@ -628,6 +738,8 @@ e_attachment_view_init (EAttachmentView *view) GtkUIManager *ui_manager; GtkActionGroup *action_group; const gchar *domain = GETTEXT_PACKAGE; + GType *children; + guint ii; GError *error = NULL; priv = e_attachment_view_get_private (view); @@ -671,7 +783,14 @@ e_attachment_view_init (EAttachmentView *view) G_OBJECT (view), "editable", G_OBJECT (priv->editable_actions), "visible"); - e_plugin_ui_register_manager (ui_manager, "attachment-view", view); + /* Instantiate attachment handlers. */ + children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL); + for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) { + EAttachmentHandler *handler; + handler = g_object_new (children[ii], "view", view, NULL); + priv->handlers = g_list_prepend (priv->handlers, handler); + } + g_free (children); } void @@ -681,6 +800,10 @@ e_attachment_view_dispose (EAttachmentView *view) priv = e_attachment_view_get_private (view); + g_list_foreach (priv->handlers, (GFunc) g_object_unref, NULL); + g_list_free (priv->handlers); + priv->handlers = NULL; + if (priv->ui_manager != NULL) { g_object_unref (priv->ui_manager); priv->ui_manager = NULL; @@ -952,6 +1075,25 @@ e_attachment_view_button_release_event (EAttachmentView *view, return FALSE; } +gboolean +e_attachment_view_key_press_event (EAttachmentView *view, + GdkEventKey *event) +{ + gboolean editable; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + editable = e_attachment_view_get_editable (view); + + if (event->keyval == GDK_Delete && editable) { + e_attachment_view_remove_selected (view, TRUE); + return TRUE; + } + + return FALSE; +} + GtkTreePath * e_attachment_view_get_path_at_pos (EAttachmentView *view, gint x, @@ -1445,108 +1587,7 @@ e_attachment_view_show_popup_menu (EAttachmentView *view, void e_attachment_view_update_actions (EAttachmentView *view) { - EAttachmentViewPrivate *priv; - EAttachment *attachment; - GtkAction *action; - GList *list, *iter; - guint n_selected; - gboolean is_image; - gboolean busy = FALSE; - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - priv = e_attachment_view_get_private (view); - list = e_attachment_view_get_selected_attachments (view); - n_selected = g_list_length (list); - - if (n_selected == 1) { - attachment = g_object_ref (list->data); - is_image = e_attachment_is_image (attachment); - busy |= e_attachment_get_loading (attachment); - busy |= e_attachment_get_saving (attachment); - } else { - attachment = NULL; - is_image = FALSE; - } - - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - - action = e_attachment_view_get_action (view, "cancel"); - gtk_action_set_visible (action, busy); - - action = e_attachment_view_get_action (view, "properties"); - gtk_action_set_visible (action, !busy && n_selected == 1); - - action = e_attachment_view_get_action (view, "remove"); - gtk_action_set_visible (action, !busy && n_selected > 0); - - action = e_attachment_view_get_action (view, "save-as"); - gtk_action_set_visible (action, !busy && n_selected > 0); - - action = e_attachment_view_get_action (view, "set-background"); - gtk_action_set_visible (action, !busy && is_image); - - /* Clear out the "openwith" action group. */ - gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); - e_action_group_remove_all_actions (priv->openwith_actions); - - if (attachment == NULL || busy) - return; - - list = e_attachment_list_apps (attachment); - - for (iter = list; iter != NULL; iter = iter->next) { - GAppInfo *app_info = iter->data; - GtkAction *action; - const gchar *app_executable; - const gchar *app_name; - gchar *action_tooltip; - gchar *action_label; - gchar *action_name; - - if (!g_app_info_should_show (app_info)) - continue; - - app_executable = g_app_info_get_executable (app_info); - app_name = g_app_info_get_name (app_info); - - action_name = g_strdup_printf ("open-in-%s", app_executable); - action_label = g_strdup_printf (_("Open in %s..."), app_name); - - action_tooltip = g_strdup_printf ( - _("Open this attachment in %s"), app_name); - - action = gtk_action_new ( - action_name, action_label, action_tooltip, NULL); - - g_object_set_data_full ( - G_OBJECT (action), - "app-info", g_object_ref (app_info), - (GDestroyNotify) g_object_unref); - - g_object_set_data_full ( - G_OBJECT (action), - "attachment", g_object_ref (attachment), - (GDestroyNotify) g_object_unref); - - g_signal_connect ( - action, "activate", - G_CALLBACK (action_open_in_cb), view); - - gtk_action_group_add_action (priv->openwith_actions, action); - - gtk_ui_manager_add_ui ( - priv->ui_manager, priv->merge_id, - "/context/open-actions", action_name, - action_name, GTK_UI_MANAGER_AUTO, FALSE); - - g_free (action_name); - g_free (action_label); - g_free (action_tooltip); - } - - g_object_unref (attachment); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); + g_signal_emit (view, signals[UPDATE_ACTIONS], 0); } diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index d33ad951ac..16a7ac1967 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -85,10 +85,16 @@ struct _EAttachmentViewIface { GdkDragAction actions); void (*drag_source_unset) (EAttachmentView *view); void (*drag_dest_unset) (EAttachmentView *view); + + /* Signals */ + void (*update_actions) (EAttachmentView *view); }; struct _EAttachmentViewPrivate { + /* Attachment Handlers */ + GList *handlers; + /* Popup Menu Management */ GtkUIManager *ui_manager; GtkActionGroup *standard_actions; @@ -127,12 +133,16 @@ void e_attachment_view_remove_selected (EAttachmentView *view, gboolean select_next); +/* Event Support */ gboolean e_attachment_view_button_press_event (EAttachmentView *view, GdkEventButton *event); gboolean e_attachment_view_button_release_event (EAttachmentView *view, GdkEventButton *event); +gboolean e_attachment_view_key_press_event + (EAttachmentView *view, + GdkEventKey *event); /* Selection Management */ GtkTreePath * e_attachment_view_get_path_at_pos diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 52a3d928f6..fb84261fa2 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -52,7 +52,7 @@ #define EMBLEM_SIGN_GOOD "stock_signature-ok" #define EMBLEM_SIGN_UNKNOWN "stock_signature" -/* Attributes needed by EAttachmentStore, et al. */ +/* Attributes needed for EAttachmentStore columns. */ #define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*" struct _EAttachmentPrivate { @@ -1184,31 +1184,6 @@ e_attachment_get_thumbnail_path (EAttachment *attachment) return g_file_info_get_attribute_byte_string (file_info, attribute); } -gboolean -e_attachment_is_image (EAttachment *attachment) -{ - GFileInfo *file_info; - const gchar *content_type; - gchar *mime_type; - gboolean is_image; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - return FALSE; - - content_type = g_file_info_get_content_type (file_info); - if (content_type == NULL) - return FALSE; - - mime_type = g_content_type_get_mime_type (content_type); - is_image = (g_ascii_strncasecmp (mime_type, "image/", 6) == 0); - g_free (mime_type); - - return is_image; -} - gboolean e_attachment_is_rfc822 (EAttachment *attachment) { @@ -1805,7 +1780,6 @@ struct _OpenContext { GSimpleAsyncResult *simple; GAppInfo *app_info; - GFile *file; }; static OpenContext * @@ -1836,9 +1810,6 @@ attachment_open_context_free (OpenContext *open_context) if (open_context->app_info != NULL) g_object_unref (open_context->app_info); - if (open_context->file != NULL) - g_object_unref (open_context->file); - g_slice_free (OpenContext, open_context); } @@ -1865,7 +1836,8 @@ attachment_open_check_for_error (OpenContext *open_context, } static void -attachment_open_file (OpenContext *open_context) +attachment_open_file (GFile *file, + OpenContext *open_context) { GdkAppLaunchContext *context; GSimpleAsyncResult *simple; @@ -1900,7 +1872,7 @@ attachment_open_file (OpenContext *open_context) goto exit; context = gdk_app_launch_context_new (); - file_list = g_list_prepend (NULL, open_context->file); + file_list = g_list_prepend (NULL, file); success = g_app_info_launch ( open_context->app_info, file_list, @@ -1926,19 +1898,22 @@ attachment_open_save_finished_cb (EAttachment *attachment, GAsyncResult *result, OpenContext *open_context) { + GFile *file; GError *error = NULL; - e_attachment_save_finish (attachment, result, &error); + file = e_attachment_save_finish (attachment, result, &error); if (attachment_open_check_for_error (open_context, error)) return; - attachment_open_file (open_context); + attachment_open_file (file, open_context); + g_object_unref (file); } static void attachment_open_save_temporary (OpenContext *open_context) { + GFile *file; gchar *path; gint fd; GError *error = NULL; @@ -1948,14 +1923,16 @@ attachment_open_save_temporary (OpenContext *open_context) if (attachment_open_check_for_error (open_context, error)) return; - close (fd); + file = g_file_new_for_path (path); - open_context->file = g_file_new_for_path (path); + close (fd); + g_free (path); e_attachment_save_async ( - open_context->attachment, open_context->file, - (GAsyncReadyCallback) attachment_open_save_finished_cb, - open_context); + open_context->attachment, file, (GAsyncReadyCallback) + attachment_open_save_finished_cb, open_context); + + g_object_unref (file); } void @@ -1985,8 +1962,7 @@ e_attachment_open_async (EAttachment *attachment, * the application directly. Otherwise we have to save the MIME * part to a temporary file and launch the application from that. */ if (file != NULL) { - open_context->file = g_object_ref (file); - attachment_open_file (open_context); + attachment_open_file (file, open_context); } else if (mime_part != NULL) attachment_open_save_temporary (open_context); @@ -2071,6 +2047,7 @@ struct _SaveContext { GSimpleAsyncResult *simple; GFile *directory; + GFile *destination; GInputStream *input_stream; GOutputStream *output_stream; goffset total_num_bytes; @@ -2115,6 +2092,9 @@ attachment_save_context_free (SaveContext *save_context) if (save_context->directory != NULL) g_object_unref (save_context->directory); + if (save_context->destination != NULL) + g_object_unref (save_context->destination); + if (save_context->input_stream != NULL) g_object_unref (save_context->input_stream); @@ -2259,12 +2239,18 @@ attachment_save_read_cb (GInputStream *input_stream, if (bytes_read == 0) { GSimpleAsyncResult *simple; + GFile *destination; /* Steal the result. */ simple = save_context->simple; save_context->simple = NULL; - g_simple_async_result_set_op_res_gboolean (simple, TRUE); + /* Steal the destination. */ + destination = save_context->destination; + save_context->destination = NULL; + + g_simple_async_result_set_op_res_gpointer ( + simple, destination, (GDestroyNotify) g_object_unref); g_simple_async_result_complete (simple); attachment_save_context_free (save_context); @@ -2366,6 +2352,7 @@ attachment_save_create_cb (GFile *destination, if (attachment_save_check_for_error (save_context, error)) return; + save_context->destination = g_object_ref (destination); attachment_save_got_output_stream (save_context); } @@ -2384,6 +2371,7 @@ attachment_save_replace_cb (GFile *destination, if (attachment_save_check_for_error (save_context, error)) return; + save_context->destination = g_object_ref (destination); attachment_save_got_output_stream (save_context); } @@ -2490,26 +2478,28 @@ e_attachment_save_async (EAttachment *attachment, attachment_save_query_info_cb, save_context); } -gboolean +GFile * e_attachment_save_finish (EAttachment *attachment, GAsyncResult *result, GError **error) { GSimpleAsyncResult *simple; - gboolean success; + GFile *destination; g_return_val_if_fail ( g_simple_async_result_is_valid (result, G_OBJECT (attachment), e_attachment_save_async), FALSE); simple = G_SIMPLE_ASYNC_RESULT (result); - success = g_simple_async_result_get_op_res_gboolean (simple); + destination = g_simple_async_result_get_op_res_gpointer (simple); + if (destination != NULL) + g_object_ref (destination); g_simple_async_result_propagate_error (simple, error); g_object_unref (simple); attachment_set_saving (attachment, FALSE); - return success; + return destination; } void @@ -2517,8 +2507,9 @@ e_attachment_save_handle_error (EAttachment *attachment, GAsyncResult *result, GtkWindow *parent) { - GtkWidget *dialog; + GFile *file; GFileInfo *file_info; + GtkWidget *dialog; const gchar *display_name; const gchar *primary_text; GError *error = NULL; @@ -2527,8 +2518,9 @@ e_attachment_save_handle_error (EAttachment *attachment, g_return_if_fail (G_IS_ASYNC_RESULT (result)); g_return_if_fail (GTK_IS_WINDOW (parent)); - if (e_attachment_save_finish (attachment, result, &error)) - return; + file = e_attachment_save_finish (attachment, result, &error); + if (file != NULL) + g_object_unref (file); /* Ignore cancellations. */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 8a13da2909..1184b32012 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -98,7 +98,6 @@ void e_attachment_set_signed (EAttachment *attachment, camel_cipher_validity_sign_t signed_); const gchar * e_attachment_get_description (EAttachment *attachment); const gchar * e_attachment_get_thumbnail_path (EAttachment *attachment); -gboolean e_attachment_is_image (EAttachment *attachment); gboolean e_attachment_is_rfc822 (EAttachment *attachment); GList * e_attachment_list_apps (EAttachment *attachment); @@ -120,7 +119,7 @@ void e_attachment_save_async (EAttachment *attachment, GFile *destination, GAsyncReadyCallback callback, gpointer user_data); -gboolean e_attachment_save_finish (EAttachment *attachment, +GFile * e_attachment_save_finish (EAttachment *attachment, GAsyncResult *result, GError **error); -- cgit v1.2.3 From 3a6dd7931ed7787b49a574ebe69eba5f46289fff Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Apr 2009 22:58:10 +0000 Subject: Finish attachment drag and drop. Expunge em-popup.c of dead code. Not much left. Kill the save-attachments (experimental) plugin. The attachment bar can already save all at once. svn path=/branches/kill-bonobo/; revision=37488 --- widgets/misc/Makefile.am | 2 - widgets/misc/e-attachment-handler.c | 34 ++ widgets/misc/e-attachment-handler.h | 11 + widgets/misc/e-attachment-paned.c | 17 + widgets/misc/e-attachment-paned.h | 8 + widgets/misc/e-attachment-store.c | 338 +++++++++----------- widgets/misc/e-attachment-store.h | 5 +- widgets/misc/e-attachment-view.c | 614 +++++++++++++++++------------------- widgets/misc/e-attachment-view.h | 18 +- widgets/misc/e-attachment.c | 25 +- widgets/misc/e-mime-part-utils.c | 223 ------------- widgets/misc/e-mime-part-utils.h | 46 --- 12 files changed, 532 insertions(+), 809 deletions(-) delete mode 100644 widgets/misc/e-mime-part-utils.c delete mode 100644 widgets/misc/e-mime-part-utils.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ad2f445eea..8ba66287f8 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -70,7 +70,6 @@ widgetsinclude_HEADERS = \ e-image-chooser.h \ e-map.h \ e-menu-tool-button.h \ - e-mime-part-utils.h \ e-online-button.h \ e-popup-action.h \ e-popup-menu.h \ @@ -134,7 +133,6 @@ libemiscwidgets_la_SOURCES = \ e-image-chooser.c \ e-map.c \ e-menu-tool-button.c \ - e-mime-part-utils.c \ e-online-button.c \ e-popup-action.c \ e-popup-menu.c \ diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c index dce139f9c3..03af1eec9b 100644 --- a/widgets/misc/e-attachment-handler.c +++ b/widgets/misc/e-attachment-handler.c @@ -155,3 +155,37 @@ e_attachment_handler_get_view (EAttachmentHandler *handler) return E_ATTACHMENT_VIEW (handler->priv->view); } + +GdkDragAction +e_attachment_handler_get_drag_actions (EAttachmentHandler *handler) +{ + EAttachmentHandlerClass *class; + + g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), 0); + + class = E_ATTACHMENT_HANDLER_GET_CLASS (handler); + + if (class->get_drag_actions != NULL) + return class->get_drag_actions (handler); + + return 0; +} + +const GtkTargetEntry * +e_attachment_handler_get_target_table (EAttachmentHandler *handler, + guint *n_targets) +{ + EAttachmentHandlerClass *class; + + g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), NULL); + + class = E_ATTACHMENT_HANDLER_GET_CLASS (handler); + + if (class->get_target_table != NULL) + return class->get_target_table (handler, n_targets); + + if (n_targets != NULL) + *n_targets = 0; + + return NULL; +} diff --git a/widgets/misc/e-attachment-handler.h b/widgets/misc/e-attachment-handler.h index 8de5743ba6..05df3e8bbe 100644 --- a/widgets/misc/e-attachment-handler.h +++ b/widgets/misc/e-attachment-handler.h @@ -56,11 +56,22 @@ struct _EAttachmentHandler { struct _EAttachmentHandlerClass { GObjectClass parent_class; + + GdkDragAction (*get_drag_actions) (EAttachmentHandler *handler); + const GtkTargetEntry * + (*get_target_table) (EAttachmentHandler *handler, + guint *n_targets); }; GType e_attachment_handler_get_type (void); EAttachmentView * e_attachment_handler_get_view (EAttachmentHandler *handler); +GdkDragAction e_attachment_handler_get_drag_actions + (EAttachmentHandler *handler); +const GtkTargetEntry * + e_attachment_handler_get_target_table + (EAttachmentHandler *handler, + guint *n_targets); G_END_DECLS diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index 42890236e9..f9f7bb1cca 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -729,3 +729,20 @@ e_attachment_paned_set_expanded (EAttachmentPaned *paned, g_object_notify (G_OBJECT (paned), "expanded"); } + +void +e_attachment_paned_drag_data_received (EAttachmentPaned *paned, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time) +{ + g_return_if_fail (E_IS_ATTACHMENT_PANED (paned)); + + /* XXX Dirty hack for forwarding drop events. */ + g_signal_emit_by_name ( + paned->priv->icon_view, "drag-data-received", + context, x, y, selection, info, time); +} diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h index c15d642771..076ab6033e 100644 --- a/widgets/misc/e-attachment-paned.h +++ b/widgets/misc/e-attachment-paned.h @@ -70,6 +70,14 @@ void e_attachment_paned_set_active_view gboolean e_attachment_paned_get_expanded (EAttachmentPaned *paned); void e_attachment_paned_set_expanded (EAttachmentPaned *paned, gboolean expanded); +void e_attachment_paned_drag_data_received + (EAttachmentPaned *paned, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time); G_END_DECLS diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index e565d68cae..589f670f34 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -21,10 +21,12 @@ #include "e-attachment-store.h" +#include +#include #include #include "e-util/e-util.h" -#include "e-util/gconf-bridge.h" +#include "e-util/e-mktemp.h" #define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -32,8 +34,6 @@ struct _EAttachmentStorePrivate { GHashTable *attachment_index; - gchar *background_filename; - gchar *background_options; gchar *current_folder; guint ignore_row_changed : 1; @@ -41,8 +41,6 @@ struct _EAttachmentStorePrivate { enum { PROP_0, - PROP_BACKGROUND_FILENAME, - PROP_BACKGROUND_OPTIONS, PROP_CURRENT_FOLDER, PROP_NUM_ATTACHMENTS, PROP_NUM_LOADING, @@ -51,44 +49,6 @@ enum { static gpointer parent_class; -static const gchar * -attachment_store_get_background_filename (EAttachmentStore *store) -{ - return store->priv->background_filename; -} - -static void -attachment_store_set_background_filename (EAttachmentStore *store, - const gchar *background_filename) -{ - if (background_filename == NULL) - background_filename = ""; - - g_free (store->priv->background_filename); - store->priv->background_filename = g_strdup (background_filename); - - g_object_notify (G_OBJECT (store), "background-filename"); -} - -static const gchar * -attachment_store_get_background_options (EAttachmentStore *store) -{ - return store->priv->background_options; -} - -static void -attachment_store_set_background_options (EAttachmentStore *store, - const gchar *background_options) -{ - if (background_options == NULL) - background_options = ""; - - g_free (store->priv->background_options); - store->priv->background_options = g_strdup (background_options); - - g_object_notify (G_OBJECT (store), "background-options"); -} - static void attachment_store_set_property (GObject *object, guint property_id, @@ -96,18 +56,6 @@ attachment_store_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BACKGROUND_FILENAME: - attachment_store_set_background_filename ( - E_ATTACHMENT_STORE (object), - g_value_get_string (value)); - return; - - case PROP_BACKGROUND_OPTIONS: - attachment_store_set_background_options ( - E_ATTACHMENT_STORE (object), - g_value_get_string (value)); - return; - case PROP_CURRENT_FOLDER: e_attachment_store_set_current_folder ( E_ATTACHMENT_STORE (object), @@ -125,20 +73,6 @@ attachment_store_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_BACKGROUND_FILENAME: - g_value_set_string ( - value, - attachment_store_get_background_filename ( - E_ATTACHMENT_STORE (object))); - return; - - case PROP_BACKGROUND_OPTIONS: - g_value_set_string ( - value, - attachment_store_get_background_options ( - E_ATTACHMENT_STORE (object))); - return; - case PROP_CURRENT_FOLDER: g_value_set_string ( value, @@ -193,34 +127,12 @@ attachment_store_finalize (GObject *object) g_hash_table_destroy (priv->attachment_index); - g_free (priv->background_filename); - g_free (priv->background_options); g_free (priv->current_folder); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } -static void -attachment_store_constructed (GObject *object) -{ - EAttachmentStorePrivate *priv; - GConfBridge *bridge; - const gchar *prop; - const gchar *key; - - priv = E_ATTACHMENT_STORE_GET_PRIVATE (object); - bridge = gconf_bridge_get (); - - prop = "background-filename"; - key = "/desktop/gnome/background/picture_filename"; - gconf_bridge_bind_property (bridge, key, object, prop); - - prop = "background-options"; - key = "/desktop/gnome/background/picture_options"; - gconf_bridge_bind_property (bridge, key, object, prop); -} - static void attachment_store_class_init (EAttachmentStoreClass *class) { @@ -234,29 +146,6 @@ attachment_store_class_init (EAttachmentStoreClass *class) object_class->get_property = attachment_store_get_property; object_class->dispose = attachment_store_dispose; object_class->finalize = attachment_store_finalize; - object_class->constructed = attachment_store_constructed; - - g_object_class_install_property ( - object_class, - PROP_BACKGROUND_FILENAME, - g_param_spec_string ( - "background-filename", - "Background Filename", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_BACKGROUND_OPTIONS, - g_param_spec_string ( - "background-options", - "Background Options", - NULL, - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, @@ -737,101 +626,124 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, return destination; } -/******************* e_attachment_store_save_list_async() ********************/ +/******************** e_attachment_store_get_uris_async() ********************/ -typedef struct _SaveContext SaveContext; +typedef struct _UriContext UriContext; -struct _SaveContext { +struct _UriContext { GSimpleAsyncResult *simple; GList *attachment_list; GError *error; + gchar **uris; + gint index; }; -static SaveContext * -attachment_store_save_context_new (EAttachmentStore *store, - GList *attachment_list, - GAsyncReadyCallback callback, - gpointer user_data) +static UriContext * +attachment_store_uri_context_new (EAttachmentStore *store, + GList *attachment_list, + GAsyncReadyCallback callback, + gpointer user_data) { - SaveContext *save_context; + UriContext *uri_context; GSimpleAsyncResult *simple; + guint length; + gchar **uris; simple = g_simple_async_result_new ( G_OBJECT (store), callback, user_data, - e_attachment_store_save_list_async); + e_attachment_store_get_uris_async); + + /* Add one for NULL terminator. */ + length = g_list_length (attachment_list) + 1; + uris = g_malloc0 (sizeof (gchar *) * length); - save_context = g_slice_new0 (SaveContext); - save_context->simple = simple; - save_context->attachment_list = g_list_copy (attachment_list); + uri_context = g_slice_new0 (UriContext); + uri_context->simple = simple; + uri_context->attachment_list = g_list_copy (attachment_list); + uri_context->uris = uris; g_list_foreach ( - save_context->attachment_list, + uri_context->attachment_list, (GFunc) g_object_ref, NULL); - return save_context; + return uri_context; } static void -attachment_store_save_context_free (SaveContext *save_context) +attachment_store_uri_context_free (UriContext *uri_context) { /* Do not free the GSimpleAsyncResult. */ /* The attachment list should be empty now. */ - g_warn_if_fail (save_context->attachment_list != NULL); + g_warn_if_fail (uri_context->attachment_list == NULL); /* So should the error. */ - g_warn_if_fail (save_context->error != NULL); + g_warn_if_fail (uri_context->error == NULL); - g_slice_free (SaveContext, save_context); + g_strfreev (uri_context->uris); + + g_slice_free (UriContext, uri_context); } static void -attachment_store_save_list_finished_cb (EAttachment *attachment, - GAsyncResult *result, - SaveContext *save_context) +attachment_store_get_uris_save_cb (EAttachment *attachment, + GAsyncResult *result, + UriContext *uri_context) { - GFile *file; GSimpleAsyncResult *simple; + GFile *file; + gchar **uris; + gchar *uri; GError *error = NULL; file = e_attachment_save_finish (attachment, result, &error); - if (file != NULL) - g_object_unref (file); /* Remove the attachment from the list. */ - save_context->attachment_list = g_list_remove ( - save_context->attachment_list, attachment); + uri_context->attachment_list = g_list_remove ( + uri_context->attachment_list, attachment); g_object_unref (attachment); - /* If this is the first error, cancel the other jobs. */ - if (error != NULL && save_context->error == NULL) { - g_propagate_error (&save_context->error, error); - g_list_foreach ( - save_context->attachment_list, - (GFunc) e_attachment_cancel, NULL); + if (file != NULL) { + uri = g_file_get_uri (file); + uri_context->uris[uri_context->index++] = uri; + g_object_unref (file); - /* Otherwise, we can only report back one error. So if this is - * something other than cancellation, dump it to the terminal. */ - } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s", error->message); + } else if (error != NULL) { + /* If this is the first error, cancel the other jobs. */ + if (uri_context->error == NULL) { + g_propagate_error (&uri_context->error, error); + g_list_foreach ( + uri_context->attachment_list, + (GFunc) e_attachment_cancel, NULL); + + /* Otherwise, we can only report back one error. So if + * this is something other than cancellation, dump it to + * the terminal. */ + } else if (!g_error_matches ( + error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s", error->message); - if (error != NULL) g_error_free (error); + } /* If there's still jobs running, let them finish. */ - if (save_context->attachment_list != NULL) + if (uri_context->attachment_list != NULL) return; /* Steal the result. */ - simple = save_context->simple; - save_context->simple = NULL; + simple = uri_context->simple; + uri_context->simple = NULL; - /* Steal the error, too. */ - error = save_context->error; - save_context->error = NULL; + /* And the URI list. */ + uris = uri_context->uris; + uri_context->uris = NULL; + + /* And the error. */ + error = uri_context->error; + uri_context->error = NULL; if (error == NULL) - g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); else { g_simple_async_result_set_from_error (simple, error); g_error_free (error); @@ -839,63 +751,109 @@ attachment_store_save_list_finished_cb (EAttachment *attachment, g_simple_async_result_complete (simple); - attachment_store_save_context_free (save_context); + attachment_store_uri_context_free (uri_context); } void -e_attachment_store_save_list_async (EAttachmentStore *store, - GList *attachment_list, - GFile *destination, - GAsyncReadyCallback callback, - gpointer user_data) +e_attachment_store_get_uris_async (EAttachmentStore *store, + GList *attachment_list, + GAsyncReadyCallback callback, + gpointer user_data) { - SaveContext *save_context; + GFile *temp_directory; + UriContext *uri_context; + GList *iter, *trash = NULL; + gchar *template; + gchar *path; g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (G_IS_FILE (destination)); g_return_if_fail (callback != NULL); - /* Passing an empty list is silly, but we'll handle it. */ - if (attachment_list == NULL) { + uri_context = attachment_store_uri_context_new ( + store, attachment_list, callback, user_data); + + /* Grab the copied attachment list. */ + attachment_list = uri_context->attachment_list; + + /* First scan the list for attachments with a GFile. */ + for (iter = attachment_list; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + GFile *file; + gchar *uri; + + file = e_attachment_get_file (attachment); + if (file == NULL) + continue; + + uri = g_file_get_uri (file); + uri_context->uris[uri_context->index++] = uri; + + /* Mark the list node for deletion. */ + trash = g_list_prepend (trash, iter); + g_object_unref (attachment); + } + + /* Expunge the list. */ + for (iter = trash; iter != NULL; iter = iter->next) { + GList *link = iter->data; + attachment_list = g_list_delete_link (attachment_list, link); + } + g_list_free (trash); + + uri_context->attachment_list = attachment_list; + + /* Any remaining attachments in the list should have MIME parts + * only, so we need to save them all to a temporary directory. + * We use a directory so the files can retain their basenames. */ + template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); + path = e_mkdtemp (template); + g_free (template); + + if (path == NULL) { GSimpleAsyncResult *simple; - simple = g_simple_async_result_new ( - G_OBJECT (store), callback, user_data, - e_attachment_store_save_list_async); - g_simple_async_result_set_op_res_gboolean (simple, TRUE); + /* Steal the result. */ + simple = uri_context->simple; + uri_context->simple = NULL; + + g_simple_async_result_set_error ( + simple, G_FILE_ERROR, + g_file_error_from_errno (errno), + "%s", g_strerror (errno)); + g_simple_async_result_complete_in_idle (simple); + attachment_store_uri_context_free (uri_context); return; } - save_context = attachment_store_save_context_new ( - store, attachment_list, callback, user_data); + temp_directory = g_file_new_for_path (path); - while (attachment_list != NULL) { + for (iter = attachment_list; iter != NULL; iter = iter->next) e_attachment_save_async ( - E_ATTACHMENT (attachment_list->data), - destination, (GAsyncReadyCallback) - attachment_store_save_list_finished_cb, - save_context); - attachment_list = g_list_next (attachment_list); - } + E_ATTACHMENT (iter->data), + temp_directory, (GAsyncReadyCallback) + attachment_store_get_uris_save_cb, + uri_context); + + g_object_unref (temp_directory); } -gboolean -e_attachment_store_save_list_finish (EAttachmentStore *store, - GAsyncResult *result, - GError **error) +gchar ** +e_attachment_store_get_uris_finish (EAttachmentStore *store, + GAsyncResult *result, + GError **error) { GSimpleAsyncResult *simple; - gboolean success; + gchar **uris; g_return_val_if_fail ( g_simple_async_result_is_valid (result, G_OBJECT (store), - e_attachment_store_save_list_async), FALSE); + e_attachment_store_get_uris_async), FALSE); simple = G_SIMPLE_ASYNC_RESULT (result); - success = g_simple_async_result_get_op_res_gboolean (simple); + uris = g_simple_async_result_get_op_res_gpointer (simple); g_simple_async_result_propagate_error (simple, error); g_object_unref (simple); - return success; + return uris; } diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index c672cb3c34..a6dd702b97 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -107,13 +107,12 @@ GFile * e_attachment_store_run_save_dialog GtkWindow *parent); /* Asynchronous Operations */ -void e_attachment_store_save_list_async +void e_attachment_store_get_uris_async (EAttachmentStore *store, GList *attachment_list, - GFile *destination, GAsyncReadyCallback callback, gpointer user_data); -gboolean e_attachment_store_save_list_finish +gchar ** e_attachment_store_get_uris_finish (EAttachmentStore *store, GAsyncResult *result, GError **error); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index b2dc62b934..d6dff653cc 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -36,38 +36,11 @@ enum { LAST_SIGNAL }; -enum { - DND_TYPE_MESSAGE_RFC822, - DND_TYPE_X_UID_LIST, - DND_TYPE_TEXT_URI_LIST, - DND_TYPE_NETSCAPE_URL, - DND_TYPE_TEXT_VCARD, - DND_TYPE_TEXT_CALENDAR -}; - -static GtkTargetEntry drop_types[] = { - { "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 }, - { "x-uid-list", 0, DND_TYPE_X_UID_LIST }, - { "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST }, - { "_NETSCAPE_URL", 0, DND_TYPE_NETSCAPE_URL }, - { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD }, - { "text/calendar", 0, DND_TYPE_TEXT_CALENDAR } -}; - -/* The atoms need initialized at runtime. */ -static struct { - const gchar *target; - GdkAtom atom; - GdkDragAction actions; -} drag_info[] = { - { "message/rfc822", NULL, GDK_ACTION_COPY }, - { "x-uid-list", NULL, GDK_ACTION_COPY | - GDK_ACTION_MOVE | - GDK_ACTION_ASK }, - { "text/uri-list", NULL, GDK_ACTION_COPY }, - { "_NETSCAPE_URL", NULL, GDK_ACTION_COPY }, - { "text/x-vcard", NULL, GDK_ACTION_COPY }, - { "text/calendar", NULL, GDK_ACTION_COPY } +/* Note: Do not use the info field. */ +static GtkTargetEntry target_table[] = { + { "_NETSCAPE_URL", 0, 0 }, + { "text/x-vcard", 0, 0 }, + { "text/calendar", 0, 0 } }; static const gchar *ui = @@ -84,12 +57,6 @@ static const gchar *ui = " " " " " " -" " -" " -" " -" " -" " -" " ""; static gulong signals[LAST_SIGNAL]; @@ -125,30 +92,6 @@ action_cancel_cb (GtkAction *action, g_list_free (selected); } -static void -action_drag_cancel_cb (GtkAction *action, - EAttachmentView *view) -{ - EAttachmentViewPrivate *priv; - - priv = e_attachment_view_get_private (view); - gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); -} - -static void -action_drag_copy_cb (GtkAction *action, - EAttachmentView *view) -{ - e_attachment_view_drag_action (view, GDK_ACTION_COPY); -} - -static void -action_drag_move_cb (GtkAction *action, - EAttachmentView *view) -{ - e_attachment_view_drag_action (view, GDK_ACTION_MOVE); -} - static void action_open_in_cb (GtkAction *action, EAttachmentView *view) @@ -312,27 +255,6 @@ static GtkActionEntry standard_entries[] = { NULL, /* XXX Add a tooltip! */ G_CALLBACK (action_cancel_cb) }, - { "drag-cancel", - NULL, - N_("Cancel _Drag"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_drag_cancel_cb) }, - - { "drag-copy", - NULL, - N_("_Copy"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_drag_copy_cb) }, - - { "drag-move", - NULL, - N_("_Move"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_drag_move_cb) }, - { "save-all", GTK_STOCK_SAVE_AS, N_("S_ave All"), @@ -382,159 +304,153 @@ static GtkActionEntry editable_entries[] = { }; static void -drop_message_rfc822 (EAttachmentView *view, - GtkSelectionData *selection_data, - EAttachmentStore *store, - GdkDragAction action) +attachment_view_netscape_url (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) { - EAttachmentViewPrivate *priv; + static GdkAtom atom = GDK_NONE; + EAttachmentStore *store; EAttachment *attachment; - CamelMimeMessage *message; - CamelDataWrapper *wrapper; - CamelStream *stream; const gchar *data; - gboolean success = FALSE; - gboolean delete = FALSE; gpointer parent; + gchar *copied_data; + gchar **strv; gint length; - priv = e_attachment_view_get_private (view); + if (G_UNLIKELY (atom == GDK_NONE)) + atom = gdk_atom_intern_static_string ("_NETSCAPE_URL"); + + if (gtk_selection_data_get_target (selection_data) != atom) + return; + + g_signal_stop_emission_by_name (view, "drag-data-received"); + + /* _NETSCAPE_URL is represented as "URI\nTITLE" */ data = (const gchar *) gtk_selection_data_get_data (selection_data); length = gtk_selection_data_get_length (selection_data); - stream = camel_stream_mem_new (); - camel_stream_write (stream, data, length); - camel_stream_reset (stream); - - message = camel_mime_message_new (); - wrapper = CAMEL_DATA_WRAPPER (message); + copied_data = g_strndup (data, length); + strv = g_strsplit (copied_data, "\n", 2); + g_free (copied_data); - if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1) - goto exit; + store = e_attachment_view_get_store (view); parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - attachment = e_attachment_new_for_message (message); + attachment = e_attachment_new_for_uri (strv[0]); e_attachment_store_add_attachment (store, attachment); e_attachment_load_async ( attachment, (GAsyncReadyCallback) e_attachment_load_handle_error, parent); g_object_unref (attachment); - success = TRUE; - delete = (action == GDK_ACTION_MOVE); - -exit: - camel_object_unref (message); - camel_object_unref (stream); + g_strfreev (strv); - gtk_drag_finish (priv->drag_context, success, delete, priv->time); + gtk_drag_finish (drag_context, TRUE, FALSE, time); } static void -drop_netscape_url (EAttachmentView *view, - GtkSelectionData *selection_data, - EAttachmentStore *store, - GdkDragAction action) +attachment_view_text_calendar (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) { - EAttachmentViewPrivate *priv; + static GdkAtom atom = GDK_NONE; + EAttachmentStore *store; EAttachment *attachment; + CamelMimePart *mime_part; + GdkAtom data_type; const gchar *data; gpointer parent; - gchar *copied_data; - gchar **strv; + gchar *content_type; gint length; - /* _NETSCAPE_URL is represented as "URI\nTITLE" */ + if (G_UNLIKELY (atom = GDK_NONE)) + atom = gdk_atom_intern_static_string ("text/calendar"); - priv = e_attachment_view_get_private (view); + if (gtk_selection_data_get_target (selection_data) != atom) + return; + + g_signal_stop_emission_by_name (view, "drag-data-received"); data = (const gchar *) gtk_selection_data_get_data (selection_data); length = gtk_selection_data_get_length (selection_data); + data_type = gtk_selection_data_get_data_type (selection_data); - copied_data = g_strndup (data, length); - strv = g_strsplit (copied_data, "\n", 2); - g_free (copied_data); + mime_part = camel_mime_part_new (); + + content_type = gdk_atom_name (data_type); + camel_mime_part_set_content (mime_part, data, length, content_type); + camel_mime_part_set_disposition (mime_part, "inline"); + g_free (content_type); + + store = e_attachment_view_get_store (view); parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - attachment = e_attachment_new_for_uri (strv[0]); + attachment = e_attachment_new (); + e_attachment_set_mime_part (attachment, mime_part); e_attachment_store_add_attachment (store, attachment); e_attachment_load_async ( attachment, (GAsyncReadyCallback) e_attachment_load_handle_error, parent); g_object_unref (attachment); - g_strfreev (strv); - - gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); -} - -static void -drop_text_uri_list (EAttachmentView *view, - GtkSelectionData *selection_data, - EAttachmentStore *store, - GdkDragAction action) -{ - EAttachmentViewPrivate *priv; - gpointer parent; - gchar **uris; - gint ii; - - priv = e_attachment_view_get_private (view); - - uris = gtk_selection_data_get_uris (selection_data); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); - parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - - for (ii = 0; uris[ii] != NULL; ii++) { - EAttachment *attachment; - - attachment = e_attachment_new_for_uri (uris[ii]); - e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, parent); - g_object_unref (attachment); - } - - g_strfreev (uris); + camel_object_unref (mime_part); - gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); + gtk_drag_finish (drag_context, TRUE, FALSE, time); } static void -drop_text_generic (EAttachmentView *view, - GtkSelectionData *selection_data, - EAttachmentStore *store, - GdkDragAction action) +attachment_view_text_x_vcard (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) { - EAttachmentViewPrivate *priv; + static GdkAtom atom = GDK_NONE; + EAttachmentStore *store; EAttachment *attachment; CamelMimePart *mime_part; - GdkAtom atom; + GdkAtom data_type; const gchar *data; gpointer parent; gchar *content_type; gint length; - priv = e_attachment_view_get_private (view); + if (G_UNLIKELY (atom = GDK_NONE)) + atom = gdk_atom_intern_static_string ("text/x-vcard"); + + if (gtk_selection_data_get_target (selection_data) != atom) + return; + + g_signal_stop_emission_by_name (view, "drag-data-received"); data = (const gchar *) gtk_selection_data_get_data (selection_data); length = gtk_selection_data_get_length (selection_data); - atom = gtk_selection_data_get_data_type (selection_data); + data_type = gtk_selection_data_get_data_type (selection_data); mime_part = camel_mime_part_new (); - content_type = gdk_atom_name (atom); + content_type = gdk_atom_name (data_type); camel_mime_part_set_content (mime_part, data, length, content_type); camel_mime_part_set_disposition (mime_part, "inline"); g_free (content_type); + store = e_attachment_view_get_store (view); + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; @@ -548,22 +464,49 @@ drop_text_generic (EAttachmentView *view, camel_object_unref (mime_part); - gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time); + gtk_drag_finish (drag_context, TRUE, FALSE, time); } static void -drop_x_uid_list (EAttachmentView *view, - GtkSelectionData *selection_data, - EAttachmentStore *store, - GdkDragAction action) +attachment_view_uris (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) { - EAttachmentViewPrivate *priv; + EAttachmentStore *store; + gpointer parent; + gchar **uris; + gint ii; - /* FIXME Ugh, this looks painful. Requires mailer stuff. */ + uris = gtk_selection_data_get_uris (selection_data); - priv = e_attachment_view_get_private (view); + if (uris == NULL) + return; + + g_signal_stop_emission_by_name (view, "drag-data-received"); + + store = e_attachment_view_get_store (view); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + for (ii = 0; uris[ii] != NULL; ii++) { + EAttachment *attachment; + + attachment = e_attachment_new_for_uri (uris[ii]); + e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); + g_object_unref (attachment); + } - gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); + g_strfreev (uris); + + gtk_drag_finish (drag_context, TRUE, FALSE, time); } static void @@ -669,10 +612,48 @@ attachment_view_update_actions (EAttachmentView *view) } static void -attachment_view_class_init (EAttachmentViewIface *iface) +attachment_view_init_handlers (EAttachmentView *view) { - gint ii; + EAttachmentViewPrivate *priv; + GtkTargetList *target_list; + GType *children; + guint ii; + + priv = e_attachment_view_get_private (view); + + target_list = gtk_target_list_new ( + target_table, G_N_ELEMENTS (target_table)); + + gtk_target_list_add_uri_targets (target_list, 0); + + priv->handlers = g_ptr_array_new (); + priv->target_list = target_list; + priv->drag_actions = GDK_ACTION_COPY; + + children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL); + + for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) { + EAttachmentHandler *handler; + const GtkTargetEntry *targets; + guint n_targets; + + handler = g_object_new (children[ii], "view", view, NULL); + targets = e_attachment_handler_get_target_table ( + handler, &n_targets); + gtk_target_list_add_table (target_list, targets, n_targets); + priv->drag_actions |= + e_attachment_handler_get_drag_actions (handler); + + g_ptr_array_add (priv->handlers, handler); + } + + g_free (children); +} + +static void +attachment_view_class_init (EAttachmentViewIface *iface) +{ iface->update_actions = attachment_view_update_actions; g_object_interface_install_property ( @@ -693,11 +674,6 @@ attachment_view_class_init (EAttachmentViewIface *iface) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) { - const gchar *target = drag_info[ii].target; - drag_info[ii].atom = gdk_atom_intern (target, FALSE); - } } GType @@ -738,15 +714,10 @@ e_attachment_view_init (EAttachmentView *view) GtkUIManager *ui_manager; GtkActionGroup *action_group; const gchar *domain = GETTEXT_PACKAGE; - GType *children; - guint ii; GError *error = NULL; priv = e_attachment_view_get_private (view); - e_attachment_view_drag_source_set (view); - e_attachment_view_drag_dest_set (view); - ui_manager = gtk_ui_manager_new (); priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); priv->ui_manager = ui_manager; @@ -783,14 +754,28 @@ e_attachment_view_init (EAttachmentView *view) G_OBJECT (view), "editable", G_OBJECT (priv->editable_actions), "visible"); - /* Instantiate attachment handlers. */ - children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL); - for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) { - EAttachmentHandler *handler; - handler = g_object_new (children[ii], "view", view, NULL); - priv->handlers = g_list_prepend (priv->handlers, handler); - } - g_free (children); + attachment_view_init_handlers (view); + + e_attachment_view_drag_source_set (view); + e_attachment_view_drag_dest_set (view); + + /* Connect built-in drag and drop handlers. */ + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_view_netscape_url), NULL); + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_view_text_calendar), NULL); + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_view_text_x_vcard), NULL); + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_view_uris), NULL); } void @@ -800,9 +785,13 @@ e_attachment_view_dispose (EAttachmentView *view) priv = e_attachment_view_get_private (view); - g_list_foreach (priv->handlers, (GFunc) g_object_unref, NULL); - g_list_free (priv->handlers); - priv->handlers = NULL; + g_ptr_array_foreach (priv->handlers, (GFunc) g_object_unref, NULL); + g_ptr_array_set_size (priv->handlers, 0); + + if (priv->target_list != NULL) { + gtk_target_list_unref (priv->target_list); + priv->target_list = NULL; + } if (priv->ui_manager != NULL) { g_object_unref (priv->ui_manager); @@ -823,11 +812,6 @@ e_attachment_view_dispose (EAttachmentView *view) g_object_unref (priv->openwith_actions); priv->openwith_actions = NULL; } - - if (priv->drag_context != NULL) { - g_object_unref (priv->drag_context); - priv->drag_context = NULL; - } } void @@ -837,8 +821,7 @@ e_attachment_view_finalize (EAttachmentView *view) priv = e_attachment_view_get_private (view); - if (priv->selection_data != NULL) - gtk_selection_data_free (priv->selection_data); + g_ptr_array_free (priv->handlers, TRUE); } EAttachmentViewPrivate * @@ -893,6 +876,30 @@ e_attachment_view_set_editable (EAttachmentView *view, g_object_notify (G_OBJECT (view), "editable"); } +GtkTargetList * +e_attachment_view_get_target_list (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + priv = e_attachment_view_get_private (view); + + return priv->target_list; +} + +GdkDragAction +e_attachment_view_get_drag_actions (EAttachmentView *view) +{ + EAttachmentViewPrivate *priv; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), 0); + + priv = e_attachment_view_get_private (view); + + return priv->drag_actions; +} + GList * e_attachment_view_get_selected_attachments (EAttachmentView *view) { @@ -1257,6 +1264,24 @@ e_attachment_view_drag_end (EAttachmentView *view, g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); } +static void +attachment_view_got_uris_cb (EAttachmentStore *store, + GAsyncResult *result, + gpointer user_data) +{ + struct { + gchar **uris; + gboolean done; + } *status = user_data; + + /* XXX Since this is a best-effort function, + * should we care about errors? */ + status->uris = e_attachment_store_get_uris_finish ( + store, result, NULL); + + status->done = TRUE; +} + void e_attachment_view_drag_data_get (EAttachmentView *view, GdkDragContext *context, @@ -1264,56 +1289,65 @@ e_attachment_view_drag_data_get (EAttachmentView *view, guint info, guint time) { - GList *selected, *iter; - gchar **uris; - gint ii = 0; + EAttachmentStore *store; + GList *selected; + + struct { + gchar **uris; + gboolean done; + } status; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); g_return_if_fail (selection != NULL); + status.uris = NULL; + status.done = FALSE; + + store = e_attachment_view_get_store (view); + selected = e_attachment_view_get_selected_attachments (view); if (selected == NULL) return; - uris = g_malloc0 (sizeof (gchar *) * (g_list_length (selected) + 1)); + e_attachment_store_get_uris_async ( + store, selected, (GAsyncReadyCallback) + attachment_view_got_uris_cb, &status); - for (iter = selected; iter != NULL; iter = iter->next) { - EAttachment *attachment = iter->data; - GFile *file; - - /* FIXME Need to handle attachments with no GFile. */ - file = e_attachment_get_file (attachment); - if (file == NULL) - continue; + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); - uris[ii++] = g_file_get_uri (file); - } + /* We can't return until we have results, so crank + * the main loop until the callback gets triggered. */ + while (!status.done) + if (gtk_main_iteration ()) + break; - gtk_selection_data_set_uris (selection, uris); + if (status.uris != NULL) + gtk_selection_data_set_uris (selection, status.uris); - g_strfreev (uris); + g_strfreev (status.uris); } void e_attachment_view_drag_dest_set (EAttachmentView *view) { + EAttachmentViewPrivate *priv; GtkTargetEntry *targets; - GtkTargetList *list; gint n_targets; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - list = gtk_target_list_new (NULL, 0); - /* FIXME Add targets here... */ - targets = gtk_target_table_new_from_list (list, &n_targets); + priv = e_attachment_view_get_private (view); + + targets = gtk_target_table_new_from_list ( + priv->target_list, &n_targets); gtk_drag_dest_set ( GTK_WIDGET (view), GTK_DEST_DEFAULT_ALL, - targets, n_targets, GDK_ACTION_COPY); + targets, n_targets, priv->drag_actions); gtk_target_table_free (targets, n_targets); - gtk_target_list_unref (list); } void @@ -1324,61 +1358,6 @@ e_attachment_view_drag_dest_unset (EAttachmentView *view) gtk_drag_dest_unset (GTK_WIDGET (view)); } -void -e_attachment_view_drag_action (EAttachmentView *view, - GdkDragAction action) -{ - EAttachmentViewPrivate *priv; - GtkSelectionData *selection_data; - EAttachmentStore *store; - GdkAtom atom; - gchar *name; - - g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - - priv = e_attachment_view_get_private (view); - - selection_data = priv->selection_data; - store = e_attachment_view_get_store (view); - atom = gtk_selection_data_get_data_type (selection_data); - - switch (priv->info) { - case DND_TYPE_MESSAGE_RFC822: - drop_message_rfc822 ( - view, selection_data, store, action); - return; - - case DND_TYPE_NETSCAPE_URL: - drop_netscape_url ( - view, selection_data, store, action); - return; - - case DND_TYPE_TEXT_URI_LIST: - drop_text_uri_list ( - view, selection_data, store, action); - return; - - case DND_TYPE_TEXT_VCARD: - case DND_TYPE_TEXT_CALENDAR: - drop_text_generic ( - view, selection_data, store, action); - return; - - case DND_TYPE_X_UID_LIST: - drop_x_uid_list ( - view, selection_data, store, action); - return; - - default: - name = gdk_atom_name (atom); - g_warning ("Unknown drag type: %s", name); - g_free (name); - break; - } - - gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time); -} - gboolean e_attachment_view_drag_motion (EAttachmentView *view, GdkDragContext *context, @@ -1386,27 +1365,20 @@ e_attachment_view_drag_motion (EAttachmentView *view, gint y, guint time) { - GList *iter; - GdkDragAction actions = 0; + EAttachmentViewPrivate *priv; + GdkDragAction actions; GdkDragAction chosen_action; g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE); g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE); + priv = e_attachment_view_get_private (view); + /* Disallow drops if we're not editable. */ if (!e_attachment_view_get_editable (view)) return FALSE; - for (iter = context->targets; iter != NULL; iter = iter->next) { - GdkAtom atom = iter->data; - gint ii; - - for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) - if (atom == drag_info[ii].atom) - actions |= drag_info[ii].actions; - } - - actions &= context->actions; + actions = priv->drag_actions & context->actions; chosen_action = context->suggested_action; if (chosen_action == GDK_ACTION_ASK) { @@ -1441,53 +1413,31 @@ e_attachment_view_drag_drop (EAttachmentView *view, void e_attachment_view_drag_data_received (EAttachmentView *view, - GdkDragContext *context, + GdkDragContext *drag_context, gint x, gint y, - GtkSelectionData *selection, + GtkSelectionData *selection_data, guint info, guint time) { - EAttachmentViewPrivate *priv; - GtkUIManager *ui_manager; - GdkDragAction action; + GdkAtom atom; + gchar *name; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); - g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - g_return_if_fail (selection != NULL); - - priv = e_attachment_view_get_private (view); - ui_manager = e_attachment_view_get_ui_manager (view); + g_return_if_fail (GDK_IS_DRAG_CONTEXT (drag_context)); - action = context->action; + /* Drop handlers are supposed to stop further emission of the + * "drag-data-received" signal if they can handle the data. If + * we get this far it means none of the handlers were successful, + * so report the drop as failed. */ - if (gtk_selection_data_get_data (selection) == NULL) - return; - - if (gtk_selection_data_get_length (selection) == -1) - return; - - if (priv->drag_context != NULL) - g_object_unref (priv->drag_context); - - if (priv->selection_data != NULL) - gtk_selection_data_free (priv->selection_data); + atom = gtk_selection_data_get_target (selection_data); - priv->drag_context = g_object_ref (context); - priv->selection_data = gtk_selection_data_copy (selection); - priv->info = info; - priv->time = time; + name = gdk_atom_name (atom); + g_warning ("Unknown selection target: %s", name); + g_free (name); - if (action == GDK_ACTION_ASK) { - GtkWidget *menu; - - menu = gtk_ui_manager_get_widget (ui_manager, "/dnd"); - g_return_if_fail (GTK_IS_MENU (menu)); - - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, time); - } else - e_attachment_view_drag_action (view, action); + gtk_drag_finish (drag_context, FALSE, FALSE, time); } GtkAction * diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 16a7ac1967..8b625d0d8a 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -93,7 +93,11 @@ struct _EAttachmentViewIface { struct _EAttachmentViewPrivate { /* Attachment Handlers */ - GList *handlers; + GPtrArray *handlers; + + /* Drag Destination */ + GtkTargetList *target_list; + GdkDragAction drag_actions; /* Popup Menu Management */ GtkUIManager *ui_manager; @@ -102,12 +106,6 @@ struct _EAttachmentViewPrivate { GtkActionGroup *openwith_actions; guint merge_id; - /* Drag and Drop State */ - GdkDragContext *drag_context; - GtkSelectionData *selection_data; - guint info; - guint time; - guint editable : 1; }; @@ -124,6 +122,10 @@ EAttachmentStore * gboolean e_attachment_view_get_editable (EAttachmentView *view); void e_attachment_view_set_editable (EAttachmentView *view, gboolean editable); +GtkTargetList * e_attachment_view_get_target_list + (EAttachmentView *view); +GdkDragAction e_attachment_view_get_drag_actions + (EAttachmentView *view); GList * e_attachment_view_get_selected_attachments (EAttachmentView *view); void e_attachment_view_open_path (EAttachmentView *view, @@ -182,8 +184,6 @@ void e_attachment_view_drag_data_get (EAttachmentView *view, void e_attachment_view_drag_dest_set (EAttachmentView *view); void e_attachment_view_drag_dest_unset (EAttachmentView *view); -void e_attachment_view_drag_action (EAttachmentView *view, - GdkDragAction action); gboolean e_attachment_view_drag_motion (EAttachmentView *view, GdkDragContext *context, gint x, diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index fb84261fa2..bd9795c908 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -22,6 +22,7 @@ #include "e-attachment.h" #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include "e-util/e-util.h" +#include "e-util/e-mktemp.h" #include "e-attachment-store.h" #define E_ATTACHMENT_GET_PRIVATE(obj) \ @@ -1914,18 +1916,30 @@ static void attachment_open_save_temporary (OpenContext *open_context) { GFile *file; + gchar *template; gchar *path; - gint fd; GError *error = NULL; - fd = e_file_open_tmp (&path, &error); + errno = 0; + /* XXX This could trigger a blocking temp directory cleanup. */ + template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); + path = e_mktemp (template); + g_free (template); + + /* XXX Let's hope errno got set properly. */ + if (path == NULL) + g_set_error ( + &error, G_FILE_ERROR, + g_file_error_from_errno (errno), + "%s", g_strerror (errno)); + + /* We already know if there's an error, but this does the cleanup. */ if (attachment_open_check_for_error (open_context, error)) return; file = g_file_new_for_path (path); - close (fd); g_free (path); e_attachment_save_async ( @@ -2519,8 +2533,11 @@ e_attachment_save_handle_error (EAttachment *attachment, g_return_if_fail (GTK_IS_WINDOW (parent)); file = e_attachment_save_finish (attachment, result, &error); - if (file != NULL) + + if (file != NULL) { g_object_unref (file); + return; + } /* Ignore cancellations. */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) diff --git a/widgets/misc/e-mime-part-utils.c b/widgets/misc/e-mime-part-utils.c deleted file mode 100644 index 3238ca93f5..0000000000 --- a/widgets/misc/e-mime-part-utils.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * e-mime-part-utils.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "e-mime-part-utils.h" - -#include -#include -#include -#include - -#include "e-util/e-util.h" - -static void -mime_part_utils_open_in_cb (GtkAction *action, - CamelMimePart *mime_part) -{ - GtkWindow *parent; - GFile *file; - gchar *path; - gchar *uri; - gint fd; - GError *error = NULL; - - parent = g_object_get_data (G_OBJECT (action), "parent-window"); - - fd = e_file_open_tmp (&path, &error); - if (error != NULL) - goto fail; - - close (fd); - - file = g_file_new_for_path (path); - e_mime_part_utils_save_to_file (mime_part, file, &error); - g_free (path); - - if (error != NULL) { - g_object_unref (file); - goto fail; - } - - uri = g_file_get_uri (file); - e_show_uri (parent, uri); - g_free (uri); - - g_object_unref (file); - - return; - -fail: - g_warning ("%s", error->message); - g_error_free (error); -} - -GList * -e_mime_part_utils_get_apps (CamelMimePart *mime_part) -{ - GList *app_info_list; - const gchar *filename; - gchar *content_type; - gchar *mime_type; - gchar *cp; - - g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL); - - filename = camel_mime_part_get_filename (mime_part); - mime_type = camel_content_type_simple ( - camel_mime_part_get_content_type (mime_part)); - g_return_val_if_fail (mime_type != NULL, NULL); - - /* GIO expects lowercase MIME types. */ - for (cp = mime_type; *cp != '\0'; cp++) - *cp = g_ascii_tolower (*cp); - - content_type = g_content_type_from_mime_type (mime_type); - if (content_type != NULL) - app_info_list = g_app_info_get_all_for_type (content_type); - else - app_info_list = g_app_info_get_all_for_type (mime_type); - g_free (content_type); - - if (app_info_list != NULL || filename == NULL) - goto exit; - - if (strcmp (mime_type, "application/octet-stream") != 0) - goto exit; - - content_type = g_content_type_guess (filename, NULL, 0, NULL); - app_info_list = g_app_info_get_all_for_type (content_type); - g_free (content_type); - -exit: - g_free (mime_type); - - return app_info_list; -} - -gboolean -e_mime_part_utils_save_to_file (CamelMimePart *mime_part, - GFile *file, - GError **error) -{ - GFileOutputStream *output_stream; - CamelDataWrapper *content; - CamelStream *stream; - - g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - output_stream = g_file_replace ( - file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); - if (output_stream == NULL) - return FALSE; - - /* The CamelStream takes ownership of the GFileOutputStream. */ - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - stream = camel_stream_vfs_new_with_stream (G_OBJECT (output_stream)); - - /* XXX Camel's streams are synchronous only, so we have to write - * the whole thing in one shot and hope it doesn't block the - * main loop for too long. */ - if (camel_data_wrapper_decode_to_stream (content, stream) < 0) - goto file_error; - - if (camel_stream_flush (stream) < 0) - goto file_error; - - camel_object_unref (stream); - - return TRUE; - -file_error: - g_set_error ( - error, G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - - camel_object_unref (stream); - - return FALSE; -} - -void -e_mime_part_utils_add_open_actions (CamelMimePart *mime_part, - GtkUIManager *ui_manager, - GtkActionGroup *action_group, - const gchar *widget_path, - GtkWindow *parent, - guint merge_id) -{ - GList *app_info_list; - GList *iter; - - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager)); - g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); - g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent)); - g_return_if_fail (widget_path != NULL); - - app_info_list = e_mime_part_utils_get_apps (mime_part); - - for (iter = app_info_list; iter != NULL; iter = iter->next) { - GAppInfo *app_info = iter->data; - GtkAction *action; - const gchar *app_executable; - const gchar *app_name; - gchar *action_tooltip; - gchar *action_label; - gchar *action_name; - - if (!g_app_info_should_show (app_info)) - continue; - - app_executable = g_app_info_get_executable (app_info); - app_name = g_app_info_get_name (app_info); - - action_name = g_strdup_printf ("open-in-%s", app_executable); - action_label = g_strdup_printf (_("Open in %s..."), app_name); - - action_tooltip = g_strdup_printf ( - _("Open this attachment in %s"), app_name); - - action = gtk_action_new ( - action_name, action_label, action_tooltip, NULL); - - g_object_set_data ( - G_OBJECT (action), "parent-window", parent); - - g_signal_connect ( - action, "activate", - G_CALLBACK (mime_part_utils_open_in_cb), mime_part); - - gtk_action_group_add_action (action_group, action); - - gtk_ui_manager_add_ui ( - ui_manager, merge_id, widget_path, action_name, - action_name, GTK_UI_MANAGER_AUTO, FALSE); - - g_free (action_name); - g_free (action_label); - g_free (action_tooltip); - } - - g_list_foreach (app_info_list, (GFunc) g_object_unref, NULL); - g_list_free (app_info_list); -} diff --git a/widgets/misc/e-mime-part-utils.h b/widgets/misc/e-mime-part-utils.h deleted file mode 100644 index e923e07c8d..0000000000 --- a/widgets/misc/e-mime-part-utils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * e-mime-part-utils.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_MIME_PART_UTILS_H -#define E_MIME_PART_UTILS_H - -#include -#include -#include - -G_BEGIN_DECLS - -GList * e_mime_part_utils_get_apps (CamelMimePart *mime_part); -gboolean e_mime_part_utils_save_to_file (CamelMimePart *mime_part, - GFile *file, - GError **error); - -void e_mime_part_utils_add_open_actions - (CamelMimePart *mime_part, - GtkUIManager *ui_manager, - GtkActionGroup *action_group, - const gchar *widget_path, - GtkWindow *parent, - guint merge_id); - -G_END_DECLS - -#endif /* E_MIME_PART_UTILS_H */ -- cgit v1.2.3 From a843a2a4d205ef45d8a5670cf0b17c238cee1f37 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 7 Apr 2009 21:40:49 +0000 Subject: Attachment rewrite pretty much complete. Just testing now. svn path=/branches/kill-bonobo/; revision=37504 --- widgets/misc/Makefile.am | 4 + widgets/misc/e-attachment-button.c | 695 ++++++++++++++++++++++++++++++++++ widgets/misc/e-attachment-button.h | 83 ++++ widgets/misc/e-attachment-icon-view.c | 2 +- widgets/misc/e-attachment-paned.c | 12 + widgets/misc/e-attachment-store.c | 9 +- widgets/misc/e-attachment-tree-view.c | 2 +- widgets/misc/e-attachment-view.c | 35 +- widgets/misc/e-attachment-view.h | 5 +- widgets/misc/e-attachment.c | 15 +- widgets/misc/e-menu-button.c | 497 ++++++++++++++++++++++++ widgets/misc/e-menu-button.h | 74 ++++ 12 files changed, 1407 insertions(+), 26 deletions(-) create mode 100644 widgets/misc/e-attachment-button.c create mode 100644 widgets/misc/e-attachment-button.h create mode 100644 widgets/misc/e-menu-button.c create mode 100644 widgets/misc/e-menu-button.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 8ba66287f8..ce22c3b065 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -40,6 +40,7 @@ widgetsinclude_HEADERS = \ e-activity-proxy.h \ e-alert-activity.h \ e-attachment.h \ + e-attachment-button.h \ e-attachment-dialog.h \ e-attachment-handler.h \ e-attachment-handler-image.h \ @@ -69,6 +70,7 @@ widgetsinclude_HEADERS = \ e-icon-entry.h \ e-image-chooser.h \ e-map.h \ + e-menu-button.h \ e-menu-tool-button.h \ e-online-button.h \ e-popup-action.h \ @@ -103,6 +105,7 @@ libemiscwidgets_la_SOURCES = \ e-activity-proxy.c \ e-alert-activity.c \ e-attachment.c \ + e-attachment-button.c \ e-attachment-dialog.c \ e-attachment-handler.c \ e-attachment-handler-image.c \ @@ -132,6 +135,7 @@ libemiscwidgets_la_SOURCES = \ e-icon-entry.c \ e-image-chooser.c \ e-map.c \ + e-menu-button.c \ e-menu-tool-button.c \ e-online-button.c \ e-popup-action.c \ diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c new file mode 100644 index 0000000000..fa43373a3c --- /dev/null +++ b/widgets/misc/e-attachment-button.c @@ -0,0 +1,695 @@ +/* + * e-attachment-button.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* Much of the popup menu logic here was ripped from GtkMenuToolButton. */ + +#include "e-attachment-button.h" + +#include "e-util/e-binding.h" + +#define E_ATTACHMENT_BUTTON_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonPrivate)) + +struct _EAttachmentButtonPrivate { + + EAttachmentView *view; + EAttachment *attachment; + gulong reference_handler_id; + + GtkWidget *expand_button; + GtkWidget *toggle_button; + GtkWidget *cell_view; + + guint expandable : 1; + guint expanded : 1; +}; + +enum { + PROP_0, + PROP_ATTACHMENT, + PROP_EXPANDABLE, + PROP_EXPANDED, + PROP_VIEW +}; + +static gpointer parent_class; + +static void +attachment_button_menu_deactivate_cb (EAttachmentButton *button) +{ + GtkToggleButton *toggle_button; + + toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); + + gtk_toggle_button_set_active (toggle_button, FALSE); +} + +static void +attachment_button_menu_position (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + EAttachmentButton *button) +{ + GtkRequisition menu_requisition; + GtkTextDirection direction; + GdkRectangle monitor; + GdkScreen *screen; + GdkWindow *window; + GtkWidget *widget; + GtkWidget *toggle_button; + gint monitor_num; + + widget = GTK_WIDGET (button); + toggle_button = button->priv->toggle_button; + gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition); + + window = gtk_widget_get_parent_window (widget); + screen = gtk_widget_get_screen (GTK_WIDGET (menu)); + monitor_num = gdk_screen_get_monitor_at_window (screen, window); + if (monitor_num < 0) + monitor_num = 0; + gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); + + gdk_window_get_origin (window, x, y); + *x += widget->allocation.x; + *y += widget->allocation.y; + + direction = gtk_widget_get_direction (widget); + if (direction == GTK_TEXT_DIR_LTR) + x += MAX (widget->allocation.width - menu_requisition.width, 0); + else if (menu_requisition.width > widget->allocation.width) + x -= menu_requisition.width - widget->allocation.width; + + if ((*y + toggle_button->allocation.height + menu_requisition.height) <= monitor.y + monitor.height) + *y += toggle_button->allocation.height; + else if ((*y - menu_requisition.height) >= monitor.y) + *y -= menu_requisition.height; + else if (monitor.y + monitor.height - (*y + toggle_button->allocation.height) > *y) + *y += toggle_button->allocation.height; + else + *y -= menu_requisition.height; + + *push_in = FALSE; +} + +static void +attachment_button_select_path (EAttachmentButton *button) +{ + EAttachmentView *view; + EAttachment *attachment; + GtkTreeRowReference *reference; + GtkTreePath *path; + + attachment = e_attachment_button_get_attachment (button); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + reference = e_attachment_get_reference (attachment); + g_return_if_fail (gtk_tree_row_reference_valid (reference)); + + view = e_attachment_button_get_view (button); + path = gtk_tree_row_reference_get_path (reference); + + e_attachment_view_unselect_all (view); + e_attachment_view_select_path (view, path); + + gtk_tree_path_free (path); +} + +static void +attachment_button_show_popup_menu (EAttachmentButton *button, + GdkEventButton *event) +{ + GtkToggleButton *toggle_button; + EAttachmentView *view; + + view = e_attachment_button_get_view (button); + toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); + + attachment_button_select_path (button); + gtk_toggle_button_set_active (toggle_button, TRUE); + + e_attachment_view_show_popup_menu ( + view, event, (GtkMenuPositionFunc) + attachment_button_menu_position, button); + +} + +static void +attachment_button_update_cell_view (EAttachmentButton *button) +{ + GtkCellView *cell_view; + EAttachment *attachment; + GtkTreeRowReference *reference; + GtkTreeModel *model = NULL; + GtkTreePath *path = NULL; + + cell_view = GTK_CELL_VIEW (button->priv->cell_view); + + attachment = e_attachment_button_get_attachment (button); + if (attachment == NULL) + goto exit; + + reference = e_attachment_get_reference (attachment); + if (reference == NULL) + goto exit; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + +exit: + gtk_cell_view_set_model (cell_view, model); + gtk_cell_view_set_displayed_row (cell_view, path); + + if (path != NULL) + gtk_tree_path_free (path); +} + +static void +attachment_button_update_pixbufs (EAttachmentButton *button) +{ + GtkCellView *cell_view; + GtkCellRenderer *renderer; + GtkIconTheme *icon_theme; + GdkPixbuf *pixbuf_expander_open; + GdkPixbuf *pixbuf_expander_closed; + GList *list; + + icon_theme = gtk_icon_theme_get_default (); + + /* Grab the first cell renderer. */ + cell_view = GTK_CELL_VIEW (button->priv->cell_view); + list = gtk_cell_view_get_cell_renderers (cell_view); + renderer = GTK_CELL_RENDERER (list->data); + g_list_free (list); + + pixbuf_expander_open = gtk_widget_render_icon ( + GTK_WIDGET (button), GTK_STOCK_GO_DOWN, + GTK_ICON_SIZE_BUTTON, NULL); + + pixbuf_expander_closed = gtk_widget_render_icon ( + GTK_WIDGET (button), GTK_STOCK_GO_FORWARD, + GTK_ICON_SIZE_BUTTON, NULL); + + g_object_set ( + renderer, + "pixbuf-expander-open", pixbuf_expander_open, + "pixbuf-expander-closed", pixbuf_expander_closed, + NULL); + + g_object_unref (pixbuf_expander_open); + g_object_unref (pixbuf_expander_closed); +} + +static void +attachment_button_expand_clicked_cb (EAttachmentButton *button) +{ + gboolean expanded; + + expanded = e_attachment_button_get_expanded (button); + e_attachment_button_set_expanded (button, !expanded); +} + +static void +attachment_button_expand_drag_data_get_cb (EAttachmentButton *button, + GdkDragContext *context, + GtkSelectionData *selection, + guint info, + guint time) +{ + EAttachmentView *view; + + attachment_button_select_path (button); + + view = e_attachment_button_get_view (button); + + e_attachment_view_drag_data_get ( + view, context, selection, info, time); +} + +static gboolean +attachment_button_toggle_button_press_event_cb (EAttachmentButton *button, + GdkEventButton *event) +{ + if (event->button == 1) { + attachment_button_show_popup_menu (button, event); + return TRUE; + } + + return FALSE; +} + +static void +attachment_button_set_view (EAttachmentButton *button, + EAttachmentView *view) +{ + GtkWidget *menu; + + g_return_if_fail (button->priv->view == NULL); + + button->priv->view = g_object_ref (view); + + menu = e_attachment_view_get_popup_menu (view); + + g_signal_connect_swapped ( + menu, "deactivate", + G_CALLBACK (attachment_button_menu_deactivate_cb), button); +} + +static void +attachment_button_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ATTACHMENT: + e_attachment_button_set_attachment ( + E_ATTACHMENT_BUTTON (object), + g_value_get_object (value)); + return; + + case PROP_EXPANDABLE: + e_attachment_button_set_expandable ( + E_ATTACHMENT_BUTTON (object), + g_value_get_boolean (value)); + return; + + case PROP_EXPANDED: + e_attachment_button_set_expanded ( + E_ATTACHMENT_BUTTON (object), + g_value_get_boolean (value)); + return; + + case PROP_VIEW: + attachment_button_set_view ( + E_ATTACHMENT_BUTTON (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_button_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ATTACHMENT: + g_value_set_object ( + value, + e_attachment_button_get_attachment ( + E_ATTACHMENT_BUTTON (object))); + return; + + case PROP_EXPANDABLE: + g_value_set_boolean ( + value, + e_attachment_button_get_expandable ( + E_ATTACHMENT_BUTTON (object))); + return; + + case PROP_EXPANDED: + g_value_set_boolean ( + value, + e_attachment_button_get_expanded ( + E_ATTACHMENT_BUTTON (object))); + return; + + case PROP_VIEW: + g_value_set_object ( + value, + e_attachment_button_get_view ( + E_ATTACHMENT_BUTTON (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +attachment_button_dispose (GObject *object) +{ + EAttachmentButtonPrivate *priv; + + priv = E_ATTACHMENT_BUTTON_GET_PRIVATE (object); + + if (priv->view != NULL) { + g_object_unref (priv->view); + priv->view = NULL; + } + + if (priv->attachment != NULL) { + g_signal_handler_disconnect ( + priv->attachment, + priv->reference_handler_id); + g_object_unref (priv->attachment); + priv->attachment = NULL; + } + + if (priv->expand_button != NULL) { + g_object_unref (priv->expand_button); + priv->expand_button = NULL; + } + + if (priv->toggle_button != NULL) { + g_object_unref (priv->toggle_button); + priv->toggle_button = NULL; + } + + if (priv->cell_view != NULL) { + g_object_unref (priv->cell_view); + priv->cell_view = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +attachment_button_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + EAttachmentButton *button; + + /* Chain up to parent's style_set() method. */ + GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style); + + button = E_ATTACHMENT_BUTTON (widget); + attachment_button_update_pixbufs (button); +} + +static void +attachment_button_class_init (EAttachmentButtonClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentButtonPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_button_set_property; + object_class->get_property = attachment_button_get_property; + object_class->dispose = attachment_button_dispose; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->style_set = attachment_button_style_set; + + g_object_class_install_property ( + object_class, + PROP_ATTACHMENT, + g_param_spec_object ( + "attachment", + "Attachment", + NULL, + E_TYPE_ATTACHMENT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_EXPANDABLE, + g_param_spec_boolean ( + "expandable", + "Expandable", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_EXPANDED, + g_param_spec_boolean ( + "expanded", + "Expanded", + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_VIEW, + g_param_spec_object ( + "view", + "View", + NULL, + E_TYPE_ATTACHMENT_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +attachment_button_init (EAttachmentButton *button) +{ + GtkCellRenderer *renderer; + GtkCellLayout *cell_layout; + GtkTargetEntry *targets; + GtkTargetList *list; + GtkWidget *container; + GtkWidget *widget; + gint n_targets; + + button->priv = E_ATTACHMENT_BUTTON_GET_PRIVATE (button); + + /* Configure Widgets */ + + container = GTK_WIDGET (button); + + widget = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + button->priv->expand_button = g_object_ref (widget); + gtk_widget_show (widget); + + e_mutual_binding_new ( + G_OBJECT (button), "expandable", + G_OBJECT (widget), "sensitive"); + + widget = gtk_toggle_button_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + button->priv->toggle_button = g_object_ref (widget); + gtk_widget_show (widget); + + container = button->priv->expand_button; + + widget = gtk_cell_view_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + button->priv->cell_view = g_object_ref (widget); + gtk_widget_show (widget); + + container = button->priv->toggle_button; + + widget = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + /* Configure Renderers */ + + cell_layout = GTK_CELL_LAYOUT (button->priv->cell_view); + + renderer = gtk_cell_renderer_pixbuf_new (); + g_object_set (renderer, "is-expander", TRUE, NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); + + e_mutual_binding_new ( + G_OBJECT (button), "expanded", + G_OBJECT (renderer), "is-expanded"); + + renderer = gtk_cell_renderer_pixbuf_new (); + g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL); + gtk_cell_layout_pack_start (cell_layout, renderer, FALSE); + + gtk_cell_layout_add_attribute ( + cell_layout, renderer, "gicon", + E_ATTACHMENT_STORE_COLUMN_ICON); + + /* Configure Drag and Drop */ + + list = gtk_target_list_new (NULL, 0); + gtk_target_list_add_uri_targets (list, 0); + targets = gtk_target_table_new_from_list (list, &n_targets); + + gtk_drag_source_set ( + button->priv->expand_button, GDK_BUTTON1_MASK, + targets, n_targets, GDK_ACTION_COPY); + + gtk_drag_source_set ( + button->priv->toggle_button, GDK_BUTTON1_MASK, + targets, n_targets, GDK_ACTION_COPY); + + gtk_target_table_free (targets, n_targets); + gtk_target_list_unref (list); + + /* Configure Signal Handlers */ + + g_signal_connect_swapped ( + button->priv->expand_button, "clicked", + G_CALLBACK (attachment_button_expand_clicked_cb), button); + + g_signal_connect_swapped ( + button->priv->expand_button, "drag-data-get", + G_CALLBACK (attachment_button_expand_drag_data_get_cb), + button); + + g_signal_connect_swapped ( + button->priv->toggle_button, "button-press-event", + G_CALLBACK (attachment_button_toggle_button_press_event_cb), + button); + + g_signal_connect_swapped ( + button->priv->toggle_button, "drag-data-get", + G_CALLBACK (attachment_button_expand_drag_data_get_cb), + button); + +} + +GType +e_attachment_button_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentButtonClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_button_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentButton), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_button_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_HBOX, "EAttachmentButton", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_attachment_button_new (EAttachmentView *view) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + return g_object_new ( + E_TYPE_ATTACHMENT_BUTTON, + "view", view, NULL); +} + +EAttachmentView * +e_attachment_button_get_view (EAttachmentButton *button) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), NULL); + + return button->priv->view; +} + +EAttachment * +e_attachment_button_get_attachment (EAttachmentButton *button) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), NULL); + + return button->priv->attachment; +} + +void +e_attachment_button_set_attachment (EAttachmentButton *button, + EAttachment *attachment) +{ + g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); + + if (attachment != NULL) { + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_object_ref (attachment); + } + + if (button->priv->attachment != NULL) { + g_signal_handler_disconnect ( + button->priv->attachment, + button->priv->reference_handler_id); + g_object_unref (button->priv->attachment); + } + + button->priv->attachment = attachment; + + if (attachment != NULL) { + gulong handler_id; + + handler_id = g_signal_connect_swapped ( + attachment, "notify::reference", + G_CALLBACK (attachment_button_update_cell_view), + button); + attachment_button_update_cell_view (button); + attachment_button_update_pixbufs (button); + button->priv->reference_handler_id = handler_id; + } + + g_object_notify (G_OBJECT (button), "attachment"); +} + +gboolean +e_attachment_button_get_expandable (EAttachmentButton *button) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), FALSE); + + return button->priv->expandable; +} + +void +e_attachment_button_set_expandable (EAttachmentButton *button, + gboolean expandable) +{ + g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); + + button->priv->expandable = expandable; + + if (!expandable) + e_attachment_button_set_expanded (button, FALSE); + + g_object_notify (G_OBJECT (button), "expandable"); +} + +gboolean +e_attachment_button_get_expanded (EAttachmentButton *button) +{ + g_return_val_if_fail (E_IS_ATTACHMENT_BUTTON (button), FALSE); + + return button->priv->expanded; +} + +void +e_attachment_button_set_expanded (EAttachmentButton *button, + gboolean expanded) +{ + g_return_if_fail (E_IS_ATTACHMENT_BUTTON (button)); + + button->priv->expanded = expanded; + + g_object_notify (G_OBJECT (button), "expanded"); +} diff --git a/widgets/misc/e-attachment-button.h b/widgets/misc/e-attachment-button.h new file mode 100644 index 0000000000..6e2f5672ef --- /dev/null +++ b/widgets/misc/e-attachment-button.h @@ -0,0 +1,83 @@ +/* + * e-attachment-button.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_BUTTON_H +#define E_ATTACHMENT_BUTTON_H + +#include +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_BUTTON \ + (e_attachment_button_get_type ()) +#define E_ATTACHMENT_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButton)) +#define E_ATTACHMENT_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonClass)) +#define E_IS_ATTACHMENT_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_BUTTON)) +#define E_IS_ATTACHMENT_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_BUTTON)) +#define E_ATTACHMENT_BUTTON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_BUTTON, EAttachmentButtonClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentButton EAttachmentButton; +typedef struct _EAttachmentButtonClass EAttachmentButtonClass; +typedef struct _EAttachmentButtonPrivate EAttachmentButtonPrivate; + +struct _EAttachmentButton { + GtkHBox parent; + EAttachmentButtonPrivate *priv; +}; + +struct _EAttachmentButtonClass { + GtkHBoxClass parent_class; +}; + +GType e_attachment_button_get_type (void); +GtkWidget * e_attachment_button_new (EAttachmentView *view); +EAttachmentView * + e_attachment_button_get_view (EAttachmentButton *button); +EAttachment * e_attachment_button_get_attachment + (EAttachmentButton *button); +void e_attachment_button_set_attachment + (EAttachmentButton *button, + EAttachment *attachment); +gboolean e_attachment_button_get_expandable + (EAttachmentButton *button); +void e_attachment_button_set_expandable + (EAttachmentButton *button, + gboolean expandable); +gboolean e_attachment_button_get_expanded(EAttachmentButton *button); +void e_attachment_button_set_expanded(EAttachmentButton *button, + gboolean expanded); + +G_END_DECLS + +#endif /* E_ATTACHMENT_BUTTON_H */ diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index e8a7db8459..0845f82a76 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -222,7 +222,7 @@ attachment_icon_view_popup_menu (GtkWidget *widget) { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - e_attachment_view_show_popup_menu (view, NULL); + e_attachment_view_show_popup_menu (view, NULL, NULL, NULL); return TRUE; } diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index f9f7bb1cca..9502f41296 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -408,6 +408,17 @@ attachment_paned_unselect_all (EAttachmentView *view) e_attachment_view_unselect_all (view); } +static void +attachment_paned_update_actions (EAttachmentView *view) +{ + EAttachmentPanedPrivate *priv; + + priv = E_ATTACHMENT_PANED_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_update_actions (view); +} + static void attachment_paned_class_init (EAttachmentPanedClass *class) { @@ -462,6 +473,7 @@ attachment_paned_iface_init (EAttachmentViewIface *iface) iface->unselect_path = attachment_paned_unselect_path; iface->select_all = attachment_paned_select_all; iface->unselect_all = attachment_paned_unselect_all; + iface->update_actions = attachment_paned_update_actions; } static void diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 589f670f34..24cc89b366 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -715,6 +715,7 @@ attachment_store_get_uris_save_cb (EAttachment *attachment, g_list_foreach ( uri_context->attachment_list, (GFunc) e_attachment_cancel, NULL); + error = NULL; /* Otherwise, we can only report back one error. So if * this is something other than cancellation, dump it to @@ -722,9 +723,10 @@ attachment_store_get_uris_save_cb (EAttachment *attachment, } else if (!g_error_matches ( error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s", error->message); + } + if (error != NULL) g_error_free (error); - } /* If there's still jobs running, let them finish. */ if (uri_context->attachment_list != NULL) @@ -846,9 +848,8 @@ e_attachment_store_get_uris_finish (EAttachmentStore *store, GSimpleAsyncResult *simple; gchar **uris; - g_return_val_if_fail ( - g_simple_async_result_is_valid (result, G_OBJECT (store), - e_attachment_store_get_uris_async), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); simple = G_SIMPLE_ASYNC_RESULT (result); uris = g_simple_async_result_get_op_res_gpointer (simple); diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index 336b3225df..f8a74d293f 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -240,7 +240,7 @@ attachment_tree_view_popup_menu (GtkWidget *widget) { EAttachmentView *view = E_ATTACHMENT_VIEW (widget); - e_attachment_view_show_popup_menu (view, NULL); + e_attachment_view_show_popup_menu (view, NULL, NULL, NULL); return TRUE; } diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index d6dff653cc..5c7acd4561 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -1059,7 +1059,8 @@ e_attachment_view_button_press_event (EAttachmentView *view, * popup menu when right-clicking on an attachment, * but editable views can show the menu any time. */ if (item_clicked || editable) { - e_attachment_view_show_popup_menu (view, event); + e_attachment_view_show_popup_menu ( + view, event, NULL, NULL); return TRUE; } } @@ -1468,6 +1469,21 @@ e_attachment_view_get_action_group (EAttachmentView *view, return e_lookup_action_group (ui_manager, group_name); } +GtkWidget * +e_attachment_view_get_popup_menu (EAttachmentView *view) +{ + GtkUIManager *ui_manager; + GtkWidget *menu; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + + ui_manager = e_attachment_view_get_ui_manager (view); + menu = gtk_ui_manager_get_widget (ui_manager, "/context"); + g_return_val_if_fail (GTK_IS_MENU (menu), NULL); + + return menu; +} + GtkUIManager * e_attachment_view_get_ui_manager (EAttachmentView *view) { @@ -1511,27 +1527,26 @@ e_attachment_view_recent_action_new (EAttachmentView *view, void e_attachment_view_show_popup_menu (EAttachmentView *view, - GdkEventButton *event) + GdkEventButton *event, + GtkMenuPositionFunc func, + gpointer user_data) { - GtkUIManager *ui_manager; GtkWidget *menu; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); e_attachment_view_update_actions (view); - ui_manager = e_attachment_view_get_ui_manager (view); - menu = gtk_ui_manager_get_widget (ui_manager, "/context"); - g_return_if_fail (GTK_IS_MENU (menu)); + menu = e_attachment_view_get_popup_menu (view); if (event != NULL) gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button, event->time); + GTK_MENU (menu), NULL, NULL, func, + user_data, event->button, event->time); else gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, NULL, NULL, - 0, gtk_get_current_event_time ()); + GTK_MENU (menu), NULL, NULL, func, + user_data, 0, gtk_get_current_event_time ()); } void diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 8b625d0d8a..8285928c5b 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -209,6 +209,7 @@ GtkAction * e_attachment_view_get_action (EAttachmentView *view, GtkActionGroup *e_attachment_view_get_action_group (EAttachmentView *view, const gchar *group_name); +GtkWidget * e_attachment_view_get_popup_menu(EAttachmentView *view); GtkUIManager * e_attachment_view_get_ui_manager(EAttachmentView *view); GtkAction * e_attachment_view_recent_action_new (EAttachmentView *view, @@ -216,7 +217,9 @@ GtkAction * e_attachment_view_recent_action_new const gchar *action_label); void e_attachment_view_show_popup_menu (EAttachmentView *view, - GdkEventButton *event); + GdkEventButton *event, + GtkMenuPositionFunc func, + gpointer user_data); void e_attachment_view_update_actions(EAttachmentView *view); G_END_DECLS diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index bd9795c908..16bd9fd26c 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1694,9 +1694,8 @@ e_attachment_load_finish (EAttachment *attachment, GSimpleAsyncResult *simple; CamelMimePart *mime_part; - g_return_val_if_fail ( - g_simple_async_result_is_valid (result, - G_OBJECT (attachment), e_attachment_load_async), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); simple = G_SIMPLE_ASYNC_RESULT (result); mime_part = g_simple_async_result_get_op_res_gpointer (simple); @@ -1990,9 +1989,8 @@ e_attachment_open_finish (EAttachment *attachment, GSimpleAsyncResult *simple; gboolean success; - g_return_val_if_fail ( - g_simple_async_result_is_valid (result, - G_OBJECT (attachment), e_attachment_open_async), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); simple = G_SIMPLE_ASYNC_RESULT (result); success = g_simple_async_result_get_op_res_gboolean (simple); @@ -2500,9 +2498,8 @@ e_attachment_save_finish (EAttachment *attachment, GSimpleAsyncResult *simple; GFile *destination; - g_return_val_if_fail ( - g_simple_async_result_is_valid (result, - G_OBJECT (attachment), e_attachment_save_async), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); simple = G_SIMPLE_ASYNC_RESULT (result); destination = g_simple_async_result_get_op_res_gpointer (simple); diff --git a/widgets/misc/e-menu-button.c b/widgets/misc/e-menu-button.c new file mode 100644 index 0000000000..af60790bc5 --- /dev/null +++ b/widgets/misc/e-menu-button.c @@ -0,0 +1,497 @@ +/* + * e-menu-button.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-menu-button.h" + +#define E_MENU_BUTTON_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MENU_BUTTON, EMenuButtonPrivate)) + +struct _EMenuButtonPrivate { + GtkWidget *toggle_button; + GtkMenu *menu; /* not referenced */ +}; + +enum { + PROP_0, + PROP_MENU +}; + +enum { + SHOW_MENU, + LAST_SIGNAL +}; + +static gpointer parent_class; +static gulong signals[LAST_SIGNAL]; + +static void +menu_button_detach (GtkWidget *widget, + GtkMenu *menu) +{ + EMenuButtonPrivate *priv; + + priv = E_MENU_BUTTON_GET_PRIVATE (widget); + + g_return_if_fail (priv->menu == menu); + + priv->menu = NULL; +} + +static void +menu_button_deactivate_cb (EMenuButton *menu_button) +{ + GtkToggleButton *toggle_button; + + toggle_button = GTK_TOGGLE_BUTTON (menu_button->priv->toggle_button); + gtk_toggle_button_set_active (toggle_button, FALSE); +} + +static void +menu_button_menu_position (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + EMenuButton *menu_button) +{ + GtkRequisition requisition; + GtkTextDirection direction; + GdkRectangle monitor; + GdkScreen *screen; + GdkWindow *window; + GtkWidget *widget; + GtkWidget *toggle_button; + gint button_bottom; + gint monitor_bottom; + gint monitor_num; + + widget = GTK_WIDGET (menu_button); + toggle_button = menu_button->priv->toggle_button; + gtk_widget_size_request (GTK_WIDGET (menu), &requisition); + + window = gtk_widget_get_parent_window (widget); + screen = gtk_widget_get_screen (GTK_WIDGET (menu)); + monitor_num = gdk_screen_get_monitor_at_window (screen, window); + if (monitor_num < 0) + monitor_num = 0; + gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); + + gdk_window_get_origin (window, x, y); + *x += widget->allocation.x; + *y += widget->allocation.y; + + direction = gtk_widget_get_direction (widget); + if (direction == GTK_TEXT_DIR_LTR) + x += MAX (widget->allocation.width - requisition.width, 0); + else if (requisition.width > widget->allocation.width) + x -= requisition.width - widget->allocation.width; + + button_bottom = *y + toggle_button->allocation.height; + monitor_bottom = monitor.y + monitor.height; + + if (button_bottom + requisition.height <= monitor_bottom) + y += toggle_button->allocation.height; + else if (*y - requisition.height >= monitor.y) + y -= requisition.height; + else if (monitor_bottom - button_bottom > *y) + y += toggle_button->allocation.height; + else + y -= requisition.height; + + *push_in = FALSE; +} + +static void +menu_button_show_popup_menu (EMenuButton *menu_button, + GdkEventButton *event) +{ + g_signal_emit (menu_button, signals[SHOW_MENU], 0); + + if (menu_button->priv->menu == NULL) + return; + + if (event != NULL) + gtk_menu_popup ( + menu_button->priv->menu, NULL, NULL, + (GtkMenuPositionFunc) menu_button_menu_position, + menu_button, event->button, event->time); + else + gtk_menu_popup ( + menu_button->priv->menu, NULL, NULL, + (GtkMenuPositionFunc) menu_button_menu_position, + menu_button, 0, gtk_get_current_event_time ()); +} + +static gboolean +menu_button_toggle_button_press_event_cb (EMenuButton *menu_button, + GdkEventButton *event) +{ + if (event->button == 1) { + menu_button_show_popup_menu (menu_button, event); + return TRUE; + } + + return FALSE; +} + +static void +menu_button_toggle_toggled_cb (EMenuButton *menu_button) +{ + GtkMenuShell *menu_shell; + GtkToggleButton *toggle_button; + + menu_shell = GTK_MENU_SHELL (menu_button->priv->menu); + toggle_button = GTK_TOGGLE_BUTTON (menu_button->priv->toggle_button); + + if (!gtk_toggle_button_get_active (toggle_button)) + return; + + if (GTK_WIDGET_VISIBLE (menu_shell)) + return; + + /* We get here only when the menu is activated by a key + * press, so that we can select the first menu item. */ + menu_button_show_popup_menu (menu_button, NULL); + gtk_menu_shell_select_first (menu_shell, FALSE); +} + +static void +menu_button_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MENU: + e_menu_button_set_menu ( + E_MENU_BUTTON (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +menu_button_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MENU: + g_value_set_object ( + value, e_menu_button_get_menu ( + E_MENU_BUTTON (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +menu_button_dispose (GObject *object) +{ + EMenuButtonPrivate *priv; + + priv = E_MENU_BUTTON_GET_PRIVATE (object); + + if (priv->toggle_button != NULL) { + g_object_unref (priv->toggle_button); + priv->toggle_button = NULL; + } + + if (priv->menu != NULL) { + g_signal_handlers_disconnect_by_func ( + priv->menu, menu_button_deactivate_cb, object); + gtk_menu_detach (priv->menu); + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +menu_button_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + EMenuButtonPrivate *priv; + GtkRequisition child_requisition; + GtkWidget *child; + + priv = E_MENU_BUTTON_GET_PRIVATE (widget); + + /* Chain up to parent's size_request() method. */ + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); + + child = priv->toggle_button; + gtk_widget_size_request (child, &child_requisition); + requisition->width += child_requisition.width; +} + +static void +menu_button_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + EMenuButtonPrivate *priv; + GtkAllocation child_allocation; + GtkRequisition child_requisition; + GtkWidget *child; + gint toggle_x; + + priv = E_MENU_BUTTON_GET_PRIVATE (widget); + + widget->allocation = *allocation; + + child = priv->toggle_button; + gtk_widget_size_request (child, &child_requisition); + + toggle_x = allocation->x + allocation->width - child_requisition.width; + + child_allocation.x = allocation->x; + child_allocation.y = allocation->y; + child_allocation.width = toggle_x - allocation->x; + child_allocation.height = allocation->height; + + /* Chain up to parent's size_allocate() method. */ + GTK_WIDGET_CLASS (parent_class)-> + size_allocate (widget, &child_allocation); + + child_allocation.x = toggle_x; + child_allocation.y = allocation->y; + child_allocation.width = child_requisition.width; + child_allocation.height = allocation->height; + + gtk_widget_size_allocate (child, &child_allocation); +} + +static void +menu_button_state_changed (GtkWidget *widget, + GtkStateType previous_state) +{ + EMenuButtonPrivate *priv; + + priv = E_MENU_BUTTON_GET_PRIVATE (widget); + + if (!GTK_WIDGET_IS_SENSITIVE (widget) && priv->menu != NULL) + gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu)); + + /* Chain up to parent's state_changed() method. */ + GTK_WIDGET_CLASS (parent_class)-> + state_changed (widget, previous_state); +} + +static void +menu_button_remove (GtkContainer *container, + GtkWidget *widget) +{ + EMenuButtonPrivate *priv; + + priv = E_MENU_BUTTON_GET_PRIVATE (container); + + /* Look in the internal widgets first. */ + + if (widget == priv->toggle_button) { + gtk_widget_unparent (priv->toggle_button); + gtk_widget_queue_resize (GTK_WIDGET (container)); + return; + } + + /* Chain up to parent's remove() method. */ + GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); +} + +static void +menu_button_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + EMenuButtonPrivate *priv; + + priv = E_MENU_BUTTON_GET_PRIVATE (container); + + if (include_internals) + callback (priv->toggle_button, callback_data); + + /* Chain up to parent's forall() method. */ + GTK_CONTAINER_CLASS (parent_class)->forall ( + container, include_internals, callback, callback_data); +} + +static void +menu_button_class_init (EMenuButtonClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkContainerClass *container_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMenuButtonPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = menu_button_set_property; + object_class->get_property = menu_button_get_property; + object_class->dispose = menu_button_dispose; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->size_request = menu_button_size_request; + widget_class->size_allocate = menu_button_size_allocate; + widget_class->state_changed = menu_button_state_changed; + + container_class = GTK_CONTAINER_CLASS (class); + container_class->remove = menu_button_remove; + container_class->forall = menu_button_forall; + + g_object_class_install_property ( + object_class, + PROP_MENU, + g_param_spec_object ( + "menu", + "Menu", + NULL, + GTK_TYPE_MENU, + G_PARAM_READWRITE)); + + signals[SHOW_MENU] = g_signal_new ( + "show-menu", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EMenuButtonClass, show_menu), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +menu_button_init (EMenuButton *menu_button) +{ + GtkWidget *container; + GtkWidget *widget; + + menu_button->priv = E_MENU_BUTTON_GET_PRIVATE (menu_button); + + container = GTK_WIDGET (menu_button); + + widget = gtk_toggle_button_new (); + gtk_widget_set_sensitive (widget, FALSE); + gtk_widget_set_parent (widget, container); + menu_button->priv->toggle_button = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + menu_button->priv->toggle_button, "button-press-event", + G_CALLBACK (menu_button_toggle_button_press_event_cb), + menu_button); + + g_signal_connect_swapped ( + menu_button->priv->toggle_button, "toggled", + G_CALLBACK (menu_button_toggle_toggled_cb), menu_button); +} + +GType +e_menu_button_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMenuButtonClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) menu_button_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_init */ + sizeof (EMenuButton), + 0, /* n_preallocs */ + (GInstanceInitFunc) menu_button_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_BUTTON, "EMenuButton", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_menu_button_new (void) +{ + return g_object_new (E_TYPE_MENU_BUTTON, NULL); +} + +GtkWidget * +e_menu_button_get_menu (EMenuButton *menu_button) +{ + g_return_val_if_fail (E_IS_MENU_BUTTON (menu_button), NULL); + + return GTK_WIDGET (menu_button->priv->menu); +} + +void +e_menu_button_set_menu (EMenuButton *menu_button, + GtkWidget *menu) +{ + g_return_if_fail (E_IS_MENU_BUTTON (menu_button)); + g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL); + + if (menu_button->priv->menu == GTK_MENU (menu)) + goto exit; + + if (menu_button->priv->menu != NULL) { + GtkMenuShell *menu_shell; + + menu_shell = GTK_MENU_SHELL (menu_button->priv->menu); + + if (GTK_WIDGET_VISIBLE (menu_shell)) + gtk_menu_shell_deactivate (menu_shell); + + g_signal_handlers_disconnect_by_func ( + menu_shell, menu_button_deactivate_cb, menu_button); + + gtk_menu_detach (menu_button->priv->menu); + } + + menu_button->priv->menu = GTK_MENU (menu); + + if (menu != NULL) { + gtk_menu_attach_to_widget ( + GTK_MENU (menu), GTK_WIDGET (menu_button), + (GtkMenuDetachFunc) menu_button_detach); + + g_signal_connect_swapped ( + menu, "deactivate", + G_CALLBACK (menu_button_deactivate_cb), menu_button); + } + + gtk_widget_set_sensitive ( + menu_button->priv->toggle_button, menu != NULL); + +exit: + g_object_notify (G_OBJECT (menu_button), "menu"); +} diff --git a/widgets/misc/e-menu-button.h b/widgets/misc/e-menu-button.h new file mode 100644 index 0000000000..fa27a77c67 --- /dev/null +++ b/widgets/misc/e-menu-button.h @@ -0,0 +1,74 @@ +/* + * e-menu-button.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* This is like a GtkMenuToolButton, expect not a GtkToolItem. */ + +#ifndef E_MENU_BUTTON_H +#define E_MENU_BUTTON_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_MENU_BUTTON \ + (e_menu_button_get_type ()) +#define E_MENU_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MENU_BUTTON, EMenuButton)) +#define E_MENU_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MENU_BUTTON, EMenuButtonClass)) +#define E_IS_MENU_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MENU_BUTTON)) +#define E_IS_MENU_BUTTON_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MENU_BUTTON)) +#define E_MENU_BUTTON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MENU_BUTTON, EMenuButtonClass)) + +G_BEGIN_DECLS + +typedef struct _EMenuButton EMenuButton; +typedef struct _EMenuButtonClass EMenuButtonClass; +typedef struct _EMenuButtonPrivate EMenuButtonPrivate; + +struct _EMenuButton { + GtkButton parent; + EMenuButtonPrivate *priv; +}; + +struct _EMenuButtonClass { + GtkButtonClass parent_class; + + /* Signals */ + void (*show_menu) (EMenuButton *menu_button); +}; + +GType e_menu_button_get_type (void); +GtkWidget * e_menu_button_new (void); +GtkWidget * e_menu_button_get_menu (EMenuButton *menu_button); +void e_menu_button_set_menu (EMenuButton *menu_button, + GtkWidget *menu); + +G_END_DECLS + +#endif /* E_MENU_BUTTON_H */ -- cgit v1.2.3 From c2282f18c4592e4c911d893290e14a5fcd4fb3b3 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 7 Apr 2009 21:45:20 +0000 Subject: Hey, how'd those get in there? svn path=/branches/kill-bonobo/; revision=37505 --- widgets/misc/Makefile.am | 2 - widgets/misc/e-menu-button.c | 497 ------------------------------------------- widgets/misc/e-menu-button.h | 74 ------- 3 files changed, 573 deletions(-) delete mode 100644 widgets/misc/e-menu-button.c delete mode 100644 widgets/misc/e-menu-button.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ce22c3b065..ffc5195367 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -70,7 +70,6 @@ widgetsinclude_HEADERS = \ e-icon-entry.h \ e-image-chooser.h \ e-map.h \ - e-menu-button.h \ e-menu-tool-button.h \ e-online-button.h \ e-popup-action.h \ @@ -135,7 +134,6 @@ libemiscwidgets_la_SOURCES = \ e-icon-entry.c \ e-image-chooser.c \ e-map.c \ - e-menu-button.c \ e-menu-tool-button.c \ e-online-button.c \ e-popup-action.c \ diff --git a/widgets/misc/e-menu-button.c b/widgets/misc/e-menu-button.c deleted file mode 100644 index af60790bc5..0000000000 --- a/widgets/misc/e-menu-button.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * e-menu-button.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "e-menu-button.h" - -#define E_MENU_BUTTON_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_MENU_BUTTON, EMenuButtonPrivate)) - -struct _EMenuButtonPrivate { - GtkWidget *toggle_button; - GtkMenu *menu; /* not referenced */ -}; - -enum { - PROP_0, - PROP_MENU -}; - -enum { - SHOW_MENU, - LAST_SIGNAL -}; - -static gpointer parent_class; -static gulong signals[LAST_SIGNAL]; - -static void -menu_button_detach (GtkWidget *widget, - GtkMenu *menu) -{ - EMenuButtonPrivate *priv; - - priv = E_MENU_BUTTON_GET_PRIVATE (widget); - - g_return_if_fail (priv->menu == menu); - - priv->menu = NULL; -} - -static void -menu_button_deactivate_cb (EMenuButton *menu_button) -{ - GtkToggleButton *toggle_button; - - toggle_button = GTK_TOGGLE_BUTTON (menu_button->priv->toggle_button); - gtk_toggle_button_set_active (toggle_button, FALSE); -} - -static void -menu_button_menu_position (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - EMenuButton *menu_button) -{ - GtkRequisition requisition; - GtkTextDirection direction; - GdkRectangle monitor; - GdkScreen *screen; - GdkWindow *window; - GtkWidget *widget; - GtkWidget *toggle_button; - gint button_bottom; - gint monitor_bottom; - gint monitor_num; - - widget = GTK_WIDGET (menu_button); - toggle_button = menu_button->priv->toggle_button; - gtk_widget_size_request (GTK_WIDGET (menu), &requisition); - - window = gtk_widget_get_parent_window (widget); - screen = gtk_widget_get_screen (GTK_WIDGET (menu)); - monitor_num = gdk_screen_get_monitor_at_window (screen, window); - if (monitor_num < 0) - monitor_num = 0; - gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - - gdk_window_get_origin (window, x, y); - *x += widget->allocation.x; - *y += widget->allocation.y; - - direction = gtk_widget_get_direction (widget); - if (direction == GTK_TEXT_DIR_LTR) - x += MAX (widget->allocation.width - requisition.width, 0); - else if (requisition.width > widget->allocation.width) - x -= requisition.width - widget->allocation.width; - - button_bottom = *y + toggle_button->allocation.height; - monitor_bottom = monitor.y + monitor.height; - - if (button_bottom + requisition.height <= monitor_bottom) - y += toggle_button->allocation.height; - else if (*y - requisition.height >= monitor.y) - y -= requisition.height; - else if (monitor_bottom - button_bottom > *y) - y += toggle_button->allocation.height; - else - y -= requisition.height; - - *push_in = FALSE; -} - -static void -menu_button_show_popup_menu (EMenuButton *menu_button, - GdkEventButton *event) -{ - g_signal_emit (menu_button, signals[SHOW_MENU], 0); - - if (menu_button->priv->menu == NULL) - return; - - if (event != NULL) - gtk_menu_popup ( - menu_button->priv->menu, NULL, NULL, - (GtkMenuPositionFunc) menu_button_menu_position, - menu_button, event->button, event->time); - else - gtk_menu_popup ( - menu_button->priv->menu, NULL, NULL, - (GtkMenuPositionFunc) menu_button_menu_position, - menu_button, 0, gtk_get_current_event_time ()); -} - -static gboolean -menu_button_toggle_button_press_event_cb (EMenuButton *menu_button, - GdkEventButton *event) -{ - if (event->button == 1) { - menu_button_show_popup_menu (menu_button, event); - return TRUE; - } - - return FALSE; -} - -static void -menu_button_toggle_toggled_cb (EMenuButton *menu_button) -{ - GtkMenuShell *menu_shell; - GtkToggleButton *toggle_button; - - menu_shell = GTK_MENU_SHELL (menu_button->priv->menu); - toggle_button = GTK_TOGGLE_BUTTON (menu_button->priv->toggle_button); - - if (!gtk_toggle_button_get_active (toggle_button)) - return; - - if (GTK_WIDGET_VISIBLE (menu_shell)) - return; - - /* We get here only when the menu is activated by a key - * press, so that we can select the first menu item. */ - menu_button_show_popup_menu (menu_button, NULL); - gtk_menu_shell_select_first (menu_shell, FALSE); -} - -static void -menu_button_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_MENU: - e_menu_button_set_menu ( - E_MENU_BUTTON (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -menu_button_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_MENU: - g_value_set_object ( - value, e_menu_button_get_menu ( - E_MENU_BUTTON (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -menu_button_dispose (GObject *object) -{ - EMenuButtonPrivate *priv; - - priv = E_MENU_BUTTON_GET_PRIVATE (object); - - if (priv->toggle_button != NULL) { - g_object_unref (priv->toggle_button); - priv->toggle_button = NULL; - } - - if (priv->menu != NULL) { - g_signal_handlers_disconnect_by_func ( - priv->menu, menu_button_deactivate_cb, object); - gtk_menu_detach (priv->menu); - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -menu_button_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EMenuButtonPrivate *priv; - GtkRequisition child_requisition; - GtkWidget *child; - - priv = E_MENU_BUTTON_GET_PRIVATE (widget); - - /* Chain up to parent's size_request() method. */ - GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); - - child = priv->toggle_button; - gtk_widget_size_request (child, &child_requisition); - requisition->width += child_requisition.width; -} - -static void -menu_button_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EMenuButtonPrivate *priv; - GtkAllocation child_allocation; - GtkRequisition child_requisition; - GtkWidget *child; - gint toggle_x; - - priv = E_MENU_BUTTON_GET_PRIVATE (widget); - - widget->allocation = *allocation; - - child = priv->toggle_button; - gtk_widget_size_request (child, &child_requisition); - - toggle_x = allocation->x + allocation->width - child_requisition.width; - - child_allocation.x = allocation->x; - child_allocation.y = allocation->y; - child_allocation.width = toggle_x - allocation->x; - child_allocation.height = allocation->height; - - /* Chain up to parent's size_allocate() method. */ - GTK_WIDGET_CLASS (parent_class)-> - size_allocate (widget, &child_allocation); - - child_allocation.x = toggle_x; - child_allocation.y = allocation->y; - child_allocation.width = child_requisition.width; - child_allocation.height = allocation->height; - - gtk_widget_size_allocate (child, &child_allocation); -} - -static void -menu_button_state_changed (GtkWidget *widget, - GtkStateType previous_state) -{ - EMenuButtonPrivate *priv; - - priv = E_MENU_BUTTON_GET_PRIVATE (widget); - - if (!GTK_WIDGET_IS_SENSITIVE (widget) && priv->menu != NULL) - gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu)); - - /* Chain up to parent's state_changed() method. */ - GTK_WIDGET_CLASS (parent_class)-> - state_changed (widget, previous_state); -} - -static void -menu_button_remove (GtkContainer *container, - GtkWidget *widget) -{ - EMenuButtonPrivate *priv; - - priv = E_MENU_BUTTON_GET_PRIVATE (container); - - /* Look in the internal widgets first. */ - - if (widget == priv->toggle_button) { - gtk_widget_unparent (priv->toggle_button); - gtk_widget_queue_resize (GTK_WIDGET (container)); - return; - } - - /* Chain up to parent's remove() method. */ - GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); -} - -static void -menu_button_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - EMenuButtonPrivate *priv; - - priv = E_MENU_BUTTON_GET_PRIVATE (container); - - if (include_internals) - callback (priv->toggle_button, callback_data); - - /* Chain up to parent's forall() method. */ - GTK_CONTAINER_CLASS (parent_class)->forall ( - container, include_internals, callback, callback_data); -} - -static void -menu_button_class_init (EMenuButtonClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EMenuButtonPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = menu_button_set_property; - object_class->get_property = menu_button_get_property; - object_class->dispose = menu_button_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->size_request = menu_button_size_request; - widget_class->size_allocate = menu_button_size_allocate; - widget_class->state_changed = menu_button_state_changed; - - container_class = GTK_CONTAINER_CLASS (class); - container_class->remove = menu_button_remove; - container_class->forall = menu_button_forall; - - g_object_class_install_property ( - object_class, - PROP_MENU, - g_param_spec_object ( - "menu", - "Menu", - NULL, - GTK_TYPE_MENU, - G_PARAM_READWRITE)); - - signals[SHOW_MENU] = g_signal_new ( - "show-menu", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EMenuButtonClass, show_menu), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -menu_button_init (EMenuButton *menu_button) -{ - GtkWidget *container; - GtkWidget *widget; - - menu_button->priv = E_MENU_BUTTON_GET_PRIVATE (menu_button); - - container = GTK_WIDGET (menu_button); - - widget = gtk_toggle_button_new (); - gtk_widget_set_sensitive (widget, FALSE); - gtk_widget_set_parent (widget, container); - menu_button->priv->toggle_button = g_object_ref (widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - menu_button->priv->toggle_button, "button-press-event", - G_CALLBACK (menu_button_toggle_button_press_event_cb), - menu_button); - - g_signal_connect_swapped ( - menu_button->priv->toggle_button, "toggled", - G_CALLBACK (menu_button_toggle_toggled_cb), menu_button); -} - -GType -e_menu_button_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EMenuButtonClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) menu_button_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_init */ - sizeof (EMenuButton), - 0, /* n_preallocs */ - (GInstanceInitFunc) menu_button_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - GTK_TYPE_BUTTON, "EMenuButton", &type_info, 0); - } - - return type; -} - -GtkWidget * -e_menu_button_new (void) -{ - return g_object_new (E_TYPE_MENU_BUTTON, NULL); -} - -GtkWidget * -e_menu_button_get_menu (EMenuButton *menu_button) -{ - g_return_val_if_fail (E_IS_MENU_BUTTON (menu_button), NULL); - - return GTK_WIDGET (menu_button->priv->menu); -} - -void -e_menu_button_set_menu (EMenuButton *menu_button, - GtkWidget *menu) -{ - g_return_if_fail (E_IS_MENU_BUTTON (menu_button)); - g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL); - - if (menu_button->priv->menu == GTK_MENU (menu)) - goto exit; - - if (menu_button->priv->menu != NULL) { - GtkMenuShell *menu_shell; - - menu_shell = GTK_MENU_SHELL (menu_button->priv->menu); - - if (GTK_WIDGET_VISIBLE (menu_shell)) - gtk_menu_shell_deactivate (menu_shell); - - g_signal_handlers_disconnect_by_func ( - menu_shell, menu_button_deactivate_cb, menu_button); - - gtk_menu_detach (menu_button->priv->menu); - } - - menu_button->priv->menu = GTK_MENU (menu); - - if (menu != NULL) { - gtk_menu_attach_to_widget ( - GTK_MENU (menu), GTK_WIDGET (menu_button), - (GtkMenuDetachFunc) menu_button_detach); - - g_signal_connect_swapped ( - menu, "deactivate", - G_CALLBACK (menu_button_deactivate_cb), menu_button); - } - - gtk_widget_set_sensitive ( - menu_button->priv->toggle_button, menu != NULL); - -exit: - g_object_notify (G_OBJECT (menu_button), "menu"); -} diff --git a/widgets/misc/e-menu-button.h b/widgets/misc/e-menu-button.h deleted file mode 100644 index fa27a77c67..0000000000 --- a/widgets/misc/e-menu-button.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * e-menu-button.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* This is like a GtkMenuToolButton, expect not a GtkToolItem. */ - -#ifndef E_MENU_BUTTON_H -#define E_MENU_BUTTON_H - -#include - -/* Standard GObject macros */ -#define E_TYPE_MENU_BUTTON \ - (e_menu_button_get_type ()) -#define E_MENU_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MENU_BUTTON, EMenuButton)) -#define E_MENU_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MENU_BUTTON, EMenuButtonClass)) -#define E_IS_MENU_BUTTON(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MENU_BUTTON)) -#define E_IS_MENU_BUTTON_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MENU_BUTTON)) -#define E_MENU_BUTTON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MENU_BUTTON, EMenuButtonClass)) - -G_BEGIN_DECLS - -typedef struct _EMenuButton EMenuButton; -typedef struct _EMenuButtonClass EMenuButtonClass; -typedef struct _EMenuButtonPrivate EMenuButtonPrivate; - -struct _EMenuButton { - GtkButton parent; - EMenuButtonPrivate *priv; -}; - -struct _EMenuButtonClass { - GtkButtonClass parent_class; - - /* Signals */ - void (*show_menu) (EMenuButton *menu_button); -}; - -GType e_menu_button_get_type (void); -GtkWidget * e_menu_button_new (void); -GtkWidget * e_menu_button_get_menu (EMenuButton *menu_button); -void e_menu_button_set_menu (EMenuButton *menu_button, - GtkWidget *menu); - -G_END_DECLS - -#endif /* E_MENU_BUTTON_H */ -- cgit v1.2.3 From 942cdf2df9091e347e09c25d62015e77775f38b6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 11 Apr 2009 00:14:51 +0000 Subject: Bug fixes and formerly unfinished bits of the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37513 --- widgets/misc/e-attachment-handler-image.c | 9 ++------- widgets/misc/e-attachment-store.c | 2 +- widgets/misc/e-attachment-store.h | 2 +- widgets/misc/e-attachment-tree-view.c | 4 ++-- widgets/misc/e-attachment-view.c | 22 ++++++++++++++++++++++ widgets/misc/e-attachment-view.h | 3 +++ widgets/misc/e-attachment.c | 10 +++++++--- 7 files changed, 38 insertions(+), 14 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-handler-image.c b/widgets/misc/e-attachment-handler-image.c index 02357facc9..ba5f8d759c 100644 --- a/widgets/misc/e-attachment-handler-image.c +++ b/widgets/misc/e-attachment-handler-image.c @@ -21,7 +21,6 @@ #include "e-attachment-handler-image.h" -#include #include #include @@ -205,7 +204,6 @@ attachment_handler_image_constructed (GObject *object) EAttachmentView *view; GtkActionGroup *action_group; GtkUIManager *ui_manager; - const gchar *domain = GETTEXT_PACKAGE; GError *error = NULL; handler = E_ATTACHMENT_HANDLER (object); @@ -215,16 +213,13 @@ attachment_handler_image_constructed (GObject *object) G_OBJECT_CLASS (parent_class)->constructed (object); view = e_attachment_handler_get_view (handler); - ui_manager = e_attachment_view_get_ui_manager (view); - action_group = gtk_action_group_new ("image"); - gtk_action_group_set_translation_domain (action_group, domain); + action_group = e_attachment_view_add_action_group (view, "image"); gtk_action_group_add_actions ( action_group, standard_entries, G_N_ELEMENTS (standard_entries), object); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); + ui_manager = e_attachment_view_get_ui_manager (view); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); if (error != NULL) { diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 24cc89b366..4a74bab915 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -213,7 +213,7 @@ attachment_store_init (EAttachmentStore *store) types[column++] = E_TYPE_ATTACHMENT; /* COLUMN_ATTACHMENT */ types[column++] = G_TYPE_STRING; /* COLUMN_CAPTION */ types[column++] = G_TYPE_STRING; /* COLUMN_CONTENT_TYPE */ - types[column++] = G_TYPE_STRING; /* COLUMN_DISPLAY_NAME */ + types[column++] = G_TYPE_STRING; /* COLUMN_DESCRIPTION */ types[column++] = G_TYPE_ICON; /* COLUMN_ICON */ types[column++] = G_TYPE_BOOLEAN; /* COLUMN_LOADING */ types[column++] = G_TYPE_INT; /* COLUMN_PERCENT */ diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index a6dd702b97..5d2271cba0 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -63,7 +63,7 @@ enum { E_ATTACHMENT_STORE_COLUMN_ATTACHMENT, /* E_TYPE_ATTACHMENT */ E_ATTACHMENT_STORE_COLUMN_CAPTION, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */ - E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, /* G_TYPE_STRING */ + E_ATTACHMENT_STORE_COLUMN_DESCRIPTION, /* G_TYPE_STRING */ E_ATTACHMENT_STORE_COLUMN_ICON, /* G_TYPE_ICON */ E_ATTACHMENT_STORE_COLUMN_LOADING, /* G_TYPE_BOOLEAN */ E_ATTACHMENT_STORE_COLUMN_PERCENT, /* G_TYPE_INT */ diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index f8a74d293f..f2c17cb078 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -493,7 +493,7 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_spacing (column, 3); - gtk_tree_view_column_set_title (column, _("Name")); + gtk_tree_view_column_set_title (column, _("Description")); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); renderer = gtk_cell_renderer_pixbuf_new (); @@ -511,7 +511,7 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view) gtk_tree_view_column_add_attribute ( column, renderer, "text", - E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME); + E_ATTACHMENT_STORE_COLUMN_DESCRIPTION); renderer = gtk_cell_renderer_progress_new (); g_object_set (renderer, "text", _("Loading"), NULL); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 5c7acd4561..f976b71483 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -1455,6 +1455,28 @@ e_attachment_view_get_action (EAttachmentView *view, return e_lookup_action (ui_manager, action_name); } +GtkActionGroup * +e_attachment_view_add_action_group (EAttachmentView *view, + const gchar *group_name) +{ + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + const gchar *domain; + + g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + ui_manager = e_attachment_view_get_ui_manager (view); + domain = GETTEXT_PACKAGE; + + action_group = gtk_action_group_new (group_name); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + g_object_unref (action_group); + + return action_group; +} + GtkActionGroup * e_attachment_view_get_action_group (EAttachmentView *view, const gchar *group_name) diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 8285928c5b..8d1bd328dd 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -206,6 +206,9 @@ void e_attachment_view_drag_data_received /* Popup Menu Management */ GtkAction * e_attachment_view_get_action (EAttachmentView *view, const gchar *action_name); +GtkActionGroup *e_attachment_view_add_action_group + (EAttachmentView *view, + const gchar *group_name); GtkActionGroup *e_attachment_view_get_action_group (EAttachmentView *view, const gchar *group_name); diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 16bd9fd26c..a97ea1e70f 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -136,6 +136,7 @@ attachment_update_file_info_columns (EAttachment *attachment) GtkTreeIter iter; GFileInfo *file_info; const gchar *content_type; + const gchar *description; const gchar *display_name; gchar *content_desc; gchar *display_size; @@ -162,17 +163,20 @@ attachment_update_file_info_columns (EAttachment *attachment) content_desc = g_content_type_get_description (content_type); display_size = g_format_size_for_display (size); + description = e_attachment_get_description (attachment); + description = (description != NULL) ? description : display_name; + if (size > 0) caption = g_strdup_printf ( - "%s\n(%s)", display_name, display_size); + "%s\n(%s)", description, display_size); else - caption = g_strdup (display_name); + caption = g_strdup (description); gtk_list_store_set ( GTK_LIST_STORE (model), &iter, E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_desc, - E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, + E_ATTACHMENT_STORE_COLUMN_DESCRIPTION, description, E_ATTACHMENT_STORE_COLUMN_SIZE, size, -1); -- cgit v1.2.3 From 582ec45a59973e3beed7370c3476edaeb16c9eac Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 14 Apr 2009 19:03:37 +0000 Subject: Make the selected attachment view and file chooser folder persistent. svn path=/branches/kill-bonobo/; revision=37523 --- widgets/misc/e-attachment-paned.c | 14 ++++++++++++++ widgets/misc/e-attachment-store.c | 14 ++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index 9502f41296..a09fef0a66 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -22,7 +22,10 @@ #include "e-attachment-paned.h" #include + #include "e-util/e-binding.h" +#include "e-util/gconf-bridge.h" + #include "e-attachment-view.h" #include "e-attachment-store.h" #include "e-attachment-icon-view.h" @@ -272,9 +275,15 @@ static void attachment_paned_constructed (GObject *object) { EAttachmentPanedPrivate *priv; + GConfBridge *bridge; + const gchar *key; priv = E_ATTACHMENT_PANED_GET_PRIVATE (object); + bridge = gconf_bridge_get (); + + /* Set up property-to-property bindings. */ + e_mutual_binding_new ( G_OBJECT (object), "active-view", G_OBJECT (priv->combo_box), "active"); @@ -302,6 +311,11 @@ attachment_paned_constructed (GObject *object) e_mutual_binding_new ( G_OBJECT (object), "expanded", G_OBJECT (priv->notebook), "visible"); + + /* Set up property-to-GConf bindings. */ + + key = "/apps/evolution/shell/attachment_view"; + gconf_bridge_bind_property (bridge, key, object, "active-view"); } static EAttachmentViewPrivate * diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 4a74bab915..0b6e5a2baa 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -27,6 +27,7 @@ #include "e-util/e-util.h" #include "e-util/e-mktemp.h" +#include "e-util/gconf-bridge.h" #define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -133,6 +134,18 @@ attachment_store_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +attachment_store_constructed (GObject *object) +{ + GConfBridge *bridge; + const gchar *key; + + bridge = gconf_bridge_get (); + + key = "/apps/evolution/shell/current_folder"; + gconf_bridge_bind_property (bridge, key, object, "current-folder"); +} + static void attachment_store_class_init (EAttachmentStoreClass *class) { @@ -146,6 +159,7 @@ attachment_store_class_init (EAttachmentStoreClass *class) object_class->get_property = attachment_store_get_property; object_class->dispose = attachment_store_dispose; object_class->finalize = attachment_store_finalize; + object_class->constructed = attachment_store_constructed; g_object_class_install_property ( object_class, -- cgit v1.2.3 From ca691310d85f7a266d070cb004d3534215ac47d0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 15 Apr 2009 00:15:46 +0000 Subject: Add "View Inline" / "Hide" menu items to the popup menu. Add application icons to the "Open With" menu items. svn path=/branches/kill-bonobo/; revision=37524 --- widgets/misc/e-attachment-button.c | 38 ++++++++++-- widgets/misc/e-attachment-view.c | 123 +++++++++++++++++++++++++++---------- widgets/misc/e-attachment-view.h | 3 - widgets/misc/e-attachment.c | 92 ++++++++++++++++++++++++++- widgets/misc/e-attachment.h | 6 ++ 5 files changed, 219 insertions(+), 43 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c index fa43373a3c..a9c230bac7 100644 --- a/widgets/misc/e-attachment-button.c +++ b/widgets/misc/e-attachment-button.c @@ -35,6 +35,9 @@ struct _EAttachmentButtonPrivate { EAttachment *attachment; gulong reference_handler_id; + EMutualBinding *can_show_binding; + EMutualBinding *shown_binding; + GtkWidget *expand_button; GtkWidget *toggle_button; GtkWidget *cell_view; @@ -56,11 +59,17 @@ static gpointer parent_class; static void attachment_button_menu_deactivate_cb (EAttachmentButton *button) { + EAttachmentView *view; + GtkActionGroup *action_group; GtkToggleButton *toggle_button; + view = e_attachment_button_get_view (button); + action_group = e_attachment_view_get_action_group (view, "inline"); toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); gtk_toggle_button_set_active (toggle_button, FALSE); + + gtk_action_group_set_visible (action_group, FALSE); } static void @@ -96,9 +105,9 @@ attachment_button_menu_position (GtkMenu *menu, direction = gtk_widget_get_direction (widget); if (direction == GTK_TEXT_DIR_LTR) - x += MAX (widget->allocation.width - menu_requisition.width, 0); + *x += MAX (widget->allocation.width - menu_requisition.width, 0); else if (menu_requisition.width > widget->allocation.width) - x -= menu_requisition.width - widget->allocation.width; + *x -= menu_requisition.width - widget->allocation.width; if ((*y + toggle_button->allocation.height + menu_requisition.height) <= monitor.y + monitor.height) *y += toggle_button->allocation.height; @@ -139,10 +148,12 @@ static void attachment_button_show_popup_menu (EAttachmentButton *button, GdkEventButton *event) { - GtkToggleButton *toggle_button; EAttachmentView *view; + GtkActionGroup *action_group; + GtkToggleButton *toggle_button; view = e_attachment_button_get_view (button); + action_group = e_attachment_view_get_action_group (view, "inline"); toggle_button = GTK_TOGGLE_BUTTON (button->priv->toggle_button); attachment_button_select_path (button); @@ -152,6 +163,7 @@ attachment_button_show_popup_menu (EAttachmentButton *button, view, event, (GtkMenuPositionFunc) attachment_button_menu_position, button); + gtk_action_group_set_visible (action_group, TRUE); } static void @@ -630,6 +642,12 @@ e_attachment_button_set_attachment (EAttachmentButton *button, } if (button->priv->attachment != NULL) { + e_mutual_binding_unbind ( + button->priv->can_show_binding); + button->priv->can_show_binding = NULL; + e_mutual_binding_unbind ( + button->priv->shown_binding); + button->priv->shown_binding = NULL; g_signal_handler_disconnect ( button->priv->attachment, button->priv->reference_handler_id); @@ -639,15 +657,27 @@ e_attachment_button_set_attachment (EAttachmentButton *button, button->priv->attachment = attachment; if (attachment != NULL) { + EMutualBinding *binding; gulong handler_id; + binding = e_mutual_binding_new ( + G_OBJECT (attachment), "can-show", + G_OBJECT (button), "expandable"); + button->priv->can_show_binding = binding; + + binding = e_mutual_binding_new ( + G_OBJECT (attachment), "shown", + G_OBJECT (button), "expanded"); + button->priv->shown_binding = binding; + handler_id = g_signal_connect_swapped ( attachment, "notify::reference", G_CALLBACK (attachment_button_update_cell_view), button); + button->priv->reference_handler_id = handler_id; + attachment_button_update_cell_view (button); attachment_button_update_pixbufs (button); - button->priv->reference_handler_id = handler_id; } g_object_notify (G_OBJECT (button), "attachment"); diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index f976b71483..2ad34d6751 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -51,6 +51,11 @@ static const gchar *ui = " " " " " " +" " +" " +" " +" " +" " " " " " " " @@ -92,6 +97,23 @@ action_cancel_cb (GtkAction *action, g_list_free (selected); } +static void +action_hide_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = selected->data; + + e_attachment_set_shown (attachment, FALSE); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + static void action_open_in_cb (GtkAction *action, EAttachmentView *view) @@ -246,6 +268,23 @@ exit: g_list_free (selected); } +static void +action_show_cb (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = selected->data; + + e_attachment_set_shown (attachment, TRUE); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + static GtkActionEntry standard_entries[] = { { "cancel", @@ -303,6 +342,23 @@ static GtkActionEntry editable_entries[] = { G_CALLBACK (action_remove_cb) } }; +static GtkActionEntry inline_entries[] = { + + { "hide", + NULL, + N_("_Hide"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_hide_cb) }, + + { "show", + NULL, + N_("_View Inline"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_show_cb) } +}; + static void attachment_view_netscape_url (EAttachmentView *view, GdkDragContext *drag_context, @@ -514,10 +570,13 @@ attachment_view_update_actions (EAttachmentView *view) { EAttachmentViewPrivate *priv; EAttachment *attachment; + GtkActionGroup *action_group; GtkAction *action; GList *list, *iter; guint n_selected; gboolean busy = FALSE; + gboolean can_show = FALSE; + gboolean shown = FALSE; g_return_if_fail (E_IS_ATTACHMENT_VIEW (view)); @@ -529,6 +588,8 @@ attachment_view_update_actions (EAttachmentView *view) attachment = g_object_ref (list->data); busy |= e_attachment_get_loading (attachment); busy |= e_attachment_get_saving (attachment); + can_show = e_attachment_get_can_show (attachment); + shown = e_attachment_get_shown (attachment); } else attachment = NULL; @@ -538,6 +599,9 @@ attachment_view_update_actions (EAttachmentView *view) action = e_attachment_view_get_action (view, "cancel"); gtk_action_set_visible (action, busy); + action = e_attachment_view_get_action (view, "hide"); + gtk_action_set_visible (action, can_show && shown); + action = e_attachment_view_get_action (view, "properties"); gtk_action_set_visible (action, !busy && n_selected == 1); @@ -547,9 +611,13 @@ attachment_view_update_actions (EAttachmentView *view) action = e_attachment_view_get_action (view, "save-as"); gtk_action_set_visible (action, !busy && n_selected > 0); + action = e_attachment_view_get_action (view, "show"); + gtk_action_set_visible (action, can_show && !shown); + /* Clear out the "openwith" action group. */ gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id); - e_action_group_remove_all_actions (priv->openwith_actions); + action_group = e_attachment_view_get_action_group (view, "openwith"); + e_action_group_remove_all_actions (action_group); if (attachment == NULL || busy) return; @@ -559,6 +627,7 @@ attachment_view_update_actions (EAttachmentView *view) for (iter = list; iter != NULL; iter = iter->next) { GAppInfo *app_info = iter->data; GtkAction *action; + GIcon *app_icon; const gchar *app_executable; const gchar *app_name; gchar *action_tooltip; @@ -569,6 +638,7 @@ attachment_view_update_actions (EAttachmentView *view) continue; app_executable = g_app_info_get_executable (app_info); + app_icon = g_app_info_get_icon (app_info); app_name = g_app_info_get_name (app_info); action_name = g_strdup_printf ("open-in-%s", app_executable); @@ -580,6 +650,8 @@ attachment_view_update_actions (EAttachmentView *view) action = gtk_action_new ( action_name, action_label, action_tooltip, NULL); + gtk_action_set_gicon (action, app_icon); + g_object_set_data_full ( G_OBJECT (action), "app-info", g_object_ref (app_info), @@ -594,7 +666,7 @@ attachment_view_update_actions (EAttachmentView *view) action, "activate", G_CALLBACK (action_open_in_cb), view); - gtk_action_group_add_action (priv->openwith_actions, action); + gtk_action_group_add_action (action_group, action); gtk_ui_manager_add_ui ( priv->ui_manager, priv->merge_id, @@ -713,7 +785,6 @@ e_attachment_view_init (EAttachmentView *view) EAttachmentViewPrivate *priv; GtkUIManager *ui_manager; GtkActionGroup *action_group; - const gchar *domain = GETTEXT_PACKAGE; GError *error = NULL; priv = e_attachment_view_get_private (view); @@ -722,26 +793,29 @@ e_attachment_view_init (EAttachmentView *view) priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager); priv->ui_manager = ui_manager; - action_group = gtk_action_group_new ("standard"); - gtk_action_group_set_translation_domain (action_group, domain); + action_group = e_attachment_view_add_action_group (view, "standard"); + gtk_action_group_add_actions ( action_group, standard_entries, G_N_ELEMENTS (standard_entries), view); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - priv->standard_actions = action_group; - action_group = gtk_action_group_new ("editable"); - gtk_action_group_set_translation_domain (action_group, domain); + action_group = e_attachment_view_add_action_group (view, "editable"); + + e_mutual_binding_new ( + G_OBJECT (view), "editable", + G_OBJECT (action_group), "visible"); gtk_action_group_add_actions ( action_group, editable_entries, G_N_ELEMENTS (editable_entries), view); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - priv->editable_actions = action_group; - action_group = gtk_action_group_new ("openwith"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - priv->openwith_actions = action_group; + action_group = e_attachment_view_add_action_group (view, "inline"); + + gtk_action_group_add_actions ( + action_group, inline_entries, + G_N_ELEMENTS (inline_entries), view); + gtk_action_group_set_visible (action_group, FALSE); + + e_attachment_view_add_action_group (view, "openwith"); /* Because we are loading from a hard-coded string, there is * no chance of I/O errors. Failure here implies a malformed @@ -750,10 +824,6 @@ e_attachment_view_init (EAttachmentView *view) if (error != NULL) g_error ("%s", error->message); - e_mutual_binding_new ( - G_OBJECT (view), "editable", - G_OBJECT (priv->editable_actions), "visible"); - attachment_view_init_handlers (view); e_attachment_view_drag_source_set (view); @@ -797,21 +867,6 @@ e_attachment_view_dispose (EAttachmentView *view) g_object_unref (priv->ui_manager); priv->ui_manager = NULL; } - - if (priv->standard_actions != NULL) { - g_object_unref (priv->standard_actions); - priv->standard_actions = NULL; - } - - if (priv->editable_actions != NULL) { - g_object_unref (priv->editable_actions); - priv->editable_actions = NULL; - } - - if (priv->openwith_actions != NULL) { - g_object_unref (priv->openwith_actions); - priv->openwith_actions = NULL; - } } void diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 8d1bd328dd..0fc5118669 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -101,9 +101,6 @@ struct _EAttachmentViewPrivate { /* Popup Menu Management */ GtkUIManager *ui_manager; - GtkActionGroup *standard_actions; - GtkActionGroup *editable_actions; - GtkActionGroup *openwith_actions; guint merge_id; guint editable : 1; diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index a97ea1e70f..92ebd36be4 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -66,8 +66,10 @@ struct _EAttachmentPrivate { gchar *disposition; gint percent; - guint loading : 1; - guint saving : 1; + guint can_show : 1; + guint loading : 1; + guint saving : 1; + guint shown : 1; camel_cipher_validity_encrypt_t encrypted; camel_cipher_validity_sign_t signed_; @@ -81,6 +83,7 @@ struct _EAttachmentPrivate { enum { PROP_0, + PROP_CAN_SHOW, PROP_DISPOSITION, PROP_ENCRYPTED, PROP_FILE, @@ -90,6 +93,7 @@ enum { PROP_PERCENT, PROP_REFERENCE, PROP_SAVING, + PROP_SHOWN, PROP_SIGNED }; @@ -445,6 +449,12 @@ attachment_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_CAN_SHOW: + e_attachment_set_can_show ( + E_ATTACHMENT (object), + g_value_get_boolean (value)); + return; + case PROP_DISPOSITION: e_attachment_set_disposition ( E_ATTACHMENT (object), @@ -463,6 +473,12 @@ attachment_set_property (GObject *object, g_value_get_object (value)); return; + case PROP_SHOWN: + e_attachment_set_shown ( + E_ATTACHMENT (object), + g_value_get_boolean (value)); + return; + case PROP_MIME_PART: e_attachment_set_mime_part ( E_ATTACHMENT (object), @@ -492,6 +508,12 @@ attachment_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_CAN_SHOW: + g_value_set_boolean ( + value, e_attachment_get_can_show ( + E_ATTACHMENT (object))); + return; + case PROP_DISPOSITION: g_value_set_string ( value, e_attachment_get_disposition ( @@ -516,6 +538,12 @@ attachment_get_property (GObject *object, E_ATTACHMENT (object))); return; + case PROP_SHOWN: + g_value_set_boolean ( + value, e_attachment_get_shown ( + E_ATTACHMENT (object))); + return; + case PROP_LOADING: g_value_set_boolean ( value, e_attachment_get_loading ( @@ -623,6 +651,17 @@ attachment_class_init (EAttachmentClass *class) object_class->dispose = attachment_dispose; object_class->finalize = attachment_finalize; + g_object_class_install_property ( + object_class, + PROP_CAN_SHOW, + g_param_spec_boolean ( + "can-show", + "Can Show", + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property ( object_class, PROP_DISPOSITION, @@ -721,6 +760,17 @@ attachment_class_init (EAttachmentClass *class) FALSE, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_SHOWN, + g_param_spec_boolean ( + "shown", + "Shown", + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + /* FIXME Define a GEnumClass for this. */ g_object_class_install_property ( object_class, @@ -985,6 +1035,25 @@ e_attachment_cancel (EAttachment *attachment) g_cancellable_cancel (attachment->priv->cancellable); } +gboolean +e_attachment_get_can_show (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->can_show; +} + +void +e_attachment_set_can_show (EAttachment *attachment, + gboolean can_show) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + attachment->priv->can_show = can_show; + + g_object_notify (G_OBJECT (attachment), "can-show"); +} + const gchar * e_attachment_get_disposition (EAttachment *attachment) { @@ -1114,6 +1183,25 @@ e_attachment_get_saving (EAttachment *attachment) return attachment->priv->saving; } +gboolean +e_attachment_get_shown (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + return attachment->priv->shown; +} + +void +e_attachment_set_shown (EAttachment *attachment, + gboolean shown) +{ + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + attachment->priv->shown = shown; + + g_object_notify (G_OBJECT (attachment), "shown"); +} + camel_cipher_validity_encrypt_t e_attachment_get_encrypted (EAttachment *attachment) { diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 1184b32012..934e1e04b6 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -71,6 +71,9 @@ void e_attachment_add_to_multipart (EAttachment *attachment, CamelMultipart *multipart, const gchar *default_charset); void e_attachment_cancel (EAttachment *attachment); +gboolean e_attachment_get_can_show (EAttachment *attachment); +void e_attachment_set_can_show (EAttachment *attachment, + gboolean can_show); const gchar * e_attachment_get_disposition (EAttachment *attachment); void e_attachment_set_disposition (EAttachment *attachment, const gchar *disposition); @@ -88,6 +91,9 @@ GtkTreeRowReference * void e_attachment_set_reference (EAttachment *attachment, GtkTreeRowReference *reference); gboolean e_attachment_get_saving (EAttachment *attachment); +gboolean e_attachment_get_shown (EAttachment *attachment); +void e_attachment_set_shown (EAttachment *attachment, + gboolean shown); camel_cipher_validity_encrypt_t e_attachment_get_encrypted (EAttachment *attachment); void e_attachment_set_encrypted (EAttachment *attachment, -- cgit v1.2.3 From 9b73ae5c7d2c016a3b1f07b1040355063b32814b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 23 Apr 2009 16:48:05 -0400 Subject: Miscellaneous bug fixes. --- widgets/misc/Makefile.am | 2 ++ widgets/misc/e-activity.c | 84 +++++++++++++++++++++++++++++++---------------- widgets/misc/e-activity.h | 4 +-- 3 files changed, 58 insertions(+), 32 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ffc5195367..2fa7327e35 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -51,6 +51,7 @@ widgetsinclude_HEADERS = \ e-attachment-view.h \ e-calendar.h \ e-calendar-item.h \ + e-camel-activity.h \ e-canvas.h \ e-canvas-background.h \ e-canvas-utils.h \ @@ -115,6 +116,7 @@ libemiscwidgets_la_SOURCES = \ e-attachment-view.c \ e-calendar.c \ e-calendar-item.c \ + e-camel-activity.c \ e-canvas.c \ e-canvas-background.c \ e-canvas-utils.c \ diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index d40d5aacbe..7cd89a7c47 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -24,6 +24,8 @@ #include #include +#include "e-util/e-util.h" + #define E_ACTIVITY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ACTIVITY, EActivityPrivate)) @@ -58,6 +60,7 @@ enum { CANCELLED, CLICKED, COMPLETED, + DESCRIBE, LAST_SIGNAL }; @@ -84,6 +87,20 @@ activity_idle_complete_cb (EActivity *activity) return FALSE; } +static gboolean +activity_describe_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer accu_data) +{ + const gchar *string; + + string = g_value_get_string (handler_return); + g_value_set_string (return_accu, string); + + return (string == NULL); +} + static void activity_set_property (GObject *object, guint property_id, @@ -211,6 +228,34 @@ activity_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +activity_cancelled (EActivity *activity) +{ + activity->priv->cancelled = TRUE; + + if (activity->priv->idle_id > 0) { + g_source_remove (activity->priv->idle_id); + activity->priv->idle_id = 0; + } +} + +static void +activity_completed (EActivity *activity) +{ + activity->priv->completed = TRUE; + + if (activity->priv->idle_id > 0) { + g_source_remove (activity->priv->idle_id); + activity->priv->idle_id = 0; + } +} + +static void +activity_clicked (EActivity *activity) +{ + /* Allow subclasses to safely chain up. */ +} + static gchar * activity_describe (EActivity *activity) { @@ -247,34 +292,6 @@ activity_describe (EActivity *activity) return g_string_free (string, FALSE); } -static void -activity_cancelled (EActivity *activity) -{ - activity->priv->cancelled = TRUE; - - if (activity->priv->idle_id > 0) { - g_source_remove (activity->priv->idle_id); - activity->priv->idle_id = 0; - } -} - -static void -activity_completed (EActivity *activity) -{ - activity->priv->completed = TRUE; - - if (activity->priv->idle_id > 0) { - g_source_remove (activity->priv->idle_id); - activity->priv->idle_id = 0; - } -} - -static void -activity_clicked (EActivity *activity) -{ - /* Allow subclasses to safely chain up. */ -} - static void activity_class_init (EActivityClass *class) { @@ -288,10 +305,10 @@ activity_class_init (EActivityClass *class) object_class->get_property = activity_get_property; object_class->finalize = activity_finalize; - class->describe = activity_describe; class->cancelled = activity_cancelled; class->completed = activity_completed; class->clicked = activity_clicked; + class->describe = activity_describe; g_object_class_install_property ( object_class, @@ -398,6 +415,15 @@ activity_class_init (EActivityClass *class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[DESCRIBE] = g_signal_new ( + "describe", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EActivityClass, describe), + activity_describe_accumulator, NULL, + e_marshal_STRING__VOID, + G_TYPE_STRING, 0); } static void diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index 68f0bf20be..34974dd415 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -57,13 +57,11 @@ struct _EActivity { struct _EActivityClass { GObjectClass parent_class; - /* Methods */ - gchar * (*describe) (EActivity *activity); - /* Signals */ void (*cancelled) (EActivity *activity); void (*completed) (EActivity *activity); void (*clicked) (EActivity *activity); + gchar * (*describe) (EActivity *activity); }; GType e_activity_get_type (void); -- cgit v1.2.3 From 8ea9f9377f071d4e8088e5c744e5470ccddb0fb1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 24 Apr 2009 09:18:58 -0400 Subject: Fix a couple attachment issues Add a fallback icon name to attachments with GThemedIcons, just in case there's a problem loading the MIME type icon. I seen this when I build GTK+ locally and it can't find gnome-icon-theme icons. Also, fix a packing issue in EAttachmentPaned. CompEditor's attachment bar is still having problems, however. --- widgets/misc/e-attachment-paned.c | 7 +++++-- widgets/misc/e-attachment.c | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index a09fef0a66..3fed031473 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -37,6 +37,9 @@ #define NUM_VIEWS 2 +/* Initial height of the lower pane. */ +#define INITIAL_HEIGHT 150 + struct _EAttachmentPanedPrivate { GtkTreeModel *model; GtkWidget *expander; @@ -511,10 +514,10 @@ attachment_paned_init (EAttachmentPaned *paned) container = GTK_WIDGET (paned); widget = gtk_notebook_new (); - gtk_widget_set_size_request (widget, -1, 40); + gtk_widget_set_size_request (widget, -1, INITIAL_HEIGHT); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE); + gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE); paned->priv->notebook = g_object_ref (widget); gtk_widget_hide (widget); diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 92ebd36be4..ee5446e699 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -347,6 +347,7 @@ attachment_set_file_info (EAttachment *attachment, GFileInfo *file_info) { GtkTreeRowReference *reference; + GIcon *icon; reference = e_attachment_get_reference (attachment); @@ -358,6 +359,13 @@ attachment_set_file_info (EAttachment *attachment, attachment->priv->file_info = file_info; + /* If the GFileInfo contains a GThemedIcon, append a + * fallback icon name to ensure we display something. */ + icon = g_file_info_get_icon (file_info); + if (G_IS_THEMED_ICON (icon)) + g_themed_icon_append_name ( + G_THEMED_ICON (icon), DEFAULT_ICON_NAME); + g_object_notify (G_OBJECT (attachment), "file-info"); /* Tell the EAttachmentStore its total size changed. */ -- cgit v1.2.3 From c2119e513bc7482fc0150287af8502a5ff67191a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 24 Apr 2009 10:58:35 -0400 Subject: Fix a couple more attachment issues. Propagate attachment property changes to the CamelMimePart and emit a "notify::file-info" signal to refresh the row in the attachment model. Also, only fall back to showing the attachment's file name if its description is -empty- (not just NULL). --- widgets/misc/e-attachment-dialog.c | 14 ++++++++++++++ widgets/misc/e-attachment.c | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index dd39a253c9..e8c599aeea 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -212,6 +212,7 @@ attachment_dialog_response (GtkDialog *dialog, EAttachment *attachment; GtkToggleButton *button; GFileInfo *file_info; + CamelMimePart *mime_part; const gchar *attribute; const gchar *text; gboolean active; @@ -226,18 +227,31 @@ attachment_dialog_response (GtkDialog *dialog, file_info = e_attachment_get_file_info (attachment); g_return_if_fail (G_IS_FILE_INFO (file_info)); + mime_part = e_attachment_get_mime_part (attachment); + attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME; text = gtk_entry_get_text (GTK_ENTRY (priv->display_name_entry)); g_file_info_set_attribute_string (file_info, attribute, text); + if (mime_part != NULL) + camel_mime_part_set_filename (mime_part, text); + attribute = G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION; text = gtk_entry_get_text (GTK_ENTRY (priv->description_entry)); g_file_info_set_attribute_string (file_info, attribute, text); + if (mime_part != NULL) + camel_mime_part_set_description (mime_part, text); + button = GTK_TOGGLE_BUTTON (priv->disposition_checkbox); active = gtk_toggle_button_get_active (button); text = active ? "inline" : "attachment"; e_attachment_set_disposition (attachment, text); + + if (mime_part != NULL) + camel_mime_part_set_disposition (mime_part, text); + + g_object_notify (G_OBJECT (attachment), "file-info"); } static void diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index ee5446e699..537a3470d7 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -168,7 +168,8 @@ attachment_update_file_info_columns (EAttachment *attachment) display_size = g_format_size_for_display (size); description = e_attachment_get_description (attachment); - description = (description != NULL) ? description : display_name; + if (description == NULL || *description == '\0') + description = display_name; if (size > 0) caption = g_strdup_printf ( -- cgit v1.2.3 From dc7efb1311d23c32a76a9a8092f734223ce3207e Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 25 Apr 2009 10:49:45 -0400 Subject: Use consistent variable names for GtkUIManager --- widgets/misc/e-signature-editor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-signature-editor.c b/widgets/misc/e-signature-editor.c index c7dcbdaad9..cc1e9f6c18 100644 --- a/widgets/misc/e-signature-editor.c +++ b/widgets/misc/e-signature-editor.c @@ -329,7 +329,7 @@ static void signature_editor_init (ESignatureEditor *editor) { GtkActionGroup *action_group; - GtkUIManager *manager; + GtkUIManager *ui_manager; GtkWidget *container; GtkWidget *widget; GtkWidget *vbox; @@ -338,9 +338,9 @@ signature_editor_init (ESignatureEditor *editor) editor->priv = E_SIGNATURE_EDITOR_GET_PRIVATE (editor); vbox = GTKHTML_EDITOR (editor)->vbox; - manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); + ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); - gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error); + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); handle_error (&error); action_group = gtk_action_group_new ("signature"); @@ -349,10 +349,10 @@ signature_editor_init (ESignatureEditor *editor) gtk_action_group_add_actions ( action_group, entries, G_N_ELEMENTS (entries), editor); - gtk_ui_manager_insert_action_group (manager, action_group, 0); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); editor->priv->action_group = g_object_ref (action_group); - gtk_ui_manager_ensure_update (manager); + gtk_ui_manager_ensure_update (ui_manager); gtk_window_set_title (GTK_WINDOW (editor), _("Edit Signature")); -- cgit v1.2.3 From 0d3ef53bd7c1d7d96906f0f8348151a453e79078 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 15:36:19 -0400 Subject: Commit the rest of the attachment UI rewrite Oops, last commit only included the -new- files. This also removes EExpander, which is no longer used. --- widgets/misc/Makefile.am | 2 - widgets/misc/e-attachment.c | 620 -------------------- widgets/misc/e-expander.c | 1341 ------------------------------------------- widgets/misc/e-expander.h | 82 --- 4 files changed, 2045 deletions(-) delete mode 100644 widgets/misc/e-expander.c delete mode 100644 widgets/misc/e-expander.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 2fa7327e35..f5dbd63d82 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -64,7 +64,6 @@ widgetsinclude_HEADERS = \ e-combo-cell-editable.h \ e-cursors.h \ e-dateedit.h \ - e-expander.h \ e-file-activity.h \ e-gui-utils.h \ e-hsv-utils.h \ @@ -129,7 +128,6 @@ libemiscwidgets_la_SOURCES = \ e-combo-cell-editable.c \ e-cursors.c \ e-dateedit.c \ - e-expander.c \ e-file-activity.c \ e-gui-utils.c \ e-hsv-utils.c \ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 537a3470d7..b2c3e1579e 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1915,626 +1915,6 @@ attachment_open_context_free (OpenContext *open_context) g_slice_free (OpenContext, open_context); } -static gboolean -attachment_open_check_for_error (OpenContext *open_context, - GError *error) -{ - GSimpleAsyncResult *simple; - - if (error == NULL) - return FALSE; - - /* Steal the result. */ - simple = open_context->simple; - open_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_open_context_free (open_context); - - return TRUE; -} - -static void -attachment_open_file (GFile *file, - OpenContext *open_context) -{ - GdkAppLaunchContext *context; - GSimpleAsyncResult *simple; - GList *file_list; - gboolean success; - GError *error = NULL; - - /* Steal the result. */ - simple = open_context->simple; - open_context->simple = NULL; - - /* Find a default app based on content type. */ - if (open_context->app_info == NULL) { - EAttachment *attachment; - GFileInfo *file_info; - const gchar *content_type; - - attachment = open_context->attachment; - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - goto exit; - - content_type = g_file_info_get_content_type (file_info); - if (content_type == NULL) - goto exit; - - open_context->app_info = g_app_info_get_default_for_type ( - content_type, FALSE); - } - - if (open_context->app_info == NULL) - goto exit; - - context = gdk_app_launch_context_new (); - file_list = g_list_prepend (NULL, file); - - success = g_app_info_launch ( - open_context->app_info, file_list, - G_APP_LAUNCH_CONTEXT (context), &error); - - g_simple_async_result_set_op_res_gboolean (simple, success); - - g_list_free (file_list); - g_object_unref (context); - -exit: - if (error != NULL) { - g_simple_async_result_set_from_error (simple, error); - g_error_free (error); - } - - g_simple_async_result_complete (simple); - attachment_open_context_free (open_context); -} - -static void -attachment_open_save_finished_cb (EAttachment *attachment, - GAsyncResult *result, - OpenContext *open_context) -{ - GFile *file; - GError *error = NULL; - - file = e_attachment_save_finish (attachment, result, &error); - - if (attachment_open_check_for_error (open_context, error)) - return; - - attachment_open_file (file, open_context); - g_object_unref (file); -} - -static void -attachment_open_save_temporary (OpenContext *open_context) -{ - GFile *file; - gchar *template; - gchar *path; - GError *error = NULL; - - errno = 0; - - /* XXX This could trigger a blocking temp directory cleanup. */ - template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mktemp (template); - g_free (template); - - /* XXX Let's hope errno got set properly. */ - if (path == NULL) - g_set_error ( - &error, G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - - /* We already know if there's an error, but this does the cleanup. */ - if (attachment_open_check_for_error (open_context, error)) - return; - - file = g_file_new_for_path (path); - - g_free (path); - - e_attachment_save_async ( - open_context->attachment, file, (GAsyncReadyCallback) - attachment_open_save_finished_cb, open_context); - - g_object_unref (file); -} - -void -e_attachment_open_async (EAttachment *attachment, - GAppInfo *app_info, - GAsyncReadyCallback callback, - gpointer user_data) -{ - OpenContext *open_context; - CamelMimePart *mime_part; - GFile *file; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (callback != NULL); - - file = e_attachment_get_file (attachment); - mime_part = e_attachment_get_mime_part (attachment); - g_return_if_fail (file != NULL || mime_part != NULL); - - open_context = attachment_open_context_new ( - attachment, callback, user_data); - - if (G_IS_APP_INFO (app_info)) - open_context->app_info = g_object_ref (app_info); - - /* If the attachment already references a GFile, we can launch - * the application directly. Otherwise we have to save the MIME - * part to a temporary file and launch the application from that. */ - if (file != NULL) { - attachment_open_file (file, open_context); - - } else if (mime_part != NULL) - attachment_open_save_temporary (open_context); -} - -gboolean -e_attachment_open_finish (EAttachment *attachment, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - gboolean success; - - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - success = g_simple_async_result_get_op_res_gboolean (simple); - g_simple_async_result_propagate_error (simple, error); - g_object_unref (simple); - - return success; -} - -void -e_attachment_open_handle_error (EAttachment *attachment, - GAsyncResult *result, - GtkWindow *parent) -{ - GtkWidget *dialog; - GFileInfo *file_info; - const gchar *display_name; - const gchar *primary_text; - GError *error = NULL; - - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_return_if_fail (GTK_IS_WINDOW (parent)); - - if (e_attachment_open_finish (attachment, result, &error)) - return; - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - else - display_name = NULL; - - if (display_name != NULL) - primary_text = g_strdup_printf ( - _("Could not open '%s'"), display_name); - else - primary_text = g_strdup_printf ( - _("Could not open the attachment")); - - dialog = gtk_message_dialog_new_with_markup ( - parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "%s", primary_text); - - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - g_error_free (error); -} - -/************************* e_attachment_save_async() *************************/ - -typedef struct _SaveContext SaveContext; - -struct _SaveContext { - EAttachment *attachment; - GSimpleAsyncResult *simple; - - GFile *directory; - GFile *destination; - GInputStream *input_stream; - GOutputStream *output_stream; - goffset total_num_bytes; - gssize bytes_read; - gchar buffer[4096]; - gint count; -}; - -/* Forward Declaration */ -static void -attachment_save_read_cb (GInputStream *input_stream, - GAsyncResult *result, - SaveContext *save_context); - -static SaveContext * -attachment_save_context_new (EAttachment *attachment, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SaveContext *save_context; - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new ( - G_OBJECT (attachment), callback, - user_data, e_attachment_save_async); - - save_context = g_slice_new0 (SaveContext); - save_context->attachment = g_object_ref (attachment); - save_context->simple = simple; - - attachment_set_saving (save_context->attachment, TRUE); - - return save_context; -} - -static void -attachment_save_context_free (SaveContext *save_context) -{ - /* Do not free the GSimpleAsyncResult. */ - g_object_unref (save_context->attachment); - - if (save_context->directory != NULL) - g_object_unref (save_context->directory); - - if (save_context->destination != NULL) - g_object_unref (save_context->destination); - - if (save_context->input_stream != NULL) - g_object_unref (save_context->input_stream); - - if (save_context->output_stream != NULL) - g_object_unref (save_context->output_stream); - - g_slice_free (SaveContext, save_context); -} - -static gboolean -attachment_save_check_for_error (SaveContext *save_context, - GError *error) -{ - GSimpleAsyncResult *simple; - - if (error == NULL) - return FALSE; - - /* Steal the result. */ - simple = save_context->simple; - save_context->simple = NULL; - - g_simple_async_result_set_from_error (simple, error); - g_simple_async_result_complete (simple); - g_error_free (error); - - attachment_save_context_free (save_context); - - return TRUE; -} - -static GFile * -attachment_save_new_candidate (SaveContext *save_context) -{ - GFile *candidate; - GFileInfo *file_info; - EAttachment *attachment; - const gchar *display_name; - gchar *basename; - - attachment = save_context->attachment; - file_info = e_attachment_get_file_info (attachment); - - if (file_info != NULL) - display_name = g_file_info_get_display_name (file_info); - if (display_name == NULL) - /* Translators: Default attachment filename. */ - display_name = _("attachment.dat"); - - if (save_context->count == 0) - basename = g_strdup (display_name); - else { - GString *string; - const gchar *ext; - gsize length; - - string = g_string_sized_new (strlen (display_name)); - ext = g_utf8_strchr (display_name, -1, '.'); - - if (ext != NULL) - length = ext - display_name; - else - length = strlen (display_name); - - g_string_append_len (string, display_name, length); - g_string_append_printf (string, " (%d)", save_context->count); - g_string_append (string, (ext != NULL) ? ext : ""); - - basename = g_string_free (string, FALSE); - } - - save_context->count++; - - candidate = g_file_get_child (save_context->directory, basename); - - g_free (basename); - - return candidate; -} - -static void -attachment_save_write_cb (GOutputStream *output_stream, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GInputStream *input_stream; - gssize bytes_written; - GError *error = NULL; - - bytes_written = g_output_stream_write_finish ( - output_stream, result, &error); - - if (attachment_save_check_for_error (save_context, error)) - return; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - input_stream = save_context->input_stream; - - if (bytes_written < save_context->bytes_read) { - g_memmove ( - save_context->buffer, - save_context->buffer + bytes_written, - save_context->bytes_read - bytes_written); - save_context->bytes_read -= bytes_written; - - g_output_stream_write_async ( - output_stream, - save_context->buffer, - save_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_write_cb, - save_context); - } else - g_input_stream_read_async ( - input_stream, - save_context->buffer, - sizeof (save_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_read_cb, - save_context); -} - -static void -attachment_save_read_cb (GInputStream *input_stream, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GOutputStream *output_stream; - gssize bytes_read; - GError *error = NULL; - - bytes_read = g_input_stream_read_finish ( - input_stream, result, &error); - - if (attachment_save_check_for_error (save_context, error)) - return; - - if (bytes_read == 0) { - GSimpleAsyncResult *simple; - GFile *destination; - - /* Steal the result. */ - simple = save_context->simple; - save_context->simple = NULL; - - /* Steal the destination. */ - destination = save_context->destination; - save_context->destination = NULL; - - g_simple_async_result_set_op_res_gpointer ( - simple, destination, (GDestroyNotify) g_object_unref); - g_simple_async_result_complete (simple); - - attachment_save_context_free (save_context); - - return; - } - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - output_stream = save_context->output_stream; - save_context->bytes_read = bytes_read; - - attachment_progress_cb ( - g_seekable_tell (G_SEEKABLE (input_stream)), - save_context->total_num_bytes, attachment); - - g_output_stream_write_async ( - output_stream, - save_context->buffer, - save_context->bytes_read, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_write_cb, - save_context); -} - -static void -attachment_save_got_output_stream (SaveContext *save_context) -{ - GCancellable *cancellable; - GInputStream *input_stream; - CamelDataWrapper *wrapper; - CamelMimePart *mime_part; - CamelStream *stream; - EAttachment *attachment; - GByteArray *buffer; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - mime_part = e_attachment_get_mime_part (attachment); - - /* Decode the MIME part to an in-memory buffer. We have to do - * this because CamelStream is synchronous-only, and using threads - * is dangerous because CamelDataWrapper is not reentrant. */ - buffer = g_byte_array_new (); - stream = camel_stream_mem_new (); - camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), buffer); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - camel_data_wrapper_decode_to_stream (wrapper, stream); - camel_object_unref (stream); - - /* Load the buffer into a GMemoryInputStream. */ - input_stream = g_memory_input_stream_new_from_data ( - buffer->data, (gssize) buffer->len, - (GDestroyNotify) g_free); - save_context->input_stream = input_stream; - save_context->total_num_bytes = (goffset) buffer->len; - g_byte_array_free (buffer, FALSE); - - g_input_stream_read_async ( - input_stream, - save_context->buffer, - sizeof (save_context->buffer), - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_read_cb, - save_context); -} - -static void -attachment_save_create_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileOutputStream *output_stream; - GError *error = NULL; - - /* Output stream might be NULL, so don't use cast macro. */ - output_stream = g_file_create_finish (destination, result, &error); - save_context->output_stream = (GOutputStream *) output_stream; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { - destination = attachment_save_new_candidate (save_context); - - g_file_create_async ( - destination, G_FILE_CREATE_NONE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_create_cb, - save_context); - - g_object_unref (destination); - g_error_free (error); - return; - } - - if (attachment_save_check_for_error (save_context, error)) - return; - - save_context->destination = g_object_ref (destination); - attachment_save_got_output_stream (save_context); -} - -static void -attachment_save_replace_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - GFileOutputStream *output_stream; - GError *error = NULL; - - /* Output stream might be NULL, so don't use cast macro. */ - output_stream = g_file_replace_finish (destination, result, &error); - save_context->output_stream = (GOutputStream *) output_stream; - - if (attachment_save_check_for_error (save_context, error)) - return; - - save_context->destination = g_object_ref (destination); - attachment_save_got_output_stream (save_context); -} - -static void -attachment_save_query_info_cb (GFile *destination, - GAsyncResult *result, - SaveContext *save_context) -{ - EAttachment *attachment; - GCancellable *cancellable; - GFileInfo *file_info; - GFileType file_type; - GError *error = NULL; - - attachment = save_context->attachment; - cancellable = attachment->priv->cancellable; - - file_info = g_file_query_info_finish (destination, result, &error); - - /* G_IO_ERROR_NOT_FOUND just means we're creating a new file. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { - g_error_free (error); - goto replace; - } - - if (attachment_save_check_for_error (save_context, error)) - return; - - file_type = g_file_info_get_file_type (file_info); - g_object_unref (file_info); - - if (file_type == G_FILE_TYPE_DIRECTORY) { - save_context->directory = g_object_ref (destination); - destination = attachment_save_new_candidate (save_context); - - g_file_create_async ( - destination, G_FILE_CREATE_NONE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) attachment_save_create_cb, - save_context); - - g_object_unref (destination); - - return; - } - -replace: - g_file_replace_async ( - destination, NULL, FALSE, - G_FILE_CREATE_REPLACE_DESTINATION, G_PRIORITY_DEFAULT, cancellable, (GAsyncReadyCallback) attachment_save_replace_cb, save_context); diff --git a/widgets/misc/e-expander.c b/widgets/misc/e-expander.c deleted file mode 100644 index 771598739d..0000000000 --- a/widgets/misc/e-expander.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * GTK - The GIMP Toolkit - * - * 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 - * - * - * Authors: - * Mark McLoughlin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2003 Sun Microsystems, Inc. - * - */ - -#include - -#include "e-expander.h" -#include "ea-widgets.h" - -#include - -#define DEFAULT_EXPANDER_SIZE 10 -#define DEFAULT_EXPANDER_SPACING 2 - -/* ESTUFF */ -#ifndef _ -#define _(x) (x) -#endif -#define E_EXPANDER_GET_PRIVATE(expander) ((EExpanderPrivate *)g_object_get_data (G_OBJECT (expander), "e-expander-priv")) - -enum { - PROP_0, - PROP_EXPANDED, - PROP_LABEL, - PROP_USE_UNDERLINE, - PROP_PADDING, - PROP_LABEL_WIDGET -}; - -typedef struct { - GtkWidget *label_widget; - gint spacing; - - GtkExpanderStyle expander_style; - guint animation_timeout; - - guint expanded : 1; - guint use_underline : 1; - guint button_down : 1; -} EExpanderPrivate; - -static void e_expander_class_init (EExpanderClass *klass); -static void e_expander_init (EExpander *expander); - -static void e_expander_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void e_expander_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void e_expander_destroy (GtkObject *object); - -static void e_expander_realize (GtkWidget *widget); -static void e_expander_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_expander_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void e_expander_map (GtkWidget *widget); -static gboolean e_expander_expose (GtkWidget *widget, - GdkEventExpose *event); -static gboolean e_expander_button_press (GtkWidget *widget, - GdkEventButton *event); -static gboolean e_expander_button_release (GtkWidget *widget, - GdkEventButton *event); -static gboolean e_expander_motion_notify (GtkWidget *widget, - GdkEventMotion *event); -static gboolean e_expander_enter_notify (GtkWidget *widget, - GdkEventCrossing *event); -static gboolean e_expander_leave_notify (GtkWidget *widget, - GdkEventCrossing *event); -static gboolean e_expander_focus (GtkWidget *widget, - GtkDirectionType direction); - -static void e_expander_add (GtkContainer *container, - GtkWidget *widget); -static void e_expander_remove (GtkContainer *container, - GtkWidget *widget); -static void e_expander_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static void e_expander_activate (EExpander *expander); - -static GtkBinClass *parent_class = NULL; - -GType -e_expander_get_type (void) -{ - static GType expander_type = 0; - - if (!expander_type) - { - static const GTypeInfo expander_info = - { - sizeof (EExpanderClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_expander_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EExpander), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_expander_init, - }; - - expander_type = g_type_register_static (GTK_TYPE_BIN, - "EExpander", - &expander_info, 0); - } - - return expander_type; -} - -static void -e_expander_class_init (EExpanderClass *klass) -{ - GObjectClass *gobject_class; - GtkObjectClass *gtkobject_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class = (GObjectClass *) klass; - gtkobject_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - container_class = (GtkContainerClass *) klass; - - gobject_class->set_property = e_expander_set_property; - gobject_class->get_property = e_expander_get_property; - - gtkobject_class->destroy = e_expander_destroy; - - widget_class->realize = e_expander_realize; - widget_class->size_request = e_expander_size_request; - widget_class->size_allocate = e_expander_size_allocate; - widget_class->map = e_expander_map; - widget_class->expose_event = e_expander_expose; - widget_class->button_press_event = e_expander_button_press; - widget_class->button_release_event = e_expander_button_release; - widget_class->motion_notify_event = e_expander_motion_notify; - widget_class->enter_notify_event = e_expander_enter_notify; - widget_class->leave_notify_event = e_expander_leave_notify; - widget_class->focus = e_expander_focus; - - container_class->add = e_expander_add; - container_class->remove = e_expander_remove; - container_class->forall = e_expander_forall; - - klass->activate = e_expander_activate; - - /* ESTUFF g_type_class_add_private (klass, sizeof (EExpanderPrivate)); */ - - g_object_class_install_property (gobject_class, - PROP_EXPANDED, - g_param_spec_boolean ("expanded", - _("Expanded"), - _("Whether or not the expander is expanded"), - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (gobject_class, - PROP_LABEL, - g_param_spec_string ("label", - _("Label"), - _("Text of the expander's label"), - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (gobject_class, - PROP_USE_UNDERLINE, - g_param_spec_boolean ("use_underline", - _("Use underline"), - _("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"), - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (gobject_class, - PROP_PADDING, - g_param_spec_int ("spacing", - _("Spacing"), - _("Space to put between the label and the child"), - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_LABEL_WIDGET, - g_param_spec_object ("label_widget", - _("Label widget"), - _("A widget to display in place of the usual expander label"), - GTK_TYPE_WIDGET, - G_PARAM_READWRITE)); - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_int ("expander-size", - _("Expander Size"), - _("Size of the expander arrow"), - 0, - G_MAXINT, - DEFAULT_EXPANDER_SIZE, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_int ("expander-spacing", - _("Indicator Spacing"), - _("Spacing around expander arrow"), - 0, - G_MAXINT, - DEFAULT_EXPANDER_SPACING, - G_PARAM_READABLE)); - - widget_class->activate_signal = - g_signal_new ("activate", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EExpanderClass, activate), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_expander_a11y_init(); -} - -static void -e_expander_init (EExpander *expander) -{ - EExpanderPrivate *priv; - - /* ESTUFF */ - priv = g_new0 (EExpanderPrivate, 1); - g_object_set_data_full (G_OBJECT (expander), "e-expander-priv", priv, g_free); - - /* ESTUFF priv = E_EXPANDER_GET_PRIVATE (expander); */ - - GTK_WIDGET_SET_FLAGS (expander, GTK_CAN_FOCUS); - GTK_WIDGET_UNSET_FLAGS (expander, GTK_NO_WINDOW); - - priv->label_widget = NULL; - priv->spacing = 0; - - priv->expander_style = GTK_EXPANDER_COLLAPSED; - priv->animation_timeout = 0; - - priv->expanded = FALSE; - priv->use_underline = FALSE; - priv->button_down = FALSE; - -} - -static void -e_expander_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EExpander *expander = E_EXPANDER (object); - - switch (prop_id) - { - case PROP_EXPANDED: - e_expander_set_expanded (expander, g_value_get_boolean (value)); - break; - case PROP_LABEL: - e_expander_set_label (expander, g_value_get_string (value)); - break; - case PROP_USE_UNDERLINE: - e_expander_set_use_underline (expander, g_value_get_boolean (value)); - break; - case PROP_PADDING: - e_expander_set_spacing (expander, g_value_get_int (value)); - break; - case PROP_LABEL_WIDGET: - e_expander_set_label_widget (expander, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -e_expander_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EExpander *expander = E_EXPANDER (object); - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - switch (prop_id) - { - case PROP_EXPANDED: - g_value_set_boolean (value, priv->expanded); - break; - case PROP_LABEL: - g_value_set_string (value, e_expander_get_label (expander)); - break; - case PROP_USE_UNDERLINE: - g_value_set_boolean (value, priv->use_underline); - break; - case PROP_PADDING: - g_value_set_int (value, priv->spacing); - break; - case PROP_LABEL_WIDGET: - g_value_set_object (value, - priv->label_widget ? - G_OBJECT (priv->label_widget) : NULL); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -e_expander_destroy (GtkObject *object) -{ - EExpander *expander = E_EXPANDER (object); - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (priv->animation_timeout) - g_source_remove (priv->animation_timeout); - priv->animation_timeout = 0; - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -e_expander_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - gint attributes_mask; - gint border_width; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - border_width = GTK_CONTAINER (widget)->border_width; - - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = widget->allocation.height - 2 * border_width; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget) | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_EXPOSURE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); -} - -static void -e_expander_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EExpander *expander; - GtkBin *bin; - EExpanderPrivate *priv; - gint border_width; - gint expander_size; - gint expander_spacing; - gboolean interior_focus; - gint focus_width; - gint focus_pad; - - expander = E_EXPANDER (widget); - bin = GTK_BIN (widget); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - border_width = GTK_CONTAINER (widget)->border_width; - - gtk_widget_style_get (widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - "focus-padding", &focus_pad, - "expander-size", &expander_size, - "expander-spacing", &expander_spacing, - NULL); - - requisition->width = expander_size + 2 * expander_spacing + - 2 * focus_width + 2 * focus_pad; - requisition->height = interior_focus ? (2 * focus_width + 2 * focus_pad) : 0; - - if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) - { - GtkRequisition label_requisition; - - gtk_widget_size_request (priv->label_widget, &label_requisition); - - requisition->width += label_requisition.width; - requisition->height += label_requisition.height; - } - - requisition->height = MAX (expander_size + 2 * expander_spacing, requisition->height); - - if (!interior_focus) - requisition->height += 2 * focus_width + 2 * focus_pad; - - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) - { - GtkRequisition child_requisition; - - gtk_widget_size_request (bin->child, &child_requisition); - - if (!interior_focus) - child_requisition.width += 2 * focus_width + 2 * focus_pad; - - requisition->width = MAX (requisition->width, child_requisition.width); - requisition->height += child_requisition.height + priv->spacing; - } - - requisition->width += 2 * border_width; - requisition->height += 2 * border_width + 2 * priv->spacing; -} - -static void -e_expander_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EExpander *expander; - GtkBin *bin; - EExpanderPrivate *priv; - GtkRequisition child_requisition; - gboolean child_visible = FALSE; - gint border_width; - gint expander_size; - gint expander_spacing; - gboolean interior_focus; - gint focus_width; - gint focus_pad; - gint label_height; - - expander = E_EXPANDER (widget); - bin = GTK_BIN (widget); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - border_width = GTK_CONTAINER (widget)->border_width; - - gtk_widget_style_get (widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - "focus-padding", &focus_pad, - "expander-size", &expander_size, - "expander-spacing", &expander_spacing, - NULL); - - child_requisition.width = 0; - child_requisition.height = 0; - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) - { - child_visible = TRUE; - gtk_widget_get_child_requisition (bin->child, &child_requisition); - } - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x + border_width, - allocation->y + border_width, - MAX (allocation->width - 2 * border_width, 0), - MAX (allocation->height - 2 * border_width, 0)); - - if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) - { - GtkAllocation label_allocation; - GtkRequisition label_requisition; - gboolean ltr; - - gtk_widget_get_child_requisition (priv->label_widget, &label_requisition); - - ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; - - label_allocation.x = focus_width + focus_pad; - if (ltr) - label_allocation.x += expander_size + 2 * expander_spacing; - label_allocation.y = priv->spacing + focus_width + focus_pad; - - label_allocation.width = MIN (label_requisition.width, - allocation->width - 2 * border_width - - expander_size - 2 * expander_spacing - - 2 * focus_width - 2 * focus_pad); - label_allocation.width = MAX (label_allocation.width, 1); - - label_allocation.height = MIN (label_requisition.height, - allocation->height - 2 * border_width - - 2 * priv->spacing - - 2 * focus_width - 2 * focus_pad - - child_requisition.height - - (child_visible ? priv->spacing : 0)); - label_allocation.height = MAX (label_allocation.height, 1); - - gtk_widget_size_allocate (priv->label_widget, &label_allocation); - - label_height = label_allocation.height; - } - else - { - label_height = 0; - } - - if (child_visible) - { - GtkAllocation child_allocation; - gint top_height; - - top_height = MAX (2 * expander_spacing + expander_size, - label_height + - (interior_focus ? 2 * focus_width + 2 * focus_pad : 0)); - - child_allocation.x = 0; - child_allocation.y = 2 * priv->spacing + top_height; - - if (!interior_focus) - { - child_allocation.x += focus_width + focus_pad; - child_allocation.y += focus_width + focus_pad; - } - - child_allocation.width = allocation->width - 2 * border_width - - (!interior_focus ? 2 * focus_width + 2 * focus_pad : 0); - child_allocation.width = MAX (child_allocation.width, 1); - - child_allocation.height = allocation->height - top_height - - 2 * border_width - - 3 * priv->spacing - - (!interior_focus ? 2 * focus_width + 2 * focus_pad : 0); - child_allocation.height = MAX (child_allocation.height, 1); - - gtk_widget_size_allocate (bin->child, &child_allocation); - } -} - -static void -e_expander_map (GtkWidget *widget) -{ - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (widget); - - if (priv->label_widget) - gtk_widget_map (priv->label_widget); - - GTK_WIDGET_CLASS (parent_class)->map (widget); -} - -static GdkRectangle -get_expander_bounds (EExpander *expander) -{ - GtkWidget *widget; - EExpanderPrivate *priv; - GdkRectangle bounds; - gint border_width; - gint expander_size; - gint expander_spacing; - gboolean interior_focus; - gint focus_width; - gint focus_pad; - gboolean ltr; - - widget = GTK_WIDGET (expander); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - border_width = GTK_CONTAINER (expander)->border_width; - - gtk_widget_style_get (widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - "focus-padding", &focus_pad, - "expander-size", &expander_size, - "expander-spacing", &expander_spacing, - NULL); - - ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; - - - if (ltr) - bounds.x = expander_spacing; - else - bounds.x = widget->allocation.width - 2 * border_width - - expander_spacing - expander_size; - - if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) - { - GtkAllocation label_allocation; - - label_allocation = priv->label_widget->allocation; - - if (expander_size < label_allocation.height) - bounds.y = label_allocation.y + (label_allocation.height - expander_size) / 2; - else - bounds.y = priv->spacing + expander_spacing; - } - else - { - bounds.y = priv->spacing + expander_spacing; - } - - if (!interior_focus) - { - if (ltr) - bounds.x += focus_width + focus_pad; - else - bounds.x -= focus_width + focus_pad; - bounds.y += focus_width + focus_pad; - } - - bounds.width = bounds.height = expander_size; - - return bounds; -} - -static void -e_expander_paint (EExpander *expander) -{ - GtkWidget *widget; - EExpanderPrivate *priv; - gint x, y; - GtkStateType state; - GdkRectangle clip; - - widget = GTK_WIDGET (expander); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - clip = get_expander_bounds (expander); - - x = clip.x + clip.width / 2; - y = clip.y + clip.height / 2; - - state = widget->state; - if (state != GTK_STATE_PRELIGHT) - state = GTK_STATE_NORMAL; - - gtk_paint_expander (widget->style, - widget->window, - state, - &clip, - widget, - "expander", - x, - y, - priv->expander_style); -} - -static void -e_expander_paint_focus (EExpander *expander, - GdkRectangle *area) -{ - GtkWidget *widget; - EExpanderPrivate *priv; - gint x, y, width, height; - gboolean interior_focus; - gint focus_width; - gint focus_pad; - gint expander_size; - gint expander_spacing; - gboolean ltr; - - widget = GTK_WIDGET (expander); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - gtk_widget_style_get (widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - "focus-padding", &focus_pad, - "expander-size", &expander_size, - "expander-spacing", &expander_spacing, - NULL); - - ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; - - if (interior_focus) - { - if (ltr) - x = expander_spacing * 2 + expander_size; - else - x = 0; - y = priv->spacing; - - width = height = 2 * focus_pad + 2 * focus_width; - - if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) - { - GtkAllocation label_allocation = priv->label_widget->allocation; - - width += label_allocation.width; - height += label_allocation.height; - } - } - else - { - x = y = 0; - width = widget->allocation.width - 2 * GTK_CONTAINER (widget)->border_width; - height = widget->allocation.height - 2 * GTK_CONTAINER (widget)->border_width; - } - - gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), - area, widget, "expander", - x, y, width, height); -} - -static gboolean -e_expander_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - if (GTK_WIDGET_DRAWABLE (widget)) - { - EExpander *expander = E_EXPANDER (widget); - - e_expander_paint (expander); - - if (GTK_WIDGET_HAS_FOCUS (expander)) - e_expander_paint_focus (expander, &event->area); - - GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); - } - - return FALSE; -} - -static gboolean -is_in_expander_panel (EExpander *expander, - GdkWindow *window, - gint x, - gint y) -{ - GtkWidget *widget; - GdkRectangle area; - - widget = GTK_WIDGET (expander); - - area = get_expander_bounds (expander); - - area.x = 0; - area.width = widget->allocation.width; - - if (widget->window == window) - { - if (x >= area.x && x <= (area.x + area.width) && - y >= area.y && y <= (area.y + area.height)) - return TRUE; - } - - return FALSE; -} - -static gboolean -e_expander_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - EExpander *expander = E_EXPANDER (widget); - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (event->button == 1 && !priv->button_down) - { - if (is_in_expander_panel (expander, event->window, event->x, event->y)) - { - priv->button_down = TRUE; - return TRUE; - } - } - - return FALSE; -} - -static gboolean -e_expander_button_release (GtkWidget *widget, - GdkEventButton *event) -{ - EExpander *expander = E_EXPANDER (widget); - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (event->button == 1 && priv->button_down) - { - g_signal_emit_by_name (expander, "activate"); - - priv->button_down = FALSE; - return TRUE; - } - - return FALSE; -} - -static void -e_expander_maybe_prelight (EExpander *expander) -{ - GtkWidget *widget; - EExpanderPrivate *priv; - GtkStateType state = GTK_STATE_NORMAL; - - widget = GTK_WIDGET (expander); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (!priv->button_down) - { - gint x, y; - - gdk_window_get_pointer (widget->window, &x, &y, NULL); - - if (is_in_expander_panel (expander, widget->window, x, y)) - state = GTK_STATE_PRELIGHT; - } - - gtk_widget_set_state (widget, state); -} - -static gboolean -e_expander_motion_notify (GtkWidget *widget, - GdkEventMotion *event) -{ - e_expander_maybe_prelight (E_EXPANDER (widget)); - - return FALSE; -} - -static gboolean -e_expander_enter_notify (GtkWidget *widget, - GdkEventCrossing *event) -{ - e_expander_maybe_prelight (E_EXPANDER (widget)); - - return FALSE; -} - -static gboolean -e_expander_leave_notify (GtkWidget *widget, - GdkEventCrossing *event) -{ - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - - return FALSE; -} - -static gboolean -focus_child_in (GtkWidget *widget, - GtkDirectionType direction) -{ - GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget)); - - if (!child) - return FALSE; - - return gtk_widget_child_focus (child, direction); -} - -static gboolean -e_expander_focus (GtkWidget *widget, - GtkDirectionType direction) -{ - EExpanderPrivate *priv; - GtkWidget *old_focus_child; - gboolean widget_is_focus; - gboolean label_can_focus; - - priv = E_EXPANDER_GET_PRIVATE (widget); - - widget_is_focus = gtk_widget_is_focus (widget); - old_focus_child = GTK_CONTAINER (widget)->focus_child; - label_can_focus = priv->label_widget && GTK_WIDGET_CAN_FOCUS (priv->label_widget); - - if (old_focus_child && old_focus_child == priv->label_widget) - { - switch (direction) - { - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_LEFT: - case GTK_DIR_UP: - gtk_widget_grab_focus (widget); - return TRUE; - case GTK_DIR_DOWN: - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_RIGHT: - return focus_child_in (widget, direction); - } - } - else if (old_focus_child) - { - if (gtk_widget_child_focus (old_focus_child, direction)) - return TRUE; - - switch (direction) - { - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_LEFT: - case GTK_DIR_UP: - if (label_can_focus) - gtk_widget_grab_focus (priv->label_widget); - else - gtk_widget_grab_focus (widget); - return TRUE; - case GTK_DIR_DOWN: - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_RIGHT: - return FALSE; - } - } - else if (widget_is_focus) - { - switch (direction) - { - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_LEFT: - case GTK_DIR_UP: - return FALSE; - case GTK_DIR_DOWN: - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_RIGHT: - if (label_can_focus) - { - gtk_widget_grab_focus (priv->label_widget); - return TRUE; - } - - return focus_child_in (widget, direction); - } - } - else - { - switch (direction) - { - case GTK_DIR_DOWN: - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_TAB_BACKWARD: - gtk_widget_grab_focus (widget); - return TRUE; - case GTK_DIR_UP: - case GTK_DIR_LEFT: - case GTK_DIR_RIGHT: - if (!focus_child_in (widget, direction)) - { - gtk_widget_grab_focus (widget); - } - return TRUE; - } - } - - g_return_val_if_reached(FALSE); -} - -static void -e_expander_add (GtkContainer *container, - GtkWidget *widget) -{ - GTK_CONTAINER_CLASS (parent_class)->add (container, widget); - - g_object_set (G_OBJECT (widget), - "visible", E_EXPANDER_GET_PRIVATE (container)->expanded, - NULL); -} - -static void -e_expander_remove (GtkContainer *container, - GtkWidget *widget) -{ - EExpander *expander = E_EXPANDER (container); - - if (E_EXPANDER_GET_PRIVATE (expander)->label_widget == widget) - e_expander_set_label_widget (expander, NULL); - else - GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); -} - -static void -e_expander_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkBin *bin = GTK_BIN (container); - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (container); - - if (bin->child) - (* callback) (bin->child, callback_data); - - if (priv->label_widget) - (* callback) (priv->label_widget, callback_data); -} - -static void -e_expander_activate (EExpander *expander) -{ - e_expander_set_expanded (expander, - !E_EXPANDER_GET_PRIVATE (expander)->expanded); -} - -GtkWidget * -e_expander_new (const gchar *label) -{ - return g_object_new (E_TYPE_EXPANDER, "label", label, NULL); -} - -GtkWidget * -e_expander_new_with_mnemonic (const gchar *label) -{ - return g_object_new (E_TYPE_EXPANDER, - "label", label, - "use_underline", TRUE, - NULL); -} - -static gboolean -e_expander_animation_timeout (EExpander *expander) -{ - EExpanderPrivate *priv; - GdkRectangle area; - gboolean finish = FALSE; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (GTK_WIDGET_REALIZED (expander)) - { - area = get_expander_bounds (expander); - gdk_window_invalidate_rect (GTK_WIDGET (expander)->window, &area, TRUE); - } - - if (priv->expanded) - { - if (priv->expander_style == GTK_EXPANDER_COLLAPSED) - { - priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED; - } - else - { - priv->expander_style = GTK_EXPANDER_EXPANDED; - finish = TRUE; - } - } - else - { - if (priv->expander_style == GTK_EXPANDER_EXPANDED) - { - priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED; - } - else - { - priv->expander_style = GTK_EXPANDER_COLLAPSED; - finish = TRUE; - } - } - - if (finish) - { - priv->animation_timeout = 0; - g_object_set (G_OBJECT (GTK_BIN (expander)->child), - "visible", priv->expanded, - NULL); - } - - return !finish; -} - -static void -e_expander_start_animation (EExpander *expander) -{ - EExpanderPrivate *priv; - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (priv->animation_timeout) - g_source_remove (priv->animation_timeout); - - priv->animation_timeout = - g_timeout_add (50, - (GSourceFunc) e_expander_animation_timeout, - expander); -} - -void -e_expander_set_expanded (EExpander *expander, - gboolean expanded) -{ - EExpanderPrivate *priv; - - g_return_if_fail (E_IS_EXPANDER (expander)); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - expanded = expanded != FALSE; - - if (priv->expanded != expanded) - { - priv->expanded = expanded; - - if (GTK_WIDGET_VISIBLE (expander)) - e_expander_start_animation (expander); - - else if (GTK_BIN (expander)->child) - { - priv->expander_style = expanded ? GTK_EXPANDER_EXPANDED : - GTK_EXPANDER_COLLAPSED; - g_object_set (G_OBJECT (GTK_BIN (expander)->child), - "visible", priv->expanded, - NULL); - } - - gtk_widget_queue_resize (GTK_WIDGET (expander)); - - g_object_notify (G_OBJECT (expander), "expanded"); - } -} - -gboolean -e_expander_get_expanded (EExpander *expander) -{ - g_return_val_if_fail (E_IS_EXPANDER (expander), FALSE); - - return E_EXPANDER_GET_PRIVATE (expander)->expanded; -} - -void -e_expander_set_spacing (EExpander *expander, - gint spacing) -{ - EExpanderPrivate *priv; - - g_return_if_fail (E_IS_EXPANDER (expander)); - g_return_if_fail (spacing >= 0); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (priv->spacing != spacing) - { - priv->spacing = spacing; - - gtk_widget_queue_resize (GTK_WIDGET (expander)); - - g_object_notify (G_OBJECT (expander), "spacing"); - } -} - -gint -e_expander_get_spacing (EExpander *expander) -{ - g_return_val_if_fail (E_IS_EXPANDER (expander), 0); - - return E_EXPANDER_GET_PRIVATE (expander)->spacing; -} - -void -e_expander_set_label (EExpander *expander, - const gchar *label) -{ - g_return_if_fail (E_IS_EXPANDER (expander)); - - if (!label) - { - e_expander_set_label_widget (expander, NULL); - } - else - { - GtkWidget *child; - - child = gtk_label_new (label); - gtk_label_set_use_underline (GTK_LABEL (child), - E_EXPANDER_GET_PRIVATE (expander)->use_underline); - gtk_widget_show (child); - - e_expander_set_label_widget (expander, child); - } - - g_object_notify (G_OBJECT (expander), "label"); -} - -/** - * e_expander_get_label: - * @expander: a #EExpander - * - * If the expander's label widget is a #GtkLabel, return the - * text in the label widget. (The frame will have a #GtkLabel - * for the label widget if a non-%NULL argument was passed - * to e_expander_new().) - * - * Return value: the text in the label, or %NULL if there - * was no label widget or the lable widget was not - * a #GtkLabel. This string is owned by GTK+ and - * must not be modified or freed. - **/ -G_CONST_RETURN char * -e_expander_get_label (EExpander *expander) -{ - EExpanderPrivate *priv; - - g_return_val_if_fail (E_IS_EXPANDER (expander), NULL); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (priv->label_widget && GTK_IS_LABEL (priv->label_widget)) - return gtk_label_get_text (GTK_LABEL (priv->label_widget)); - else - return NULL; -} - -void -e_expander_set_use_underline (EExpander *expander, - gboolean use_underline) -{ - EExpanderPrivate *priv; - - g_return_if_fail (E_IS_EXPANDER (expander)); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - use_underline = use_underline != FALSE; - - if (priv->use_underline != use_underline) - { - priv->use_underline = use_underline; - - if (priv->label_widget && GTK_IS_LABEL (priv->label_widget)) - gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), use_underline); - - g_object_notify (G_OBJECT (expander), "use_underline"); - } -} - -gboolean -e_expander_get_use_underline (EExpander *expander) -{ - g_return_val_if_fail (E_IS_EXPANDER (expander), FALSE); - - return E_EXPANDER_GET_PRIVATE (expander)->use_underline; -} - -/** - * e_expander_set_label_widget: - * @expander: a #EExpander - * @label_widget: the new label widget - * - * Set the label widget for the expander. This is the widget - * that will appear embedded alongside the expander arrow. - **/ -void -e_expander_set_label_widget (EExpander *expander, - GtkWidget *label_widget) -{ - EExpanderPrivate *priv; - gboolean need_resize = FALSE; - - g_return_if_fail (E_IS_EXPANDER (expander)); - g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget)); - g_return_if_fail (label_widget == NULL || label_widget->parent == NULL); - - priv = E_EXPANDER_GET_PRIVATE (expander); - - if (priv->label_widget == label_widget) - return; - - if (priv->label_widget) - { - need_resize = GTK_WIDGET_VISIBLE (priv->label_widget); - gtk_widget_unparent (priv->label_widget); - } - - priv->label_widget = label_widget; - - if (label_widget) - { - priv->label_widget = label_widget; - gtk_widget_set_parent (label_widget, GTK_WIDGET (expander)); - need_resize |= GTK_WIDGET_VISIBLE (label_widget); - } - - if (GTK_WIDGET_VISIBLE (expander) && need_resize) - gtk_widget_queue_resize (GTK_WIDGET (expander)); - - g_object_notify (G_OBJECT (expander), "label_widget"); -} - -/** - * e_expander_get_label_widget: - * @expander: a #EExpander - * - * Retrieves the label widget for the frame. See - * e_expander_set_label_widget(). - * - * Return value: the label widget, or %NULL if there is none. - **/ -GtkWidget * -e_expander_get_label_widget (EExpander *expander) -{ - g_return_val_if_fail (E_IS_EXPANDER (expander), NULL); - - return E_EXPANDER_GET_PRIVATE (expander)->label_widget; -} diff --git a/widgets/misc/e-expander.h b/widgets/misc/e-expander.h deleted file mode 100644 index 6ddb68087e..0000000000 --- a/widgets/misc/e-expander.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Mark McLoughlin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) 2003 Sun Microsystems, Inc. - * - */ - -#ifndef _E_EXPANDER_H_ -#define _E_EXPANDER_H_ - -#include - -G_BEGIN_DECLS - -#define E_TYPE_EXPANDER (e_expander_get_type ()) -#define E_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_EXPANDER, EExpander)) -#define E_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_EXPANDER, EExpanderClass)) -#define E_IS_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_EXPANDER)) -#define E_IS_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_EXPANDER)) -#define E_EXPANDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_EXPANDER, EExpanderClass)) -/* ESTUFF #define E_EXPANDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_EXPANDER, EExpanderPrivate)) */ - -typedef struct _EExpander EExpander; -typedef struct _EExpanderClass EExpanderClass; - -struct _EExpander -{ - GtkBin bin; -}; - -struct _EExpanderClass -{ - GtkBinClass parent_class; - - void (* activate) (EExpander *expander); -}; - -GType e_expander_get_type (void); - -GtkWidget *e_expander_new (const gchar *label); -GtkWidget *e_expander_new_with_mnemonic (const gchar *label); - -void e_expander_set_expanded (EExpander *expander, - gboolean expanded); -gboolean e_expander_get_expanded (EExpander *expander); - -/* Spacing between the expander/label and the child */ -void e_expander_set_spacing (EExpander *expander, - gint spacing); -gint e_expander_get_spacing (EExpander *expander); - -void e_expander_set_label (EExpander *expander, - const gchar *label); -G_CONST_RETURN gchar *e_expander_get_label (EExpander *expander); - -void e_expander_set_use_underline (EExpander *expander, - gboolean use_underline); -gboolean e_expander_get_use_underline (EExpander *expander); - -void e_expander_set_label_widget (EExpander *expander, - GtkWidget *label_widget); -GtkWidget *e_expander_get_label_widget (EExpander *expander); - -G_END_DECLS - -#endif /* _E_EXPANDER_H_ */ -- cgit v1.2.3 From 6f2f7292a7934a93e18d36594a8b9ef8dc4454e7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 28 Apr 2009 10:57:05 -0400 Subject: Resolve some differences between this branch and master. --- widgets/misc/e-attachment.c | 620 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 620 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index b2c3e1579e..537a3470d7 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1915,6 +1915,626 @@ attachment_open_context_free (OpenContext *open_context) g_slice_free (OpenContext, open_context); } +static gboolean +attachment_open_check_for_error (OpenContext *open_context, + GError *error) +{ + GSimpleAsyncResult *simple; + + if (error == NULL) + return FALSE; + + /* Steal the result. */ + simple = open_context->simple; + open_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_open_context_free (open_context); + + return TRUE; +} + +static void +attachment_open_file (GFile *file, + OpenContext *open_context) +{ + GdkAppLaunchContext *context; + GSimpleAsyncResult *simple; + GList *file_list; + gboolean success; + GError *error = NULL; + + /* Steal the result. */ + simple = open_context->simple; + open_context->simple = NULL; + + /* Find a default app based on content type. */ + if (open_context->app_info == NULL) { + EAttachment *attachment; + GFileInfo *file_info; + const gchar *content_type; + + attachment = open_context->attachment; + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + goto exit; + + content_type = g_file_info_get_content_type (file_info); + if (content_type == NULL) + goto exit; + + open_context->app_info = g_app_info_get_default_for_type ( + content_type, FALSE); + } + + if (open_context->app_info == NULL) + goto exit; + + context = gdk_app_launch_context_new (); + file_list = g_list_prepend (NULL, file); + + success = g_app_info_launch ( + open_context->app_info, file_list, + G_APP_LAUNCH_CONTEXT (context), &error); + + g_simple_async_result_set_op_res_gboolean (simple, success); + + g_list_free (file_list); + g_object_unref (context); + +exit: + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + g_simple_async_result_complete (simple); + attachment_open_context_free (open_context); +} + +static void +attachment_open_save_finished_cb (EAttachment *attachment, + GAsyncResult *result, + OpenContext *open_context) +{ + GFile *file; + GError *error = NULL; + + file = e_attachment_save_finish (attachment, result, &error); + + if (attachment_open_check_for_error (open_context, error)) + return; + + attachment_open_file (file, open_context); + g_object_unref (file); +} + +static void +attachment_open_save_temporary (OpenContext *open_context) +{ + GFile *file; + gchar *template; + gchar *path; + GError *error = NULL; + + errno = 0; + + /* XXX This could trigger a blocking temp directory cleanup. */ + template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); + path = e_mktemp (template); + g_free (template); + + /* XXX Let's hope errno got set properly. */ + if (path == NULL) + g_set_error ( + &error, G_FILE_ERROR, + g_file_error_from_errno (errno), + "%s", g_strerror (errno)); + + /* We already know if there's an error, but this does the cleanup. */ + if (attachment_open_check_for_error (open_context, error)) + return; + + file = g_file_new_for_path (path); + + g_free (path); + + e_attachment_save_async ( + open_context->attachment, file, (GAsyncReadyCallback) + attachment_open_save_finished_cb, open_context); + + g_object_unref (file); +} + +void +e_attachment_open_async (EAttachment *attachment, + GAppInfo *app_info, + GAsyncReadyCallback callback, + gpointer user_data) +{ + OpenContext *open_context; + CamelMimePart *mime_part; + GFile *file; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (callback != NULL); + + file = e_attachment_get_file (attachment); + mime_part = e_attachment_get_mime_part (attachment); + g_return_if_fail (file != NULL || mime_part != NULL); + + open_context = attachment_open_context_new ( + attachment, callback, user_data); + + if (G_IS_APP_INFO (app_info)) + open_context->app_info = g_object_ref (app_info); + + /* If the attachment already references a GFile, we can launch + * the application directly. Otherwise we have to save the MIME + * part to a temporary file and launch the application from that. */ + if (file != NULL) { + attachment_open_file (file, open_context); + + } else if (mime_part != NULL) + attachment_open_save_temporary (open_context); +} + +gboolean +e_attachment_open_finish (EAttachment *attachment, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gboolean success; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + success = g_simple_async_result_get_op_res_gboolean (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + return success; +} + +void +e_attachment_open_handle_error (EAttachment *attachment, + GAsyncResult *result, + GtkWindow *parent) +{ + GtkWidget *dialog; + GFileInfo *file_info; + const gchar *display_name; + const gchar *primary_text; + GError *error = NULL; + + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_return_if_fail (GTK_IS_WINDOW (parent)); + + if (e_attachment_open_finish (attachment, result, &error)) + return; + + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + else + display_name = NULL; + + if (display_name != NULL) + primary_text = g_strdup_printf ( + _("Could not open '%s'"), display_name); + else + primary_text = g_strdup_printf ( + _("Could not open the attachment")); + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", primary_text); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); +} + +/************************* e_attachment_save_async() *************************/ + +typedef struct _SaveContext SaveContext; + +struct _SaveContext { + EAttachment *attachment; + GSimpleAsyncResult *simple; + + GFile *directory; + GFile *destination; + GInputStream *input_stream; + GOutputStream *output_stream; + goffset total_num_bytes; + gssize bytes_read; + gchar buffer[4096]; + gint count; +}; + +/* Forward Declaration */ +static void +attachment_save_read_cb (GInputStream *input_stream, + GAsyncResult *result, + SaveContext *save_context); + +static SaveContext * +attachment_save_context_new (EAttachment *attachment, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (attachment), callback, + user_data, e_attachment_save_async); + + save_context = g_slice_new0 (SaveContext); + save_context->attachment = g_object_ref (attachment); + save_context->simple = simple; + + attachment_set_saving (save_context->attachment, TRUE); + + return save_context; +} + +static void +attachment_save_context_free (SaveContext *save_context) +{ + /* Do not free the GSimpleAsyncResult. */ + g_object_unref (save_context->attachment); + + if (save_context->directory != NULL) + g_object_unref (save_context->directory); + + if (save_context->destination != NULL) + g_object_unref (save_context->destination); + + if (save_context->input_stream != NULL) + g_object_unref (save_context->input_stream); + + if (save_context->output_stream != NULL) + g_object_unref (save_context->output_stream); + + g_slice_free (SaveContext, save_context); +} + +static gboolean +attachment_save_check_for_error (SaveContext *save_context, + GError *error) +{ + GSimpleAsyncResult *simple; + + if (error == NULL) + return FALSE; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + g_error_free (error); + + attachment_save_context_free (save_context); + + return TRUE; +} + +static GFile * +attachment_save_new_candidate (SaveContext *save_context) +{ + GFile *candidate; + GFileInfo *file_info; + EAttachment *attachment; + const gchar *display_name; + gchar *basename; + + attachment = save_context->attachment; + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) + display_name = g_file_info_get_display_name (file_info); + if (display_name == NULL) + /* Translators: Default attachment filename. */ + display_name = _("attachment.dat"); + + if (save_context->count == 0) + basename = g_strdup (display_name); + else { + GString *string; + const gchar *ext; + gsize length; + + string = g_string_sized_new (strlen (display_name)); + ext = g_utf8_strchr (display_name, -1, '.'); + + if (ext != NULL) + length = ext - display_name; + else + length = strlen (display_name); + + g_string_append_len (string, display_name, length); + g_string_append_printf (string, " (%d)", save_context->count); + g_string_append (string, (ext != NULL) ? ext : ""); + + basename = g_string_free (string, FALSE); + } + + save_context->count++; + + candidate = g_file_get_child (save_context->directory, basename); + + g_free (basename); + + return candidate; +} + +static void +attachment_save_write_cb (GOutputStream *output_stream, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GInputStream *input_stream; + gssize bytes_written; + GError *error = NULL; + + bytes_written = g_output_stream_write_finish ( + output_stream, result, &error); + + if (attachment_save_check_for_error (save_context, error)) + return; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + input_stream = save_context->input_stream; + + if (bytes_written < save_context->bytes_read) { + g_memmove ( + save_context->buffer, + save_context->buffer + bytes_written, + save_context->bytes_read - bytes_written); + save_context->bytes_read -= bytes_written; + + g_output_stream_write_async ( + output_stream, + save_context->buffer, + save_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_write_cb, + save_context); + } else + g_input_stream_read_async ( + input_stream, + save_context->buffer, + sizeof (save_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_read_cb, + save_context); +} + +static void +attachment_save_read_cb (GInputStream *input_stream, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GOutputStream *output_stream; + gssize bytes_read; + GError *error = NULL; + + bytes_read = g_input_stream_read_finish ( + input_stream, result, &error); + + if (attachment_save_check_for_error (save_context, error)) + return; + + if (bytes_read == 0) { + GSimpleAsyncResult *simple; + GFile *destination; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* Steal the destination. */ + destination = save_context->destination; + save_context->destination = NULL; + + g_simple_async_result_set_op_res_gpointer ( + simple, destination, (GDestroyNotify) g_object_unref); + g_simple_async_result_complete (simple); + + attachment_save_context_free (save_context); + + return; + } + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + output_stream = save_context->output_stream; + save_context->bytes_read = bytes_read; + + attachment_progress_cb ( + g_seekable_tell (G_SEEKABLE (input_stream)), + save_context->total_num_bytes, attachment); + + g_output_stream_write_async ( + output_stream, + save_context->buffer, + save_context->bytes_read, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_write_cb, + save_context); +} + +static void +attachment_save_got_output_stream (SaveContext *save_context) +{ + GCancellable *cancellable; + GInputStream *input_stream; + CamelDataWrapper *wrapper; + CamelMimePart *mime_part; + CamelStream *stream; + EAttachment *attachment; + GByteArray *buffer; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + mime_part = e_attachment_get_mime_part (attachment); + + /* Decode the MIME part to an in-memory buffer. We have to do + * this because CamelStream is synchronous-only, and using threads + * is dangerous because CamelDataWrapper is not reentrant. */ + buffer = g_byte_array_new (); + stream = camel_stream_mem_new (); + camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), buffer); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + camel_data_wrapper_decode_to_stream (wrapper, stream); + camel_object_unref (stream); + + /* Load the buffer into a GMemoryInputStream. */ + input_stream = g_memory_input_stream_new_from_data ( + buffer->data, (gssize) buffer->len, + (GDestroyNotify) g_free); + save_context->input_stream = input_stream; + save_context->total_num_bytes = (goffset) buffer->len; + g_byte_array_free (buffer, FALSE); + + g_input_stream_read_async ( + input_stream, + save_context->buffer, + sizeof (save_context->buffer), + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_read_cb, + save_context); +} + +static void +attachment_save_create_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GFileOutputStream *output_stream; + GError *error = NULL; + + /* Output stream might be NULL, so don't use cast macro. */ + output_stream = g_file_create_finish (destination, result, &error); + save_context->output_stream = (GOutputStream *) output_stream; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { + destination = attachment_save_new_candidate (save_context); + + g_file_create_async ( + destination, G_FILE_CREATE_NONE, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_create_cb, + save_context); + + g_object_unref (destination); + g_error_free (error); + return; + } + + if (attachment_save_check_for_error (save_context, error)) + return; + + save_context->destination = g_object_ref (destination); + attachment_save_got_output_stream (save_context); +} + +static void +attachment_save_replace_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + GFileOutputStream *output_stream; + GError *error = NULL; + + /* Output stream might be NULL, so don't use cast macro. */ + output_stream = g_file_replace_finish (destination, result, &error); + save_context->output_stream = (GOutputStream *) output_stream; + + if (attachment_save_check_for_error (save_context, error)) + return; + + save_context->destination = g_object_ref (destination); + attachment_save_got_output_stream (save_context); +} + +static void +attachment_save_query_info_cb (GFile *destination, + GAsyncResult *result, + SaveContext *save_context) +{ + EAttachment *attachment; + GCancellable *cancellable; + GFileInfo *file_info; + GFileType file_type; + GError *error = NULL; + + attachment = save_context->attachment; + cancellable = attachment->priv->cancellable; + + file_info = g_file_query_info_finish (destination, result, &error); + + /* G_IO_ERROR_NOT_FOUND just means we're creating a new file. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { + g_error_free (error); + goto replace; + } + + if (attachment_save_check_for_error (save_context, error)) + return; + + file_type = g_file_info_get_file_type (file_info); + g_object_unref (file_info); + + if (file_type == G_FILE_TYPE_DIRECTORY) { + save_context->directory = g_object_ref (destination); + destination = attachment_save_new_candidate (save_context); + + g_file_create_async ( + destination, G_FILE_CREATE_NONE, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) attachment_save_create_cb, + save_context); + + g_object_unref (destination); + + return; + } + +replace: + g_file_replace_async ( + destination, NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, G_PRIORITY_DEFAULT, cancellable, (GAsyncReadyCallback) attachment_save_replace_cb, save_context); -- cgit v1.2.3 From 5f55aba5b052fb7284973f50009f8b369334d084 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 1 May 2009 06:44:36 -0400 Subject: Merge in changes from master. --- widgets/misc/test-charset-picker.c | 38 -------------------------------------- widgets/misc/test-error.c | 4 +--- 2 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 widgets/misc/test-charset-picker.c (limited to 'widgets/misc') diff --git a/widgets/misc/test-charset-picker.c b/widgets/misc/test-charset-picker.c deleted file mode 100644 index 5b49e2d0f7..0000000000 --- a/widgets/misc/test-charset-picker.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * 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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include -#include "e-charset-picker.h" - -int -main (int argc, char **argv) -{ - char *charset; - - gnome_init ("test-charset-picker", "1.0", argc, argv); - - charset = e_charset_picker_dialog ("test-charset-picker", - "Pick a charset, any charset", - NULL, NULL); - if (charset) - printf ("You picked: %s\n", charset); - - return 0; -} diff --git a/widgets/misc/test-error.c b/widgets/misc/test-error.c index 84abd76ce3..c8b442b23a 100644 --- a/widgets/misc/test-error.c +++ b/widgets/misc/test-error.c @@ -25,14 +25,12 @@ #include #endif -#include -#include #include "e-error.h" int main (int argc, char **argv) { - gnome_init ("test-error", "0.0", argc, argv); + gtk_init (&argc, &argv); argc--; switch (argc) { -- cgit v1.2.3 From fa28940b0106ae2121fdccb78008c31f2cd99df3 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 30 Apr 2009 23:30:00 -0400 Subject: Only #include specific libgnome[ui] headers; easier to track. Stop including top-level libgnome[ui] headers -- , and . Instead, include specific header files so we can track them easier. Also, remove several unshipped test programs. Mostly ETable stuff. --- widgets/misc/test-error.c | 61 ----------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 widgets/misc/test-error.c (limited to 'widgets/misc') diff --git a/widgets/misc/test-error.c b/widgets/misc/test-error.c deleted file mode 100644 index c8b442b23a..0000000000 --- a/widgets/misc/test-error.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-error.h" - -int -main (int argc, char **argv) -{ - gtk_init (&argc, &argv); - - argc--; - switch (argc) { - case 1: - e_error_run(NULL, argv[1], NULL); - break; - case 2: - e_error_run(NULL, argv[1], argv[2], NULL); - break; - case 3: - e_error_run(NULL, argv[1], argv[2], argv[3], NULL); - break; - case 4: - e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], NULL); - break; - case 5: - e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], argv[5], NULL); - break; - case 6: - e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); - break; - default: - printf("Error: too many or too few arguments\n"); - printf("Usage:\n %s domain:error-id [ args ... ]\n", argv[0]); - } - - return 0; -} -- cgit v1.2.3 From 504642b7984f5fed0db6284e2f4da6b1c9b8d1e0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 2 May 2009 11:09:30 -0400 Subject: Use Behdad's brilliant git.mk to generate .gitignore files. --- widgets/misc/Makefile.am | 2 ++ widgets/misc/pixmaps/Makefile.am | 2 ++ 2 files changed, 4 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index f5dbd63d82..a16d9acc13 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -218,3 +218,5 @@ EXTRA_DIST = \ dist-hook: -mkdir $(distdir)/pixmaps cp $(srcdir)/pixmaps/*.xpm $(distdir)/pixmaps + +-include $(top_srcdir)/git.mk diff --git a/widgets/misc/pixmaps/Makefile.am b/widgets/misc/pixmaps/Makefile.am index 5092e20ba3..fa86dee8fb 100644 --- a/widgets/misc/pixmaps/Makefile.am +++ b/widgets/misc/pixmaps/Makefile.am @@ -7,3 +7,5 @@ pixmaps = \ EXTRA_DIST = \ $(pixmaps) + +-include $(top_srcdir)/git.mk -- cgit v1.2.3 From d0ab4dfedbb7bf45445cff43edf011b44b10a10b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 2 May 2009 22:44:31 -0400 Subject: Remove obsolete Glade files. --- widgets/misc/Makefile.am | 4 +- widgets/misc/e-attachment.glade | 237 -------------------------------------- widgets/misc/gal-categories.glade | 173 ---------------------------- 3 files changed, 1 insertion(+), 413 deletions(-) delete mode 100644 widgets/misc/e-attachment.glade delete mode 100644 widgets/misc/gal-categories.glade (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index a16d9acc13..35d9289536 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -28,9 +28,7 @@ pilot_sources = pilot_headers = endif -glade_DATA = e-send-options.glade \ - gal-categories.glade \ - e-attachment.glade +glade_DATA = e-send-options.glade widgetsinclude_HEADERS = \ $(pilot_headers) \ diff --git a/widgets/misc/e-attachment.glade b/widgets/misc/e-attachment.glade deleted file mode 100644 index 4ac617d672..0000000000 --- a/widgets/misc/e-attachment.glade +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - 6 - True - Attachment Properties - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_CENTER_ON_PARENT - False - True - False - True - - - - True - False - 6 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - -6 - - - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - -5 - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - 4 - 2 - False - 6 - 6 - - - - True - True - True - True - 0 - - True - * - False - - - 1 - 2 - 1 - 2 - - - - - - - True - False - True - False - True - 0 - - True - * - False - - - 1 - 2 - 2 - 3 - - - - - - - True - MIME type: - False - False - GTK_JUSTIFY_LEFT - False - False - 1 - 0.5 - 0 - 0 - - - 0 - 1 - 2 - 3 - fill - - - - - - - True - Description: - False - False - GTK_JUSTIFY_CENTER - False - False - 1 - 0.5 - 0 - 0 - - - 0 - 1 - 1 - 2 - fill - - - - - - - True - File name: - False - False - GTK_JUSTIFY_CENTER - False - False - 1 - 0.5 - 0 - 0 - - - 0 - 1 - 0 - 1 - fill - - - - - - - True - True - True - True - 0 - - True - * - False - - - 1 - 2 - 0 - 1 - - - - - - - True - True - Suggest automatic display of attachment - True - GTK_RELIEF_NORMAL - False - False - True - - - 0 - 2 - 3 - 4 - fill - - - - - - 0 - True - True - - - - - - - diff --git a/widgets/misc/gal-categories.glade b/widgets/misc/gal-categories.glade deleted file mode 100644 index 97a295bd44..0000000000 --- a/widgets/misc/gal-categories.glade +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - categories - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - False - - - - True - False - 6 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - 0 - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - 0 - - - - - 0 - False - True - GTK_PACK_END - - - - - - 12 - True - 5 - 1 - False - 6 - 6 - - - - True - True - True - True - 0 - - True - * - False - - - 0 - 1 - 1 - 2 - - - - - - - True - Item(s) belong to these _categories: - True - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - entry-categories - - - 0 - 1 - 0 - 1 - fill - - - - - - - True - _Available Categories: - True - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - - - 0 - 1 - 2 - 3 - fill - - - - - - - True - True - Edit Master Category List... - True - GTK_RELIEF_NORMAL - True - - - 0 - 1 - 4 - 5 - fill - - - - - 0 - True - True - - - - - - - -- cgit v1.2.3 From 4b8de5b7652b3a2e11799926b2cbc6c873c2181c Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 2 May 2009 23:57:44 -0400 Subject: =?UTF-8?q?Bug=20574781=20=E2=80=93=20Bad=20e-send-options.glade?= =?UTF-8?q?=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-send-options.glade | 2074 +++++++++++++++---------------------- 1 file changed, 808 insertions(+), 1266 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-send-options.glade b/widgets/misc/e-send-options.glade index 1c1cc486d0..58ee7f32c4 100644 --- a/widgets/misc/e-send-options.glade +++ b/widgets/misc/e-send-options.glade @@ -1,1280 +1,822 @@ - - - + - - - - True - True - Send Options - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_MOUSE - True - False - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - True - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-help - True - GTK_RELIEF_NORMAL - True - -11 - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - True - True - True - GTK_POS_TOP - False - False - - - - 12 - True - 4 - 4 - False - 12 - 12 - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 4 - 1 - 2 - - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - 12 - True - 2 - 3 - False - 12 - 12 - - - - True - True - R_eply requested - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 3 - 0 - 1 - fill - - - - - - - True - 0.5 - 0.5 - 0 - 1 - 0 - 0 - 12 - 0 - - - - True - 2 - 3 - False - 12 - 12 - - - - True - True - Wi_thin - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 1 - 2 - fill - - - - - - - True - True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 5 0 100 1 10 0 - - - 1 - 2 - 1 - 2 - - - - - - - True - days - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - True - _When convenient - True - GTK_RELIEF_NORMAL - True - False - False - True - reply-within - - - 0 - 3 - 0 - 1 - fill - - - - - - - - 0 - 3 - 1 - 2 - - - - - - - - - - True - <b>Replies</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - 4 - 2 - 3 - fill - - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - 12 - True - 4 - 2 - False - 0 - 0 - - - - True - True - _Delay message delivery - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 0 - 1 - fill - - - - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 0 - 1 - - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - 12 - True - False - 12 - - - - True - _After: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - expire-after - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 2 0 100 1 10 0 - - - 0 - False - False - - - - - - True - days - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - 0 - 2 - 3 - 4 - expand - - - - - - True - True - _Set expiration date - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 2 - 3 - fill - - - - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 2 - 3 - fill - - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - 12 - True - True - False - 12 - - - - True - _Until: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - send_options_make_dateedit - 0 - 0 - Wed, 08 Dec 2004 16:19:08 GMT - - - 0 - False - False - - - - - - - 0 - 2 - 1 - 2 - - - - - - - - - True - <b>Delivery Options</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - 4 - 3 - 4 - fill - - - - - - - True - Undefined + + + + True + True + Send Options + False + True + mouse + dialog + False + + + True + True + + + True + True + + + True + 12 + 4 + 4 + 12 + 12 + + + True + 0 + + + 2 + 4 + 1 + 2 + + + + + + True + 0 + none + + + True + 12 + 2 + 3 + 12 + 12 + + + R_eply requested + True + True + False + True + True + + + 3 + GTK_FILL + + + + + + True + 0 + 12 + + + True + 2 + 3 + 12 + 12 + + + Wi_thin + True + True + False + True + True + + + 1 + 2 + GTK_FILL + + + + + + True + True + 5 0 100 1 10 0 + 1 + + + 1 + 2 + 1 + 2 + + + + + + True + 0 + days + + + 2 + 3 + 1 + 2 + GTK_FILL + + + + + + _When convenient + True + True + False + True + True + reply-within + + + 3 + GTK_FILL + + + + + + + + 3 + 1 + 2 + + + + + + + + + True + <b>Replies</b> + True + + + label_item + + + + + 4 + 2 + 3 + GTK_FILL + + + + + + True + 0 + none + + + True + 12 + 4 + 2 + + + _Delay message delivery + True + True + False + True + True + + + GTK_FILL + + + + + + True + 0 + + + 1 + 2 + + + + + + True + 12 + + + True + 12 + 12 + + + True + 0 + _After: + True + expire-after + + + False + False + 0 + + + + + True + True + 2 0 100 1 10 0 + 1 + + + False + False + 1 + + + + + True + 0 + days + + + False + False + 2 + + + + + + + 2 + 3 + 4 + GTK_EXPAND + + + + + _Set expiration date + True + True + False + True + True + + + 2 + 3 + GTK_FILL + + + + + + True + 0 + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + 12 + + + True + True + 12 + 12 + + + True + 0 + _Until: + True + until-date + + + False + False + 0 + + + + + True + send_options_make_dateedit + + + False + False + 1 + + + + + + + 2 + 1 + 2 + + + + + + + + True + <b>Delivery Options</b> + True + + + label_item + + + + + 4 + 3 + 4 + GTK_FILL + + + + + + True + Undefined High Standard Low - False - True - - - 1 - 2 - 1 - 2 - fill - - - - - - True - _Priority: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 1 - 2 - - - - - - - True - Classification - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 0 - 1 - fill - - - - - - - True - Normal + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + 1 + _Priority: + True + combo-priority + + + 1 + 2 + + + + + + True + 1 + _Classification: + True + security-combo + + + GTK_FILL + + + + + + True + Normal Proprietary Confidential Secret Top Secret For Your Eyes Only - False - True - - - 1 - 2 - 0 - 1 - fill - fill - - - - - False - True - - - - - - True - Gene_ral Options - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - - 12 - True - False - 12 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - 12 - True - False - 12 - - - - True - True - Creat_e a sent item to track information - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 19 - 0 - - - - True - True - _Delivered - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - - 0 - False - False - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 19 - 0 - - - - True - True - Deli_vered and opened - True - GTK_RELIEF_NORMAL - True - False - False - True - delivered - - - - - 0 - False - False - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 19 - 0 - - - - True - True - _All information - True - GTK_RELIEF_NORMAL - True - False - False - True - delivered - - - - - 0 - False - False - - - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 19 - 0 - - - - True - True - A_uto-delete sent item - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - - 0 - False - False - - - - - - - - - - True - <b>Status Tracking</b> - True - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - 12 - True - 4 - 2 - False - 12 - 12 - - - - True - _When opened: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 0 - 1 - - - - - - - - True - When decli_ned: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 1 - 2 - - - - - - - - True - When co_mpleted: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 3 - 4 - fill - - - - - - - True - When acce_pted: - True - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 2 - 3 - - - - - - - - True - None + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + + + + + + + + + True + Gene_ral Options + True + + + False + tab + + + + + True + 12 + 12 + + + True + 0 + none + + + True + 12 + + + True + 12 + 12 + + + Creat_e a sent item to track information + True + True + False + True + True + + + False + False + 0 + + + + + True + 19 + + + _Delivered + True + True + False + True + True + + + + + False + False + 1 + + + + + True + 19 + + + Deli_vered and opened + True + True + False + True + True + delivered + + + + + False + False + 2 + + + + + True + 19 + + + _All information + True + True + False + True + True + delivered + + + + + False + False + 3 + + + + + True + 19 + + + A_uto-delete sent item + True + True + False + True + True + + + + + False + False + 4 + + + + + + + + + True + <b>Status Tracking</b> + True + True + + + label_item + + + + + False + False + 0 + + + + + True + 0 + none + + + True + 12 + + + True + 12 + 4 + 2 + 12 + 12 + + + True + 1 + _When opened: + True + open-combo + + + GTK_FILL + + + + + + True + 1 + When decli_ned: + True + delete-combo + + + 1 + 2 + GTK_FILL + + + + + + True + 0 + When co_mpleted: + True + complete-combo + + + 3 + 4 + GTK_FILL + + + + + + True + 1 + When acce_pted: + True + accept-combo + + + 2 + 3 + GTK_FILL + + + + + + True + None Mail Receipt - False - True - - - 1 - 2 - 0 - 1 - fill - - - - - - True - None + + + 1 + 2 + GTK_FILL + + + + + True + None Mail Receipt - False - True - - - 1 - 2 - 1 - 2 - fill - - - - - - True - None + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + None Mail Receipt - False - True - - - 1 - 2 - 2 - 3 - fill - - - - - - True - None + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + None Mail Receipt - False - True - - - 1 - 2 - 3 - 4 - - - - - - - - - - True - <b>Return Notification</b> - True - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - False - True - - - - - - True - Sta_tus Tracking - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - 0 - True - True - - - - - - + + + 1 + 2 + 3 + 4 + + + + + + + + + True + <b>Return Notification</b> + True + True + + + label_item + + + + + False + False + 1 + + + + + 1 + + + + + True + Sta_tus Tracking + True + + + 1 + False + tab + + + + + 2 + + + + + True + end + + + gtk-help + -11 + True + True + True + False + True + + + False + False + 0 + + + + + gtk-cancel + -6 + True + True + True + False + True + + + False + False + 1 + + + + + gtk-ok + -5 + True + True + True + False + True + + + False + False + 2 + + + + + False + end + 0 + + + + + -- cgit v1.2.3 From 662ede69bbdfa5fe4b2aca2e412303fc20190ad7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 5 May 2009 14:25:48 -0400 Subject: =?UTF-8?q?Bug=20581454=20=E2=80=93=20Move=20nautilus-sendto=20int?= =?UTF-8?q?egration=20to=20Evolution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/Makefile.am | 2 + widgets/misc/e-attachment-handler-sendto.c | 248 +++++++++++++++++++++++++++++ widgets/misc/e-attachment-handler-sendto.h | 62 ++++++++ widgets/misc/e-attachment-view.c | 2 + 4 files changed, 314 insertions(+) create mode 100644 widgets/misc/e-attachment-handler-sendto.c create mode 100644 widgets/misc/e-attachment-handler-sendto.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 35d9289536..212d67557b 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -42,6 +42,7 @@ widgetsinclude_HEADERS = \ e-attachment-dialog.h \ e-attachment-handler.h \ e-attachment-handler-image.h \ + e-attachment-handler-sendto.h \ e-attachment-icon-view.h \ e-attachment-paned.h \ e-attachment-store.h \ @@ -106,6 +107,7 @@ libemiscwidgets_la_SOURCES = \ e-attachment-dialog.c \ e-attachment-handler.c \ e-attachment-handler-image.c \ + e-attachment-handler-sendto.c \ e-attachment-icon-view.c \ e-attachment-paned.c \ e-attachment-store.c \ diff --git a/widgets/misc/e-attachment-handler-sendto.c b/widgets/misc/e-attachment-handler-sendto.c new file mode 100644 index 0000000000..7cf651d98f --- /dev/null +++ b/widgets/misc/e-attachment-handler-sendto.c @@ -0,0 +1,248 @@ +/* + * e-attachment-handler-sendto.c + * + * Copyright (C) 2009 Matthew Barnes + * + * 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) any later version. + * + * 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 + * + */ + +#include "e-attachment-handler-sendto.h" + +#include +#include + +#include + +static gpointer parent_class; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +""; + +static void +sendto_save_finished_cb (EAttachment *attachment, + GAsyncResult *result, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + EAttachmentStore *store; + GtkWidget *dialog; + gchar **uris; + gpointer parent; + gchar *arguments; + gchar *command_line; + guint n_uris = 1; + GError *error = NULL; + + view = e_attachment_handler_get_view (handler); + store = e_attachment_view_get_store (view); + + uris = e_attachment_store_get_uris_finish (store, result, &error); + + if (uris != NULL) + n_uris = g_strv_length (uris); + + if (error != NULL) + goto error; + + arguments = g_strjoinv (" ", uris); + command_line = g_strdup_printf ("nautilus-sendto %s", arguments); + + g_message ("Command: %s", command_line); + g_spawn_command_line_async (command_line, &error); + + g_free (command_line); + g_free (arguments); + + if (error != NULL) + goto error; + + goto exit; + +error: + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", + ngettext ("Could not send attachment", + "Could not send attachments", n_uris)); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); + +exit: + g_object_unref (handler); + g_strfreev (uris); +} + +static void +action_sendto_cb (GtkAction *action, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + EAttachmentStore *store; + GList *selected; + + view = e_attachment_handler_get_view (handler); + store = e_attachment_view_get_store (view); + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (selected != NULL); + + e_attachment_store_get_uris_async ( + store, selected, (GAsyncReadyCallback) + sendto_save_finished_cb, g_object_ref (handler)); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static GtkActionEntry standard_entries[] = { + + { "sendto", + "document-send", + N_("_Send To..."), + NULL, + N_("Send the selected attachments somewhere"), + G_CALLBACK (action_sendto_cb) } +}; + +static void +attachment_handler_sendto_update_actions_cb (EAttachmentView *view, + EAttachmentHandler *handler) +{ + GtkActionGroup *action_group; + GList *selected, *iter; + gboolean visible = FALSE; + gchar *program; + + program = g_find_program_in_path ("nautilus-sendto"); + selected = e_attachment_view_get_selected_attachments (view); + + if (program == NULL || selected == NULL) + goto exit; + + /* Make sure no file transfers are in progress. */ + for (iter = selected; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + + if (e_attachment_get_loading (attachment)) + goto exit; + + if (e_attachment_get_saving (attachment)) + goto exit; + } + + visible = TRUE; + +exit: + action_group = e_attachment_view_get_action_group (view, "sendto"); + gtk_action_group_set_visible (action_group, visible); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); + + g_free (program); +} + +static void +attachment_handler_sendto_constructed (GObject *object) +{ + EAttachmentHandler *handler; + EAttachmentView *view; + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + GError *error = NULL; + + handler = E_ATTACHMENT_HANDLER (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + view = e_attachment_handler_get_view (handler); + ui_manager = e_attachment_view_get_ui_manager (view); + + action_group = gtk_action_group_new ("sendto"); + gtk_action_group_set_translation_domain ( + action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), object); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_signal_connect ( + view, "update-actions", + G_CALLBACK (attachment_handler_sendto_update_actions_cb), + object); +} + +static void +attachment_handler_sendto_class_init (EAttachmentHandlerSendtoClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = attachment_handler_sendto_constructed; +} + +GType +e_attachment_handler_sendto_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentHandlerSendtoClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_handler_sendto_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentHandlerSendto), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ATTACHMENT_HANDLER, + "EAttachmentHandlerSendto", + &type_info, 0); + } + + return type; +} diff --git a/widgets/misc/e-attachment-handler-sendto.h b/widgets/misc/e-attachment-handler-sendto.h new file mode 100644 index 0000000000..9ae272ad7a --- /dev/null +++ b/widgets/misc/e-attachment-handler-sendto.h @@ -0,0 +1,62 @@ +/* + * e-attachment-handler-sendto.h + * + * Copyright (C) 2009 Matthew Barnes + * + * 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) any later version. + * + * 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 + * + */ + +#ifndef E_ATTACHMENT_HANDLER_SENDTO_H +#define E_ATTACHMENT_HANDLER_SENDTO_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_HANDLER_SENDTO \ + (e_attachment_handler_sendto_get_type ()) +#define E_ATTACHMENT_HANDLER_SENDTO(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendto)) +#define E_ATTACHMENT_HANDLER_SENDTO_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendtoClass)) +#define E_IS_ATTACHMENT_HANDLER_SENDTO(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO)) +#define E_IS_ATTACHMENT_HANDLER_SENDTO_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_SENDTO)) +#define E_ATTACHMENT_HANDLER_SENDTO_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_SENDTO, EAttachmentHandlerSendtoClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentHandlerSendto EAttachmentHandlerSendto; +typedef struct _EAttachmentHandlerSendtoClass EAttachmentHandlerSendtoClass; + +struct _EAttachmentHandlerSendto { + EAttachmentHandler parent; +}; + +struct _EAttachmentHandlerSendtoClass { + EAttachmentHandlerClass parent_class; +}; + +GType e_attachment_handler_sendto_get_type (void); + +G_END_DECLS + +#endif /* E_ATTACHMENT_HANDLER_SENDTO_H */ diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 2ad34d6751..f8917d141c 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -30,6 +30,7 @@ #include "e-util/e-util.h" #include "e-attachment-dialog.h" #include "e-attachment-handler-image.h" +#include "e-attachment-handler-sendto.h" enum { UPDATE_ACTIONS, @@ -774,6 +775,7 @@ e_attachment_view_get_type (void) /* Register known handler types. */ e_attachment_handler_image_get_type (); + e_attachment_handler_sendto_get_type (); } return type; -- cgit v1.2.3 From 17138e29b4d9a2cafa068266d0b706f4bf4de775 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 5 May 2009 14:36:33 -0400 Subject: Use 'Open with "$foo"' instead of 'Open in $foo...' For better consistency with Nautilus. --- widgets/misc/e-attachment-view.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index f8917d141c..f85fcdbace 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -643,7 +643,7 @@ attachment_view_update_actions (EAttachmentView *view) app_name = g_app_info_get_name (app_info); action_name = g_strdup_printf ("open-in-%s", app_executable); - action_label = g_strdup_printf (_("Open in %s..."), app_name); + action_label = g_strdup_printf (_("Open with \"%s\""), app_name); action_tooltip = g_strdup_printf ( _("Open this attachment in %s"), app_name); -- cgit v1.2.3 From f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 20 May 2009 16:50:00 +0200 Subject: Use -no-undefined on Linux too There still left two things opened, search for KILL-BONOBO to find them. One is in calendar's Makefile.am, one in composer. --- widgets/misc/Makefile.am | 43 +- widgets/misc/a11y/ea-calendar-cell.c | 387 +++++++ widgets/misc/a11y/ea-calendar-cell.h | 90 ++ widgets/misc/a11y/ea-calendar-item.c | 1314 ++++++++++++++++++++++ widgets/misc/a11y/ea-calendar-item.h | 72 ++ widgets/misc/a11y/ea-widgets.c | 32 + widgets/misc/a11y/ea-widgets.h | 32 + widgets/misc/e-calendar-item.c | 2 +- widgets/misc/e-cell-date-edit.c | 1033 ----------------- widgets/misc/e-cell-date-edit.h | 106 -- widgets/misc/e-cell-percent.c | 152 --- widgets/misc/e-cell-percent.h | 51 - widgets/misc/e-reflow-model.c | 350 ------ widgets/misc/e-reflow-model.h | 112 -- widgets/misc/e-reflow.c | 1534 ------------------------- widgets/misc/e-reflow.h | 146 --- widgets/misc/e-search-bar.c | 2 +- widgets/misc/e-unicode.c | 2052 ---------------------------------- widgets/misc/e-unicode.h | 113 -- 19 files changed, 1944 insertions(+), 5679 deletions(-) create mode 100644 widgets/misc/a11y/ea-calendar-cell.c create mode 100644 widgets/misc/a11y/ea-calendar-cell.h create mode 100644 widgets/misc/a11y/ea-calendar-item.c create mode 100644 widgets/misc/a11y/ea-calendar-item.h create mode 100644 widgets/misc/a11y/ea-widgets.c create mode 100644 widgets/misc/a11y/ea-widgets.h delete mode 100644 widgets/misc/e-cell-date-edit.c delete mode 100644 widgets/misc/e-cell-date-edit.h delete mode 100644 widgets/misc/e-cell-percent.c delete mode 100644 widgets/misc/e-cell-percent.h delete mode 100644 widgets/misc/e-reflow-model.c delete mode 100644 widgets/misc/e-reflow-model.h delete mode 100644 widgets/misc/e-reflow.c delete mode 100644 widgets/misc/e-reflow.h delete mode 100644 widgets/misc/e-unicode.c delete mode 100644 widgets/misc/e-unicode.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 212d67557b..bd2c9f9f36 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -1,10 +1,5 @@ -if OS_WIN32 -WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libfilter.la -endif - INCLUDES = \ -I$(top_srcdir) \ - -I$(top_srcdir)/a11y/widgets \ -I$(top_srcdir)/filter \ -I$(top_srcdir)/widgets \ -DEVOLUTION_IMAGES=\""$(imagesdir)"\" \ @@ -50,13 +45,10 @@ widgetsinclude_HEADERS = \ e-attachment-view.h \ e-calendar.h \ e-calendar-item.h \ - e-camel-activity.h \ e-canvas.h \ e-canvas-background.h \ e-canvas-utils.h \ e-canvas-vbox.h \ - e-cell-date-edit.h \ - e-cell-percent.h \ e-cell-renderer-combo.h \ e-charset-picker.h \ e-colors.h \ @@ -75,8 +67,6 @@ widgetsinclude_HEADERS = \ e-popup-menu.h \ e-preferences-window.h \ e-printable.h \ - e-reflow.h \ - e-reflow-model.h \ e-search-bar.h \ e-selection-model.h \ e-selection-model-array.h \ @@ -91,8 +81,10 @@ widgetsinclude_HEADERS = \ e-spinner.c \ e-spinner.h \ e-timeout-activity.h \ - e-unicode.h \ - e-url-entry.h + e-url-entry.h \ + a11y/ea-calendar-cell.h \ + a11y/ea-calendar-item.h \ + a11y/ea-widgets.h libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ @@ -115,13 +107,10 @@ libemiscwidgets_la_SOURCES = \ e-attachment-view.c \ e-calendar.c \ e-calendar-item.c \ - e-camel-activity.c \ e-canvas.c \ e-canvas-background.c \ e-canvas-utils.c \ e-canvas-vbox.c \ - e-cell-date-edit.c \ - e-cell-percent.c \ e-cell-renderer-combo.c \ e-charset-picker.c \ e-colors.c \ @@ -140,8 +129,6 @@ libemiscwidgets_la_SOURCES = \ e-popup-menu.c \ e-preferences-window.c \ e-printable.c \ - e-reflow-model.c \ - e-reflow.c \ e-search-bar.c \ e-selection-model.c \ e-selection-model-array.c \ @@ -154,20 +141,20 @@ libemiscwidgets_la_SOURCES = \ e-signature-script-dialog.c \ e-signature-tree-view.c \ e-timeout-activity.c \ - e-unicode.c \ - e-url-entry.c + e-url-entry.c \ + a11y/ea-calendar-cell.c \ + a11y/ea-calendar-item.c \ + a11y/ea-widgets.c libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) -libemiscwidgets_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(top_builddir)/widgets/table/libetable.la \ - $(top_builddir)/widgets/text/libetext.la \ - $(top_builddir)/a11y/widgets/libevolution-widgets-a11y.la \ - $(top_builddir)/a11y/libevolution-a11y.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ +libemiscwidgets_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ + $(top_builddir)/a11y/libevolution-a11y.la \ + $(EVOLUTION_MAIL_LIBS) \ + $(GNOME_PLATFORM_LIBS) \ + $(MATH_LIB) \ $(ICONV_LIBS) noinst_PROGRAMS = \ diff --git a/widgets/misc/a11y/ea-calendar-cell.c b/widgets/misc/a11y/ea-calendar-cell.c new file mode 100644 index 0000000000..8173d6d25f --- /dev/null +++ b/widgets/misc/a11y/ea-calendar-cell.c @@ -0,0 +1,387 @@ +/* + * + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include +#include +#include "ea-calendar-cell.h" +#include "ea-calendar-item.h" +#include "a11y/ea-factory.h" + +/* ECalendarCell */ + +static void e_calendar_cell_class_init (ECalendarCellClass *class); + +EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new) + +GType +e_calendar_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (ECalendarCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) e_calendar_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (ECalendarCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "ECalendarCell", &tinfo, 0); + } + + return type; +} + +static void +e_calendar_cell_class_init (ECalendarCellClass *class) +{ + EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell); +} + +ECalendarCell * +e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column) +{ + GObject *object; + ECalendarCell *cell; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL); + + object = g_object_new (E_TYPE_CALENDAR_CELL, NULL); + cell = E_CALENDAR_CELL (object); + cell->calitem = calitem; + cell->row = row; + cell->column = column; + +#ifdef ACC_DEBUG + g_print ("EvoAcc: e_calendar_cell created %p\n", (void *)cell); +#endif + + return cell; +} + +/* EaCalendarCell */ + +static void ea_calendar_cell_class_init (EaCalendarCellClass *klass); +static void ea_calendar_cell_init (EaCalendarCell *a11y); + +static G_CONST_RETURN gchar* ea_calendar_cell_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_calendar_cell_get_description (AtkObject *accessible); +static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible); +static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible); +static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible); + +/* component interface */ +static void atk_component_interface_init (AtkComponentIface *iface); +static void component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, + gint *width, gint *height, + AtkCoordType coord_type); +static gboolean component_interface_grab_focus (AtkComponent *component); + +static gpointer parent_class = NULL; + +#ifdef ACC_DEBUG +static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0; +static void ea_calendar_cell_finalize (GObject *object); +#endif + +GType +ea_calendar_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalendarCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_calendar_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalendarCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) ea_calendar_cell_init, /* instance init */ + NULL /* value table */ + }; + + static const GInterfaceInfo atk_component_info = { + (GInterfaceInitFunc) atk_component_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + type = g_type_register_static (ATK_TYPE_GOBJECT_ACCESSIBLE, + "EaCalendarCell", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + } + + return type; +} + +static void +ea_calendar_cell_class_init (EaCalendarCellClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + +#ifdef ACC_DEBUG + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ea_calendar_cell_finalize; +#endif + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_calendar_cell_get_name; + class->get_description = ea_calendar_cell_get_description; + + class->get_parent = ea_calendar_cell_get_parent; + class->get_index_in_parent = ea_calendar_cell_get_index_in_parent; + class->ref_state_set = ea_calendar_cell_ref_state_set; +} + +static void +ea_calendar_cell_init (EaCalendarCell *a11y) +{ + a11y->state_set = atk_state_set_new (); + atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); + atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); + atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); +} + +AtkObject* +ea_calendar_cell_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + + g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL); + object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL); + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, obj); + atk_object->role = ATK_ROLE_TABLE_CELL; + +#ifdef ACC_DEBUG + ++n_ea_calendar_cell_created; + g_print ("ACC_DEBUG: n_ea_calendar_cell_created = %d\n", + n_ea_calendar_cell_created); +#endif + return atk_object; +} + +#ifdef ACC_DEBUG +static void ea_calendar_cell_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (object); + + ++n_ea_calendar_cell_destroyed; + g_print ("ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n", + n_ea_calendar_cell_destroyed); +} +#endif + +static G_CONST_RETURN gchar* +ea_calendar_cell_get_name (AtkObject *accessible) +{ + GObject *g_obj; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + /* defunct object*/ + return NULL; + + if (!accessible->name) { + AtkObject *atk_obj; + EaCalendarItem *ea_calitem; + ECalendarCell *cell; + gint day_index; + gint year, month, day; + gchar buffer[128]; + + cell = E_CALENDAR_CELL (g_obj); + atk_obj = ea_calendar_cell_get_parent (accessible); + ea_calitem = EA_CALENDAR_ITEM (atk_obj); + day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), + cell->row, cell->column); + e_calendar_item_get_date_for_offset (cell->calitem, day_index, + &year, &month, &day); + + g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day); + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer); + } + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_calendar_cell_get_description (AtkObject *accessible) +{ + return ea_calendar_cell_get_name (accessible); +} + +static AtkObject * +ea_calendar_cell_get_parent (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarCell *cell; + ECalendarItem *calitem; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + /* defunct object*/ + return NULL; + + cell = E_CALENDAR_CELL (g_obj); + calitem = cell->calitem; + return atk_gobject_accessible_for_object (G_OBJECT (calitem)); +} + +static gint +ea_calendar_cell_get_index_in_parent (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarCell *cell; + AtkObject *parent; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return -1; + cell = E_CALENDAR_CELL (g_obj); + parent = atk_object_get_parent (accessible); + return atk_table_get_index_at (ATK_TABLE (parent), + cell->row, cell->column); +} + +static AtkStateSet * +ea_calendar_cell_ref_state_set (AtkObject *accessible) +{ + EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible); + + g_return_val_if_fail (atk_cell->state_set, NULL); + + g_object_ref(atk_cell->state_set); + + return atk_cell->state_set; + +} + +/* Atk Component Interface */ + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = component_interface_get_extents; + iface->grab_focus = component_interface_grab_focus; +} + +static void +component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, gint *width, gint *height, + AtkCoordType coord_type) +{ + GObject *g_obj; + AtkObject *atk_obj, *atk_canvas; + ECalendarCell *cell; + ECalendarItem *calitem; + EaCalendarItem *ea_calitem; + gint day_index; + gint year, month, day; + gint canvas_x, canvas_y, canvas_width, canvas_height; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_CALENDAR_CELL (component)); + + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + + cell = E_CALENDAR_CELL (g_obj); + calitem = cell->calitem; + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calitem = EA_CALENDAR_ITEM (atk_obj); + day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), + cell->row, cell->column); + e_calendar_item_get_date_for_offset (calitem, day_index, + &year, &month, &day); + + if (!e_calendar_item_get_day_extents (calitem, + year, month, day, + x, y, width, height)) + return; + atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem)); + atk_component_get_extents (ATK_COMPONENT (atk_canvas), + &canvas_x, &canvas_y, + &canvas_width, &canvas_height, + coord_type); + *x += canvas_x; + *y += canvas_y; +} + +static gboolean +component_interface_grab_focus (AtkComponent *component) +{ + GObject *g_obj; + GtkWidget *toplevel; + AtkObject *ea_calitem; + ECalendarItem *calitem; + EaCalendarCell *a11y; + gint index; + + a11y = EA_CALENDAR_CELL (component); + ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(ea_calitem)); + calitem = E_CALENDAR_ITEM (g_obj); + + index = atk_object_get_index_in_parent (ATK_OBJECT (a11y)); + + atk_selection_clear_selection (ATK_SELECTION (ea_calitem)); + atk_selection_add_selection (ATK_SELECTION (ea_calitem), index); + + gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); + if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel)) + gtk_window_present (GTK_WINDOW (toplevel)); + + return TRUE; + +} diff --git a/widgets/misc/a11y/ea-calendar-cell.h b/widgets/misc/a11y/ea-calendar-cell.h new file mode 100644 index 0000000000..a07b7e8bbc --- /dev/null +++ b/widgets/misc/a11y/ea-calendar-cell.h @@ -0,0 +1,90 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CALENDAR_CELL_H__ +#define __EA_CALENDAR_CELL_H__ + +#include +#include "misc/e-calendar-item.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ()) +#define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell)) +#define E_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) +#define E_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CALENDAR_CELL)) +#define E_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CALENDAR_CELL)) +#define E_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) + +typedef struct _ECalendarCell ECalendarCell; +typedef struct _ECalendarCellClass ECalendarCellClass; + +struct _ECalendarCell +{ + GObject parent; + ECalendarItem *calitem; + gint row; + gint column; +}; + +GType e_calendar_cell_get_type (void); + +struct _ECalendarCellClass +{ + GObjectClass parent_class; +}; + +ECalendarCell * e_calendar_cell_new (ECalendarItem *calitem, + gint row, gint column); + +#define EA_TYPE_CALENDAR_CELL (ea_calendar_cell_get_type ()) +#define EA_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCell)) +#define EA_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) +#define EA_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_CELL)) +#define EA_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_CELL)) +#define EA_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) + +typedef struct _EaCalendarCell EaCalendarCell; +typedef struct _EaCalendarCellClass EaCalendarCellClass; + +struct _EaCalendarCell +{ + AtkGObjectAccessible parent; + AtkStateSet *state_set; +}; + +GType ea_calendar_cell_get_type (void); + +struct _EaCalendarCellClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_calendar_cell_new (GObject *gobj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_CALENDAR_CELL_H__ */ diff --git a/widgets/misc/a11y/ea-calendar-item.c b/widgets/misc/a11y/ea-calendar-item.c new file mode 100644 index 0000000000..66f40a92a0 --- /dev/null +++ b/widgets/misc/a11y/ea-calendar-item.c @@ -0,0 +1,1314 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ea-calendar-item.h" +#include "ea-calendar-cell.h" +#include "a11y/ea-cell-table.h" + +#define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH + +/* EaCalendarItem */ +static void ea_calendar_item_class_init (EaCalendarItemClass *klass); +static void ea_calendar_item_finalize (GObject *object); + +static G_CONST_RETURN gchar* ea_calendar_item_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_calendar_item_get_description (AtkObject *accessible); +static gint ea_calendar_item_get_n_children (AtkObject *accessible); +static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index); +static AtkStateSet* ea_calendar_item_ref_state_set (AtkObject *accessible); + +/* atk table interface */ +static void atk_table_interface_init (AtkTableIface *iface); +static gint table_interface_get_index_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_column_at_index (AtkTable *table, + gint index); +static gint table_interface_get_row_at_index (AtkTable *table, + gint index); +static AtkObject* table_interface_ref_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_n_rows (AtkTable *table); +static gint table_interface_get_n_columns (AtkTable *table); +static gint table_interface_get_column_extent_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_row_extent_at (AtkTable *table, + gint row, + gint column); + +static gboolean table_interface_is_row_selected (AtkTable *table, + gint row); +static gboolean table_interface_is_column_selected (AtkTable *table, + gint row); +static gboolean table_interface_is_selected (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_selected_rows (AtkTable *table, + gint **rows_selected); +static gint table_interface_get_selected_columns (AtkTable *table, + gint **columns_selected); +static gboolean table_interface_add_row_selection (AtkTable *table, gint row); +static gboolean table_interface_remove_row_selection (AtkTable *table, + gint row); +static gboolean table_interface_add_column_selection (AtkTable *table, + gint column); +static gboolean table_interface_remove_column_selection (AtkTable *table, + gint column); +static AtkObject* table_interface_get_row_header (AtkTable *table, gint row); +static AtkObject* table_interface_get_column_header (AtkTable *table, + gint in_col); +static AtkObject* table_interface_get_caption (AtkTable *table); + +static G_CONST_RETURN gchar* +table_interface_get_column_description (AtkTable *table, gint in_col); + +static G_CONST_RETURN gchar* +table_interface_get_row_description (AtkTable *table, gint row); + +static AtkObject* table_interface_get_summary (AtkTable *table); + +/* atk selection interface */ +static void atk_selection_interface_init (AtkSelectionIface *iface); +static gboolean selection_interface_add_selection (AtkSelection *selection, + gint i); +static gboolean selection_interface_clear_selection (AtkSelection *selection); +static AtkObject* selection_interface_ref_selection (AtkSelection *selection, + gint i); +static gint selection_interface_get_selection_count (AtkSelection *selection); +static gboolean selection_interface_is_child_selected (AtkSelection *selection, + gint i); + +/* callbacks */ +static void selection_preview_change_cb (ECalendarItem *calitem); +static void date_range_changed_cb (ECalendarItem *calitem); + +/* helpers */ +static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem); +static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem); +static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, + gint column, + gchar *buffer, + gint buffer_size); +static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, + gint row, + gchar *buffer, + gint buffer_size); +static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem, + gint year, gint month, gint day, + gint *offset); +static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, + AtkObject *item_cell); + +#ifdef ACC_DEBUG +static gint n_ea_calendar_item_created = 0; +static gint n_ea_calendar_item_destroyed = 0; +#endif + +static gpointer parent_class = NULL; + +GType +ea_calendar_item_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalendarItemClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_calendar_item_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalendarItem), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + static const GInterfaceInfo atk_table_info = { + (GInterfaceInitFunc) atk_table_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + static const GInterfaceInfo atk_selection_info = { + (GInterfaceInitFunc) atk_selection_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (GailCanvasItem, in this case) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + GNOME_TYPE_CANVAS_ITEM); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + g_type_query (derived_atk_type, &query); + + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + + type = g_type_register_static (derived_atk_type, + "EaCalendarItem", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_TABLE, + &atk_table_info); + g_type_add_interface_static (type, ATK_TYPE_SELECTION, + &atk_selection_info); + } + + return type; +} + +static void +ea_calendar_item_class_init (EaCalendarItemClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = ea_calendar_item_finalize; + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_calendar_item_get_name; + class->get_description = ea_calendar_item_get_description; + class->ref_state_set = ea_calendar_item_ref_state_set; + + class->get_n_children = ea_calendar_item_get_n_children; + class->ref_child = ea_calendar_item_ref_child; +} + +AtkObject* +ea_calendar_item_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + AtkObject *item_cell; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL); + object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL); + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, obj); + atk_object->role = ATK_ROLE_CALENDAR; + + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_object), + 0); + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell); + +#ifdef ACC_DEBUG + ++n_ea_calendar_item_created; + g_print ("ACC_DEBUG: n_ea_calendar_item_created = %d\n", + n_ea_calendar_item_created); +#endif + /* connect signal handlers */ + g_signal_connect (obj, "selection_preview_changed", + G_CALLBACK (selection_preview_change_cb), + atk_object); + g_signal_connect (obj, "date_range_changed", + G_CALLBACK (date_range_changed_cb), + atk_object); + + return atk_object; +} + +static void +ea_calendar_item_finalize (GObject *object) +{ + EaCalendarItem *ea_calitem; + + g_return_if_fail (EA_IS_CALENDAR_ITEM (object)); + + ea_calitem = EA_CALENDAR_ITEM (object); + + /* Free the allocated cell data */ + ea_calendar_item_destory_cell_data (ea_calitem); + + G_OBJECT_CLASS (parent_class)->finalize (object); +#ifdef ACC_DEBUG + ++n_ea_calendar_item_destroyed; + printf ("ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n", + n_ea_calendar_item_destroyed); +#endif +} + +static G_CONST_RETURN gchar* +ea_calendar_item_get_name (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarItem *calitem; + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + gchar *name_str = NULL; + gchar buffer_start[128] = ""; + gchar buffer_end[128] = ""; + struct tm day_start = { 0 }; + struct tm day_end = { 0 }; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return NULL; + g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL); + + calitem = E_CALENDAR_ITEM (g_obj); + if (e_calendar_item_get_date_range (calitem, + &start_year, &start_month, &start_day, + &end_year, &end_month, &end_day)) { + + day_start.tm_year = start_year - 1900; + day_start.tm_mon = start_month; + day_start.tm_mday = start_day; + day_start.tm_isdst = -1; + e_utf8_strftime (buffer_start, sizeof (buffer_start), _("%d %B %Y"), &day_start); + + day_end.tm_year = end_year - 1900; + day_end.tm_mon = end_month; + day_end.tm_mday = end_day; + day_end.tm_isdst = -1; + e_utf8_strftime (buffer_end, sizeof (buffer_end), _("%d %B %Y"), &day_end); + + name_str = g_strdup_printf (_("Calendar: from %s to %s"), buffer_start, buffer_end); + } + +#if 0 + if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) { + GDate select_start, select_end; + gint year1, year2, month1, month2, day1, day2; + + year1 = g_date_get_year (&select_start); + month1 = g_date_get_month (&select_start); + day1 = g_date_get_day (&select_start); + + year2 = g_date_get_year (&select_end); + month2 = g_date_get_month (&select_end); + day2 = g_date_get_day (&select_end); + + sprintf (new_name + strlen (new_name), + " : current selection: from %d-%d-%d to %d-%d-%d.", + year1, month1, day1, + year2, month2, day2); + } +#endif + + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); + g_free (name_str); + + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_calendar_item_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + + return _("evolution calendar item"); +} + +static AtkStateSet* +ea_calendar_item_ref_state_set (AtkObject *accessible) +{ + AtkStateSet *state_set; + GObject *g_obj; + + state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible); + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return state_set; + + atk_state_set_add_state (state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); + + return state_set; +} + +static gint +ea_calendar_item_get_n_children (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint n_children = 0; + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date, *end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return 0; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + end_date = g_date_new_dmy (end_day, end_month + 1, end_year); + + n_children = g_date_days_between (start_date, end_date) + 1; + g_free (start_date); + g_free (end_date); + return n_children; +} + +static AtkObject * +ea_calendar_item_ref_child (AtkObject *accessible, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint n_children; + ECalendarCell *cell; + EaCellTable *cell_data; + EaCalendarItem *ea_calitem; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + calitem = E_CALENDAR_ITEM (g_obj); + + n_children = ea_calendar_item_get_n_children (accessible); + if (index < 0 || index >= n_children) + return NULL; + + ea_calitem = EA_CALENDAR_ITEM (accessible); + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + cell = ea_cell_table_get_cell_at_index (cell_data, index); + if (!cell) { + cell = e_calendar_cell_new (calitem, + index / EA_CALENDAR_COLUMN_NUM, + index % EA_CALENDAR_COLUMN_NUM); + ea_cell_table_set_cell_at_index (cell_data, index, cell); + g_object_unref (cell); + } + +#ifdef ACC_DEBUG + g_print ("AccDebug: ea_calendar_item children[%d]=%p\n", index, + (gpointer)cell); +#endif + return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT(cell))); +} + +/* atk table interface */ + +static void +atk_table_interface_init (AtkTableIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->ref_at = table_interface_ref_at; + + iface->get_n_rows = table_interface_get_n_rows; + iface->get_n_columns = table_interface_get_n_columns; + iface->get_index_at = table_interface_get_index_at; + iface->get_column_at_index = table_interface_get_column_at_index; + iface->get_row_at_index = table_interface_get_row_at_index; + iface->get_column_extent_at = table_interface_get_column_extent_at; + iface->get_row_extent_at = table_interface_get_row_extent_at; + + iface->is_selected = table_interface_is_selected; + iface->get_selected_rows = table_interface_get_selected_rows; + iface->get_selected_columns = table_interface_get_selected_columns; + iface->is_row_selected = table_interface_is_row_selected; + iface->is_column_selected = table_interface_is_column_selected; + iface->add_row_selection = table_interface_add_row_selection; + iface->remove_row_selection = table_interface_remove_row_selection; + iface->add_column_selection = table_interface_add_column_selection; + iface->remove_column_selection = table_interface_remove_column_selection; + + iface->get_row_header = table_interface_get_row_header; + iface->get_column_header = table_interface_get_column_header; + iface->get_caption = table_interface_get_caption; + iface->get_summary = table_interface_get_summary; + iface->get_row_description = table_interface_get_row_description; + iface->get_column_description = table_interface_get_column_description; +} + +static AtkObject* +table_interface_ref_at (AtkTable *table, + gint row, + gint column) +{ + gint index; + + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + index = EA_CALENDAR_COLUMN_NUM * row + column; + return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index); +} + +static gint +table_interface_get_n_rows (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1; +} + +static gint +table_interface_get_n_columns (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + return EA_CALENDAR_COLUMN_NUM; +} + +static gint +table_interface_get_index_at (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + return row * EA_CALENDAR_COLUMN_NUM + column; +} + +static gint +table_interface_get_column_at_index (AtkTable *table, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + if (index >= 0 && index < n_children) + return index % EA_CALENDAR_COLUMN_NUM; + return -1; +} + +static gint +table_interface_get_row_at_index (AtkTable *table, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + if (index >= 0 && index < n_children) + return index / EA_CALENDAR_COLUMN_NUM; + return -1; +} + +static gint +table_interface_get_column_extent_at (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + return calitem->cell_width; +} + +static gint +table_interface_get_row_extent_at (AtkTable *table, + gint row, gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + return calitem->cell_height; +} + +/* any day in the row is selected, the row is selected */ +static gboolean +table_interface_is_row_selected (AtkTable *table, + gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + gint n_rows; + ECalendarItem *calitem; + gint row_index_start, row_index_end; + gint sel_index_start, sel_index_end; + + GDate start_date, end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return FALSE; + + row_index_start = row * EA_CALENDAR_COLUMN_NUM; + row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return FALSE; + + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date), + g_date_get_day (&start_date), + &sel_index_start); + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&end_date), + g_date_get_month (&end_date), + g_date_get_day (&end_date), + &sel_index_end); + + if ((sel_index_start < row_index_start && + sel_index_end >= row_index_start) || + (sel_index_start >= row_index_start && + sel_index_start <= row_index_end)) + return TRUE; + return FALSE; +} + +static gboolean +table_interface_is_selected (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + gint n_rows, n_columns; + ECalendarItem *calitem; + gint index; + gint sel_index_start, sel_index_end; + + GDate start_date, end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return FALSE; + n_columns = table_interface_get_n_columns (table); + if (column < 0 || column >= n_columns) + return FALSE; + + index = table_interface_get_index_at (table, row, column); + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return FALSE; + + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date), + g_date_get_day (&start_date), + &sel_index_start); + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&end_date), + g_date_get_month (&end_date), + g_date_get_day (&end_date), &sel_index_end); + + if (sel_index_start <= index && sel_index_end >= index) + return TRUE; + return FALSE; +} + +static gboolean +table_interface_is_column_selected (AtkTable *table, + gint column) +{ + return FALSE; +} + +static gint +table_interface_get_selected_rows (AtkTable *table, + gint **rows_selected) +{ + *rows_selected = NULL; + return -1; +} + +static gint +table_interface_get_selected_columns (AtkTable *table, + gint **columns_selected) +{ + *columns_selected = NULL; + return -1; +} + +static gboolean +table_interface_add_row_selection (AtkTable *table, + gint row) +{ + return FALSE; +} + +static gboolean +table_interface_remove_row_selection (AtkTable *table, + gint row) +{ + return FALSE; +} + +static gboolean +table_interface_add_column_selection (AtkTable *table, + gint column) +{ + return FALSE; +} + +static gboolean +table_interface_remove_column_selection (AtkTable *table, + gint column) +{ + /* FIXME: NOT IMPLEMENTED */ + return FALSE; +} + +static AtkObject* +table_interface_get_row_header (AtkTable *table, + gint row) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static AtkObject* +table_interface_get_column_header (AtkTable *table, + gint in_col) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static AtkObject* +table_interface_get_caption (AtkTable *table) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static G_CONST_RETURN gchar* +table_interface_get_column_description (AtkTable *table, gint in_col) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + const gchar *description = NULL; + EaCellTable *cell_data; + gint n_columns; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + n_columns = table_interface_get_n_columns (table); + if (in_col < 0 || in_col >= n_columns) + return NULL; + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_column_label (cell_data, in_col); + if (!description) { + gchar buffer[128] = "column description"; + ea_calendar_item_get_column_label (ea_calitem, in_col, + buffer, sizeof (buffer)); + ea_cell_table_set_column_label (cell_data, in_col, buffer); + description = ea_cell_table_get_column_label (cell_data, + in_col); + } + return description; +} + +static G_CONST_RETURN gchar* +table_interface_get_row_description (AtkTable *table, gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + const gchar *description = NULL; + EaCellTable *cell_data; + gint n_rows; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return NULL; + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_row_label (cell_data, row); + if (!description) { + gchar buffer[128] = "row description"; + ea_calendar_item_get_row_label (ea_calitem, row, + buffer, sizeof (buffer)); + ea_cell_table_set_row_label (cell_data, row, buffer); + description = ea_cell_table_get_row_label (cell_data, + row); + } + return description; +} + +static AtkObject* +table_interface_get_summary (AtkTable *table) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +/* atkselection interface */ + +static void +atk_selection_interface_init (AtkSelectionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->add_selection = selection_interface_add_selection; + iface->clear_selection = selection_interface_clear_selection; + iface->ref_selection = selection_interface_ref_selection; + iface->get_selection_count = selection_interface_get_selection_count; + iface->is_child_selected = selection_interface_is_child_selected; +} + +static gboolean +selection_interface_add_selection (AtkSelection *selection, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint year, month, day; + GDate start_date, end_date; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_date_for_offset (calitem, index, + &year, &month, &day)) + return FALSE; + + /* FIXME: not support mulit-selection */ + g_date_set_dmy (&start_date, day, month + 1, year); + end_date = start_date; + e_calendar_item_set_selection (calitem, &start_date, &end_date); + return TRUE; +} + +static gboolean +selection_interface_clear_selection (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + e_calendar_item_set_selection (calitem, NULL, NULL); + + return TRUE; +} + +static AtkObject* +selection_interface_ref_selection (AtkSelection *selection, gint i) +{ + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint count, sel_offset; + GDate start_date, end_date; + + count = selection_interface_get_selection_count (selection); + if (i < 0 || i >= count) + return NULL; + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem)); + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return NULL; + if (!e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date) - 1, + g_date_get_day (&start_date), + &sel_offset)) + return NULL; + + return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i); +} + +static gint +selection_interface_get_selection_count (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + GDate start_date, end_date; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return 0; + + calitem = E_CALENDAR_ITEM (g_obj); + if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return g_date_days_between (&start_date, &end_date) + 1; + else + return 0; +} + +static gboolean +selection_interface_is_child_selected (AtkSelection *selection, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint row, column, n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection)); + if (index < 0 || index >= n_children) + return FALSE; + + row = index / EA_CALENDAR_COLUMN_NUM; + column = index % EA_CALENDAR_COLUMN_NUM; + + return table_interface_is_selected (ATK_TABLE (selection), row, column); +} + +/* callbacks */ + +static void +selection_preview_change_cb (ECalendarItem *calitem) +{ + AtkObject *atk_obj; + AtkObject *item_cell; + + g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); + + /* only deal with the first selected child, for now */ + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), + 0); + + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); + + g_signal_emit_by_name (atk_obj, + "active-descendant-changed", + item_cell); + g_signal_emit_by_name (atk_obj, "selection_changed"); +} + +static void +date_range_changed_cb (ECalendarItem *calitem) +{ + AtkObject *atk_obj; + AtkObject *item_cell; + + g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); + + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), + 0); + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); + + g_signal_emit_by_name (atk_obj, "model_changed"); +} + +/* helpers */ + +static EaCellTable * +ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCellTable *cell_data; + + g_return_val_if_fail (ea_calitem, NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + cell_data = g_object_get_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table"); + + if (!cell_data) { + gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT(ea_calitem)); + cell_data = ea_cell_table_create (n_cells/EA_CALENDAR_COLUMN_NUM, + EA_CALENDAR_COLUMN_NUM, + FALSE); + g_object_set_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table", cell_data); + } + return cell_data; +} + +static void +ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem) +{ + EaCellTable *cell_data; + + g_return_if_fail (ea_calitem); + + cell_data = g_object_get_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table"); + if (cell_data) { + g_object_set_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table", NULL); + ea_cell_table_destroy (cell_data); + } +} + +static gboolean +ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, gint row, + gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint index, week_num; + gint year, month, day; + + g_return_val_if_fail (ea_calitem, FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + + index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0); + if (!e_calendar_item_get_date_for_offset (calitem, index, + &year, &month, &day)) + return FALSE; + + week_num = e_calendar_item_get_week_number (calitem, + day, month, year); + + g_snprintf (buffer, buffer_size, "week number : %d", week_num); + return TRUE; +} + +static gboolean +ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, gint column, + gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + const gchar *abbr_name; + + g_return_val_if_fail (ea_calitem, FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + /* Columns are 0 = Monday ... 6 = Sunday */ + calitem = E_CALENDAR_ITEM (g_obj); + abbr_name = e_get_weekday_name (column + 1, TRUE); + g_strlcpy (buffer, abbr_name, buffer_size); + + return TRUE; +} + +/* the coordinate the e-calendar canvas coord */ +gboolean +e_calendar_item_get_day_extents (ECalendarItem *calitem, + gint year, gint month, gint date, + gint *x, gint *y, + gint *width, gint *height) +{ + GnomeCanvasItem *item; + GtkWidget *widget; + GtkStyle *style; + PangoFontDescription *font_desc; + PangoContext *pango_context; + PangoFontMetrics *font_metrics; + gint char_height, xthickness, ythickness, text_y; + gint new_year, new_month, num_months, months_offset; + gint month_x, month_y, month_cell_x, month_cell_y; + gint month_row, month_col; + gint day_row, day_col; + gint days_from_week_start; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + item = GNOME_CANVAS_ITEM (calitem); + widget = GTK_WIDGET (item->canvas); + style = widget->style; + + /* Set up Pango prerequisites */ + font_desc = calitem->font_desc; + if (!font_desc) + font_desc = style->font_desc; + pango_context = gtk_widget_get_pango_context (widget); + font_metrics = pango_context_get_metrics (pango_context, font_desc, + pango_context_get_language (pango_context)); + + char_height = + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); + + xthickness = style->xthickness; + ythickness = style->ythickness; + + new_year = year; + new_month = month; + e_calendar_item_normalize_date (calitem, &new_year, &new_month); + num_months = calitem->rows * calitem->cols; + months_offset = (new_year - calitem->year) * 12 + + new_month - calitem->month; + + if (months_offset > num_months || months_offset < 0) + return FALSE; + + month_row = months_offset / calitem->cols; + month_col = months_offset % calitem->cols; + + month_x = item->x1 + xthickness + calitem->x_offset + + month_col * calitem->month_width; + month_y = item->y1 + ythickness + month_row * calitem->month_height; + + month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; + text_y = month_y + ythickness * 2 + + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME + + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; + + month_cell_y = text_y + char_height + + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 + + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; + + days_from_week_start = + e_calendar_item_get_n_days_from_week_start (calitem, new_year, + new_month); + day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM; + day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM; + + *x = month_cell_x + day_col * calitem->cell_width; + *y = month_cell_y + day_row * calitem->cell_height; + *width = calitem->cell_width; + *height = calitem->cell_height; + + return TRUE; +} + +/* month is from 0 to 11 */ +gboolean +e_calendar_item_get_date_for_offset (ECalendarItem *calitem, gint day_offset, + gint *year, gint *month, gint *day) +{ + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return FALSE; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + + g_date_add_days (start_date, day_offset); + + *year = g_date_get_year (start_date); + *month = g_date_get_month (start_date) - 1; + *day = g_date_get_day (start_date); + + return TRUE; +} + +/* the arg month is from 0 to 11 */ +static gboolean +e_calendar_item_get_offset_for_date (ECalendarItem *calitem, + gint year, gint month, gint day, + gint *offset) +{ + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date, *end_date; + + *offset = 0; + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return FALSE; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + end_date = g_date_new_dmy (day, month + 1, year); + + *offset = g_date_days_between (start_date, end_date); + g_free (start_date); + g_free (end_date); + + return TRUE; +} + +gint +e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, + gint year, gint month) +{ + struct tm tmp_tm; + gint start_weekday, days_from_week_start; + + memset (&tmp_tm, 0, sizeof (tmp_tm)); + tmp_tm.tm_year = year - 1900; + tmp_tm.tm_mon = month; + tmp_tm.tm_mday = 1; + tmp_tm.tm_isdst = -1; + mktime (&tmp_tm); + start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */ + days_from_week_start = (start_weekday + 7 - calitem->week_start_day) + % 7; + return days_from_week_start; +} + +static void +ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, AtkObject *item_cell) +{ + AtkStateSet *state_set, *old_state_set; + AtkObject *old_cell; + + old_cell = (AtkObject *)g_object_get_data (G_OBJECT(ea_calitem), "gail-focus-object"); + if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) { + old_state_set = atk_object_ref_state_set (old_cell); + atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED); + g_object_unref (old_state_set); + } + if (old_cell) + g_object_unref (old_cell); + + state_set = atk_object_ref_state_set (item_cell); + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + g_object_set_data (G_OBJECT(ea_calitem), "gail-focus-object", item_cell); + g_object_unref (state_set); +} diff --git a/widgets/misc/a11y/ea-calendar-item.h b/widgets/misc/a11y/ea-calendar-item.h new file mode 100644 index 0000000000..87b825b479 --- /dev/null +++ b/widgets/misc/a11y/ea-calendar-item.h @@ -0,0 +1,72 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CALENDAR_ITEM_H__ +#define __EA_CALENDAR_ITEM_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ()) +#define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem)) +#define EA_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) +#define EA_IS_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_ITEM)) +#define EA_IS_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_ITEM)) +#define EA_CALENDAR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) + +typedef struct _EaCalendarItem EaCalendarItem; +typedef struct _EaCalendarItemClass EaCalendarItemClass; + +struct _EaCalendarItem +{ + AtkGObjectAccessible parent; +}; + +GType ea_calendar_item_get_type (void); + +struct _EaCalendarItemClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject *ea_calendar_item_new (GObject *obj); +gboolean e_calendar_item_get_day_extents (ECalendarItem *calitem, + gint year, gint month, gint date, + gint *x, gint *y, + gint *width, gint *height); +gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem, + gint day_offset, + gint *year, gint *month, + gint *day); +gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, + gint year, gint month); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/a11y/ea-widgets.c b/widgets/misc/a11y/ea-widgets.c new file mode 100644 index 0000000000..239299da0b --- /dev/null +++ b/widgets/misc/a11y/ea-widgets.c @@ -0,0 +1,32 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "a11y/ea-factory.h" +#include "ea-calendar-item.h" +#include "ea-widgets.h" + +EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new) + +void e_calendar_item_a11y_init (void) +{ + EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item); +} diff --git a/widgets/misc/a11y/ea-widgets.h b/widgets/misc/a11y/ea-widgets.h new file mode 100644 index 0000000000..d19c908293 --- /dev/null +++ b/widgets/misc/a11y/ea-widgets.h @@ -0,0 +1,32 @@ +/* + * + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* Evolution Accessibility +*/ + +#ifndef _EA_WIDGETS_H__ +#define _EA_WIDGETS_H__ + +void e_calendar_item_a11y_init (void); + +#endif /* _EA_WIDGETS_H__ */ diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 32e74dd535..d5f5efd462 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -26,7 +26,7 @@ #endif #include "e-calendar-item.h" -#include "ea-widgets.h" +#include "a11y/ea-widgets.h" #include #include diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c deleted file mode 100644 index 97947980d9..0000000000 --- a/widgets/misc/e-cell-date-edit.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-cell-date-edit.h" - -#include -#include -#include - -#include -#include - -#include
-#include
- -#include - -#include - -/* This depends on ECalendar which is why I didn't put it in gal. */ -#include "e-calendar.h" - -static void e_cell_date_edit_destroy (GtkObject *object); -static void e_cell_date_edit_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void e_cell_date_edit_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); - -static gint e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event, - int row, - int view_col); -static void e_cell_date_edit_set_popup_values (ECellDateEdit *ecde); -static void e_cell_date_edit_select_matching_time(ECellDateEdit *ecde, - char *time); -static void e_cell_date_edit_show_popup (ECellDateEdit *ecde, - int row, - int view_col); -static void e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - int row, - int view_col, - gint *x, - gint *y, - gint *height, - gint *width); - -static void e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde); - -static int e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde); -static int e_cell_date_edit_button_press (GtkWidget *popup_window, - GdkEventButton *event, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde); -static void e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde); -static void e_cell_date_edit_update_cell (ECellDateEdit *ecde, - char *text); -static void e_cell_date_edit_on_time_selected (GtkTreeSelection *selection, ECellDateEdit *ecde); -static void e_cell_date_edit_hide_popup (ECellDateEdit *ecde); - - -/* Our arguments. */ -enum { - PROP_0, - PROP_SHOW_TIME, - PROP_SHOW_NOW_BUTTON, - PROP_SHOW_TODAY_BUTTON, - PROP_ALLOW_NO_DATE_SET, - PROP_USE_24_HOUR_FORMAT, - PROP_LOWER_HOUR, - PROP_UPPER_HOUR -}; - -G_DEFINE_TYPE (ECellDateEdit, e_cell_date_edit, E_CELL_POPUP_TYPE) - - -static void -e_cell_date_edit_class_init (ECellDateEditClass *class) -{ - GObjectClass *object_class; - GtkObjectClass *gtk_object_class; - ECellPopupClass *ecpc; - - object_class = G_OBJECT_CLASS (class); - object_class->get_property = e_cell_date_edit_get_property; - object_class->set_property = e_cell_date_edit_set_property; - - gtk_object_class = GTK_OBJECT_CLASS (class); - gtk_object_class->destroy = e_cell_date_edit_destroy; - - ecpc = E_CELL_POPUP_CLASS (class); - ecpc->popup = e_cell_date_edit_do_popup; - - g_object_class_install_property ( - object_class, - PROP_SHOW_TIME, - g_param_spec_boolean ( - "show_time", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_NOW_BUTTON, - g_param_spec_boolean ( - "show_now_button", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SHOW_TODAY_BUTTON, - g_param_spec_boolean ( - "show_today_button", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_ALLOW_NO_DATE_SET, - g_param_spec_boolean ( - "allow_no_date_set", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_USE_24_HOUR_FORMAT, - g_param_spec_boolean ( - "use_24_hour_format", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_LOWER_HOUR, - g_param_spec_int ( - "lower_hour", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_UPPER_HOUR, - g_param_spec_int ( - "upper_hour", - NULL, - NULL, - G_MININT, - G_MAXINT, - 24, - G_PARAM_READWRITE)); -} - - -static void -e_cell_date_edit_init (ECellDateEdit *ecde) -{ - GtkWidget *frame, *vbox, *hbox, *vbox2; - GtkWidget *scrolled_window, *bbox, *tree_view; - GtkWidget *now_button, *today_button, *none_button, *ok_button; - GtkListStore *store; - - ecde->lower_hour = 0; - ecde->upper_hour = 24; - ecde->use_24_hour_format = TRUE; - ecde->need_time_list_rebuild = TRUE; - ecde->freeze_count = 0; - ecde->time_callback = NULL; - ecde->time_callback_data = NULL; - ecde->time_callback_destroy = NULL; - - /* We create one popup window for the ECell, since there will only - ever be one popup in use at a time. */ - ecde->popup_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_type_hint (GTK_WINDOW (ecde->popup_window), - GDK_WINDOW_TYPE_HINT_COMBO); - gtk_window_set_resizable (GTK_WINDOW (ecde->popup_window), TRUE); - - frame = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (ecde->popup_window), frame); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_widget_show (vbox); - - hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - ecde->calendar = e_calendar_new (); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem), - "move_selection_when_moving", FALSE, - NULL); - gtk_box_pack_start (GTK_BOX (hbox), ecde->calendar, TRUE, TRUE, 0); - gtk_widget_show (ecde->calendar); - - vbox2 = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); - gtk_widget_show (vbox2); - - ecde->time_entry = gtk_entry_new (); - gtk_widget_set_size_request (ecde->time_entry, 50, -1); - gtk_box_pack_start (GTK_BOX (vbox2), ecde->time_entry, - FALSE, FALSE, 0); - gtk_widget_show (ecde->time_entry); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - gtk_widget_show (scrolled_window); - - store = gtk_list_store_new (1, G_TYPE_STRING); - tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - g_object_unref (store); - - gtk_tree_view_append_column ( - GTK_TREE_VIEW (tree_view), - gtk_tree_view_column_new_with_attributes ("Text", gtk_cell_renderer_text_new (), "text", 0, NULL)); - - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); - - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), tree_view); - gtk_container_set_focus_vadjustment (GTK_CONTAINER (tree_view), - gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window))); - gtk_container_set_focus_hadjustment (GTK_CONTAINER (tree_view), - gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window))); - gtk_widget_show (tree_view); - ecde->time_tree_view = tree_view; - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), "changed", - G_CALLBACK (e_cell_date_edit_on_time_selected), - ecde); - - bbox = gtk_hbutton_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (bbox), 4); - gtk_box_set_spacing (GTK_BOX (bbox), 2); - gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - now_button = gtk_button_new_with_label (_("Now")); - gtk_container_add (GTK_CONTAINER (bbox), now_button); - gtk_widget_show (now_button); - g_signal_connect((now_button), "clicked", - G_CALLBACK (e_cell_date_edit_on_now_clicked), - ecde); - ecde->now_button = now_button; - - today_button = gtk_button_new_with_label (_("Today")); - gtk_container_add (GTK_CONTAINER (bbox), today_button); - gtk_widget_show (today_button); - g_signal_connect((today_button), "clicked", - G_CALLBACK (e_cell_date_edit_on_today_clicked), - ecde); - ecde->today_button = today_button; - - none_button = gtk_button_new_with_label (_("None")); - gtk_container_add (GTK_CONTAINER (bbox), none_button); - gtk_widget_show (none_button); - g_signal_connect((none_button), "clicked", - G_CALLBACK (e_cell_date_edit_on_none_clicked), - ecde); - ecde->none_button = none_button; - - ok_button = gtk_button_new_with_label (_("OK")); - gtk_container_add (GTK_CONTAINER (bbox), ok_button); - gtk_widget_show (ok_button); - g_signal_connect((ok_button), "clicked", - G_CALLBACK (e_cell_date_edit_on_ok_clicked), - ecde); - - - g_signal_connect((ecde->popup_window), - "key_press_event", - G_CALLBACK (e_cell_date_edit_key_press), - ecde); - g_signal_connect((ecde->popup_window), - "button_press_event", - G_CALLBACK (e_cell_date_edit_button_press), - ecde); -} - - -/** - * e_cell_date_edit_new: - * - * Creates a new ECellDateEdit renderer. - * - * Returns: an ECellDateEdit object. - */ -ECell * -e_cell_date_edit_new (void) -{ - return g_object_new (e_cell_date_edit_get_type (), NULL); -} - - -/* - * GtkObject::destroy method - */ -static void -e_cell_date_edit_destroy (GtkObject *object) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (object); - - e_cell_date_edit_set_get_time_callback (ecde, NULL, NULL, NULL); - - gtk_widget_destroy (ecde->popup_window); - ecde->popup_window = NULL; - - GTK_OBJECT_CLASS (e_cell_date_edit_parent_class)->destroy (object); -} - - -static void -e_cell_date_edit_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ECellDateEdit *ecde; - - ecde = E_CELL_DATE_EDIT (object); - - switch (property_id) { - case PROP_SHOW_TIME: - g_value_set_boolean (value, GTK_WIDGET_VISIBLE (ecde->time_entry)); - return; - case PROP_SHOW_NOW_BUTTON: - g_value_set_boolean (value, GTK_WIDGET_VISIBLE (ecde->now_button)); - return; - case PROP_SHOW_TODAY_BUTTON: - g_value_set_boolean (value, GTK_WIDGET_VISIBLE (ecde->today_button)); - return; - case PROP_ALLOW_NO_DATE_SET: - g_value_set_boolean (value, GTK_WIDGET_VISIBLE (ecde->none_button)); - return; - case PROP_USE_24_HOUR_FORMAT: - g_value_set_boolean (value, ecde->use_24_hour_format); - return; - case PROP_LOWER_HOUR: - g_value_set_int (value, ecde->lower_hour); - return; - case PROP_UPPER_HOUR: - g_value_set_int (value, ecde->upper_hour); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - - -static void -e_cell_date_edit_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ECellDateEdit *ecde; - gint ivalue; - gboolean bvalue; - - ecde = E_CELL_DATE_EDIT (object); - - switch (property_id) { - case PROP_SHOW_TIME: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->time_entry); - gtk_widget_show (ecde->time_tree_view); - } else { - gtk_widget_hide (ecde->time_entry); - gtk_widget_hide (ecde->time_tree_view); - } - return; - case PROP_SHOW_NOW_BUTTON: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->now_button); - } else { - gtk_widget_hide (ecde->now_button); - } - return; - case PROP_SHOW_TODAY_BUTTON: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->today_button); - } else { - gtk_widget_hide (ecde->today_button); - } - return; - case PROP_ALLOW_NO_DATE_SET: - if (g_value_get_boolean (value)) { - gtk_widget_show (ecde->none_button); - } else { - /* FIXME: What if we have no date set now. */ - gtk_widget_hide (ecde->none_button); - } - return; - case PROP_USE_24_HOUR_FORMAT: - bvalue = g_value_get_boolean (value); - if (ecde->use_24_hour_format != bvalue) { - ecde->use_24_hour_format = bvalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - case PROP_LOWER_HOUR: - ivalue = g_value_get_int (value); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->lower_hour != ivalue) { - ecde->lower_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - case PROP_UPPER_HOUR: - ivalue = g_value_get_int (value); - ivalue = CLAMP (ivalue, 0, 24); - if (ecde->upper_hour != ivalue) { - ecde->upper_hour = ivalue; - ecde->need_time_list_rebuild = TRUE; - } - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - - -static gint -e_cell_date_edit_do_popup (ECellPopup *ecp, - GdkEvent *event, - int row, - int view_col) -{ - ECellDateEdit *ecde = E_CELL_DATE_EDIT (ecp); - - e_cell_date_edit_show_popup (ecde, row, view_col); - e_cell_date_edit_set_popup_values (ecde); - - gtk_grab_add (ecde->popup_window); - - /* Set the focus to the first widget. */ - gtk_widget_grab_focus (ecde->time_entry); - gdk_window_focus (ecde->popup_window->window, GDK_CURRENT_TIME); - - return TRUE; -} - - -static void -e_cell_date_edit_set_popup_values (ECellDateEdit *ecde) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ECellView *ecv = (ECellView*) ecp->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - ETableCol *ecol; - char *cell_text; - ETimeParseStatus status; - struct tm date_tm; - GDate date; - ECalendarItem *calitem; - char buffer[64]; - gboolean is_date = TRUE; - - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - cell_text = e_cell_text_get_text (ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* Try to parse just a date first. If the value is only a date, we - use a DATE value. */ - status = e_time_parse_date (cell_text, &date_tm); - if (status == E_TIME_PARSE_INVALID) { - is_date = FALSE; - status = e_time_parse_date_and_time (cell_text, &date_tm); - } - - /* If there is no date and time set, or the date is invalid, we clear - the selections, else we select the appropriate date & time. */ - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - if (status == E_TIME_PARSE_NONE || status == E_TIME_PARSE_INVALID) { - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), ""); - e_calendar_item_set_selection (calitem, NULL, NULL); - gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (ecde->time_tree_view))); - } else { - if (is_date) { - buffer[0] = '\0'; - } else { - e_time_format_time (&date_tm, ecde->use_24_hour_format, - FALSE, buffer, sizeof (buffer)); - } - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), buffer); - - g_date_clear (&date, 1); - g_date_set_dmy (&date, date_tm.tm_mday, date_tm.tm_mon + 1, - date_tm.tm_year + 1900); - e_calendar_item_set_selection (calitem, &date, &date); - - if (is_date) { - gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (ecde->time_tree_view))); - } else { - e_cell_date_edit_select_matching_time (ecde, buffer); - } - } - - e_cell_text_free_text (ecell_text, cell_text); -} - - -static void -e_cell_date_edit_select_matching_time (ECellDateEdit *ecde, - char *time) -{ - gboolean found = FALSE; - gboolean valid; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeModel *model; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (ecde->time_tree_view)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ecde->time_tree_view)); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid && !found; - valid = gtk_tree_model_iter_next (model, &iter)) { - char *str = NULL; - - gtk_tree_model_get (model, &iter, 0, &str, -1); - - if (g_str_equal (str, time)) { - GtkTreePath *path = gtk_tree_model_get_path (model, &iter); - - gtk_tree_view_set_cursor (GTK_TREE_VIEW (ecde->time_tree_view), path, NULL, FALSE); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (ecde->time_tree_view), path, NULL, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - found = TRUE; - } - - g_free (str); - } - - if (!found) { - gtk_tree_selection_unselect_all (selection); - gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (ecde->time_tree_view), 0, 0); - } -} - - -static void -e_cell_date_edit_show_popup (ECellDateEdit *ecde, - int row, - int view_col) -{ - gint x, y, width, height; - - if (ecde->need_time_list_rebuild) - e_cell_date_edit_rebuild_time_list (ecde); - - /* This code is practically copied from GtkCombo. */ - - e_cell_date_edit_get_popup_pos (ecde, row, view_col, &x, &y, &height, &width); - - gtk_window_move (GTK_WINDOW (ecde->popup_window), x, y); - gtk_widget_set_size_request (ecde->popup_window, width, height); - gtk_widget_realize (ecde->popup_window); - gdk_window_resize (ecde->popup_window->window, width, height); - gtk_widget_show (ecde->popup_window); - - e_cell_popup_set_shown (E_CELL_POPUP (ecde), TRUE); -} - - -/* Calculates the size and position of the popup window (like GtkCombo). */ -static void -e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde, - int row, - int view_col, - gint *x, - gint *y, - gint *height, - gint *width) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view); - GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas); - GtkRequisition popup_requisition; - gint avail_height, screen_width, column_width, row_height; - double x1, y1, wx, wy; - - gdk_window_get_origin (canvas->window, x, y); - - x1 = e_table_header_col_diff (eti->header, 0, view_col + 1); - y1 = e_table_item_row_diff (eti, 0, row + 1); - column_width = e_table_header_col_diff (eti->header, view_col, - view_col + 1); - row_height = e_table_item_row_diff (eti, row, - row + 1); - gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1); - - gnome_canvas_world_to_window (GNOME_CANVAS (canvas), - x1, - y1, - &wx, - &wy); - - x1 = wx; - y1 = wy; - - *x += x1; - /* The ETable positions don't include the grid lines, I think, so we - add 1. */ - *y += y1 + 1 - - (int)((GnomeCanvas *)canvas)->layout.vadjustment->value - + ((GnomeCanvas *)canvas)->zoom_yofs; - - avail_height = gdk_screen_height () - *y; - - /* We'll use the entire screen width if needed, but we save space for - the vertical scrollbar in case we need to show that. */ - screen_width = gdk_screen_width (); - - gtk_widget_size_request (ecde->popup_window, &popup_requisition); - - /* Calculate the desired width. */ - *width = popup_requisition.width; - - /* Use at least the same width as the column. */ - if (*width < column_width) - *width = column_width; - - /* Check if it fits in the available height. */ - if (popup_requisition.height > avail_height) { - /* It doesn't fit, so we see if we have the minimum space - needed. */ - if (*y - row_height > avail_height) { - /* We don't, so we show the popup above the cell - instead of below it. */ - avail_height = *y - row_height; - *y -= (popup_requisition.height + row_height); - if (*y < 0) - *y = 0; - } - } - - /* We try to line it up with the right edge of the column, but we don't - want it to go off the edges of the screen. */ - if (*x > screen_width) - *x = screen_width; - *x -= *width; - if (*x < 0) - *x = 0; - - *height = popup_requisition.height; -} - - -/* This handles key press events in the popup window. If the Escape key is - pressed we hide the popup, and do not change the cell contents. */ -static int -e_cell_date_edit_key_press (GtkWidget *popup_window, - GdkEventKey *event, - ECellDateEdit *ecde) -{ - /* If the Escape key is pressed we hide the popup. */ - if (event->keyval != GDK_Escape) - return FALSE; - - e_cell_date_edit_hide_popup (ecde); - - return TRUE; -} - - -/* This handles button press events in the popup window. If the button is - pressed outside the popup, we hide it and do not change the cell contents. -*/ -static int -e_cell_date_edit_button_press (GtkWidget *popup_window, - GdkEventButton *event, - ECellDateEdit *ecde) -{ - GtkWidget *event_widget; - - event_widget = gtk_get_event_widget ((GdkEvent*) event); - if (gtk_widget_get_toplevel (event_widget) != popup_window) { - e_cell_date_edit_hide_popup (ecde); - } - - return TRUE; -} - - -/* Clears the time list and rebuilds it using the lower_hour, upper_hour - and use_24_hour_format settings. */ -static void -e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde) -{ - GtkListStore *store; - char buffer[40]; - struct tm tmp_tm; - gint hour, min; - - store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (ecde->time_tree_view))); - gtk_list_store_clear (store); - - /* Fill the struct tm with some sane values. */ - tmp_tm.tm_year = 2000; - tmp_tm.tm_mon = 0; - tmp_tm.tm_mday = 1; - tmp_tm.tm_sec = 0; - tmp_tm.tm_isdst = 0; - - for (hour = ecde->lower_hour; hour <= ecde->upper_hour; hour++) { - /* We don't want to display midnight at the end, since that is - really in the next day. */ - if (hour == 24) - break; - - /* We want to finish on upper_hour, with min == 0. */ - for (min = 0; - min == 0 || (min < 60 && hour != ecde->upper_hour); - min += 30) { - GtkTreeIter iter; - - tmp_tm.tm_hour = hour; - tmp_tm.tm_min = min; - e_time_format_time (&tmp_tm, ecde->use_24_hour_format, - FALSE, buffer, sizeof (buffer)); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, buffer, -1); - } - } - - ecde->need_time_list_rebuild = FALSE; -} - - -static void -e_cell_date_edit_on_ok_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - ECalendarItem *calitem; - GDate start_date, end_date; - gboolean day_selected; - struct tm date_tm; - char buffer[64]; - const char *text; - ETimeParseStatus status; - gboolean is_date = FALSE; - - calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem); - day_selected = e_calendar_item_get_selection (calitem, &start_date, - &end_date); - - text = gtk_entry_get_text (GTK_ENTRY (ecde->time_entry)); - status = e_time_parse_time (text, &date_tm); - if (status == E_TIME_PARSE_INVALID) { - e_cell_date_edit_show_time_invalid_warning (ecde); - return; - } else if (status == E_TIME_PARSE_NONE) { - is_date = TRUE; - } - - if (day_selected) { - date_tm.tm_year = g_date_get_year (&start_date) - 1900; - date_tm.tm_mon = g_date_get_month (&start_date) - 1; - date_tm.tm_mday = g_date_get_day (&start_date); - /* We need to call this to set the weekday. */ - mktime (&date_tm); - e_time_format_date_and_time (&date_tm, - ecde->use_24_hour_format, - !is_date, FALSE, - buffer, sizeof (buffer)); - } else { - buffer[0] = '\0'; - } - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde) -{ - GtkWidget *dialog; - struct tm date_tm; - char buffer[64]; - - /* Create a useful error message showing the correct format. */ - date_tm.tm_year = 100; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = 1; - date_tm.tm_min = 30; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - e_time_format_time (&date_tm, ecde->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - /* FIXME: Fix transient settings - I'm not sure it works with popup - windows. Maybe we need to use a normal window without decorations.*/ - dialog = gtk_message_dialog_new ( - GTK_WINDOW (ecde->popup_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("The time must be in the format: %s"), - buffer); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - - -static void -e_cell_date_edit_on_now_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm tmp_tm; - time_t t; - char buffer[64]; - - if (ecde->time_callback) { - tmp_tm = (*ecde->time_callback) (ecde, ecde->time_callback_data); - } else { - t = time (NULL); - tmp_tm = *localtime (&t); - } - e_time_format_date_and_time (&tmp_tm, - ecde->use_24_hour_format, - TRUE, FALSE, - buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_on_none_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - e_cell_date_edit_update_cell (ecde, ""); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_on_today_clicked (GtkWidget *button, - ECellDateEdit *ecde) -{ - struct tm tmp_tm; - time_t t; - char buffer[64]; - - if (ecde->time_callback) { - tmp_tm = (*ecde->time_callback) (ecde, ecde->time_callback_data); - } else { - t = time (NULL); - tmp_tm = *localtime (&t); - } - - tmp_tm.tm_hour = 0; - tmp_tm.tm_min = 0; - tmp_tm.tm_sec = 0; - e_time_format_date_and_time (&tmp_tm, - ecde->use_24_hour_format, - FALSE, FALSE, - buffer, sizeof (buffer)); - - e_cell_date_edit_update_cell (ecde, buffer); - e_cell_date_edit_hide_popup (ecde); -} - - -static void -e_cell_date_edit_update_cell (ECellDateEdit *ecde, - char *text) -{ - ECellPopup *ecp = E_CELL_POPUP (ecde); - ECellText *ecell_text = E_CELL_TEXT (ecp->child); - ECellView *ecv = (ECellView*) ecp->popup_cell_view; - ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view); - ETableCol *ecol; - gchar *old_text; - - /* Compare the new text with the existing cell contents. */ - ecol = e_table_header_get_column (eti->header, ecp->popup_view_col); - - old_text = e_cell_text_get_text (ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row); - - /* If they are different, update the cell contents. */ - if (strcmp (old_text, text)) { - e_cell_text_set_value (ecell_text, ecv->e_table_model, - ecol->col_idx, ecp->popup_row, text); - e_cell_leave_edit (ecv, ecp->popup_view_col, ecol->col_idx, ecp->popup_row, NULL); - } - - e_cell_text_free_text (ecell_text, old_text); -} - - -static void -e_cell_date_edit_on_time_selected (GtkTreeSelection *selection, ECellDateEdit *ecde) -{ - gchar *list_item_text = NULL; - GtkTreeIter iter; - GtkTreeModel *model; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return; - - gtk_tree_model_get (model, &iter, 0, &list_item_text, -1); - - g_return_if_fail (list_item_text != NULL); - - gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), list_item_text); - - g_free (list_item_text); -} - - -static void -e_cell_date_edit_hide_popup (ECellDateEdit *ecde) -{ - gtk_grab_remove (ecde->popup_window); - gtk_widget_hide (ecde->popup_window); - e_cell_popup_set_shown (E_CELL_POPUP (ecde), FALSE); -} - - -/* These freeze and thaw the rebuilding of the time list. They are useful when - setting several properties which result in rebuilds of the list, e.g. the - lower_hour, upper_hour and use_24_hour_format properties. */ -void -e_cell_date_edit_freeze (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - ecde->freeze_count++; -} - - -void -e_cell_date_edit_thaw (ECellDateEdit *ecde) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - if (ecde->freeze_count > 0) { - ecde->freeze_count--; - - if (ecde->freeze_count == 0) - e_cell_date_edit_rebuild_time_list (ecde); - } -} - - -/* Sets a callback to use to get the current time. This is useful if the - application needs to use its own timezone data rather than rely on the - Unix timezone. */ -void -e_cell_date_edit_set_get_time_callback (ECellDateEdit *ecde, - ECellDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - if (ecde->time_callback_data && ecde->time_callback_destroy) - (*ecde->time_callback_destroy) (ecde->time_callback_data); - - ecde->time_callback = cb; - ecde->time_callback_data = data; - ecde->time_callback_destroy = destroy; -} diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/misc/e-cell-date-edit.h deleted file mode 100644 index 30dee535e8..0000000000 --- a/widgets/misc/e-cell-date-edit.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellDateEdit - a subclass of ECellPopup used to show a date with a popup - * window to edit it. - */ - -#ifndef _E_CELL_DATE_EDIT_H_ -#define _E_CELL_DATE_EDIT_H_ - -#include -#include
- -#define E_CELL_DATE_EDIT_TYPE (e_cell_date_edit_get_type ()) -#define E_CELL_DATE_EDIT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_CELL_DATE_EDIT_TYPE, ECellDateEdit)) -#define E_CELL_DATE_EDIT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_CELL_DATE_EDIT_TYPE, ECellDateEditClass)) -#define E_IS_CELL_DATE_EDIT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_CELL_DATE_EDIT_TYPE)) -#define E_IS_CELL_DATE_EDIT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_CELL_DATE_EDIT_TYPE)) - - -typedef struct _ECellDateEdit ECellDateEdit; -typedef struct _ECellDateEditClass ECellDateEditClass; - -/* The type of the callback function optionally used to get the current time. - */ -typedef struct tm (*ECellDateEditGetTimeCallback) (ECellDateEdit *ecde, - gpointer data); - -struct _ECellDateEdit { - ECellPopup parent; - - GtkWidget *popup_window; - GtkWidget *calendar; - GtkWidget *time_entry; - GtkWidget *time_tree_view; - - GtkWidget *now_button; - GtkWidget *today_button; - GtkWidget *none_button; - - /* This is the range of hours we show in the time list. */ - gint lower_hour; - gint upper_hour; - - /* TRUE if we use 24-hour format for the time list and entry. */ - gboolean use_24_hour_format; - - /* This is TRUE if we need to rebuild the list of times. */ - gboolean need_time_list_rebuild; - - /* The freeze count for rebuilding the time list. We only rebuild when - this is 0. */ - gint freeze_count; - - ECellDateEditGetTimeCallback time_callback; - gpointer time_callback_data; - GDestroyNotify time_callback_destroy; -}; - -struct _ECellDateEditClass { - ECellPopupClass parent_class; -}; - - -GType e_cell_date_edit_get_type (void); -ECell *e_cell_date_edit_new (void); - - -/* These freeze and thaw the rebuilding of the time list. They are useful when - setting several properties which result in rebuilds of the list, e.g. the - lower_hour, upper_hour and use_24_hour_format properties. */ -void e_cell_date_edit_freeze (ECellDateEdit *ecde); -void e_cell_date_edit_thaw (ECellDateEdit *ecde); - - -/* Sets a callback to use to get the current time. This is useful if the - application needs to use its own timezone data rather than rely on the - Unix timezone. */ -void e_cell_date_edit_set_get_time_callback(ECellDateEdit *ecde, - ECellDateEditGetTimeCallback cb, - gpointer data, - GDestroyNotify destroy); - - -#endif /* _E_CELL_DATE_EDIT_H_ */ diff --git a/widgets/misc/e-cell-percent.c b/widgets/misc/e-cell-percent.c deleted file mode 100644 index 94e33489e5..0000000000 --- a/widgets/misc/e-cell-percent.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPercent - a subclass of ECellText used to show an integer percentage - * in an ETable. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include -#include -#include - -#include "e-cell-percent.h" - -G_DEFINE_TYPE (ECellPercent, e_cell_percent, E_CELL_TEXT_TYPE) - - -static char * -ecp_get_text (ECellText *cell, ETableModel *model, int col, int row) -{ - int percent; - static char buffer[8]; - - percent = GPOINTER_TO_INT (e_table_model_value_at (model, col, row)); - - /* A -ve value means the property is not set. */ - if (percent < 0) { - buffer[0] = '\0'; - } else { - g_snprintf (buffer, sizeof (buffer), "%i%%", percent); - } - - return buffer; -} - -static void -ecp_free_text(ECellText *cell, char *text) -{ - /* Do Nothing. */ -} - -/* FIXME: We need to set the "transient_for" property for the dialog. */ -static void -show_percent_warning (void) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new ( - NULL, 0, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "%s", _("The percent value must be between 0 and 100, inclusive")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - -static void -ecp_set_value (ECellText *cell, ETableModel *model, int col, int row, - const char *text) -{ - int matched, percent; - gboolean empty = TRUE; - const char *p; - - if (text) { - p = text; - while (*p) { - if (!isspace ((unsigned char) *p)) { - empty = FALSE; - break; - } - p++; - } - } - - if (empty) { - percent = -1; - } else { - matched = sscanf (text, "%i", &percent); - - if (matched != 1 || percent < 0 || percent > 100) { - show_percent_warning (); - return; - } - } - - e_table_model_set_value_at (model, col, row, - GINT_TO_POINTER (percent)); -} - -static void -e_cell_percent_class_init (ECellPercentClass *ecpc) -{ - ECellTextClass *ectc = (ECellTextClass *) ecpc; - - ectc->get_text = ecp_get_text; - ectc->free_text = ecp_free_text; - ectc->set_value = ecp_set_value; -} - -static void -e_cell_percent_init (ECellPercent *ecp) -{ -} - -/** - * e_cell_percent_new: - * @fontname: font to be used to render on the screen - * @justify: Justification of the string in the cell. - * - * Creates a new ECell renderer that can be used to render an integer - * percentage that comes from the model. The value returned from the model is - * interpreted as being an int. - * - * See ECellText for other features. - * - * Returns: an ECell object that can be used to render numbers. - */ -ECell * -e_cell_percent_new (const char *fontname, GtkJustification justify) -{ - ECellPercent *ecn = g_object_new (E_CELL_PERCENT_TYPE, NULL); - - e_cell_text_construct (E_CELL_TEXT(ecn), fontname, justify); - - return (ECell *) ecn; -} diff --git a/widgets/misc/e-cell-percent.h b/widgets/misc/e-cell-percent.h deleted file mode 100644 index 46a7ddc3e3..0000000000 --- a/widgets/misc/e-cell-percent.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Damon Chaplin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * ECellPercent - a subclass of ECellText used to show an integer percentage - * in an ETable. - */ - -#ifndef _E_CELL_PERCENT_H_ -#define _E_CELL_PERCENT_H_ - -#include
- -#define E_CELL_PERCENT_TYPE (e_cell_percent_get_type ()) -#define E_CELL_PERCENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_CELL_PERCENT_TYPE, ECellPercent)) -#define E_CELL_PERCENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_CELL_PERCENT_TYPE, ECellPercentClass)) -#define E_IS_CELL_NUMBER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_CELL_PERCENT_TYPE)) -#define E_IS_CELL_NUMBER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_CELL_PERCENT_TYPE)) - -typedef struct { - ECellText base; -} ECellPercent; - -typedef struct { - ECellTextClass parent_class; -} ECellPercentClass; - -GType e_cell_percent_get_type (void); -ECell *e_cell_percent_new (const char *fontname, GtkJustification justify); - -#endif /* _E_CELL_PERCENT_H_ */ diff --git a/widgets/misc/e-reflow-model.c b/widgets/misc/e-reflow-model.c deleted file mode 100644 index eae3d43324..0000000000 --- a/widgets/misc/e-reflow-model.c +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * 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 - * - * - * Authors: - * Chris Lahey - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ -#include - -#include "e-util/e-util.h" - -#include "e-reflow-model.h" - -G_DEFINE_TYPE (EReflowModel, e_reflow_model, G_TYPE_OBJECT) - -#define d(x) - -d(static gint depth = 0;) - - -enum { - MODEL_CHANGED, - COMPARISON_CHANGED, - MODEL_ITEMS_INSERTED, - MODEL_ITEM_CHANGED, - MODEL_ITEM_REMOVED, - LAST_SIGNAL -}; - -static guint e_reflow_model_signals [LAST_SIGNAL] = { 0, }; - -/** - * e_reflow_model_set_width: - * @e_reflow_model: The e-reflow-model to operate on - * @width: The new value for the width of each item. - */ -void -e_reflow_model_set_width (EReflowModel *e_reflow_model, int width) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->set_width (e_reflow_model, width); -} - -/** - * e_reflow_model_count: - * @e_reflow_model: The e-reflow-model to operate on - * - * Returns: the number of items in the reflow model. - */ -int -e_reflow_model_count (EReflowModel *e_reflow_model) -{ - g_return_val_if_fail (e_reflow_model != NULL, 0); - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); - - return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->count (e_reflow_model); -} - -/** - * e_reflow_model_height: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item number to get the height of. - * @parent: The parent GnomeCanvasItem. - * - * Returns: the height of the nth item. - */ -int -e_reflow_model_height (EReflowModel *e_reflow_model, int n, GnomeCanvasGroup *parent) -{ - g_return_val_if_fail (e_reflow_model != NULL, 0); - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); - - return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->height (e_reflow_model, n, parent); -} - -/** - * e_reflow_model_incarnate: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item to create. - * @parent: The parent GnomeCanvasItem to create a child of. - * - * Create a GnomeCanvasItem to represent the nth piece of data. - * - * Returns: the new GnomeCanvasItem. - */ -GnomeCanvasItem * -e_reflow_model_incarnate (EReflowModel *e_reflow_model, int n, GnomeCanvasGroup *parent) -{ - g_return_val_if_fail (e_reflow_model != NULL, NULL); - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), NULL); - - return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->incarnate (e_reflow_model, n, parent); -} - -/** - * e_reflow_model_compare: - * @e_reflow_model: The e-reflow-model to operate on - * @n1: The first item to compare - * @n2: The second item to compare - * - * Compares item n1 and item n2 to see which should come first. - * - * Returns: strcmp like semantics for the comparison value. - */ -int -e_reflow_model_compare (EReflowModel *e_reflow_model, int n1, int n2) -{ -#if 0 - g_return_val_if_fail (e_reflow_model != NULL, 0); - g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); -#endif - - return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->compare (e_reflow_model, n1, n2); -} - -/** - * e_reflow_model_reincarnate: - * @e_reflow_model: The e-reflow-model to operate on - * @n: The item to create. - * @item: The item to reuse. - * - * Update item to represent the nth piece of data. - */ -void -e_reflow_model_reincarnate (EReflowModel *e_reflow_model, int n, GnomeCanvasItem *item) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->reincarnate (e_reflow_model, n, item); -} - -static void -e_reflow_model_class_init (EReflowModelClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - e_reflow_model_signals [MODEL_CHANGED] = - g_signal_new ("model_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_reflow_model_signals [COMPARISON_CHANGED] = - g_signal_new ("comparison_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, comparison_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - e_reflow_model_signals [MODEL_ITEMS_INSERTED] = - g_signal_new ("model_items_inserted", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_items_inserted), - NULL, NULL, - e_marshal_NONE__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - - e_reflow_model_signals [MODEL_ITEM_CHANGED] = - g_signal_new ("model_item_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_item_changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - e_reflow_model_signals [MODEL_ITEM_REMOVED] = - g_signal_new ("model_item_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowModelClass, model_item_removed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - klass->set_width = NULL; - klass->count = NULL; - klass->height = NULL; - klass->incarnate = NULL; - klass->reincarnate = NULL; - - klass->model_changed = NULL; - klass->comparison_changed = NULL; - klass->model_items_inserted = NULL; - klass->model_item_removed = NULL; - klass->model_item_changed = NULL; -} - -static void -e_reflow_model_init (EReflowModel *e_reflow_model) -{ -} - -#if d(!)0 -static void -print_tabs (void) -{ - int i; - for (i = 0; i < depth; i++) - g_print("\t"); -} -#endif - -/** - * e_reflow_model_changed: - * @e_reflow_model: the reflow model to notify of the change - * - * Use this function to notify any views of this reflow model that - * the contents of the reflow model have changed. This will emit - * the signal "model_changed" on the @e_reflow_model object. - * - * It is preferable to use the e_reflow_model_item_changed() signal to - * notify of smaller changes than to invalidate the entire model, as - * the views might have ways of caching the information they render - * from the model. - */ -void -e_reflow_model_changed (EReflowModel *e_reflow_model) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d(print_tabs()); - d(g_print("Emitting model_changed on model 0x%p.\n", e_reflow_model)); - d(depth++); - g_signal_emit (e_reflow_model, - e_reflow_model_signals [MODEL_CHANGED], 0); - d(depth--); -} - -/** - * e_reflow_model_comparison_changed: - * @e_reflow_model: the reflow model to notify of the change - * - * Use this function to notify any views of this reflow model that the - * sorting has changed. The actual contents of the items hasn't, so - * there's no need to re-query the model for the heights of the - * individual items. - */ -void -e_reflow_model_comparison_changed (EReflowModel *e_reflow_model) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d(print_tabs()); - d(g_print("Emitting comparison_changed on model 0x%p.\n", e_reflow_model)); - d(depth++); - g_signal_emit (e_reflow_model, - e_reflow_model_signals [COMPARISON_CHANGED], 0); - d(depth--); -} - -/** - * e_reflow_model_items_inserted: - * @e_reflow_model: The model changed. - * @position: The position the items were insert in. - * @count: The number of items inserted. - * - * Use this function to notify any views of the reflow model that a number of items have been inserted. - **/ -void -e_reflow_model_items_inserted (EReflowModel *e_reflow_model, int position, int count) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d(print_tabs()); - d(g_print("Emitting items_inserted on model 0x%p, position=%d, count=%d.\n", e_reflow_model, position, count)); - d(depth++); - g_signal_emit (e_reflow_model, - e_reflow_model_signals [MODEL_ITEMS_INSERTED], 0, - position, count); - d(depth--); -} - -/** - * e_reflow_model_item_removed: - * @e_reflow_model: The model changed. - * @n: The position from which the items were removed. - * - * Use this function to notify any views of the reflow model that an - * item has been removed. - **/ -void -e_reflow_model_item_removed (EReflowModel *e_reflow_model, - int n) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d(print_tabs()); - d(g_print("Emitting item_removed on model 0x%p, n=%d.\n", e_reflow_model, n)); - d(depth++); - g_signal_emit (e_reflow_model, - e_reflow_model_signals [MODEL_ITEM_REMOVED], 0, - n); - d(depth--); -} - - -/** - * e_reflow_model_item_changed: - * @e_reflow_model: the reflow model to notify of the change - * @item: the item that was changed in the model. - * - * Use this function to notify any views of the reflow model that the - * contents of item @item have changed in model such that the height - * has changed or the item needs to be reincarnated. This function - * will emit the "model_item_changed" signal on the @e_reflow_model - * object - */ -void -e_reflow_model_item_changed (EReflowModel *e_reflow_model, int n) -{ - g_return_if_fail (e_reflow_model != NULL); - g_return_if_fail (E_IS_REFLOW_MODEL (e_reflow_model)); - - d(print_tabs()); - d(g_print("Emitting item_changed on model 0x%p, n=%d.\n", e_reflow_model, n)); - d(depth++); - g_signal_emit (e_reflow_model, - e_reflow_model_signals [MODEL_ITEM_CHANGED], 0, - n); - d(depth--); -} diff --git a/widgets/misc/e-reflow-model.h b/widgets/misc/e-reflow-model.h deleted file mode 100644 index 7482e5079f..0000000000 --- a/widgets/misc/e-reflow-model.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Chris Lahey - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_REFLOW_MODEL_H_ -#define _E_REFLOW_MODEL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define E_REFLOW_MODEL_TYPE (e_reflow_model_get_type ()) -#define E_REFLOW_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_REFLOW_MODEL_TYPE, EReflowModel)) -#define E_REFLOW_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_REFLOW_MODEL_TYPE, EReflowModelClass)) -#define E_IS_REFLOW_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_REFLOW_MODEL_TYPE)) -#define E_IS_REFLOW_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_REFLOW_MODEL_TYPE)) -#define E_REFLOW_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_REFLOW_MODEL_TYPE, EReflowModelClass)) - -typedef struct { - GObject base; -} EReflowModel; - -typedef struct { - GObjectClass parent_class; - - /* - * Virtual methods - */ - void (*set_width) (EReflowModel *etm, int width); - - int (*count) (EReflowModel *etm); - int (*height) (EReflowModel *etm, int n, GnomeCanvasGroup *parent); - GnomeCanvasItem *(*incarnate) (EReflowModel *etm, int n, GnomeCanvasGroup *parent); - int (*compare) (EReflowModel *etm, int n1, int n2); - void (*reincarnate) (EReflowModel *etm, int n, GnomeCanvasItem *item); - - /* - * Signals - */ - - /* - * These all come after the change has been made. - * Major structural changes: model_changed - * Changes to the sorting of elements: comparison_changed - * Changes only in an item: item_changed - */ - void (*model_changed) (EReflowModel *etm); - void (*comparison_changed) (EReflowModel *etm); - void (*model_items_inserted) (EReflowModel *etm, int position, int count); - void (*model_item_removed) (EReflowModel *etm, int position); - void (*model_item_changed) (EReflowModel *etm, int n); -} EReflowModelClass; - -GType e_reflow_model_get_type (void); - -/**/ -void e_reflow_model_set_width (EReflowModel *e_reflow_model, - int width); -int e_reflow_model_count (EReflowModel *e_reflow_model); -int e_reflow_model_height (EReflowModel *e_reflow_model, - int n, - GnomeCanvasGroup *parent); -GnomeCanvasItem *e_reflow_model_incarnate (EReflowModel *e_reflow_model, - int n, - GnomeCanvasGroup *parent); -int e_reflow_model_compare (EReflowModel *e_reflow_model, - int n1, - int n2); -void e_reflow_model_reincarnate (EReflowModel *e_reflow_model, - int n, - GnomeCanvasItem *item); - -/* - * Routines for emitting signals on the e_reflow - */ -void e_reflow_model_changed (EReflowModel *e_reflow_model); -void e_reflow_model_comparison_changed (EReflowModel *e_reflow_model); -void e_reflow_model_items_inserted (EReflowModel *e_reflow_model, - int position, - int count); -void e_reflow_model_item_removed (EReflowModel *e_reflow_model, - int n); -void e_reflow_model_item_changed (EReflowModel *e_reflow_model, - int n); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_REFLOW_MODEL_H_ */ diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c deleted file mode 100644 index f51a502a83..0000000000 --- a/widgets/misc/e-reflow.c +++ /dev/null @@ -1,1534 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * 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 - * - * - * Authors: - * Chris Lahey - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ -#include - -#include -#include - -#include -#include - -#include "text/e-text.h" -#include -#include "e-util/e-util.h" -#include "misc/e-unicode.h" - -#include "e-canvas.h" -#include "e-canvas-utils.h" -#include "e-reflow.h" -#include "e-selection-model-simple.h" - -static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event); -static void e_reflow_realize (GnomeCanvasItem *item); -static void e_reflow_unrealize (GnomeCanvasItem *item); -static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height); -static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags); -static double e_reflow_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); -static void e_reflow_reflow (GnomeCanvasItem *item, int flags); -static void set_empty(EReflow *reflow); - -static void e_reflow_resize_children (GnomeCanvasItem *item); - -#define E_REFLOW_DIVIDER_WIDTH 2 -#define E_REFLOW_BORDER_WIDTH 7 -#define E_REFLOW_FULL_GUTTER (E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH * 2) - -G_DEFINE_TYPE (EReflow, e_reflow, GNOME_TYPE_CANVAS_GROUP) - -/* The arguments we take */ -enum { - PROP_0, - PROP_MINIMUM_WIDTH, - PROP_WIDTH, - PROP_HEIGHT, - PROP_EMPTY_MESSAGE, - PROP_MODEL, - PROP_COLUMN_WIDTH -}; - -enum { - SELECTION_EVENT, - COLUMN_WIDTH_CHANGED, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = {0, }; - -static gint -er_compare (int i1, int i2, gpointer user_data) -{ - EReflow *reflow = user_data; - return e_reflow_model_compare (reflow->model, i1, i2); -} - -static gint -e_reflow_pick_line (EReflow *reflow, double x) -{ - x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - x /= reflow->column_width + E_REFLOW_FULL_GUTTER; - return x; -} - -static int -er_find_item (EReflow *reflow, GnomeCanvasItem *item) -{ - int i; - for (i = 0; i < reflow->count; i++) { - if (reflow->items[i] == item) - return i; - } - return -1; -} - -static void -e_reflow_resize_children (GnomeCanvasItem *item) -{ - EReflow *reflow; - int i; - int count; - - reflow = E_REFLOW (item); - - count = reflow->count; - for (i = 0; i < count; i++) { - if (reflow->items[i]) - gnome_canvas_item_set(reflow->items[i], - "width", (double) reflow->column_width, - NULL); - } -} - -static inline void -e_reflow_update_selection_row (EReflow *reflow, int row) -{ - if (reflow->items[row]) { - g_object_set(reflow->items[row], - "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), - NULL); - } else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row)) { - reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); - g_object_set (reflow->items[row], - "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), - "width", (double) reflow->column_width, - NULL); - } -} - -static void -e_reflow_update_selection (EReflow *reflow) -{ - int i; - int count; - - count = reflow->count; - for (i = 0; i < count; i++) { - e_reflow_update_selection_row (reflow, i); - } -} - -static void -selection_changed (ESelectionModel *selection, EReflow *reflow) -{ - e_reflow_update_selection (reflow); -} - -static void -selection_row_changed (ESelectionModel *selection, int row, EReflow *reflow) -{ - e_reflow_update_selection_row (reflow, row); -} - -static gboolean -do_adjustment (gpointer user_data) -{ - int row; - GtkAdjustment *adj ; - gfloat value, min_value, max_value; - EReflow *reflow = user_data; - - row = reflow->cursor_row; - if (row == -1) - return FALSE; - - adj = gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas)); - value = adj->value; - - if ((!reflow->items) || (!reflow->items[row])) - return TRUE; - min_value = reflow->items[row]->x2 - adj->page_size; - max_value = reflow->items[row]->x1; - - if (value < min_value) - value = min_value; - - if (value > max_value) - value = max_value; - - if (value != adj->value) { - adj->value = value; - gtk_adjustment_value_changed (adj); - } - - reflow->do_adjustment_idle_id = 0; - - return FALSE; -} - -static void -cursor_changed (ESelectionModel *selection, int row, int col, EReflow *reflow) -{ - int count = reflow->count; - int old_cursor = reflow->cursor_row; - - if (old_cursor < count && old_cursor >= 0) { - if (reflow->items[old_cursor]) { - g_object_set (reflow->items[old_cursor], - "has_cursor", FALSE, - NULL); - } - } - - reflow->cursor_row = row; - - if (row < count && row >= 0) { - if (reflow->items[row]) { - g_object_set (reflow->items[row], - "has_cursor", TRUE, - NULL); - } else { - reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); - g_object_set (reflow->items[row], - "has_cursor", TRUE, - "width", (double) reflow->column_width, - NULL); - } - } - - if (reflow->do_adjustment_idle_id == 0) - reflow->do_adjustment_idle_id = g_idle_add (do_adjustment, reflow); - -} - - -static void -incarnate (EReflow *reflow) -{ - int column_width; - int first_column; - int last_column; - int first_cell; - int last_cell; - int i; - GtkAdjustment *adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (GNOME_CANVAS_ITEM (reflow)->canvas)); - - column_width = reflow->column_width; - - first_column = adjustment->value - 1 + E_REFLOW_BORDER_WIDTH; - first_column /= column_width + E_REFLOW_FULL_GUTTER; - - last_column = adjustment->value + adjustment->page_size + 1 - E_REFLOW_BORDER_WIDTH - E_REFLOW_DIVIDER_WIDTH; - last_column /= column_width + E_REFLOW_FULL_GUTTER; - last_column ++; - - if (first_column >= 0 && first_column < reflow->column_count) - first_cell = reflow->columns[first_column]; - else - first_cell = 0; - - if (last_column >= 0 && last_column < reflow->column_count) - last_cell = reflow->columns[last_column]; - else - last_cell = reflow->count; - - for (i = first_cell; i < last_cell; i++) { - int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (reflow->items[unsorted] == NULL) { - if (reflow->model) { - reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); - g_object_set (reflow->items[unsorted], - "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), unsorted), - "width", (double) reflow->column_width, - NULL); - } - } - } - reflow->incarnate_idle_id = 0; -} - -static gboolean -invoke_incarnate (gpointer user_data) -{ - EReflow *reflow = user_data; - incarnate (reflow); - return FALSE; -} - -static void -queue_incarnate (EReflow *reflow) -{ - if (reflow->incarnate_idle_id == 0) - reflow->incarnate_idle_id = - g_idle_add_full (25, invoke_incarnate, reflow, NULL); -} - -static void -reflow_columns (EReflow *reflow) -{ - GSList *list; - int count; - int start; - int i; - int column_count, column_start; - double running_height; - - if (reflow->reflow_from_column <= 1) { - start = 0; - column_count = 1; - column_start = 0; - } - else { - /* we start one column before the earliest new entry, - so we can handle the case where the new entry is - inserted at the start of the column */ - column_start = reflow->reflow_from_column - 1; - start = reflow->columns[column_start]; - column_count = column_start + 1; - } - - list = NULL; - - running_height = E_REFLOW_BORDER_WIDTH; - - count = reflow->count - start; - for (i = start; i < count; i++) { - int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (i != 0 && running_height + reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH > reflow->height) { - list = g_slist_prepend (list, GINT_TO_POINTER(i)); - column_count ++; - running_height = E_REFLOW_BORDER_WIDTH * 2 + reflow->heights[unsorted]; - } else - running_height += reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH; - } - - reflow->column_count = column_count; - reflow->columns = g_renew (int, reflow->columns, column_count); - column_count --; - - for (; column_count > column_start; column_count--) { - GSList *to_free; - reflow->columns[column_count] = GPOINTER_TO_INT(list->data); - to_free = list; - list = list->next; - g_slist_free_1 (to_free); - } - reflow->columns[column_start] = start; - - queue_incarnate (reflow); - - reflow->need_reflow_columns = FALSE; - reflow->reflow_from_column = -1; -} - -static void -item_changed (EReflowModel *model, int i, EReflow *reflow) -{ - if (i < 0 || i >= reflow->count) - return; - - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - if (reflow->items[i] != NULL) - e_reflow_model_reincarnate (model, i, reflow->items[i]); - e_sorter_array_clean (reflow->sorter); - reflow->reflow_from_column = -1; - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); -} - -static void -item_removed (EReflowModel *model, int i, EReflow *reflow) -{ - int c; - int sorted; - - if (i < 0 || i >= reflow->count) - return; - - sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); - for (c = reflow->column_count - 1; c >= 0; c--) { - int start_of_column = reflow->columns[c]; - - if (start_of_column <= sorted) { - if (reflow->reflow_from_column == -1 - || reflow->reflow_from_column > c) { - reflow->reflow_from_column = c; - } - break; - } - } - - if (reflow->items[i]) - gtk_object_destroy (GTK_OBJECT (reflow->items[i])); - - memmove (reflow->heights + i, reflow->heights + i + 1, (reflow->count - i - 1) * sizeof (int)); - memmove (reflow->items + i, reflow->items + i + 1, (reflow->count - i - 1) * sizeof (GnomeCanvasItem *)); - - reflow->count --; - - reflow->heights [reflow->count] = 0; - reflow->items [reflow->count] = NULL; - - reflow->need_reflow_columns = TRUE; - set_empty (reflow); - e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); - - e_sorter_array_set_count (reflow->sorter, reflow->count); - - e_selection_model_simple_delete_rows (E_SELECTION_MODEL_SIMPLE (reflow->selection), i, 1); -} - -static void -items_inserted (EReflowModel *model, int position, int count, EReflow *reflow) -{ - int i, oldcount; - - if (position < 0 || position > reflow->count) - return; - - oldcount = reflow->count; - - reflow->count += count; - - if (reflow->count > reflow->allocated_count) { - while (reflow->count > reflow->allocated_count) - reflow->allocated_count += 256; - reflow->heights = g_renew (int, reflow->heights, reflow->allocated_count); - reflow->items = g_renew (GnomeCanvasItem *, reflow->items, reflow->allocated_count); - } - memmove (reflow->heights + position + count, reflow->heights + position, (reflow->count - position - count) * sizeof (int)); - memmove (reflow->items + position + count, reflow->items + position, (reflow->count - position - count) * sizeof (GnomeCanvasItem *)); - for (i = position; i < position + count; i++) { - reflow->items[i] = NULL; - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - } - - e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), reflow->count); - if (position == oldcount) - e_sorter_array_append (reflow->sorter, count); - else - e_sorter_array_set_count (reflow->sorter, reflow->count); - - for (i = position; i < position + count; i ++) { - int sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); - int c; - - for (c = reflow->column_count - 1; c >= 0; c--) { - int start_of_column = reflow->columns[c]; - - if (start_of_column <= sorted) { - if (reflow->reflow_from_column == -1 - || reflow->reflow_from_column > c) { - reflow->reflow_from_column = c; - } - break; - } - } - } - - reflow->need_reflow_columns = TRUE; - set_empty (reflow); - e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); -} - -static void -model_changed (EReflowModel *model, EReflow *reflow) -{ - int i; - int count; - int oldcount; - - count = reflow->count; - oldcount = count; - - for (i = 0; i < count; i++) { - if (reflow->items[i]) - gtk_object_destroy (GTK_OBJECT (reflow->items[i])); - } - g_free (reflow->items); - g_free (reflow->heights); - reflow->count = e_reflow_model_count (model); - reflow->allocated_count = reflow->count; - reflow->items = g_new (GnomeCanvasItem *, reflow->count); - reflow->heights = g_new (int, reflow->count); - - count = reflow->count; - for (i = 0; i < count; i++) { - reflow->items[i] = NULL; - reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - } - - e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), count); - e_sorter_array_set_count (reflow->sorter, reflow->count); - - reflow->need_reflow_columns = TRUE; - if (oldcount > reflow->count) - reflow_columns (reflow); - set_empty (reflow); - e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); -} - -static void -comparison_changed (EReflowModel *model, EReflow *reflow) -{ - e_sorter_array_clean (reflow->sorter); - reflow->reflow_from_column = -1; - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); -} - -static void -set_empty(EReflow *reflow) -{ - if (reflow->count == 0) { - if (reflow->empty_text) { - if (reflow->empty_message) { - gnome_canvas_item_set(reflow->empty_text, - "width", reflow->minimum_width, - "text", reflow->empty_message, - NULL); - e_canvas_item_move_absolute(reflow->empty_text, - reflow->minimum_width / 2, - 0); - } else { - gtk_object_destroy(GTK_OBJECT(reflow->empty_text)); - reflow->empty_text = NULL; - } - } else { - if (reflow->empty_message) { - reflow->empty_text = - gnome_canvas_item_new(GNOME_CANVAS_GROUP(reflow), - e_text_get_type(), - "anchor", GTK_ANCHOR_N, - "width", reflow->minimum_width, - "clip", TRUE, - "use_ellipsis", TRUE, - "justification", GTK_JUSTIFY_CENTER, - "text", reflow->empty_message, - "draw_background", FALSE, - NULL); - e_canvas_item_move_absolute(reflow->empty_text, - reflow->minimum_width / 2, - 0); - } - } - } else { - if (reflow->empty_text) { - gtk_object_destroy(GTK_OBJECT(reflow->empty_text)); - reflow->empty_text = NULL; - } - } -} - -static void -disconnect_model (EReflow *reflow) -{ - if (reflow->model == NULL) - return; - - g_signal_handler_disconnect (reflow->model, - reflow->model_changed_id); - g_signal_handler_disconnect (reflow->model, - reflow->comparison_changed_id); - g_signal_handler_disconnect (reflow->model, - reflow->model_items_inserted_id); - g_signal_handler_disconnect (reflow->model, - reflow->model_item_removed_id); - g_signal_handler_disconnect (reflow->model, - reflow->model_item_changed_id); - g_object_unref (reflow->model); - - reflow->model_changed_id = 0; - reflow->comparison_changed_id = 0; - reflow->model_items_inserted_id = 0; - reflow->model_item_removed_id = 0; - reflow->model_item_changed_id = 0; - reflow->model = NULL; -} - -static void -disconnect_selection (EReflow *reflow) -{ - if (reflow->selection == NULL) - return; - - g_signal_handler_disconnect (reflow->selection, - reflow->selection_changed_id); - g_signal_handler_disconnect (reflow->selection, - reflow->selection_row_changed_id); - g_signal_handler_disconnect (reflow->selection, - reflow->cursor_changed_id); - g_object_unref (reflow->selection); - - reflow->selection_changed_id = 0; - reflow->selection_row_changed_id = 0; - reflow->cursor_changed_id = 0; - reflow->selection = NULL; -} - -static void -connect_model (EReflow *reflow, EReflowModel *model) -{ - if (reflow->model != NULL) - disconnect_model (reflow); - - if (model == NULL) - return; - - reflow->model = model; - g_object_ref (reflow->model); - reflow->model_changed_id = - g_signal_connect (reflow->model, "model_changed", - G_CALLBACK (model_changed), reflow); - reflow->comparison_changed_id = - g_signal_connect (reflow->model, "comparison_changed", - G_CALLBACK (comparison_changed), reflow); - reflow->model_items_inserted_id = - g_signal_connect (reflow->model, "model_items_inserted", - G_CALLBACK (items_inserted), reflow); - reflow->model_item_removed_id = - g_signal_connect (reflow->model, "model_item_removed", - G_CALLBACK (item_removed), reflow); - reflow->model_item_changed_id = - g_signal_connect (reflow->model, "model_item_changed", - G_CALLBACK (item_changed), reflow); - model_changed (model, reflow); -} - -static void -adjustment_changed (GtkAdjustment *adjustment, EReflow *reflow) -{ - queue_incarnate (reflow); -} - -static void -disconnect_adjustment (EReflow *reflow) -{ - if (reflow->adjustment == NULL) - return; - - g_signal_handler_disconnect (reflow->adjustment, - reflow->adjustment_changed_id); - g_signal_handler_disconnect (reflow->adjustment, - reflow->adjustment_value_changed_id); - - g_object_unref (reflow->adjustment); - - reflow->adjustment_changed_id = 0; - reflow->adjustment_value_changed_id = 0; - reflow->adjustment = NULL; -} - -static void -connect_adjustment (EReflow *reflow, GtkAdjustment *adjustment) -{ - if (reflow->adjustment != NULL) - disconnect_adjustment (reflow); - - if (adjustment == NULL) - return; - - reflow->adjustment = adjustment; - reflow->adjustment_changed_id = - g_signal_connect (adjustment, "changed", - G_CALLBACK (adjustment_changed), reflow); - reflow->adjustment_value_changed_id = - g_signal_connect (adjustment, "value_changed", - G_CALLBACK (adjustment_changed), reflow); - g_object_ref (adjustment); -} - -#if 0 -static void -set_scroll_adjustments (GtkLayout *layout, GtkAdjustment *hadj, GtkAdjustment *vadj, EReflow *reflow) -{ - connect_adjustment (reflow, hadj); -} - -static void -connect_set_adjustment (EReflow *reflow) -{ - reflow->set_scroll_adjustments_id = - g_signal_connect (GNOME_CANVAS_ITEM (reflow)->canvas, - "set_scroll_adjustments", - G_CALLBACK (set_scroll_adjustments), reflow); -} -#endif - -static void -disconnect_set_adjustment (EReflow *reflow) -{ - if (reflow->set_scroll_adjustments_id != 0) { - g_signal_handler_disconnect (GNOME_CANVAS_ITEM (reflow)->canvas, - reflow->set_scroll_adjustments_id); - reflow->set_scroll_adjustments_id = 0; - } -} - -static void -column_width_changed (EReflow *reflow) -{ - g_signal_emit (reflow, signals[COLUMN_WIDTH_CHANGED], 0, reflow->column_width); -} - - - - -/* Virtual functions */ -static void -e_reflow_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GnomeCanvasItem *item; - EReflow *reflow; - - item = GNOME_CANVAS_ITEM (object); - reflow = E_REFLOW (object); - - switch (prop_id){ - case PROP_HEIGHT: - reflow->height = g_value_get_double (value); - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow(item); - break; - case PROP_MINIMUM_WIDTH: - reflow->minimum_width = g_value_get_double (value); - if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object)) - set_empty(reflow); - e_canvas_item_request_reflow(item); - break; - case PROP_EMPTY_MESSAGE: - g_free(reflow->empty_message); - reflow->empty_message = g_strdup(g_value_get_string (value)); - if (GNOME_CANVAS_ITEM_REALIZED & GTK_OBJECT_FLAGS(object)) - set_empty(reflow); - break; - case PROP_MODEL: - connect_model (reflow, (EReflowModel *) g_value_get_object (value)); - break; - case PROP_COLUMN_WIDTH: - if (reflow->column_width != g_value_get_double (value)) { - GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - double old_width = reflow->column_width; - - reflow->column_width = g_value_get_double (value); - adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2; - adjustment->page_increment = adjustment->page_size - adjustment->step_increment; - gtk_adjustment_changed(adjustment); - e_reflow_resize_children(item); - e_canvas_item_request_reflow(item); - - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update(item); - - if (old_width != reflow->column_width) - column_width_changed (reflow); - } - break; - } -} - -static void -e_reflow_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - EReflow *reflow; - - reflow = E_REFLOW (object); - - switch (prop_id) { - case PROP_MINIMUM_WIDTH: - g_value_set_double (value, reflow->minimum_width); - break; - case PROP_WIDTH: - g_value_set_double (value, reflow->width); - break; - case PROP_HEIGHT: - g_value_set_double (value, reflow->height); - break; - case PROP_EMPTY_MESSAGE: - g_value_set_string (value, reflow->empty_message); - break; - case PROP_MODEL: - g_value_set_object (value, reflow->model); - break; - case PROP_COLUMN_WIDTH: - g_value_set_double (value, reflow->column_width); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -e_reflow_dispose (GObject *object) -{ - EReflow *reflow = E_REFLOW(object); - - g_free (reflow->items); - g_free (reflow->heights); - g_free (reflow->columns); - - reflow->items = NULL; - reflow->heights = NULL; - reflow->columns = NULL; - reflow->count = 0; - reflow->allocated_count = 0; - - if (reflow->incarnate_idle_id) - g_source_remove (reflow->incarnate_idle_id); - reflow->incarnate_idle_id = 0; - - if (reflow->do_adjustment_idle_id) - g_source_remove (reflow->do_adjustment_idle_id); - reflow->do_adjustment_idle_id = 0; - - disconnect_model (reflow); - disconnect_selection (reflow); - - g_free(reflow->empty_message); - reflow->empty_message = NULL; - - if (reflow->sorter) { - g_object_unref (reflow->sorter); - reflow->sorter = NULL; - } - - G_OBJECT_CLASS(e_reflow_parent_class)->dispose (object); -} - -static void -e_reflow_realize (GnomeCanvasItem *item) -{ - EReflow *reflow; - GtkAdjustment *adjustment; - int count; - int i; - - reflow = E_REFLOW (item); - - if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize) - (* GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->realize) (item); - - reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); - - count = reflow->count; - for(i = 0; i < count; i++) { - if (reflow->items[i]) - gnome_canvas_item_set(reflow->items[i], - "width", reflow->column_width, - NULL); - } - - set_empty(reflow); - - reflow->need_reflow_columns = TRUE; - e_canvas_item_request_reflow(item); - - adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - -#if 0 - connect_set_adjustment (reflow); -#endif - connect_adjustment (reflow, adjustment); - - adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2; - adjustment->page_increment = adjustment->page_size - adjustment->step_increment; - gtk_adjustment_changed(adjustment); - - if (!item->canvas->aa) { - } -} - -static void -e_reflow_unrealize (GnomeCanvasItem *item) -{ - EReflow *reflow; - - reflow = E_REFLOW (item); - - if (!item->canvas->aa) { - } - - gdk_cursor_unref (reflow->arrow_cursor); - gdk_cursor_unref (reflow->default_cursor); - reflow->arrow_cursor = NULL; - reflow->default_cursor = NULL; - - g_free (reflow->columns); - reflow->columns = NULL; - - disconnect_set_adjustment (reflow); - disconnect_adjustment (reflow); - - if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize) - (* GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->unrealize) (item); -} - -static gboolean -e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EReflow *reflow; - int return_val = FALSE; - - reflow = E_REFLOW (item); - - switch( event->type ) - { - case GDK_KEY_PRESS: - return_val = e_selection_model_key_press(reflow->selection, (GdkEventKey *) event); - break; -#if 0 - if (event->key.keyval == GDK_Tab || - event->key.keyval == GDK_KP_Tab || - event->key.keyval == GDK_ISO_Left_Tab) { - int i; - int count; - count = reflow->count; - for (i = 0; i < count; i++) { - int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - GnomeCanvasItem *item = reflow->items[unsorted]; - EFocus has_focus; - if (item) { - g_object_get(item, - "has_focus", &has_focus, - NULL); - if (has_focus) { - if (event->key.state & GDK_SHIFT_MASK) { - if (i == 0) - return FALSE; - i--; - } else { - if (i == count - 1) - return FALSE; - i++; - } - - unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (reflow->items[unsorted] == NULL) { - reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); - } - - item = reflow->items[unsorted]; - gnome_canvas_item_set(item, - "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START, - NULL); - return TRUE; - } - } - } - } -#endif - case GDK_BUTTON_PRESS: - switch(event->button.button) - { - case 1: - { - GdkEventButton *button = (GdkEventButton *) event; - double n_x; - n_x = button->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - if ( button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { - /* don't allow to drag the first line*/ - if (e_reflow_pick_line(reflow, button->x) == 0) - return TRUE; - reflow->which_column_dragged = e_reflow_pick_line(reflow, button->x); - reflow->start_x = reflow->which_column_dragged * (reflow->column_width + E_REFLOW_FULL_GUTTER) - E_REFLOW_DIVIDER_WIDTH / 2; - reflow->temp_column_width = reflow->column_width; - reflow->column_drag = TRUE; - - gnome_canvas_item_grab (item, - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - reflow->arrow_cursor, - button->time); - - reflow->previous_temp_column_width = -1; - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update(item); - return TRUE; - } - } - break; - case 4: - { - GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - gdouble new_value = adjustment->value; - new_value -= adjustment->step_increment; - gtk_adjustment_set_value(adjustment, new_value); - } - break; - case 5: - { - GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - gdouble new_value = adjustment->value; - new_value += adjustment->step_increment; - if ( new_value > adjustment->upper - adjustment->page_size ) - new_value = adjustment->upper - adjustment->page_size; - gtk_adjustment_set_value(adjustment, new_value); - } - break; - } - break; - case GDK_BUTTON_RELEASE: - if (reflow->column_drag) { - gdouble old_width = reflow->column_width; - GdkEventButton *button = (GdkEventButton *) event; - GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - reflow->temp_column_width = reflow->column_width + - (button->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value)); - if ( reflow->temp_column_width < 50 ) - reflow->temp_column_width = 50; - reflow->column_drag = FALSE; - if ( old_width != reflow->temp_column_width ) { - gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(reflow, adjustment->value) * (reflow->temp_column_width - reflow->column_width)); - reflow->column_width = reflow->temp_column_width; - adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2; - adjustment->page_increment = adjustment->page_size - adjustment->step_increment; - gtk_adjustment_changed(adjustment); - e_reflow_resize_children(item); - e_canvas_item_request_reflow(item); - gnome_canvas_request_redraw(item->canvas, 0, 0, reflow->width, reflow->height); - column_width_changed (reflow); - } - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update(item); - gnome_canvas_item_ungrab (item, button->time); - return TRUE; - } - break; - case GDK_MOTION_NOTIFY: - if (reflow->column_drag) { - double old_width = reflow->temp_column_width; - GdkEventMotion *motion = (GdkEventMotion *) event; - GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas)); - reflow->temp_column_width = reflow->column_width + - (motion->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value)); - if (reflow->temp_column_width < 50) - reflow->temp_column_width = 50; - if (old_width != reflow->temp_column_width) { - reflow->need_column_resize = TRUE; - gnome_canvas_item_request_update(item); - } - return TRUE; - } else { - GdkEventMotion *motion = (GdkEventMotion *) event; - double n_x; - - n_x = motion->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - if ( motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { - if ( reflow->default_cursor_shown ) { - gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor); - reflow->default_cursor_shown = FALSE; - } - } else - if ( ! reflow->default_cursor_shown ) { - gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor); - reflow->default_cursor_shown = TRUE; - } - - } - break; - case GDK_ENTER_NOTIFY: - if (!reflow->column_drag) { - GdkEventCrossing *crossing = (GdkEventCrossing *) event; - double n_x; - n_x = crossing->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - - if ( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) { - if ( reflow->default_cursor_shown ) { - gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor); - reflow->default_cursor_shown = FALSE; - } - } - } - break; - case GDK_LEAVE_NOTIFY: - if (!reflow->column_drag) { - GdkEventCrossing *crossing = (GdkEventCrossing *) event; - double n_x; - n_x = crossing->x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER)); - if ( !( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) ) { - if ( ! reflow->default_cursor_shown ) { - gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor); - reflow->default_cursor_shown = TRUE; - } - } - } - break; - default: - break; - } - if (return_val) - return return_val; - else if (GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) - return (* GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) (item, event); - else - return FALSE; -} - -static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height) -{ - int x_rect, y_rect, width_rect, height_rect; - gdouble running_width; - EReflow *reflow = E_REFLOW(item); - int i; - double column_width; - - if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw) - GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->draw (item, drawable, x, y, width, height); - column_width = reflow->column_width; - running_width = E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - x_rect = running_width; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - /* Compute first column to draw. */ - i = x; - i /= column_width + E_REFLOW_FULL_GUTTER; - running_width += i * (column_width + E_REFLOW_FULL_GUTTER); - - for ( ; i < reflow->column_count; i++) { - if ( running_width > x + width ) - break; - x_rect = running_width; - gtk_paint_flat_box(GTK_WIDGET(item->canvas)->style, - drawable, - GTK_STATE_ACTIVE, - GTK_SHADOW_NONE, - NULL, - GTK_WIDGET(item->canvas), - "reflow", - x_rect - x, - y_rect - y, - width_rect, - height_rect); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - if (reflow->column_drag) { - int start_line = e_reflow_pick_line(reflow, - gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); - i = x - start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width = start_line * (column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - i += start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - x_rect = running_width; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - /* Compute first column to draw. */ - i /= column_width + E_REFLOW_FULL_GUTTER; - running_width += i * (column_width + E_REFLOW_FULL_GUTTER); - - for ( ; i < reflow->column_count; i++) { - if ( running_width > x + width ) - break; - x_rect = running_width; - gdk_draw_rectangle(drawable, - GTK_WIDGET(item->canvas)->style->fg_gc[GTK_STATE_NORMAL], - TRUE, - x_rect - x, - y_rect - y, - width_rect - 1, - height_rect - 1); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - } -} - -static void -e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) -{ - EReflow *reflow; - double x0, x1, y0, y1; - - reflow = E_REFLOW (item); - - if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update) - GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->update (item, affine, clip_path, flags); - - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x1 < x0 + reflow->width ) - x1 = x0 + reflow->width; - if ( y1 < y0 + reflow->height ) - y1 = y0 + reflow->height; - item->x2 = x1; - item->y2 = y1; - - if (reflow->need_height_update) { - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x0 > 0 ) - x0 = 0; - if ( y0 > 0 ) - y0 = 0; - if ( x1 < E_REFLOW(item)->width ) - x1 = E_REFLOW(item)->width; - if ( x1 < E_REFLOW(item)->height ) - x1 = E_REFLOW(item)->height; - - gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1); - reflow->need_height_update = FALSE; - } else if (reflow->need_column_resize) { - int x_rect, y_rect, width_rect, height_rect; - int start_line = e_reflow_pick_line(reflow, - gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); - gdouble running_width; - int i; - double column_width; - - if ( reflow->previous_temp_column_width != -1 ) { - running_width = start_line * (reflow->column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->previous_temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - for ( i = 0; i < reflow->column_count; i++) { - x_rect = running_width; - gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - } - - if ( reflow->temp_column_width != -1 ) { - running_width = start_line * (reflow->column_width + E_REFLOW_FULL_GUTTER); - column_width = reflow->temp_column_width; - running_width -= start_line * (column_width + E_REFLOW_FULL_GUTTER); - running_width += E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - y_rect = E_REFLOW_BORDER_WIDTH; - width_rect = E_REFLOW_DIVIDER_WIDTH; - height_rect = reflow->height - (E_REFLOW_BORDER_WIDTH * 2); - - for ( i = 0; i < reflow->column_count; i++) { - x_rect = running_width; - gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); - running_width += E_REFLOW_DIVIDER_WIDTH + E_REFLOW_BORDER_WIDTH + column_width + E_REFLOW_BORDER_WIDTH; - } - } - - reflow->previous_temp_column_width = reflow->temp_column_width; - reflow->need_column_resize = FALSE; - } -} - -static double -e_reflow_point (GnomeCanvasItem *item, - double x, double y, int cx, int cy, - GnomeCanvasItem **actual_item) -{ - double distance = 1; - - *actual_item = NULL; - - if (GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point) - distance = GNOME_CANVAS_ITEM_CLASS(e_reflow_parent_class)->point (item, x, y, cx, cy, actual_item); - if ((int) (distance * item->canvas->pixels_per_unit + 0.5) <= item->canvas->close_enough && *actual_item) - return distance; - - *actual_item = item; - return 0; -#if 0 - if (y >= E_REFLOW_BORDER_WIDTH && y <= reflow->height - E_REFLOW_BORDER_WIDTH) { - float n_x; - n_x = x; - n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH; - n_x = fmod(n_x, (reflow->column_width + E_REFLOW_FULL_GUTTER)); - if (n_x < E_REFLOW_FULL_GUTTER) { - *actual_item = item; - return 0; - } - } - return distance; -#endif -} - -static void -e_reflow_reflow( GnomeCanvasItem *item, int flags ) -{ - EReflow *reflow = E_REFLOW(item); - gdouble old_width; - gdouble running_width; - gdouble running_height; - int next_column; - int i; - - if (! (GTK_OBJECT_FLAGS (reflow) & GNOME_CANVAS_ITEM_REALIZED)) - return; - - if (reflow->need_reflow_columns) { - reflow_columns (reflow); - } - - old_width = reflow->width; - - running_width = E_REFLOW_BORDER_WIDTH; - running_height = E_REFLOW_BORDER_WIDTH; - - next_column = 1; - - for (i = 0; i < reflow->count; i++) { - int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (next_column < reflow->column_count && i == reflow->columns[next_column]) { - running_height = E_REFLOW_BORDER_WIDTH; - running_width += reflow->column_width + E_REFLOW_FULL_GUTTER; - next_column ++; - } - - if (unsorted >= 0 && reflow->items[unsorted]) { - e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(reflow->items[unsorted]), - (double) running_width, - (double) running_height); - running_height += reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH; - } - } - reflow->width = running_width + reflow->column_width + E_REFLOW_BORDER_WIDTH; - if ( reflow->width < reflow->minimum_width ) - reflow->width = reflow->minimum_width; - if (old_width != reflow->width) - e_canvas_item_request_parent_reflow(item); -} - -static int -e_reflow_selection_event_real (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event) -{ - int row; - int return_val = TRUE; - switch (event->type) { - case GDK_BUTTON_PRESS: - switch (event->button.button) { - case 1: /* Fall through. */ - case 2: - row = er_find_item (reflow, item); - if (event->button.button == 1) { - reflow->maybe_did_something = - e_selection_model_maybe_do_something(reflow->selection, row, 0, event->button.state); - reflow->maybe_in_drag = TRUE; - } else { - e_selection_model_do_something(reflow->selection, row, 0, event->button.state); - } - break; - case 3: - row = er_find_item (reflow, item); - e_selection_model_right_click_down(reflow->selection, row, 0, 0); - break; - default: - return_val = FALSE; - break; - } - break; - case GDK_BUTTON_RELEASE: - if (event->button.button == 1) { - if (reflow->maybe_in_drag) { - reflow->maybe_in_drag = FALSE; - if (!reflow->maybe_did_something) { - row = er_find_item (reflow, item); - e_selection_model_do_something(reflow->selection, row, 0, event->button.state); - } - } - } - break; - case GDK_KEY_PRESS: - return_val = e_selection_model_key_press(reflow->selection, (GdkEventKey *) event); - break; - default: - return_val = FALSE; - break; - } - - return return_val; -} - -static void -e_reflow_class_init (EReflowClass *klass) -{ - GObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GObjectClass*) klass; - item_class = (GnomeCanvasItemClass *) klass; - - object_class->set_property = e_reflow_set_property; - object_class->get_property = e_reflow_get_property; - object_class->dispose = e_reflow_dispose; - - /* GnomeCanvasItem method overrides */ - item_class->event = e_reflow_event; - item_class->realize = e_reflow_realize; - item_class->unrealize = e_reflow_unrealize; - item_class->draw = e_reflow_draw; - item_class->update = e_reflow_update; - item_class->point = e_reflow_point; - - klass->selection_event = e_reflow_selection_event_real; - klass->column_width_changed = NULL; - - g_object_class_install_property (object_class, PROP_MINIMUM_WIDTH, - g_param_spec_double ("minimum_width", - _( "Minimum width" ), - _( "Minimum Width" ), - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WIDTH, - g_param_spec_double ("width", - _( "Width" ), - _( "Width" ), - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READABLE)); - - - g_object_class_install_property (object_class, PROP_HEIGHT, - g_param_spec_double ("height", - _( "Height" ), - _( "Height" ), - 0.0, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_EMPTY_MESSAGE, - g_param_spec_string ("empty_message", - _( "Empty message" ), - _( "Empty message" ), - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_MODEL, - g_param_spec_object ("model", - _( "Reflow model" ), - _( "Reflow model" ), - E_REFLOW_MODEL_TYPE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_COLUMN_WIDTH, - g_param_spec_double ("column_width", - _( "Column width" ), - _( "Column width" ), - 0.0, G_MAXDOUBLE, 150.0, - G_PARAM_READWRITE)); - - signals [SELECTION_EVENT] = - g_signal_new ("selection_event", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowClass, selection_event), - NULL, NULL, - e_marshal_INT__OBJECT_BOXED, - G_TYPE_INT, 2, G_TYPE_OBJECT, - GDK_TYPE_EVENT); - - signals [COLUMN_WIDTH_CHANGED] = - g_signal_new ("column_width_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EReflowClass, column_width_changed), - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, G_TYPE_DOUBLE); -} - -static void -e_reflow_init (EReflow *reflow) -{ - reflow->model = NULL; - reflow->items = NULL; - reflow->heights = NULL; - reflow->count = 0; - - reflow->columns = NULL; - reflow->column_count = 0; - - reflow->empty_text = NULL; - reflow->empty_message = NULL; - - reflow->minimum_width = 10; - reflow->width = 10; - reflow->height = 10; - - reflow->column_width = 150; - - reflow->column_drag = FALSE; - - reflow->need_height_update = FALSE; - reflow->need_column_resize = FALSE; - reflow->need_reflow_columns = FALSE; - - reflow->maybe_did_something = FALSE; - reflow->maybe_in_drag = FALSE; - - reflow->default_cursor_shown = TRUE; - reflow->arrow_cursor = NULL; - reflow->default_cursor = NULL; - - reflow->cursor_row = -1; - - reflow->incarnate_idle_id = 0; - reflow->do_adjustment_idle_id = 0; - reflow->set_scroll_adjustments_id = 0; - - reflow->selection = E_SELECTION_MODEL (e_selection_model_simple_new()); - reflow->sorter = e_sorter_array_new (er_compare, reflow); - - g_object_set (reflow->selection, - "sorter", reflow->sorter, - NULL); - - reflow->selection_changed_id = - g_signal_connect(reflow->selection, "selection_changed", - G_CALLBACK (selection_changed), reflow); - reflow->selection_row_changed_id = - g_signal_connect(reflow->selection, "selection_row_changed", - G_CALLBACK (selection_row_changed), reflow); - reflow->cursor_changed_id = - g_signal_connect(reflow->selection, "cursor_changed", - G_CALLBACK (cursor_changed), reflow); - - e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow); -} diff --git a/widgets/misc/e-reflow.h b/widgets/misc/e-reflow.h deleted file mode 100644 index 6d67369209..0000000000 --- a/widgets/misc/e-reflow.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Chris Lahey - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_REFLOW_H__ -#define __E_REFLOW_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -/* EReflow - A canvas item container. - * - * The following arguments are available: - * - * name type read/write description - * -------------------------------------------------------------------------------- - * minimum_width double RW minimum width of the reflow. width >= minimum_width - * width double R width of the reflow - * height double RW height of the reflow - */ - -#define E_REFLOW_TYPE (e_reflow_get_type ()) -#define E_REFLOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_REFLOW_TYPE, EReflow)) -#define E_REFLOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_REFLOW_TYPE, EReflowClass)) -#define E_IS_REFLOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_REFLOW_TYPE)) -#define E_IS_REFLOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_REFLOW_TYPE)) - - -typedef struct EReflowPriv EReflowPriv; - -typedef struct _EReflow EReflow; -typedef struct _EReflowClass EReflowClass; - -struct _EReflow -{ - GnomeCanvasGroup parent; - - /* item specific fields */ - EReflowModel *model; - guint model_changed_id; - guint comparison_changed_id; - guint model_items_inserted_id; - guint model_item_removed_id; - guint model_item_changed_id; - - ESelectionModel *selection; - guint selection_changed_id; - guint selection_row_changed_id; - guint cursor_changed_id; - ESorterArray *sorter; - - GtkAdjustment *adjustment; - guint adjustment_changed_id; - guint adjustment_value_changed_id; - guint set_scroll_adjustments_id; - - int *heights; - GnomeCanvasItem **items; - int count; - int allocated_count; - - int *columns; - gint column_count; /* Number of columnns */ - - GnomeCanvasItem *empty_text; - gchar *empty_message; - - double minimum_width; - double width; - double height; - - double column_width; - - int incarnate_idle_id; - int do_adjustment_idle_id; - - /* These are all for when the column is being dragged. */ - gdouble start_x; - gint which_column_dragged; - double temp_column_width; - double previous_temp_column_width; - - int cursor_row; - - int reflow_from_column; - - guint column_drag : 1; - - guint need_height_update : 1; - guint need_column_resize : 1; - guint need_reflow_columns : 1; - - guint default_cursor_shown : 1; - - guint maybe_did_something : 1; - guint maybe_in_drag : 1; - GdkCursor *arrow_cursor; - GdkCursor *default_cursor; -}; - -struct _EReflowClass -{ - GnomeCanvasGroupClass parent_class; - - int (*selection_event) (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event); - void (*column_width_changed) (EReflow *reflow, double width); -}; - -/* - * To be added to a reflow, an item must have the argument "width" as - * a Read/Write argument and "height" as a Read Only argument. It - * should also do an ECanvas parent reflow request if its size - * changes. - */ -GType e_reflow_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_REFLOW_H__ */ diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 050f840fa8..a588b73b0c 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -31,11 +31,11 @@ #include #include #include +#include #include #include #include -#include #define E_SEARCH_BAR_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/widgets/misc/e-unicode.c b/widgets/misc/e-unicode.c deleted file mode 100644 index 9d660b6600..0000000000 --- a/widgets/misc/e-unicode.c +++ /dev/null @@ -1,2052 +0,0 @@ -/* - * e-unicode.c - utf-8 support functions for gal - * - * 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 - * - * - * Authors: - * Lauris Kaplinski - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* - * TODO: Break simple ligatures in e_utf8_strstrcasedecomp - */ - -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_ALLOCA_H -#include -#endif - -#include -#include -#include - -#include - -#include -#include "e-unicode.h" - -#define d(x) - -#define FONT_TESTING -#define MAX_DECOMP 8 - -static gint e_canonical_decomposition (gunichar ch, gunichar * buf); -static gunichar e_stripped_char (gunichar ch); - -/* FIXME: this has not been ported fully yet - non ASCII people beware. */ - -/* - * This my favourite - * - * strstr doing case insensitive, decomposing search - * - * Lauris - */ - -const gchar * -e_utf8_strstrcasedecomp (const gchar *haystack, const gchar *needle) -{ - gunichar *nuni; - gunichar unival; - gint nlen; - const gchar *o, *p; - - if (haystack == NULL) return NULL; - if (needle == NULL) return NULL; - if (strlen (needle) == 0) return haystack; - if (strlen (haystack) == 0) return NULL; - - nuni = alloca (sizeof (gunichar) * strlen (needle)); - - nlen = 0; - for (p = e_unicode_get_utf8 (needle, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) { - gint sc; - sc = e_stripped_char (unival); - if (sc) { - nuni[nlen++] = sc; - } - } - /* NULL means there was illegal utf-8 sequence */ - if (!p) return NULL; - /* If everything is correct, we have decomposed, lowercase, stripped needle */ - if (nlen < 1) return haystack; - - o = haystack; - for (p = e_unicode_get_utf8 (o, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) { - gint sc; - sc = e_stripped_char (unival); - if (sc) { - /* We have valid stripped char */ - if (sc == nuni[0]) { - const gchar *q = p; - gint npos = 1; - while (npos < nlen) { - q = e_unicode_get_utf8 (q, &unival); - if (!q || !unival) return NULL; - sc = e_stripped_char (unival); - if ((!sc) || (sc != nuni[npos])) break; - npos++; - } - if (npos == nlen) { - return o; - } - } - } - o = p; - } - - return NULL; -} - -const gchar * -e_utf8_strstrcase (const gchar *haystack, const gchar *needle) -{ - gunichar *nuni; - gunichar unival; - gint nlen; - const gchar *o, *p; - - if (haystack == NULL) return NULL; - if (needle == NULL) return NULL; - if (strlen (needle) == 0) return haystack; - if (strlen (haystack) == 0) return NULL; - - nuni = alloca (sizeof (gunichar) * strlen (needle)); - - nlen = 0; - for (p = e_unicode_get_utf8 (needle, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) { - nuni[nlen++] = g_unichar_tolower (unival); - } - /* NULL means there was illegal utf-8 sequence */ - if (!p) return NULL; - - o = haystack; - for (p = e_unicode_get_utf8 (o, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) { - gint sc; - sc = g_unichar_tolower (unival); - /* We have valid stripped char */ - if (sc == nuni[0]) { - const gchar *q = p; - gint npos = 1; - while (npos < nlen) { - q = e_unicode_get_utf8 (q, &unival); - if (!q || !unival) return NULL; - sc = g_unichar_tolower (unival); - if (sc != nuni[npos]) break; - npos++; - } - if (npos == nlen) { - return o; - } - } - o = p; - } - - return NULL; -} - -#if 0 -const gchar * -e_utf8_strstrcase (const gchar *haystack, const gchar *needle) -{ - gchar *p; - gunichar *huni, *nuni; - gunichar unival; - gint hlen, nlen, hp, np; - - if (haystack == NULL) return NULL; - if (needle == NULL) return NULL; - if (strlen (needle) == 0) return haystack; - - huni = alloca (sizeof (gunichar) * strlen (haystack)); - - for (hlen = 0, p = e_unicode_get_utf8 (haystack, &unival); p && unival; hlen++, p = e_unicode_get_utf8 (p, &unival)) { - huni[hlen] = g_unichar_tolower (unival); - } - - if (!p) return NULL; - if (hlen == 0) return NULL; - - nuni = alloca (sizeof (gunichar) * strlen (needle)); - - for (nlen = 0, p = e_unicode_get_utf8 (needle, &unival); p && unival; nlen++, p = e_unicode_get_utf8 (p, &unival)) { - nuni[nlen] = g_unichar_tolower (unival); - } - - if (!p) return NULL; - if (nlen == 0) return NULL; - - if (hlen < nlen) return NULL; - - for (hp = 0; hp <= hlen - nlen; hp++) { - for (np = 0; np < nlen; np++) { - if (huni[hp + np] != nuni[np]) break; - } - if (np == nlen) return haystack + unicode_offset_to_index (haystack, hp); - } - - return NULL; -} -#endif - -gchar * -e_utf8_from_gtk_event_key (GtkWidget *widget, guint keyval, const gchar *string) -{ - gint unival; - gchar *utf; - gint unilen; - - if (keyval == GDK_VoidSymbol) { - utf = e_utf8_from_locale_string (string); - } else { - unival = gdk_keyval_to_unicode (keyval); - - if (unival < ' ') return NULL; - - utf = g_new (gchar, 7); - - unilen = e_unichar_to_utf8 (unival, utf); - - utf[unilen] = '\0'; - } - - return utf; -} - -gchar * -e_utf8_from_iconv_string_sized (iconv_t ic, const gchar *string, gint bytes) -{ - char *new, *ob; - const char *ib; - size_t ibl, obl; - - if (!string) return NULL; - - if (ic == (iconv_t) -1) { - gint i; - /* iso-8859-1 */ - ib = (char *) string; - new = ob = (char *)g_new (unsigned char, bytes * 2 + 1); - for (i = 0; i < (bytes); i ++) { - ob += e_unichar_to_utf8 (ib[i], ob); - } - *ob = '\0'; - return new; - } - - ib = string; - ibl = bytes; - new = ob = g_new (gchar, ibl * 6 + 1); - obl = ibl * 6; - - while (ibl > 0) { - camel_iconv (ic, &ib, &ibl, &ob, &obl); - if (ibl > 0) { - gint len; - if ((*ib & 0x80) == 0x00) len = 1; - else if ((*ib &0xe0) == 0xc0) len = 2; - else if ((*ib &0xf0) == 0xe0) len = 3; - else if ((*ib &0xf8) == 0xf0) len = 4; - else { - g_warning ("Invalid UTF-8 sequence"); - break; - } - ib += len; - ibl = bytes - (ib - string); - if (ibl > bytes) ibl = 0; - *ob++ = '_'; - obl--; - } - } - - *ob = '\0'; - - return new; -} - -gchar * -e_utf8_from_iconv_string (iconv_t ic, const gchar *string) -{ - if (!string) return NULL; - return e_utf8_from_iconv_string_sized (ic, string, strlen (string)); -} - -gchar * -e_utf8_to_iconv_string_sized (iconv_t ic, const gchar *string, gint bytes) -{ - char *new, *ob; - const char *ib; - size_t ibl, obl; - - if (!string) return NULL; - - if (ic == (iconv_t) -1) { - gint len; - const gchar *u; - gunichar uc; - - new = (char *)g_new (unsigned char, bytes * 4 + 1); - u = string; - len = 0; - - while ((u) && (u - string < bytes)) { - u = e_unicode_get_utf8 (u, &uc); - new[len++] = uc & 0xff; - } - new[len] = '\0'; - return new; - } - - ib = string; - ibl = bytes; - new = ob = g_new (char, ibl * 4 + 4); - obl = ibl * 4; - - while (ibl > 0) { - camel_iconv (ic, &ib, &ibl, &ob, &obl); - if (ibl > 0) { - gint len; - if ((*ib & 0x80) == 0x00) len = 1; - else if ((*ib &0xe0) == 0xc0) len = 2; - else if ((*ib &0xf0) == 0xe0) len = 3; - else if ((*ib &0xf8) == 0xf0) len = 4; - else { - g_warning ("Invalid UTF-8 sequence"); - break; - } - ib += len; - ibl = bytes - (ib - string); - if (ibl > bytes) ibl = 0; - - /* FIXME: this is wrong... what if the destination charset is 16 or 32 bit? */ - *ob++ = '_'; - obl--; - } - } - - /* Make sure to terminate with plenty of padding */ - memset (ob, 0, 4); - - return new; -} - -gchar * -e_utf8_to_iconv_string (iconv_t ic, const gchar *string) -{ - if (!string) return NULL; - return e_utf8_to_iconv_string_sized (ic, string, strlen (string)); -} - -gchar * -e_utf8_from_charset_string_sized (const gchar *charset, const gchar *string, gint bytes) -{ - iconv_t ic; - char *ret; - - if (!string) return NULL; - - ic = camel_iconv_open("utf-8", charset); - ret = e_utf8_from_iconv_string_sized (ic, string, bytes); - camel_iconv_close(ic); - - return ret; -} - -gchar * -e_utf8_from_charset_string (const gchar *charset, const gchar *string) -{ - if (!string) return NULL; - return e_utf8_from_charset_string_sized (charset, string, strlen (string)); -} - -gchar * -e_utf8_to_charset_string_sized (const gchar *charset, const gchar *string, gint bytes) -{ - iconv_t ic; - char *ret; - - if (!string) return NULL; - - ic = camel_iconv_open(charset, "utf-8"); - ret = e_utf8_to_iconv_string_sized (ic, string, bytes); - camel_iconv_close(ic); - - return ret; -} - -gchar * -e_utf8_to_charset_string (const gchar *charset, const gchar *string) -{ - if (!string) return NULL; - return e_utf8_to_charset_string_sized (charset, string, strlen (string)); -} - -gchar * -e_utf8_from_locale_string_sized (const gchar *string, gint bytes) -{ - iconv_t ic; - char *ret; - - if (!string) return NULL; - - ic = camel_iconv_open("utf-8", camel_iconv_locale_charset()); - ret = e_utf8_from_iconv_string_sized (ic, string, bytes); - camel_iconv_close(ic); - - return ret; -} - -gchar * -e_utf8_from_locale_string (const gchar *string) -{ - if (!string) return NULL; - return e_utf8_from_locale_string_sized (string, strlen (string)); -} - -gchar * -e_utf8_to_locale_string_sized (const gchar *string, gint bytes) -{ - iconv_t ic; - char *ret; - - if (!string) return NULL; - - ic = camel_iconv_open(camel_iconv_locale_charset(), "utf-8"); - ret = e_utf8_to_iconv_string_sized (ic, string, bytes); - camel_iconv_close(ic); - - return ret; -} - -gchar * -e_utf8_to_locale_string (const gchar *string) -{ - if (!string) return NULL; - return e_utf8_to_locale_string_sized (string, strlen (string)); -} - -gboolean -e_utf8_is_ascii (const gchar *string) -{ - char c; - - g_return_val_if_fail (string != NULL, FALSE); - - for (; (c = *string); string++) { - if (c & 0x80) - return FALSE; - } - - return TRUE; -} - -gchar * -e_utf8_gtk_entry_get_text (GtkEntry *entry) -{ - return g_strdup (gtk_entry_get_text (entry)); -} - -gchar * -e_utf8_gtk_editable_get_text (GtkEditable *editable) -{ - return gtk_editable_get_chars (editable, 0, -1); -} - -gchar * -e_utf8_gtk_editable_get_chars (GtkEditable *editable, gint start, gint end) -{ - return gtk_editable_get_chars (editable, start, end); -} - -void -e_utf8_gtk_editable_insert_text (GtkEditable *editable, const gchar *text, gint length, gint *position) -{ - gtk_editable_insert_text (editable, text, length, position); -} - -void -e_utf8_gtk_editable_set_text (GtkEditable *editable, const gchar *text) -{ - int position; - - gtk_editable_delete_text(editable, 0, -1); - gtk_editable_insert_text (editable, text, strlen (text), &position); -} - -void -e_utf8_gtk_entry_set_text (GtkEntry *entry, const gchar *text) -{ - if (!text) - gtk_entry_set_text(entry, ""); - else - gtk_entry_set_text (entry, text); -} - -/* - * Translate \U+XXXX\ sequences to utf8 chars - */ - -gchar * -e_utf8_xml1_decode (const gchar *text) -{ - const guchar *c; - gchar *u, *d; - int len, s; - - g_return_val_if_fail (text != NULL, NULL); - - len = strlen (text)+1; - /* len * 2 is absolute maximum */ - u = d = g_malloc (len * 2); - - c = (guchar *)text; - s = 0; - while (s < len) { - if ((s <= (len - 8)) && - (c[s ] == '\\') && - (c[s + 1] == 'U' ) && - (c[s + 2] == '+' ) && - isxdigit (c[s + 3]) && - isxdigit (c[s + 4]) && - isxdigit (c[s + 5]) && - isxdigit (c[s + 6]) && - (c[s + 7] == '\\')) { - /* Valid \U+XXXX\ sequence */ - int unival; - unival = strtol ((char *)(c + s + 3), NULL, 16); - d += e_unichar_to_utf8 (unival, d); - s += 8; - } else if (c[s] > 127) { - /* fixme: We assume iso-8859-1 currently */ - d += e_unichar_to_utf8 (c[s], d); - s += 1; - } else { - *d++ = c[s++]; - } - } - *d++ = '\0'; - u = g_realloc (u, (d - u)); - - return u; -} - -gchar * -e_utf8_xml1_encode (const gchar *text) -{ - gchar *u, *d, *c; - unsigned int unival; - int len; - - g_return_val_if_fail (text != NULL, NULL); - - len = 0; - for (u = e_unicode_get_utf8 (text, &unival); u && unival; u = e_unicode_get_utf8 (u, &unival)) { - if ((unival >= 0x80) || (unival == '\\')) { - len += 8; - } else { - len += 1; - } - } - d = c = (char *)g_new (guchar, len + 1); - - for (u = e_unicode_get_utf8 (text, &unival); u && unival; u = e_unicode_get_utf8 (u, &unival)) { - if ((unival >= 0x80) || (unival == '\\')) { - *c++ = '\\'; - *c++ = 'U'; - *c++ = '+'; - c += sprintf (c, "%04x", unival); - *c++ = '\\'; - } else { - *c++ = unival; - } - } - *c = '\0'; - - return d; -} - -/** - * e_unichar_to_utf8: - * @c: a ISO10646 character code - * @outbuf: output buffer, must have at least 6 bytes of space. - * If %NULL, the length will be computed and returned - * and nothing will be written to @out. - * - * Convert a single character to utf8 - * - * Return value: number of bytes written - **/ - -gint -e_unichar_to_utf8 (gint c, gchar *outbuf) -{ - size_t len = 0; - int first; - int i; - - if (c < 0x80) - { - first = 0; - len = 1; - } - else if (c < 0x800) - { - first = 0xc0; - len = 2; - } - else if (c < 0x10000) - { - first = 0xe0; - len = 3; - } - else if (c < 0x200000) - { - first = 0xf0; - len = 4; - } - else if (c < 0x4000000) - { - first = 0xf8; - len = 5; - } - else - { - first = 0xfc; - len = 6; - } - - if (outbuf) - { - for (i = len - 1; i > 0; --i) - { - outbuf[i] = (c & 0x3f) | 0x80; - c >>= 6; - } - outbuf[0] = c | first; - } - - return len; -} - -gchar * -e_unicode_get_utf8 (const gchar *text, gunichar *out) -{ - *out = g_utf8_get_char (text); - return (*out == (gunichar)-1) ? NULL : g_utf8_next_char (text); -} - -/* - * Canonical decomposition - * - * It is copied here from libunicode, because we do not want malloc - * - */ - -typedef struct -{ - unsigned short ch; - char *expansion; -} e_decomposition; - -static e_decomposition e_decomp_table[] = -{ - { 0x00c0, "\x00\x41\x03\x00\0" }, - { 0x00c1, "\x00\x41\x03\x01\0" }, - { 0x00c2, "\x00\x41\x03\x02\0" }, - { 0x00c3, "\x00\x41\x03\x03\0" }, - { 0x00c4, "\x00\x41\x03\x08\0" }, - { 0x00c5, "\x00\x41\x03\x0a\0" }, - { 0x00c7, "\x00\x43\x03\x27\0" }, - { 0x00c8, "\x00\x45\x03\x00\0" }, - { 0x00c9, "\x00\x45\x03\x01\0" }, - { 0x00ca, "\x00\x45\x03\x02\0" }, - { 0x00cb, "\x00\x45\x03\x08\0" }, - { 0x00cc, "\x00\x49\x03\x00\0" }, - { 0x00cd, "\x00\x49\x03\x01\0" }, - { 0x00ce, "\x00\x49\x03\x02\0" }, - { 0x00cf, "\x00\x49\x03\x08\0" }, - { 0x00d1, "\x00\x4e\x03\x03\0" }, - { 0x00d2, "\x00\x4f\x03\x00\0" }, - { 0x00d3, "\x00\x4f\x03\x01\0" }, - { 0x00d4, "\x00\x4f\x03\x02\0" }, - { 0x00d5, "\x00\x4f\x03\x03\0" }, - { 0x00d6, "\x00\x4f\x03\x08\0" }, - { 0x00d9, "\x00\x55\x03\x00\0" }, - { 0x00da, "\x00\x55\x03\x01\0" }, - { 0x00db, "\x00\x55\x03\x02\0" }, - { 0x00dc, "\x00\x55\x03\x08\0" }, - { 0x00dd, "\x00\x59\x03\x01\0" }, - { 0x00e0, "\x00\x61\x03\x00\0" }, - { 0x00e1, "\x00\x61\x03\x01\0" }, - { 0x00e2, "\x00\x61\x03\x02\0" }, - { 0x00e3, "\x00\x61\x03\x03\0" }, - { 0x00e4, "\x00\x61\x03\x08\0" }, - { 0x00e5, "\x00\x61\x03\x0a\0" }, - { 0x00e7, "\x00\x63\x03\x27\0" }, - { 0x00e8, "\x00\x65\x03\x00\0" }, - { 0x00e9, "\x00\x65\x03\x01\0" }, - { 0x00ea, "\x00\x65\x03\x02\0" }, - { 0x00eb, "\x00\x65\x03\x08\0" }, - { 0x00ec, "\x00\x69\x03\x00\0" }, - { 0x00ed, "\x00\x69\x03\x01\0" }, - { 0x00ee, "\x00\x69\x03\x02\0" }, - { 0x00ef, "\x00\x69\x03\x08\0" }, - { 0x00f1, "\x00\x6e\x03\x03\0" }, - { 0x00f2, "\x00\x6f\x03\x00\0" }, - { 0x00f3, "\x00\x6f\x03\x01\0" }, - { 0x00f4, "\x00\x6f\x03\x02\0" }, - { 0x00f5, "\x00\x6f\x03\x03\0" }, - { 0x00f6, "\x00\x6f\x03\x08\0" }, - { 0x00f9, "\x00\x75\x03\x00\0" }, - { 0x00fa, "\x00\x75\x03\x01\0" }, - { 0x00fb, "\x00\x75\x03\x02\0" }, - { 0x00fc, "\x00\x75\x03\x08\0" }, - { 0x00fd, "\x00\x79\x03\x01\0" }, - { 0x00ff, "\x00\x79\x03\x08\0" }, - { 0x0100, "\x00\x41\x03\x04\0" }, - { 0x0101, "\x00\x61\x03\x04\0" }, - { 0x0102, "\x00\x41\x03\x06\0" }, - { 0x0103, "\x00\x61\x03\x06\0" }, - { 0x0104, "\x00\x41\x03\x28\0" }, - { 0x0105, "\x00\x61\x03\x28\0" }, - { 0x0106, "\x00\x43\x03\x01\0" }, - { 0x0107, "\x00\x63\x03\x01\0" }, - { 0x0108, "\x00\x43\x03\x02\0" }, - { 0x0109, "\x00\x63\x03\x02\0" }, - { 0x010a, "\x00\x43\x03\x07\0" }, - { 0x010b, "\x00\x63\x03\x07\0" }, - { 0x010c, "\x00\x43\x03\x0c\0" }, - { 0x010d, "\x00\x63\x03\x0c\0" }, - { 0x010e, "\x00\x44\x03\x0c\0" }, - { 0x010f, "\x00\x64\x03\x0c\0" }, - { 0x0112, "\x00\x45\x03\x04\0" }, - { 0x0113, "\x00\x65\x03\x04\0" }, - { 0x0114, "\x00\x45\x03\x06\0" }, - { 0x0115, "\x00\x65\x03\x06\0" }, - { 0x0116, "\x00\x45\x03\x07\0" }, - { 0x0117, "\x00\x65\x03\x07\0" }, - { 0x0118, "\x00\x45\x03\x28\0" }, - { 0x0119, "\x00\x65\x03\x28\0" }, - { 0x011a, "\x00\x45\x03\x0c\0" }, - { 0x011b, "\x00\x65\x03\x0c\0" }, - { 0x011c, "\x00\x47\x03\x02\0" }, - { 0x011d, "\x00\x67\x03\x02\0" }, - { 0x011e, "\x00\x47\x03\x06\0" }, - { 0x011f, "\x00\x67\x03\x06\0" }, - { 0x0120, "\x00\x47\x03\x07\0" }, - { 0x0121, "\x00\x67\x03\x07\0" }, - { 0x0122, "\x00\x47\x03\x27\0" }, - { 0x0123, "\x00\x67\x03\x27\0" }, - { 0x0124, "\x00\x48\x03\x02\0" }, - { 0x0125, "\x00\x68\x03\x02\0" }, - { 0x0128, "\x00\x49\x03\x03\0" }, - { 0x0129, "\x00\x69\x03\x03\0" }, - { 0x012a, "\x00\x49\x03\x04\0" }, - { 0x012b, "\x00\x69\x03\x04\0" }, - { 0x012c, "\x00\x49\x03\x06\0" }, - { 0x012d, "\x00\x69\x03\x06\0" }, - { 0x012e, "\x00\x49\x03\x28\0" }, - { 0x012f, "\x00\x69\x03\x28\0" }, - { 0x0130, "\x00\x49\x03\x07\0" }, - { 0x0134, "\x00\x4a\x03\x02\0" }, - { 0x0135, "\x00\x6a\x03\x02\0" }, - { 0x0136, "\x00\x4b\x03\x27\0" }, - { 0x0137, "\x00\x6b\x03\x27\0" }, - { 0x0139, "\x00\x4c\x03\x01\0" }, - { 0x013a, "\x00\x6c\x03\x01\0" }, - { 0x013b, "\x00\x4c\x03\x27\0" }, - { 0x013c, "\x00\x6c\x03\x27\0" }, - { 0x013d, "\x00\x4c\x03\x0c\0" }, - { 0x013e, "\x00\x6c\x03\x0c\0" }, - { 0x0143, "\x00\x4e\x03\x01\0" }, - { 0x0144, "\x00\x6e\x03\x01\0" }, - { 0x0145, "\x00\x4e\x03\x27\0" }, - { 0x0146, "\x00\x6e\x03\x27\0" }, - { 0x0147, "\x00\x4e\x03\x0c\0" }, - { 0x0148, "\x00\x6e\x03\x0c\0" }, - { 0x014c, "\x00\x4f\x03\x04\0" }, - { 0x014d, "\x00\x6f\x03\x04\0" }, - { 0x014e, "\x00\x4f\x03\x06\0" }, - { 0x014f, "\x00\x6f\x03\x06\0" }, - { 0x0150, "\x00\x4f\x03\x0b\0" }, - { 0x0151, "\x00\x6f\x03\x0b\0" }, - { 0x0154, "\x00\x52\x03\x01\0" }, - { 0x0155, "\x00\x72\x03\x01\0" }, - { 0x0156, "\x00\x52\x03\x27\0" }, - { 0x0157, "\x00\x72\x03\x27\0" }, - { 0x0158, "\x00\x52\x03\x0c\0" }, - { 0x0159, "\x00\x72\x03\x0c\0" }, - { 0x015a, "\x00\x53\x03\x01\0" }, - { 0x015b, "\x00\x73\x03\x01\0" }, - { 0x015c, "\x00\x53\x03\x02\0" }, - { 0x015d, "\x00\x73\x03\x02\0" }, - { 0x015e, "\x00\x53\x03\x27\0" }, - { 0x015f, "\x00\x73\x03\x27\0" }, - { 0x0160, "\x00\x53\x03\x0c\0" }, - { 0x0161, "\x00\x73\x03\x0c\0" }, - { 0x0162, "\x00\x54\x03\x27\0" }, - { 0x0163, "\x00\x74\x03\x27\0" }, - { 0x0164, "\x00\x54\x03\x0c\0" }, - { 0x0165, "\x00\x74\x03\x0c\0" }, - { 0x0168, "\x00\x55\x03\x03\0" }, - { 0x0169, "\x00\x75\x03\x03\0" }, - { 0x016a, "\x00\x55\x03\x04\0" }, - { 0x016b, "\x00\x75\x03\x04\0" }, - { 0x016c, "\x00\x55\x03\x06\0" }, - { 0x016d, "\x00\x75\x03\x06\0" }, - { 0x016e, "\x00\x55\x03\x0a\0" }, - { 0x016f, "\x00\x75\x03\x0a\0" }, - { 0x0170, "\x00\x55\x03\x0b\0" }, - { 0x0171, "\x00\x75\x03\x0b\0" }, - { 0x0172, "\x00\x55\x03\x28\0" }, - { 0x0173, "\x00\x75\x03\x28\0" }, - { 0x0174, "\x00\x57\x03\x02\0" }, - { 0x0175, "\x00\x77\x03\x02\0" }, - { 0x0176, "\x00\x59\x03\x02\0" }, - { 0x0177, "\x00\x79\x03\x02\0" }, - { 0x0178, "\x00\x59\x03\x08\0" }, - { 0x0179, "\x00\x5a\x03\x01\0" }, - { 0x017a, "\x00\x7a\x03\x01\0" }, - { 0x017b, "\x00\x5a\x03\x07\0" }, - { 0x017c, "\x00\x7a\x03\x07\0" }, - { 0x017d, "\x00\x5a\x03\x0c\0" }, - { 0x017e, "\x00\x7a\x03\x0c\0" }, - { 0x01a0, "\x00\x4f\x03\x1b\0" }, - { 0x01a1, "\x00\x6f\x03\x1b\0" }, - { 0x01af, "\x00\x55\x03\x1b\0" }, - { 0x01b0, "\x00\x75\x03\x1b\0" }, - { 0x01cd, "\x00\x41\x03\x0c\0" }, - { 0x01ce, "\x00\x61\x03\x0c\0" }, - { 0x01cf, "\x00\x49\x03\x0c\0" }, - { 0x01d0, "\x00\x69\x03\x0c\0" }, - { 0x01d1, "\x00\x4f\x03\x0c\0" }, - { 0x01d2, "\x00\x6f\x03\x0c\0" }, - { 0x01d3, "\x00\x55\x03\x0c\0" }, - { 0x01d4, "\x00\x75\x03\x0c\0" }, - { 0x01d5, "\x00\x55\x03\x08\x03\x04\0" }, - { 0x01d6, "\x00\x75\x03\x08\x03\x04\0" }, - { 0x01d7, "\x00\x55\x03\x08\x03\x01\0" }, - { 0x01d8, "\x00\x75\x03\x08\x03\x01\0" }, - { 0x01d9, "\x00\x55\x03\x08\x03\x0c\0" }, - { 0x01da, "\x00\x75\x03\x08\x03\x0c\0" }, - { 0x01db, "\x00\x55\x03\x08\x03\x00\0" }, - { 0x01dc, "\x00\x75\x03\x08\x03\x00\0" }, - { 0x01de, "\x00\x41\x03\x08\x03\x04\0" }, - { 0x01df, "\x00\x61\x03\x08\x03\x04\0" }, - { 0x01e0, "\x00\x41\x03\x07\x03\x04\0" }, - { 0x01e1, "\x00\x61\x03\x07\x03\x04\0" }, - { 0x01e2, "\x00\xc6\x03\x04\0" }, - { 0x01e3, "\x00\xe6\x03\x04\0" }, - { 0x01e6, "\x00\x47\x03\x0c\0" }, - { 0x01e7, "\x00\x67\x03\x0c\0" }, - { 0x01e8, "\x00\x4b\x03\x0c\0" }, - { 0x01e9, "\x00\x6b\x03\x0c\0" }, - { 0x01ea, "\x00\x4f\x03\x28\0" }, - { 0x01eb, "\x00\x6f\x03\x28\0" }, - { 0x01ec, "\x00\x4f\x03\x28\x03\x04\0" }, - { 0x01ed, "\x00\x6f\x03\x28\x03\x04\0" }, - { 0x01ee, "\x01\xb7\x03\x0c\0" }, - { 0x01ef, "\x02\x92\x03\x0c\0" }, - { 0x01f0, "\x00\x6a\x03\x0c\0" }, - { 0x01f4, "\x00\x47\x03\x01\0" }, - { 0x01f5, "\x00\x67\x03\x01\0" }, - { 0x01fa, "\x00\x41\x03\x0a\x03\x01\0" }, - { 0x01fb, "\x00\x61\x03\x0a\x03\x01\0" }, - { 0x01fc, "\x00\xc6\x03\x01\0" }, - { 0x01fd, "\x00\xe6\x03\x01\0" }, - { 0x01fe, "\x00\xd8\x03\x01\0" }, - { 0x01ff, "\x00\xf8\x03\x01\0" }, - { 0x0200, "\x00\x41\x03\x0f\0" }, - { 0x0201, "\x00\x61\x03\x0f\0" }, - { 0x0202, "\x00\x41\x03\x11\0" }, - { 0x0203, "\x00\x61\x03\x11\0" }, - { 0x0204, "\x00\x45\x03\x0f\0" }, - { 0x0205, "\x00\x65\x03\x0f\0" }, - { 0x0206, "\x00\x45\x03\x11\0" }, - { 0x0207, "\x00\x65\x03\x11\0" }, - { 0x0208, "\x00\x49\x03\x0f\0" }, - { 0x0209, "\x00\x69\x03\x0f\0" }, - { 0x020a, "\x00\x49\x03\x11\0" }, - { 0x020b, "\x00\x69\x03\x11\0" }, - { 0x020c, "\x00\x4f\x03\x0f\0" }, - { 0x020d, "\x00\x6f\x03\x0f\0" }, - { 0x020e, "\x00\x4f\x03\x11\0" }, - { 0x020f, "\x00\x6f\x03\x11\0" }, - { 0x0210, "\x00\x52\x03\x0f\0" }, - { 0x0211, "\x00\x72\x03\x0f\0" }, - { 0x0212, "\x00\x52\x03\x11\0" }, - { 0x0213, "\x00\x72\x03\x11\0" }, - { 0x0214, "\x00\x55\x03\x0f\0" }, - { 0x0215, "\x00\x75\x03\x0f\0" }, - { 0x0216, "\x00\x55\x03\x11\0" }, - { 0x0217, "\x00\x75\x03\x11\0" }, - { 0x0340, "\x03\x00\0" }, - { 0x0341, "\x03\x01\0" }, - { 0x0343, "\x03\x13\0" }, - { 0x0344, "\x03\x08\x03\x01\0" }, - { 0x0374, "\x02\xb9\0" }, - { 0x037e, "\x00\x3b\0" }, - { 0x0385, "\x00\xa8\x03\x01\0" }, - { 0x0386, "\x03\x91\x03\x01\0" }, - { 0x0387, "\x00\xb7\0" }, - { 0x0388, "\x03\x95\x03\x01\0" }, - { 0x0389, "\x03\x97\x03\x01\0" }, - { 0x038a, "\x03\x99\x03\x01\0" }, - { 0x038c, "\x03\x9f\x03\x01\0" }, - { 0x038e, "\x03\xa5\x03\x01\0" }, - { 0x038f, "\x03\xa9\x03\x01\0" }, - { 0x0390, "\x03\xb9\x03\x08\x03\x01\0" }, - { 0x03aa, "\x03\x99\x03\x08\0" }, - { 0x03ab, "\x03\xa5\x03\x08\0" }, - { 0x03ac, "\x03\xb1\x03\x01\0" }, - { 0x03ad, "\x03\xb5\x03\x01\0" }, - { 0x03ae, "\x03\xb7\x03\x01\0" }, - { 0x03af, "\x03\xb9\x03\x01\0" }, - { 0x03b0, "\x03\xc5\x03\x08\x03\x01\0" }, - { 0x03ca, "\x03\xb9\x03\x08\0" }, - { 0x03cb, "\x03\xc5\x03\x08\0" }, - { 0x03cc, "\x03\xbf\x03\x01\0" }, - { 0x03cd, "\x03\xc5\x03\x01\0" }, - { 0x03ce, "\x03\xc9\x03\x01\0" }, - { 0x03d3, "\x03\xd2\x03\x01\0" }, - { 0x03d4, "\x03\xd2\x03\x08\0" }, - { 0x0401, "\x04\x15\x03\x08\0" }, - { 0x0403, "\x04\x13\x03\x01\0" }, - { 0x0407, "\x04\x06\x03\x08\0" }, - { 0x040c, "\x04\x1a\x03\x01\0" }, - { 0x040e, "\x04\x23\x03\x06\0" }, - { 0x0419, "\x04\x18\x03\x06\0" }, - { 0x0439, "\x04\x38\x03\x06\0" }, - { 0x0451, "\x04\x35\x03\x08\0" }, - { 0x0453, "\x04\x33\x03\x01\0" }, - { 0x0457, "\x04\x56\x03\x08\0" }, - { 0x045c, "\x04\x3a\x03\x01\0" }, - { 0x045e, "\x04\x43\x03\x06\0" }, - { 0x0476, "\x04\x74\x03\x0f\0" }, - { 0x0477, "\x04\x75\x03\x0f\0" }, - { 0x04c1, "\x04\x16\x03\x06\0" }, - { 0x04c2, "\x04\x36\x03\x06\0" }, - { 0x04d0, "\x04\x10\x03\x06\0" }, - { 0x04d1, "\x04\x30\x03\x06\0" }, - { 0x04d2, "\x04\x10\x03\x08\0" }, - { 0x04d3, "\x04\x30\x03\x08\0" }, - { 0x04d6, "\x04\x15\x03\x06\0" }, - { 0x04d7, "\x04\x35\x03\x06\0" }, - { 0x04da, "\x04\xd8\x03\x08\0" }, - { 0x04db, "\x04\xd9\x03\x08\0" }, - { 0x04dc, "\x04\x16\x03\x08\0" }, - { 0x04dd, "\x04\x36\x03\x08\0" }, - { 0x04de, "\x04\x17\x03\x08\0" }, - { 0x04df, "\x04\x37\x03\x08\0" }, - { 0x04e2, "\x04\x18\x03\x04\0" }, - { 0x04e3, "\x04\x38\x03\x04\0" }, - { 0x04e4, "\x04\x18\x03\x08\0" }, - { 0x04e5, "\x04\x38\x03\x08\0" }, - { 0x04e6, "\x04\x1e\x03\x08\0" }, - { 0x04e7, "\x04\x3e\x03\x08\0" }, - { 0x04ea, "\x04\xe8\x03\x08\0" }, - { 0x04eb, "\x04\xe9\x03\x08\0" }, - { 0x04ee, "\x04\x23\x03\x04\0" }, - { 0x04ef, "\x04\x43\x03\x04\0" }, - { 0x04f0, "\x04\x23\x03\x08\0" }, - { 0x04f1, "\x04\x43\x03\x08\0" }, - { 0x04f2, "\x04\x23\x03\x0b\0" }, - { 0x04f3, "\x04\x43\x03\x0b\0" }, - { 0x04f4, "\x04\x27\x03\x08\0" }, - { 0x04f5, "\x04\x47\x03\x08\0" }, - { 0x04f8, "\x04\x2b\x03\x08\0" }, - { 0x04f9, "\x04\x4b\x03\x08\0" }, - { 0x0929, "\x09\x28\x09\x3c\0" }, - { 0x0931, "\x09\x30\x09\x3c\0" }, - { 0x0934, "\x09\x33\x09\x3c\0" }, - { 0x0958, "\x09\x15\x09\x3c\0" }, - { 0x0959, "\x09\x16\x09\x3c\0" }, - { 0x095a, "\x09\x17\x09\x3c\0" }, - { 0x095b, "\x09\x1c\x09\x3c\0" }, - { 0x095c, "\x09\x21\x09\x3c\0" }, - { 0x095d, "\x09\x22\x09\x3c\0" }, - { 0x095e, "\x09\x2b\x09\x3c\0" }, - { 0x095f, "\x09\x2f\x09\x3c\0" }, - { 0x09b0, "\x09\xac\x09\xbc\0" }, - { 0x09cb, "\x09\xc7\x09\xbe\0" }, - { 0x09cc, "\x09\xc7\x09\xd7\0" }, - { 0x09dc, "\x09\xa1\x09\xbc\0" }, - { 0x09dd, "\x09\xa2\x09\xbc\0" }, - { 0x09df, "\x09\xaf\x09\xbc\0" }, - { 0x0a59, "\x0a\x16\x0a\x3c\0" }, - { 0x0a5a, "\x0a\x17\x0a\x3c\0" }, - { 0x0a5b, "\x0a\x1c\x0a\x3c\0" }, - { 0x0a5c, "\x0a\x21\x0a\x3c\0" }, - { 0x0a5e, "\x0a\x2b\x0a\x3c\0" }, - { 0x0b48, "\x0b\x47\x0b\x56\0" }, - { 0x0b4b, "\x0b\x47\x0b\x3e\0" }, - { 0x0b4c, "\x0b\x47\x0b\x57\0" }, - { 0x0b5c, "\x0b\x21\x0b\x3c\0" }, - { 0x0b5d, "\x0b\x22\x0b\x3c\0" }, - { 0x0b5f, "\x0b\x2f\x0b\x3c\0" }, - { 0x0b94, "\x0b\x92\x0b\xd7\0" }, - { 0x0bca, "\x0b\xc6\x0b\xbe\0" }, - { 0x0bcb, "\x0b\xc7\x0b\xbe\0" }, - { 0x0bcc, "\x0b\xc6\x0b\xd7\0" }, - { 0x0c48, "\x0c\x46\x0c\x56\0" }, - { 0x0cc0, "\x0c\xbf\x0c\xd5\0" }, - { 0x0cc7, "\x0c\xc6\x0c\xd5\0" }, - { 0x0cc8, "\x0c\xc6\x0c\xd6\0" }, - { 0x0cca, "\x0c\xc6\x0c\xc2\0" }, - { 0x0ccb, "\x0c\xc6\x0c\xc2\x0c\xd5\0" }, - { 0x0d4a, "\x0d\x46\x0d\x3e\0" }, - { 0x0d4b, "\x0d\x47\x0d\x3e\0" }, - { 0x0d4c, "\x0d\x46\x0d\x57\0" }, - { 0x0e33, "\x0e\x4d\x0e\x32\0" }, - { 0x0eb3, "\x0e\xcd\x0e\xb2\0" }, - { 0x0f43, "\x0f\x42\x0f\xb7\0" }, - { 0x0f4d, "\x0f\x4c\x0f\xb7\0" }, - { 0x0f52, "\x0f\x51\x0f\xb7\0" }, - { 0x0f57, "\x0f\x56\x0f\xb7\0" }, - { 0x0f5c, "\x0f\x5b\x0f\xb7\0" }, - { 0x0f69, "\x0f\x40\x0f\xb5\0" }, - { 0x0f73, "\x0f\x71\x0f\x72\0" }, - { 0x0f75, "\x0f\x71\x0f\x74\0" }, - { 0x0f76, "\x0f\xb2\x0f\x80\0" }, - { 0x0f78, "\x0f\xb3\x0f\x80\0" }, - { 0x0f81, "\x0f\x71\x0f\x80\0" }, - { 0x0f93, "\x0f\x92\x0f\xb7\0" }, - { 0x0f9d, "\x0f\x9c\x0f\xb7\0" }, - { 0x0fa2, "\x0f\xa1\x0f\xb7\0" }, - { 0x0fa7, "\x0f\xa6\x0f\xb7\0" }, - { 0x0fac, "\x0f\xab\x0f\xb7\0" }, - { 0x0fb9, "\x0f\x90\x0f\xb5\0" }, - { 0x1e00, "\x00\x41\x03\x25\0" }, - { 0x1e01, "\x00\x61\x03\x25\0" }, - { 0x1e02, "\x00\x42\x03\x07\0" }, - { 0x1e03, "\x00\x62\x03\x07\0" }, - { 0x1e04, "\x00\x42\x03\x23\0" }, - { 0x1e05, "\x00\x62\x03\x23\0" }, - { 0x1e06, "\x00\x42\x03\x31\0" }, - { 0x1e07, "\x00\x62\x03\x31\0" }, - { 0x1e08, "\x00\x43\x03\x27\x03\x01\0" }, - { 0x1e09, "\x00\x63\x03\x27\x03\x01\0" }, - { 0x1e0a, "\x00\x44\x03\x07\0" }, - { 0x1e0b, "\x00\x64\x03\x07\0" }, - { 0x1e0c, "\x00\x44\x03\x23\0" }, - { 0x1e0d, "\x00\x64\x03\x23\0" }, - { 0x1e0e, "\x00\x44\x03\x31\0" }, - { 0x1e0f, "\x00\x64\x03\x31\0" }, - { 0x1e10, "\x00\x44\x03\x27\0" }, - { 0x1e11, "\x00\x64\x03\x27\0" }, - { 0x1e12, "\x00\x44\x03\x2d\0" }, - { 0x1e13, "\x00\x64\x03\x2d\0" }, - { 0x1e14, "\x00\x45\x03\x04\x03\x00\0" }, - { 0x1e15, "\x00\x65\x03\x04\x03\x00\0" }, - { 0x1e16, "\x00\x45\x03\x04\x03\x01\0" }, - { 0x1e17, "\x00\x65\x03\x04\x03\x01\0" }, - { 0x1e18, "\x00\x45\x03\x2d\0" }, - { 0x1e19, "\x00\x65\x03\x2d\0" }, - { 0x1e1a, "\x00\x45\x03\x30\0" }, - { 0x1e1b, "\x00\x65\x03\x30\0" }, - { 0x1e1c, "\x00\x45\x03\x27\x03\x06\0" }, - { 0x1e1d, "\x00\x65\x03\x27\x03\x06\0" }, - { 0x1e1e, "\x00\x46\x03\x07\0" }, - { 0x1e1f, "\x00\x66\x03\x07\0" }, - { 0x1e20, "\x00\x47\x03\x04\0" }, - { 0x1e21, "\x00\x67\x03\x04\0" }, - { 0x1e22, "\x00\x48\x03\x07\0" }, - { 0x1e23, "\x00\x68\x03\x07\0" }, - { 0x1e24, "\x00\x48\x03\x23\0" }, - { 0x1e25, "\x00\x68\x03\x23\0" }, - { 0x1e26, "\x00\x48\x03\x08\0" }, - { 0x1e27, "\x00\x68\x03\x08\0" }, - { 0x1e28, "\x00\x48\x03\x27\0" }, - { 0x1e29, "\x00\x68\x03\x27\0" }, - { 0x1e2a, "\x00\x48\x03\x2e\0" }, - { 0x1e2b, "\x00\x68\x03\x2e\0" }, - { 0x1e2c, "\x00\x49\x03\x30\0" }, - { 0x1e2d, "\x00\x69\x03\x30\0" }, - { 0x1e2e, "\x00\x49\x03\x08\x03\x01\0" }, - { 0x1e2f, "\x00\x69\x03\x08\x03\x01\0" }, - { 0x1e30, "\x00\x4b\x03\x01\0" }, - { 0x1e31, "\x00\x6b\x03\x01\0" }, - { 0x1e32, "\x00\x4b\x03\x23\0" }, - { 0x1e33, "\x00\x6b\x03\x23\0" }, - { 0x1e34, "\x00\x4b\x03\x31\0" }, - { 0x1e35, "\x00\x6b\x03\x31\0" }, - { 0x1e36, "\x00\x4c\x03\x23\0" }, - { 0x1e37, "\x00\x6c\x03\x23\0" }, - { 0x1e38, "\x00\x4c\x03\x23\x03\x04\0" }, - { 0x1e39, "\x00\x6c\x03\x23\x03\x04\0" }, - { 0x1e3a, "\x00\x4c\x03\x31\0" }, - { 0x1e3b, "\x00\x6c\x03\x31\0" }, - { 0x1e3c, "\x00\x4c\x03\x2d\0" }, - { 0x1e3d, "\x00\x6c\x03\x2d\0" }, - { 0x1e3e, "\x00\x4d\x03\x01\0" }, - { 0x1e3f, "\x00\x6d\x03\x01\0" }, - { 0x1e40, "\x00\x4d\x03\x07\0" }, - { 0x1e41, "\x00\x6d\x03\x07\0" }, - { 0x1e42, "\x00\x4d\x03\x23\0" }, - { 0x1e43, "\x00\x6d\x03\x23\0" }, - { 0x1e44, "\x00\x4e\x03\x07\0" }, - { 0x1e45, "\x00\x6e\x03\x07\0" }, - { 0x1e46, "\x00\x4e\x03\x23\0" }, - { 0x1e47, "\x00\x6e\x03\x23\0" }, - { 0x1e48, "\x00\x4e\x03\x31\0" }, - { 0x1e49, "\x00\x6e\x03\x31\0" }, - { 0x1e4a, "\x00\x4e\x03\x2d\0" }, - { 0x1e4b, "\x00\x6e\x03\x2d\0" }, - { 0x1e4c, "\x00\x4f\x03\x03\x03\x01\0" }, - { 0x1e4d, "\x00\x6f\x03\x03\x03\x01\0" }, - { 0x1e4e, "\x00\x4f\x03\x03\x03\x08\0" }, - { 0x1e4f, "\x00\x6f\x03\x03\x03\x08\0" }, - { 0x1e50, "\x00\x4f\x03\x04\x03\x00\0" }, - { 0x1e51, "\x00\x6f\x03\x04\x03\x00\0" }, - { 0x1e52, "\x00\x4f\x03\x04\x03\x01\0" }, - { 0x1e53, "\x00\x6f\x03\x04\x03\x01\0" }, - { 0x1e54, "\x00\x50\x03\x01\0" }, - { 0x1e55, "\x00\x70\x03\x01\0" }, - { 0x1e56, "\x00\x50\x03\x07\0" }, - { 0x1e57, "\x00\x70\x03\x07\0" }, - { 0x1e58, "\x00\x52\x03\x07\0" }, - { 0x1e59, "\x00\x72\x03\x07\0" }, - { 0x1e5a, "\x00\x52\x03\x23\0" }, - { 0x1e5b, "\x00\x72\x03\x23\0" }, - { 0x1e5c, "\x00\x52\x03\x23\x03\x04\0" }, - { 0x1e5d, "\x00\x72\x03\x23\x03\x04\0" }, - { 0x1e5e, "\x00\x52\x03\x31\0" }, - { 0x1e5f, "\x00\x72\x03\x31\0" }, - { 0x1e60, "\x00\x53\x03\x07\0" }, - { 0x1e61, "\x00\x73\x03\x07\0" }, - { 0x1e62, "\x00\x53\x03\x23\0" }, - { 0x1e63, "\x00\x73\x03\x23\0" }, - { 0x1e64, "\x00\x53\x03\x01\x03\x07\0" }, - { 0x1e65, "\x00\x73\x03\x01\x03\x07\0" }, - { 0x1e66, "\x00\x53\x03\x0c\x03\x07\0" }, - { 0x1e67, "\x00\x73\x03\x0c\x03\x07\0" }, - { 0x1e68, "\x00\x53\x03\x23\x03\x07\0" }, - { 0x1e69, "\x00\x73\x03\x23\x03\x07\0" }, - { 0x1e6a, "\x00\x54\x03\x07\0" }, - { 0x1e6b, "\x00\x74\x03\x07\0" }, - { 0x1e6c, "\x00\x54\x03\x23\0" }, - { 0x1e6d, "\x00\x74\x03\x23\0" }, - { 0x1e6e, "\x00\x54\x03\x31\0" }, - { 0x1e6f, "\x00\x74\x03\x31\0" }, - { 0x1e70, "\x00\x54\x03\x2d\0" }, - { 0x1e71, "\x00\x74\x03\x2d\0" }, - { 0x1e72, "\x00\x55\x03\x24\0" }, - { 0x1e73, "\x00\x75\x03\x24\0" }, - { 0x1e74, "\x00\x55\x03\x30\0" }, - { 0x1e75, "\x00\x75\x03\x30\0" }, - { 0x1e76, "\x00\x55\x03\x2d\0" }, - { 0x1e77, "\x00\x75\x03\x2d\0" }, - { 0x1e78, "\x00\x55\x03\x03\x03\x01\0" }, - { 0x1e79, "\x00\x75\x03\x03\x03\x01\0" }, - { 0x1e7a, "\x00\x55\x03\x04\x03\x08\0" }, - { 0x1e7b, "\x00\x75\x03\x04\x03\x08\0" }, - { 0x1e7c, "\x00\x56\x03\x03\0" }, - { 0x1e7d, "\x00\x76\x03\x03\0" }, - { 0x1e7e, "\x00\x56\x03\x23\0" }, - { 0x1e7f, "\x00\x76\x03\x23\0" }, - { 0x1e80, "\x00\x57\x03\x00\0" }, - { 0x1e81, "\x00\x77\x03\x00\0" }, - { 0x1e82, "\x00\x57\x03\x01\0" }, - { 0x1e83, "\x00\x77\x03\x01\0" }, - { 0x1e84, "\x00\x57\x03\x08\0" }, - { 0x1e85, "\x00\x77\x03\x08\0" }, - { 0x1e86, "\x00\x57\x03\x07\0" }, - { 0x1e87, "\x00\x77\x03\x07\0" }, - { 0x1e88, "\x00\x57\x03\x23\0" }, - { 0x1e89, "\x00\x77\x03\x23\0" }, - { 0x1e8a, "\x00\x58\x03\x07\0" }, - { 0x1e8b, "\x00\x78\x03\x07\0" }, - { 0x1e8c, "\x00\x58\x03\x08\0" }, - { 0x1e8d, "\x00\x78\x03\x08\0" }, - { 0x1e8e, "\x00\x59\x03\x07\0" }, - { 0x1e8f, "\x00\x79\x03\x07\0" }, - { 0x1e90, "\x00\x5a\x03\x02\0" }, - { 0x1e91, "\x00\x7a\x03\x02\0" }, - { 0x1e92, "\x00\x5a\x03\x23\0" }, - { 0x1e93, "\x00\x7a\x03\x23\0" }, - { 0x1e94, "\x00\x5a\x03\x31\0" }, - { 0x1e95, "\x00\x7a\x03\x31\0" }, - { 0x1e96, "\x00\x68\x03\x31\0" }, - { 0x1e97, "\x00\x74\x03\x08\0" }, - { 0x1e98, "\x00\x77\x03\x0a\0" }, - { 0x1e99, "\x00\x79\x03\x0a\0" }, - { 0x1e9b, "\x01\x7f\x03\x07\0" }, - { 0x1ea0, "\x00\x41\x03\x23\0" }, - { 0x1ea1, "\x00\x61\x03\x23\0" }, - { 0x1ea2, "\x00\x41\x03\x09\0" }, - { 0x1ea3, "\x00\x61\x03\x09\0" }, - { 0x1ea4, "\x00\x41\x03\x02\x03\x01\0" }, - { 0x1ea5, "\x00\x61\x03\x02\x03\x01\0" }, - { 0x1ea6, "\x00\x41\x03\x02\x03\x00\0" }, - { 0x1ea7, "\x00\x61\x03\x02\x03\x00\0" }, - { 0x1ea8, "\x00\x41\x03\x02\x03\x09\0" }, - { 0x1ea9, "\x00\x61\x03\x02\x03\x09\0" }, - { 0x1eaa, "\x00\x41\x03\x02\x03\x03\0" }, - { 0x1eab, "\x00\x61\x03\x02\x03\x03\0" }, - { 0x1eac, "\x00\x41\x03\x23\x03\x02\0" }, - { 0x1ead, "\x00\x61\x03\x23\x03\x02\0" }, - { 0x1eae, "\x00\x41\x03\x06\x03\x01\0" }, - { 0x1eaf, "\x00\x61\x03\x06\x03\x01\0" }, - { 0x1eb0, "\x00\x41\x03\x06\x03\x00\0" }, - { 0x1eb1, "\x00\x61\x03\x06\x03\x00\0" }, - { 0x1eb2, "\x00\x41\x03\x06\x03\x09\0" }, - { 0x1eb3, "\x00\x61\x03\x06\x03\x09\0" }, - { 0x1eb4, "\x00\x41\x03\x06\x03\x03\0" }, - { 0x1eb5, "\x00\x61\x03\x06\x03\x03\0" }, - { 0x1eb6, "\x00\x41\x03\x23\x03\x06\0" }, - { 0x1eb7, "\x00\x61\x03\x23\x03\x06\0" }, - { 0x1eb8, "\x00\x45\x03\x23\0" }, - { 0x1eb9, "\x00\x65\x03\x23\0" }, - { 0x1eba, "\x00\x45\x03\x09\0" }, - { 0x1ebb, "\x00\x65\x03\x09\0" }, - { 0x1ebc, "\x00\x45\x03\x03\0" }, - { 0x1ebd, "\x00\x65\x03\x03\0" }, - { 0x1ebe, "\x00\x45\x03\x02\x03\x01\0" }, - { 0x1ebf, "\x00\x65\x03\x02\x03\x01\0" }, - { 0x1ec0, "\x00\x45\x03\x02\x03\x00\0" }, - { 0x1ec1, "\x00\x65\x03\x02\x03\x00\0" }, - { 0x1ec2, "\x00\x45\x03\x02\x03\x09\0" }, - { 0x1ec3, "\x00\x65\x03\x02\x03\x09\0" }, - { 0x1ec4, "\x00\x45\x03\x02\x03\x03\0" }, - { 0x1ec5, "\x00\x65\x03\x02\x03\x03\0" }, - { 0x1ec6, "\x00\x45\x03\x23\x03\x02\0" }, - { 0x1ec7, "\x00\x65\x03\x23\x03\x02\0" }, - { 0x1ec8, "\x00\x49\x03\x09\0" }, - { 0x1ec9, "\x00\x69\x03\x09\0" }, - { 0x1eca, "\x00\x49\x03\x23\0" }, - { 0x1ecb, "\x00\x69\x03\x23\0" }, - { 0x1ecc, "\x00\x4f\x03\x23\0" }, - { 0x1ecd, "\x00\x6f\x03\x23\0" }, - { 0x1ece, "\x00\x4f\x03\x09\0" }, - { 0x1ecf, "\x00\x6f\x03\x09\0" }, - { 0x1ed0, "\x00\x4f\x03\x02\x03\x01\0" }, - { 0x1ed1, "\x00\x6f\x03\x02\x03\x01\0" }, - { 0x1ed2, "\x00\x4f\x03\x02\x03\x00\0" }, - { 0x1ed3, "\x00\x6f\x03\x02\x03\x00\0" }, - { 0x1ed4, "\x00\x4f\x03\x02\x03\x09\0" }, - { 0x1ed5, "\x00\x6f\x03\x02\x03\x09\0" }, - { 0x1ed6, "\x00\x4f\x03\x02\x03\x03\0" }, - { 0x1ed7, "\x00\x6f\x03\x02\x03\x03\0" }, - { 0x1ed8, "\x00\x4f\x03\x23\x03\x02\0" }, - { 0x1ed9, "\x00\x6f\x03\x23\x03\x02\0" }, - { 0x1eda, "\x00\x4f\x03\x1b\x03\x01\0" }, - { 0x1edb, "\x00\x6f\x03\x1b\x03\x01\0" }, - { 0x1edc, "\x00\x4f\x03\x1b\x03\x00\0" }, - { 0x1edd, "\x00\x6f\x03\x1b\x03\x00\0" }, - { 0x1ede, "\x00\x4f\x03\x1b\x03\x09\0" }, - { 0x1edf, "\x00\x6f\x03\x1b\x03\x09\0" }, - { 0x1ee0, "\x00\x4f\x03\x1b\x03\x03\0" }, - { 0x1ee1, "\x00\x6f\x03\x1b\x03\x03\0" }, - { 0x1ee2, "\x00\x4f\x03\x1b\x03\x23\0" }, - { 0x1ee3, "\x00\x6f\x03\x1b\x03\x23\0" }, - { 0x1ee4, "\x00\x55\x03\x23\0" }, - { 0x1ee5, "\x00\x75\x03\x23\0" }, - { 0x1ee6, "\x00\x55\x03\x09\0" }, - { 0x1ee7, "\x00\x75\x03\x09\0" }, - { 0x1ee8, "\x00\x55\x03\x1b\x03\x01\0" }, - { 0x1ee9, "\x00\x75\x03\x1b\x03\x01\0" }, - { 0x1eea, "\x00\x55\x03\x1b\x03\x00\0" }, - { 0x1eeb, "\x00\x75\x03\x1b\x03\x00\0" }, - { 0x1eec, "\x00\x55\x03\x1b\x03\x09\0" }, - { 0x1eed, "\x00\x75\x03\x1b\x03\x09\0" }, - { 0x1eee, "\x00\x55\x03\x1b\x03\x03\0" }, - { 0x1eef, "\x00\x75\x03\x1b\x03\x03\0" }, - { 0x1ef0, "\x00\x55\x03\x1b\x03\x23\0" }, - { 0x1ef1, "\x00\x75\x03\x1b\x03\x23\0" }, - { 0x1ef2, "\x00\x59\x03\x00\0" }, - { 0x1ef3, "\x00\x79\x03\x00\0" }, - { 0x1ef4, "\x00\x59\x03\x23\0" }, - { 0x1ef5, "\x00\x79\x03\x23\0" }, - { 0x1ef6, "\x00\x59\x03\x09\0" }, - { 0x1ef7, "\x00\x79\x03\x09\0" }, - { 0x1ef8, "\x00\x59\x03\x03\0" }, - { 0x1ef9, "\x00\x79\x03\x03\0" }, - { 0x1f00, "\x03\xb1\x03\x13\0" }, - { 0x1f01, "\x03\xb1\x03\x14\0" }, - { 0x1f02, "\x03\xb1\x03\x13\x03\x00\0" }, - { 0x1f03, "\x03\xb1\x03\x14\x03\x00\0" }, - { 0x1f04, "\x03\xb1\x03\x13\x03\x01\0" }, - { 0x1f05, "\x03\xb1\x03\x14\x03\x01\0" }, - { 0x1f06, "\x03\xb1\x03\x13\x03\x42\0" }, - { 0x1f07, "\x03\xb1\x03\x14\x03\x42\0" }, - { 0x1f08, "\x03\x91\x03\x13\0" }, - { 0x1f09, "\x03\x91\x03\x14\0" }, - { 0x1f0a, "\x03\x91\x03\x13\x03\x00\0" }, - { 0x1f0b, "\x03\x91\x03\x14\x03\x00\0" }, - { 0x1f0c, "\x03\x91\x03\x13\x03\x01\0" }, - { 0x1f0d, "\x03\x91\x03\x14\x03\x01\0" }, - { 0x1f0e, "\x03\x91\x03\x13\x03\x42\0" }, - { 0x1f0f, "\x03\x91\x03\x14\x03\x42\0" }, - { 0x1f10, "\x03\xb5\x03\x13\0" }, - { 0x1f11, "\x03\xb5\x03\x14\0" }, - { 0x1f12, "\x03\xb5\x03\x13\x03\x00\0" }, - { 0x1f13, "\x03\xb5\x03\x14\x03\x00\0" }, - { 0x1f14, "\x03\xb5\x03\x13\x03\x01\0" }, - { 0x1f15, "\x03\xb5\x03\x14\x03\x01\0" }, - { 0x1f18, "\x03\x95\x03\x13\0" }, - { 0x1f19, "\x03\x95\x03\x14\0" }, - { 0x1f1a, "\x03\x95\x03\x13\x03\x00\0" }, - { 0x1f1b, "\x03\x95\x03\x14\x03\x00\0" }, - { 0x1f1c, "\x03\x95\x03\x13\x03\x01\0" }, - { 0x1f1d, "\x03\x95\x03\x14\x03\x01\0" }, - { 0x1f20, "\x03\xb7\x03\x13\0" }, - { 0x1f21, "\x03\xb7\x03\x14\0" }, - { 0x1f22, "\x03\xb7\x03\x13\x03\x00\0" }, - { 0x1f23, "\x03\xb7\x03\x14\x03\x00\0" }, - { 0x1f24, "\x03\xb7\x03\x13\x03\x01\0" }, - { 0x1f25, "\x03\xb7\x03\x14\x03\x01\0" }, - { 0x1f26, "\x03\xb7\x03\x13\x03\x42\0" }, - { 0x1f27, "\x03\xb7\x03\x14\x03\x42\0" }, - { 0x1f28, "\x03\x97\x03\x13\0" }, - { 0x1f29, "\x03\x97\x03\x14\0" }, - { 0x1f2a, "\x03\x97\x03\x13\x03\x00\0" }, - { 0x1f2b, "\x03\x97\x03\x14\x03\x00\0" }, - { 0x1f2c, "\x03\x97\x03\x13\x03\x01\0" }, - { 0x1f2d, "\x03\x97\x03\x14\x03\x01\0" }, - { 0x1f2e, "\x03\x97\x03\x13\x03\x42\0" }, - { 0x1f2f, "\x03\x97\x03\x14\x03\x42\0" }, - { 0x1f30, "\x03\xb9\x03\x13\0" }, - { 0x1f31, "\x03\xb9\x03\x14\0" }, - { 0x1f32, "\x03\xb9\x03\x13\x03\x00\0" }, - { 0x1f33, "\x03\xb9\x03\x14\x03\x00\0" }, - { 0x1f34, "\x03\xb9\x03\x13\x03\x01\0" }, - { 0x1f35, "\x03\xb9\x03\x14\x03\x01\0" }, - { 0x1f36, "\x03\xb9\x03\x13\x03\x42\0" }, - { 0x1f37, "\x03\xb9\x03\x14\x03\x42\0" }, - { 0x1f38, "\x03\x99\x03\x13\0" }, - { 0x1f39, "\x03\x99\x03\x14\0" }, - { 0x1f3a, "\x03\x99\x03\x13\x03\x00\0" }, - { 0x1f3b, "\x03\x99\x03\x14\x03\x00\0" }, - { 0x1f3c, "\x03\x99\x03\x13\x03\x01\0" }, - { 0x1f3d, "\x03\x99\x03\x14\x03\x01\0" }, - { 0x1f3e, "\x03\x99\x03\x13\x03\x42\0" }, - { 0x1f3f, "\x03\x99\x03\x14\x03\x42\0" }, - { 0x1f40, "\x03\xbf\x03\x13\0" }, - { 0x1f41, "\x03\xbf\x03\x14\0" }, - { 0x1f42, "\x03\xbf\x03\x13\x03\x00\0" }, - { 0x1f43, "\x03\xbf\x03\x14\x03\x00\0" }, - { 0x1f44, "\x03\xbf\x03\x13\x03\x01\0" }, - { 0x1f45, "\x03\xbf\x03\x14\x03\x01\0" }, - { 0x1f48, "\x03\x9f\x03\x13\0" }, - { 0x1f49, "\x03\x9f\x03\x14\0" }, - { 0x1f4a, "\x03\x9f\x03\x13\x03\x00\0" }, - { 0x1f4b, "\x03\x9f\x03\x14\x03\x00\0" }, - { 0x1f4c, "\x03\x9f\x03\x13\x03\x01\0" }, - { 0x1f4d, "\x03\x9f\x03\x14\x03\x01\0" }, - { 0x1f50, "\x03\xc5\x03\x13\0" }, - { 0x1f51, "\x03\xc5\x03\x14\0" }, - { 0x1f52, "\x03\xc5\x03\x13\x03\x00\0" }, - { 0x1f53, "\x03\xc5\x03\x14\x03\x00\0" }, - { 0x1f54, "\x03\xc5\x03\x13\x03\x01\0" }, - { 0x1f55, "\x03\xc5\x03\x14\x03\x01\0" }, - { 0x1f56, "\x03\xc5\x03\x13\x03\x42\0" }, - { 0x1f57, "\x03\xc5\x03\x14\x03\x42\0" }, - { 0x1f59, "\x03\xa5\x03\x14\0" }, - { 0x1f5b, "\x03\xa5\x03\x14\x03\x00\0" }, - { 0x1f5d, "\x03\xa5\x03\x14\x03\x01\0" }, - { 0x1f5f, "\x03\xa5\x03\x14\x03\x42\0" }, - { 0x1f60, "\x03\xc9\x03\x13\0" }, - { 0x1f61, "\x03\xc9\x03\x14\0" }, - { 0x1f62, "\x03\xc9\x03\x13\x03\x00\0" }, - { 0x1f63, "\x03\xc9\x03\x14\x03\x00\0" }, - { 0x1f64, "\x03\xc9\x03\x13\x03\x01\0" }, - { 0x1f65, "\x03\xc9\x03\x14\x03\x01\0" }, - { 0x1f66, "\x03\xc9\x03\x13\x03\x42\0" }, - { 0x1f67, "\x03\xc9\x03\x14\x03\x42\0" }, - { 0x1f68, "\x03\xa9\x03\x13\0" }, - { 0x1f69, "\x03\xa9\x03\x14\0" }, - { 0x1f6a, "\x03\xa9\x03\x13\x03\x00\0" }, - { 0x1f6b, "\x03\xa9\x03\x14\x03\x00\0" }, - { 0x1f6c, "\x03\xa9\x03\x13\x03\x01\0" }, - { 0x1f6d, "\x03\xa9\x03\x14\x03\x01\0" }, - { 0x1f6e, "\x03\xa9\x03\x13\x03\x42\0" }, - { 0x1f6f, "\x03\xa9\x03\x14\x03\x42\0" }, - { 0x1f70, "\x03\xb1\x03\x00\0" }, - { 0x1f71, "\x03\xb1\x03\x01\0" }, - { 0x1f72, "\x03\xb5\x03\x00\0" }, - { 0x1f73, "\x03\xb5\x03\x01\0" }, - { 0x1f74, "\x03\xb7\x03\x00\0" }, - { 0x1f75, "\x03\xb7\x03\x01\0" }, - { 0x1f76, "\x03\xb9\x03\x00\0" }, - { 0x1f77, "\x03\xb9\x03\x01\0" }, - { 0x1f78, "\x03\xbf\x03\x00\0" }, - { 0x1f79, "\x03\xbf\x03\x01\0" }, - { 0x1f7a, "\x03\xc5\x03\x00\0" }, - { 0x1f7b, "\x03\xc5\x03\x01\0" }, - { 0x1f7c, "\x03\xc9\x03\x00\0" }, - { 0x1f7d, "\x03\xc9\x03\x01\0" }, - { 0x1f80, "\x03\xb1\x03\x13\x03\x45\0" }, - { 0x1f81, "\x03\xb1\x03\x14\x03\x45\0" }, - { 0x1f82, "\x03\xb1\x03\x13\x03\x00\x03\x45\0" }, - { 0x1f83, "\x03\xb1\x03\x14\x03\x00\x03\x45\0" }, - { 0x1f84, "\x03\xb1\x03\x13\x03\x01\x03\x45\0" }, - { 0x1f85, "\x03\xb1\x03\x14\x03\x01\x03\x45\0" }, - { 0x1f86, "\x03\xb1\x03\x13\x03\x42\x03\x45\0" }, - { 0x1f87, "\x03\xb1\x03\x14\x03\x42\x03\x45\0" }, - { 0x1f88, "\x03\x91\x03\x13\x03\x45\0" }, - { 0x1f89, "\x03\x91\x03\x14\x03\x45\0" }, - { 0x1f8a, "\x03\x91\x03\x13\x03\x00\x03\x45\0" }, - { 0x1f8b, "\x03\x91\x03\x14\x03\x00\x03\x45\0" }, - { 0x1f8c, "\x03\x91\x03\x13\x03\x01\x03\x45\0" }, - { 0x1f8d, "\x03\x91\x03\x14\x03\x01\x03\x45\0" }, - { 0x1f8e, "\x03\x91\x03\x13\x03\x42\x03\x45\0" }, - { 0x1f8f, "\x03\x91\x03\x14\x03\x42\x03\x45\0" }, - { 0x1f90, "\x03\xb7\x03\x13\x03\x45\0" }, - { 0x1f91, "\x03\xb7\x03\x14\x03\x45\0" }, - { 0x1f92, "\x03\xb7\x03\x13\x03\x00\x03\x45\0" }, - { 0x1f93, "\x03\xb7\x03\x14\x03\x00\x03\x45\0" }, - { 0x1f94, "\x03\xb7\x03\x13\x03\x01\x03\x45\0" }, - { 0x1f95, "\x03\xb7\x03\x14\x03\x01\x03\x45\0" }, - { 0x1f96, "\x03\xb7\x03\x13\x03\x42\x03\x45\0" }, - { 0x1f97, "\x03\xb7\x03\x14\x03\x42\x03\x45\0" }, - { 0x1f98, "\x03\x97\x03\x13\x03\x45\0" }, - { 0x1f99, "\x03\x97\x03\x14\x03\x45\0" }, - { 0x1f9a, "\x03\x97\x03\x13\x03\x00\x03\x45\0" }, - { 0x1f9b, "\x03\x97\x03\x14\x03\x00\x03\x45\0" }, - { 0x1f9c, "\x03\x97\x03\x13\x03\x01\x03\x45\0" }, - { 0x1f9d, "\x03\x97\x03\x14\x03\x01\x03\x45\0" }, - { 0x1f9e, "\x03\x97\x03\x13\x03\x42\x03\x45\0" }, - { 0x1f9f, "\x03\x97\x03\x14\x03\x42\x03\x45\0" }, - { 0x1fa0, "\x03\xc9\x03\x13\x03\x45\0" }, - { 0x1fa1, "\x03\xc9\x03\x14\x03\x45\0" }, - { 0x1fa2, "\x03\xc9\x03\x13\x03\x00\x03\x45\0" }, - { 0x1fa3, "\x03\xc9\x03\x14\x03\x00\x03\x45\0" }, - { 0x1fa4, "\x03\xc9\x03\x13\x03\x01\x03\x45\0" }, - { 0x1fa5, "\x03\xc9\x03\x14\x03\x01\x03\x45\0" }, - { 0x1fa6, "\x03\xc9\x03\x13\x03\x42\x03\x45\0" }, - { 0x1fa7, "\x03\xc9\x03\x14\x03\x42\x03\x45\0" }, - { 0x1fa8, "\x03\xa9\x03\x13\x03\x45\0" }, - { 0x1fa9, "\x03\xa9\x03\x14\x03\x45\0" }, - { 0x1faa, "\x03\xa9\x03\x13\x03\x00\x03\x45\0" }, - { 0x1fab, "\x03\xa9\x03\x14\x03\x00\x03\x45\0" }, - { 0x1fac, "\x03\xa9\x03\x13\x03\x01\x03\x45\0" }, - { 0x1fad, "\x03\xa9\x03\x14\x03\x01\x03\x45\0" }, - { 0x1fae, "\x03\xa9\x03\x13\x03\x42\x03\x45\0" }, - { 0x1faf, "\x03\xa9\x03\x14\x03\x42\x03\x45\0" }, - { 0x1fb0, "\x03\xb1\x03\x06\0" }, - { 0x1fb1, "\x03\xb1\x03\x04\0" }, - { 0x1fb2, "\x03\xb1\x03\x00\x03\x45\0" }, - { 0x1fb3, "\x03\xb1\x03\x45\0" }, - { 0x1fb4, "\x03\xb1\x03\x01\x03\x45\0" }, - { 0x1fb6, "\x03\xb1\x03\x42\0" }, - { 0x1fb7, "\x03\xb1\x03\x42\x03\x45\0" }, - { 0x1fb8, "\x03\x91\x03\x06\0" }, - { 0x1fb9, "\x03\x91\x03\x04\0" }, - { 0x1fba, "\x03\x91\x03\x00\0" }, - { 0x1fbb, "\x03\x91\x03\x01\0" }, - { 0x1fbc, "\x03\x91\x03\x45\0" }, - { 0x1fbe, "\x03\xb9\0" }, - { 0x1fc1, "\x00\xa8\x03\x42\0" }, - { 0x1fc2, "\x03\xb7\x03\x00\x03\x45\0" }, - { 0x1fc3, "\x03\xb7\x03\x45\0" }, - { 0x1fc4, "\x03\xb7\x03\x01\x03\x45\0" }, - { 0x1fc6, "\x03\xb7\x03\x42\0" }, - { 0x1fc7, "\x03\xb7\x03\x42\x03\x45\0" }, - { 0x1fc8, "\x03\x95\x03\x00\0" }, - { 0x1fc9, "\x03\x95\x03\x01\0" }, - { 0x1fca, "\x03\x97\x03\x00\0" }, - { 0x1fcb, "\x03\x97\x03\x01\0" }, - { 0x1fcc, "\x03\x97\x03\x45\0" }, - { 0x1fcd, "\x1f\xbf\x03\x00\0" }, - { 0x1fce, "\x1f\xbf\x03\x01\0" }, - { 0x1fcf, "\x1f\xbf\x03\x42\0" }, - { 0x1fd0, "\x03\xb9\x03\x06\0" }, - { 0x1fd1, "\x03\xb9\x03\x04\0" }, - { 0x1fd2, "\x03\xb9\x03\x08\x03\x00\0" }, - { 0x1fd3, "\x03\xb9\x03\x08\x03\x01\0" }, - { 0x1fd6, "\x03\xb9\x03\x42\0" }, - { 0x1fd7, "\x03\xb9\x03\x08\x03\x42\0" }, - { 0x1fd8, "\x03\x99\x03\x06\0" }, - { 0x1fd9, "\x03\x99\x03\x04\0" }, - { 0x1fda, "\x03\x99\x03\x00\0" }, - { 0x1fdb, "\x03\x99\x03\x01\0" }, - { 0x1fdd, "\x1f\xfe\x03\x00\0" }, - { 0x1fde, "\x1f\xfe\x03\x01\0" }, - { 0x1fdf, "\x1f\xfe\x03\x42\0" }, - { 0x1fe0, "\x03\xc5\x03\x06\0" }, - { 0x1fe1, "\x03\xc5\x03\x04\0" }, - { 0x1fe2, "\x03\xc5\x03\x08\x03\x00\0" }, - { 0x1fe3, "\x03\xc5\x03\x08\x03\x01\0" }, - { 0x1fe4, "\x03\xc1\x03\x13\0" }, - { 0x1fe5, "\x03\xc1\x03\x14\0" }, - { 0x1fe6, "\x03\xc5\x03\x42\0" }, - { 0x1fe7, "\x03\xc5\x03\x08\x03\x42\0" }, - { 0x1fe8, "\x03\xa5\x03\x06\0" }, - { 0x1fe9, "\x03\xa5\x03\x04\0" }, - { 0x1fea, "\x03\xa5\x03\x00\0" }, - { 0x1feb, "\x03\xa5\x03\x01\0" }, - { 0x1fec, "\x03\xa1\x03\x14\0" }, - { 0x1fed, "\x00\xa8\x03\x00\0" }, - { 0x1fee, "\x00\xa8\x03\x01\0" }, - { 0x1fef, "\x00\x60\0" }, - { 0x1ff2, "\x03\xc9\x03\x00\x03\x45\0" }, - { 0x1ff3, "\x03\xc9\x03\x45\0" }, - { 0x1ff4, "\x03\xc9\x03\x01\x03\x45\0" }, - { 0x1ff6, "\x03\xc9\x03\x42\0" }, - { 0x1ff7, "\x03\xc9\x03\x42\x03\x45\0" }, - { 0x1ff8, "\x03\x9f\x03\x00\0" }, - { 0x1ff9, "\x03\x9f\x03\x01\0" }, - { 0x1ffa, "\x03\xa9\x03\x00\0" }, - { 0x1ffb, "\x03\xa9\x03\x01\0" }, - { 0x1ffc, "\x03\xa9\x03\x45\0" }, - { 0x1ffd, "\x00\xb4\0" }, - { 0x2000, "\x20\x02\0" }, - { 0x2001, "\x20\x03\0" }, - { 0x2126, "\x03\xa9\0" }, - { 0x212a, "\x00\x4b\0" }, - { 0x212b, "\x00\x41\x03\x0a\0" }, - { 0x2204, "\x22\x03\x03\x38\0" }, - { 0x2209, "\x22\x08\x03\x38\0" }, - { 0x220c, "\x22\x0b\x03\x38\0" }, - { 0x2224, "\x22\x23\x03\x38\0" }, - { 0x2226, "\x22\x25\x03\x38\0" }, - { 0x2241, "\x00\x7e\x03\x38\0" }, - { 0x2244, "\x22\x43\x03\x38\0" }, - { 0x2247, "\x22\x45\x03\x38\0" }, - { 0x2249, "\x22\x48\x03\x38\0" }, - { 0x2260, "\x00\x3d\x03\x38\0" }, - { 0x2262, "\x22\x61\x03\x38\0" }, - { 0x226d, "\x22\x4d\x03\x38\0" }, - { 0x226e, "\x00\x3c\x03\x38\0" }, - { 0x226f, "\x00\x3e\x03\x38\0" }, - { 0x2270, "\x22\x64\x03\x38\0" }, - { 0x2271, "\x22\x65\x03\x38\0" }, - { 0x2274, "\x22\x72\x03\x38\0" }, - { 0x2275, "\x22\x73\x03\x38\0" }, - { 0x2278, "\x22\x76\x03\x38\0" }, - { 0x2279, "\x22\x77\x03\x38\0" }, - { 0x2280, "\x22\x7a\x03\x38\0" }, - { 0x2281, "\x22\x7b\x03\x38\0" }, - { 0x2284, "\x22\x82\x03\x38\0" }, - { 0x2285, "\x22\x83\x03\x38\0" }, - { 0x2288, "\x22\x86\x03\x38\0" }, - { 0x2289, "\x22\x87\x03\x38\0" }, - { 0x22ac, "\x22\xa2\x03\x38\0" }, - { 0x22ad, "\x22\xa8\x03\x38\0" }, - { 0x22ae, "\x22\xa9\x03\x38\0" }, - { 0x22af, "\x22\xab\x03\x38\0" }, - { 0x22e0, "\x22\x7c\x03\x38\0" }, - { 0x22e1, "\x22\x7d\x03\x38\0" }, - { 0x22e2, "\x22\x91\x03\x38\0" }, - { 0x22e3, "\x22\x92\x03\x38\0" }, - { 0x22ea, "\x22\xb2\x03\x38\0" }, - { 0x22eb, "\x22\xb3\x03\x38\0" }, - { 0x22ec, "\x22\xb4\x03\x38\0" }, - { 0x22ed, "\x22\xb5\x03\x38\0" }, - { 0x2329, "\x30\x08\0" }, - { 0x232a, "\x30\x09\0" }, - { 0x304c, "\x30\x4b\x30\x99\0" }, - { 0x304e, "\x30\x4d\x30\x99\0" }, - { 0x3050, "\x30\x4f\x30\x99\0" }, - { 0x3052, "\x30\x51\x30\x99\0" }, - { 0x3054, "\x30\x53\x30\x99\0" }, - { 0x3056, "\x30\x55\x30\x99\0" }, - { 0x3058, "\x30\x57\x30\x99\0" }, - { 0x305a, "\x30\x59\x30\x99\0" }, - { 0x305c, "\x30\x5b\x30\x99\0" }, - { 0x305e, "\x30\x5d\x30\x99\0" }, - { 0x3060, "\x30\x5f\x30\x99\0" }, - { 0x3062, "\x30\x61\x30\x99\0" }, - { 0x3065, "\x30\x64\x30\x99\0" }, - { 0x3067, "\x30\x66\x30\x99\0" }, - { 0x3069, "\x30\x68\x30\x99\0" }, - { 0x3070, "\x30\x6f\x30\x99\0" }, - { 0x3071, "\x30\x6f\x30\x9a\0" }, - { 0x3073, "\x30\x72\x30\x99\0" }, - { 0x3074, "\x30\x72\x30\x9a\0" }, - { 0x3076, "\x30\x75\x30\x99\0" }, - { 0x3077, "\x30\x75\x30\x9a\0" }, - { 0x3079, "\x30\x78\x30\x99\0" }, - { 0x307a, "\x30\x78\x30\x9a\0" }, - { 0x307c, "\x30\x7b\x30\x99\0" }, - { 0x307d, "\x30\x7b\x30\x9a\0" }, - { 0x3094, "\x30\x46\x30\x99\0" }, - { 0x309e, "\x30\x9d\x30\x99\0" }, - { 0x30ac, "\x30\xab\x30\x99\0" }, - { 0x30ae, "\x30\xad\x30\x99\0" }, - { 0x30b0, "\x30\xaf\x30\x99\0" }, - { 0x30b2, "\x30\xb1\x30\x99\0" }, - { 0x30b4, "\x30\xb3\x30\x99\0" }, - { 0x30b6, "\x30\xb5\x30\x99\0" }, - { 0x30b8, "\x30\xb7\x30\x99\0" }, - { 0x30ba, "\x30\xb9\x30\x99\0" }, - { 0x30bc, "\x30\xbb\x30\x99\0" }, - { 0x30be, "\x30\xbd\x30\x99\0" }, - { 0x30c0, "\x30\xbf\x30\x99\0" }, - { 0x30c2, "\x30\xc1\x30\x99\0" }, - { 0x30c5, "\x30\xc4\x30\x99\0" }, - { 0x30c7, "\x30\xc6\x30\x99\0" }, - { 0x30c9, "\x30\xc8\x30\x99\0" }, - { 0x30d0, "\x30\xcf\x30\x99\0" }, - { 0x30d1, "\x30\xcf\x30\x9a\0" }, - { 0x30d3, "\x30\xd2\x30\x99\0" }, - { 0x30d4, "\x30\xd2\x30\x9a\0" }, - { 0x30d6, "\x30\xd5\x30\x99\0" }, - { 0x30d7, "\x30\xd5\x30\x9a\0" }, - { 0x30d9, "\x30\xd8\x30\x99\0" }, - { 0x30da, "\x30\xd8\x30\x9a\0" }, - { 0x30dc, "\x30\xdb\x30\x99\0" }, - { 0x30dd, "\x30\xdb\x30\x9a\0" }, - { 0x30f4, "\x30\xa6\x30\x99\0" }, - { 0x30f7, "\x30\xef\x30\x99\0" }, - { 0x30f8, "\x30\xf0\x30\x99\0" }, - { 0x30f9, "\x30\xf1\x30\x99\0" }, - { 0x30fa, "\x30\xf2\x30\x99\0" }, - { 0x30fe, "\x30\xfd\x30\x99\0" }, - { 0xf900, "\x8c\x48\0" }, - { 0xf901, "\x66\xf4\0" }, - { 0xf902, "\x8e\xca\0" }, - { 0xf903, "\x8c\xc8\0" }, - { 0xf904, "\x6e\xd1\0" }, - { 0xf905, "\x4e\x32\0" }, - { 0xf906, "\x53\xe5\0" }, - { 0xf907, "\x9f\x9c\0" }, - { 0xf908, "\x9f\x9c\0" }, - { 0xf909, "\x59\x51\0" }, - { 0xf90a, "\x91\xd1\0" }, - { 0xf90b, "\x55\x87\0" }, - { 0xf90c, "\x59\x48\0" }, - { 0xf90d, "\x61\xf6\0" }, - { 0xf90e, "\x76\x69\0" }, - { 0xf90f, "\x7f\x85\0" }, - { 0xf910, "\x86\x3f\0" }, - { 0xf911, "\x87\xba\0" }, - { 0xf912, "\x88\xf8\0" }, - { 0xf913, "\x90\x8f\0" }, - { 0xf914, "\x6a\x02\0" }, - { 0xf915, "\x6d\x1b\0" }, - { 0xf916, "\x70\xd9\0" }, - { 0xf917, "\x73\xde\0" }, - { 0xf918, "\x84\x3d\0" }, - { 0xf919, "\x91\x6a\0" }, - { 0xf91a, "\x99\xf1\0" }, - { 0xf91b, "\x4e\x82\0" }, - { 0xf91c, "\x53\x75\0" }, - { 0xf91d, "\x6b\x04\0" }, - { 0xf91e, "\x72\x1b\0" }, - { 0xf91f, "\x86\x2d\0" }, - { 0xf920, "\x9e\x1e\0" }, - { 0xf921, "\x5d\x50\0" }, - { 0xf922, "\x6f\xeb\0" }, - { 0xf923, "\x85\xcd\0" }, - { 0xf924, "\x89\x64\0" }, - { 0xf925, "\x62\xc9\0" }, - { 0xf926, "\x81\xd8\0" }, - { 0xf927, "\x88\x1f\0" }, - { 0xf928, "\x5e\xca\0" }, - { 0xf929, "\x67\x17\0" }, - { 0xf92a, "\x6d\x6a\0" }, - { 0xf92b, "\x72\xfc\0" }, - { 0xf92c, "\x90\xce\0" }, - { 0xf92d, "\x4f\x86\0" }, - { 0xf92e, "\x51\xb7\0" }, - { 0xf92f, "\x52\xde\0" }, - { 0xf930, "\x64\xc4\0" }, - { 0xf931, "\x6a\xd3\0" }, - { 0xf932, "\x72\x10\0" }, - { 0xf933, "\x76\xe7\0" }, - { 0xf934, "\x80\x01\0" }, - { 0xf935, "\x86\x06\0" }, - { 0xf936, "\x86\x5c\0" }, - { 0xf937, "\x8d\xef\0" }, - { 0xf938, "\x97\x32\0" }, - { 0xf939, "\x9b\x6f\0" }, - { 0xf93a, "\x9d\xfa\0" }, - { 0xf93b, "\x78\x8c\0" }, - { 0xf93c, "\x79\x7f\0" }, - { 0xf93d, "\x7d\xa0\0" }, - { 0xf93e, "\x83\xc9\0" }, - { 0xf93f, "\x93\x04\0" }, - { 0xf940, "\x9e\x7f\0" }, - { 0xf941, "\x8a\xd6\0" }, - { 0xf942, "\x58\xdf\0" }, - { 0xf943, "\x5f\x04\0" }, - { 0xf944, "\x7c\x60\0" }, - { 0xf945, "\x80\x7e\0" }, - { 0xf946, "\x72\x62\0" }, - { 0xf947, "\x78\xca\0" }, - { 0xf948, "\x8c\xc2\0" }, - { 0xf949, "\x96\xf7\0" }, - { 0xf94a, "\x58\xd8\0" }, - { 0xf94b, "\x5c\x62\0" }, - { 0xf94c, "\x6a\x13\0" }, - { 0xf94d, "\x6d\xda\0" }, - { 0xf94e, "\x6f\x0f\0" }, - { 0xf94f, "\x7d\x2f\0" }, - { 0xf950, "\x7e\x37\0" }, - { 0xf951, "\x96\xfb\0" }, - { 0xf952, "\x52\xd2\0" }, - { 0xf953, "\x80\x8b\0" }, - { 0xf954, "\x51\xdc\0" }, - { 0xf955, "\x51\xcc\0" }, - { 0xf956, "\x7a\x1c\0" }, - { 0xf957, "\x7d\xbe\0" }, - { 0xf958, "\x83\xf1\0" }, - { 0xf959, "\x96\x75\0" }, - { 0xf95a, "\x8b\x80\0" }, - { 0xf95b, "\x62\xcf\0" }, - { 0xf95c, "\x6a\x02\0" }, - { 0xf95d, "\x8a\xfe\0" }, - { 0xf95e, "\x4e\x39\0" }, - { 0xf95f, "\x5b\xe7\0" }, - { 0xf960, "\x60\x12\0" }, - { 0xf961, "\x73\x87\0" }, - { 0xf962, "\x75\x70\0" }, - { 0xf963, "\x53\x17\0" }, - { 0xf964, "\x78\xfb\0" }, - { 0xf965, "\x4f\xbf\0" }, - { 0xf966, "\x5f\xa9\0" }, - { 0xf967, "\x4e\x0d\0" }, - { 0xf968, "\x6c\xcc\0" }, - { 0xf969, "\x65\x78\0" }, - { 0xf96a, "\x7d\x22\0" }, - { 0xf96b, "\x53\xc3\0" }, - { 0xf96c, "\x58\x5e\0" }, - { 0xf96d, "\x77\x01\0" }, - { 0xf96e, "\x84\x49\0" }, - { 0xf96f, "\x8a\xaa\0" }, - { 0xf970, "\x6b\xba\0" }, - { 0xf971, "\x8f\xb0\0" }, - { 0xf972, "\x6c\x88\0" }, - { 0xf973, "\x62\xfe\0" }, - { 0xf974, "\x82\xe5\0" }, - { 0xf975, "\x63\xa0\0" }, - { 0xf976, "\x75\x65\0" }, - { 0xf977, "\x4e\xae\0" }, - { 0xf978, "\x51\x69\0" }, - { 0xf979, "\x51\xc9\0" }, - { 0xf97a, "\x68\x81\0" }, - { 0xf97b, "\x7c\xe7\0" }, - { 0xf97c, "\x82\x6f\0" }, - { 0xf97d, "\x8a\xd2\0" }, - { 0xf97e, "\x91\xcf\0" }, - { 0xf97f, "\x52\xf5\0" }, - { 0xf980, "\x54\x42\0" }, - { 0xf981, "\x59\x73\0" }, - { 0xf982, "\x5e\xec\0" }, - { 0xf983, "\x65\xc5\0" }, - { 0xf984, "\x6f\xfe\0" }, - { 0xf985, "\x79\x2a\0" }, - { 0xf986, "\x95\xad\0" }, - { 0xf987, "\x9a\x6a\0" }, - { 0xf988, "\x9e\x97\0" }, - { 0xf989, "\x9e\xce\0" }, - { 0xf98a, "\x52\x9b\0" }, - { 0xf98b, "\x66\xc6\0" }, - { 0xf98c, "\x6b\x77\0" }, - { 0xf98d, "\x8f\x62\0" }, - { 0xf98e, "\x5e\x74\0" }, - { 0xf98f, "\x61\x90\0" }, - { 0xf990, "\x62\x00\0" }, - { 0xf991, "\x64\x9a\0" }, - { 0xf992, "\x6f\x23\0" }, - { 0xf993, "\x71\x49\0" }, - { 0xf994, "\x74\x89\0" }, - { 0xf995, "\x79\xca\0" }, - { 0xf996, "\x7d\xf4\0" }, - { 0xf997, "\x80\x6f\0" }, - { 0xf998, "\x8f\x26\0" }, - { 0xf999, "\x84\xee\0" }, - { 0xf99a, "\x90\x23\0" }, - { 0xf99b, "\x93\x4a\0" }, - { 0xf99c, "\x52\x17\0" }, - { 0xf99d, "\x52\xa3\0" }, - { 0xf99e, "\x54\xbd\0" }, - { 0xf99f, "\x70\xc8\0" }, - { 0xf9a0, "\x88\xc2\0" }, - { 0xf9a1, "\x8a\xaa\0" }, - { 0xf9a2, "\x5e\xc9\0" }, - { 0xf9a3, "\x5f\xf5\0" }, - { 0xf9a4, "\x63\x7b\0" }, - { 0xf9a5, "\x6b\xae\0" }, - { 0xf9a6, "\x7c\x3e\0" }, - { 0xf9a7, "\x73\x75\0" }, - { 0xf9a8, "\x4e\xe4\0" }, - { 0xf9a9, "\x56\xf9\0" }, - { 0xf9aa, "\x5b\xe7\0" }, - { 0xf9ab, "\x5d\xba\0" }, - { 0xf9ac, "\x60\x1c\0" }, - { 0xf9ad, "\x73\xb2\0" }, - { 0xf9ae, "\x74\x69\0" }, - { 0xf9af, "\x7f\x9a\0" }, - { 0xf9b0, "\x80\x46\0" }, - { 0xf9b1, "\x92\x34\0" }, - { 0xf9b2, "\x96\xf6\0" }, - { 0xf9b3, "\x97\x48\0" }, - { 0xf9b4, "\x98\x18\0" }, - { 0xf9b5, "\x4f\x8b\0" }, - { 0xf9b6, "\x79\xae\0" }, - { 0xf9b7, "\x91\xb4\0" }, - { 0xf9b8, "\x96\xb8\0" }, - { 0xf9b9, "\x60\xe1\0" }, - { 0xf9ba, "\x4e\x86\0" }, - { 0xf9bb, "\x50\xda\0" }, - { 0xf9bc, "\x5b\xee\0" }, - { 0xf9bd, "\x5c\x3f\0" }, - { 0xf9be, "\x65\x99\0" }, - { 0xf9bf, "\x6a\x02\0" }, - { 0xf9c0, "\x71\xce\0" }, - { 0xf9c1, "\x76\x42\0" }, - { 0xf9c2, "\x84\xfc\0" }, - { 0xf9c3, "\x90\x7c\0" }, - { 0xf9c4, "\x9f\x8d\0" }, - { 0xf9c5, "\x66\x88\0" }, - { 0xf9c6, "\x96\x2e\0" }, - { 0xf9c7, "\x52\x89\0" }, - { 0xf9c8, "\x67\x7b\0" }, - { 0xf9c9, "\x67\xf3\0" }, - { 0xf9ca, "\x6d\x41\0" }, - { 0xf9cb, "\x6e\x9c\0" }, - { 0xf9cc, "\x74\x09\0" }, - { 0xf9cd, "\x75\x59\0" }, - { 0xf9ce, "\x78\x6b\0" }, - { 0xf9cf, "\x7d\x10\0" }, - { 0xf9d0, "\x98\x5e\0" }, - { 0xf9d1, "\x51\x6d\0" }, - { 0xf9d2, "\x62\x2e\0" }, - { 0xf9d3, "\x96\x78\0" }, - { 0xf9d4, "\x50\x2b\0" }, - { 0xf9d5, "\x5d\x19\0" }, - { 0xf9d6, "\x6d\xea\0" }, - { 0xf9d7, "\x8f\x2a\0" }, - { 0xf9d8, "\x5f\x8b\0" }, - { 0xf9d9, "\x61\x44\0" }, - { 0xf9da, "\x68\x17\0" }, - { 0xf9db, "\x73\x87\0" }, - { 0xf9dc, "\x96\x86\0" }, - { 0xf9dd, "\x52\x29\0" }, - { 0xf9de, "\x54\x0f\0" }, - { 0xf9df, "\x5c\x65\0" }, - { 0xf9e0, "\x66\x13\0" }, - { 0xf9e1, "\x67\x4e\0" }, - { 0xf9e2, "\x68\xa8\0" }, - { 0xf9e3, "\x6c\xe5\0" }, - { 0xf9e4, "\x74\x06\0" }, - { 0xf9e5, "\x75\xe2\0" }, - { 0xf9e6, "\x7f\x79\0" }, - { 0xf9e7, "\x88\xcf\0" }, - { 0xf9e8, "\x88\xe1\0" }, - { 0xf9e9, "\x91\xcc\0" }, - { 0xf9ea, "\x96\xe2\0" }, - { 0xf9eb, "\x53\x3f\0" }, - { 0xf9ec, "\x6e\xba\0" }, - { 0xf9ed, "\x54\x1d\0" }, - { 0xf9ee, "\x71\xd0\0" }, - { 0xf9ef, "\x74\x98\0" }, - { 0xf9f0, "\x85\xfa\0" }, - { 0xf9f1, "\x96\xa3\0" }, - { 0xf9f2, "\x9c\x57\0" }, - { 0xf9f3, "\x9e\x9f\0" }, - { 0xf9f4, "\x67\x97\0" }, - { 0xf9f5, "\x6d\xcb\0" }, - { 0xf9f6, "\x81\xe8\0" }, - { 0xf9f7, "\x7a\xcb\0" }, - { 0xf9f8, "\x7b\x20\0" }, - { 0xf9f9, "\x7c\x92\0" }, - { 0xf9fa, "\x72\xc0\0" }, - { 0xf9fb, "\x70\x99\0" }, - { 0xf9fc, "\x8b\x58\0" }, - { 0xf9fd, "\x4e\xc0\0" }, - { 0xf9fe, "\x83\x36\0" }, - { 0xf9ff, "\x52\x3a\0" }, - { 0xfa00, "\x52\x07\0" }, - { 0xfa01, "\x5e\xa6\0" }, - { 0xfa02, "\x62\xd3\0" }, - { 0xfa03, "\x7c\xd6\0" }, - { 0xfa04, "\x5b\x85\0" }, - { 0xfa05, "\x6d\x1e\0" }, - { 0xfa06, "\x66\xb4\0" }, - { 0xfa07, "\x8f\x3b\0" }, - { 0xfa08, "\x88\x4c\0" }, - { 0xfa09, "\x96\x4d\0" }, - { 0xfa0a, "\x89\x8b\0" }, - { 0xfa0b, "\x5e\xd3\0" }, - { 0xfa0c, "\x51\x40\0" }, - { 0xfa0d, "\x55\xc0\0" }, - { 0xfa10, "\x58\x5a\0" }, - { 0xfa12, "\x66\x74\0" }, - { 0xfa15, "\x51\xde\0" }, - { 0xfa16, "\x73\x2a\0" }, - { 0xfa17, "\x76\xca\0" }, - { 0xfa18, "\x79\x3c\0" }, - { 0xfa19, "\x79\x5e\0" }, - { 0xfa1a, "\x79\x65\0" }, - { 0xfa1b, "\x79\x8f\0" }, - { 0xfa1c, "\x97\x56\0" }, - { 0xfa1d, "\x7c\xbe\0" }, - { 0xfa1e, "\x7f\xbd\0" }, - { 0xfa20, "\x86\x12\0" }, - { 0xfa22, "\x8a\xf8\0" }, - { 0xfa25, "\x90\x38\0" }, - { 0xfa26, "\x90\xfd\0" }, - { 0xfa2a, "\x98\xef\0" }, - { 0xfa2b, "\x98\xfc\0" }, - { 0xfa2c, "\x99\x28\0" }, - { 0xfa2d, "\x9d\xb4\0" }, - { 0xfb1f, "\x05\xf2\x05\xb7\0" }, - { 0xfb2a, "\x05\xe9\x05\xc1\0" }, - { 0xfb2b, "\x05\xe9\x05\xc2\0" }, - { 0xfb2c, "\x05\xe9\x05\xbc\x05\xc1\0" }, - { 0xfb2d, "\x05\xe9\x05\xbc\x05\xc2\0" }, - { 0xfb2e, "\x05\xd0\x05\xb7\0" }, - { 0xfb2f, "\x05\xd0\x05\xb8\0" }, - { 0xfb30, "\x05\xd0\x05\xbc\0" }, - { 0xfb31, "\x05\xd1\x05\xbc\0" }, - { 0xfb32, "\x05\xd2\x05\xbc\0" }, - { 0xfb33, "\x05\xd3\x05\xbc\0" }, - { 0xfb34, "\x05\xd4\x05\xbc\0" }, - { 0xfb35, "\x05\xd5\x05\xbc\0" }, - { 0xfb36, "\x05\xd6\x05\xbc\0" }, - { 0xfb38, "\x05\xd8\x05\xbc\0" }, - { 0xfb39, "\x05\xd9\x05\xbc\0" }, - { 0xfb3a, "\x05\xda\x05\xbc\0" }, - { 0xfb3b, "\x05\xdb\x05\xbc\0" }, - { 0xfb3c, "\x05\xdc\x05\xbc\0" }, - { 0xfb3e, "\x05\xde\x05\xbc\0" }, - { 0xfb40, "\x05\xe0\x05\xbc\0" }, - { 0xfb41, "\x05\xe1\x05\xbc\0" }, - { 0xfb43, "\x05\xe3\x05\xbc\0" }, - { 0xfb44, "\x05\xe4\x05\xbc\0" }, - { 0xfb46, "\x05\xe6\x05\xbc\0" }, - { 0xfb47, "\x05\xe7\x05\xbc\0" }, - { 0xfb48, "\x05\xe8\x05\xbc\0" }, - { 0xfb49, "\x05\xe9\x05\xbc\0" }, - { 0xfb4a, "\x05\xea\x05\xbc\0" }, - { 0xfb4b, "\x05\xd5\x05\xb9\0" }, - { 0xfb4c, "\x05\xd1\x05\xbf\0" }, - { 0xfb4d, "\x05\xdb\x05\xbf\0" }, - { 0xfb4e, "\x05\xe4\x05\xbf\0" } -}; - -/* - * WARNING! - * - * NO BUFFER CHECKING AHEAD! - * - */ - -static gint -e_canonical_decomposition (gunichar ch, gunichar * buf) -{ - gint len = 0; - - if (ch <= 0xffff) - { - int start = 0; - int end = sizeof (e_decomp_table) / sizeof (e_decomp_table[0]); - while (start != end) - { - int half = (start + end) / 2; - if (ch == e_decomp_table[half].ch) { - /* Found it. */ - int i; - /* We store as a double-nul terminated string. */ - for (len = 0; (e_decomp_table[half].expansion[len] || e_decomp_table[half].expansion[len + 1]); len += 2) ; - - /* We've counted twice as many bytes as there are - characters. */ - len /= 2; - - for (i = 0; i < len; i ++) { - buf[i] = (e_decomp_table[half].expansion[2 * i] << 8) | e_decomp_table[half].expansion[2 * i + 1]; - } - break; - } else if (ch > e_decomp_table[half].ch) { - if (start == half) break; - start = half; - } else { - if (end == half) break; - end = half; - } - } - } - - if (len == 0) - { - /* Not in our table. */ - *buf = ch; - len = 1; - } - - /* Supposedly following the Unicode 2.1.9 table means that the - decompositions come out in canonical order. I haven't tested - this, but we rely on it here. */ - return len; -} - -static gunichar -e_stripped_char (gunichar ch) -{ - gunichar decomp[MAX_DECOMP]; - GUnicodeType utype; - gint dlen; - - utype = g_unichar_type (ch); - - switch (utype) { - case G_UNICODE_CONTROL: - case G_UNICODE_FORMAT: - case G_UNICODE_UNASSIGNED: - case G_UNICODE_COMBINING_MARK: - /* Ignore those */ - return 0; - default: - /* Convert to lowercase, fall through */ - ch = g_unichar_tolower (ch); - case G_UNICODE_LOWERCASE_LETTER: - dlen = e_canonical_decomposition (ch, decomp); - if (dlen > 0) return *decomp; - break; - } - - return 0; -} - -gchar * -e_xml_get_translated_utf8_string_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) -{ - xmlChar *prop; - gchar *ret_val = NULL; - gchar *combined_name; - - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (prop_name != NULL, NULL); - - prop = xmlGetProp ((xmlNode *) parent, prop_name); - if (prop != NULL) { - ret_val = g_strdup ((char *)prop); - xmlFree (prop); - return ret_val; - } - - combined_name = g_strdup_printf("_%s", prop_name); - prop = xmlGetProp ((xmlNode *) parent, (unsigned char *)combined_name); - if (prop != NULL) { - ret_val = g_strdup (gettext ((char *)prop)); - xmlFree (prop); - } - g_free(combined_name); - - return ret_val; -} diff --git a/widgets/misc/e-unicode.h b/widgets/misc/e-unicode.h deleted file mode 100644 index b745876b6d..0000000000 --- a/widgets/misc/e-unicode.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * e-unicode.h - utf-8 support functions for gal - * - * 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 - * - * - * Authors: - * Lauris Kaplinski - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_UNICODE_H_ -#define _E_UNICODE_H_ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define G_UTF8_IN_GAL - -/* - * UTF-8 searching implementations - * - * e_utf8_strstrcase - case insensitive search - * e_utf8_strstrcasedecomp - case insensitive and decompositing search (i.e. accented - * letters are treated equal to their base letters, explicit accent marks (unicode - * not ascii/iso ones) are ignored). - */ - -const gchar *e_utf8_strstrcase (const gchar *haystack, - const gchar *needle); -const gchar *e_utf8_strstrcasedecomp (const gchar *haystack, - const gchar *needle); -gchar *e_utf8_from_gtk_event_key (GtkWidget *widget, - guint keyval, - const gchar *string); -gchar *e_utf8_from_iconv_string (iconv_t ic, - const gchar *string); -gchar *e_utf8_from_iconv_string_sized (iconv_t ic, - const gchar *string, - gint bytes); -gchar *e_utf8_to_iconv_string (iconv_t ic, - const gchar *string); -gchar *e_utf8_to_iconv_string_sized (iconv_t ic, - const gchar *string, - gint bytes); -gchar *e_utf8_from_charset_string (const gchar *charset, - const gchar *string); -gchar *e_utf8_from_charset_string_sized (const gchar *charset, - const gchar *string, - gint bytes); -gchar *e_utf8_to_charset_string (const gchar *charset, - const gchar *string); -gchar *e_utf8_to_charset_string_sized (const gchar *charset, - const gchar *string, - gint bytes); -gchar *e_utf8_from_locale_string (const gchar *string); -gchar *e_utf8_from_locale_string_sized (const gchar *string, - gint bytes); -gchar *e_utf8_to_locale_string (const gchar *string); -gchar *e_utf8_to_locale_string_sized (const gchar *string, - gint bytes); -gboolean e_utf8_is_ascii (const gchar *string); -/* - * These are simple wrappers that save us some typing - */ - -/* NB! This return newly allocated string, not const as gtk+ one */ -gchar *e_utf8_gtk_entry_get_text (GtkEntry *entry); -void e_utf8_gtk_entry_set_text (GtkEntry *entry, - const gchar *text); -gchar *e_utf8_gtk_editable_get_text (GtkEditable *editable); -void e_utf8_gtk_editable_set_text (GtkEditable *editable, - const gchar *text); -gchar *e_utf8_gtk_editable_get_chars (GtkEditable *editable, - gint start, - gint end); -void e_utf8_gtk_editable_insert_text (GtkEditable *editable, - const gchar *text, - gint length, - gint *position); -gchar *e_utf8_xml1_decode (const gchar *text); -gchar *e_utf8_xml1_encode (const gchar *text); -gint e_unichar_to_utf8 (gint c, - gchar *outbuf); -gchar *e_unicode_get_utf8 (const gchar *text, - gunichar *out); -guint32 gdk_keyval_to_unicode (guint keysym); -gchar *e_xml_get_translated_utf8_string_prop_by_name (const xmlNode *parent, - const xmlChar *prop_name); - -G_END_DECLS - -#endif - - -- cgit v1.2.3 From 099293ed216aac18a42dd3c41906978f44b056b1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 12 May 2009 21:43:37 -0400 Subject: =?UTF-8?q?Bug=20440919=20=E2=80=93=20Evolution=20can't=20attach?= =?UTF-8?q?=20"zero=20length"=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 537a3470d7..67647116e3 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -418,6 +418,10 @@ attachment_progress_cb (goffset current_num_bytes, goffset total_num_bytes, EAttachment *attachment) { + /* Avoid dividing by zero. */ + if (total_num_bytes == 0) + return; + attachment->priv->percent = (current_num_bytes * 100) / total_num_bytes; @@ -1493,6 +1497,12 @@ attachment_load_finish (LoadContext *load_context) if (disposition != NULL) camel_mime_part_set_disposition (mime_part, disposition); + /* Correctly report the size of zero length special files. */ + if (g_file_info_get_size (file_info) == 0) { + g_file_info_set_size (file_info, size); + attachment_set_file_info (attachment, file_info); + } + g_simple_async_result_set_op_res_gpointer ( simple, mime_part, (GDestroyNotify) camel_object_unref); -- cgit v1.2.3 From 643186eba2927295ac46d4966578189a2b241e0a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 13 May 2009 11:39:18 -0400 Subject: =?UTF-8?q?Bug=20582144=20=E2=80=93=20Evolution=20not=20showing=20?= =?UTF-8?q?proper=20attachment=20filename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment-store.c | 5 ++++- widgets/misc/e-attachment.c | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 9d0fe6d21e..53a1cbe1ff 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -839,11 +839,13 @@ e_attachment_store_get_uris_async (EAttachmentStore *store, /* Any remaining attachments in the list should have MIME parts * only, so we need to save them all to a temporary directory. - * We use a directory so the files can retain their basenames. */ + * We use a directory so the files can retain their basenames. + * XXX This could trigger a blocking temp directory cleanup. */ template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); path = e_mkdtemp (template); g_free (template); + /* XXX Let's hope errno got set property. */ if (path == NULL) { GSimpleAsyncResult *simple; @@ -871,6 +873,7 @@ e_attachment_store_get_uris_async (EAttachmentStore *store, uri_context); g_object_unref (temp_directory); + g_free (path); } gchar ** diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 67647116e3..e4e336e58b 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -2025,16 +2025,18 @@ attachment_open_save_finished_cb (EAttachment *attachment, static void attachment_open_save_temporary (OpenContext *open_context) { - GFile *file; + GFile *temp_directory; gchar *template; gchar *path; GError *error = NULL; errno = 0; - /* XXX This could trigger a blocking temp directory cleanup. */ + /* Save the file to a temporary directory. + * We use a directory so the files can retain their basenames. + * XXX This could trigger a blocking temp directory cleanup. */ template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mktemp (template); + path = e_mkdtemp (template); g_free (template); /* XXX Let's hope errno got set properly. */ @@ -2048,15 +2050,15 @@ attachment_open_save_temporary (OpenContext *open_context) if (attachment_open_check_for_error (open_context, error)) return; - file = g_file_new_for_path (path); - - g_free (path); + temp_directory = g_file_new_for_path (path); e_attachment_save_async ( - open_context->attachment, file, (GAsyncReadyCallback) + open_context->attachment, + temp_directory, (GAsyncReadyCallback) attachment_open_save_finished_cb, open_context); - g_object_unref (file); + g_object_unref (temp_directory); + g_free (path); } void -- cgit v1.2.3 From 63b66d68529f434d16a12da81a5c611e0df1e7ee Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 14 May 2009 10:50:38 -0400 Subject: =?UTF-8?q?Bug=20582585=20=E2=80=93=20Crash=20when=20deleting=20mu?= =?UTF-8?q?ltiple=20attachments=20from=20composed=20mail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment-view.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 27ef5d84a8..48292cfbc3 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -1038,6 +1038,12 @@ e_attachment_view_remove_selected (EAttachmentView *view, store = e_attachment_view_get_store (view); model = GTK_TREE_MODEL (store); + /* Remove attachments in reverse order to avoid invalidating + * tree paths as we iterate over the list. Note, the list is + * probably already sorted but we sort again just to be safe. */ + selected = g_list_reverse (g_list_sort ( + selected, (GCompareFunc) gtk_tree_path_compare)); + for (item = selected; item != NULL; item = item->next) { EAttachment *attachment; GtkTreePath *path = item->data; -- cgit v1.2.3 From fea524b5292d45a5d02cbfa04bd809cb478fbbcd Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 14 May 2009 12:55:33 -0400 Subject: Add e_attachment_store_get_attachments(). --- widgets/misc/e-attachment-store.c | 76 +++++++++++++++++++++------------------ widgets/misc/e-attachment-store.h | 2 ++ 2 files changed, 44 insertions(+), 34 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 53a1cbe1ff..216a60d32a 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -360,12 +360,35 @@ e_attachment_store_add_to_multipart (EAttachmentStore *store, CamelMultipart *multipart, const gchar *default_charset) { + GList *list, *iter; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (CAMEL_MULTIPART (multipart)); + + list = e_attachment_store_get_attachments (store); + + for (iter = list; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; + + /* Skip the attachment if it's still loading. */ + if (!e_attachment_get_loading (attachment)) + e_attachment_add_to_multipart ( + attachment, multipart, default_charset); + } + + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); +} + +GList * +e_attachment_store_get_attachments (EAttachmentStore *store) +{ + GList *list = NULL; GtkTreeModel *model; GtkTreeIter iter; gboolean valid; - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (CAMEL_MULTIPART (multipart)); + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); model = GTK_TREE_MODEL (store); valid = gtk_tree_model_get_iter_first (model, &iter); @@ -377,15 +400,12 @@ e_attachment_store_add_to_multipart (EAttachmentStore *store, column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; gtk_tree_model_get (model, &iter, column_id, &attachment, -1); - /* Skip the attachment if it's still loading. */ - if (!e_attachment_get_loading (attachment)) - e_attachment_add_to_multipart ( - attachment, multipart, default_charset); - - g_object_unref (attachment); + list = g_list_prepend (list, attachment); valid = gtk_tree_model_iter_next (model, &iter); } + + return g_list_reverse (list); } const gchar * @@ -422,60 +442,48 @@ e_attachment_store_get_num_attachments (EAttachmentStore *store) guint e_attachment_store_get_num_loading (EAttachmentStore *store) { - GtkTreeModel *model; - GtkTreeIter iter; + GList *list, *iter; guint num_loading = 0; - gboolean valid; g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - model = GTK_TREE_MODEL (store); - valid = gtk_tree_model_get_iter_first (model, &iter); + list = e_attachment_store_get_attachments (store); - while (valid) { - EAttachment *attachment; - gint column_id; + for (iter = list; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); if (e_attachment_get_loading (attachment)) num_loading++; - g_object_unref (attachment); - - valid = gtk_tree_model_iter_next (model, &iter); } + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + return num_loading; } goffset e_attachment_store_get_total_size (EAttachmentStore *store) { - GtkTreeModel *model; - GtkTreeIter iter; + GList *list, *iter; goffset total_size = 0; - gboolean valid; g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0); - model = GTK_TREE_MODEL (store); - valid = gtk_tree_model_get_iter_first (model, &iter); + list = e_attachment_store_get_attachments (store); - while (valid) { - EAttachment *attachment; + for (iter = list; iter != NULL; iter = iter->next) { + EAttachment *attachment = iter->data; GFileInfo *file_info; - gint column_id; - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - gtk_tree_model_get (model, &iter, column_id, &attachment, -1); file_info = e_attachment_get_file_info (attachment); if (file_info != NULL) total_size += g_file_info_get_size (file_info); - g_object_unref (attachment); - - valid = gtk_tree_model_iter_next (model, &iter); } + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + return total_size; } diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index e7f89b7f6c..9fdd74d493 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -84,6 +84,8 @@ void e_attachment_store_add_to_multipart (EAttachmentStore *store, CamelMultipart *multipart, const gchar *default_charset); +GList * e_attachment_store_get_attachments + (EAttachmentStore *store); const gchar * e_attachment_store_get_current_folder (EAttachmentStore *store); void e_attachment_store_set_current_folder -- cgit v1.2.3 From a538f3f3100dbdbae1ea172ae3b8344e650d529d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 16 May 2009 12:11:55 -0400 Subject: Fix several types of pedantic compiler warnings. --- widgets/misc/e-canvas-background.c | 2 +- widgets/misc/e-canvas.c | 8 ++++---- widgets/misc/e-charset-picker.c | 2 +- widgets/misc/e-filter-bar.c | 2 +- widgets/misc/e-filter-bar.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c index 77cad661e1..4d300f01d4 100644 --- a/widgets/misc/e-canvas-background.c +++ b/widgets/misc/e-canvas-background.c @@ -74,7 +74,7 @@ enum { PROP_X1, PROP_X2, PROP_Y1, - PROP_Y2, + PROP_Y2 }; static void diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 3cb85c5839..903331576e 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -837,7 +837,7 @@ e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id) if (func) func(info->item, flags, info->id); g_message ("ECANVAS: free info (2): item %p, id %p", - info->item, info->id); + (gpointer) info->item, (gpointer) info->id); g_object_unref (info->item); g_free(info); } @@ -851,7 +851,7 @@ e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id) info->item = item; g_object_ref (info->item); info->id = id; - g_message ("ECANVAS: new info item %p, id %p", item, id); + g_message ("ECANVAS: new info item %p, id %p", (gpointer) item, (gpointer) id); flags = E_CANVAS_ITEM_SELECTION_SELECT | E_CANVAS_ITEM_SELECTION_CURSOR; func = (ECanvasItemSelectionFunc)g_object_get_data(G_OBJECT(item), @@ -920,7 +920,7 @@ e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id) info->item = item; g_object_ref (info->item); info->id = id; - g_message ("ECANVAS: new info (2): item %p, id %p", item, id); + g_message ("ECANVAS: new info (2): item %p, id %p", (gpointer) item, (gpointer) id); func = (ECanvasItemSelectionFunc)g_object_get_data(G_OBJECT(item), "ECanvasItem::selection_callback"); @@ -967,7 +967,7 @@ e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id) canvas->cursor = NULL; g_message ("ECANVAS: removing info: item %p, info %p", - info->item, info->id); + (gpointer) info->item, (gpointer) info->id); g_object_unref (info->item); g_free(info); g_list_free_1(list); diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 6b30b3b11c..81505dcb02 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -46,7 +46,7 @@ typedef enum { E_CHARSET_TURKISH, E_CHARSET_UNICODE, E_CHARSET_WESTERN_EUROPEAN, - E_CHARSET_WESTERN_EUROPEAN_NEW, + E_CHARSET_WESTERN_EUROPEAN_NEW } ECharsetClass; static const char *classnames[] = { diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 2125bdf30d..6d4bff46ca 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -37,7 +37,7 @@ enum { PROP_0, PROP_QUERY, - PROP_STATE, + PROP_STATE }; static gpointer parent_class; diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index edc20e2fec..957eea3d0b 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -107,7 +107,7 @@ enum { E_FILTERBAR_CURRENT_MESSAGE_ID = -6, E_FILTERBAR_CURRENT_FOLDER_ID = -7, E_FILTERBAR_CURRENT_ACCOUNT_ID = -8, - E_FILTERBAR_ALL_ACCOUNTS_ID = -9, + E_FILTERBAR_ALL_ACCOUNTS_ID = -9 }; #define E_FILTERBAR_SAVE { N_("_Save Search..."), E_FILTERBAR_SAVE_ID, 0 } -- cgit v1.2.3 From 74cdb40199a1a429861c11b5356f302c99917d12 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 16 May 2009 14:26:50 -0400 Subject: =?UTF-8?q?Bug=20578478=20=E2=80=93=20Composer=20shows=20not=20all?= =?UTF-8?q?=20"From"=20information?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-account-combo-box.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c index ebde2b5c0e..21f30b697c 100644 --- a/widgets/misc/e-account-combo-box.c +++ b/widgets/misc/e-account-combo-box.c @@ -57,7 +57,7 @@ account_combo_box_has_dupes (GList *list, for (iter = list; iter != NULL; iter = iter->next) { EAccount *account = iter->data; - if (strcmp (account->id->address, address) == 0) + if (g_ascii_strcasecmp (account->id->address, address) == 0) count++; } -- cgit v1.2.3 From 03ca12814b49f7f7999c635d7449dabce0b145b5 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 23 May 2009 22:13:47 -0400 Subject: =?UTF-8?q?Bug=20583339=20=E2=80=93=20Edit->Preferences->Mail=20Ac?= =?UTF-8?q?counts=20inconsistent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/Makefile.am | 4 + widgets/misc/e-account-combo-box.c | 1 + widgets/misc/e-account-combo-box.h | 1 + widgets/misc/e-account-manager.c | 461 +++++++++++++++++++++++++++ widgets/misc/e-account-manager.h | 82 +++++ widgets/misc/e-account-tree-view.c | 621 +++++++++++++++++++++++++++++++++++++ widgets/misc/e-account-tree-view.h | 84 +++++ widgets/misc/e-signature-manager.c | 18 +- widgets/misc/e-signature-manager.h | 4 +- 9 files changed, 1265 insertions(+), 11 deletions(-) create mode 100644 widgets/misc/e-account-manager.c create mode 100644 widgets/misc/e-account-manager.h create mode 100644 widgets/misc/e-account-tree-view.c create mode 100644 widgets/misc/e-account-tree-view.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index bd2c9f9f36..6067149bb5 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -28,6 +28,8 @@ glade_DATA = e-send-options.glade widgetsinclude_HEADERS = \ $(pilot_headers) \ e-account-combo-box.h \ + e-account-manager.h \ + e-account-tree-view.h \ e-action-combo-box.h \ e-activity.h \ e-activity-proxy.h \ @@ -90,6 +92,8 @@ libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ $(pilot_sources) \ e-account-combo-box.c \ + e-account-manager.c \ + e-account-tree-view.c \ e-action-combo-box.c \ e-activity.c \ e-activity-proxy.c \ diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c index 21f30b697c..f9dd3905a7 100644 --- a/widgets/misc/e-account-combo-box.c +++ b/widgets/misc/e-account-combo-box.c @@ -1,4 +1,5 @@ /* + * e-account-combo-box.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/widgets/misc/e-account-combo-box.h b/widgets/misc/e-account-combo-box.h index 87f7eb9704..57f2ebe8ba 100644 --- a/widgets/misc/e-account-combo-box.h +++ b/widgets/misc/e-account-combo-box.h @@ -1,4 +1,5 @@ /* + * e-account-combo-box.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/widgets/misc/e-account-manager.c b/widgets/misc/e-account-manager.c new file mode 100644 index 0000000000..04e050b71d --- /dev/null +++ b/widgets/misc/e-account-manager.c @@ -0,0 +1,461 @@ +/* + * e-account-manager.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-account-manager.h" + +#include +#include +#include "e-util/e-binding.h" +#include "e-account-tree-view.h" + +#define E_ACCOUNT_MANAGER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManagerPrivate)) + +struct _EAccountManagerPrivate { + EAccountList *account_list; + + GtkWidget *tree_view; + GtkWidget *add_button; + GtkWidget *edit_button; + GtkWidget *delete_button; + GtkWidget *default_button; +}; + +enum { + PROP_0, + PROP_ACCOUNT_LIST +}; + +enum { + ADD_ACCOUNT, + EDIT_ACCOUNT, + DELETE_ACCOUNT, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +account_manager_default_clicked_cb (EAccountManager *manager) +{ + EAccountTreeView *tree_view; + EAccountList *account_list; + EAccount *account; + + tree_view = e_account_manager_get_tree_view (manager); + account_list = e_account_manager_get_account_list (manager); + account = e_account_tree_view_get_selected (tree_view); + g_return_if_fail (account != NULL); + + e_account_list_set_default (account_list, account); + + /* This signals the tree view to refresh. */ + e_account_list_change (account_list, account); +} + +static gboolean +account_manager_key_press_event_cb (EAccountManager *manager, + GdkEventKey *event) +{ + if (event->keyval == GDK_Delete) { + e_account_manager_delete_account (manager); + return TRUE; + } + + return FALSE; +} + +static void +account_manager_selection_changed_cb (EAccountManager *manager, + GtkTreeSelection *selection) +{ + EAccountTreeView *tree_view; + EAccountList *account_list; + EAccount *default_account; + EAccount *account; + GtkWidget *add_button; + GtkWidget *edit_button; + GtkWidget *delete_button; + GtkWidget *default_button; + const gchar *url = NULL; + gboolean has_proxies; + gboolean sensitive; + + add_button = manager->priv->add_button; + edit_button = manager->priv->edit_button; + delete_button = manager->priv->delete_button; + default_button = manager->priv->default_button; + + tree_view = e_account_manager_get_tree_view (manager); + account = e_account_tree_view_get_selected (tree_view); + account_list = e_account_tree_view_get_account_list (tree_view); + + if (account != NULL) + url = e_account_get_string (account, E_ACCOUNT_SOURCE_URL); + else + gtk_widget_grab_focus (add_button); + + has_proxies = (url != NULL) && + e_account_list_account_has_proxies (account_list, account); + + /* XXX EAccountList misuses const */ + default_account = (EAccount *) + e_account_list_get_default (account_list); + + sensitive = (account != NULL) && !has_proxies; + gtk_widget_set_sensitive (edit_button, sensitive); + + sensitive = (account != NULL); + gtk_widget_set_sensitive (delete_button, sensitive); + + sensitive = (account != NULL && account != default_account); + gtk_widget_set_sensitive (default_button, sensitive); +} + +static void +account_manager_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACCOUNT_LIST: + e_account_manager_set_account_list ( + E_ACCOUNT_MANAGER (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +account_manager_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACCOUNT_LIST: + g_value_set_object ( + value, + e_account_manager_get_account_list ( + E_ACCOUNT_MANAGER (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +account_manager_dispose (GObject *object) +{ + EAccountManagerPrivate *priv; + + priv = E_ACCOUNT_MANAGER_GET_PRIVATE (object); + + if (priv->account_list != NULL) { + g_object_unref (priv->account_list); + priv->account_list = NULL; + } + + if (priv->tree_view != NULL) { + g_object_unref (priv->tree_view); + priv->tree_view = NULL; + } + + if (priv->add_button != NULL) { + g_object_unref (priv->add_button); + priv->add_button = NULL; + } + + if (priv->edit_button != NULL) { + g_object_unref (priv->edit_button); + priv->edit_button = NULL; + } + + if (priv->delete_button != NULL) { + g_object_unref (priv->delete_button); + priv->delete_button = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +account_manager_class_init (EAccountManagerClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAccountManagerPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = account_manager_set_property; + object_class->get_property = account_manager_get_property; + object_class->dispose = account_manager_dispose; + + /* XXX If we moved the account editor to /widgets/misc we + * could handle adding and editing accounts directly. */ + + g_object_class_install_property ( + object_class, + PROP_ACCOUNT_LIST, + g_param_spec_object ( + "account-list", + "Account List", + NULL, + E_TYPE_ACCOUNT_LIST, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + signals[ADD_ACCOUNT] = g_signal_new ( + "add-account", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EAccountManagerClass, add_account), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[EDIT_ACCOUNT] = g_signal_new ( + "edit-account", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EAccountManagerClass, edit_account), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[DELETE_ACCOUNT] = g_signal_new ( + "delete-account", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EAccountManagerClass, delete_account), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +account_manager_init (EAccountManager *manager) +{ + GtkTreeSelection *selection; + GtkWidget *container; + GtkWidget *widget; + + manager->priv = E_ACCOUNT_MANAGER_GET_PRIVATE (manager); + + gtk_table_resize (GTK_TABLE (manager), 1, 2); + gtk_table_set_col_spacings (GTK_TABLE (manager), 6); + gtk_table_set_row_spacings (GTK_TABLE (manager), 12); + + container = GTK_WIDGET (manager); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_table_attach ( + GTK_TABLE (container), widget, 0, 1, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_widget_show (widget); + + container = widget; + + widget = e_account_tree_view_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + manager->priv->tree_view = g_object_ref (widget); + gtk_widget_show (widget); + + e_mutual_binding_new ( + G_OBJECT (manager), "account-list", + G_OBJECT (widget), "account-list"); + + g_signal_connect_swapped ( + widget, "key-press-event", + G_CALLBACK (account_manager_key_press_event_cb), + manager); + + g_signal_connect_swapped ( + widget, "row-activated", + G_CALLBACK (e_account_manager_edit_account), + manager); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); + + g_signal_connect_swapped ( + selection, "changed", + G_CALLBACK (account_manager_selection_changed_cb), + manager); + + container = GTK_WIDGET (manager); + + widget = gtk_vbutton_box_new (); + gtk_button_box_set_layout ( + GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START); + gtk_box_set_spacing (GTK_BOX (widget), 6); + gtk_table_attach ( + GTK_TABLE (container), widget, + 1, 2, 0, 2, 0, GTK_FILL, 0, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_button_new_from_stock (GTK_STOCK_ADD); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + manager->priv->add_button = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (e_account_manager_add_account), manager); + + widget = gtk_button_new_from_stock (GTK_STOCK_EDIT); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + manager->priv->edit_button = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (e_account_manager_edit_account), manager); + + widget = gtk_button_new_from_stock (GTK_STOCK_DELETE); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + manager->priv->delete_button = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (e_account_manager_delete_account), manager); + + widget = gtk_button_new_with_mnemonic (_("De_fault")); + gtk_button_set_image ( + GTK_BUTTON (widget), gtk_image_new_from_icon_name ( + "emblem-default", GTK_ICON_SIZE_BUTTON)); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + manager->priv->default_button = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (account_manager_default_clicked_cb), manager); +} + +GType +e_account_manager_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAccountManagerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) account_manager_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_init */ + sizeof (EAccountManager), + 0, /* n_preallocs */ + (GInstanceInitFunc) account_manager_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_TABLE, "EAccountManager", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_account_manager_new (EAccountList *account_list) +{ + g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL); + + return g_object_new ( + E_TYPE_ACCOUNT_MANAGER, + "account-list", account_list, NULL); +} + +void +e_account_manager_add_account (EAccountManager *manager) +{ + g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager)); + + g_signal_emit (manager, signals[ADD_ACCOUNT], 0); +} + +void +e_account_manager_edit_account (EAccountManager *manager) +{ + g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager)); + + g_signal_emit (manager, signals[EDIT_ACCOUNT], 0); +} + +void +e_account_manager_delete_account (EAccountManager *manager) +{ + g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager)); + + g_signal_emit (manager, signals[DELETE_ACCOUNT], 0); +} + +EAccountList * +e_account_manager_get_account_list (EAccountManager *manager) +{ + g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL); + + return manager->priv->account_list; +} + +void +e_account_manager_set_account_list (EAccountManager *manager, + EAccountList *account_list) +{ + g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager)); + + if (account_list != NULL) { + g_return_if_fail (E_IS_ACCOUNT_LIST (account_list)); + g_object_ref (account_list); + } + + if (manager->priv->account_list != NULL) + g_object_unref (manager->priv->account_list); + + manager->priv->account_list = account_list; + + g_object_notify (G_OBJECT (manager), "account-list"); +} + +EAccountTreeView * +e_account_manager_get_tree_view (EAccountManager *manager) +{ + g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL); + + return E_ACCOUNT_TREE_VIEW (manager->priv->tree_view); +} diff --git a/widgets/misc/e-account-manager.h b/widgets/misc/e-account-manager.h new file mode 100644 index 0000000000..c714576357 --- /dev/null +++ b/widgets/misc/e-account-manager.h @@ -0,0 +1,82 @@ +/* + * e-account-manager.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ACCOUNT_MANAGER_H +#define E_ACCOUNT_MANAGER_H + +#include +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ACCOUNT_MANAGER \ + (e_account_manager_get_type ()) +#define E_ACCOUNT_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManager)) +#define E_ACCOUNT_MANAGER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ACCOUNT_MANAGER, EAccountManagerClass)) +#define E_IS_ACCOUNT_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ACCOUNT_MANAGER)) +#define E_IS_ACCOUNT_MANAGER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ACCOUNT_MANAGER)) +#define E_ACCOUNT_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManagerClass)) + +G_BEGIN_DECLS + +typedef struct _EAccountManager EAccountManager; +typedef struct _EAccountManagerClass EAccountManagerClass; +typedef struct _EAccountManagerPrivate EAccountManagerPrivate; + +struct _EAccountManager { + GtkTable parent; + EAccountManagerPrivate *priv; +}; + +struct _EAccountManagerClass { + GtkTableClass parent_class; + + void (*add_account) (EAccountManager *manager); + void (*edit_account) (EAccountManager *manager); + void (*delete_account) (EAccountManager *manager); +}; + +GType e_account_manager_get_type (void); +GtkWidget * e_account_manager_new (EAccountList *account_list); +void e_account_manager_add_account (EAccountManager *manager); +void e_account_manager_edit_account (EAccountManager *manager); +void e_account_manager_delete_account(EAccountManager *manager); +EAccountList * e_account_manager_get_account_list + (EAccountManager *manager); +void e_account_manager_set_account_list + (EAccountManager *manager, + EAccountList *account_list); +EAccountTreeView * + e_account_manager_get_tree_view (EAccountManager *manager); + +G_END_DECLS + +#endif /* E_ACCOUNT_MANAGER_H */ diff --git a/widgets/misc/e-account-tree-view.c b/widgets/misc/e-account-tree-view.c new file mode 100644 index 0000000000..9f2d33a050 --- /dev/null +++ b/widgets/misc/e-account-tree-view.c @@ -0,0 +1,621 @@ +/* + * e-account-tree-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-account-tree-view.h" + +#include +#include + +#define E_ACCOUNT_TREE_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewPrivate)) + +enum { + COLUMN_ACCOUNT, + COLUMN_DEFAULT, + COLUMN_ENABLED, + COLUMN_NAME, + COLUMN_PROTOCOL +}; + +enum { + PROP_0, + PROP_ACCOUNT_LIST, + PROP_SELECTED +}; + +enum { + ENABLE_ACCOUNT, + DISABLE_ACCOUNT, + REFRESHED, + LAST_SIGNAL +}; + +struct _EAccountTreeViewPrivate { + EAccountList *account_list; + GHashTable *index; +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +account_tree_view_refresh_cb (EAccountList *account_list, + EAccount *account, + EAccountTreeView *tree_view) +{ + GtkListStore *store; + GtkTreeModel *model; + GtkTreeIter tree_iter; + EIterator *account_iter; + EAccount *default_account; + GHashTable *index; + GList *list = NULL; + GList *iter; + + store = gtk_list_store_new ( + 5, E_TYPE_ACCOUNT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_STRING); + model = GTK_TREE_MODEL (store); + index = tree_view->priv->index; + + g_hash_table_remove_all (index); + + if (account_list == NULL) + goto skip; + + /* XXX EAccountList misuses const. */ + default_account = (EAccount *) + e_account_list_get_default (account_list); + + /* Build a list of EAccounts to display. */ + account_iter = e_list_get_iterator (E_LIST (account_list)); + while (e_iterator_is_valid (account_iter)) { + + /* XXX EIterator misuses const. */ + account = (EAccount *) e_iterator_get (account_iter); + list = g_list_prepend (list, account); + e_iterator_next (account_iter); + } + g_object_unref (account_iter); + + list = g_list_reverse (list); + + /* Populate the list store and index. */ + for (iter = list; iter != NULL; iter = iter->next) { + GtkTreeRowReference *reference; + GtkTreePath *path; + CamelURL *url = NULL; + gboolean is_default; + const gchar *protocol; + + account = iter->data; + + /* Skip proxy accounts. */ + if (account->parent_uid != NULL) + continue; + + is_default = (account == default_account); + + if (account->source != NULL && account->source->url != NULL) + url = camel_url_new (account->source->url, NULL); + + if (url != NULL && url->protocol != NULL) + protocol = url->protocol; + else + protocol = _("None"); + + gtk_list_store_append (store, &tree_iter); + gtk_list_store_set ( + store, &tree_iter, + COLUMN_ACCOUNT, account, + COLUMN_DEFAULT, is_default, + COLUMN_ENABLED, account->enabled, + COLUMN_NAME, account->name, + COLUMN_PROTOCOL, protocol, -1); + + path = gtk_tree_model_get_path (model, &tree_iter); + reference = gtk_tree_row_reference_new (model, path); + g_hash_table_insert (index, account, reference); + gtk_tree_path_free (path); + + if (url != NULL) + camel_url_free (url); + } + +skip: + /* Restore the previously selected account. */ + account = e_account_tree_view_get_selected (tree_view); + if (account != NULL) + g_object_ref (account); + gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model); + e_account_tree_view_set_selected (tree_view, account); + if (account != NULL) + g_object_unref (account); + + g_signal_emit (tree_view, signals[REFRESHED], 0); +} + +static void +account_tree_view_enabled_toggled_cb (EAccountTreeView *tree_view, + gchar *path_string, + GtkCellRendererToggle *renderer) +{ + /* Change the selection first so we enable or disable the + * correct account. */ + + if (gtk_cell_renderer_toggle_get_active (renderer)) + e_account_tree_view_disable_account (tree_view); + else + e_account_tree_view_enable_account (tree_view); +} + +static void +account_tree_view_selection_changed_cb (EAccountTreeView *tree_view) +{ + g_object_notify (G_OBJECT (tree_view), "selected"); +} + +static GObject * +account_tree_view_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GObject *object; + GtkTreeView *tree_view; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + /* Chain up to parent's constructor() method. */ + object = G_OBJECT_CLASS (parent_class)->constructor ( + type, n_construct_properties, construct_properties); + + tree_view = GTK_TREE_VIEW (object); + gtk_tree_view_set_headers_visible (tree_view, TRUE); + + /* Column: Enabled */ + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_expand (column, FALSE); + gtk_tree_view_column_set_title (column, _("Enabled")); + + renderer = gtk_cell_renderer_toggle_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + g_signal_connect_swapped ( + renderer, "toggled", + G_CALLBACK (account_tree_view_enabled_toggled_cb), + tree_view); + + gtk_tree_view_column_add_attribute ( + column, renderer, "active", COLUMN_ENABLED); + + gtk_tree_view_append_column (tree_view, column); + + /* Column: Account Name */ + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_column_set_title (column, _("Account Name")); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "text", COLUMN_NAME); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "text", _("Default"), NULL); + gtk_tree_view_column_pack_end (column, renderer, FALSE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "visible", COLUMN_DEFAULT); + + renderer = gtk_cell_renderer_pixbuf_new (); + g_object_set ( + renderer, "icon-name", "emblem-default", + "stock-size", GTK_ICON_SIZE_MENU, NULL); + gtk_tree_view_column_pack_end (column, renderer, FALSE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "visible", COLUMN_DEFAULT); + + gtk_tree_view_append_column (tree_view, column); + + /* Column: Protocol */ + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_expand (column, FALSE); + gtk_tree_view_column_set_title (column, _("Protocol")); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + + gtk_tree_view_column_add_attribute ( + column, renderer, "text", COLUMN_PROTOCOL); + + gtk_tree_view_append_column (tree_view, column); + + return object; +} + +static void +account_tree_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACCOUNT_LIST: + e_account_tree_view_set_account_list ( + E_ACCOUNT_TREE_VIEW (object), + g_value_get_object (value)); + return; + + case PROP_SELECTED: + e_account_tree_view_set_selected ( + E_ACCOUNT_TREE_VIEW (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +account_tree_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACCOUNT_LIST: + g_value_set_object ( + value, + e_account_tree_view_get_account_list ( + E_ACCOUNT_TREE_VIEW (object))); + return; + + case PROP_SELECTED: + g_value_set_object ( + value, + e_account_tree_view_get_selected ( + E_ACCOUNT_TREE_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +account_tree_view_dispose (GObject *object) +{ + EAccountTreeViewPrivate *priv; + + priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (object); + + if (priv->account_list != NULL) { + g_signal_handlers_disconnect_by_func ( + priv->account_list, + account_tree_view_refresh_cb, object); + g_object_unref (priv->account_list); + priv->account_list = NULL; + } + + g_hash_table_remove_all (priv->index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +account_tree_view_finalize (GObject *object) +{ + EAccountTreeViewPrivate *priv; + + priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (object); + + g_hash_table_destroy (priv->index); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +account_tree_view_enable_account (EAccountTreeView *tree_view) +{ + EAccountList *account_list; + EAccount *account; + + account = e_account_tree_view_get_selected (tree_view); + if (account == NULL || account->enabled) + return; + + account_list = e_account_tree_view_get_account_list (tree_view); + g_return_if_fail (account_list != NULL); + + account->enabled = TRUE; + e_account_list_change (account_list, account); +} + +static void +account_tree_view_disable_account (EAccountTreeView *tree_view) +{ + EAccountList *account_list; + EAccount *account; + + account = e_account_tree_view_get_selected (tree_view); + if (account == NULL || !account->enabled) + return; + + account_list = e_account_tree_view_get_account_list (tree_view); + g_return_if_fail (account_list != NULL); + + account->enabled = FALSE; + e_account_list_change (account_list, account); +} + +static void +account_tree_view_class_init (EAccountTreeViewClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAccountTreeViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructor = account_tree_view_constructor; + object_class->set_property = account_tree_view_set_property; + object_class->get_property = account_tree_view_get_property; + object_class->dispose = account_tree_view_dispose; + object_class->finalize = account_tree_view_finalize; + + class->enable_account = account_tree_view_enable_account; + class->disable_account = account_tree_view_disable_account; + + g_object_class_install_property ( + object_class, + PROP_SELECTED, + g_param_spec_object ( + "selected", + "Selected Account", + NULL, + E_TYPE_ACCOUNT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_ACCOUNT_LIST, + g_param_spec_object ( + "account-list", + "Account List", + NULL, + E_TYPE_ACCOUNT_LIST, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + signals[ENABLE_ACCOUNT] = g_signal_new ( + "enable-account", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAccountTreeViewClass, enable_account), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[DISABLE_ACCOUNT] = g_signal_new ( + "disable-account", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAccountTreeViewClass, disable_account), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[REFRESHED] = g_signal_new ( + "refreshed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAccountTreeViewClass, refreshed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +account_tree_view_init (EAccountTreeView *tree_view) +{ + GHashTable *index; + GtkTreeSelection *selection; + + /* Reverse-lookup index */ + index = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) gtk_tree_row_reference_free); + + tree_view->priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view); + tree_view->priv->index = index; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + + g_signal_connect_swapped ( + selection, "changed", + G_CALLBACK (account_tree_view_selection_changed_cb), + tree_view); +} + +GType +e_account_tree_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAccountTreeViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) account_tree_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAccountTreeView), + 0, /* n_preallocs */ + (GInstanceInitFunc) account_tree_view_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_TREE_VIEW, "EAccountTreeView", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_account_tree_view_new (void) +{ + return g_object_new (E_TYPE_ACCOUNT_TREE_VIEW, NULL); +} + +void +e_account_tree_view_enable_account (EAccountTreeView *tree_view) +{ + g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view)); + + g_signal_emit (tree_view, signals[ENABLE_ACCOUNT], 0); +} + +void +e_account_tree_view_disable_account (EAccountTreeView *tree_view) +{ + g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view)); + + g_signal_emit (tree_view, signals[DISABLE_ACCOUNT], 0); +} + +EAccountList * +e_account_tree_view_get_account_list (EAccountTreeView *tree_view) +{ + g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), NULL); + + return tree_view->priv->account_list; +} + +void +e_account_tree_view_set_account_list (EAccountTreeView *tree_view, + EAccountList *account_list) +{ + EAccountTreeViewPrivate *priv; + + g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view)); + + if (account_list != NULL) + g_return_if_fail (E_IS_ACCOUNT_LIST (account_list)); + + priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view); + + if (priv->account_list != NULL) { + g_signal_handlers_disconnect_by_func ( + priv->account_list, + account_tree_view_refresh_cb, tree_view); + g_object_unref (priv->account_list); + priv->account_list = NULL; + } + + if (account_list != NULL) { + priv->account_list = g_object_ref (account_list); + + /* Listen for changes to the account list. */ + g_signal_connect ( + priv->account_list, "account-added", + G_CALLBACK (account_tree_view_refresh_cb), + tree_view); + g_signal_connect ( + priv->account_list, "account-changed", + G_CALLBACK (account_tree_view_refresh_cb), + tree_view); + g_signal_connect ( + priv->account_list, "account-removed", + G_CALLBACK (account_tree_view_refresh_cb), + tree_view); + } + + account_tree_view_refresh_cb (account_list, NULL, tree_view); + + g_object_notify (G_OBJECT (tree_view), "account-list"); +} + +EAccount * +e_account_tree_view_get_selected (EAccountTreeView *tree_view) +{ + EAccount *account; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return NULL; + + gtk_tree_model_get (model, &iter, COLUMN_ACCOUNT, &account, -1); + + return account; +} + +gboolean +e_account_tree_view_set_selected (EAccountTreeView *tree_view, + EAccount *account) +{ + GtkTreeRowReference *reference; + GtkTreeSelection *selection; + GtkTreePath *path; + + g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE); + + if (account != NULL) + g_return_val_if_fail (E_IS_ACCOUNT (account), FALSE); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + + /* NULL means clear the selection. */ + if (account == NULL) { + gtk_tree_selection_unselect_all (selection); + return TRUE; + } + + /* Lookup the tree row reference for the account. */ + reference = g_hash_table_lookup (tree_view->priv->index, account); + if (reference == NULL) + return FALSE; + + /* Select the referenced path. */ + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); + + g_object_notify (G_OBJECT (tree_view), "selected"); + + return TRUE; +} diff --git a/widgets/misc/e-account-tree-view.h b/widgets/misc/e-account-tree-view.h new file mode 100644 index 0000000000..9d86a8f803 --- /dev/null +++ b/widgets/misc/e-account-tree-view.h @@ -0,0 +1,84 @@ +/* + * e-account-tree-view.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ACCOUNT_TREE_VIEW_H +#define E_ACCOUNT_TREE_VIEW_H + +#include +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_ACCOUNT_TREE_VIEW \ + (e_account_tree_view_get_type ()) +#define E_ACCOUNT_TREE_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeView)) +#define E_ACCOUNT_TREE_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewClass)) +#define E_IS_ACCOUNT_TREE_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ACCOUNT_TREE_VIEW)) +#define E_IS_ACCOUNT_TREE_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ACCOUNT_TREE_VIEW)) +#define E_ACCOUNT_TREE_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewClass)) + +G_BEGIN_DECLS + +typedef struct _EAccountTreeView EAccountTreeView; +typedef struct _EAccountTreeViewClass EAccountTreeViewClass; +typedef struct _EAccountTreeViewPrivate EAccountTreeViewPrivate; + +struct _EAccountTreeView { + GtkTreeView parent; + EAccountTreeViewPrivate *priv; +}; + +struct _EAccountTreeViewClass { + GtkTreeViewClass parent_class; + + void (*enable_account) (EAccountTreeView *tree_view); + void (*disable_account) (EAccountTreeView *tree_view); + void (*refreshed) (EAccountTreeView *tree_view); +}; + +GType e_account_tree_view_get_type (void); +GtkWidget * e_account_tree_view_new (void); +void e_account_tree_view_enable_account + (EAccountTreeView *tree_view); +void e_account_tree_view_disable_account + (EAccountTreeView *tree_view); +EAccountList * e_account_tree_view_get_account_list + (EAccountTreeView *tree_view); +void e_account_tree_view_set_account_list + (EAccountTreeView *tree_view, + EAccountList *account_list); +EAccount * e_account_tree_view_get_selected(EAccountTreeView *tree_view); +gboolean e_account_tree_view_set_selected(EAccountTreeView *tree_view, + EAccount *account); + +G_END_DECLS + +#endif /* E_ACCOUNT_TREE_VIEW_H */ diff --git a/widgets/misc/e-signature-manager.c b/widgets/misc/e-signature-manager.c index 0c145e9821..a602710fd3 100644 --- a/widgets/misc/e-signature-manager.c +++ b/widgets/misc/e-signature-manager.c @@ -143,21 +143,21 @@ static void signature_manager_selection_changed_cb (ESignatureManager *manager, GtkTreeSelection *selection) { + ESignatureTreeView *tree_view; + ESignature *signature; GtkWidget *edit_button; GtkWidget *remove_button; - GtkTreeModel *model; - GtkTreeIter iter; + gboolean sensitive; edit_button = manager->priv->edit_button; remove_button = manager->priv->remove_button; - if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - gtk_widget_set_sensitive (edit_button, TRUE); - gtk_widget_set_sensitive (remove_button, TRUE); - } else { - gtk_widget_set_sensitive (edit_button, FALSE); - gtk_widget_set_sensitive (remove_button, FALSE); - } + tree_view = e_signature_manager_get_tree_view (manager); + signature = e_signature_tree_view_get_selected (tree_view); + sensitive = (signature != NULL); + + gtk_widget_set_sensitive (edit_button, sensitive); + gtk_widget_set_sensitive (remove_button, sensitive); } static void diff --git a/widgets/misc/e-signature-manager.h b/widgets/misc/e-signature-manager.h index 6c182badab..f00ad143ec 100644 --- a/widgets/misc/e-signature-manager.h +++ b/widgets/misc/e-signature-manager.h @@ -24,8 +24,8 @@ #include #include -#include -#include +#include +#include /* Standard GObject macros */ #define E_TYPE_SIGNATURE_MANAGER \ -- cgit v1.2.3 From 4324f34596feee175c5934bfbe8011fc1f31f7b8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 24 May 2009 00:52:23 -0400 Subject: Fix some account UI glitches. --- widgets/misc/e-account-tree-view.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-account-tree-view.c b/widgets/misc/e-account-tree-view.c index 9f2d33a050..78f92d5f06 100644 --- a/widgets/misc/e-account-tree-view.c +++ b/widgets/misc/e-account-tree-view.c @@ -159,8 +159,15 @@ account_tree_view_enabled_toggled_cb (EAccountTreeView *tree_view, gchar *path_string, GtkCellRendererToggle *renderer) { + GtkTreeSelection *selection; + GtkTreePath *path; + /* Change the selection first so we enable or disable the * correct account. */ + path = gtk_tree_path_new_from_string (path_string); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); if (gtk_cell_renderer_toggle_get_active (renderer)) e_account_tree_view_disable_account (tree_view); @@ -355,6 +362,8 @@ account_tree_view_enable_account (EAccountTreeView *tree_view) account->enabled = TRUE; e_account_list_change (account_list, account); + + e_account_list_save (account_list); } static void @@ -372,6 +381,8 @@ account_tree_view_disable_account (EAccountTreeView *tree_view) account->enabled = FALSE; e_account_list_change (account_list, account); + + e_account_list_save (account_list); } static void -- cgit v1.2.3 From 2ea8d8f1930bdc7f30e8556d6abeca33eb263af6 Mon Sep 17 00:00:00 2001 From: Srinivasa Ragavan Date: Fri, 22 May 2009 17:07:09 +0530 Subject: Filter/Search bar changes for Anjal. --- widgets/misc/Makefile.am | 3 +- widgets/misc/e-filter-bar.c | 27 ++- widgets/misc/e-filter-bar.h | 29 +++- widgets/misc/e-search-bar.c | 395 +++++++++++++++++++++++++++++++++++++------- widgets/misc/e-search-bar.h | 112 ++++++++----- widgets/misc/e-spinner.c | 7 +- 6 files changed, 462 insertions(+), 111 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 6067149bb5..d6a42f10c2 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -14,6 +14,7 @@ privsolib_LTLIBRARIES = \ libemiscwidgets.la widgetsincludedir = $(privincludedir)/misc +filterbarincludedir = $(privincludedir)/misc if ENABLE_PILOT_CONDUITS pilot_sources = e-pilot-settings.c @@ -69,7 +70,6 @@ widgetsinclude_HEADERS = \ e-popup-menu.h \ e-preferences-window.h \ e-printable.h \ - e-search-bar.h \ e-selection-model.h \ e-selection-model-array.h \ e-selection-model-simple.h \ @@ -133,7 +133,6 @@ libemiscwidgets_la_SOURCES = \ e-popup-menu.c \ e-preferences-window.c \ e-printable.c \ - e-search-bar.c \ e-selection-model.c \ e-selection-model-array.c \ e-selection-model-simple.c \ diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index b842bc86d0..9f38ecc3d3 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -843,6 +843,7 @@ e_filter_bar_get_type (void) { static GType type = 0; +<<<<<<< HEAD:widgets/misc/e-filter-bar.c if (G_UNLIKELY (type == 0)) { static const GTypeInfo type_info = { sizeof (EFilterBarClass), @@ -856,6 +857,10 @@ e_filter_bar_get_type (void) (GInstanceInitFunc) filter_bar_init, NULL /* value_table */ }; +======= + bar = g_object_new (e_filter_bar_get_type (), NULL); + ((ESearchBar *)bar)->lite = FALSE; +>>>>>>> ff25805... Filter/Search bar changes for Anjal.:widgets/misc/e-filter-bar.c type = g_type_register_static ( E_TYPE_SEARCH_BAR, "EFilterBar", &type_info, 0); @@ -865,9 +870,25 @@ e_filter_bar_get_type (void) } EFilterBar * -e_filter_bar_new (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, +e_filter_bar_lite_new (RuleContext *context, + const char *systemrules, + const char *userrules, + EFilterBarConfigRule config, + void *data) +{ + EFilterBar *bar; + + bar = g_object_new (e_filter_bar_get_type (), NULL); + ((ESearchBar *)bar)->lite = TRUE; + e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar); + + return bar; +} + +void +e_filter_bar_new_construct (RuleContext *context, + const char *systemrules, + const char *userrules, EFilterBarConfigRule config, gpointer data) { diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index b41f24e293..4e51d54c3e 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -126,12 +126,29 @@ const char * strings[] = { #endif -GType e_filter_bar_get_type (void); -EFilterBar * e_filter_bar_new (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data); +GType e_filter_bar_get_type (void); + +EFilterBar *e_filter_bar_new (RuleContext *context, + const char *systemrules, + const char *userrules, + EFilterBarConfigRule config, + void *data); +EFilterBar *e_filter_bar_lite_new (RuleContext *context, + const char *systemrules, + const char *userrules, + EFilterBarConfigRule config, + void *data); + +void +e_filter_bar_new_construct (RuleContext *context, + const char *systemrules, + const char *userrules, + EFilterBarConfigRule config, + void *data ,EFilterBar *bar ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ G_END_DECLS diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index a588b73b0c..2d1fd5eb5e 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -91,37 +91,69 @@ action_search_find_cb (GtkAction *action, } static void -action_search_type_cb (GtkAction *action, - ESearchBar *search_bar) +clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearchBar *search_bar) { - gtk_menu_popup ( - GTK_MENU (search_bar->priv->search_popup_menu), - NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); + g_return_if_fail (clear_button != NULL && search_bar != NULL); + + if (!search_bar->lite) + update_clear_menuitem_sensitive (search_bar); } -static GtkActionEntry search_entries[] = { - - { "search-clear", - GTK_STOCK_CLEAR, - NULL, - "q", - N_("Clear the most recent search"), - G_CALLBACK (action_search_clear_cb) }, - - { "search-find", - GTK_STOCK_FIND, - N_("_Find Now"), - NULL, - N_("Execute the search"), - G_CALLBACK (action_search_find_cb) }, - - { "search-type", - GTK_STOCK_FIND, - NULL, - NULL, - NULL, - G_CALLBACK (action_search_type_cb) } -}; +static char * +verb_name_from_id (int id) +{ + return g_strdup_printf ("ESearchBar:Activate:%d", id); +} + +/* This implements the "clear" action, i.e. clears the text and then emits + * ::search_activated. */ + +static void +clear_search (ESearchBar *esb) +{ + e_search_bar_set_text (esb, ""); + esb->block_search = TRUE; + if (esb->item_id < 0) + e_search_bar_set_item_id (esb, esb->last_search_option); + e_search_bar_set_viewitem_id (esb, 0); + esb->block_search = FALSE; + emit_search_activated (esb); +} + +static void +free_menu_items (ESearchBar *esb) +{ + GSList *p; + + if (esb->menu_items == NULL) + return; + + for (p = esb->menu_items; p != NULL; p = p->next) { + ESearchBarItem *item; + + item = (ESearchBarItem *) p->data; + + /* (No submitems for the menu_items, so no need to free that + member.) */ + + g_free (item->text); + g_free (item); + } + + g_slist_free (esb->menu_items); + esb->menu_items = NULL; +} + + +/* Signals. */ + +static void +emit_query_changed (ESearchBar *esb) +{ + g_signal_emit (esb, esb_signals [QUERY_CHANGED], 0); + if (!esb->lite) + update_clear_menuitem_sensitive (esb); +} static void search_bar_rule_changed (FilterRule *rule, @@ -131,10 +163,10 @@ search_bar_rule_changed (FilterRule *rule, sensitive = (rule != NULL && rule->parts != NULL); - gtk_dialog_set_response_sensitive ( - dialog, GTK_RESPONSE_OK, sensitive); - gtk_dialog_set_response_sensitive ( - dialog, GTK_RESPONSE_APPLY, sensitive); + if (!esb->lite) { + set_find_now_sensitive (esb, FALSE); + update_clear_menuitem_sensitive (esb); + } } static void @@ -221,8 +253,37 @@ paint_search_text (GtkWidget *widget, void e_search_bar_paint (ESearchBar *search_bar) { - EIconEntry *icon_entry; - GtkWidget *entry; + paint_search_text (search_bar->entry, search_bar); +} + +static gboolean +entry_focus_out_cb (GtkWidget *widget, + GdkEventFocus *event, + ESearchBar *esb) +{ + return paint_search_text (widget, esb); +} + +static void +entry_activated_cb (GtkWidget *widget, + ESearchBar *esb) +{ + const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); + GtkStyle *style = gtk_widget_get_default_style (); + + if (text && *text) { + gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + if (!esb->lite) + gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); + } else { + gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); + if (!esb->lite) + gtk_widget_set_sensitive (esb->clear_button, FALSE); + } icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); entry = e_icon_entry_get_entry (icon_entry); @@ -539,10 +600,68 @@ search_bar_dispose (GObject *object) priv->filter_combo_box = NULL; } - if (priv->search_label != NULL) { - g_object_unref (priv->search_label); - priv->search_label = NULL; - } + if (!esb->lite && esb->ui_component != NULL) + update_bonobo_menus (esb); +} + +/* /\* Callback used when an option item is destroyed. We have to destroy its */ +/* * suboption items. */ +/* *\/ */ +/* static void */ +/* option_item_destroy_cb (GtkObject *object, gpointer data) */ +/* { */ +/* /\* ESearchBarSubitem *subitems; *\/ */ + +/* /\* subitems = data; *\/ */ + +/* /\* g_assert (subitems != NULL); *\/ */ +/* /\* free_subitems (subitems); *\/ */ +/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */ +/* } */ + +static void +set_option (ESearchBar *esb, ESearchBarItem *items) +{ + GtkWidget *menu; + GSList *group = NULL; + int i; + + if (esb->option_menu) + gtk_widget_destroy (esb->option_menu); + + esb->option_menu = menu = gtk_menu_new (); + for (i = 0; items[i].id != -1; i++) { + GtkWidget *item; + + /* Create a new group */ + if (items[i].id == 0) + group = NULL; + + if (items[i].text) { + char *str; + str = e_str_without_underscores (_(items[i].text)); + switch (items[i].type) { + case ESB_ITEMTYPE_NORMAL: + item = gtk_menu_item_new_with_label (str); + break; + case ESB_ITEMTYPE_CHECK: + item = gtk_check_menu_item_new_with_label (str); + break; + case ESB_ITEMTYPE_RADIO: + item = gtk_radio_menu_item_new_with_label (group, str); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); + break; + default: + /* Fixme : this should be a normal item */ + item = gtk_radio_menu_item_new_with_label (group, str); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); + break; + } + g_free (str); + } else { + item = gtk_menu_item_new (); + gtk_widget_set_sensitive (item, FALSE); + } if (priv->search_entry != NULL) { g_object_unref (priv->search_entry); @@ -816,19 +935,18 @@ e_search_bar_get_type (void) { static GType type = 0; - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (ESearchBarClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) search_bar_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (ESearchBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) search_bar_init, - NULL /* value_table */ - }; + if (!esb->lite && esb->ui_component != NULL) { + bonobo_object_unref (BONOBO_OBJECT (esb->ui_component)); + esb->ui_component = NULL; + } +/* if (esb->entry) { */ +/* g_object_unref (esb->entry); */ +/* esb->entry = NULL; */ +/* } */ + if (esb->suboption) { + g_object_unref (esb->suboption); + esb->suboption = NULL; + } type = g_type_register_static ( GTK_TYPE_HBOX, "ESearchBar", &type_info, 0); @@ -869,8 +987,115 @@ e_search_bar_set_context (ESearchBar *search_bar, if (search_bar->priv->context != NULL) g_object_unref (search_bar->priv->context); - search_bar->priv->context = g_object_ref (context); - g_object_notify (G_OBJECT (search_bar), "context"); + bighbox = gtk_hbox_new (FALSE, 0); + search_bar->entry_box = gtk_hbox_new (0, FALSE); + search_bar->icon_entry = e_icon_entry_new (); + search_bar->entry = e_icon_entry_get_entry (E_ICON_ENTRY (search_bar->icon_entry)); + + g_signal_connect (search_bar->entry, "changed", + G_CALLBACK (entry_changed_cb), search_bar); + g_signal_connect (search_bar->entry, "activate", + G_CALLBACK (entry_activated_cb), search_bar); + g_signal_connect (search_bar->entry, "focus-in-event", + G_CALLBACK (entry_focus_in_cb), search_bar); + g_signal_connect (search_bar->entry, "focus-out-event", + G_CALLBACK (entry_focus_out_cb), search_bar); + g_signal_connect (search_bar->entry, "key-press-event", + G_CALLBACK (entry_key_press_cb), search_bar); + + search_bar->clear_button = e_icon_entry_create_button ("gtk-clear"); + g_signal_connect (G_OBJECT (search_bar->clear_button), "button-press-event", G_CALLBACK(clear_button_clicked_cb), search_bar); + e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->clear_button, FALSE); + + search_bar->option_button = e_icon_entry_create_button ("gtk-find"); + g_signal_connect (G_OBJECT (search_bar->option_button), "button-press-event", G_CALLBACK(option_button_clicked_cb), search_bar); + e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->option_button, TRUE); + + if (!search_bar->lite) + gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, FALSE, FALSE, 0); + else + gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, TRUE, TRUE, 0); + + + gtk_widget_show_all (search_bar->entry_box); + gtk_widget_set_sensitive (search_bar->clear_button, FALSE); + + if (!search_bar->lite) { + /* Current View filter */ + search_bar->viewoption_box = gtk_hbox_new (0, FALSE); + + /* To Translators: The "Show: " label is followed by the Quick Search Dropdown Menu where you can choose + to display "All Messages", "Unread Messages", "Message with 'Important' Label" and so on... */ + label = gtk_label_new_with_mnemonic (_("Sho_w: ")); + gtk_widget_show (label); + gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), label, FALSE, FALSE, 0); + + search_bar->viewoption = gtk_option_menu_new (); + gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->viewoption); + gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), search_bar->viewoption, FALSE, TRUE, 0); + gtk_widget_show_all (search_bar->viewoption_box); + gtk_box_pack_start (GTK_BOX(search_bar), search_bar->viewoption_box, FALSE, FALSE, 0); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); + } + + /* Search entry */ + hbox = gtk_hbox_new (FALSE, 0); + /* To Translators: The "Show: " label is followed by the Quick Search Text input field where one enters + the term to search for */ + if (!search_bar->lite) { + label = gtk_label_new_with_mnemonic (_("Sear_ch: ")); + gtk_widget_show (label); + gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, FALSE, FALSE, 0); + gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->entry); + } else { + gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, TRUE, TRUE, 0); + } + gtk_widget_show (search_bar->entry_box); + + if (!search_bar->lite) { + /* Search Scope Widgets */ + search_bar->scopeoption_box = gtk_hbox_new (0, FALSE); + gtk_box_set_spacing (GTK_BOX (search_bar->scopeoption_box), 3); + /* To Translators: The " in " label is part of the Quick Search Bar, example: + Search: | | in | Current Folder/All Accounts/Current Account */ + label = gtk_label_new_with_mnemonic (_(" i_n ")); + gtk_widget_show (label); + gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0); + + search_bar->scopeoption = gtk_option_menu_new (); + /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ + gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0); + gtk_widget_show_all (search_bar->scopeoption_box); + gtk_widget_hide (hbox); + gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->scopeoption); + + gtk_box_pack_end (GTK_BOX(hbox), search_bar->scopeoption_box, FALSE, FALSE, 0); + gtk_widget_hide (search_bar->scopeoption_box); + + } + if (!search_bar->lite) + gtk_box_pack_end (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); + else + gtk_box_pack_end (GTK_BOX(search_bar), hbox, TRUE, TRUE, 0); + + gtk_widget_show (hbox); + + /* Set the menu */ + e_search_bar_set_menu (search_bar, menu_items); + e_search_bar_set_option (search_bar, option_items); + + /* + * If the default choice for the option menu has subitems, then we need to + * activate the search immediately. However, the developer won't have + * connected to the activated signal until after the object is constructed, + * so we can't emit here. Thus we launch a one-shot idle function that will + * emit the changed signal, so that the proper callback will get invoked. + */ + if (!search_bar->lite) + search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar); } GtkRadioAction * @@ -996,10 +1221,42 @@ e_search_bar_get_search_text (ESearchBar *search_bar) color1 = &style1->text[GTK_STATE_NORMAL]; color2 = &style2->text[GTK_STATE_INSENSITIVE]; - if (gdk_color_equal (color1, color2)) - return ""; +GtkWidget * +e_search_bar_lite_new (ESearchBarItem *menu_items, + ESearchBarItem *option_items) +{ + GtkWidget *widget; + + g_return_val_if_fail (option_items != NULL, NULL); + + widget = g_object_new (e_search_bar_get_type (), NULL); + E_SEARCH_BAR(widget)->lite = TRUE; - return gtk_entry_get_text (GTK_ENTRY (entry)); + e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); + + return widget; +} + +void +e_search_bar_set_ui_component (ESearchBar *search_bar, + BonoboUIComponent *ui_component) +{ + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + + if (search_bar->lite) + return; + + if (search_bar->ui_component != NULL) { + remove_bonobo_menus (search_bar); + bonobo_object_unref (BONOBO_OBJECT (search_bar->ui_component)); + } + + search_bar->ui_component = ui_component; + if (ui_component != NULL) { + bonobo_object_ref (BONOBO_OBJECT (ui_component)); + setup_standard_verbs (search_bar); + setup_bonobo_menus (search_bar); + } } void @@ -1009,7 +1266,12 @@ e_search_bar_set_search_text (ESearchBar *search_bar, EIconEntry *icon_entry; GtkWidget *entry; - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + if (search_bar->lite) + return; + + verb_name = verb_name_from_id (id); + path = g_strconcat ("/commands/", verb_name, NULL); + g_free (verb_name); icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); entry = e_icon_entry_get_entry (icon_entry); @@ -1033,6 +1295,8 @@ e_search_bar_set_search_value (ESearchBar *search_bar, gint value) { g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + if (!search_bar->viewoption_menu) + return; /* FIXME */ @@ -1044,7 +1308,22 @@ e_search_bar_get_search_visible (ESearchBar *search_bar) { g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - return GTK_WIDGET_VISIBLE (search_bar->priv->search_entry); + if (!search_bar->option_menu) + return; + row = find_id (search_bar->option_menu, id, "EsbItemId", NULL); + if (row == -1) + return; + + if (id>=0) + search_bar->last_search_option = id; + search_bar->item_id = id; + gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row); + + if (!search_bar->block_search) + emit_query_changed (search_bar); + + if (!search_bar->lite) + update_clear_menuitem_sensitive (search_bar); } void diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index 333cbabc82..aadfc42ab5 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -56,51 +56,85 @@ typedef struct _ESearchBarPrivate ESearchBarPrivate; struct _ESearchBar { GtkHBox parent; - ESearchBarPrivate *priv; + + BonoboUIComponent *ui_component; + + GSList *menu_items; + + /* item specific fields */ + GtkWidget *option; + GtkWidget *entry; + GtkWidget *suboption; /* an option menu for the choices associated with some options */ + + /* PRIVATE */ + GtkWidget *dropdown_holder; /* holds the dropdown */ + GtkWidget *option_menu; + GtkWidget *suboption_menu; + GtkWidget *option_button; + GtkWidget *clear_button; + GtkWidget *entry_box; + GtkWidget *icon_entry; + + /* show option widgets */ + GtkWidget *viewoption_box; + GtkWidget *viewoption; /* an option menu for the choices associated with some search options */ + GtkWidget *viewoption_menu; + + /* search scope widgets */ + GtkWidget *scopeoption_box; + GtkWidget *scopeoption; /* an option menu for the choices associated with scope search */ + GtkWidget *scopeoption_menu; + + guint pending_activate; + + /* The currently-selected item & subitem */ + int item_id; + int viewitem_id; /* Current View Id */ + int scopeitem_id; /* Scope of search */ + int last_search_option; + + gboolean block_search; + gboolean lite; }; struct _ESearchBarClass { GtkHBoxClass parent_class; }; -GType e_search_bar_get_type (void); -GtkWidget * e_search_bar_new (void); -GtkActionGroup *e_search_bar_get_action_group (ESearchBar *search_bar); -RuleContext * e_search_bar_get_context (ESearchBar *search_bar); -void e_search_bar_set_context (ESearchBar *search_bar, - RuleContext *context); -GtkRadioAction *e_search_bar_get_filter_action (ESearchBar *search_bar); -void e_search_bar_set_filter_action (ESearchBar *search_bar, - GtkRadioAction *action); -gint e_search_bar_get_filter_value (ESearchBar *search_bar); -void e_search_bar_set_filter_value (ESearchBar *search_bar, - gint value); -gboolean e_search_bar_get_filter_visible (ESearchBar *search_bar); -void e_search_bar_set_filter_visible (ESearchBar *search_bar, - gboolean visible); -GtkRadioAction *e_search_bar_get_search_action (ESearchBar *search_bar); -void e_search_bar_set_search_action (ESearchBar *search_bar, - GtkRadioAction *action); -const gchar * e_search_bar_get_search_text (ESearchBar *search_bar); -void e_search_bar_set_search_text (ESearchBar *search_bar, - const gchar *text); -gint e_search_bar_get_search_value (ESearchBar *search_bar); -void e_search_bar_set_search_value (ESearchBar *search_bar, - gint value); -gboolean e_search_bar_get_search_visible (ESearchBar *search_bar); -void e_search_bar_set_search_visible (ESearchBar *search_bar, - gboolean visible); -GtkRadioAction *e_search_bar_get_scope_action (ESearchBar *search_bar); -void e_search_bar_set_scope_action (ESearchBar *search_bar, - GtkRadioAction *action); -gint e_search_bar_get_scope_value (ESearchBar *search_bar); -void e_search_bar_set_scope_value (ESearchBar *search_bar, - gint value); -gboolean e_search_bar_get_scope_visible (ESearchBar *search_bar); -void e_search_bar_set_scope_visible (ESearchBar *search_bar, - gboolean visible); -void e_search_bar_save_search_dialog (ESearchBar *search_bar, - const gchar *filename); + +GType e_search_bar_get_type (void); +void e_search_bar_construct (ESearchBar *search_bar, + ESearchBarItem *menu_items, + ESearchBarItem *option_items); +GtkWidget *e_search_bar_new (ESearchBarItem *menu_items, + ESearchBarItem *option_items); +GtkWidget *e_search_bar_lite_new (ESearchBarItem *menu_items, + ESearchBarItem *option_items); + +void e_search_bar_set_ui_component (ESearchBar *search_bar, + BonoboUIComponent *ui_component); + +void e_search_bar_set_menu (ESearchBar *search_bar, + ESearchBarItem *menu_items); +void e_search_bar_add_menu (ESearchBar *search_bar, + ESearchBarItem *menu_item); + +void e_search_bar_set_option (ESearchBar *search_bar, + ESearchBarItem *option_items); +void e_search_bar_paint (ESearchBar *search_bar); +void e_search_bar_set_viewoption (ESearchBar *search_bar, + int option_id, + ESearchBarItem *subitems); + +void e_search_bar_set_menu_sensitive (ESearchBar *search_bar, + int id, + gboolean state); + +void e_search_bar_set_item_id (ESearchBar *search_bar, + int id); +void e_search_bar_set_item_menu (ESearchBar *search_bar, + int id); +int e_search_bar_get_item_id (ESearchBar *search_bar); G_END_DECLS diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index 56990d71a1..d980991b03 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -888,9 +888,10 @@ e_spinner_dispose (GObject *object) { ESpinner *spinner = E_SPINNER (object); - g_signal_handlers_disconnect_by_func - (spinner->details->icon_theme, - G_CALLBACK (icon_theme_changed_cb), spinner); + if (spinner->details->icon_theme) + g_signal_handlers_disconnect_by_func + (spinner->details->icon_theme, + G_CALLBACK (icon_theme_changed_cb), spinner); G_OBJECT_CLASS (parent_class)->dispose (object); } -- cgit v1.2.3 From e4afd3f9fb962ea1295a0657ec9f83a427829171 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 26 May 2009 23:21:02 -0400 Subject: Remove trailing whitespace, again. --- widgets/misc/e-account-combo-box.c | 2 +- widgets/misc/e-account-combo-box.h | 2 +- widgets/misc/e-activity-handler.c | 30 +++++++++++++++--------------- widgets/misc/e-activity-handler.h | 2 +- widgets/misc/e-attachment-button.c | 2 +- widgets/misc/e-attachment-button.h | 2 +- widgets/misc/e-attachment-dialog.c | 2 +- widgets/misc/e-attachment-dialog.h | 2 +- widgets/misc/e-attachment-handler-image.c | 2 +- widgets/misc/e-attachment-handler-image.h | 2 +- widgets/misc/e-attachment-handler.c | 2 +- widgets/misc/e-attachment-handler.h | 2 +- widgets/misc/e-attachment-icon-view.c | 2 +- widgets/misc/e-attachment-icon-view.h | 2 +- widgets/misc/e-attachment-paned.c | 2 +- widgets/misc/e-attachment-paned.h | 2 +- widgets/misc/e-attachment-store.c | 2 +- widgets/misc/e-attachment-store.h | 2 +- widgets/misc/e-attachment-tree-view.c | 2 +- widgets/misc/e-attachment-tree-view.h | 2 +- widgets/misc/e-attachment-view.c | 2 +- widgets/misc/e-attachment-view.h | 2 +- widgets/misc/e-attachment.c | 2 +- widgets/misc/e-attachment.h | 2 +- widgets/misc/e-calendar-item.c | 8 ++++---- widgets/misc/e-calendar-item.h | 2 +- widgets/misc/e-calendar.c | 2 +- widgets/misc/e-calendar.h | 2 +- widgets/misc/e-canvas-background.c | 2 +- widgets/misc/e-canvas-background.h | 2 +- widgets/misc/e-canvas-utils.c | 2 +- widgets/misc/e-canvas-utils.h | 2 +- widgets/misc/e-canvas-vbox.c | 2 +- widgets/misc/e-canvas-vbox.h | 2 +- widgets/misc/e-canvas.c | 2 +- widgets/misc/e-canvas.h | 2 +- widgets/misc/e-cell-date-edit.c | 2 +- widgets/misc/e-cell-date-edit.h | 2 +- widgets/misc/e-cell-percent.c | 2 +- widgets/misc/e-cell-percent.h | 2 +- widgets/misc/e-cell-renderer-combo.c | 2 +- widgets/misc/e-cell-renderer-combo.h | 2 +- widgets/misc/e-charset-picker.c | 4 ++-- widgets/misc/e-charset-picker.h | 2 +- widgets/misc/e-colors.c | 2 +- widgets/misc/e-colors.h | 2 +- widgets/misc/e-combo-button.c | 2 +- widgets/misc/e-combo-button.h | 2 +- widgets/misc/e-combo-cell-editable.c | 2 +- widgets/misc/e-combo-cell-editable.h | 2 +- widgets/misc/e-config-page.c | 2 +- widgets/misc/e-config-page.h | 2 +- widgets/misc/e-cursors.c | 2 +- widgets/misc/e-cursors.h | 2 +- widgets/misc/e-dateedit.c | 6 +++--- widgets/misc/e-dropdown-button.c | 2 +- widgets/misc/e-dropdown-button.h | 2 +- widgets/misc/e-filter-bar.c | 2 +- widgets/misc/e-filter-bar.h | 2 +- widgets/misc/e-gui-utils.c | 2 +- widgets/misc/e-gui-utils.h | 2 +- widgets/misc/e-image-chooser.c | 2 +- widgets/misc/e-image-chooser.h | 2 +- widgets/misc/e-info-label.c | 2 +- widgets/misc/e-info-label.h | 2 +- widgets/misc/e-map.c | 2 +- widgets/misc/e-map.h | 2 +- widgets/misc/e-multi-config-dialog.c | 2 +- widgets/misc/e-multi-config-dialog.h | 2 +- widgets/misc/e-online-button.c | 2 +- widgets/misc/e-online-button.h | 2 +- widgets/misc/e-pilot-settings.c | 2 +- widgets/misc/e-pilot-settings.h | 2 +- widgets/misc/e-popup-menu.c | 2 +- widgets/misc/e-popup-menu.h | 2 +- widgets/misc/e-printable.c | 2 +- widgets/misc/e-printable.h | 2 +- widgets/misc/e-reflow-model.c | 2 +- widgets/misc/e-reflow-model.h | 2 +- widgets/misc/e-reflow.c | 2 +- widgets/misc/e-reflow.h | 2 +- widgets/misc/e-search-bar.c | 4 ++-- widgets/misc/e-search-bar.h | 2 +- widgets/misc/e-selection-model-array.c | 2 +- widgets/misc/e-selection-model-array.h | 2 +- widgets/misc/e-selection-model-simple.c | 2 +- widgets/misc/e-selection-model-simple.h | 2 +- widgets/misc/e-selection-model.c | 2 +- widgets/misc/e-selection-model.h | 2 +- widgets/misc/e-send-options.c | 2 +- widgets/misc/e-send-options.h | 4 ++-- widgets/misc/e-signature-combo-box.c | 2 +- widgets/misc/e-signature-combo-box.h | 2 +- widgets/misc/e-task-bar.c | 8 ++++---- widgets/misc/e-task-bar.h | 4 ++-- widgets/misc/e-task-widget.c | 4 ++-- widgets/misc/e-task-widget.h | 2 +- widgets/misc/e-unicode.c | 2 +- widgets/misc/e-unicode.h | 2 +- widgets/misc/e-url-entry.c | 2 +- widgets/misc/e-url-entry.h | 2 +- widgets/misc/test-calendar.c | 2 +- widgets/misc/test-dateedit.c | 2 +- widgets/misc/test-dropdown-button.c | 2 +- widgets/misc/test-error.c | 2 +- widgets/misc/test-info-label.c | 2 +- widgets/misc/test-multi-config-dialog.c | 2 +- 107 files changed, 134 insertions(+), 134 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c index 21f30b697c..7663f0faee 100644 --- a/widgets/misc/e-account-combo-box.c +++ b/widgets/misc/e-account-combo-box.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-account-combo-box.h b/widgets/misc/e-account-combo-box.h index 87f7eb9704..b163278dcd 100644 --- a/widgets/misc/e-account-combo-box.h +++ b/widgets/misc/e-account-combo-box.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c index e464353665..dd0bd60e9b 100644 --- a/widgets/misc/e-activity-handler.c +++ b/widgets/misc/e-activity-handler.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -142,7 +142,7 @@ activity_info_new (const char *component_id, info->menu = NULL; info->error = NULL; info->cancel_func = NULL; - + return info; } @@ -209,7 +209,7 @@ setup_task_bar (EActivityHandler *activity_handler, g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(info->id)); g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(info->error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); + g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); } } } @@ -360,14 +360,14 @@ e_activity_handler_attach_task_bar (EActivityHandler *activity_handler, } struct _cancel_wdata { - EActivityHandler *handler; + EActivityHandler *handler; ActivityInfo *info; guint id; void (*cancel)(gpointer); gpointer data; }; -static void +static void cancel_wrapper (gpointer pdata) { struct _cancel_wdata *data = (struct _cancel_wdata *) pdata; @@ -379,7 +379,7 @@ cancel_wrapper (gpointer pdata) int order, len; GSList *sp; GList *p = lookup_activity (handler->priv->activity_infos, data->id, &order); - e_logger_log (handler->priv->logger, E_LOG_ERROR, g_object_get_data (data->info->error, "primary"), + e_logger_log (handler->priv->logger, E_LOG_ERROR, g_object_get_data (data->info->error, "primary"), g_object_get_data (data->info->error, "secondary")); gtk_widget_destroy (data->info->error); data->info->error = NULL; @@ -388,7 +388,7 @@ cancel_wrapper (gpointer pdata) ETaskBar *task_bar; task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, info->id); + e_task_bar_remove_task_from_id (task_bar, info->id); } activity_info_free (info); len = g_list_length (handler->priv->activity_infos); @@ -488,8 +488,8 @@ handle_error (ETaskWidget *task) id = GPOINTER_TO_UINT (g_object_get_data ((GObject *) task, "activity")); e_activity_handler_operation_finished (activity_handler, id); gtk_widget_show (error); - e_logger_log (activity_handler->priv->logger, error_type, - g_object_get_data ((GObject *) error, "primary"), + e_logger_log (activity_handler->priv->logger, error_type, + g_object_get_data ((GObject *) error, "primary"), g_object_get_data ((GObject *) error, "secondary")); } @@ -511,7 +511,7 @@ error_cleanup (EActivityHandler *activity_handler) berror = TRUE; if (info->error && info->error_time && (now - info->error_time) > 5 ) { /* Error older than wanted time. So cleanup */ - e_logger_log (priv->logger, info->error_type, g_object_get_data (info->error, "primary"), + e_logger_log (priv->logger, info->error_type, g_object_get_data (info->error, "primary"), g_object_get_data (info->error, "secondary")); if (GTK_IS_DIALOG (info->error)) @@ -530,7 +530,7 @@ error_cleanup (EActivityHandler *activity_handler) } activity_info_free (info); priv->activity_infos = g_list_remove_link (priv->activity_infos, node); - + } else p = p->next; } @@ -559,7 +559,7 @@ e_activity_handler_make_error (EActivityHandler *activity_handler, activity_info->error = error; activity_info->error_time = time (NULL); activity_info->error_type = error_type; - + img = error_type ? icon_data[1] : icon_data[0]; for (p = priv->task_bars; p != NULL; p = p->next) { ETaskBar *task_bar; @@ -567,17 +567,17 @@ e_activity_handler_make_error (EActivityHandler *activity_handler, GtkWidget *tool; task_bar = E_TASK_BAR (p->data); - task_widget = task_widget_new_from_activity_info (activity_info); + task_widget = task_widget_new_from_activity_info (activity_info); task_widget->id = activity_id; e_task_bar_prepend_task (E_TASK_BAR (p->data), task_widget); - + tool = e_task_widget_update_image (task_widget, (char *)img, information); g_object_set_data ((GObject *) task_widget, "tool", tool); g_object_set_data ((GObject *) task_widget, "error", error); g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id)); g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); + g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); } priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); diff --git a/widgets/misc/e-activity-handler.h b/widgets/misc/e-activity-handler.h index 5dc1820dd0..bf8d8e0095 100644 --- a/widgets/misc/e-activity-handler.h +++ b/widgets/misc/e-activity-handler.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c index a9c230bac7..d64dcafb4a 100644 --- a/widgets/misc/e-attachment-button.c +++ b/widgets/misc/e-attachment-button.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-button.h b/widgets/misc/e-attachment-button.h index 72592efefe..89ecccfe9b 100644 --- a/widgets/misc/e-attachment-button.h +++ b/widgets/misc/e-attachment-button.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index e8c599aeea..e1037ae175 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-dialog.h b/widgets/misc/e-attachment-dialog.h index e8ed583b18..503dcbbc67 100644 --- a/widgets/misc/e-attachment-dialog.h +++ b/widgets/misc/e-attachment-dialog.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-handler-image.c b/widgets/misc/e-attachment-handler-image.c index ba5f8d759c..a91b433c6e 100644 --- a/widgets/misc/e-attachment-handler-image.c +++ b/widgets/misc/e-attachment-handler-image.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-handler-image.h b/widgets/misc/e-attachment-handler-image.h index 44ff404a99..bade5cec5e 100644 --- a/widgets/misc/e-attachment-handler-image.h +++ b/widgets/misc/e-attachment-handler-image.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c index 03af1eec9b..0a6ed0505d 100644 --- a/widgets/misc/e-attachment-handler.c +++ b/widgets/misc/e-attachment-handler.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-handler.h b/widgets/misc/e-attachment-handler.h index f95bc55123..e7e52c8c18 100644 --- a/widgets/misc/e-attachment-handler.h +++ b/widgets/misc/e-attachment-handler.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c index 0845f82a76..a7d8ad271c 100644 --- a/widgets/misc/e-attachment-icon-view.c +++ b/widgets/misc/e-attachment-icon-view.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-icon-view.h b/widgets/misc/e-attachment-icon-view.h index ab9360e42e..4aabf6c429 100644 --- a/widgets/misc/e-attachment-icon-view.h +++ b/widgets/misc/e-attachment-icon-view.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c index 3fed031473..a88f9fa8b2 100644 --- a/widgets/misc/e-attachment-paned.c +++ b/widgets/misc/e-attachment-paned.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h index 076ab6033e..401ec581cb 100644 --- a/widgets/misc/e-attachment-paned.h +++ b/widgets/misc/e-attachment-paned.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 216a60d32a..2977be9593 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index 9fdd74d493..46ca9e4aa6 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c index f2c17cb078..42876e4bfb 100644 --- a/widgets/misc/e-attachment-tree-view.c +++ b/widgets/misc/e-attachment-tree-view.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-tree-view.h b/widgets/misc/e-attachment-tree-view.h index 7f16ba5ab2..4300ffa71f 100644 --- a/widgets/misc/e-attachment-tree-view.h +++ b/widgets/misc/e-attachment-tree-view.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index d2b676993d..41e0b302a2 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h index 38480c30c4..89d2d28664 100644 --- a/widgets/misc/e-attachment-view.h +++ b/widgets/misc/e-attachment-view.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index e4e336e58b..e9df6024bc 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 934e1e04b6..d7cfb5be06 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 32e74dd535..be3751f852 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * Authors: * Damon Chaplin @@ -1386,9 +1386,9 @@ get_digit_fomat () if (major > 2 || minor > 2 || (minor == 2 && revision > 2)) { return "%Id"; - } + } #endif - + return "%d"; } @@ -1984,7 +1984,7 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) for (digit = 0; digit < 10; digit++) { gchar locale_digit[5]; int locale_digit_len; - + locale_digit_len = sprintf (locale_digit, get_digit_fomat (), digit); pango_layout_set_text (layout, locale_digit, locale_digit_len); diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h index 0032e12a6c..c0ee9a43bc 100644 --- a/widgets/misc/e-calendar-item.h +++ b/widgets/misc/e-calendar-item.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index 824a79d4e0..88e59b87db 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h index aebc615cfc..7a3c8fd010 100644 --- a/widgets/misc/e-calendar.h +++ b/widgets/misc/e-calendar.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c index 4d300f01d4..181d7887d4 100644 --- a/widgets/misc/e-canvas-background.c +++ b/widgets/misc/e-canvas-background.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-background.h b/widgets/misc/e-canvas-background.h index 5d75735c12..562987e7d7 100644 --- a/widgets/misc/e-canvas-background.h +++ b/widgets/misc/e-canvas-background.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c index c46f64c199..62ea6c54ef 100644 --- a/widgets/misc/e-canvas-utils.c +++ b/widgets/misc/e-canvas-utils.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-utils.h b/widgets/misc/e-canvas-utils.h index fa09a86c25..cda34e99b5 100644 --- a/widgets/misc/e-canvas-utils.h +++ b/widgets/misc/e-canvas-utils.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index 377a7a2605..3d4e879c0c 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h index 51602e77de..7fa38fa778 100644 --- a/widgets/misc/e-canvas-vbox.h +++ b/widgets/misc/e-canvas-vbox.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 40aaf7d510..055f0311f4 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index e06bed7824..00692c457a 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c index 76450b8f5f..e994120b33 100644 --- a/widgets/misc/e-cell-date-edit.c +++ b/widgets/misc/e-cell-date-edit.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/misc/e-cell-date-edit.h index 30dee535e8..2e125fece3 100644 --- a/widgets/misc/e-cell-date-edit.h +++ b/widgets/misc/e-cell-date-edit.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-percent.c b/widgets/misc/e-cell-percent.c index 94e33489e5..194a7bd6b6 100644 --- a/widgets/misc/e-cell-percent.c +++ b/widgets/misc/e-cell-percent.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-percent.h b/widgets/misc/e-cell-percent.h index 46a7ddc3e3..5e202dfa82 100644 --- a/widgets/misc/e-cell-percent.h +++ b/widgets/misc/e-cell-percent.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-renderer-combo.c b/widgets/misc/e-cell-renderer-combo.c index 96f474d0d9..ab03c73f2b 100644 --- a/widgets/misc/e-cell-renderer-combo.c +++ b/widgets/misc/e-cell-renderer-combo.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cell-renderer-combo.h b/widgets/misc/e-cell-renderer-combo.h index 547eca7e7a..515ed75256 100644 --- a/widgets/misc/e-cell-renderer-combo.h +++ b/widgets/misc/e-cell-renderer-combo.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 6c7233ab9f..5d1f8c036a 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -444,7 +444,7 @@ e_charset_picker_dialog (const char *title, const char *prompt, * locale character set * @callback: a callback function for actions in the group, or %NULL * @user_data: user data to be passed to @callback, or %NULL - * + * * Adds a set of #GtkRadioActions for available character sets to * @action_group. The @default_charset (or locale character set if * @default_charset is %NULL) will be added first, and selected by diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index 7250b10dfb..88c89fb308 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-colors.c b/widgets/misc/e-colors.c index c9c72d06d7..74fbdbf58c 100644 --- a/widgets/misc/e-colors.c +++ b/widgets/misc/e-colors.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-colors.h b/widgets/misc/e-colors.h index 30ddfd496a..710ee59f59 100644 --- a/widgets/misc/e-colors.h +++ b/widgets/misc/e-colors.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-combo-button.c b/widgets/misc/e-combo-button.c index aabb7073f1..dc978af91a 100644 --- a/widgets/misc/e-combo-button.c +++ b/widgets/misc/e-combo-button.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-combo-button.h b/widgets/misc/e-combo-button.h index 0abe347a93..edeb1be9bd 100644 --- a/widgets/misc/e-combo-button.h +++ b/widgets/misc/e-combo-button.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-combo-cell-editable.c b/widgets/misc/e-combo-cell-editable.c index 5502a83a0d..8cee128619 100644 --- a/widgets/misc/e-combo-cell-editable.c +++ b/widgets/misc/e-combo-cell-editable.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-combo-cell-editable.h b/widgets/misc/e-combo-cell-editable.h index d3f64a36d3..c37e786f84 100644 --- a/widgets/misc/e-combo-cell-editable.h +++ b/widgets/misc/e-combo-cell-editable.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-config-page.c b/widgets/misc/e-config-page.c index c9823a29e8..00fb991578 100644 --- a/widgets/misc/e-config-page.c +++ b/widgets/misc/e-config-page.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-config-page.h b/widgets/misc/e-config-page.h index 24317d3f9d..886d89d851 100644 --- a/widgets/misc/e-config-page.h +++ b/widgets/misc/e-config-page.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index f0b9ca6843..ebc2f9bd78 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-cursors.h b/widgets/misc/e-cursors.h index c22e295c7b..7df3404092 100644 --- a/widgets/misc/e-cursors.h +++ b/widgets/misc/e-cursors.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 2120483abf..701cf69444 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -10,7 +10,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with the program; if not, see + * License along with the program; if not, see * * Authors: * Damon Chaplin @@ -1471,7 +1471,7 @@ e_date_edit_parse_date (EDateEdit *dedit, if (date_tm->tm_year > today_tm->tm_year) date_tm->tm_year -= 100; } - + return TRUE; } @@ -1725,7 +1725,7 @@ e_date_edit_update_date_entry (EDateEdit *dedit) if (priv->date_set_to_none || !priv->date_is_valid) { gtk_entry_set_text (GTK_ENTRY (priv->date_entry), _("None")); } else { - /* This is a strftime() format for a short date. + /* This is a strftime() format for a short date. %x the preferred date representation for the current locale without the time, but has forced to use 4 digit year */ char *format = e_time_get_d_fmt_with_4digit_year (); diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c index 6008f64ad9..00b2695e5f 100644 --- a/widgets/misc/e-dropdown-button.c +++ b/widgets/misc/e-dropdown-button.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-dropdown-button.h b/widgets/misc/e-dropdown-button.h index b10fd9a670..bd4fe6feb4 100644 --- a/widgets/misc/e-dropdown-button.h +++ b/widgets/misc/e-dropdown-button.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 2dffb39cac..9a67636939 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index 4178070405..8f06c867ae 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c index 4e0b099944..6acbe920ef 100644 --- a/widgets/misc/e-gui-utils.c +++ b/widgets/misc/e-gui-utils.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-gui-utils.h b/widgets/misc/e-gui-utils.h index d0a54f7c42..840a55289b 100644 --- a/widgets/misc/e-gui-utils.h +++ b/widgets/misc/e-gui-utils.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index 7d504685a5..d3b5a1ac07 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h index 0e78026683..b7f599f0c1 100644 --- a/widgets/misc/e-image-chooser.h +++ b/widgets/misc/e-image-chooser.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-info-label.c b/widgets/misc/e-info-label.c index e1959607fb..e6db111a74 100644 --- a/widgets/misc/e-info-label.c +++ b/widgets/misc/e-info-label.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-info-label.h b/widgets/misc/e-info-label.h index 905a39b0ca..d4dd16e395 100644 --- a/widgets/misc/e-info-label.h +++ b/widgets/misc/e-info-label.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index f9742b597f..c2c0806178 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-map.h b/widgets/misc/e-map.h index 4d65c7b47b..0c915fb5fa 100644 --- a/widgets/misc/e-map.h +++ b/widgets/misc/e-map.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-multi-config-dialog.c b/widgets/misc/e-multi-config-dialog.c index 6cee26e75c..f78f764f03 100644 --- a/widgets/misc/e-multi-config-dialog.c +++ b/widgets/misc/e-multi-config-dialog.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-multi-config-dialog.h b/widgets/misc/e-multi-config-dialog.h index 462d593c81..e8d9896d55 100644 --- a/widgets/misc/e-multi-config-dialog.h +++ b/widgets/misc/e-multi-config-dialog.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c index dec24a6587..114d76ac32 100644 --- a/widgets/misc/e-online-button.c +++ b/widgets/misc/e-online-button.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ diff --git a/widgets/misc/e-online-button.h b/widgets/misc/e-online-button.h index 6576035a9d..03f676d75c 100644 --- a/widgets/misc/e-online-button.h +++ b/widgets/misc/e-online-button.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ diff --git a/widgets/misc/e-pilot-settings.c b/widgets/misc/e-pilot-settings.c index 80ad52d083..1bed8630c5 100644 --- a/widgets/misc/e-pilot-settings.c +++ b/widgets/misc/e-pilot-settings.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-pilot-settings.h b/widgets/misc/e-pilot-settings.h index fbba3b2f71..0c4fbd7a81 100644 --- a/widgets/misc/e-pilot-settings.h +++ b/widgets/misc/e-pilot-settings.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-popup-menu.c b/widgets/misc/e-popup-menu.c index 1581d3e409..143eaff327 100644 --- a/widgets/misc/e-popup-menu.c +++ b/widgets/misc/e-popup-menu.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-popup-menu.h b/widgets/misc/e-popup-menu.h index 37589f4243..ddf6ed04a9 100644 --- a/widgets/misc/e-popup-menu.h +++ b/widgets/misc/e-popup-menu.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-printable.c b/widgets/misc/e-printable.c index 7f2db7ecc4..05a219f901 100644 --- a/widgets/misc/e-printable.c +++ b/widgets/misc/e-printable.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-printable.h b/widgets/misc/e-printable.h index d0d3223dbf..32cbadddbd 100644 --- a/widgets/misc/e-printable.h +++ b/widgets/misc/e-printable.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-reflow-model.c b/widgets/misc/e-reflow-model.c index eae3d43324..d24b915e6e 100644 --- a/widgets/misc/e-reflow-model.c +++ b/widgets/misc/e-reflow-model.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-reflow-model.h b/widgets/misc/e-reflow-model.h index 7482e5079f..c772621d07 100644 --- a/widgets/misc/e-reflow-model.h +++ b/widgets/misc/e-reflow-model.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index f51a502a83..129046a89e 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-reflow.h b/widgets/misc/e-reflow.h index 6d67369209..69f34d0fd9 100644 --- a/widgets/misc/e-reflow.h +++ b/widgets/misc/e-reflow.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index d3d579178d..2bbbc91a00 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -1048,7 +1048,7 @@ e_search_bar_construct (ESearchBar *search_bar, label = gtk_label_new_with_mnemonic (_(" i_n ")); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0); - + search_bar->scopeoption = gtk_option_menu_new (); /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0); diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index f2d9b0576b..fd91068ebd 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index f45923c1dd..7e82039d6e 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index abbf828374..9f297c1fed 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model-simple.c b/widgets/misc/e-selection-model-simple.c index f2856622ec..b9f1d33bfe 100644 --- a/widgets/misc/e-selection-model-simple.c +++ b/widgets/misc/e-selection-model-simple.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model-simple.h b/widgets/misc/e-selection-model-simple.h index 2cd2ecabd3..7f11d3ac0e 100644 --- a/widgets/misc/e-selection-model-simple.h +++ b/widgets/misc/e-selection-model-simple.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index 697bb68096..66187e6e7c 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index 18bbc2a115..24eccd304f 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index 6c10a60c1c..8740f2d02e 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-send-options.h b/widgets/misc/e-send-options.h index 9a32357358..3ed5d6fd24 100644 --- a/widgets/misc/e-send-options.h +++ b/widgets/misc/e-send-options.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -20,7 +20,7 @@ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ - + #ifndef __E_SENDOPTIONS_DIALOG_H__ #define __E_SENDOPTIONS_DIALOG_H__ diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c index 9ebd20a0b2..cb11ba632f 100644 --- a/widgets/misc/e-signature-combo-box.c +++ b/widgets/misc/e-signature-combo-box.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-signature-combo-box.h b/widgets/misc/e-signature-combo-box.h index ec05c2b5d7..fac47518e1 100644 --- a/widgets/misc/e-signature-combo-box.h +++ b/widgets/misc/e-signature-combo-box.h @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) diff --git a/widgets/misc/e-task-bar.c b/widgets/misc/e-task-bar.c index 8400f298f7..c7a715decd 100644 --- a/widgets/misc/e-task-bar.c +++ b/widgets/misc/e-task-bar.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -37,7 +37,7 @@ struct _ETaskBarPrivate G_DEFINE_TYPE (ETaskBar, e_task_bar, GTK_TYPE_HBOX) -#if 0 +#if 0 static void reduce_displayed_activities_per_component (ETaskBar *task_bar) { @@ -80,7 +80,7 @@ reduce_displayed_activities_per_component (ETaskBar *task_bar) g_hash_table_destroy (component_ids_hash); } -#endif +#endif static void impl_finalize (GObject *object); @@ -281,7 +281,7 @@ e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, w = NULL; list = list->next; } - + return w; } diff --git a/widgets/misc/e-task-bar.h b/widgets/misc/e-task-bar.h index 363e062ee8..d36898ebb8 100644 --- a/widgets/misc/e-task-bar.h +++ b/widgets/misc/e-task-bar.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -66,7 +66,7 @@ void e_task_bar_prepend_task (ETaskBar *task_bar, ETaskWidget *task_widget); void e_task_bar_remove_task (ETaskBar *task_bar, int n); -ETaskWidget * e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, +ETaskWidget * e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, guint id); void e_task_bar_remove_task_from_id (ETaskBar *task_bar, diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c index d545613998..2569a46557 100644 --- a/widgets/misc/e-task-widget.c +++ b/widgets/misc/e-task-widget.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: @@ -106,7 +106,7 @@ prepare_popup (ETaskWidget *widget, GdkEventButton *event) if (event->button != 3) return FALSE; - + /* FIXME: Implement Cancel */ return TRUE; diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h index e478e91145..4770b9d108 100644 --- a/widgets/misc/e-task-widget.h +++ b/widgets/misc/e-task-widget.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-unicode.c b/widgets/misc/e-unicode.c index cc50b39d95..2769001120 100644 --- a/widgets/misc/e-unicode.c +++ b/widgets/misc/e-unicode.c @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-unicode.h b/widgets/misc/e-unicode.h index b0319b0f25..77d1a351cb 100644 --- a/widgets/misc/e-unicode.h +++ b/widgets/misc/e-unicode.h @@ -12,7 +12,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index 32490f6590..6c8eab7c8b 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/e-url-entry.h b/widgets/misc/e-url-entry.h index 1c051ac0e8..a4edc51df2 100644 --- a/widgets/misc/e-url-entry.h +++ b/widgets/misc/e-url-entry.h @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c index 10a463de12..6852010b24 100644 --- a/widgets/misc/test-calendar.c +++ b/widgets/misc/test-calendar.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c index d359d120c4..7468053f31 100644 --- a/widgets/misc/test-dateedit.c +++ b/widgets/misc/test-dateedit.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c index 51143ff560..b76174fb0e 100644 --- a/widgets/misc/test-dropdown-button.c +++ b/widgets/misc/test-dropdown-button.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-error.c b/widgets/misc/test-error.c index c8b442b23a..e67e6985f5 100644 --- a/widgets/misc/test-error.c +++ b/widgets/misc/test-error.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-info-label.c b/widgets/misc/test-info-label.c index 2ef47483ed..31298ed7c1 100644 --- a/widgets/misc/test-info-label.c +++ b/widgets/misc/test-info-label.c @@ -11,7 +11,7 @@ * 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 + * License along with the program; if not, see * * * Authors: diff --git a/widgets/misc/test-multi-config-dialog.c b/widgets/misc/test-multi-config-dialog.c index bc52f493c6..34a7624a39 100644 --- a/widgets/misc/test-multi-config-dialog.c +++ b/widgets/misc/test-multi-config-dialog.c @@ -10,7 +10,7 @@ * 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 + * License along with the program; if not, see * * * Authors: -- cgit v1.2.3 From 948235c3d1076dbe6ed2e57a24c16a083bbd9f01 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 27 May 2009 10:29:19 -0400 Subject: Prefer GLib basic types over C types. --- widgets/misc/a11y/ea-calendar-cell.c | 10 ++-- widgets/misc/a11y/ea-calendar-item.c | 16 +++--- widgets/misc/e-calendar-item.c | 22 ++++---- widgets/misc/e-calendar-item.h | 2 +- widgets/misc/e-canvas-background.c | 10 ++-- widgets/misc/e-canvas-utils.c | 10 ++-- widgets/misc/e-canvas-vbox.c | 4 +- widgets/misc/e-canvas.c | 28 +++++----- widgets/misc/e-canvas.h | 10 ++-- widgets/misc/e-charset-picker.c | 30 +++++------ widgets/misc/e-charset-picker.h | 10 ++-- widgets/misc/e-colors.c | 2 +- widgets/misc/e-colors.h | 2 +- widgets/misc/e-combo-cell-editable.c | 2 +- widgets/misc/e-cursors.c | 16 +++--- widgets/misc/e-dateedit.c | 22 ++++---- widgets/misc/e-filter-bar.c | 90 ++++++++++++++++----------------- widgets/misc/e-filter-bar.h | 32 ++++++------ widgets/misc/e-gui-utils.c | 8 +-- widgets/misc/e-gui-utils.h | 8 +-- widgets/misc/e-icon-entry.c | 2 +- widgets/misc/e-image-chooser.c | 40 +++++++-------- widgets/misc/e-image-chooser.h | 6 +-- widgets/misc/e-map.c | 56 ++++++++++---------- widgets/misc/e-popup-menu.c | 18 +++---- widgets/misc/e-popup-menu.h | 8 +-- widgets/misc/e-search-bar.c | 12 ++--- widgets/misc/e-search-bar.h | 18 +++---- widgets/misc/e-selection-model-array.c | 44 ++++++++-------- widgets/misc/e-selection-model-array.h | 12 ++--- widgets/misc/e-selection-model-simple.c | 14 ++--- widgets/misc/e-selection-model-simple.h | 16 +++--- widgets/misc/e-selection-model.c | 58 ++++++++++----------- widgets/misc/e-selection-model.h | 60 +++++++++++----------- widgets/misc/e-send-options.c | 4 +- widgets/misc/e-spinner.c | 22 ++++---- widgets/misc/e-url-entry.c | 2 +- widgets/misc/test-calendar.c | 4 +- widgets/misc/test-dateedit.c | 4 +- widgets/misc/test-preferences-window.c | 12 ++--- 40 files changed, 373 insertions(+), 373 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/a11y/ea-calendar-cell.c b/widgets/misc/a11y/ea-calendar-cell.c index 2d2a92de62..af9471c5af 100644 --- a/widgets/misc/a11y/ea-calendar-cell.c +++ b/widgets/misc/a11y/ea-calendar-cell.c @@ -80,7 +80,7 @@ e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column) cell->column = column; #ifdef ACC_DEBUG - g_print ("EvoAcc: e_calendar_cell created %p\n", (void *)cell); + g_print ("EvoAcc: e_calendar_cell created %p\n", (gpointer)cell); #endif return cell; @@ -91,8 +91,8 @@ e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column) static void ea_calendar_cell_class_init (EaCalendarCellClass *klass); static void ea_calendar_cell_init (EaCalendarCell *a11y); -static G_CONST_RETURN gchar* ea_calendar_cell_get_name (AtkObject *accessible); -static G_CONST_RETURN gchar* ea_calendar_cell_get_description (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_cell_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_cell_get_description (AtkObject *accessible); static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible); static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible); static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible); @@ -209,7 +209,7 @@ static void ea_calendar_cell_finalize (GObject *object) } #endif -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * ea_calendar_cell_get_name (AtkObject *accessible) { GObject *g_obj; @@ -243,7 +243,7 @@ ea_calendar_cell_get_name (AtkObject *accessible) return accessible->name; } -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * ea_calendar_cell_get_description (AtkObject *accessible) { return ea_calendar_cell_get_name (accessible); diff --git a/widgets/misc/a11y/ea-calendar-item.c b/widgets/misc/a11y/ea-calendar-item.c index 34db081692..e1fb365aff 100644 --- a/widgets/misc/a11y/ea-calendar-item.c +++ b/widgets/misc/a11y/ea-calendar-item.c @@ -38,8 +38,8 @@ static void ea_calendar_item_class_init (EaCalendarItemClass *klass); static void ea_calendar_item_finalize (GObject *object); -static G_CONST_RETURN gchar* ea_calendar_item_get_name (AtkObject *accessible); -static G_CONST_RETURN gchar* ea_calendar_item_get_description (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_item_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_item_get_description (AtkObject *accessible); static gint ea_calendar_item_get_n_children (AtkObject *accessible); static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index); static AtkStateSet* ea_calendar_item_ref_state_set (AtkObject *accessible); @@ -88,10 +88,10 @@ static AtkObject* table_interface_get_column_header (AtkTable *table, gint in_col); static AtkObject* table_interface_get_caption (AtkTable *table); -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * table_interface_get_column_description (AtkTable *table, gint in_col); -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * table_interface_get_row_description (AtkTable *table, gint row); static AtkObject* table_interface_get_summary (AtkTable *table); @@ -263,7 +263,7 @@ ea_calendar_item_finalize (GObject *object) #endif } -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * ea_calendar_item_get_name (AtkObject *accessible) { GObject *g_obj; @@ -329,7 +329,7 @@ ea_calendar_item_get_name (AtkObject *accessible) return accessible->name; } -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * ea_calendar_item_get_description (AtkObject *accessible) { if (accessible->description) @@ -782,7 +782,7 @@ table_interface_get_caption (AtkTable *table) return NULL; } -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * table_interface_get_column_description (AtkTable *table, gint in_col) { AtkGObjectAccessible *atk_gobj; @@ -816,7 +816,7 @@ table_interface_get_column_description (AtkTable *table, gint in_col) return description; } -static G_CONST_RETURN gchar* +static G_CONST_RETURN gchar * table_interface_get_row_description (AtkTable *table, gint row) { AtkGObjectAccessible *atk_gobj; diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index bd6ff35cf7..c1d599e879 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -36,7 +36,7 @@ #include #include -static const int e_calendar_item_days_in_month[12] = { +static const gint e_calendar_item_days_in_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -1139,7 +1139,7 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item, static void -layout_set_day_text (ECalendarItem *calitem, PangoLayout *layout, int day_index) +layout_set_day_text (ECalendarItem *calitem, PangoLayout *layout, gint day_index) { const gchar *abbr_name; @@ -1364,18 +1364,18 @@ e_calendar_item_draw_month (ECalendarItem *calitem, cairo_destroy (cr); } -static const char * +static const gchar * get_digit_fomat () { #ifdef HAVE_GNU_GET_LIBC_VERSION #include - const char *libc_version = gnu_get_libc_version (); - char **split = g_strsplit (libc_version, ".", -1); - int major = 0; - int minor = 0; - int revision = 0; + const gchar *libc_version = gnu_get_libc_version (); + gchar **split = g_strsplit (libc_version, ".", -1); + gint major = 0; + gint minor = 0; + gint revision = 0; major = atoi (split [0]); minor = atoi (split [1]); @@ -1716,7 +1716,7 @@ e_calendar_item_get_week_number (ECalendarItem *calitem, { GDate date; guint weekday, yearday; - int offset, week_num; + gint offset, week_num; /* FIXME: check what happens at year boundaries. */ @@ -1757,7 +1757,7 @@ e_calendar_item_get_week_number (ECalendarItem *calitem, This is needed so that we get button/motion events. */ static double e_calendar_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, + gint cx, gint cy, GnomeCanvasItem **actual_item) { *actual_item = item; @@ -1983,7 +1983,7 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) max_week_number_digit_width = 0; for (digit = 0; digit < 10; digit++) { gchar locale_digit[5]; - int locale_digit_len; + gint locale_digit_len; locale_digit_len = sprintf (locale_digit, get_digit_fomat (), digit); diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h index c0ee9a43bc..926ba1c077 100644 --- a/widgets/misc/e-calendar-item.h +++ b/widgets/misc/e-calendar-item.h @@ -126,7 +126,7 @@ struct _ECalendarItem gint year; gint month; /* 0 to 11 */ - /* Points to an array of styles, one char for each day. We use 32 + /* Points to an array of styles, one gchar for each day. We use 32 chars for each month, with n + 2 months, where n is the number of complete months shown (since we show some days before the first month and after the last month grayes out). diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c index 181d7887d4..41b03d7f65 100644 --- a/widgets/misc/e-canvas-background.c +++ b/widgets/misc/e-canvas-background.c @@ -127,7 +127,7 @@ ecb_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y * GnomeCanvasItem::update method */ static void -ecb_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) +ecb_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags) { ArtPoint o1, o2; ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item); @@ -158,7 +158,7 @@ ecb_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) /* Sets the stipple pattern for the text */ static void -set_stipple (ECanvasBackground *ecb, GdkBitmap *stipple, int use_value) +set_stipple (ECanvasBackground *ecb, GdkBitmap *stipple, gint use_value) { if (use_value) { if (ecb->priv->stipple) @@ -365,10 +365,10 @@ ecb_unrealize (GnomeCanvasItem *item) } static void -ecb_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) +ecb_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x, gint y, gint width, gint height) { ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item); - int x1, x2, y1, y2; + gint x1, x2, y1, y2; double i2c [6]; ArtPoint upper_left, lower_right, ecb_base_point; @@ -402,7 +402,7 @@ ecb_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, } static double -ecb_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, +ecb_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy, GnomeCanvasItem **actual_item) { ECanvasBackground *ecb = E_CANVAS_BACKGROUND (item); diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c index 62ea6c54ef..cae41d859f 100644 --- a/widgets/misc/e-canvas-utils.c +++ b/widgets/misc/e-canvas-utils.c @@ -37,10 +37,10 @@ e_canvas_item_move_absolute (GnomeCanvasItem *item, double dx, double dy) } static double -compute_offset(int top, int bottom, int page_top, int page_bottom) +compute_offset(gint top, gint bottom, gint page_top, gint page_bottom) { - int size = bottom - top; - int offset = 0; + gint size = bottom - top; + gint offset = 0; if (top <= page_top && bottom >= page_bottom) return 0; @@ -68,7 +68,7 @@ static void e_canvas_show_area (GnomeCanvas *canvas, double x1, double y1, double x2, double y2) { GtkAdjustment *h, *v; - int dx = 0, dy = 0; + gint dx = 0, dy = 0; g_return_if_fail (canvas != NULL); g_return_if_fail (GNOME_IS_CANVAS (canvas)); @@ -101,7 +101,7 @@ static gboolean e_canvas_area_shown (GnomeCanvas *canvas, double x1, double y1, double x2, double y2) { GtkAdjustment *h, *v; - int dx = 0, dy = 0; + gint dx = 0, dy = 0; g_return_val_if_fail (canvas != NULL, FALSE); g_return_val_if_fail (GNOME_IS_CANVAS (canvas), FALSE); diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index 3d4e879c0c..1eb0ddec12 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -41,7 +41,7 @@ static void e_canvas_vbox_dispose (GObject *object); static gint e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event); static void e_canvas_vbox_realize (GnomeCanvasItem *item); -static void e_canvas_vbox_reflow (GnomeCanvasItem *item, int flags); +static void e_canvas_vbox_reflow (GnomeCanvasItem *item, gint flags); static void e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); static void e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); @@ -295,7 +295,7 @@ e_canvas_vbox_resize_children (GnomeCanvasItem *item) } static void -e_canvas_vbox_reflow( GnomeCanvasItem *item, int flags ) +e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags ) { ECanvasVbox *e_canvas_vbox = E_CANVAS_VBOX(item); if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) { diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 055f0311f4..39b89d2675 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -48,7 +48,7 @@ static gint e_canvas_focus_out (GtkWidget *widget, static void e_canvas_style_set (GtkWidget *widget, GtkStyle *previous_style); -static int emit_event (GnomeCanvas *canvas, GdkEvent *event); +static gint emit_event (GnomeCanvas *canvas, GdkEvent *event); #define d(x) @@ -287,7 +287,7 @@ e_canvas_key (GtkWidget *widget, GdkEventKey *event) #define HACKISH_AFFINE static double -gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, +gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, gint cx, gint cy, GnomeCanvasItem **actual_item) { #ifdef HACKISH_AFFINE @@ -319,10 +319,10 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, int c static int pick_current_item (GnomeCanvas *canvas, GdkEvent *event) { - int button_down; + gint button_down; double x, y; - int cx, cy; - int retval; + gint cx, cy; + gint retval; retval = FALSE; @@ -460,8 +460,8 @@ static gint e_canvas_button (GtkWidget *widget, GdkEventButton *event) { GnomeCanvas *canvas; - int mask; - int retval; + gint mask; + gint retval; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNOME_IS_CANVAS (widget), FALSE); @@ -695,7 +695,7 @@ e_canvas_unrealize (GtkWidget *widget) } static void -e_canvas_item_invoke_reflow (GnomeCanvasItem *item, int flags) +e_canvas_item_invoke_reflow (GnomeCanvasItem *item, gint flags) { GnomeCanvasGroup *group; GList *list; @@ -814,7 +814,7 @@ void e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id) { GList *list; - int flags; + gint flags; ECanvas *canvas; ECanvasSelectionInfo *info; ECanvasItemSelectionFunc func; @@ -869,7 +869,7 @@ e_canvas_item_set_cursor_end (GnomeCanvasItem *item, gpointer id) void e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id) { - int flags; + gint flags; ECanvas *canvas; ECanvasSelectionInfo *info; ECanvasItemSelectionFunc func; @@ -932,7 +932,7 @@ e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id) void e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id) { - int flags; + gint flags; ECanvas *canvas; ECanvasSelectionInfo *info; GList *list; @@ -975,7 +975,7 @@ e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id) } } -void e_canvas_popup_tooltip (ECanvas *canvas, GtkWidget *widget, int x, int y) +void e_canvas_popup_tooltip (ECanvas *canvas, GtkWidget *widget, gint x, gint y) { if (canvas->tooltip_window && canvas->tooltip_window != widget) { e_canvas_hide_tooltip(canvas); @@ -1034,7 +1034,7 @@ grab_cancelled_check (gpointer data) return TRUE; } -int +gint e_canvas_item_grab (ECanvas *canvas, GnomeCanvasItem *item, guint event_mask, @@ -1046,7 +1046,7 @@ e_canvas_item_grab (ECanvas *canvas, if (gtk_grab_get_current ()) { return GDK_GRAB_ALREADY_GRABBED; } else { - int ret_val = gnome_canvas_item_grab (item, event_mask, cursor, etime); + gint ret_val = gnome_canvas_item_grab (item, event_mask, cursor, etime); if (ret_val == GDK_GRAB_SUCCESS) { canvas->grab_cancelled_cb = cancelled_cb; canvas->grab_cancelled_check_id = diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index 00692c457a..e23d29f057 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -79,12 +79,12 @@ typedef void (*ECanvasItemGrabCancelled) (ECanvas *canvas, GnomeCanvasItem *item struct _ECanvas { GnomeCanvas parent; - int idle_id; + gint idle_id; GList *selection; ECanvasSelectionInfo *cursor; GtkWidget *tooltip_window; - int visibility_notify_id; + gint visibility_notify_id; GtkWidget *toplevel; guint visibility_first : 1; @@ -128,7 +128,7 @@ void e_canvas_item_add_selection (GnomeCanvasItem void e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id); -int e_canvas_item_grab (ECanvas *canvas, +gint e_canvas_item_grab (ECanvas *canvas, GnomeCanvasItem *item, guint event_mask, GdkCursor *cursor, @@ -144,8 +144,8 @@ void e_canvas_item_set_cursor_end (GnomeCanvasItem gpointer id); void e_canvas_popup_tooltip (ECanvas *canvas, GtkWidget *widget, - int x, - int y); + gint x, + gint y); void e_canvas_hide_tooltip (ECanvas *canvas); #ifdef __cplusplus diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index d140fe9a5c..34e9c63545 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -49,7 +49,7 @@ typedef enum { E_CHARSET_WESTERN_EUROPEAN_NEW } ECharsetClass; -static const char *classnames[] = { +static const gchar *classnames[] = { N_("Unknown"), N_("Arabic"), N_("Baltic"), @@ -107,7 +107,7 @@ static ECharset charsets[] = { { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL }, { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN_NEW, NULL }, }; -static const int num_charsets = sizeof (charsets) / sizeof (charsets[0]); +static const gint num_charsets = sizeof (charsets) / sizeof (charsets[0]); static void select_item (GtkMenuShell *menu_shell, GtkWidget *item) @@ -126,7 +126,7 @@ static GtkWidget * add_charset (GtkWidget *menu, ECharset *charset, gboolean free_name) { GtkWidget *item; - char *label; + gchar *label; if (charset->subclass) { label = g_strdup_printf ("%s, %s (%s)", @@ -154,7 +154,7 @@ add_charset (GtkWidget *menu, ECharset *charset, gboolean free_name) } static gboolean -add_other_charset (GtkWidget *menu, GtkWidget *other, const char *new_charset) +add_other_charset (GtkWidget *menu, GtkWidget *other, const gchar *new_charset) { ECharset charset = { NULL, E_CHARSET_UNKNOWN, NULL }; GtkWidget *item; @@ -200,7 +200,7 @@ static void activate_other (GtkWidget *item, gpointer menu) { GtkWidget *window, *entry, *label, *vbox, *hbox; - char *old_charset, *new_charset; + gchar *old_charset, *new_charset; GtkDialog *dialog; window = gtk_widget_get_toplevel (menu); @@ -254,7 +254,7 @@ activate_other (GtkWidget *item, gpointer menu) g_object_ref (dialog); if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) { - new_charset = (char *)gtk_entry_get_text (GTK_ENTRY (entry)); + new_charset = (gchar *)gtk_entry_get_text (GTK_ENTRY (entry)); if (*new_charset) { if (add_other_charset (menu, item, new_charset)) { @@ -289,11 +289,11 @@ activate_other (GtkWidget *item, gpointer menu) * attached. */ GtkWidget * -e_charset_picker_new (const char *default_charset) +e_charset_picker_new (const gchar *default_charset) { GtkWidget *menu, *item; - int def, i; - const char *locale_charset; + gint def, i; + const gchar *locale_charset; g_get_charset (&locale_charset); if (!g_ascii_strcasecmp (locale_charset, "US-ASCII")) @@ -347,11 +347,11 @@ e_charset_picker_new (const char *default_charset) * Return value: the currently-selected character set in @picker, * which must be freed with g_free(). **/ -char * +gchar * e_charset_picker_get_charset (GtkWidget *menu) { GtkWidget *item; - char *charset; + gchar *charset; g_return_val_if_fail (GTK_IS_MENU (menu), NULL); @@ -375,13 +375,13 @@ e_charset_picker_get_charset (GtkWidget *menu) * Return value: the selected character set (which must be freed with * g_free()), or %NULL. **/ -char * -e_charset_picker_dialog (const char *title, const char *prompt, - const char *default_charset, GtkWindow *parent) +gchar * +e_charset_picker_dialog (const gchar *title, const gchar *prompt, + const gchar *default_charset, GtkWindow *parent) { GtkDialog *dialog; GtkWidget *label, *omenu, *picker, *vbox, *hbox; - char *charset = NULL; + gchar *charset = NULL; dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (title, parent, diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index 4f701679a5..e399cf788c 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -25,11 +25,11 @@ G_BEGIN_DECLS -GtkWidget * e_charset_picker_new (const char *default_charset); -char * e_charset_picker_get_charset (GtkWidget *picker); -char * e_charset_picker_dialog (const char *title, - const char *prompt, - const char *default_charset, +GtkWidget * e_charset_picker_new (const gchar *default_charset); +gchar * e_charset_picker_get_charset (GtkWidget *picker); +gchar * e_charset_picker_dialog (const gchar *title, + const gchar *prompt, + const gchar *default_charset, GtkWindow *parent); GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, diff --git a/widgets/misc/e-colors.c b/widgets/misc/e-colors.c index 74fbdbf58c..5e2fddabc8 100644 --- a/widgets/misc/e-colors.c +++ b/widgets/misc/e-colors.c @@ -48,7 +48,7 @@ e_color_alloc_gdk (GtkWidget *widget, GdkColor *c) } void -e_color_alloc_name (GtkWidget *widget, const char *name, GdkColor *c) +e_color_alloc_name (GtkWidget *widget, const gchar *name, GdkColor *c) { GdkColormap *map; diff --git a/widgets/misc/e-colors.h b/widgets/misc/e-colors.h index 710ee59f59..c867d6425c 100644 --- a/widgets/misc/e-colors.h +++ b/widgets/misc/e-colors.h @@ -31,7 +31,7 @@ void e_color_init (void); /* Return the pixel value for the given red, green and blue */ gulong e_color_alloc (gushort red, gushort green, gushort blue); -void e_color_alloc_name (GtkWidget *widget, const char *name, GdkColor *color); +void e_color_alloc_name (GtkWidget *widget, const gchar *name, GdkColor *color); void e_color_alloc_gdk (GtkWidget *widget, GdkColor *color); extern GdkColor e_white, e_dark_gray, e_black; diff --git a/widgets/misc/e-combo-cell-editable.c b/widgets/misc/e-combo-cell-editable.c index 8cee128619..3d3c777986 100644 --- a/widgets/misc/e-combo-cell-editable.c +++ b/widgets/misc/e-combo-cell-editable.c @@ -170,7 +170,7 @@ lookup_row (GList *list, const gchar *text) gint result = 0; for (l = list; l; l = l->next, result++) - if (!g_utf8_collate (text, (char *) l->data)) + if (!g_utf8_collate (text, (gchar *) l->data)) break; return result; diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index ebc2f9bd78..ddf5f1ac26 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -65,11 +65,11 @@ static CursorDef cursors [] = { static void create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gchar **xpm) { - int height, width, colors; - char pixmap_buffer [(32 * 32)/8]; - char mask_buffer [(32 * 32)/8]; - int x, y, pix, yofs; - int transparent_color, black_color; + gint height, width, colors; + gchar pixmap_buffer [(32 * 32)/8]; + gchar mask_buffer [(32 * 32)/8]; + gint x, y, pix, yofs; + gint transparent_color, black_color; sscanf (xpm [0], "%d %d %d %d", &height, &width, &colors, &pix); @@ -83,7 +83,7 @@ create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gch yofs = colors + 1; for (y = 0; y < 32; y++){ for (x = 0; x < 32;){ - char value = 0, maskv = 0; + gchar value = 0, maskv = 0; for (pix = 0; pix < 8; pix++, x++){ if (xpm [y + yofs][x] != transparent_color){ @@ -111,7 +111,7 @@ create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gch void e_cursors_init (void) { - int i; + gint i; e_color_init (); @@ -144,7 +144,7 @@ e_cursors_init (void) void e_cursors_shutdown (void) { - int i; + gint i; for (i = 0; cursors [i].hot_x; i++) gdk_cursor_unref (cursors [i].cursor); diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 701cf69444..e8034eb487 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -1403,7 +1403,7 @@ rebuild_time_popup (EDateEdit *dedit) { EDateEditPrivate *priv; GtkComboBox *combo; - char buffer[40]; + gchar buffer[40]; struct tm tmp_tm; gint hour, min; @@ -1497,11 +1497,11 @@ e_date_edit_parse_time (EDateEdit *dedit, /* Returns TRUE if the string is empty or is "None" in the current locale. It ignores whitespace. */ static gboolean -field_set_to_none (const char *text) +field_set_to_none (const gchar *text) { - const char *pos; - const char *none_string; - int n; + const gchar *pos; + const gchar *none_string; + gint n; pos = text; while (n = (int)((unsigned char)*pos), isspace (n)) @@ -1717,7 +1717,7 @@ static void e_date_edit_update_date_entry (EDateEdit *dedit) { EDateEditPrivate *priv; - char buffer[100]; + gchar buffer[100]; struct tm tmp_tm = { 0 }; priv = dedit->priv; @@ -1728,7 +1728,7 @@ e_date_edit_update_date_entry (EDateEdit *dedit) /* This is a strftime() format for a short date. %x the preferred date representation for the current locale without the time, but has forced to use 4 digit year */ - char *format = e_time_get_d_fmt_with_4digit_year (); + gchar *format = e_time_get_d_fmt_with_4digit_year (); tmp_tm.tm_year = priv->year; tmp_tm.tm_mon = priv->month; @@ -1750,7 +1750,7 @@ static void e_date_edit_update_time_entry (EDateEdit *dedit) { EDateEditPrivate *priv; - char buffer[40]; + gchar buffer[40]; struct tm tmp_tm = { 0 }; priv = dedit->priv; @@ -1761,7 +1761,7 @@ e_date_edit_update_time_entry (EDateEdit *dedit) } else { GtkTreeModel *model; GtkTreeIter iter; - char *b; + gchar *b; /* Set these to reasonable values just in case. */ tmp_tm.tm_year = 2000; @@ -1797,11 +1797,11 @@ e_date_edit_update_time_entry (EDateEdit *dedit) model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->time_combo)); if (gtk_tree_model_get_iter_first (model, &iter)) { do { - char *text = NULL; + gchar *text = NULL; gtk_tree_model_get (model, &iter, 0, &text, -1); if (text) { - char *t = text; + gchar *t = text; /* truncate left spaces */ while (*t == ' ') diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index a113d1f101..77c20d506b 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -55,7 +55,7 @@ rule_editor_destroyed (EFilterBar *filter_bar, GObject *deadbeef) } static void -rule_advanced_response (GtkWidget *dialog, int response, void *data) +rule_advanced_response (GtkWidget *dialog, gint response, gpointer data) { EFilterBar *filter_bar = data; /* the below generates a compiler warning about incompatible pointer types */ @@ -163,7 +163,7 @@ save_search_dialog (ESearchBar *search_bar) } static void -menubar_activated (ESearchBar *search_bar, int id, void *data) +menubar_activated (ESearchBar *search_bar, gint id, gpointer data) { EFilterBar *filter_bar = (EFilterBar *)search_bar; GtkWidget *dialog; @@ -208,11 +208,11 @@ menubar_activated (ESearchBar *search_bar, int id, void *data) } static void -option_changed (ESearchBar *search_bar, void *data) +option_changed (ESearchBar *search_bar, gpointer data) { EFilterBar *filter_bar = (EFilterBar *)search_bar; - int id = e_search_bar_get_item_id (search_bar); - char *query; + gint id = e_search_bar_get_item_id (search_bar); + gchar *query; d(printf("option changed, id = %d, setquery = %s %d\n", id, efb->setquery ? "true" : "false", esb->block_search)); @@ -256,16 +256,16 @@ dup_item_no_subitems (ESearchBarItem *dest, } static GArray * -build_items (ESearchBar *search_bar, ESearchBarItem *items, int type, int *start, GPtrArray *rules) +build_items (ESearchBar *search_bar, ESearchBarItem *items, gint type, gint *start, GPtrArray *rules) { FilterRule *rule = NULL; EFilterBar *filter_bar = (EFilterBar *)search_bar; - int id = 0, i; + gint id = 0, i; GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem)); ESearchBarItem item = { NULL, -1, 2 }; const gchar *source; GSList *gtksux = NULL; - int num; + gint num; for (i=0;ilen;i++) gtksux = g_slist_prepend(gtksux, rules->pdata[i]); @@ -357,7 +357,7 @@ build_items (ESearchBar *search_bar, ESearchBarItem *items, int type, int *start static void free_built_items (GArray *menu) { - int i; + gint i; for (i = 0; i < menu->len; i ++) { ESearchBarItem *item; @@ -383,7 +383,7 @@ generate_menu (ESearchBar *search_bar, ESearchBarItem *items) static void free_items (ESearchBarItem *items) { - int i; + gint i; for (i = 0; items[i].id != -1; i++) g_free (items[i].text); @@ -398,7 +398,7 @@ set_menu (ESearchBar *search_bar, ESearchBarItem *items) { EFilterBar *filter_bar = E_FILTER_BAR (search_bar); ESearchBarItem *default_items; - int i, num; + gint i, num; if (filter_bar->default_items) free_items (filter_bar->default_items); @@ -472,7 +472,7 @@ filter_bar_get_property (GObject *object, switch (property_id) { case PROP_QUERY: { - char *text = e_search_bar_get_text (E_SEARCH_BAR (filter_bar)); + gchar *text = e_search_bar_get_text (E_SEARCH_BAR (filter_bar)); /* empty search text means searching turned off */ if (filter_bar->current_query && text && *text) { @@ -490,15 +490,15 @@ filter_bar_get_property (GObject *object, case PROP_STATE: { /* FIXME: we should have ESearchBar save its own state to the xmlDocPtr */ xmlChar *xmlbuf; - char *text, buf[12]; - int searchscope, item_id, n, view_id; + gchar *text, buf[12]; + gint searchscope, item_id, n, view_id; xmlNodePtr root, node; xmlDocPtr doc; item_id = e_search_bar_get_item_id ((ESearchBar *) filter_bar); - doc = xmlNewDoc ((const unsigned char *)"1.0"); - root = xmlNewDocNode (doc, NULL, (const unsigned char *)"state", NULL); + doc = xmlNewDoc ((const guchar *)"1.0"); + root = xmlNewDocNode (doc, NULL, (const guchar *)"state", NULL); xmlDocSetRootElement (doc, root); searchscope = e_search_bar_get_search_scope ((ESearchBar *) filter_bar); view_id = e_search_bar_get_viewitem_id ((ESearchBar *) filter_bar); @@ -508,28 +508,28 @@ filter_bar_get_property (GObject *object, if (item_id == E_FILTERBAR_ADVANCED_ID) { /* advanced query, save the filterbar state */ - node = xmlNewChild (root, NULL, (const unsigned char *)"filter-bar", NULL); + node = xmlNewChild (root, NULL, (const guchar *)"filter-bar", NULL); sprintf (buf, "%d", search_bar->last_search_option); - xmlSetProp (node, (const unsigned char *)"item_id", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf); sprintf (buf, "%d", searchscope); - xmlSetProp (node, (const unsigned char *)"searchscope", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf); sprintf (buf, "%d", view_id); - xmlSetProp (node, (const unsigned char *)"view_id", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf); xmlAddChild (node, filter_rule_xml_encode (filter_bar->current_query)); } else { /* simple query, save the searchbar state */ text = e_search_bar_get_text ((ESearchBar *) filter_bar); - node = xmlNewChild (root, NULL, (const unsigned char *)"search-bar", NULL); - xmlSetProp (node, (const unsigned char *)"text", (unsigned char *)(text ? text : "")); + node = xmlNewChild (root, NULL, (const guchar *)"search-bar", NULL); + xmlSetProp (node, (const guchar *)"text", (guchar *)(text ? text : "")); sprintf (buf, "%d", item_id); - xmlSetProp (node, (const unsigned char *)"item_id", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf); sprintf (buf, "%d", searchscope); - xmlSetProp (node, (const unsigned char *)"searchscope", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf); sprintf (buf, "%d", view_id); - xmlSetProp (node, (const unsigned char *)"view_id", (unsigned char *)buf); + xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf); g_free (text); } @@ -538,7 +538,7 @@ filter_bar_get_property (GObject *object, /* remap to glib memory */ text = g_malloc (n + 1); - memcpy (text, (char *)xmlbuf, n); + memcpy (text, (gchar *)xmlbuf, n); text[n] = '\0'; xmlFree (xmlbuf); @@ -552,12 +552,12 @@ filter_bar_get_property (GObject *object, } static int -xml_get_prop_int (xmlNodePtr node, const char *prop) +xml_get_prop_int (xmlNodePtr node, const gchar *prop) { - char *buf; - int ret; + gchar *buf; + gint ret; - if ((buf = (char *)xmlGetProp (node, (unsigned char *)prop))) { + if ((buf = (gchar *)xmlGetProp (node, (guchar *)prop))) { ret = strtol (buf, NULL, 10); xmlFree (buf); } else { @@ -576,26 +576,26 @@ filter_bar_set_property (GObject *object, EFilterBar *filter_bar = (EFilterBar *) object; ESearchBar *search_bar = E_SEARCH_BAR (object); xmlNodePtr root, node; - const char *state; + const gchar *state; xmlDocPtr doc; gboolean rule_set = FALSE, is_cur_folder=FALSE; - int view_id, scope, item_id; + gint view_id, scope, item_id; switch (property_id) { case PROP_STATE: if ((state = g_value_get_string (value))) { - if (!(doc = xmlParseDoc ((unsigned char *) state))) + if (!(doc = xmlParseDoc ((guchar *) state))) return; root = doc->children; - if (strcmp ((char *)root->name, "state") != 0) { + if (strcmp ((gchar *)root->name, "state") != 0) { xmlFreeDoc (doc); return; } node = root->children; while (node != NULL) { - if (!strcmp ((char *)node->name, "filter-bar")) { + if (!strcmp ((gchar *)node->name, "filter-bar")) { FilterRule *rule = NULL; @@ -638,7 +638,7 @@ filter_bar_set_property (GObject *object, search_bar->block_search = FALSE; filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; if (filter_bar->config && filter_bar->current_query) { - char *query = e_search_bar_get_text (search_bar); + gchar *query = e_search_bar_get_text (search_bar); filter_bar->config (filter_bar, filter_bar->current_query, item_id, query, filter_bar->config_data); g_free (query); @@ -651,9 +651,9 @@ filter_bar_set_property (GObject *object, filter_bar->setquery = FALSE; break; - } else if (!strcmp ((char *)node->name, "search-bar")) { - int subitem_id, item_id, scope, view_id; - char *text; + } else if (!strcmp ((gchar *)node->name, "search-bar")) { + gint subitem_id, item_id, scope, view_id; + gchar *text; GtkStyle *style = gtk_widget_get_default_style (); /* set the text first (it doesn't emit a signal) */ @@ -674,7 +674,7 @@ filter_bar_set_property (GObject *object, scope = xml_get_prop_int (node, "searchscope"); e_search_bar_set_search_scope (E_SEARCH_BAR (filter_bar), scope); - text = (char *)xmlGetProp (node, (const unsigned char *)"text"); + text = (gchar *)xmlGetProp (node, (const guchar *)"text"); e_search_bar_set_text (E_SEARCH_BAR (filter_bar), text); if (text && *text) { filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; @@ -866,10 +866,10 @@ e_filter_bar_get_type (void) EFilterBar * e_filter_bar_lite_new (RuleContext *context, - const char *systemrules, - const char *userrules, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, - void *data) + gpointer data) { EFilterBar *bar; @@ -882,8 +882,8 @@ e_filter_bar_lite_new (RuleContext *context, void e_filter_bar_new_construct (RuleContext *context, - const char *systemrules, - const char *userrules, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, gpointer data) { diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index 350a990890..859a21b6c9 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -66,11 +66,11 @@ G_BEGIN_DECLS typedef struct _EFilterBar EFilterBar; typedef struct _EFilterBarClass EFilterBarClass; -typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, int id, const char *query, void *data); +typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, gint id, const gchar *query, gpointer data); struct _EFilterBar { ESearchBar parent; - int menu_base, option_base; + gint menu_base, option_base; GPtrArray *menu_rules, *option_rules; ESearchBarItem *default_items; @@ -78,14 +78,14 @@ struct _EFilterBar { GtkWidget *save_dialog; /* current save dialogue (so we dont pop up multiple ones) */ FilterRule *current_query; /* as it says */ - int setquery; /* true when we're setting a query directly to advanced, so dont popup the dialog */ + gint setquery; /* true when we're setting a query directly to advanced, so dont popup the dialog */ RuleContext *context; - char *systemrules; - char *userrules; + gchar *systemrules; + gchar *userrules; EFilterBarConfigRule config; - void *config_data; + gpointer config_data; CamelVeeFolder *all_account_search_vf; CamelVeeFolder *account_search_vf; @@ -118,7 +118,7 @@ enum { #define E_FILTERBAR_SEPARATOR { NULL, 0, 0 } #ifdef JUST_FOR_TRANSLATORS -const char * strings[] = { +const gchar * strings[] = { N_("_Save Search..."), N_("_Edit Saved Searches..."), N_("_Advanced Search...") @@ -129,22 +129,22 @@ const char * strings[] = { GType e_filter_bar_get_type (void); EFilterBar *e_filter_bar_new (RuleContext *context, - const char *systemrules, - const char *userrules, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, - void *data); + gpointer data); EFilterBar *e_filter_bar_lite_new (RuleContext *context, - const char *systemrules, - const char *userrules, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, - void *data); + gpointer data); void e_filter_bar_new_construct (RuleContext *context, - const char *systemrules, - const char *userrules, + const gchar *systemrules, + const gchar *userrules, EFilterBarConfigRule config, - void *data ,EFilterBar *bar ); + gpointer data ,EFilterBar *bar ); #ifdef __cplusplus } diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c index 6acbe920ef..9110e14257 100644 --- a/widgets/misc/e-gui-utils.c +++ b/widgets/misc/e-gui-utils.c @@ -172,7 +172,7 @@ e_container_change_tab_order(GtkContainer *container, GList *widgets) struct widgetandint { GtkWidget *widget; - int count; + gint count; }; static void @@ -191,7 +191,7 @@ nth_entry_callback(GtkWidget *widget, struct widgetandint *data) } void -e_container_focus_nth_entry(GtkContainer *container, int n) +e_container_focus_nth_entry(GtkContainer *container, gint n) { struct widgetandint data; data.widget = NULL; @@ -202,7 +202,7 @@ e_container_focus_nth_entry(GtkContainer *container, int n) } gboolean -e_glade_xml_connect_widget (GladeXML *gui, char *name, char *signal, GCallback cb, gpointer closure) +e_glade_xml_connect_widget (GladeXML *gui, gchar *name, gchar *signal, GCallback cb, gpointer closure) { GtkWidget *widget; @@ -218,7 +218,7 @@ e_glade_xml_connect_widget (GladeXML *gui, char *name, char *signal, GCallback c } gboolean -e_glade_xml_set_sensitive (GladeXML *gui, char *name, gboolean sensitive) +e_glade_xml_set_sensitive (GladeXML *gui, gchar *name, gboolean sensitive) { GtkWidget *widget; diff --git a/widgets/misc/e-gui-utils.h b/widgets/misc/e-gui-utils.h index 840a55289b..b66160c2d1 100644 --- a/widgets/misc/e-gui-utils.h +++ b/widgets/misc/e-gui-utils.h @@ -36,18 +36,18 @@ void e_container_foreach_leaf (GtkContainer *container, GtkCallback callback, gpointer closure); void e_container_focus_nth_entry (GtkContainer *container, - int n); + gint n); gint e_container_change_tab_order (GtkContainer *container, GList *widgets); /* Returns TRUE on success. */ gboolean e_glade_xml_connect_widget (GladeXML *gui, - char *name, - char *signal, + gchar *name, + gchar *signal, GCallback cb, gpointer closure); gboolean e_glade_xml_set_sensitive (GladeXML *gui, - char *name, + gchar *name, gboolean sensitive); G_END_DECLS diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index cfcce8f8c5..fb11c98323 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -137,7 +137,7 @@ icon_entry_paint (GtkWidget *widget, { EIconEntry *entry = E_ICON_ENTRY (widget); GtkWidget *entry_widget = entry->priv->entry; - int x = 0, y = 0, width, height, focus_width; + gint x = 0, y = 0, width, height, focus_width; gboolean interior_focus; gtk_widget_style_get ( diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index d3b5a1ac07..e11439eb26 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -37,10 +37,10 @@ struct _EImageChooserPrivate { GtkWidget *image; GtkWidget *browse_button; - char *image_buf; - int image_buf_size; - int image_width; - int image_height; + gchar *image_buf; + gint image_buf_size; + gint image_width; + gint image_height; gboolean editable; }; @@ -87,7 +87,7 @@ enum DndTargetType { static GtkTargetEntry image_drag_types[] = { { (gchar *) URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST }, }; -static const int num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]); +static const gint num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]); GtkWidget * e_image_chooser_new (void) @@ -222,13 +222,13 @@ e_image_chooser_dispose (GObject *object) static gboolean set_image_from_data (EImageChooser *chooser, - char *data, int length) + gchar *data, gint length) { gboolean rv = FALSE; GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); GdkPixbuf *pixbuf; - gdk_pixbuf_loader_write (loader, (unsigned char *)data, length, NULL); + gdk_pixbuf_loader_write (loader, (guchar *)data, length, NULL); gdk_pixbuf_loader_close (loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); @@ -242,7 +242,7 @@ set_image_from_data (EImageChooser *chooser, GdkPixbuf *composite; float scale; - int new_height, new_width; + gint new_height, new_width; new_height = gdk_pixbuf_get_height (pixbuf); new_width = gdk_pixbuf_get_width (pixbuf); @@ -331,7 +331,7 @@ image_drag_motion_cb (GtkWidget *widget, return FALSE; for (p = context->targets; p != NULL; p = p->next) { - char *possible_type; + gchar *possible_type; possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data)); if (!strcmp (possible_type, URI_LIST_TYPE)) { @@ -372,7 +372,7 @@ image_drag_drop_cb (GtkWidget *widget, } for (p = context->targets; p != NULL; p = p->next) { - char *possible_type; + gchar *possible_type; possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data)); if (!strcmp (possible_type, URI_LIST_TYPE)) { @@ -398,22 +398,22 @@ image_drag_data_received_cb (GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time, EImageChooser *chooser) { - char *target_type; + gchar *target_type; gboolean handled = FALSE; target_type = gdk_atom_name (selection_data->target); if (!strcmp (target_type, URI_LIST_TYPE)) { GError *error = NULL; - char *uri; - char *nl = strstr ((char *)selection_data->data, "\r\n"); - char *buf = NULL; + gchar *uri; + gchar *nl = strstr ((gchar *)selection_data->data, "\r\n"); + gchar *buf = NULL; gsize read = 0; if (nl) - uri = g_strndup ((char *)selection_data->data, nl - (char*)selection_data->data); + uri = g_strndup ((gchar *)selection_data->data, nl - (gchar *)selection_data->data); else - uri = g_strdup ((char *)selection_data->data); + uri = g_strdup ((gchar *)selection_data->data); if (e_util_read_file (uri, TRUE, &buf, &read, &error) && read > 0 && buf) { if (set_image_from_data (chooser, buf, read)) { @@ -436,7 +436,7 @@ image_drag_data_received_cb (GtkWidget *widget, gboolean -e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename) +e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename) { gchar *data; gsize data_length; @@ -465,7 +465,7 @@ e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable) } gboolean -e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length) +e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length) { g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); g_return_val_if_fail (data != NULL, FALSE); @@ -479,9 +479,9 @@ e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data } gboolean -e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length) +e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length) { - char *buf; + gchar *buf; g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); g_return_val_if_fail (data != NULL, FALSE); diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h index b7f599f0c1..a3972bd26d 100644 --- a/widgets/misc/e-image-chooser.h +++ b/widgets/misc/e-image-chooser.h @@ -58,10 +58,10 @@ struct _EImageChooserClass GtkWidget *e_image_chooser_new (void); GType e_image_chooser_get_type (void); -gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename); -gboolean e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length); +gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename); +gboolean e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length); void e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable); -gboolean e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length); +gboolean e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length); #endif /* _E_IMAGE_CHOOSER_H_ */ diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index c2c0806178..c44e75886b 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -71,7 +71,7 @@ typedef struct GtkAdjustment *vadj; /* Current scrolling offsets */ - int xofs, yofs; + gint xofs, yofs; /* Realtime zoom data */ EMapZoomState zoom_state; @@ -104,9 +104,9 @@ static void e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj static void update_render_pixbuf (EMap *map, GdkInterpType interp, gboolean render_overlays); static void set_scroll_area (EMap *view); static void request_paint_area (EMap *view, GdkRectangle *area); -static void center_at (EMap *map, int x, int y, gboolean scroll); -static void smooth_center_at (EMap *map, int x, int y); -static void scroll_to (EMap *view, int x, int y); +static void center_at (EMap *map, gint x, gint y, gboolean scroll); +static void smooth_center_at (EMap *map, gint x, gint y); +static void scroll_to (EMap *view, gint x, gint y); static void zoom_do (EMap *map); static gint load_map_background (EMap *view, gchar *name); static void adjustment_changed_cb (GtkAdjustment *adj, gpointer data); @@ -207,7 +207,7 @@ static void e_map_init (EMap *view) { EMapPrivate *priv; - char *map_file_name = g_build_filename (EVOLUTION_IMAGES, "world_map-960.png", NULL); + gchar *map_file_name = g_build_filename (EVOLUTION_IMAGES, "world_map-960.png", NULL); priv = g_new0 (EMapPrivate, 1); view->priv = priv; @@ -305,7 +305,7 @@ static void e_map_realize (GtkWidget *widget) { GdkWindowAttr attr; - int attr_mask; + gint attr_mask; g_return_if_fail (widget != NULL); g_return_if_fail (IS_E_MAP (widget)); @@ -538,7 +538,7 @@ e_map_key_press (GtkWidget *widget, GdkEventKey *event) EMap *view; EMapPrivate *priv; gboolean do_scroll; - int xofs, yofs; + gint xofs, yofs; view = E_MAP (widget); priv = view->priv; @@ -578,7 +578,7 @@ e_map_key_press (GtkWidget *widget, GdkEventKey *event) if (do_scroll) { - int x, y; + gint x, y; x = CLAMP (priv->xofs + xofs, 0, priv->hadj->upper - priv->hadj->page_size); y = CLAMP (priv->yofs + yofs, 0, priv->vadj->upper - priv->vadj->page_size); @@ -644,7 +644,7 @@ void e_map_window_to_world (EMap *map, double win_x, double win_y, double *world_longitude, double *world_latitude) { EMapPrivate *priv; - int width, height; + gint width, height; g_return_if_fail (map); @@ -665,7 +665,7 @@ void e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, double *win_x, double *win_y) { EMapPrivate *priv; - int width, height; + gint width, height; g_return_if_fail (map); @@ -895,7 +895,7 @@ e_map_get_closest_point (EMap *map, double longitude, double latitude, gboolean EMapPoint *point_chosen = NULL, *point; double min_dist = 0.0, dist; double dx, dy; - int i; + gint i; priv = map->priv; @@ -971,9 +971,9 @@ update_render_pixbuf (EMap *map, GdkInterpType interp, gboolean render_overlays) { EMapPrivate *priv; EMapPoint *point; - int width, height, orig_width, orig_height; + gint width, height, orig_width, orig_height; double zoom; - int i; + gint i; if (!GTK_WIDGET_REALIZED (GTK_WIDGET (map))) return; @@ -1039,7 +1039,7 @@ static void request_paint_area (EMap *view, GdkRectangle *area) { EMapPrivate *priv; - int width, height; + gint width, height; if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (view)) || !GTK_WIDGET_REALIZED (GTK_WIDGET (view))) return; @@ -1065,7 +1065,7 @@ request_paint_area (EMap *view, GdkRectangle *area) gdk_pixbuf_get_bits_per_sample (priv->map_render_pixbuf) == 8) { guchar *pixels; - int rowstride; + gint rowstride; rowstride = gdk_pixbuf_get_rowstride (priv->map_render_pixbuf); pixels = gdk_pixbuf_get_pixels (priv->map_render_pixbuf) + (area->y + priv->yofs) * rowstride + 3 * (area->x + priv->xofs); @@ -1162,10 +1162,10 @@ repaint_point (EMap *map, EMapPoint *point) static void -center_at (EMap *map, int x, int y, gboolean scroll) +center_at (EMap *map, gint x, gint y, gboolean scroll) { EMapPrivate *priv; - int pb_width, pb_height, + gint pb_width, pb_height, view_width, view_height; priv = map->priv; @@ -1189,12 +1189,12 @@ center_at (EMap *map, int x, int y, gboolean scroll) static void -smooth_center_at (EMap *map, int x, int y) +smooth_center_at (EMap *map, gint x, gint y) { EMapPrivate *priv; - int pb_width, pb_height, + gint pb_width, pb_height, view_width, view_height; - int dx, dy; + gint dx, dy; priv = map->priv; @@ -1222,15 +1222,15 @@ smooth_center_at (EMap *map, int x, int y) /* Scrolls the view to the specified offsets. Does not perform range checking! */ static void -scroll_to (EMap *view, int x, int y) +scroll_to (EMap *view, gint x, gint y) { EMapPrivate *priv; - int xofs, yofs; + gint xofs, yofs; GdkWindow *window; GdkGC *gc; - int width, height; - int src_x, src_y; - int dest_x, dest_y; + gint width, height; + gint src_x, src_y; + gint dest_x, dest_y; GdkEvent *event; priv = view->priv; @@ -1322,7 +1322,7 @@ scroll_to (EMap *view, int x, int y) } -static int divide_seq[] = +static gint divide_seq[] = { /* Dividends for divisor of 2 */ @@ -1417,7 +1417,7 @@ blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, gint divide_width_index, divide_height_index; gint area_width, area_height; gint i, j; - int line; + gint line; /* Set up the GC we'll be using */ @@ -1548,7 +1548,7 @@ zoom_in_smooth (EMap *map) GdkRectangle area; EMapPrivate *priv; GdkWindow *window; - int width, height; + gint width, height; double x, y; g_return_if_fail (map); diff --git a/widgets/misc/e-popup-menu.c b/widgets/misc/e-popup-menu.c index 143eaff327..20b570df24 100644 --- a/widgets/misc/e-popup-menu.c +++ b/widgets/misc/e-popup-menu.c @@ -37,7 +37,7 @@ * Creates an item with an optional icon */ static void -make_item (GtkMenu *menu, GtkMenuItem *item, const char *name, GtkWidget *pixmap) +make_item (GtkMenu *menu, GtkMenuItem *item, const gchar *name, GtkWidget *pixmap) { GtkWidget *label; @@ -63,7 +63,7 @@ GtkMenu * e_popup_menu_create (EPopupMenu *menu_list, guint32 disable_mask, guint32 hide_mask, - void *default_closure) + gpointer default_closure) { return e_popup_menu_create_with_domain (menu_list, disable_mask, @@ -77,14 +77,14 @@ GtkMenu * e_popup_menu_create_with_domain (EPopupMenu *menu_list, guint32 disable_mask, guint32 hide_mask, - void *default_closure, - const char *domain) + gpointer default_closure, + const gchar *domain) { GtkMenu *menu = GTK_MENU (gtk_menu_new ()); GSList *group = NULL; gboolean last_item_separator = TRUE; - int last_non_separator = -1; - int i; + gint last_non_separator = -1; + gint i; for (i = 0; menu_list[i].name; i++) { if (strcmp ("", menu_list[i].name) && !(menu_list [i].disable_mask & hide_mask)) { @@ -147,7 +147,7 @@ e_popup_menu_create_with_domain (EPopupMenu *menu_list, } void -e_popup_menu_run (EPopupMenu *menu_list, GdkEvent *event, guint32 disable_mask, guint32 hide_mask, void *default_closure) +e_popup_menu_run (EPopupMenu *menu_list, GdkEvent *event, guint32 disable_mask, guint32 hide_mask, gpointer default_closure) { GtkMenu *menu; @@ -195,7 +195,7 @@ e_popup_menu_free_1 (EPopupMenu *menu_item) EPopupMenu * e_popup_menu_copy (const EPopupMenu *menu_list) { - int i; + gint i; EPopupMenu *ret_val; if (menu_list == NULL) @@ -220,7 +220,7 @@ e_popup_menu_copy (const EPopupMenu *menu_list) void e_popup_menu_free (EPopupMenu *menu_list) { - int i; + gint i; if (menu_list == NULL) return; diff --git a/widgets/misc/e-popup-menu.h b/widgets/misc/e-popup-menu.h index ddf6ed04a9..75246ebda6 100644 --- a/widgets/misc/e-popup-menu.h +++ b/widgets/misc/e-popup-menu.h @@ -71,8 +71,8 @@ G_BEGIN_DECLS typedef struct _EPopupMenu EPopupMenu; struct _EPopupMenu { - char *name; - char *pixname; + gchar *name; + gchar *pixname; GCallback fn; EPopupMenu *submenu; @@ -80,7 +80,7 @@ struct _EPopupMenu { /* Added post 0.19 */ GtkWidget *pixmap_widget; - void *closure; + gpointer closure; guint is_toggle : 1; guint is_radio : 1; @@ -97,7 +97,7 @@ GtkMenu *e_popup_menu_create_with_domain (EPopupMenu *menu_list, guint32 disable_mask, guint32 hide_mask, void *default_closure, - const char *domain); + const gchar *domain); void e_popup_menu_run (EPopupMenu *menu_list, GdkEvent *event, guint32 disable_mask, diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 9abc60442a..849825e160 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -99,8 +99,8 @@ clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearch update_clear_menuitem_sensitive (search_bar); } -static char * -verb_name_from_id (int id) +static gchar * +verb_name_from_id (gint id) { return g_strdup_printf ("ESearchBar:Activate:%d", id); } @@ -268,7 +268,7 @@ static void entry_activated_cb (GtkWidget *widget, ESearchBar *esb) { - const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); + const gchar *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); GtkStyle *style = gtk_widget_get_default_style (); if (text && *text) { @@ -607,7 +607,7 @@ search_bar_dispose (GObject *object) /* /\* Callback used when an option item is destroyed. We have to destroy its */ /* * suboption items. */ /* *\/ */ -/* static void */ +/* static gpointer / /* option_item_destroy_cb (GtkObject *object, gpointer data) */ /* { */ /* /\* ESearchBarSubitem *subitems; *\/ */ @@ -624,7 +624,7 @@ set_option (ESearchBar *esb, ESearchBarItem *items) { GtkWidget *menu; GSList *group = NULL; - int i; + gint i; if (esb->option_menu) gtk_widget_destroy (esb->option_menu); @@ -638,7 +638,7 @@ set_option (ESearchBar *esb, ESearchBarItem *items) group = NULL; if (items[i].text) { - char *str; + gchar *str; str = e_str_without_underscores (_(items[i].text)); switch (items[i].type) { case ESB_ITEMTYPE_NORMAL: diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index aadfc42ab5..41bebf96fd 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -88,10 +88,10 @@ struct _ESearchBar { guint pending_activate; /* The currently-selected item & subitem */ - int item_id; - int viewitem_id; /* Current View Id */ - int scopeitem_id; /* Scope of search */ - int last_search_option; + gint item_id; + gint viewitem_id; /* Current View Id */ + gint scopeitem_id; /* Scope of search */ + gint last_search_option; gboolean block_search; gboolean lite; @@ -123,18 +123,18 @@ void e_search_bar_set_option (ESearchBar *search_bar, ESearchBarItem *option_items); void e_search_bar_paint (ESearchBar *search_bar); void e_search_bar_set_viewoption (ESearchBar *search_bar, - int option_id, + gint option_id, ESearchBarItem *subitems); void e_search_bar_set_menu_sensitive (ESearchBar *search_bar, - int id, + gint id, gboolean state); void e_search_bar_set_item_id (ESearchBar *search_bar, - int id); + gint id); void e_search_bar_set_item_menu (ESearchBar *search_bar, - int id); -int e_search_bar_get_item_id (ESearchBar *search_bar); + gint id); +gint e_search_bar_get_item_id (ESearchBar *search_bar); G_END_DECLS diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index 7e82039d6e..dde69a7e06 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -42,7 +42,7 @@ void e_selection_model_array_confirm_row_count(ESelectionModelArray *esma) { if (esma->eba == NULL) { - int row_count = e_selection_model_array_get_row_count(esma); + gint row_count = e_selection_model_array_get_row_count(esma); esma->eba = e_bit_array_new(row_count); esma->selected_row = -1; esma->selected_range_end = -1; @@ -69,7 +69,7 @@ es_row_sorted_to_model (ESelectionModelArray *esma, gint sorted_row) /* FIXME: Should this deal with moving the selection if it's in single mode? */ void -e_selection_model_array_delete_rows(ESelectionModelArray *esma, int row, int count) +e_selection_model_array_delete_rows(ESelectionModelArray *esma, gint row, gint count) { if (esma->eba) { if (E_SELECTION_MODEL(esma)->mode == GTK_SELECTION_SINGLE) @@ -119,7 +119,7 @@ e_selection_model_array_delete_rows(ESelectionModelArray *esma, int row, int cou } void -e_selection_model_array_insert_rows(ESelectionModelArray *esma, int row, int count) +e_selection_model_array_insert_rows(ESelectionModelArray *esma, gint row, gint count) { if (esma->eba) { e_bit_array_insert(esma->eba, row, count); @@ -135,7 +135,7 @@ e_selection_model_array_insert_rows(ESelectionModelArray *esma, int row, int cou } void -e_selection_model_array_move_row(ESelectionModelArray *esma, int old_row, int new_row) +e_selection_model_array_move_row(ESelectionModelArray *esma, gint old_row, gint new_row) { ESelectionModel *esm = E_SELECTION_MODEL(esma); @@ -366,7 +366,7 @@ esma_row_count (ESelectionModel *selection) } static void -esma_change_one_row(ESelectionModel *selection, int row, gboolean grow) +esma_change_one_row(ESelectionModel *selection, gint row, gboolean grow) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); e_selection_model_array_confirm_row_count(esma); @@ -374,7 +374,7 @@ esma_change_one_row(ESelectionModel *selection, int row, gboolean grow) } static void -esma_change_cursor (ESelectionModel *selection, int row, int col) +esma_change_cursor (ESelectionModel *selection, gint row, gint col) { ESelectionModelArray *esma; @@ -389,9 +389,9 @@ esma_change_cursor (ESelectionModel *selection, int row, int col) } static void -esma_change_range(ESelectionModel *selection, int start, int end, gboolean grow) +esma_change_range(ESelectionModel *selection, gint start, gint end, gboolean grow) { - int i; + gint i; ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); if (start != end) { if (selection->sorter && e_sorter_needs_sorting(selection->sorter)) { @@ -420,7 +420,7 @@ esma_cursor_col (ESelectionModel *selection) } static void -esma_real_select_single_row (ESelectionModel *selection, int row) +esma_real_select_single_row (ESelectionModel *selection, gint row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); @@ -434,10 +434,10 @@ esma_real_select_single_row (ESelectionModel *selection, int row) } static void -esma_select_single_row (ESelectionModel *selection, int row) +esma_select_single_row (ESelectionModel *selection, gint row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); - int selected_row = esma->selected_row; + gint selected_row = esma->selected_row; esma_real_select_single_row (selection, row); if (selected_row != -1 && esma->eba && selected_row < e_bit_array_bit_count (esma->eba)) { @@ -451,7 +451,7 @@ esma_select_single_row (ESelectionModel *selection, int row) } static void -esma_toggle_single_row (ESelectionModel *selection, int row) +esma_toggle_single_row (ESelectionModel *selection, gint row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); @@ -465,13 +465,13 @@ esma_toggle_single_row (ESelectionModel *selection, int row) } static void -esma_real_move_selection_end (ESelectionModel *selection, int row) +esma_real_move_selection_end (ESelectionModel *selection, gint row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); - int old_start; - int old_end; - int new_start; - int new_end; + gint old_start; + gint old_end; + gint new_start; + gint new_end; if (selection->sorter && e_sorter_needs_sorting(selection->sorter)) { old_start = MIN (e_sorter_model_to_sorted(selection->sorter, esma->selection_start_row), e_sorter_model_to_sorted(selection->sorter, esma->cursor_row)); @@ -501,18 +501,18 @@ esma_real_move_selection_end (ESelectionModel *selection, int row) } static void -esma_move_selection_end (ESelectionModel *selection, int row) +esma_move_selection_end (ESelectionModel *selection, gint row) { esma_real_move_selection_end (selection, row); e_selection_model_selection_changed(selection); } static void -esma_set_selection_end (ESelectionModel *selection, int row) +esma_set_selection_end (ESelectionModel *selection, gint row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); - int selected_range_end = esma->selected_range_end; - int view_row = e_sorter_model_to_sorted(selection->sorter, row); + gint selected_range_end = esma->selected_range_end; + gint view_row = e_sorter_model_to_sorted(selection->sorter, row); esma_real_select_single_row(selection, esma->selection_start_row); esma->cursor_row = esma->selection_start_row; @@ -530,7 +530,7 @@ esma_set_selection_end (ESelectionModel *selection, int row) e_selection_model_selection_changed(selection); } -int +gint e_selection_model_array_get_row_count (ESelectionModelArray *esma) { g_return_val_if_fail(esma != NULL, 0); diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index 9f297c1fed..be21a5557e 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -76,14 +76,14 @@ GType e_selection_model_array_get_type (void); /* Protected Functions */ void e_selection_model_array_insert_rows (ESelectionModelArray *esm, - int row, - int count); + gint row, + gint count); void e_selection_model_array_delete_rows (ESelectionModelArray *esm, - int row, - int count); + gint row, + gint count); void e_selection_model_array_move_row (ESelectionModelArray *esm, - int old_row, - int new_row); + gint old_row, + gint new_row); void e_selection_model_array_confirm_row_count (ESelectionModelArray *esm); /* Protected Virtual Function */ diff --git a/widgets/misc/e-selection-model-simple.c b/widgets/misc/e-selection-model-simple.c index b9f1d33bfe..b0b151dd6d 100644 --- a/widgets/misc/e-selection-model-simple.c +++ b/widgets/misc/e-selection-model-simple.c @@ -63,7 +63,7 @@ e_selection_model_simple_new (void) void e_selection_model_simple_set_row_count (ESelectionModelSimple *esms, - int row_count) + gint row_count) { if (esms->row_count != row_count) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(esms); @@ -85,8 +85,8 @@ esms_get_row_count (ESelectionModelArray *esma) } void e_selection_model_simple_insert_rows (ESelectionModelSimple *esms, - int row, - int count) + gint row, + gint count) { esms->row_count += count; e_selection_model_array_insert_rows (E_SELECTION_MODEL_ARRAY(esms), row, count); @@ -94,8 +94,8 @@ void e_selection_model_simple_insert_rows (ESelectionModelSimple *e void e_selection_model_simple_delete_rows (ESelectionModelSimple *esms, - int row, - int count) + gint row, + gint count) { esms->row_count -= count; e_selection_model_array_delete_rows (E_SELECTION_MODEL_ARRAY(esms), row, count); @@ -103,8 +103,8 @@ e_selection_model_simple_delete_rows (ESelectionModelSimple *esms, void e_selection_model_simple_move_row (ESelectionModelSimple *esms, - int old_row, - int new_row) + gint old_row, + gint new_row) { e_selection_model_array_move_row (E_SELECTION_MODEL_ARRAY(esms), old_row, new_row); } diff --git a/widgets/misc/e-selection-model-simple.h b/widgets/misc/e-selection-model-simple.h index 7f11d3ac0e..8db463b32f 100644 --- a/widgets/misc/e-selection-model-simple.h +++ b/widgets/misc/e-selection-model-simple.h @@ -39,7 +39,7 @@ extern "C" { typedef struct { ESelectionModelArray parent; - int row_count; + gint row_count; } ESelectionModelSimple; typedef struct { @@ -50,17 +50,17 @@ GType e_selection_model_simple_get_type (void); ESelectionModelSimple *e_selection_model_simple_new (void); void e_selection_model_simple_insert_rows (ESelectionModelSimple *esms, - int row, - int count); + gint row, + gint count); void e_selection_model_simple_delete_rows (ESelectionModelSimple *esms, - int row, - int count); + gint row, + gint count); void e_selection_model_simple_move_row (ESelectionModelSimple *esms, - int old_row, - int new_row); + gint old_row, + gint new_row); void e_selection_model_simple_set_row_count (ESelectionModelSimple *selection, - int row_count); + gint row_count); #ifdef __cplusplus } diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index 66187e6e7c..cc1d3b3780 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -113,8 +113,8 @@ esm_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpe case PROP_SELECTION_MODE: esm->mode = g_value_get_int (value); if (esm->mode == GTK_SELECTION_SINGLE) { - int cursor_row = e_selection_model_cursor_row(esm); - int cursor_col = e_selection_model_cursor_col(esm); + gint cursor_row = e_selection_model_cursor_row(esm); + gint cursor_col = e_selection_model_cursor_col(esm); e_selection_model_do_something(esm, cursor_row, cursor_col, 0); } break; @@ -322,7 +322,7 @@ e_selection_model_invert_selection (ESelectionModel *selection) E_SELECTION_MODEL_GET_CLASS(selection)->invert_selection (selection); } -int +gint e_selection_model_row_count (ESelectionModel *selection) { if (E_SELECTION_MODEL_GET_CLASS(selection)->row_count) @@ -332,20 +332,20 @@ e_selection_model_row_count (ESelectionModel *selection) } void -e_selection_model_change_one_row(ESelectionModel *selection, int row, gboolean grow) +e_selection_model_change_one_row(ESelectionModel *selection, gint row, gboolean grow) { if (E_SELECTION_MODEL_GET_CLASS(selection)->change_one_row) E_SELECTION_MODEL_GET_CLASS(selection)->change_one_row (selection, row, grow); } void -e_selection_model_change_cursor (ESelectionModel *selection, int row, int col) +e_selection_model_change_cursor (ESelectionModel *selection, gint row, gint col) { if (E_SELECTION_MODEL_GET_CLASS(selection)->change_cursor) E_SELECTION_MODEL_GET_CLASS(selection)->change_cursor (selection, row, col); } -int +gint e_selection_model_cursor_row (ESelectionModel *selection) { if (E_SELECTION_MODEL_GET_CLASS(selection)->cursor_row) @@ -354,7 +354,7 @@ e_selection_model_cursor_row (ESelectionModel *selection) return -1; } -int +gint e_selection_model_cursor_col (ESelectionModel *selection) { if (E_SELECTION_MODEL_GET_CLASS(selection)->cursor_col) @@ -364,28 +364,28 @@ e_selection_model_cursor_col (ESelectionModel *selection) } void -e_selection_model_select_single_row (ESelectionModel *selection, int row) +e_selection_model_select_single_row (ESelectionModel *selection, gint row) { if (E_SELECTION_MODEL_GET_CLASS(selection)->select_single_row) E_SELECTION_MODEL_GET_CLASS(selection)->select_single_row (selection, row); } void -e_selection_model_toggle_single_row (ESelectionModel *selection, int row) +e_selection_model_toggle_single_row (ESelectionModel *selection, gint row) { if (E_SELECTION_MODEL_GET_CLASS(selection)->toggle_single_row) E_SELECTION_MODEL_GET_CLASS(selection)->toggle_single_row (selection, row); } void -e_selection_model_move_selection_end (ESelectionModel *selection, int row) +e_selection_model_move_selection_end (ESelectionModel *selection, gint row) { if (E_SELECTION_MODEL_GET_CLASS(selection)->move_selection_end) E_SELECTION_MODEL_GET_CLASS(selection)->move_selection_end (selection, row); } void -e_selection_model_set_selection_end (ESelectionModel *selection, int row) +e_selection_model_set_selection_end (ESelectionModel *selection, gint row) { if (E_SELECTION_MODEL_GET_CLASS(selection)->set_selection_end) E_SELECTION_MODEL_GET_CLASS(selection)->set_selection_end (selection, row); @@ -409,7 +409,7 @@ e_selection_model_do_something (ESelectionModel *selection, { gint shift_p = state & GDK_SHIFT_MASK; gint ctrl_p = state & GDK_CONTROL_MASK; - int row_count; + gint row_count; selection->old_selection = -1; @@ -511,7 +511,7 @@ e_selection_model_select_as_key_press (ESelectionModel *selection, guint col, GdkModifierType state) { - int cursor_activated = TRUE; + gint cursor_activated = TRUE; gint shift_p = state & GDK_SHIFT_MASK; gint ctrl_p = state & GDK_CONTROL_MASK; @@ -552,9 +552,9 @@ move_selection (ESelectionModel *selection, gboolean up, GdkModifierType state) { - int row = e_selection_model_cursor_row(selection); - int col = e_selection_model_cursor_col(selection); - int row_count; + gint row = e_selection_model_cursor_row(selection); + gint col = e_selection_model_cursor_col(selection); + gint row_count; /* there is no selected row when row is -1 */ if (row != -1) @@ -601,8 +601,8 @@ e_selection_model_key_press (ESelectionModel *selection, case GDK_space: case GDK_KP_Space: if (selection->mode != GTK_SELECTION_SINGLE) { - int row = e_selection_model_cursor_row(selection); - int col = e_selection_model_cursor_col(selection); + gint row = e_selection_model_cursor_row(selection); + gint col = e_selection_model_cursor_col(selection); if (row == -1) break; @@ -616,8 +616,8 @@ e_selection_model_key_press (ESelectionModel *selection, case GDK_Return: case GDK_KP_Enter: if (selection->mode != GTK_SELECTION_SINGLE) { - int row = e_selection_model_cursor_row(selection); - int col = e_selection_model_cursor_col(selection); + gint row = e_selection_model_cursor_row(selection); + gint col = e_selection_model_cursor_col(selection); e_selection_model_select_single_row (selection, row); g_signal_emit(selection, e_selection_model_signals[CURSOR_ACTIVATED], 0, @@ -628,8 +628,8 @@ e_selection_model_key_press (ESelectionModel *selection, case GDK_Home: case GDK_KP_Home: if (selection->cursor_mode == E_CURSOR_LINE) { - int row = 0; - int cursor_col = e_selection_model_cursor_col(selection); + gint row = 0; + gint cursor_col = e_selection_model_cursor_col(selection); row = e_sorter_sorted_to_model(selection->sorter, row); e_selection_model_select_as_key_press (selection, row, cursor_col, key->state); @@ -639,8 +639,8 @@ e_selection_model_key_press (ESelectionModel *selection, case GDK_End: case GDK_KP_End: if (selection->cursor_mode == E_CURSOR_LINE) { - int row = e_selection_model_row_count(selection) - 1; - int cursor_col = e_selection_model_cursor_col(selection); + gint row = e_selection_model_row_count(selection) - 1; + gint cursor_col = e_selection_model_cursor_col(selection); row = e_sorter_sorted_to_model(selection->sorter, row); e_selection_model_select_as_key_press (selection, row, cursor_col, key->state); @@ -653,8 +653,8 @@ e_selection_model_key_press (ESelectionModel *selection, void e_selection_model_cursor_changed (ESelectionModel *selection, - int row, - int col) + gint row, + gint col) { g_signal_emit(selection, e_selection_model_signals[CURSOR_CHANGED], 0, @@ -663,8 +663,8 @@ e_selection_model_cursor_changed (ESelectionModel *selection, void e_selection_model_cursor_activated (ESelectionModel *selection, - int row, - int col) + gint row, + gint col) { g_signal_emit(selection, e_selection_model_signals[CURSOR_ACTIVATED], 0, @@ -680,7 +680,7 @@ e_selection_model_selection_changed (ESelectionModel *selection) void e_selection_model_selection_row_changed (ESelectionModel *selection, - int row) + gint row) { g_signal_emit(selection, e_selection_model_signals[SELECTION_ROW_CHANGED], 0, diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index 24eccd304f..16194000a5 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -40,7 +40,7 @@ extern "C" { #ifndef _E_FOREACH_FUNC_H_ #define _E_FOREACH_FUNC_H_ -typedef void (*EForeachFunc) (int model_row, +typedef void (*EForeachFunc) (gint model_row, gpointer closure); #endif @@ -59,39 +59,39 @@ typedef struct { GtkSelectionMode mode; ECursorMode cursor_mode; - int old_selection; + gint old_selection; } ESelectionModel; typedef struct { GObjectClass parent_class; /* Virtual methods */ - gboolean (*is_row_selected) (ESelectionModel *esm, int row); + gboolean (*is_row_selected) (ESelectionModel *esm, gint row); void (*foreach) (ESelectionModel *esm, EForeachFunc callback, gpointer closure); void (*clear) (ESelectionModel *esm); gint (*selected_count) (ESelectionModel *esm); void (*select_all) (ESelectionModel *esm); void (*invert_selection) (ESelectionModel *esm); - int (*row_count) (ESelectionModel *esm); + gint (*row_count) (ESelectionModel *esm); /* Protected virtual methods. */ - void (*change_one_row) (ESelectionModel *esm, int row, gboolean on); - void (*change_cursor) (ESelectionModel *esm, int row, int col); - int (*cursor_row) (ESelectionModel *esm); - int (*cursor_col) (ESelectionModel *esm); + void (*change_one_row) (ESelectionModel *esm, gint row, gboolean on); + void (*change_cursor) (ESelectionModel *esm, gint row, gint col); + gint (*cursor_row) (ESelectionModel *esm); + gint (*cursor_col) (ESelectionModel *esm); - void (*select_single_row) (ESelectionModel *selection, int row); - void (*toggle_single_row) (ESelectionModel *selection, int row); - void (*move_selection_end) (ESelectionModel *selection, int row); - void (*set_selection_end) (ESelectionModel *selection, int row); + void (*select_single_row) (ESelectionModel *selection, gint row); + void (*toggle_single_row) (ESelectionModel *selection, gint row); + void (*move_selection_end) (ESelectionModel *selection, gint row); + void (*set_selection_end) (ESelectionModel *selection, gint row); /* * Signals */ - void (*cursor_changed) (ESelectionModel *esm, int row, int col); - void (*cursor_activated) (ESelectionModel *esm, int row, int col); - void (*selection_row_changed) (ESelectionModel *esm, int row); + void (*cursor_changed) (ESelectionModel *esm, gint row, gint col); + void (*cursor_activated) (ESelectionModel *esm, gint row, gint col); + void (*selection_row_changed) (ESelectionModel *esm, gint row); void (*selection_changed) (ESelectionModel *esm); } ESelectionModelClass; @@ -128,36 +128,36 @@ void e_selection_model_clear (ESelectionModel *esm); gint e_selection_model_selected_count (ESelectionModel *esm); void e_selection_model_select_all (ESelectionModel *esm); void e_selection_model_invert_selection (ESelectionModel *esm); -int e_selection_model_row_count (ESelectionModel *esm); +gint e_selection_model_row_count (ESelectionModel *esm); /* Private virtual Functions */ void e_selection_model_change_one_row (ESelectionModel *esm, - int row, + gint row, gboolean on); void e_selection_model_change_cursor (ESelectionModel *esm, - int row, - int col); -int e_selection_model_cursor_row (ESelectionModel *esm); -int e_selection_model_cursor_col (ESelectionModel *esm); + gint row, + gint col); +gint e_selection_model_cursor_row (ESelectionModel *esm); +gint e_selection_model_cursor_col (ESelectionModel *esm); void e_selection_model_select_single_row (ESelectionModel *selection, - int row); + gint row); void e_selection_model_toggle_single_row (ESelectionModel *selection, - int row); + gint row); void e_selection_model_move_selection_end (ESelectionModel *selection, - int row); + gint row); void e_selection_model_set_selection_end (ESelectionModel *selection, - int row); + gint row); /* Signals */ void e_selection_model_cursor_changed (ESelectionModel *selection, - int row, - int col); + gint row, + gint col); void e_selection_model_cursor_activated (ESelectionModel *selection, - int row, - int col); + gint row, + gint col); void e_selection_model_selection_row_changed (ESelectionModel *selection, - int row); + gint row); void e_selection_model_selection_changed (ESelectionModel *selection); #ifdef __cplusplus diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index 8740f2d02e..b42630ebae 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -97,7 +97,7 @@ struct _ESendOptionsDialogPrivate { GtkWidget *accepted_label; GtkWidget *completed_label; GtkWidget *until_label; - char *help_section; + gchar *help_section; }; static void e_sendoptions_dialog_class_init (GObjectClass *object_class); @@ -345,7 +345,7 @@ delay_until_date_changed_cb (GtkWidget *dedit, gpointer data) } static void -page_changed_cb (GtkNotebook *notebook, GtkNotebookPage *page, int num, gpointer data) +page_changed_cb (GtkNotebook *notebook, GtkNotebookPage *page, gint num, gpointer data) { ESendOptionsDialog *sod = data; ESendOptionsDialogPrivate *priv = sod->priv; diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index 6e18410018..87e53dce8f 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -100,8 +100,8 @@ typedef struct { guint ref_count; GtkIconSize size; - int width; - int height; + gint width; + gint height; GdkPixbuf **animation_pixbufs; guint n_animation_pixbufs; } ESpinnerImages; @@ -208,9 +208,9 @@ e_spinner_cache_data_unload (ESpinnerCacheData *data) static GdkPixbuf * extract_frame (GdkPixbuf *grid_pixbuf, - int x, - int y, - int size) + gint x, + gint y, + gint size) { GdkPixbuf *pixbuf; @@ -230,11 +230,11 @@ extract_frame (GdkPixbuf *grid_pixbuf, static GdkPixbuf * scale_to_size (GdkPixbuf *pixbuf, - int dw, - int dh) + gint dw, + gint dh) { GdkPixbuf *result; - int pw, ph; + gint pw, ph; g_return_val_if_fail (pixbuf != NULL, NULL); @@ -259,8 +259,8 @@ e_spinner_images_load (GdkScreen *screen, ESpinnerImages *images; GdkPixbuf *icon_pixbuf, *pixbuf; GtkIconInfo *icon_info = NULL; - int grid_width, grid_height, x, y, requested_size, size, isw, ish, n; - const char *icon; + gint grid_width, grid_height, x, y, requested_size, size, isw, ish, n; + const gchar *icon; GSList *list = NULL, *l; LOG ("ESpinnerCacheData loading for screen %p at size %d", screen, icon_size); @@ -642,7 +642,7 @@ e_spinner_expose (GtkWidget *widget, ESpinnerImages *images; GdkPixbuf *pixbuf; GdkGC *gc; - int x_offset, y_offset, width, height; + gint x_offset, y_offset, width, height; GdkRectangle pix_area, dest; if (!GTK_WIDGET_DRAWABLE (spinner)) diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index 6c8eab7c8b..2dd47ebb8f 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -186,7 +186,7 @@ entry_changed_cb (GtkEditable *editable, gpointer data) { EUrlEntry *url_entry; EUrlEntryPrivate *priv; - const char *url; + const gchar *url; url_entry = E_URL_ENTRY (data); priv = url_entry->priv; diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c index 20f34d8ba8..7b2d59056d 100644 --- a/widgets/misc/test-calendar.c +++ b/widgets/misc/test-calendar.c @@ -55,8 +55,8 @@ delete_event_cb (GtkWidget *widget, gtk_main_quit (); } -int -main (int argc, char **argv) +gint +main (gint argc, gchar **argv) { GtkWidget *window; GtkWidget *cal; diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c index 7468053f31..745c982b8d 100644 --- a/widgets/misc/test-dateedit.c +++ b/widgets/misc/test-dateedit.c @@ -47,8 +47,8 @@ static void on_time_changed (EDateEdit *dedit, gchar *name); #endif -int -main (int argc, char **argv) +gint +main (gint argc, gchar **argv) { GtkWidget *window; EDateEdit *dedit; diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c index c0f13f5845..4e4d9894fa 100644 --- a/widgets/misc/test-preferences-window.c +++ b/widgets/misc/test-preferences-window.c @@ -28,12 +28,12 @@ static void add_pages (EPreferencesWindow *preferences_window) { - int i; + gint i; for (i = 0; i < NUM_PAGES; i ++) { GtkWidget *widget; - char *caption; - char *page_name; + gchar *caption; + gchar *page_name; caption = g_strdup_printf ("Title of page %d", i); page_name = g_strdup_printf ("page-%d", i); @@ -53,15 +53,15 @@ add_pages (EPreferencesWindow *preferences_window) static int delete_event_callback (GtkWidget *widget, GdkEventAny *event, - void *data) + gpointer data) { gtk_main_quit (); return TRUE; } -int -main (int argc, char **argv) +gint +main (gint argc, gchar **argv) { GtkWidget *window; -- cgit v1.2.3 From 14f8eee012382f04090ea9277e9567d5f32e8bf0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 28 May 2009 13:06:29 -0400 Subject: Whitespace cleanup. --- widgets/misc/a11y/ea-calendar-item.c | 4 ++-- widgets/misc/e-attachment-dialog.c | 2 +- widgets/misc/e-calendar.c | 12 ++++++------ widgets/misc/e-canvas.h | 2 +- widgets/misc/e-charset-picker.c | 2 +- widgets/misc/e-cursors.h | 2 +- widgets/misc/e-dateedit.c | 4 ++-- widgets/misc/e-filter-bar.c | 4 ++-- widgets/misc/e-filter-bar.h | 2 +- widgets/misc/e-icon-entry.c | 4 ++-- widgets/misc/e-image-chooser.h | 6 +++--- widgets/misc/e-map.c | 8 ++++---- widgets/misc/e-search-bar.c | 20 ++++++++++---------- widgets/misc/e-send-options.c | 14 +++++++------- widgets/misc/e-spinner.c | 14 +++++++------- 15 files changed, 50 insertions(+), 50 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/a11y/ea-calendar-item.c b/widgets/misc/a11y/ea-calendar-item.c index e1fb365aff..56a01b510b 100644 --- a/widgets/misc/a11y/ea-calendar-item.c +++ b/widgets/misc/a11y/ea-calendar-item.c @@ -280,7 +280,7 @@ ea_calendar_item_get_name (AtkObject *accessible) g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); if (!g_obj) - return NULL; + return NULL; g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL); calitem = E_CALENDAR_ITEM (g_obj); @@ -1192,7 +1192,7 @@ e_calendar_item_get_day_extents (ECalendarItem *calitem, month_y = item->y1 + ythickness + month_row * calitem->month_height; month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS - + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; + + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; text_y = month_y + ythickness * 2 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index e1037ae175..45c2103e3d 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -407,7 +407,7 @@ e_attachment_dialog_new (GtkWindow *parent, EAttachment *attachment) { if (parent != NULL) - g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); + g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); if (attachment != NULL) g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index 88e59b87db..a0adf46cf5 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -83,7 +83,7 @@ static void e_calendar_drag_leave (GtkWidget *widget, guint time); static gboolean e_calendar_button_has_focus (ECalendar *cal); static gboolean e_calendar_focus (GtkWidget *widget, - GtkDirectionType direction); + GtkDirectionType direction); static void e_calendar_on_prev_pressed (ECalendar *cal); static void e_calendar_on_prev_released (ECalendar *cal); @@ -113,11 +113,11 @@ e_calendar_class_init (ECalendarClass *class) widget_class->realize = e_calendar_realize; widget_class->style_set = e_calendar_style_set; - widget_class->size_request = e_calendar_size_request; - widget_class->size_allocate = e_calendar_size_allocate; + widget_class->size_request = e_calendar_size_request; + widget_class->size_allocate = e_calendar_size_allocate; widget_class->drag_motion = e_calendar_drag_motion; widget_class->drag_leave = e_calendar_drag_leave; - widget_class->focus = e_calendar_focus; + widget_class->focus = e_calendar_focus; } @@ -351,7 +351,7 @@ e_calendar_size_allocate (GtkWidget *widget, gnome_canvas_item_set (cal->prev_item, "x", (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? new_x2 + 1 - xthickness * 2 - E_CALENDAR_ARROW_BUTTON_X_PAD - - arrow_button_size + - arrow_button_size : xthickness * 2 + E_CALENDAR_ARROW_BUTTON_X_PAD, "y", ythickness * 2 + E_CALENDAR_ARROW_BUTTON_Y_PAD, @@ -363,7 +363,7 @@ e_calendar_size_allocate (GtkWidget *widget, "x", (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? xthickness * 2 + E_CALENDAR_ARROW_BUTTON_X_PAD : new_x2 + 1 - xthickness * 2 - E_CALENDAR_ARROW_BUTTON_X_PAD - - arrow_button_size, + - arrow_button_size, "y", ythickness * 2 + E_CALENDAR_ARROW_BUTTON_Y_PAD, "width", arrow_button_size, diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index e23d29f057..5f60fc4046 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -42,7 +42,7 @@ extern "C" { #define E_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_CANVAS_TYPE)) typedef void (*ECanvasItemReflowFunc) (GnomeCanvasItem *item, - gint flags); + gint flags); typedef void (*ECanvasItemSelectionFunc) (GnomeCanvasItem *item, gint flags, diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 34e9c63545..593df6b651 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -256,7 +256,7 @@ activate_other (GtkWidget *item, gpointer menu) if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) { new_charset = (gchar *)gtk_entry_get_text (GTK_ENTRY (entry)); - if (*new_charset) { + if (*new_charset) { if (add_other_charset (menu, item, new_charset)) { gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (dialog); diff --git a/widgets/misc/e-cursors.h b/widgets/misc/e-cursors.h index 7df3404092..23ac7c0899 100644 --- a/widgets/misc/e-cursors.h +++ b/widgets/misc/e-cursors.h @@ -51,7 +51,7 @@ void e_cursors_shutdown (void); #define e_cursor_set(win, c) \ G_STMT_START { \ - if (win) \ + if (win) \ gdk_window_set_cursor (win, e_cursor_get (c)); \ } G_STMT_END diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index e8034eb487..b9ae1ad901 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -1247,7 +1247,7 @@ position_date_popup (EDateEdit *dedit) x += win_x; y += win_y; - screen_width = gdk_screen_width (); + screen_width = gdk_screen_width (); screen_height = gdk_screen_height (); x = CLAMP (x, 0, MAX (0, screen_width - cal_req.width)); @@ -1326,7 +1326,7 @@ on_date_popup_key_press (GtkWidget *widget, EDateEdit *dedit) { if (event->keyval != GDK_Escape) { - gdk_keyboard_grab (dedit->priv->cal_popup->window, TRUE, GDK_CURRENT_TIME); + gdk_keyboard_grab (dedit->priv->cal_popup->window, TRUE, GDK_CURRENT_TIME); return FALSE; } diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 77c20d506b..1bc183dbe5 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -875,7 +875,7 @@ e_filter_bar_lite_new (RuleContext *context, bar = g_object_new (e_filter_bar_get_type (), NULL); ((ESearchBar *)bar)->lite = TRUE; - e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar); + e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar); return bar; } @@ -901,7 +901,7 @@ e_filter_bar_new_construct (RuleContext *context, bar->all_account_search_vf = NULL; bar->account_search_vf = NULL; - bar->account_search_cancel = NULL; + bar->account_search_cancel = NULL; g_signal_connect (context, "changed", G_CALLBACK (context_changed), bar); g_signal_connect (context, "rule_removed", G_CALLBACK (context_rule_removed), bar); diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index 859a21b6c9..30c3ac5585 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -140,7 +140,7 @@ EFilterBar *e_filter_bar_lite_new (RuleContext *context, gpointer data); void -e_filter_bar_new_construct (RuleContext *context, +e_filter_bar_new_construct (RuleContext *context, const gchar *systemrules, const gchar *userrules, EFilterBarConfigRule config, diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c index fb11c98323..6da15943e4 100644 --- a/widgets/misc/e-icon-entry.c +++ b/widgets/misc/e-icon-entry.c @@ -99,8 +99,8 @@ icon_entry_create_proxy (GtkAction *action) } static gboolean icon_entry_focus_change_cb (GtkWidget *widget, - GdkEventFocus *event, - GtkWidget *entry) + GdkEventFocus *event, + GtkWidget *entry) { gtk_widget_queue_draw (entry); diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h index a3972bd26d..be2d427291 100644 --- a/widgets/misc/e-image-chooser.h +++ b/widgets/misc/e-image-chooser.h @@ -28,10 +28,10 @@ G_BEGIN_DECLS -#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ()) -#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser)) +#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ()) +#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser)) #define E_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) -#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER)) +#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER)) #define E_IS_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_IMAGE_CHOOSER)) typedef struct _EImageChooser EImageChooser; diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index c44e75886b..f35335f37d 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -345,7 +345,7 @@ e_map_unrealize (GtkWidget *widget) g_return_if_fail (IS_E_MAP (widget)); if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } @@ -882,7 +882,7 @@ e_map_point_is_in_view (EMap *map, EMapPoint *point) if (x >= 0 && x < GTK_WIDGET (map)->allocation.width && y >= 0 && y < GTK_WIDGET (map)->allocation.height) - return TRUE; + return TRUE; return FALSE; } @@ -1011,8 +1011,8 @@ update_render_pixbuf (EMap *map, GdkInterpType interp, gboolean render_overlays) if (width > 1 && height > 1) { gdk_pixbuf_scale (priv->map_pixbuf, priv->map_render_pixbuf, 0, 0, /* Dest (x, y) */ - width, height, 0, 0, /* Offset (x, y) */ - zoom, zoom, /* Scale (x, y) */ + width, height, 0, 0, /* Offset (x, y) */ + zoom, zoom, /* Scale (x, y) */ interp); } diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 849825e160..83f4fda189 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -610,13 +610,13 @@ search_bar_dispose (GObject *object) /* static gpointer / /* option_item_destroy_cb (GtkObject *object, gpointer data) */ /* { */ -/* /\* ESearchBarSubitem *subitems; *\/ */ +/* /\* ESearchBarSubitem *subitems; *\/ */ -/* /\* subitems = data; *\/ */ +/* /\* subitems = data; *\/ */ -/* /\* g_assert (subitems != NULL); *\/ */ -/* /\* free_subitems (subitems); *\/ */ -/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */ +/* /\* g_assert (subitems != NULL); *\/ */ +/* /\* free_subitems (subitems); *\/ */ +/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */ /* } */ static void @@ -939,10 +939,10 @@ e_search_bar_get_type (void) bonobo_object_unref (BONOBO_OBJECT (esb->ui_component)); esb->ui_component = NULL; } -/* if (esb->entry) { */ -/* g_object_unref (esb->entry); */ -/* esb->entry = NULL; */ -/* } */ +/* if (esb->entry) { */ +/* g_object_unref (esb->entry); */ +/* esb->entry = NULL; */ +/* } */ if (esb->suboption) { g_object_unref (esb->suboption); esb->suboption = NULL; @@ -1066,7 +1066,7 @@ e_search_bar_set_context (ESearchBar *search_bar, gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0); search_bar->scopeoption = gtk_option_menu_new (); - /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ + /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0); gtk_widget_show_all (search_bar->scopeoption_box); gtk_widget_hide (hbox); diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index b42630ebae..fa84e86cc8 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -397,7 +397,7 @@ init_widgets (ESendOptionsDialog *sod) g_signal_connect (priv->delay_until, "changed", G_CALLBACK (delay_until_date_changed_cb), sod); if (priv->global) - g_signal_connect (priv->notebook, "switch-page", G_CALLBACK (page_changed_cb), sod); + g_signal_connect (priv->notebook, "switch-page", G_CALLBACK (page_changed_cb), sod); } @@ -502,7 +502,7 @@ setup_widgets (ESendOptionsDialog *sod, Item_type type) gtk_label_set_mnemonic_widget (GTK_LABEL (priv->until_label), priv->delay_until); if (priv->global) { - GtkWidget *widget = gtk_label_new ("Calendar"); + GtkWidget *widget = gtk_label_new ("Calendar"); gtk_label_set_text (GTK_LABEL (priv->sopts_label), "Mail"); gtk_notebook_append_page (priv->notebook, priv->status, widget); gtk_widget_show (widget); @@ -514,7 +514,7 @@ setup_widgets (ESendOptionsDialog *sod, Item_type type) switch (type) { case E_ITEM_MAIL: - priv->help_section = g_strdup ("usage-mail"); + priv->help_section = g_strdup ("usage-mail"); gtk_widget_hide (priv->accepted_label); gtk_widget_hide (priv->when_accepted); gtk_widget_hide (priv->completed_label); @@ -522,11 +522,11 @@ setup_widgets (ESendOptionsDialog *sod, Item_type type) gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->declined_label), (_("When de_leted:"))); break; case E_ITEM_CALENDAR: - priv->help_section = g_strdup ("usage-calendar"); + priv->help_section = g_strdup ("usage-calendar"); gtk_widget_hide (priv->completed_label); gtk_widget_hide (priv->when_completed); case E_ITEM_TASK: - priv->help_section = g_strdup ("usage-calendar-todo"); + priv->help_section = g_strdup ("usage-calendar-todo"); gtk_widget_hide (priv->security_label); gtk_widget_hide (priv->security); gtk_widget_set_sensitive (priv->autodelete, FALSE); @@ -606,7 +606,7 @@ static void e_send_options_cb (GtkDialog *dialog, gint state, gpointer func_data e_display_help ( GTK_WINDOW (priv->main), priv->help_section); - break; + break; } g_signal_emit (G_OBJECT (func_data), signals[SOD_RESPONSE], 0, state); @@ -821,7 +821,7 @@ GType e_sendoptions_dialog_get_type (void) sizeof (ESendOptionsDialog), 0, /* n_preallocs */ (GInstanceInitFunc) e_sendoptions_dialog_init, - NULL /* instance_init */ + NULL /* instance_init */ }; type = g_type_register_static (G_TYPE_OBJECT, "ESendOptionsDialogType", diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index 87e53dce8f..78303cc9ec 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -66,7 +66,7 @@ struct _ESpinnerClass #define E_TYPE_SPINNER_CACHE (e_spinner_cache_get_type()) #define E_SPINNER_CACHE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), E_TYPE_SPINNER_CACHE, ESpinnerCache)) -#define E_SPINNER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), E_TYPE_SPINNER_CACHE, ESpinnerCacheClass)) +#define E_SPINNER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), E_TYPE_SPINNER_CACHE, ESpinnerCacheClass)) #define E_IS_SPINNER_CACHE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), E_TYPE_SPINNER_CACHE)) #define E_IS_SPINNER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), E_TYPE_SPINNER_CACHE)) #define E_SPINNER_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), E_TYPE_SPINNER_CACHE, ESpinnerCacheClass)) @@ -275,7 +275,7 @@ e_spinner_images_load (GdkScreen *screen, /* Load the animation. The 'rest icon' is the 0th frame */ icon_info = gtk_icon_theme_lookup_icon (icon_theme, SPINNER_ICON_NAME, - requested_size, 0); + requested_size, 0); if (icon_info == NULL) { g_warning ("Throbber animation not found"); @@ -741,10 +741,10 @@ e_spinner_start (ESpinner *spinner) details->timer_task = g_timeout_add_full (G_PRIORITY_LOW, - details->timeout, - (GSourceFunc) bump_spinner_frame_cb, - spinner, - NULL); + details->timeout, + (GSourceFunc) bump_spinner_frame_cb, + spinner, + NULL); } } @@ -843,7 +843,7 @@ e_spinner_size_request (GtkWidget *widget, gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget), details->size, &requisition->width, - &requisition->height); + &requisition->height); return; } -- cgit v1.2.3 From 878989677a3c8d0a4e3b7c26757a2c6be6ea0d3d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 28 May 2009 14:21:47 -0400 Subject: =?UTF-8?q?Bug=20583991=20=E2=80=93=20"Suggest=20automatic=20displ?= =?UTF-8?q?ay=20of=20attachment"=20does=20not=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment-store.c | 1 + 1 file changed, 1 insertion(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 2977be9593..baa1ef6c7f 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -569,6 +569,7 @@ e_attachment_store_run_load_dialog (EAttachmentStore *store, attachment = e_attachment_new (); e_attachment_set_file (attachment, file); + e_attachment_set_disposition (attachment, disposition); e_attachment_store_add_attachment (store, attachment); e_attachment_load_async ( attachment, (GAsyncReadyCallback) -- cgit v1.2.3 From e6c6cbdfb5fd5723ff840b24b29690235be0d74d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 1 Jun 2009 22:50:46 -0400 Subject: Fix more compiler warnings. --- widgets/misc/e-search-bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 83f4fda189..dcab44ac4b 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -607,7 +607,7 @@ search_bar_dispose (GObject *object) /* /\* Callback used when an option item is destroyed. We have to destroy its */ /* * suboption items. */ /* *\/ */ -/* static gpointer / +/* static gpointer */ /* option_item_destroy_cb (GtkObject *object, gpointer data) */ /* { */ /* /\* ESearchBarSubitem *subitems; *\/ */ -- cgit v1.2.3 From 433eac7844481b8ceda0bae8bf08f6bb623185b0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 1 Jun 2009 19:09:19 -0400 Subject: More code cleanup. --- widgets/misc/e-calendar-item.c | 76 +++++++++++++++++----------------- widgets/misc/e-canvas-vbox.c | 2 +- widgets/misc/e-canvas.c | 8 ++-- widgets/misc/e-dateedit.c | 6 +-- widgets/misc/e-filter-bar.c | 2 +- widgets/misc/e-image-chooser.c | 10 ++--- widgets/misc/e-map.c | 6 +-- widgets/misc/e-map.h | 2 +- widgets/misc/e-selection-model-array.c | 44 ++++++++++---------- widgets/misc/e-spinner.c | 4 +- widgets/misc/test-preferences-window.c | 2 +- 11 files changed, 81 insertions(+), 81 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index c1d599e879..9c9bd94b15 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -60,37 +60,37 @@ static void e_calendar_item_unmap (GnomeCanvasItem *item); static void e_calendar_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, - int flags); + gint flags); static void e_calendar_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, - int y, - int width, - int height); + gint x, + gint y, + gint width, + gint height); static void e_calendar_item_draw_month (ECalendarItem *calitem, GdkDrawable *drawable, - int x, - int y, - int width, - int height, - int row, - int col); + gint x, + gint y, + gint width, + gint height, + gint row, + gint col); static void e_calendar_item_draw_day_numbers (ECalendarItem *calitem, GdkDrawable *drawable, - int width, - int height, - int row, - int col, - int year, - int month, - int start_weekday, + gint width, + gint height, + gint row, + gint col, + gint year, + gint month, + gint start_weekday, gint cells_x, gint cells_y); static double e_calendar_item_point (GnomeCanvasItem *item, double x, double y, - int cx, - int cy, + gint cx, + gint cy, GnomeCanvasItem **actual_item); static void e_calendar_item_stop_selecting (ECalendarItem *calitem, guint32 time); @@ -891,7 +891,7 @@ static void e_calendar_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, - int flags) + gint flags) { ECalendarItem *calitem; GtkStyle *style; @@ -1024,10 +1024,10 @@ e_calendar_item_update (GnomeCanvasItem *item, static void e_calendar_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, - int x, - int y, - int width, - int height) + gint x, + gint y, + gint width, + gint height) { ECalendarItem *calitem; GtkStyle *style; @@ -1151,12 +1151,12 @@ layout_set_day_text (ECalendarItem *calitem, PangoLayout *layout, gint day_index static void e_calendar_item_draw_month (ECalendarItem *calitem, GdkDrawable *drawable, - int x, - int y, - int width, - int height, - int row, - int col) + gint x, + gint y, + gint width, + gint height, + gint row, + gint col) { GnomeCanvasItem *item; GtkWidget *widget; @@ -1395,13 +1395,13 @@ get_digit_fomat () static void e_calendar_item_draw_day_numbers (ECalendarItem *calitem, GdkDrawable *drawable, - int width, - int height, - int row, - int col, - int year, - int month, - int start_weekday, + gint width, + gint height, + gint row, + gint col, + gint year, + gint month, + gint start_weekday, gint cells_x, gint cells_y) { diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index 1eb0ddec12..bb0bd775e9 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -330,7 +330,7 @@ e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags ) max_width = item_width; list = g_list_next(list); - for( ; list; list = g_list_next(list)) { + for(; list; list = g_list_next(list)) { running_height += e_canvas_vbox->spacing; g_object_get (list->data, diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 39b89d2675..53e3eafeec 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -147,7 +147,7 @@ e_canvas_new (void) /* Emits an event for an item in the canvas, be it the current item, grabbed * item, or focused item, as appropriate. */ -static int +static gint emit_event (GnomeCanvas *canvas, GdkEvent *event) { GdkEvent *ev; @@ -316,7 +316,7 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, gint */ #define DISPLAY_X1(canvas) (GNOME_CANVAS (canvas)->layout.xoffset) #define DISPLAY_Y1(canvas) (GNOME_CANVAS (canvas)->layout.yoffset) -static int +static gint pick_current_item (GnomeCanvas *canvas, GdkEvent *event) { gint button_down; @@ -392,8 +392,8 @@ pick_current_item (GnomeCanvas *canvas, GdkEvent *event) /* canvas pixel coords */ - cx = (int) (x + 0.5); - cy = (int) (y + 0.5); + cx = (gint) (x + 0.5); + cy = (gint) (y + 0.5); /* world coords */ diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index b9ae1ad901..84b016934e 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -153,9 +153,9 @@ static void on_date_popup_date_selected (ECalendarItem *calitem, EDateEdit *dedit); static void hide_date_popup (EDateEdit *dedit); static void rebuild_time_popup (EDateEdit *dedit); -static gboolean field_set_to_none (const char *text); +static gboolean field_set_to_none (const gchar *text); static gboolean e_date_edit_parse_date (EDateEdit *dedit, - const char *date_text, + const gchar *date_text, struct tm *date_tm); static gboolean e_date_edit_parse_time (EDateEdit *dedit, const gchar *time_text, @@ -1504,7 +1504,7 @@ field_set_to_none (const gchar *text) gint n; pos = text; - while (n = (int)((unsigned char)*pos), isspace (n)) + while (n = (gint)((guchar)*pos), isspace (n)) pos++; none_string = _("None"); diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 1bc183dbe5..4463fd12d8 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -551,7 +551,7 @@ filter_bar_get_property (GObject *object, } } -static int +static gint xml_get_prop_int (xmlNodePtr node, const gchar *prop) { gchar *buf; diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index e11439eb26..3c83cb1048 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -241,7 +241,7 @@ set_image_from_data (EImageChooser *chooser, GdkPixbuf *scaled; GdkPixbuf *composite; - float scale; + gfloat scale; gint new_height, new_width; new_height = gdk_pixbuf_get_height (pixbuf); @@ -259,17 +259,17 @@ set_image_from_data (EImageChooser *chooser, /* we need to scale down */ printf ("we need to scale down\n"); if (new_height > new_width) - scale = (float)chooser->priv->image_height / new_height; + scale = (gfloat)chooser->priv->image_height / new_height; else - scale = (float)chooser->priv->image_width / new_width; + scale = (gfloat)chooser->priv->image_width / new_width; } else { /* we need to scale up */ printf ("we need to scale up\n"); if (new_height > new_width) - scale = (float)new_height / chooser->priv->image_height; + scale = (gfloat)new_height / chooser->priv->image_height; else - scale = (float)new_width / chooser->priv->image_width; + scale = (gfloat)new_width / chooser->priv->image_width; } printf ("scale = %g\n", scale); diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index f35335f37d..82ce1c17aa 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -689,7 +689,7 @@ e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, /* --- Zoom --- */ -double +gdouble e_map_get_magnification (EMap *map) { EMapPrivate *priv; @@ -1153,8 +1153,8 @@ repaint_point (EMap *map, EMapPoint *point) e_map_world_to_window (map, point->longitude, point->latitude, &px, &py); - area.x = (int) px - 2; - area.y = (int) py - 2; + area.x = (gint) px - 2; + area.y = (gint) py - 2; area.width = 5; area.height = 5; request_paint_area (map, &area); diff --git a/widgets/misc/e-map.h b/widgets/misc/e-map.h index 0c915fb5fa..df3f70a343 100644 --- a/widgets/misc/e-map.h +++ b/widgets/misc/e-map.h @@ -96,7 +96,7 @@ void e_map_world_to_window (EMap *map, /* --- Zoom --- */ -double e_map_get_magnification (EMap *map); +gdouble e_map_get_magnification (EMap *map); /* Pass TRUE if we want the smooth zoom hack */ void e_map_set_smooth_zoom (EMap *map, gboolean state); diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index dde69a7e06..90922b5560 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -357,7 +357,7 @@ esma_invert_selection (ESelectionModel *selection) e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), -1, -1); } -static int +static gint esma_row_count (ESelectionModel *selection) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); @@ -405,14 +405,14 @@ esma_change_range(ESelectionModel *selection, gint start, gint end, gboolean gro } } -static int +static gint esma_cursor_row (ESelectionModel *selection) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); return esma->cursor_row; } -static int +static gint esma_cursor_col (ESelectionModel *selection) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); @@ -569,25 +569,25 @@ e_selection_model_array_class_init (ESelectionModelArrayClass *klass) object_class->get_property = esma_get_property; object_class->set_property = esma_set_property; - esm_class->is_row_selected = esma_is_row_selected ; - esm_class->foreach = esma_foreach ; - esm_class->clear = esma_clear ; - esm_class->selected_count = esma_selected_count ; - esm_class->select_all = esma_select_all ; - esm_class->invert_selection = esma_invert_selection ; - esm_class->row_count = esma_row_count ; - - esm_class->change_one_row = esma_change_one_row ; - esm_class->change_cursor = esma_change_cursor ; - esm_class->cursor_row = esma_cursor_row ; - esm_class->cursor_col = esma_cursor_col ; - - esm_class->select_single_row = esma_select_single_row ; - esm_class->toggle_single_row = esma_toggle_single_row ; - esm_class->move_selection_end = esma_move_selection_end ; - esm_class->set_selection_end = esma_set_selection_end ; - - klass->get_row_count = NULL ; + esm_class->is_row_selected = esma_is_row_selected; + esm_class->foreach = esma_foreach; + esm_class->clear = esma_clear; + esm_class->selected_count = esma_selected_count; + esm_class->select_all = esma_select_all; + esm_class->invert_selection = esma_invert_selection; + esm_class->row_count = esma_row_count; + + esm_class->change_one_row = esma_change_one_row; + esm_class->change_cursor = esma_change_cursor; + esm_class->cursor_row = esma_cursor_row; + esm_class->cursor_col = esma_cursor_col; + + esm_class->select_single_row = esma_select_single_row; + esm_class->toggle_single_row = esma_toggle_single_row; + esm_class->move_selection_end = esma_move_selection_end; + esm_class->set_selection_end = esma_set_selection_end; + + klass->get_row_count = NULL; g_object_class_install_property (object_class, PROP_CURSOR_ROW, g_param_spec_int ("cursor_row", diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index 78303cc9ec..bf71e4e50c 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -315,7 +315,7 @@ e_spinner_images_load (GdkScreen *screen, n = 0; for (y = 0; y < grid_height; y += size) { - for (x = 0; x < grid_width ; x += size) + for (x = 0; x < grid_width; x += size) { pixbuf = extract_frame (icon_pixbuf, x, y, size); @@ -633,7 +633,7 @@ e_spinner_init (ESpinner *spinner) details->need_load = TRUE; } -static int +static gint e_spinner_expose (GtkWidget *widget, GdkEventExpose *event) { diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c index 4e4d9894fa..c5291cf755 100644 --- a/widgets/misc/test-preferences-window.c +++ b/widgets/misc/test-preferences-window.c @@ -50,7 +50,7 @@ add_pages (EPreferencesWindow *preferences_window) } } -static int +static gint delete_event_callback (GtkWidget *widget, GdkEventAny *event, gpointer data) -- cgit v1.2.3 From abf31aee9f84cc700f9947425bf575165d96c77b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 14 May 2009 13:39:23 -0400 Subject: =?UTF-8?q?Bug=20581280=20=E2=80=93=20Wrong=20attachment=20name=20?= =?UTF-8?q?in=20event?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment-store.c | 327 +++++++++++++++++++++++++++++++++++++- widgets/misc/e-attachment-store.h | 7 + 2 files changed, 333 insertions(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index baa1ef6c7f..c99bdeab3f 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -854,7 +854,7 @@ e_attachment_store_get_uris_async (EAttachmentStore *store, path = e_mkdtemp (template); g_free (template); - /* XXX Let's hope errno got set property. */ + /* XXX Let's hope errno got set properly. */ if (path == NULL) { GSimpleAsyncResult *simple; @@ -903,3 +903,328 @@ e_attachment_store_get_uris_finish (EAttachmentStore *store, return uris; } + +/********************** e_attachment_store_save_async() **********************/ + +typedef struct _SaveContext SaveContext; + +struct _SaveContext { + GSimpleAsyncResult *simple; + GFile *destination; + GFile *fresh_directory; + GFile *trash_directory; + GList *attachment_list; + GError *error; + gchar **uris; + gint index; +}; + +static SaveContext * +attachment_store_save_context_new (EAttachmentStore *store, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + GSimpleAsyncResult *simple; + GList *attachment_list; + guint length; + gchar **uris; + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, user_data, + e_attachment_store_save_async); + + attachment_list = e_attachment_store_get_attachments (store); + + /* Add one for NULL terminator. */ + length = g_list_length (attachment_list) + 1; + uris = g_malloc0 (sizeof (gchar *) * length); + + save_context = g_slice_new0 (SaveContext); + save_context->simple = simple; + save_context->destination = g_object_ref (destination); + save_context->attachment_list = attachment_list; + save_context->uris = uris; + + return save_context; +} + +static void +attachment_store_save_context_free (SaveContext *save_context) +{ + /* Do not free the GSimpleAsyncResult. */ + + /* The attachment list should be empty now. */ + g_warn_if_fail (save_context->attachment_list == NULL); + + /* So should the error. */ + g_warn_if_fail (save_context->error == NULL); + + if (save_context->destination) { + g_object_unref (save_context->destination); + save_context->destination = NULL; + } + + if (save_context->fresh_directory) { + g_object_unref (save_context->fresh_directory); + save_context->fresh_directory = NULL; + } + + if (save_context->trash_directory) { + g_object_unref (save_context->trash_directory); + save_context->trash_directory = NULL; + } + + g_strfreev (save_context->uris); + + g_slice_free (SaveContext, save_context); +} + +static void +attachment_store_save_cb (EAttachment *attachment, + GAsyncResult *result, + SaveContext *save_context) +{ + GSimpleAsyncResult *simple; + GFile *file; + gchar **uris; + gchar *template; + gchar *path; + GError *error = NULL; + + file = e_attachment_save_finish (attachment, result, &error); + + /* Remove the attachment from the list. */ + save_context->attachment_list = g_list_remove ( + save_context->attachment_list, attachment); + g_object_unref (attachment); + + if (file != NULL) { + /* Assemble the file's final URI from its basename. */ + gchar *basename; + gchar *uri; + + basename = g_file_get_basename (file); + g_object_unref (file); + + file = save_context->destination; + file = g_file_get_child (file, basename); + uri = g_file_get_uri (file); + g_object_unref (file); + + save_context->uris[save_context->index++] = uri; + + } else if (error != NULL) { + /* If this is the first error, cancel the other jobs. */ + if (save_context->error == NULL) { + g_propagate_error (&save_context->error, error); + g_list_foreach ( + save_context->attachment_list, + (GFunc) e_attachment_cancel, NULL); + error = NULL; + + /* Otherwise, we can only report back one error. So if + * this is something other than cancellation, dump it to + * the terminal. */ + } else if (!g_error_matches ( + error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s", error->message); + } + + if (error != NULL) + g_error_free (error); + + /* If there's still jobs running, let them finish. */ + if (save_context->attachment_list != NULL) + return; + + /* If an error occurred while saving, we're done. */ + if (save_context->error != NULL) { + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* And the error. */ + error = save_context->error; + save_context->error = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + attachment_store_save_context_free (save_context); + g_error_free (error); + return; + } + + /* Attachments are all saved to a temporary directory. + * Now we need to move the existing destination directory + * out of the way (if it exists). Instead of testing for + * existence we'll just attempt the move and ignore any + * G_IO_ERROR_NOT_FOUND errors. */ + + /* First, however, we need another temporary directory to + * move the existing destination directory to. Note we're + * not actually creating the directory yet, just picking a + * name for it. The usual raciness with this approach + * applies here (read up on mktemp(3)), but worst case is + * we get a spurious G_IO_ERROR_WOULD_MERGE error and the + * user has to try saving attachments again. */ + template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); + path = e_mktemp (template); + g_free (template); + + save_context->trash_directory = g_file_new_for_path (path); + g_free (path); + + /* XXX No asynchronous move operation in GIO? */ + g_file_move ( + save_context->destination, + save_context->trash_directory, + G_FILE_COPY_NONE, NULL, NULL, NULL, &error); + + if (error != NULL && !g_error_matches ( + error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + attachment_store_save_context_free (save_context); + g_error_free (error); + return; + } + + g_clear_error (&error); + + /* Now we can move the first temporary directory containing + * the newly saved files to the user-specified destination. */ + g_file_move ( + save_context->fresh_directory, + save_context->destination, + G_FILE_COPY_NONE, NULL, NULL, NULL, &error); + + if (error != NULL) { + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + g_simple_async_result_set_from_error (simple, error); + g_simple_async_result_complete (simple); + attachment_store_save_context_free (save_context); + g_error_free (error); + return; + } + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* And the URI list. */ + uris = save_context->uris; + save_context->uris = NULL; + + g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); + g_simple_async_result_complete (simple); + + attachment_store_save_context_free (save_context); +} + +void +e_attachment_store_save_async (EAttachmentStore *store, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + GList *attachment_list, *iter; + GFile *temp_directory; + gchar *template; + gchar *path; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (callback != NULL); + + save_context = attachment_store_save_context_new ( + store, destination, callback, user_data); + + attachment_list = save_context->attachment_list; + + /* Deal with an empty attachment store. The caller will get + * an empty NULL-terminated list as opposed to NULL, to help + * distinguish it from an error. */ + if (attachment_list == NULL) { + GSimpleAsyncResult *simple; + gchar **uris; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* And the URI list. */ + uris = save_context->uris; + save_context->uris = NULL; + + g_simple_async_result_set_op_res_gpointer (simple, uris, NULL); + g_simple_async_result_complete_in_idle (simple); + attachment_store_save_context_free (save_context); + return; + } + + /* Save all attachments to a temporary directory, which we'll + * then move to its proper location. We use a directory so + * files can retain their basenames. + * XXX This could trigger a blocking temp directory cleanup. */ + template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); + path = e_mkdtemp (template); + g_free (template); + + /* XXX Let's hope errno got set properly. */ + if (path == NULL) { + GSimpleAsyncResult *simple; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + g_simple_async_result_set_error ( + simple, G_FILE_ERROR, + g_file_error_from_errno (errno), + "%s", g_strerror (errno)); + + g_simple_async_result_complete_in_idle (simple); + attachment_store_save_context_free (save_context); + return; + } + + temp_directory = g_file_new_for_path (path); + save_context->fresh_directory = temp_directory; + g_free (path); + + for (iter = attachment_list; iter != NULL; iter = iter->next) + e_attachment_save_async ( + E_ATTACHMENT (iter->data), + temp_directory, (GAsyncReadyCallback) + attachment_store_save_cb, save_context); +} + +gchar ** +e_attachment_store_save_finish (EAttachmentStore *store, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gchar **uris; + + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + uris = g_simple_async_result_get_op_res_gpointer (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); + + return uris; +} diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h index 46ca9e4aa6..1c3cb52731 100644 --- a/widgets/misc/e-attachment-store.h +++ b/widgets/misc/e-attachment-store.h @@ -118,6 +118,13 @@ gchar ** e_attachment_store_get_uris_finish (EAttachmentStore *store, GAsyncResult *result, GError **error); +void e_attachment_store_save_async (EAttachmentStore *store, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data); +gchar ** e_attachment_store_save_finish (EAttachmentStore *store, + GAsyncResult *result, + GError **error); G_END_DECLS -- cgit v1.2.3 From 7a4f610ca3b6410b1ed2d5e93fa7e6e2d32dd63a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 4 Jun 2009 10:55:12 -0400 Subject: Use GtkEntry instead of EIconEntry in the main search bar. --- widgets/misc/Makefile.am | 2 - widgets/misc/e-icon-entry.c | 543 -------------------------------------------- widgets/misc/e-icon-entry.h | 91 -------- 3 files changed, 636 deletions(-) delete mode 100644 widgets/misc/e-icon-entry.c delete mode 100644 widgets/misc/e-icon-entry.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index d6a42f10c2..56a927041e 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -61,7 +61,6 @@ widgetsinclude_HEADERS = \ e-file-activity.h \ e-gui-utils.h \ e-hsv-utils.h \ - e-icon-entry.h \ e-image-chooser.h \ e-map.h \ e-menu-tool-button.h \ @@ -124,7 +123,6 @@ libemiscwidgets_la_SOURCES = \ e-file-activity.c \ e-gui-utils.c \ e-hsv-utils.c \ - e-icon-entry.c \ e-image-chooser.c \ e-map.c \ e-menu-tool-button.c \ diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c deleted file mode 100644 index 6da15943e4..0000000000 --- a/widgets/misc/e-icon-entry.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * e-icon-entry.c - * - * Author: Johnny Jacob - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Copyright (C) 2003, 2004, 2005 Christian Persch - * - * This library 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) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Adapted and modified from gtk+ code: - * - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * Modified by the GTK+ Team and others 1997-2005. See the AUTHORS - * file in the gtk+ distribution for a list of people on the GTK+ Team. - * See the ChangeLog in the gtk+ distribution files for a list of changes. - * These files are distributed with GTK+ at ftp://ftp.gtk.org/pub/gtk/. - * - */ - -#include "e-icon-entry.h" - -#define E_ICON_ENTRY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_ICON_ENTRY, EIconEntryPrivate)) - -struct _EIconEntryPrivate { - GtkStateType visual_state; - GtkWidget *entry; - GtkWidget *hbox; -}; - -enum { - PROP_0, - PROP_VISUAL_STATE -}; - -static gpointer parent_class; - -static void -icon_entry_proxy_set_cursor (GtkWidget *widget, - GdkEventCrossing *event) -{ - if (event->type == GDK_ENTER_NOTIFY) { - GdkCursor *cursor; - - cursor = gdk_cursor_new (GDK_HAND1); - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_unref (cursor); - } else - gdk_window_set_cursor (widget->window, NULL); -} - -static GtkWidget * -icon_entry_create_proxy (GtkAction *action) -{ - GtkWidget *proxy; - GtkWidget *widget; - gchar *tooltip; - - proxy = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (proxy), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (proxy), 2); - gtk_widget_show (proxy); - - widget = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (proxy), widget); - gtk_widget_show (widget); - - g_object_get (action, "tooltip", &tooltip, NULL); - gtk_widget_set_tooltip_text (proxy, tooltip); - g_free (tooltip); - - g_signal_connect_swapped ( - proxy, "button-press-event", - G_CALLBACK (gtk_action_activate), action); - g_signal_connect_after ( - proxy, "enter-notify-event", - G_CALLBACK (icon_entry_proxy_set_cursor), NULL); - g_signal_connect_after ( - proxy, "leave-notify-event", - G_CALLBACK (icon_entry_proxy_set_cursor), NULL); - - return proxy; -} -static gboolean -icon_entry_focus_change_cb (GtkWidget *widget, - GdkEventFocus *event, - GtkWidget *entry) -{ - gtk_widget_queue_draw (entry); - - return FALSE; -} - -static void -icon_entry_get_borders (GtkWidget *widget, - GtkWidget *entry, - gint *xborder, - gint *yborder) -{ - gint focus_width; - gboolean interior_focus; - - g_return_if_fail (entry->style != NULL); - - gtk_widget_style_get ( - entry, "focus-line-width", &focus_width, - "interior-focus", &interior_focus, NULL); - - *xborder = entry->style->xthickness; - *yborder = entry->style->ythickness; - - if (!interior_focus) { - *xborder += focus_width; - *yborder += focus_width; - } -} - -static void -icon_entry_paint (GtkWidget *widget, - GdkEventExpose *event) -{ - EIconEntry *entry = E_ICON_ENTRY (widget); - GtkWidget *entry_widget = entry->priv->entry; - gint x = 0, y = 0, width, height, focus_width; - gboolean interior_focus; - - gtk_widget_style_get ( - entry_widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, NULL); - - gdk_drawable_get_size (widget->window, &width, &height); - - if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) { - x += focus_width; - y += focus_width; - width -= 2 * focus_width; - height -= 2 * focus_width; - } - - gtk_paint_flat_box ( - entry_widget->style, widget->window, - GTK_WIDGET_STATE (entry_widget), GTK_SHADOW_NONE, - NULL, entry_widget, "entry_bg", - /* FIXME: was 0, 0 in gtk_entry_expose, but I think this is correct: */ - x, y, width, height); - - gtk_paint_shadow ( - entry_widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - NULL, entry_widget, "entry", - x, y, width, height); - - if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus) { - x -= focus_width; - y -= focus_width; - width += 2 * focus_width; - height += 2 * focus_width; - - gtk_paint_focus ( - entry_widget->style, widget->window, - GTK_WIDGET_STATE (entry_widget), - NULL, entry_widget, "entry", - /* FIXME: was 0, 0 in gtk_entry_draw_frame, but I think this is correct: */ - x, y, width, height); - } -} - -static void -icon_entry_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_VISUAL_STATE: - e_icon_entry_set_visual_state ( - E_ICON_ENTRY (object), - g_value_get_enum (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -icon_entry_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_VISUAL_STATE: - g_value_set_enum ( - value, e_icon_entry_get_visual_state ( - E_ICON_ENTRY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -icon_entry_dispose (GObject *object) -{ - EIconEntryPrivate *priv; - - priv = E_ICON_ENTRY_GET_PRIVATE (object); - - if (priv->entry != NULL) { - g_object_unref (priv->entry); - priv->entry = NULL; - } - - if (priv->hbox != NULL) { - g_object_unref (priv->hbox); - priv->hbox = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -icon_entry_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - gint attributes_mask; - gint border_width; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - border_width = GTK_CONTAINER (widget)->border_width; - - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = widget->allocation.height - 2 * border_width; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.event_mask = gtk_widget_get_events (widget) - | GDK_EXPOSURE_MASK; - - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.wclass = GDK_INPUT_OUTPUT; - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - widget->window = gdk_window_new ( - gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - - gtk_style_set_background ( - widget->style, widget->window, GTK_STATE_NORMAL); -} - -static void -icon_entry_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EIconEntryPrivate *priv; - GtkContainer *container; - GtkWidget *child; - gint xborder, yborder; - - priv = E_ICON_ENTRY_GET_PRIVATE (widget); - container = GTK_CONTAINER (widget); - - requisition->width = container->border_width * 2; - requisition->height = container->border_width * 2; - - gtk_widget_ensure_style (priv->entry); - icon_entry_get_borders (widget, priv->entry, &xborder, &yborder); - - child = GTK_BIN (widget)->child; - if (GTK_WIDGET_VISIBLE (child)) { - GtkRequisition child_requisition; - - gtk_widget_size_request (child, &child_requisition); - requisition->width += child_requisition.width; - requisition->height += child_requisition.height; - } - - requisition->width += 2 * xborder; - requisition->height += 2 * yborder; -} - -static void -icon_entry_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EIconEntryPrivate *priv; - GtkContainer *container; - GtkAllocation child_allocation; - gint xborder, yborder; - gint width, height; - - priv = E_ICON_ENTRY_GET_PRIVATE (widget); - container = GTK_CONTAINER (widget); - - widget->allocation = *allocation; - - icon_entry_get_borders (widget, priv->entry, &xborder, &yborder); - - if (GTK_WIDGET_REALIZED (widget)) { - width = allocation->width - container->border_width * 2; - height = allocation->height - container->border_width * 2; - - child_allocation.x = container->border_width; - child_allocation.y = container->border_width; - child_allocation.width = MAX (width, 0); - child_allocation.height = MAX (height, 0); - - gdk_window_move_resize ( - widget->window, - allocation->x + child_allocation.x, - allocation->y + child_allocation.y, - child_allocation.width, - child_allocation.height); - } - - width = allocation->width - (container->border_width + xborder) * 2; - height = allocation->height - (container->border_width + yborder) * 2; - - child_allocation.x = container->border_width + xborder; - child_allocation.y = container->border_width + yborder; - child_allocation.width = MAX (width, 0); - child_allocation.height = MAX (height, 0); - - gtk_widget_size_allocate (GTK_BIN (widget)->child, &child_allocation); -} - -static gboolean -icon_entry_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - if (GTK_WIDGET_DRAWABLE (widget) && event->window == widget->window) - icon_entry_paint (widget, event); - - /* Chain up to parent's expose() method. */ - return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); -} - -static void -icon_entry_class_init (EIconEntryClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EIconEntryPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = icon_entry_set_property; - object_class->get_property = icon_entry_get_property; - object_class->dispose = icon_entry_dispose; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = icon_entry_realize; - widget_class->size_request = icon_entry_size_request; - widget_class->size_allocate = icon_entry_size_allocate; - widget_class->expose_event = icon_entry_expose; - - g_object_class_install_property ( - object_class, - PROP_VISUAL_STATE, - g_param_spec_enum ( - "visual-state", - NULL, - NULL, - GTK_TYPE_STATE_TYPE, - GTK_STATE_NORMAL, - G_PARAM_READWRITE)); -} - -static void -icon_entry_init (EIconEntry *icon_entry) -{ - GtkWidget *widget; - GtkWidget *container; - - icon_entry->priv = E_ICON_ENTRY_GET_PRIVATE (icon_entry); - icon_entry->priv->visual_state = GTK_STATE_NORMAL; - - GTK_WIDGET_UNSET_FLAGS (icon_entry, GTK_NO_WINDOW); - - widget = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (icon_entry), widget); - icon_entry->priv->hbox = g_object_ref (widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_entry_new (); - gtk_entry_set_has_frame (GTK_ENTRY (widget), FALSE); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - icon_entry->priv->entry = g_object_ref (widget); - gtk_widget_show (widget); - - /* We need to queue a redraw when focus changes, to comply with - * themes (like Clearlooks) which draw focused and unfocused - * entries differently. */ - g_signal_connect_after ( - widget, "focus-in-event", - G_CALLBACK (icon_entry_focus_change_cb), icon_entry); - g_signal_connect_after ( - widget, "focus-out-event", - G_CALLBACK (icon_entry_focus_change_cb), icon_entry); -} - -GType -e_icon_entry_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - static const GTypeInfo type_info = { - sizeof (EIconEntryClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) icon_entry_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EIconEntry), - 0, /* n_preallocs */ - (GInstanceInitFunc) icon_entry_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - GTK_TYPE_BIN, "EIconEntry", &type_info, 0); - } - - return type; -} - -GtkWidget * -e_icon_entry_new (void) -{ - return GTK_WIDGET (g_object_new (E_TYPE_ICON_ENTRY, NULL)); -} - -GtkWidget * -e_icon_entry_get_entry (EIconEntry *icon_entry) -{ - g_return_val_if_fail (E_IS_ICON_ENTRY (icon_entry), NULL); - - return icon_entry->priv->entry; -} - -void -e_icon_entry_add_action_start (EIconEntry *icon_entry, - GtkAction *action) -{ - GtkWidget *proxy; - GtkBox *box; - - g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); - g_return_if_fail (GTK_IS_ACTION (action)); - - box = GTK_BOX (icon_entry->priv->hbox); - proxy = icon_entry_create_proxy (action); - gtk_box_pack_start (box, proxy, FALSE, FALSE, 2); - gtk_box_reorder_child (box, proxy, 0); -} - -void -e_icon_entry_add_action_end (EIconEntry *icon_entry, - GtkAction *action) -{ - GtkWidget *proxy; - GtkBox *box; - - g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); - g_return_if_fail (GTK_IS_ACTION (action)); - - box = GTK_BOX (icon_entry->priv->hbox); - proxy = icon_entry_create_proxy (action); - gtk_box_pack_end (box, proxy, FALSE, FALSE, 2); -} - -GtkStateType -e_icon_entry_get_visual_state (EIconEntry *icon_entry) -{ - g_return_val_if_fail (E_IS_ICON_ENTRY (icon_entry), GTK_STATE_NORMAL); - - return icon_entry->priv->visual_state; -} - -void -e_icon_entry_set_visual_state (EIconEntry *icon_entry, - GtkStateType visual_state) -{ - GtkWidget *widget; - const GdkColor *base_color; - const GdkColor *text_color; - - g_return_if_fail (E_IS_ICON_ENTRY (icon_entry)); - - if (visual_state == GTK_STATE_NORMAL) { - base_color = NULL; - text_color = NULL; - } else { - GtkStyle *style; - - style = gtk_widget_get_default_style (); - base_color = &style->base[visual_state]; - text_color = &style->text[visual_state]; - } - - widget = GTK_WIDGET (icon_entry); - gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); - - widget = icon_entry->priv->entry; - gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); - gtk_widget_modify_text (widget, GTK_STATE_NORMAL, text_color); - - widget = icon_entry->priv->hbox; - gtk_widget_modify_base (widget, GTK_STATE_NORMAL, base_color); - - icon_entry->priv->visual_state = visual_state; - g_object_notify (G_OBJECT (icon_entry), "visual-state"); -} diff --git a/widgets/misc/e-icon-entry.h b/widgets/misc/e-icon-entry.h deleted file mode 100644 index e18b0fdbe0..0000000000 --- a/widgets/misc/e-icon-entry.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * e-icon-entry.h - * - * Authors: Johnny Jacob - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * Adapted and modified from Epiphany. - * - * Copyright (C) 2003, 2004, 2005 Christian Persch - * - * This library 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) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Adapted and modified from gtk+ code: - * - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file in the gtk+ distribution for a list of people on the GTK+ Team. - * See the ChangeLog in the gtk+ distribution files for a list of changes. - * These files are distributed with GTK+ at ftp://ftp.gtk.org/pub/gtk/. - * - */ - -#ifndef E_ICON_ENTRY_H -#define E_ICON_ENTRY_H - -#include - -G_BEGIN_DECLS - -/* Standard GObject macros */ -#define E_TYPE_ICON_ENTRY \ - (e_icon_entry_get_type()) -#define E_ICON_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_ICON_ENTRY, EIconEntry)) -#define E_ICON_ENTRY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_ICON_ENTRY, EIconEntryClass)) -#define E_IS_ICON_ENTRY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_ICON_ENTRY)) -#define E_IS_ICON_ENTRY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_ICON_ENTRY)) -#define E_ICON_ENTRY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_ICON_ENTRY, EIconEntryClass)) - -typedef struct _EIconEntry EIconEntry; -typedef struct _EIconEntryClass EIconEntryClass; -typedef struct _EIconEntryPrivate EIconEntryPrivate; - -struct _EIconEntry -{ - GtkBin parent; - EIconEntryPrivate *priv; -}; - -struct _EIconEntryClass -{ - GtkBinClass parent_class; -}; - -GType e_icon_entry_get_type (void); -GtkWidget * e_icon_entry_new (void); -GtkWidget * e_icon_entry_get_entry (EIconEntry *entry); -void e_icon_entry_add_action_start (EIconEntry *entry, - GtkAction *action); -void e_icon_entry_add_action_end (EIconEntry *entry, - GtkAction *action); -GtkStateType e_icon_entry_get_visual_state (EIconEntry *entry); -void e_icon_entry_set_visual_state (EIconEntry *entry, - GtkStateType visual_state); - -G_END_DECLS - -#endif -- cgit v1.2.3 From a8b5c89d61f4816d46e6b0da2853aea93e569d68 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 3 Jun 2009 11:55:52 -0400 Subject: =?UTF-8?q?Bug=20572543=20=E2=80=93=20Doesn't=20show=20correct=20a?= =?UTF-8?q?pplication=20for=20pdf=20attachments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fix got dropped in the attachment rewrite. Also, ignore the application's NoDisplay setting when building the "open with" menu. That's mainly so "Document Viewer" shows up in the list. --- widgets/misc/e-attachment-view.c | 3 --- widgets/misc/e-attachment.c | 12 +++++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c index 41e0b302a2..345510230b 100644 --- a/widgets/misc/e-attachment-view.c +++ b/widgets/misc/e-attachment-view.c @@ -635,9 +635,6 @@ attachment_view_update_actions (EAttachmentView *view) gchar *action_label; gchar *action_name; - if (!g_app_info_should_show (app_info)) - continue; - app_executable = g_app_info_get_executable (app_info); app_icon = g_app_info_get_icon (app_info); app_name = g_app_info_get_name (app_info); diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index e9df6024bc..e7a03950db 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1320,9 +1320,11 @@ GList * e_attachment_list_apps (EAttachment *attachment) { GList *app_info_list; + GList *guessed_infos; GFileInfo *file_info; const gchar *content_type; const gchar *display_name; + gboolean type_is_unknown; gchar *allocated; g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); @@ -1336,18 +1338,22 @@ e_attachment_list_apps (EAttachment *attachment) g_return_val_if_fail (content_type != NULL, NULL); app_info_list = g_app_info_get_all_for_type (content_type); + type_is_unknown = g_content_type_is_unknown (content_type); - if (app_info_list != NULL || display_name == NULL) + if (app_info_list != NULL && !type_is_unknown) goto exit; - if (!g_content_type_is_unknown (content_type)) + if (display_name == NULL) goto exit; allocated = g_content_type_guess (display_name, NULL, 0, NULL); - app_info_list = g_app_info_get_all_for_type (allocated); + guessed_infos = g_app_info_get_all_for_type (allocated); + app_info_list = g_list_concat (guessed_infos, app_info_list); g_free (allocated); exit: + g_debug ("App List Length: %d", g_list_length (app_info_list)); + return app_info_list; } -- cgit v1.2.3 From 02ed9abe371c7a92462df95d7deba989039e47b2 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 3 Jun 2009 12:03:55 -0400 Subject: Whoops, forgot to remove a debug message. --- widgets/misc/e-attachment.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index e7a03950db..35c377abe5 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1352,8 +1352,6 @@ e_attachment_list_apps (EAttachment *attachment) g_free (allocated); exit: - g_debug ("App List Length: %d", g_list_length (app_info_list)); - return app_info_list; } -- cgit v1.2.3 From 05ffc39af8369116e830fd6a70c4fe54857a6336 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 3 Jun 2009 15:02:14 -0400 Subject: Fix a runtime warning for zero-length attachments. --- widgets/misc/e-attachment.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 35c377abe5..ba2811d5d9 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -2430,10 +2430,14 @@ attachment_save_got_output_stream (SaveContext *save_context) camel_data_wrapper_decode_to_stream (wrapper, stream); camel_object_unref (stream); - /* Load the buffer into a GMemoryInputStream. */ - input_stream = g_memory_input_stream_new_from_data ( - buffer->data, (gssize) buffer->len, - (GDestroyNotify) g_free); + /* Load the buffer into a GMemoryInputStream. + * But watch out for zero length MIME parts. */ + input_stream = g_memory_input_stream_new (); + if (buffer->len > 0) + g_memory_input_stream_add_data ( + G_MEMORY_INPUT_STREAM (input_stream), + buffer->data, (gssize) buffer->len, + (GDestroyNotify) g_free); save_context->input_stream = input_stream; save_context->total_num_bytes = (goffset) buffer->len; g_byte_array_free (buffer, FALSE); -- cgit v1.2.3 From df17adc5aa4ff6af69686d0957e1ab6dfa58732d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 9 Jun 2009 00:28:07 -0400 Subject: Search bar improvements. Split the search entry into a new widget to manage hints (EHintedEntry). Let the search entry expand to use available horizontal space. --- widgets/misc/Makefile.am | 2 + widgets/misc/e-hinted-entry.c | 298 ++++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-hinted-entry.h | 73 +++++++++++ 3 files changed, 373 insertions(+) create mode 100644 widgets/misc/e-hinted-entry.c create mode 100644 widgets/misc/e-hinted-entry.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 56a927041e..cbbd283fb2 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -60,6 +60,7 @@ widgetsinclude_HEADERS = \ e-dateedit.h \ e-file-activity.h \ e-gui-utils.h \ + e-hinted-entry.h \ e-hsv-utils.h \ e-image-chooser.h \ e-map.h \ @@ -122,6 +123,7 @@ libemiscwidgets_la_SOURCES = \ e-dateedit.c \ e-file-activity.c \ e-gui-utils.c \ + e-hinted-entry.c \ e-hsv-utils.c \ e-image-chooser.c \ e-map.c \ diff --git a/widgets/misc/e-hinted-entry.c b/widgets/misc/e-hinted-entry.c new file mode 100644 index 0000000000..ca75e85297 --- /dev/null +++ b/widgets/misc/e-hinted-entry.c @@ -0,0 +1,298 @@ +/* + * e-hinted-entry.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-hinted-entry.h" + +#define E_HINTED_ENTRY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_HINTED_ENTRY, EHintedEntryPrivate)) + +struct _EHintedEntryPrivate { + gchar *hint; + guint hint_shown : 1; +}; + +enum { + PROP_0, + PROP_HINT, + PROP_HINT_SHOWN +}; + +static gpointer parent_class; + +static void +hinted_entry_hide_hint (EHintedEntry *entry) +{ + gtk_entry_set_text (GTK_ENTRY (entry), ""); + + gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, NULL); + + entry->priv->hint_shown = FALSE; + + g_object_notify (G_OBJECT (entry), "hint-shown"); +} + +static void +hinted_entry_show_hint (EHintedEntry *entry) +{ + GtkStyle *style; + const GdkColor *color; + const gchar *hint; + + hint = e_hinted_entry_get_hint (entry); + gtk_entry_set_text (GTK_ENTRY (entry), hint); + + style = gtk_widget_get_style (GTK_WIDGET (entry)); + color = &style->text[GTK_STATE_INSENSITIVE]; + gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, color); + + entry->priv->hint_shown = TRUE; + + g_object_notify (G_OBJECT (entry), "hint-shown"); +} + +static void +hinted_entry_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_HINT: + e_hinted_entry_set_hint ( + E_HINTED_ENTRY (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +hinted_entry_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_HINT: + g_value_set_string ( + value, e_hinted_entry_get_hint ( + E_HINTED_ENTRY (object))); + return; + + case PROP_HINT_SHOWN: + g_value_set_boolean ( + value, e_hinted_entry_get_hint_shown ( + E_HINTED_ENTRY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +hinted_entry_finalize (GObject *object) +{ + EHintedEntryPrivate *priv; + + priv = E_HINTED_ENTRY_GET_PRIVATE (object); + + g_free (priv->hint); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +hinted_entry_focus_in_event (GtkWidget *widget, + GdkEventFocus *event) +{ + EHintedEntry *entry = E_HINTED_ENTRY (widget); + + if (e_hinted_entry_get_hint_shown (entry)) + hinted_entry_hide_hint (entry); + + /* Chain up to parent's focus_in_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + focus_in_event (widget, event); +} + +static gboolean +hinted_entry_focus_out_event (GtkWidget *widget, + GdkEventFocus *event) +{ + EHintedEntry *entry = E_HINTED_ENTRY (widget); + const gchar *text; + + text = e_hinted_entry_get_text (entry); + + if (text == NULL || *text == '\0') + hinted_entry_show_hint (E_HINTED_ENTRY (widget)); + + /* Chain up to parent's focus_out_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + focus_out_event (widget, event); +} + +static void +hinted_entry_class_init (EHintedEntryClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EHintedEntryPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = hinted_entry_set_property; + object_class->get_property = hinted_entry_get_property; + object_class->finalize = hinted_entry_finalize; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->focus_in_event = hinted_entry_focus_in_event; + widget_class->focus_out_event = hinted_entry_focus_out_event; + + g_object_class_install_property ( + object_class, + PROP_HINT, + g_param_spec_string ( + "hint", + "Hint", + NULL, + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_HINT_SHOWN, + g_param_spec_boolean ( + "hint-shown", + "Hint Shown", + NULL, + FALSE, + G_PARAM_READABLE)); +} + +static void +hinted_entry_init (EHintedEntry *entry) +{ + entry->priv = E_HINTED_ENTRY_GET_PRIVATE (entry); + entry->priv->hint = g_strdup (""); /* hint must never be NULL */ +} + +GType +e_hinted_entry_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EHintedEntryClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) hinted_entry_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EHintedEntry), + 0, /* n_preallocs */ + (GInstanceInitFunc) hinted_entry_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_ENTRY, "EHintedEntry", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_hinted_entry_new (void) +{ + return g_object_new (E_TYPE_HINTED_ENTRY, NULL); +} + +const gchar * +e_hinted_entry_get_hint (EHintedEntry *entry) +{ + g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), NULL); + + return entry->priv->hint; +} + +void +e_hinted_entry_set_hint (EHintedEntry *entry, + const gchar *hint) +{ + g_return_if_fail (E_IS_HINTED_ENTRY (entry)); + + if (hint == NULL) + hint = ""; + + g_free (entry->priv->hint); + entry->priv->hint = g_strdup (hint); + + if (e_hinted_entry_get_hint_shown (entry)) + gtk_entry_set_text (GTK_ENTRY (entry), hint); + + g_object_notify (G_OBJECT (entry), "hint"); +} + +gboolean +e_hinted_entry_get_hint_shown (EHintedEntry *entry) +{ + g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), FALSE); + + return entry->priv->hint_shown; +} + +const gchar * +e_hinted_entry_get_text (EHintedEntry *entry) +{ + /* XXX This clumsily overrides gtk_entry_get_text(). */ + + g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), NULL); + + if (e_hinted_entry_get_hint_shown (entry)) + return ""; + + return gtk_entry_get_text (GTK_ENTRY (entry)); +} + +void +e_hinted_entry_set_text (EHintedEntry *entry, + const gchar *text) +{ + /* XXX This clumsily overrides gtk_entry_set_text(). */ + + g_return_if_fail (E_IS_HINTED_ENTRY (entry)); + + if (text == NULL) + text = ""; + + if (*text == '\0' && !GTK_WIDGET_HAS_FOCUS (entry)) + hinted_entry_show_hint (entry); + else { + hinted_entry_hide_hint (entry); + gtk_entry_set_text (GTK_ENTRY (entry), text); + } +} diff --git a/widgets/misc/e-hinted-entry.h b/widgets/misc/e-hinted-entry.h new file mode 100644 index 0000000000..02379d4ad7 --- /dev/null +++ b/widgets/misc/e-hinted-entry.h @@ -0,0 +1,73 @@ +/* + * e-hinted-entry.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_HINTED_ENTRY_H +#define E_HINTED_ENTRY_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_HINTED_ENTRY \ + (e_hinted_entry_get_type ()) +#define E_HINTED_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_HINTED_ENTRY, EHintedEntry)) +#define E_HINTED_ENTRY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_HINTED_ENTRY, EHintedEntryClass)) +#define E_IS_HINTED_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_HINTED_ENTRY)) +#define E_IS_HINTED_ENTRY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_HINTED_ENTRY)) +#define E_HINTED_ENTRY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_HINTED_ENTRY, EHintedEntryClass)) + +G_BEGIN_DECLS + +typedef struct _EHintedEntry EHintedEntry; +typedef struct _EHintedEntryClass EHintedEntryClass; +typedef struct _EHintedEntryPrivate EHintedEntryPrivate; + +struct _EHintedEntry { + GtkEntry parent; + EHintedEntryPrivate *priv; +}; + +struct _EHintedEntryClass { + GtkEntryClass parent_class; +}; + +GType e_hinted_entry_get_type (void); +GtkWidget * e_hinted_entry_new (void); +const gchar * e_hinted_entry_get_hint (EHintedEntry *entry); +void e_hinted_entry_set_hint (EHintedEntry *entry, + const gchar *hint); +gboolean e_hinted_entry_get_hint_shown (EHintedEntry *entry); +const gchar * e_hinted_entry_get_text (EHintedEntry *entry); +void e_hinted_entry_set_text (EHintedEntry *entry, + const gchar *text); + +G_END_DECLS + +#endif /* E_HINTED_ENTRY_H */ -- cgit v1.2.3 From 71b0c7034e3574a671143b41ed3c5df017e14f6c Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 9 Jun 2009 08:09:19 -0400 Subject: Remove ESearchBar and EFilterBar. --- widgets/misc/e-filter-bar.c | 910 -------------------------- widgets/misc/e-filter-bar.h | 155 ----- widgets/misc/e-search-bar.c | 1515 ------------------------------------------- widgets/misc/e-search-bar.h | 141 ---- 4 files changed, 2721 deletions(-) delete mode 100644 widgets/misc/e-filter-bar.c delete mode 100644 widgets/misc/e-filter-bar.h delete mode 100644 widgets/misc/e-search-bar.c delete mode 100644 widgets/misc/e-search-bar.h (limited to 'widgets/misc') diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c deleted file mode 100644 index 4463fd12d8..0000000000 --- a/widgets/misc/e-filter-bar.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include - -#include "e-filter-bar.h" -#include "filter/rule-editor.h" - -/* The arguments we take */ -enum { - PROP_0, - PROP_QUERY, - PROP_STATE -}; - -static gpointer parent_class; - -/* Callbacks. */ - -static void rule_changed (FilterRule *rule, gpointer user_data); - -/* rule editor thingy */ -static void -rule_editor_destroyed (EFilterBar *filter_bar, GObject *deadbeef) -{ - filter_bar->save_dialog = NULL; - e_search_bar_set_menu_sensitive (E_SEARCH_BAR (filter_bar), E_FILTERBAR_SAVE_ID, TRUE); -} - -static void -rule_advanced_response (GtkWidget *dialog, gint response, gpointer data) -{ - EFilterBar *filter_bar = data; - /* the below generates a compiler warning about incompatible pointer types */ - ESearchBar *search_bar = (ESearchBar *)filter_bar; - FilterRule *rule; - - if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) { - rule = g_object_get_data ((GObject *) dialog, "rule"); - if (rule) { - GtkStyle *style = gtk_widget_get_default_style (); - - if (!filter_rule_validate (rule)) - return; - - filter_bar->current_query = rule; - g_object_ref (rule); - - gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (search_bar->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - e_search_bar_set_text (search_bar,_("Advanced Search")); - gtk_widget_set_sensitive (search_bar->clear_button, TRUE); - - g_signal_emit_by_name (efb, "search_activated"); - - g_signal_emit_by_name (efb, "search_activated"); - - if (response == GTK_RESPONSE_APPLY) { - if (!rule_context_find_rule (filter_bar->context, rule->name, rule->source)) - rule_context_add_rule (filter_bar->context, rule); - /* FIXME: check return */ - rule_context_save (filter_bar->context, filter_bar->userrules); - } - } - } else { - e_search_bar_set_item_id (search_bar, search_bar->last_search_option); - } - - if (response != GTK_RESPONSE_APPLY) - gtk_widget_destroy (dialog); -} - -static void -dialog_rule_changed (FilterRule *fr, GtkWidget *dialog) -{ - /* mbarnes: converted */ -} - -static void -do_advanced (ESearchBar *search_bar) -{ - EFilterBar *filter_bar = (EFilterBar *)search_bar; - - if (!filter_bar->save_dialog && !filter_bar->setquery) { - GtkWidget *dialog, *w; - FilterRule *rule; - - if (filter_bar->current_query) - rule = filter_rule_clone (filter_bar->current_query); - else { - rule = filter_rule_new (); - filter_bar->current_query = rule; - } - - w = filter_rule_get_widget (rule, filter_bar->context); - filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); - gtk_container_set_border_width (GTK_CONTAINER (w), 12); - - /* FIXME: get the toplevel window... */ - dialog = gtk_dialog_new_with_buttons (_("Advanced Search"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_SAVE, GTK_RESPONSE_APPLY, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - - filter_bar->save_dialog = dialog; - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 300); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); - - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 0); - - g_object_ref (rule); - g_object_set_data_full ((GObject *) dialog, "rule", rule, (GDestroyNotify) g_object_unref); - - g_signal_connect (rule, "changed", G_CALLBACK (dialog_rule_changed), dialog); - dialog_rule_changed (rule, dialog); - - g_signal_connect (dialog, "response", G_CALLBACK (rule_advanced_response), filter_bar); - g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, filter_bar); - - e_search_bar_set_menu_sensitive (search_bar, E_FILTERBAR_SAVE_ID, FALSE); - - gtk_widget_show (dialog); - } -} - -static void -save_search_dialog (ESearchBar *search_bar) -{ - /* mbarnes: converted */ -} - -static void -menubar_activated (ESearchBar *search_bar, gint id, gpointer data) -{ - EFilterBar *filter_bar = (EFilterBar *)search_bar; - GtkWidget *dialog; - GtkStyle *style; - - switch (id) { - case E_FILTERBAR_EDIT_ID: - /* mbarnes: converted */ - break; - case E_FILTERBAR_SAVE_ID: - if (filter_bar->current_query && !filter_bar->save_dialog) - save_search_dialog (search_bar); - - break; - case E_FILTERBAR_ADVANCED_ID: - e_search_bar_set_item_id (search_bar, E_FILTERBAR_ADVANCED_ID); - break; - default: - if (id >= filter_bar->menu_base && id < filter_bar->menu_base + filter_bar->menu_rules->len) { - filter_bar->current_query = (FilterRule *)filter_bar->menu_rules->pdata[id - filter_bar->menu_base]; - - filter_bar->setquery = TRUE; - e_search_bar_set_item_id (search_bar, E_FILTERBAR_ADVANCED_ID); - filter_bar->setquery = FALSE; - - /* saved searches activated */ - style = gtk_widget_get_default_style (); - filter_bar->setquery = TRUE; - gtk_widget_modify_base (search_bar->entry , GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED] )); - gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text [GTK_STATE_SELECTED] )); - gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); - gtk_widget_modify_base (search_bar->viewoption, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] )); - e_search_bar_set_text (search_bar,_("Advanced Search")); - g_signal_emit_by_name (filter_bar, "search_activated", NULL); - filter_bar->setquery = FALSE; - } else { - return; - } - } - - g_signal_stop_emission_by_name (search_bar, "menu_activated"); -} - -static void -option_changed (ESearchBar *search_bar, gpointer data) -{ - EFilterBar *filter_bar = (EFilterBar *)search_bar; - gint id = e_search_bar_get_item_id (search_bar); - gchar *query; - - d(printf("option changed, id = %d, setquery = %s %d\n", id, efb->setquery ? "true" : "false", esb->block_search)); - - if (efb->setquery) - return; - - switch (id) { - case E_FILTERBAR_SAVE_ID: - /* Fixme */ - /* save_search_dialog (search_bar); */ - break; - case E_FILTERBAR_ADVANCED_ID: - if (!search_bar->block_search) - do_advanced (search_bar); - break; - default: - if (id >= filter_bar->option_base && id < filter_bar->option_base + filter_bar->option_rules->len) { - filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[id - filter_bar->option_base]; - if (filter_bar->config && filter_bar->current_query) { - query = e_search_bar_get_text (search_bar); - filter_bar->config (filter_bar, filter_bar->current_query, id, query, filter_bar->config_data); - g_free (query); - } - } else { - gtk_widget_modify_base (search_bar->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (search_bar->icon_entry, GTK_STATE_NORMAL, NULL); - filter_bar->current_query = NULL; - gtk_entry_set_text ((GtkEntry *)search_bar->entry, ""); - } - } -} - -static void -dup_item_no_subitems (ESearchBarItem *dest, - const ESearchBarItem *src) -{ - dest->id = src->id; - dest->text = g_strdup (src->text); - dest->type = src->type; -} - -static GArray * -build_items (ESearchBar *search_bar, ESearchBarItem *items, gint type, gint *start, GPtrArray *rules) -{ - FilterRule *rule = NULL; - EFilterBar *filter_bar = (EFilterBar *)search_bar; - gint id = 0, i; - GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem)); - ESearchBarItem item = { NULL, -1, 2 }; - const gchar *source; - GSList *gtksux = NULL; - gint num; - - for (i=0;ilen;i++) - gtksux = g_slist_prepend(gtksux, rules->pdata[i]); - - g_ptr_array_set_size(rules, 0); - - /* find a unique starting point for the id's of our items */ - for (i = 0; items[i].id != -1; i++) { - ESearchBarItem dup_item = { NULL, -1, 2 }; - - if (items[i].id >= id) - id = items[i].id + 1; - - dup_item_no_subitems (&dup_item, items + i); - g_array_append_vals (menu, &dup_item, 1); - } - - *start = id; - - if (type == 0) { - source = FILTER_SOURCE_INCOMING; - - /* Add a separator if there is at least one custom rule. */ - if (rule_context_next_rule (filter_bar->context, rule, source) != NULL) { - item.id = 0; - item.text = NULL; - item.type = 0; - g_array_append_vals (menu, &item, 1); - } - } else { - source = FILTER_SOURCE_DEMAND; - } - - num = 1; - while ((rule = rule_context_next_rule (filter_bar->context, rule, source))) { - item.id = id++; - - if (type == 0 && num <= 10) { - item.text = g_strdup_printf ("_%d. %s", num % 10, rule->name); - num ++; - } else { - item.text = g_strdup (rule->name); - } - g_array_append_vals (menu, &item, 1); - - if (g_slist_find(gtksux, rule) == NULL) { - g_object_ref (rule); - g_signal_connect (rule, "changed", G_CALLBACK (rule_changed), filter_bar); - } else { - gtksux = g_slist_remove(gtksux, rule); - } - g_ptr_array_add (rules, rule); - } - - /* anything elft in gtksux has gone away, and we need to unref/disconnect from it */ - while (gtksux) { - GSList *next; - - next = gtksux->next; - rule = gtksux->data; - - g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), filter_bar); - g_object_unref (rule); - - g_slist_free_1(gtksux); - gtksux = next; - } - - /* always add on the advanced menu */ - if (type == 1) { - ESearchBarItem sb_items[2] = { E_FILTERBAR_SEPARATOR, E_FILTERBAR_ADVANCED, - /* E_FILTERBAR_SEPARATOR, E_FILTERBAR_SAVE */ }; - ESearchBarItem dup_items[2]; - - dup_item_no_subitems (&dup_items[0], &sb_items[0]); - dup_item_no_subitems (&dup_items[1], &sb_items[1]); - /* dup_item_no_subitems (&dup_items[2], &sb_items[2]); */ - /* dup_item_no_subitems (&dup_items[3], &sb_items[3]); */ - g_array_append_vals (menu, &dup_items, 2); - } - - item.id = -1; - item.text = NULL; - g_array_append_vals (menu, &item, 1); - - return menu; -} - -static void -free_built_items (GArray *menu) -{ - gint i; - - for (i = 0; i < menu->len; i ++) { - ESearchBarItem *item; - - item = & g_array_index (menu, ESearchBarItem, i); - g_free (item->text); - } - - g_array_free (menu, TRUE); -} - -static void -generate_menu (ESearchBar *search_bar, ESearchBarItem *items) -{ - EFilterBar *filter_bar = (EFilterBar *)search_bar; - GArray *menu; - - menu = build_items (search_bar, items, 0, &filter_bar->menu_base, filter_bar->menu_rules); - ((ESearchBarClass *)parent_class)->set_menu (search_bar, (ESearchBarItem *)menu->data); - free_built_items (menu); -} - -static void -free_items (ESearchBarItem *items) -{ - gint i; - - for (i = 0; items[i].id != -1; i++) - g_free (items[i].text); - - - g_free (items); -} - -/* Virtual methods */ -static void -set_menu (ESearchBar *search_bar, ESearchBarItem *items) -{ - EFilterBar *filter_bar = E_FILTER_BAR (search_bar); - ESearchBarItem *default_items; - gint i, num; - - if (filter_bar->default_items) - free_items (filter_bar->default_items); - - for (num = 0; items[num].id != -1; num++) - ; - - default_items = g_new (ESearchBarItem, num + 1); - for (i = 0; i < num + 1; i++) { - default_items[i].text = g_strdup (items[i].text); - default_items[i].id = items[i].id; - default_items[i].type = items[i].type; - } - - filter_bar->default_items = default_items; - - generate_menu (search_bar, default_items); -} - -static void -set_option (ESearchBar *search_bar, ESearchBarItem *items) -{ - GArray *menu; - EFilterBar *filter_bar = (EFilterBar *)search_bar; - - menu = build_items (search_bar, items, 1, &filter_bar->option_base, filter_bar->option_rules); - ((ESearchBarClass *)parent_class)->set_option (search_bar, (ESearchBarItem *)menu->data); - free_built_items (menu); - - e_search_bar_set_item_id (search_bar, filter_bar->option_base); -} - -static void -context_changed (RuleContext *context, gpointer user_data) -{ - EFilterBar *filter_bar = E_FILTER_BAR (user_data); - ESearchBar *search_bar = E_SEARCH_BAR (user_data); - - /* just generate whole menu again */ - generate_menu (search_bar, filter_bar->default_items); -} - -static void -context_rule_removed (RuleContext *context, FilterRule *rule, gpointer user_data) -{ - EFilterBar *filter_bar = E_FILTER_BAR (user_data); - ESearchBar *search_bar = E_SEARCH_BAR (user_data); - - /* just generate whole menu again */ - generate_menu (search_bar, filter_bar->default_items); -} - -static void -rule_changed (FilterRule *rule, gpointer user_data) -{ - EFilterBar *filter_bar = E_FILTER_BAR (user_data); - ESearchBar *search_bar = E_SEARCH_BAR (user_data); - - /* just generate whole menu again */ - generate_menu (search_bar, filter_bar->default_items); -} - -static void -filter_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EFilterBar *filter_bar = (EFilterBar *) object; - ESearchBar *search_bar = E_SEARCH_BAR (object); - - switch (property_id) { - case PROP_QUERY: { - gchar *text = e_search_bar_get_text (E_SEARCH_BAR (filter_bar)); - - /* empty search text means searching turned off */ - if (filter_bar->current_query && text && *text) { - GString *out = g_string_new (""); - - filter_rule_build_code (filter_bar->current_query, out); - g_value_take_string (value, out->str); - g_string_free (out, FALSE); - } else { - g_value_set_string (value, NULL); - } - - g_free (text); - break; } - case PROP_STATE: { - /* FIXME: we should have ESearchBar save its own state to the xmlDocPtr */ - xmlChar *xmlbuf; - gchar *text, buf[12]; - gint searchscope, item_id, n, view_id; - xmlNodePtr root, node; - xmlDocPtr doc; - - item_id = e_search_bar_get_item_id ((ESearchBar *) filter_bar); - - doc = xmlNewDoc ((const guchar *)"1.0"); - root = xmlNewDocNode (doc, NULL, (const guchar *)"state", NULL); - xmlDocSetRootElement (doc, root); - searchscope = e_search_bar_get_search_scope ((ESearchBar *) filter_bar); - view_id = e_search_bar_get_viewitem_id ((ESearchBar *) filter_bar); - - if (searchscope < E_FILTERBAR_CURRENT_FOLDER_ID) - item_id = search_bar->last_search_option; - - if (item_id == E_FILTERBAR_ADVANCED_ID) { - /* advanced query, save the filterbar state */ - node = xmlNewChild (root, NULL, (const guchar *)"filter-bar", NULL); - - sprintf (buf, "%d", search_bar->last_search_option); - xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf); - sprintf (buf, "%d", searchscope); - xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf); - sprintf (buf, "%d", view_id); - xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf); - - xmlAddChild (node, filter_rule_xml_encode (filter_bar->current_query)); - } else { - /* simple query, save the searchbar state */ - text = e_search_bar_get_text ((ESearchBar *) filter_bar); - - node = xmlNewChild (root, NULL, (const guchar *)"search-bar", NULL); - xmlSetProp (node, (const guchar *)"text", (guchar *)(text ? text : "")); - sprintf (buf, "%d", item_id); - xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf); - sprintf (buf, "%d", searchscope); - xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf); - sprintf (buf, "%d", view_id); - xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf); - g_free (text); - } - - xmlDocDumpMemory (doc, &xmlbuf, &n); - xmlFreeDoc (doc); - - /* remap to glib memory */ - text = g_malloc (n + 1); - memcpy (text, (gchar *)xmlbuf, n); - text[n] = '\0'; - xmlFree (xmlbuf); - - g_value_take_string (value, text); - - break; } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gint -xml_get_prop_int (xmlNodePtr node, const gchar *prop) -{ - gchar *buf; - gint ret; - - if ((buf = (gchar *)xmlGetProp (node, (guchar *)prop))) { - ret = strtol (buf, NULL, 10); - xmlFree (buf); - } else { - ret = -1; - } - - return ret; -} - -static void -filter_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - EFilterBar *filter_bar = (EFilterBar *) object; - ESearchBar *search_bar = E_SEARCH_BAR (object); - xmlNodePtr root, node; - const gchar *state; - xmlDocPtr doc; - gboolean rule_set = FALSE, is_cur_folder=FALSE; - gint view_id, scope, item_id; - - switch (property_id) { - case PROP_STATE: - if ((state = g_value_get_string (value))) { - if (!(doc = xmlParseDoc ((guchar *) state))) - return; - - root = doc->children; - if (strcmp ((gchar *)root->name, "state") != 0) { - xmlFreeDoc (doc); - return; - } - - node = root->children; - while (node != NULL) { - if (!strcmp ((gchar *)node->name, "filter-bar")) { - FilterRule *rule = NULL; - - - view_id = xml_get_prop_int (node, "view_id"); - scope = xml_get_prop_int (node, "searchscope"); - item_id = xml_get_prop_int (node, "item_id"); - if (item_id == -1) - item_id = 0; - - if (scope == E_FILTERBAR_CURRENT_FOLDER_ID) - is_cur_folder = TRUE; - - if ((node = node->children)) { - GtkStyle *style = gtk_widget_get_default_style (); - - rule = filter_rule_new (); - if (filter_rule_xml_decode (rule, node, filter_bar->context) != 0) { - gtk_widget_modify_base (E_SEARCH_BAR (filter_bar)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, NULL); - g_object_unref (rule); - rule = NULL; - } else { - rule_set = TRUE; - gtk_widget_set_sensitive (search_bar->clear_button, TRUE); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - g_object_set_data_full (object, "rule", rule, (GDestroyNotify) g_object_unref); - } - } - - - if (rule_set) { - search_bar->block_search = TRUE; - e_search_bar_set_text (search_bar, _("Advanced Search")); - e_search_bar_set_item_menu ((ESearchBar *) filter_bar, item_id); - e_search_bar_set_search_scope ((ESearchBar *) filter_bar, scope); - search_bar->block_search = FALSE; - filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; - if (filter_bar->config && filter_bar->current_query) { - gchar *query = e_search_bar_get_text (search_bar); - filter_bar->config (filter_bar, filter_bar->current_query, item_id, query, filter_bar->config_data); - g_free (query); - - } - } - e_search_bar_set_viewitem_id ((ESearchBar *) filter_bar, view_id); - filter_bar->current_query = rule; - filter_bar->setquery = TRUE; - e_search_bar_set_item_id ((ESearchBar *) filter_bar, E_FILTERBAR_ADVANCED_ID); - filter_bar->setquery = FALSE; - - break; - } else if (!strcmp ((gchar *)node->name, "search-bar")) { - gint subitem_id, item_id, scope, view_id; - gchar *text; - GtkStyle *style = gtk_widget_get_default_style (); - - /* set the text first (it doesn't emit a signal) */ - - - /* now set the item_id and subitem_id */ - item_id = xml_get_prop_int (node, "item_id"); - subitem_id = xml_get_prop_int (node, "subitem_id"); - - search_bar->block_search = TRUE; - if (subitem_id >= 0) - e_search_bar_set_ids (E_SEARCH_BAR (filter_bar), item_id, subitem_id); - else - e_search_bar_set_item_menu (E_SEARCH_BAR (filter_bar), item_id); - search_bar->block_search = FALSE; - view_id = xml_get_prop_int (node, "view_id"); - e_search_bar_set_viewitem_id (E_SEARCH_BAR (filter_bar), view_id); - scope = xml_get_prop_int (node, "searchscope"); - e_search_bar_set_search_scope (E_SEARCH_BAR (filter_bar), scope); - - text = (gchar *)xmlGetProp (node, (const guchar *)"text"); - e_search_bar_set_text (E_SEARCH_BAR (filter_bar), text); - if (text && *text) { - filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; - if (filter_bar->config && filter_bar->current_query) - filter_bar->config (filter_bar, filter_bar->current_query, item_id, text, filter_bar->config_data); - gtk_widget_set_sensitive (search_bar->clear_button, TRUE); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - } else { - gtk_widget_modify_base (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (((ESearchBar *)filter_bar)->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (((ESearchBar *)filter_bar)->icon_entry, GTK_STATE_NORMAL, NULL); - e_search_bar_paint (search_bar); - filter_bar->current_query = (FilterRule *)filter_bar->option_rules->pdata[item_id - filter_bar->option_base]; - if (filter_bar->config && filter_bar->current_query) - filter_bar->config (filter_bar, filter_bar->current_query, item_id, "", filter_bar->config_data); - } - - xmlFree (text); - - - break; - } - - node = node->next; - } - - xmlFreeDoc (doc); - } else { - /* set default state */ - e_search_bar_set_item_id ((ESearchBar *) filter_bar, 0); - e_search_bar_set_viewitem_id ((ESearchBar *) filter_bar, 0); - e_search_bar_set_search_scope ((ESearchBar *) filter_bar, E_FILTERBAR_CURRENT_FOLDER_ID); - } - - /* we don't want to run option_changed */ - filter_bar->setquery = TRUE; - g_signal_emit_by_name (filter_bar, "search_activated", NULL); - filter_bar->setquery = FALSE; - - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -filter_bar_clear_rules (EFilterBar *filter_bar, - GPtrArray *rules) -{ - FilterRule *rule; - gint ii; - - /* Clear out any data on old rules. */ - for (ii = 0; ii < rules->len; ii++) { - FilterRule *rule = rules->pdata[ii]; - - g_signal_handlers_disconnect_by_func ( - rule, G_CALLBACK (rule_changed), filter_bar); - g_object_unref(rule); - } - - g_ptr_array_set_size (rules, 0); -} - -static void -filter_bar_dispose (GObject *object) -{ - EFilterBar *bar; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_FILTER_BAR (object)); - - bar = E_FILTER_BAR (object); - - if (bar->context != NULL && bar->userrules != NULL) - rule_context_save (bar->context, bar->userrules); - - if (bar->menu_rules != NULL) { - filter_bar_clear_rules (bar, bar->menu_rules); - filter_bar_clear_rules (bar, bar->option_rules); - - g_ptr_array_free (bar->menu_rules, TRUE); - g_ptr_array_free (bar->option_rules, TRUE); - - g_free (bar->systemrules); - g_free (bar->userrules); - - bar->menu_rules = NULL; - bar->option_rules = NULL; - bar->systemrules = NULL; - bar->userrules = NULL; - } - - if (bar->context != NULL) { - g_signal_handlers_disconnect_by_func (bar->context, G_CALLBACK (context_changed), bar); - g_signal_handlers_disconnect_by_func (bar->context, G_CALLBACK (context_rule_removed), bar); - - g_object_unref (bar->context); - bar->context = NULL; - } - - if (bar->default_items) { - free_items (bar->default_items); - bar->default_items = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -class_init (EFilterBarClass *class) -{ - GObjectClass *object_class; - ESearchBarClass *search_bar_class; - GParamSpec *pspec; - - parent_class = g_type_class_peek_parent (class); - - object_class = G_OBJECT_CLASS (object_class); - object_class->set_property = filter_bar_set_property; - object_class->get_property = filter_bar_get_property; - object_class->dispose = filter_bar_dispose; - - search_bar_class = E_SEARCH_BAR_CLASS (class); - search_bar_class->set_menu = set_menu; - search_bar_class->set_option = set_option; - - g_object_class_install_property ( - object_class, - PROP_QUERY, - g_param_spec_string ( - "query", - NULL, - NULL, - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_STATE, - g_param_spec_string ( - "state", - NULL, - NULL, - NULL, - G_PARAM_READWRITE)); -} - -static void -filter_bar_init (EFilterBar *filter_bar) -{ - g_signal_connect (filter_bar, "menu_activated", G_CALLBACK (menubar_activated), NULL); - g_signal_connect (filter_bar, "query_changed", G_CALLBACK (option_changed), NULL); - g_signal_connect (filter_bar, "search_activated", G_CALLBACK (option_changed), NULL); - - filter_bar->menu_rules = g_ptr_array_new (); - filter_bar->option_rules = g_ptr_array_new (); -} - -GType -e_filter_bar_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EFilterBarClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) filter_bar_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EFilterBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) filter_bar_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - E_TYPE_SEARCH_BAR, "EFilterBar", &type_info, 0); - } - - return type; -} - -EFilterBar * -e_filter_bar_lite_new (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data) -{ - EFilterBar *bar; - - bar = g_object_new (e_filter_bar_get_type (), NULL); - ((ESearchBar *)bar)->lite = TRUE; - e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar); - - return bar; -} - -void -e_filter_bar_new_construct (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data) -{ - EFilterBar *bar; - - bar = g_object_new (E_TYPE_FILTER_BAR, NULL); - - bar->context = g_object_ref (context); - - bar->config = config; - bar->config_data = data; - - bar->systemrules = g_strdup (systemrules); - bar->userrules = g_strdup (userrules); - - bar->all_account_search_vf = NULL; - bar->account_search_vf = NULL; - bar->account_search_cancel = NULL; - - g_signal_connect (context, "changed", G_CALLBACK (context_changed), bar); - g_signal_connect (context, "rule_removed", G_CALLBACK (context_rule_removed), bar); - - return bar; -} diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h deleted file mode 100644 index 30c3ac5585..0000000000 --- a/widgets/misc/e-filter-bar.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_BAR_H -#define E_FILTER_BAR_H - -#include -#include -#include - -#include "e-search-bar.h" - -#include "filter/rule-context.h" -#include "filter/filter-rule.h" - -/* EFilterBar - A filter rule driven search bar. - * - * The following arguments are available: - * - * name type read/write description - * --------------------------------------------------------------------------------- - * query string R String representing query. - * state string RW XML string representing the state. - */ - -/* Standard GObject macros */ -#define E_TYPE_FILTER_BAR \ - (e_filter_bar_get_type ()) -#define E_FILTER_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_BAR, EFilterBar)) -#define E_FILTER_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_BAR, EFilterBarClass)) -#define E_IS_FILTER_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_BAR)) -#define E_IS_FILTER_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_FILTER_BAR)) -#define E_FILTER_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_BAR, EFilterBarClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterBar EFilterBar; -typedef struct _EFilterBarClass EFilterBarClass; - -typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, gint id, const gchar *query, gpointer data); - -struct _EFilterBar { - ESearchBar parent; - gint menu_base, option_base; - GPtrArray *menu_rules, *option_rules; - - ESearchBarItem *default_items; - - GtkWidget *save_dialog; /* current save dialogue (so we dont pop up multiple ones) */ - - FilterRule *current_query; /* as it says */ - gint setquery; /* true when we're setting a query directly to advanced, so dont popup the dialog */ - - RuleContext *context; - gchar *systemrules; - gchar *userrules; - - EFilterBarConfigRule config; - gpointer config_data; - - CamelVeeFolder *all_account_search_vf; - CamelVeeFolder *account_search_vf; - CamelOperation *account_search_cancel; -}; - -struct _EFilterBarClass { - ESearchBarClass parent_class; -}; - -/* "preset" items */ -enum { - /* preset menu options */ - E_FILTERBAR_SAVE_ID = -3, - E_FILTERBAR_EDIT_ID = -4, - - /* preset option options */ - E_FILTERBAR_ADVANCED_ID = -5, - E_FILTERBAR_CURRENT_FOLDER_ID = -7, - E_FILTERBAR_CURRENT_ACCOUNT_ID = -8, - E_FILTERBAR_ALL_ACCOUNTS_ID = -9 -}; - -#define E_FILTERBAR_SAVE { (gchar *) N_("_Save Search..."), E_FILTERBAR_SAVE_ID, 0 } -#define E_FILTERBAR_EDIT { (gchar *) N_("_Edit Saved Searches..."), E_FILTERBAR_EDIT_ID, 0 } -#define E_FILTERBAR_ADVANCED { (gchar *) N_("_Advanced Search..."), E_FILTERBAR_ADVANCED_ID, 0 } -#define E_FILTERBAR_ALL_ACCOUNTS { (gchar *) N_("All Accounts"), E_FILTERBAR_ALL_ACCOUNTS_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_CURRENT_ACCOUNT { (gchar *) N_("Current Account"), E_FILTERBAR_CURRENT_ACCOUNT_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_CURRENT_FOLDER { (gchar *) N_("Current Folder"), E_FILTERBAR_CURRENT_FOLDER_ID, ESB_ITEMTYPE_RADIO } -#define E_FILTERBAR_SEPARATOR { NULL, 0, 0 } - -#ifdef JUST_FOR_TRANSLATORS -const gchar * strings[] = { - N_("_Save Search..."), - N_("_Edit Saved Searches..."), - N_("_Advanced Search...") -}; -#endif - - -GType e_filter_bar_get_type (void); - -EFilterBar *e_filter_bar_new (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data); -EFilterBar *e_filter_bar_lite_new (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data); - -void -e_filter_bar_new_construct (RuleContext *context, - const gchar *systemrules, - const gchar *userrules, - EFilterBarConfigRule config, - gpointer data ,EFilterBar *bar ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -G_END_DECLS - -#endif /* E_FILTER_BAR_H */ diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c deleted file mode 100644 index dcab44ac4b..0000000000 --- a/widgets/misc/e-search-bar.c +++ /dev/null @@ -1,1515 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Chris Lahey - * Ettore Perazzoli - * Jon Trowbridge - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "e-search-bar.h" - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define E_SEARCH_BAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate)) - -struct _ESearchBarPrivate { - RuleContext *context; - FilterRule *current_query; - - GtkWidget *filter_label; - GtkWidget *filter_combo_box; - GtkWidget *search_label; - GtkWidget *search_entry; - GtkWidget *scope_label; - GtkWidget *scope_combo_box; - - GtkRadioAction *search_action; - GtkWidget *search_popup_menu; - - GtkActionGroup *action_group; -}; - -enum { - PROP_0, - PROP_CONTEXT, - PROP_FILTER_ACTION, - PROP_FILTER_VALUE, - PROP_FILTER_VISIBLE, - PROP_SEARCH_ACTION, - PROP_SEARCH_TEXT, - PROP_SEARCH_VALUE, - PROP_SEARCH_VISIBLE, - PROP_SCOPE_ACTION, - PROP_SCOPE_VALUE, - PROP_SCOPE_VISIBLE -}; - -static gpointer parent_class; - -static void -action_search_clear_cb (GtkAction *action, - ESearchBar *search_bar) -{ - e_search_bar_set_search_text (search_bar, ""); - gtk_action_set_sensitive (action, FALSE); -} - -static void -action_search_find_cb (GtkAction *action, - ESearchBar *search_bar) -{ - gtk_action_set_sensitive (action, FALSE); -} - -static void -clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearchBar *search_bar) -{ - g_return_if_fail (clear_button != NULL && search_bar != NULL); - - if (!search_bar->lite) - update_clear_menuitem_sensitive (search_bar); -} - -static gchar * -verb_name_from_id (gint id) -{ - return g_strdup_printf ("ESearchBar:Activate:%d", id); -} - -/* This implements the "clear" action, i.e. clears the text and then emits - * ::search_activated. */ - -static void -clear_search (ESearchBar *esb) -{ - e_search_bar_set_text (esb, ""); - esb->block_search = TRUE; - if (esb->item_id < 0) - e_search_bar_set_item_id (esb, esb->last_search_option); - e_search_bar_set_viewitem_id (esb, 0); - esb->block_search = FALSE; - emit_search_activated (esb); -} - -static void -free_menu_items (ESearchBar *esb) -{ - GSList *p; - - if (esb->menu_items == NULL) - return; - - for (p = esb->menu_items; p != NULL; p = p->next) { - ESearchBarItem *item; - - item = (ESearchBarItem *) p->data; - - /* (No submitems for the menu_items, so no need to free that - member.) */ - - g_free (item->text); - g_free (item); - } - - g_slist_free (esb->menu_items); - esb->menu_items = NULL; -} - - -/* Signals. */ - -static void -emit_query_changed (ESearchBar *esb) -{ - g_signal_emit (esb, esb_signals [QUERY_CHANGED], 0); - if (!esb->lite) - update_clear_menuitem_sensitive (esb); -} - -static void -search_bar_rule_changed (FilterRule *rule, - GtkDialog *dialog) -{ - gboolean sensitive; - - sensitive = (rule != NULL && rule->parts != NULL); - - if (!esb->lite) { - set_find_now_sensitive (esb, FALSE); - update_clear_menuitem_sensitive (esb); - } -} - -static void -search_bar_update_search_popup (ESearchBar *search_bar) -{ - GtkAction *action; - GtkMenuShell *menu_shell; - GSList *list, *iter; - - action = gtk_action_group_get_action ( - search_bar->priv->action_group, "search-type"); - - if (search_bar->priv->search_popup_menu != NULL) { - g_object_unref (search_bar->priv->search_popup_menu); - search_bar->priv->search_popup_menu = NULL; - } - - if (search_bar->priv->search_action == NULL) { - gtk_action_set_sensitive (action, FALSE); - return; - } - - search_bar->priv->search_popup_menu = gtk_menu_new (); - menu_shell = GTK_MENU_SHELL (search_bar->priv->search_popup_menu); - list = gtk_radio_action_get_group (search_bar->priv->search_action); - - for (iter = list; iter != NULL; iter = iter->next) { - GtkAction *action = iter->data; - GtkWidget *widget; - - widget = gtk_action_create_menu_item (action); - gtk_menu_shell_append (menu_shell, widget); - gtk_widget_show (widget); - } - - gtk_action_set_sensitive (action, TRUE); -} - -static gboolean -paint_search_text (GtkWidget *widget, - ESearchBar *search_bar) -{ -#if 0 - GtkStyle *style = gtk_widget_get_default_style (); - const gchar *text; - GtkWidget *menu_widget = search_bar->option_menu; - - text = gtk_entry_get_text (GTK_ENTRY (widget)); - if (text && *text) - return FALSE; - - style = gtk_widget_get_default_style (); - - if (!GTK_WIDGET_SENSITIVE (search_bar->option_button)) { - menu_widget = search_bar->scopeoption_menu; - text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (search_bar->scopeoption_menu))),"string"); - } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (search_bar->option_menu)))) - return FALSE; - else /* no query in search entry .. so set the current option */ - text = get_selected_item_label (menu_widget); - - - if (text && *text) { - gchar *t; - - if (!GTK_WIDGET_HAS_FOCUS(search_bar->entry)) { - gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text); - gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE])); - } - - t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type")); - gtk_widget_set_tooltip_text (search_bar->option_button, t); - g_free (t); - - gtk_widget_set_sensitive (search_bar->clear_button, FALSE); - } - - return FALSE; -#endif - - return FALSE; -} - -void -e_search_bar_paint (ESearchBar *search_bar) -{ - paint_search_text (search_bar->entry, search_bar); -} - -static gboolean -entry_focus_out_cb (GtkWidget *widget, - GdkEventFocus *event, - ESearchBar *esb) -{ - return paint_search_text (widget, esb); -} - -static void -entry_activated_cb (GtkWidget *widget, - ESearchBar *esb) -{ - const gchar *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); - GtkStyle *style = gtk_widget_get_default_style (); - - if (text && *text) { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - if (!esb->lite) - gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED])); - } else { - gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL); - if (!esb->lite) - gtk_widget_set_sensitive (esb->clear_button, FALSE); - } - - icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); - entry = e_icon_entry_get_entry (icon_entry); - paint_search_text (entry, search_bar); -} - -static void -search_bar_entry_activated_cb (ESearchBar *search_bar, - GtkWidget *entry) -{ - GtkStyle *style; - GtkAction *action; - GtkActionGroup *action_group; - gboolean sensitive; - const gchar *text; - - style = gtk_widget_get_default_style (); - text = gtk_entry_get_text (GTK_ENTRY (entry)); - action_group = e_search_bar_get_action_group (search_bar); - - if (text && *text) { - gtk_widget_modify_base ( - entry, GTK_STATE_NORMAL, - &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_text ( - entry, GTK_STATE_NORMAL, - &(style->text[GTK_STATE_SELECTED])); - gtk_widget_modify_base ( - search_bar->priv->search_entry, - GTK_STATE_NORMAL, - &(style->base[GTK_STATE_SELECTED])); - gtk_widget_modify_base ( - search_bar->priv->filter_combo_box, - GTK_STATE_NORMAL, - &(style->base[GTK_STATE_SELECTED])); - sensitive = TRUE; - } else { - gtk_widget_modify_base ( - entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_text ( - entry, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base ( - search_bar->priv->search_entry, - GTK_STATE_NORMAL, NULL); - sensitive = FALSE; - } - - action = gtk_action_group_get_action ( - action_group, E_SEARCH_BAR_ACTION_CLEAR); - gtk_action_set_sensitive (action, sensitive); - - action = gtk_action_group_get_action ( - action_group, E_SEARCH_BAR_ACTION_FIND); - gtk_action_activate (action); -} - -static void -search_bar_entry_changed_cb (ESearchBar *search_bar, - GtkWidget *entry) -{ - GtkActionGroup *action_group; - GtkAction *action; - GtkStyle *style1; - GtkStyle *style2; - GdkColor *color1; - GdkColor *color2; - gboolean sensitive; - const gchar *text; - - style1 = gtk_widget_get_style (entry); - style2 = gtk_widget_get_default_style (); - - text = gtk_entry_get_text (GTK_ENTRY (entry)); - - if (text != NULL && *text != '\0') { - color1 = &style1->text[GTK_STATE_NORMAL]; - color2 = &style2->text[GTK_STATE_INSENSITIVE]; - sensitive = !gdk_color_equal (color1, color2); - } else { - color1 = &style1->text[GTK_STATE_NORMAL]; - color2 = &style2->text[GTK_STATE_SELECTED]; - sensitive = gdk_color_equal (color1, color2); - } - - action_group = search_bar->priv->action_group; - action = gtk_action_group_get_action ( - action_group, E_SEARCH_BAR_ACTION_CLEAR); - gtk_action_set_sensitive (action, sensitive); -} - -static gboolean -search_bar_entry_focus_in_cb (ESearchBar *search_bar, - GdkEventFocus *event, - GtkWidget *entry) -{ - GtkStyle *style1; - GtkStyle *style2; - GdkColor *color1; - GdkColor *color2; - - style1 = gtk_widget_get_style (entry); - style2 = gtk_widget_get_default_style (); - - color1 = &style1->text[GTK_STATE_NORMAL]; - color2 = &style2->text[GTK_STATE_INSENSITIVE]; - - if (gdk_color_equal (color1, color2)) { - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL); - } - - return FALSE; -} - -static gboolean -search_bar_entry_focus_out_cb (ESearchBar *search_bar, - GdkEventFocus *event, - GtkWidget *entry) -{ - return paint_search_text (entry, search_bar); -} - -static gboolean -search_bar_entry_key_press_cb (ESearchBar *search_bar, - GdkEventKey *key_event, - GtkWidget *entry) -{ - guint state; - -#if 0 /* FIXME */ - state = key_event->state & gtk_accelerator_get_default_mod_mask (); - if (state == GDK_MOD1_MASK && key_event->keyval == GDK_Down) { - search_bar_option_clicked_cb (search_bar, NULL, NULL); - return TRUE; - } -#endif - - return FALSE; -} - -static void -search_bar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CONTEXT: - e_search_bar_set_context ( - E_SEARCH_BAR (object), - g_value_get_object (value)); - return; - - case PROP_FILTER_ACTION: - e_search_bar_set_filter_action ( - E_SEARCH_BAR (object), - g_value_get_object (value)); - return; - - case PROP_FILTER_VALUE: - e_search_bar_set_filter_value ( - E_SEARCH_BAR (object), - g_value_get_int (value)); - return; - - case PROP_FILTER_VISIBLE: - e_search_bar_set_filter_visible ( - E_SEARCH_BAR (object), - g_value_get_boolean (value)); - return; - - case PROP_SEARCH_ACTION: - e_search_bar_set_search_action ( - E_SEARCH_BAR (object), - g_value_get_object (value)); - return; - - case PROP_SEARCH_TEXT: - e_search_bar_set_search_text ( - E_SEARCH_BAR (object), - g_value_get_string (value)); - return; - - case PROP_SEARCH_VALUE: - e_search_bar_set_search_value ( - E_SEARCH_BAR (object), - g_value_get_int (value)); - return; - - case PROP_SEARCH_VISIBLE: - e_search_bar_set_search_visible ( - E_SEARCH_BAR (object), - g_value_get_boolean (value)); - return; - - case PROP_SCOPE_ACTION: - e_search_bar_set_scope_action ( - E_SEARCH_BAR (object), - g_value_get_object (value)); - return; - - case PROP_SCOPE_VALUE: - e_search_bar_set_scope_value ( - E_SEARCH_BAR (object), - g_value_get_int (value)); - return; - - case PROP_SCOPE_VISIBLE: - e_search_bar_set_scope_visible ( - E_SEARCH_BAR (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -search_bar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CONTEXT: - g_value_set_object ( - value, e_search_bar_get_context ( - E_SEARCH_BAR (object))); - return; - - case PROP_FILTER_ACTION: - g_value_set_object ( - value, e_search_bar_get_filter_action ( - E_SEARCH_BAR (object))); - return; - - case PROP_FILTER_VALUE: - g_value_set_int ( - value, e_search_bar_get_filter_value ( - E_SEARCH_BAR (object))); - return; - - case PROP_FILTER_VISIBLE: - g_value_set_boolean ( - value, e_search_bar_get_filter_visible ( - E_SEARCH_BAR (object))); - return; - - case PROP_SEARCH_ACTION: - g_value_set_object ( - value, e_search_bar_get_search_action ( - E_SEARCH_BAR (object))); - return; - - case PROP_SEARCH_TEXT: - g_value_set_string ( - value, e_search_bar_get_search_text ( - E_SEARCH_BAR (object))); - return; - - case PROP_SEARCH_VALUE: - g_value_set_int ( - value, e_search_bar_get_search_value ( - E_SEARCH_BAR (object))); - return; - - case PROP_SEARCH_VISIBLE: - g_value_set_boolean ( - value, e_search_bar_get_search_visible ( - E_SEARCH_BAR (object))); - return; - - case PROP_SCOPE_ACTION: - g_value_set_object ( - value, e_search_bar_get_scope_action ( - E_SEARCH_BAR (object))); - return; - - case PROP_SCOPE_VALUE: - g_value_set_int ( - value, e_search_bar_get_scope_value ( - E_SEARCH_BAR (object))); - return; - - case PROP_SCOPE_VISIBLE: - g_value_set_boolean ( - value, e_search_bar_get_scope_visible ( - E_SEARCH_BAR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -search_bar_dispose (GObject *object) -{ - ESearchBarPrivate *priv; - - priv = E_SEARCH_BAR_GET_PRIVATE (object); - - if (priv->context != NULL) { - g_object_unref (priv->context); - priv->context = NULL; - } - - if (priv->filter_label != NULL) { - g_object_unref (priv->filter_label); - priv->filter_label = NULL; - } - - if (priv->filter_combo_box != NULL) { - g_object_unref (priv->filter_combo_box); - priv->filter_combo_box = NULL; - } - - if (!esb->lite && esb->ui_component != NULL) - update_bonobo_menus (esb); -} - -/* /\* Callback used when an option item is destroyed. We have to destroy its */ -/* * suboption items. */ -/* *\/ */ -/* static gpointer */ -/* option_item_destroy_cb (GtkObject *object, gpointer data) */ -/* { */ -/* /\* ESearchBarSubitem *subitems; *\/ */ - -/* /\* subitems = data; *\/ */ - -/* /\* g_assert (subitems != NULL); *\/ */ -/* /\* free_subitems (subitems); *\/ */ -/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */ -/* } */ - -static void -set_option (ESearchBar *esb, ESearchBarItem *items) -{ - GtkWidget *menu; - GSList *group = NULL; - gint i; - - if (esb->option_menu) - gtk_widget_destroy (esb->option_menu); - - esb->option_menu = menu = gtk_menu_new (); - for (i = 0; items[i].id != -1; i++) { - GtkWidget *item; - - /* Create a new group */ - if (items[i].id == 0) - group = NULL; - - if (items[i].text) { - gchar *str; - str = e_str_without_underscores (_(items[i].text)); - switch (items[i].type) { - case ESB_ITEMTYPE_NORMAL: - item = gtk_menu_item_new_with_label (str); - break; - case ESB_ITEMTYPE_CHECK: - item = gtk_check_menu_item_new_with_label (str); - break; - case ESB_ITEMTYPE_RADIO: - item = gtk_radio_menu_item_new_with_label (group, str); - group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); - break; - default: - /* Fixme : this should be a normal item */ - item = gtk_radio_menu_item_new_with_label (group, str); - group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); - break; - } - g_free (str); - } else { - item = gtk_menu_item_new (); - gtk_widget_set_sensitive (item, FALSE); - } - - if (priv->search_entry != NULL) { - g_object_unref (priv->search_entry); - priv->search_entry = NULL; - } - - if (priv->scope_label != NULL) { - g_object_unref (priv->scope_label); - priv->scope_label = NULL; - } - - if (priv->scope_combo_box != NULL) { - g_object_unref (priv->scope_combo_box); - priv->scope_combo_box = NULL; - } - - if (priv->search_action != NULL) { - g_object_unref (priv->search_action); - priv->search_action = NULL; - } - - if (priv->action_group != NULL) { - g_object_unref (priv->action_group); - priv->action_group = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -search_bar_class_init (ESearchBarClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (ESearchBarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = search_bar_set_property; - object_class->get_property = search_bar_get_property; - object_class->dispose = search_bar_dispose; - - g_object_class_install_property ( - object_class, - PROP_CONTEXT, - g_param_spec_object ( - "context", - NULL, - NULL, - RULE_TYPE_CONTEXT, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FILTER_ACTION, - g_param_spec_object ( - "filter-action", - NULL, - NULL, - GTK_TYPE_RADIO_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FILTER_VALUE, - g_param_spec_int ( - "filter-value", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FILTER_VISIBLE, - g_param_spec_boolean ( - "filter-visible", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_SEARCH_ACTION, - g_param_spec_object ( - "search-action", - NULL, - NULL, - GTK_TYPE_RADIO_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SEARCH_TEXT, - g_param_spec_string ( - "search-text", - NULL, - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SEARCH_VALUE, - g_param_spec_int ( - "search-value", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SEARCH_VISIBLE, - g_param_spec_boolean ( - "search-visible", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_SCOPE_ACTION, - g_param_spec_object ( - "scope-action", - NULL, - NULL, - GTK_TYPE_RADIO_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SCOPE_VALUE, - g_param_spec_int ( - "scope-value", - NULL, - NULL, - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SCOPE_VISIBLE, - g_param_spec_boolean ( - "scope-visible", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); -} - -static void -search_bar_init (ESearchBar *search_bar) -{ - EIconEntry *icon_entry; - GtkActionGroup *action_group; - GtkAction *action; - GtkLabel *label; - GtkWidget *mnemonic; - GtkWidget *widget; - - search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar); - - gtk_box_set_spacing (GTK_BOX (search_bar), 3); - gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE); - - /*** Filter Widgets ***/ - - /* Translators: The "Show: " label is followed by the Quick Search - * Dropdown Menu where you can choose to display "All Messages", - * "Unread Messages", "Message with 'Important' Label" and so on... */ - widget = gtk_label_new_with_mnemonic (_("Sho_w: ")); - gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); - search_bar->priv->filter_label = g_object_ref (widget); - gtk_widget_show (widget); - - label = GTK_LABEL (widget); - - widget = e_action_combo_box_new (); - gtk_label_set_mnemonic_widget (label, widget); - gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, TRUE, 0); - search_bar->priv->filter_combo_box = g_object_ref (widget); - gtk_widget_show (widget); - - /*** Scope Widgets ***/ - - widget = e_action_combo_box_new (); - gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); - search_bar->priv->scope_combo_box = g_object_ref (widget); - gtk_widget_show (widget); - - mnemonic = widget; - - /* Translators: The " in " label is part of the Quick Search Bar, - * example: Search: [_________________] in [ Current Folder ] */ - widget = gtk_label_new_with_mnemonic (_(" i_n ")); - gtk_label_set_mnemonic_widget (GTK_LABEL (widget), mnemonic); - gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); - search_bar->priv->scope_label = g_object_ref (widget); - gtk_widget_show (widget); - - /*** Search Widgets ***/ - - widget = e_icon_entry_new (); - gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); - search_bar->priv->search_entry = g_object_ref (widget); - gtk_widget_show (widget); - - icon_entry = E_ICON_ENTRY (widget); - - /* Translators: The "Search: " label is followed by the Quick Search - * Text input field where one enters the term to search for. */ - widget = gtk_label_new_with_mnemonic (_("Sear_ch: ")); - gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); - search_bar->priv->search_label = g_object_ref (widget); - gtk_widget_show (widget); - - label = GTK_LABEL (widget); - - widget = e_icon_entry_get_entry (icon_entry); - gtk_label_set_mnemonic_widget (label, widget); - g_signal_connect_swapped ( - widget, "activate", - G_CALLBACK (search_bar_entry_activated_cb), search_bar); - g_signal_connect_swapped ( - widget, "changed", - G_CALLBACK (search_bar_entry_changed_cb), search_bar); - g_signal_connect_swapped ( - widget, "focus-in-event", - G_CALLBACK (search_bar_entry_focus_in_cb), search_bar); - g_signal_connect_swapped ( - widget, "focus-out-event", - G_CALLBACK (search_bar_entry_focus_out_cb), search_bar); - g_signal_connect_swapped ( - widget, "key-press-event", - G_CALLBACK (search_bar_entry_key_press_cb), search_bar); - - action_group = gtk_action_group_new ("search"); - gtk_action_group_set_translation_domain ( - action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions ( - action_group, search_entries, - G_N_ELEMENTS (search_entries), search_bar); - search_bar->priv->action_group = action_group; - - action = gtk_action_group_get_action ( - action_group, E_SEARCH_BAR_ACTION_TYPE); - e_icon_entry_add_action_start (icon_entry, action); - gtk_action_set_sensitive (action, FALSE); - - action = gtk_action_group_get_action ( - action_group, E_SEARCH_BAR_ACTION_CLEAR); - e_icon_entry_add_action_end (icon_entry, action); - gtk_action_set_sensitive (action, FALSE); -} - -GType -e_search_bar_get_type (void) -{ - static GType type = 0; - - if (!esb->lite && esb->ui_component != NULL) { - bonobo_object_unref (BONOBO_OBJECT (esb->ui_component)); - esb->ui_component = NULL; - } -/* if (esb->entry) { */ -/* g_object_unref (esb->entry); */ -/* esb->entry = NULL; */ -/* } */ - if (esb->suboption) { - g_object_unref (esb->suboption); - esb->suboption = NULL; - } - - type = g_type_register_static ( - GTK_TYPE_HBOX, "ESearchBar", &type_info, 0); - } - - return type; -} - -GtkWidget * -e_search_bar_new (void) -{ - return g_object_new (E_TYPE_SEARCH_BAR, NULL); -} - -GtkActionGroup * -e_search_bar_get_action_group (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - return search_bar->priv->action_group; -} - -RuleContext * -e_search_bar_get_context (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - return search_bar->priv->context; -} - -void -e_search_bar_set_context (ESearchBar *search_bar, - RuleContext *context) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (IS_RULE_CONTEXT (context)); - - if (search_bar->priv->context != NULL) - g_object_unref (search_bar->priv->context); - - bighbox = gtk_hbox_new (FALSE, 0); - search_bar->entry_box = gtk_hbox_new (0, FALSE); - search_bar->icon_entry = e_icon_entry_new (); - search_bar->entry = e_icon_entry_get_entry (E_ICON_ENTRY (search_bar->icon_entry)); - - g_signal_connect (search_bar->entry, "changed", - G_CALLBACK (entry_changed_cb), search_bar); - g_signal_connect (search_bar->entry, "activate", - G_CALLBACK (entry_activated_cb), search_bar); - g_signal_connect (search_bar->entry, "focus-in-event", - G_CALLBACK (entry_focus_in_cb), search_bar); - g_signal_connect (search_bar->entry, "focus-out-event", - G_CALLBACK (entry_focus_out_cb), search_bar); - g_signal_connect (search_bar->entry, "key-press-event", - G_CALLBACK (entry_key_press_cb), search_bar); - - search_bar->clear_button = e_icon_entry_create_button ("gtk-clear"); - g_signal_connect (G_OBJECT (search_bar->clear_button), "button-press-event", G_CALLBACK(clear_button_clicked_cb), search_bar); - e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->clear_button, FALSE); - - search_bar->option_button = e_icon_entry_create_button ("gtk-find"); - g_signal_connect (G_OBJECT (search_bar->option_button), "button-press-event", G_CALLBACK(option_button_clicked_cb), search_bar); - e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->option_button, TRUE); - - if (!search_bar->lite) - gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, FALSE, FALSE, 0); - else - gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, TRUE, TRUE, 0); - - - gtk_widget_show_all (search_bar->entry_box); - gtk_widget_set_sensitive (search_bar->clear_button, FALSE); - - if (!search_bar->lite) { - /* Current View filter */ - search_bar->viewoption_box = gtk_hbox_new (0, FALSE); - - /* To Translators: The "Show: " label is followed by the Quick Search Dropdown Menu where you can choose - to display "All Messages", "Unread Messages", "Message with 'Important' Label" and so on... */ - label = gtk_label_new_with_mnemonic (_("Sho_w: ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), label, FALSE, FALSE, 0); - - search_bar->viewoption = gtk_option_menu_new (); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->viewoption); - gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), search_bar->viewoption, FALSE, TRUE, 0); - gtk_widget_show_all (search_bar->viewoption_box); - gtk_box_pack_start (GTK_BOX(search_bar), search_bar->viewoption_box, FALSE, FALSE, 0); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); - } - - /* Search entry */ - hbox = gtk_hbox_new (FALSE, 0); - /* To Translators: The "Show: " label is followed by the Quick Search Text input field where one enters - the term to search for */ - if (!search_bar->lite) { - label = gtk_label_new_with_mnemonic (_("Sear_ch: ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, FALSE, FALSE, 0); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->entry); - } else { - gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, TRUE, TRUE, 0); - } - gtk_widget_show (search_bar->entry_box); - - if (!search_bar->lite) { - /* Search Scope Widgets */ - search_bar->scopeoption_box = gtk_hbox_new (0, FALSE); - gtk_box_set_spacing (GTK_BOX (search_bar->scopeoption_box), 3); - /* To Translators: The " in " label is part of the Quick Search Bar, example: - Search: | | in | Current Folder/All Accounts/Current Account */ - label = gtk_label_new_with_mnemonic (_(" i_n ")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0); - - search_bar->scopeoption = gtk_option_menu_new (); - /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */ - gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0); - gtk_widget_show_all (search_bar->scopeoption_box); - gtk_widget_hide (hbox); - gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->scopeoption); - - gtk_box_pack_end (GTK_BOX(hbox), search_bar->scopeoption_box, FALSE, FALSE, 0); - gtk_widget_hide (search_bar->scopeoption_box); - - } - if (!search_bar->lite) - gtk_box_pack_end (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0); - else - gtk_box_pack_end (GTK_BOX(search_bar), hbox, TRUE, TRUE, 0); - - gtk_widget_show (hbox); - - /* Set the menu */ - e_search_bar_set_menu (search_bar, menu_items); - e_search_bar_set_option (search_bar, option_items); - - /* - * If the default choice for the option menu has subitems, then we need to - * activate the search immediately. However, the developer won't have - * connected to the activated signal until after the object is constructed, - * so we can't emit here. Thus we launch a one-shot idle function that will - * emit the changed signal, so that the proper callback will get invoked. - */ - if (!search_bar->lite) - search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar); -} - -GtkRadioAction * -e_search_bar_get_filter_action (ESearchBar *search_bar) -{ - EActionComboBox *combo_box; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - - return e_action_combo_box_get_action (combo_box); -} - -void -e_search_bar_set_filter_action (ESearchBar *search_bar, - GtkRadioAction *action) -{ - EActionComboBox *combo_box; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - - e_action_combo_box_set_action (combo_box, action); - g_object_notify (G_OBJECT (search_bar), "filter-action"); -} - -gint -e_search_bar_get_filter_value (ESearchBar *search_bar) -{ - EActionComboBox *combo_box; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - - return e_action_combo_box_get_current_value (combo_box); -} - -void -e_search_bar_set_filter_value (ESearchBar *search_bar, - gint value) -{ - EActionComboBox *combo_box; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - - e_action_combo_box_set_current_value (combo_box, value); - g_object_notify (G_OBJECT (search_bar), "filter-value"); -} - -gboolean -e_search_bar_get_filter_visible (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - - return GTK_WIDGET_VISIBLE (search_bar->priv->filter_combo_box); -} - -void -e_search_bar_set_filter_visible (ESearchBar *search_bar, - gboolean visible) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (visible) { - gtk_widget_show (search_bar->priv->filter_label); - gtk_widget_show (search_bar->priv->filter_combo_box); - } else { - gtk_widget_hide (search_bar->priv->filter_label); - gtk_widget_hide (search_bar->priv->filter_combo_box); - } - - g_object_notify (G_OBJECT (search_bar), "filter-visible"); -} - -GtkRadioAction * -e_search_bar_get_search_action (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - return search_bar->priv->search_action; -} - -void -e_search_bar_set_search_action (ESearchBar *search_bar, - GtkRadioAction *action) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (action != NULL) { - g_return_if_fail (GTK_IS_RADIO_ACTION (action)); - g_object_ref (action); - } - - search_bar->priv->search_action = action; - search_bar_update_search_popup (search_bar); - - g_object_notify (G_OBJECT (search_bar), "search-action"); -} - -const gchar * -e_search_bar_get_search_text (ESearchBar *search_bar) -{ - EIconEntry *icon_entry; - GtkWidget *entry; - GtkStyle *style1; - GtkStyle *style2; - GdkColor *color1; - GdkColor *color2; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); - entry = e_icon_entry_get_entry (icon_entry); - - style1 = gtk_widget_get_style (entry); - style2 = gtk_widget_get_default_style (); - - color1 = &style1->text[GTK_STATE_NORMAL]; - color2 = &style2->text[GTK_STATE_INSENSITIVE]; - -GtkWidget * -e_search_bar_lite_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items) -{ - GtkWidget *widget; - - g_return_val_if_fail (option_items != NULL, NULL); - - widget = g_object_new (e_search_bar_get_type (), NULL); - E_SEARCH_BAR(widget)->lite = TRUE; - - e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); - - return widget; -} - -GtkWidget * -e_search_bar_lite_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items) -{ - GtkWidget *widget; - - g_return_val_if_fail (option_items != NULL, NULL); - - widget = g_object_new (e_search_bar_get_type (), NULL); - E_SEARCH_BAR(widget)->lite = TRUE; - - e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); - - return widget; -} - -void -e_search_bar_set_ui_component (ESearchBar *search_bar, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (search_bar->lite) - return; - - if (search_bar->ui_component != NULL) { - remove_bonobo_menus (search_bar); - bonobo_object_unref (BONOBO_OBJECT (search_bar->ui_component)); - } - - search_bar->ui_component = ui_component; - if (ui_component != NULL) { - bonobo_object_ref (BONOBO_OBJECT (ui_component)); - setup_standard_verbs (search_bar); - setup_bonobo_menus (search_bar); - } -} - -void -e_search_bar_set_search_text (ESearchBar *search_bar, - const gchar *text) -{ - EIconEntry *icon_entry; - GtkWidget *entry; - - if (search_bar->lite) - return; - - if (search_bar->lite) - return; - - verb_name = verb_name_from_id (id); - path = g_strconcat ("/commands/", verb_name, NULL); - g_free (verb_name); - - icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); - entry = e_icon_entry_get_entry (icon_entry); - - text = (text != NULL) ? text : ""; - gtk_entry_set_text (GTK_ENTRY (entry), text); - g_object_notify (G_OBJECT (search_bar), "search-text"); -} - -gint -e_search_bar_get_search_value (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - - /* FIXME */ - return 0; -} - -void -e_search_bar_set_search_value (ESearchBar *search_bar, - gint value) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - if (!search_bar->viewoption_menu) - return; - - /* FIXME */ - - g_object_notify (G_OBJECT (search_bar), "search-value"); -} - -gboolean -e_search_bar_get_search_visible (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - - if (!search_bar->option_menu) - return; - row = find_id (search_bar->option_menu, id, "EsbItemId", NULL); - if (row == -1) - return; - - if (id>=0) - search_bar->last_search_option = id; - search_bar->item_id = id; - gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row); - - if (!search_bar->block_search) - emit_query_changed (search_bar); - - if (!search_bar->lite) - update_clear_menuitem_sensitive (search_bar); -} - -void -e_search_bar_set_search_visible (ESearchBar *search_bar, - gboolean visible) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (visible) { - gtk_widget_show (search_bar->priv->search_label); - gtk_widget_show (search_bar->priv->search_entry); - } else { - gtk_widget_hide (search_bar->priv->search_label); - gtk_widget_hide (search_bar->priv->search_entry); - } - - g_object_notify (G_OBJECT (search_bar), "search-visible"); -} - -GtkRadioAction * -e_search_bar_get_scope_action (ESearchBar *search_bar) -{ - EActionComboBox *combo_box; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - - return e_action_combo_box_get_action (combo_box); -} - -void -e_search_bar_set_scope_action (ESearchBar *search_bar, - GtkRadioAction *action) -{ - EActionComboBox *combo_box; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (GTK_IS_RADIO_ACTION (action)); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - - e_action_combo_box_set_action (combo_box, action); - g_object_notify (G_OBJECT (search_bar), "scope-action"); -} - -gint -e_search_bar_get_scope_value (ESearchBar *search_bar) -{ - EActionComboBox *combo_box; - - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - - return e_action_combo_box_get_current_value (combo_box); -} - -void -e_search_bar_set_scope_value (ESearchBar *search_bar, - gint value) -{ - EActionComboBox *combo_box; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - - e_action_combo_box_set_current_value (combo_box, value); - g_object_notify (G_OBJECT (search_bar), "scope-value"); -} - -gboolean -e_search_bar_get_scope_visible (ESearchBar *search_bar) -{ - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - - return GTK_WIDGET_VISIBLE (search_bar->priv->scope_combo_box); -} - -void -e_search_bar_set_scope_visible (ESearchBar *search_bar, - gboolean visible) -{ - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - if (visible) { - gtk_widget_show (search_bar->priv->scope_label); - gtk_widget_show (search_bar->priv->scope_combo_box); - } else { - gtk_widget_hide (search_bar->priv->scope_label); - gtk_widget_hide (search_bar->priv->scope_combo_box); - } - - g_object_notify (G_OBJECT (search_bar), "scope-visible"); -} - -static void -search_bar_rule_changed_cb (FilterRule *rule, - GtkDialog *dialog) -{ - /* FIXME Think this does something with sensitivity. */ -} - -void -e_search_bar_save_search_dialog (ESearchBar *search_bar, - const gchar *filename) -{ - RuleContext *context; - FilterRule *rule; - GtkWidget *dialog; - GtkWidget *parent; - GtkWidget *widget; - const gchar *search_text; - gchar *rule_name; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (filename != NULL); - - g_return_if_fail (search_bar->priv->current_query != NULL); - - rule = filter_rule_clone (search_bar->priv->current_query); - search_text = e_search_bar_get_search_text (search_bar); - if (search_text == NULL || *search_text == '\0') - search_text = "''"; - - rule_name = g_strdup_printf ("%s %s", rule->name, search_text); - filter_rule_set_name (rule, rule_name); - g_free (rule_name); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (search_bar)); - - dialog = gtk_dialog_new_with_buttons ( - _("Save Search"), GTK_WINDOW (parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300); - gtk_container_set_border_width ( - GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); - gtk_container_set_border_width ( - GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); - - context = search_bar->priv->context; - widget = filter_rule_get_widget (rule, context); - filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); - gtk_container_set_border_width (GTK_CONTAINER (widget), 12); - gtk_box_pack_start ( - GTK_BOX (GTK_DIALOG (dialog)->vbox), - widget, TRUE, TRUE, 0); - - g_signal_connect ( - rule, "changed", - G_CALLBACK (search_bar_rule_changed_cb), - dialog); - - search_bar_rule_changed_cb (rule, GTK_DIALOG (dialog)); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - if (filter_rule_validate (rule)) { - rule_context_add_rule (context, rule); - rule_context_save (context, filename); - } - } - - gtk_widget_destroy (dialog); -} diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h deleted file mode 100644 index 41bebf96fd..0000000000 --- a/widgets/misc/e-search-bar.h +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-search-bar.h - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Author: Chris Lahey - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef E_SEARCH_BAR_H -#define E_SEARCH_BAR_H - -#include -#include - -/* Standard GObject macros */ -#define E_TYPE_SEARCH_BAR \ - (e_search_bar_get_type ()) -#define E_SEARCH_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBar)) -#define E_SEARCH_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SEARCH_BAR, ESearchBarClass)) -#define E_IS_SEARCH_BAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SEARCH_BAR)) -#define E_IS_SEARCH_BAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SEARCH_BAR)) -#define E_SEARCH_BAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SEARCH_BAR, ESearchBarClass)) - -/* Action Names */ -#define E_SEARCH_BAR_ACTION_CLEAR "search-clear" -#define E_SEARCH_BAR_ACTION_FIND "search-find" -#define E_SEARCH_BAR_ACTION_TYPE "search-type" - -G_BEGIN_DECLS - -typedef struct _ESearchBar ESearchBar; -typedef struct _ESearchBarClass ESearchBarClass; -typedef struct _ESearchBarPrivate ESearchBarPrivate; - -struct _ESearchBar { - GtkHBox parent; - - BonoboUIComponent *ui_component; - - GSList *menu_items; - - /* item specific fields */ - GtkWidget *option; - GtkWidget *entry; - GtkWidget *suboption; /* an option menu for the choices associated with some options */ - - /* PRIVATE */ - GtkWidget *dropdown_holder; /* holds the dropdown */ - GtkWidget *option_menu; - GtkWidget *suboption_menu; - GtkWidget *option_button; - GtkWidget *clear_button; - GtkWidget *entry_box; - GtkWidget *icon_entry; - - /* show option widgets */ - GtkWidget *viewoption_box; - GtkWidget *viewoption; /* an option menu for the choices associated with some search options */ - GtkWidget *viewoption_menu; - - /* search scope widgets */ - GtkWidget *scopeoption_box; - GtkWidget *scopeoption; /* an option menu for the choices associated with scope search */ - GtkWidget *scopeoption_menu; - - guint pending_activate; - - /* The currently-selected item & subitem */ - gint item_id; - gint viewitem_id; /* Current View Id */ - gint scopeitem_id; /* Scope of search */ - gint last_search_option; - - gboolean block_search; - gboolean lite; -}; - -struct _ESearchBarClass { - GtkHBoxClass parent_class; -}; - - -GType e_search_bar_get_type (void); -void e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items); -GtkWidget *e_search_bar_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items); -GtkWidget *e_search_bar_lite_new (ESearchBarItem *menu_items, - ESearchBarItem *option_items); - -void e_search_bar_set_ui_component (ESearchBar *search_bar, - BonoboUIComponent *ui_component); - -void e_search_bar_set_menu (ESearchBar *search_bar, - ESearchBarItem *menu_items); -void e_search_bar_add_menu (ESearchBar *search_bar, - ESearchBarItem *menu_item); - -void e_search_bar_set_option (ESearchBar *search_bar, - ESearchBarItem *option_items); -void e_search_bar_paint (ESearchBar *search_bar); -void e_search_bar_set_viewoption (ESearchBar *search_bar, - gint option_id, - ESearchBarItem *subitems); - -void e_search_bar_set_menu_sensitive (ESearchBar *search_bar, - gint id, - gboolean state); - -void e_search_bar_set_item_id (ESearchBar *search_bar, - gint id); -void e_search_bar_set_item_menu (ESearchBar *search_bar, - gint id); -gint e_search_bar_get_item_id (ESearchBar *search_bar); - -G_END_DECLS - -#endif /* E_SEARCH_BAR_H */ -- cgit v1.2.3 From 477736ea33b961f72a583f320632fd12c411b164 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 12 Jun 2009 21:45:52 -0400 Subject: =?UTF-8?q?Bug=20585554=20=E2=80=93=20Opening=20PDF=20attachment?= =?UTF-8?q?=20crashes=20in=20e=5Fattachment=5Fopen=5Fhandle=5Ferror()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widgets/misc/e-attachment.c | 47 ++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index ba2811d5d9..7735be8872 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1957,7 +1957,6 @@ attachment_open_file (GFile *file, { GdkAppLaunchContext *context; GSimpleAsyncResult *simple; - GList *file_list; gboolean success; GError *error = NULL; @@ -1965,41 +1964,29 @@ attachment_open_file (GFile *file, simple = open_context->simple; open_context->simple = NULL; - /* Find a default app based on content type. */ - if (open_context->app_info == NULL) { - EAttachment *attachment; - GFileInfo *file_info; - const gchar *content_type; - - attachment = open_context->attachment; - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) - goto exit; - - content_type = g_file_info_get_content_type (file_info); - if (content_type == NULL) - goto exit; + context = gdk_app_launch_context_new (); - open_context->app_info = g_app_info_get_default_for_type ( - content_type, FALSE); + if (open_context->app_info != NULL) { + GList *file_list; + + file_list = g_list_prepend (NULL, file); + success = g_app_info_launch ( + open_context->app_info, file_list, + G_APP_LAUNCH_CONTEXT (context), &error); + g_list_free (file_list); + } else { + gchar *uri; + + uri = g_file_get_uri (file); + success = g_app_info_launch_default_for_uri ( + uri, G_APP_LAUNCH_CONTEXT (context), &error); + g_free (uri); } - if (open_context->app_info == NULL) - goto exit; - - context = gdk_app_launch_context_new (); - file_list = g_list_prepend (NULL, file); - - success = g_app_info_launch ( - open_context->app_info, file_list, - G_APP_LAUNCH_CONTEXT (context), &error); + g_object_unref (context); g_simple_async_result_set_op_res_gboolean (simple, success); - g_list_free (file_list); - g_object_unref (context); - -exit: if (error != NULL) { g_simple_async_result_set_from_error (simple, error); g_error_free (error); -- cgit v1.2.3 From dfefb7f6862425dee32d19048ce7cda623a6f9e7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 15 Jun 2009 00:12:25 -0400 Subject: Clean up EImageChooser. --- widgets/misc/e-image-chooser.c | 587 +++++++++++++++++++---------------------- widgets/misc/e-image-chooser.h | 66 +++-- 2 files changed, 311 insertions(+), 342 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index 3c83cb1048..2f451543e3 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -1,4 +1,6 @@ /* + * e-image-chooser.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 @@ -13,9 +15,6 @@ * License along with the program; if not, see * * - * Authors: - * Chris Toshok - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ @@ -28,21 +27,20 @@ #include #include "e-image-chooser.h" -#include "e-util/e-icon-factory.h" #include "e-util/e-util.h" -struct _EImageChooserPrivate { +#define E_IMAGE_CHOOSER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserPrivate)) +struct _EImageChooserPrivate { GtkWidget *frame; GtkWidget *image; - GtkWidget *browse_button; gchar *image_buf; - gint image_buf_size; - gint image_width; - gint image_height; - - gboolean editable; + gint image_buf_size; + gint image_width; + gint image_height; }; enum { @@ -50,185 +48,24 @@ enum { LAST_SIGNAL }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; -static gint image_chooser_signals [LAST_SIGNAL] = { 0 }; - -static void e_image_chooser_init (EImageChooser *chooser); -static void e_image_chooser_class_init (EImageChooserClass *klass); -#if 0 -static void e_image_chooser_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void e_image_chooser_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -#endif -static void e_image_chooser_dispose (GObject *object); - -static gboolean image_drag_motion_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, guint time, EImageChooser *chooser); -static void image_drag_leave_cb (GtkWidget *widget, - GdkDragContext *context, - guint time, EImageChooser *chooser); -static gboolean image_drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, guint time, EImageChooser *chooser); -static void image_drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, - GtkSelectionData *selection_data, - guint info, guint time, EImageChooser *chooser); - -static GtkObjectClass *parent_class = NULL; -#define PARENT_TYPE GTK_TYPE_VBOX - -enum DndTargetType { - DND_TARGET_TYPE_URI_LIST -}; #define URI_LIST_TYPE "text/uri-list" -static GtkTargetEntry image_drag_types[] = { - { (gchar *) URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST }, -}; -static const gint num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]); - -GtkWidget * -e_image_chooser_new (void) -{ - return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL); -} - -GType -e_image_chooser_get_type (void) -{ - static GType eic_type = 0; - - if (!eic_type) { - static const GTypeInfo eic_info = { - sizeof (EImageChooserClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_image_chooser_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EImageChooser), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_image_chooser_init, - }; - - eic_type = g_type_register_static (PARENT_TYPE, "EImageChooser", &eic_info, 0); - } - - return eic_type; -} - - -static void -e_image_chooser_class_init (EImageChooserClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (PARENT_TYPE); - - image_chooser_signals [CHANGED] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EImageChooserClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* - object_class->set_property = e_image_chooser_set_property; - object_class->get_property = e_image_chooser_get_property; - */ - object_class->dispose = e_image_chooser_dispose; -} - -#ifdef UI_CHANGE_OK -static void -browse_for_image_cb (GtkWidget *button, gpointer data) -{ -} -#endif - -static void -e_image_chooser_init (EImageChooser *chooser) -{ - EImageChooserPrivate *priv; - GtkWidget *alignment; - - priv = chooser->priv = g_new0 (EImageChooserPrivate, 1); - - alignment = gtk_alignment_new (0, 0, 0, 0); - priv->frame = gtk_frame_new (""); - priv->image = gtk_image_new (); - - gtk_container_add (GTK_CONTAINER (alignment), priv->image); - -#ifdef UI_CHANGE_OK - priv->browse_button = gtk_button_new_with_label (_("Choose Image")); -#endif - - gtk_frame_set_shadow_type (GTK_FRAME (priv->frame), GTK_SHADOW_NONE); - - gtk_container_add (GTK_CONTAINER (priv->frame), alignment); - gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE); - gtk_box_pack_start (GTK_BOX (chooser), priv->frame, TRUE, TRUE, 0); -#ifdef UI_CHANGE_OK - gtk_box_pack_start (GTK_BOX (chooser), priv->browse_button, FALSE, FALSE, 0); - - g_signal_connect (priv->browse_button, "clicked", G_CALLBACK (browse_for_image_cb), NULL); -#endif - - gtk_drag_dest_set (priv->image, 0, image_drag_types, num_image_drag_types, GDK_ACTION_COPY); - g_signal_connect (priv->image, - "drag_motion", G_CALLBACK (image_drag_motion_cb), chooser); - g_signal_connect (priv->image, - "drag_leave", G_CALLBACK (image_drag_leave_cb), chooser); - g_signal_connect (priv->image, - "drag_drop", G_CALLBACK (image_drag_drop_cb), chooser); - g_signal_connect (priv->image, - "drag_data_received", G_CALLBACK (image_drag_data_received_cb), chooser); - - gtk_widget_show_all (priv->frame); -#ifdef UI_CHANGE_OK - gtk_widget_show (priv->browse_button); -#endif - - /* we default to being editable */ - priv->editable = TRUE; -} - -static void -e_image_chooser_dispose (GObject *object) -{ - EImageChooser *eic = E_IMAGE_CHOOSER (object); - - if (eic->priv) { - EImageChooserPrivate *priv = eic->priv; - - if (priv->image_buf) { - g_free (priv->image_buf); - priv->image_buf = NULL; - } - - g_free (eic->priv); - eic->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - - static gboolean set_image_from_data (EImageChooser *chooser, - gchar *data, gint length) + gchar *data, + gint length) { - gboolean rv = FALSE; - GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); + GdkPixbufLoader *loader; GdkPixbuf *pixbuf; + gfloat scale; + gint new_height; + gint new_width; - gdk_pixbuf_loader_write (loader, (guchar *)data, length, NULL); + loader = gdk_pixbuf_loader_new (); + gdk_pixbuf_loader_write (loader, (guchar *) data, length, NULL); gdk_pixbuf_loader_close (loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); @@ -237,98 +74,92 @@ set_image_from_data (EImageChooser *chooser, g_object_unref (loader); - if (pixbuf) { - GdkPixbuf *scaled; - GdkPixbuf *composite; - - gfloat scale; - gint new_height, new_width; - - new_height = gdk_pixbuf_get_height (pixbuf); - new_width = gdk_pixbuf_get_width (pixbuf); - - printf ("new dimensions = (%d,%d)\n", new_width, new_height); - - if (chooser->priv->image_height == 0 - && chooser->priv->image_width == 0) { - printf ("initial setting of an image. no scaling\n"); - scale = 1.0; - } - else if (chooser->priv->image_height < new_height - || chooser->priv->image_width < new_width) { - /* we need to scale down */ - printf ("we need to scale down\n"); - if (new_height > new_width) - scale = (gfloat)chooser->priv->image_height / new_height; - else - scale = (gfloat)chooser->priv->image_width / new_width; - } - else { - /* we need to scale up */ - printf ("we need to scale up\n"); - if (new_height > new_width) - scale = (gfloat)new_height / chooser->priv->image_height; - else - scale = (gfloat)new_width / chooser->priv->image_width; - } - - printf ("scale = %g\n", scale); + if (pixbuf == NULL) + return FALSE; - if (scale == 1.0) { - gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), pixbuf); + new_height = gdk_pixbuf_get_height (pixbuf); + new_width = gdk_pixbuf_get_width (pixbuf); + + if (chooser->priv->image_height == 0 + && chooser->priv->image_width == 0) { + scale = 1.0; + } else if (chooser->priv->image_height < new_height + || chooser->priv->image_width < new_width) { + /* we need to scale down */ + if (new_height > new_width) + scale = (gfloat)chooser->priv->image_height / new_height; + else + scale = (gfloat)chooser->priv->image_width / new_width; + } else { + /* we need to scale up */ + if (new_height > new_width) + scale = (gfloat)new_height / chooser->priv->image_height; + else + scale = (gfloat)new_width / chooser->priv->image_width; + } - chooser->priv->image_width = new_width; - chooser->priv->image_height = new_height; - } - else { - new_width *= scale; - new_height *= scale; - new_width = MIN (new_width, chooser->priv->image_width); - new_height = MIN (new_height, chooser->priv->image_height); + if (scale == 1.0) { + gtk_image_set_from_pixbuf ( + GTK_IMAGE (chooser->priv->image), pixbuf); + chooser->priv->image_width = new_width; + chooser->priv->image_height = new_height; + } else { + GdkPixbuf *scaled; + GdkPixbuf *composite; - printf ("new scaled dimensions = (%d,%d)\n", new_width, new_height); + new_width *= scale; + new_height *= scale; + new_width = MIN (new_width, chooser->priv->image_width); + new_height = MIN (new_height, chooser->priv->image_height); - scaled = e_icon_factory_pixbuf_scale (pixbuf, new_width, new_height); + scaled = gdk_pixbuf_scale_simple ( + pixbuf, new_width, new_height, + GDK_INTERP_BILINEAR); - composite = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (pixbuf), - chooser->priv->image_width, chooser->priv->image_height); + composite = gdk_pixbuf_new ( + GDK_COLORSPACE_RGB, TRUE, + gdk_pixbuf_get_bits_per_sample (pixbuf), + chooser->priv->image_width, + chooser->priv->image_height); - gdk_pixbuf_fill (composite, 0x00000000); + gdk_pixbuf_fill (composite, 0x00000000); - gdk_pixbuf_copy_area (scaled, 0, 0, new_width, new_height, - composite, - chooser->priv->image_width / 2 - new_width / 2, - chooser->priv->image_height / 2 - new_height / 2); + gdk_pixbuf_copy_area ( + scaled, 0, 0, new_width, new_height, + composite, + chooser->priv->image_width / 2 - new_width / 2, + chooser->priv->image_height / 2 - new_height / 2); - gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), composite); - g_object_unref (scaled); - g_object_unref (composite); - } + gtk_image_set_from_pixbuf ( + GTK_IMAGE (chooser->priv->image), composite); - g_object_unref (pixbuf); + g_object_unref (scaled); + g_object_unref (composite); + } - g_free (chooser->priv->image_buf); - chooser->priv->image_buf = data; - chooser->priv->image_buf_size = length; + g_object_unref (pixbuf); - g_signal_emit (chooser, - image_chooser_signals [CHANGED], 0); + g_free (chooser->priv->image_buf); + chooser->priv->image_buf = data; + chooser->priv->image_buf_size = length; - rv = TRUE; - } + g_signal_emit (chooser, signals[CHANGED], 0); - return rv; + return TRUE; } static gboolean image_drag_motion_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, guint time, EImageChooser *chooser) + GdkDragContext *context, + gint x, + gint y, + guint time, + EImageChooser *chooser) { + GtkFrame *frame; GList *p; - if (!chooser->priv->editable) - return FALSE; + frame = GTK_FRAME (chooser->priv->frame); for (p = context->targets; p != NULL; p = p->next) { gchar *possible_type; @@ -337,37 +168,45 @@ image_drag_motion_cb (GtkWidget *widget, if (!strcmp (possible_type, URI_LIST_TYPE)) { g_free (possible_type); gdk_drag_status (context, GDK_ACTION_COPY, time); - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_IN); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_IN); return TRUE; } g_free (possible_type); } - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); + return FALSE; } static void image_drag_leave_cb (GtkWidget *widget, - GdkDragContext *context, - guint time, EImageChooser *chooser) + GdkDragContext *context, + guint time, + EImageChooser *chooser) { - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE); + GtkFrame *frame; + + frame = GTK_FRAME (chooser->priv->frame); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); } static gboolean image_drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, guint time, EImageChooser *chooser) + GdkDragContext *context, + gint x, + gint y, + guint time, + EImageChooser *chooser) { + GtkFrame *frame; GList *p; - if (!chooser->priv->editable) - return FALSE; + frame = GTK_FRAME (chooser->priv->frame); if (context->targets == NULL) { - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); return FALSE; } @@ -377,76 +216,204 @@ image_drag_drop_cb (GtkWidget *widget, possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data)); if (!strcmp (possible_type, URI_LIST_TYPE)) { g_free (possible_type); - gtk_drag_get_data (widget, context, - GDK_POINTER_TO_ATOM (p->data), - time); - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE); + gtk_drag_get_data ( + widget, context, + GDK_POINTER_TO_ATOM (p->data), time); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); return TRUE; } g_free (possible_type); } - gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE); + gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE); + return FALSE; } static void image_drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, gint y, - GtkSelectionData *selection_data, - guint info, guint time, EImageChooser *chooser) + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time, + EImageChooser *chooser) { - gchar *target_type; gboolean handled = FALSE; + gchar **uris; + gchar *buf = NULL; + gsize read = 0; + GError *error = NULL; - target_type = gdk_atom_name (selection_data->target); + uris = gtk_selection_data_get_uris (selection_data); - if (!strcmp (target_type, URI_LIST_TYPE)) { - GError *error = NULL; - gchar *uri; - gchar *nl = strstr ((gchar *)selection_data->data, "\r\n"); - gchar *buf = NULL; - gsize read = 0; + if (uris == NULL) + goto exit; - if (nl) - uri = g_strndup ((gchar *)selection_data->data, nl - (gchar *)selection_data->data); - else - uri = g_strdup ((gchar *)selection_data->data); + if (e_util_read_file (uris[0], TRUE, &buf, &read, &error) && read > 0 && buf) + handled = set_image_from_data (chooser, buf, read); - if (e_util_read_file (uri, TRUE, &buf, &read, &error) && read > 0 && buf) { - if (set_image_from_data (chooser, buf, read)) { - handled = TRUE; - } - } + g_free (buf); - g_free (buf); - g_free (uri); + g_strfreev (uris); - if (error) { - g_warning ("%s", error->message); - g_error_free (error); - } + if (error) { + g_warning ("%s", error->message); + g_error_free (error); } +exit: gtk_drag_finish (context, handled, FALSE, time); } - +static void +image_chooser_dispose (GObject *object) +{ + EImageChooserPrivate *priv; + + priv = E_IMAGE_CHOOSER_GET_PRIVATE (object); + + if (priv->frame != NULL) { + g_object_unref (priv->frame); + priv->frame = NULL; + } + + if (priv->image != NULL) { + g_object_unref (priv->image); + priv->image = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +image_chooser_finalize (GObject *object) +{ + EImageChooserPrivate *priv; + + priv = E_IMAGE_CHOOSER_GET_PRIVATE (object); + + g_free (priv->image_buf); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +e_image_chooser_class_init (EImageChooserClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EImageChooserPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = image_chooser_dispose; + object_class->finalize = image_chooser_finalize; + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EImageChooserClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +e_image_chooser_init (EImageChooser *chooser) +{ + GtkWidget *container; + GtkWidget *widget; + + chooser->priv = E_IMAGE_CHOOSER_GET_PRIVATE (chooser); + + container = GTK_WIDGET (chooser); + + widget = gtk_frame_new (""); + gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_NONE); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + chooser->priv->frame = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_alignment_new (0, 0, 0, 0); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_image_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + chooser->priv->image = g_object_ref (widget); + gtk_widget_show (widget); + + gtk_drag_dest_set (widget, 0, NULL, 0, GDK_ACTION_COPY); + gtk_drag_dest_add_uri_targets (widget); + + g_signal_connect ( + widget, "drag-motion", + G_CALLBACK (image_drag_motion_cb), chooser); + g_signal_connect ( + widget, "drag-leave", + G_CALLBACK (image_drag_leave_cb), chooser); + g_signal_connect ( + widget, "drag-drop", + G_CALLBACK (image_drag_drop_cb), chooser); + g_signal_connect ( + widget, "drag-data-received", + G_CALLBACK (image_drag_data_received_cb), chooser); +} + +GType +e_image_chooser_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EImageChooserClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) e_image_chooser_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EImageChooser), + 0, /* n_preallocs */ + (GInstanceInitFunc) e_image_chooser_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_VBOX, "EImageChooser", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_image_chooser_new (void) +{ + return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL); +} gboolean -e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename) +e_image_chooser_set_from_file (EImageChooser *chooser, + const gchar *filename) { gchar *data; gsize data_length; g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); - g_return_val_if_fail (filename, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); - if (!g_file_get_contents (filename, &data, &data_length, NULL)) { + if (!g_file_get_contents (filename, &data, &data_length, NULL)) return FALSE; - } if (!set_image_from_data (chooser, data, data_length)) g_free (data); @@ -454,18 +421,10 @@ e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename) return TRUE; } -void -e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable) -{ - g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser)); - - chooser->priv->editable = editable; - - gtk_widget_set_sensitive (chooser->priv->browse_button, editable); -} - gboolean -e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length) +e_image_chooser_get_image_data (EImageChooser *chooser, + gchar **data, + gsize *data_length) { g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE); g_return_val_if_fail (data != NULL, FALSE); @@ -479,7 +438,9 @@ e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *dat } gboolean -e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length) +e_image_chooser_set_image_data (EImageChooser *chooser, + gchar *data, + gsize data_length) { gchar *buf; diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h index be2d427291..7116500dc4 100644 --- a/widgets/misc/e-image-chooser.h +++ b/widgets/misc/e-image-chooser.h @@ -1,4 +1,5 @@ /* + * e-image-chooser.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,54 +15,61 @@ * License along with the program; if not, see * * - * Authors: - * Chris Toshok - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef _E_IMAGE_CHOOSER_H_ -#define _E_IMAGE_CHOOSER_H_ +#ifndef E_IMAGE_CHOOSER_H +#define E_IMAGE_CHOOSER_H #include -G_BEGIN_DECLS +/* Standard GObject macros */ +#define E_TYPE_IMAGE_CHOOSER \ + (e_image_chooser_get_type ()) +#define E_IMAGE_CHOOSER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser)) +#define E_IMAGE_CHOOSER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) +#define E_IS_IMAGE_CHOOSER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_IMAGE_CHOOSER)) +#define E_IS_IMAGE_CHOOSER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_IMAGE_CHOOSER)) +#define E_IMAGE_CHOOSER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) -#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ()) -#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser)) -#define E_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_IMAGE_CHOOSER, EImageChooserClass)) -#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER)) -#define E_IS_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_IMAGE_CHOOSER)) +G_BEGIN_DECLS -typedef struct _EImageChooser EImageChooser; -typedef struct _EImageChooserClass EImageChooserClass; +typedef struct _EImageChooser EImageChooser; +typedef struct _EImageChooserClass EImageChooserClass; typedef struct _EImageChooserPrivate EImageChooserPrivate; -struct _EImageChooser -{ +struct _EImageChooser { GtkVBox parent; - EImageChooserPrivate *priv; }; -struct _EImageChooserClass -{ +struct _EImageChooserClass { GtkVBoxClass parent_class; /* signals */ void (*changed) (EImageChooser *chooser); - - }; -GtkWidget *e_image_chooser_new (void); -GType e_image_chooser_get_type (void); - -gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename); -gboolean e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length); -void e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable); - -gboolean e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length); +GType e_image_chooser_get_type (void); +GtkWidget * e_image_chooser_new (void); +gboolean e_image_chooser_set_from_file (EImageChooser *chooser, + const gchar *filename); +gboolean e_image_chooser_set_image_data (EImageChooser *chooser, + gchar *data, + gsize data_length); +gboolean e_image_chooser_get_image_data (EImageChooser *chooser, + gchar **data, + gsize *data_length); -#endif /* _E_IMAGE_CHOOSER_H_ */ +#endif /* E_IMAGE_CHOOSER_H */ -- cgit v1.2.3 From 00d56cd32c5d0a7f49567d5241ba0d6fd80940bb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 18 Jun 2009 10:50:51 -0400 Subject: Use G_BEGIN_DECLS / G_END_DECLS macros. --- widgets/misc/a11y/ea-calendar-cell.h | 8 ++------ widgets/misc/a11y/ea-calendar-item.h | 8 ++------ widgets/misc/e-calendar-item.h | 8 ++------ widgets/misc/e-calendar.h | 8 ++------ widgets/misc/e-canvas-vbox.h | 9 ++------- widgets/misc/e-canvas.h | 9 ++------- widgets/misc/e-selection-model-array.h | 8 ++------ widgets/misc/e-selection-model-simple.h | 8 ++------ widgets/misc/e-selection-model.h | 8 ++------ widgets/misc/e-url-entry.h | 9 ++------- 10 files changed, 20 insertions(+), 63 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/a11y/ea-calendar-cell.h b/widgets/misc/a11y/ea-calendar-cell.h index be35c66312..fa68fdca55 100644 --- a/widgets/misc/a11y/ea-calendar-cell.h +++ b/widgets/misc/a11y/ea-calendar-cell.h @@ -26,9 +26,7 @@ #include #include "misc/e-calendar-item.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ()) #define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell)) @@ -83,8 +81,6 @@ struct _EaCalendarCellClass AtkObject* ea_calendar_cell_new (GObject *gobj); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __EA_CALENDAR_CELL_H__ */ diff --git a/widgets/misc/a11y/ea-calendar-item.h b/widgets/misc/a11y/ea-calendar-item.h index b5f1b0ce81..36cc671a3b 100644 --- a/widgets/misc/a11y/ea-calendar-item.h +++ b/widgets/misc/a11y/ea-calendar-item.h @@ -26,9 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ()) #define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem)) @@ -64,9 +62,7 @@ gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem, gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, gint year, gint month); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h index 926ba1c077..f86fc4fd79 100644 --- a/widgets/misc/e-calendar-item.h +++ b/widgets/misc/e-calendar-item.h @@ -27,9 +27,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS /* * ECalendarItem - canvas item displaying a calendar. @@ -367,8 +365,6 @@ gint e_calendar_item_get_week_number (ECalendarItem *calitem, void e_calendar_item_style_set (GtkWidget *widget, ECalendarItem *calitem); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_CALENDAR_ITEM_H_ */ diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h index d6b9f653d8..c281e7436b 100644 --- a/widgets/misc/e-calendar.h +++ b/widgets/misc/e-calendar.h @@ -27,9 +27,7 @@ #include #include "e-calendar-item.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS /* * ECalendar - displays a table of monthly calendars, allowing highlighting @@ -110,8 +108,6 @@ void e_calendar_get_border_size (ECalendar *cal, void e_calendar_set_focusable (ECalendar *cal, gboolean focusable); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_CALENDAR_H_ */ diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h index 7fa38fa778..fb049c3e9c 100644 --- a/widgets/misc/e-canvas-vbox.h +++ b/widgets/misc/e-canvas-vbox.h @@ -26,10 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS /* ECanvasVbox - A canvas item container. * @@ -84,9 +81,7 @@ void e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *i void e_canvas_vbox_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item); GType e_canvas_vbox_get_type (void); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __E_CANVAS_VBOX_H__ */ diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index 5f60fc4046..58994d6e29 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -26,10 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS /* ECanvas - A class derived from canvas for the purpose of adding * evolution specific canvas hacks. @@ -148,9 +145,7 @@ void e_canvas_popup_tooltip (ECanvas gint y); void e_canvas_hide_tooltip (ECanvas *canvas); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __E_CANVAS_H__ */ diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index be21a5557e..3f69fca342 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -28,9 +28,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define E_SELECTION_MODEL_ARRAY_TYPE (e_selection_model_array_get_type ()) #define E_SELECTION_MODEL_ARRAY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_SELECTION_MODEL_ARRAY_TYPE, ESelectionModelArray)) @@ -89,9 +87,7 @@ void e_selection_model_array_confirm_row_count (ESelectionModelArray *esm); /* Protected Virtual Function */ gint e_selection_model_array_get_row_count (ESelectionModelArray *esm); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_SELECTION_MODEL_ARRAY_H_ */ diff --git a/widgets/misc/e-selection-model-simple.h b/widgets/misc/e-selection-model-simple.h index 8db463b32f..2433543ade 100644 --- a/widgets/misc/e-selection-model-simple.h +++ b/widgets/misc/e-selection-model-simple.h @@ -26,9 +26,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define E_SELECTION_MODEL_SIMPLE_TYPE (e_selection_model_simple_get_type ()) #define E_SELECTION_MODEL_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_SELECTION_MODEL_SIMPLE_TYPE, ESelectionModelSimple)) @@ -62,9 +60,7 @@ void e_selection_model_simple_move_row (ESelectionModelS void e_selection_model_simple_set_row_count (ESelectionModelSimple *selection, gint row_count); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_SELECTION_MODEL_SIMPLE_H_ */ diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index 16194000a5..c87ccf960e 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -27,9 +27,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define E_SELECTION_MODEL_TYPE (e_selection_model_get_type ()) #define E_SELECTION_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_SELECTION_MODEL_TYPE, ESelectionModel)) @@ -160,9 +158,7 @@ void e_selection_model_selection_row_changed (ESelectionModel *selection, gint row); void e_selection_model_selection_changed (ESelectionModel *selection); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_SELECTION_MODEL_H_ */ diff --git a/widgets/misc/e-url-entry.h b/widgets/misc/e-url-entry.h index a4edc51df2..e5c83323db 100644 --- a/widgets/misc/e-url-entry.h +++ b/widgets/misc/e-url-entry.h @@ -29,10 +29,7 @@ #include -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS #define E_TYPE_URL_ENTRY (e_url_entry_get_type ()) #define E_URL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_URL_ENTRY, EUrlEntry)) @@ -61,8 +58,6 @@ GType e_url_entry_get_type (void); GtkWidget *e_url_entry_new (void); GtkWidget *e_url_entry_get_entry (EUrlEntry *url_entry); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* _E_URL_ENTRY_H_ */ -- cgit v1.2.3 From 94ec01deda562c323ead315c4ea48043db68b8d0 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 19 Jun 2009 16:58:10 -0400 Subject: Remove a weak pointer when disposing EAttachmentHandler. --- widgets/misc/e-attachment-handler.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c index 0a6ed0505d..303fc33cc2 100644 --- a/widgets/misc/e-attachment-handler.c +++ b/widgets/misc/e-attachment-handler.c @@ -90,6 +90,23 @@ attachment_handler_constructed (GObject *object) * something here in the future. */ } +static void +attachment_handler_dispose (GObject *object) +{ + EAttachmentHandlerPrivate *priv; + + priv = E_ATTACHMENT_HANDLER_GET_PRIVATE (object); + + if (priv->view != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->view), &priv->view); + priv->view = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + static void attachment_handler_class_init (EAttachmentHandlerClass *class) { @@ -102,6 +119,7 @@ attachment_handler_class_init (EAttachmentHandlerClass *class) object_class->set_property = attachment_handler_set_property; object_class->get_property = attachment_handler_get_property; object_class->constructed = attachment_handler_constructed; + object_class->dispose = attachment_handler_dispose; g_object_class_install_property ( object_class, -- cgit v1.2.3 From f0d3f3afdfa314e1e8cd7d8da790878008a46aad Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 24 Jun 2009 12:59:33 -0400 Subject: Radically reorganize source code. - Collect all shell modules into a new top-level 'modules' directory: $(top_srcdir)/modules/addressbook $(top_srcdir)/modules/calendar $(top_srcdir)/modules/mail Nothing is allowed to link to these, not plugins nor other modules. THIS SOLVES BUG #571275 AND OPENS THE DOOR TO PORTING TO MAC OS X. - Mimic the libevolution-mail-shared library from master (except drop the "shared" suffix) and have libevolution-mail-importers and all mail-related plugins link to it. - Discard the a11y subdirectories and have the files live alongside their counterpart widgets. --- widgets/misc/Makefile.am | 12 +- widgets/misc/a11y/ea-calendar-cell.c | 387 ---------- widgets/misc/a11y/ea-calendar-cell.h | 86 --- widgets/misc/a11y/ea-calendar-item.c | 1314 ---------------------------------- widgets/misc/a11y/ea-calendar-item.h | 68 -- widgets/misc/a11y/ea-widgets.c | 32 - widgets/misc/a11y/ea-widgets.h | 32 - widgets/misc/e-calendar-item.c | 2 +- widgets/misc/ea-calendar-cell.c | 387 ++++++++++ widgets/misc/ea-calendar-cell.h | 86 +++ widgets/misc/ea-calendar-item.c | 1314 ++++++++++++++++++++++++++++++++++ widgets/misc/ea-calendar-item.h | 68 ++ widgets/misc/ea-widgets.c | 32 + widgets/misc/ea-widgets.h | 32 + 14 files changed, 1926 insertions(+), 1926 deletions(-) delete mode 100644 widgets/misc/a11y/ea-calendar-cell.c delete mode 100644 widgets/misc/a11y/ea-calendar-cell.h delete mode 100644 widgets/misc/a11y/ea-calendar-item.c delete mode 100644 widgets/misc/a11y/ea-calendar-item.h delete mode 100644 widgets/misc/a11y/ea-widgets.c delete mode 100644 widgets/misc/a11y/ea-widgets.h create mode 100644 widgets/misc/ea-calendar-cell.c create mode 100644 widgets/misc/ea-calendar-cell.h create mode 100644 widgets/misc/ea-calendar-item.c create mode 100644 widgets/misc/ea-calendar-item.h create mode 100644 widgets/misc/ea-widgets.c create mode 100644 widgets/misc/ea-widgets.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index cbbd283fb2..c7123d6977 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -84,9 +84,9 @@ widgetsinclude_HEADERS = \ e-spinner.h \ e-timeout-activity.h \ e-url-entry.h \ - a11y/ea-calendar-cell.h \ - a11y/ea-calendar-item.h \ - a11y/ea-widgets.h + ea-calendar-cell.h \ + ea-calendar-item.h \ + ea-widgets.h libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ @@ -145,9 +145,9 @@ libemiscwidgets_la_SOURCES = \ e-signature-tree-view.c \ e-timeout-activity.c \ e-url-entry.c \ - a11y/ea-calendar-cell.c \ - a11y/ea-calendar-item.c \ - a11y/ea-widgets.c + ea-calendar-cell.c \ + ea-calendar-item.c \ + ea-widgets.c libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) diff --git a/widgets/misc/a11y/ea-calendar-cell.c b/widgets/misc/a11y/ea-calendar-cell.c deleted file mode 100644 index af9471c5af..0000000000 --- a/widgets/misc/a11y/ea-calendar-cell.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include -#include -#include "ea-calendar-cell.h" -#include "ea-calendar-item.h" -#include "a11y/ea-factory.h" - -/* ECalendarCell */ - -static void e_calendar_cell_class_init (ECalendarCellClass *class); - -EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new) - -GType -e_calendar_cell_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (ECalendarCellClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) e_calendar_cell_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (ECalendarCell), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) NULL, /* instance init */ - NULL /* value table */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "ECalendarCell", &tinfo, 0); - } - - return type; -} - -static void -e_calendar_cell_class_init (ECalendarCellClass *class) -{ - EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell); -} - -ECalendarCell * -e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column) -{ - GObject *object; - ECalendarCell *cell; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL); - - object = g_object_new (E_TYPE_CALENDAR_CELL, NULL); - cell = E_CALENDAR_CELL (object); - cell->calitem = calitem; - cell->row = row; - cell->column = column; - -#ifdef ACC_DEBUG - g_print ("EvoAcc: e_calendar_cell created %p\n", (gpointer)cell); -#endif - - return cell; -} - -/* EaCalendarCell */ - -static void ea_calendar_cell_class_init (EaCalendarCellClass *klass); -static void ea_calendar_cell_init (EaCalendarCell *a11y); - -static G_CONST_RETURN gchar * ea_calendar_cell_get_name (AtkObject *accessible); -static G_CONST_RETURN gchar * ea_calendar_cell_get_description (AtkObject *accessible); -static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible); -static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible); -static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible); - -/* component interface */ -static void atk_component_interface_init (AtkComponentIface *iface); -static void component_interface_get_extents (AtkComponent *component, - gint *x, gint *y, - gint *width, gint *height, - AtkCoordType coord_type); -static gboolean component_interface_grab_focus (AtkComponent *component); - -static gpointer parent_class = NULL; - -#ifdef ACC_DEBUG -static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0; -static void ea_calendar_cell_finalize (GObject *object); -#endif - -GType -ea_calendar_cell_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (EaCalendarCellClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) ea_calendar_cell_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (EaCalendarCell), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) ea_calendar_cell_init, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) atk_component_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static (ATK_TYPE_GOBJECT_ACCESSIBLE, - "EaCalendarCell", &tinfo, 0); - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, - &atk_component_info); - } - - return type; -} - -static void -ea_calendar_cell_class_init (EaCalendarCellClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - -#ifdef ACC_DEBUG - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = ea_calendar_cell_finalize; -#endif - - parent_class = g_type_class_peek_parent (klass); - - class->get_name = ea_calendar_cell_get_name; - class->get_description = ea_calendar_cell_get_description; - - class->get_parent = ea_calendar_cell_get_parent; - class->get_index_in_parent = ea_calendar_cell_get_index_in_parent; - class->ref_state_set = ea_calendar_cell_ref_state_set; -} - -static void -ea_calendar_cell_init (EaCalendarCell *a11y) -{ - a11y->state_set = atk_state_set_new (); - atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); - atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); - atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); - atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); -} - -AtkObject* -ea_calendar_cell_new (GObject *obj) -{ - gpointer object; - AtkObject *atk_object; - - g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL); - object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL); - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, obj); - atk_object->role = ATK_ROLE_TABLE_CELL; - -#ifdef ACC_DEBUG - ++n_ea_calendar_cell_created; - g_print ("ACC_DEBUG: n_ea_calendar_cell_created = %d\n", - n_ea_calendar_cell_created); -#endif - return atk_object; -} - -#ifdef ACC_DEBUG -static void ea_calendar_cell_finalize (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->finalize (object); - - ++n_ea_calendar_cell_destroyed; - g_print ("ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n", - n_ea_calendar_cell_destroyed); -} -#endif - -static G_CONST_RETURN gchar * -ea_calendar_cell_get_name (AtkObject *accessible) -{ - GObject *g_obj; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); - if (!g_obj) - /* defunct object*/ - return NULL; - - if (!accessible->name) { - AtkObject *atk_obj; - EaCalendarItem *ea_calitem; - ECalendarCell *cell; - gint day_index; - gint year, month, day; - gchar buffer[128]; - - cell = E_CALENDAR_CELL (g_obj); - atk_obj = ea_calendar_cell_get_parent (accessible); - ea_calitem = EA_CALENDAR_ITEM (atk_obj); - day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), - cell->row, cell->column); - e_calendar_item_get_date_for_offset (cell->calitem, day_index, - &year, &month, &day); - - g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day); - ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer); - } - return accessible->name; -} - -static G_CONST_RETURN gchar * -ea_calendar_cell_get_description (AtkObject *accessible) -{ - return ea_calendar_cell_get_name (accessible); -} - -static AtkObject * -ea_calendar_cell_get_parent (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarCell *cell; - ECalendarItem *calitem; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); - if (!g_obj) - /* defunct object*/ - return NULL; - - cell = E_CALENDAR_CELL (g_obj); - calitem = cell->calitem; - return atk_gobject_accessible_for_object (G_OBJECT (calitem)); -} - -static gint -ea_calendar_cell_get_index_in_parent (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarCell *cell; - AtkObject *parent; - - g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); - if (!g_obj) - return -1; - cell = E_CALENDAR_CELL (g_obj); - parent = atk_object_get_parent (accessible); - return atk_table_get_index_at (ATK_TABLE (parent), - cell->row, cell->column); -} - -static AtkStateSet * -ea_calendar_cell_ref_state_set (AtkObject *accessible) -{ - EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible); - - g_return_val_if_fail (atk_cell->state_set, NULL); - - g_object_ref(atk_cell->state_set); - - return atk_cell->state_set; - -} - -/* Atk Component Interface */ - -static void -atk_component_interface_init (AtkComponentIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->get_extents = component_interface_get_extents; - iface->grab_focus = component_interface_grab_focus; -} - -static void -component_interface_get_extents (AtkComponent *component, - gint *x, gint *y, gint *width, gint *height, - AtkCoordType coord_type) -{ - GObject *g_obj; - AtkObject *atk_obj, *atk_canvas; - ECalendarCell *cell; - ECalendarItem *calitem; - EaCalendarItem *ea_calitem; - gint day_index; - gint year, month, day; - gint canvas_x, canvas_y, canvas_width, canvas_height; - - *x = *y = *width = *height = 0; - - g_return_if_fail (EA_IS_CALENDAR_CELL (component)); - - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); - if (!g_obj) - /* defunct object*/ - return; - - cell = E_CALENDAR_CELL (g_obj); - calitem = cell->calitem; - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calitem = EA_CALENDAR_ITEM (atk_obj); - day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), - cell->row, cell->column); - e_calendar_item_get_date_for_offset (calitem, day_index, - &year, &month, &day); - - if (!e_calendar_item_get_day_extents (calitem, - year, month, day, - x, y, width, height)) - return; - atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem)); - atk_component_get_extents (ATK_COMPONENT (atk_canvas), - &canvas_x, &canvas_y, - &canvas_width, &canvas_height, - coord_type); - *x += canvas_x; - *y += canvas_y; -} - -static gboolean -component_interface_grab_focus (AtkComponent *component) -{ - GObject *g_obj; - GtkWidget *toplevel; - AtkObject *ea_calitem; - ECalendarItem *calitem; - EaCalendarCell *a11y; - gint index; - - a11y = EA_CALENDAR_CELL (component); - ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y)); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(ea_calitem)); - calitem = E_CALENDAR_ITEM (g_obj); - - index = atk_object_get_index_in_parent (ATK_OBJECT (a11y)); - - atk_selection_clear_selection (ATK_SELECTION (ea_calitem)); - atk_selection_add_selection (ATK_SELECTION (ea_calitem), index); - - gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); - if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel)) - gtk_window_present (GTK_WINDOW (toplevel)); - - return TRUE; - -} diff --git a/widgets/misc/a11y/ea-calendar-cell.h b/widgets/misc/a11y/ea-calendar-cell.h deleted file mode 100644 index fa68fdca55..0000000000 --- a/widgets/misc/a11y/ea-calendar-cell.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __EA_CALENDAR_CELL_H__ -#define __EA_CALENDAR_CELL_H__ - -#include -#include "misc/e-calendar-item.h" - -G_BEGIN_DECLS - -#define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ()) -#define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell)) -#define E_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) -#define E_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CALENDAR_CELL)) -#define E_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CALENDAR_CELL)) -#define E_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) - -typedef struct _ECalendarCell ECalendarCell; -typedef struct _ECalendarCellClass ECalendarCellClass; - -struct _ECalendarCell -{ - GObject parent; - ECalendarItem *calitem; - gint row; - gint column; -}; - -GType e_calendar_cell_get_type (void); - -struct _ECalendarCellClass -{ - GObjectClass parent_class; -}; - -ECalendarCell * e_calendar_cell_new (ECalendarItem *calitem, - gint row, gint column); - -#define EA_TYPE_CALENDAR_CELL (ea_calendar_cell_get_type ()) -#define EA_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCell)) -#define EA_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) -#define EA_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_CELL)) -#define EA_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_CELL)) -#define EA_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) - -typedef struct _EaCalendarCell EaCalendarCell; -typedef struct _EaCalendarCellClass EaCalendarCellClass; - -struct _EaCalendarCell -{ - AtkGObjectAccessible parent; - AtkStateSet *state_set; -}; - -GType ea_calendar_cell_get_type (void); - -struct _EaCalendarCellClass -{ - AtkGObjectAccessibleClass parent_class; -}; - -AtkObject* ea_calendar_cell_new (GObject *gobj); - -G_END_DECLS - -#endif /* __EA_CALENDAR_CELL_H__ */ diff --git a/widgets/misc/a11y/ea-calendar-item.c b/widgets/misc/a11y/ea-calendar-item.c deleted file mode 100644 index 56a01b510b..0000000000 --- a/widgets/misc/a11y/ea-calendar-item.c +++ /dev/null @@ -1,1314 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ea-calendar-item.h" -#include "ea-calendar-cell.h" -#include "a11y/ea-cell-table.h" - -#define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH - -/* EaCalendarItem */ -static void ea_calendar_item_class_init (EaCalendarItemClass *klass); -static void ea_calendar_item_finalize (GObject *object); - -static G_CONST_RETURN gchar * ea_calendar_item_get_name (AtkObject *accessible); -static G_CONST_RETURN gchar * ea_calendar_item_get_description (AtkObject *accessible); -static gint ea_calendar_item_get_n_children (AtkObject *accessible); -static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index); -static AtkStateSet* ea_calendar_item_ref_state_set (AtkObject *accessible); - -/* atk table interface */ -static void atk_table_interface_init (AtkTableIface *iface); -static gint table_interface_get_index_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_column_at_index (AtkTable *table, - gint index); -static gint table_interface_get_row_at_index (AtkTable *table, - gint index); -static AtkObject* table_interface_ref_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_n_rows (AtkTable *table); -static gint table_interface_get_n_columns (AtkTable *table); -static gint table_interface_get_column_extent_at (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_row_extent_at (AtkTable *table, - gint row, - gint column); - -static gboolean table_interface_is_row_selected (AtkTable *table, - gint row); -static gboolean table_interface_is_column_selected (AtkTable *table, - gint row); -static gboolean table_interface_is_selected (AtkTable *table, - gint row, - gint column); -static gint table_interface_get_selected_rows (AtkTable *table, - gint **rows_selected); -static gint table_interface_get_selected_columns (AtkTable *table, - gint **columns_selected); -static gboolean table_interface_add_row_selection (AtkTable *table, gint row); -static gboolean table_interface_remove_row_selection (AtkTable *table, - gint row); -static gboolean table_interface_add_column_selection (AtkTable *table, - gint column); -static gboolean table_interface_remove_column_selection (AtkTable *table, - gint column); -static AtkObject* table_interface_get_row_header (AtkTable *table, gint row); -static AtkObject* table_interface_get_column_header (AtkTable *table, - gint in_col); -static AtkObject* table_interface_get_caption (AtkTable *table); - -static G_CONST_RETURN gchar * -table_interface_get_column_description (AtkTable *table, gint in_col); - -static G_CONST_RETURN gchar * -table_interface_get_row_description (AtkTable *table, gint row); - -static AtkObject* table_interface_get_summary (AtkTable *table); - -/* atk selection interface */ -static void atk_selection_interface_init (AtkSelectionIface *iface); -static gboolean selection_interface_add_selection (AtkSelection *selection, - gint i); -static gboolean selection_interface_clear_selection (AtkSelection *selection); -static AtkObject* selection_interface_ref_selection (AtkSelection *selection, - gint i); -static gint selection_interface_get_selection_count (AtkSelection *selection); -static gboolean selection_interface_is_child_selected (AtkSelection *selection, - gint i); - -/* callbacks */ -static void selection_preview_change_cb (ECalendarItem *calitem); -static void date_range_changed_cb (ECalendarItem *calitem); - -/* helpers */ -static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem); -static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem); -static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, - gint column, - gchar *buffer, - gint buffer_size); -static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, - gint row, - gchar *buffer, - gint buffer_size); -static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem, - gint year, gint month, gint day, - gint *offset); -static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, - AtkObject *item_cell); - -#ifdef ACC_DEBUG -static gint n_ea_calendar_item_created = 0; -static gint n_ea_calendar_item_destroyed = 0; -#endif - -static gpointer parent_class = NULL; - -GType -ea_calendar_item_get_type (void) -{ - static GType type = 0; - AtkObjectFactory *factory; - GTypeQuery query; - GType derived_atk_type; - - if (!type) { - static GTypeInfo tinfo = { - sizeof (EaCalendarItemClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) ea_calendar_item_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (EaCalendarItem), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) NULL, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_table_info = { - (GInterfaceInitFunc) atk_table_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - static const GInterfaceInfo atk_selection_info = { - (GInterfaceInitFunc) atk_selection_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - /* - * Figure out the size of the class and instance - * we are run-time deriving from (GailCanvasItem, in this case) - */ - - factory = atk_registry_get_factory (atk_get_default_registry (), - GNOME_TYPE_CANVAS_ITEM); - derived_atk_type = atk_object_factory_get_accessible_type (factory); - g_type_query (derived_atk_type, &query); - - tinfo.class_size = query.class_size; - tinfo.instance_size = query.instance_size; - - type = g_type_register_static (derived_atk_type, - "EaCalendarItem", &tinfo, 0); - g_type_add_interface_static (type, ATK_TYPE_TABLE, - &atk_table_info); - g_type_add_interface_static (type, ATK_TYPE_SELECTION, - &atk_selection_info); - } - - return type; -} - -static void -ea_calendar_item_class_init (EaCalendarItemClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - gobject_class->finalize = ea_calendar_item_finalize; - parent_class = g_type_class_peek_parent (klass); - - class->get_name = ea_calendar_item_get_name; - class->get_description = ea_calendar_item_get_description; - class->ref_state_set = ea_calendar_item_ref_state_set; - - class->get_n_children = ea_calendar_item_get_n_children; - class->ref_child = ea_calendar_item_ref_child; -} - -AtkObject* -ea_calendar_item_new (GObject *obj) -{ - gpointer object; - AtkObject *atk_object; - AtkObject *item_cell; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL); - object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL); - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, obj); - atk_object->role = ATK_ROLE_CALENDAR; - - item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_object), - 0); - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell); - -#ifdef ACC_DEBUG - ++n_ea_calendar_item_created; - g_print ("ACC_DEBUG: n_ea_calendar_item_created = %d\n", - n_ea_calendar_item_created); -#endif - /* connect signal handlers */ - g_signal_connect (obj, "selection_preview_changed", - G_CALLBACK (selection_preview_change_cb), - atk_object); - g_signal_connect (obj, "date_range_changed", - G_CALLBACK (date_range_changed_cb), - atk_object); - - return atk_object; -} - -static void -ea_calendar_item_finalize (GObject *object) -{ - EaCalendarItem *ea_calitem; - - g_return_if_fail (EA_IS_CALENDAR_ITEM (object)); - - ea_calitem = EA_CALENDAR_ITEM (object); - - /* Free the allocated cell data */ - ea_calendar_item_destory_cell_data (ea_calitem); - - G_OBJECT_CLASS (parent_class)->finalize (object); -#ifdef ACC_DEBUG - ++n_ea_calendar_item_destroyed; - printf ("ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n", - n_ea_calendar_item_destroyed); -#endif -} - -static G_CONST_RETURN gchar * -ea_calendar_item_get_name (AtkObject *accessible) -{ - GObject *g_obj; - ECalendarItem *calitem; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - gchar *name_str = NULL; - gchar buffer_start[128] = ""; - gchar buffer_end[128] = ""; - struct tm day_start = { 0 }; - struct tm day_end = { 0 }; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); - if (!g_obj) - return NULL; - g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL); - - calitem = E_CALENDAR_ITEM (g_obj); - if (e_calendar_item_get_date_range (calitem, - &start_year, &start_month, &start_day, - &end_year, &end_month, &end_day)) { - - day_start.tm_year = start_year - 1900; - day_start.tm_mon = start_month; - day_start.tm_mday = start_day; - day_start.tm_isdst = -1; - e_utf8_strftime (buffer_start, sizeof (buffer_start), _("%d %B %Y"), &day_start); - - day_end.tm_year = end_year - 1900; - day_end.tm_mon = end_month; - day_end.tm_mday = end_day; - day_end.tm_isdst = -1; - e_utf8_strftime (buffer_end, sizeof (buffer_end), _("%d %B %Y"), &day_end); - - name_str = g_strdup_printf (_("Calendar: from %s to %s"), buffer_start, buffer_end); - } - -#if 0 - if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) { - GDate select_start, select_end; - gint year1, year2, month1, month2, day1, day2; - - year1 = g_date_get_year (&select_start); - month1 = g_date_get_month (&select_start); - day1 = g_date_get_day (&select_start); - - year2 = g_date_get_year (&select_end); - month2 = g_date_get_month (&select_end); - day2 = g_date_get_day (&select_end); - - sprintf (new_name + strlen (new_name), - " : current selection: from %d-%d-%d to %d-%d-%d.", - year1, month1, day1, - year2, month2, day2); - } -#endif - - ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); - g_free (name_str); - - return accessible->name; -} - -static G_CONST_RETURN gchar * -ea_calendar_item_get_description (AtkObject *accessible) -{ - if (accessible->description) - return accessible->description; - - return _("evolution calendar item"); -} - -static AtkStateSet* -ea_calendar_item_ref_state_set (AtkObject *accessible) -{ - AtkStateSet *state_set; - GObject *g_obj; - - state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible); - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); - if (!g_obj) - return state_set; - - atk_state_set_add_state (state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); - - return state_set; -} - -static gint -ea_calendar_item_get_n_children (AtkObject *accessible) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint n_children = 0; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date, *end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return 0; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - end_date = g_date_new_dmy (end_day, end_month + 1, end_year); - - n_children = g_date_days_between (start_date, end_date) + 1; - g_free (start_date); - g_free (end_date); - return n_children; -} - -static AtkObject * -ea_calendar_item_ref_child (AtkObject *accessible, gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint n_children; - ECalendarCell *cell; - EaCellTable *cell_data; - EaCalendarItem *ea_calitem; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - calitem = E_CALENDAR_ITEM (g_obj); - - n_children = ea_calendar_item_get_n_children (accessible); - if (index < 0 || index >= n_children) - return NULL; - - ea_calitem = EA_CALENDAR_ITEM (accessible); - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - cell = ea_cell_table_get_cell_at_index (cell_data, index); - if (!cell) { - cell = e_calendar_cell_new (calitem, - index / EA_CALENDAR_COLUMN_NUM, - index % EA_CALENDAR_COLUMN_NUM); - ea_cell_table_set_cell_at_index (cell_data, index, cell); - g_object_unref (cell); - } - -#ifdef ACC_DEBUG - g_print ("AccDebug: ea_calendar_item children[%d]=%p\n", index, - (gpointer)cell); -#endif - return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT(cell))); -} - -/* atk table interface */ - -static void -atk_table_interface_init (AtkTableIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->ref_at = table_interface_ref_at; - - iface->get_n_rows = table_interface_get_n_rows; - iface->get_n_columns = table_interface_get_n_columns; - iface->get_index_at = table_interface_get_index_at; - iface->get_column_at_index = table_interface_get_column_at_index; - iface->get_row_at_index = table_interface_get_row_at_index; - iface->get_column_extent_at = table_interface_get_column_extent_at; - iface->get_row_extent_at = table_interface_get_row_extent_at; - - iface->is_selected = table_interface_is_selected; - iface->get_selected_rows = table_interface_get_selected_rows; - iface->get_selected_columns = table_interface_get_selected_columns; - iface->is_row_selected = table_interface_is_row_selected; - iface->is_column_selected = table_interface_is_column_selected; - iface->add_row_selection = table_interface_add_row_selection; - iface->remove_row_selection = table_interface_remove_row_selection; - iface->add_column_selection = table_interface_add_column_selection; - iface->remove_column_selection = table_interface_remove_column_selection; - - iface->get_row_header = table_interface_get_row_header; - iface->get_column_header = table_interface_get_column_header; - iface->get_caption = table_interface_get_caption; - iface->get_summary = table_interface_get_summary; - iface->get_row_description = table_interface_get_row_description; - iface->get_column_description = table_interface_get_column_description; -} - -static AtkObject* -table_interface_ref_at (AtkTable *table, - gint row, - gint column) -{ - gint index; - - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - index = EA_CALENDAR_COLUMN_NUM * row + column; - return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index); -} - -static gint -table_interface_get_n_rows (AtkTable *table) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1; -} - -static gint -table_interface_get_n_columns (AtkTable *table) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - return EA_CALENDAR_COLUMN_NUM; -} - -static gint -table_interface_get_index_at (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - return row * EA_CALENDAR_COLUMN_NUM + column; -} - -static gint -table_interface_get_column_at_index (AtkTable *table, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - if (index >= 0 && index < n_children) - return index % EA_CALENDAR_COLUMN_NUM; - return -1; -} - -static gint -table_interface_get_row_at_index (AtkTable *table, - gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - gint n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return -1; - - n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); - if (index >= 0 && index < n_children) - return index / EA_CALENDAR_COLUMN_NUM; - return -1; -} - -static gint -table_interface_get_column_extent_at (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - return calitem->cell_width; -} - -static gint -table_interface_get_row_extent_at (AtkTable *table, - gint row, gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - return calitem->cell_height; -} - -/* any day in the row is selected, the row is selected */ -static gboolean -table_interface_is_row_selected (AtkTable *table, - gint row) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - gint n_rows; - ECalendarItem *calitem; - gint row_index_start, row_index_end; - gint sel_index_start, sel_index_end; - - GDate start_date, end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return FALSE; - - row_index_start = row * EA_CALENDAR_COLUMN_NUM; - row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return FALSE; - - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date), - g_date_get_day (&start_date), - &sel_index_start); - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&end_date), - g_date_get_month (&end_date), - g_date_get_day (&end_date), - &sel_index_end); - - if ((sel_index_start < row_index_start && - sel_index_end >= row_index_start) || - (sel_index_start >= row_index_start && - sel_index_start <= row_index_end)) - return TRUE; - return FALSE; -} - -static gboolean -table_interface_is_selected (AtkTable *table, - gint row, - gint column) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - gint n_rows, n_columns; - ECalendarItem *calitem; - gint index; - gint sel_index_start, sel_index_end; - - GDate start_date, end_date; - - g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return FALSE; - n_columns = table_interface_get_n_columns (table); - if (column < 0 || column >= n_columns) - return FALSE; - - index = table_interface_get_index_at (table, row, column); - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return FALSE; - - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date), - g_date_get_day (&start_date), - &sel_index_start); - e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&end_date), - g_date_get_month (&end_date), - g_date_get_day (&end_date), &sel_index_end); - - if (sel_index_start <= index && sel_index_end >= index) - return TRUE; - return FALSE; -} - -static gboolean -table_interface_is_column_selected (AtkTable *table, - gint column) -{ - return FALSE; -} - -static gint -table_interface_get_selected_rows (AtkTable *table, - gint **rows_selected) -{ - *rows_selected = NULL; - return -1; -} - -static gint -table_interface_get_selected_columns (AtkTable *table, - gint **columns_selected) -{ - *columns_selected = NULL; - return -1; -} - -static gboolean -table_interface_add_row_selection (AtkTable *table, - gint row) -{ - return FALSE; -} - -static gboolean -table_interface_remove_row_selection (AtkTable *table, - gint row) -{ - return FALSE; -} - -static gboolean -table_interface_add_column_selection (AtkTable *table, - gint column) -{ - return FALSE; -} - -static gboolean -table_interface_remove_column_selection (AtkTable *table, - gint column) -{ - /* FIXME: NOT IMPLEMENTED */ - return FALSE; -} - -static AtkObject* -table_interface_get_row_header (AtkTable *table, - gint row) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static AtkObject* -table_interface_get_column_header (AtkTable *table, - gint in_col) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static AtkObject* -table_interface_get_caption (AtkTable *table) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -static G_CONST_RETURN gchar * -table_interface_get_column_description (AtkTable *table, gint in_col) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - const gchar *description = NULL; - EaCellTable *cell_data; - gint n_columns; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - n_columns = table_interface_get_n_columns (table); - if (in_col < 0 || in_col >= n_columns) - return NULL; - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - description = ea_cell_table_get_column_label (cell_data, in_col); - if (!description) { - gchar buffer[128] = "column description"; - ea_calendar_item_get_column_label (ea_calitem, in_col, - buffer, sizeof (buffer)); - ea_cell_table_set_column_label (cell_data, in_col, buffer); - description = ea_cell_table_get_column_label (cell_data, - in_col); - } - return description; -} - -static G_CONST_RETURN gchar * -table_interface_get_row_description (AtkTable *table, gint row) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); - const gchar *description = NULL; - EaCellTable *cell_data; - gint n_rows; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - n_rows = table_interface_get_n_rows (table); - if (row < 0 || row >= n_rows) - return NULL; - cell_data = ea_calendar_item_get_cell_data (ea_calitem); - if (!cell_data) - return NULL; - - description = ea_cell_table_get_row_label (cell_data, row); - if (!description) { - gchar buffer[128] = "row description"; - ea_calendar_item_get_row_label (ea_calitem, row, - buffer, sizeof (buffer)); - ea_cell_table_set_row_label (cell_data, row, buffer); - description = ea_cell_table_get_row_label (cell_data, - row); - } - return description; -} - -static AtkObject* -table_interface_get_summary (AtkTable *table) -{ - /* FIXME: NOT IMPLEMENTED */ - return NULL; -} - -/* atkselection interface */ - -static void -atk_selection_interface_init (AtkSelectionIface *iface) -{ - g_return_if_fail (iface != NULL); - - iface->add_selection = selection_interface_add_selection; - iface->clear_selection = selection_interface_clear_selection; - iface->ref_selection = selection_interface_ref_selection; - iface->get_selection_count = selection_interface_get_selection_count; - iface->is_child_selected = selection_interface_is_child_selected; -} - -static gboolean -selection_interface_add_selection (AtkSelection *selection, gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); - gint year, month, day; - GDate start_date, end_date; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_date_for_offset (calitem, index, - &year, &month, &day)) - return FALSE; - - /* FIXME: not support mulit-selection */ - g_date_set_dmy (&start_date, day, month + 1, year); - end_date = start_date; - e_calendar_item_set_selection (calitem, &start_date, &end_date); - return TRUE; -} - -static gboolean -selection_interface_clear_selection (AtkSelection *selection) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - e_calendar_item_set_selection (calitem, NULL, NULL); - - return TRUE; -} - -static AtkObject* -selection_interface_ref_selection (AtkSelection *selection, gint i) -{ - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); - gint count, sel_offset; - GDate start_date, end_date; - - count = selection_interface_get_selection_count (selection); - if (i < 0 || i >= count) - return NULL; - - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem)); - - calitem = E_CALENDAR_ITEM (g_obj); - if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return NULL; - if (!e_calendar_item_get_offset_for_date (calitem, - g_date_get_year (&start_date), - g_date_get_month (&start_date) - 1, - g_date_get_day (&start_date), - &sel_offset)) - return NULL; - - return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i); -} - -static gint -selection_interface_get_selection_count (AtkSelection *selection) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); - GDate start_date, end_date; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return 0; - - calitem = E_CALENDAR_ITEM (g_obj); - if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) - return g_date_days_between (&start_date, &end_date) + 1; - else - return 0; -} - -static gboolean -selection_interface_is_child_selected (AtkSelection *selection, gint index) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); - gint row, column, n_children; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection)); - if (index < 0 || index >= n_children) - return FALSE; - - row = index / EA_CALENDAR_COLUMN_NUM; - column = index % EA_CALENDAR_COLUMN_NUM; - - return table_interface_is_selected (ATK_TABLE (selection), row, column); -} - -/* callbacks */ - -static void -selection_preview_change_cb (ECalendarItem *calitem) -{ - AtkObject *atk_obj; - AtkObject *item_cell; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); - - /* only deal with the first selected child, for now */ - item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), - 0); - - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); - - g_signal_emit_by_name (atk_obj, - "active-descendant-changed", - item_cell); - g_signal_emit_by_name (atk_obj, "selection_changed"); -} - -static void -date_range_changed_cb (ECalendarItem *calitem) -{ - AtkObject *atk_obj; - AtkObject *item_cell; - - g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); - ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); - - item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), - 0); - if (item_cell) - ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); - - g_signal_emit_by_name (atk_obj, "model_changed"); -} - -/* helpers */ - -static EaCellTable * -ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - EaCellTable *cell_data; - - g_return_val_if_fail (ea_calitem, NULL); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return NULL; - - cell_data = g_object_get_data (G_OBJECT(ea_calitem), - "ea-calendar-cell-table"); - - if (!cell_data) { - gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT(ea_calitem)); - cell_data = ea_cell_table_create (n_cells/EA_CALENDAR_COLUMN_NUM, - EA_CALENDAR_COLUMN_NUM, - FALSE); - g_object_set_data (G_OBJECT(ea_calitem), - "ea-calendar-cell-table", cell_data); - } - return cell_data; -} - -static void -ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem) -{ - EaCellTable *cell_data; - - g_return_if_fail (ea_calitem); - - cell_data = g_object_get_data (G_OBJECT(ea_calitem), - "ea-calendar-cell-table"); - if (cell_data) { - g_object_set_data (G_OBJECT(ea_calitem), - "ea-calendar-cell-table", NULL); - ea_cell_table_destroy (cell_data); - } -} - -static gboolean -ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, gint row, - gchar *buffer, gint buffer_size) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - gint index, week_num; - gint year, month, day; - - g_return_val_if_fail (ea_calitem, FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - calitem = E_CALENDAR_ITEM (g_obj); - - index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0); - if (!e_calendar_item_get_date_for_offset (calitem, index, - &year, &month, &day)) - return FALSE; - - week_num = e_calendar_item_get_week_number (calitem, - day, month, year); - - g_snprintf (buffer, buffer_size, "week number : %d", week_num); - return TRUE; -} - -static gboolean -ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, gint column, - gchar *buffer, gint buffer_size) -{ - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalendarItem *calitem; - const gchar *abbr_name; - - g_return_val_if_fail (ea_calitem, FALSE); - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj) - return FALSE; - - /* Columns are 0 = Monday ... 6 = Sunday */ - calitem = E_CALENDAR_ITEM (g_obj); - abbr_name = e_get_weekday_name (column + 1, TRUE); - g_strlcpy (buffer, abbr_name, buffer_size); - - return TRUE; -} - -/* the coordinate the e-calendar canvas coord */ -gboolean -e_calendar_item_get_day_extents (ECalendarItem *calitem, - gint year, gint month, gint date, - gint *x, gint *y, - gint *width, gint *height) -{ - GnomeCanvasItem *item; - GtkWidget *widget; - GtkStyle *style; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - gint char_height, xthickness, ythickness, text_y; - gint new_year, new_month, num_months, months_offset; - gint month_x, month_y, month_cell_x, month_cell_y; - gint month_row, month_col; - gint day_row, day_col; - gint days_from_week_start; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - item = GNOME_CANVAS_ITEM (calitem); - widget = GTK_WIDGET (item->canvas); - style = widget->style; - - /* Set up Pango prerequisites */ - font_desc = calitem->font_desc; - if (!font_desc) - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - - char_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - xthickness = style->xthickness; - ythickness = style->ythickness; - - new_year = year; - new_month = month; - e_calendar_item_normalize_date (calitem, &new_year, &new_month); - num_months = calitem->rows * calitem->cols; - months_offset = (new_year - calitem->year) * 12 - + new_month - calitem->month; - - if (months_offset > num_months || months_offset < 0) - return FALSE; - - month_row = months_offset / calitem->cols; - month_col = months_offset % calitem->cols; - - month_x = item->x1 + xthickness + calitem->x_offset - + month_col * calitem->month_width; - month_y = item->y1 + ythickness + month_row * calitem->month_height; - - month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS - + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; - text_y = month_y + ythickness * 2 - + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME - + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME - + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; - - month_cell_y = text_y + char_height - + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 - + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; - - days_from_week_start = - e_calendar_item_get_n_days_from_week_start (calitem, new_year, - new_month); - day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM; - day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM; - - *x = month_cell_x + day_col * calitem->cell_width; - *y = month_cell_y + day_row * calitem->cell_height; - *width = calitem->cell_width; - *height = calitem->cell_height; - - return TRUE; -} - -/* month is from 0 to 11 */ -gboolean -e_calendar_item_get_date_for_offset (ECalendarItem *calitem, gint day_offset, - gint *year, gint *month, gint *day) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date; - - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return FALSE; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - - g_date_add_days (start_date, day_offset); - - *year = g_date_get_year (start_date); - *month = g_date_get_month (start_date) - 1; - *day = g_date_get_day (start_date); - - return TRUE; -} - -/* the arg month is from 0 to 11 */ -static gboolean -e_calendar_item_get_offset_for_date (ECalendarItem *calitem, - gint year, gint month, gint day, - gint *offset) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - GDate *start_date, *end_date; - - *offset = 0; - g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); - - if (!e_calendar_item_get_date_range (calitem, &start_year, - &start_month, &start_day, - &end_year, &end_month, - &end_day)) - return FALSE; - - start_date = g_date_new_dmy (start_day, start_month + 1, start_year); - end_date = g_date_new_dmy (day, month + 1, year); - - *offset = g_date_days_between (start_date, end_date); - g_free (start_date); - g_free (end_date); - - return TRUE; -} - -gint -e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, - gint year, gint month) -{ - struct tm tmp_tm; - gint start_weekday, days_from_week_start; - - memset (&tmp_tm, 0, sizeof (tmp_tm)); - tmp_tm.tm_year = year - 1900; - tmp_tm.tm_mon = month; - tmp_tm.tm_mday = 1; - tmp_tm.tm_isdst = -1; - mktime (&tmp_tm); - start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */ - days_from_week_start = (start_weekday + 7 - calitem->week_start_day) - % 7; - return days_from_week_start; -} - -static void -ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, AtkObject *item_cell) -{ - AtkStateSet *state_set, *old_state_set; - AtkObject *old_cell; - - old_cell = (AtkObject *)g_object_get_data (G_OBJECT(ea_calitem), "gail-focus-object"); - if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) { - old_state_set = atk_object_ref_state_set (old_cell); - atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED); - g_object_unref (old_state_set); - } - if (old_cell) - g_object_unref (old_cell); - - state_set = atk_object_ref_state_set (item_cell); - atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); - g_object_set_data (G_OBJECT(ea_calitem), "gail-focus-object", item_cell); - g_object_unref (state_set); -} diff --git a/widgets/misc/a11y/ea-calendar-item.h b/widgets/misc/a11y/ea-calendar-item.h deleted file mode 100644 index 36cc671a3b..0000000000 --- a/widgets/misc/a11y/ea-calendar-item.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __EA_CALENDAR_ITEM_H__ -#define __EA_CALENDAR_ITEM_H__ - -#include -#include - -G_BEGIN_DECLS - -#define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ()) -#define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem)) -#define EA_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) -#define EA_IS_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_ITEM)) -#define EA_IS_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_ITEM)) -#define EA_CALENDAR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) - -typedef struct _EaCalendarItem EaCalendarItem; -typedef struct _EaCalendarItemClass EaCalendarItemClass; - -struct _EaCalendarItem -{ - AtkGObjectAccessible parent; -}; - -GType ea_calendar_item_get_type (void); - -struct _EaCalendarItemClass -{ - AtkGObjectAccessibleClass parent_class; -}; - -AtkObject *ea_calendar_item_new (GObject *obj); -gboolean e_calendar_item_get_day_extents (ECalendarItem *calitem, - gint year, gint month, gint date, - gint *x, gint *y, - gint *width, gint *height); -gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem, - gint day_offset, - gint *year, gint *month, - gint *day); -gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, - gint year, gint month); - -G_END_DECLS - - -#endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/a11y/ea-widgets.c b/widgets/misc/a11y/ea-widgets.c deleted file mode 100644 index 9deede235e..0000000000 --- a/widgets/misc/a11y/ea-widgets.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "a11y/ea-factory.h" -#include "ea-calendar-item.h" -#include "ea-widgets.h" - -EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new) - -void e_calendar_item_a11y_init (void) -{ - EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item); -} diff --git a/widgets/misc/a11y/ea-widgets.h b/widgets/misc/a11y/ea-widgets.h deleted file mode 100644 index 495222ae05..0000000000 --- a/widgets/misc/a11y/ea-widgets.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * 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 - * - * - * Authors: - * Bolian Yin - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* Evolution Accessibility -*/ - -#ifndef _EA_WIDGETS_H__ -#define _EA_WIDGETS_H__ - -void e_calendar_item_a11y_init (void); - -#endif /* _EA_WIDGETS_H__ */ diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 9c9bd94b15..890355620b 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -26,7 +26,7 @@ #endif #include "e-calendar-item.h" -#include "a11y/ea-widgets.h" +#include "ea-widgets.h" #include #include diff --git a/widgets/misc/ea-calendar-cell.c b/widgets/misc/ea-calendar-cell.c new file mode 100644 index 0000000000..af9471c5af --- /dev/null +++ b/widgets/misc/ea-calendar-cell.c @@ -0,0 +1,387 @@ +/* + * + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include +#include +#include "ea-calendar-cell.h" +#include "ea-calendar-item.h" +#include "a11y/ea-factory.h" + +/* ECalendarCell */ + +static void e_calendar_cell_class_init (ECalendarCellClass *class); + +EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new) + +GType +e_calendar_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (ECalendarCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) e_calendar_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (ECalendarCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "ECalendarCell", &tinfo, 0); + } + + return type; +} + +static void +e_calendar_cell_class_init (ECalendarCellClass *class) +{ + EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell); +} + +ECalendarCell * +e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column) +{ + GObject *object; + ECalendarCell *cell; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL); + + object = g_object_new (E_TYPE_CALENDAR_CELL, NULL); + cell = E_CALENDAR_CELL (object); + cell->calitem = calitem; + cell->row = row; + cell->column = column; + +#ifdef ACC_DEBUG + g_print ("EvoAcc: e_calendar_cell created %p\n", (gpointer)cell); +#endif + + return cell; +} + +/* EaCalendarCell */ + +static void ea_calendar_cell_class_init (EaCalendarCellClass *klass); +static void ea_calendar_cell_init (EaCalendarCell *a11y); + +static G_CONST_RETURN gchar * ea_calendar_cell_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_cell_get_description (AtkObject *accessible); +static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible); +static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible); +static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible); + +/* component interface */ +static void atk_component_interface_init (AtkComponentIface *iface); +static void component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, + gint *width, gint *height, + AtkCoordType coord_type); +static gboolean component_interface_grab_focus (AtkComponent *component); + +static gpointer parent_class = NULL; + +#ifdef ACC_DEBUG +static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0; +static void ea_calendar_cell_finalize (GObject *object); +#endif + +GType +ea_calendar_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalendarCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_calendar_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalendarCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) ea_calendar_cell_init, /* instance init */ + NULL /* value table */ + }; + + static const GInterfaceInfo atk_component_info = { + (GInterfaceInitFunc) atk_component_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + type = g_type_register_static (ATK_TYPE_GOBJECT_ACCESSIBLE, + "EaCalendarCell", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + } + + return type; +} + +static void +ea_calendar_cell_class_init (EaCalendarCellClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + +#ifdef ACC_DEBUG + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ea_calendar_cell_finalize; +#endif + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_calendar_cell_get_name; + class->get_description = ea_calendar_cell_get_description; + + class->get_parent = ea_calendar_cell_get_parent; + class->get_index_in_parent = ea_calendar_cell_get_index_in_parent; + class->ref_state_set = ea_calendar_cell_ref_state_set; +} + +static void +ea_calendar_cell_init (EaCalendarCell *a11y) +{ + a11y->state_set = atk_state_set_new (); + atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); + atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); + atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); +} + +AtkObject* +ea_calendar_cell_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + + g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL); + object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL); + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, obj); + atk_object->role = ATK_ROLE_TABLE_CELL; + +#ifdef ACC_DEBUG + ++n_ea_calendar_cell_created; + g_print ("ACC_DEBUG: n_ea_calendar_cell_created = %d\n", + n_ea_calendar_cell_created); +#endif + return atk_object; +} + +#ifdef ACC_DEBUG +static void ea_calendar_cell_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (object); + + ++n_ea_calendar_cell_destroyed; + g_print ("ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n", + n_ea_calendar_cell_destroyed); +} +#endif + +static G_CONST_RETURN gchar * +ea_calendar_cell_get_name (AtkObject *accessible) +{ + GObject *g_obj; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + /* defunct object*/ + return NULL; + + if (!accessible->name) { + AtkObject *atk_obj; + EaCalendarItem *ea_calitem; + ECalendarCell *cell; + gint day_index; + gint year, month, day; + gchar buffer[128]; + + cell = E_CALENDAR_CELL (g_obj); + atk_obj = ea_calendar_cell_get_parent (accessible); + ea_calitem = EA_CALENDAR_ITEM (atk_obj); + day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), + cell->row, cell->column); + e_calendar_item_get_date_for_offset (cell->calitem, day_index, + &year, &month, &day); + + g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day); + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer); + } + return accessible->name; +} + +static G_CONST_RETURN gchar * +ea_calendar_cell_get_description (AtkObject *accessible) +{ + return ea_calendar_cell_get_name (accessible); +} + +static AtkObject * +ea_calendar_cell_get_parent (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarCell *cell; + ECalendarItem *calitem; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + /* defunct object*/ + return NULL; + + cell = E_CALENDAR_CELL (g_obj); + calitem = cell->calitem; + return atk_gobject_accessible_for_object (G_OBJECT (calitem)); +} + +static gint +ea_calendar_cell_get_index_in_parent (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarCell *cell; + AtkObject *parent; + + g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return -1; + cell = E_CALENDAR_CELL (g_obj); + parent = atk_object_get_parent (accessible); + return atk_table_get_index_at (ATK_TABLE (parent), + cell->row, cell->column); +} + +static AtkStateSet * +ea_calendar_cell_ref_state_set (AtkObject *accessible) +{ + EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible); + + g_return_val_if_fail (atk_cell->state_set, NULL); + + g_object_ref(atk_cell->state_set); + + return atk_cell->state_set; + +} + +/* Atk Component Interface */ + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = component_interface_get_extents; + iface->grab_focus = component_interface_grab_focus; +} + +static void +component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, gint *width, gint *height, + AtkCoordType coord_type) +{ + GObject *g_obj; + AtkObject *atk_obj, *atk_canvas; + ECalendarCell *cell; + ECalendarItem *calitem; + EaCalendarItem *ea_calitem; + gint day_index; + gint year, month, day; + gint canvas_x, canvas_y, canvas_width, canvas_height; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_CALENDAR_CELL (component)); + + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + + cell = E_CALENDAR_CELL (g_obj); + calitem = cell->calitem; + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calitem = EA_CALENDAR_ITEM (atk_obj); + day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem), + cell->row, cell->column); + e_calendar_item_get_date_for_offset (calitem, day_index, + &year, &month, &day); + + if (!e_calendar_item_get_day_extents (calitem, + year, month, day, + x, y, width, height)) + return; + atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem)); + atk_component_get_extents (ATK_COMPONENT (atk_canvas), + &canvas_x, &canvas_y, + &canvas_width, &canvas_height, + coord_type); + *x += canvas_x; + *y += canvas_y; +} + +static gboolean +component_interface_grab_focus (AtkComponent *component) +{ + GObject *g_obj; + GtkWidget *toplevel; + AtkObject *ea_calitem; + ECalendarItem *calitem; + EaCalendarCell *a11y; + gint index; + + a11y = EA_CALENDAR_CELL (component); + ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(ea_calitem)); + calitem = E_CALENDAR_ITEM (g_obj); + + index = atk_object_get_index_in_parent (ATK_OBJECT (a11y)); + + atk_selection_clear_selection (ATK_SELECTION (ea_calitem)); + atk_selection_add_selection (ATK_SELECTION (ea_calitem), index); + + gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas)); + if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel)) + gtk_window_present (GTK_WINDOW (toplevel)); + + return TRUE; + +} diff --git a/widgets/misc/ea-calendar-cell.h b/widgets/misc/ea-calendar-cell.h new file mode 100644 index 0000000000..fa68fdca55 --- /dev/null +++ b/widgets/misc/ea-calendar-cell.h @@ -0,0 +1,86 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CALENDAR_CELL_H__ +#define __EA_CALENDAR_CELL_H__ + +#include +#include "misc/e-calendar-item.h" + +G_BEGIN_DECLS + +#define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ()) +#define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell)) +#define E_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) +#define E_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CALENDAR_CELL)) +#define E_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CALENDAR_CELL)) +#define E_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CALENDAR_CELL, ECalendarCellClass)) + +typedef struct _ECalendarCell ECalendarCell; +typedef struct _ECalendarCellClass ECalendarCellClass; + +struct _ECalendarCell +{ + GObject parent; + ECalendarItem *calitem; + gint row; + gint column; +}; + +GType e_calendar_cell_get_type (void); + +struct _ECalendarCellClass +{ + GObjectClass parent_class; +}; + +ECalendarCell * e_calendar_cell_new (ECalendarItem *calitem, + gint row, gint column); + +#define EA_TYPE_CALENDAR_CELL (ea_calendar_cell_get_type ()) +#define EA_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCell)) +#define EA_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) +#define EA_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_CELL)) +#define EA_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_CELL)) +#define EA_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass)) + +typedef struct _EaCalendarCell EaCalendarCell; +typedef struct _EaCalendarCellClass EaCalendarCellClass; + +struct _EaCalendarCell +{ + AtkGObjectAccessible parent; + AtkStateSet *state_set; +}; + +GType ea_calendar_cell_get_type (void); + +struct _EaCalendarCellClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_calendar_cell_new (GObject *gobj); + +G_END_DECLS + +#endif /* __EA_CALENDAR_CELL_H__ */ diff --git a/widgets/misc/ea-calendar-item.c b/widgets/misc/ea-calendar-item.c new file mode 100644 index 0000000000..56a01b510b --- /dev/null +++ b/widgets/misc/ea-calendar-item.c @@ -0,0 +1,1314 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ea-calendar-item.h" +#include "ea-calendar-cell.h" +#include "a11y/ea-cell-table.h" + +#define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH + +/* EaCalendarItem */ +static void ea_calendar_item_class_init (EaCalendarItemClass *klass); +static void ea_calendar_item_finalize (GObject *object); + +static G_CONST_RETURN gchar * ea_calendar_item_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar * ea_calendar_item_get_description (AtkObject *accessible); +static gint ea_calendar_item_get_n_children (AtkObject *accessible); +static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index); +static AtkStateSet* ea_calendar_item_ref_state_set (AtkObject *accessible); + +/* atk table interface */ +static void atk_table_interface_init (AtkTableIface *iface); +static gint table_interface_get_index_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_column_at_index (AtkTable *table, + gint index); +static gint table_interface_get_row_at_index (AtkTable *table, + gint index); +static AtkObject* table_interface_ref_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_n_rows (AtkTable *table); +static gint table_interface_get_n_columns (AtkTable *table); +static gint table_interface_get_column_extent_at (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_row_extent_at (AtkTable *table, + gint row, + gint column); + +static gboolean table_interface_is_row_selected (AtkTable *table, + gint row); +static gboolean table_interface_is_column_selected (AtkTable *table, + gint row); +static gboolean table_interface_is_selected (AtkTable *table, + gint row, + gint column); +static gint table_interface_get_selected_rows (AtkTable *table, + gint **rows_selected); +static gint table_interface_get_selected_columns (AtkTable *table, + gint **columns_selected); +static gboolean table_interface_add_row_selection (AtkTable *table, gint row); +static gboolean table_interface_remove_row_selection (AtkTable *table, + gint row); +static gboolean table_interface_add_column_selection (AtkTable *table, + gint column); +static gboolean table_interface_remove_column_selection (AtkTable *table, + gint column); +static AtkObject* table_interface_get_row_header (AtkTable *table, gint row); +static AtkObject* table_interface_get_column_header (AtkTable *table, + gint in_col); +static AtkObject* table_interface_get_caption (AtkTable *table); + +static G_CONST_RETURN gchar * +table_interface_get_column_description (AtkTable *table, gint in_col); + +static G_CONST_RETURN gchar * +table_interface_get_row_description (AtkTable *table, gint row); + +static AtkObject* table_interface_get_summary (AtkTable *table); + +/* atk selection interface */ +static void atk_selection_interface_init (AtkSelectionIface *iface); +static gboolean selection_interface_add_selection (AtkSelection *selection, + gint i); +static gboolean selection_interface_clear_selection (AtkSelection *selection); +static AtkObject* selection_interface_ref_selection (AtkSelection *selection, + gint i); +static gint selection_interface_get_selection_count (AtkSelection *selection); +static gboolean selection_interface_is_child_selected (AtkSelection *selection, + gint i); + +/* callbacks */ +static void selection_preview_change_cb (ECalendarItem *calitem); +static void date_range_changed_cb (ECalendarItem *calitem); + +/* helpers */ +static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem); +static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem); +static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, + gint column, + gchar *buffer, + gint buffer_size); +static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, + gint row, + gchar *buffer, + gint buffer_size); +static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem, + gint year, gint month, gint day, + gint *offset); +static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, + AtkObject *item_cell); + +#ifdef ACC_DEBUG +static gint n_ea_calendar_item_created = 0; +static gint n_ea_calendar_item_destroyed = 0; +#endif + +static gpointer parent_class = NULL; + +GType +ea_calendar_item_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalendarItemClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_calendar_item_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalendarItem), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + static const GInterfaceInfo atk_table_info = { + (GInterfaceInitFunc) atk_table_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + static const GInterfaceInfo atk_selection_info = { + (GInterfaceInitFunc) atk_selection_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (GailCanvasItem, in this case) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + GNOME_TYPE_CANVAS_ITEM); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + g_type_query (derived_atk_type, &query); + + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + + type = g_type_register_static (derived_atk_type, + "EaCalendarItem", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_TABLE, + &atk_table_info); + g_type_add_interface_static (type, ATK_TYPE_SELECTION, + &atk_selection_info); + } + + return type; +} + +static void +ea_calendar_item_class_init (EaCalendarItemClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = ea_calendar_item_finalize; + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_calendar_item_get_name; + class->get_description = ea_calendar_item_get_description; + class->ref_state_set = ea_calendar_item_ref_state_set; + + class->get_n_children = ea_calendar_item_get_n_children; + class->ref_child = ea_calendar_item_ref_child; +} + +AtkObject* +ea_calendar_item_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + AtkObject *item_cell; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL); + object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL); + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, obj); + atk_object->role = ATK_ROLE_CALENDAR; + + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_object), + 0); + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell); + +#ifdef ACC_DEBUG + ++n_ea_calendar_item_created; + g_print ("ACC_DEBUG: n_ea_calendar_item_created = %d\n", + n_ea_calendar_item_created); +#endif + /* connect signal handlers */ + g_signal_connect (obj, "selection_preview_changed", + G_CALLBACK (selection_preview_change_cb), + atk_object); + g_signal_connect (obj, "date_range_changed", + G_CALLBACK (date_range_changed_cb), + atk_object); + + return atk_object; +} + +static void +ea_calendar_item_finalize (GObject *object) +{ + EaCalendarItem *ea_calitem; + + g_return_if_fail (EA_IS_CALENDAR_ITEM (object)); + + ea_calitem = EA_CALENDAR_ITEM (object); + + /* Free the allocated cell data */ + ea_calendar_item_destory_cell_data (ea_calitem); + + G_OBJECT_CLASS (parent_class)->finalize (object); +#ifdef ACC_DEBUG + ++n_ea_calendar_item_destroyed; + printf ("ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n", + n_ea_calendar_item_destroyed); +#endif +} + +static G_CONST_RETURN gchar * +ea_calendar_item_get_name (AtkObject *accessible) +{ + GObject *g_obj; + ECalendarItem *calitem; + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + gchar *name_str = NULL; + gchar buffer_start[128] = ""; + gchar buffer_end[128] = ""; + struct tm day_start = { 0 }; + struct tm day_end = { 0 }; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return NULL; + g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL); + + calitem = E_CALENDAR_ITEM (g_obj); + if (e_calendar_item_get_date_range (calitem, + &start_year, &start_month, &start_day, + &end_year, &end_month, &end_day)) { + + day_start.tm_year = start_year - 1900; + day_start.tm_mon = start_month; + day_start.tm_mday = start_day; + day_start.tm_isdst = -1; + e_utf8_strftime (buffer_start, sizeof (buffer_start), _("%d %B %Y"), &day_start); + + day_end.tm_year = end_year - 1900; + day_end.tm_mon = end_month; + day_end.tm_mday = end_day; + day_end.tm_isdst = -1; + e_utf8_strftime (buffer_end, sizeof (buffer_end), _("%d %B %Y"), &day_end); + + name_str = g_strdup_printf (_("Calendar: from %s to %s"), buffer_start, buffer_end); + } + +#if 0 + if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) { + GDate select_start, select_end; + gint year1, year2, month1, month2, day1, day2; + + year1 = g_date_get_year (&select_start); + month1 = g_date_get_month (&select_start); + day1 = g_date_get_day (&select_start); + + year2 = g_date_get_year (&select_end); + month2 = g_date_get_month (&select_end); + day2 = g_date_get_day (&select_end); + + sprintf (new_name + strlen (new_name), + " : current selection: from %d-%d-%d to %d-%d-%d.", + year1, month1, day1, + year2, month2, day2); + } +#endif + + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); + g_free (name_str); + + return accessible->name; +} + +static G_CONST_RETURN gchar * +ea_calendar_item_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + + return _("evolution calendar item"); +} + +static AtkStateSet* +ea_calendar_item_ref_state_set (AtkObject *accessible) +{ + AtkStateSet *state_set; + GObject *g_obj; + + state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible); + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + return state_set; + + atk_state_set_add_state (state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); + + return state_set; +} + +static gint +ea_calendar_item_get_n_children (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint n_children = 0; + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date, *end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return 0; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + end_date = g_date_new_dmy (end_day, end_month + 1, end_year); + + n_children = g_date_days_between (start_date, end_date) + 1; + g_free (start_date); + g_free (end_date); + return n_children; +} + +static AtkObject * +ea_calendar_item_ref_child (AtkObject *accessible, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint n_children; + ECalendarCell *cell; + EaCellTable *cell_data; + EaCalendarItem *ea_calitem; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + calitem = E_CALENDAR_ITEM (g_obj); + + n_children = ea_calendar_item_get_n_children (accessible); + if (index < 0 || index >= n_children) + return NULL; + + ea_calitem = EA_CALENDAR_ITEM (accessible); + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + cell = ea_cell_table_get_cell_at_index (cell_data, index); + if (!cell) { + cell = e_calendar_cell_new (calitem, + index / EA_CALENDAR_COLUMN_NUM, + index % EA_CALENDAR_COLUMN_NUM); + ea_cell_table_set_cell_at_index (cell_data, index, cell); + g_object_unref (cell); + } + +#ifdef ACC_DEBUG + g_print ("AccDebug: ea_calendar_item children[%d]=%p\n", index, + (gpointer)cell); +#endif + return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT(cell))); +} + +/* atk table interface */ + +static void +atk_table_interface_init (AtkTableIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->ref_at = table_interface_ref_at; + + iface->get_n_rows = table_interface_get_n_rows; + iface->get_n_columns = table_interface_get_n_columns; + iface->get_index_at = table_interface_get_index_at; + iface->get_column_at_index = table_interface_get_column_at_index; + iface->get_row_at_index = table_interface_get_row_at_index; + iface->get_column_extent_at = table_interface_get_column_extent_at; + iface->get_row_extent_at = table_interface_get_row_extent_at; + + iface->is_selected = table_interface_is_selected; + iface->get_selected_rows = table_interface_get_selected_rows; + iface->get_selected_columns = table_interface_get_selected_columns; + iface->is_row_selected = table_interface_is_row_selected; + iface->is_column_selected = table_interface_is_column_selected; + iface->add_row_selection = table_interface_add_row_selection; + iface->remove_row_selection = table_interface_remove_row_selection; + iface->add_column_selection = table_interface_add_column_selection; + iface->remove_column_selection = table_interface_remove_column_selection; + + iface->get_row_header = table_interface_get_row_header; + iface->get_column_header = table_interface_get_column_header; + iface->get_caption = table_interface_get_caption; + iface->get_summary = table_interface_get_summary; + iface->get_row_description = table_interface_get_row_description; + iface->get_column_description = table_interface_get_column_description; +} + +static AtkObject* +table_interface_ref_at (AtkTable *table, + gint row, + gint column) +{ + gint index; + + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + index = EA_CALENDAR_COLUMN_NUM * row + column; + return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index); +} + +static gint +table_interface_get_n_rows (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1; +} + +static gint +table_interface_get_n_columns (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + return EA_CALENDAR_COLUMN_NUM; +} + +static gint +table_interface_get_index_at (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + return row * EA_CALENDAR_COLUMN_NUM + column; +} + +static gint +table_interface_get_column_at_index (AtkTable *table, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + if (index >= 0 && index < n_children) + return index % EA_CALENDAR_COLUMN_NUM; + return -1; +} + +static gint +table_interface_get_row_at_index (AtkTable *table, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + gint n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem)); + if (index >= 0 && index < n_children) + return index / EA_CALENDAR_COLUMN_NUM; + return -1; +} + +static gint +table_interface_get_column_extent_at (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + return calitem->cell_width; +} + +static gint +table_interface_get_row_extent_at (AtkTable *table, + gint row, gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + return calitem->cell_height; +} + +/* any day in the row is selected, the row is selected */ +static gboolean +table_interface_is_row_selected (AtkTable *table, + gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + gint n_rows; + ECalendarItem *calitem; + gint row_index_start, row_index_end; + gint sel_index_start, sel_index_end; + + GDate start_date, end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return FALSE; + + row_index_start = row * EA_CALENDAR_COLUMN_NUM; + row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return FALSE; + + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date), + g_date_get_day (&start_date), + &sel_index_start); + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&end_date), + g_date_get_month (&end_date), + g_date_get_day (&end_date), + &sel_index_end); + + if ((sel_index_start < row_index_start && + sel_index_end >= row_index_start) || + (sel_index_start >= row_index_start && + sel_index_start <= row_index_end)) + return TRUE; + return FALSE; +} + +static gboolean +table_interface_is_selected (AtkTable *table, + gint row, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + gint n_rows, n_columns; + ECalendarItem *calitem; + gint index; + gint sel_index_start, sel_index_end; + + GDate start_date, end_date; + + g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (table); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return FALSE; + n_columns = table_interface_get_n_columns (table); + if (column < 0 || column >= n_columns) + return FALSE; + + index = table_interface_get_index_at (table, row, column); + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return FALSE; + + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date), + g_date_get_day (&start_date), + &sel_index_start); + e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&end_date), + g_date_get_month (&end_date), + g_date_get_day (&end_date), &sel_index_end); + + if (sel_index_start <= index && sel_index_end >= index) + return TRUE; + return FALSE; +} + +static gboolean +table_interface_is_column_selected (AtkTable *table, + gint column) +{ + return FALSE; +} + +static gint +table_interface_get_selected_rows (AtkTable *table, + gint **rows_selected) +{ + *rows_selected = NULL; + return -1; +} + +static gint +table_interface_get_selected_columns (AtkTable *table, + gint **columns_selected) +{ + *columns_selected = NULL; + return -1; +} + +static gboolean +table_interface_add_row_selection (AtkTable *table, + gint row) +{ + return FALSE; +} + +static gboolean +table_interface_remove_row_selection (AtkTable *table, + gint row) +{ + return FALSE; +} + +static gboolean +table_interface_add_column_selection (AtkTable *table, + gint column) +{ + return FALSE; +} + +static gboolean +table_interface_remove_column_selection (AtkTable *table, + gint column) +{ + /* FIXME: NOT IMPLEMENTED */ + return FALSE; +} + +static AtkObject* +table_interface_get_row_header (AtkTable *table, + gint row) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static AtkObject* +table_interface_get_column_header (AtkTable *table, + gint in_col) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static AtkObject* +table_interface_get_caption (AtkTable *table) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +static G_CONST_RETURN gchar * +table_interface_get_column_description (AtkTable *table, gint in_col) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + const gchar *description = NULL; + EaCellTable *cell_data; + gint n_columns; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + n_columns = table_interface_get_n_columns (table); + if (in_col < 0 || in_col >= n_columns) + return NULL; + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_column_label (cell_data, in_col); + if (!description) { + gchar buffer[128] = "column description"; + ea_calendar_item_get_column_label (ea_calitem, in_col, + buffer, sizeof (buffer)); + ea_cell_table_set_column_label (cell_data, in_col, buffer); + description = ea_cell_table_get_column_label (cell_data, + in_col); + } + return description; +} + +static G_CONST_RETURN gchar * +table_interface_get_row_description (AtkTable *table, gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table); + const gchar *description = NULL; + EaCellTable *cell_data; + gint n_rows; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + n_rows = table_interface_get_n_rows (table); + if (row < 0 || row >= n_rows) + return NULL; + cell_data = ea_calendar_item_get_cell_data (ea_calitem); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_row_label (cell_data, row); + if (!description) { + gchar buffer[128] = "row description"; + ea_calendar_item_get_row_label (ea_calitem, row, + buffer, sizeof (buffer)); + ea_cell_table_set_row_label (cell_data, row, buffer); + description = ea_cell_table_get_row_label (cell_data, + row); + } + return description; +} + +static AtkObject* +table_interface_get_summary (AtkTable *table) +{ + /* FIXME: NOT IMPLEMENTED */ + return NULL; +} + +/* atkselection interface */ + +static void +atk_selection_interface_init (AtkSelectionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->add_selection = selection_interface_add_selection; + iface->clear_selection = selection_interface_clear_selection; + iface->ref_selection = selection_interface_ref_selection; + iface->get_selection_count = selection_interface_get_selection_count; + iface->is_child_selected = selection_interface_is_child_selected; +} + +static gboolean +selection_interface_add_selection (AtkSelection *selection, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint year, month, day; + GDate start_date, end_date; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_date_for_offset (calitem, index, + &year, &month, &day)) + return FALSE; + + /* FIXME: not support mulit-selection */ + g_date_set_dmy (&start_date, day, month + 1, year); + end_date = start_date; + e_calendar_item_set_selection (calitem, &start_date, &end_date); + return TRUE; +} + +static gboolean +selection_interface_clear_selection (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + e_calendar_item_set_selection (calitem, NULL, NULL); + + return TRUE; +} + +static AtkObject* +selection_interface_ref_selection (AtkSelection *selection, gint i) +{ + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint count, sel_offset; + GDate start_date, end_date; + + count = selection_interface_get_selection_count (selection); + if (i < 0 || i >= count) + return NULL; + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem)); + + calitem = E_CALENDAR_ITEM (g_obj); + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return NULL; + if (!e_calendar_item_get_offset_for_date (calitem, + g_date_get_year (&start_date), + g_date_get_month (&start_date) - 1, + g_date_get_day (&start_date), + &sel_offset)) + return NULL; + + return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i); +} + +static gint +selection_interface_get_selection_count (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + GDate start_date, end_date; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return 0; + + calitem = E_CALENDAR_ITEM (g_obj); + if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return g_date_days_between (&start_date, &end_date) + 1; + else + return 0; +} + +static gboolean +selection_interface_is_child_selected (AtkSelection *selection, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection); + gint row, column, n_children; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection)); + if (index < 0 || index >= n_children) + return FALSE; + + row = index / EA_CALENDAR_COLUMN_NUM; + column = index % EA_CALENDAR_COLUMN_NUM; + + return table_interface_is_selected (ATK_TABLE (selection), row, column); +} + +/* callbacks */ + +static void +selection_preview_change_cb (ECalendarItem *calitem) +{ + AtkObject *atk_obj; + AtkObject *item_cell; + + g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); + + /* only deal with the first selected child, for now */ + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), + 0); + + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); + + g_signal_emit_by_name (atk_obj, + "active-descendant-changed", + item_cell); + g_signal_emit_by_name (atk_obj, "selection_changed"); +} + +static void +date_range_changed_cb (ECalendarItem *calitem) +{ + AtkObject *atk_obj; + AtkObject *item_cell; + + g_return_if_fail (E_IS_CALENDAR_ITEM (calitem)); + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem)); + ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj)); + + item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj), + 0); + if (item_cell) + ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell); + + g_signal_emit_by_name (atk_obj, "model_changed"); +} + +/* helpers */ + +static EaCellTable * +ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaCellTable *cell_data; + + g_return_val_if_fail (ea_calitem, NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + cell_data = g_object_get_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table"); + + if (!cell_data) { + gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT(ea_calitem)); + cell_data = ea_cell_table_create (n_cells/EA_CALENDAR_COLUMN_NUM, + EA_CALENDAR_COLUMN_NUM, + FALSE); + g_object_set_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table", cell_data); + } + return cell_data; +} + +static void +ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem) +{ + EaCellTable *cell_data; + + g_return_if_fail (ea_calitem); + + cell_data = g_object_get_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table"); + if (cell_data) { + g_object_set_data (G_OBJECT(ea_calitem), + "ea-calendar-cell-table", NULL); + ea_cell_table_destroy (cell_data); + } +} + +static gboolean +ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, gint row, + gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + gint index, week_num; + gint year, month, day; + + g_return_val_if_fail (ea_calitem, FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + calitem = E_CALENDAR_ITEM (g_obj); + + index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0); + if (!e_calendar_item_get_date_for_offset (calitem, index, + &year, &month, &day)) + return FALSE; + + week_num = e_calendar_item_get_week_number (calitem, + day, month, year); + + g_snprintf (buffer, buffer_size, "week number : %d", week_num); + return TRUE; +} + +static gboolean +ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, gint column, + gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarItem *calitem; + const gchar *abbr_name; + + g_return_val_if_fail (ea_calitem, FALSE); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + /* Columns are 0 = Monday ... 6 = Sunday */ + calitem = E_CALENDAR_ITEM (g_obj); + abbr_name = e_get_weekday_name (column + 1, TRUE); + g_strlcpy (buffer, abbr_name, buffer_size); + + return TRUE; +} + +/* the coordinate the e-calendar canvas coord */ +gboolean +e_calendar_item_get_day_extents (ECalendarItem *calitem, + gint year, gint month, gint date, + gint *x, gint *y, + gint *width, gint *height) +{ + GnomeCanvasItem *item; + GtkWidget *widget; + GtkStyle *style; + PangoFontDescription *font_desc; + PangoContext *pango_context; + PangoFontMetrics *font_metrics; + gint char_height, xthickness, ythickness, text_y; + gint new_year, new_month, num_months, months_offset; + gint month_x, month_y, month_cell_x, month_cell_y; + gint month_row, month_col; + gint day_row, day_col; + gint days_from_week_start; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + item = GNOME_CANVAS_ITEM (calitem); + widget = GTK_WIDGET (item->canvas); + style = widget->style; + + /* Set up Pango prerequisites */ + font_desc = calitem->font_desc; + if (!font_desc) + font_desc = style->font_desc; + pango_context = gtk_widget_get_pango_context (widget); + font_metrics = pango_context_get_metrics (pango_context, font_desc, + pango_context_get_language (pango_context)); + + char_height = + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); + + xthickness = style->xthickness; + ythickness = style->ythickness; + + new_year = year; + new_month = month; + e_calendar_item_normalize_date (calitem, &new_year, &new_month); + num_months = calitem->rows * calitem->cols; + months_offset = (new_year - calitem->year) * 12 + + new_month - calitem->month; + + if (months_offset > num_months || months_offset < 0) + return FALSE; + + month_row = months_offset / calitem->cols; + month_col = months_offset % calitem->cols; + + month_x = item->x1 + xthickness + calitem->x_offset + + month_col * calitem->month_width; + month_y = item->y1 + ythickness + month_row * calitem->month_height; + + month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS + + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS; + text_y = month_y + ythickness * 2 + + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME + + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME + + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad; + + month_cell_y = text_y + char_height + + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1 + + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS; + + days_from_week_start = + e_calendar_item_get_n_days_from_week_start (calitem, new_year, + new_month); + day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM; + day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM; + + *x = month_cell_x + day_col * calitem->cell_width; + *y = month_cell_y + day_row * calitem->cell_height; + *width = calitem->cell_width; + *height = calitem->cell_height; + + return TRUE; +} + +/* month is from 0 to 11 */ +gboolean +e_calendar_item_get_date_for_offset (ECalendarItem *calitem, gint day_offset, + gint *year, gint *month, gint *day) +{ + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date; + + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return FALSE; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + + g_date_add_days (start_date, day_offset); + + *year = g_date_get_year (start_date); + *month = g_date_get_month (start_date) - 1; + *day = g_date_get_day (start_date); + + return TRUE; +} + +/* the arg month is from 0 to 11 */ +static gboolean +e_calendar_item_get_offset_for_date (ECalendarItem *calitem, + gint year, gint month, gint day, + gint *offset) +{ + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + GDate *start_date, *end_date; + + *offset = 0; + g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE); + + if (!e_calendar_item_get_date_range (calitem, &start_year, + &start_month, &start_day, + &end_year, &end_month, + &end_day)) + return FALSE; + + start_date = g_date_new_dmy (start_day, start_month + 1, start_year); + end_date = g_date_new_dmy (day, month + 1, year); + + *offset = g_date_days_between (start_date, end_date); + g_free (start_date); + g_free (end_date); + + return TRUE; +} + +gint +e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, + gint year, gint month) +{ + struct tm tmp_tm; + gint start_weekday, days_from_week_start; + + memset (&tmp_tm, 0, sizeof (tmp_tm)); + tmp_tm.tm_year = year - 1900; + tmp_tm.tm_mon = month; + tmp_tm.tm_mday = 1; + tmp_tm.tm_isdst = -1; + mktime (&tmp_tm); + start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */ + days_from_week_start = (start_weekday + 7 - calitem->week_start_day) + % 7; + return days_from_week_start; +} + +static void +ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, AtkObject *item_cell) +{ + AtkStateSet *state_set, *old_state_set; + AtkObject *old_cell; + + old_cell = (AtkObject *)g_object_get_data (G_OBJECT(ea_calitem), "gail-focus-object"); + if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) { + old_state_set = atk_object_ref_state_set (old_cell); + atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED); + g_object_unref (old_state_set); + } + if (old_cell) + g_object_unref (old_cell); + + state_set = atk_object_ref_state_set (item_cell); + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + g_object_set_data (G_OBJECT(ea_calitem), "gail-focus-object", item_cell); + g_object_unref (state_set); +} diff --git a/widgets/misc/ea-calendar-item.h b/widgets/misc/ea-calendar-item.h new file mode 100644 index 0000000000..36cc671a3b --- /dev/null +++ b/widgets/misc/ea-calendar-item.h @@ -0,0 +1,68 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CALENDAR_ITEM_H__ +#define __EA_CALENDAR_ITEM_H__ + +#include +#include + +G_BEGIN_DECLS + +#define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ()) +#define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem)) +#define EA_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) +#define EA_IS_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_ITEM)) +#define EA_IS_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_ITEM)) +#define EA_CALENDAR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass)) + +typedef struct _EaCalendarItem EaCalendarItem; +typedef struct _EaCalendarItemClass EaCalendarItemClass; + +struct _EaCalendarItem +{ + AtkGObjectAccessible parent; +}; + +GType ea_calendar_item_get_type (void); + +struct _EaCalendarItemClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject *ea_calendar_item_new (GObject *obj); +gboolean e_calendar_item_get_day_extents (ECalendarItem *calitem, + gint year, gint month, gint date, + gint *x, gint *y, + gint *width, gint *height); +gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem, + gint day_offset, + gint *year, gint *month, + gint *day); +gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, + gint year, gint month); + +G_END_DECLS + + +#endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/ea-widgets.c b/widgets/misc/ea-widgets.c new file mode 100644 index 0000000000..9deede235e --- /dev/null +++ b/widgets/misc/ea-widgets.c @@ -0,0 +1,32 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "a11y/ea-factory.h" +#include "ea-calendar-item.h" +#include "ea-widgets.h" + +EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new) + +void e_calendar_item_a11y_init (void) +{ + EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item); +} diff --git a/widgets/misc/ea-widgets.h b/widgets/misc/ea-widgets.h new file mode 100644 index 0000000000..495222ae05 --- /dev/null +++ b/widgets/misc/ea-widgets.h @@ -0,0 +1,32 @@ +/* + * + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* Evolution Accessibility +*/ + +#ifndef _EA_WIDGETS_H__ +#define _EA_WIDGETS_H__ + +void e_calendar_item_a11y_init (void); + +#endif /* _EA_WIDGETS_H__ */ -- cgit v1.2.3 From bfc5ba2511dc5fd9f5aa9868946c8860afad81bf Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 30 Jun 2009 18:34:08 -0400 Subject: Fix "make distcheck" errors and other build cleanups. --- widgets/misc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index c7123d6977..69f9cf6f12 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/filter \ -I$(top_srcdir)/widgets \ -- cgit v1.2.3 From b554b165941e9b4e394554591e93e31e5accef16 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Jul 2009 12:16:23 -0400 Subject: Fix merge issues in EMAccountEditor. --- widgets/misc/e-charset-picker.c | 80 ++--------------------------------------- widgets/misc/e-charset-picker.h | 11 ++---- 2 files changed, 6 insertions(+), 85 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c index 593df6b651..dedeebd844 100644 --- a/widgets/misc/e-charset-picker.c +++ b/widgets/misc/e-charset-picker.c @@ -107,7 +107,6 @@ static ECharset charsets[] = { { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL }, { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN_NEW, NULL }, }; -static const gint num_charsets = sizeof (charsets) / sizeof (charsets[0]); static void select_item (GtkMenuShell *menu_shell, GtkWidget *item) @@ -301,13 +300,13 @@ e_charset_picker_new (const gchar *default_charset) if (!default_charset) default_charset = locale_charset; - for (def = 0; def < num_charsets; def++) { + for (def = 0; def < G_N_ELEMENTS (charsets); def++) { if (!g_ascii_strcasecmp (charsets[def].name, default_charset)) break; } menu = gtk_menu_new (); - for (i = 0; i < num_charsets; i++) { + for (i = 0; i < G_N_ELEMENTS (charsets); i++) { item = add_charset (menu, &charsets[i], FALSE); if (i == def) { activate (item, menu); @@ -318,7 +317,7 @@ e_charset_picker_new (const gchar *default_charset) /* do the Unknown/Other section */ gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new ()); - if (def == num_charsets) { + if (def == G_N_ELEMENTS (charsets)) { ECharset other = { NULL, E_CHARSET_UNKNOWN, NULL }; /* Add an entry for @default_charset */ @@ -361,79 +360,6 @@ e_charset_picker_get_charset (GtkWidget *menu) return g_strdup (charset); } -/** - * e_charset_picker_dialog: - * @title: title for the dialog box - * @prompt: prompt string for the dialog box - * @default_charset: as for e_charset_picker_new() - * @parent: a parent window for the dialog box, or %NULL - * - * This creates a new dialog box with the given @title and @prompt and - * a character set picker menu. It then runs the dialog and returns - * the selected character set, or %NULL if the user clicked "Cancel". - * - * Return value: the selected character set (which must be freed with - * g_free()), or %NULL. - **/ -gchar * -e_charset_picker_dialog (const gchar *title, const gchar *prompt, - const gchar *default_charset, GtkWindow *parent) -{ - GtkDialog *dialog; - GtkWidget *label, *omenu, *picker, *vbox, *hbox; - gchar *charset = NULL; - - dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (title, - parent, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL)); - - gtk_dialog_set_has_separator (dialog, FALSE); - gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); - gtk_box_pack_start (GTK_BOX (dialog->vbox), vbox, FALSE, FALSE, 0); - gtk_widget_show (vbox); - - label = gtk_label_new (prompt); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - - picker = e_charset_picker_new (default_charset); - omenu = gtk_option_menu_new (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), picker); - gtk_box_pack_start (GTK_BOX (hbox), omenu, TRUE, TRUE, 0); - gtk_widget_show (omenu); - - gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 12); - - gtk_widget_show_all (GTK_WIDGET (dialog)); - - g_object_ref (dialog); - - if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) - charset = e_charset_picker_get_charset (picker); - - gtk_widget_destroy (GTK_WIDGET (dialog)); - g_object_unref (dialog); - - return charset; -} - /** * e_charset_add_radio_actions: * @action_group: a #GtkActionGroup diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h index e399cf788c..16f19e3509 100644 --- a/widgets/misc/e-charset-picker.h +++ b/widgets/misc/e-charset-picker.h @@ -18,8 +18,8 @@ * */ -#ifndef E_CHARSETPICKER_H -#define E_CHARSETPICKER_H +#ifndef E_CHARSET_PICKER_H +#define E_CHARSET_PICKER_H #include @@ -27,11 +27,6 @@ G_BEGIN_DECLS GtkWidget * e_charset_picker_new (const gchar *default_charset); gchar * e_charset_picker_get_charset (GtkWidget *picker); -gchar * e_charset_picker_dialog (const gchar *title, - const gchar *prompt, - const gchar *default_charset, - GtkWindow *parent); - GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, const gchar *action_prefix, const gchar *default_charset, @@ -40,4 +35,4 @@ GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, G_END_DECLS -#endif /* E_CHARSETPICKER_H */ +#endif /* E_CHARSET_PICKER_H */ -- cgit v1.2.3 From a1082f0e45e1e34c3f0193ff3a51588c89f914c1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 2 Jul 2009 13:49:11 -0400 Subject: Kill the last GtkOptionMenu instances. Wrote a new widget (ECharsetComboBox) to replace e-charset-picker.c. The widget provides a "charset" string property that allows us to bind to GConf keys (via EShellSettings). Moved e_charset_add_radio_actions() to e-util/e-charset.c. Updated Glade files, #include lines, etc. --- widgets/misc/Makefile.am | 4 +- widgets/misc/e-charset-picker.c | 508 ---------------------------------------- widgets/misc/e-charset-picker.h | 38 --- 3 files changed, 2 insertions(+), 548 deletions(-) delete mode 100644 widgets/misc/e-charset-picker.c delete mode 100644 widgets/misc/e-charset-picker.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ee11ea746e..d893247818 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -57,7 +57,7 @@ widgetsinclude_HEADERS = \ e-canvas-utils.h \ e-canvas-vbox.h \ e-cell-renderer-combo.h \ - e-charset-picker.h \ + e-charset-combo-box.h \ e-colors.h \ e-combo-cell-editable.h \ e-cursors.h \ @@ -120,7 +120,7 @@ libemiscwidgets_la_SOURCES = \ e-canvas-utils.c \ e-canvas-vbox.c \ e-cell-renderer-combo.c \ - e-charset-picker.c \ + e-charset-combo-box.c \ e-colors.c \ e-combo-cell-editable.c \ e-cursors.c \ diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c deleted file mode 100644 index dedeebd844..0000000000 --- a/widgets/misc/e-charset-picker.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * 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 - * - * - * Authors: - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-charset-picker.h" -#include "e-util/e-dialog-utils.h" - -#include -#include - -#include - -typedef enum { - E_CHARSET_UNKNOWN, - E_CHARSET_ARABIC, - E_CHARSET_BALTIC, - E_CHARSET_CENTRAL_EUROPEAN, - E_CHARSET_CHINESE, - E_CHARSET_CYRILLIC, - E_CHARSET_GREEK, - E_CHARSET_HEBREW, - E_CHARSET_JAPANESE, - E_CHARSET_KOREAN, - E_CHARSET_THAI, - E_CHARSET_TURKISH, - E_CHARSET_UNICODE, - E_CHARSET_WESTERN_EUROPEAN, - E_CHARSET_WESTERN_EUROPEAN_NEW -} ECharsetClass; - -static const gchar *classnames[] = { - N_("Unknown"), - N_("Arabic"), - N_("Baltic"), - N_("Central European"), - N_("Chinese"), - N_("Cyrillic"), - N_("Greek"), - N_("Hebrew"), - N_("Japanese"), - N_("Korean"), - N_("Thai"), - N_("Turkish"), - N_("Unicode"), - N_("Western European"), - N_("Western European, New"), -}; - -typedef struct { - const gchar *name; - ECharsetClass class; - const gchar *subclass; -} ECharset; - -/* This list is based on what other mailers/browsers support. There's - * not a lot of point in using, say, ISO-8859-3, if anything that can - * read that can read UTF8 too. - */ -/* To Translators: Character set "Logical Hebrew" */ -static ECharset charsets[] = { - { "ISO-8859-6", E_CHARSET_ARABIC, NULL }, - { "ISO-8859-13", E_CHARSET_BALTIC, NULL }, - { "ISO-8859-4", E_CHARSET_BALTIC, NULL }, - { "ISO-8859-2", E_CHARSET_CENTRAL_EUROPEAN, NULL }, - { "Big5", E_CHARSET_CHINESE, N_("Traditional") }, - { "BIG5HKSCS", E_CHARSET_CHINESE, N_("Traditional") }, - { "EUC-TW", E_CHARSET_CHINESE, N_("Traditional") }, - { "GB18030", E_CHARSET_CHINESE, N_("Simplified") }, - { "GB2312", E_CHARSET_CHINESE, N_("Simplified") }, - { "HZ", E_CHARSET_CHINESE, N_("Simplified") }, - { "ISO-2022-CN", E_CHARSET_CHINESE, N_("Simplified") }, - { "KOI8-R", E_CHARSET_CYRILLIC, NULL }, - { "Windows-1251", E_CHARSET_CYRILLIC, NULL }, - { "KOI8-U", E_CHARSET_CYRILLIC, N_("Ukrainian") }, - { "ISO-8859-5", E_CHARSET_CYRILLIC, NULL }, - { "ISO-8859-7", E_CHARSET_GREEK, NULL }, - { "ISO-8859-8", E_CHARSET_HEBREW, N_("Visual") }, - { "ISO-2022-JP", E_CHARSET_JAPANESE, NULL }, - { "EUC-JP", E_CHARSET_JAPANESE, NULL }, - { "Shift_JIS", E_CHARSET_JAPANESE, NULL }, - { "EUC-KR", E_CHARSET_KOREAN, NULL }, - { "TIS-620", E_CHARSET_THAI, NULL }, - { "ISO-8859-9", E_CHARSET_TURKISH, NULL }, - { "UTF-8", E_CHARSET_UNICODE, NULL }, - { "UTF-7", E_CHARSET_UNICODE, NULL }, - { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL }, - { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN_NEW, NULL }, -}; - -static void -select_item (GtkMenuShell *menu_shell, GtkWidget *item) -{ - gtk_menu_shell_select_item (menu_shell, item); - gtk_menu_shell_deactivate (menu_shell); -} - -static void -activate (GtkWidget *item, gpointer menu) -{ - g_object_set_data ((GObject *) menu, "activated_item", item); -} - -static GtkWidget * -add_charset (GtkWidget *menu, ECharset *charset, gboolean free_name) -{ - GtkWidget *item; - gchar *label; - - if (charset->subclass) { - label = g_strdup_printf ("%s, %s (%s)", - _(classnames[charset->class]), - _(charset->subclass), - charset->name); - } else if (charset->class) { - label = g_strdup_printf ("%s (%s)", - _(classnames[charset->class]), - charset->name); - } else { - label = g_strdup (charset->name); - } - - item = gtk_menu_item_new_with_label (label); - g_object_set_data_full ((GObject *) item, "charset", - (gpointer) charset->name, free_name ? g_free : NULL); - g_free (label); - - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - g_signal_connect (item, "activate", G_CALLBACK (activate), menu); - - return item; -} - -static gboolean -add_other_charset (GtkWidget *menu, GtkWidget *other, const gchar *new_charset) -{ - ECharset charset = { NULL, E_CHARSET_UNKNOWN, NULL }; - GtkWidget *item; - iconv_t ic; - - ic = iconv_open ("UTF-8", new_charset); - if (ic == (iconv_t)-1) { - GtkWidget *window = gtk_widget_get_ancestor (other, GTK_TYPE_WINDOW); - e_notice (window, GTK_MESSAGE_ERROR, - _("Unknown character set: %s"), new_charset); - return FALSE; - } - iconv_close (ic); - - /* Temporarily remove the "Other..." item */ - g_object_ref (other); - gtk_container_remove (GTK_CONTAINER (menu), other); - - /* Create new menu item */ - charset.name = g_strdup (new_charset); - item = add_charset (menu, &charset, TRUE); - - /* And re-add "Other..." */ - gtk_menu_shell_append (GTK_MENU_SHELL (menu), other); - g_object_unref (other); - - g_object_set_data_full ((GObject *) menu, "other_charset", - g_strdup (new_charset), g_free); - - g_object_set_data ((GObject *) menu, "activated_item", item); - select_item (GTK_MENU_SHELL (menu), item); - - return TRUE; -} - -static void -activate_entry (GtkWidget *entry, GtkDialog *dialog) -{ - gtk_dialog_response (dialog, GTK_RESPONSE_OK); -} - -static void -activate_other (GtkWidget *item, gpointer menu) -{ - GtkWidget *window, *entry, *label, *vbox, *hbox; - gchar *old_charset, *new_charset; - GtkDialog *dialog; - - window = gtk_widget_get_toplevel (menu); - if (!GTK_WIDGET_TOPLEVEL (window)) - window = gtk_widget_get_ancestor (item, GTK_TYPE_WINDOW); - - old_charset = g_object_get_data(menu, "other_charset"); - - dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Character Encoding"), - GTK_WINDOW (window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL)); - - gtk_dialog_set_has_separator (dialog, FALSE); - gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); - gtk_box_pack_start (GTK_BOX (dialog->vbox), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - label = gtk_label_new (_("Enter the character set to use")); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); - gtk_widget_show (entry); - - if (old_charset) - gtk_entry_set_text (GTK_ENTRY (entry), old_charset); - g_signal_connect (entry, "activate", - G_CALLBACK (activate_entry), dialog); - - gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0); - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 12); - - gtk_widget_show_all (GTK_WIDGET (dialog)); - - g_object_ref (dialog); - if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) { - new_charset = (gchar *)gtk_entry_get_text (GTK_ENTRY (entry)); - - if (*new_charset) { - if (add_other_charset (menu, item, new_charset)) { - gtk_widget_destroy (GTK_WIDGET (dialog)); - g_object_unref (dialog); - return; - } - } - } - gtk_widget_destroy (GTK_WIDGET (dialog)); - g_object_unref (dialog); - - /* Revert to previous selection */ - select_item (GTK_MENU_SHELL (menu), g_object_get_data(G_OBJECT(menu), "activated_item")); -} - -/** - * e_charset_picker_new: - * @default_charset: the default character set, or %NULL to use the - * locale character set. - * - * This creates an option menu widget and fills it in with a selection - * of available character sets. The @default_charset (or locale character - * set if @default_charset is %NULL) will be listed first, and selected - * by default (except that iso-8859-1 will always be used instead of - * US-ASCII). Any other character sets of the same language class as - * the default will be listed next, followed by the remaining character - * sets, a separator, and an "Other..." menu item, which can be used to - * select other charsets. - * - * Return value: an option menu widget, filled in and with signals - * attached. - */ -GtkWidget * -e_charset_picker_new (const gchar *default_charset) -{ - GtkWidget *menu, *item; - gint def, i; - const gchar *locale_charset; - - g_get_charset (&locale_charset); - if (!g_ascii_strcasecmp (locale_charset, "US-ASCII")) - locale_charset = "iso-8859-1"; - - if (!default_charset) - default_charset = locale_charset; - for (def = 0; def < G_N_ELEMENTS (charsets); def++) { - if (!g_ascii_strcasecmp (charsets[def].name, default_charset)) - break; - } - - menu = gtk_menu_new (); - for (i = 0; i < G_N_ELEMENTS (charsets); i++) { - item = add_charset (menu, &charsets[i], FALSE); - if (i == def) { - activate (item, menu); - select_item (GTK_MENU_SHELL (menu), item); - } - } - - /* do the Unknown/Other section */ - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new ()); - - if (def == G_N_ELEMENTS (charsets)) { - ECharset other = { NULL, E_CHARSET_UNKNOWN, NULL }; - - /* Add an entry for @default_charset */ - other.name = g_strdup (default_charset); - item = add_charset (menu, &other, TRUE); - activate (item, menu); - select_item (GTK_MENU_SHELL (menu), item); - g_object_set_data_full ((GObject *) menu, "other_charset", - g_strdup (default_charset), g_free); - def++; - } - - item = gtk_menu_item_new_with_label (_("Other...")); - g_signal_connect (item, "activate", G_CALLBACK (activate_other), menu); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - gtk_widget_show_all (menu); - - return menu; -} - -/** - * e_charset_picker_get_charset: - * @menu: a character set menu from e_charset_picker_new() - * - * Return value: the currently-selected character set in @picker, - * which must be freed with g_free(). - **/ -gchar * -e_charset_picker_get_charset (GtkWidget *menu) -{ - GtkWidget *item; - gchar *charset; - - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - item = gtk_menu_get_active (GTK_MENU (menu)); - charset = g_object_get_data ((GObject *) item, "charset"); - - return g_strdup (charset); -} - -/** - * e_charset_add_radio_actions: - * @action_group: a #GtkActionGroup - * @action_prefix: a prefix for action names, or %NULL - * @default_charset: the default character set, or %NULL to use the - * locale character set - * @callback: a callback function for actions in the group, or %NULL - * @user_data: user data to be passed to @callback, or %NULL - * - * Adds a set of #GtkRadioActions for available character sets to - * @action_group. The @default_charset (or locale character set if - * @default_charset is %NULL) will be added first, and selected by - * default (except that iso-8859-1 will always be used instead of - * US-ASCII). Any other character sets of the same language class as - * the default will be added next, followed by the remaining character - * sets. - **/ -GSList * -e_charset_add_radio_actions (GtkActionGroup *action_group, - const gchar *action_prefix, - const gchar *default_charset, - GCallback callback, - gpointer user_data) -{ - GtkRadioAction *action = NULL; - GSList *group = NULL; - const gchar *locale_charset; - gint def, ii; - - g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL); - - if (action_prefix == NULL) - action_prefix = ""; - - g_get_charset (&locale_charset); - if (!g_ascii_strcasecmp (locale_charset, "US-ASCII")) - locale_charset = "iso-8859-1"; - - if (default_charset == NULL) - default_charset = locale_charset; - for (def = 0; def < G_N_ELEMENTS (charsets); def++) - if (!g_ascii_strcasecmp (charsets[def].name, default_charset)) - break; - - for (ii = 0; ii < G_N_ELEMENTS (charsets); ii++) { - const gchar *charset_name; - gchar *action_name; - gchar *escaped_name; - gchar *charset_label; - gchar **str_array; - - charset_name = charsets[ii].name; - action_name = g_strconcat (action_prefix, charset_name, NULL); - - /* Escape underlines in the character set name so - * they're not treated as GtkLabel mnemonics. */ - str_array = g_strsplit (charset_name, "_", -1); - escaped_name = g_strjoinv ("__", str_array); - g_strfreev (str_array); - - if (charsets[ii].subclass != NULL) - charset_label = g_strdup_printf ( - "%s, %s (%s)", - gettext (classnames[charsets[ii].class]), - gettext (charsets[ii].subclass), - escaped_name); - else if (charsets[ii].class != E_CHARSET_UNKNOWN) - charset_label = g_strdup_printf ( - "%s (%s)", - gettext (classnames[charsets[ii].class]), - escaped_name); - else - charset_label = g_strdup (escaped_name); - - /* XXX Add a tooltip! */ - action = gtk_radio_action_new ( - action_name, charset_label, NULL, NULL, ii); - - /* Character set name is static so no need to free it. */ - g_object_set_data ( - G_OBJECT (action), "charset", - (gpointer) charset_name); - - gtk_radio_action_set_group (action, group); - group = gtk_radio_action_get_group (action); - - if (callback != NULL) - g_signal_connect ( - action, "changed", callback, user_data); - - gtk_action_group_add_action ( - action_group, GTK_ACTION (action)); - - g_object_unref (action); - - g_free (action_name); - g_free (escaped_name); - g_free (charset_label); - } - - if (def == G_N_ELEMENTS (charsets)) { - const gchar *charset_name; - gchar *action_name; - gchar *charset_label; - gchar **str_array; - - charset_name = default_charset; - action_name = g_strconcat (action_prefix, charset_name, NULL); - - /* Escape underlines in the character set name so - * they're not treated as GtkLabel mnemonics. */ - str_array = g_strsplit (charset_name, "_", -1); - charset_label = g_strjoinv ("__", str_array); - g_strfreev (str_array); - - /* XXX Add a tooltip! */ - action = gtk_radio_action_new ( - action_name, charset_label, NULL, NULL, def); - - /* Character set name is static so no need to free it. */ - g_object_set_data ( - G_OBJECT (action), "charset", - (gpointer) charset_name); - - gtk_radio_action_set_group (action, group); - group = gtk_radio_action_get_group (action); - - if (callback != NULL) - g_signal_connect ( - action, "changed", callback, user_data); - - gtk_action_group_add_action ( - action_group, GTK_ACTION (action)); - - g_object_unref (action); - - g_free (action_name); - g_free (charset_label); - } - - /* Any of the actions in the action group will do. */ - if (action != NULL) - gtk_radio_action_set_current_value (action, def); - - return group; -} diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h deleted file mode 100644 index 16f19e3509..0000000000 --- a/widgets/misc/e-charset-picker.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * 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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_CHARSET_PICKER_H -#define E_CHARSET_PICKER_H - -#include - -G_BEGIN_DECLS - -GtkWidget * e_charset_picker_new (const gchar *default_charset); -gchar * e_charset_picker_get_charset (GtkWidget *picker); -GSList * e_charset_add_radio_actions (GtkActionGroup *action_group, - const gchar *action_prefix, - const gchar *default_charset, - GCallback callback, - gpointer user_data); - -G_END_DECLS - -#endif /* E_CHARSET_PICKER_H */ -- cgit v1.2.3 From 11a1fab991cefe94f90a5c4f4a5567dc068dce05 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 2 Jul 2009 16:30:51 -0400 Subject: Add missing files. --- widgets/misc/e-charset-combo-box.c | 428 +++++++++++++++++++++++++++++++++++++ widgets/misc/e-charset-combo-box.h | 69 ++++++ 2 files changed, 497 insertions(+) create mode 100644 widgets/misc/e-charset-combo-box.c create mode 100644 widgets/misc/e-charset-combo-box.h (limited to 'widgets/misc') diff --git a/widgets/misc/e-charset-combo-box.c b/widgets/misc/e-charset-combo-box.c new file mode 100644 index 0000000000..9c992ce1f7 --- /dev/null +++ b/widgets/misc/e-charset-combo-box.c @@ -0,0 +1,428 @@ +/* + * e-charset-combo-box.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-charset-combo-box.h" + +#include + +#include "e-util/e-charset.h" +#include "e-util/e-util.h" + +#define E_CHARSET_COMBO_BOX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxPrivate)) + +#define DEFAULT_CHARSET "UTF-8" +#define OTHER_VALUE G_MAXINT + +struct _ECharsetComboBoxPrivate { + GtkActionGroup *action_group; + GtkRadioAction *other_action; + GHashTable *charset_index; + + /* Used when the user clicks Cancel in the character set + * dialog. Reverts to the previous combo box setting. */ + gint previous_index; + + /* When setting the character set programmatically, this + * prevents the custom character set dialog from running. */ + guint block_dialog : 1; +}; + +enum { + PROP_0, + PROP_CHARSET +}; + +static gpointer parent_class; + +static void +charset_combo_box_entry_changed_cb (GtkEntry *entry, + GtkDialog *dialog) +{ + const gchar *text; + gboolean sensitive; + + text = gtk_entry_get_text (entry); + sensitive = (text != NULL && *text != '\0'); + gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, sensitive); +} + +static void +charset_combo_box_run_dialog (ECharsetComboBox *combo_box) +{ + GtkDialog *dialog; + GtkEntry *entry; + GtkWidget *container; + GtkWidget *widget; + GObject *object; + gpointer parent; + const gchar *charset; + + /* FIXME Using a dialog for this is lame. Selecting "Other..." + * should unlock an entry directly in the Preferences tab. + * Unfortunately space in Preferences is at a premium right + * now, but we should revisit this when the space issue is + * finally resolved. */ + + parent = gtk_widget_get_toplevel (GTK_WIDGET (combo_box)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + object = G_OBJECT (combo_box->priv->other_action); + charset = g_object_get_data (object, "charset"); + + widget = gtk_dialog_new_with_buttons ( + _("Character Encoding"), parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + + /* Load the broken border width defaults so we can override them. */ + gtk_widget_ensure_style (widget); + + dialog = GTK_DIALOG (widget); + + gtk_dialog_set_has_separator (dialog, FALSE); + gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); + + widget = gtk_dialog_get_action_area (dialog); + gtk_container_set_border_width (GTK_CONTAINER (widget), 0); + + widget = gtk_dialog_get_content_area (dialog); + gtk_box_set_spacing (GTK_BOX (widget), 12); + gtk_container_set_border_width (GTK_CONTAINER (widget), 0); + + container = widget; + + widget = gtk_label_new (_("Enter the character set to use")); + gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_entry_new (); + entry = GTK_ENTRY (widget); + gtk_entry_set_activates_default (entry, TRUE); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + g_signal_connect ( + entry, "changed", + G_CALLBACK (charset_combo_box_entry_changed_cb), dialog); + + /* Set the default text -after- connecting the signal handler. + * This will initialize the "OK" button to the proper state. */ + gtk_entry_set_text (entry, charset); + + if (gtk_dialog_run (dialog) != GTK_RESPONSE_OK) { + gint active; + + /* Revert to the previously selected character set. */ + combo_box->priv->block_dialog = TRUE; + active = combo_box->priv->previous_index; + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), active); + combo_box->priv->block_dialog = FALSE; + + goto exit; + } + + charset = gtk_entry_get_text (entry); + g_return_if_fail (charset != NULL && charset != '\0'); + + g_object_set_data_full ( + object, "charset", g_strdup (charset), + (GDestroyNotify) g_free); + +exit: + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void +charset_combo_box_notify_charset_cb (ECharsetComboBox *combo_box) +{ + GtkToggleAction *action; + + action = GTK_TOGGLE_ACTION (combo_box->priv->other_action); + if (!gtk_toggle_action_get_active (action)) + return; + + if (combo_box->priv->block_dialog) + return; + + /* "Other" action was selected by user. */ + charset_combo_box_run_dialog (combo_box); +} + +static void +charset_combo_box_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CHARSET: + e_charset_combo_box_set_charset ( + E_CHARSET_COMBO_BOX (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +charset_combo_box_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CHARSET: + g_value_set_string ( + value, e_charset_combo_box_get_charset ( + E_CHARSET_COMBO_BOX (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +charset_combo_box_dispose (GObject *object) +{ + ECharsetComboBoxPrivate *priv; + + priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object); + + if (priv->action_group != NULL) { + g_object_unref (priv->action_group); + priv->action_group = NULL; + } + + if (priv->other_action != NULL) { + g_object_unref (priv->other_action); + priv->other_action = NULL; + } + + g_hash_table_remove_all (priv->charset_index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +charset_combo_box_finalize (GObject *object) +{ + ECharsetComboBoxPrivate *priv; + + priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object); + + g_hash_table_destroy (priv->charset_index); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +charset_combo_box_changed (GtkComboBox *combo_box) +{ + ECharsetComboBoxPrivate *priv; + + priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box); + + /* Chain up to parent's changed() method. */ + GTK_COMBO_BOX_CLASS (parent_class)->changed (combo_box); + + /* Notify -before- updating previous index. */ + g_object_notify (G_OBJECT (combo_box), "charset"); + priv->previous_index = gtk_combo_box_get_active (combo_box); +} + +static void +charset_combo_box_class_init (ECharsetComboBoxClass *class) +{ + GObjectClass *object_class; + GtkComboBoxClass *combo_box_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECharsetComboBoxPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = charset_combo_box_set_property; + object_class->get_property = charset_combo_box_get_property; + object_class->dispose = charset_combo_box_dispose; + object_class->finalize = charset_combo_box_finalize; + + combo_box_class = GTK_COMBO_BOX_CLASS (class); + combo_box_class->changed = charset_combo_box_changed; + + g_object_class_install_property ( + object_class, + PROP_CHARSET, + g_param_spec_string ( + "charset", + "Charset", + "The selected character set", + "UTF-8", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); +} + +static void +charset_combo_box_init (ECharsetComboBox *combo_box) +{ + GtkActionGroup *action_group; + GtkRadioAction *radio_action; + GHashTable *charset_index; + GSList *group, *iter; + + action_group = gtk_action_group_new ("charset-combo-box-internal"); + + charset_index = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + combo_box->priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box); + combo_box->priv->action_group = action_group; + combo_box->priv->charset_index = charset_index; + + group = e_charset_add_radio_actions ( + action_group, "charset-", NULL, NULL, NULL); + + /* Populate the character set index. */ + for (iter = group; iter != NULL; iter = iter->next) { + GObject *object = iter->data; + const gchar *charset; + + charset = g_object_get_data (object, "charset"); + g_return_if_fail (charset != NULL); + + g_hash_table_insert ( + charset_index, g_strdup (charset), + g_object_ref (object)); + } + + /* Note the "other" action is not included in the index. */ + + radio_action = gtk_radio_action_new ( + "charset-other", _("Other..."), NULL, NULL, OTHER_VALUE); + + g_object_set_data (G_OBJECT (radio_action), "charset", (gpointer) ""); + + gtk_radio_action_set_group (radio_action, group); + group = gtk_radio_action_get_group (radio_action); + + e_action_combo_box_set_action ( + E_ACTION_COMBO_BOX (combo_box), radio_action); + + e_action_combo_box_add_separator_after ( + E_ACTION_COMBO_BOX (combo_box), g_slist_length (group)); + + g_signal_connect ( + combo_box, "notify::charset", + G_CALLBACK (charset_combo_box_notify_charset_cb), NULL); + + combo_box->priv->other_action = radio_action; +} + +GType +e_charset_combo_box_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECharsetComboBoxClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) charset_combo_box_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECharsetComboBox), + 0, /* n_preallocs */ + (GInstanceInitFunc) charset_combo_box_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ACTION_COMBO_BOX, "ECharsetComboBox", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_charset_combo_box_new (void) +{ + return g_object_new (E_TYPE_CHARSET_COMBO_BOX, NULL); +} + +const gchar * +e_charset_combo_box_get_charset (ECharsetComboBox *combo_box) +{ + GtkRadioAction *radio_action; + + g_return_val_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box), NULL); + + radio_action = combo_box->priv->other_action; + radio_action = e_radio_action_get_current_action (radio_action); + + return g_object_get_data (G_OBJECT (radio_action), "charset"); +} + +void +e_charset_combo_box_set_charset (ECharsetComboBox *combo_box, + const gchar *charset) +{ + GHashTable *charset_index; + GtkRadioAction *radio_action; + + g_return_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box)); + + if (charset == NULL || *charset == '\0') + charset = "UTF-8"; + + charset_index = combo_box->priv->charset_index; + radio_action = g_hash_table_lookup (charset_index, charset); + + if (radio_action == NULL) { + radio_action = combo_box->priv->other_action; + g_object_set_data_full ( + G_OBJECT (radio_action), + "charset", g_strdup (charset), + (GDestroyNotify) g_free); + } + + combo_box->priv->block_dialog = TRUE; + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (radio_action), TRUE); + combo_box->priv->block_dialog = FALSE; +} diff --git a/widgets/misc/e-charset-combo-box.h b/widgets/misc/e-charset-combo-box.h new file mode 100644 index 0000000000..471dfa6a54 --- /dev/null +++ b/widgets/misc/e-charset-combo-box.h @@ -0,0 +1,69 @@ +/* + * e-charset-combo-box.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CHARSET_COMBO_BOX_H +#define E_CHARSET_COMBO_BOX_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_CHARSET_COMBO_BOX \ + (e_charset_combo_box_get_type ()) +#define E_CHARSET_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBox)) +#define E_CHARSET_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass)) +#define E_IS_CHARSET_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CHARSET_COMBO_BOX)) +#define E_IS_CHARSET_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CHARSET_COMBO_BOX)) +#define E_CHARSET_COMBO_BOX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass)) + +G_BEGIN_DECLS + +typedef struct _ECharsetComboBox ECharsetComboBox; +typedef struct _ECharsetComboBoxClass ECharsetComboBoxClass; +typedef struct _ECharsetComboBoxPrivate ECharsetComboBoxPrivate; + +struct _ECharsetComboBox { + EActionComboBox parent; + ECharsetComboBoxPrivate *priv; +}; + +struct _ECharsetComboBoxClass { + EActionComboBoxClass parent_class; +}; + +GType e_charset_combo_box_get_type (void); +GtkWidget * e_charset_combo_box_new (void); +const gchar * e_charset_combo_box_get_charset (ECharsetComboBox *combo_box); +void e_charset_combo_box_set_charset (ECharsetComboBox *combo_box, + const gchar *charset); + +G_END_DECLS + +#endif /* E_CHARSET_COMBO_BOX_H */ -- cgit v1.2.3 From 374bd42f69aca2e132fd854c9619f3d7491f1f96 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 12 Jul 2009 23:33:07 -0400 Subject: Fix excessive whitespace. --- widgets/misc/e-calendar-item.c | 55 ---------------------------- widgets/misc/e-calendar-item.h | 4 --- widgets/misc/e-calendar.c | 18 ---------- widgets/misc/e-calendar.h | 2 -- widgets/misc/e-canvas-background.h | 2 -- widgets/misc/e-canvas-utils.c | 2 -- widgets/misc/e-canvas-vbox.c | 1 - widgets/misc/e-canvas-vbox.h | 2 -- widgets/misc/e-canvas.c | 6 ---- widgets/misc/e-canvas.h | 3 -- widgets/misc/e-cursors.c | 2 -- widgets/misc/e-dateedit.c | 60 ------------------------------- widgets/misc/e-gui-utils.c | 1 - widgets/misc/e-hsv-utils.c | 1 - widgets/misc/e-map.c | 65 ---------------------------------- widgets/misc/e-map.h | 1 - widgets/misc/e-pilot-settings.c | 3 -- widgets/misc/e-popup-menu.c | 1 - widgets/misc/e-popup-menu.h | 3 -- widgets/misc/e-printable.c | 1 - widgets/misc/e-selection-model-array.c | 1 - widgets/misc/e-selection-model-array.h | 1 - widgets/misc/e-selection-model.h | 3 -- widgets/misc/e-send-options.c | 4 --- widgets/misc/e-spinner.c | 1 - widgets/misc/e-url-entry.c | 3 -- widgets/misc/ea-calendar-cell.c | 1 - widgets/misc/ea-calendar-item.h | 1 - widgets/misc/test-calendar.c | 5 --- widgets/misc/test-dateedit.c | 6 ---- 30 files changed, 259 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 9c548947d6..41b5eea6ca 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -44,7 +44,6 @@ static const gint e_calendar_item_days_in_month[12] = { e_calendar_item_days_in_month[month] + (((month) == 1 \ && ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))) ? 1 : 0) - static void e_calendar_item_dispose (GObject *object); static void e_calendar_item_get_property(GObject *object, guint property_id, @@ -227,12 +226,10 @@ enum { LAST_SIGNAL }; - static guint e_calendar_item_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (ECalendarItem, e_calendar_item, GNOME_TYPE_CANVAS_ITEM) - static void e_calendar_item_class_init (ECalendarItemClass *class) { @@ -526,7 +523,6 @@ e_calendar_item_class_init (ECalendarItemClass *class) e_calendar_item_a11y_init (); } - static void e_calendar_item_init (ECalendarItem *calitem) { @@ -582,7 +578,6 @@ e_calendar_item_init (ECalendarItem *calitem) calitem->signal_emission_idle_id = 0; } - static void e_calendar_item_dispose (GObject *object) { @@ -619,7 +614,6 @@ e_calendar_item_dispose (GObject *object) G_OBJECT_CLASS (e_calendar_item_parent_class)->dispose (object); } - static void e_calendar_item_get_property (GObject *object, guint property_id, @@ -701,7 +695,6 @@ e_calendar_item_get_property (GObject *object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } - static void e_calendar_item_set_property (GObject *object, guint property_id, @@ -853,7 +846,6 @@ e_calendar_item_realize (GnomeCanvasItem *item) e_calendar_item_style_set (GTK_WIDGET(item->canvas), calitem); } - static void e_calendar_item_unrealize (GnomeCanvasItem *item) { @@ -870,7 +862,6 @@ e_calendar_item_unrealize (GnomeCanvasItem *item) (* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unrealize) (item); } - static void e_calendar_item_unmap (GnomeCanvasItem *item) { @@ -887,7 +878,6 @@ e_calendar_item_unmap (GnomeCanvasItem *item) (* GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class)->unmap) (item); } - static void e_calendar_item_update (GnomeCanvasItem *item, double *affine, @@ -1018,7 +1008,6 @@ e_calendar_item_update (GnomeCanvasItem *item, pango_font_metrics_unref (font_metrics); } - /* * DRAWING ROUTINES - functions to paint the canvas item. */ @@ -1068,7 +1057,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item, bg = style->bg[GTK_STATE_NORMAL]; cr = gdk_cairo_create (drawable); - /* Clear the entire background. */ cairo_save (cr); gdk_cairo_set_source_color (cr, &base); @@ -1111,7 +1099,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item, - xthickness * 2, bar_height); - for (col = 0; col < calitem->cols; col++) { if (col != 0) { col_x = calitem->x1 + calitem->x_offset @@ -1126,7 +1113,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item, col_x - 1 - x); } - e_calendar_item_draw_month (calitem, drawable, x, y, width, height, row, col); } @@ -1138,7 +1124,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item, cairo_destroy (cr); } - static void layout_set_day_text (ECalendarItem *calitem, PangoLayout *layout, gint day_index) { @@ -1764,8 +1749,6 @@ e_calendar_item_get_week_number (ECalendarItem *calitem, return week_num + 1; } - - /* This is supposed to return the nearest item the the point and the distance. Since we are the only item we just return ourself and 0 for the distance. This is needed so that we get button/motion events. */ @@ -1978,7 +1961,6 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) pango_context_get_language (pango_context)); layout = pango_layout_new (pango_context); - char_height = PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); @@ -2052,7 +2034,6 @@ e_calendar_item_recalc_sizes (ECalendarItem *calitem) pango_font_metrics_unref (font_metrics); } - static void e_calendar_item_get_day_style (ECalendarItem *calitem, gint year, @@ -2100,8 +2081,6 @@ e_calendar_item_get_day_style (ECalendarItem *calitem, } } - - static gboolean e_calendar_item_button_press (ECalendarItem *calitem, GdkEvent *event) @@ -2192,7 +2171,6 @@ e_calendar_item_button_release (ECalendarItem *calitem, return FALSE; } - static gboolean e_calendar_item_motion (ECalendarItem *calitem, GdkEvent *event) @@ -2272,7 +2250,6 @@ e_calendar_item_motion (ECalendarItem *calitem, e_calendar_item_round_down_selection (calitem, &start_month, &start_day); - /* Check we don't go over the maximum number of days to select. */ if (calitem->selection_dragging_end) { e_calendar_item_check_selection_end (calitem, @@ -2304,7 +2281,6 @@ e_calendar_item_motion (ECalendarItem *calitem, return TRUE; } - static void e_calendar_item_check_selection_end (ECalendarItem *calitem, gint start_month, @@ -2345,7 +2321,6 @@ e_calendar_item_check_selection_end (ECalendarItem *calitem, } } - static void e_calendar_item_check_selection_start (ECalendarItem *calitem, gint *start_month, @@ -2384,7 +2359,6 @@ e_calendar_item_check_selection_start (ECalendarItem *calitem, } } - /* Converts a position within the item to a month & day. The month returned is 0 for the top-left month displayed. If the position is over the month heading -1 is returned for the day. @@ -2529,7 +2503,6 @@ e_calendar_item_convert_position_to_day (ECalendarItem *calitem, return TRUE; } - static void e_calendar_item_get_month_info (ECalendarItem *calitem, gint row, @@ -2568,7 +2541,6 @@ e_calendar_item_get_month_info (ECalendarItem *calitem, *first_day_offset = first_day_of_month; } - void e_calendar_item_get_first_month(ECalendarItem *calitem, gint *year, @@ -2578,7 +2550,6 @@ e_calendar_item_get_first_month(ECalendarItem *calitem, *month = calitem->month; } - static void e_calendar_item_preserve_day_selection (ECalendarItem *calitem, gint selected_day, @@ -2710,7 +2681,6 @@ e_calendar_item_get_max_days_sel (ECalendarItem *calitem) return calitem->max_days_selected; } - /* Set the maximum number of days selectable */ void e_calendar_item_set_max_days_sel (ECalendarItem *calitem, @@ -2720,7 +2690,6 @@ e_calendar_item_set_max_days_sel (ECalendarItem *calitem, gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); } - /* Get the maximum number of days before whole weeks are selected */ gint e_calendar_item_get_days_start_week_sel(ECalendarItem *calitem) @@ -2728,7 +2697,6 @@ e_calendar_item_get_days_start_week_sel(ECalendarItem *calitem) return calitem->days_to_start_week_selection; } - /* Set the maximum number of days before whole weeks are selected */ void e_calendar_item_set_days_start_week_sel(ECalendarItem *calitem, @@ -2743,7 +2711,6 @@ e_calendar_item_get_display_popup (ECalendarItem *calitem) return calitem->display_popup; } - void e_calendar_item_set_display_popup (ECalendarItem *calitem, gboolean display) @@ -2751,7 +2718,6 @@ e_calendar_item_set_display_popup (ECalendarItem *calitem, calitem->display_popup = display; } - /* This will make sure that the given year & month are valid, i.e. if month is < 0 or > 11 the year and month will be updated accordingly. */ void @@ -2770,7 +2736,6 @@ e_calendar_item_normalize_date (ECalendarItem *calitem, } } - /* Adds or subtracts days from the selection. It is used when we switch months and the selection extends past the end of a month but we want to keep the number of days selected the same. days should not be more than 30. */ @@ -2799,7 +2764,6 @@ e_calendar_item_add_days_to_selection (ECalendarItem *calitem, } } - /* Gets the range of dates actually shown. Months are 0 to 11. This also includes the last days of the previous month and the first days of the following month, which are normally shown in gray. @@ -2830,7 +2794,6 @@ e_calendar_item_get_date_range (ECalendarItem *calitem, } *start_day = days_in_prev_month + 1 - first_day_offset; - /* Calculate the last day shown. This will be one of the greyed-out days after the last full month ends. */ e_calendar_item_get_month_info (calitem, calitem->rows - 1, @@ -2845,7 +2808,6 @@ e_calendar_item_get_date_range (ECalendarItem *calitem, return TRUE; } - /* Simple way to mark days so they appear bold. A more flexible interface may be added later. */ void @@ -2862,7 +2824,6 @@ e_calendar_item_clear_marks (ECalendarItem *calitem) item->x2, item->y2); } - /* add_day_style - whether bit-or with the actual style or change the style fully */ void e_calendar_item_mark_day (ECalendarItem *calitem, @@ -2886,7 +2847,6 @@ e_calendar_item_mark_day (ECalendarItem *calitem, gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); } - void e_calendar_item_mark_days (ECalendarItem *calitem, gint start_year, @@ -2951,7 +2911,6 @@ e_calendar_item_mark_days (ECalendarItem *calitem, gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (calitem)); } - /* Rounds up the given day to the end of the week. */ static void e_calendar_item_round_up_selection (ECalendarItem *calitem, @@ -2985,7 +2944,6 @@ e_calendar_item_round_up_selection (ECalendarItem *calitem, } } - /* Rounds down the given day to the start of the week. */ static void e_calendar_item_round_down_selection (ECalendarItem *calitem, @@ -3024,7 +2982,6 @@ e_calendar_item_round_down_selection (ECalendarItem *calitem, } } - static gint e_calendar_item_get_inclusive_days (ECalendarItem *calitem, gint start_month_offset, @@ -3056,7 +3013,6 @@ e_calendar_item_get_inclusive_days (ECalendarItem *calitem, return days; } - /* If the day is off the end of the month it is set to the last day of the month. */ static void @@ -3075,7 +3031,6 @@ e_calendar_item_ensure_valid_day (ECalendarItem *calitem, *day = days_in_month; } - gboolean e_calendar_item_get_selection (ECalendarItem *calitem, GDate *start_date, @@ -3106,7 +3061,6 @@ e_calendar_item_get_selection (ECalendarItem *calitem, return TRUE; } - static void e_calendar_item_set_selection_if_emission (ECalendarItem *calitem, GDate *start_date, @@ -3161,7 +3115,6 @@ e_calendar_item_set_selection_if_emission (ECalendarItem *calitem, + end_month - calitem->month; new_end_day = end_day; - if (!calitem->selection_set || calitem->selection_start_month_offset != new_start_month_offset || calitem->selection_start_day != new_start_day @@ -3312,7 +3265,6 @@ e_calendar_item_ensure_days_visible (ECalendarItem *calitem, return need_update; } - static void e_calendar_item_show_popup_menu (ECalendarItem *calitem, GdkEventButton *event, @@ -3371,7 +3323,6 @@ e_calendar_item_show_popup_menu (ECalendarItem *calitem, gtk_widget_destroy (menu); } - static void e_calendar_item_on_menu_item_activate (GtkWidget *menuitem, ECalendarItem *calitem) @@ -3387,7 +3338,6 @@ e_calendar_item_on_menu_item_activate (GtkWidget *menuitem, e_calendar_item_set_first_month (calitem, year, month); } - static void e_calendar_item_position_menu (GtkMenu *menu, gint *x, @@ -3412,7 +3362,6 @@ e_calendar_item_position_menu (GtkMenu *menu, *y = CLAMP (*y, 0, screen_height - requisition.height); } - /* Sets the function to call to get the colors to use for a particular day. */ void e_calendar_item_set_style_callback (ECalendarItem *calitem, @@ -3430,7 +3379,6 @@ e_calendar_item_set_style_callback (ECalendarItem *calitem, calitem->style_callback_destroy = destroy; } - static void e_calendar_item_date_range_changed (ECalendarItem *calitem) { @@ -3440,7 +3388,6 @@ e_calendar_item_date_range_changed (ECalendarItem *calitem) e_calendar_item_queue_signal_emission (calitem); } - static void e_calendar_item_queue_signal_emission (ECalendarItem *calitem) { @@ -3449,7 +3396,6 @@ e_calendar_item_queue_signal_emission (ECalendarItem *calitem) } } - static gboolean e_calendar_item_signal_emission_idle_cb (gpointer data) { @@ -3483,7 +3429,6 @@ e_calendar_item_signal_emission_idle_cb (gpointer data) return FALSE; } - /* Sets a callback to use to get the current time. This is useful if the application needs to use its own timezone data rather than rely on the Unix timezone. */ diff --git a/widgets/misc/e-calendar-item.h b/widgets/misc/e-calendar-item.h index 936e86ebab..0ab34b3bdd 100644 --- a/widgets/misc/e-calendar-item.h +++ b/widgets/misc/e-calendar-item.h @@ -70,7 +70,6 @@ G_BEGIN_DECLS #define E_CALENDAR_ITEM_XPAD_BEFORE_CELLS 1 #define E_CALENDAR_ITEM_XPAD_AFTER_CELLS 4 - /* These index our colors array. */ typedef enum { @@ -110,7 +109,6 @@ typedef void (*ECalendarItemStyleCallback) (ECalendarItem *calitem, typedef struct tm (*ECalendarItemGetTimeCallback) (ECalendarItem *calitem, gpointer data); - #define E_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ e_calendar_item_get_type (), ECalendarItem)) #define E_CALENDAR_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k),\ @@ -265,7 +263,6 @@ struct _ECalendarItemClass void (* selection_preview_changed) (ECalendarItem *calitem); }; - GType e_calendar_item_get_type (void); /* FIXME: months are 0-11 throughout, but 1-12 may be better. */ @@ -368,7 +365,6 @@ gint e_calendar_item_get_week_number (ECalendarItem *calitem, gint year); void e_calendar_item_style_set (GtkWidget *widget, ECalendarItem *calitem); - G_END_DECLS #endif /* _E_CALENDAR_ITEM_H_ */ diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index a0adf46cf5..fd17c67aab 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -99,7 +99,6 @@ static void e_calendar_stop_auto_move (ECalendar *cal); G_DEFINE_TYPE (ECalendar, e_calendar, E_CANVAS_TYPE) - static void e_calendar_class_init (ECalendarClass *class) { @@ -120,7 +119,6 @@ e_calendar_class_init (ECalendarClass *class) widget_class->focus = e_calendar_focus; } - static void e_calendar_init (ECalendar *cal) { @@ -202,7 +200,6 @@ e_calendar_init (ECalendar *cal) cal->timeout_id = 0; } - /** * e_calendar_new: * @Returns: a new #ECalendar. @@ -222,7 +219,6 @@ e_calendar_new (void) return cal; } - static void e_calendar_destroy (GtkObject *object) { @@ -242,7 +238,6 @@ e_calendar_destroy (GtkObject *object) (* GTK_OBJECT_CLASS (e_calendar_parent_class)->destroy) (object); } - static void e_calendar_realize (GtkWidget *widget) { @@ -254,7 +249,6 @@ e_calendar_realize (GtkWidget *widget) &widget->style->bg[GTK_STATE_NORMAL]); } - static void e_calendar_style_set (GtkWidget *widget, GtkStyle *previous_style) @@ -274,7 +268,6 @@ e_calendar_style_set (GtkWidget *widget, e_calendar_item_style_set (widget, e_calendar->calitem); } - static void e_calendar_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -298,7 +291,6 @@ e_calendar_size_request (GtkWidget *widget, requisition->height = height + style->ythickness * 2; } - static void e_calendar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -339,7 +331,6 @@ e_calendar_size_allocate (GtkWidget *widget, "y2", new_y2, NULL); - /* Position the arrow buttons. */ arrow_button_size = PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) @@ -391,7 +382,6 @@ e_calendar_set_minimum_size (ECalendar *cal, gtk_widget_queue_resize (GTK_WIDGET (cal)); } - void e_calendar_set_maximum_size (ECalendar *cal, gint rows, @@ -410,7 +400,6 @@ e_calendar_set_maximum_size (ECalendar *cal, gtk_widget_queue_resize (GTK_WIDGET (cal)); } - /* Returns the border size on each side of the month displays. */ void e_calendar_get_border_size (ECalendar *cal, @@ -435,7 +424,6 @@ e_calendar_get_border_size (ECalendar *cal, } } - static void e_calendar_on_prev_pressed (ECalendar *cal) { @@ -462,7 +450,6 @@ e_calendar_start_auto_move (ECalendar *cal, } - static gboolean e_calendar_auto_move_handler (gpointer data) { @@ -489,21 +476,18 @@ e_calendar_auto_move_handler (gpointer data) return TRUE; } - static void e_calendar_on_prev_released (ECalendar *cal) { e_calendar_stop_auto_move (cal); } - static void e_calendar_on_next_released (ECalendar *cal) { e_calendar_stop_auto_move (cal); } - static void e_calendar_stop_auto_move (ECalendar *cal) { @@ -527,7 +511,6 @@ e_calendar_on_next_clicked (ECalendar *cal) cal->calitem->month + 1); } - static gint e_calendar_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -542,7 +525,6 @@ e_calendar_drag_motion (GtkWidget *widget, return FALSE; } - static void e_calendar_drag_leave (GtkWidget *widget, GdkDragContext *context, diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h index c281e7436b..d6b50209a7 100644 --- a/widgets/misc/e-calendar.h +++ b/widgets/misc/e-calendar.h @@ -56,7 +56,6 @@ G_BEGIN_DECLS (G_TYPE_INSTANCE_GET_CLASS \ ((obj), E_TYPE_CALENDAR, ECalendarClass)) - typedef struct _ECalendar ECalendar; typedef struct _ECalendarClass ECalendarClass; @@ -88,7 +87,6 @@ struct _ECalendarClass ECanvasClass parent_class; }; - GType e_calendar_get_type (void); GtkWidget* e_calendar_new (void); diff --git a/widgets/misc/e-canvas-background.h b/widgets/misc/e-canvas-background.h index 562987e7d7..7e3ac19a13 100644 --- a/widgets/misc/e-canvas-background.h +++ b/widgets/misc/e-canvas-background.h @@ -42,7 +42,6 @@ G_BEGIN_DECLS * y2 double RW If you need the rectangle to have negative coordinates, use an affine. */ - #define E_CANVAS_BACKGROUND_TYPE (e_canvas_background_get_type ()) #define E_CANVAS_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_CANVAS_BACKGROUND_TYPE, ECanvasBackground)) #define E_CANVAS_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_CANVAS_BACKGROUND_TYPE, ECanvasBackgroundClass)) @@ -64,7 +63,6 @@ struct _ECanvasBackgroundClass { void (*style_set) (ECanvasBackground *eti, GtkStyle *previous_style); }; - /* Standard Gtk function */ GType e_canvas_background_get_type (void); diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c index cae41d859f..e69bb9c980 100644 --- a/widgets/misc/e-canvas-utils.c +++ b/widgets/misc/e-canvas-utils.c @@ -63,7 +63,6 @@ compute_offset(gint top, gint bottom, gint page_top, gint page_bottom) return offset; } - static void e_canvas_show_area (GnomeCanvas *canvas, double x1, double y1, double x2, double y2) { @@ -96,7 +95,6 @@ e_canvas_item_show_area (GnomeCanvasItem *item, double x1, double y1, double x2, e_canvas_show_area(item->canvas, x1, y1, x2, y2); } - static gboolean e_canvas_area_shown (GnomeCanvas *canvas, double x1, double y1, double x2, double y2) { diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index bb0bd775e9..a7e8191bc4 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -264,7 +264,6 @@ e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item) } } - static void e_canvas_vbox_real_add_item_start(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item) { diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h index fb049c3e9c..b41b8f80ec 100644 --- a/widgets/misc/e-canvas-vbox.h +++ b/widgets/misc/e-canvas-vbox.h @@ -45,7 +45,6 @@ G_BEGIN_DECLS #define E_IS_CANVAS_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_CANVAS_VBOX_TYPE)) #define E_IS_CANVAS_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_CANVAS_VBOX_TYPE)) - typedef struct _ECanvasVbox ECanvasVbox; typedef struct _ECanvasVboxClass ECanvasVboxClass; @@ -83,5 +82,4 @@ GType e_canvas_vbox_get_type (void); G_END_DECLS - #endif /* __E_CANVAS_VBOX_H__ */ diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 53e3eafeec..aeb26344ab 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -143,7 +143,6 @@ e_canvas_new (void) return GTK_WIDGET (g_object_new (E_CANVAS_TYPE, NULL)); } - /* Emits an event for an item in the canvas, be it the current item, grabbed * item, or focused item, as appropriate. */ @@ -279,7 +278,6 @@ e_canvas_key (GtkWidget *widget, GdkEventKey *event) return emit_event (canvas, &full_event); } - /* This routine invokes the point method of the item. The argument x, y should * be in the parent's item-relative coordinate system. This routine applies the * inverse of the item's transform, maintaining the affine invariant. @@ -546,7 +544,6 @@ e_canvas_visibility (GtkWidget *widget, GdkEventVisibility *event, ECanvas *canv return FALSE; } - /** * e_canvas_item_grab_focus: * @item: A canvas item. @@ -664,7 +661,6 @@ e_canvas_style_set (GtkWidget *widget, GtkStyle *previous_style) ec_style_set_recursive (GNOME_CANVAS_ITEM (gnome_canvas_root (GNOME_CANVAS (widget))), previous_style); } - static void e_canvas_realize (GtkWidget *widget) { @@ -797,7 +793,6 @@ e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc g_object_set_data(G_OBJECT(item), "ECanvasItem::reflow_callback", (gpointer) func); } - void e_canvas_item_set_selection_callback (GnomeCanvasItem *item, ECanvasItemSelectionFunc func) { @@ -1004,7 +999,6 @@ void e_canvas_hide_tooltip (ECanvas *canvas) } } - static gboolean grab_cancelled_check (gpointer data) { diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index 58994d6e29..a78824e1ef 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -50,7 +50,6 @@ typedef gint (*ECanvasItemSelectionCompareFunc) (GnomeCanvasItem gpointer data2, gint flags); - typedef struct _ECanvas ECanvas; typedef struct _ECanvasClass ECanvasClass; @@ -101,7 +100,6 @@ struct _ECanvasClass void (* reflow) (ECanvas *canvas); }; - GType e_canvas_get_type (void); GtkWidget *e_canvas_new (void); @@ -147,5 +145,4 @@ void e_canvas_hide_tooltip (ECanvas G_END_DECLS - #endif /* __E_CANVAS_H__ */ diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index ddf5f1ac26..e8f4221b60 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -61,7 +61,6 @@ static CursorDef cursors [] = { { NULL, 0, 0, NULL } }; - static void create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gchar **xpm) { @@ -150,7 +149,6 @@ e_cursors_shutdown (void) gdk_cursor_unref (cursors [i].cursor); } - /* Returns a cursor given its type */ GdkCursor * e_cursor_get (ECursorType type) diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 1d69016b20..e7b1a0555e 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -23,7 +23,6 @@ * time field with popups for entering a date. */ - #ifdef HAVE_CONFIG_H #include #endif @@ -113,10 +112,8 @@ enum { LAST_SIGNAL }; - static gint date_edit_signals [LAST_SIGNAL] = { 0 }; - static void e_date_edit_class_init (EDateEditClass *class); static void e_date_edit_init (EDateEdit *dedit); static void create_children (EDateEdit *dedit); @@ -191,7 +188,6 @@ static gboolean e_date_edit_set_time_internal (EDateEdit *dedit, gint hour, gint minute); - static GtkHBoxClass *parent_class; /** @@ -223,7 +219,6 @@ e_date_edit_get_type (void) return date_edit_type; } - static void e_date_edit_class_init (EDateEditClass *class) { @@ -249,7 +244,6 @@ e_date_edit_class_init (EDateEditClass *class) class->changed = NULL; } - static void e_date_edit_init (EDateEdit *dedit) { @@ -282,7 +276,6 @@ e_date_edit_init (EDateEdit *dedit) e_date_edit_set_time (dedit, 0); } - /** * e_date_edit_new: * @@ -304,7 +297,6 @@ e_date_edit_new (void) return GTK_WIDGET (dedit); } - static void create_children (EDateEdit *dedit) { @@ -480,7 +472,6 @@ create_children (EDateEdit *dedit) G_CALLBACK (on_date_popup_none_button_clicked), dedit); } - static void e_date_edit_dispose (GObject *object) { @@ -504,7 +495,6 @@ e_date_edit_dispose (GObject *object) (* G_OBJECT_CLASS (parent_class)->dispose) (object); } - /* GtkWidget::mnemonic_activate() handler for the EDateEdit */ static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget, gboolean group_cycling) @@ -530,7 +520,6 @@ e_date_edit_grab_focus (GtkWidget *widget) gtk_widget_grab_focus (GTK_BIN (dedit->priv->time_combo)->child); } - /** * e_date_edit_set_editable: * @dedit: an #EDateEdit widget. @@ -553,7 +542,6 @@ e_date_edit_set_editable (EDateEdit *dedit, gboolean editable) gtk_widget_set_sensitive (priv->date_button, editable); } - /** * e_date_edit_get_time: * @dedit: an #EDateEdit widget. @@ -600,7 +588,6 @@ e_date_edit_get_time (EDateEdit *dedit) return mktime (&tmp_tm); } - /** * e_date_edit_set_time: * @dedit: the EDateEdit widget @@ -664,7 +651,6 @@ e_date_edit_set_time (EDateEdit *dedit, date_edit_signals [CHANGED], 0); } - /** * e_date_edit_get_date: * @dedit: an #EDateEdit widget. @@ -701,7 +687,6 @@ e_date_edit_get_date (EDateEdit *dedit, return TRUE; } - /** * e_date_edit_set_date: * @dedit: an #EDateEdit widget. @@ -734,7 +719,6 @@ e_date_edit_set_date (EDateEdit *dedit, date_edit_signals [CHANGED], 0); } - /** * e_date_edit_get_time_of_day: * @dedit: an #EDateEdit widget. @@ -769,7 +753,6 @@ e_date_edit_get_time_of_day (EDateEdit *dedit, } } - /** * e_date_edit_set_time_of_day: * @dedit: an #EDateEdit widget. @@ -854,7 +837,6 @@ e_date_edit_get_show_date (EDateEdit *dedit) return dedit->priv->show_date; } - /** * e_date_edit_set_show_date: * @dedit: an #EDateEdit widget. @@ -895,7 +877,6 @@ e_date_edit_set_show_date (EDateEdit *dedit, gtk_widget_hide (priv->space); } - /** * e_date_edit_get_show_time: * @dedit: an #EDateEdit widget @@ -911,7 +892,6 @@ e_date_edit_get_show_time (EDateEdit *dedit) return dedit->priv->show_time; } - /** * e_date_edit_set_show_time: * @dedit: an #EDateEdit widget @@ -938,7 +918,6 @@ e_date_edit_set_show_time (EDateEdit *dedit, e_date_edit_update_time_combo_state (dedit); } - /** * e_date_edit_get_make_time_insensitive: * @dedit: an #EDateEdit widget @@ -956,7 +935,6 @@ e_date_edit_get_make_time_insensitive (EDateEdit *dedit) return dedit->priv->make_time_insensitive; } - /** * e_date_edit_set_make_time_insensitive: * @dedit: an #EDateEdit widget @@ -988,7 +966,6 @@ e_date_edit_set_make_time_insensitive (EDateEdit *dedit, e_date_edit_update_time_combo_state (dedit); } - /** * e_date_edit_get_week_start_day: * @dedit: an #EDateEdit widget @@ -1011,7 +988,6 @@ e_date_edit_get_week_start_day (EDateEdit *dedit) return week_start_day; } - /** * e_date_edit_set_week_start_day: * @dedit: an #EDateEdit widget @@ -1030,7 +1006,6 @@ e_date_edit_set_week_start_day (EDateEdit *dedit, NULL); } - /* Whether we show week numbers in the date popup. */ gboolean e_date_edit_get_show_week_numbers (EDateEdit *dedit) @@ -1046,7 +1021,6 @@ e_date_edit_get_show_week_numbers (EDateEdit *dedit) return show_week_numbers; } - void e_date_edit_set_show_week_numbers (EDateEdit *dedit, gboolean show_week_numbers) @@ -1058,7 +1032,6 @@ e_date_edit_set_show_week_numbers (EDateEdit *dedit, NULL); } - /* Whether we use 24 hour format in the time field & popup. */ gboolean e_date_edit_get_use_24_hour_format (EDateEdit *dedit) @@ -1068,7 +1041,6 @@ e_date_edit_get_use_24_hour_format (EDateEdit *dedit) return dedit->priv->use_24_hour_format; } - void e_date_edit_set_use_24_hour_format (EDateEdit *dedit, gboolean use_24_hour_format) @@ -1085,7 +1057,6 @@ e_date_edit_set_use_24_hour_format (EDateEdit *dedit, e_date_edit_update_time_entry (dedit); } - /* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will return (time_t) -1 in this case. */ gboolean @@ -1096,7 +1067,6 @@ e_date_edit_get_allow_no_date_set (EDateEdit *dedit) return GTK_WIDGET_VISIBLE (dedit->priv->none_button); } - void e_date_edit_set_allow_no_date_set (EDateEdit *dedit, gboolean allow_no_date_set) @@ -1121,7 +1091,6 @@ e_date_edit_set_allow_no_date_set (EDateEdit *dedit, } } - /* The range of time to show in the time combo popup. */ void e_date_edit_get_time_popup_range (EDateEdit *dedit, @@ -1134,7 +1103,6 @@ e_date_edit_get_time_popup_range (EDateEdit *dedit, *upper_hour = dedit->priv->upper_hour; } - void e_date_edit_set_time_popup_range (EDateEdit *dedit, gint lower_hour, @@ -1161,7 +1129,6 @@ e_date_edit_set_time_popup_range (EDateEdit *dedit, e_date_edit_update_time_entry (dedit); } - /* The arrow button beside the date field has been clicked, so we show the popup with the ECalendar in. */ static void @@ -1171,7 +1138,6 @@ on_date_button_clicked (GtkWidget *widget, e_date_edit_show_date_popup (dedit); } - static void e_date_edit_show_date_popup (EDateEdit *dedit) { @@ -1217,7 +1183,6 @@ e_date_edit_show_date_popup (EDateEdit *dedit) gdk_window_focus (priv->cal_popup->window, GDK_CURRENT_TIME); } - /* This positions the date popup below and to the left of the arrow button, just before it is shown. */ static void @@ -1256,7 +1221,6 @@ position_date_popup (EDateEdit *dedit) gtk_window_move (GTK_WINDOW (dedit->priv->cal_popup), x, y); } - /* A date has been selected in the date popup, so we set the date field and hide the popup. */ static void @@ -1275,7 +1239,6 @@ on_date_popup_date_selected (ECalendarItem *calitem, g_date_get_day (&start_date)); } - static void on_date_popup_now_button_clicked (GtkWidget *button, EDateEdit *dedit) @@ -1284,7 +1247,6 @@ on_date_popup_now_button_clicked (GtkWidget *button, e_date_edit_set_time (dedit, 0); } - static void on_date_popup_today_button_clicked (GtkWidget *button, EDateEdit *dedit) @@ -1308,7 +1270,6 @@ on_date_popup_today_button_clicked (GtkWidget *button, tmp_tm.tm_mon + 1, tmp_tm.tm_mday); } - static void on_date_popup_none_button_clicked (GtkWidget *button, EDateEdit *dedit) @@ -1317,7 +1278,6 @@ on_date_popup_none_button_clicked (GtkWidget *button, e_date_edit_set_time (dedit, -1); } - /* A key has been pressed while the date popup is showing. If it is the Escape key we hide the popup. */ static gint @@ -1336,7 +1296,6 @@ on_date_popup_key_press (GtkWidget *widget, return TRUE; } - /* A mouse button has been pressed while the date popup is showing. Any button press events used to select days etc. in the popup will have have been handled elsewhere, so here we just hide the popup. @@ -1373,7 +1332,6 @@ on_date_popup_button_press (GtkWidget *widget, return TRUE; } - /* A delete event has been received for the date popup, so we hide it and return TRUE so it doesn't get destroyed. */ static gint @@ -1384,7 +1342,6 @@ on_date_popup_delete_event (GtkWidget *widget, return TRUE; } - /* Hides the date popup, removing any grabs. */ static void hide_date_popup (EDateEdit *dedit) @@ -1395,7 +1352,6 @@ hide_date_popup (EDateEdit *dedit) gdk_keyboard_ungrab (GDK_CURRENT_TIME); } - /* Clears the time popup and rebuilds it using the lower_hour, upper_hour and use_24_hour_format settings. */ static void @@ -1451,7 +1407,6 @@ rebuild_time_popup (EDateEdit *dedit) } } - static gboolean e_date_edit_parse_date (EDateEdit *dedit, const gchar *date_text, @@ -1475,7 +1430,6 @@ e_date_edit_parse_date (EDateEdit *dedit, return TRUE; } - static gboolean e_date_edit_parse_time (EDateEdit *dedit, const gchar *time_text, @@ -1493,7 +1447,6 @@ e_date_edit_parse_time (EDateEdit *dedit, return TRUE; } - /* Returns TRUE if the string is empty or is "None" in the current locale. It ignores whitespace. */ static gboolean @@ -1514,7 +1467,6 @@ field_set_to_none (const gchar *text) return FALSE; } - static void on_date_edit_time_selected (GtkComboBox *combo, EDateEdit *dedit) @@ -1530,7 +1482,6 @@ on_date_edit_time_selected (GtkComboBox *combo, e_date_edit_check_time_changed (dedit); } - static gint on_date_entry_key_press (GtkWidget *widget, GdkEventKey *event, @@ -1555,7 +1506,6 @@ on_date_entry_key_press (GtkWidget *widget, return FALSE; } - static gint on_time_entry_key_press (GtkWidget *widget, GdkEventKey *event, @@ -1611,7 +1561,6 @@ on_time_entry_key_release (GtkWidget *widget, return FALSE; } - static gint on_date_entry_focus_out (GtkEntry *entry, GdkEventFocus *event, @@ -1647,7 +1596,6 @@ on_date_entry_focus_out (GtkEntry *entry, return FALSE; } - static gint on_time_entry_focus_out (GtkEntry *entry, GdkEventFocus *event, @@ -1750,7 +1698,6 @@ e_date_edit_update_date_entry (EDateEdit *dedit) add_relation (dedit, priv->date_button); } - /* This sets the text in the time entry according to the current settings. */ static void e_date_edit_update_time_entry (EDateEdit *dedit) @@ -1827,7 +1774,6 @@ e_date_edit_update_time_entry (EDateEdit *dedit) add_relation (dedit, priv->time_combo); } - static void e_date_edit_update_time_combo_state (EDateEdit *dedit) { @@ -1882,7 +1828,6 @@ e_date_edit_update_time_combo_state (EDateEdit *dedit) gtk_widget_hide (priv->space); } - /* Parses the date, and if it is different from the current settings it updates the settings and emits a "date_changed" signal. */ static void @@ -1909,7 +1854,6 @@ e_date_edit_check_date_changed (EDateEdit *dedit) tmp_tm.tm_mday = 0; } - date_changed = e_date_edit_set_date_internal (dedit, valid, none, tmp_tm.tm_year, tmp_tm.tm_mon, @@ -1920,7 +1864,6 @@ e_date_edit_check_date_changed (EDateEdit *dedit) date_edit_signals [CHANGED], 0); } - /* Parses the time, and if it is different from the current settings it updates the settings and emits a "time_changed" signal. */ static void @@ -1953,7 +1896,6 @@ e_date_edit_check_time_changed (EDateEdit *dedit) } } - /** * e_date_edit_date_is_valid: * @dedit: an #EDateEdit widget. @@ -1981,7 +1923,6 @@ e_date_edit_date_is_valid (EDateEdit *dedit) return TRUE; } - /** * e_date_edit_time_is_valid: * @dedit: an #EDateEdit widget. @@ -2072,7 +2013,6 @@ e_date_edit_set_date_internal (EDateEdit *dedit, return date_changed; } - static gboolean e_date_edit_set_time_internal (EDateEdit *dedit, gboolean valid, diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c index 9110e14257..6cd4958127 100644 --- a/widgets/misc/e-gui-utils.c +++ b/widgets/misc/e-gui-utils.c @@ -94,7 +94,6 @@ e_container_change_tab_order_destroy_notify(gpointer data) g_list_free(list); } - static gint e_container_change_tab_order_callback(GtkContainer *container, GtkDirectionType direction, diff --git a/widgets/misc/e-hsv-utils.c b/widgets/misc/e-hsv-utils.c index b42271fb19..3a2e4500e0 100644 --- a/widgets/misc/e-hsv-utils.c +++ b/widgets/misc/e-hsv-utils.c @@ -175,4 +175,3 @@ e_rgb_to_hsv (gdouble r, gdouble g, gdouble b, } } - diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c index 82ce1c17aa..d9114a5e82 100644 --- a/widgets/misc/e-map.c +++ b/widgets/misc/e-map.c @@ -37,13 +37,11 @@ #define SCROLL_STEP_SIZE 32 - /* */ #define E_MAP_GET_WIDTH(map) gdk_pixbuf_get_width(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf) #define E_MAP_GET_HEIGHT(map) gdk_pixbuf_get_height(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf) - /* Zoom state - keeps track of animation hacks */ typedef enum @@ -55,7 +53,6 @@ typedef enum } EMapZoomState; - /* Private part of the EMap structure */ typedef struct @@ -82,7 +79,6 @@ typedef struct } EMapPrivate; - /* Internal prototypes */ static void e_map_class_init (EMapClass *class); @@ -116,12 +112,10 @@ static void repaint_point (EMap *map, EMapPoint *point); static GtkWidgetClass *parent_class; - /* ----------------- * * Widget management * * ----------------- */ - /** * e_map_get_type: * @void: @@ -200,7 +194,6 @@ e_map_class_init (EMapClass *class) widget_class->key_press_event = e_map_key_press; } - /* Object initialization function for the map view */ static void @@ -223,7 +216,6 @@ e_map_init (EMap *view) GTK_WIDGET_UNSET_FLAGS (view, GTK_NO_WINDOW); } - /* Destroy handler for the map view */ static void @@ -245,7 +237,6 @@ e_map_destroy (GtkObject *object) (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); } - /* Finalize handler for the map view */ static void @@ -285,7 +276,6 @@ e_map_finalize (GObject *object) (*G_OBJECT_CLASS (parent_class)->finalize) (object); } - /* Unmap handler for the map view */ static void @@ -298,7 +288,6 @@ e_map_unmap (GtkWidget *widget) (*GTK_WIDGET_CLASS (parent_class)->unmap) (widget); } - /* Realize handler for the map view */ static void @@ -335,7 +324,6 @@ e_map_realize (GtkWidget *widget) update_render_pixbuf (E_MAP (widget), GDK_INTERP_BILINEAR, TRUE); } - /* Unrealize handler for the map view */ static void @@ -348,7 +336,6 @@ e_map_unrealize (GtkWidget *widget) (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } - /* Size_request handler for the map view */ static void @@ -370,7 +357,6 @@ e_map_size_request (GtkWidget *widget, GtkRequisition *requisition) requisition->height = gdk_pixbuf_get_height (priv->map_pixbuf); } - /* Size_allocate handler for the map view */ static void @@ -403,7 +389,6 @@ e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation) update_render_pixbuf (view, GDK_INTERP_BILINEAR, TRUE); } - /* Button press handler for the map view */ static gint @@ -413,7 +398,6 @@ e_map_button_press (GtkWidget *widget, GdkEventButton *event) return TRUE; } - /* Button release handler for the map view */ static gint @@ -425,7 +409,6 @@ e_map_button_release (GtkWidget *widget, GdkEventButton *event) return TRUE; } - /* Motion handler for the map view */ static gint @@ -446,7 +429,6 @@ e_map_motion (GtkWidget *widget, GdkEventMotion *event) */ } - /* Expose handler for the map view */ static gint @@ -464,7 +446,6 @@ e_map_expose (GtkWidget *widget, GdkEventExpose *event) return TRUE; } - /* Set_scroll_adjustments handler for the map view */ static void @@ -529,7 +510,6 @@ e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustm if (need_adjust) adjustment_changed_cb (NULL, view); } - /* Key press handler for the map view */ static gint @@ -601,12 +581,10 @@ e_map_key_press (GtkWidget *widget, GdkEventKey *event) return TRUE; } - /* ---------------- * * Widget interface * * ---------------- */ - /** * e_map_new: * @void: @@ -630,10 +608,8 @@ e_map_new (void) return (E_MAP (widget)); } - /* --- Coordinate translation --- */ - /* These functions translate coordinates between longitude/latitude and * the image x/y offsets, using the equidistant cylindrical projection. * @@ -660,7 +636,6 @@ e_map_window_to_world (EMap *map, double win_x, double win_y, double *world_long ((double) height / 2.0) * 90.0; } - void e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, double *win_x, double *win_y) { @@ -685,10 +660,8 @@ e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, #endif } - /* --- Zoom --- */ - gdouble e_map_get_magnification (EMap *map) { @@ -699,7 +672,6 @@ e_map_get_magnification (EMap *map) else return 1.0; } - void e_map_zoom_to_location (EMap *map, double longitude, double latitude) { @@ -720,7 +692,6 @@ e_map_zoom_to_location (EMap *map, double longitude, double latitude) zoom_do (map); } - void e_map_zoom_out (EMap *map) { @@ -738,28 +709,24 @@ e_map_zoom_out (EMap *map) priv->zoom_state = E_MAP_ZOOMED_OUT; } - void e_map_set_smooth_zoom (EMap *map, gboolean state) { ((EMapPrivate *) map->priv)->smooth_zoom = state; } - gboolean e_map_get_smooth_zoom (EMap *map) { return (((EMapPrivate *) map->priv)->smooth_zoom); } - void e_map_freeze (EMap *map) { ((EMapPrivate *) map->priv)->frozen = TRUE; } - void e_map_thaw (EMap *map) { @@ -767,10 +734,8 @@ e_map_thaw (EMap *map) update_and_paint (map); } - /* --- Point manipulation --- */ - EMapPoint * e_map_add_point (EMap *map, gchar *name, double longitude, double latitude, guint32 color_rgba) { @@ -796,7 +761,6 @@ e_map_add_point (EMap *map, gchar *name, double longitude, double latitude, guin return point; } - void e_map_remove_point (EMap *map, EMapPoint *point) { @@ -817,7 +781,6 @@ e_map_remove_point (EMap *map, EMapPoint *point) g_free (point); } - void e_map_point_get_location (EMapPoint *point, double *longitude, double *latitude) { @@ -825,21 +788,18 @@ e_map_point_get_location (EMapPoint *point, double *longitude, double *latitude) *latitude = point->latitude; } - gchar * e_map_point_get_name (EMapPoint *point) { return point->name; } - guint32 e_map_point_get_color_rgba (EMapPoint *point) { return point->rgba; } - void e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba) { @@ -854,21 +814,18 @@ e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba) } } - void e_map_point_set_data (EMapPoint *point, gpointer data) { point->user_data = data; } - gpointer e_map_point_get_data (EMapPoint *point) { return point->user_data; } - gboolean e_map_point_is_in_view (EMap *map, EMapPoint *point) { @@ -887,7 +844,6 @@ e_map_point_is_in_view (EMap *map, EMapPoint *point) return FALSE; } - EMapPoint * e_map_get_closest_point (EMap *map, double longitude, double latitude, gboolean in_view) { @@ -918,12 +874,10 @@ e_map_get_closest_point (EMap *map, double longitude, double latitude, gboolean return point_chosen; } - /* ------------------ * * Internal functions * * ------------------ */ - static void repaint_visible (EMap *map) { @@ -937,7 +891,6 @@ repaint_visible (EMap *map) request_paint_area (map, &area); } - static void update_and_paint (EMap *map) { @@ -945,7 +898,6 @@ update_and_paint (EMap *map) repaint_visible (map); } - static gint load_map_background (EMap *view, gchar *name) { @@ -965,7 +917,6 @@ load_map_background (EMap *view, gchar *name) return TRUE; } - static void update_render_pixbuf (EMap *map, GdkInterpType interp, gboolean render_overlays) { @@ -1032,7 +983,6 @@ update_render_pixbuf (EMap *map, GdkInterpType interp, gboolean render_overlays) set_scroll_area (map); } - /* Queues a repaint of the specified area in window coordinates */ static void @@ -1106,7 +1056,6 @@ put_pixel_with_clipping (GdkPixbuf *pixbuf, gint x, gint y, guint rgba) } } - /* Redraw point in client pixbuf */ static void @@ -1140,7 +1089,6 @@ update_render_point (EMap *map, EMapPoint *point) put_pixel_with_clipping (pb, px + 1, py + 1, 0x000000ff); } - /* Repaint point on X server */ static void @@ -1160,7 +1108,6 @@ repaint_point (EMap *map, EMapPoint *point) request_paint_area (map, &area); } - static void center_at (EMap *map, gint x, gint y, gboolean scroll) { @@ -1187,7 +1134,6 @@ center_at (EMap *map, gint x, gint y, gboolean scroll) } } - static void smooth_center_at (EMap *map, gint x, gint y) { @@ -1218,7 +1164,6 @@ smooth_center_at (EMap *map, gint x, gint y) } } - /* Scrolls the view to the specified offsets. Does not perform range checking! */ static void @@ -1321,7 +1266,6 @@ scroll_to (EMap *view, gint x, gint y) } } - static gint divide_seq[] = { /* Dividends for divisor of 2 */ @@ -1397,7 +1341,6 @@ static gint divide_seq[] = 0 }; - typedef enum { AXIS_X, @@ -1405,7 +1348,6 @@ typedef enum } AxisType; - static void blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, gint target_y, gint total_width, gint total_height, gfloat zoom_factor) { @@ -1419,7 +1361,6 @@ blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, gint i, j; gint line; - /* Set up the GC we'll be using */ gc = gdk_gc_new (window); @@ -1541,7 +1482,6 @@ blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, g_object_unref (gc); } - static void zoom_in_smooth (EMap *map) { @@ -1598,7 +1538,6 @@ zoom_in_smooth (EMap *map) request_paint_area (map, &area); } - static void zoom_in (EMap *map) { @@ -1624,7 +1563,6 @@ zoom_in (EMap *map) request_paint_area (map, &area); } - static void zoom_out (EMap *map) { @@ -1654,7 +1592,6 @@ zoom_out (EMap *map) repaint_visible (map); } - static void zoom_do (EMap *map) { @@ -1681,7 +1618,6 @@ zoom_do (EMap *map) set_scroll_area(map); } - /* Callback used when an adjustment is changed */ static void @@ -1696,7 +1632,6 @@ adjustment_changed_cb (GtkAdjustment *adj, gpointer data) scroll_to (view, priv->hadj->value, priv->vadj->value); } - static void set_scroll_area (EMap *view) { diff --git a/widgets/misc/e-map.h b/widgets/misc/e-map.h index df3f70a343..6c0e44e93b 100644 --- a/widgets/misc/e-map.h +++ b/widgets/misc/e-map.h @@ -67,7 +67,6 @@ struct _EMapPoint gpointer user_data; }; - /* --- Widget --- */ GType e_map_get_type (void); diff --git a/widgets/misc/e-pilot-settings.c b/widgets/misc/e-pilot-settings.c index 1bed8630c5..0327ca84ff 100644 --- a/widgets/misc/e-pilot-settings.c +++ b/widgets/misc/e-pilot-settings.c @@ -37,13 +37,11 @@ struct _EPilotSettingsPrivate GtkWidget *cat_btn; }; - static void class_init (EPilotSettingsClass *klass); static void init (EPilotSettings *ps); static GObjectClass *parent_class = NULL; - GType e_pilot_settings_get_type (void) { @@ -86,7 +84,6 @@ init (EPilotSettings *ps) ps->priv = priv; } - static void build_ui (EPilotSettings *ps, ESourceList *source_list) { diff --git a/widgets/misc/e-popup-menu.c b/widgets/misc/e-popup-menu.c index 20b570df24..129a52e0ca 100644 --- a/widgets/misc/e-popup-menu.c +++ b/widgets/misc/e-popup-menu.c @@ -72,7 +72,6 @@ e_popup_menu_create (EPopupMenu *menu_list, NULL); } - GtkMenu * e_popup_menu_create_with_domain (EPopupMenu *menu_list, guint32 disable_mask, diff --git a/widgets/misc/e-popup-menu.h b/widgets/misc/e-popup-menu.h index 75246ebda6..627ed611a6 100644 --- a/widgets/misc/e-popup-menu.h +++ b/widgets/misc/e-popup-menu.h @@ -32,7 +32,6 @@ G_BEGIN_DECLS #define E_POPUP_SEPARATOR { (gchar *) "", NULL, (NULL), NULL, 0 } #define E_POPUP_TERMINATOR { NULL, NULL, (NULL), NULL, 0 } - /* In the following, CC = custom closure */ #define E_POPUP_ITEM(name,fn,disable_mask) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), NULL, NULL, 0, 0, 0, 0 } @@ -47,7 +46,6 @@ G_BEGIN_DECLS #define E_POPUP_PIXMAP_WIDGET_ITEM_CC(name,pixmap_widget,fn,closure,disable_mask) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), (pixmap_widget), (closure), 0, 0, 0, 1 } #define E_POPUP_PIXMAP_WIDGET_SUBMENU(name,pixmap_widget,submenu,disable_mask) { (gchar *) (name), NULL, NULL, (submenu), (disable_mask), (pixmap_widget), NULL, 0, 0, 0, 0 } - #define E_POPUP_TOGGLE_ITEM(name,fn,disable_mask,value) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), NULL, NULL, 1, 0, value, 0 } #define E_POPUP_TOGGLE_ITEM_CC(name,fn,closure,disable_mask,value) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), NULL, (closure), 1, 0, value, 1 } #define E_POPUP_TOGGLE_ITEM_CC(name,fn,closure,disable_mask,value) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), NULL, (closure), 1, 0, value, 1 } @@ -67,7 +65,6 @@ G_BEGIN_DECLS #define E_POPUP_RADIO_PIXMAP_WIDGET_ITEM(name,pixmap_widget,fn,disable_mask) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), (pixmap_widget), NULL, 0, 1, value, 0 } #define E_POPUP_RADIO_PIXMAP_WIDGET_ITEM_CC(name,pixmap_widget,fn,closure,disable_mask) { (gchar *) (name), NULL, (fn), NULL, (disable_mask), (pixmap_widget), (closure), 0, 1, value, 1 } - typedef struct _EPopupMenu EPopupMenu; struct _EPopupMenu { diff --git a/widgets/misc/e-printable.c b/widgets/misc/e-printable.c index 05a219f901..b42080886a 100644 --- a/widgets/misc/e-printable.c +++ b/widgets/misc/e-printable.c @@ -28,7 +28,6 @@ #include "e-printable.h" - #define EP_CLASS(e) ((EPrintableClass *)((GtkObject *)e)->klass) G_DEFINE_TYPE (EPrintable, e_printable, GTK_TYPE_OBJECT) diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index 90922b5560..84a18eb925 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -542,7 +542,6 @@ e_selection_model_array_get_row_count (ESelectionModelArray *esma) return 0; } - static void e_selection_model_array_init (ESelectionModelArray *esma) { diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index 3f69fca342..2f7687b578 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -89,5 +89,4 @@ gint e_selection_model_array_get_row_count (ESelectionModelArray *esm); G_END_DECLS - #endif /* _E_SELECTION_MODEL_ARRAY_H_ */ diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index c87ccf960e..fb62b1fc9f 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -94,7 +94,6 @@ typedef struct { } ESelectionModelClass; - GType e_selection_model_get_type (void); void e_selection_model_do_something (ESelectionModel *esm, guint row, @@ -128,7 +127,6 @@ void e_selection_model_select_all (ESelectionModel *esm); void e_selection_model_invert_selection (ESelectionModel *esm); gint e_selection_model_row_count (ESelectionModel *esm); - /* Private virtual Functions */ void e_selection_model_change_one_row (ESelectionModel *esm, gint row, @@ -160,6 +158,5 @@ void e_selection_model_selection_changed (ESelectionModel *selection); G_END_DECLS - #endif /* _E_SELECTION_MODEL_H_ */ diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index fa84e86cc8..eff79544fd 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -37,7 +37,6 @@ #include "e-dateedit.h" #include "e-send-options.h" - struct _ESendOptionsDialogPrivate { /* Glade XML data */ GladeXML *xml; @@ -380,7 +379,6 @@ page_changed_cb (GtkNotebook *notebook, GtkNotebookPage *page, gint num, gpointe e_send_options_fill_widgets_with_data (sod); } - static void init_widgets (ESendOptionsDialog *sod) { @@ -399,7 +397,6 @@ init_widgets (ESendOptionsDialog *sod) if (priv->global) g_signal_connect (priv->notebook, "switch-page", G_CALLBACK (page_changed_cb), sod); - } static gboolean @@ -733,7 +730,6 @@ e_sendoptions_dialog_init (GObject *object) ESendOptionsDialogPrivate *priv; ESendOptionsData *new; - sod = E_SENDOPTIONS_DIALOG (object); new = g_new0 (ESendOptionsData, 1); new->gopts = g_new0 (ESendOptionsGeneral, 1); diff --git a/widgets/misc/e-spinner.c b/widgets/misc/e-spinner.c index bf71e4e50c..3e7b732def 100644 --- a/widgets/misc/e-spinner.c +++ b/widgets/misc/e-spinner.c @@ -800,7 +800,6 @@ e_spinner_stop (ESpinner *spinner) } } - /* * e_spinner_set_timeout: * @spinner: a #ESpinner diff --git a/widgets/misc/e-url-entry.c b/widgets/misc/e-url-entry.c index 2dd47ebb8f..6900bd12f3 100644 --- a/widgets/misc/e-url-entry.c +++ b/widgets/misc/e-url-entry.c @@ -45,7 +45,6 @@ static gboolean mnemonic_activate (GtkWidget *widget, gboolean group_cycling); static gpointer parent_class = NULL; - GType e_url_entry_get_type (void) { @@ -87,7 +86,6 @@ class_init (EUrlEntryClass *class) widget_class->mnemonic_activate = mnemonic_activate; } - static void init (EUrlEntry *url_entry) { @@ -151,7 +149,6 @@ e_url_entry_new (void) return g_object_new (E_TYPE_URL_ENTRY, NULL); } - GtkWidget * e_url_entry_get_entry (EUrlEntry *url_entry) { diff --git a/widgets/misc/ea-calendar-cell.c b/widgets/misc/ea-calendar-cell.c index af9471c5af..05d0dcce6b 100644 --- a/widgets/misc/ea-calendar-cell.c +++ b/widgets/misc/ea-calendar-cell.c @@ -328,7 +328,6 @@ component_interface_get_extents (AtkComponent *component, g_return_if_fail (EA_IS_CALENDAR_CELL (component)); - g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); if (!g_obj) /* defunct object*/ diff --git a/widgets/misc/ea-calendar-item.h b/widgets/misc/ea-calendar-item.h index 36cc671a3b..b5271a9f8b 100644 --- a/widgets/misc/ea-calendar-item.h +++ b/widgets/misc/ea-calendar-item.h @@ -64,5 +64,4 @@ gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem, G_END_DECLS - #endif /* __EA_CALENDAR_ITEM_H__ */ diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c index ed670a817c..458d60f90a 100644 --- a/widgets/misc/test-calendar.c +++ b/widgets/misc/test-calendar.c @@ -43,7 +43,6 @@ static GtkTargetEntry target_table[] = { static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); - static void on_date_range_changed (ECalendarItem *calitem); static void on_selection_changed (ECalendarItem *calitem); @@ -84,13 +83,11 @@ main (gint argc, gchar **argv) g_signal_connect (calitem, "selection_changed", G_CALLBACK (on_selection_changed), NULL); - gtk_drag_dest_set (cal, GTK_DEST_DEFAULT_ALL, target_table, n_targets, GDK_ACTION_COPY | GDK_ACTION_MOVE); - vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), cal, TRUE, TRUE, 0); gtk_widget_show (vbox); @@ -103,7 +100,6 @@ main (gint argc, gchar **argv) return 0; } - static void on_date_range_changed (ECalendarItem *calitem) { @@ -125,7 +121,6 @@ on_date_range_changed (ECalendarItem *calitem) E_CALENDAR_ITEM_MARK_BOLD, FALSE); } - static void on_selection_changed (ECalendarItem *calitem) { diff --git a/widgets/misc/test-dateedit.c b/widgets/misc/test-dateedit.c index 745c982b8d..c7b973904a 100644 --- a/widgets/misc/test-dateedit.c +++ b/widgets/misc/test-dateedit.c @@ -167,7 +167,6 @@ main (gint argc, gchar **argv) return 0; } - static void delete_event_cb (GtkWidget *widget, GdkEventAny *event, @@ -178,7 +177,6 @@ delete_event_cb (GtkWidget *widget, gtk_main_quit (); } - static void on_get_date_clicked (GtkWidget *button, EDateEdit *dedit) @@ -198,7 +196,6 @@ on_get_date_clicked (GtkWidget *button, g_print (" Time invalid\n"); } - static void on_toggle_24_hour_clicked (GtkWidget *button, EDateEdit *dedit) @@ -206,7 +203,6 @@ on_toggle_24_hour_clicked (GtkWidget *button, e_date_edit_set_use_24_hour_format (dedit, !e_date_edit_get_use_24_hour_format (dedit)); } - #if 0 static void on_date_changed (EDateEdit *dedit, @@ -226,7 +222,6 @@ on_date_changed (EDateEdit *dedit, } } - static void on_time_changed (EDateEdit *dedit, gchar *name) @@ -246,7 +241,6 @@ on_time_changed (EDateEdit *dedit, } #endif - static void on_changed (EDateEdit *dedit, gchar *name) -- cgit v1.2.3 From f8b8692499922f1aefe6c673549d6cd9f13c7856 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 17 Jul 2009 15:58:11 -0400 Subject: Remove unused EActivity properties and subclasses. --- widgets/misc/Makefile.am | 2 - widgets/misc/e-activity.c | 159 ------------------ widgets/misc/e-activity.h | 9 - widgets/misc/e-file-activity.c | 365 ----------------------------------------- widgets/misc/e-file-activity.h | 83 ---------- 5 files changed, 618 deletions(-) delete mode 100644 widgets/misc/e-file-activity.c delete mode 100644 widgets/misc/e-file-activity.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 284a914953..c210393737 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -60,7 +60,6 @@ widgetsinclude_HEADERS = \ e-combo-cell-editable.h \ e-cursors.h \ e-dateedit.h \ - e-file-activity.h \ e-gui-utils.h \ e-hinted-entry.h \ e-hsv-utils.h \ @@ -123,7 +122,6 @@ libemiscwidgets_la_SOURCES = \ e-combo-cell-editable.c \ e-cursors.c \ e-dateedit.c \ - e-file-activity.c \ e-gui-utils.c \ e-hinted-entry.c \ e-hsv-utils.c \ diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c index ac9a3d7e8a..9f8faf75cb 100644 --- a/widgets/misc/e-activity.c +++ b/widgets/misc/e-activity.c @@ -35,11 +35,8 @@ struct _EActivityPrivate { gchar *primary_text; gchar *secondary_text; gdouble percent; - guint idle_id; - GError *error; guint allow_cancel : 1; - guint blocking : 1; guint cancelled : 1; guint clickable : 1; guint completed : 1; @@ -48,7 +45,6 @@ struct _EActivityPrivate { enum { PROP_0, PROP_ALLOW_CANCEL, - PROP_BLOCKING, PROP_CLICKABLE, PROP_ICON_NAME, PROP_PERCENT, @@ -67,26 +63,6 @@ enum { static gpointer parent_class; static gulong signals[LAST_SIGNAL]; -static gboolean -activity_idle_cancel_cb (EActivity *activity) -{ - activity->priv->idle_id = 0; - e_activity_cancel (activity); - g_object_unref (activity); - - return FALSE; -} - -static gboolean -activity_idle_complete_cb (EActivity *activity) -{ - activity->priv->idle_id = 0; - e_activity_complete (activity); - g_object_unref (activity); - - return FALSE; -} - static gboolean activity_describe_accumulator (GSignalInvocationHint *ihint, GValue *return_accu, @@ -114,12 +90,6 @@ activity_set_property (GObject *object, g_value_get_boolean (value)); return; - case PROP_BLOCKING: - e_activity_set_blocking ( - E_ACTIVITY (object), - g_value_get_boolean (value)); - return; - case PROP_CLICKABLE: e_activity_set_clickable ( E_ACTIVITY (object), @@ -167,12 +137,6 @@ activity_get_property (GObject *object, E_ACTIVITY (object))); return; - case PROP_BLOCKING: - g_value_set_boolean ( - value, e_activity_get_blocking ( - E_ACTIVITY (object))); - return; - case PROP_CLICKABLE: g_value_set_boolean ( value, e_activity_get_clickable ( @@ -218,12 +182,6 @@ activity_finalize (GObject *object) g_free (priv->primary_text); g_free (priv->secondary_text); - if (priv->idle_id > 0) - g_source_remove (priv->idle_id); - - if (priv->error != NULL) - g_error_free (priv->error); - /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -232,22 +190,12 @@ static void activity_cancelled (EActivity *activity) { activity->priv->cancelled = TRUE; - - if (activity->priv->idle_id > 0) { - g_source_remove (activity->priv->idle_id); - activity->priv->idle_id = 0; - } } static void activity_completed (EActivity *activity) { activity->priv->completed = TRUE; - - if (activity->priv->idle_id > 0) { - g_source_remove (activity->priv->idle_id); - activity->priv->idle_id = 0; - } } static void @@ -321,17 +269,6 @@ activity_class_init (EActivityClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property ( - object_class, - PROP_BLOCKING, - g_param_spec_boolean ( - "blocking", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - g_object_class_install_property ( object_class, PROP_CLICKABLE, @@ -499,29 +436,6 @@ e_activity_cancel (EActivity *activity) g_signal_emit (activity, signals[CANCELLED], 0); } -void -e_activity_cancel_in_idle (EActivity *activity) -{ - guint old_idle_id; - - g_return_if_fail (E_IS_ACTIVITY (activity)); - - /* Be careful not to finalize the activity. Decrement the - * reference count only after incrementing it, in case this - * is the last reference. */ - - old_idle_id = activity->priv->idle_id; - - activity->priv->idle_id = g_idle_add ( - (GSourceFunc) activity_idle_cancel_cb, - g_object_ref (activity)); - - if (old_idle_id > 0) { - g_source_remove (old_idle_id); - g_object_unref (activity); - } -} - void e_activity_complete (EActivity *activity) { @@ -536,29 +450,6 @@ e_activity_complete (EActivity *activity) g_signal_emit (activity, signals[COMPLETED], 0); } -void -e_activity_complete_in_idle (EActivity *activity) -{ - guint old_idle_id; - - g_return_if_fail (E_IS_ACTIVITY (activity)); - - /* Be careful not to finalize the activity. Decrement the - * reference count only after incrementing it, in case this - * is the last reference. */ - - old_idle_id = activity->priv->idle_id; - - activity->priv->idle_id = g_idle_add ( - (GSourceFunc) activity_idle_complete_cb, - g_object_ref (activity)); - - if (old_idle_id > 0) { - g_source_remove (old_idle_id); - g_object_unref (activity); - } -} - void e_activity_clicked (EActivity *activity) { @@ -615,25 +506,6 @@ e_activity_set_allow_cancel (EActivity *activity, g_object_notify (G_OBJECT (activity), "allow-cancel"); } -gboolean -e_activity_get_blocking (EActivity *activity) -{ - g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); - - return activity->priv->blocking; -} - -void -e_activity_set_blocking (EActivity *activity, - gboolean blocking) -{ - g_return_if_fail (E_IS_ACTIVITY (activity)); - - activity->priv->blocking = blocking; - - g_object_notify (G_OBJECT (activity), "blocking"); -} - gboolean e_activity_get_clickable (EActivity *activity) { @@ -731,34 +603,3 @@ e_activity_set_secondary_text (EActivity *activity, g_object_notify (G_OBJECT (activity), "secondary-text"); } - -void -e_activity_set_error (EActivity *activity, - const GError *error) -{ - g_return_if_fail (E_IS_ACTIVITY (activity)); - - if (activity->priv->error != NULL) { - g_error_free (activity->priv->error); - activity->priv->error = NULL; - } - - if (error != NULL) - activity->priv->error = g_error_copy (error); -} - -gboolean -e_activity_propagate_error (EActivity *activity, - GError **destination) -{ - gboolean propagated; - - g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE); - - if ((propagated = (activity->priv->error != NULL))) { - g_propagate_error (destination, activity->priv->error); - activity->priv->error = NULL; - } - - return propagated; -} diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h index aca262172c..b396e3a630 100644 --- a/widgets/misc/e-activity.h +++ b/widgets/misc/e-activity.h @@ -69,9 +69,7 @@ EActivity * e_activity_new (const gchar *primary_text); EActivity * e_activity_newv (const gchar *format, ...) G_GNUC_PRINTF (1, 2); void e_activity_cancel (EActivity *activity); -void e_activity_cancel_in_idle (EActivity *activity); void e_activity_complete (EActivity *activity); -void e_activity_complete_in_idle (EActivity *activity); void e_activity_clicked (EActivity *activity); gchar * e_activity_describe (EActivity *activity); gboolean e_activity_is_cancelled (EActivity *activity); @@ -79,9 +77,6 @@ gboolean e_activity_is_completed (EActivity *activity); gboolean e_activity_get_allow_cancel (EActivity *activity); void e_activity_set_allow_cancel (EActivity *activity, gboolean allow_cancel); -gboolean e_activity_get_blocking (EActivity *activity); -void e_activity_set_blocking (EActivity *activity, - gboolean blocking); gboolean e_activity_get_clickable (EActivity *activity); void e_activity_set_clickable (EActivity *activity, gboolean clickable); @@ -97,10 +92,6 @@ void e_activity_set_primary_text (EActivity *activity, const gchar * e_activity_get_secondary_text (EActivity *activity); void e_activity_set_secondary_text (EActivity *activity, const gchar *secondary_text); -void e_activity_set_error (EActivity *activity, - const GError *error); -gboolean e_activity_propagate_error (EActivity *activity, - GError **destination); G_END_DECLS diff --git a/widgets/misc/e-file-activity.c b/widgets/misc/e-file-activity.c deleted file mode 100644 index e35ab4955c..0000000000 --- a/widgets/misc/e-file-activity.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * e-file-activity.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include "e-file-activity.h" - -#include - -#define E_FILE_ACTIVITY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_FILE_ACTIVITY, EFileActivityPrivate)) - -struct _EFileActivityPrivate { - GCancellable *cancellable; - GAsyncResult *result; - GFile *file; - - gulong handler_id; -}; - -enum { - PROP_0, - PROP_CANCELLABLE, - PROP_FILE, - PROP_RESULT -}; - -static gpointer parent_class; - -static void -file_activity_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CANCELLABLE: - e_file_activity_set_cancellable ( - E_FILE_ACTIVITY (object), - g_value_get_object (value)); - return; - - case PROP_FILE: - e_file_activity_set_file ( - E_FILE_ACTIVITY (object), - g_value_get_object (value)); - return; - - case PROP_RESULT: - e_file_activity_set_result ( - E_FILE_ACTIVITY (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -file_activity_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CANCELLABLE: - g_value_set_object ( - value, e_file_activity_get_cancellable ( - E_FILE_ACTIVITY (object))); - return; - - case PROP_FILE: - g_value_set_object ( - value, e_file_activity_get_file ( - E_FILE_ACTIVITY (object))); - return; - - case PROP_RESULT: - g_value_set_object ( - value, e_file_activity_get_result ( - E_FILE_ACTIVITY (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -file_activity_dispose (GObject *object) -{ - EFileActivityPrivate *priv; - - priv = E_FILE_ACTIVITY_GET_PRIVATE (object); - - if (priv->cancellable != NULL) { - g_signal_handler_disconnect ( - priv->cancellable, priv->handler_id); - g_object_unref (priv->cancellable); - priv->cancellable = NULL; - } - - if (priv->result != NULL) { - g_object_unref (priv->result); - priv->result = NULL; - } - - if (priv->file != NULL) { - g_object_unref (priv->file); - priv->file = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -file_activity_cancelled (EActivity *activity) -{ - EFileActivity *file_activity; - GCancellable *cancellable; - - file_activity = E_FILE_ACTIVITY (activity); - cancellable = e_file_activity_get_cancellable (file_activity); - g_cancellable_cancel (cancellable); - - /* Chain up to parent's cancelled() method. */ - E_ACTIVITY_CLASS (parent_class)->cancelled (activity); -} - -static void -file_activity_class_init (EFileActivityClass *class) -{ - GObjectClass *object_class; - EActivityClass *activity_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EFileActivityPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = file_activity_set_property; - object_class->get_property = file_activity_get_property; - object_class->dispose = file_activity_dispose; - - activity_class = E_ACTIVITY_CLASS (class); - activity_class->cancelled = file_activity_cancelled; - - g_object_class_install_property ( - object_class, - PROP_CANCELLABLE, - g_param_spec_object ( - "cancellable", - "Cancellable", - NULL, - G_TYPE_CANCELLABLE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_FILE, - g_param_spec_object ( - "file", - "File", - NULL, - G_TYPE_FILE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_RESULT, - g_param_spec_object ( - "result", - "Result", - NULL, - G_TYPE_ASYNC_RESULT, - G_PARAM_READWRITE)); -} - -static void -file_activity_init (EFileActivity *file_activity) -{ - GCancellable *cancellable; - - file_activity->priv = E_FILE_ACTIVITY_GET_PRIVATE (file_activity); - - e_activity_set_allow_cancel (E_ACTIVITY (file_activity), TRUE); - - cancellable = g_cancellable_new (); - e_file_activity_set_cancellable (file_activity, cancellable); - g_object_unref (cancellable); -} - -GType -e_file_activity_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EFileActivityClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) file_activity_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EFileActivity), - 0, /* n_preallocs */ - (GInstanceInitFunc) file_activity_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - E_TYPE_ACTIVITY, "EFileActivity", &type_info, 0); - } - - return type; -} - -EActivity * -e_file_activity_new (const gchar *primary_text) -{ - return g_object_new ( - E_TYPE_FILE_ACTIVITY, - "primary-text", primary_text, NULL); -} - -EActivity * -e_file_activity_newv (const gchar *format, ...) -{ - EActivity *activity; - gchar *primary_text; - va_list args; - - va_start (args, format); - primary_text = g_strdup_vprintf (format, args); - activity = e_file_activity_new (primary_text); - g_free (primary_text); - va_end (args); - - return activity; -} - -GCancellable * -e_file_activity_get_cancellable (EFileActivity *file_activity) -{ - g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); - - return file_activity->priv->cancellable; -} - -void -e_file_activity_set_cancellable (EFileActivity *file_activity, - GCancellable *cancellable) -{ - g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); - - if (cancellable != NULL) { - g_return_if_fail (G_IS_CANCELLABLE (cancellable)); - g_object_ref (cancellable); - } - - if (file_activity->priv->cancellable != NULL) { - g_signal_handler_disconnect ( - file_activity->priv->cancellable, - file_activity->priv->handler_id); - g_object_unref (file_activity->priv->cancellable); - file_activity->priv->handler_id = 0; - } - - file_activity->priv->cancellable = cancellable; - - if (cancellable != NULL) - file_activity->priv->handler_id = - g_signal_connect_swapped ( - cancellable, "cancelled", - G_CALLBACK (e_activity_cancel), - file_activity); - - g_object_notify (G_OBJECT (file_activity), "cancellable"); -} - -GFile * -e_file_activity_get_file (EFileActivity *file_activity) -{ - g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); - - return file_activity->priv->file; -} - -void -e_file_activity_set_file (EFileActivity *file_activity, - GFile *file) -{ - g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); - - if (file != NULL) { - g_return_if_fail (G_IS_FILE (file)); - g_object_ref (file); - } - - if (file_activity->priv->file != NULL) - g_object_unref (file_activity->priv->file); - - file_activity->priv->file = file; - - g_object_notify (G_OBJECT (file_activity), "file"); -} - -GAsyncResult * -e_file_activity_get_result (EFileActivity *file_activity) -{ - g_return_val_if_fail (E_IS_FILE_ACTIVITY (file_activity), NULL); - - return file_activity->priv->result; -} - -void -e_file_activity_set_result (EFileActivity *file_activity, - GAsyncResult *result) -{ - g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity)); - - if (result != NULL) { - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_object_ref (result); - } - - if (file_activity->priv->result != NULL) - g_object_unref (file_activity->priv->result); - - file_activity->priv->result = result; - - g_object_notify (G_OBJECT (file_activity), "result"); -} - -void -e_file_activity_progress (goffset current_num_bytes, - goffset total_num_bytes, - gpointer activity) -{ - gdouble percent = -1.0; - - g_return_if_fail (E_IS_ACTIVITY (activity)); - - if (current_num_bytes > 0 && total_num_bytes > 0) - percent = (gdouble) current_num_bytes / total_num_bytes; - - e_activity_set_percent (activity, percent); -} diff --git a/widgets/misc/e-file-activity.h b/widgets/misc/e-file-activity.h deleted file mode 100644 index b4a5433c21..0000000000 --- a/widgets/misc/e-file-activity.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * e-file-activity.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 - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILE_ACTIVITY_H -#define E_FILE_ACTIVITY_H - -#include -#include - -/* Standard GObject macros */ -#define E_TYPE_FILE_ACTIVITY \ - (e_file_activity_get_type ()) -#define E_FILE_ACTIVITY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILE_ACTIVITY, EFileActivity)) -#define E_FILE_ACTIVITY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILE_ACTIVITY, EFileActivityClass)) -#define E_IS_FILE_ACTIVITY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILE_ACTIVITY)) -#define E_IS_FILE_ACTIVITY_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILE_ACTIVITY)) -#define E_FILE_ACTIVITY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILE_ACTIVITY, EFileActivityClass)) - -G_BEGIN_DECLS - -typedef struct _EFileActivity EFileActivity; -typedef struct _EFileActivityClass EFileActivityClass; -typedef struct _EFileActivityPrivate EFileActivityPrivate; - -struct _EFileActivity { - EActivity parent; - EFileActivityPrivate *priv; -}; - -struct _EFileActivityClass { - EActivityClass parent_class; -}; - -GType e_file_activity_get_type (void); -EActivity * e_file_activity_new (const gchar *primary_text); -EActivity * e_file_activity_newv (const gchar *format, - ...) G_GNUC_PRINTF (1, 2); -GCancellable * e_file_activity_get_cancellable (EFileActivity *file_activity); -void e_file_activity_set_cancellable (EFileActivity *file_activity, - GCancellable *cancellable); -GFile * e_file_activity_get_file (EFileActivity *file_activity); -void e_file_activity_set_file (EFileActivity *file_activity, - GFile *file); -GAsyncResult * e_file_activity_get_result (EFileActivity *file_activity); -void e_file_activity_set_result (EFileActivity *file_activity, - GAsyncResult *result); - -/* This can be used as a GFileProgressCallback. */ -void e_file_activity_progress (goffset current_num_bytes, - goffset total_num_bytes, - gpointer activity); - -G_END_DECLS - -#endif /* E_FILE_ACTIVITY_H */ -- cgit v1.2.3 From 787e1f93d51f647457d874b3be1b1681d884a401 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 17 Jul 2009 16:51:25 -0400 Subject: Make errors in taskbar clickable. --- widgets/misc/e-activity-proxy.c | 1 + widgets/misc/e-alert-activity.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c index b045394442..10249b1911 100644 --- a/widgets/misc/e-activity-proxy.c +++ b/widgets/misc/e-activity-proxy.c @@ -272,6 +272,7 @@ activity_proxy_init (EActivityProxy *proxy) gtk_widget_hide (widget); widget = gtk_button_new (); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); proxy->priv->button = g_object_ref (widget); gtk_widget_hide (widget); diff --git a/widgets/misc/e-alert-activity.c b/widgets/misc/e-alert-activity.c index 860b129ef9..1e8f915213 100644 --- a/widgets/misc/e-alert-activity.c +++ b/widgets/misc/e-alert-activity.c @@ -114,6 +114,11 @@ alert_activity_constructed (GObject *object) activity = E_ACTIVITY (alert_activity); e_activity_set_primary_text (activity, primary_text); e_activity_set_secondary_text (activity, secondary_text); + + /* This is a constructor property, so can't do it in init(). + * XXX What we really want to do is override the property's + * default value, but GObject does not support that. */ + e_activity_set_clickable (E_ACTIVITY (alert_activity), TRUE); } static void @@ -181,7 +186,6 @@ alert_activity_init (EAlertActivity *alert_activity) { alert_activity->priv = E_ALERT_ACTIVITY_GET_PRIVATE (alert_activity); - e_activity_set_clickable (E_ACTIVITY (alert_activity), TRUE); e_timeout_activity_set_timeout (E_TIMEOUT_ACTIVITY (alert_activity), 60); } -- cgit v1.2.3 From fa360fde289f9b850191f89059d1a5e6d67c07c7 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 18 Jul 2009 14:07:42 -0400 Subject: More whitespace cleanup. --- widgets/misc/e-canvas-background.c | 4 ++-- widgets/misc/e-canvas-vbox.c | 4 ++-- widgets/misc/e-cursors.c | 12 ++++++------ widgets/misc/e-dateedit.c | 2 +- widgets/misc/e-gui-utils.c | 2 +- widgets/misc/e-popup-menu.c | 2 +- widgets/misc/e-selection-model-array.c | 4 ++-- widgets/misc/e-selection-model.c | 4 ++-- widgets/misc/e-send-options.c | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-canvas-background.c b/widgets/misc/e-canvas-background.c index 41b03d7f65..04c163ef06 100644 --- a/widgets/misc/e-canvas-background.c +++ b/widgets/misc/e-canvas-background.c @@ -212,7 +212,7 @@ ecb_set_property (GObject *object, item = GNOME_CANVAS_ITEM (object); ecb = E_CANVAS_BACKGROUND (object); - switch (prop_id){ + switch (prop_id) { case PROP_FILL_COLOR: if (g_value_get_string (value)) gdk_color_parse (g_value_get_string (value), &color); @@ -288,7 +288,7 @@ ecb_get_property (GObject *object, ecb = E_CANVAS_BACKGROUND (object); - switch (prop_id){ + switch (prop_id) { case PROP_FILL_COLOR_GDK: g_value_set_boxed (value, gdk_color_copy (&ecb->priv->color)); break; diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c index a7e8191bc4..af159b2000 100644 --- a/widgets/misc/e-canvas-vbox.c +++ b/widgets/misc/e-canvas-vbox.c @@ -126,7 +126,7 @@ e_canvas_vbox_set_property (GObject *object, guint prop_id, const GValue *value, item = GNOME_CANVAS_ITEM (object); e_canvas_vbox = E_CANVAS_VBOX (object); - switch (prop_id){ + switch (prop_id) { case PROP_WIDTH: case PROP_MINIMUM_WIDTH: e_canvas_vbox->minimum_width = g_value_get_double (value); @@ -329,7 +329,7 @@ e_canvas_vbox_reflow( GnomeCanvasItem *item, gint flags ) max_width = item_width; list = g_list_next(list); - for(; list; list = g_list_next(list)) { + for (; list; list = g_list_next(list)) { running_height += e_canvas_vbox->spacing; g_object_get (list->data, diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index e8f4221b60..4ec2717d1c 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -80,12 +80,12 @@ create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gch black_color = '.'; yofs = colors + 1; - for (y = 0; y < 32; y++){ - for (x = 0; x < 32;){ + for (y = 0; y < 32; y++) { + for (x = 0; x < 32;) { gchar value = 0, maskv = 0; - for (pix = 0; pix < 8; pix++, x++){ - if (xpm [y + yofs][x] != transparent_color){ + for (pix = 0; pix < 8; pix++, x++) { + if (xpm [y + yofs][x] != transparent_color) { maskv |= 1 << pix; /* @@ -94,7 +94,7 @@ create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, const gch * We reverse the foreground & background in the next * routine to compensate. */ - if (xpm [y + yofs][x] == black_color){ + if (xpm [y + yofs][x] == black_color) { value |= 1 << pix; } } @@ -114,7 +114,7 @@ e_cursors_init (void) e_color_init (); - for (i = 0; cursors [i].hot_x; i++){ + for (i = 0; cursors [i].hot_x; i++) { if (cursors [i].hot_x < 0) cursors [i].cursor = gdk_cursor_new (cursors [i].hot_y); else { diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index e7b1a0555e..775ab3b8a3 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -200,7 +200,7 @@ e_date_edit_get_type (void) { static GType date_edit_type = 0; - if (!date_edit_type){ + if (!date_edit_type) { static const GTypeInfo date_edit_info = { sizeof (EDateEditClass), NULL, /* base_init */ diff --git a/widgets/misc/e-gui-utils.c b/widgets/misc/e-gui-utils.c index 6cd4958127..d33e3c1139 100644 --- a/widgets/misc/e-gui-utils.c +++ b/widgets/misc/e-gui-utils.c @@ -50,7 +50,7 @@ e_popup_menu (GtkMenu *menu, GdkEvent *event) else if ((event->type == GDK_BUTTON_PRESS) || (event->type == GDK_BUTTON_RELEASE) || (event->type == GDK_2BUTTON_PRESS) || - (event->type == GDK_3BUTTON_PRESS)){ + (event->type == GDK_3BUTTON_PRESS)) { gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time); diff --git a/widgets/misc/e-popup-menu.c b/widgets/misc/e-popup-menu.c index 129a52e0ca..953d0c67dd 100644 --- a/widgets/misc/e-popup-menu.c +++ b/widgets/misc/e-popup-menu.c @@ -53,7 +53,7 @@ make_item (GtkMenu *menu, GtkMenuItem *item, const gchar *name, GtkWidget *pixma gtk_container_add (GTK_CONTAINER (item), label); - if (pixmap && GTK_IS_IMAGE_MENU_ITEM (item)){ + if (pixmap && GTK_IS_IMAGE_MENU_ITEM (item)) { gtk_widget_show (pixmap); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), pixmap); } diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index 84a18eb925..9a2a6a8e68 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -194,7 +194,7 @@ esma_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *ps { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (object); - switch (prop_id){ + switch (prop_id) { case PROP_CURSOR_ROW: g_value_set_int (value, esma->cursor_row); break; @@ -211,7 +211,7 @@ esma_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp ESelectionModel *esm = E_SELECTION_MODEL (object); ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY (object); - switch (prop_id){ + switch (prop_id) { case PROP_CURSOR_ROW: e_selection_model_do_something(esm, g_value_get_int (value), esma->cursor_col, 0); break; diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index cc1d3b3780..fb43d73ffb 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -84,7 +84,7 @@ esm_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *psp { ESelectionModel *esm = E_SELECTION_MODEL (object); - switch (prop_id){ + switch (prop_id) { case PROP_SORTER: g_value_set_object (value, esm->sorter); break; @@ -104,7 +104,7 @@ esm_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpe { ESelectionModel *esm = E_SELECTION_MODEL (object); - switch (prop_id){ + switch (prop_id) { case PROP_SORTER: drop_sorter(esm); add_sorter(esm, g_value_get_object (value) ? E_SORTER(g_value_get_object(value)) : NULL); diff --git a/widgets/misc/e-send-options.c b/widgets/misc/e-send-options.c index eff79544fd..aa6c41e6d2 100644 --- a/widgets/misc/e-send-options.c +++ b/widgets/misc/e-send-options.c @@ -249,7 +249,7 @@ sensitize_widgets (ESendOptionsDialog *sod) if (!gopts->expiration_enabled) gtk_widget_set_sensitive (priv->expire_after, FALSE); - if (!gopts->delay_enabled){ + if (!gopts->delay_enabled) { gtk_widget_set_sensitive (priv->delay_until, FALSE); } -- cgit v1.2.3 From bfd6635397f29dc7b0ad6b6a27101c241a7287b6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Jul 2009 15:41:54 -0400 Subject: Get GnomeCalendar and the a11y stuff building. --- widgets/misc/Makefile.am | 2 + widgets/misc/ea-calendar-item.c | 2 +- widgets/misc/ea-cell-table.c | 202 ++++++++++++++++++++++++++++++++++++++++ widgets/misc/ea-cell-table.h | 60 ++++++++++++ 4 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 widgets/misc/ea-cell-table.c create mode 100644 widgets/misc/ea-cell-table.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index c210393737..ebd5562c30 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -87,6 +87,7 @@ widgetsinclude_HEADERS = \ e-url-entry.h \ ea-calendar-cell.h \ ea-calendar-item.h \ + ea-cell-table.h \ ea-widgets.h libemiscwidgets_la_SOURCES = \ @@ -147,6 +148,7 @@ libemiscwidgets_la_SOURCES = \ e-url-entry.c \ ea-calendar-cell.c \ ea-calendar-item.c \ + ea-cell-table.c \ ea-widgets.c libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) diff --git a/widgets/misc/ea-calendar-item.c b/widgets/misc/ea-calendar-item.c index 56a01b510b..9dcb83449c 100644 --- a/widgets/misc/ea-calendar-item.c +++ b/widgets/misc/ea-calendar-item.c @@ -30,7 +30,7 @@ #include #include "ea-calendar-item.h" #include "ea-calendar-cell.h" -#include "a11y/ea-cell-table.h" +#include "ea-cell-table.h" #define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH diff --git a/widgets/misc/ea-cell-table.c b/widgets/misc/ea-cell-table.c new file mode 100644 index 0000000000..95ae59dea4 --- /dev/null +++ b/widgets/misc/ea-cell-table.c @@ -0,0 +1,202 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-cell-table.h" + +EaCellTable * +ea_cell_table_create (gint rows, gint columns, gboolean column_first) +{ + EaCellTable * cell_data; + gint index; + + g_return_val_if_fail (((columns > 0) && (rows > 0)), NULL); + + cell_data = g_new0 (EaCellTable, 1); + + cell_data->column_first = column_first; + cell_data->columns = columns; + cell_data->rows = rows; + + cell_data->column_labels = g_new0 (gchar *, columns); + for (index = columns -1; index >= 0; --index) + cell_data->column_labels [index] = NULL; + + cell_data->row_labels = g_new0 (gchar *, rows); + for (index = rows -1; index >= 0; --index) + cell_data->row_labels [index] = NULL; + + cell_data->cells = g_new0(gpointer, (columns * rows)); + for (index = (columns * rows) -1; index >= 0; --index) + cell_data->cells [index] = NULL; + return cell_data; +} + +void +ea_cell_table_destroy (EaCellTable * cell_data) +{ + gint index; + g_return_if_fail (cell_data); + + for (index = 0; index < cell_data->columns; ++index) + if (cell_data->column_labels [index]) + g_free (cell_data->column_labels [index]); + g_free (cell_data->column_labels); + + for (index = 0; index < cell_data->rows; ++index) + if (cell_data->row_labels [index]) + g_free (cell_data->row_labels [index]); + g_free (cell_data->row_labels); + + for (index = (cell_data->columns * cell_data->rows) -1; + index >= 0; --index) + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + + g_free (cell_data->cells); +} + +gpointer +ea_cell_table_get_cell (EaCellTable * cell_data, + gint row, gint column) +{ + gint index; + + g_return_val_if_fail (cell_data, NULL); + + index = ea_cell_table_get_index (cell_data, column, row); + if (index == -1) + return NULL; + + return cell_data->cells[index]; +} + +gboolean +ea_cell_table_set_cell (EaCellTable * cell_data, + gint row, gint column, gpointer cell) +{ + gint index; + + g_return_val_if_fail (cell_data, FALSE); + + index = ea_cell_table_get_index (cell_data, column, row); + if (index == -1) + return FALSE; + + if (cell && G_IS_OBJECT(cell)) + g_object_ref (cell); + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + cell_data->cells[index] = cell; + + return TRUE; +} + +gpointer +ea_cell_table_get_cell_at_index (EaCellTable * cell_data, + gint index) +{ + g_return_val_if_fail (cell_data, NULL); + + if (index >=0 && index < (cell_data->columns * cell_data->rows)) + return cell_data->cells [index]; + return NULL; +} + +gboolean +ea_cell_table_set_cell_at_index (EaCellTable * cell_data, + gint index, gpointer cell) +{ + g_return_val_if_fail (cell_data, FALSE); + + if (index < 0 || index >=cell_data->columns * cell_data->rows) + return FALSE; + + if (cell && G_IS_OBJECT(cell)) + g_object_ref (cell); + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + cell_data->cells[index] = cell; + + return TRUE; +} + +G_CONST_RETURN gchar * +ea_cell_table_get_column_label (EaCellTable * cell_data, + gint column) +{ + g_return_val_if_fail (cell_data, NULL); + g_return_val_if_fail ((column >= 0 && column < cell_data->columns), NULL); + + return cell_data->column_labels[column]; +} + +void +ea_cell_table_set_column_label (EaCellTable * cell_data, + gint column, const gchar *label) +{ + g_return_if_fail (cell_data); + g_return_if_fail ((column >= 0 && column < cell_data->columns)); + + if (cell_data->column_labels[column]) + g_free (cell_data->column_labels[column]); + cell_data->column_labels[column] = g_strdup(label); +} + +G_CONST_RETURN gchar * +ea_cell_table_get_row_label (EaCellTable * cell_data, + gint row) +{ + g_return_val_if_fail (cell_data, NULL); + g_return_val_if_fail ((row >= 0 && row < cell_data->rows), NULL); + + return cell_data->row_labels[row]; +} + +void +ea_cell_table_set_row_label (EaCellTable * cell_data, + gint row, const gchar *label) +{ + g_return_if_fail (cell_data); + g_return_if_fail ((row >= 0 && row < cell_data->rows)); + + if (cell_data->row_labels[row]) + g_free (cell_data->row_labels[row]); + cell_data->row_labels[row] = g_strdup(label); +} + +gint +ea_cell_table_get_index (EaCellTable *cell_data, + gint row, gint column) +{ + g_return_val_if_fail (cell_data, -1); + if (row < 0 || row >= cell_data->rows || + column < 0 || column >= cell_data->columns) + return -1; + + if (cell_data->column_first) + return column * cell_data->rows + row; + else + return row * cell_data->columns + column; +} diff --git a/widgets/misc/ea-cell-table.h b/widgets/misc/ea-cell-table.h new file mode 100644 index 0000000000..353bbd0634 --- /dev/null +++ b/widgets/misc/ea-cell-table.h @@ -0,0 +1,60 @@ +/* + * 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 + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* EaCellTable */ + +#include +#include + +struct _EaCellTable { + gint columns; + gint rows; + gboolean column_first; /* index order */ + gchar **column_labels; + gchar **row_labels; + gpointer *cells; +}; + +typedef struct _EaCellTable EaCellTable; + +EaCellTable * ea_cell_table_create (gint rows, gint columns, + gboolean column_first); +void ea_cell_table_destroy (EaCellTable * cell_data); +gpointer ea_cell_table_get_cell (EaCellTable * cell_data, + gint row, gint column); +gboolean ea_cell_table_set_cell (EaCellTable * cell_data, + gint row, gint column, gpointer cell); +gpointer ea_cell_table_get_cell_at_index (EaCellTable * cell_data, + gint index); +gboolean ea_cell_table_set_cell_at_index (EaCellTable * cell_data, + gint index, gpointer cell); + +G_CONST_RETURN gchar * +ea_cell_table_get_column_label (EaCellTable * cell_data, gint column); +void ea_cell_table_set_column_label (EaCellTable * cell_data, + gint column, const gchar *label); +G_CONST_RETURN gchar * +ea_cell_table_get_row_label (EaCellTable * cell_data, gint row); +void ea_cell_table_set_row_label (EaCellTable * cell_data, + gint row, const gchar *label); +gint ea_cell_table_get_index (EaCellTable *cell_data, + gint row, gint column); -- cgit v1.2.3 From de85e3c7862100da10fe860aef2b651245a1fdbf Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 1 Aug 2009 07:29:41 -0400 Subject: Replace more "config" classes with property bindings. --- widgets/misc/e-dateedit.c | 336 +++++++++++++++++++++++++++++----------------- 1 file changed, 213 insertions(+), 123 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c index 775ab3b8a3..07a9fc61c4 100644 --- a/widgets/misc/e-dateedit.c +++ b/widgets/misc/e-dateedit.c @@ -42,6 +42,10 @@ #include #include "e-calendar.h" +#define E_DATE_EDIT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_DATE_EDIT, EDateEditPrivate)) + struct _EDateEditPrivate { GtkWidget *date_entry; GtkWidget *date_button; @@ -107,17 +111,19 @@ struct _EDateEditPrivate { gboolean twodigit_year_can_future; }; +enum { + PROP_0, + PROP_SHOW_WEEK_NUMBERS, + PROP_USE_24_HOUR_FORMAT, + PROP_WEEK_START_DAY +}; + enum { CHANGED, LAST_SIGNAL }; -static gint date_edit_signals [LAST_SIGNAL] = { 0 }; - -static void e_date_edit_class_init (EDateEditClass *class); -static void e_date_edit_init (EDateEdit *dedit); static void create_children (EDateEdit *dedit); -static void e_date_edit_dispose (GObject *object); static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); static void e_date_edit_grab_focus (GtkWidget *widget); @@ -188,87 +194,168 @@ static gboolean e_date_edit_set_time_internal (EDateEdit *dedit, gint hour, gint minute); -static GtkHBoxClass *parent_class; +static gpointer parent_class; +static gint signals[LAST_SIGNAL]; -/** - * e_date_edit_get_type: - * - * Returns the GType for the EDateEdit widget - */ -GType -e_date_edit_get_type (void) -{ - static GType date_edit_type = 0; +static void +date_edit_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHOW_WEEK_NUMBERS: + e_date_edit_set_show_week_numbers ( + E_DATE_EDIT (object), + g_value_get_boolean (value)); + return; - if (!date_edit_type) { - static const GTypeInfo date_edit_info = { - sizeof (EDateEditClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_date_edit_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EDateEdit), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_date_edit_init, - }; + case PROP_USE_24_HOUR_FORMAT: + e_date_edit_set_use_24_hour_format ( + E_DATE_EDIT (object), + g_value_get_boolean (value)); + return; + + case PROP_WEEK_START_DAY: + e_date_edit_set_week_start_day ( + E_DATE_EDIT (object), + g_value_get_int (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} - date_edit_type = g_type_register_static (GTK_TYPE_HBOX, "EDateEdit", &date_edit_info, 0); +static void +date_edit_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHOW_WEEK_NUMBERS: + g_value_set_boolean ( + value, e_date_edit_get_show_week_numbers ( + E_DATE_EDIT (object))); + return; + + case PROP_USE_24_HOUR_FORMAT: + g_value_set_boolean ( + value, e_date_edit_get_use_24_hour_format ( + E_DATE_EDIT (object))); + return; + + case PROP_WEEK_START_DAY: + g_value_set_int ( + value, e_date_edit_get_week_start_day ( + E_DATE_EDIT (object))); + return; } - return date_edit_type; + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -e_date_edit_class_init (EDateEditClass *class) +date_edit_dispose (GObject *object) { - GObjectClass *object_class = (GObjectClass *) class; - GtkWidgetClass *widget_class = (GtkWidgetClass *) class; + EDateEdit *dedit; - parent_class = g_type_class_ref (GTK_TYPE_HBOX); + dedit = E_DATE_EDIT (object); - date_edit_signals [CHANGED] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EDateEditClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL); - object_class->dispose = e_date_edit_dispose; + if (dedit->priv->cal_popup != NULL) { + gtk_widget_destroy (dedit->priv->cal_popup); + dedit->priv->cal_popup = NULL; + } + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +date_edit_class_init (EDateEditClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EDateEditPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = date_edit_set_property; + object_class->get_property = date_edit_get_property; + object_class->dispose = date_edit_dispose; + + widget_class = GTK_WIDGET_CLASS (class); widget_class->mnemonic_activate = e_date_edit_mnemonic_activate; widget_class->grab_focus = e_date_edit_grab_focus; - class->changed = NULL; + g_object_class_install_property ( + object_class, + PROP_SHOW_WEEK_NUMBERS, + g_param_spec_boolean ( + "show-week-numbers", + "Show Week Numbers", + NULL, + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_USE_24_HOUR_FORMAT, + g_param_spec_boolean ( + "use-24-hour-format", + "Use 24-Hour Format", + NULL, + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_WEEK_START_DAY, + g_param_spec_int ( + "week-start-day", + "Week Start Day", + NULL, + 0, /* Monday */ + 6, /* Sunday */ + 0, + G_PARAM_READWRITE)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EDateEditClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -e_date_edit_init (EDateEdit *dedit) +date_edit_init (EDateEdit *dedit) { - EDateEditPrivate *priv; + dedit->priv = E_DATE_EDIT_GET_PRIVATE (dedit); - dedit->priv = priv = g_new0 (EDateEditPrivate, 1); + dedit->priv->show_date = TRUE; + dedit->priv->show_time = TRUE; + dedit->priv->use_24_hour_format = TRUE; - priv->show_date = TRUE; - priv->show_time = TRUE; - priv->use_24_hour_format = TRUE; + dedit->priv->make_time_insensitive = FALSE; - priv->make_time_insensitive = FALSE; + dedit->priv->lower_hour = 0; + dedit->priv->upper_hour = 24; - priv->lower_hour = 0; - priv->upper_hour = 24; + dedit->priv->date_is_valid = TRUE; + dedit->priv->date_set_to_none = TRUE; + dedit->priv->time_is_valid = TRUE; + dedit->priv->time_set_to_none = TRUE; + dedit->priv->time_callback = NULL; + dedit->priv->time_callback_data = NULL; + dedit->priv->time_callback_destroy = NULL; - priv->date_is_valid = TRUE; - priv->date_set_to_none = TRUE; - priv->time_is_valid = TRUE; - priv->time_set_to_none = TRUE; - priv->time_callback = NULL; - priv->time_callback_data = NULL; - priv->time_callback_destroy = NULL; - - priv->twodigit_year_can_future = TRUE; + dedit->priv->twodigit_year_can_future = TRUE; create_children (dedit); @@ -276,6 +363,32 @@ e_date_edit_init (EDateEdit *dedit) e_date_edit_set_time (dedit, 0); } +GType +e_date_edit_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EDateEditClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) date_edit_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EDateEdit), + 0, /* n_preallocs */ + (GInstanceInitFunc) date_edit_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_HBOX, "EDateEdit", &type_info, 0); + } + + return type; +} + /** * e_date_edit_new: * @@ -472,29 +585,6 @@ create_children (EDateEdit *dedit) G_CALLBACK (on_date_popup_none_button_clicked), dedit); } -static void -e_date_edit_dispose (GObject *object) -{ - EDateEdit *dedit; - - g_return_if_fail (E_IS_DATE_EDIT (object)); - - dedit = E_DATE_EDIT (object); - - if (dedit->priv) { - e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL); - - gtk_widget_destroy (dedit->priv->cal_popup); - dedit->priv->cal_popup = NULL; - - g_free (dedit->priv); - dedit->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - /* GtkWidget::mnemonic_activate() handler for the EDateEdit */ static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget, gboolean group_cycling) @@ -647,8 +737,7 @@ e_date_edit_set_time (EDateEdit *dedit, /* Emit the signals if the date and/or time has actually changed. */ if (date_changed || time_changed) - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } /** @@ -715,8 +804,7 @@ e_date_edit_set_date (EDateEdit *dedit, /* Emit the signals if the date has actually changed. */ if (date_changed) - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } /** @@ -792,8 +880,7 @@ e_date_edit_set_time_of_day (EDateEdit *dedit, e_date_edit_update_time_entry (dedit); if (time_changed) - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } void @@ -818,8 +905,7 @@ e_date_edit_set_date_and_time_of_day (EDateEdit *dedit, e_date_edit_update_time_combo_state (dedit); if (date_changed || time_changed) - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } /** @@ -969,21 +1055,21 @@ e_date_edit_set_make_time_insensitive (EDateEdit *dedit, /** * e_date_edit_get_week_start_day: * @dedit: an #EDateEdit widget - * @Returns: the week start day, from 0 (Sunday) to 6 (Saturday). + * @Returns: the week start day, from 0 (Monday) to 6 (Sunday). * * Description: Returns the week start day currently used in the calendar * popup. */ gint -e_date_edit_get_week_start_day (EDateEdit *dedit) +e_date_edit_get_week_start_day (EDateEdit *dedit) { gint week_start_day; g_return_val_if_fail (E_IS_DATE_EDIT (dedit), 1); - g_object_get (E_CALENDAR (dedit->priv->calendar)->calitem, - "week_start_day", &week_start_day, - NULL); + g_object_get ( + E_CALENDAR (dedit->priv->calendar)->calitem, + "week_start_day", &week_start_day, NULL); return week_start_day; } @@ -991,50 +1077,54 @@ e_date_edit_get_week_start_day (EDateEdit *dedit) /** * e_date_edit_set_week_start_day: * @dedit: an #EDateEdit widget - * @week_start_day: the week start day, from 0 (Sunday) to 6 (Saturday). + * @week_start_day: the week start day, from 0 (Monday) to 6 (Sunday). * * Description: Sets the week start day to use in the calendar popup. */ void -e_date_edit_set_week_start_day (EDateEdit *dedit, - gint week_start_day) +e_date_edit_set_week_start_day (EDateEdit *dedit, + gint week_start_day) { g_return_if_fail (E_IS_DATE_EDIT (dedit)); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "week_start_day", week_start_day, - NULL); + gnome_canvas_item_set ( + GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), + "week_start_day", week_start_day, NULL); + + g_object_notify (G_OBJECT (dedit), "week-start-day"); } /* Whether we show week numbers in the date popup. */ gboolean -e_date_edit_get_show_week_numbers (EDateEdit *dedit) +e_date_edit_get_show_week_numbers (EDateEdit *dedit) { gboolean show_week_numbers; g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE); - g_object_get (E_CALENDAR (dedit->priv->calendar)->calitem, - "show_week_numbers", &show_week_numbers, - NULL); + g_object_get ( + E_CALENDAR (dedit->priv->calendar)->calitem, + "show_week_numbers", &show_week_numbers, NULL); return show_week_numbers; } void -e_date_edit_set_show_week_numbers (EDateEdit *dedit, - gboolean show_week_numbers) +e_date_edit_set_show_week_numbers (EDateEdit *dedit, + gboolean show_week_numbers) { g_return_if_fail (E_IS_DATE_EDIT (dedit)); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), - "show_week_numbers", show_week_numbers, - NULL); + gnome_canvas_item_set ( + GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem), + "show_week_numbers", show_week_numbers, NULL); + + g_object_notify (G_OBJECT (dedit), "show-week-numbers"); } /* Whether we use 24 hour format in the time field & popup. */ gboolean -e_date_edit_get_use_24_hour_format (EDateEdit *dedit) +e_date_edit_get_use_24_hour_format (EDateEdit *dedit) { g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE); @@ -1042,8 +1132,8 @@ e_date_edit_get_use_24_hour_format (EDateEdit *dedit) } void -e_date_edit_set_use_24_hour_format (EDateEdit *dedit, - gboolean use_24_hour_format) +e_date_edit_set_use_24_hour_format (EDateEdit *dedit, + gboolean use_24_hour_format) { g_return_if_fail (E_IS_DATE_EDIT (dedit)); @@ -1055,6 +1145,8 @@ e_date_edit_set_use_24_hour_format (EDateEdit *dedit, rebuild_time_popup (dedit); e_date_edit_update_time_entry (dedit); + + g_object_notify (G_OBJECT (dedit), "use-24-hour-format"); } /* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will @@ -1399,8 +1491,8 @@ rebuild_time_popup (EDateEdit *dedit) /* For 12-hour am/pm format, we want space padding, not zero padding. This * can be done with strftime's %l, but it's a potentially unportable extension. */ - if (!priv->use_24_hour_format && buffer [0] == '0') - buffer [0] = ' '; + if (!priv->use_24_hour_format && buffer[0] == '0') + buffer[0] = ' '; gtk_combo_box_append_text (combo, buffer); } @@ -1736,8 +1828,8 @@ e_date_edit_update_time_entry (EDateEdit *dedit) /* For 12-hour am/pm format, we want space padding, not zero padding. This * can be done with strftime's %l, but it's a potentially unportable extension. */ - if (!priv->use_24_hour_format && buffer [0] == '0') - buffer [0] = ' '; + if (!priv->use_24_hour_format && buffer[0] == '0') + buffer[0] = ' '; gtk_entry_set_text (GTK_ENTRY (GTK_BIN (priv->time_combo)->child), buffer); @@ -1860,8 +1952,7 @@ e_date_edit_check_date_changed (EDateEdit *dedit) tmp_tm.tm_mday); if (date_changed) - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } /* Parses the time, and if it is different from the current settings it @@ -1891,8 +1982,7 @@ e_date_edit_check_time_changed (EDateEdit *dedit) if (time_changed) { e_date_edit_update_time_entry (dedit); - g_signal_emit (dedit, - date_edit_signals [CHANGED], 0); + g_signal_emit (dedit, signals[CHANGED], 0); } } -- cgit v1.2.3 From 052e89dd423b5ba2f394f55c2fcc48102e7b9bc3 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 6 Aug 2009 17:48:45 -0400 Subject: Seal up ESignature and add GObject properties. --- widgets/misc/e-signature-combo-box.c | 6 +---- widgets/misc/e-signature-editor.c | 32 ++++++++++++++---------- widgets/misc/e-signature-manager.c | 47 +++++++++++++++++++++--------------- widgets/misc/e-signature-preview.c | 13 +++++++--- widgets/misc/e-signature-tree-view.c | 7 ++++-- 5 files changed, 61 insertions(+), 44 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c index d447cccb8e..fe4e474729 100644 --- a/widgets/misc/e-signature-combo-box.c +++ b/widgets/misc/e-signature-combo-box.c @@ -98,11 +98,7 @@ signature_combo_box_refresh_cb (ESignatureList *signature_list, const gchar *string; signature = iter->data; - - if (signature->autogen) - string = _("Autogenerated"); - else - string = signature->name; + string = e_signature_get_name (signature); gtk_list_store_append (store, &tree_iter); gtk_list_store_set ( diff --git a/widgets/misc/e-signature-editor.c b/widgets/misc/e-signature-editor.c index 53cb34906b..699216784f 100644 --- a/widgets/misc/e-signature-editor.c +++ b/widgets/misc/e-signature-editor.c @@ -124,19 +124,23 @@ action_save_and_close_cb (GtkAction *action, html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor)); if (editor->priv->signature == NULL) { + gchar *new_filename; + signature = e_signature_new (); - signature->name = g_strdup (_("Unnamed")); - signature->script = FALSE; - signature->html = html; + e_signature_set_name (signature, _("Unnamed")); + e_signature_set_is_script (signature, FALSE); + e_signature_set_is_html (signature, html); /* FIXME Pass a GError and deal with it. */ - signature->filename = e_create_signature_file (NULL); + new_filename = e_create_signature_file (NULL); + e_signature_set_filename (signature, new_filename); + g_free (new_filename); } else { signature = g_object_ref (editor->priv->signature); - signature->html = html; + e_signature_set_is_html (signature, html); } - filename = signature->filename; + filename = e_signature_get_filename (signature); gtkhtml_editor_save (GTKHTML_EDITOR (editor), filename, html, &error); if (error != NULL) { @@ -167,7 +171,7 @@ action_save_and_close_cb (GtkAction *action, * XXX ESignatureList misuses const. */ same_name = (ESignature *) e_signature_list_find ( signature_list, E_SIGNATURE_FIND_NAME, signature_name); - if (same_name != NULL && strcmp (signature->uid, same_name->uid) != 0) { + if (same_name != NULL && !e_signature_is_equal (signature, same_name)) { e_error_run ( GTK_WINDOW (editor), "mail:signature-already-exists", @@ -177,8 +181,8 @@ action_save_and_close_cb (GtkAction *action, return; } - g_free (signature->name); - signature->name = signature_name; + e_signature_set_name (signature, signature_name); + g_free (signature_name); if (editor->priv->signature != NULL) e_signature_list_change (signature_list, signature); @@ -428,6 +432,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor, { const gchar *filename; const gchar *signature_name; + gboolean is_html; gchar *contents; gsize length; GError *error = NULL; @@ -449,9 +454,10 @@ e_signature_editor_set_signature (ESignatureEditor *editor, /* Load signature content. */ - filename = signature->filename; + filename = e_signature_get_filename (signature); + is_html = e_signature_get_is_html (signature); - if (signature->html) + if (is_html) g_file_get_contents (filename, &contents, &length, &error); else { gchar *data; @@ -467,7 +473,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor, if (error == NULL) { gtkhtml_editor_set_html_mode ( - GTKHTML_EDITOR (editor), signature->html); + GTKHTML_EDITOR (editor), is_html); gtkhtml_editor_set_text_html ( GTKHTML_EDITOR (editor), contents, length); g_free (contents); @@ -478,7 +484,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor, exit: if (signature != NULL) - signature_name = signature->name; + signature_name = e_signature_get_name (signature); else signature_name = _("Unnamed"); diff --git a/widgets/misc/e-signature-manager.c b/widgets/misc/e-signature-manager.c index a70bc1dc60..7e29f75cef 100644 --- a/widgets/misc/e-signature-manager.c +++ b/widgets/misc/e-signature-manager.c @@ -92,9 +92,12 @@ signature_manager_run_script_dialog (ESignatureManager *manager, { GtkWidget *dialog; GFile *script_file; + const gchar *name; + const gchar *filename; const gchar *script_name; gboolean success = FALSE; gpointer parent; + gchar *path; parent = gtk_widget_get_toplevel (GTK_WIDGET (manager)); parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; @@ -102,10 +105,13 @@ signature_manager_run_script_dialog (ESignatureManager *manager, dialog = e_signature_script_dialog_new (parent); gtk_window_set_title (GTK_WINDOW (dialog), title); - if (signature->filename != NULL && signature->name != NULL) { + name = e_signature_get_name (signature); + filename = e_signature_get_filename (signature); - script_file = g_file_new_for_path (signature->filename); - script_name = signature->name; + if (filename != NULL && name != NULL) { + + script_file = g_file_new_for_path (filename); + script_name = name; e_signature_script_dialog_set_script_file ( E_SIGNATURE_SCRIPT_DIALOG (dialog), script_file); @@ -123,11 +129,10 @@ signature_manager_run_script_dialog (ESignatureManager *manager, script_name = e_signature_script_dialog_get_script_name ( E_SIGNATURE_SCRIPT_DIALOG (dialog)); - g_free (signature->filename); - signature->filename = g_file_get_path (script_file); - - g_free (signature->name); - signature->name = g_strdup (script_name); + path = g_file_get_path (script_file); + e_signature_set_name (signature, script_name); + e_signature_set_filename (signature, path); + g_free (path); g_object_unref (script_file); @@ -291,8 +296,8 @@ signature_manager_add_signature_script (ESignatureManager *manager) signature_list = e_signature_manager_get_signature_list (manager); signature = e_signature_new (); - signature->script = TRUE; - signature->html = TRUE; + e_signature_set_is_script (signature, TRUE); + e_signature_set_is_html (signature, TRUE); if (signature_manager_run_script_dialog (manager, signature, title)) e_signature_list_add (signature_list, signature); @@ -327,7 +332,7 @@ signature_manager_edit_signature (ESignatureManager *manager) ESignature *signature; GtkWidget *editor; const gchar *title; - gchar *filename; + const gchar *filename; tree_view = e_signature_manager_get_tree_view (manager); signature = e_signature_tree_view_get_selected (tree_view); @@ -336,15 +341,12 @@ signature_manager_edit_signature (ESignatureManager *manager) if (signature == NULL) return; - if (signature->script) + if (e_signature_get_is_script (signature)) goto script; - filename = signature->filename; - if (filename == NULL || *filename == '\0') { - g_free (filename); - filename = g_strdup (_("Unnamed")); - signature->filename = filename; - } + filename = e_signature_get_filename (signature); + if (filename == NULL || *filename == '\0') + e_signature_set_filename (signature, _("Unnamed")); editor = e_signature_editor_new (); e_signature_editor_set_signature ( @@ -373,6 +375,8 @@ signature_manager_remove_signature (ESignatureManager *manager) ESignatureTreeView *tree_view; ESignatureList *signature_list; ESignature *signature; + const gchar *filename; + gboolean is_script; tree_view = e_signature_manager_get_tree_view (manager); signature = e_signature_tree_view_get_selected (tree_view); @@ -381,8 +385,11 @@ signature_manager_remove_signature (ESignatureManager *manager) if (signature == NULL) return; - if (signature->filename != NULL && !signature->script) - g_unlink (signature->filename); + filename = e_signature_get_filename (signature); + is_script = e_signature_get_is_script (signature); + + if (filename != NULL && !is_script) + g_unlink (filename); e_signature_list_remove (signature_list, signature); e_signature_list_save (signature_list); diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c index f8e168cd5a..bbef65f39c 100644 --- a/widgets/misc/e-signature-preview.c +++ b/widgets/misc/e-signature-preview.c @@ -155,6 +155,8 @@ signature_preview_refresh (ESignaturePreview *preview) { GtkHTML *html; ESignature *signature; + const gchar *filename; + gboolean is_script; gchar *content = NULL; gsize length; @@ -166,11 +168,14 @@ signature_preview_refresh (ESignaturePreview *preview) if (signature == NULL) goto clear; - if (signature->script && !preview->priv->allow_scripts) + filename = e_signature_get_filename (signature); + is_script = e_signature_get_is_script (signature); + + if (is_script && !preview->priv->allow_scripts) goto clear; - if (signature->script) - content = e_run_signature_script (signature->filename); + if (is_script) + content = e_run_signature_script (filename); else content = e_read_signature_file (signature, FALSE, NULL); @@ -179,7 +184,7 @@ signature_preview_refresh (ESignaturePreview *preview) length = strlen (content); - if (signature->html) + if (e_signature_get_is_html (signature)) gtk_html_load_from_string (html, content, length); else { GtkHTMLStream *stream; diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c index b2cc9d6f66..5c931c8d93 100644 --- a/widgets/misc/e-signature-tree-view.c +++ b/widgets/misc/e-signature-tree-view.c @@ -89,17 +89,20 @@ signature_tree_view_refresh_cb (ESignatureList *signature_list, for (iter = list; iter != NULL; iter = iter->next) { GtkTreeRowReference *reference; GtkTreePath *path; + const gchar *name; signature = iter->data; /* Skip autogenerated signatures. */ - if (signature->autogen) + if (e_signature_get_autogenerated (signature)) continue; + name = e_signature_get_name (signature); + gtk_list_store_append (store, &tree_iter); gtk_list_store_set ( store, &tree_iter, - COLUMN_STRING, signature->name, + COLUMN_STRING, name, COLUMN_SIGNATURE, signature, -1); path = gtk_tree_model_get_path (model, &tree_iter); -- cgit v1.2.3 From cf3c80c4bd200f9a9360a77c768f0eac2281753a Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 3 Aug 2009 20:56:30 -0400 Subject: Add a FIXME comment to e-attachment.c --- widgets/misc/e-attachment.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 7735be8872..3bf05ae579 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -1729,6 +1729,8 @@ attachment_load_from_mime_part (LoadContext *load_context) g_file_info_set_attribute_string ( file_info, attribute, string); + /* FIXME This can cause Camel to block while downloading the + * MIME part in order to determine the content size. */ size = (goffset) camel_mime_part_get_content_size (mime_part); g_file_info_set_size (file_info, size); -- cgit v1.2.3 From cdd06c393d2c6dd0b5716a354aecc92c8457dc4d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Jul 2009 20:55:30 +0200 Subject: Compiler warning fixes (as part of bug #424078) --- widgets/misc/e-attachment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 3bf05ae579..e1afb45246 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -2250,7 +2250,7 @@ attachment_save_new_candidate (SaveContext *save_context) GFile *candidate; GFileInfo *file_info; EAttachment *attachment; - const gchar *display_name; + const gchar *display_name = NULL; gchar *basename; attachment = save_context->attachment; -- cgit v1.2.3 From f22e25d7352235c187059c4180c084cae3a28b74 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 3 Aug 2009 20:42:45 +0200 Subject: Bug #580895 - Kill libgnomeui/gnome-thumbnail.h --- widgets/misc/e-attachment.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index e1afb45246..7d8984dba0 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -31,7 +31,11 @@ #include #include #include +#include +#include + +#include "e-util/e-icon-factory.h" #include "e-util/e-util.h" #include "e-util/e-mktemp.h" #include "e-attachment-store.h" @@ -99,6 +103,48 @@ enum { static gpointer parent_class; +static gboolean +create_system_thumbnail (EAttachment *attachment, GIcon **icon) +{ + GFile *file; + gchar *thumbnail = NULL; + + g_return_val_if_fail (attachment != NULL, FALSE); + g_return_val_if_fail (icon != NULL, FALSE); + + file = e_attachment_get_file (attachment); + + if (file && g_file_has_uri_scheme (file, "file")) { + gchar *path = g_file_get_path (file); + if (path) { + thumbnail = e_icon_factory_create_thumbnail (path); + g_free (path); + } + } + + if (thumbnail) { + GFile *gf = g_file_new_for_path (thumbnail); + + g_return_val_if_fail (gf != NULL, FALSE); + if (*icon) + g_object_unref (*icon); + + *icon = g_file_icon_new (gf); + g_object_unref (gf); + + if (file) { + GFileInfo *fi = e_attachment_get_file_info (attachment); + + if (fi) + g_file_info_set_attribute_byte_string (fi, G_FILE_ATTRIBUTE_THUMBNAIL_PATH, thumbnail); + } + } + + g_free (thumbnail); + + return thumbnail != NULL; +} + static gchar * attachment_get_default_charset (void) { @@ -229,6 +275,10 @@ attachment_update_icon_column (EAttachment *attachment) icon = g_file_icon_new (file); g_object_unref (file); + /* try the system thumbnailer */ + } else if (create_system_thumbnail (attachment, &icon)) { + /* actually do nothing, just use the icon */ + /* Else use the standard icon for the content type. */ } else if (icon != NULL) g_object_ref (icon); -- cgit v1.2.3 From 672adf12a0923437e90d08ab7925bd9329fcce0d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 16 Aug 2009 11:25:08 -0400 Subject: Fix compiler warnings and deprecated GTK+ API usage. --- widgets/misc/e-attachment-button.c | 6 +++--- widgets/misc/e-menu-tool-button.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c index d64dcafb4a..1cd517d3e2 100644 --- a/widgets/misc/e-attachment-button.c +++ b/widgets/misc/e-attachment-button.c @@ -199,7 +199,7 @@ exit: static void attachment_button_update_pixbufs (EAttachmentButton *button) { - GtkCellView *cell_view; + GtkCellLayout *cell_layout; GtkCellRenderer *renderer; GtkIconTheme *icon_theme; GdkPixbuf *pixbuf_expander_open; @@ -209,8 +209,8 @@ attachment_button_update_pixbufs (EAttachmentButton *button) icon_theme = gtk_icon_theme_get_default (); /* Grab the first cell renderer. */ - cell_view = GTK_CELL_VIEW (button->priv->cell_view); - list = gtk_cell_view_get_cell_renderers (cell_view); + cell_layout = GTK_CELL_LAYOUT (button->priv->cell_view); + list = gtk_cell_layout_get_cells (cell_layout); renderer = GTK_CELL_RENDERER (list->data); g_list_free (list); diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c index 53778e6678..58c8317053 100644 --- a/widgets/misc/e-menu-tool-button.c +++ b/widgets/misc/e-menu-tool-button.c @@ -84,7 +84,8 @@ menu_tool_button_update_button (GtkToolButton *tool_button) /* If the menu item is a proxy for a GtkAction, extract * the action's tooltip and use it as our own tooltip. */ - action = gtk_widget_get_action (GTK_WIDGET (menu_item)); + action = gtk_activatable_get_related_action ( + GTK_ACTIVATABLE (menu_item)); if (action != NULL) g_object_get (action, "tooltip", &tooltip, NULL); gtk_widget_set_tooltip_text (GTK_WIDGET (tool_button), tooltip); -- cgit v1.2.3 From 2a8e2030e46b63a9cac0cd5d3017fd9d73a57407 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 16 Aug 2009 12:36:13 -0400 Subject: Chip away at GSEAL compliance. --- widgets/misc/e-calendar.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index fd17c67aab..e9aacfa8b9 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -241,12 +241,16 @@ e_calendar_destroy (GtkObject *object) static void e_calendar_realize (GtkWidget *widget) { + GtkStyle *style; + GdkWindow *window; + (*GTK_WIDGET_CLASS (e_calendar_parent_class)->realize) (widget); /* Set the background of the canvas window to the normal color, or the arrow buttons are not displayed properly. */ - gdk_window_set_background (GTK_LAYOUT (widget)->bin_window, - &widget->style->bg[GTK_STATE_NORMAL]); + style = gtk_widget_get_style (widget); + window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); + gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]); } static void @@ -254,6 +258,7 @@ e_calendar_style_set (GtkWidget *widget, GtkStyle *previous_style) { ECalendar *e_calendar; + GtkWidget *parent; e_calendar = E_CALENDAR(widget); if (GTK_WIDGET_CLASS (e_calendar_parent_class)->style_set) @@ -262,9 +267,15 @@ e_calendar_style_set (GtkWidget *widget, /* Set the background of the canvas window to the normal color, or the arrow buttons are not displayed properly. */ - if (GTK_WIDGET_REALIZED (widget->parent)) - gdk_window_set_background (GTK_LAYOUT (widget)->bin_window, - &widget->style->bg[GTK_STATE_NORMAL]); + parent = gtk_widget_get_parent (widget); + if (GTK_WIDGET_REALIZED (parent)) { + GtkStyle *style; + GdkWindow *window; + + style = gtk_widget_get_style (widget); + window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); + gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]); + } e_calendar_item_style_set (widget, e_calendar->calitem); } @@ -277,7 +288,7 @@ e_calendar_size_request (GtkWidget *widget, gint col_width, row_height, width, height; cal = E_CALENDAR (widget); - style = GTK_WIDGET (cal)->style; + style = gtk_widget_get_style (GTK_WIDGET (cal)); g_object_get((cal->calitem), "row_height", &row_height, @@ -296,6 +307,7 @@ e_calendar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { ECalendar *cal; + GtkStyle *style; PangoFontDescription *font_desc; PangoContext *pango_context; PangoFontMetrics *font_metrics; @@ -303,8 +315,9 @@ e_calendar_size_allocate (GtkWidget *widget, gdouble xthickness, ythickness, arrow_button_size; cal = E_CALENDAR (widget); - xthickness = widget->style->xthickness; - ythickness = widget->style->ythickness; + style = gtk_widget_get_style (widget); + xthickness = style->xthickness; + ythickness = style->ythickness; (*GTK_WIDGET_CLASS (e_calendar_parent_class)->size_allocate) (widget, allocation); @@ -412,7 +425,7 @@ e_calendar_get_border_size (ECalendar *cal, g_return_if_fail (E_IS_CALENDAR (cal)); - style = GTK_WIDGET (cal)->style; + style = gtk_widget_get_style (GTK_WIDGET (cal)); if (style) { *top = style->ythickness; -- cgit v1.2.3 From 452650a573432a6416f3f31ec0594b888a52b93f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 24 Aug 2009 23:35:46 -0400 Subject: Bug 359909 - "New" Button too small --- widgets/misc/e-menu-tool-button.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c index 58c8317053..fcf73d6c4e 100644 --- a/widgets/misc/e-menu-tool-button.c +++ b/widgets/misc/e-menu-tool-button.c @@ -92,6 +92,27 @@ menu_tool_button_update_button (GtkToolButton *tool_button) g_free (tooltip); } +static void +menu_tool_button_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + gint minimum_width; + + /* Chain up to parent's size_request() method. */ + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); + + /* XXX This is a hack. This widget is only used for the New + * button in the main window toolbar. The New button is + * pretty important, but the word "New" is pretty short + * (in English, anyway) and this results in a small screen + * target when using a "text below item" toolbar style. + * + * We can't go hard-coding a width, but we -can- use a + * heuristic based on the toolbar button height. */ + minimum_width = requisition->height * 2; + requisition->width = MAX (minimum_width, requisition->width); +} + static void menu_tool_button_clicked (GtkToolButton *tool_button) { @@ -108,10 +129,14 @@ menu_tool_button_clicked (GtkToolButton *tool_button) static void menu_tool_button_class_init (EMenuToolButtonClass *class) { + GtkWidgetClass *widget_class; GtkToolButtonClass *tool_button_class; parent_class = g_type_class_peek_parent (class); + widget_class = GTK_WIDGET_CLASS (class); + widget_class->size_request = menu_tool_button_size_request; + tool_button_class = GTK_TOOL_BUTTON_CLASS (class); tool_button_class->clicked = menu_tool_button_clicked; } -- cgit v1.2.3 From 473f8dca644b3f9f48529daeed44de2097ee311d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 25 Aug 2009 00:09:45 -0400 Subject: Bug 511769 - Poor indication of when network is unavailable --- widgets/misc/e-online-button.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c index c14114b9c3..444296dcef 100644 --- a/widgets/misc/e-online-button.c +++ b/widgets/misc/e-online-button.c @@ -24,10 +24,13 @@ ((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate)) #define ONLINE_TOOLTIP \ - "Evolution is currently online. Click this button to work offline." + _("Evolution is currently online. Click this button to work offline.") #define OFFLINE_TOOLTIP \ - "Evolution is currently offline. Click this button to work online." + _("Evolution is currently offline. Click this button to work online.") + +#define NETWORK_UNAVAILABLE_TOOLTIP \ + _("Evolution is currently offline because the network is unavailable.") struct _EOnlineButtonPrivate { GtkWidget *image; @@ -41,6 +44,21 @@ enum { static gpointer parent_class; +static void +online_button_update_tooltip (EOnlineButton *button) +{ + const gchar *tooltip; + + if (e_online_button_get_online (button)) + tooltip = ONLINE_TOOLTIP; + else if (GTK_WIDGET_SENSITIVE (button)) + tooltip = OFFLINE_TOOLTIP; + else + tooltip = NETWORK_UNAVAILABLE_TOOLTIP; + + gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip); +} + static void online_button_set_property (GObject *object, guint property_id, @@ -130,6 +148,14 @@ online_button_init (EOnlineButton *button) gtk_container_add (GTK_CONTAINER (button), widget); button->priv->image = g_object_ref (widget); gtk_widget_show (widget); + + g_signal_connect ( + button, "notify::online", + G_CALLBACK (online_button_update_tooltip), NULL); + + g_signal_connect ( + button, "notify::sensitive", + G_CALLBACK (online_button_update_tooltip), NULL); } GType @@ -181,7 +207,6 @@ e_online_button_set_online (EOnlineButton *button, GtkIconTheme *icon_theme; const gchar *filename; const gchar *icon_name; - const gchar *tooltip; g_return_if_fail (E_IS_ONLINE_BUTTON (button)); @@ -198,8 +223,5 @@ e_online_button_set_online (EOnlineButton *button, gtk_image_set_from_file (image, filename); gtk_icon_info_free (icon_info); - tooltip = _(online ? ONLINE_TOOLTIP : OFFLINE_TOOLTIP); - gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip); - g_object_notify (G_OBJECT (button), "online"); } -- cgit v1.2.3 From 54568ac94cd317d0bcc40cc6b12758ce641ddfaa Mon Sep 17 00:00:00 2001 From: Kjartan Maraas Date: Wed, 26 Aug 2009 21:51:35 +0200 Subject: Fix return types to match the type of function --- widgets/misc/e-attachment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 7d8984dba0..85979679c5 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -2658,8 +2658,8 @@ e_attachment_save_finish (EAttachment *attachment, GSimpleAsyncResult *simple; GFile *destination; - g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); simple = G_SIMPLE_ASYNC_RESULT (result); destination = g_simple_async_result_get_op_res_gpointer (simple); -- cgit v1.2.3 From 0e1066b431b3d172c18b7be8744875942515e117 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 26 Aug 2009 23:46:56 -0400 Subject: Add EPaned widget to generalize vertical view. --- widgets/misc/Makefile.am | 2 + widgets/misc/e-paned.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++ widgets/misc/e-paned.h | 75 +++++++++++ 3 files changed, 421 insertions(+) create mode 100644 widgets/misc/e-paned.c create mode 100644 widgets/misc/e-paned.h (limited to 'widgets/misc') diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index ebd5562c30..29607758e5 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -67,6 +67,7 @@ widgetsinclude_HEADERS = \ e-map.h \ e-menu-tool-button.h \ e-online-button.h \ + e-paned.h \ e-popup-action.h \ e-popup-menu.h \ e-preferences-window.h \ @@ -130,6 +131,7 @@ libemiscwidgets_la_SOURCES = \ e-map.c \ e-menu-tool-button.c \ e-online-button.c \ + e-paned.c \ e-popup-action.c \ e-popup-menu.c \ e-preferences-window.c \ diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c new file mode 100644 index 0000000000..350042413a --- /dev/null +++ b/widgets/misc/e-paned.c @@ -0,0 +1,344 @@ +/* + * e-paned.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-paned.h" + +#include +#include + +#define E_PANED_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_PANED, EPanedPrivate)) + +struct _EPanedPrivate { + gint hposition; + gint vposition; + + guint sync_position : 1; +}; + +enum { + PROP_0, + PROP_HPOSITION, + PROP_VPOSITION, + PROP_VERTICAL_VIEW +}; + +static gpointer parent_class; + +static void +paned_notify_orientation_cb (EPaned *paned) +{ + paned->priv->sync_position = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (paned)); + + g_object_notify (G_OBJECT (paned), "vertical-view"); +} + +static void +paned_notify_position_cb (EPaned *paned) +{ + GtkAllocation *allocation; + gint position; + + if (paned->priv->sync_position) + return; + + allocation = >K_WIDGET (paned)->allocation; + position = gtk_paned_get_position (GTK_PANED (paned)); + + if (e_paned_get_vertical_view (paned)) { + position = MAX (0, allocation->width - position); + e_paned_set_hposition (paned, position); + } else { + position = MAX (0, allocation->height - position); + e_paned_set_vposition (paned, position); + } +} + +static void +paned_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_HPOSITION: + e_paned_set_hposition ( + E_PANED (object), + g_value_get_int (value)); + return; + + case PROP_VPOSITION: + e_paned_set_vposition ( + E_PANED (object), + g_value_get_int (value)); + return; + + case PROP_VERTICAL_VIEW: + e_paned_set_vertical_view ( + E_PANED (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +paned_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_HPOSITION: + g_value_set_int ( + value, e_paned_get_hposition ( + E_PANED (object))); + return; + + case PROP_VPOSITION: + g_value_set_int ( + value, e_paned_get_vposition ( + E_PANED (object))); + return; + + case PROP_VERTICAL_VIEW: + g_value_set_boolean ( + value, e_paned_get_vertical_view ( + E_PANED (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +paned_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + EPaned *paned = E_PANED (widget); + gint allocated; + gint position; + + /* Chain up to parent's size_allocate() method. */ + GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); + + if (!paned->priv->sync_position) + return; + + if (e_paned_get_vertical_view (paned)) { + allocated = allocation->width; + position = e_paned_get_hposition (paned); + } else { + allocated = allocation->height; + position = e_paned_get_vposition (paned); + } + + position = MAX (0, allocated - position); + gtk_paned_set_position (GTK_PANED (paned), position); + + paned->priv->sync_position = FALSE; +} + +static void +paned_class_init (EPanedClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EPanedPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = paned_set_property; + object_class->get_property = paned_get_property; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->size_allocate = paned_size_allocate; + + g_object_class_install_property ( + object_class, + PROP_HPOSITION, + g_param_spec_int ( + "hposition", + _("Horizontal Position"), + _("Pane position when oriented horizontally"), + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_VPOSITION, + g_param_spec_int ( + "vposition", + _("Vertical Position"), + _("Pane position when oriented vertically"), + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_VERTICAL_VIEW, + g_param_spec_boolean ( + "vertical-view", + _("Vertical View"), + _("Whether vertical view is enabled"), + FALSE, + G_PARAM_READWRITE)); +} + +static void +paned_init (EPaned *paned) +{ + paned->priv = E_PANED_GET_PRIVATE (paned); + + g_signal_connect ( + paned, "notify::orientation", + G_CALLBACK (paned_notify_orientation_cb), NULL); + + g_signal_connect ( + paned, "notify::position", + G_CALLBACK (paned_notify_position_cb), NULL); +} + +GType +e_paned_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EPanedClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) paned_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EPaned), + 0, /* n_preallocs */ + (GInstanceInitFunc) paned_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_PANED, "EPaned", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_paned_new (GtkOrientation orientation) +{ + return g_object_new (E_TYPE_PANED, "orientation", orientation, NULL); +} + +gint +e_paned_get_hposition (EPaned *paned) +{ + g_return_val_if_fail (E_IS_PANED (paned), 0); + + return paned->priv->hposition; +} + +void +e_paned_set_hposition (EPaned *paned, + gint hposition) +{ + g_return_if_fail (E_IS_PANED (paned)); + + if (hposition == paned->priv->hposition) + return; + + paned->priv->hposition = hposition; + + g_object_notify (G_OBJECT (paned), "hposition"); + + if (e_paned_get_vertical_view (paned)) { + paned->priv->sync_position = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (paned)); + } +} + +gint +e_paned_get_vposition (EPaned *paned) +{ + g_return_val_if_fail (E_IS_PANED (paned), 0); + + return paned->priv->vposition; +} + +void +e_paned_set_vposition (EPaned *paned, + gint vposition) +{ + g_return_if_fail (E_IS_PANED (paned)); + + if (vposition == paned->priv->vposition) + return; + + paned->priv->vposition = vposition; + + g_object_notify (G_OBJECT (paned), "vposition"); + + if (!e_paned_get_vertical_view (paned)) { + paned->priv->sync_position = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (paned)); + } +} + +gboolean +e_paned_get_vertical_view (EPaned *paned) +{ + GtkOrientable *orientable; + GtkOrientation orientation; + + g_return_val_if_fail (E_IS_PANED (paned), FALSE); + + orientable = GTK_ORIENTABLE (paned); + orientation = gtk_orientable_get_orientation (orientable); + + return (orientation == GTK_ORIENTATION_HORIZONTAL); +} + +void +e_paned_set_vertical_view (EPaned *paned, + gboolean vertical_view) +{ + GtkOrientable *orientable; + GtkOrientation orientation; + + g_return_if_fail (E_IS_PANED (paned)); + + if (vertical_view) + orientation = GTK_ORIENTATION_HORIZONTAL; + else + orientation = GTK_ORIENTATION_VERTICAL; + + orientable = GTK_ORIENTABLE (paned); + gtk_orientable_set_orientation (orientable, orientation); +} diff --git a/widgets/misc/e-paned.h b/widgets/misc/e-paned.h new file mode 100644 index 0000000000..ea37cbab21 --- /dev/null +++ b/widgets/misc/e-paned.h @@ -0,0 +1,75 @@ +/* + * e-paned.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 + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_PANED_H +#define E_PANED_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_PANED \ + (e_paned_get_type ()) +#define E_PANED(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_PANED, EPaned)) +#define E_PANED_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_PANED, EPanedClass)) +#define E_IS_PANED(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_PANED)) +#define E_IS_PANED_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_PANED)) +#define E_PANED_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_PANED, EPanedClass)) + +G_BEGIN_DECLS + +typedef struct _EPaned EPaned; +typedef struct _EPanedClass EPanedClass; +typedef struct _EPanedPrivate EPanedPrivate; + +struct _EPaned { + GtkPaned parent; + EPanedPrivate *priv; +}; + +struct _EPanedClass { + GtkPanedClass parent_class; +}; + +GType e_paned_get_type (void); +GtkWidget * e_paned_new (GtkOrientation orientation); +gint e_paned_get_hposition (EPaned *paned); +void e_paned_set_hposition (EPaned *paned, + gint hposition); +gint e_paned_get_vposition (EPaned *paned); +void e_paned_set_vposition (EPaned *paned, + gint vposition); +gboolean e_paned_get_vertical_view (EPaned *paned); +void e_paned_set_vertical_view (EPaned *paned, + gboolean vertical_view); + +G_END_DECLS + +#endif /* E_PANED_H */ -- cgit v1.2.3 From 7dc82b2dcbab7f85504c3061ef45cc4249821e42 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 27 Aug 2009 13:38:17 -0400 Subject: Add vertical view to Memos and Tasks. --- widgets/misc/e-paned.c | 1 + 1 file changed, 1 insertion(+) (limited to 'widgets/misc') diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c index 350042413a..2c8a1820d7 100644 --- a/widgets/misc/e-paned.c +++ b/widgets/misc/e-paned.c @@ -47,6 +47,7 @@ static gpointer parent_class; static void paned_notify_orientation_cb (EPaned *paned) { + /* Ignore the next "notify::position" emission. */ paned->priv->sync_position = TRUE; gtk_widget_queue_resize (GTK_WIDGET (paned)); -- cgit v1.2.3 From 0fda8cb5a28729724c678c4e379c12a79f1e820e Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 27 Aug 2009 14:42:36 -0400 Subject: Remove redundant "vertical view" functions. --- widgets/misc/e-paned.c | 89 +++++++++++++++----------------------------------- widgets/misc/e-paned.h | 3 -- 2 files changed, 27 insertions(+), 65 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c index 2c8a1820d7..51f8dbfa1c 100644 --- a/widgets/misc/e-paned.c +++ b/widgets/misc/e-paned.c @@ -38,8 +38,7 @@ struct _EPanedPrivate { enum { PROP_0, PROP_HPOSITION, - PROP_VPOSITION, - PROP_VERTICAL_VIEW + PROP_VPOSITION }; static gpointer parent_class; @@ -50,23 +49,26 @@ paned_notify_orientation_cb (EPaned *paned) /* Ignore the next "notify::position" emission. */ paned->priv->sync_position = TRUE; gtk_widget_queue_resize (GTK_WIDGET (paned)); - - g_object_notify (G_OBJECT (paned), "vertical-view"); } static void paned_notify_position_cb (EPaned *paned) { GtkAllocation *allocation; + GtkOrientable *orientable; + GtkOrientation orientation; gint position; if (paned->priv->sync_position) return; + orientable = GTK_ORIENTABLE (paned); + orientation = gtk_orientable_get_orientation (orientable); + allocation = >K_WIDGET (paned)->allocation; position = gtk_paned_get_position (GTK_PANED (paned)); - if (e_paned_get_vertical_view (paned)) { + if (orientation == GTK_ORIENTATION_HORIZONTAL) { position = MAX (0, allocation->width - position); e_paned_set_hposition (paned, position); } else { @@ -93,12 +95,6 @@ paned_set_property (GObject *object, E_PANED (object), g_value_get_int (value)); return; - - case PROP_VERTICAL_VIEW: - e_paned_set_vertical_view ( - E_PANED (object), - g_value_get_boolean (value)); - return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -122,12 +118,6 @@ paned_get_property (GObject *object, value, e_paned_get_vposition ( E_PANED (object))); return; - - case PROP_VERTICAL_VIEW: - g_value_set_boolean ( - value, e_paned_get_vertical_view ( - E_PANED (object))); - return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -138,6 +128,8 @@ paned_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { EPaned *paned = E_PANED (widget); + GtkOrientable *orientable; + GtkOrientation orientation; gint allocated; gint position; @@ -147,7 +139,10 @@ paned_size_allocate (GtkWidget *widget, if (!paned->priv->sync_position) return; - if (e_paned_get_vertical_view (paned)) { + orientable = GTK_ORIENTABLE (paned); + orientation = gtk_orientable_get_orientation (orientable); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { allocated = allocation->width; position = e_paned_get_hposition (paned); } else { @@ -200,16 +195,6 @@ paned_class_init (EPanedClass *class) G_MAXINT, 0, G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_VERTICAL_VIEW, - g_param_spec_boolean ( - "vertical-view", - _("Vertical View"), - _("Whether vertical view is enabled"), - FALSE, - G_PARAM_READWRITE)); } static void @@ -270,6 +255,9 @@ void e_paned_set_hposition (EPaned *paned, gint hposition) { + GtkOrientable *orientable; + GtkOrientation orientation; + g_return_if_fail (E_IS_PANED (paned)); if (hposition == paned->priv->hposition) @@ -279,7 +267,10 @@ e_paned_set_hposition (EPaned *paned, g_object_notify (G_OBJECT (paned), "hposition"); - if (e_paned_get_vertical_view (paned)) { + orientable = GTK_ORIENTABLE (paned); + orientation = gtk_orientable_get_orientation (orientable); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { paned->priv->sync_position = TRUE; gtk_widget_queue_resize (GTK_WIDGET (paned)); } @@ -297,6 +288,9 @@ void e_paned_set_vposition (EPaned *paned, gint vposition) { + GtkOrientable *orientable; + GtkOrientation orientation; + g_return_if_fail (E_IS_PANED (paned)); if (vposition == paned->priv->vposition) @@ -306,40 +300,11 @@ e_paned_set_vposition (EPaned *paned, g_object_notify (G_OBJECT (paned), "vposition"); - if (!e_paned_get_vertical_view (paned)) { - paned->priv->sync_position = TRUE; - gtk_widget_queue_resize (GTK_WIDGET (paned)); - } -} - -gboolean -e_paned_get_vertical_view (EPaned *paned) -{ - GtkOrientable *orientable; - GtkOrientation orientation; - - g_return_val_if_fail (E_IS_PANED (paned), FALSE); - orientable = GTK_ORIENTABLE (paned); orientation = gtk_orientable_get_orientation (orientable); - return (orientation == GTK_ORIENTATION_HORIZONTAL); -} - -void -e_paned_set_vertical_view (EPaned *paned, - gboolean vertical_view) -{ - GtkOrientable *orientable; - GtkOrientation orientation; - - g_return_if_fail (E_IS_PANED (paned)); - - if (vertical_view) - orientation = GTK_ORIENTATION_HORIZONTAL; - else - orientation = GTK_ORIENTATION_VERTICAL; - - orientable = GTK_ORIENTABLE (paned); - gtk_orientable_set_orientation (orientable, orientation); + if (orientation == GTK_ORIENTATION_VERTICAL) { + paned->priv->sync_position = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (paned)); + } } diff --git a/widgets/misc/e-paned.h b/widgets/misc/e-paned.h index ea37cbab21..8bd1c22024 100644 --- a/widgets/misc/e-paned.h +++ b/widgets/misc/e-paned.h @@ -66,9 +66,6 @@ void e_paned_set_hposition (EPaned *paned, gint e_paned_get_vposition (EPaned *paned); void e_paned_set_vposition (EPaned *paned, gint vposition); -gboolean e_paned_get_vertical_view (EPaned *paned); -void e_paned_set_vertical_view (EPaned *paned, - gboolean vertical_view); G_END_DECLS -- cgit v1.2.3 From 0f7f4cfe38b3c4cd83efbe9922ae15c5aee00317 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 30 Aug 2009 00:48:57 -0400 Subject: Coding style and whitespace cleanup. --- widgets/misc/e-attachment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 85979679c5..44bf29c202 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -108,7 +108,7 @@ create_system_thumbnail (EAttachment *attachment, GIcon **icon) { GFile *file; gchar *thumbnail = NULL; - + g_return_val_if_fail (attachment != NULL, FALSE); g_return_val_if_fail (icon != NULL, FALSE); -- cgit v1.2.3