1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <glib/gi18n.h>
31 #include <tny-account-store.h>
32 #include <tny-simple-list.h>
33 #include <modest-conf.h>
34 #include <modest-runtime.h>
35 #include <modest-tny-msg.h>
37 #include <widgets/modest-window-priv.h>
38 #include <widgets/modest-msg-edit-window.h>
39 #include <widgets/modest-msg-edit-window-ui.h>
40 #include <widgets/modest-combo-box.h>
42 #include <modest-widget-memory.h>
43 #include <modest-account-mgr-helpers.h>
45 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
46 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
47 static void modest_msg_edit_window_finalize (GObject *obj);
56 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
57 struct _ModestMsgEditWindowPrivate {
64 ModestProtoList *from_field_protos;
65 GtkWidget *from_field;
70 GtkWidget *subject_field;
75 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
76 MODEST_TYPE_MSG_EDIT_WINDOW, \
77 ModestMsgEditWindowPrivate))
79 static GtkWindowClass *parent_class = NULL;
81 /* uncomment the following if you have defined any signals */
82 /* static guint signals[LAST_SIGNAL] = {0}; */
85 modest_msg_edit_window_get_type (void)
87 static GType my_type = 0;
89 static const GTypeInfo my_info = {
90 sizeof(ModestMsgEditWindowClass),
92 NULL, /* base finalize */
93 (GClassInitFunc) modest_msg_edit_window_class_init,
94 NULL, /* class finalize */
95 NULL, /* class data */
96 sizeof(ModestMsgEditWindow),
98 (GInstanceInitFunc) modest_msg_edit_window_init,
101 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
102 "ModestMsgEditWindow",
110 save_state (ModestWindow *self)
112 modest_widget_memory_save (modest_runtime_get_conf (),
113 G_OBJECT(self), "modest-edit-msg-window");
118 restore_settings (ModestMsgEditWindow *self)
120 modest_widget_memory_restore (modest_runtime_get_conf (),
121 G_OBJECT(self), "modest-edit-msg-window");
125 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
127 GObjectClass *gobject_class;
128 ModestWindowClass *modest_window_class;
130 gobject_class = (GObjectClass*) klass;
131 modest_window_class = (ModestWindowClass*) klass;
133 parent_class = g_type_class_peek_parent (klass);
134 gobject_class->finalize = modest_msg_edit_window_finalize;
136 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
138 modest_window_class->save_state_func = save_state;
142 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
144 ModestMsgEditWindowPrivate *priv;
145 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
147 priv->toolbar = NULL;
148 priv->menubar = NULL;
149 priv->msg_body = NULL;
150 priv->from_field = NULL;
151 priv->to_field = NULL;
152 priv->cc_field = NULL;
153 priv->bcc_field = NULL;
154 priv->subject_field = NULL;
159 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
161 static ModestPairList*
162 get_transports (void)
164 ModestAccountMgr *account_mgr;
165 GSList *transports = NULL;
166 GSList *cursor, *accounts;
168 account_mgr = modest_runtime_get_account_mgr();
169 cursor = accounts = modest_account_mgr_account_names (account_mgr, TRUE);
171 gchar *account_name = cursor->data ? g_strdup((gchar*)cursor->data) : NULL;
172 gchar *from_string = modest_account_mgr_get_from_string (account_mgr,
175 /* something went wrong: ignore this one */
176 g_free (account_name);
180 pair = modest_pair_new ((gpointer) account_name,
181 (gpointer) from_string , TRUE);
182 transports = g_slist_prepend (transports, pair);
183 } /* don't free account name; it's freed when the transports list is freed */
184 cursor = cursor->next;
186 g_slist_free (accounts);
192 on_from_combo_changed (ModestComboBox *combo, ModestWindow *win)
194 modest_window_set_active_account (
195 win, modest_combo_box_get_active_id(combo));
201 init_window (ModestMsgEditWindow *obj, const gchar* account)
203 GtkWidget *to_button, *cc_button, *bcc_button;
204 GtkWidget *header_table;
205 GtkWidget *main_vbox;
206 ModestMsgEditWindowPrivate *priv;
207 ModestWindowPrivate *parent_priv;
209 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
210 parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
212 to_button = gtk_button_new_with_label (_("To..."));
213 cc_button = gtk_button_new_with_label (_("Cc..."));
214 bcc_button = gtk_button_new_with_label (_("Bcc..."));
216 /* Note: This ModestPairList* must exist for as long as the combo
217 * that uses it, because the ModestComboBox uses the ID opaquely,
218 * so it can't know how to manage its memory. */
219 priv->from_field_protos = get_transports ();
220 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
223 modest_combo_box_set_active_id (MODEST_COMBO_BOX(priv->from_field),
225 modest_window_set_active_account (MODEST_WINDOW(obj), account);
227 /* auto-update the active account */
228 g_signal_connect (G_OBJECT(priv->from_field), "changed", G_CALLBACK(on_from_combo_changed), obj);
230 priv->to_field = gtk_entry_new_with_max_length (80);
231 priv->cc_field = gtk_entry_new_with_max_length (80);
232 priv->bcc_field = gtk_entry_new_with_max_length (80);
233 priv->subject_field = gtk_entry_new_with_max_length (80);
235 header_table = gtk_table_new (5,2, FALSE);
237 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
238 0,1,0,1, GTK_SHRINK, 0, 0, 0);
239 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,1,2, GTK_SHRINK, 0, 0, 0);
240 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,2,3, GTK_SHRINK, 0, 0, 0);
241 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,3,4, GTK_SHRINK, 0, 0, 0);
242 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
243 0,1,4,5, GTK_SHRINK, 0, 0, 0);
245 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field, 1,2,0,1);
246 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,1,2);
247 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,2,3);
248 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,3,4);
249 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
251 priv->msg_body = gtk_text_view_new ();
253 main_vbox = gtk_vbox_new (FALSE, 6);
255 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
256 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
257 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
258 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
260 gtk_widget_show_all (GTK_WIDGET(main_vbox));
261 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
266 modest_msg_edit_window_finalize (GObject *obj)
268 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
270 /* These had to stay alive for as long as the comboboxes that used them: */
271 modest_pair_list_free (priv->from_field_protos);
273 G_OBJECT_CLASS(parent_class)->finalize (obj);
279 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
281 modest_window_save_state (MODEST_WINDOW(self));
287 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
291 const gchar *to, *cc, *bcc, *subject;
292 ModestMsgEditWindowPrivate *priv;
295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
296 g_return_if_fail (TNY_IS_MSG (msg));
298 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
300 header = tny_msg_get_header (msg);
301 to = tny_header_get_to (header);
302 cc = tny_header_get_cc (header);
303 bcc = tny_header_get_bcc (header);
304 subject = tny_header_get_subject (header);
307 gtk_entry_set_text (GTK_ENTRY(priv->to_field), to);
309 gtk_entry_set_text (GTK_ENTRY(priv->cc_field), cc);
311 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field), bcc);
313 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
316 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
317 body = modest_tny_msg_get_body (msg, FALSE, NULL);
319 gtk_text_buffer_set_text (buf, body, -1);
325 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account)
327 ModestMsgEditWindow *self;
328 ModestMsgEditWindowPrivate *priv;
329 ModestWindowPrivate *parent_priv;
330 GtkActionGroup *action_group;
331 GError *error = NULL;
333 g_return_val_if_fail (msg, NULL);
335 self = MODEST_MSG_EDIT_WINDOW(g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL));
336 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(self);
337 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
339 parent_priv->ui_manager = gtk_ui_manager_new();
340 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
342 /* Add common actions */
343 gtk_action_group_add_actions (action_group,
344 modest_msg_edit_action_entries,
345 G_N_ELEMENTS (modest_msg_edit_action_entries),
347 gtk_action_group_add_toggle_actions (action_group,
348 modest_msg_edit_toggle_action_entries,
349 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
351 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
352 g_object_unref (action_group);
354 /* Load the UI definition */
355 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
356 MODEST_UIDIR "modest-msg-edit-window-ui.xml",
359 g_printerr ("modest: could not merge modest-msg-edit-window-ui.xml: %s\n", error->message);
360 g_error_free (error);
365 /* Add accelerators */
366 gtk_window_add_accel_group (GTK_WINDOW (self),
367 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
369 /* Toolbar / Menubar */
370 priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
371 priv->menubar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar");
373 gtk_toolbar_set_tooltips (GTK_TOOLBAR (priv->toolbar), TRUE);
376 init_window (MODEST_MSG_EDIT_WINDOW(self), account);
378 restore_settings (MODEST_MSG_EDIT_WINDOW(self));
380 gtk_window_set_title (GTK_WINDOW(self), "Modest");
381 gtk_window_set_icon_from_file (GTK_WINDOW(self), MODEST_APP_ICON, NULL);
383 g_signal_connect (G_OBJECT(self), "delete-event",
384 G_CALLBACK(on_delete_event), self);
388 return MODEST_WINDOW(self);
393 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
397 const gchar *account_name;
398 gchar *from_string = NULL;
399 ModestMsgEditWindowPrivate *priv;
401 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
403 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
405 account_name = (gchar*)modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
407 from_string = modest_account_mgr_get_from_string (
408 modest_runtime_get_account_mgr(), account_name);
410 g_printerr ("modest: cannot get from string\n");
416 data = g_slice_new0 (MsgData);
417 data->from = from_string; /* will be freed when data is freed */
418 data->to = g_strdup (gtk_entry_get_text (GTK_ENTRY(priv->to_field)));
419 data->cc = g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->cc_field)));
420 data->bcc = g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->bcc_field)));
421 data->subject = g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->subject_field)));
424 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
426 gtk_text_buffer_get_bounds (buf, &b, &e);
427 data->plain_body = gtk_text_buffer_get_text (buf, &b, &e, FALSE); /* Returns a copy. */
429 /* No rich supported yet, then html body is NULL */
430 data->html_body = NULL;
436 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
439 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
447 g_free (data->subject);
448 g_free (data->plain_body);
449 g_free (data->html_body);
451 /* TODO: Free data->attachments? */
453 g_slice_free (MsgData, data);
456 /* Rich formatting API functions */
458 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
460 return MODEST_MSG_EDIT_FORMAT_TEXT;
464 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
465 ModestMsgEditFormat format)
468 case MODEST_MSG_EDIT_FORMAT_TEXT:
470 case MODEST_MSG_EDIT_FORMAT_HTML:
471 g_message ("HTML format not supported in Gnome ModestMsgEditWindow");
478 ModestMsgEditFormatState *
479 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
481 ModestMsgEditFormatState *format_state;
483 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
485 format_state = g_new0 (ModestMsgEditFormatState, 1);
491 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
492 const ModestMsgEditFormatState *format_state)
494 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (self));
496 /* Ends silently as set_format_state should do nothing when edit window format
502 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
504 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
506 g_message ("Select color operation is not supported");
510 modest_msg_edit_window_select_file_format (ModestMsgEditWindow *window,
513 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
515 g_message ("Select file format operation is not supported");
519 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
521 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
523 g_message ("Select font operation is not supported");
527 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
529 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
531 g_message ("Select background color operation is not supported");
535 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
537 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
539 g_message ("Insert image operation is not supported");
543 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
545 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
547 g_message ("Attach file operation is not supported");
551 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
554 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
556 g_message ("Remove attachments operation is not supported");
560 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
563 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
565 g_message ("not implemented yet %s", __FUNCTION__);
568 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
573 g_message ("not implemented yet %s", __FUNCTION__);
576 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
578 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
580 g_message ("not implemented yet %s", __FUNCTION__);
583 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
585 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
587 g_message ("not implemented yet %s", __FUNCTION__);
590 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
591 TnyHeaderFlags priority_flags)
593 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
595 g_message ("not implemented yet %s", __FUNCTION__);
600 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
602 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
604 g_message ("not implemented yet %s", __FUNCTION__);
608 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
610 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
612 g_message ("not implemented yet %s", __FUNCTION__);
617 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
622 g_message ("not implemented yet %s", __FUNCTION__);
626 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
628 ModestMsgEditWindowPrivate *priv;
630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
635 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
638 ModestMsgEditWindowPrivate *priv;
640 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);