Statistics
| Revision:

root / src / messageview.c @ 130

History | View | Annotate | Download (24.8 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1 hiro
 * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#include "defs.h"
21 1 hiro
22 1 hiro
#include <glib.h>
23 92 hiro
#include <glib/gi18n.h>
24 1 hiro
#include <gdk/gdkkeysyms.h>
25 1 hiro
#include <gtk/gtkvbox.h>
26 1 hiro
#include <gtk/gtkcontainer.h>
27 1 hiro
#include <gtk/gtkwindow.h>
28 1 hiro
#include <gtk/gtktextview.h>
29 1 hiro
#include <gtk/gtkmenu.h>
30 1 hiro
#include <gtk/gtkmenuitem.h>
31 1 hiro
#include <stdio.h>
32 1 hiro
#include <ctype.h>
33 1 hiro
#include <string.h>
34 1 hiro
35 1 hiro
#include "main.h"
36 1 hiro
#include "messageview.h"
37 1 hiro
#include "message_search.h"
38 1 hiro
#include "headerview.h"
39 1 hiro
#include "textview.h"
40 1 hiro
#include "imageview.h"
41 1 hiro
#include "mimeview.h"
42 1 hiro
#include "menu.h"
43 1 hiro
#include "about.h"
44 1 hiro
#include "filesel.h"
45 1 hiro
#include "sourcewindow.h"
46 1 hiro
#include "addressbook.h"
47 1 hiro
#include "alertpanel.h"
48 1 hiro
#include "inputdialog.h"
49 1 hiro
#include "manage_window.h"
50 1 hiro
#include "procmsg.h"
51 1 hiro
#include "procheader.h"
52 1 hiro
#include "procmime.h"
53 1 hiro
#include "account.h"
54 1 hiro
#include "action.h"
55 1 hiro
#include "prefs_common.h"
56 1 hiro
#include "prefs_account.h"
57 1 hiro
#include "prefs_filter.h"
58 1 hiro
#include "gtkutils.h"
59 1 hiro
#include "utils.h"
60 1 hiro
#include "rfc2015.h"
61 1 hiro
62 1 hiro
static GList *messageview_list = NULL;
63 1 hiro
64 1 hiro
static void messageview_change_view_type(MessageView        *messageview,
65 1 hiro
                                         MessageType         type);
66 1 hiro
static void messageview_destroy_cb        (GtkWidget        *widget,
67 1 hiro
                                         MessageView        *messageview);
68 1 hiro
static void messageview_size_allocate_cb(GtkWidget        *widget,
69 1 hiro
                                         GtkAllocation        *allocation);
70 1 hiro
static gboolean key_pressed                (GtkWidget        *widget,
71 1 hiro
                                         GdkEventKey        *event,
72 1 hiro
                                         MessageView        *messageview);
73 1 hiro
74 1 hiro
static void save_as_cb                        (gpointer         data,
75 1 hiro
                                         guint                 action,
76 1 hiro
                                         GtkWidget        *widget);
77 1 hiro
static void print_cb                        (gpointer         data,
78 1 hiro
                                         guint                 action,
79 1 hiro
                                         GtkWidget        *widget);
80 1 hiro
static void close_cb                        (gpointer         data,
81 1 hiro
                                         guint                 action,
82 1 hiro
                                         GtkWidget        *widget);
83 1 hiro
static void copy_cb                        (gpointer         data,
84 1 hiro
                                         guint                 action,
85 1 hiro
                                         GtkWidget        *widget);
86 1 hiro
static void allsel_cb                        (gpointer         data,
87 1 hiro
                                         guint                 action,
88 1 hiro
                                         GtkWidget        *widget);
89 1 hiro
static void search_cb                        (gpointer         data,
90 1 hiro
                                         guint                 action,
91 1 hiro
                                         GtkWidget        *widget);
92 1 hiro
93 1 hiro
static void set_charset_cb                (gpointer         data,
94 1 hiro
                                         guint                 action,
95 1 hiro
                                         GtkWidget        *widget);
96 1 hiro
static void view_source_cb                (gpointer         data,
97 1 hiro
                                         guint                 action,
98 1 hiro
                                         GtkWidget        *widget);
99 1 hiro
static void show_all_header_cb                (gpointer         data,
100 1 hiro
                                         guint                 action,
101 1 hiro
                                         GtkWidget        *widget);
102 1 hiro
103 1 hiro
static void compose_cb                        (gpointer         data,
104 1 hiro
                                         guint                 action,
105 1 hiro
                                         GtkWidget        *widget);
106 1 hiro
static void reply_cb                        (gpointer         data,
107 1 hiro
                                         guint                 action,
108 1 hiro
                                         GtkWidget        *widget);
109 1 hiro
static void reedit_cb                        (gpointer         data,
110 1 hiro
                                         guint                 action,
111 1 hiro
                                         GtkWidget        *widget);
112 1 hiro
113 1 hiro
static void addressbook_open_cb                (gpointer         data,
114 1 hiro
                                         guint                 action,
115 1 hiro
                                         GtkWidget        *widget);
116 1 hiro
static void add_address_cb                (gpointer         data,
117 1 hiro
                                         guint                 action,
118 1 hiro
                                         GtkWidget        *widget);
119 1 hiro
static void create_filter_cb                (gpointer         data,
120 1 hiro
                                         guint                 action,
121 1 hiro
                                         GtkWidget        *widget);
122 1 hiro
123 1 hiro
static void about_cb                        (gpointer         data,
124 1 hiro
                                         guint                 action,
125 1 hiro
                                         GtkWidget        *widget);
126 1 hiro
127 1 hiro
static GtkItemFactoryEntry msgview_entries[] =
128 1 hiro
{
129 1 hiro
        {N_("/_File"),                        NULL, NULL, 0, "<Branch>"},
130 1 hiro
        {N_("/_File/_Save as..."),        NULL, save_as_cb, 0, NULL},
131 1 hiro
        {N_("/_File/_Print..."),        NULL, print_cb, 0, NULL},
132 1 hiro
        {N_("/_File/---"),                NULL, NULL, 0, "<Separator>"},
133 1 hiro
        {N_("/_File/_Close"),                NULL, close_cb, 0, NULL},
134 1 hiro
135 1 hiro
        {N_("/_Edit"),                        NULL, NULL, 0, "<Branch>"},
136 1 hiro
        {N_("/_Edit/_Copy"),                NULL, copy_cb, 0, NULL},
137 1 hiro
        {N_("/_Edit/Select _all"),        NULL, allsel_cb, 0, NULL},
138 1 hiro
        {N_("/_Edit/---"),                NULL, NULL, 0, "<Separator>"},
139 1 hiro
        {N_("/_Edit/_Find in current message..."),
140 1 hiro
                                        NULL, search_cb, 0, NULL},
141 1 hiro
142 1 hiro
        {N_("/_View"),                        NULL, NULL, 0, "<Branch>"},
143 1 hiro
144 1 hiro
#define CODESET_SEPARATOR \
145 1 hiro
        {N_("/_View/_Code set/---"),        NULL, NULL, 0, "<Separator>"}
146 1 hiro
#define CODESET_ACTION(action) \
147 1 hiro
        NULL, set_charset_cb, action, "/View/Code set/Auto detect"
148 1 hiro
149 1 hiro
        {N_("/_View/_Code set"),        NULL, NULL, 0, "<Branch>"},
150 1 hiro
        {N_("/_View/_Code set/_Auto detect"),
151 1 hiro
                                        NULL, set_charset_cb, C_AUTO, "<RadioItem>"},
152 1 hiro
        CODESET_SEPARATOR,
153 1 hiro
        {N_("/_View/_Code set/7bit ascii (US-ASC_II)"),
154 1 hiro
         CODESET_ACTION(C_US_ASCII)},
155 1 hiro
156 1 hiro
        {N_("/_View/_Code set/Unicode (_UTF-8)"),
157 1 hiro
         CODESET_ACTION(C_UTF_8)},
158 1 hiro
        CODESET_SEPARATOR,
159 1 hiro
        {N_("/_View/_Code set/Western European (ISO-8859-_1)"),
160 1 hiro
         CODESET_ACTION(C_ISO_8859_1)},
161 1 hiro
        {N_("/_View/_Code set/Western European (ISO-8859-15)"),
162 1 hiro
         CODESET_ACTION(C_ISO_8859_15)},
163 1 hiro
        CODESET_SEPARATOR,
164 1 hiro
        {N_("/_View/_Code set/Central European (ISO-8859-_2)"),
165 1 hiro
         CODESET_ACTION(C_ISO_8859_2)},
166 1 hiro
        CODESET_SEPARATOR,
167 1 hiro
        {N_("/_View/_Code set/_Baltic (ISO-8859-13)"),
168 1 hiro
         CODESET_ACTION(C_ISO_8859_13)},
169 1 hiro
        {N_("/_View/_Code set/Baltic (ISO-8859-_4)"),
170 1 hiro
         CODESET_ACTION(C_ISO_8859_4)},
171 1 hiro
        CODESET_SEPARATOR,
172 1 hiro
        {N_("/_View/_Code set/Greek (ISO-8859-_7)"),
173 1 hiro
         CODESET_ACTION(C_ISO_8859_7)},
174 1 hiro
        CODESET_SEPARATOR,
175 1 hiro
        {N_("/_View/_Code set/Turkish (ISO-8859-_9)"),
176 1 hiro
         CODESET_ACTION(C_ISO_8859_9)},
177 1 hiro
        CODESET_SEPARATOR,
178 1 hiro
        {N_("/_View/_Code set/Cyrillic (ISO-8859-_5)"),
179 1 hiro
         CODESET_ACTION(C_ISO_8859_5)},
180 1 hiro
        {N_("/_View/_Code set/Cyrillic (KOI8-_R)"),
181 1 hiro
         CODESET_ACTION(C_KOI8_R)},
182 1 hiro
        {N_("/_View/_Code set/Cyrillic (KOI8-U)"),
183 1 hiro
         CODESET_ACTION(C_KOI8_U)},
184 1 hiro
        {N_("/_View/_Code set/Cyrillic (Windows-1251)"),
185 1 hiro
         CODESET_ACTION(C_CP1251)},
186 1 hiro
        CODESET_SEPARATOR,
187 1 hiro
        {N_("/_View/_Code set/Japanese (ISO-2022-_JP)"),
188 1 hiro
         CODESET_ACTION(C_ISO_2022_JP)},
189 1 hiro
        {N_("/_View/_Code set/Japanese (ISO-2022-JP-2)"),
190 1 hiro
         CODESET_ACTION(C_ISO_2022_JP_2)},
191 1 hiro
        {N_("/_View/_Code set/Japanese (_EUC-JP)"),
192 1 hiro
         CODESET_ACTION(C_EUC_JP)},
193 1 hiro
        {N_("/_View/_Code set/Japanese (_Shift__JIS)"),
194 1 hiro
         CODESET_ACTION(C_SHIFT_JIS)},
195 1 hiro
        CODESET_SEPARATOR,
196 1 hiro
        {N_("/_View/_Code set/Simplified Chinese (_GB2312)"),
197 1 hiro
         CODESET_ACTION(C_GB2312)},
198 1 hiro
        {N_("/_View/_Code set/Traditional Chinese (_Big5)"),
199 1 hiro
         CODESET_ACTION(C_BIG5)},
200 1 hiro
        {N_("/_View/_Code set/Traditional Chinese (EUC-_TW)"),
201 1 hiro
         CODESET_ACTION(C_EUC_TW)},
202 1 hiro
        {N_("/_View/_Code set/Chinese (ISO-2022-_CN)"),
203 1 hiro
         CODESET_ACTION(C_ISO_2022_CN)},
204 1 hiro
        CODESET_SEPARATOR,
205 1 hiro
        {N_("/_View/_Code set/Korean (EUC-_KR)"),
206 1 hiro
         CODESET_ACTION(C_EUC_KR)},
207 1 hiro
        {N_("/_View/_Code set/Korean (ISO-2022-KR)"),
208 1 hiro
         CODESET_ACTION(C_ISO_2022_KR)},
209 1 hiro
        CODESET_SEPARATOR,
210 1 hiro
        {N_("/_View/_Code set/Thai (TIS-620)"),
211 1 hiro
         CODESET_ACTION(C_TIS_620)},
212 1 hiro
        {N_("/_View/_Code set/Thai (Windows-874)"),
213 1 hiro
         CODESET_ACTION(C_WINDOWS_874)},
214 1 hiro
215 1 hiro
#undef CODESET_SEPARATOR
216 1 hiro
#undef CODESET_ACTION
217 1 hiro
218 1 hiro
        {N_("/_View/---"),                NULL, NULL, 0, "<Separator>"},
219 1 hiro
        {N_("/_View/Mess_age source"),        NULL, view_source_cb, 0, NULL},
220 1 hiro
        {N_("/_View/Show all _header"),        NULL, show_all_header_cb, 0, "<ToggleItem>"},
221 1 hiro
222 1 hiro
        {N_("/_Message"),                NULL, NULL, 0, "<Branch>"},
223 1 hiro
        {N_("/_Message/Compose _new message"),
224 1 hiro
                                        NULL, compose_cb, 0, NULL},
225 1 hiro
        {N_("/_Message/---"),                NULL, NULL, 0, "<Separator>"},
226 1 hiro
        {N_("/_Message/_Reply"),        NULL, reply_cb, COMPOSE_REPLY, NULL},
227 1 hiro
        {N_("/_Message/Repl_y to/_all"),
228 1 hiro
                                        NULL, reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
229 1 hiro
        {N_("/_Message/Repl_y to/_sender"),
230 1 hiro
                                        NULL, reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
231 1 hiro
        {N_("/_Message/Repl_y to/mailing _list"),
232 1 hiro
                                        NULL, reply_cb, COMPOSE_REPLY_TO_LIST, NULL},
233 1 hiro
        {N_("/_Message/---"),                NULL, NULL, 0, "<Separator>"},
234 1 hiro
        {N_("/_Message/_Forward"),        NULL, reply_cb, COMPOSE_FORWARD, NULL},
235 1 hiro
        {N_("/_Message/For_ward as attachment"),
236 1 hiro
                                        NULL, reply_cb, COMPOSE_FORWARD_AS_ATTACH, NULL},
237 1 hiro
        {N_("/_Message/Redirec_t"),        NULL, reply_cb, COMPOSE_REDIRECT, NULL},
238 1 hiro
        {N_("/_Message/---"),                NULL, NULL, 0, "<Separator>"},
239 1 hiro
        {N_("/_Message/Re-_edit"),        NULL, reedit_cb, 0, NULL},
240 1 hiro
241 1 hiro
        {N_("/_Tools"),                        NULL, NULL, 0, "<Branch>"},
242 1 hiro
        {N_("/_Tools/_Address book"),        NULL, addressbook_open_cb, 0, NULL},
243 1 hiro
        {N_("/_Tools/Add sender to address boo_k"),
244 1 hiro
                                        NULL, add_address_cb, 0, NULL},
245 1 hiro
        {N_("/_Tools/---"),                NULL, NULL, 0, "<Separator>"},
246 1 hiro
        {N_("/_Tools/_Create filter rule"),
247 1 hiro
                                        NULL, NULL, 0, "<Branch>"},
248 1 hiro
        {N_("/_Tools/_Create filter rule/_Automatically"),
249 1 hiro
                                        NULL, create_filter_cb, FILTER_BY_AUTO, NULL},
250 1 hiro
        {N_("/_Tools/_Create filter rule/by _From"),
251 1 hiro
                                        NULL, create_filter_cb, FILTER_BY_FROM, NULL},
252 1 hiro
        {N_("/_Tools/_Create filter rule/by _To"),
253 1 hiro
                                        NULL, create_filter_cb, FILTER_BY_TO, NULL},
254 1 hiro
        {N_("/_Tools/_Create filter rule/by _Subject"),
255 1 hiro
                                        NULL, create_filter_cb, FILTER_BY_SUBJECT, NULL},
256 1 hiro
        {N_("/_Tools/---"),                NULL, NULL, 0, "<Separator>"},
257 1 hiro
        {N_("/_Tools/Actio_ns"),        NULL, NULL, 0, "<Branch>"},
258 1 hiro
259 1 hiro
        {N_("/_Help"),                        NULL, NULL, 0, "<Branch>"},
260 1 hiro
        {N_("/_Help/_About"),                NULL, about_cb, 0, NULL}
261 1 hiro
};
262 1 hiro
263 1 hiro
264 1 hiro
MessageView *messageview_create(void)
265 1 hiro
{
266 1 hiro
        MessageView *messageview;
267 1 hiro
        GtkWidget *vbox;
268 1 hiro
        HeaderView *headerview;
269 1 hiro
        TextView *textview;
270 1 hiro
        MimeView *mimeview;
271 1 hiro
272 1 hiro
        debug_print(_("Creating message view...\n"));
273 1 hiro
        messageview = g_new0(MessageView, 1);
274 1 hiro
275 1 hiro
        messageview->type = MVIEW_TEXT;
276 1 hiro
277 1 hiro
        headerview = headerview_create();
278 1 hiro
279 1 hiro
        textview = textview_create();
280 1 hiro
        textview->messageview = messageview;
281 1 hiro
282 1 hiro
        mimeview = mimeview_create();
283 1 hiro
        mimeview->textview = textview_create();
284 1 hiro
        mimeview->textview->messageview = messageview;
285 1 hiro
        mimeview->imageview = imageview_create();
286 1 hiro
        mimeview->imageview->messageview = messageview;
287 1 hiro
        mimeview->messageview = messageview;
288 1 hiro
289 1 hiro
        vbox = gtk_vbox_new(FALSE, 0);
290 1 hiro
        gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(headerview),
291 1 hiro
                           FALSE, FALSE, 0);
292 1 hiro
        gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(textview),
293 1 hiro
                           TRUE, TRUE, 0);
294 1 hiro
        gtk_widget_show(vbox);
295 1 hiro
296 1 hiro
        /* to remove without destroyed */
297 1 hiro
        gtk_widget_ref(GTK_WIDGET_PTR(textview));
298 1 hiro
        gtk_widget_ref(GTK_WIDGET_PTR(mimeview));
299 1 hiro
        gtk_widget_ref(GTK_WIDGET_PTR(mimeview->textview));
300 1 hiro
        gtk_widget_ref(GTK_WIDGET_PTR(mimeview->imageview));
301 1 hiro
302 1 hiro
        messageview->vbox        = vbox;
303 1 hiro
        messageview->new_window  = FALSE;
304 1 hiro
        messageview->window      = NULL;
305 1 hiro
        messageview->window_vbox = NULL;
306 1 hiro
        messageview->headerview  = headerview;
307 1 hiro
        messageview->textview    = textview;
308 1 hiro
        messageview->mimeview    = mimeview;
309 1 hiro
310 1 hiro
        messageview->statusbar     = NULL;
311 1 hiro
        messageview->statusbar_cid = 0;
312 1 hiro
313 1 hiro
        return messageview;
314 1 hiro
}
315 1 hiro
316 1 hiro
MessageView *messageview_create_with_new_window(void)
317 1 hiro
{
318 1 hiro
        MessageView *msgview;
319 1 hiro
        GtkWidget *window;
320 1 hiro
        GtkWidget *window_vbox;
321 1 hiro
        GtkWidget *body_vbox;
322 1 hiro
        GtkWidget *menubar;
323 1 hiro
        GtkItemFactory *ifactory;
324 1 hiro
        GtkWidget *statusbar;
325 1 hiro
        guint n_menu_entries;
326 1 hiro
327 1 hiro
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
328 1 hiro
        gtk_window_set_title(GTK_WINDOW(window), _("Sylpheed - Message View"));
329 1 hiro
        gtk_window_set_wmclass(GTK_WINDOW(window), "message_view", "Sylpheed");
330 1 hiro
        gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
331 1 hiro
        gtk_widget_set_size_request(window, prefs_common.msgwin_width,
332 1 hiro
                                    prefs_common.msgwin_height);
333 1 hiro
334 1 hiro
        msgview = messageview_create();
335 1 hiro
336 1 hiro
        window_vbox = gtk_vbox_new(FALSE, 0);
337 1 hiro
        gtk_container_add(GTK_CONTAINER(window), window_vbox);
338 1 hiro
339 1 hiro
        g_signal_connect(G_OBJECT(window), "size_allocate",
340 1 hiro
                         G_CALLBACK(messageview_size_allocate_cb),
341 1 hiro
                         msgview);
342 1 hiro
        g_signal_connect(G_OBJECT(window), "destroy",
343 1 hiro
                         G_CALLBACK(messageview_destroy_cb), msgview);
344 1 hiro
        g_signal_connect(G_OBJECT(window), "key_press_event",
345 1 hiro
                         G_CALLBACK(key_pressed), msgview);
346 1 hiro
        MANAGE_WINDOW_SIGNALS_CONNECT(window);
347 1 hiro
348 1 hiro
        n_menu_entries = sizeof(msgview_entries) / sizeof (msgview_entries[0]);
349 1 hiro
        menubar = menubar_create(window, msgview_entries, n_menu_entries,
350 1 hiro
                                 "<MessageView>", msgview);
351 1 hiro
#warning FIXME_GTK2
352 1 hiro
#if 0
353 1 hiro
        menu_factory_copy_rc("<Main>", "<MessageView>");
354 1 hiro
#endif
355 1 hiro
        gtk_box_pack_start(GTK_BOX(window_vbox), menubar, FALSE, TRUE, 0);
356 1 hiro
357 1 hiro
        body_vbox = gtk_vbox_new(FALSE, BORDER_WIDTH);
358 1 hiro
        gtk_container_set_border_width(GTK_CONTAINER(body_vbox), BORDER_WIDTH);
359 1 hiro
        gtk_box_pack_start(GTK_BOX(window_vbox), body_vbox, TRUE, TRUE, 0);
360 1 hiro
361 1 hiro
        gtk_box_pack_start(GTK_BOX(body_vbox), GTK_WIDGET_PTR(msgview),
362 1 hiro
                           TRUE, TRUE, 0);
363 1 hiro
        gtk_widget_grab_focus(msgview->textview->text);
364 1 hiro
365 1 hiro
        statusbar = gtk_statusbar_new();
366 1 hiro
        gtk_box_pack_end(GTK_BOX(body_vbox), statusbar, FALSE, FALSE, 0);
367 1 hiro
        msgview->statusbar = statusbar;
368 1 hiro
        msgview->statusbar_cid = gtk_statusbar_get_context_id
369 1 hiro
                (GTK_STATUSBAR(statusbar), "Message View");
370 1 hiro
371 1 hiro
        gtk_widget_show_all(window);
372 1 hiro
373 1 hiro
        msgview->new_window = TRUE;
374 1 hiro
        msgview->window = window;
375 1 hiro
        msgview->window_vbox = window_vbox;
376 1 hiro
        msgview->body_vbox = body_vbox;
377 1 hiro
        msgview->visible = TRUE;
378 1 hiro
379 1 hiro
        messageview_init(msgview);
380 1 hiro
381 1 hiro
        ifactory = gtk_item_factory_from_widget(menubar);
382 1 hiro
        action_update_msgview_menu(ifactory, msgview);
383 1 hiro
384 1 hiro
        messageview_list = g_list_append(messageview_list, msgview);
385 1 hiro
386 1 hiro
        return msgview;
387 1 hiro
}
388 1 hiro
389 1 hiro
void messageview_init(MessageView *messageview)
390 1 hiro
{
391 1 hiro
        headerview_init(messageview->headerview);
392 1 hiro
        textview_init(messageview->textview);
393 1 hiro
        mimeview_init(messageview->mimeview);
394 1 hiro
        /* messageview_set_font(messageview); */
395 1 hiro
}
396 1 hiro
397 1 hiro
GList *messageview_get_window_list(void)
398 1 hiro
{
399 1 hiro
        return messageview_list;
400 1 hiro
}
401 1 hiro
402 1 hiro
gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
403 1 hiro
                      gboolean all_headers)
