aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-11-18 01:06:40 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-11-18 02:59:25 +0800
commitef498ab03510076d9b4a80f52164032a413ec867 (patch)
treeaf54307fc3d76074bd88ada151db91814e2cf41d
parentc745f731823dec03232e656352fcdba29eb57b96 (diff)
downloadgsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar.gz
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar.bz2
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar.lz
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar.xz
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.tar.zst
gsoc2013-evolution-ef498ab03510076d9b4a80f52164032a413ec867.zip
Remove some redundancy from EABContactDisplay.
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c469
-rw-r--r--widgets/misc/e-web-view.c2
2 files changed, 196 insertions, 275 deletions
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index 0ade284323..692b6f003e 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -46,14 +46,6 @@
struct _EABContactDisplayPrivate {
EContact *contact;
EABContactDisplayMode mode;
-
- GtkUIManager *ui_manager;
- GtkActionGroup *email_actions;
- GtkActionGroup *uri_actions;
- GtkWidget *invisible;
-
- gchar *selected_uri;
- gchar *clipboard_uri;
};
enum {
@@ -98,11 +90,13 @@ common_location [] =
static const gchar *ui =
"<ui>"
-" <popup>"
-" <menuitem action='open-link'/>"
-" <menuitem action='copy-link'/>"
-" <menuitem action='send-message'/>"
-" <menuitem action='copy-address'/>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-1'>"
+" <menuitem action='contact-send-message'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-2'>"
+" <menuitem action='contact-mailto-copy'/>"
+" </placeholder>"
" </popup>"
"</ui>";
@@ -110,135 +104,85 @@ static gpointer parent_class;
static guint signals[LAST_SIGNAL];
static void
-action_copy_address_cb (GtkAction *action,
- EABContactDisplay *display)
+contact_display_emit_send_message (EABContactDisplay *display,
+ gint email_num)
{
+ EDestination *destination;
+ EContact *contact;
+
+ g_return_if_fail (email_num >= 0);
+
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, email_num);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
+}
+
+static void
+action_contact_mailto_copy_cb (GtkAction *action,
+ EABContactDisplay *display)
+{
+ GtkClipboard *clipboard;
+ EWebView *web_view;
EContact *contact;
GList *list;
+ const gchar *text;
const gchar *uri;
- gchar *html;
gint index;
- uri = display->priv->selected_uri;
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
index = atoi (uri + strlen ("internal-mailto:"));
- contact = eab_contact_display_get_contact (display);
+ g_return_if_fail (index >= 0);
+ contact = eab_contact_display_get_contact (display);
list = e_contact_get (contact, E_CONTACT_EMAIL);
- html = e_text_to_html (g_list_nth_data (list, index), 0);
- g_list_foreach (list, (GFunc) g_free, NULL);
- g_list_free (list);
-
- display->priv->clipboard_uri = html;
- display->priv->selected_uri = NULL;
+ text = g_list_nth_data (list, index);
- gtk_selection_owner_set (
- display->priv->invisible, GDK_SELECTION_PRIMARY,
- gtk_get_current_event_time ());
- gtk_selection_owner_set (
- display->priv->invisible, GDK_SELECTION_CLIPBOARD,
- gtk_get_current_event_time ());
-}
-
-static void
-action_copy_link_cb (GtkAction *action,
- EABContactDisplay *display)
-{
- display->priv->clipboard_uri = display->priv->selected_uri;
- display->priv->selected_uri = NULL;
-
- gtk_selection_owner_set (
- display->priv->invisible, GDK_SELECTION_PRIMARY,
- gtk_get_current_event_time ());
- gtk_selection_owner_set (
- display->priv->invisible, GDK_SELECTION_CLIPBOARD,
- gtk_get_current_event_time ());
-}
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
-static void
-action_open_link_cb (GtkAction *action,
- EABContactDisplay *display)
-{
- /* XXX Pass a parent window. */
- e_show_uri (NULL, display->priv->selected_uri);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
}
static void
-action_send_message_cb (GtkAction *action,
- EABContactDisplay *display)
+action_contact_send_message_cb (GtkAction *action,
+ EABContactDisplay *display)
{
- EDestination *destination;
- EContact *contact;
+ EWebView *web_view;
const gchar *uri;
- gint row;
+ gint index;
- uri = display->priv->selected_uri;
- row = atoi (uri + strlen ("internal-mailto:"));
- g_return_if_fail (row >= 0);
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
- destination = e_destination_new ();
- contact = eab_contact_display_get_contact (display);
- e_destination_set_contact (destination, contact, row);
- g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
- g_object_unref (destination);
+ index = atoi (uri + strlen ("internal-mailto:"));
+ contact_display_emit_send_message (display, index);
}
-static GtkActionEntry email_entries[] = {
+static GtkActionEntry internal_mailto_entries[] = {
- { "copy-address",
- NULL,
+ { "contact-mailto-copy",
+ GTK_STOCK_COPY,
N_("Copy _Email Address"),
NULL,
- NULL,
- G_CALLBACK (action_copy_address_cb) },
+ N_("Copy the email address to the clipboard"),
+ G_CALLBACK (action_contact_mailto_copy_cb) },
- { "send-message",
- NULL,
+ { "contact-send-message",
+ "mail-message-new",
N_("_Send New Message To..."),
NULL,
- NULL,
- G_CALLBACK (action_send_message_cb) }
+ N_("Send a mail message to this address"),
+ G_CALLBACK (action_contact_send_message_cb) }
};
-static GtkActionEntry uri_entries[] = {
-
- { "copy-link",
- NULL,
- N_("_Copy Link Location"),
- NULL,
- NULL,
- G_CALLBACK (action_copy_link_cb) },
-
- { "open-link",
- NULL,
- N_("_Open Link in Browser"),
- NULL,
- NULL,
- G_CALLBACK (action_open_link_cb) }
-};
-
-static void
-contact_display_selection_get (EABContactDisplay *display,
- GtkSelectionData *data,
- guint info,
- guint time_stamp)
-{
- if (display->priv->clipboard_uri == NULL)
- return;
-
- gtk_selection_data_set (
- data, data->target, 8,
- (guchar *) display->priv->clipboard_uri,
- strlen (display->priv->clipboard_uri));
-}
-
-static void
-contact_display_selection_clear_event (EABContactDisplay *display,
- GdkEventSelection *event)
-{
- g_free (display->priv->clipboard_uri);
- display->priv->clipboard_uri = NULL;
-}
-
static void
render_name_value (GtkHTMLStream *html_stream, const gchar *label, const gchar *str, const gchar *icon, guint html_flags)
{
@@ -823,54 +767,6 @@ eab_contact_display_render_compact (EABContactDisplay *display,
gtk_html_end (GTK_HTML (display), html_stream, GTK_HTML_STREAM_OK);
}
-static gint
-contact_display_button_press_event (GtkWidget *widget,
- GdkEvent *event,
- EABContactDisplay *display)
-{
- GtkUIManager *ui_manager;
- GtkActionGroup *action_group;
- GtkWidget *menu;
- gboolean has_email;
- gchar *uri;
-
- if (event->button.button != 3)
- return FALSE;
-
- uri = gtk_html_get_url_at (
- GTK_HTML (widget),
- event->button.x, event->button.y);
-
- if (uri == NULL)
- return FALSE;
-
- g_free (display->priv->selected_uri);
- display->priv->selected_uri = uri;
-
- ui_manager = display->priv->ui_manager;
- menu = gtk_ui_manager_get_widget (ui_manager, "/popup");
- g_return_val_if_fail (GTK_IS_MENU (menu), FALSE);
-
- has_email = (g_ascii_strncasecmp (uri, "internal-mailto:", 16) == 0);
-
- /* Show the appropriate actions. */
- action_group = display->priv->email_actions;
- gtk_action_group_set_visible (action_group, has_email);
- action_group = display->priv->uri_actions;
- gtk_action_group_set_visible (action_group, !has_email);
-
- if (event != NULL)
- gtk_menu_popup (
- GTK_MENU (menu), NULL, NULL, NULL, NULL,
- event->button.button, event->button.time);
- else
- gtk_menu_popup (
- GTK_MENU (menu), NULL, NULL, NULL, NULL,
- 0, gtk_get_current_event_time ());
-
- return TRUE;
-}
-
static void
contact_display_set_property (GObject *object,
guint property_id,
@@ -929,26 +825,6 @@ contact_display_dispose (GObject *object)
priv->contact = NULL;
}
- if (priv->ui_manager != NULL) {
- g_object_unref (priv->ui_manager);
- priv->ui_manager = NULL;
- }
-
- if (priv->email_actions != NULL) {
- g_object_unref (priv->email_actions);
- priv->email_actions = NULL;
- }
-
- if (priv->uri_actions != NULL) {
- g_object_unref (priv->uri_actions);
- priv->uri_actions = NULL;
- }
-
- if (priv->invisible != NULL) {
- g_object_unref (priv->invisible);
- priv->invisible = NULL;
- }
-
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -960,30 +836,35 @@ contact_display_finalize (GObject *object)
priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (object);
- g_free (priv->selected_uri);
- g_free (priv->clipboard_uri);
-
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
contact_display_url_requested (GtkHTML *html,
- const gchar *url,
+ const gchar *uri,
GtkHTMLStream *handle)
{
- EABContactDisplayPrivate *priv;
+ EABContactDisplay *display;
+ GtkHTMLClass *class;
+ gsize length;
- priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (html);
+ display = EAB_CONTACT_DISPLAY (html);
+ class = GTK_HTML_CLASS (parent_class);
- if (strcmp (url, "internal-contact-photo:") == 0) {
+ /* internal-contact-photo: */
+ if (strcmp (uri, "internal-contact-photo:") == 0) {
EContactPhoto *photo;
+ EContact *contact;
- photo = e_contact_get (priv->contact, E_CONTACT_PHOTO);
- if (!photo)
- photo = e_contact_get (priv->contact, E_CONTACT_LOGO);
+ contact = eab_contact_display_get_contact (display);
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (photo == NULL)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
- gtk_html_stream_write (handle, (gchar *)photo->data.inlined.data, photo->data.inlined.length);
+ gtk_html_stream_write (
+ handle, (gchar *) photo->data.inlined.data,
+ photo->data.inlined.length);
gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
@@ -992,26 +873,39 @@ contact_display_url_requested (GtkHTML *html,
return;
}
- if (strncmp (url, "evo-icon:", strlen ("evo-icon:")) == 0) {
- gchar *data;
- gsize data_length;
- gchar *filename;
-
- filename = e_icon_factory_get_icon_filename (url + strlen ("evo-icon:"), GTK_ICON_SIZE_MENU);
- if (g_file_get_contents (filename, &data, &data_length, NULL)) {
- gtk_html_stream_write (handle, data, data_length);
- g_free (data);
+ /* evo-icon:<<themed-icon-name>> */
+ length = strlen ("evo-icon:");
+ if (g_ascii_strncasecmp (uri, "evo-icon:", length) == 0) {
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+ const gchar *filename;
+ gchar *icon_uri;
+ GError *error = NULL;
+
+ icon_theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_icon (
+ icon_theme, uri + length, GTK_ICON_SIZE_MENU, 0);
+ g_return_if_fail (icon_info != NULL);
+
+ filename = gtk_icon_info_get_filename (icon_info);
+ icon_uri = g_filename_to_uri (filename, NULL, &error);
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
- gtk_html_stream_close (handle, GTK_HTML_STREAM_OK);
+ /* Chain up with the URI for the icon file. */
+ class->url_requested (html, icon_uri, handle);
- g_free (filename);
+ gtk_icon_info_free (icon_info);
+ g_free (icon_uri);
return;
}
- /* Chain up to parent's url_requested() method. */
- GTK_HTML_CLASS (parent_class)->url_requested (html, url, handle);
+ /* Chain up to parent's uri_requested() method. */
+ class->url_requested (html, uri, handle);
}
static void
@@ -1019,38 +913,93 @@ contact_display_link_clicked (GtkHTML *html,
const gchar *uri)
{
EABContactDisplay *display;
+ gsize length;
display = EAB_CONTACT_DISPLAY (html);
-#ifdef HANDLE_MAILTO_INTERNALLY
- if (!strncmp (uri, "internal-mailto:", strlen ("internal-mailto:"))) {
- EDestination *destination;
- EContact *contact;
- gint email_num;
-
- email_num = atoi (uri + strlen ("internal-mailto:"));
- if (email_num == -1)
- return;
-
- destination = e_destination_new ();
- contact = eab_contact_display_get_contact (display);
- e_destination_set_contact (destination, contact, email_num);
- g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
- g_object_unref (destination);
+ length = strlen ("internal-mailto:");
+ if (g_ascii_strncasecmp (uri, "internal-mailto:", length) == 0) {
+ gint index;
+ index = atoi (uri + length);
+ contact_display_emit_send_message (display, index);
return;
}
-#endif
/* Chain up to parent's link_clicked() method. */
GTK_HTML_CLASS (parent_class)->link_clicked (html, uri);
}
static void
+contact_display_on_url (GtkHTML *html,
+ const gchar *uri)
+{
+ EABContactDisplay *display;
+ EContact *contact;
+ const gchar *name;
+ gchar *message;
+
+ if (uri == NULL || *uri == '\0')
+ goto chainup;
+
+ if (!g_str_has_prefix (uri, "internal-mailto:"))
+ goto chainup;
+
+ display = EAB_CONTACT_DISPLAY (html);
+ contact = eab_contact_display_get_contact (display);
+
+ name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (name == NULL)
+ e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ g_return_if_fail (name != NULL);
+
+ message = g_strdup_printf (_("Click to mail %s"), name);
+ e_web_view_status_message (E_WEB_VIEW (html), message);
+ g_free (message);
+
+ return;
+
+chainup:
+ /* Chain up to parent's on_url() method. */
+ GTK_HTML_CLASS (parent_class)->on_url (html, uri);
+}
+
+static void
+contact_display_update_actions (EWebView *web_view)
+{
+ GtkActionGroup *action_group;
+ gboolean scheme_is_internal_mailto;
+ gboolean visible;
+ const gchar *group_name;
+ const gchar *uri;
+
+ /* Chain up to parent's update_actions() method. */
+ E_WEB_VIEW_CLASS (parent_class)->update_actions (web_view);
+
+ uri = e_web_view_get_selected_uri (web_view);
+
+ scheme_is_internal_mailto = (uri == NULL) ? FALSE :
+ (g_ascii_strncasecmp (uri, "internal-mailto:", 16) == 0);
+
+ /* Override how EWebView treats internal-mailto URIs. */
+ group_name = "uri";
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ visible = gtk_action_group_get_visible (action_group);
+ visible &= !scheme_is_internal_mailto;
+ gtk_action_group_set_visible (action_group, visible);
+
+ group_name = "internal-mailto";
+ visible = scheme_is_internal_mailto;
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ gtk_action_group_set_visible (action_group, visible);
+}
+
+static void
eab_contact_display_class_init (EABContactDisplayClass *class)
{
GObjectClass *object_class;
GtkHTMLClass *html_class;
+ EWebViewClass *web_view_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EABContactDisplayPrivate));
@@ -1064,6 +1013,10 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
html_class = GTK_HTML_CLASS (class);
html_class->url_requested = contact_display_url_requested;
html_class->link_clicked = contact_display_link_clicked;
+ html_class->on_url = contact_display_on_url;
+
+ web_view_class = E_WEB_VIEW_CLASS (class);
+ web_view_class->update_actions = contact_display_update_actions;
g_object_class_install_property (
object_class,
@@ -1102,65 +1055,33 @@ eab_contact_display_class_init (EABContactDisplayClass *class)
static void
eab_contact_display_init (EABContactDisplay *display)
{
+ EWebView *web_view;
+ GtkUIManager *ui_manager;
GtkActionGroup *action_group;
- GtkHTML *html;
- const gchar *id;
+ const gchar *domain = GETTEXT_PACKAGE;
+ GError *error = NULL;
display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display);
display->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
- display->priv->ui_manager = gtk_ui_manager_new ();
- display->priv->invisible = gtk_invisible_new ();
- g_object_ref_sink (display->priv->invisible);
+ web_view = E_WEB_VIEW (display);
+ ui_manager = e_web_view_get_ui_manager (web_view);
+
+ action_group = gtk_action_group_new ("internal-mailto");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
- action_group = gtk_action_group_new ("email");
- gtk_action_group_set_translation_domain (
- action_group, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (
- action_group, email_entries,
- G_N_ELEMENTS (email_entries), display);
- gtk_ui_manager_insert_action_group (
- display->priv->ui_manager, action_group, 0);
- display->priv->email_actions = action_group;
-
- action_group = gtk_action_group_new ("uri");
- gtk_action_group_set_translation_domain (
- action_group, GETTEXT_PACKAGE);
gtk_action_group_add_actions (
- action_group, uri_entries,
- G_N_ELEMENTS (uri_entries), display);
- gtk_ui_manager_insert_action_group (
- display->priv->ui_manager, action_group, 0);
- display->priv->uri_actions = action_group;
-
- gtk_ui_manager_add_ui_from_string (
- display->priv->ui_manager, ui, -1, NULL);
-
- html = GTK_HTML (display);
- gtk_html_construct (html);
- gtk_html_set_editable (html, FALSE);
- gtk_html_set_default_content_type (html, "text/html; charset=utf-8");
-
- g_signal_connect (
- display, "button-press-event",
- G_CALLBACK (contact_display_button_press_event), display);
-
- g_signal_connect_swapped (
- display->priv->invisible, "selection-get",
- G_CALLBACK (contact_display_selection_get), display);
- g_signal_connect_swapped (
- display->priv->invisible, "selection-clear-event",
- G_CALLBACK (contact_display_selection_clear_event), display);
- gtk_selection_add_target (
- display->priv->invisible,
- GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
- gtk_selection_add_target (
- display->priv->invisible,
- GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
-
- id = "org.gnome.evolution.contact-display";
- e_plugin_ui_register_manager (display->priv->ui_manager, id, display);
- e_plugin_ui_enable_manager (display->priv->ui_manager, id);
+ action_group, internal_mailto_entries,
+ G_N_ELEMENTS (internal_mailto_entries), display);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
}
GType
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 5d56735e5e..a71bf8299a 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -272,7 +272,6 @@ action_mailto_copy_cb (GtkAction *action,
const gchar *uri;
gchar *text;
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
uri = e_web_view_get_selected_uri (web_view);
g_return_if_fail (uri != NULL);
@@ -289,6 +288,7 @@ action_mailto_copy_cb (GtkAction *action,
camel_object_unref (inet_addr);
camel_url_free (curl);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text (clipboard, text, -1);
gtk_clipboard_store (clipboard);