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>
30 #include <tny-account-store.h>
31 #include "modest-edit-msg-window.h"
32 #include "modest-widget-memory.h"
33 #include "modest-mail-operation.h"
34 #include "modest-tny-platform-factory.h"
35 #include "modest-tny-msg-actions.h"
36 #include <tny-simple-list.h>
38 static void modest_edit_msg_window_class_init (ModestEditMsgWindowClass *klass);
39 static void modest_edit_msg_window_init (ModestEditMsgWindow *obj);
40 static void modest_edit_msg_window_finalize (GObject *obj);
49 typedef struct _ModestEditMsgWindowPrivate ModestEditMsgWindowPrivate;
50 struct _ModestEditMsgWindowPrivate {
52 ModestWidgetFactory *factory;
53 TnyPlatformFactory *fact;
55 GtkWidget *toolbar, *menubar;
57 GtkWidget *from_field, *to_field, *cc_field, *bcc_field,
60 #define MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
61 MODEST_TYPE_EDIT_MSG_WINDOW, \
62 ModestEditMsgWindowPrivate))
64 static GtkWindowClass *parent_class = NULL;
66 /* uncomment the following if you have defined any signals */
67 /* static guint signals[LAST_SIGNAL] = {0}; */
70 modest_edit_msg_window_get_type (void)
72 static GType my_type = 0;
74 static const GTypeInfo my_info = {
75 sizeof(ModestEditMsgWindowClass),
77 NULL, /* base finalize */
78 (GClassInitFunc) modest_edit_msg_window_class_init,
79 NULL, /* class finalize */
80 NULL, /* class data */
81 sizeof(ModestEditMsgWindow),
83 (GInstanceInitFunc) modest_edit_msg_window_init,
86 my_type = g_type_register_static (GTK_TYPE_WINDOW,
87 "ModestEditMsgWindow",
94 modest_edit_msg_window_class_init (ModestEditMsgWindowClass *klass)
96 GObjectClass *gobject_class;
97 gobject_class = (GObjectClass*) klass;
99 parent_class = g_type_class_peek_parent (klass);
100 gobject_class->finalize = modest_edit_msg_window_finalize;
102 g_type_class_add_private (gobject_class, sizeof(ModestEditMsgWindowPrivate));
104 /* signal definitions go here, e.g.: */
105 /* signals[MY_SIGNAL_1] = */
106 /* g_signal_new ("my_signal_1",....); */
107 /* signals[MY_SIGNAL_2] = */
108 /* g_signal_new ("my_signal_2",....); */
113 modest_edit_msg_window_init (ModestEditMsgWindow *obj)
115 ModestEditMsgWindowPrivate *priv;
116 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
118 priv->fact = modest_tny_platform_factory_get_instance ();
119 priv->factory = NULL;
120 priv->toolbar = NULL;
121 priv->menubar = NULL;
127 save_settings (ModestEditMsgWindow *self)
129 ModestEditMsgWindowPrivate *priv;
132 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
133 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->fact);
135 modest_widget_memory_save_settings (conf, GTK_WIDGET(self),
136 "modest-edit-msg-window");
141 restore_settings (ModestEditMsgWindow *self)
143 ModestEditMsgWindowPrivate *priv;
146 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
147 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->fact);
149 modest_widget_memory_restore_settings (conf, GTK_WIDGET(self),
150 "modest-edit-msg-window");
156 on_menu_quit (ModestEditMsgWindow *self, guint action, GtkWidget *widget)
158 save_settings (self);
159 gtk_widget_destroy (GTK_WIDGET(self));
166 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
167 static GtkItemFactoryEntry menu_items[] = {
168 { "/_File", NULL, NULL, 0, "<Branch>" ,NULL},
169 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
170 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
171 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
172 { "/File/Save _As", NULL, NULL, 0, "<Item>", NULL} ,
173 { "/File/Save Draft", "<control><shift>S", NULL, 0, "<Item>",NULL },
176 { "/File/sep1", NULL, NULL, 0, "<Separator>" ,NULL },
177 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
179 { "/_Edit", NULL, NULL, 0, "<Branch>" ,NULL },
180 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
181 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
182 { "/File/sep1", NULL, NULL, 0, "<Separator>",NULL },
183 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
184 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
185 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
186 { "/Edit/sep1", NULL, NULL, 0, "<Separator>",NULL },
187 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" ,NULL },
188 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" ,NULL },
189 { "/Edit/Deselect all", "<Shift><CTRL>A", NULL, 0, "<Item>",NULL },
191 { "/_View", NULL, NULL, 0, "<Branch>",NULL },
192 { "/View/To-field", NULL, NULL, 0, "<CheckItem>",NULL },
194 { "/View/Cc-field:", NULL, NULL, 0, "<CheckItem>",NULL },
195 { "/View/Bcc-field:", NULL, NULL, 0, "<CheckItem>",NULL },
198 { "/_Insert", NULL, NULL, 0, "<Branch>",NULL },
199 /* { "/Actions/_Reply", NULL, NULL, 0, "<Item>" }, */
200 /* { "/Actions/_Forward", NULL, NULL, 0, "<Item>" }, */
201 /* { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" }, */
203 { "/_Format", NULL, NULL, 0, "<Branch>",NULL }
204 /* { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" }, */
205 /* { "/Options/_Contacts", NULL, NULL, 0, "<Item>" }, */
208 /* { "/_Help", NULL, NULL, 0, "<Branch>" }, */
209 /* { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT}, */
212 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
216 menubar_new (ModestEditMsgWindow *self)
218 GtkItemFactory *item_factory;
219 GtkAccelGroup *accel_group;
221 /* Make an accelerator group (shortcut keys) */
222 accel_group = gtk_accel_group_new ();
224 /* Make an ItemFactory (that makes a menubar) */
225 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
228 /* This function generates the menu items. Pass the item factory,
229 the number of items in the array, the array itself, and any
230 callback data for the the menu items. */
231 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
233 ///* Attach the new accelerator group to the window. */
234 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
236 /* Finally, return the actual menu bar created by the item factory. */
237 return gtk_item_factory_get_widget (item_factory, "<main>");
242 send_mail (ModestEditMsgWindow *self)
244 const gchar *to, *cc, *bcc, *subject;
246 ModestEditMsgWindowPrivate *priv;
247 TnyTransportAccount *transport_account;
248 ModestMailOperation *mail_operation;
249 ModestAccountData *data;
254 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
255 data = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
257 /* don't free these (except from) */
258 from = g_strdup_printf ("%s <%s>", data->full_name, data->email) ;
259 to = gtk_entry_get_text (GTK_ENTRY(priv->to_field));
260 cc = gtk_entry_get_text (GTK_ENTRY(priv->cc_field));
261 bcc = gtk_entry_get_text (GTK_ENTRY(priv->bcc_field));
262 subject = gtk_entry_get_text (GTK_ENTRY(priv->subject_field));
265 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
267 gtk_text_buffer_get_bounds (buf, &b, &e);
268 body = gtk_text_buffer_get_text (buf, &b, &e,
269 FALSE); /* free this one */
271 /* FIXME: Code added just for testing. The transport_account
272 should be provided by the account manager, maybe using
273 _get_current_account () or _get_default_account
274 (TRANSPORT_ACCOUNT). These methods do not exist currently. */
278 TnyAccountStore *account_store;
280 accounts = TNY_LIST(tny_simple_list_new ());
281 account_store = tny_platform_factory_new_account_store (priv->fact);
282 tny_account_store_get_accounts (account_store, accounts,
283 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
285 iter = tny_list_create_iterator(accounts);
286 tny_iterator_first (iter);
287 if (tny_iterator_is_done (iter)) {
288 /* FIXME: Add error handling through mail operation */
289 g_printerr("modest: no transport accounts defined\n");
293 transport_account = TNY_TRANSPORT_ACCOUNT (tny_iterator_get_current(iter));
296 mail_operation = modest_mail_operation_new ();
298 modest_mail_operation_send_new_mail (mail_operation,
301 subject, body, NULL);
303 g_object_unref (mail_operation);
310 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
311 ModestEditMsgWindow *self)
314 case MODEST_TOOLBAR_BUTTON_MAIL_SEND:
316 save_settings (self);
317 gtk_widget_destroy (GTK_WIDGET(self));
320 case MODEST_TOOLBAR_BUTTON_REPLY:
321 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
322 case MODEST_TOOLBAR_BUTTON_FORWARD:
323 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
324 case MODEST_TOOLBAR_BUTTON_NEXT:
325 case MODEST_TOOLBAR_BUTTON_PREV:
326 case MODEST_TOOLBAR_BUTTON_DELETE:
329 g_printerr ("modest: key %d pressed\n", button_id);
336 static ModestToolbar*
337 toolbar_new (ModestEditMsgWindow *self)
340 ModestToolbar *toolbar;
341 GSList *buttons = NULL;
342 ModestEditMsgWindowPrivate *priv;
344 ModestToolbarButton button_ids[] = {
345 MODEST_TOOLBAR_BUTTON_MAIL_SEND
348 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
350 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
351 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
353 toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
354 g_slist_free (buttons);
356 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
357 G_CALLBACK(on_toolbar_button_clicked), self);
364 init_window (ModestEditMsgWindow *obj)
366 GtkWidget *to_button, *cc_button, *bcc_button;
367 GtkWidget *header_table;
368 GtkWidget *main_vbox;
370 ModestEditMsgWindowPrivate *priv;
371 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
373 to_button = gtk_button_new_with_label (_("To..."));
374 cc_button = gtk_button_new_with_label (_("Cc..."));
375 bcc_button = gtk_button_new_with_label (_("Bcc..."));
377 priv->from_field = modest_widget_factory_get_combo_box (priv->factory,
378 MODEST_COMBO_BOX_TYPE_TRANSPORTS);
379 priv->to_field = gtk_entry_new_with_max_length (40);
380 priv->cc_field = gtk_entry_new_with_max_length (40);
381 priv->bcc_field = gtk_entry_new_with_max_length (40);
382 priv->subject_field = gtk_entry_new_with_max_length (40);
384 header_table = gtk_table_new (5,2, FALSE);
386 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
387 0,1,0,1, GTK_SHRINK, 0, 0, 0);
388 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,1,2, GTK_SHRINK, 0, 0, 0);
389 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,2,3, GTK_SHRINK, 0, 0, 0);
390 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,3,4, GTK_SHRINK, 0, 0, 0);
391 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
392 0,1,4,5, GTK_SHRINK, 0, 0, 0);
394 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field, 1,2,0,1);
395 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,1,2);
396 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,2,3);
397 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,3,4);
398 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
400 priv->msg_body = gtk_text_view_new ();
402 main_vbox = gtk_vbox_new (FALSE, 6);
404 priv->menubar = menubar_new (obj);
405 priv->toolbar = GTK_WIDGET(toolbar_new (obj));
407 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
408 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
409 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
410 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
412 gtk_widget_show_all (GTK_WIDGET(main_vbox));
413 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
419 modest_edit_msg_window_finalize (GObject *obj)
421 ModestEditMsgWindowPrivate *priv;
423 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
425 g_object_unref (G_OBJECT(priv->factory));
426 priv->factory = NULL;
428 G_OBJECT_CLASS(parent_class)->finalize (obj);
435 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
437 save_settings (self);
443 modest_edit_msg_window_new (ModestWidgetFactory *factory,
444 ModestEditType type, TnyMsg *msg)
447 ModestEditMsgWindowPrivate *priv;
449 g_return_val_if_fail (factory, NULL);
450 g_return_val_if_fail (type < MODEST_EDIT_TYPE_NUM, NULL);
451 g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL);
452 g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);
454 obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
455 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
457 g_object_ref (factory);
458 priv->factory = factory;
460 init_window (MODEST_EDIT_MSG_WINDOW(obj));
462 restore_settings (MODEST_EDIT_MSG_WINDOW(obj));
464 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
465 gtk_window_set_icon (GTK_WINDOW(obj),
466 modest_icon_factory_get_icon (MODEST_APP_ICON));
468 g_signal_connect (G_OBJECT(obj), "delete-event",
469 G_CALLBACK(on_delete_event), obj);
472 /* Testing code. Should be into a set_msg method */
476 header = tny_msg_get_header (msg);
477 gtk_entry_set_text (GTK_ENTRY(priv->to_field),
478 tny_header_get_to (header));
479 gtk_entry_set_text (GTK_ENTRY(priv->cc_field),
480 tny_header_get_cc (header));
481 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field),
482 tny_header_get_bcc (header));
483 gtk_entry_set_text (GTK_ENTRY(priv->subject_field),
484 tny_header_get_subject (header));
486 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
487 gtk_text_buffer_set_text (buf,
488 (const gchar *) modest_tny_msg_actions_find_body (msg, TRUE),
491 /* TODO: lower priority, select in the From: combo to
492 the value that comes from msg */
494 /* TODO: set attachments */
497 return GTK_WIDGET (obj);