diff options
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/misc/Makefile.am | 4 | ||||
-rw-r--r-- | widgets/misc/e-focus-tracker.c | 859 | ||||
-rw-r--r-- | widgets/misc/e-focus-tracker.h | 99 | ||||
-rw-r--r-- | widgets/misc/e-selectable.c | 133 | ||||
-rw-r--r-- | widgets/misc/e-selectable.h | 76 | ||||
-rw-r--r-- | widgets/misc/e-signature-editor.c | 64 | ||||
-rw-r--r-- | widgets/misc/e-signature-editor.h | 3 | ||||
-rw-r--r-- | widgets/misc/e-web-view.c | 78 | ||||
-rw-r--r-- | widgets/misc/e-web-view.h | 2 | ||||
-rw-r--r-- | widgets/table/e-table.c | 10 | ||||
-rw-r--r-- | widgets/table/e-tree.c | 9 |
11 files changed, 1322 insertions, 15 deletions
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 33b9311d90..aa29f406df 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -46,6 +46,7 @@ widgetsinclude_HEADERS = \ e-colors.h \ e-combo-cell-editable.h \ e-dateedit.h \ + e-focus-tracker.h \ e-gui-utils.h \ e-hinted-entry.h \ e-hsv-utils.h \ @@ -60,6 +61,7 @@ widgetsinclude_HEADERS = \ e-popup-menu.h \ e-preferences-window.h \ e-printable.h \ + e-selectable.h \ e-selection-model.h \ e-selection-model-array.h \ e-selection-model-simple.h \ @@ -121,6 +123,7 @@ libemiscwidgets_la_SOURCES = \ e-colors.c \ e-combo-cell-editable.c \ e-dateedit.c \ + e-focus-tracker.c \ e-gui-utils.c \ e-hinted-entry.c \ e-hsv-utils.c \ @@ -135,6 +138,7 @@ libemiscwidgets_la_SOURCES = \ e-popup-menu.c \ e-preferences-window.c \ e-printable.c \ + e-selectable.c \ e-selection-model.c \ e-selection-model-array.c \ e-selection-model-simple.c \ diff --git a/widgets/misc/e-focus-tracker.c b/widgets/misc/e-focus-tracker.c new file mode 100644 index 0000000000..d1cb32adde --- /dev/null +++ b/widgets/misc/e-focus-tracker.c @@ -0,0 +1,859 @@ +/* + * e-focus-tracker.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-focus-tracker.h" + +#include <config.h> +#include <glib/gi18n-lib.h> + +#include <misc/e-selectable.h> + +#define E_FOCUS_TRACKER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_FOCUS_TRACKER, EFocusTrackerPrivate)) + +struct _EFocusTrackerPrivate { + GtkWidget *focus; /* not referenced */ + GtkWindow *window; + + GtkAction *cut_clipboard; + GtkAction *copy_clipboard; + GtkAction *paste_clipboard; + GtkAction *delete_selection; + GtkAction *select_all; +}; + +enum { + PROP_0, + PROP_FOCUS, + PROP_WINDOW, + PROP_CUT_CLIPBOARD_ACTION, + PROP_COPY_CLIPBOARD_ACTION, + PROP_PASTE_CLIPBOARD_ACTION, + PROP_DELETE_SELECTION_ACTION, + PROP_SELECT_ALL_ACTION +}; + +static gpointer parent_class; + +static void +focus_tracker_disable_actions (EFocusTracker *focus_tracker) +{ + GtkAction *action; + + action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); + if (action != NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); + if (action != NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); + if (action != NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_delete_selection_action (focus_tracker); + if (action != NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_select_all_action (focus_tracker); + if (action != NULL) + gtk_action_set_sensitive (action, FALSE); +} + +static void +focus_tracker_editable_update_actions (EFocusTracker *focus_tracker, + GtkEditable *editable, + GdkAtom *targets, + gint n_targets) +{ + GtkAction *action; + gboolean can_edit_text; + gboolean clipboard_has_text; + gboolean text_is_selected; + gboolean sensitive; + + can_edit_text = + gtk_editable_get_editable (editable); + + clipboard_has_text = (targets != NULL) && + gtk_targets_include_text (targets, n_targets); + + text_is_selected = + gtk_editable_get_selection_bounds (editable, NULL, NULL); + + action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); + if (action != NULL) { + sensitive = can_edit_text && text_is_selected; + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, _("Cut the selection")); + } + + action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); + if (action != NULL) { + sensitive = text_is_selected; + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, _("Copy the selection")); + } + + action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); + if (action != NULL) { + sensitive = can_edit_text && clipboard_has_text; + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, _("Paste the clipboard")); + } + + action = e_focus_tracker_get_delete_selection_action (focus_tracker); + if (action != NULL) { + sensitive = can_edit_text && text_is_selected; + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, _("Delete the selection")); + } + + action = e_focus_tracker_get_select_all_action (focus_tracker); + if (action != NULL) { + sensitive = TRUE; /* always enabled */ + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, _("Select all text")); + } +} + +static void +focus_tracker_selectable_update_actions (EFocusTracker *focus_tracker, + ESelectable *selectable, + GdkAtom *targets, + gint n_targets) +{ + ESelectableInterface *interface; + GtkAction *action; + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + e_selectable_update_actions ( + selectable, focus_tracker, targets, n_targets); + + /* Disable actions for which the corresponding method is not + * implemented. This allows update_actions() implementations + * to simply skip the actions they don't support, which in turn + * allows us to add new actions without disturbing the existing + * ESelectable implementations. */ + + action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); + if (action != NULL && interface->cut_clipboard == NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); + if (action != NULL && interface->copy_clipboard == NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); + if (action != NULL && interface->paste_clipboard == NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_delete_selection_action (focus_tracker); + if (action != NULL && interface->delete_selection == NULL) + gtk_action_set_sensitive (action, FALSE); + + action = e_focus_tracker_get_select_all_action (focus_tracker); + if (action != NULL && interface->select_all == NULL) + gtk_action_set_sensitive (action, FALSE); +} + +static void +focus_tracker_targets_received_cb (GtkClipboard *clipboard, + GdkAtom *targets, + gint n_targets, + EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (focus == NULL) + focus_tracker_disable_actions (focus_tracker); + + else if (GTK_IS_EDITABLE (focus)) + focus_tracker_editable_update_actions ( + focus_tracker, GTK_EDITABLE (focus), + targets, n_targets); + + else if (E_IS_SELECTABLE (focus)) + focus_tracker_selectable_update_actions ( + focus_tracker, E_SELECTABLE (focus), + targets, n_targets); + + g_object_unref (focus_tracker); +} + +static void +focus_tracker_set_focus_cb (GtkWindow *window, + GtkWidget *focus, + EFocusTracker *focus_tracker) +{ + while (focus != NULL) { + if (GTK_IS_EDITABLE (focus)) + break; + + if (E_IS_SELECTABLE (focus)) + break; + + focus = gtk_widget_get_parent (focus); + } + + if (focus == focus_tracker->priv->focus) + return; + + focus_tracker->priv->focus = focus; + g_object_notify (G_OBJECT (focus_tracker), "focus"); + + e_focus_tracker_update_actions (focus_tracker); +} + +static void +focus_tracker_set_window (EFocusTracker *focus_tracker, + GtkWindow *window) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (focus_tracker->priv->window == NULL); + + focus_tracker->priv->window = g_object_ref (window); + + g_signal_connect ( + window, "set-focus", + G_CALLBACK (focus_tracker_set_focus_cb), focus_tracker); +} + +static void +focus_tracker_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_WINDOW: + focus_tracker_set_window ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + + case PROP_CUT_CLIPBOARD_ACTION: + e_focus_tracker_set_cut_clipboard_action ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + + case PROP_COPY_CLIPBOARD_ACTION: + e_focus_tracker_set_copy_clipboard_action ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + + case PROP_PASTE_CLIPBOARD_ACTION: + e_focus_tracker_set_paste_clipboard_action ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + + case PROP_DELETE_SELECTION_ACTION: + e_focus_tracker_set_delete_selection_action ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + + case PROP_SELECT_ALL_ACTION: + e_focus_tracker_set_select_all_action ( + E_FOCUS_TRACKER (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +focus_tracker_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_FOCUS: + g_value_set_object ( + value, + e_focus_tracker_get_focus ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_WINDOW: + g_value_set_object ( + value, + e_focus_tracker_get_window ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_CUT_CLIPBOARD_ACTION: + g_value_set_object ( + value, + e_focus_tracker_get_cut_clipboard_action ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_COPY_CLIPBOARD_ACTION: + g_value_set_object ( + value, + e_focus_tracker_get_copy_clipboard_action ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_PASTE_CLIPBOARD_ACTION: + g_value_set_object ( + value, + e_focus_tracker_get_paste_clipboard_action ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_DELETE_SELECTION_ACTION: + g_value_set_object ( + value, + e_focus_tracker_get_delete_selection_action ( + E_FOCUS_TRACKER (object))); + return; + + case PROP_SELECT_ALL_ACTION: + g_value_set_object ( + value, + e_focus_tracker_get_select_all_action ( + E_FOCUS_TRACKER (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +focus_tracker_dispose (GObject *object) +{ + EFocusTrackerPrivate *priv; + + priv = E_FOCUS_TRACKER_GET_PRIVATE (object); + + g_signal_handlers_disconnect_matched ( + gtk_clipboard_get (GDK_SELECTION_PRIMARY), + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, object); + + if (priv->window != NULL) { + g_signal_handlers_disconnect_matched ( + priv->window, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->window); + priv->window = NULL; + } + + if (priv->cut_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + priv->cut_clipboard, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->cut_clipboard); + priv->cut_clipboard = NULL; + } + + if (priv->copy_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + priv->copy_clipboard, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->copy_clipboard); + priv->copy_clipboard = NULL; + } + + if (priv->paste_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + priv->paste_clipboard, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->paste_clipboard); + priv->paste_clipboard = NULL; + } + + if (priv->delete_selection != NULL) { + g_signal_handlers_disconnect_matched ( + priv->delete_selection, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->delete_selection); + priv->delete_selection = NULL; + } + + if (priv->select_all != NULL) { + g_signal_handlers_disconnect_matched ( + priv->select_all, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->select_all); + priv->select_all = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +focus_tracker_constructed (GObject *object) +{ + GtkClipboard *clipboard; + + /* Listen for "owner-change" signals from the primary selection + * clipboard to learn when text selections change in GtkEditable + * widgets. It's a bit of an overkill, but I don't know of any + * other notification mechanism. */ + + clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + + g_signal_connect_swapped ( + clipboard, "owner-change", + G_CALLBACK (e_focus_tracker_update_actions), object); +} + +static void +focus_tracker_class_init (EFocusTrackerClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EFocusTrackerPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = focus_tracker_set_property; + object_class->get_property = focus_tracker_get_property; + object_class->dispose = focus_tracker_dispose; + object_class->constructed = focus_tracker_constructed; + + g_object_class_install_property ( + object_class, + PROP_FOCUS, + g_param_spec_object ( + "focus", + "Focus", + NULL, + GTK_TYPE_WIDGET, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_WINDOW, + g_param_spec_object ( + "window", + "Window", + NULL, + GTK_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_CUT_CLIPBOARD_ACTION, + g_param_spec_object ( + "cut-clipboard-action", + "Cut Clipboard Action", + NULL, + GTK_TYPE_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_COPY_CLIPBOARD_ACTION, + g_param_spec_object ( + "copy-clipboard-action", + "Copy Clipboard Action", + NULL, + GTK_TYPE_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_PASTE_CLIPBOARD_ACTION, + g_param_spec_object ( + "paste-clipboard-action", + "Paste Clipboard Action", + NULL, + GTK_TYPE_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_DELETE_SELECTION_ACTION, + g_param_spec_object ( + "delete-selection-action", + "Delete Selection Action", + NULL, + GTK_TYPE_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SELECT_ALL_ACTION, + g_param_spec_object ( + "select-all-action", + "Select All Action", + NULL, + GTK_TYPE_ACTION, + G_PARAM_READWRITE)); +} + +static void +focus_tracker_init (EFocusTracker *focus_tracker) +{ + focus_tracker->priv = E_FOCUS_TRACKER_GET_PRIVATE (focus_tracker); +} + +GType +e_focus_tracker_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EFocusTrackerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) focus_tracker_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EFocusTracker), + 0, /* n_preallocs */ + (GInstanceInitFunc) focus_tracker_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EFocusTracker", &type_info, 0); + } + + return type; +} + +EFocusTracker * +e_focus_tracker_new (GtkWindow *window) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); + + return g_object_new (E_TYPE_FOCUS_TRACKER, "window", window, NULL); +} + +GtkWidget * +e_focus_tracker_get_focus (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->focus; +} + +GtkWindow * +e_focus_tracker_get_window (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->window; +} + +GtkAction * +e_focus_tracker_get_cut_clipboard_action (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->cut_clipboard; +} + +void +e_focus_tracker_set_cut_clipboard_action (EFocusTracker *focus_tracker, + GtkAction *cut_clipboard) +{ + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + if (cut_clipboard != NULL) { + g_return_if_fail (GTK_IS_ACTION (cut_clipboard)); + g_object_ref (cut_clipboard); + } + + if (focus_tracker->priv->cut_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + focus_tracker->priv->cut_clipboard, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + focus_tracker); + g_object_unref (focus_tracker->priv->cut_clipboard); + } + + focus_tracker->priv->cut_clipboard = cut_clipboard; + + if (cut_clipboard != NULL) + g_signal_connect_swapped ( + cut_clipboard, "activate", + G_CALLBACK (e_focus_tracker_cut_clipboard), + focus_tracker); + + g_object_notify (G_OBJECT (focus_tracker), "cut-clipboard-action"); +} + +GtkAction * +e_focus_tracker_get_copy_clipboard_action (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->copy_clipboard; +} + +void +e_focus_tracker_set_copy_clipboard_action (EFocusTracker *focus_tracker, + GtkAction *copy_clipboard) +{ + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + if (copy_clipboard != NULL) { + g_return_if_fail (GTK_IS_ACTION (copy_clipboard)); + g_object_ref (copy_clipboard); + } + + if (focus_tracker->priv->copy_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + focus_tracker->priv->copy_clipboard, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + focus_tracker); + g_object_unref (focus_tracker->priv->copy_clipboard); + } + + focus_tracker->priv->copy_clipboard = copy_clipboard; + + if (copy_clipboard != NULL) + g_signal_connect_swapped ( + copy_clipboard, "activate", + G_CALLBACK (e_focus_tracker_copy_clipboard), + focus_tracker); + + g_object_notify (G_OBJECT (focus_tracker), "copy-clipboard-action"); +} + +GtkAction * +e_focus_tracker_get_paste_clipboard_action (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->paste_clipboard; +} + +void +e_focus_tracker_set_paste_clipboard_action (EFocusTracker *focus_tracker, + GtkAction *paste_clipboard) +{ + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + if (paste_clipboard != NULL) { + g_return_if_fail (GTK_IS_ACTION (paste_clipboard)); + g_object_ref (paste_clipboard); + } + + if (focus_tracker->priv->paste_clipboard != NULL) { + g_signal_handlers_disconnect_matched ( + focus_tracker->priv->paste_clipboard, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + focus_tracker); + g_object_unref (focus_tracker->priv->paste_clipboard); + } + + focus_tracker->priv->paste_clipboard = paste_clipboard; + + if (paste_clipboard != NULL) + g_signal_connect_swapped ( + paste_clipboard, "activate", + G_CALLBACK (e_focus_tracker_paste_clipboard), + focus_tracker); + + g_object_notify (G_OBJECT (focus_tracker), "paste-clipboard-action"); +} + +GtkAction * +e_focus_tracker_get_delete_selection_action (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->delete_selection; +} + +void +e_focus_tracker_set_delete_selection_action (EFocusTracker *focus_tracker, + GtkAction *delete_selection) +{ + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + if (delete_selection != NULL) { + g_return_if_fail (GTK_IS_ACTION (delete_selection)); + g_object_ref (delete_selection); + } + + if (focus_tracker->priv->delete_selection != NULL) { + g_signal_handlers_disconnect_matched ( + focus_tracker->priv->delete_selection, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + focus_tracker); + g_object_unref (focus_tracker->priv->delete_selection); + } + + focus_tracker->priv->delete_selection = delete_selection; + + if (delete_selection != NULL) + g_signal_connect_swapped ( + delete_selection, "activate", + G_CALLBACK (e_focus_tracker_delete_selection), + focus_tracker); + + g_object_notify (G_OBJECT (focus_tracker), "delete-selection-action"); +} + +GtkAction * +e_focus_tracker_get_select_all_action (EFocusTracker *focus_tracker) +{ + g_return_val_if_fail (E_IS_FOCUS_TRACKER (focus_tracker), NULL); + + return focus_tracker->priv->select_all; +} + +void +e_focus_tracker_set_select_all_action (EFocusTracker *focus_tracker, + GtkAction *select_all) +{ + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + if (select_all != NULL) { + g_return_if_fail (GTK_IS_ACTION (select_all)); + g_object_ref (select_all); + } + + if (focus_tracker->priv->select_all != NULL) { + g_signal_handlers_disconnect_matched ( + focus_tracker->priv->select_all, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, + focus_tracker); + g_object_unref (focus_tracker->priv->select_all); + } + + focus_tracker->priv->select_all = select_all; + + if (select_all != NULL) + g_signal_connect_swapped ( + select_all, "activate", + G_CALLBACK (e_focus_tracker_select_all), + focus_tracker); + + g_object_notify (G_OBJECT (focus_tracker), "select-all-action"); +} + +void +e_focus_tracker_update_actions (EFocusTracker *focus_tracker) +{ + GtkClipboard *clipboard; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + /* Request clipboard targets asynchronously. */ + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + + gtk_clipboard_request_targets ( + clipboard, (GtkClipboardTargetsReceivedFunc) + focus_tracker_targets_received_cb, + g_object_ref (focus_tracker)); +} + +void +e_focus_tracker_cut_clipboard (EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (GTK_IS_EDITABLE (focus)) + gtk_editable_cut_clipboard (GTK_EDITABLE (focus)); + + else if (E_IS_SELECTABLE (focus)) + e_selectable_cut_clipboard (E_SELECTABLE (focus)); +} + +void +e_focus_tracker_copy_clipboard (EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (GTK_IS_EDITABLE (focus)) + gtk_editable_copy_clipboard (GTK_EDITABLE (focus)); + + else if (E_IS_SELECTABLE (focus)) + e_selectable_copy_clipboard (E_SELECTABLE (focus)); +} + +void +e_focus_tracker_paste_clipboard (EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (GTK_IS_EDITABLE (focus)) + gtk_editable_paste_clipboard (GTK_EDITABLE (focus)); + + else if (E_IS_SELECTABLE (focus)) + e_selectable_paste_clipboard (E_SELECTABLE (focus)); +} + +void +e_focus_tracker_delete_selection (EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (GTK_IS_EDITABLE (focus)) + gtk_editable_delete_selection (GTK_EDITABLE (focus)); + + else if (E_IS_SELECTABLE (focus)) + e_selectable_delete_selection (E_SELECTABLE (focus)); +} + +void +e_focus_tracker_select_all (EFocusTracker *focus_tracker) +{ + GtkWidget *focus; + + g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker)); + + focus = e_focus_tracker_get_focus (focus_tracker); + + if (GTK_IS_EDITABLE (focus)) + gtk_editable_select_region (GTK_EDITABLE (focus), 0, -1); + + else if (E_IS_SELECTABLE (focus)) + e_selectable_select_all (E_SELECTABLE (focus)); +} diff --git a/widgets/misc/e-focus-tracker.h b/widgets/misc/e-focus-tracker.h new file mode 100644 index 0000000000..679cc4b655 --- /dev/null +++ b/widgets/misc/e-focus-tracker.h @@ -0,0 +1,99 @@ +/* + * e-focus-tracker.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_FOCUS_TRACKER_H +#define E_FOCUS_TRACKER_H + +#include <gtk/gtk.h> + +/* Standard GObject macros */ +#define E_TYPE_FOCUS_TRACKER \ + (e_focus_tracker_get_type ()) +#define E_FOCUS_TRACKER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_FOCUS_TRACKER, EFocusTracker)) +#define E_FOCUS_TRACKER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_FOCUS_TRACKER, EFocusTrackerClass)) +#define E_IS_FOCUS_TRACKER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_FOCUS_TRACKER)) +#define E_IS_FOCUS_TRACKER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_FOCUS_TRACKER)) +#define E_FOCUS_TRACKER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_FOCUS_TRACKER, EFocusTrackerClass)) + +G_BEGIN_DECLS + +typedef struct _EFocusTracker EFocusTracker; +typedef struct _EFocusTrackerClass EFocusTrackerClass; +typedef struct _EFocusTrackerPrivate EFocusTrackerPrivate; + +struct _EFocusTracker { + GObject parent; + EFocusTrackerPrivate *priv; +}; + +struct _EFocusTrackerClass { + GObjectClass parent_class; +}; + +GType e_focus_tracker_get_type (void); +EFocusTracker * e_focus_tracker_new (GtkWindow *window); +GtkWidget * e_focus_tracker_get_focus (EFocusTracker *focus_tracker); +GtkWindow * e_focus_tracker_get_window (EFocusTracker *focus_tracker); +GtkAction * e_focus_tracker_get_cut_clipboard_action + (EFocusTracker *focus_tracker); +void e_focus_tracker_set_cut_clipboard_action + (EFocusTracker *focus_tracker, + GtkAction *cut_clipboard); +GtkAction * e_focus_tracker_get_copy_clipboard_action + (EFocusTracker *focus_tracker); +void e_focus_tracker_set_copy_clipboard_action + (EFocusTracker *focus_tracker, + GtkAction *copy_clipboard); +GtkAction * e_focus_tracker_get_paste_clipboard_action + (EFocusTracker *focus_tracker); +void e_focus_tracker_set_paste_clipboard_action + (EFocusTracker *focus_tracker, + GtkAction *paste_clipboard); +GtkAction * e_focus_tracker_get_delete_selection_action + (EFocusTracker *focus_tracker); +void e_focus_tracker_set_delete_selection_action + (EFocusTracker *focus_tracker, + GtkAction *delete_selection); +GtkAction * e_focus_tracker_get_select_all_action + (EFocusTracker *focus_tracker); +void e_focus_tracker_set_select_all_action + (EFocusTracker *focus_tracker, + GtkAction *select_all); +void e_focus_tracker_update_actions (EFocusTracker *focus_tracker); +void e_focus_tracker_cut_clipboard (EFocusTracker *focus_tracker); +void e_focus_tracker_copy_clipboard (EFocusTracker *focus_tracker); +void e_focus_tracker_paste_clipboard (EFocusTracker *focus_tracker); +void e_focus_tracker_delete_selection(EFocusTracker *focus_tracker); +void e_focus_tracker_select_all (EFocusTracker *focus_tracker); + +G_END_DECLS + +#endif /* E_FOCUS_TRACKER_H */ diff --git a/widgets/misc/e-selectable.c b/widgets/misc/e-selectable.c new file mode 100644 index 0000000000..95cd2bb06f --- /dev/null +++ b/widgets/misc/e-selectable.c @@ -0,0 +1,133 @@ +/* + * e-selectable.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-selectable.h" + +GType +e_selectable_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESelectableInterface), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_INTERFACE, "ESelectable", &type_info, 0); + + g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + } + + return type; +} + +void +e_selectable_update_actions (ESelectable *selectable, + EFocusTracker *focus_tracker, + GdkAtom *clipboard_targets, + gint n_clipboard_targets) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + g_return_if_fail (interface->update_actions != NULL); + + return interface->update_actions ( + selectable, focus_tracker, + clipboard_targets, n_clipboard_targets); +} + +void +e_selectable_cut_clipboard (ESelectable *selectable) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + if (interface->cut_clipboard != NULL) + interface->cut_clipboard (selectable); +} + +void +e_selectable_copy_clipboard (ESelectable *selectable) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + if (interface->copy_clipboard != NULL) + interface->copy_clipboard (selectable); +} + +void +e_selectable_paste_clipboard (ESelectable *selectable) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + if (interface->paste_clipboard != NULL) + interface->paste_clipboard (selectable); +} + +void +e_selectable_delete_selection (ESelectable *selectable) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + if (interface->delete_selection != NULL) + interface->delete_selection (selectable); +} + +void +e_selectable_select_all (ESelectable *selectable) +{ + ESelectableInterface *interface; + + g_return_if_fail (E_IS_SELECTABLE (selectable)); + + interface = E_SELECTABLE_GET_INTERFACE (selectable); + + if (interface->select_all != NULL) + interface->select_all (selectable); +} diff --git a/widgets/misc/e-selectable.h b/widgets/misc/e-selectable.h new file mode 100644 index 0000000000..fca400ce65 --- /dev/null +++ b/widgets/misc/e-selectable.h @@ -0,0 +1,76 @@ +/* + * e-selectable.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_SELECTABLE_H +#define E_SELECTABLE_H + +#include <gtk/gtk.h> +#include <misc/e-focus-tracker.h> + +/* Standard GObject macros */ +#define E_TYPE_SELECTABLE \ + (e_selectable_get_type ()) +#define E_SELECTABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SELECTABLE, ESelectable)) +#define E_IS_SELECTABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SELECTABLE)) +#define E_SELECTABLE_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE \ + ((obj), E_TYPE_SELECTABLE, ESelectableInterface)) + +G_BEGIN_DECLS + +typedef struct _ESelectable ESelectable; +typedef struct _ESelectableInterface ESelectableInterface; + +struct _ESelectableInterface { + GTypeInterface parent_iface; + + /* Required Methods */ + void (*update_actions) (ESelectable *selectable, + EFocusTracker *focus_tracker, + GdkAtom *clipboard_targets, + gint n_clipboard_targets); + + /* Optional Methods */ + void (*cut_clipboard) (ESelectable *selectable); + void (*copy_clipboard) (ESelectable *selectable); + void (*paste_clipboard) (ESelectable *selectable); + void (*delete_selection) (ESelectable *selectable); + void (*select_all) (ESelectable *selectable); +}; + +GType e_selectable_get_type (void); +void e_selectable_update_actions (ESelectable *selectable, + EFocusTracker *focus_tracker, + GdkAtom *clipboard_targets, + gint n_clipboard_targets); +void e_selectable_cut_clipboard (ESelectable *selectable); +void e_selectable_copy_clipboard (ESelectable *selectable); +void e_selectable_paste_clipboard (ESelectable *selectable); +void e_selectable_delete_selection (ESelectable *selectable); +void e_selectable_select_all (ESelectable *selectable); + +G_END_DECLS + +#endif /* E_SELECTABLE_H */ diff --git a/widgets/misc/e-signature-editor.c b/widgets/misc/e-signature-editor.c index 9266425494..91a4d81c8d 100644 --- a/widgets/misc/e-signature-editor.c +++ b/widgets/misc/e-signature-editor.c @@ -26,6 +26,7 @@ #include <e-util/e-alert-dialog.h> #include <e-util/e-signature-utils.h> +#include <misc/e-web-view.h> #define E_SIGNATURE_EDITOR_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -33,11 +34,13 @@ enum { PROP_0, + PROP_FOCUS_TRACKER, PROP_SIGNATURE }; struct _ESignatureEditorPrivate { GtkActionGroup *action_group; + EFocusTracker *focus_tracker; ESignature *signature; GtkWidget *entry; gchar *original_name; @@ -255,6 +258,12 @@ signature_editor_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_FOCUS_TRACKER: + g_value_set_object ( + value, e_signature_editor_get_focus_tracker ( + E_SIGNATURE_EDITOR (object))); + return; + case PROP_SIGNATURE: g_value_set_object ( value, e_signature_editor_get_signature ( @@ -277,6 +286,11 @@ signature_editor_dispose (GObject *object) priv->action_group = NULL; } + if (priv->focus_tracker != NULL) { + g_object_unref (priv->focus_tracker); + priv->focus_tracker = NULL; + } + if (priv->signature != NULL) { g_object_unref (priv->signature); priv->signature = NULL; @@ -320,6 +334,16 @@ signature_editor_class_init (ESignatureEditorClass *class) g_object_class_install_property ( object_class, + PROP_FOCUS_TRACKER, + g_param_spec_object ( + "focus-tracker", + NULL, + NULL, + E_TYPE_FOCUS_TRACKER, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, PROP_SIGNATURE, g_param_spec_object ( "signature", @@ -333,7 +357,10 @@ static void signature_editor_init (ESignatureEditor *editor) { GtkActionGroup *action_group; + EFocusTracker *focus_tracker; + GtkhtmlEditor *gtkhtml_editor; GtkUIManager *ui_manager; + GtkAction *action; GtkWidget *container; GtkWidget *widget; GtkWidget *vbox; @@ -342,7 +369,8 @@ signature_editor_init (ESignatureEditor *editor) editor->priv = E_SIGNATURE_EDITOR_GET_PRIVATE (editor); vbox = GTKHTML_EDITOR (editor)->vbox; - ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); + gtkhtml_editor = GTKHTML_EDITOR (editor); + ui_manager = gtkhtml_editor_get_ui_manager (gtkhtml_editor); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); handle_error (&error); @@ -383,6 +411,28 @@ signature_editor_init (ESignatureEditor *editor) G_CALLBACK (signature_editor_delete_event_cb), NULL); e_signature_editor_set_signature (editor, NULL); + + /* Configure an EFocusTracker to manage selection actions. + * + * XXX GtkhtmlEditor does not manage its own selection actions, + * which is technically a bug but works in our favor here + * because it won't cause any conflicts with EFocusTracker. */ + + focus_tracker = e_focus_tracker_new (GTK_WINDOW (editor)); + + action = gtkhtml_editor_get_action (gtkhtml_editor, "cut"); + e_focus_tracker_set_cut_clipboard_action (focus_tracker, action); + + action = gtkhtml_editor_get_action (gtkhtml_editor, "copy"); + e_focus_tracker_set_copy_clipboard_action (focus_tracker, action); + + action = gtkhtml_editor_get_action (gtkhtml_editor, "paste"); + e_focus_tracker_set_paste_clipboard_action (focus_tracker, action); + + action = gtkhtml_editor_get_action (gtkhtml_editor, "select-all"); + e_focus_tracker_set_select_all_action (focus_tracker, action); + + editor->priv->focus_tracker = focus_tracker; } GType @@ -415,7 +465,17 @@ e_signature_editor_get_type (void) GtkWidget * e_signature_editor_new (void) { - return g_object_new (E_TYPE_SIGNATURE_EDITOR, NULL); + return g_object_new ( + E_TYPE_SIGNATURE_EDITOR, + "html", e_web_view_new (), NULL); +} + +EFocusTracker * +e_signature_editor_get_focus_tracker (ESignatureEditor *editor) +{ + g_return_val_if_fail (E_IS_SIGNATURE_EDITOR (editor), NULL); + + return editor->priv->focus_tracker; } ESignature * diff --git a/widgets/misc/e-signature-editor.h b/widgets/misc/e-signature-editor.h index 1e8b88a909..6d9f4a9b61 100644 --- a/widgets/misc/e-signature-editor.h +++ b/widgets/misc/e-signature-editor.h @@ -24,6 +24,7 @@ #include <gtkhtml-editor.h> #include <e-util/e-signature.h> +#include <misc/e-focus-tracker.h> /* Standard GObject macros */ #define E_TYPE_SIGNATURE_EDITOR \ @@ -61,6 +62,8 @@ struct _ESignatureEditorClass { GType e_signature_editor_get_type (void); GtkWidget * e_signature_editor_new (void); +EFocusTracker * e_signature_editor_get_focus_tracker + (ESignatureEditor *editor); ESignature * e_signature_editor_get_signature (ESignatureEditor *editor); void e_signature_editor_set_signature (ESignatureEditor *editor, ESignature *signature); diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c index f52d7399eb..a873731014 100644 --- a/widgets/misc/e-web-view.c +++ b/widgets/misc/e-web-view.c @@ -33,6 +33,7 @@ #include "e-util/e-plugin-ui.h" #include "e-popup-action.h" +#include "e-selectable.h" #define E_WEB_VIEW_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -89,7 +90,7 @@ static guint signals[LAST_SIGNAL]; static const gchar *ui = "<ui>" " <popup name='context'>" -" <menuitem action='clipboard-copy'/>" +" <menuitem action='copy-clipboard'/>" " <separator/>" " <placeholder name='custom-actions-1'>" " <menuitem action='open'/>" @@ -240,10 +241,10 @@ web_view_request_read_cb (GFile *file, } static void -action_clipboard_copy_cb (GtkAction *action, +action_copy_clipboard_cb (GtkAction *action, EWebView *web_view) { - e_web_view_clipboard_copy (web_view); + e_web_view_copy_clipboard (web_view); } static void @@ -372,12 +373,12 @@ static GtkActionEntry mailto_entries[] = { static GtkActionEntry selection_entries[] = { - { "clipboard-copy", + { "copy-clipboard", GTK_STOCK_COPY, NULL, NULL, - N_("Copy the selection to the clipboard"), - G_CALLBACK (action_clipboard_copy_cb) }, + N_("Copy the selection"), + G_CALLBACK (action_copy_clipboard_cb) }, }; static GtkActionEntry standard_entries[] = { @@ -859,6 +860,52 @@ web_view_update_actions (EWebView *web_view) } static void +web_view_selectable_update_actions (ESelectable *selectable, + EFocusTracker *focus_tracker, + GdkAtom *clipboard_targets, + gint n_clipboard_targets) +{ + EWebView *web_view; + GtkAction *action; + const gchar *tooltip; + gboolean sensitive; + + web_view = E_WEB_VIEW (selectable); + + /* Copy Clipboard */ + + action = e_web_view_get_action (web_view, "copy-clipboard"); + sensitive = gtk_action_get_sensitive (action); + tooltip = gtk_action_get_tooltip (action); + + action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, tooltip); + + /* Select All */ + + action = e_web_view_get_action (web_view, "select-all"); + sensitive = gtk_action_get_sensitive (action); + tooltip = gtk_action_get_tooltip (action); + + action = e_focus_tracker_get_select_all_action (focus_tracker); + gtk_action_set_sensitive (action, sensitive); + gtk_action_set_tooltip (action, tooltip); +} + +static void +web_view_selectable_copy_clipboard (ESelectable *selectable) +{ + e_web_view_copy_clipboard (E_WEB_VIEW (selectable)); +} + +static void +web_view_selectable_select_all (ESelectable *selectable) +{ + e_web_view_select_all (E_WEB_VIEW (selectable)); +} + +static void web_view_class_init (EWebViewClass *class) { GObjectClass *object_class; @@ -1010,6 +1057,14 @@ web_view_class_init (EWebViewClass *class) } static void +web_view_selectable_init (ESelectableInterface *interface) +{ + interface->update_actions = web_view_selectable_update_actions; + interface->copy_clipboard = web_view_selectable_copy_clipboard; + interface->select_all = web_view_selectable_select_all; +} + +static void web_view_init (EWebView *web_view) { GtkUIManager *ui_manager; @@ -1140,8 +1195,17 @@ e_web_view_get_type (void) NULL /* value_table */ }; + static const GInterfaceInfo selectable_info = { + (GInterfaceInitFunc) web_view_selectable_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + type = g_type_register_static ( GTK_TYPE_HTML, "EWebView", &type_info, 0); + + g_type_add_interface_static ( + type, E_TYPE_SELECTABLE, &selectable_info); } return type; @@ -1411,7 +1475,7 @@ e_web_view_extract_uri (EWebView *web_view, } void -e_web_view_clipboard_copy (EWebView *web_view) +e_web_view_copy_clipboard (EWebView *web_view) { g_return_if_fail (E_IS_WEB_VIEW (web_view)); diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h index 4a30b4bd80..123965c7d0 100644 --- a/widgets/misc/e-web-view.h +++ b/widgets/misc/e-web-view.h @@ -118,7 +118,7 @@ GtkActionGroup *e_web_view_get_action_group (EWebView *web_view, gchar * e_web_view_extract_uri (EWebView *web_view, GdkEventButton *event, GtkHTML *frame); -void e_web_view_clipboard_copy (EWebView *web_view); +void e_web_view_copy_clipboard (EWebView *web_view); gboolean e_web_view_is_selection_active (EWebView *web_view); gboolean e_web_view_scroll_forward (EWebView *web_view); gboolean e_web_view_scroll_backward (EWebView *web_view); diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index f5cd6c0d16..2656f7f949 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -55,8 +55,6 @@ #define COLUMN_HEADER_HEIGHT 16 -G_DEFINE_TYPE (ETable, e_table, GTK_TYPE_TABLE) - #define d(x) #if d(!)0 @@ -77,6 +75,11 @@ enum { STATE_CHANGE, WHITE_SPACE_EVENT, + CUT_CLIPBOARD, + COPY_CLIPBOARD, + PASTE_CLIPBOARD, + SELECT_ALL, + TABLE_DRAG_BEGIN, TABLE_DRAG_END, TABLE_DRAG_DATA_GET, @@ -159,6 +162,8 @@ static gint et_focus (GtkWidget *container, GtkDirectionType direction); static void scroll_off (ETable *et); static void scroll_on (ETable *et, guint scroll_direction); +G_DEFINE_TYPE (ETable, e_table, GTK_TYPE_TABLE) + static void et_disconnect_model (ETable *et) { @@ -3357,4 +3362,3 @@ e_table_class_init (ETableClass *class) gal_a11y_e_table_init (); } - diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c index 38c7a5111b..ba50be0625 100644 --- a/widgets/table/e-tree.c +++ b/widgets/table/e-tree.c @@ -54,8 +54,6 @@ #define COLUMN_HEADER_HEIGHT 16 -G_DEFINE_TYPE (ETree, e_tree, GTK_TYPE_TABLE) - #define d(x) #if d(!)0 @@ -76,6 +74,11 @@ enum { STATE_CHANGE, WHITE_SPACE_EVENT, + CUT_CLIPBOARD, + COPY_CLIPBOARD, + PASTE_CLIPBOARD, + SELECT_ALL, + TREE_DRAG_BEGIN, TREE_DRAG_END, TREE_DRAG_DATA_GET, @@ -245,6 +248,8 @@ static void hover_off (ETree *et); static void hover_on (ETree *et, gint x, gint y); static void context_destroyed (gpointer data, GObject *ctx); +G_DEFINE_TYPE (ETree, e_tree, GTK_TYPE_TABLE) + static void et_disconnect_from_etta (ETree *et) { |