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 *from, *to, *cc, *bcc, *subject;
246 ModestEditMsgWindowPrivate *priv;
247 TnyTransportAccount *transport_account;
248 ModestMailOperation *mail_operation;
253 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
255 /* don't free these */
256 from = "djcb@djcbsoftware.nl";
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 (TNY_ACCOUNT (transport_account));
296 modest_mail_operation_send_new_mail (mail_operation,
298 subject, body, NULL);
300 g_object_unref (mail_operation);
306 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
307 ModestEditMsgWindow *self)
310 case MODEST_TOOLBAR_BUTTON_MAIL_SEND:
312 save_settings (self);
313 gtk_widget_destroy (GTK_WIDGET(self));
316 case MODEST_TOOLBAR_BUTTON_REPLY:
317 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
318 case MODEST_TOOLBAR_BUTTON_FORWARD:
319 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
320 case MODEST_TOOLBAR_BUTTON_NEXT:
321 case MODEST_TOOLBAR_BUTTON_PREV:
322 case MODEST_TOOLBAR_BUTTON_DELETE:
325 g_printerr ("modest: key %d pressed\n", button_id);
332 static ModestToolbar*
333 toolbar_new (ModestEditMsgWindow *self)
336 ModestToolbar *toolbar;
337 GSList *buttons = NULL;
338 ModestEditMsgWindowPrivate *priv;
340 ModestToolbarButton button_ids[] = {
341 MODEST_TOOLBAR_BUTTON_MAIL_SEND
344 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
346 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
347 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
349 toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
350 g_slist_free (buttons);
352 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
353 G_CALLBACK(on_toolbar_button_clicked), self);
360 init_window (ModestEditMsgWindow *obj)
362 GtkWidget *to_button, *cc_button, *bcc_button;
363 GtkWidget *header_table;
364 GtkWidget *main_vbox;
366 ModestEditMsgWindowPrivate *priv;
367 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
369 to_button = gtk_button_new_with_label (_("To..."));
370 cc_button = gtk_button_new_with_label (_("Cc..."));
371 bcc_button = gtk_button_new_with_label (_("Bcc..."));
373 priv->from_field = modest_widget_factory_get_combo_box (priv->factory,
374 MODEST_COMBO_BOX_TYPE_TRANSPORTS);
375 priv->to_field = gtk_entry_new_with_max_length (40);
376 priv->cc_field = gtk_entry_new_with_max_length (40);
377 priv->bcc_field = gtk_entry_new_with_max_length (40);
378 priv->subject_field = gtk_entry_new_with_max_length (40);
380 header_table = gtk_table_new (5,2, FALSE);
382 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
383 0,1,0,1, GTK_SHRINK, 0, 0, 0);
384 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,1,2, GTK_SHRINK, 0, 0, 0);
385 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,2,3, GTK_SHRINK, 0, 0, 0);
386 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,3,4, GTK_SHRINK, 0, 0, 0);
387 gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
388 0,1,4,5, GTK_SHRINK, 0, 0, 0);
390 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field, 1,2,0,1);
391 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,1,2);
392 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,2,3);
393 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,3,4);
394 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
396 priv->msg_body = gtk_text_view_new ();
398 main_vbox = gtk_vbox_new (FALSE, 6);
400 priv->menubar = menubar_new (obj);
401 priv->toolbar = GTK_WIDGET(toolbar_new (obj));
403 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
404 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
405 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
406 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
408 gtk_widget_show_all (GTK_WIDGET(main_vbox));
409 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
415 modest_edit_msg_window_finalize (GObject *obj)
417 ModestEditMsgWindowPrivate *priv;
419 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
421 g_object_unref (G_OBJECT(priv->factory));
422 priv->factory = NULL;
424 G_OBJECT_CLASS(parent_class)->finalize (obj);
431 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
433 save_settings (self);
439 modest_edit_msg_window_new (ModestWidgetFactory *factory,
440 ModestEditType type, TnyMsg *msg)
443 ModestEditMsgWindowPrivate *priv;
445 g_return_val_if_fail (factory, NULL);
446 g_return_val_if_fail (type < MODEST_EDIT_TYPE_NUM, NULL);
447 g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL);
448 g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);
450 obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
451 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
453 g_object_ref (factory);
454 priv->factory = factory;
456 init_window (MODEST_EDIT_MSG_WINDOW(obj));
458 restore_settings (MODEST_EDIT_MSG_WINDOW(obj));
460 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
461 gtk_window_set_icon (GTK_WINDOW(obj),
462 modest_icon_factory_get_icon (MODEST_APP_ICON));
464 g_signal_connect (G_OBJECT(obj), "delete-event",
465 G_CALLBACK(on_delete_event), obj);
468 /* Testing code. Should be into a set_msg method */
472 header = tny_msg_get_header (msg);
473 gtk_entry_set_text (GTK_ENTRY(priv->to_field),
474 tny_header_get_to (header));
475 gtk_entry_set_text (GTK_ENTRY(priv->cc_field),
476 tny_header_get_cc (header));
477 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field),
478 tny_header_get_bcc (header));
479 gtk_entry_set_text (GTK_ENTRY(priv->subject_field),
480 tny_header_get_subject (header));
482 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
483 gtk_text_buffer_set_text (buf,
484 (const gchar *) modest_tny_msg_actions_find_body (msg, FALSE),
488 return GTK_WIDGET (obj);