404 1 hiro
{
405 1 hiro
        gchar *file;
406 1 hiro
        MimeInfo *mimeinfo;
407 1 hiro
408 1 hiro
        g_return_val_if_fail(msginfo != NULL, -1);
409 1 hiro
410 1 hiro
        mimeinfo = procmime_scan_message(msginfo);
411 1 hiro
        if (!mimeinfo) {
412 1 hiro
                messageview_change_view_type(messageview, MVIEW_TEXT);
413 1 hiro
                textview_show_error(messageview->textview);
414 1 hiro
                return -1;
415 1 hiro
        }
416 1 hiro
417 1 hiro
        file = procmsg_get_message_file_path(msginfo);
418 1 hiro
        if (!file) {
419 1 hiro
                g_warning("can't get message file path.\n");
420 1 hiro
                procmime_mimeinfo_free_all(mimeinfo);
421 1 hiro
                messageview_change_view_type(messageview, MVIEW_TEXT);
422 1 hiro
                textview_show_error(messageview->textview);
423 1 hiro
                return -1;
424 1 hiro
        }
425 1 hiro
426 1 hiro
        if (messageview->msginfo != msginfo) {
427 1 hiro
                procmsg_msginfo_free(messageview->msginfo);
428 1 hiro
                messageview->msginfo = procmsg_msginfo_get_full_info(msginfo);
429 20 hiro
                if (!messageview->msginfo)
430 20 hiro
                        messageview->msginfo = procmsg_msginfo_copy(msginfo);
431 1 hiro
        }
432 1 hiro
        headerview_show(messageview->headerview, messageview->msginfo);
433 1 hiro
434 1 hiro
        textview_set_all_headers(messageview->textview, all_headers);
435 1 hiro
        textview_set_all_headers(messageview->mimeview->textview, all_headers);
436 1 hiro
437 1 hiro
        if (mimeinfo->mime_type != MIME_TEXT &&
438 1 hiro
            mimeinfo->mime_type != MIME_TEXT_HTML) {
439 1 hiro
                messageview_change_view_type(messageview, MVIEW_MIME);
440 1 hiro
                mimeview_show_message(messageview->mimeview, mimeinfo, file);
441 1 hiro
        } else {
442 1 hiro
                messageview_change_view_type(messageview, MVIEW_TEXT);
443 1 hiro
                textview_show_message(messageview->textview, mimeinfo, file);
444 1 hiro
                procmime_mimeinfo_free_all(mimeinfo);
445 1 hiro
        }
446 1 hiro
447 1 hiro
        g_free(file);
448 1 hiro
449 1 hiro
        return 0;
450 1 hiro
}
451 1 hiro
452 1 hiro
static void messageview_change_view_type(MessageView *messageview,
453 1 hiro
                                         MessageType type)
