diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2010-01-17 02:34:32 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-01-18 01:11:08 +0800 |
commit | 3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff (patch) | |
tree | d74cd0017e310c79b796eba3df7bfb8947a673d7 /composer | |
parent | 2cf0c27e2ece428dd2af1945f6fececbe9dbcc15 (diff) | |
download | gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.gz gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.bz2 gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.lz gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.xz gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.zst gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.zip |
Improve clipboard behavior.
Add "copy-target-list" and "paste-target-list" to the ESelectable
interface. These are underutilized for the moment, but will eventually
be used to help integrate drag-and-drop support into ESelectable.
Add cut and paste support to EWebView, along with a new "editable"
property and new clipboard signals "copy-clipboard", "cut-clipboard" and
"paste-clipboard".
In EFocusTracker, listen for "owner-changed" signals from the default
clipboard as another trigger to update actions, particularly the Paste
action. (Unfortunately this doesn't work for EWebView since GtkHtml
implements its own clipboard.)
In EMsgComposer, convert GtkhtmlEditor's clipboard methods to empty
stubs, since EFocusTracker will now trigger EWebView's clipboard
actions. Also, intercept EWebView::paste-clipboard signals and improve
the interaction between the HTML editor and the attachment bar based on
use cases in bug #603715.
Diffstat (limited to 'composer')
-rw-r--r-- | composer/e-composer-private.c | 42 | ||||
-rw-r--r-- | composer/e-composer-private.h | 5 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 134 |
3 files changed, 111 insertions, 70 deletions
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c index b0bc0c999d..0f7ffbb64c 100644 --- a/composer/e-composer-private.c +++ b/composer/e-composer-private.c @@ -509,6 +509,27 @@ e_composer_get_default_charset (void) } gboolean +e_composer_paste_html (EMsgComposer *composer, + GtkClipboard *clipboard) +{ + GtkhtmlEditor *editor; + gchar *html; + + g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); + g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE); + + html = e_clipboard_wait_for_html (clipboard); + g_return_val_if_fail (html != NULL, FALSE); + + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_insert_html (editor, html); + + g_free (html); + + return TRUE; +} + +gboolean e_composer_paste_image (EMsgComposer *composer, GtkClipboard *clipboard) { @@ -583,6 +604,27 @@ exit: } gboolean +e_composer_paste_text (EMsgComposer *composer, + GtkClipboard *clipboard) +{ + GtkhtmlEditor *editor; + gchar *text; + + g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); + g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE); + + text = gtk_clipboard_wait_for_text (clipboard); + g_return_val_if_fail (text != NULL, FALSE); + + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_insert_text (editor, text); + + g_free (text); + + return TRUE; +} + +gboolean e_composer_paste_uris (EMsgComposer *composer, GtkClipboard *clipboard) { diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h index 1711e0c17b..cac41aabe4 100644 --- a/composer/e-composer-private.h +++ b/composer/e-composer-private.h @@ -52,6 +52,7 @@ #include "e-util/e-binding.h" #include "e-util/e-charset.h" #include "e-util/e-mktemp.h" +#include "e-util/e-selection.h" #include "e-util/e-util.h" #include "e-util/gconf-bridge.h" #include "widgets/misc/e-attachment-icon-view.h" @@ -157,8 +158,12 @@ void e_composer_private_finalize (EMsgComposer *composer); void e_composer_actions_init (EMsgComposer *composer); gchar * e_composer_find_data_file (const gchar *basename); gchar * e_composer_get_default_charset (void); +gboolean e_composer_paste_html (EMsgComposer *composer, + GtkClipboard *clipboard); gboolean e_composer_paste_image (EMsgComposer *composer, GtkClipboard *clipboard); +gboolean e_composer_paste_text (EMsgComposer *composer, + GtkClipboard *clipboard); gboolean e_composer_paste_uris (EMsgComposer *composer, GtkClipboard *clipboard); diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index bdac5d44ab..b57bd156a5 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -1488,6 +1488,60 @@ msg_composer_account_changed_cb (EMsgComposer *composer) e_msg_composer_show_sig_file (composer); } +static void +msg_composer_paste_clipboard_targets_cb (GtkClipboard *clipboard, + GdkAtom *targets, + gint n_targets, + EMsgComposer *composer) +{ + GtkhtmlEditor *editor; + gboolean html_mode; + + editor = GTKHTML_EDITOR (composer); + html_mode = gtkhtml_editor_get_html_mode (editor); + + /* Order is important here to ensure common use cases are + * handled correctly. See GNOME bug #603715 for details. */ + + if (gtk_targets_include_uri (targets, n_targets)) { + e_composer_paste_uris (composer, clipboard); + return; + } + + /* Only paste HTML content in HTML mode. */ + if (html_mode) { + if (e_targets_include_html (targets, n_targets)) { + e_composer_paste_html (composer, clipboard); + return; + } + } + + if (gtk_targets_include_text (targets, n_targets)) { + e_composer_paste_text (composer, clipboard); + return; + } + + if (gtk_targets_include_image (targets, n_targets, TRUE)) { + e_composer_paste_image (composer, clipboard); + return; + } +} + +static void +msg_composer_paste_clipboard_cb (EWebView *web_view, + EMsgComposer *composer) +{ + GtkClipboard *clipboard; + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + + gtk_clipboard_request_targets ( + clipboard, (GtkClipboardTargetsReceivedFunc) + msg_composer_paste_clipboard_targets_cb, composer); + + g_signal_stop_emission_by_name (web_view, "paste-clipboard"); +} + struct _drop_data { EMsgComposer *composer; @@ -1616,6 +1670,12 @@ msg_composer_constructed (GObject *object) shell_settings, "composer-request-receipt"); gtk_toggle_action_set_active (action, active); + /* Clipboard Support */ + + g_signal_connect ( + html, "paste-clipboard", + G_CALLBACK (msg_composer_paste_clipboard_cb), composer); + /* Drag-and-Drop Support */ target_list = e_attachment_view_get_target_list (view); @@ -1840,91 +1900,25 @@ msg_composer_drag_data_received (GtkWidget *widget, static void msg_composer_cut_clipboard (GtkhtmlEditor *editor) { - EMsgComposer *composer; - GtkWidget *parent; - GtkWidget *widget; - - composer = E_MSG_COMPOSER (editor); - widget = gtk_window_get_focus (GTK_WINDOW (editor)); - parent = gtk_widget_get_parent (widget); - - /* EFocusTracker handles the header widgets. */ - if (parent == composer->priv->header_table) - return; - - /* Chain up to parent's cut_clipboard() method. */ - GTKHTML_EDITOR_CLASS (parent_class)->cut_clipboard (editor); + /* Do nothing. EFocusTracker handles this. */ } static void msg_composer_copy_clipboard (GtkhtmlEditor *editor) { - EMsgComposer *composer; - GtkWidget *parent; - GtkWidget *widget; - - composer = E_MSG_COMPOSER (editor); - widget = gtk_window_get_focus (GTK_WINDOW (editor)); - parent = gtk_widget_get_parent (widget); - - /* EFocusTracker handles the header widgets. */ - if (parent == composer->priv->header_table) - return; - - /* Chain up to parent's copy_clipboard() method. */ - GTKHTML_EDITOR_CLASS (parent_class)->copy_clipboard (editor); + /* Do nothing. EFocusTracker handles this. */ } static void msg_composer_paste_clipboard (GtkhtmlEditor *editor) { - EMsgComposer *composer; - GtkClipboard *clipboard; - GtkWidget *parent; - GtkWidget *widget; - - composer = E_MSG_COMPOSER (editor); - - widget = gtk_window_get_focus (GTK_WINDOW (editor)); - parent = gtk_widget_get_parent (widget); - - /* EFocusTracker handles the header widgets. */ - if (parent == composer->priv->header_table) - return; - - clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD); - - if (gtk_clipboard_wait_is_image_available (clipboard)) { - e_composer_paste_image (composer, clipboard); - return; - } - - if (gtk_clipboard_wait_is_uris_available (clipboard)) { - e_composer_paste_uris (composer, clipboard); - return; - } - - /* Chain up to parent's paste_clipboard() method. */ - GTKHTML_EDITOR_CLASS (parent_class)->paste_clipboard (editor); + /* Do nothing. EFocusTracker handles this. */ } static void msg_composer_select_all (GtkhtmlEditor *editor) { - EMsgComposer *composer; - GtkWidget *parent; - GtkWidget *widget; - - composer = E_MSG_COMPOSER (editor); - widget = gtk_window_get_focus (GTK_WINDOW (editor)); - parent = gtk_widget_get_parent (widget); - - /* EFocusTracker handles the header widgets. */ - if (parent == composer->priv->header_table) - return; - - /* Chain up to the parent's select_all() method. */ - GTKHTML_EDITOR_CLASS (parent_class)->select_all (editor); + /* Do nothing. EFocusTracker handles this. */ } static void |