aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--src/mimeview.c85
-rw-r--r--src/mimeview.h7
-rw-r--r--src/textview.c138
4 files changed, 236 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index c58895fb..5f6021b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
}