aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-12-08 00:31:17 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-12-26 04:42:17 +0800
commitabc0e4c694fb3d9624e890384880def730769fa0 (patch)
tree8d411f90f4edb0859ffe0b260c85e02e7d273088
parent83dc7625983470bff4ce8b9070fbc23c3370c472 (diff)
downloadgsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.gz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.bz2
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.lz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.xz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.zst
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.zip
Introduce ESelectable and EFocusTracker.
EFocusTracker tracks the input focus within a window and helps keep the sensitivity of "selectable" actions in the main menu up-to-date. Selectable actions include Cut, Copy, Paste, Select All and Delete. EFocusTracker has built-in support for widgets that implement the GtkEditable interface such as GtkEntry and GtkTextView. It also supports custom widgets that implement the ESelectable interface, which is a subset of GtkEditable and can apply to anything that displays selectable content (esp. tree views and ETables). This commit integrates EFocusTracker with EShellWindow, CompEditor, EMsgComposer, and ESignatureManager. It also bumps the GtkHTML requirement to 2.29.5 to utilize the new GtkhtmlEditor:html constructor property.
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c230
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h4
-rw-r--r--calendar/gui/dialogs/comp-editor.c153
-rw-r--r--calendar/gui/dialogs/comp-editor.h2
-rw-r--r--calendar/gui/e-cal-list-view.h3
-rw-r--r--calendar/gui/e-calendar-table.c540
-rw-r--r--calendar/gui/e-calendar-table.h5
-rw-r--r--calendar/gui/e-calendar-view.c682
-rw-r--r--calendar/gui/e-calendar-view.h3
-rw-r--r--calendar/gui/e-day-view-main-item.c1
-rw-r--r--calendar/gui/e-memo-table.c544
-rw-r--r--calendar/gui/e-memo-table.h5
-rw-r--r--calendar/gui/gnome-cal.h2
-rw-r--r--calendar/gui/goto.c1
-rw-r--r--calendar/gui/print.h1
-rw-r--r--composer/e-composer-private.c28
-rw-r--r--composer/e-composer-private.h3
-rw-r--r--composer/e-msg-composer.c295
-rw-r--r--composer/e-msg-composer.h2
-rw-r--r--configure.ac2
-rw-r--r--doc/reference/shell/tmpl/e-shell-window.sgml5
-rw-r--r--mail/e-mail-reader.c83
-rw-r--r--mail/message-list.c106
-rw-r--r--mail/message-list.h111
-rw-r--r--modules/addressbook/e-book-shell-content.c31
-rw-r--r--modules/addressbook/e-book-shell-content.h6
-rw-r--r--modules/addressbook/e-book-shell-view-actions.c92
-rw-r--r--modules/addressbook/e-book-shell-view-actions.h8
-rw-r--r--modules/addressbook/e-book-shell-view.c25
-rw-r--r--modules/calendar/e-cal-shell-content.c108
-rw-r--r--modules/calendar/e-cal-shell-content.h7
-rw-r--r--modules/calendar/e-cal-shell-view-actions.c63
-rw-r--r--modules/calendar/e-cal-shell-view-actions.h18
-rw-r--r--modules/calendar/e-cal-shell-view-memopad.c72
-rw-r--r--modules/calendar/e-cal-shell-view-taskpad.c72
-rw-r--r--modules/calendar/e-cal-shell-view.c20
-rw-r--r--modules/calendar/e-memo-shell-content.c5
-rw-r--r--modules/calendar/e-memo-shell-content.h3
-rw-r--r--modules/calendar/e-memo-shell-view-actions.c72
-rw-r--r--modules/calendar/e-memo-shell-view-actions.h6
-rw-r--r--modules/calendar/e-memo-shell-view.c18
-rw-r--r--modules/calendar/e-task-shell-content.c5
-rw-r--r--modules/calendar/e-task-shell-content.h3
-rw-r--r--modules/calendar/e-task-shell-view-actions.c72
-rw-r--r--modules/calendar/e-task-shell-view-actions.h6
-rw-r--r--modules/calendar/e-task-shell-view.c18
-rw-r--r--modules/mail/e-mail-shell-view-actions.c49
-rw-r--r--modules/mail/e-mail-shell-view-private.c1
-rw-r--r--modules/mail/e-mail-shell-view.c7
-rw-r--r--shell/e-shell-view.c45
-rw-r--r--shell/e-shell-window-actions.c73
-rw-r--r--shell/e-shell-window-actions.h10
-rw-r--r--shell/e-shell-window-private.c1
-rw-r--r--shell/e-shell-window-private.h2
-rw-r--r--shell/e-shell-window.c40
-rw-r--r--shell/e-shell-window.h2
-rw-r--r--ui/evolution-calendars.ui24
-rw-r--r--ui/evolution-contacts.ui12
-rw-r--r--ui/evolution-mail-reader.ui6
-rw-r--r--ui/evolution-mail.ui1
-rw-r--r--ui/evolution-memos.ui16
-rw-r--r--ui/evolution-shell.ui6
-rw-r--r--ui/evolution-tasks.ui16
-rw-r--r--widgets/misc/Makefile.am4
-rw-r--r--widgets/misc/e-focus-tracker.c859
-rw-r--r--widgets/misc/e-focus-tracker.h99
-rw-r--r--widgets/misc/e-selectable.c133
-rw-r--r--widgets/misc/e-selectable.h76
-rw-r--r--widgets/misc/e-signature-editor.c64
-rw-r--r--widgets/misc/e-signature-editor.h3
-rw-r--r--widgets/misc/e-web-view.c78
-rw-r--r--widgets/misc/e-web-view.h2
-rw-r--r--widgets/table/e-table.c10
-rw-r--r--widgets/table/e-tree.c9
74 files changed, 3140 insertions, 2049 deletions
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index a48ea8c351..91fdb16e4b 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -28,6 +28,7 @@
#include <table/e-table-model.h>
#include <table/e-cell-date.h>
#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <widgets/menus/gal-view-factory-etable.h>
#include <filter/e-rule-editor.h>
#include <widgets/menus/gal-view-etable.h>
@@ -539,6 +540,140 @@ addressbook_view_constructed (GObject *object)
}
static void
+addressbook_view_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ ESelectionModel *selection_model;
+ GtkAction *action;
+ gboolean clipboard_has_directory;
+ gboolean source_is_editable;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_contacts;
+ gint n_selected;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ model = e_addressbook_view_get_model (view);
+ selection_model = e_addressbook_view_get_selection_model (view);
+
+ source_is_editable = e_addressbook_model_get_editable (model);
+ n_contacts = (selection_model != NULL) ?
+ e_selection_model_row_count (selection_model) : 0;
+ n_selected = (selection_model != NULL) ?
+ e_selection_model_selected_count (selection_model) : 0;
+
+ clipboard_has_directory = (clipboard_targets != NULL) &&
+ e_targets_include_directory (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && (n_selected > 0);
+ tooltip = _("Cut selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && clipboard_has_directory;
+ tooltip = _("Paste contacts from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = (n_contacts > 0);
+ tooltip = _("Select all visible contacts");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+addressbook_view_cut_clipboard (ESelectable *selectable)
+{
+ EAddressbookView *view;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ e_addressbook_view_delete_selection (view, FALSE);
+}
+
+static void
+addressbook_view_copy_clipboard (ESelectable *selectable)
+{
+ EAddressbookView *view;
+ GtkClipboard *clipboard;
+ GList *contact_list;
+ gchar *string;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ contact_list = e_addressbook_view_get_selected (view);
+
+ string = eab_contact_list_to_string (contact_list);
+ e_clipboard_set_directory (clipboard, string, -1);
+ g_free (string);
+
+ g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
+ g_list_free (contact_list);
+}
+
+static void
+addressbook_view_paste_clipboard (ESelectable *selectable)
+{
+ EBook *book;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ GtkClipboard *clipboard;
+ GList *contact_list, *iter;
+ gchar *string;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ if (!e_clipboard_wait_is_directory_available (clipboard))
+ return;
+
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+
+ string = e_clipboard_wait_for_directory (clipboard);
+ contact_list = eab_contact_list_from_string (string);
+ g_free (string);
+
+ for (iter = contact_list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
+
+ eab_merging_book_add_contact (book, contact, NULL, NULL);
+ }
+
+ g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
+ g_list_free (contact_list);
+}
+
+static void
+addressbook_view_select_all (ESelectable *selectable)
+{
+ EAddressbookView *view;
+ ESelectionModel *selection_model;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ selection_model = e_addressbook_view_get_selection_model (view);
+
+ if (selection_model != NULL)
+ e_selection_model_select_all (selection_model);
+}
+
+static void
addressbook_view_class_init (EAddressbookViewClass *class)
{
GObjectClass *object_class;
@@ -641,6 +776,16 @@ addressbook_view_init (EAddressbookView *view)
GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
}
+static void
+addressbook_view_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = addressbook_view_update_actions;
+ interface->cut_clipboard = addressbook_view_cut_clipboard;
+ interface->copy_clipboard = addressbook_view_copy_clipboard;
+ interface->paste_clipboard = addressbook_view_paste_clipboard;
+ interface->select_all = addressbook_view_select_all;
+}
+
GType
e_addressbook_view_get_type (void)
{
@@ -660,9 +805,18 @@ e_addressbook_view_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) addressbook_view_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
GTK_TYPE_SCROLLED_WINDOW, "EAddressbookView",
&type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -1238,82 +1392,6 @@ e_addressbook_view_view (EAddressbookView *view)
}
void
-e_addressbook_view_cut (EAddressbookView *view)
-{
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-
- e_addressbook_view_copy (view);
- e_addressbook_view_delete_selection (view, FALSE);
-}
-
-void
-e_addressbook_view_copy (EAddressbookView *view)
-{
- GtkClipboard *clipboard;
- GList *contact_list;
- gchar *string;
-
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- contact_list = e_addressbook_view_get_selected (view);
-
- string = eab_contact_list_to_string (contact_list);
- e_clipboard_set_directory (clipboard, string, -1);
- g_free (string);
-
- g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
- g_list_free (contact_list);
-}
-
-void
-e_addressbook_view_paste (EAddressbookView *view)
-{
- EBook *book;
- EAddressbookModel *model;
- GtkClipboard *clipboard;
- GList *contact_list, *iter;
- gchar *string;
-
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- if (!e_clipboard_wait_is_directory_available (clipboard))
- return;
-
- model = e_addressbook_view_get_model (view);
- book = e_addressbook_model_get_book (model);
-
- string = e_clipboard_wait_for_directory (clipboard);
- contact_list = eab_contact_list_from_string (string);
- g_free (string);
-
- for (iter = contact_list; iter != NULL; iter = iter->next) {
- EContact *contact = iter->data;
-
- eab_merging_book_add_contact (book, contact, NULL, NULL);
- }
-
- g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
- g_list_free (contact_list);
-}
-
-void
-e_addressbook_view_select_all (EAddressbookView *view)
-{
- ESelectionModel *model;
-
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-
- model = e_addressbook_view_get_selection_model (view);
- g_return_if_fail (model);
-
- e_selection_model_select_all (model);
-}
-
-void
e_addressbook_view_show_all (EAddressbookView *view)
{
g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 319d060b89..55f114a538 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -103,10 +103,6 @@ void e_addressbook_view_print (EAddressbookView *view,
void e_addressbook_view_delete_selection
(EAddressbookView *view,
gboolean is_delete);
-void e_addressbook_view_cut (EAddressbookView *view);
-void e_addressbook_view_copy (EAddressbookView *view);
-void e_addressbook_view_paste (EAddressbookView *view);
-void e_addressbook_view_select_all (EAddressbookView *view);
void e_addressbook_view_show_all (EAddressbookView *view);
void e_addressbook_view_stop (EAddressbookView *view);
void e_addressbook_view_copy_to_folder
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 18bd574728..21384032d9 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -80,6 +80,9 @@ struct _CompEditorPrivate {
gpointer shell; /* weak pointer */
+ /* EFocusTracker keeps selection actions up-to-date. */
+ EFocusTracker *focus_tracker;
+
/* Each CompEditor window gets its own GtkWindowGroup, so it
* doesn't block the main window or other CompEditor windows. */
GtkWindowGroup *window_group;
@@ -133,6 +136,7 @@ enum {
PROP_CHANGED,
PROP_CLIENT,
PROP_FLAGS,
+ PROP_FOCUS_TRACKER,
PROP_SHELL,
PROP_SUMMARY
};
@@ -149,9 +153,10 @@ static const gchar *ui =
" <menuitem action='close'/>"
" </menu>"
" <menu action='edit-menu'>"
-" <menuitem action='cut'/>"
-" <menuitem action='copy'/>"
-" <menuitem action='paste'/>"
+" <menuitem action='cut-clipboard'/>"
+" <menuitem action='copy-clipboard'/>"
+" <menuitem action='paste-clipboard'/>"
+" <menuitem action='delete-selection'/>"
" <separator/>"
" <menuitem action='select-all'/>"
" </menu>"
@@ -677,36 +682,6 @@ action_close_cb (GtkAction *action,
}
static void
-action_copy_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_copy_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "copy-clipboard");
-}
-
-static void
-action_cut_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_cut_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "cut-clipboard");
-}
-
-static void
action_help_cb (GtkAction *action,
CompEditor *editor)
{
@@ -714,21 +689,6 @@ action_help_cb (GtkAction *action,
}
static void
-action_paste_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_paste_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "paste-clipboard");
-}
-
-static void
action_print_cb (GtkAction *action,
CompEditor *editor)
{
@@ -886,23 +846,6 @@ action_save_cb (GtkAction *action,
}
static void
-action_select_all_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus)) {
- gtk_editable_set_position (GTK_EDITABLE (focus), -1);
- gtk_editable_select_region (GTK_EDITABLE (focus), 0, -1);
- }
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "select-all", TRUE);
-}
-
-static void
action_view_categories_cb (GtkToggleAction *action,
CompEditor *editor)
{
@@ -995,19 +938,26 @@ static GtkActionEntry core_entries[] = {
N_("Click here to close the current window"),
G_CALLBACK (action_close_cb) },
- { "copy",
+ { "copy-clipboard",
GTK_STOCK_COPY,
NULL,
NULL,
- N_("Copy selected text to the clipboard"),
- G_CALLBACK (action_copy_cb) },
+ N_("Copy the selection"),
+ NULL }, /* Handled by EFocusTracker */
- { "cut",
+ { "cut-clipboard",
GTK_STOCK_CUT,
NULL,
NULL,
- N_("Cut selected text to the clipboard"),
- G_CALLBACK (action_cut_cb) },
+ N_("Cut the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "delete-selection",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Delete the selection"),
+ NULL }, /* Handled by EFocusTracker */
{ "help",
GTK_STOCK_HELP,
@@ -1016,12 +966,12 @@ static GtkActionEntry core_entries[] = {
N_("Click here to view help available"),
G_CALLBACK (action_help_cb) },
- { "paste",
+ { "paste-clipboard",
GTK_STOCK_PASTE,
NULL,
NULL,
- N_("Paste text from the clipboard"),
- G_CALLBACK (action_paste_cb) },
+ N_("Paste the clipboard"),
+ NULL }, /* Handled by EFocusTracker */
{ "print",
GTK_STOCK_PRINT,
@@ -1047,9 +997,9 @@ static GtkActionEntry core_entries[] = {
{ "select-all",
GTK_STOCK_SELECT_ALL,
NULL,
- NULL,
+ "<Control>a",
N_("Select all text"),
- G_CALLBACK (action_select_all_cb) },
+ NULL }, /* Handled by EFocusTracker */
/* Menus */
@@ -1302,6 +1252,12 @@ comp_editor_get_property (GObject *object,
COMP_EDITOR (object)));
return;
+ case PROP_FOCUS_TRACKER:
+ g_value_set_object (
+ value, comp_editor_get_focus_tracker (
+ COMP_EDITOR (object)));
+ return;
+
case PROP_SHELL:
g_value_set_object (
value, comp_editor_get_shell (
@@ -1331,6 +1287,11 @@ comp_editor_dispose (GObject *object)
priv->shell = NULL;
}
+ if (priv->focus_tracker != NULL) {
+ g_object_unref (priv->focus_tracker);
+ priv->focus_tracker = NULL;
+ }
+
if (priv->window_group != NULL) {
g_object_unref (priv->window_group);
priv->window_group = NULL;
@@ -1566,6 +1527,16 @@ comp_editor_class_init (CompEditorClass *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_SHELL,
g_param_spec_object (
"shell",
@@ -1601,6 +1572,7 @@ comp_editor_init (CompEditor *editor)
CompEditorPrivate *priv;
EAttachmentView *view;
EAttachmentStore *store;
+ EFocusTracker *focus_tracker;
GdkDragAction drag_actions;
GtkTargetList *target_list;
GtkTargetEntry *targets;
@@ -1684,6 +1656,27 @@ comp_editor_init (CompEditor *editor)
priv->ui_manager, action_group, 0);
g_object_unref (action_group);
+ /* Configure an EFocusTracker to manage selection actions. */
+
+ focus_tracker = e_focus_tracker_new (GTK_WINDOW (editor));
+
+ action = comp_editor_get_action (editor, "cut-clipboard");
+ e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "copy-clipboard");
+ e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "paste-clipboard");
+ e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "delete-selection");
+ e_focus_tracker_set_delete_selection_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "select-all");
+ e_focus_tracker_set_select_all_action (focus_tracker, action);
+
+ priv->focus_tracker = focus_tracker;
+
/* Fine Tuning */
action = comp_editor_get_action (editor, "attach");
@@ -2093,6 +2086,14 @@ comp_editor_get_changed (CompEditor *editor)
return editor->priv->changed;
}
+EFocusTracker *
+comp_editor_get_focus_tracker (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->focus_tracker;
+}
+
void
comp_editor_set_flags (CompEditor *editor,
CompEditorFlags flags)
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index 0b3ea047e7..54672ec3b8 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -30,6 +30,7 @@
#include "../itip-utils.h"
#include "comp-editor-page.h"
#include <shell/e-shell.h>
+#include <misc/e-focus-tracker.h>
/* Standard GObject macros */
#define TYPE_COMP_EDITOR \
@@ -92,6 +93,7 @@ GType comp_editor_get_type (void);
void comp_editor_set_changed (CompEditor *editor,
gboolean changed);
gboolean comp_editor_get_changed (CompEditor *editor);
+EFocusTracker * comp_editor_get_focus_tracker (CompEditor *editor);
void comp_editor_set_needs_send (CompEditor *editor,
gboolean needs_send);
gboolean comp_editor_get_needs_send (CompEditor *editor);
diff --git a/calendar/gui/e-cal-list-view.h b/calendar/gui/e-cal-list-view.h
index 0874b73c5b..faf37bbc9f 100644
--- a/calendar/gui/e-cal-list-view.h
+++ b/calendar/gui/e-cal-list-view.h
@@ -27,6 +27,9 @@
#include <time.h>
#include <gtk/gtk.h>
+#include <table/e-table.h>
+#include <table/e-cell-date-edit.h>
+
#include "e-calendar-view.h"
#include "gnome-cal.h"
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index a1495fb005..9ac534e333 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -37,6 +37,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
#include <table/e-cell-text.h>
@@ -248,6 +249,32 @@ calendar_table_model_cal_view_done_cb (ECalendarTable *cal_table,
calendar_table_emit_status_message (cal_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (ECalendarTable *cal_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_calendar_table_get_selected (cal_table);
+
+ status_message = _("Deleting selected objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ for (l = objs; l; l = l->next) {
+ ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+ GError *error = NULL;
+
+ e_cal_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_TODO);
+ g_clear_error (&error);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
static void
calendar_table_set_model (ECalendarTable *cal_table,
ECalModel *model)
@@ -846,6 +873,270 @@ calendar_table_right_click (ETable *table,
}
static void
+calendar_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ ECalendarTable *cal_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (cal_table));
+
+ list = e_calendar_table_get_selected (cal_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+ g_slist_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste tasks from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = TRUE;
+ tooltip = _("Select all visible tasks");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+calendar_table_cut_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (cal_table);
+}
+
+/* Helper for calendar_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ ECalendarTable *cal_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ g_return_if_fail (cal_table->tmp_vcal != NULL);
+
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (!comp_data)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ cal_table->tmp_vcal, comp_data->icalcomp);
+
+ /* Add the new component to the VCALENDAR component. */
+ comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
+ child = icalparser_parse_string (comp_str);
+ if (child) {
+ icalcomponent_add_component (
+ cal_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+calendar_table_copy_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ cal_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (cal_table), copy_row_cb, cal_table);
+ comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (comp_str);
+
+ icalcomponent_free (cal_table->tmp_vcal);
+ cal_table->tmp_vcal = NULL;
+}
+
+/* Helper for calenable_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (ECalendarTable *cal_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECalModel *model;
+ ECal *client;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string (text);
+ if (!icalcomp)
+ return;
+
+ /* check the type of the component */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
+ kind != ICAL_VJOURNAL_COMPONENT) {
+ return;
+ }
+
+ model = e_calendar_table_get_model (cal_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ icalcomponent *vcal_comp;
+
+ vcal_comp = icalcomp;
+ subcomp = icalcomponent_get_first_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ while (subcomp) {
+ child_kind = icalcomponent_isa (subcomp);
+ if (child_kind == ICAL_VEVENT_COMPONENT ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
+ ECalComponent *tmp_comp;
+
+ uid = e_cal_component_gen_uid ();
+ tmp_comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ tmp_comp,
+ icalcomponent_new_clone (subcomp));
+ e_cal_component_set_uid (tmp_comp, uid);
+ free (uid);
+
+ /* FIXME should we convert start/due/complete
+ * times? Also, need error handling. */
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (tmp_comp),
+ NULL, NULL);
+
+ g_object_unref (tmp_comp);
+ }
+ subcomp = icalcomponent_get_next_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ }
+ } else {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (comp, (const gchar *) uid);
+ free (uid);
+
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (comp),
+ NULL, NULL);
+
+ g_object_unref (comp);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+}
+
+static void
+calendar_table_paste_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (cal_table)->table_canvas;
+ item = table_canvas->focused_item;
+
+ /* XXX Should ECellText implement GtkEditable? */
+
+ /* Paste text into a cell being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard) &&
+ GTK_WIDGET_HAS_FOCUS (table_canvas) &&
+ E_IS_TABLE_ITEM (item) &&
+ E_TABLE_ITEM (item)->editing_col >= 0 &&
+ E_TABLE_ITEM (item)->editing_row >= 0) {
+
+ ETableItem *etable_item = E_TABLE_ITEM (item);
+
+ e_cell_text_paste_clipboard (
+ etable_item->cell_views[etable_item->editing_col],
+ etable_item->editing_col,
+ etable_item->editing_row);
+
+ /* Paste iCalendar data into the table. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (cal_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+calendar_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
calendar_table_class_init (ECalendarTableClass *class)
{
GObjectClass *object_class;
@@ -937,6 +1228,16 @@ calendar_table_init (ECalendarTable *cal_table)
cal_table->priv = E_CALENDAR_TABLE_GET_PRIVATE (cal_table);
}
+static void
+calendar_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = calendar_table_update_actions;
+ interface->cut_clipboard = calendar_table_cut_clipboard;
+ interface->copy_clipboard = calendar_table_copy_clipboard;
+ interface->paste_clipboard = calendar_table_paste_clipboard;
+ interface->select_all = calendar_table_select_all;
+}
+
GType
e_calendar_table_get_type (void)
{
@@ -956,8 +1257,17 @@ e_calendar_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) calendar_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "ECalendarTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -1061,32 +1371,6 @@ add_uid_cb (gint model_row, gpointer data)
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-/* Deletes all of the selected components in the table */
-static void
-delete_selected_components (ECalendarTable *cal_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_calendar_table_get_selected (cal_table);
-
- status_message = _("Deleting selected objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- for (l = objs; l; l = l->next) {
- ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
- GError *error = NULL;
-
- e_cal_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp), &error);
- delete_error_dialog (error, E_CAL_COMPONENT_TODO);
- g_clear_error (&error);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
static void
add_retract_data (ECalComponent *comp, const gchar *retract_comment)
{
@@ -1223,210 +1507,6 @@ e_calendar_table_get_selected (ECalendarTable *cal_table)
return closure.objects;
}
-/**
- * e_calendar_table_cut_clipboard:
- * @cal_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_calendar_table_cut_clipboard (ECalendarTable *cal_table)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- e_calendar_table_copy_clipboard (cal_table);
- delete_selected_components (cal_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- cal_table = E_CALENDAR_TABLE (data);
-
- g_return_if_fail (cal_table->tmp_vcal != NULL);
-
- model = e_calendar_table_get_model (cal_table);
- comp_data = e_cal_model_get_component_at (model, model_row);
- if (!comp_data)
- return;
-
- /* add timezones to the VCALENDAR component */
- e_cal_util_add_timezones_from_component (cal_table->tmp_vcal, comp_data->icalcomp);
-
- /* add the new component to the VCALENDAR component */
- comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
- child = icalparser_parse_string (comp_str);
- if (child) {
- icalcomponent_add_component (cal_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_calendar_table_copy_clipboard:
- * @cal_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- /* create temporary VCALENDAR object */
- cal_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (cal_table), copy_row_cb, cal_table);
- comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (cal_table->tmp_vcal);
- g_free (comp_str);
- cal_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECalModel *model;
- ECal *client;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string (text);
- if (!icalcomp)
- return;
-
- /* check the type of the component */
- kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
- return;
- }
-
- model = e_calendar_table_get_model (cal_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent_kind child_kind;
- icalcomponent *subcomp;
- icalcomponent *vcal_comp;
-
- vcal_comp = icalcomp;
- subcomp = icalcomponent_get_first_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- while (subcomp) {
- child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- ECalComponent *tmp_comp;
-
- uid = e_cal_component_gen_uid ();
- tmp_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (
- tmp_comp, icalcomponent_new_clone (subcomp));
- e_cal_component_set_uid (tmp_comp, uid);
- free (uid);
-
- /* FIXME should we convert start/due/complete times? */
- /* FIXME Error handling */
- e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
-
- g_object_unref (tmp_comp);
- }
- subcomp = icalcomponent_get_next_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- }
- } else {
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
- uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (comp, (const gchar *) uid);
- free (uid);
-
- e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
- g_object_unref (comp);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-}
-
-/**
- * e_calendar_table_paste_clipboard:
- * @cal_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (cal_table)->table_canvas;
- item = table_canvas->focused_item;
-
- /* Paste text into a cell being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard) &&
- GTK_WIDGET_HAS_FOCUS (table_canvas) &&
- E_IS_TABLE_ITEM (item) &&
- E_TABLE_ITEM (item)->editing_col >= 0 &&
- E_TABLE_ITEM (item)->editing_row >= 0) {
-
- ETableItem *etable_item = E_TABLE_ITEM (item);
-
- e_cell_text_paste_clipboard (
- etable_item->cell_views[etable_item->editing_col],
- etable_item->editing_col,
- etable_item->editing_row);
-
- /* Paste iCalendar data into the table. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (cal_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
static void
hide_completed_rows (ECalModel *model, GList *clients_list, gchar *hide_sexp, GPtrArray *comp_objects)
{
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index aa98aee7fa..71c7b716f2 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -92,11 +92,6 @@ EShellView * e_calendar_table_get_shell_view (ECalendarTable *cal_table);
void e_calendar_table_delete_selected(ECalendarTable *cal_table);
GSList * e_calendar_table_get_selected (ECalendarTable *cal_table);
-/* Clipboard related functions */
-void e_calendar_table_cut_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_copy_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_paste_clipboard(ECalendarTable *cal_table);
-
ECalModelComponent *
e_calendar_table_get_selected_comp
(ECalendarTable *cal_table);
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index f23088af83..5c04c7848b 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -39,6 +39,7 @@
#include <e-util/e-icon-factory.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-component.h>
+#include <misc/e-selectable.h>
#include <shell/e-shell.h>
#include "common/authentication.h"
@@ -94,10 +95,9 @@ enum {
LAST_SIGNAL
};
+static gpointer parent_class;
static guint signals[LAST_SIGNAL];
-G_DEFINE_TYPE (ECalendarView, e_calendar_view, GTK_TYPE_TABLE)
-
static void
calendar_view_set_model (ECalendarView *calendar_view,
ECalModel *model)
@@ -158,7 +158,7 @@ calendar_view_dispose (GObject *object)
}
/* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
@@ -171,11 +171,352 @@ calendar_view_finalize (GObject *object)
g_free (priv->default_category);
/* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_calendar_view_parent_class)->finalize (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+calendar_view_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ ECalendarView *view;
+ GtkAction *action;
+ GList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ view = E_CALENDAR_VIEW (selectable);
+
+ list = e_calendar_view_get_selected_events (view);
+ n_selected = g_list_length (list);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalendarViewEvent *event = iter->data;
+ gboolean read_only;
+
+ if (event == NULL || event->comp_data == NULL)
+ continue;
+
+ e_cal_is_read_only (event->comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+
+ g_list_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected events to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected events to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste events from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+calendar_view_cut_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GList *selected, *l;
+ const gchar *uid;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ selected = e_calendar_view_get_selected_events (cal_view);
+ if (!selected)
+ return;
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1);
+#endif
+
+ e_selectable_copy_clipboard (selectable);
+
+ for (l = selected; l != NULL; l = l->next) {
+ ECalComponent *comp;
+ ECalendarViewEvent *event = (ECalendarViewEvent *) l->data;
+ GError *error = NULL;
+
+ if (!event)
+ continue;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
+
+ if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp, event->comp_data->client))
+ && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ event->comp_data->client, comp, TRUE))
+ itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
+ event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+
+ e_cal_component_get_uid (comp, &uid);
+ if (e_cal_component_is_instance (comp)) {
+ gchar *rid = NULL;
+ icalcomponent *icalcomp;
+
+ /* when cutting detached instances, only cut that instance */
+ rid = e_cal_component_get_recurid_as_string (comp);
+ if (e_cal_get_object (event->comp_data->client, uid, rid, &icalcomp, NULL)) {
+ e_cal_remove_object_with_mod (event->comp_data->client, uid,
+ rid, CALOBJ_MOD_THIS,
+ &error);
+ icalcomponent_free (icalcomp);
+ } else
+ e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL,
+ CALOBJ_MOD_ALL, &error);
+ g_free (rid);
+ } else
+ e_cal_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_EVENT);
+
+ g_clear_error (&error);
+
+ g_object_unref (comp);
+ }
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
+
+ g_list_free (selected);
+}
+
+static void
+add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client)
+{
+ icalproperty_kind look_in[] = {
+ ICAL_DTSTART_PROPERTY,
+ ICAL_DTEND_PROPERTY,
+ ICAL_NO_PROPERTY
+ };
+ gint i;
+
+ g_return_if_fail (des_icalcomp != NULL);
+ g_return_if_fail (src_icalcomp != NULL);
+ g_return_if_fail (client != NULL);
+
+ for (i = 0; look_in[i] != ICAL_NO_PROPERTY; i++) {
+ icalproperty *prop = icalcomponent_get_first_property (src_icalcomp, look_in[i]);
+
+ if (prop) {
+ icalparameter *par = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
+
+ if (par) {
+ const gchar *tzid = icalparameter_get_tzid (par);
+
+ if (tzid) {
+ GError *error = NULL;
+ icaltimezone *zone = NULL;
+
+ if (!e_cal_get_timezone (client, tzid, &zone, &error)) {
+ g_warning ("%s: Cannot get timezone for '%s'. %s", G_STRFUNC, tzid, error ? error->message : "");
+ if (error)
+ g_error_free (error);
+ } else if (zone &&
+ icalcomponent_get_timezone (des_icalcomp, icaltimezone_get_tzid (zone)) == NULL) {
+ /* do not duplicate timezones in the component */
+ icalcomponent *vtz_comp;
+
+ vtz_comp = icaltimezone_get_component (zone);
+ if (vtz_comp)
+ icalcomponent_add_component (des_icalcomp, icalcomponent_new_clone (vtz_comp));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+calendar_view_copy_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GList *selected, *l;
+ gchar *comp_str;
+ icalcomponent *vcal_comp;
+ icalcomponent *new_icalcomp;
+ ECalendarViewEvent *event;
+ GtkClipboard *clipboard;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ selected = e_calendar_view_get_selected_events (cal_view);
+ if (!selected)
+ return;
+
+ /* create top-level VCALENDAR component and add VTIMEZONE's */
+ vcal_comp = e_cal_util_new_top_level ();
+ for (l = selected; l != NULL; l = l->next) {
+ event = (ECalendarViewEvent *) l->data;
+
+ if (event) {
+ e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp);
+
+ add_related_timezones (vcal_comp, event->comp_data->icalcomp, event->comp_data->client);
+ }
+ }
+
+ for (l = selected; l != NULL; l = l->next) {
+ event = (ECalendarViewEvent *) l->data;
+
+ new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
+
+ /* remove RECURRENCE-IDs from copied objects */
+ if (e_cal_util_component_is_instance (new_icalcomp)) {
+ icalproperty *prop;
+
+ prop = icalcomponent_get_first_property (new_icalcomp, ICAL_RECURRENCEID_PROPERTY);
+ if (prop)
+ icalcomponent_remove_property (new_icalcomp, prop);
+ }
+ icalcomponent_add_component (vcal_comp, new_icalcomp);
+ }
+
+ comp_str = icalcomponent_as_ical_string_r (vcal_comp);
+
+ /* copy the VCALENDAR to the clipboard */
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ /* free memory */
+ icalcomponent_free (vcal_comp);
+ g_free (comp_str);
+ g_list_free (selected);
+}
+
+static void
+clipboard_get_calendar_data (ECalendarView *cal_view,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+ time_t selected_time_start, selected_time_end;
+ icaltimezone *default_zone;
+ ECal *client;
+ gboolean in_top_canvas;
+
+ g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string ((const gchar *) text);
+ if (!icalcomp)
+ return;
+
+ default_zone = calendar_config_get_icaltimezone ();
+ client = e_cal_model_get_default_client (cal_view->priv->model);
+
+ /* check the type of the component */
+ /* FIXME An error dialog if we return? */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
+ return;
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1);
+#endif
+ e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+
+ if ((selected_time_end - selected_time_start) == 60 * 60 * 24)
+ in_top_canvas = TRUE;
+ else
+ in_top_canvas = FALSE;
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent *subcomp;
+
+ /* add timezones first, to have them ready */
+ for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
+ icaltimezone *zone;
+ GError *error = NULL;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ if (!e_cal_add_timezone (client, zone, &error)) {
+ icalproperty *tzidprop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY);
+
+ g_warning ("%s: Add zone '%s' failed. %s", G_STRFUNC, tzidprop ? icalproperty_get_tzid (tzidprop) : "???", error ? error->message : "");
+ if (error)
+ g_error_free (error);
+ }
+
+ icaltimezone_free (zone, 1);
+ }
+
+ for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VEVENT_COMPONENT)) {
+ if (e_cal_util_component_has_recurrences (subcomp)) {
+ icalproperty *icalprop = icalcomponent_get_first_property (subcomp, ICAL_RRULE_PROPERTY);
+ if (icalprop)
+ icalproperty_remove_parameter_by_name (icalprop, "X-EVOLUTION-ENDDATE");
+ }
+
+ e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, subcomp, in_top_canvas);
+ }
+
+ icalcomponent_free (icalcomp);
+ } else {
+ e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas);
+ }
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
+}
+
+static void
+calendar_view_paste_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GtkClipboard *clipboard;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ /* Paste text into an event being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard)) {
+ ECalendarViewClass *class;
+
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_if_fail (class->paste_text != NULL);
+
+ class->paste_text (cal_view);
+
+ /* Paste iCalendar data into the view. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (cal_view, calendar_source);
+ g_free (calendar_source);
+ }
}
static void
-e_calendar_view_class_init (ECalendarViewClass *class)
+calendar_view_class_init (ECalendarViewClass *class)
{
GObjectClass *object_class;
GtkBindingSet *binding_set;
@@ -290,9 +631,7 @@ e_calendar_view_class_init (ECalendarViewClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- /*
- * Key bindings
- */
+ /* Key bindings */
binding_set = gtk_binding_set_by_class (class);
@@ -304,11 +643,56 @@ e_calendar_view_class_init (ECalendarViewClass *class)
}
static void
-e_calendar_view_init (ECalendarView *calendar_view)
+calendar_view_init (ECalendarView *calendar_view)
{
calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view);
}
+static void
+calendar_view_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = calendar_view_update_actions;
+ interface->cut_clipboard = calendar_view_cut_clipboard;
+ interface->copy_clipboard = calendar_view_copy_clipboard;
+ interface->paste_clipboard = calendar_view_paste_clipboard;
+}
+
+GType
+e_calendar_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ECalendarViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) calendar_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalendarView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) calendar_view_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) calendar_view_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "ECalendarView", &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
+ }
+
+ return type;
+}
+
void
e_calendar_view_popup_event (ECalendarView *calendar_view,
GdkEventButton *event)
@@ -586,286 +970,6 @@ e_calendar_view_update_query (ECalendarView *cal_view)
class->update_query (cal_view);
}
-void
-e_calendar_view_cut_clipboard (ECalendarView *cal_view)
-{
- GList *selected, *l;
- const gchar *uid;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1);
-#endif
-
- e_calendar_view_copy_clipboard (cal_view);
- for (l = selected; l != NULL; l = l->next) {
- ECalComponent *comp;
- ECalendarViewEvent *event = (ECalendarViewEvent *) l->data;
- GError *error = NULL;
-
- if (!event)
- continue;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
-
- if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp, event->comp_data->client))
- && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- event->comp_data->client, comp, TRUE))
- itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
- event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
-
- e_cal_component_get_uid (comp, &uid);
- if (e_cal_component_is_instance (comp)) {
- gchar *rid = NULL;
- icalcomponent *icalcomp;
-
- /* when cutting detached instances, only cut that instance */
- rid = e_cal_component_get_recurid_as_string (comp);
- if (e_cal_get_object (event->comp_data->client, uid, rid, &icalcomp, NULL)) {
- e_cal_remove_object_with_mod (event->comp_data->client, uid,
- rid, CALOBJ_MOD_THIS,
- &error);
- icalcomponent_free (icalcomp);
- } else
- e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL,
- CALOBJ_MOD_ALL, &error);
- g_free (rid);
- } else
- e_cal_remove_object (event->comp_data->client, uid, &error);
- delete_error_dialog (error, E_CAL_COMPONENT_EVENT);
-
- g_clear_error (&error);
-
- g_object_unref (comp);
- }
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, NULL, -1);
-#endif
-
- g_list_free (selected);
-}
-
-static void
-add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client)
-{
- icalproperty_kind look_in[] = {
- ICAL_DTSTART_PROPERTY,
- ICAL_DTEND_PROPERTY,
- ICAL_NO_PROPERTY
- };
- gint i;
-
- g_return_if_fail (des_icalcomp != NULL);
- g_return_if_fail (src_icalcomp != NULL);
- g_return_if_fail (client != NULL);
-
- for (i = 0; look_in[i] != ICAL_NO_PROPERTY; i++) {
- icalproperty *prop = icalcomponent_get_first_property (src_icalcomp, look_in[i]);
-
- if (prop) {
- icalparameter *par = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
-
- if (par) {
- const gchar *tzid = icalparameter_get_tzid (par);
-
- if (tzid) {
- GError *error = NULL;
- icaltimezone *zone = NULL;
-
- if (!e_cal_get_timezone (client, tzid, &zone, &error)) {
- g_warning ("%s: Cannot get timezone for '%s'. %s", G_STRFUNC, tzid, error ? error->message : "");
- if (error)
- g_error_free (error);
- } else if (zone &&
- icalcomponent_get_timezone (des_icalcomp, icaltimezone_get_tzid (zone)) == NULL) {
- /* do not duplicate timezones in the component */
- icalcomponent *vtz_comp;
-
- vtz_comp = icaltimezone_get_component (zone);
- if (vtz_comp)
- icalcomponent_add_component (des_icalcomp, icalcomponent_new_clone (vtz_comp));
- }
- }
- }
- }
- }
-}
-
-void
-e_calendar_view_copy_clipboard (ECalendarView *cal_view)
-{
- GList *selected, *l;
- gchar *comp_str;
- icalcomponent *vcal_comp;
- icalcomponent *new_icalcomp;
- ECalendarViewEvent *event;
- GtkClipboard *clipboard;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- /* create top-level VCALENDAR component and add VTIMEZONE's */
- vcal_comp = e_cal_util_new_top_level ();
- for (l = selected; l != NULL; l = l->next) {
- event = (ECalendarViewEvent *) l->data;
-
- if (event) {
- e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp);
-
- add_related_timezones (vcal_comp, event->comp_data->icalcomp, event->comp_data->client);
- }
- }
-
- for (l = selected; l != NULL; l = l->next) {
- event = (ECalendarViewEvent *) l->data;
-
- new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
-
- /* remove RECURRENCE-IDs from copied objects */
- if (e_cal_util_component_is_instance (new_icalcomp)) {
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (new_icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop)
- icalcomponent_remove_property (new_icalcomp, prop);
- }
- icalcomponent_add_component (vcal_comp, new_icalcomp);
- }
-
- comp_str = icalcomponent_as_ical_string_r (vcal_comp);
-
- /* copy the VCALENDAR to the clipboard */
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (vcal_comp);
- g_free (comp_str);
- g_list_free (selected);
-}
-
-static void
-clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text)
-{
- icalcomponent *icalcomp;
- icalcomponent_kind kind;
- time_t selected_time_start, selected_time_end;
- icaltimezone *default_zone;
- ECal *client;
- gboolean in_top_canvas;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string ((const gchar *) text);
- if (!icalcomp)
- return;
-
- default_zone = calendar_config_get_icaltimezone ();
- client = e_cal_model_get_default_client (cal_view->priv->model);
-
- /* check the type of the component */
- /* FIXME An error dialog if we return? */
- kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
- return;
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1);
-#endif
- e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
-
- if ((selected_time_end - selected_time_start) == 60 * 60 * 24)
- in_top_canvas = TRUE;
- else
- in_top_canvas = FALSE;
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent *subcomp;
-
- /* add timezones first, to have them ready */
- for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
- subcomp;
- subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
- icaltimezone *zone;
- GError *error = NULL;
-
- zone = icaltimezone_new ();
- icaltimezone_set_component (zone, subcomp);
- if (!e_cal_add_timezone (client, zone, &error)) {
- icalproperty *tzidprop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY);
-
- g_warning ("%s: Add zone '%s' failed. %s", G_STRFUNC, tzidprop ? icalproperty_get_tzid (tzidprop) : "???", error ? error->message : "");
- if (error)
- g_error_free (error);
- }
-
- icaltimezone_free (zone, 1);
- }
-
- for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT);
- subcomp;
- subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VEVENT_COMPONENT)) {
- if (e_cal_util_component_has_recurrences (subcomp)) {
- icalproperty *icalprop = icalcomponent_get_first_property (subcomp, ICAL_RRULE_PROPERTY);
- if (icalprop)
- icalproperty_remove_parameter_by_name (icalprop, "X-EVOLUTION-ENDDATE");
- }
-
- e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, subcomp, in_top_canvas);
- }
-
- icalcomponent_free (icalcomp);
- } else {
- e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas);
- }
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, NULL, -1);
-#endif
-}
-
-void
-e_calendar_view_paste_clipboard (ECalendarView *cal_view)
-{
- GtkClipboard *clipboard;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- /* Paste text into an event being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard)) {
- ECalendarViewClass *class;
-
- class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
- g_return_if_fail (class->paste_text != NULL);
-
- class->paste_text (cal_view);
-
- /* Paste iCalendar data into the view. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (cal_view, calendar_source);
- g_free (calendar_source);
- }
-}
-
static void
add_retract_data (ECalComponent *comp, const gchar *retract_comment, CalObjModType mod)
{
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index 7ae643a707..a7ed224fcb 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -174,9 +174,6 @@ gboolean e_calendar_view_get_visible_time_range
time_t *end_time);
void e_calendar_view_update_query (ECalendarView *cal_view);
-void e_calendar_view_cut_clipboard (ECalendarView *cal_view);
-void e_calendar_view_copy_clipboard (ECalendarView *cal_view);
-void e_calendar_view_paste_clipboard (ECalendarView *cal_view);
void e_calendar_view_delete_selected_event
(ECalendarView *cal_view);
void e_calendar_view_delete_selected_events
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index 6b34018fe7..16be4ffc89 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -33,6 +33,7 @@
#include <e-calendar-view.h>
#include "e-util/e-categories-config.h"
+#include "e-util/e-util.h"
#include "e-day-view-layout.h"
#include "e-day-view-main-item.h"
#include "ea-calendar.h"
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 977715898e..4df17c5487 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -36,7 +36,8 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <e-util/e-binding.h>
-#include <widgets/misc/e-gui-utils.h>
+#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
#include <table/e-cell-text.h>
@@ -181,6 +182,33 @@ memo_table_model_cal_view_done_cb (EMemoTable *memo_table,
memo_table_emit_status_message (memo_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (EMemoTable *memo_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_memo_table_get_selected (memo_table);
+
+ status_message = _("Deleting selected objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
+
+ for (l = objs; l; l = l->next) {
+ ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+ GError *error = NULL;
+
+ e_cal_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL);
+ g_clear_error (&error);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
+
static void
memo_table_set_model (EMemoTable *memo_table,
ECalModel *model)
@@ -629,6 +657,270 @@ memo_table_right_click (ETable *table,
}
static void
+memo_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ EMemoTable *memo_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ memo_table = E_MEMO_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (memo_table));
+
+ list = e_memo_table_get_selected (memo_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+ g_slist_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected memos to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected memos to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste memos from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = TRUE;
+ tooltip = _("Select all visible memos");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+memo_table_cut_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (memo_table);
+}
+
+/* Helper for memo_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ memo_table = E_MEMO_TABLE (data);
+
+ g_return_if_fail (memo_table->tmp_vcal != NULL);
+
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (comp_data == NULL)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ memo_table->tmp_vcal, comp_data->icalcomp);
+
+ /* Add the new component to the VCALENDAR component. */
+ comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
+ child = icalparser_parse_string (comp_str);
+ if (child) {
+ icalcomponent_add_component (
+ memo_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+memo_table_copy_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ memo_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (memo_table), copy_row_cb, memo_table);
+ comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (comp_str);
+
+ icalcomponent_free (memo_table->tmp_vcal);
+ memo_table->tmp_vcal = NULL;
+}
+
+/* Helper for memo_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (EMemoTable *memo_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECal *client;
+ ECalModel *model;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string (text);
+ if (!icalcomp)
+ return;
+
+ /* check the type of the component */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
+ kind != ICAL_VJOURNAL_COMPONENT) {
+ return;
+ }
+
+ model = e_memo_table_get_model (memo_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ icalcomponent *vcal_comp;
+
+ vcal_comp = icalcomp;
+ subcomp = icalcomponent_get_first_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ while (subcomp) {
+ child_kind = icalcomponent_isa (subcomp);
+ if (child_kind == ICAL_VEVENT_COMPONENT ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
+ ECalComponent *tmp_comp;
+
+ uid = e_cal_component_gen_uid ();
+ tmp_comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ tmp_comp,
+ icalcomponent_new_clone (subcomp));
+ e_cal_component_set_uid (tmp_comp, uid);
+ free (uid);
+
+ /* FIXME Should we convert start/due/complete
+ * times? Also, need error handling.*/
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (tmp_comp),
+ NULL, NULL);
+
+ g_object_unref (tmp_comp);
+ }
+ subcomp = icalcomponent_get_next_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ }
+ } else {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (comp, (const gchar *) uid);
+ free (uid);
+
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (comp),
+ NULL, NULL);
+
+ g_object_unref (comp);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+}
+
+static void
+memo_table_paste_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (memo_table)->table_canvas;
+ item = table_canvas->focused_item;
+
+ /* XXX Should ECellText implement GtkEditable? */
+
+ /* Paste text into a cell being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard) &&
+ GTK_WIDGET_HAS_FOCUS (table_canvas) &&
+ E_IS_TABLE_ITEM (item) &&
+ E_TABLE_ITEM (item)->editing_col >= 0 &&
+ E_TABLE_ITEM (item)->editing_row >= 0) {
+
+ ETableItem *etable_item = E_TABLE_ITEM (item);
+
+ e_cell_text_paste_clipboard (
+ etable_item->cell_views[etable_item->editing_col],
+ etable_item->editing_col,
+ etable_item->editing_row);
+
+ /* Paste iCalendar data into the table. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (memo_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+memo_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
memo_table_class_init (EMemoTableClass *class)
{
GObjectClass *object_class;
@@ -720,6 +1012,16 @@ memo_table_init (EMemoTable *memo_table)
memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table);
}
+static void
+memo_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = memo_table_update_actions;
+ interface->cut_clipboard = memo_table_cut_clipboard;
+ interface->copy_clipboard = memo_table_copy_clipboard;
+ interface->paste_clipboard = memo_table_paste_clipboard;
+ interface->select_all = memo_table_select_all;
+}
+
GType
e_memo_table_get_type (void)
{
@@ -739,8 +1041,17 @@ e_memo_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) memo_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "EMemoTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -847,33 +1158,6 @@ add_uid_cb (gint model_row, gpointer data)
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-/* Deletes all of the selected components in the table */
-static void
-delete_selected_components (EMemoTable *memo_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_memo_table_get_selected (memo_table);
-
- status_message = _("Deleting selected objects");
- memo_table_emit_status_message (memo_table, status_message, -1.0);
-
- for (l = objs; l; l = l->next) {
- ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
- GError *error = NULL;
-
- e_cal_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp), &error);
- delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL);
- g_clear_error (&error);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
-
/**
* e_memo_table_delete_selected:
* @memo_table: A memo table.
@@ -938,210 +1222,6 @@ e_memo_table_get_selected (EMemoTable *memo_table)
return closure.objects;
}
-/**
- * e_memo_table_cut_clipboard:
- * @memo_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_memo_table_cut_clipboard (EMemoTable *memo_table)
-{
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- e_memo_table_copy_clipboard (memo_table);
- delete_selected_components (memo_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- EMemoTable *memo_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- memo_table = E_MEMO_TABLE (data);
-
- g_return_if_fail (memo_table->tmp_vcal != NULL);
-
- model = e_memo_table_get_model (memo_table);
- comp_data = e_cal_model_get_component_at (model, model_row);
- if (!comp_data)
- return;
-
- /* add timezones to the VCALENDAR component */
- e_cal_util_add_timezones_from_component (memo_table->tmp_vcal, comp_data->icalcomp);
-
- /* add the new component to the VCALENDAR component */
- comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
- child = icalparser_parse_string (comp_str);
- if (child) {
- icalcomponent_add_component (memo_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_memo_table_copy_clipboard:
- * @memo_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_memo_table_copy_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- /* create temporary VCALENDAR object */
- memo_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (memo_table), copy_row_cb, memo_table);
- comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (memo_table->tmp_vcal);
- g_free (comp_str);
- memo_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECal *client;
- ECalModel *model;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string (text);
- if (!icalcomp)
- return;
-
- /* check the type of the component */
- kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
- return;
- }
-
- model = e_memo_table_get_model (memo_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- memo_table_emit_status_message (memo_table, status_message, -1.0);
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent_kind child_kind;
- icalcomponent *subcomp;
- icalcomponent *vcal_comp;
-
- vcal_comp = icalcomp;
- subcomp = icalcomponent_get_first_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- while (subcomp) {
- child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- ECalComponent *tmp_comp;
-
- uid = e_cal_component_gen_uid ();
- tmp_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (
- tmp_comp, icalcomponent_new_clone (subcomp));
- e_cal_component_set_uid (tmp_comp, uid);
- free (uid);
-
- /* FIXME should we convert start/due/complete times? */
- /* FIXME Error handling */
- e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
-
- g_object_unref (tmp_comp);
- }
- subcomp = icalcomponent_get_next_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- }
- } else {
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
- uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (comp, (const gchar *) uid);
- free (uid);
-
- e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
- g_object_unref (comp);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-}
-
-/**
- * e_memo_table_paste_clipboard:
- * @memo_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_memo_table_paste_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (memo_table)->table_canvas;
- item = table_canvas->focused_item;
-
- /* Paste text into a cell being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard) &&
- GTK_WIDGET_HAS_FOCUS (table_canvas) &&
- E_IS_TABLE_ITEM (item) &&
- E_TABLE_ITEM (item)->editing_col >= 0 &&
- E_TABLE_ITEM (item)->editing_row >= 0) {
-
- ETableItem *etable_item = E_TABLE_ITEM (item);
-
- e_cell_text_paste_clipboard (
- etable_item->cell_views[etable_item->editing_col],
- etable_item->editing_col,
- etable_item->editing_row);
-
- /* Paste iCalendar data into the table. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (memo_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
/* Returns the current time, for the ECellDateEdit items.
FIXME: Should probably use the timezone of the item rather than the
current timezone, though that may be difficult to get from here. */
diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h
index 4d4347db4a..b55ddc5e66 100644
--- a/calendar/gui/e-memo-table.h
+++ b/calendar/gui/e-memo-table.h
@@ -106,11 +106,6 @@ void e_memo_table_set_use_24_hour_format
void e_memo_table_delete_selected (EMemoTable *memo_table);
GSList * e_memo_table_get_selected (EMemoTable *memo_table);
-/* Clipboard related functions */
-void e_memo_table_cut_clipboard (EMemoTable *memo_table);
-void e_memo_table_copy_clipboard (EMemoTable *memo_table);
-void e_memo_table_paste_clipboard (EMemoTable *memo_table);
-
G_END_DECLS
#endif /* _E_MEMO_TABLE_H_ */
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 0cc528fe3c..197396dbd6 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -33,7 +33,7 @@
#include <libecal/e-cal.h>
#include <shell/e-shell-settings.h>
-#include "e-calendar-table.h"
+#include "e-cal-model.h"
/* Standard GObject macros */
#define GNOME_TYPE_CALENDAR \
diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c
index 86f06f32dc..569c15f38f 100644
--- a/calendar/gui/goto.c
+++ b/calendar/gui/goto.c
@@ -26,6 +26,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
#include "calendar-config.h"
#include "tag-calendar.h"
diff --git a/calendar/gui/print.h b/calendar/gui/print.h
index 39d5608222..5217c473a1 100644
--- a/calendar/gui/print.h
+++ b/calendar/gui/print.h
@@ -25,6 +25,7 @@
#ifndef PRINT_H
#define PRINT_H
+#include <table/e-table.h>
#include "calendar/gui/gnome-cal.h"
typedef enum {
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index d16afa32f0..8dfdeeb4b0 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -83,12 +83,13 @@ composer_setup_recent_menu (EMsgComposer *composer)
}
void
-e_composer_private_init (EMsgComposer *composer)
+e_composer_private_constructed (EMsgComposer *composer)
{
EMsgComposerPrivate *priv = composer->priv;
-
+ EFocusTracker *focus_tracker;
GtkhtmlEditor *editor;
GtkUIManager *ui_manager;
+ GtkAction *action;
GtkWidget *container;
GtkWidget *widget;
GtkWidget *send_widget;
@@ -157,6 +158,24 @@ e_composer_private_init (EMsgComposer *composer)
g_clear_error (&error);
}
+ /* Configure an EFocusTracker to manage selection actions. */
+
+ focus_tracker = e_focus_tracker_new (GTK_WINDOW (composer));
+
+ action = gtkhtml_editor_get_action (editor, "cut");
+ e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
+
+ action = gtkhtml_editor_get_action (editor, "copy");
+ e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
+
+ action = gtkhtml_editor_get_action (editor, "paste");
+ e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
+
+ action = gtkhtml_editor_get_action (editor, "select-all");
+ e_focus_tracker_set_select_all_action (focus_tracker, action);
+
+ priv->focus_tracker = focus_tracker;
+
/* Construct the header table. */
container = editor->vbox;
@@ -314,6 +333,11 @@ e_composer_private_dispose (EMsgComposer *composer)
composer->priv->attachment_paned = NULL;
}
+ if (composer->priv->focus_tracker != NULL) {
+ g_object_unref (composer->priv->focus_tracker);
+ composer->priv->focus_tracker = NULL;
+ }
+
if (composer->priv->window_group != NULL) {
g_object_unref (composer->priv->window_group);
composer->priv->window_group = NULL;
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index 54837b9093..bab8dd160a 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -94,6 +94,7 @@ struct _EMsgComposerPrivate {
GtkWidget *header_table;
GtkWidget *attachment_paned;
+ EFocusTracker *focus_tracker;
GtkWindowGroup *window_group;
GtkActionGroup *charset_actions;
@@ -130,7 +131,7 @@ struct _EMsgComposerPrivate {
gboolean mail_sent;
};
-void e_composer_private_init (EMsgComposer *composer);
+void e_composer_private_constructed (EMsgComposer *composer);
void e_composer_private_dispose (EMsgComposer *composer);
void e_composer_private_finalize (EMsgComposer *composer);
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 6477936011..eed3893d95 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -55,6 +55,7 @@
#include "shell/e-shell.h"
#include "em-format/em-format.h"
#include "em-format/em-format-quote.h"
+#include "misc/e-web-view.h"
#include <camel/camel-charset-map.h>
#include <camel/camel-cipher-context.h>
@@ -92,6 +93,11 @@
((obj), E_TYPE_MSG_COMPOSER, EMsgComposerPrivate))
enum {
+ PROP_0,
+ PROP_FOCUS_TRACKER
+};
+
+enum {
SEND,
SAVE_DRAFT,
PRINT,
@@ -118,6 +124,14 @@ static void handle_multipart_alternative (EMsgComposer *composer, CamelMultipart
static void handle_multipart_encrypted (EMsgComposer *composer, CamelMimePart *multipart, gint depth);
static void handle_multipart_signed (EMsgComposer *composer, CamelMultipart *multipart, gint depth);
+static void msg_composer_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection,
+ guint info,
+ guint time);
+
/**
* emcu_part_to_html:
* @part:
@@ -1514,32 +1528,90 @@ msg_composer_notify_header_cb (EMsgComposer *composer)
gtkhtml_editor_set_changed (editor, TRUE);
}
-static GObject *
-msg_composer_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
+static void
+msg_composer_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FOCUS_TRACKER:
+ g_value_set_object (
+ value, e_msg_composer_get_focus_tracker (
+ E_MSG_COMPOSER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+msg_composer_dispose (GObject *object)
+{
+ EMsgComposer *composer = E_MSG_COMPOSER (object);
+
+ e_composer_private_dispose (composer);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+msg_composer_finalize (GObject *object)
+{
+ EMsgComposer *composer = E_MSG_COMPOSER (object);
+
+ e_composer_autosave_unregister (composer);
+ e_composer_private_finalize (composer);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+msg_composer_constructed (GObject *object)
{
EShell *shell;
EShellSettings *shell_settings;
- GObject *object;
+ GtkhtmlEditor *editor;
EMsgComposer *composer;
+ EAttachmentView *view;
+ EAttachmentStore *store;
+ EComposerHeaderTable *table;
+ GdkDragAction drag_actions;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ GtkUIManager *ui_manager;
GtkToggleAction *action;
+ GtkHTML *html;
GArray *array;
+ const gchar *id;
gboolean active;
guint binding_id;
+ gint n_targets;
- /* Chain up to parent's constructor() method. */
- object = G_OBJECT_CLASS (parent_class)->constructor (
- type, n_construct_properties, construct_properties);
-
+ editor = GTKHTML_EDITOR (object);
composer = E_MSG_COMPOSER (object);
- array = composer->priv->gconf_bridge_binding_ids;
shell = e_shell_get_default ();
shell_settings = e_shell_get_shell_settings (shell);
+ e_composer_private_constructed (composer);
+
+ html = gtkhtml_editor_get_html (editor);
+ ui_manager = gtkhtml_editor_get_ui_manager (editor);
+ view = e_msg_composer_get_attachment_view (composer);
+ table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table);
+
+ gtk_window_set_title (GTK_WINDOW (composer), _("Compose Message"));
+ gtk_window_set_icon_name (GTK_WINDOW (composer), "mail-message-new");
+
+ e_shell_watch_window (shell, GTK_WINDOW (object));
+
/* Restore Persistent State */
+ array = composer->priv->gconf_bridge_binding_ids;
+
binding_id = gconf_bridge_bind_property (
gconf_bridge_get (),
COMPOSER_GCONF_CURRENT_FOLDER_KEY,
@@ -1563,32 +1635,77 @@ msg_composer_constructor (GType type,
shell_settings, "composer-request-receipt");
gtk_toggle_action_set_active (action, active);
- e_shell_watch_window (shell, GTK_WINDOW (object));
+ /* Drag-and-Drop Support */
- return object;
-}
+ target_list = e_attachment_view_get_target_list (view);
+ drag_actions = e_attachment_view_get_drag_actions (view);
-static void
-msg_composer_dispose (GObject *object)
-{
- EMsgComposer *composer = E_MSG_COMPOSER (object);
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
- e_composer_private_dispose (composer);
+ gtk_drag_dest_set (
+ GTK_WIDGET (composer), GTK_DEST_DEFAULT_ALL,
+ targets, n_targets, drag_actions);
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
+ g_signal_connect (
+ html, "drag-data-received",
+ G_CALLBACK (msg_composer_drag_data_received), NULL);
-static void
-msg_composer_finalize (GObject *object)
-{
- EMsgComposer *composer = E_MSG_COMPOSER (object);
+ gtk_target_table_free (targets, n_targets);
- e_composer_autosave_unregister (composer);
- e_composer_private_finalize (composer);
+ /* Configure Headers */
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ e_composer_header_table_set_account_list (
+ table, e_get_account_list ());
+ e_composer_header_table_set_signature_list (
+ table, e_get_signature_list ());
+
+ g_signal_connect_swapped (
+ table, "notify::account",
+ G_CALLBACK (msg_composer_account_changed_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::destinations-bcc",
+ G_CALLBACK (msg_composer_notify_header_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::destinations-cc",
+ G_CALLBACK (msg_composer_notify_header_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::destinations-to",
+ G_CALLBACK (msg_composer_notify_header_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::reply-to",
+ G_CALLBACK (msg_composer_notify_header_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::signature",
+ G_CALLBACK (e_msg_composer_show_sig_file), composer);
+ g_signal_connect_swapped (
+ table, "notify::subject",
+ G_CALLBACK (msg_composer_subject_changed_cb), composer);
+ g_signal_connect_swapped (
+ table, "notify::subject",
+ G_CALLBACK (msg_composer_notify_header_cb), composer);
+
+ msg_composer_account_changed_cb (composer);
+
+ /* Attachments */
+
+ store = e_attachment_view_get_store (view);
+
+ g_signal_connect_swapped (
+ store, "row-deleted",
+ G_CALLBACK (attachment_store_changed_cb), composer);
+
+ g_signal_connect_swapped (
+ store, "row-inserted",
+ G_CALLBACK (attachment_store_changed_cb), composer);
+
+ e_composer_autosave_register (composer);
+
+ /* Initialization may have tripped the "changed" state. */
+ gtkhtml_editor_set_changed (editor, FALSE);
+
+ id = "org.gnome.evolution.composer";
+ e_plugin_ui_register_manager (ui_manager, id, composer);
+ e_plugin_ui_enable_manager (ui_manager, id);
}
static void
@@ -2045,9 +2162,10 @@ msg_composer_class_init (EMsgComposerClass *class)
g_type_class_add_private (class, sizeof (EMsgComposerPrivate));
object_class = G_OBJECT_CLASS (class);
- object_class->constructor = msg_composer_constructor;
+ object_class->get_property = msg_composer_get_property;
object_class->dispose = msg_composer_dispose;
object_class->finalize = msg_composer_finalize;
+ object_class->constructed = msg_composer_constructed;
gtk_object_class = GTK_OBJECT_CLASS (class);
gtk_object_class->destroy = msg_composer_destroy;
@@ -2071,6 +2189,16 @@ msg_composer_class_init (EMsgComposerClass *class)
editor_class->object_deleted = msg_composer_object_deleted;
editor_class->uri_requested = msg_composer_uri_requested;
+ 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));
+
signals[SEND] = g_signal_new (
"send",
G_OBJECT_CLASS_TYPE (class),
@@ -2100,103 +2228,8 @@ msg_composer_class_init (EMsgComposerClass *class)
static void
msg_composer_init (EMsgComposer *composer)
{
- EAttachmentView *view;
- EAttachmentStore *store;
- EComposerHeaderTable *table;
- GdkDragAction drag_actions;
- GtkTargetList *target_list;
- GtkTargetEntry *targets;
- GtkUIManager *ui_manager;
- GtkhtmlEditor *editor;
- GtkHTML *html;
- const gchar *id;
- gint n_targets;
-
composer->lite = composer_lite;
composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
-
- e_composer_private_init (composer);
-
- editor = GTKHTML_EDITOR (composer);
- html = gtkhtml_editor_get_html (editor);
- ui_manager = gtkhtml_editor_get_ui_manager (editor);
- view = e_msg_composer_get_attachment_view (composer);
- table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table);
-
- gtk_window_set_title (GTK_WINDOW (composer), _("Compose Message"));
- gtk_window_set_icon_name (GTK_WINDOW (composer), "mail-message-new");
-
- /* Drag-and-Drop Support */
-
- target_list = e_attachment_view_get_target_list (view);
- drag_actions = e_attachment_view_get_drag_actions (view);
-
- targets = gtk_target_table_new_from_list (target_list, &n_targets);
-
- gtk_drag_dest_set (
- GTK_WIDGET (composer), GTK_DEST_DEFAULT_ALL,
- targets, n_targets, drag_actions);
-
- g_signal_connect (
- html, "drag-data-received",
- G_CALLBACK (msg_composer_drag_data_received), NULL);
-
- gtk_target_table_free (targets, n_targets);
-
- /* Configure Headers */
-
- e_composer_header_table_set_account_list (
- table, e_get_account_list ());
- e_composer_header_table_set_signature_list (
- table, e_get_signature_list ());
-
- g_signal_connect_swapped (
- table, "notify::account",
- G_CALLBACK (msg_composer_account_changed_cb), composer);
- g_signal_connect_swapped (
- table, "notify::destinations-bcc",
- G_CALLBACK (msg_composer_notify_header_cb), composer);
- g_signal_connect_swapped (
- table, "notify::destinations-cc",
- G_CALLBACK (msg_composer_notify_header_cb), composer);
- g_signal_connect_swapped (
- table, "notify::destinations-to",
- G_CALLBACK (msg_composer_notify_header_cb), composer);
- g_signal_connect_swapped (
- table, "notify::reply-to",
- G_CALLBACK (msg_composer_notify_header_cb), composer);
- g_signal_connect_swapped (
- table, "notify::signature",
- G_CALLBACK (e_msg_composer_show_sig_file), composer);
- g_signal_connect_swapped (
- table, "notify::subject",
- G_CALLBACK (msg_composer_subject_changed_cb), composer);
- g_signal_connect_swapped (
- table, "notify::subject",
- G_CALLBACK (msg_composer_notify_header_cb), composer);
-
- msg_composer_account_changed_cb (composer);
-
- /* Attachments */
-
- store = e_attachment_view_get_store (view);
-
- g_signal_connect_swapped (
- store, "row-deleted",
- G_CALLBACK (attachment_store_changed_cb), composer);
-
- g_signal_connect_swapped (
- store, "row-inserted",
- G_CALLBACK (attachment_store_changed_cb), composer);
-
- e_composer_autosave_register (composer);
-
- /* Initialization may have tripped the "changed" state. */
- gtkhtml_editor_set_changed (editor, FALSE);
-
- id = "org.gnome.evolution.composer";
- e_plugin_ui_register_manager (ui_manager, id, composer);
- e_plugin_ui_enable_manager (ui_manager, id);
}
GType
@@ -2237,7 +2270,9 @@ e_msg_composer_get_type (void)
EMsgComposer *
e_msg_composer_new (void)
{
- return g_object_new (E_TYPE_MSG_COMPOSER, NULL);
+ return g_object_new (
+ E_TYPE_MSG_COMPOSER,
+ "html", e_web_view_new (), NULL);
}
void
@@ -2265,6 +2300,14 @@ e_msg_composer_lite_new (void)
return composer;
}
+EFocusTracker *
+e_msg_composer_get_focus_tracker (EMsgComposer *composer)
+{
+ g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
+
+ return composer->priv->focus_tracker;
+}
+
static void
e_msg_composer_set_pending_body (EMsgComposer *composer,
gchar *text,
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index 74128e0c0f..c55237ce52 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -31,6 +31,7 @@
#include <libebook/e-destination.h>
#include <gtkhtml-editor.h>
#include <misc/e-attachment-view.h>
+#include <misc/e-focus-tracker.h>
#include "e-composer-header-table.h"
@@ -78,6 +79,7 @@ EMsgComposer * e_msg_composer_new_with_message (CamelMimeMessage *msg);
EMsgComposer * e_msg_composer_new_from_url (const gchar *url);
EMsgComposer * e_msg_composer_new_redirect (CamelMimeMessage *message,
const gchar *resent_from);
+EFocusTracker * e_msg_composer_get_focus_tracker(EMsgComposer *composer);
CamelSession * e_msg_composer_get_session (EMsgComposer *composer);
void e_msg_composer_send (EMsgComposer *composer);
diff --git a/configure.ac b/configure.ac
index 1d97d640a2..ecf88edd00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ m4_define([gtk_minimum_version], [2.16.0])
m4_define([eds_minimum_version], [evo_version])
m4_define([gnome_icon_theme_minimum_version], [2.19.91])
m4_define([gnome_desktop_minimum_version], [2.26.0])
-m4_define([libgtkhtml_minimum_version], [3.29.2])
+m4_define([libgtkhtml_minimum_version], [3.29.5])
m4_define([gconf_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libgnomecanvas_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libxml_minimum_version], [2.7.3])
diff --git a/doc/reference/shell/tmpl/e-shell-window.sgml b/doc/reference/shell/tmpl/e-shell-window.sgml
index 33a5928476..89da4a143c 100644
--- a/doc/reference/shell/tmpl/e-shell-window.sgml
+++ b/doc/reference/shell/tmpl/e-shell-window.sgml
@@ -28,6 +28,11 @@ EShellWindow
</para>
+<!-- ##### ARG EShellWindow:focus-tracker ##### -->
+<para>
+
+</para>
+
<!-- ##### ARG EShellWindow:geometry ##### -->
<para>
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 6dae4ded13..9b7cc4d887 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -166,19 +166,6 @@ action_mail_check_for_junk_cb (GtkAction *action,
}
static void
-action_mail_clipboard_copy_cb (GtkAction *action,
- EMailReader *reader)
-{
- EMFormatHTMLDisplay *html_display;
- EWebView *web_view;
-
- html_display = e_mail_reader_get_html_display (reader);
- web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
-
- e_web_view_clipboard_copy (web_view);
-}
-
-static void
action_mail_copy_cb (GtkAction *action,
EMailReader *reader)
{
@@ -875,26 +862,6 @@ action_mail_search_folder_from_subject_cb (GtkAction *action,
}
static void
-action_mail_select_all_cb (GtkAction *action,
- EMailReader *reader)
-{
- EMFormatHTMLDisplay *html_display;
- EWebView *web_view;
- const gchar *action_name;
- gboolean selection_active;
-
- html_display = e_mail_reader_get_html_display (reader);
- web_view = E_WEB_VIEW (EM_FORMAT_HTML (html_display)->html);
-
- e_web_view_select_all (web_view);
-
- action_name = "mail-clipboard-copy";
- action = e_mail_reader_get_action (reader, action_name);
- selection_active = e_web_view_is_selection_active (web_view);
- gtk_action_set_sensitive (action, selection_active);
-}
-
-static void
action_mail_show_all_headers_cb (GtkToggleAction *action,
EMailReader *reader)
{
@@ -1112,13 +1079,6 @@ static GtkActionEntry mail_reader_entries[] = {
N_("Filter the selected messages for junk status"),
G_CALLBACK (action_mail_check_for_junk_cb) },
- { "mail-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy selected messages to the clipboard"),
- G_CALLBACK (action_mail_clipboard_copy_cb) },
-
{ "mail-copy",
"mail-copy",
N_("_Copy to Folder..."),
@@ -1441,13 +1401,6 @@ static GtkActionEntry mail_reader_entries[] = {
N_("Create a search folder for this subject"),
G_CALLBACK (action_mail_search_folder_from_subject_cb) },
- { "mail-select-all",
- NULL,
- N_("Select _All Text"),
- "<Shift><Control>x",
- N_("Select all the text in a message"),
- G_CALLBACK (action_mail_select_all_cb) },
-
{ "mail-show-source",
NULL,
N_("_Message Source"),
@@ -1544,10 +1497,6 @@ static GtkActionEntry mail_reader_entries[] = {
static EPopupActionEntry mail_reader_popup_entries[] = {
- { "mail-popup-clipboard-copy",
- NULL,
- "mail-clipboard-copy" },
-
{ "mail-popup-copy",
NULL,
"mail-copy" },
@@ -1644,25 +1593,6 @@ static GtkToggleActionEntry mail_reader_toggle_entries[] = {
FALSE }
};
-static gboolean
-mail_reader_button_release_event_cb (EMailReader *reader,
- GdkEventButton *button,
- GtkHTML *html)
-{
- GtkAction *action;
- EWebView *web_view;
- const gchar *action_name;
- gboolean selection_active;
-
- web_view = E_WEB_VIEW (html);
- action_name = "mail-clipboard-copy";
- action = e_mail_reader_get_action (reader, action_name);
- selection_active = e_web_view_is_selection_active (web_view);
- gtk_action_set_sensitive (action, selection_active);
-
- return FALSE;
-}
-
static void
mail_reader_double_click_cb (EMailReader *reader,
gint row,
@@ -2377,11 +2307,6 @@ mail_reader_update_actions (EMailReader *reader)
action = e_mail_reader_get_action (reader, action_name);
gtk_action_set_sensitive (action, sensitive);
- action_name = "mail-select-all";
- sensitive = single_message_selected;
- action = e_mail_reader_get_action (reader, action_name);
- gtk_action_set_sensitive (action, sensitive);
-
action_name = "mail-show-source";
sensitive = single_message_selected;
action = e_mail_reader_get_action (reader, action_name);
@@ -2585,10 +2510,6 @@ e_mail_reader_init (EMailReader *reader)
/* Fine tuning. */
- action_name = "mail-clipboard-copy";
- action = e_mail_reader_get_action (reader, action_name);
- gtk_action_set_sensitive (action, FALSE);
-
action_name = "mail-delete";
action = e_mail_reader_get_action (reader, action_name);
g_object_set (action, "short-label", _("Delete"), NULL);
@@ -2661,10 +2582,6 @@ e_mail_reader_init (EMailReader *reader)
/* Connect signals. */
g_signal_connect_swapped (
- web_view, "button-release-event",
- G_CALLBACK (mail_reader_button_release_event_cb), reader);
-
- g_signal_connect_swapped (
web_view, "key-press-event",
G_CALLBACK (mail_reader_key_press_event_cb), reader);
diff --git a/mail/message-list.c b/mail/message-list.c
index dcf2e4fed1..49a839a7ba 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -52,6 +52,7 @@
#include "e-util/e-util.h"
#include "misc/e-gui-utils.h"
+#include "misc/e-selectable.h"
#include "shell/e-shell.h"
#include "shell/e-shell-settings.h"
@@ -126,6 +127,8 @@ enum {
PROP_SHELL_BACKEND
};
+static gpointer parent_class;
+
static struct {
const gchar *target;
GdkAtom atom;
@@ -197,8 +200,6 @@ struct _EMailAddress {
typedef struct _EMailAddress EMailAddress;
#endif /* SMART_ADDRESS_COMPARE */
-G_DEFINE_TYPE (MessageList, message_list, E_TREE_TYPE)
-
static void on_cursor_activated_cmd (ETree *tree, gint row, ETreePath path, gpointer user_data);
static void on_selection_changed_cmd(ETree *tree, MessageList *ml);
static gint on_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, MessageList *list);
@@ -718,6 +719,18 @@ message_list_select_next_thread (MessageList *ml)
}
}
+static gboolean
+message_list_select_all_timeout_cb (MessageList *message_list)
+{
+ ESelectionModel *etsm;
+
+ etsm = e_tree_get_selection_model (E_TREE (message_list));
+
+ e_selection_model_select_all (etsm);
+
+ return FALSE;
+}
+
/**
* message_list_select_all:
* @message_list: Message List widget
@@ -727,11 +740,21 @@ message_list_select_next_thread (MessageList *ml)
void
message_list_select_all (MessageList *message_list)
{
- ESelectionModel *etsm;
-
- etsm = e_tree_get_selection_model (E_TREE (message_list));
+ g_return_if_fail (IS_MESSAGE_LIST (message_list));
- e_selection_model_select_all (etsm);
+ if (message_list->threaded) {
+ /* XXX The timeout below is added so that the execution
+ * thread to expand all conversation threads would
+ * have completed. The timeout 505 is just to ensure
+ * that the value is a small delta more than the
+ * timeout value in mail_regen_list(). */
+ g_timeout_add (
+ 505, (GSourceFunc)
+ message_list_select_all_timeout_cb,
+ message_list);
+ } else
+ /* If there is no threading, just select all immediately. */
+ message_list_select_all_timeout_cb (message_list);
}
typedef struct thread_select_info {
@@ -2295,9 +2318,6 @@ message_list_init (MessageList *message_list)
message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
-/* adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, G_MAXDOUBLE, 0.0, 0.0, 0.0);
- gtk_scrolled_window_set_vadjustment ((GtkScrolledWindow *) message_list, adjustment);*/
-
message_list->normalised_hash = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
@@ -2390,7 +2410,7 @@ message_list_destroy(GtkObject *object)
}
/* Chain up to parent's destroy() method. */
- GTK_OBJECT_CLASS (message_list_parent_class)->destroy(object);
+ GTK_OBJECT_CLASS (parent_class)->destroy(object);
}
static void
@@ -2440,7 +2460,7 @@ message_list_dispose (GObject *object)
}
/* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (message_list_parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
@@ -2480,7 +2500,7 @@ message_list_finalize (GObject *object)
clear_selection(message_list, &priv->clipboard);
/* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
@@ -2490,6 +2510,25 @@ message_list_built (MessageList *message_list)
}
static void
+message_list_selectable_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ GtkAction *action;
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ gtk_action_set_tooltip (action, _("Select all visible messages"));
+ gtk_action_set_sensitive (action, TRUE);
+}
+
+static void
+message_list_selectable_select_all (ESelectable *selectable)
+{
+ message_list_select_all (MESSAGE_LIST (selectable));
+}
+
+static void
message_list_class_init (MessageListClass *class)
{
GObjectClass *object_class;
@@ -2499,6 +2538,7 @@ message_list_class_init (MessageListClass *class)
for (i = 0; i < G_N_ELEMENTS (ml_drag_info); i++)
ml_drag_info[i].atom = gdk_atom_intern(ml_drag_info[i].target, FALSE);
+ parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (MessageListPrivate));
object_class = G_OBJECT_CLASS (class);
@@ -2546,6 +2586,13 @@ message_list_class_init (MessageListClass *class)
message_list_init_images ();
}
+static void
+message_list_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = message_list_selectable_update_actions;
+ interface->select_all = message_list_selectable_select_all;
+}
+
static gboolean
read_boolean_with_default (GConfClient *gconf, const gchar *key, gboolean def_value)
{
@@ -2668,6 +2715,41 @@ message_list_construct (MessageList *message_list)
G_CALLBACK (ml_tree_sorting_changed), message_list);
}
+GType
+message_list_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (MessageListClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) message_list_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (MessageList),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) message_list_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) message_list_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ E_TREE_TYPE, "MessageList", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
+ }
+
+ return type;
+}
+
/**
* message_list_new:
*
diff --git a/mail/message-list.h b/mail/message-list.h
index 72960babe1..e239944783 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -170,9 +170,9 @@ struct _MessageListClass {
ETreeClass parent_class;
/* signals - select a message */
- void (*message_selected) (MessageList *ml, const gchar *uid);
- void (*message_list_built) (MessageList *ml);
- void (*message_list_scrolled) (MessageList *ml);
+ void (*message_selected) (MessageList *message_list, const gchar *uid);
+ void (*message_list_built) (MessageList *message_list);
+ void (*message_list_scrolled) (MessageList *message_list);
};
typedef enum {
@@ -182,58 +182,59 @@ typedef enum {
MESSAGE_LIST_SELECT_WRAP = 1<<1 /* option bit */
} MessageListSelectDirection;
-GType message_list_get_type (void);
-GtkWidget *message_list_new (EShellBackend *shell_backend);
-EShellBackend *message_list_get_shell_backend (MessageList *message_list);
-void message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder, const gchar *uri, gboolean outgoing);
-
-void message_list_freeze(MessageList *ml);
-void message_list_thaw(MessageList *ml);
-
-GPtrArray *message_list_get_uids(MessageList *message_list);
-GPtrArray *message_list_get_selected(MessageList *ml);
-void message_list_set_selected(MessageList *ml, GPtrArray *uids);
-
-/* select next/prev message helpers */
-gboolean message_list_select (MessageList *message_list,
- MessageListSelectDirection direction,
- guint32 flags,
- guint32 mask);
-gboolean message_list_can_select(MessageList *ml, MessageListSelectDirection direction, guint32 flags, guint32 mask);
-
-void message_list_select_uid (MessageList *message_list,
- const gchar *uid);
-
-void message_list_select_next_thread (MessageList *ml);
-
-/* selection manipulation */
-void message_list_select_all (MessageList *ml);
-void message_list_select_thread (MessageList *ml);
-void message_list_select_subthread (MessageList *ml);
-void message_list_invert_selection (MessageList *ml);
-
-/* clipboard stuff */
-void message_list_copy(MessageList *ml, gboolean cut);
-void message_list_paste (MessageList *ml);
-
-/* info */
-guint message_list_length (MessageList *ml);
-guint message_list_hidden (MessageList *ml);
-
-/* hide specific messages */
-void message_list_hide_add (MessageList *ml, const gchar *expr, guint lower, guint upper);
-void message_list_hide_uids (MessageList *ml, GPtrArray *uids);
-void message_list_hide_clear (MessageList *ml);
-
-void message_list_set_threaded (MessageList *ml, gboolean threaded);
-void message_list_set_threaded_expand_all (MessageList *ml);
-void message_list_set_threaded_collapse_all (MessageList *ml);
-
-void message_list_set_hidedeleted (MessageList *ml, gboolean hidedeleted);
-void message_list_set_search (MessageList *ml, const gchar *search);
-void message_list_ensure_message (MessageList *ml, const gchar *uid);
-
-void message_list_save_state (MessageList *ml);
+GType message_list_get_type (void);
+GtkWidget * message_list_new (EShellBackend *shell_backend);
+EShellBackend * message_list_get_shell_backend (MessageList *message_list);
+void message_list_set_folder (MessageList *message_list,
+ CamelFolder *camel_folder,
+ const gchar *uri,
+ gboolean outgoing);
+void message_list_freeze (MessageList *message_list);
+void message_list_thaw (MessageList *message_list);
+GPtrArray * message_list_get_uids (MessageList *message_list);
+GPtrArray * message_list_get_selected (MessageList *message_list);
+void message_list_set_selected (MessageList *message_list,
+ GPtrArray *uids);
+gboolean message_list_select (MessageList *message_list,
+ MessageListSelectDirection direction,
+ guint32 flags,
+ guint32 mask);
+gboolean message_list_can_select (MessageList *message_list,
+ MessageListSelectDirection direction,
+ guint32 flags,
+ guint32 mask);
+void message_list_select_uid (MessageList *message_list,
+ const gchar *uid);
+void message_list_select_next_thread (MessageList *message_list);
+void message_list_select_all (MessageList *message_list);
+void message_list_select_thread (MessageList *message_list);
+void message_list_select_subthread (MessageList *message_list);
+void message_list_invert_selection (MessageList *message_list);
+void message_list_copy (MessageList *message_list,
+ gboolean cut);
+void message_list_paste (MessageList *message_list);
+guint message_list_length (MessageList *message_list);
+guint message_list_hidden (MessageList *message_list);
+void message_list_hide_add (MessageList *message_list,
+ const gchar *expr,
+ guint lower,
+ guint upper);
+void message_list_hide_uids (MessageList *message_list,
+ GPtrArray *uids);
+void message_list_hide_clear (MessageList *message_list);
+void message_list_set_threaded (MessageList *message_list,
+ gboolean threaded);
+void message_list_set_threaded_expand_all
+ (MessageList *message_list);
+void message_list_set_threaded_collapse_all
+ (MessageList *message_list);
+void message_list_set_hidedeleted (MessageList *message_list,
+ gboolean hidedeleted);
+void message_list_set_search (MessageList *message_list,
+ const gchar *search);
+void message_list_ensure_message (MessageList *message_list,
+ const gchar *uid);
+void message_list_save_state (MessageList *message_list);
#define MESSAGE_LIST_LOCK(m, l) g_mutex_lock(((MessageList *)m)->l)
#define MESSAGE_LIST_UNLOCK(m, l) g_mutex_unlock(((MessageList *)m)->l)
diff --git a/modules/addressbook/e-book-shell-content.c b/modules/addressbook/e-book-shell-content.c
index 5eb4459b7b..a7a616fc18 100644
--- a/modules/addressbook/e-book-shell-content.c
+++ b/modules/addressbook/e-book-shell-content.c
@@ -284,11 +284,9 @@ book_shell_content_check_state (EShellContent *shell_content)
ESelectionModel *selection_model;
EAddressbookModel *model;
EAddressbookView *view;
- GtkClipboard *clipboard;
gboolean has_email = TRUE;
gboolean is_contact_list = TRUE;
guint32 state = 0;
- gint n_contacts;
gint n_selected;
struct {
@@ -301,8 +299,6 @@ book_shell_content_check_state (EShellContent *shell_content)
model = e_addressbook_view_get_model (view);
selection_model = e_addressbook_view_get_selection_model (view);
- n_contacts = (selection_model != NULL) ?
- e_selection_model_row_count (selection_model) : 0;
n_selected = (selection_model != NULL) ?
e_selection_model_selected_count (selection_model) : 0;
@@ -333,8 +329,6 @@ book_shell_content_check_state (EShellContent *shell_content)
foreach_data.list, foreach_data.list);
}
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
if (n_selected == 1)
state |= E_BOOK_SHELL_CONTENT_SELECTION_SINGLE;
if (n_selected > 1)
@@ -347,10 +341,6 @@ book_shell_content_check_state (EShellContent *shell_content)
state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY;
if (e_addressbook_model_get_editable (model))
state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE;
- if (n_contacts == 0)
- state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY;
- if (e_clipboard_wait_is_directory_available (clipboard))
- state |= E_BOOK_SHELL_CONTENT_CLIPBOARD_HAS_DIRECTORY;
return state;
}
@@ -649,24 +639,3 @@ e_book_shell_content_get_searchbar (EBookShellContent *book_shell_content)
return E_SHELL_SEARCHBAR (widget);
}
-
-void
-e_book_shell_content_clipboard_copy (EBookShellContent *book_shell_content)
-{
- EAddressbookView *addressbook_view;
- EWebView *web_view;
-
- g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
-
- web_view = E_WEB_VIEW (book_shell_content->priv->preview);
- addressbook_view =
- e_book_shell_content_get_current_view (book_shell_content);
- g_return_if_fail (addressbook_view != NULL);
-
- if (!GTK_WIDGET_HAS_FOCUS (web_view)) {
- e_addressbook_view_copy (addressbook_view);
- return;
- }
-
- e_web_view_clipboard_copy (web_view);
-}
diff --git a/modules/addressbook/e-book-shell-content.h b/modules/addressbook/e-book-shell-content.h
index 62cc7bf80f..6ed5b38a62 100644
--- a/modules/addressbook/e-book-shell-content.h
+++ b/modules/addressbook/e-book-shell-content.h
@@ -62,9 +62,7 @@ enum {
E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL = 1 << 2,
E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST = 1 << 3,
E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY = 1 << 4,
- E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE = 1 << 5,
- E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY = 1 << 6,
- E_BOOK_SHELL_CONTENT_CLIPBOARD_HAS_DIRECTORY = 1 << 7
+ E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE = 1 << 5
};
struct _EBookShellContent {
@@ -108,8 +106,6 @@ void e_book_shell_content_set_preview_visible
EShellSearchbar *
e_book_shell_content_get_searchbar
(EBookShellContent *book_shell_content);
-void e_book_shell_content_clipboard_copy
- (EBookShellContent *book_shell_content);
G_END_DECLS
diff --git a/modules/addressbook/e-book-shell-view-actions.c b/modules/addressbook/e-book-shell-view-actions.c
index 904b777c8b..5cfdbd347d 100644
--- a/modules/addressbook/e-book-shell-view-actions.c
+++ b/modules/addressbook/e-book-shell-view-actions.c
@@ -312,44 +312,6 @@ action_address_book_stop_cb (GtkAction *action,
}
static void
-action_contact_clipboard_copy_cb (GtkAction *action,
- EBookShellView *book_shell_view)
-{
- EBookShellContent *book_shell_content;
-
- book_shell_content = book_shell_view->priv->book_shell_content;
- e_book_shell_content_clipboard_copy (book_shell_content);
-}
-
-static void
-action_contact_clipboard_cut_cb (GtkAction *action,
- EBookShellView *book_shell_view)
-{
- EBookShellContent *book_shell_content;
- EAddressbookView *view;
-
- book_shell_content = book_shell_view->priv->book_shell_content;
- view = e_book_shell_content_get_current_view (book_shell_content);
- g_return_if_fail (view != NULL);
-
- e_addressbook_view_cut (view);
-}
-
-static void
-action_contact_clipboard_paste_cb (GtkAction *action,
- EBookShellView *book_shell_view)
-{
- EBookShellContent *book_shell_content;
- EAddressbookView *view;
-
- book_shell_content = book_shell_view->priv->book_shell_content;
- view = e_book_shell_content_get_current_view (book_shell_content);
- g_return_if_fail (view != NULL);
-
- e_addressbook_view_paste (view);
-}
-
-static void
action_contact_copy_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
@@ -599,20 +561,6 @@ exit:
}
static void
-action_contact_select_all_cb (GtkAction *action,
- EBookShellView *book_shell_view)
-{
- EBookShellContent *book_shell_content;
- EAddressbookView *view;
-
- book_shell_content = book_shell_view->priv->book_shell_content;
- view = e_book_shell_content_get_current_view (book_shell_content);
- g_return_if_fail (view != NULL);
-
- e_addressbook_view_select_all (view);
-}
-
-static void
action_contact_send_message_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
@@ -758,27 +706,6 @@ static GtkActionEntry contact_entries[] = {
N_("Stop loading"),
G_CALLBACK (action_address_book_stop_cb) },
- { "contact-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy the selection"),
- G_CALLBACK (action_contact_clipboard_copy_cb) },
-
- { "contact-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut the selection"),
- G_CALLBACK (action_contact_clipboard_cut_cb) },
-
- { "contact-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste the clipboard"),
- G_CALLBACK (action_contact_clipboard_paste_cb) },
-
{ "contact-copy",
NULL,
N_("_Copy Contact To..."),
@@ -828,13 +755,6 @@ static GtkActionEntry contact_entries[] = {
N_("View the current contact"),
G_CALLBACK (action_contact_open_cb) },
- { "contact-select-all",
- GTK_STOCK_SELECT_ALL,
- NULL,
- NULL,
- N_("Select all contacts"),
- G_CALLBACK (action_contact_select_all_cb) },
-
{ "contact-send-message",
"mail-message-new",
N_("_Send Message to Contact..."),
@@ -877,18 +797,6 @@ static EPopupActionEntry contact_popup_entries[] = {
N_("_Save as vCard..."),
"address-book-save-as" },
- { "contact-popup-clipboard-copy",
- NULL,
- "contact-clipboard-copy" },
-
- { "contact-popup-clipboard-cut",
- NULL,
- "contact-clipboard-cut" },
-
- { "contact-popup-clipboard-paste",
- NULL,
- "contact-clipboard-paste" },
-
{ "contact-popup-copy",
NULL,
"contact-copy" },
diff --git a/modules/addressbook/e-book-shell-view-actions.h b/modules/addressbook/e-book-shell-view-actions.h
index 98cd8b6689..250ec5fa99 100644
--- a/modules/addressbook/e-book-shell-view-actions.h
+++ b/modules/addressbook/e-book-shell-view-actions.h
@@ -45,12 +45,6 @@
E_SHELL_WINDOW_ACTION ((window), "address-book-stop")
/* Contact Actions */
-#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_CONTACT_COPY(window) \
E_SHELL_WINDOW_ACTION ((window), "contact-copy")
#define E_SHELL_WINDOW_ACTION_CONTACT_DELETE(window) \
@@ -71,8 +65,6 @@
E_SHELL_WINDOW_ACTION ((window), "contact-print")
#define E_SHELL_WINDOW_ACTION_CONTACT_SAVE_AS(window) \
E_SHELL_WINDOW_ACTION ((window), "contact-save-as")
-#define E_SHELL_WINDOW_ACTION_CONTACT_SELECT_ALL(window) \
- E_SHELL_WINDOW_ACTION ((window), "contact-select-all")
#define E_SHELL_WINDOW_ACTION_CONTACT_SEND_MESSAGE(window) \
E_SHELL_WINDOW_ACTION ((window), "contact-send-message")
#define E_SHELL_WINDOW_ACTION_CONTACT_VIEW_CLASSIC(window) \
diff --git a/modules/addressbook/e-book-shell-view.c b/modules/addressbook/e-book-shell-view.c
index fa5e5bbe29..9ab9cb743a 100644
--- a/modules/addressbook/e-book-shell-view.c
+++ b/modules/addressbook/e-book-shell-view.c
@@ -268,8 +268,9 @@ book_shell_view_update_actions (EShellView *shell_view)
gboolean selection_has_email;
gboolean source_is_busy;
gboolean source_is_editable;
- gboolean source_is_empty;
- gboolean clipboard_has_directory;
+
+ /* Chain up to parent's update_actions() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view);
@@ -290,10 +291,6 @@ book_shell_view_update_actions (EShellView *shell_view)
(state & E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY);
source_is_editable =
(state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE);
- source_is_empty =
- (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY);
- clipboard_has_directory =
- (state & E_BOOK_SHELL_CONTENT_CLIPBOARD_HAS_DIRECTORY);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
state = e_shell_sidebar_check_state (shell_sidebar);
@@ -328,18 +325,6 @@ book_shell_view_update_actions (EShellView *shell_view)
sensitive = source_is_busy;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (CONTACT_CLIPBOARD_COPY);
- sensitive = any_contacts_selected;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CONTACT_CLIPBOARD_CUT);
- sensitive = source_is_editable && any_contacts_selected;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CONTACT_CLIPBOARD_PASTE);
- sensitive = source_is_editable && clipboard_has_directory;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (CONTACT_COPY);
sensitive = any_contacts_selected;
gtk_action_set_sensitive (action, sensitive);
@@ -381,10 +366,6 @@ book_shell_view_update_actions (EShellView *shell_view)
sensitive = any_contacts_selected;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (CONTACT_SELECT_ALL);
- sensitive = !(source_is_empty);
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (CONTACT_SEND_MESSAGE);
sensitive = any_contacts_selected && selection_has_email;
gtk_action_set_sensitive (action, sensitive);
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
index c3112cf42c..4946972efd 100644
--- a/modules/calendar/e-cal-shell-content.c
+++ b/modules/calendar/e-cal-shell-content.c
@@ -721,114 +721,6 @@ e_cal_shell_content_get_view_instance (ECalShellContent *cal_shell_content)
}
void
-e_cal_shell_content_copy_clipboard (ECalShellContent *cal_shell_content)
-{
- GnomeCalendar *calendar;
- EMemoTable *memo_table;
- ECalendarTable *task_table;
- GnomeCalendarViewType view_type;
- ECalendarView *calendar_view;
-
- g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
-
- calendar = e_cal_shell_content_get_calendar (cal_shell_content);
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- view_type = gnome_calendar_get_view (calendar);
- calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
-
- switch (cal_shell_content_get_focus_location (cal_shell_content)) {
- case FOCUS_CALENDAR:
- e_calendar_view_copy_clipboard (calendar_view);
- break;
-
- case FOCUS_MEMO_TABLE:
- e_memo_table_copy_clipboard (memo_table);
- break;
-
- case FOCUS_TASK_TABLE:
- e_calendar_table_copy_clipboard (task_table);
- break;
-
- default:
- g_return_if_reached ();
- }
-}
-
-void
-e_cal_shell_content_cut_clipboard (ECalShellContent *cal_shell_content)
-{
- GnomeCalendar *calendar;
- EMemoTable *memo_table;
- ECalendarTable *task_table;
- GnomeCalendarViewType view_type;
- ECalendarView *calendar_view;
-
- g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
-
- calendar = e_cal_shell_content_get_calendar (cal_shell_content);
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- view_type = gnome_calendar_get_view (calendar);
- calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
-
- switch (cal_shell_content_get_focus_location (cal_shell_content)) {
- case FOCUS_CALENDAR:
- e_calendar_view_cut_clipboard (calendar_view);
- break;
-
- case FOCUS_MEMO_TABLE:
- e_memo_table_copy_clipboard (memo_table);
- break;
-
- case FOCUS_TASK_TABLE:
- e_calendar_table_copy_clipboard (task_table);
- break;
-
- default:
- g_return_if_reached ();
- }
-}
-
-void
-e_cal_shell_content_paste_clipboard (ECalShellContent *cal_shell_content)
-{
- GnomeCalendar *calendar;
- EMemoTable *memo_table;
- ECalendarTable *task_table;
- GnomeCalendarViewType view_type;
- ECalendarView *calendar_view;
-
- g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
-
- calendar = e_cal_shell_content_get_calendar (cal_shell_content);
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- view_type = gnome_calendar_get_view (calendar);
- calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
-
- switch (cal_shell_content_get_focus_location (cal_shell_content)) {
- case FOCUS_CALENDAR:
- e_calendar_view_paste_clipboard (calendar_view);
- break;
-
- case FOCUS_MEMO_TABLE:
- e_memo_table_paste_clipboard (memo_table);
- break;
-
- case FOCUS_TASK_TABLE:
- e_calendar_table_paste_clipboard (task_table);
- break;
-
- default:
- g_return_if_reached ();
- }
-}
-
-void
e_cal_shell_content_delete_selection (ECalShellContent *cal_shell_content)
{
GnomeCalendar *calendar;
diff --git a/modules/calendar/e-cal-shell-content.h b/modules/calendar/e-cal-shell-content.h
index eae8bf3301..db82889eab 100644
--- a/modules/calendar/e-cal-shell-content.h
+++ b/modules/calendar/e-cal-shell-content.h
@@ -26,6 +26,7 @@
#include <shell/e-shell-searchbar.h>
#include <shell/e-shell-view.h>
+#include <calendar/gui/e-calendar-table.h>
#include <calendar/gui/e-memo-table.h>
#include <calendar/gui/gnome-cal.h>
#include <menus/gal-view-instance.h>
@@ -96,12 +97,6 @@ EShellSearchbar *
GalViewInstance *
e_cal_shell_content_get_view_instance
(ECalShellContent *cal_shell_content);
-void e_cal_shell_content_copy_clipboard
- (ECalShellContent *cal_shell_content);
-void e_cal_shell_content_cut_clipboard
- (ECalShellContent *cal_shell_content);
-void e_cal_shell_content_paste_clipboard
- (ECalShellContent *cal_shell_content);
void e_cal_shell_content_delete_selection
(ECalShellContent *cal_shell_content);
void e_cal_shell_content_delete_selected_occurrence
diff --git a/modules/calendar/e-cal-shell-view-actions.c b/modules/calendar/e-cal-shell-view-actions.c
index 148cc4a426..117868d646 100644
--- a/modules/calendar/e-cal-shell-view-actions.c
+++ b/modules/calendar/e-cal-shell-view-actions.c
@@ -482,36 +482,6 @@ action_event_all_day_new_cb (GtkAction *action,
}
static void
-action_event_clipboard_copy_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- e_cal_shell_content_copy_clipboard (cal_shell_content);
-}
-
-static void
-action_event_clipboard_cut_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- e_cal_shell_content_cut_clipboard (cal_shell_content);
-}
-
-static void
-action_event_clipboard_paste_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- e_cal_shell_content_paste_clipboard (cal_shell_content);
-}
-
-static void
action_event_copy_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
@@ -1314,27 +1284,6 @@ static GtkActionEntry calendar_entries[] = {
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_calendar_select_one_cb) },
- { "event-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy the selection"),
- G_CALLBACK (action_event_clipboard_copy_cb) },
-
- { "event-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut the selection"),
- G_CALLBACK (action_event_clipboard_cut_cb) },
-
- { "event-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste the clipboard"),
- G_CALLBACK (action_event_clipboard_paste_cb) },
-
{ "event-copy",
NULL,
N_("Cop_y to Calendar..."),
@@ -1502,18 +1451,6 @@ static EPopupActionEntry calendar_popup_entries[] = {
NULL,
"calendar-select-one" },
- { "event-popup-clipboard-copy",
- NULL,
- "event-clipboard-copy" },
-
- { "event-popup-clipboard-cut",
- NULL,
- "event-clipboard-cut" },
-
- { "event-popup-clipboard-paste",
- NULL,
- "event-clipboard-paste" },
-
{ "event-popup-copy",
NULL,
"event-copy" },
diff --git a/modules/calendar/e-cal-shell-view-actions.h b/modules/calendar/e-cal-shell-view-actions.h
index a6b1c3d01c..a1cb31398b 100644
--- a/modules/calendar/e-cal-shell-view-actions.h
+++ b/modules/calendar/e-cal-shell-view-actions.h
@@ -65,12 +65,6 @@
E_SHELL_WINDOW_ACTION ((window), "calendar-view-workweek")
/* Event Actions */
-#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "event-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "event-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "event-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_EVENT_DELEGATE(window) \
E_SHELL_WINDOW_ACTION ((window), "event-delegate")
#define E_SHELL_WINDOW_ACTION_EVENT_DELETE(window) \
@@ -97,12 +91,6 @@
E_SHELL_WINDOW_ACTION ((window), "event-occurrence-movable")
/* Memo Pad Actions */
-#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_DELETE(window) \
E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-delete")
#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_FORWARD(window) \
@@ -121,12 +109,6 @@
/* Task Pad Actions */
#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_ASSIGN(window) \
E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-assign")
-#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_DELETE(window) \
E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-delete")
#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_FORWARD(window) \
diff --git a/modules/calendar/e-cal-shell-view-memopad.c b/modules/calendar/e-cal-shell-view-memopad.c
index 3a92cbc777..a65bf82cdd 100644
--- a/modules/calendar/e-cal-shell-view-memopad.c
+++ b/modules/calendar/e-cal-shell-view-memopad.c
@@ -24,45 +24,6 @@
/* Much of this file is based on e-memo-shell-view-actions.c. */
static void
-action_calendar_memopad_clipboard_copy_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- EMemoTable *memo_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
-
- e_memo_table_copy_clipboard (memo_table);
-}
-
-static void
-action_calendar_memopad_clipboard_cut_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- EMemoTable *memo_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
-
- e_memo_table_cut_clipboard (memo_table);
-}
-
-static void
-action_calendar_memopad_clipboard_paste_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- EMemoTable *memo_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
-
- e_memo_table_paste_clipboard (memo_table);
-}
-
-static void
action_calendar_memopad_delete_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
@@ -292,27 +253,6 @@ action_calendar_memopad_save_as_cb (GtkAction *action,
static GtkActionEntry calendar_memopad_entries[] = {
- { "calendar-memopad-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy selected memo"),
- G_CALLBACK (action_calendar_memopad_clipboard_copy_cb) },
-
- { "calendar-memopad-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut selected memo"),
- G_CALLBACK (action_calendar_memopad_clipboard_cut_cb) },
-
- { "calendar-memopad-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste memo from the clipboard"),
- G_CALLBACK (action_calendar_memopad_clipboard_paste_cb) },
-
{ "calendar-memopad-delete",
GTK_STOCK_DELETE,
N_("_Delete Memo"),
@@ -427,18 +367,6 @@ e_cal_shell_view_memopad_actions_update (ECalShellView *cal_shell_view)
}
g_slist_free (list);
- action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_COPY);
- sensitive = (n_selected > 0);
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_CUT);
- sensitive = (n_selected > 0) && editable;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_PASTE);
- sensitive = editable;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (CALENDAR_MEMOPAD_DELETE);
sensitive = (n_selected > 0) && editable;
gtk_action_set_sensitive (action, sensitive);
diff --git a/modules/calendar/e-cal-shell-view-taskpad.c b/modules/calendar/e-cal-shell-view-taskpad.c
index c88dee0d4c..f73d5839d1 100644
--- a/modules/calendar/e-cal-shell-view-taskpad.c
+++ b/modules/calendar/e-cal-shell-view-taskpad.c
@@ -47,45 +47,6 @@ action_calendar_taskpad_assign_cb (GtkAction *action,
}
static void
-action_calendar_taskpad_clipboard_copy_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- ECalendarTable *task_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- e_calendar_table_copy_clipboard (task_table);
-}
-
-static void
-action_calendar_taskpad_clipboard_cut_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- ECalendarTable *task_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- e_calendar_table_cut_clipboard (task_table);
-}
-
-static void
-action_calendar_taskpad_clipboard_paste_cb (GtkAction *action,
- ECalShellView *cal_shell_view)
-{
- ECalShellContent *cal_shell_content;
- ECalendarTable *task_table;
-
- cal_shell_content = cal_shell_view->priv->cal_shell_content;
- task_table = e_cal_shell_content_get_task_table (cal_shell_content);
-
- e_calendar_table_paste_clipboard (task_table);
-}
-
-static void
action_calendar_taskpad_delete_cb (GtkAction *action,
ECalShellView *cal_shell_view)
{
@@ -366,27 +327,6 @@ static GtkActionEntry calendar_taskpad_entries[] = {
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_calendar_taskpad_assign_cb) },
- { "calendar-taskpad-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy selected tasks"),
- G_CALLBACK (action_calendar_taskpad_clipboard_copy_cb) },
-
- { "calendar-taskpad-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut selected tasks"),
- G_CALLBACK (action_calendar_taskpad_clipboard_cut_cb) },
-
- { "calendar-taskpad-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste tasks from the clipboard"),
- G_CALLBACK (action_calendar_taskpad_clipboard_paste_cb) },
-
{ "calendar-taskpad-delete",
GTK_STOCK_DELETE,
N_("_Delete Task"),
@@ -538,18 +478,6 @@ e_cal_shell_view_taskpad_actions_update (ECalShellView *cal_shell_view)
sensitive = (n_selected == 1) && editable && assignable;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_COPY);
- sensitive = (n_selected > 0);
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_CUT);
- sensitive = (n_selected > 0) && editable;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_PASTE);
- sensitive = editable;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (CALENDAR_TASKPAD_DELETE);
sensitive = (n_selected > 0) && editable;
gtk_action_set_sensitive (action, sensitive);
diff --git a/modules/calendar/e-cal-shell-view.c b/modules/calendar/e-cal-shell-view.c
index 262cd39246..5b9940b1dd 100644
--- a/modules/calendar/e-cal-shell-view.c
+++ b/modules/calendar/e-cal-shell-view.c
@@ -296,9 +296,11 @@ cal_shell_view_update_actions (EShellView *shell_view)
gboolean is_instance = FALSE;
gboolean is_meeting = FALSE;
gboolean is_delegatable = FALSE;
- gboolean clipboard_has_calendar;
gboolean refresh_supported = FALSE;
+ /* Chain up to parent's update_actions() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
+
priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
@@ -361,10 +363,6 @@ cal_shell_view_update_actions (EShellView *shell_view)
g_list_free (list);
- clipboard_has_calendar =
- e_clipboard_wait_is_calendar_available (
- gtk_clipboard_get (GDK_SELECTION_CLIPBOARD));
-
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
state = e_shell_sidebar_check_state (shell_sidebar);
@@ -397,18 +395,6 @@ cal_shell_view_update_actions (EShellView *shell_view)
sensitive = can_delete_primary_source;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (EVENT_CLIPBOARD_COPY);
- sensitive = (n_selected > 0);
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (EVENT_CLIPBOARD_CUT);
- sensitive = (n_selected > 0) && editable;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (EVENT_CLIPBOARD_PASTE);
- sensitive = editable && clipboard_has_calendar;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (EVENT_DELEGATE);
sensitive =
(n_selected == 1) && editable &&
diff --git a/modules/calendar/e-memo-shell-content.c b/modules/calendar/e-memo-shell-content.c
index 4de685cd4b..709ae9a8e6 100644
--- a/modules/calendar/e-memo-shell-content.c
+++ b/modules/calendar/e-memo-shell-content.c
@@ -537,7 +537,6 @@ memo_shell_content_check_state (EShellContent *shell_content)
EMemoShellContent *memo_shell_content;
EMemoTable *memo_table;
GSList *list, *iter;
- GtkClipboard *clipboard;
gboolean editable = TRUE;
gboolean has_url = FALSE;
gint n_selected;
@@ -563,8 +562,6 @@ memo_shell_content_check_state (EShellContent *shell_content)
}
g_slist_free (list);
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
if (n_selected == 1)
state |= E_MEMO_SHELL_CONTENT_SELECTION_SINGLE;
if (n_selected > 1)
@@ -573,8 +570,6 @@ memo_shell_content_check_state (EShellContent *shell_content)
state |= E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT;
if (has_url)
state |= E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL;
- if (e_clipboard_wait_is_calendar_available (clipboard))
- state |= E_MEMO_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR;
return state;
}
diff --git a/modules/calendar/e-memo-shell-content.h b/modules/calendar/e-memo-shell-content.h
index a923b27f0b..16aae229b2 100644
--- a/modules/calendar/e-memo-shell-content.h
+++ b/modules/calendar/e-memo-shell-content.h
@@ -60,8 +60,7 @@ enum {
E_MEMO_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0,
E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1,
E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 2,
- E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 3,
- E_MEMO_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR = 1 << 4
+ E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 3
};
struct _EMemoShellContent {
diff --git a/modules/calendar/e-memo-shell-view-actions.c b/modules/calendar/e-memo-shell-view-actions.c
index baf90f5a73..7a0fdaf8af 100644
--- a/modules/calendar/e-memo-shell-view-actions.c
+++ b/modules/calendar/e-memo-shell-view-actions.c
@@ -43,45 +43,6 @@ action_gal_save_custom_view_cb (GtkAction *action,
}
static void
-action_memo_clipboard_copy_cb (GtkAction *action,
- EMemoShellView *memo_shell_view)
-{
- EMemoShellContent *memo_shell_content;
- EMemoTable *memo_table;
-
- memo_shell_content = memo_shell_view->priv->memo_shell_content;
- memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
-
- e_memo_table_copy_clipboard (memo_table);
-}
-
-static void
-action_memo_clipboard_cut_cb (GtkAction *action,
- EMemoShellView *memo_shell_view)
-{
- EMemoShellContent *memo_shell_content;
- EMemoTable *memo_table;
-
- memo_shell_content = memo_shell_view->priv->memo_shell_content;
- memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
-
- e_memo_table_cut_clipboard (memo_table);
-}
-
-static void
-action_memo_clipboard_paste_cb (GtkAction *action,
- EMemoShellView *memo_shell_view)
-{
- EMemoShellContent *memo_shell_content;
- EMemoTable *memo_table;
-
- memo_shell_content = memo_shell_view->priv->memo_shell_content;
- memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
-
- e_memo_table_paste_clipboard (memo_table);
-}
-
-static void
action_memo_delete_cb (GtkAction *action,
EMemoShellView *memo_shell_view)
{
@@ -590,27 +551,6 @@ action_search_filter_cb (GtkRadioAction *action,
static GtkActionEntry memo_entries[] = {
- { "memo-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy selected memo"),
- G_CALLBACK (action_memo_clipboard_copy_cb) },
-
- { "memo-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut selected memo"),
- G_CALLBACK (action_memo_clipboard_cut_cb) },
-
- { "memo-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste memo from the clipboard"),
- G_CALLBACK (action_memo_clipboard_paste_cb) },
-
{ "memo-delete",
GTK_STOCK_DELETE,
N_("_Delete Memo"),
@@ -731,18 +671,6 @@ static EPopupActionEntry memo_popup_entries[] = {
NULL,
"memo-list-select-one" },
- { "memo-popup-clipboard-copy",
- NULL,
- "memo-clipboard-copy" },
-
- { "memo-popup-clipboard-cut",
- NULL,
- "memo-clipboard-cut" },
-
- { "memo-popup-clipboard-paste",
- NULL,
- "memo-clipboard-paste" },
-
{ "memo-popup-delete",
NULL,
"memo-delete" },
diff --git a/modules/calendar/e-memo-shell-view-actions.h b/modules/calendar/e-memo-shell-view-actions.h
index cb4309c18a..5b49ca06b1 100644
--- a/modules/calendar/e-memo-shell-view-actions.h
+++ b/modules/calendar/e-memo-shell-view-actions.h
@@ -25,12 +25,6 @@
#include <shell/e-shell-window-actions.h>
/* Memo Actions */
-#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_MEMO_DELETE(window) \
E_SHELL_WINDOW_ACTION ((window), "memo-delete")
#define E_SHELL_WINDOW_ACTION_MEMO_FORWARD(window) \
diff --git a/modules/calendar/e-memo-shell-view.c b/modules/calendar/e-memo-shell-view.c
index 29a82524c4..0afbe18e77 100644
--- a/modules/calendar/e-memo-shell-view.c
+++ b/modules/calendar/e-memo-shell-view.c
@@ -175,7 +175,6 @@ memo_shell_view_update_actions (EShellView *shell_view)
/* Be descriptive. */
gboolean any_memos_selected;
gboolean can_delete_primary_source;
- gboolean clipboard_has_calendar;
gboolean has_primary_source;
gboolean multiple_memos_selected;
gboolean primary_source_is_system;
@@ -184,6 +183,9 @@ memo_shell_view_update_actions (EShellView *shell_view)
gboolean sources_are_editable;
gboolean refresh_supported;
+ /* Chain up to parent's update_actions() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
+
priv = E_MEMO_SHELL_VIEW_GET_PRIVATE (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
@@ -199,8 +201,6 @@ memo_shell_view_update_actions (EShellView *shell_view)
(state & E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT);
selection_has_url =
(state & E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL);
- clipboard_has_calendar =
- (state & E_MEMO_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
state = e_shell_sidebar_check_state (shell_sidebar);
@@ -217,18 +217,6 @@ memo_shell_view_update_actions (EShellView *shell_view)
any_memos_selected =
(single_memo_selected || multiple_memos_selected);
- action = ACTION (MEMO_CLIPBOARD_COPY);
- sensitive = any_memos_selected;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (MEMO_CLIPBOARD_CUT);
- sensitive = any_memos_selected && sources_are_editable;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (MEMO_CLIPBOARD_PASTE);
- sensitive = sources_are_editable && clipboard_has_calendar;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (MEMO_DELETE);
sensitive = any_memos_selected && sources_are_editable;
gtk_action_set_sensitive (action, sensitive);
diff --git a/modules/calendar/e-task-shell-content.c b/modules/calendar/e-task-shell-content.c
index 4692e7bf7e..e50b67bf5a 100644
--- a/modules/calendar/e-task-shell-content.c
+++ b/modules/calendar/e-task-shell-content.c
@@ -535,7 +535,6 @@ task_shell_content_check_state (EShellContent *shell_content)
ETaskShellContent *task_shell_content;
ECalendarTable *task_table;
GSList *list, *iter;
- GtkClipboard *clipboard;
gboolean assignable = TRUE;
gboolean editable = TRUE;
gboolean has_url = FALSE;
@@ -580,8 +579,6 @@ task_shell_content_check_state (EShellContent *shell_content)
}
g_slist_free (list);
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
if (n_selected == 1)
state |= E_TASK_SHELL_CONTENT_SELECTION_SINGLE;
if (n_selected > 1)
@@ -596,8 +593,6 @@ task_shell_content_check_state (EShellContent *shell_content)
state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE;
if (has_url)
state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_URL;
- if (e_clipboard_wait_is_calendar_available (clipboard))
- state |= E_TASK_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR;
return state;
}
diff --git a/modules/calendar/e-task-shell-content.h b/modules/calendar/e-task-shell-content.h
index 971d46ad95..7a5e8efd81 100644
--- a/modules/calendar/e-task-shell-content.h
+++ b/modules/calendar/e-task-shell-content.h
@@ -64,8 +64,7 @@ enum {
E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 3,
E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE = 1 << 4,
E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE = 1 << 5,
- E_TASK_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 6,
- E_TASK_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR = 1 << 7
+ E_TASK_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 6
};
struct _ETaskShellContent {
diff --git a/modules/calendar/e-task-shell-view-actions.c b/modules/calendar/e-task-shell-view-actions.c
index 8e28b55863..067bd48370 100644
--- a/modules/calendar/e-task-shell-view-actions.c
+++ b/modules/calendar/e-task-shell-view-actions.c
@@ -74,45 +74,6 @@ action_task_assign_cb (GtkAction *action,
}
static void
-action_task_clipboard_copy_cb (GtkAction *action,
- ETaskShellView *task_shell_view)
-{
- ETaskShellContent *task_shell_content;
- ECalendarTable *task_table;
-
- task_shell_content = task_shell_view->priv->task_shell_content;
- task_table = e_task_shell_content_get_task_table (task_shell_content);
-
- e_calendar_table_copy_clipboard (task_table);
-}
-
-static void
-action_task_clipboard_cut_cb (GtkAction *action,
- ETaskShellView *task_shell_view)
-{
- ETaskShellContent *task_shell_content;
- ECalendarTable *task_table;
-
- task_shell_content = task_shell_view->priv->task_shell_content;
- task_table = e_task_shell_content_get_task_table (task_shell_content);
-
- e_calendar_table_cut_clipboard (task_table);
-}
-
-static void
-action_task_clipboard_paste_cb (GtkAction *action,
- ETaskShellView *task_shell_view)
-{
- ETaskShellContent *task_shell_content;
- ECalendarTable *task_table;
-
- task_shell_content = task_shell_view->priv->task_shell_content;
- task_table = e_task_shell_content_get_task_table (task_shell_content);
-
- e_calendar_table_paste_clipboard (task_table);
-}
-
-static void
action_task_delete_cb (GtkAction *action,
ETaskShellView *task_shell_view)
{
@@ -714,27 +675,6 @@ static GtkActionEntry task_entries[] = {
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_task_assign_cb) },
- { "task-clipboard-copy",
- GTK_STOCK_COPY,
- NULL,
- NULL,
- N_("Copy selected tasks"),
- G_CALLBACK (action_task_clipboard_copy_cb) },
-
- { "task-clipboard-cut",
- GTK_STOCK_CUT,
- NULL,
- NULL,
- N_("Cut selected tasks"),
- G_CALLBACK (action_task_clipboard_cut_cb) },
-
- { "task-clipboard-paste",
- GTK_STOCK_PASTE,
- NULL,
- NULL,
- N_("Paste tasks from the clipboard"),
- G_CALLBACK (action_task_clipboard_paste_cb) },
-
{ "task-delete",
GTK_STOCK_DELETE,
N_("_Delete Task"),
@@ -887,18 +827,6 @@ static EPopupActionEntry task_popup_entries[] = {
NULL,
"task-assign" },
- { "task-popup-clipboard-copy",
- NULL,
- "task-clipboard-copy" },
-
- { "task-popup-clipboard-cut",
- NULL,
- "task-clipboard-cut" },
-
- { "task-popup-clipboard-paste",
- NULL,
- "task-clipboard-paste" },
-
{ "task-popup-delete",
NULL,
"task-delete" },
diff --git a/modules/calendar/e-task-shell-view-actions.h b/modules/calendar/e-task-shell-view-actions.h
index 3d49ff636e..f323fb38f9 100644
--- a/modules/calendar/e-task-shell-view-actions.h
+++ b/modules/calendar/e-task-shell-view-actions.h
@@ -27,12 +27,6 @@
/* Task Actions */
#define E_SHELL_WINDOW_ACTION_TASK_ASSIGN(window) \
E_SHELL_WINDOW_ACTION ((window), "task-assign")
-#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_COPY(window) \
- E_SHELL_WINDOW_ACTION ((window), "task-clipboard-copy")
-#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_CUT(window) \
- E_SHELL_WINDOW_ACTION ((window), "task-clipboard-cut")
-#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_PASTE(window) \
- E_SHELL_WINDOW_ACTION ((window), "task-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_TASK_DELETE(window) \
E_SHELL_WINDOW_ACTION ((window), "task-delete")
#define E_SHELL_WINDOW_ACTION_TASK_FORWARD(window) \
diff --git a/modules/calendar/e-task-shell-view.c b/modules/calendar/e-task-shell-view.c
index a481356690..07fb12e369 100644
--- a/modules/calendar/e-task-shell-view.c
+++ b/modules/calendar/e-task-shell-view.c
@@ -297,9 +297,11 @@ task_shell_view_update_actions (EShellView *shell_view)
gboolean some_tasks_complete;
gboolean some_tasks_incomplete;
gboolean sources_are_editable;
- gboolean clipboard_has_calendar;
gboolean refresh_supported;
+ /* Chain up to parent's update_actions() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
+
priv = E_TASK_SHELL_VIEW_GET_PRIVATE (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
@@ -321,8 +323,6 @@ task_shell_view_update_actions (EShellView *shell_view)
(state & E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE);
selection_has_url =
(state & E_TASK_SHELL_CONTENT_SELECTION_HAS_URL);
- clipboard_has_calendar =
- (state & E_TASK_SHELL_CONTENT_CLIPBOARD_HAS_CALENDAR);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
state = e_shell_sidebar_check_state (shell_sidebar);
@@ -345,18 +345,6 @@ task_shell_view_update_actions (EShellView *shell_view)
selection_is_assignable;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (TASK_CLIPBOARD_COPY);
- sensitive = any_tasks_selected;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (TASK_CLIPBOARD_CUT);
- sensitive = any_tasks_selected && sources_are_editable;
- gtk_action_set_sensitive (action, sensitive);
-
- action = ACTION (TASK_CLIPBOARD_PASTE);
- sensitive = sources_are_editable && clipboard_has_calendar;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (TASK_DELETE);
sensitive = any_tasks_selected && sources_are_editable;
gtk_action_set_sensitive (action, sensitive);
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index 2ab36d46fb..139dd9474f 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -353,48 +353,6 @@ action_mail_folder_rename_cb (GtkAction *action,
em_folder_tree_edit_selected (folder_tree);
}
-/* Helper for action_mail_folder_select_all_cb() */
-static gboolean
-action_mail_folder_select_all_timeout_cb (GtkWidget *message_list)
-{
- message_list_select_all (MESSAGE_LIST (message_list));
- gtk_widget_grab_focus (message_list);
-
- return FALSE;
-}
-
-static void
-action_mail_folder_select_all_cb (GtkAction *action,
- EMailShellView *mail_shell_view)
-{
- EMailReader *reader;
- GtkWidget *message_list;
- EShellWindow *shell_window;
- EShellView *shell_view;
-
- shell_view = E_SHELL_VIEW (mail_shell_view);
- shell_window = e_shell_view_get_shell_window (shell_view);
-
- reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
- message_list = e_mail_reader_get_message_list (reader);
-
- if (MESSAGE_LIST (message_list)->threaded) {
- gtk_action_activate (ACTION (MAIL_THREADS_EXPAND_ALL));
-
- /* XXX The timeout below is added so that the execution
- * thread to expand all conversation threads would
- * have completed. The timeout 505 is just to ensure
- * that the value is a small delta more than the
- * timeout value in mail_regen_list(). */
- g_timeout_add (
- 505, (GSourceFunc)
- action_mail_folder_select_all_timeout_cb,
- message_list);
- } else
- /* If there is no threading, just select all immediately. */
- action_mail_folder_select_all_timeout_cb (message_list);
-}
-
static void
action_mail_folder_select_thread_cb (GtkAction *action,
EMailShellView *mail_shell_view)
@@ -1059,13 +1017,6 @@ static GtkActionEntry mail_entries[] = {
N_("Change the name of this folder"),
G_CALLBACK (action_mail_folder_rename_cb) },
- { "mail-folder-select-all",
- NULL,
- N_("Select _All Messages"),
- "<Control>a",
- N_("Select all visible messages"),
- G_CALLBACK (action_mail_folder_select_all_cb) },
-
{ "mail-folder-select-thread",
NULL,
N_("Select Message _Thread"),
diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c
index b198b69cd1..85395fd8ed 100644
--- a/modules/mail/e-mail-shell-view-private.c
+++ b/modules/mail/e-mail-shell-view-private.c
@@ -443,6 +443,7 @@ e_mail_shell_view_private_constructed (EMailShellView *mail_shell_view)
shell_content = e_shell_view_get_shell_content (shell_view);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
+
ui_manager = e_shell_window_get_ui_manager (shell_window);
shell = e_shell_window_get_shell (shell_window);
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
index de81e131c5..bd0b3cbe48 100644
--- a/modules/mail/e-mail-shell-view.c
+++ b/modules/mail/e-mail-shell-view.c
@@ -440,6 +440,9 @@ mail_shell_view_update_actions (EShellView *shell_view)
gboolean folder_has_unread_rec = FALSE;
gboolean folder_tree_and_message_list_agree = TRUE;
+ /* Chain up to parent's update_actions() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->update_actions (shell_view);
+
mail_shell_view = E_MAIL_SHELL_VIEW (shell_view);
shell_window = e_shell_view_get_shell_window (shell_view);
@@ -554,10 +557,6 @@ mail_shell_view_update_actions (EShellView *shell_view)
folder_tree_and_message_list_agree;
gtk_action_set_sensitive (action, sensitive);
- action = ACTION (MAIL_FOLDER_SELECT_ALL);
- sensitive = !folder_is_store;
- gtk_action_set_sensitive (action, sensitive);
-
action = ACTION (MAIL_FOLDER_SELECT_THREAD);
sensitive = !folder_is_store;
gtk_action_set_sensitive (action, sensitive);
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index d87f8b7632..fdffe92fd6 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -507,21 +507,6 @@ shell_view_constructed (GObject *object)
}
static void
-shell_view_clear_search (EShellView *shell_view)
-{
- e_shell_view_set_search_rule (shell_view, NULL);
- e_shell_view_execute_search (shell_view);
-}
-
-static void
-shell_view_custom_search (EShellView *shell_view,
- EFilterRule *custom_rule)
-{
- e_shell_view_set_search_rule (shell_view, custom_rule);
- e_shell_view_execute_search (shell_view);
-}
-
-static void
shell_view_toggled (EShellView *shell_view)
{
EShellViewPrivate *priv = shell_view->priv;
@@ -553,6 +538,33 @@ shell_view_toggled (EShellView *shell_view)
}
static void
+shell_view_clear_search (EShellView *shell_view)
+{
+ e_shell_view_set_search_rule (shell_view, NULL);
+ e_shell_view_execute_search (shell_view);
+}
+
+static void
+shell_view_custom_search (EShellView *shell_view,
+ EFilterRule *custom_rule)
+{
+ e_shell_view_set_search_rule (shell_view, custom_rule);
+ e_shell_view_execute_search (shell_view);
+}
+
+static void
+shell_view_update_actions (EShellView *shell_view)
+{
+ EShellWindow *shell_window;
+ EFocusTracker *focus_tracker;
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ focus_tracker = e_shell_window_get_focus_tracker (shell_window);
+
+ e_focus_tracker_update_actions (focus_tracker);
+}
+
+static void
shell_view_class_init (EShellViewClass *class)
{
GObjectClass *object_class;
@@ -574,9 +586,10 @@ shell_view_class_init (EShellViewClass *class)
class->new_shell_sidebar = e_shell_sidebar_new;
class->new_shell_taskbar = e_shell_taskbar_new;
+ class->toggled = shell_view_toggled;
class->clear_search = shell_view_clear_search;
class->custom_search = shell_view_custom_search;
- class->toggled = shell_view_toggled;
+ class->update_actions = shell_view_update_actions;
/**
* EShellView:action:
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index 4483347beb..5cdf2a932f 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -1437,6 +1437,27 @@ static GtkActionEntry shell_entries[] = {
N_("Open the Evolution User Guide"),
G_CALLBACK (action_contents_cb) },
+ { "copy-clipboard",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "cut-clipboard",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "delete-selection",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Delete the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
{ "faq",
"help-faq",
N_("Evolution _FAQ"),
@@ -1465,6 +1486,13 @@ static GtkActionEntry shell_entries[] = {
N_("Create a new window displaying this view"),
G_CALLBACK (action_new_window_cb) },
+ { "paste-clipboard",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste the clipboard"),
+ NULL }, /* Handled by EFocusTracker */
+
{ "preferences",
GTK_STOCK_PREFERENCES,
NULL,
@@ -1528,6 +1556,13 @@ static GtkActionEntry shell_entries[] = {
N_("Save the current search parameters"),
G_CALLBACK (action_search_save_cb) },
+ { "select-all",
+ GTK_STOCK_SELECT_ALL,
+ NULL,
+ "<Control>a",
+ N_("Select all text"),
+ NULL }, /* Handled by EFocusTracker */
+
{ "send-receive",
"mail-send-receive",
N_("Send / _Receive"),
@@ -1629,6 +1664,25 @@ static GtkActionEntry shell_entries[] = {
NULL }
};
+static EPopupActionEntry shell_popup_entries[] = {
+
+ { "popup-copy-clipboard",
+ NULL,
+ "copy-clipboard" },
+
+ { "popup-cut-clipboard",
+ NULL,
+ "cut-clipboard" },
+
+ { "popup-delete-selection",
+ NULL,
+ "delete-selection" },
+
+ { "popup-paste-clipboard",
+ NULL,
+ "paste-clipboard" }
+};
+
static GtkToggleActionEntry shell_toggle_entries[] = {
{ "show-sidebar",
@@ -1811,6 +1865,7 @@ void
e_shell_window_actions_init (EShellWindow *shell_window)
{
GtkActionGroup *action_group;
+ EFocusTracker *focus_tracker;
GtkUIManager *ui_manager;
g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
@@ -1824,6 +1879,9 @@ e_shell_window_actions_init (EShellWindow *shell_window)
gtk_action_group_add_actions (
action_group, shell_entries,
G_N_ELEMENTS (shell_entries), shell_window);
+ e_action_group_add_popup_actions (
+ action_group, shell_popup_entries,
+ G_N_ELEMENTS (shell_popup_entries));
gtk_action_group_add_toggle_actions (
action_group, shell_toggle_entries,
G_N_ELEMENTS (shell_toggle_entries), shell_window);
@@ -1854,6 +1912,21 @@ e_shell_window_actions_init (EShellWindow *shell_window)
G_N_ELEMENTS (shell_lockdown_print_setup_entries),
shell_window);
+ /* Configure an EFocusTracker to manage selection actions. */
+
+ focus_tracker = e_focus_tracker_new (GTK_WINDOW (shell_window));
+ e_focus_tracker_set_cut_clipboard_action (
+ focus_tracker, ACTION (CUT_CLIPBOARD));
+ e_focus_tracker_set_copy_clipboard_action (
+ focus_tracker, ACTION (COPY_CLIPBOARD));
+ e_focus_tracker_set_paste_clipboard_action (
+ focus_tracker, ACTION (PASTE_CLIPBOARD));
+ e_focus_tracker_set_delete_selection_action (
+ focus_tracker, ACTION (DELETE_SELECTION));
+ e_focus_tracker_set_select_all_action (
+ focus_tracker, ACTION (SELECT_ALL));
+ shell_window->priv->focus_tracker = focus_tracker;
+
/* Fine tuning. */
gtk_action_set_sensitive (ACTION (SEARCH_QUICK), FALSE);
diff --git a/shell/e-shell-window-actions.h b/shell/e-shell-window-actions.h
index 8636b69648..4833ad0c9f 100644
--- a/shell/e-shell-window-actions.h
+++ b/shell/e-shell-window-actions.h
@@ -35,6 +35,12 @@
E_SHELL_WINDOW_ACTION ((window), "close")
#define E_SHELL_WINDOW_ACTION_CONTENTS(window) \
E_SHELL_WINDOW_ACTION ((window), "contents")
+#define E_SHELL_WINDOW_ACTION_COPY_CLIPBOARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "copy-clipboard")
+#define E_SHELL_WINDOW_ACTION_CUT_CLIPBOARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "cut-clipboard")
+#define E_SHELL_WINDOW_ACTION_DELETE_SELECTION(window) \
+ E_SHELL_WINDOW_ACTION ((window), "delete-selection")
#define E_SHELL_WINDOW_ACTION_FAQ(window) \
E_SHELL_WINDOW_ACTION ((window), "faq")
#define E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS(window) \
@@ -51,6 +57,8 @@
E_SHELL_WINDOW_ACTION ((window), "new-window")
#define E_SHELL_WINDOW_ACTION_PAGE_SETUP(window) \
E_SHELL_WINDOW_ACTION ((window), "page-setup")
+#define E_SHELL_WINDOW_ACTION_PASTE_CLIPBOARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "paste-clipboard")
#define E_SHELL_WINDOW_ACTION_PREFERENCES(window) \
E_SHELL_WINDOW_ACTION ((window), "preferences")
#define E_SHELL_WINDOW_ACTION_QUICK_REFERENCE(window) \
@@ -69,6 +77,8 @@
E_SHELL_WINDOW_ACTION ((window), "search-quick")
#define E_SHELL_WINDOW_ACTION_SEARCH_SAVE(window) \
E_SHELL_WINDOW_ACTION ((window), "search-save")
+#define E_SHELL_WINDOW_ACTION_SELECT_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "select-all")
#define E_SHELL_WINDOW_ACTION_SEND_RECEIVE(window) \
E_SHELL_WINDOW_ACTION ((window), "send-receive")
#define E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR(window) \
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
index 0d9dda59cb..a2805f46bf 100644
--- a/shell/e-shell-window-private.c
+++ b/shell/e-shell-window-private.c
@@ -473,6 +473,7 @@ e_shell_window_private_dispose (EShellWindow *shell_window)
priv->shell = NULL;
}
+ DISPOSE (priv->focus_tracker);
DISPOSE (priv->ui_manager);
g_hash_table_remove_all (priv->loaded_views);
diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h
index 635b6b6630..87e18646c4 100644
--- a/shell/e-shell-window-private.h
+++ b/shell/e-shell-window-private.h
@@ -34,6 +34,7 @@
#include <widgets/misc/e-import-assistant.h>
#include <widgets/misc/e-menu-tool-button.h>
#include <widgets/misc/e-online-button.h>
+#include <widgets/misc/e-popup-action.h>
#include <e-shell.h>
#include <e-shell-content.h>
@@ -70,6 +71,7 @@ struct _EShellWindowPrivate {
/*** UI Management ***/
+ EFocusTracker *focus_tracker;
GtkUIManager *ui_manager;
guint custom_rule_merge_id;
guint gal_view_merge_id;
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 25b56caecb..d3d6107e24 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -29,6 +29,7 @@
enum {
PROP_0,
PROP_ACTIVE_VIEW,
+ PROP_FOCUS_TRACKER,
PROP_GEOMETRY,
PROP_SAFE_MODE,
PROP_SHELL,
@@ -234,6 +235,12 @@ shell_window_get_property (GObject *object,
E_SHELL_WINDOW (object)));
return;
+ case PROP_FOCUS_TRACKER:
+ g_value_set_object (
+ value, e_shell_window_get_focus_tracker (
+ E_SHELL_WINDOW (object)));
+ return;
+
case PROP_SAFE_MODE:
g_value_set_boolean (
value, e_shell_window_get_safe_mode (
@@ -609,6 +616,21 @@ shell_window_class_init (EShellWindowClass *class)
G_PARAM_READWRITE));
/**
+ * EShellWindow:focus-tracker
+ *
+ * The shell window's #EFocusTracker.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FOCUS_TRACKER,
+ g_param_spec_object (
+ "focus-tracker",
+ _("Focus Tracker"),
+ _("The shell window's EFocusTracker"),
+ E_TYPE_FOCUS_TRACKER,
+ G_PARAM_READABLE));
+
+ /**
* EShellWindow:geometry
*
* User-specified initial window geometry string.
@@ -886,6 +908,24 @@ e_shell_window_get_shell_view_action (EShellWindow *shell_window,
}
/**
+ * e_shell_window_get_focus_tracker:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns @shell_window<!-- -->'s focus tracker, which directs
+ * Cut, Copy, Paste and Select All main menu activations to the
+ * appropriate editable or selectable widget.
+ *
+ * Returns: the #EFocusTracker for @shell_window
+ **/
+EFocusTracker *
+e_shell_window_get_focus_tracker (EShellWindow *shell_window)
+{
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+
+ return shell_window->priv->focus_tracker;
+}
+
+/**
* e_shell_window_get_ui_manager:
* @shell_window: an #EShellWindow
*
diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h
index bb88003955..4ac76ba5d4 100644
--- a/shell/e-shell-window.h
+++ b/shell/e-shell-window.h
@@ -29,6 +29,7 @@
#define E_SHELL_WINDOW_H
#include <shell/e-shell.h>
+#include <misc/e-focus-tracker.h>
/* Standard GObject macros */
#define E_TYPE_SHELL_WINDOW \
@@ -94,6 +95,7 @@ struct _EShellView *
GtkAction * e_shell_window_get_shell_view_action
(EShellWindow *shell_window,
const gchar *view_name);
+EFocusTracker * e_shell_window_get_focus_tracker(EShellWindow *shell_window);
GtkUIManager * e_shell_window_get_ui_manager (EShellWindow *shell_window);
GtkAction * e_shell_window_get_action (EShellWindow *shell_window,
const gchar *action_name);
diff --git a/ui/evolution-calendars.ui b/ui/evolution-calendars.ui
index 8bff0fc506..818ed176b3 100644
--- a/ui/evolution-calendars.ui
+++ b/ui/evolution-calendars.ui
@@ -11,10 +11,6 @@
</menu>
<menu action='edit-menu'>
<placeholder name='edit-actions'>
- <menuitem action='event-clipboard-cut'/>
- <menuitem action='event-clipboard-copy'/>
- <menuitem action='event-clipboard-paste'/>
- <separator/>
<menuitem action='event-delete'/>
<menuitem action='event-delete-occurrence'/>
<menuitem action='event-delete-occurrence-all'/>
@@ -66,7 +62,7 @@
<separator/>
<menuitem action='event-popup-print'/>
<separator/>
- <menuitem action='event-popup-clipboard-paste'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menu action='gal-view-menu'>
<menuitem action='calendar-view-day'/>
@@ -85,9 +81,9 @@
<menuitem action='event-popup-save-as'/>
<menuitem action='event-popup-print'/>
<separator/>
- <menuitem action='event-popup-clipboard-cut'/>
- <menuitem action='event-popup-clipboard-copy'/>
- <menuitem action='event-popup-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menuitem action='event-popup-copy'/>
<menuitem action='event-popup-move'/>
@@ -113,9 +109,9 @@
<menuitem action='calendar-memopad-save-as'/>
<menuitem action='calendar-memopad-print'/>
<separator/>
- <menuitem action='calendar-memopad-clipboard-cut'/>
- <menuitem action='calendar-memopad-clipboard-copy'/>
- <menuitem action='calendar-memopad-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menuitem action='calendar-memopad-forward'/>
<separator/>
@@ -129,9 +125,9 @@
<menuitem action='calendar-taskpad-save-as'/>
<menuitem action='calendar-taskpad-print'/>
<separator/>
- <menuitem action='calendar-taskpad-clipboard-cut'/>
- <menuitem action='calendar-taskpad-clipboard-copy'/>
- <menuitem action='calendar-taskpad-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menuitem action='calendar-taskpad-assign'/>
<menuitem action='calendar-taskpad-forward'/>
diff --git a/ui/evolution-contacts.ui b/ui/evolution-contacts.ui
index 864a5aa887..c3ce87108a 100644
--- a/ui/evolution-contacts.ui
+++ b/ui/evolution-contacts.ui
@@ -13,12 +13,6 @@
</menu>
<menu action='edit-menu'>
<placeholder name='edit-actions'>
- <menuitem action='contact-select-all'/>
- <separator/>
- <menuitem action='contact-clipboard-cut'/>
- <menuitem action='contact-clipboard-copy'/>
- <menuitem action='contact-clipboard-paste'/>
- <separator/>
<menuitem action='contact-delete'/>
<menuitem action='address-book-delete'/>
</placeholder>
@@ -77,9 +71,9 @@
<menuitem action='contact-popup-copy'/>
<menuitem action='contact-popup-move'/>
<separator/>
- <menuitem action='contact-popup-clipboard-cut'/>
- <menuitem action='contact-popup-clipboard-copy'/>
- <menuitem action='contact-popup-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<menuitem action='contact-popup-delete'/>
</popup>
<popup name='contact-search-options'>
diff --git a/ui/evolution-mail-reader.ui b/ui/evolution-mail-reader.ui
index 1209144486..b54f4b970e 100644
--- a/ui/evolution-mail-reader.ui
+++ b/ui/evolution-mail-reader.ui
@@ -11,10 +11,6 @@
</menu>
<menu action='edit-menu'>
<placeholder name='edit-actions'>
- <menuitem action='mail-clipboard-copy'/>
- <separator/>
- <menuitem action='mail-select-all'/>
- <separator/>
<menuitem action='mail-delete'/>
<menuitem action='mail-undelete'/>
<separator/>
@@ -145,8 +141,6 @@
</placeholder>
</popup>
<popup name='mail-preview-popup'>
- <menuitem action='mail-popup-clipboard-copy'/>
- <separator/>
<menuitem action='mail-popup-reply-sender'/>
<menuitem action='mail-popup-reply-all'/>
<menuitem action='mail-popup-forward'/>
diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui
index f2c162c387..ec971201d1 100644
--- a/ui/evolution-mail.ui
+++ b/ui/evolution-mail.ui
@@ -42,7 +42,6 @@
<menuitem action='mail-folder-copy'/>
<menuitem action='mail-folder-move'/>
<separator/>
- <menuitem action='mail-folder-select-all'/>
<menuitem action='mail-folder-select-thread'/>
<menuitem action='mail-folder-select-subthread'/>
<menuitem action='mail-folder-mark-all-as-read'/>
diff --git a/ui/evolution-memos.ui b/ui/evolution-memos.ui
index 0d842b1526..29c4263440 100644
--- a/ui/evolution-memos.ui
+++ b/ui/evolution-memos.ui
@@ -11,10 +11,6 @@
</menu>
<menu action='edit-menu'>
<placeholder name='edit-actions'>
- <menuitem action='memo-clipboard-cut'/>
- <menuitem action='memo-clipboard-copy'/>
- <menuitem action='memo-clipboard-paste'/>
- <separator/>
<menuitem action='memo-delete'/>
</placeholder>
</menu>
@@ -31,9 +27,9 @@
</menubar>
<toolbar name='main-toolbar'>
<placeholder name='toolbar-actions'>
- <toolitem action='memo-clipboard-cut'/>
- <toolitem action='memo-clipboard-copy'/>
- <toolitem action='memo-clipboard-paste'/>
+ <toolitem action='cut-clipboard'/>
+ <toolitem action='copy-clipboard'/>
+ <toolitem action='paste-clipboard'/>
<separator/>
<toolitem action='memo-list-print'/>
<toolitem action='memo-delete'/>
@@ -47,9 +43,9 @@
<menuitem action='memo-popup-save-as'/>
<menuitem action='memo-popup-print'/>
<separator/>
- <menuitem action='memo-popup-clipboard-cut'/>
- <menuitem action='memo-popup-clipboard-copy'/>
- <menuitem action='memo-popup-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menuitem action='memo-popup-forward'/>
<separator/>
diff --git a/ui/evolution-shell.ui b/ui/evolution-shell.ui
index ccfeb865d2..654d322f60 100644
--- a/ui/evolution-shell.ui
+++ b/ui/evolution-shell.ui
@@ -20,6 +20,12 @@
<menuitem action='quit'/>
</menu>
<menu action='edit-menu'>
+ <menuitem action='cut-clipboard'/>
+ <menuitem action='copy-clipboard'/>
+ <menuitem action='paste-clipboard'/>
+ <separator/>
+ <menuitem action='select-all'/>
+ <separator/>
<placeholder name='edit-actions'/>
<separator/>
<menuitem action='sync-options'/>
diff --git a/ui/evolution-tasks.ui b/ui/evolution-tasks.ui
index 70695883df..de4d97e067 100644
--- a/ui/evolution-tasks.ui
+++ b/ui/evolution-tasks.ui
@@ -11,10 +11,6 @@
</menu>
<menu action='edit-menu'>
<placeholder name='edit-actions'>
- <menuitem action='task-clipboard-cut'/>
- <menuitem action='task-clipboard-copy'/>
- <menuitem action='task-clipboard-paste'/>
- <separator/>
<menuitem action='task-delete'/>
<separator/>
<menuitem action='task-mark-complete'/>
@@ -40,9 +36,9 @@
</placeholder>
</menubar>
<toolbar name='main-toolbar'>
- <toolitem action='task-clipboard-cut'/>
- <toolitem action='task-clipboard-copy'/>
- <toolitem action='task-clipboard-paste'/>
+ <toolitem action='cut-clipboard'/>
+ <toolitem action='copy-clipboard'/>
+ <toolitem action='paste-clipboard'/>
<separator/>
<toolitem action='task-print'/>
<toolitem action='task-delete'/>
@@ -55,9 +51,9 @@
<menuitem action='task-popup-save-as'/>
<menuitem action='task-popup-print'/>
<separator/>
- <menuitem action='task-popup-clipboard-cut'/>
- <menuitem action='task-popup-clipboard-copy'/>
- <menuitem action='task-popup-clipboard-paste'/>
+ <menuitem action='popup-cut-clipboard'/>
+ <menuitem action='popup-copy-clipboard'/>
+ <menuitem action='popup-paste-clipboard'/>
<separator/>
<menuitem action='task-popup-assign'/>
<menuitem action='task-popup-forward'/>
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)
{