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 (conf, G_OBJECT(self), "modest-edit-msg-window");
140 restore_settings (ModestEditMsgWindow *self)
142 ModestEditMsgWindowPrivate *priv;
145 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
146 conf = modest_tny_platform_factory_get_modest_conf_instance (priv->fact);
148 modest_widget_memory_restore (conf, G_OBJECT(self), "modest-edit-msg-window");
154 on_menu_quit (ModestEditMsgWindow *self, guint action, GtkWidget *widget)
156 save_settings (self);
157 gtk_widget_destroy (GTK_WIDGET(self));
164 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
165 static GtkItemFactoryEntry menu_items[] = {
166 { "/_File", NULL, NULL, 0, "<Branch>" ,NULL},
167 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
168 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
169 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
170 { "/File/Save _As", NULL, NULL, 0, "<Item>", NULL} ,
171 { "/File/Save Draft", "<control><shift>S", NULL, 0, "<Item>",NULL },
174 { "/File/sep1", NULL, NULL, 0, "<Separator>" ,NULL },
175 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
177 { "/_Edit", NULL, NULL, 0, "<Branch>" ,NULL },
178 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
179 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
180 { "/File/sep1", NULL, NULL, 0, "<Separator>",NULL },
181 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
182 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
183 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
184 { "/Edit/sep1", NULL, NULL, 0, "<Separator>",NULL },
185 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" ,NULL },
186 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" ,NULL },
187 { "/Edit/Deselect all", "<Shift><CTRL>A", NULL, 0, "<Item>",NULL },
189 { "/_View", NULL, NULL, 0, "<Branch>",NULL },
190 { "/View/To-field", NULL, NULL, 0, "<CheckItem>",NULL },
192 { "/View/Cc-field:", NULL, NULL, 0, "<CheckItem>",NULL },
193 { "/View/Bcc-field:", NULL, NULL, 0, "<CheckItem>",NULL },
196 { "/_Insert", NULL, NULL, 0, "<Branch>",NULL },
197 /* { "/Actions/_Reply", NULL, NULL, 0, "<Item>" }, */
198 /* { "/Actions/_Forward", NULL, NULL, 0, "<Item>" }, */
199 /* { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" }, */
201 { "/_Format", NULL, NULL, 0, "<Branch>",NULL }
202 /* { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" }, */
203 /* { "/Options/_Contacts", NULL, NULL, 0, "<Item>" }, */
206 /* { "/_Help", NULL, NULL, 0, "<Branch>" }, */
207 /* { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT}, */
210 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
214 menubar_new (ModestEditMsgWindow *self)
216 GtkItemFactory *item_factory;
217 GtkAccelGroup *accel_group;
219 /* Make an accelerator group (shortcut keys) */
220 accel_group = gtk_accel_group_new ();
222 /* Make an ItemFactory (that makes a menubar) */
223 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
226 /* This function generates the menu items. Pass the item factory,
227 the number of items in the array, the array itself, and any
228 callback data for the the menu items. */
229 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
231 ///* Attach the new accelerator group to the window. */
232 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
234 /* Finally, return the actual menu bar created by the item factory. */
235 return gtk_item_factory_get_widget (item_factory, "<main>");
240 send_mail (ModestEditMsgWindow *self)
242 const gchar *to, *cc, *bcc, *subject;
244 ModestEditMsgWindowPrivate *priv;
245 TnyTransportAccount *transport_account;
246 ModestMailOperation *mail_operation;
247 ModestAccountData *data;
252 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
253 data = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
255 /* don't free these (except from) */
256 from = g_strdup_printf ("%s <%s>", data->full_name, data->email) ;
257 to = gtk_entry_get_text (GTK_ENTRY(priv->to_field));
258 cc = gtk_entry_get_text (GTK_ENTRY(priv->cc_field));
259 bcc = gtk_entry_get_text (GTK_ENTRY(priv->bcc_field));
260 subject = gtk_entry_get_text (GTK_ENTRY(priv->subject_field));
263 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
265 gtk_text_buffer_get_bounds (buf, &b, &e);
266 body = gtk_text_buffer_get_text (buf, &b, &e,
267 FALSE); /* free this one */
269 /* FIXME: Code added just for testing. The transport_account
270 should be provided by the account manager, maybe using
271 _get_current_account () or _get_default_account
272 (TRANSPORT_ACCOUNT). These methods do not exist currently. */
276 TnyAccountStore *account_store;
278 accounts = TNY_LIST(tny_simple_list_new ());
279 account_store = tny_platform_factory_new_account_store (priv->fact);
280 tny_account_store_get_accounts (account_store, accounts,
281 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
283 iter = tny_list_create_iterator(accounts);
284 tny_iterator_first (iter);
285 if (tny_iterator_is_done (iter)) {
286 /* FIXME: Add error handling through mail operation */
287 g_printerr("modest: no transport accounts defined\n");
291 transport_account = TNY_TRANSPORT_ACCOUNT (tny_iterator_get_current(iter));
294 mail_operation = modest_mail_operation_new ();
296 modest_mail_operation_send_new_mail (mail_operation,
299 subject, body, NULL);
301 g_object_unref (mail_operation);
308 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
309 ModestEditMsgWindow *self)
312 case MODEST_TOOLBAR_BUTTON_MAIL_SEND:
314 save_settings (self);
315 gtk_widget_destroy (GTK_WIDGET(self));
318 case MODEST_TOOLBAR_BUTTON_REPLY:
319 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
320 case MODEST_TOOLBAR_BUTTON_FORWARD:
321 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
322 case MODEST_TOOLBAR_BUTTON_NEXT:
323 case MODEST_TOOLBAR_BUTTON_PREV:
324 case MODEST_TOOLBAR_BUTTON_DELETE:
327 g_printerr ("modest: key %d pressed\n", button_id);
334 static ModestToolbar*
335 toolbar_new (ModestEditMsgWindow *self)
338 ModestToolbar *toolbar;
339 GSList *buttons = NULL;
340 ModestEditMsgWindowPrivate *priv;
342 ModestToolbarButton button_ids[] = {
343 MODEST_TOOLBAR_BUTTON_MAIL_SEND
346 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
348 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
349 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
351 toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
352 g_slist_free (buttons);
354 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
355 G_CALLBACK(on_toolbar_button_clicked), self);
362 init_window (ModestEditMsgWindow *obj)
364 GtkWidget *to_button, *cc_button, *bcc_button;
365 GtkWidget *header_table;
366 GtkWidget *main_vbox;
368 ModestEditMsgWindowPrivate *priv;
369 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
371 to_button = gtk_button_new_with_label (_("To..."));
372 cc_button = gtk_button_new_with_label (_("Cc..."));
373 bcc_button = gtk_button_new_with_label (_("Bcc..."));
375 priv->from_field = modest_widget_factory_get_combo_box (priv->factory,
376 MODEST_COMBO_BOX_TYPE_TRANSPORTS);
377 priv->to_field = gtk_entry_new_with_max_length (80);
378 priv->cc_field = gtk_entry_new_with_max_length (80);
379 priv->bcc_field = gtk_entry_new_with_max_length (80);
380 priv->subject_field = gtk_entry_new_with_max_length (80);
382 header_table = gtk_table_new (5,2, FALSE);
384 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
385 0,1,0,1, GTK_SHRINK, 0, 0, 0);
386 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,1,2, GTK_SHRINK, 0, 0, 0);
387 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,2,3, GTK_SHRINK, 0, 0, 0);
388 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,3,4, GTK_SHRINK, 0, 0, 0);
389 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
390 0,1,4,5, GTK_SHRINK, 0, 0, 0);
392 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field, 1,2,0,1);
393 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,1,2);
394 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,2,3);
395 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,3,4);
396 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
398 priv->msg_body = gtk_text_view_new ();
400 main_vbox = gtk_vbox_new (FALSE, 6);
402 priv->menubar = menubar_new (obj);
403 priv->toolbar = GTK_WIDGET(toolbar_new (obj));
405 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
406 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
407 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
408 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
410 gtk_widget_show_all (GTK_WIDGET(main_vbox));
411 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
417 modest_edit_msg_window_finalize (GObject *obj)
419 ModestEditMsgWindowPrivate *priv;
421 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
423 g_object_unref (G_OBJECT(priv->factory));
424 priv->factory = NULL;
426 G_OBJECT_CLASS(parent_class)->finalize (obj);
433 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
435 save_settings (self);
441 modest_edit_msg_window_new (ModestWidgetFactory *factory,
442 ModestEditType type, TnyMsg *msg)
445 ModestEditMsgWindowPrivate *priv;
447 g_return_val_if_fail (factory, NULL);
448 g_return_val_if_fail (type < MODEST_EDIT_TYPE_NUM, NULL);
449 g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL);
450 g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);
452 obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
453 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
455 g_object_ref (factory);
456 priv->factory = factory;
458 init_window (MODEST_EDIT_MSG_WINDOW(obj));
460 restore_settings (MODEST_EDIT_MSG_WINDOW(obj));
462 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
463 gtk_window_set_icon (GTK_WINDOW(obj),
464 modest_icon_factory_get_icon (MODEST_APP_ICON));
466 g_signal_connect (G_OBJECT(obj), "delete-event",
467 G_CALLBACK(on_delete_event), obj);
470 /* Testing code. Should be into a set_msg method */
474 header = tny_msg_get_header (msg);
475 gtk_entry_set_text (GTK_ENTRY(priv->to_field),
476 tny_header_get_to (header));
477 gtk_entry_set_text (GTK_ENTRY(priv->cc_field),
478 tny_header_get_cc (header));
479 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field),
480 tny_header_get_bcc (header));
481 gtk_entry_set_text (GTK_ENTRY(priv->subject_field),
482 tny_header_get_subject (header));
484 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
485 gtk_text_buffer_set_text (buf,
486 (const gchar *) modest_tny_msg_actions_find_body (msg, TRUE),
489 /* TODO: lower priority, select in the From: combo to
490 the value that comes from msg */
492 /* TODO: set attachments */
495 return GTK_WIDGET (obj);