diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/mimeview.c | 85 | ||||
-rw-r--r-- | src/mimeview.h | 7 | ||||
-rw-r--r-- | src/textview.c | 138 |
4 files changed, 236 insertions, 0 deletions
@@ -1,5 +1,11 @@ 2011-06-13 + * src/textview.c + src/mimeview.[ch]: implemented popup menu of attachments in text + view. + +2011-06-13 + * src/textview.c: fixed handling of button release event. 2011-06-10 diff --git a/src/mimeview.c b/src/mimeview.c index be13eaf5..8fe0a8fd 100644 --- a/src/mimeview.c +++ b/src/mimeview.c @@ -1137,6 +1137,91 @@ void mimeview_print(MimeView *mimeview) } } +void mimeview_lauhch_part(MimeView *mimeview, MimeInfo *partinfo) +{ + gchar *filename; + + g_return_if_fail(partinfo != NULL); + + if (!mimeview->file) return; + + filename = procmime_get_tmp_file_name(partinfo); + + if (procmime_get_part(filename, mimeview->file, partinfo) < 0) + alertpanel_error + (_("Can't save the part of multipart message.")); + else + mimeview_view_file(filename, partinfo, NULL); + + g_free(filename); +} + +void mimeview_open_part_with(MimeView *mimeview, MimeInfo *partinfo) +{ + gchar *filename; + gchar *cmd; + + g_return_if_fail(partinfo != NULL); + + if (!mimeview->file) return; + + filename = procmime_get_tmp_file_name(partinfo); + + if (procmime_get_part(filename, mimeview->file, partinfo) < 0) { + alertpanel_error + (_("Can't save the part of multipart message.")); + g_free(filename); + return; + } + + if (!prefs_common.mime_open_cmd_history) + prefs_common.mime_open_cmd_history = + add_history(NULL, prefs_common.mime_open_cmd); + + cmd = input_dialog_combo + (_("Open with"), + _("Enter the command line to open file:\n" + "(`%s' will be replaced with file name)"), + prefs_common.mime_open_cmd, + prefs_common.mime_open_cmd_history, + TRUE); + if (cmd) { + mimeview_view_file(filename, partinfo, cmd); + g_free(prefs_common.mime_open_cmd); + prefs_common.mime_open_cmd = cmd; + prefs_common.mime_open_cmd_history = + add_history(prefs_common.mime_open_cmd_history, cmd); + } + + g_free(filename); +} + +void mimeview_save_part_as(MimeView *mimeview, MimeInfo *partinfo) +{ + gchar *filename; + gchar *defname = NULL; + + g_return_if_fail(partinfo != NULL); + + if (!mimeview->file) return; + + if (partinfo->filename) + defname = partinfo->filename; + else if (partinfo->name) { + Xstrdup_a(defname, partinfo->name, return); + subst_for_filename(defname); + } + + filename = filesel_save_as(defname); + if (!filename) return; + + if (procmime_get_part(filename, mimeview->file, partinfo) < 0) + alertpanel_error + (_("Can't save the part of multipart message.")); + + g_free(filename); +} + static void mimeview_launch(MimeView *mimeview) { MimeInfo *partinfo; diff --git a/src/mimeview.h b/src/mimeview.h index f8ac8c4f..f5742c8d 100644 --- a/src/mimeview.h +++ b/src/mimeview.h @@ -94,4 +94,11 @@ void mimeview_save_all (MimeView *mimeview); void mimeview_print (MimeView *mimeview); +void mimeview_lauhch_part (MimeView *mimeview, + MimeInfo *partinfo); +void mimeview_open_part_with (MimeView *mimeview, + MimeInfo *partinfo); +void mimeview_save_part_as (MimeView *mimeview, + MimeInfo *partinfo); + #endif /* __MIMEVIEW_H__ */ diff --git a/src/textview.c b/src/textview.c index ff8047a1..1284ea88 100644 --- a/src/textview.c +++ b/src/textview.c @@ -56,6 +56,7 @@ #include "displayheader.h" #include "filesel.h" #include "alertpanel.h" +#include "menu.h" #include "plugin.h" typedef struct _RemoteURI RemoteURI; @@ -622,10 +623,68 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp) gtk_text_view_scroll_mark_onscreen(text, mark); } +enum { + PART_MENU_NONE, + PART_MENU_OPEN, + PART_MENU_OPEN_WITH, + PART_MENU_SAVE_AS, + PART_MENU_COPY_FILENAME +}; + +static void part_widget_menu_button_position(GtkMenu *menu, gint *x, gint *y, + gboolean *push_in, + gpointer user_data) +{ + GtkWidget *widget; + GtkRequisition requisition; + gint button_xpos, button_ypos; + gint xpos, ypos; + gint width, height; + gint scr_width, scr_height; + + g_return_if_fail(x != NULL && y != NULL); + + widget = GTK_WIDGET(user_data); + gtk_widget_get_child_requisition(GTK_WIDGET(menu), &requisition); + width = requisition.width; + height = requisition.height; + gdk_window_get_origin(widget->window, &button_xpos, &button_ypos); + g_print("pos: %d, %d\n", button_xpos, button_ypos); + + xpos = button_xpos; + ypos = button_ypos + widget->requisition.height; + + scr_width = gdk_screen_width(); + scr_height = gdk_screen_height(); + + if (xpos + width > scr_width) + xpos -= (xpos + width) - scr_width; + if (ypos + height > scr_height) + ypos -= widget->requisition.height + height; + if (xpos < 0) + xpos = 0; + if (ypos < 0) + ypos = 0; + + *x = xpos; + *y = ypos; +} + static gboolean textview_part_widget_button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer data) { + GtkWidget *menu; + MimeInfo *mimeinfo; + + if (!event) + return FALSE; + + menu = g_object_get_data(G_OBJECT(widget), "part-menu"); + mimeinfo = g_object_get_data(G_OBJECT(widget), "mimeinfo"); + + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, part_widget_menu_button_position, widget, event->button, event->time); + return TRUE; } @@ -652,6 +711,58 @@ static gboolean textview_part_widget_exposed(GtkWidget *widget, return TRUE; } +static void textview_part_widget_destroy_notify(gpointer data) +{ + GtkWidget *menu; + + menu = g_object_get_data(G_OBJECT(data), "part-menu"); + gtk_widget_destroy(menu); +} + +static void textview_part_widget_menu_activated(GtkWidget *widget, + gpointer data) +{ + TextView *textview = (TextView *)data; + GtkWidget *menu; + gint type; + MimeInfo *mimeinfo; + MimeView *mimeview = textview->messageview->mimeview; + const gchar *filename; + GtkClipboard *clipboard; + + g_print("textview_part_widget_menu_activated\n"); + + menu = gtk_widget_get_parent(widget); + mimeinfo = g_object_get_data(G_OBJECT(menu), "mimeinfo"); + if (!mimeinfo) + return; + type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), MENU_VAL_ID)); + + switch (type) { + case PART_MENU_OPEN: + mimeview_lauhch_part(mimeview, mimeinfo); + break; + case PART_MENU_OPEN_WITH: + mimeview_open_part_with(mimeview, mimeinfo); + break; + case PART_MENU_SAVE_AS: + mimeview_save_part_as(mimeview, mimeinfo); + break; + case PART_MENU_COPY_FILENAME: + filename = mimeinfo->filename ? mimeinfo->filename : + mimeinfo->name ? mimeinfo->name : NULL; + if (filename) { + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, filename, -1); + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, filename, -1); + } + break; + default: + break; + } +} + static void textview_add_part_widget(TextView *textview, GtkTextIter *iter, MimeInfo *mimeinfo, const gchar *str) { @@ -662,6 +773,8 @@ static void textview_add_part_widget(TextView *textview, GtkTextIter *iter, GtkWidget *ebox; GtkWidget *label; GtkWidget *arrow; + GtkWidget *menu; + GtkWidget *menuitem; GdkColor bg = {0, 0xd000, 0xd800, 0xffff}; GdkColor fg = {0, 0x7000, 0x9000, 0xffff}; @@ -684,6 +797,31 @@ static void textview_add_part_widget(TextView *textview, GtkTextIter *iter, G_CALLBACK(textview_part_widget_exposed), textview); gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, &bg); gtk_widget_modify_fg(ebox, GTK_STATE_NORMAL, &fg); + + menu = gtk_menu_new(); + MENUITEM_ADD_WITH_MNEMONIC(menu, menuitem, _("_Open"), PART_MENU_OPEN); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(textview_part_widget_menu_activated), + textview); + MENUITEM_ADD_WITH_MNEMONIC(menu, menuitem, _("Open _with..."), PART_MENU_OPEN_WITH); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(textview_part_widget_menu_activated), + textview); + MENUITEM_ADD_WITH_MNEMONIC(menu, menuitem, _("_Save as..."), PART_MENU_SAVE_AS); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(textview_part_widget_menu_activated), + textview); + MENUITEM_ADD(menu, menuitem, NULL, 0); + MENUITEM_ADD_WITH_MNEMONIC(menu, menuitem, _("_Copy file name"), PART_MENU_COPY_FILENAME); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(textview_part_widget_menu_activated), + textview); + gtk_widget_show_all(menu); + g_object_set_data(G_OBJECT(ebox), "mimeinfo", mimeinfo); + g_object_set_data(G_OBJECT(menu), "mimeinfo", mimeinfo); + g_object_set_data_full(G_OBJECT(ebox), "part-menu", menu, + textview_part_widget_destroy_notify); + gtk_text_view_add_child_at_anchor(text, ebox, anchor); gtk_text_buffer_insert(buffer, iter, "\n", 1); } |