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 (TNY_ACCOUNT (transport_account));
298 modest_mail_operation_send_new_mail (mail_operation,
300 subject, body, NULL);
302 g_object_unref (mail_operation);
309 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
310 ModestEditMsgWindow *self)
313 case MODEST_TOOLBAR_BUTTON_MAIL_SEND:
315 save_settings (self);
316 gtk_widget_destroy (GTK_WIDGET(self));
319 case MODEST_TOOLBAR_BUTTON_REPLY:
320 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
321 case MODEST_TOOLBAR_BUTTON_FORWARD:
322 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
323 case MODEST_TOOLBAR_BUTTON_NEXT:
324 case MODEST_TOOLBAR_BUTTON_PREV:
325 case MODEST_TOOLBAR_BUTTON_DELETE:
328 g_printerr ("modest: key %d pressed\n", button_id);
335 static ModestToolbar*
336 toolbar_new (ModestEditMsgWindow *self)
339 ModestToolbar *toolbar;
340 GSList *buttons = NULL;
341 ModestEditMsgWindowPrivate *priv;
343 ModestToolbarButton button_ids[] = {
344 MODEST_TOOLBAR_BUTTON_MAIL_SEND
347 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
349 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
350 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
352 toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
353 g_slist_free (buttons);
355 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
356 G_CALLBACK(on_toolbar_button_clicked), self);
363 init_window (ModestEditMsgWindow *obj)
365 GtkWidget *to_button, *cc_button, *bcc_button;
366 GtkWidget *header_table;
367 GtkWidget *main_vbox;
369 ModestEditMsgWindowPrivate *priv;
370 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
372 to_button = gtk_button_new_with_label (_("To..."));
373 cc_button = gtk_button_new_with_label (_("Cc..."));
374 bcc_button = gtk_button_new_with_label (_("Bcc..."));
376 priv->from_field = modest_widget_factory_get_combo_box (priv->factory,
377 MODEST_COMBO_BOX_TYPE_TRANSPORTS);
378 priv->to_field = gtk_entry_new_with_max_length (40);
379 priv->cc_field = gtk_entry_new_with_max_length (40);
380 priv->bcc_field = gtk_entry_new_with_max_length (40);
381 priv->subject_field = gtk_entry_new_with_max_length (40);
383 header_table = gtk_table_new (5,2, FALSE);
385 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
386 0,1,0,1, GTK_SHRINK, 0, 0, 0);
387 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,1,2, GTK_SHRINK, 0, 0, 0);
388 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,2,3, GTK_SHRINK, 0, 0, 0);
389 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,3,4, GTK_SHRINK, 0, 0, 0);
390 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
391 0,1,4,5, GTK_SHRINK, 0, 0, 0);
393 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field, 1,2,0,1);
394 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,1,2);
395 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,2,3);
396 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,3,4);
397 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
399 priv->msg_body = gtk_text_view_new ();
401 main_vbox = gtk_vbox_new (FALSE, 6);
403 priv->menubar = menubar_new (obj);
404 priv->toolbar = GTK_WIDGET(toolbar_new (obj));
406 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
407 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
408 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
409 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
411 gtk_widget_show_all (GTK_WIDGET(main_vbox));
412 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
418 modest_edit_msg_window_finalize (GObject *obj)
420 ModestEditMsgWindowPrivate *priv;
422 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
424 g_object_unref (G_OBJECT(priv->factory));
425 priv->factory = NULL;
427 G_OBJECT_CLASS(parent_class)->finalize (obj);
434 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
436 save_settings (self);
442 modest_edit_msg_window_new (ModestWidgetFactory *factory,
443 ModestEditType type, TnyMsg *msg)
446 ModestEditMsgWindowPrivate *priv;
448 g_return_val_if_fail (factory, NULL);
449 g_return_val_if_fail (type < MODEST_EDIT_TYPE_NUM, NULL);
450 g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL);
451 g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);
453 obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
454 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
456 g_object_ref (factory);
457 priv->factory = factory;
459 init_window (MODEST_EDIT_MSG_WINDOW(obj));
461 restore_settings (MODEST_EDIT_MSG_WINDOW(obj));
463 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
464 gtk_window_set_icon (GTK_WINDOW(obj),
465 modest_icon_factory_get_icon (MODEST_APP_ICON));
467 g_signal_connect (G_OBJECT(obj), "delete-event",
468 G_CALLBACK(on_delete_event), obj);
471 /* Testing code. Should be into a set_msg method */
475 header = tny_msg_get_header (msg);
476 gtk_entry_set_text (GTK_ENTRY(priv->to_field),
477 tny_header_get_to (header));
478 gtk_entry_set_text (GTK_ENTRY(priv->cc_field),
479 tny_header_get_cc (header));
480 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field),
481 tny_header_get_bcc (header));
482 gtk_entry_set_text (GTK_ENTRY(priv->subject_field),
483 tny_header_get_subject (header));
485 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
486 gtk_text_buffer_set_text (buf,
487 (const gchar *) modest_tny_msg_actions_find_body (msg, FALSE),
490 /* TODO: lower priority, select in the From: combo to
491 the value that comes from msg */
493 /* TODO: set attachments */
496 return GTK_WIDGET (obj);