Revision 275 src/mimeview.c
| mimeview.c (revision 275) | ||
|---|---|---|
| 27 | 27 |
#include <glib/gi18n.h> |
| 28 | 28 |
#include <gdk/gdkkeysyms.h> |
| 29 | 29 |
#include <gtk/gtkscrolledwindow.h> |
| 30 |
#include <gtk/gtkctree.h> |
|
| 30 |
#include <gtk/gtktreestore.h> |
|
| 31 |
#include <gtk/gtktreeview.h> |
|
| 32 |
#include <gtk/gtktreeselection.h> |
|
| 33 |
#include <gtk/gtkcellrenderertext.h> |
|
| 31 | 34 |
#include <gtk/gtkvbox.h> |
| 32 | 35 |
#include <gtk/gtkvpaned.h> |
| 33 | 36 |
#include <gtk/gtksignal.h> |
| ... | ... | |
| 35 | 38 |
#include <gtk/gtkdnd.h> |
| 36 | 39 |
#include <gtk/gtkselection.h> |
| 37 | 40 |
#include <gtk/gtknotebook.h> |
| 41 |
#include <gtk/gtkvbbox.h> |
|
| 38 | 42 |
#include <stdio.h> |
| 39 | 43 |
#include <unistd.h> |
| 40 | 44 |
|
| ... | ... | |
| 52 | 56 |
#include "gtkutils.h" |
| 53 | 57 |
#include "prefs_common.h" |
| 54 | 58 |
#include "rfc2015.h" |
| 55 |
#include "gtksctree.h" |
|
| 56 | 59 |
|
| 57 |
typedef enum
|
|
| 60 |
enum |
|
| 58 | 61 |
{
|
| 59 |
COL_MIMETYPE = 0, |
|
| 60 |
COL_SIZE = 1, |
|
| 61 |
COL_NAME = 2 |
|
| 62 |
} MimeViewColumnPos; |
|
| 62 |
COL_MIMETYPE, |
|
| 63 |
COL_SIZE, |
|
| 64 |
COL_NAME, |
|
| 65 |
COL_MIME_INFO, |
|
| 66 |
N_COLS |
|
| 67 |
}; |
|
| 63 | 68 |
|
| 64 |
#define N_MIMEVIEW_COLS 3 |
|
| 65 |
|
|
| 66 | 69 |
static void mimeview_set_multipart_tree (MimeView *mimeview, |
| 67 | 70 |
MimeInfo *mimeinfo, |
| 68 |
GtkCTreeNode *parent);
|
|
| 69 |
static GtkCTreeNode *mimeview_append_part (MimeView *mimeview,
|
|
| 71 |
GtkTreeIter *parent);
|
|
| 72 |
static gboolean mimeview_append_part (MimeView *mimeview,
|
|
| 70 | 73 |
MimeInfo *partinfo, |
| 71 |
GtkCTreeNode *parent); |
|
| 74 |
GtkTreeIter *iter, |
|
| 75 |
GtkTreeIter *parent); |
|
| 72 | 76 |
static void mimeview_show_message_part (MimeView *mimeview, |
| 73 | 77 |
MimeInfo *partinfo); |
| 74 | 78 |
static void mimeview_show_image_part (MimeView *mimeview, |
| ... | ... | |
| 82 | 86 |
static void mimeview_change_view_type (MimeView *mimeview, |
| 83 | 87 |
MimeViewType type); |
| 84 | 88 |
|
| 85 |
static void mimeview_selected (GtkCTree *ctree, |
|
| 86 |
GtkCTreeNode *node, |
|
| 87 |
gint column, |
|
| 88 |
MimeView *mimeview); |
|
| 89 |
static void mimeview_start_drag (GtkWidget *widget, |
|
| 90 |
gint button, |
|
| 91 |
GdkEvent *event, |
|
| 92 |
MimeView *mimeview); |
|
| 89 |
static void mimeview_selection_changed (GtkTreeSelection *selection, |
|
| 90 |
MimeView *mimeview); |
|
| 91 |
|
|
| 93 | 92 |
static gint mimeview_button_pressed (GtkWidget *widget, |
| 94 | 93 |
GdkEventButton *event, |
| 95 | 94 |
MimeView *mimeview); |
| ... | ... | |
| 97 | 96 |
GdkEventKey *event, |
| 98 | 97 |
MimeView *mimeview); |
| 99 | 98 |
|
| 99 |
static void mimeview_drag_begin (GtkWidget *widget, |
|
| 100 |
GdkDragContext *drag_context, |
|
| 101 |
MimeView *mimeview); |
|
| 102 |
static void mimeview_drag_end (GtkWidget *widget, |
|
| 103 |
GdkDragContext *drag_context, |
|
| 104 |
MimeView *mimeview); |
|
| 100 | 105 |
static void mimeview_drag_data_get (GtkWidget *widget, |
| 101 | 106 |
GdkDragContext *drag_context, |
| 102 | 107 |
GtkSelectionData *selection_data, |
| ... | ... | |
| 137 | 142 |
|
| 138 | 143 |
GtkWidget *paned; |
| 139 | 144 |
GtkWidget *scrolledwin; |
| 140 |
GtkWidget *ctree; |
|
| 145 |
GtkWidget *treeview; |
|
| 146 |
GtkTreeStore *store; |
|
| 147 |
GtkTreeSelection *selection; |
|
| 148 |
GtkTreeViewColumn *column; |
|
| 149 |
GtkCellRenderer *renderer; |
|
| 141 | 150 |
GtkWidget *mime_vbox; |
| 142 | 151 |
GtkWidget *popupmenu; |
| 143 | 152 |
GtkItemFactory *popupfactory; |
| 144 |
gchar *titles[N_MIMEVIEW_COLS]; |
|
| 145 | 153 |
gint n_entries; |
| 146 |
gint i; |
|
| 147 | 154 |
|
| 148 | 155 |
debug_print(_("Creating MIME view...\n"));
|
| 149 | 156 |
mimeview = g_new0(MimeView, 1); |
| 150 | 157 |
|
| 151 |
titles[COL_MIMETYPE] = _("MIME Type");
|
|
| 152 |
titles[COL_SIZE] = _("Size");
|
|
| 153 |
titles[COL_NAME] = _("Name");
|
|
| 154 |
|
|
| 155 | 158 |
scrolledwin = gtk_scrolled_window_new(NULL, NULL); |
| 156 | 159 |
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin), |
| 157 | 160 |
GTK_POLICY_AUTOMATIC, |
| 158 | 161 |
GTK_POLICY_ALWAYS); |
| 162 |
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin), |
|
| 163 |
GTK_SHADOW_IN); |
|
| 159 | 164 |
gtk_widget_set_size_request(scrolledwin, -1, 80); |
| 160 | 165 |
|
| 161 |
ctree = gtk_sctree_new_with_titles(N_MIMEVIEW_COLS, 0, titles); |
|
| 162 |
gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE); |
|
| 163 |
gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_NONE); |
|
| 164 |
gtk_clist_set_column_justification(GTK_CLIST(ctree), COL_SIZE, |
|
| 165 |
GTK_JUSTIFY_RIGHT); |
|
| 166 |
gtk_clist_set_column_width(GTK_CLIST(ctree), COL_MIMETYPE, 240); |
|
| 167 |
gtk_clist_set_column_width(GTK_CLIST(ctree), COL_SIZE, 64); |
|
| 168 |
for (i = 0; i < N_MIMEVIEW_COLS; i++) |
|
| 169 |
GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[i].button, |
|
| 170 |
GTK_CAN_FOCUS); |
|
| 171 |
gtk_container_add(GTK_CONTAINER(scrolledwin), ctree); |
|
| 166 |
store = gtk_tree_store_new(N_COLS, G_TYPE_STRING, G_TYPE_STRING, |
|
| 167 |
G_TYPE_STRING, G_TYPE_POINTER); |
|
| 172 | 168 |
|
| 173 |
g_signal_connect(G_OBJECT(ctree), "tree_select_row", |
|
| 174 |
G_CALLBACK(mimeview_selected), mimeview); |
|
| 175 |
g_signal_connect(G_OBJECT(ctree), "button_press_event", |
|
| 169 |
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); |
|
| 170 |
g_object_unref(G_OBJECT(store)); |
|
| 171 |
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE); |
|
| 172 |
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); |
|
| 173 |
gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), COL_NAME); |
|
| 174 |
gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), FALSE); |
|
| 175 |
|
|
| 176 |
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
|
| 177 |
gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); |
|
| 178 |
|
|
| 179 |
gtk_container_add(GTK_CONTAINER(scrolledwin), treeview); |
|
| 180 |
|
|
| 181 |
renderer = gtk_cell_renderer_text_new(); |
|
| 182 |
g_object_set(renderer, "ypad", 0, NULL); |
|
| 183 |
column = gtk_tree_view_column_new_with_attributes |
|
| 184 |
(_("MIME Type"), renderer, "text", COL_MIMETYPE, NULL);
|
|
| 185 |
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); |
|
| 186 |
gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 187 |
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
|
| 188 |
|
|
| 189 |
renderer = gtk_cell_renderer_text_new(); |
|
| 190 |
g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL); |
|
| 191 |
column = gtk_tree_view_column_new_with_attributes |
|
| 192 |
(_("Size"), renderer, "text", COL_SIZE, NULL);
|
|
| 193 |
gtk_tree_view_column_set_alignment(column, 1.0); |
|
| 194 |
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); |
|
| 195 |
gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 196 |
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
|
| 197 |
|
|
| 198 |
renderer = gtk_cell_renderer_text_new(); |
|
| 199 |
g_object_set(renderer, "ypad", 0, NULL); |
|
| 200 |
column = gtk_tree_view_column_new_with_attributes |
|
| 201 |
(_("Name"), renderer, "text", COL_NAME, NULL);
|
|
| 202 |
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); |
|
| 203 |
gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 204 |
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
|
| 205 |
|
|
| 206 |
gtk_tree_view_enable_model_drag_source |
|
| 207 |
(GTK_TREE_VIEW(treeview), 0, mimeview_mime_types, 1, |
|
| 208 |
GDK_ACTION_COPY); |
|
| 209 |
|
|
| 210 |
g_signal_connect(G_OBJECT(selection), "changed", |
|
| 211 |
G_CALLBACK(mimeview_selection_changed), mimeview); |
|
| 212 |
g_signal_connect(G_OBJECT(treeview), "button_press_event", |
|
| 176 | 213 |
G_CALLBACK(mimeview_button_pressed), mimeview); |
| 177 |
g_signal_connect(G_OBJECT(ctree), "key_press_event",
|
|
| 214 |
g_signal_connect(G_OBJECT(treeview), "key_press_event",
|
|
| 178 | 215 |
G_CALLBACK(mimeview_key_pressed), mimeview); |
| 179 |
g_signal_connect(G_OBJECT (ctree),"start_drag", |
|
| 180 |
G_CALLBACK (mimeview_start_drag), mimeview); |
|
| 181 |
g_signal_connect(G_OBJECT(ctree), "drag_data_get", |
|
| 216 |
|
|
| 217 |
g_signal_connect_after(G_OBJECT (treeview),"drag-begin", |
|
| 218 |
G_CALLBACK (mimeview_drag_begin), mimeview); |
|
| 219 |
g_signal_connect(G_OBJECT (treeview),"drag-end", |
|
| 220 |
G_CALLBACK (mimeview_drag_end), mimeview); |
|
| 221 |
g_signal_connect(G_OBJECT(treeview), "drag-data-get", |
|
| 182 | 222 |
G_CALLBACK(mimeview_drag_data_get), mimeview); |
| 183 | 223 |
|
| 184 | 224 |
mime_vbox = gtk_vbox_new(FALSE, 0); |
| ... | ... | |
| 195 | 235 |
|
| 196 | 236 |
mimeview->paned = paned; |
| 197 | 237 |
mimeview->scrolledwin = scrolledwin; |
| 198 |
mimeview->ctree = ctree; |
|
| 238 |
mimeview->treeview = treeview; |
|
| 239 |
mimeview->store = store; |
|
| 240 |
mimeview->selection = selection; |
|
| 199 | 241 |
mimeview->mime_vbox = mime_vbox; |
| 200 | 242 |
mimeview->popupmenu = popupmenu; |
| 201 | 243 |
mimeview->popupfactory = popupfactory; |
| ... | ... | |
| 257 | 299 |
g_free(signedinfo[1]->sigstatus_full); |
| 258 | 300 |
signedinfo[1]->sigstatus_full = NULL; |
| 259 | 301 |
|
| 260 |
g_free(signedinfo);
|
|
| 302 |
g_free(signedinfo);
|
|
| 261 | 303 |
} |
| 262 | 304 |
#endif /* USE_GPGME */ |
| 263 | 305 |
|
| 264 | 306 |
void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo, |
| 265 | 307 |
const gchar *file) |
| 266 | 308 |
{
|
| 267 |
GtkCTree *ctree = GTK_CTREE(mimeview->ctree); |
|
| 268 |
GtkCTreeNode *node; |
|
| 309 |
GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store); |
|
| 310 |
GtkTreeIter iter; |
|
| 311 |
gboolean valid; |
|
| 269 | 312 |
|
| 270 | 313 |
mimeview_clear(mimeview); |
| 271 | 314 |
textview_clear(mimeview->messageview->textview); |
| ... | ... | |
| 292 | 335 |
#endif |
| 293 | 336 |
|
| 294 | 337 |
g_signal_handlers_block_by_func |
| 295 |
(G_OBJECT(ctree), G_CALLBACK(mimeview_selected), mimeview); |
|
| 338 |
(G_OBJECT(mimeview->selection), |
|
| 339 |
G_CALLBACK(mimeview_selection_changed), mimeview); |
|
| 296 | 340 |
|
| 297 | 341 |
mimeview_set_multipart_tree(mimeview, mimeinfo, NULL); |
| 342 |
gtk_tree_view_expand_all(GTK_TREE_VIEW(mimeview->treeview)); |
|
| 298 | 343 |
|
| 299 | 344 |
g_signal_handlers_unblock_by_func |
| 300 |
(G_OBJECT(ctree), G_CALLBACK(mimeview_selected), mimeview); |
|
| 345 |
(G_OBJECT(mimeview->selection), |
|
| 346 |
G_CALLBACK(mimeview_selection_changed), mimeview); |
|
| 301 | 347 |
|
| 302 | 348 |
/* search first text part */ |
| 303 |
for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
|
|
| 304 |
node != NULL; node = GTK_CTREE_NODE_NEXT(node)) {
|
|
| 349 |
for (valid = gtk_tree_model_get_iter_first(model, &iter); valid;
|
|
| 350 |
valid = gtkut_tree_model_next(model, &iter)) {
|
|
| 305 | 351 |
MimeInfo *partinfo; |
| 306 | 352 |
|
| 307 |
partinfo = gtk_ctree_node_get_row_data(ctree, node);
|
|
| 353 |
gtk_tree_model_get(model, &iter, COL_MIME_INFO, &partinfo, -1);
|
|
| 308 | 354 |
if (partinfo && |
| 309 | 355 |
(partinfo->mime_type == MIME_TEXT || |
| 310 | 356 |
partinfo->mime_type == MIME_TEXT_HTML)) |
| ... | ... | |
| 312 | 358 |
} |
| 313 | 359 |
textview_show_message(mimeview->messageview->textview, mimeinfo, file); |
| 314 | 360 |
|
| 315 |
if (!node)
|
|
| 316 |
node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
|
|
| 361 |
if (!valid)
|
|
| 362 |
valid = gtk_tree_model_get_iter_first(model, &iter);
|
|
| 317 | 363 |
|
| 318 |
if (node) {
|
|
| 319 |
gtk_ctree_select(ctree, node); |
|
| 320 |
gtkut_ctree_set_focus_row(ctree, node); |
|
| 364 |
if (valid) {
|
|
| 365 |
GtkTreePath *path; |
|
| 366 |
|
|
| 367 |
path = gtk_tree_model_get_path(model, &iter); |
|
| 368 |
gtk_tree_view_set_cursor(GTK_TREE_VIEW(mimeview->treeview), |
|
| 369 |
path, NULL, FALSE); |
|
| 370 |
gtk_tree_path_free(path); |
|
| 321 | 371 |
if (mimeview_get_selected_part(mimeview)) |
| 322 |
gtk_widget_grab_focus(mimeview->ctree);
|
|
| 372 |
gtk_widget_grab_focus(mimeview->treeview);
|
|
| 323 | 373 |
} |
| 324 | 374 |
} |
| 325 | 375 |
|
| 326 | 376 |
void mimeview_clear(MimeView *mimeview) |
| 327 | 377 |
{
|
| 328 |
GtkCList *clist = GTK_CLIST(mimeview->ctree); |
|
| 329 |
|
|
| 330 | 378 |
procmime_mimeinfo_free_all(mimeview->mimeinfo); |
| 331 | 379 |
mimeview->mimeinfo = NULL; |
| 332 | 380 |
|
| 333 |
gtk_clist_clear(clist);
|
|
| 381 |
gtk_tree_store_clear(mimeview->store);
|
|
| 334 | 382 |
textview_clear(mimeview->textview); |
| 335 | 383 |
imageview_clear(mimeview->imageview); |
| 336 | 384 |
|
| 385 |
gtk_tree_path_free(mimeview->opened); |
|
| 337 | 386 |
mimeview->opened = NULL; |
| 338 | 387 |
|
| 339 | 388 |
g_free(mimeview->file); |
| ... | ... | |
| 346 | 395 |
imageview_destroy(mimeview->imageview); |
| 347 | 396 |
procmime_mimeinfo_free_all(mimeview->mimeinfo); |
| 348 | 397 |
g_free(mimeview->file); |
| 398 |
g_free(mimeview->drag_file); |
|
| 349 | 399 |
g_free(mimeview); |
| 350 | 400 |
} |
| 351 | 401 |
|
| 352 | 402 |
MimeInfo *mimeview_get_selected_part(MimeView *mimeview) |
| 353 | 403 |
{
|
| 404 |
GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store); |
|
| 405 |
GtkTreeIter iter; |
|
| 406 |
MimeInfo *partinfo = NULL; |
|
| 407 |
|
|
| 408 |
if (!mimeview->opened) |
|
| 409 |
return NULL; |
|
| 354 | 410 |
if (gtk_notebook_get_current_page |
| 355 | 411 |
(GTK_NOTEBOOK(mimeview->messageview->notebook)) == 0) |
| 356 | 412 |
return NULL; |
| 357 | 413 |
|
| 358 |
return gtk_ctree_node_get_row_data |
|
| 359 |
(GTK_CTREE(mimeview->ctree), mimeview->opened); |
|
| 414 |
if (gtk_tree_model_get_iter(model, &iter, mimeview->opened)) |
|
| 415 |
gtk_tree_model_get(model, &iter, COL_MIME_INFO, &partinfo, -1); |
|
| 416 |
|
|
| 417 |
return partinfo; |
|
| 360 | 418 |
} |
| 361 | 419 |
|
| 362 | 420 |
gboolean mimeview_step(MimeView *mimeview, GtkScrollType type) |
| 363 | 421 |
{
|
| 364 |
GtkCTree *ctree = GTK_CTREE(mimeview->ctree); |
|
| 365 |
GtkCTreeNode *node; |
|
| 422 |
GtkTreeView *treeview = GTK_TREE_VIEW(mimeview->treeview); |
|
| 423 |
GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store); |
|
| 424 |
GtkTreeIter iter; |
|
| 425 |
gboolean moved; |
|
| 366 | 426 |
|
| 427 |
if (!mimeview->opened) |
|
| 428 |
return FALSE; |
|
| 429 |
if (!gtk_tree_model_get_iter(model, &iter, mimeview->opened)) |
|
| 430 |
return FALSE; |
|
| 431 |
|
|
| 367 | 432 |
if (type == GTK_SCROLL_STEP_FORWARD) {
|
| 368 |
node = gtkut_ctree_node_next(ctree, mimeview->opened); |
|
| 369 |
if (node) |
|
| 370 |
gtkut_ctree_expand_parent_all(ctree, node); |
|
| 433 |
if (gtkut_tree_model_next(model, &iter)) |
|
| 434 |
gtkut_tree_view_expand_parent_all(treeview, &iter); |
|
| 371 | 435 |
else |
| 372 | 436 |
return FALSE; |
| 373 | 437 |
} else {
|
| 374 |
if (mimeview->opened) {
|
|
| 375 |
node = GTK_CTREE_NODE_PREV(mimeview->opened); |
|
| 376 |
if (!node) return FALSE; |
|
| 377 |
} else |
|
| 438 |
if (!gtkut_tree_model_prev(model, &iter)) |
|
| 378 | 439 |
return FALSE; |
| 379 | 440 |
} |
| 380 | 441 |
|
| 381 |
g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical", type, 0.0); |
|
| 442 |
g_signal_emit_by_name(G_OBJECT(treeview), "move-cursor", |
|
| 443 |
GTK_MOVEMENT_DISPLAY_LINES, |
|
| 444 |
type == GTK_SCROLL_STEP_FORWARD ? 1 : -1, &moved); |
|
| 382 | 445 |
|
| 383 | 446 |
return TRUE; |
| 384 | 447 |
} |
| 385 | 448 |
|
| 386 | 449 |
static void mimeview_set_multipart_tree(MimeView *mimeview, |
| 387 | 450 |
MimeInfo *mimeinfo, |
| 388 |
GtkCTreeNode *parent)
|
|
| 451 |
GtkTreeIter *parent)
|
|
| 389 | 452 |
{
|
| 390 |
GtkCTreeNode *node;
|
|
| 453 |
GtkTreeIter iter;
|
|
| 391 | 454 |
|
| 392 | 455 |
g_return_if_fail(mimeinfo != NULL); |
| 393 | 456 |
|
| ... | ... | |
| 395 | 458 |
mimeinfo = mimeinfo->children; |
| 396 | 459 |
|
| 397 | 460 |
while (mimeinfo != NULL) {
|
| 398 |
node = mimeview_append_part(mimeview, mimeinfo, parent);
|
|
| 461 |
mimeview_append_part(mimeview, mimeinfo, &iter, parent);
|
|
| 399 | 462 |
|
| 400 | 463 |
if (mimeinfo->children) |
| 401 |
mimeview_set_multipart_tree(mimeview, mimeinfo, node);
|
|
| 464 |
mimeview_set_multipart_tree(mimeview, mimeinfo, &iter);
|
|
| 402 | 465 |
else if (mimeinfo->sub && |
| 403 | 466 |
mimeinfo->sub->mime_type != MIME_TEXT && |
| 404 | 467 |
mimeinfo->sub->mime_type != MIME_TEXT_HTML) |
| 405 | 468 |
mimeview_set_multipart_tree(mimeview, mimeinfo->sub, |
| 406 |
node);
|
|
| 469 |
&iter);
|
|
| 407 | 470 |
mimeinfo = mimeinfo->next; |
| 408 | 471 |
} |
| 409 | 472 |
} |
| ... | ... | |
| 423 | 486 |
return ""; |
| 424 | 487 |
} |
| 425 | 488 |
|
| 426 |
static GtkCTreeNode *mimeview_append_part(MimeView *mimeview, |
|
| 427 |
MimeInfo *partinfo, |
|
| 428 |
GtkCTreeNode *parent) |
|
| 489 |
static gboolean mimeview_append_part(MimeView *mimeview, MimeInfo *partinfo, |
|
| 490 |
GtkTreeIter *iter, GtkTreeIter *parent) |
|
| 429 | 491 |
{
|
| 430 |
GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
|
|
| 431 |
GtkCTreeNode *node;
|
|
| 432 |
gchar *str[N_MIMEVIEW_COLS];
|
|
| 492 |
gchar *mime_type;
|
|
| 493 |
gchar *size;
|
|
| 494 |
gchar *name;
|
|
| 433 | 495 |
|
| 434 |
str[COL_MIMETYPE] = |
|
| 435 |
partinfo->content_type ? partinfo->content_type : ""; |
|
| 436 |
str[COL_SIZE] = to_human_readable(partinfo->size); |
|
| 437 |
str[COL_NAME] = get_part_name(partinfo); |
|
| 496 |
mime_type = partinfo->content_type ? partinfo->content_type : ""; |
|
| 497 |
size = to_human_readable(partinfo->size); |
|
| 498 |
name = get_part_name(partinfo); |
|
| 438 | 499 |
|
| 439 |
node = gtk_ctree_insert_node(ctree, parent, NULL, str, 0, |
|
| 440 |
NULL, NULL, NULL, NULL, |
|
| 441 |
FALSE, TRUE); |
|
| 442 |
gtk_ctree_node_set_row_data(ctree, node, partinfo); |
|
| 500 |
gtk_tree_store_append(mimeview->store, iter, parent); |
|
| 501 |
gtk_tree_store_set(mimeview->store, iter, |
|
| 502 |
COL_MIMETYPE, mime_type, |
|
| 503 |
COL_SIZE, size, |
|
| 504 |
COL_NAME, name, |
|
| 505 |
COL_MIME_INFO, partinfo, |
|
| 506 |
-1); |
|
| 443 | 507 |
|
| 444 |
return node;
|
|
| 508 |
return TRUE;
|
|
| 445 | 509 |
} |
| 446 | 510 |
|
| 447 | 511 |
static void mimeview_show_message_part(MimeView *mimeview, MimeInfo *partinfo) |
| ... | ... | |
| 671 | 735 |
mimeview->type = type; |
| 672 | 736 |
} |
| 673 | 737 |
|
| 674 |
static void mimeview_selected(GtkCTree *ctree, GtkCTreeNode *node, gint column,
|
|
| 675 |
MimeView *mimeview) |
|
| 738 |
static void mimeview_selection_changed(GtkTreeSelection *selection,
|
|
| 739 |
MimeView *mimeview)
|
|
| 676 | 740 |
{
|
| 741 |
GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store); |
|
| 742 |
GtkTreeIter iter; |
|
| 743 |
GtkTreePath *path; |
|
| 677 | 744 |
MimeInfo *partinfo; |
| 678 | 745 |
|
| 679 |
if (mimeview->opened == node) return; |
|
| 680 |
mimeview->opened = node; |
|
| 681 |
gtk_ctree_node_moveto(ctree, node, -1, 0.5, 0); |
|
| 746 |
if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) {
|
|
| 747 |
if (mimeview->opened) {
|
|
| 748 |
gtk_tree_path_free(mimeview->opened); |
|
| 749 |
mimeview->opened = NULL; |
|
| 750 |
} |
|
| 751 |
return; |
|
| 752 |
} |
|
| 682 | 753 |
|
| 683 |
partinfo = gtk_ctree_node_get_row_data(ctree, node); |
|
| 684 |
if (!partinfo) return; |
|
| 754 |
path = gtk_tree_model_get_path(model, &iter); |
|
| 685 | 755 |
|
| 686 |
/* ungrab the mouse event */ |
|
| 687 |
if (GTK_WIDGET_HAS_GRAB(ctree)) {
|
|
| 688 |
gtk_grab_remove(GTK_WIDGET(ctree)); |
|
| 689 |
if (gdk_pointer_is_grabbed()) |
|
| 690 |
gdk_pointer_ungrab(GDK_CURRENT_TIME); |
|
| 756 |
if (mimeview->opened && |
|
| 757 |
gtk_tree_path_compare(mimeview->opened, path) == 0) {
|
|
| 758 |
gtk_tree_path_free(path); |
|
| 759 |
return; |
|
| 691 | 760 |
} |
| 692 | 761 |
|
| 762 |
gtk_tree_path_free(mimeview->opened); |
|
| 763 |
mimeview->opened = path; |
|
| 764 |
path = NULL; |
|
| 765 |
|
|
| 766 |
gtk_tree_model_get(model, &iter, COL_MIME_INFO, &partinfo, -1); |
|
| 767 |
if (!partinfo) |
|
| 768 |
return; |
|
| 769 |
|
|
| 693 | 770 |
switch (partinfo->mime_type) {
|
| 694 | 771 |
case MIME_TEXT: |
| 695 | 772 |
case MIME_TEXT_HTML: |
| ... | ... | |
| 713 | 790 |
} |
| 714 | 791 |
} |
| 715 | 792 |
|
| 716 |
static void mimeview_start_drag(GtkWidget *widget, gint button, |
|
| 717 |
GdkEvent *event, MimeView *mimeview) |
|
| 718 |
{
|
|
| 719 |
GtkTargetList *list; |
|
| 720 |
GdkDragContext *context; |
|
| 721 |
MimeInfo *partinfo; |
|
| 722 |
|
|
| 723 |
g_return_if_fail(mimeview != NULL); |
|
| 724 |
|
|
| 725 |
partinfo = mimeview_get_selected_part(mimeview); |
|
| 726 |
if (partinfo->filename == NULL && partinfo->name == NULL) return; |
|
| 727 |
|
|
| 728 |
list = gtk_target_list_new(mimeview_mime_types, 1); |
|
| 729 |
context = gtk_drag_begin(widget, list, |
|
| 730 |
GDK_ACTION_COPY, button, event); |
|
| 731 |
gtk_drag_set_icon_default(context); |
|
| 732 |
} |
|
| 733 |
|
|
| 734 | 793 |
static gint mimeview_button_pressed(GtkWidget *widget, GdkEventButton *event, |
| 735 | 794 |
MimeView *mimeview) |
| 736 | 795 |
{
|
| 737 |
GtkCList *clist = GTK_CLIST(widget);
|
|
| 796 |
GtkTreeView *treeview = GTK_TREE_VIEW(widget);
|
|
| 738 | 797 |
MimeInfo *partinfo; |
| 739 |
gint row, column; |
|
| 740 | 798 |
|
| 741 | 799 |
if (!event) return FALSE; |
| 742 | 800 |
|
| 743 | 801 |
if (event->button == 2 || event->button == 3) {
|
| 744 |
if (!gtk_clist_get_selection_info(clist, event->x, event->y, |
|
| 745 |
&row, &column)) |
|
| 802 |
GtkTreePath *path; |
|
| 803 |
|
|
| 804 |
if (!gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, |
|
| 805 |
&path, NULL, NULL, NULL)) |
|
| 746 | 806 |
return FALSE; |
| 747 |
gtk_clist_unselect_all(clist); |
|
| 748 |
gtk_clist_select_row(clist, row, column); |
|
| 749 |
gtkut_clist_set_focus_row(clist, row); |
|
| 807 |
gtk_tree_view_set_cursor(treeview, path, NULL, FALSE); |
|
| 808 |
gtk_tree_path_free(path); |
|
| 750 | 809 |
} |
| 751 | 810 |
|
| 752 | 811 |
if (event->button == 2 || |
| ... | ... | |
| 789 | 848 |
|
| 790 | 849 |
void mimeview_pass_key_press_event(MimeView *mimeview, GdkEventKey *event) |
| 791 | 850 |
{
|
| 792 |
mimeview_key_pressed(mimeview->ctree, event, mimeview);
|
|
| 851 |
mimeview_key_pressed(mimeview->treeview, event, mimeview);
|
|
| 793 | 852 |
} |
| 794 | 853 |
|
| 795 | 854 |
#define BREAK_ON_MODIFIER_KEY() \ |
| 796 | 855 |
if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0) break |
| 797 | 856 |
|
| 798 | 857 |
#define KEY_PRESS_EVENT_STOP() \ |
| 799 |
g_signal_stop_emission_by_name(G_OBJECT(ctree), "key_press_event");
|
|
| 858 |
g_signal_stop_emission_by_name(G_OBJECT(treeview), "key_press_event");
|
|
| 800 | 859 |
|
| 801 | 860 |
static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event, |
| 802 | 861 |
MimeView *mimeview) |
| 803 | 862 |
{
|
| 804 | 863 |
SummaryView *summaryview = NULL; |
| 805 |
GtkCTree *ctree = GTK_CTREE(widget); |
|
| 806 |
GtkCTreeNode *node; |
|
| 864 |
GtkTreeView *treeview = GTK_TREE_VIEW(widget); |
|
| 865 |
GtkTreeModel *model = GTK_TREE_MODEL(mimeview->store); |
|
| 866 |
GtkTreeIter iter; |
|
| 807 | 867 |
gboolean mod_pressed; |
| 808 | 868 |
|
| 809 | 869 |
if (!event) return FALSE; |
| 810 | 870 |
if (!mimeview->opened) return FALSE; |
| 871 |
if (!gtk_tree_model_get_iter(model, &iter, mimeview->opened)) |
|
| 872 |
return FALSE; |
|
| 811 | 873 |
|
| 812 | 874 |
if (mimeview->messageview->mainwin) |
| 813 | 875 |
summaryview = mimeview->messageview->mainwin->summaryview; |
| ... | ... | |
| 819 | 881 |
if (textview_scroll_page(mimeview->textview, mod_pressed)) |
| 820 | 882 |
return TRUE; |
| 821 | 883 |
|
| 822 |
node = GTK_CTREE_NODE_NEXT(mimeview->opened); |
|
| 823 |
if (node) {
|
|
| 824 |
gtk_sctree_unselect_all(GTK_SCTREE(ctree)); |
|
| 825 |
gtk_sctree_select(GTK_SCTREE(ctree), node); |
|
| 884 |
if (gtkut_tree_model_next(model, &iter)) {
|
|
| 885 |
GtkTreePath *path; |
|
| 886 |
|
|
| 887 |
path = gtk_tree_model_get_path(model, &iter); |
|
| 888 |
gtk_tree_view_set_cursor(treeview, path, NULL, FALSE); |
|
| 889 |
gtk_tree_path_free(path); |
|
| 826 | 890 |
return TRUE; |
| 827 | 891 |
} |
| 828 | 892 |
if (summaryview) |
| ... | ... | |
| 855 | 919 |
return FALSE; |
| 856 | 920 |
} |
| 857 | 921 |
|
| 858 |
static void mimeview_drag_data_get(GtkWidget *widget, |
|
| 859 |
GdkDragContext *drag_context, |
|
| 860 |
GtkSelectionData *selection_data, |
|
| 861 |
guint info, |
|
| 862 |
guint time, |
|
| 863 |
MimeView *mimeview) |
|
| 922 |
static void mimeview_drag_begin(GtkWidget *widget, GdkDragContext *drag_context, |
|
| 923 |
MimeView *mimeview) |
|
| 864 | 924 |
{
|
| 865 |
gchar *filename, *uriname;
|
|
| 866 |
const gchar *bname;
|
|
| 925 |
gchar *filename; |
|
| 926 |
gchar *bname = NULL;
|
|
| 867 | 927 |
MimeInfo *partinfo; |
| 868 | 928 |
|
| 869 | 929 |
if (!mimeview->opened) return; |
| ... | ... | |
| 871 | 931 |
|
| 872 | 932 |
partinfo = mimeview_get_selected_part(mimeview); |
| 873 | 933 |
if (!partinfo) return; |
| 874 |
if (!partinfo->filename && !partinfo->name) return; |
|
| 875 | 934 |
|
| 876 | 935 |
filename = partinfo->filename ? partinfo->filename : partinfo->name; |
| 877 |
bname = g_basename(filename);
|
|
| 878 |
if (*bname == '\0') return;
|
|
| 936 |
if (filename) {
|
|
| 937 |
const gchar *bname_;
|
|
| 879 | 938 |
|
| 880 |
filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S, |
|
| 881 |
bname, NULL); |
|
| 939 |
bname_ = g_basename(filename); |
|
| 940 |
bname = conv_filename_from_utf8(bname_); |
|
| 941 |
subst_for_filename(bname); |
|
| 942 |
} |
|
| 943 |
if (!bname || *bname == '\0') |
|
| 944 |
filename = procmime_get_tmp_file_name(partinfo); |
|
| 945 |
else |
|
| 946 |
filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S, |
|
| 947 |
bname, NULL); |
|
| 882 | 948 |
|
| 883 |
if (procmime_get_part(filename, mimeview->file, partinfo) < 0) |
|
| 884 |
alertpanel_error |
|
| 885 |
(_("Can't save the part of multipart message."));
|
|
| 949 |
if (procmime_get_part(filename, mimeview->file, partinfo) < 0) {
|
|
| 950 |
g_warning(_("Can't save the part of multipart message."));
|
|
| 951 |
g_free(filename); |
|
| 952 |
} else |
|
| 953 |
mimeview->drag_file = filename; |
|
| 886 | 954 |
|
| 887 |
uriname = g_strconcat("file://", filename, NULL);
|
|
| 955 |
gtk_drag_set_icon_default(drag_context); |
|
| 956 |
} |
|
| 957 |
|
|
| 958 |
static void mimeview_drag_end(GtkWidget *widget, GdkDragContext *drag_context, |
|
| 959 |
MimeView *mimeview) |
|
| 960 |
{
|
|
| 961 |
if (mimeview->drag_file) {
|
|
| 962 |
g_free(mimeview->drag_file); |
|
| 963 |
mimeview->drag_file = NULL; |
|
| 964 |
} |
|
| 965 |
} |
|
| 966 |
|
|
| 967 |
static void mimeview_drag_data_get(GtkWidget *widget, |
|
| 968 |
GdkDragContext *drag_context, |
|
| 969 |
GtkSelectionData *selection_data, |
|
| 970 |
guint info, |
|
| 971 |
guint time, |
|
| 972 |
MimeView *mimeview) |
|
| 973 |
{
|
|
| 974 |
gchar *uriname; |
|
| 975 |
|
|
| 976 |
if (!mimeview->drag_file) return; |
|
| 977 |
|
|
| 978 |
uriname = g_strconcat("file://", mimeview->drag_file, NULL);
|
|
| 888 | 979 |
gtk_selection_data_set(selection_data, selection_data->target, 8, |
| 889 | 980 |
uriname, strlen(uriname)); |
| 890 |
|
|
| 891 | 981 |
g_free(uriname); |
| 892 |
g_free(filename); |
|
| 893 | 982 |
} |
| 894 | 983 |
|
| 895 | 984 |
static void mimeview_display_as_text(MimeView *mimeview) |
| ... | ... | |
| 1047 | 1136 |
} |
| 1048 | 1137 |
|
| 1049 | 1138 |
#if USE_GPGME |
| 1050 |
static void update_node_name(GtkCTree *ctree, GtkCTreeNode *node,
|
|
| 1051 |
gpointer data)
|
|
| 1139 |
static gboolean update_node_name_func(GtkTreeModel *model, GtkTreePath *path,
|
|
| 1140 |
GtkTreeIter *iter, gpointer data)
|
|
| 1052 | 1141 |
{
|
| 1053 | 1142 |
MimeInfo *partinfo; |
| 1054 | 1143 |
gchar *part_name; |
| 1055 | 1144 |
|
| 1056 |
partinfo = gtk_ctree_node_get_row_data(ctree, node);
|
|
| 1057 |
g_return_if_fail(partinfo != NULL);
|
|
| 1145 |
gtk_tree_model_get(model, iter, COL_MIME_INFO, &partinfo, -1);
|
|
| 1146 |
g_return_val_if_fail(partinfo != NULL, FALSE);
|
|
| 1058 | 1147 |
|
| 1059 | 1148 |
part_name = get_part_name(partinfo); |
| 1060 |
gtk_ctree_node_set_text(ctree, node, COL_NAME, part_name); |
|
| 1149 |
gtk_tree_store_set(GTK_TREE_STORE(model), iter, COL_NAME, part_name, |
|
| 1150 |
-1); |
|
| 1151 |
|
|
| 1152 |
return FALSE; |
|
| 1061 | 1153 |
} |
| 1062 | 1154 |
|
| 1063 | 1155 |
static void mimeview_update_names(MimeView *mimeview) |
| 1064 | 1156 |
{
|
| 1065 |
GtkCTree *ctree = GTK_CTREE(mimeview->ctree); |
|
| 1066 |
|
|
| 1067 |
gtk_ctree_pre_recursive(ctree, NULL, update_node_name, NULL); |
|
| 1157 |
gtk_tree_model_foreach(GTK_TREE_MODEL(mimeview->store), |
|
| 1158 |
update_node_name_func, NULL); |
|
| 1068 | 1159 |
} |
| 1069 | 1160 |
|
| 1070 | 1161 |
static void mimeview_update_signature_info(MimeView *mimeview) |
Also available in: Unified diff