454 1 hiro
{
455 1 hiro
        TextView *textview = messageview->textview;
456 1 hiro
        MimeView *mimeview = messageview->mimeview;
457 1 hiro
458 1 hiro
        if (messageview->type == type) return;
459 1 hiro
460 1 hiro
        if (type == MVIEW_MIME) {
461 1 hiro
                gtkut_container_remove
462 1 hiro
                        (GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
463 1 hiro
                         GTK_WIDGET_PTR(textview));
464 1 hiro
                gtk_box_pack_start(GTK_BOX(messageview->vbox),
465 1 hiro
                                   GTK_WIDGET_PTR(mimeview), TRUE, TRUE, 0);
466 1 hiro
                gtk_container_add(GTK_CONTAINER(mimeview->vbox),
467 1 hiro
                                  GTK_WIDGET_PTR(textview));
468 1 hiro
        } else if (type == MVIEW_TEXT) {
469 1 hiro
                gtkut_container_remove
470 1 hiro
                        (GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
471 1 hiro
                         GTK_WIDGET_PTR(mimeview));
472 1 hiro
                mimeview_clear(mimeview);
473 1 hiro
474 1 hiro
                if (mimeview->vbox == GTK_WIDGET_PTR(textview)->parent)
475 1 hiro
                        gtkut_container_remove(GTK_CONTAINER(mimeview->vbox),
476 1 hiro
                                                GTK_WIDGET_PTR(textview));
477 1 hiro
478 1 hiro
                gtk_box_pack_start(GTK_BOX(messageview->vbox),
479 1 hiro
                                   GTK_WIDGET_PTR(textview), TRUE, TRUE, 0);
480 1 hiro
        } else
481 1 hiro
                return;
482 1 hiro
483 1 hiro
        messageview->type = type;
484 1 hiro
}
485 1 hiro
486 1 hiro
void messageview_clear(MessageView *messageview)
487 1 hiro
{
488 1 hiro
        procmsg_msginfo_free(messageview->msginfo);
489 1 hiro
        messageview->msginfo = NULL;
490 1 hiro
        messageview_change_view_type(messageview, MVIEW_TEXT);
491 1 hiro
        headerview_clear(messageview->headerview);
492 1 hiro
        textview_clear(messageview->textview);
493 1 hiro
        mimeview_clear(messageview->mimeview);
494 1 hiro
}
495 1 hiro
496 1 hiro
void messageview_destroy(MessageView *messageview)
497 1 hiro
{
498 1 hiro
        GtkWidget *textview  = GTK_WIDGET_PTR(messageview->textview);
499 1 hiro
        GtkWidget *imageview = GTK_WIDGET_PTR(messageview->mimeview->imageview);
500 1 hiro
        GtkWidget *mimeview  = GTK_WIDGET_PTR(messageview->mimeview);
501 1 hiro
502 1 hiro
        messageview_list = g_list_remove(messageview_list, messageview);
503 1 hiro
504 1 hiro
        headerview_destroy(messageview->headerview);
505 1 hiro
        textview_destroy(messageview->textview);
506 1 hiro
        mimeview_destroy(messageview->mimeview);
507 1 hiro
508 1 hiro
        procmsg_msginfo_free(messageview->msginfo);
509 1 hiro
510 1 hiro
        g_free(messageview);
511 1 hiro
512 1 hiro
        gtk_widget_unref(textview);
513 1 hiro
        gtk_widget_unref(imageview);
514 1 hiro
        gtk_widget_unref(mimeview);
515 1 hiro
}
516 1 hiro
517 1 hiro
void messageview_quote_color_set(void)
518 1 hiro
{
519 1 hiro
}
520 1 hiro
521 1 hiro
void messageview_set_font(MessageView *messageview)
522 1 hiro
{
523 1 hiro
        textview_set_font(messageview->textview, NULL);
524 1 hiro
}
525 1 hiro
526 1 hiro
TextView *messageview_get_current_textview(MessageView *messageview)
527 1 hiro
{
528 1 hiro
        TextView *text = NULL;
529 1 hiro
530 1 hiro
        if (messageview->type == MVIEW_TEXT)
531 1 hiro
                text = messageview->textview;
532 1 hiro
        else if (messageview->type == MVIEW_MIME) {
533 1 hiro
                if (gtk_notebook_get_current_page
534 1 hiro
                        (GTK_NOTEBOOK(messageview->mimeview->notebook)) == 0)
535 1 hiro
                        text = messageview->textview;
536 1 hiro
                else if (messageview->mimeview->type == MIMEVIEW_TEXT)
537 1 hiro
                        text = messageview->mimeview->textview;
538 1 hiro
        }
539 1 hiro
540 1 hiro
        return text;
541 1 hiro
}
542 1 hiro
543 1 hiro
MimeInfo *messageview_get_selected_mime_part(MessageView *messageview)
544 1 hiro
{
545 1 hiro
        if (messageview->type == MVIEW_MIME)
546 1 hiro
                return mimeview_get_selected_part(messageview->mimeview);
547 1 hiro
548 1 hiro
        return NULL;
549 1 hiro
}
550 1 hiro
551 1 hiro
void messageview_copy_clipboard(MessageView *messageview)
552 1 hiro
{
553 1 hiro
        TextView *text;
554 1 hiro
555 1 hiro
        text = messageview_get_current_textview(messageview);
556 1 hiro
        if (text) {
557 1 hiro
                GtkTextView *textview = GTK_TEXT_VIEW(text->text);
558 1 hiro
                GtkTextBuffer *buffer;
559 1 hiro
                GtkClipboard *clipboard;
560 1 hiro
561 1 hiro
                buffer = gtk_text_view_get_buffer(textview);
562 1 hiro
                clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
563 1 hiro
                gtk_text_buffer_copy_clipboard(buffer, clipboard);
564 1 hiro
        }
565 1 hiro
}
566 1 hiro
567 1 hiro
void messageview_select_all(MessageView *messageview)
568 1 hiro
{
569 1 hiro
        TextView *text;
570 1 hiro
571 1 hiro
        text = messageview_get_current_textview(messageview);
572 130 hiro
        if (text) {
573 130 hiro
                GtkTextView *textview = GTK_TEXT_VIEW(text->text);
574 130 hiro
                GtkTextBuffer *buffer;
575 130 hiro
                GtkTextIter start, end;
576 130 hiro
577 130 hiro
                buffer = gtk_text_view_get_buffer(textview);
578 130 hiro
                gtk_text_buffer_get_bounds(buffer, &start, &end);
579 130 hiro
                gtk_text_buffer_select_range(buffer, &start, &end);
580 130 hiro
        }
581 1 hiro
}
582 1 hiro
583 1 hiro
void messageview_set_position(MessageView *messageview, gint pos)
584 1 hiro
{
585 1 hiro
        textview_set_position(messageview->textview, pos);
586 1 hiro
}
587 1 hiro
588 1 hiro
gboolean messageview_search_string(MessageView *messageview, const gchar *str,
589 1 hiro
                                   gboolean case_sens)
590 1 hiro
{
591 1 hiro
        return textview_search_string(messageview->textview, str, case_sens);
592 1 hiro
        return FALSE;
593 1 hiro
}
594 1 hiro
595 1 hiro
gboolean messageview_search_string_backward(MessageView *messageview,
596 1 hiro
                                            const gchar *str,
597 1 hiro
                                            gboolean case_sens)
598 1 hiro
{
599 1 hiro
        return textview_search_string_backward(messageview->textview,
600 1 hiro
                                               str, case_sens);
601 1 hiro
        return FALSE;
602 1 hiro
}
603 1 hiro
604 1 hiro
gboolean messageview_is_visible(MessageView *messageview)
605 1 hiro
{
606 1 hiro
        return messageview->visible;
607 1 hiro
}
608 1 hiro
609 1 hiro
void messageview_save_as(MessageView *messageview)
610 1 hiro
{
611 1 hiro
        gchar *filename = NULL;
612 1 hiro
        MsgInfo *msginfo;
613 1 hiro
        gchar *src, *dest;
614 1 hiro
615 1 hiro
        if (!messageview->msginfo) return;
616 1 hiro
        msginfo = messageview->msginfo;
617 1 hiro
618 1 hiro
        if (msginfo->subject) {
619 1 hiro
                Xstrdup_a(filename, msginfo->subject, return);
620 1 hiro
                subst_for_filename(filename);
621 1 hiro
        }
622 128 hiro
623 128 hiro
        dest = filesel_save_as(filename);
624 1 hiro
        if (!dest) return;
625 1 hiro
626 1 hiro
        src = procmsg_get_message_file(msginfo);
627 1 hiro
        if (copy_file(src, dest, TRUE) < 0) {
628 1 hiro
                alertpanel_error(_("Can't save the file `%s'."),
629 1 hiro
                                 g_basename(dest));
630 1 hiro
        }
631 1 hiro
        g_free(src);
632 128 hiro
633 128 hiro
        g_free(dest);
634 1 hiro
}
635 1 hiro
636 1 hiro
static void messageview_destroy_cb(GtkWidget *widget, MessageView *messageview)
637 1 hiro
{
638 1 hiro
        messageview_destroy(messageview);
639 1 hiro
}
640 1 hiro
641 1 hiro
static void messageview_size_allocate_cb(GtkWidget *widget,
642 1 hiro
                                         GtkAllocation *allocation)
643 1 hiro
{
644 1 hiro
        g_return_if_fail(allocation != NULL);
645 1 hiro
646 1 hiro
        prefs_common.msgwin_width  = allocation->width;
647 1 hiro
        prefs_common.msgwin_height = allocation->height;
648 1 hiro
}
649 1 hiro
650 1 hiro
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
651 1 hiro
                            MessageView *messageview)
652 1 hiro
{
653 1 hiro
        if (event && event->keyval == GDK_Escape && messageview->window)
654 1 hiro
                gtk_widget_destroy(messageview->window);
655 1 hiro
        return FALSE;
656 1 hiro
}
657 1 hiro
658 1 hiro
static void save_as_cb(gpointer data, guint action, GtkWidget *widget)
659 1 hiro
{
660 1 hiro
        MessageView *messageview = (MessageView *)data;
661 1 hiro
        messageview_save_as(messageview);
662 1 hiro
}
663 1 hiro
664 1 hiro
static void print_cb(gpointer data, guint action, GtkWidget *widget)
665 1 hiro
{
666 1 hiro
        MessageView *messageview = (MessageView *)data;
667 1 hiro
        gchar *cmdline;
668 1 hiro
        gchar *p;
669 1 hiro
670 1 hiro
        if (!messageview->msginfo) return;
671 1 hiro
672 1 hiro
        cmdline = input_dialog(_("Print"),
673 1 hiro
                               _("Enter the print command line:\n"
674 1 hiro
                                 "(`%s' will be replaced with file name)"),
675 1 hiro
                               prefs_common.print_cmd);
676 1 hiro
        if (!cmdline) return;
677 1 hiro
        if (!(p = strchr(cmdline, '%')) || *(p + 1) != 's' ||
678 1 hiro
            strchr(p + 2, '%')) {
679 1 hiro
                alertpanel_error(_("Print command line is invalid:\n`%s'"),
680 1 hiro
                                 cmdline);
681 1 hiro
                g_free(cmdline);
682 1 hiro
                return;
683 1 hiro
        }
684 1 hiro
685 1 hiro
        procmsg_print_message(messageview->msginfo, cmdline);
686 1 hiro
        g_free(cmdline);
687 1 hiro
}
688 1 hiro
689 1 hiro
static void close_cb(gpointer data, guint action, GtkWidget *widget)
690 1 hiro
{
691 1 hiro
        MessageView *messageview = (MessageView *)data;
692 1 hiro
        gtk_widget_destroy(messageview->window);
693 1 hiro
}
694 1 hiro
695 1 hiro
static void copy_cb(gpointer data, guint action, GtkWidget *widget)
696 1 hiro
{
697 1 hiro
        MessageView *messageview = (MessageView *)data;
698 1 hiro
        messageview_copy_clipboard(messageview);
699 1 hiro
}
700 1 hiro
701 1 hiro
static void allsel_cb(gpointer data, guint action, GtkWidget *widget)
702 1 hiro
{
703 1 hiro
        MessageView *messageview = (MessageView *)data;
704 1 hiro
        messageview_select_all(messageview);
705 1 hiro
}
706 1 hiro
707 1 hiro
static void search_cb(gpointer data, guint action, GtkWidget *widget)
708 1 hiro
{
709 1 hiro
        MessageView *messageview = (MessageView *)data;
710 1 hiro
        message_search(messageview);
711 1 hiro
}
712 1 hiro
713 1 hiro
static void set_charset_cb(gpointer data, guint action, GtkWidget *widget)
714 1 hiro
{
715 1 hiro
        MessageView *messageview = (MessageView *)data;
716 1 hiro
        const gchar *charset;
717 1 hiro
718 1 hiro
        if (GTK_CHECK_MENU_ITEM(widget)->active) {
719 1 hiro
                charset = conv_get_charset_str((CharSet)action);
720 1 hiro
                g_free(messageview->forced_charset);
721 1 hiro
                messageview->forced_charset = g_strdup(charset);
722 1 hiro
                messageview_show(messageview, messageview->msginfo, FALSE);
723 1 hiro
        }
724 1 hiro
}
725 1 hiro
726 1 hiro
static void view_source_cb(gpointer data, guint action, GtkWidget *widget)
727 1 hiro
{
728 1 hiro
        MessageView *messageview = (MessageView *)data;
729 1 hiro
        SourceWindow *srcwin;
730 1 hiro
731 1 hiro
        if (!messageview->msginfo) return;
732 1 hiro
733 1 hiro
        srcwin = source_window_create();
734 1 hiro
        source_window_show_msg(srcwin, messageview->msginfo);
735 1 hiro
        source_window_show(srcwin);
736 1 hiro
}
737 1 hiro
738 1 hiro
static void show_all_header_cb(gpointer data, guint action, GtkWidget *widget)
739 1 hiro
{
740 1 hiro
        MessageView *messageview = (MessageView *)data;
741 1 hiro
        MsgInfo *msginfo = messageview->msginfo;
742 1 hiro
743 1 hiro
        if (!msginfo) return;
744 1 hiro
        messageview->msginfo = NULL;
745 1 hiro
        messageview_show(messageview, msginfo,
746 1 hiro
                         GTK_CHECK_MENU_ITEM(widget)->active);
747 1 hiro
        procmsg_msginfo_free(msginfo);
748 1 hiro
}
749 1 hiro
750 1 hiro
static void compose_cb(gpointer data, guint action, GtkWidget *widget)
751 1 hiro
{
752 1 hiro
        MessageView *messageview = (MessageView *)data;
753 1 hiro
        PrefsAccount *ac = NULL;
754 1 hiro
        FolderItem *item = NULL;
755 1 hiro
756 1 hiro
        if (messageview->msginfo)
757 1 hiro
                item = messageview->msginfo->folder;
758 1 hiro
759 1 hiro
        if (item) {
760 1 hiro
                ac = account_find_from_item(item);
761 1 hiro
                if (ac && ac->protocol == A_NNTP &&
762 1 hiro
                    FOLDER_TYPE(item->folder) == F_NEWS) {
763 1 hiro
                        compose_new(ac, item, item->path, NULL);
764 1 hiro
                        return;
765 1 hiro
                }
766 1 hiro
        }
767 1 hiro
768 1 hiro
        compose_new(ac, item, NULL, NULL);
769 1 hiro
}
770 1 hiro
771 1 hiro
static void reply_cb(gpointer data, guint action, GtkWidget *widget)
772 1 hiro
{
773 1 hiro
        MessageView *messageview = (MessageView *)data;
774 1 hiro
        GSList *mlist = NULL;
775 1 hiro
        MsgInfo *msginfo;
776 1 hiro
        gchar *text = NULL;
777 1 hiro
        ComposeMode mode = (ComposeMode)action;
778 1 hiro
779 1 hiro
        msginfo = messageview->msginfo;
780 1 hiro
        mlist = g_slist_append(NULL, msginfo);
781 1 hiro
782 130 hiro
        text = gtkut_text_view_get_selection
783 130 hiro
                (GTK_TEXT_VIEW(messageview->textview->text));
784 1 hiro
        if (text && *text == '\0') {
785 1 hiro
                g_free(text);
786 1 hiro
                text = NULL;
787 1 hiro
        }
788 1 hiro
789 1 hiro
        if (!COMPOSE_QUOTE_MODE(mode))
790 1 hiro
                mode |= prefs_common.reply_with_quote
791 1 hiro
                        ? COMPOSE_WITH_QUOTE : COMPOSE_WITHOUT_QUOTE;
792 1 hiro
793 1 hiro
        switch (COMPOSE_MODE(mode)) {
794 1 hiro
        case COMPOSE_REPLY:
795 1 hiro
        case COMPOSE_REPLY_TO_SENDER:
796 1 hiro
        case COMPOSE_REPLY_TO_ALL:
797 1 hiro
        case COMPOSE_REPLY_TO_LIST:
798 1 hiro
                compose_reply(msginfo, msginfo->folder, mode, text);
799 1 hiro
                break;
800 1 hiro
        case COMPOSE_FORWARD:
801 1 hiro
                compose_forward(mlist, msginfo->folder, FALSE, text);
802 1 hiro
                break;
803 1 hiro
        case COMPOSE_FORWARD_AS_ATTACH:
804 1 hiro
                compose_forward(mlist, msginfo->folder, TRUE, NULL);
805 1 hiro
                break;
806 1 hiro
        case COMPOSE_REDIRECT:
807 1 hiro
                compose_redirect(msginfo, msginfo->folder);
808 1 hiro
                break;
809 1 hiro
        default:
810 1 hiro
                g_warning("messageview.c: reply_cb(): invalid mode: %d\n",
811 1 hiro
                          mode);
812 1 hiro
        }
813 1 hiro
814 1 hiro
        /* summary_set_marks_selected(summaryview); */
815 1 hiro
        g_free(text);
816 1 hiro
        g_slist_free(mlist);
817 1 hiro
}
818 1 hiro
819 1 hiro
static void reedit_cb(gpointer data, guint action, GtkWidget *widget)
820 1 hiro
{
821 1 hiro
        MessageView *messageview = (MessageView *)data;
822 1 hiro
        MsgInfo *msginfo;
823 1 hiro
824 1 hiro
        if (!messageview->msginfo) return;
825 1 hiro
        msginfo = messageview->msginfo;
826 1 hiro
        if (!msginfo->folder) return;
827 1 hiro
        if (msginfo->folder->stype != F_OUTBOX &&
828 1 hiro
            msginfo->folder->stype != F_DRAFT &&
829 1 hiro
            msginfo->folder->stype != F_QUEUE) return;
830 1 hiro
831 1 hiro
        compose_reedit(msginfo);
832 1 hiro
}
833 1 hiro
834 1 hiro
static void addressbook_open_cb(gpointer data, guint action, GtkWidget *widget)
835 1 hiro
{
836 1 hiro
        addressbook_open(NULL);
837 1 hiro
}
838 1 hiro
839 1 hiro
static void add_address_cb(gpointer data, guint action, GtkWidget *widget)
840 1 hiro
{
841 1 hiro
        MessageView *messageview = (MessageView *)data;
842 1 hiro
        MsgInfo *msginfo;
843 1 hiro
        gchar *from;
844 1 hiro
845 1 hiro
        if (!messageview->msginfo) return;
846 1 hiro
        msginfo = messageview->msginfo;
847 1 hiro
        Xstrdup_a(from, msginfo->from, return);
848 1 hiro
        eliminate_address_comment(from);
849 1 hiro
        extract_address(from);
850 1 hiro
        addressbook_add_contact(msginfo->fromname, from, NULL);
851 1 hiro
}
852 1 hiro
853 1 hiro
static void create_filter_cb(gpointer data, guint action, GtkWidget *widget)
854 1 hiro
{
855 1 hiro
        MessageView *messageview = (MessageView *)data;
856 1 hiro
        gchar *header = NULL;
857 1 hiro
        gchar *key = NULL;
858 1 hiro
859 1 hiro
        if (!messageview->msginfo) return;
860 1 hiro
861 1 hiro
        procmsg_get_filter_keyword(messageview->msginfo, &header, &key,
862 1 hiro
                                   (PrefsFilterType)action);
863 1 hiro
        prefs_filter_open(messageview->msginfo, header);
864 1 hiro
865 1 hiro
        g_free(header);
866 1 hiro
        g_free(key);
867 1 hiro
}
868 1 hiro
869 1 hiro
static void about_cb(gpointer data, guint action, GtkWidget *widget)
870 1 hiro
{
871 1 hiro
        about_show();
872 1 hiro
}