* add the new toolbar to main-window and edit-msg-window
[modest] / src / gtk2 / modest-edit-msg-window.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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.
16  *
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.
28  */
29
30 #include "modest-edit-msg-window.h"
31 #include <widgets/modest-msg-view.h>
32 #include <modest-widget-memory.h>
33 #include <modest-widget-factory.h>
34 #include "modest-icon-names.h"
35
36 static void  modest_edit_msg_window_class_init   (ModestEditMsgWindowClass *klass);
37 static void  modest_edit_msg_window_init         (ModestEditMsgWindow *obj);
38 static void  modest_edit_msg_window_finalize     (GObject *obj);
39
40 /* list my signals */
41 enum {
42         /* MY_SIGNAL_1, */
43         /* MY_SIGNAL_2, */
44         LAST_SIGNAL
45 };
46
47 typedef struct _ModestEditMsgWindowPrivate ModestEditMsgWindowPrivate;
48 struct _ModestEditMsgWindowPrivate {
49
50         ModestConf *conf;
51         ModestWidgetFactory *factory;
52         
53         GtkWidget      *toolbar, *menubar;
54         GtkWidget      *msg_body;
55         GtkWidget      *to_field, *cc_field, *bcc_field,
56                        *subject_field;
57 };
58 #define MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
59                                                     MODEST_TYPE_EDIT_MSG_WINDOW, \
60                                                     ModestEditMsgWindowPrivate))
61 /* globals */
62 static GtkWindowClass *parent_class = NULL;
63
64 /* uncomment the following if you have defined any signals */
65 /* static guint signals[LAST_SIGNAL] = {0}; */
66
67 GType
68 modest_edit_msg_window_get_type (void)
69 {
70         static GType my_type = 0;
71         if (!my_type) {
72                 static const GTypeInfo my_info = {
73                         sizeof(ModestEditMsgWindowClass),
74                         NULL,           /* base init */
75                         NULL,           /* base finalize */
76                         (GClassInitFunc) modest_edit_msg_window_class_init,
77                         NULL,           /* class finalize */
78                         NULL,           /* class data */
79                         sizeof(ModestEditMsgWindow),
80                         1,              /* n_preallocs */
81                         (GInstanceInitFunc) modest_edit_msg_window_init,
82                         NULL
83                 };
84                 my_type = g_type_register_static (GTK_TYPE_WINDOW,
85                                                   "ModestEditMsgWindow",
86                                                   &my_info, 0);
87         }
88         return my_type;
89 }
90
91 static void
92 modest_edit_msg_window_class_init (ModestEditMsgWindowClass *klass)
93 {
94         GObjectClass *gobject_class;
95         gobject_class = (GObjectClass*) klass;
96
97         parent_class            = g_type_class_peek_parent (klass);
98         gobject_class->finalize = modest_edit_msg_window_finalize;
99
100         g_type_class_add_private (gobject_class, sizeof(ModestEditMsgWindowPrivate));
101
102         /* signal definitions go here, e.g.: */
103 /*      signals[MY_SIGNAL_1] = */
104 /*              g_signal_new ("my_signal_1",....); */
105 /*      signals[MY_SIGNAL_2] = */
106 /*              g_signal_new ("my_signal_2",....); */
107 /*      etc. */
108 }
109
110 static void
111 modest_edit_msg_window_init (ModestEditMsgWindow *obj)
112 {
113         ModestEditMsgWindowPrivate *priv;
114         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
115
116         priv->factory = NULL;
117         priv->toolbar = NULL;
118         priv->menubar = NULL;
119                 
120 }
121
122
123
124
125 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
126 static GtkItemFactoryEntry menu_items[] = {
127         { "/_File",             NULL,                   NULL,           0, "<Branch>" },
128         { "/File/_New",         "<control>N",           NULL,           0, "<StockItem>", GTK_STOCK_NEW },
129         { "/File/_Open",        "<control>O",           NULL,           0, "<StockItem>", GTK_STOCK_OPEN },
130         { "/File/_Save",        "<control>S",           NULL,           0, "<StockItem>", GTK_STOCK_SAVE },
131         { "/File/Save _As",     NULL,                   NULL,           0, "<Item>" },
132         { "/File/Save Draft",   "<control><shift>S",    NULL,           0, "<Item>" },
133
134
135         { "/File/sep1",         NULL,                   NULL,           0, "<Separator>" },
136         { "/File/_Quit",        "<CTRL>Q",              NULL,           0, "<StockItem>", GTK_STOCK_QUIT },
137
138         { "/_Edit",             NULL,                   NULL,           0, "<Branch>" },
139         { "/Edit/_Undo",        "<CTRL>Z",              NULL,           0, "<StockItem>", GTK_STOCK_UNDO },
140         { "/Edit/_Redo",        "<shift><CTRL>Z",       NULL,           0, "<StockItem>", GTK_STOCK_REDO },
141         { "/File/sep1",         NULL,                   NULL,           0, "<Separator>" },
142         { "/Edit/Cut",          "<control>X",           NULL,           0, "<StockItem>", GTK_STOCK_CUT  },
143         { "/Edit/Copy",         "<CTRL>C",              NULL,           0, "<StockItem>", GTK_STOCK_COPY },
144         { "/Edit/Paste",        NULL,                   NULL,           0, "<StockItem>", GTK_STOCK_PASTE},
145         { "/Edit/sep1",         NULL,                   NULL,           0, "<Separator>" },
146         { "/Edit/Delete",       "<CTRL>Q",              NULL,           0, "<Item>" },
147         { "/Edit/Select all",   "<CTRL>A",              NULL,           0, "<Item>" },
148         { "/Edit/Deselect all",  "<Shift><CTRL>A",      NULL,           0, "<Item>" },
149
150         { "/_View",             NULL,           NULL,           0, "<Branch>" },
151         { "/View/To-field",          NULL,              NULL,           0, "<Item>" },
152         
153         { "/View/Cc-field:",          NULL,             NULL,           0, "<Item>" },
154         { "/View/Bcc-field:",          NULL,            NULL,           0, "<Item>" },
155         
156         
157         { "/_Insert",             NULL,         NULL,           0, "<Branch>" },
158 /*      { "/Actions/_Reply",    NULL,                   NULL,           0, "<Item>" }, */
159 /*      { "/Actions/_Forward",  NULL,                   NULL,           0, "<Item>" }, */
160 /*      { "/Actions/_Bounce",   NULL,                   NULL,           0, "<Item>" },   */
161         
162         { "/_Format",            NULL,                  NULL,           0, "<Branch>" }
163 /*      { "/Options/_Accounts",  NULL,                  on_menu_accounts,0, "<Item>" }, */
164 /*      { "/Options/_Contacts",  NULL,                  NULL,           0, "<Item>" }, */
165
166
167 /*      { "/_Help",         NULL,                       NULL,           0, "<Branch>" }, */
168 /*      { "/_Help/About",   NULL,                       on_menu_about,  0, "<StockItem>", GTK_STOCK_ABOUT}, */
169 };
170
171 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
172
173
174 static GtkWidget *
175 menubar_new (ModestEditMsgWindow *self)
176 {
177         GtkItemFactory *item_factory;
178         GtkAccelGroup *accel_group;
179         
180         /* Make an accelerator group (shortcut keys) */
181         accel_group = gtk_accel_group_new ();
182         
183         /* Make an ItemFactory (that makes a menubar) */
184         item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
185                                              accel_group);
186         
187         /* This function generates the menu items. Pass the item factory,
188            the number of items in the array, the array itself, and any
189            callback data for the the menu items. */
190         gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
191         
192         ///* Attach the new accelerator group to the window. */
193         gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
194         
195         /* Finally, return the actual menu bar created by the item factory. */
196         return gtk_item_factory_get_widget (item_factory, "<main>");
197 }
198
199
200
201
202 static ModestToolbar*
203 toolbar_new (ModestEditMsgWindow *self)
204 {
205         int i;
206         ModestToolbar *toolbar;
207         GSList *buttons = NULL;
208         ModestEditMsgWindowPrivate *priv;
209
210         ModestToolbarButton button_ids[] = {
211                 MODEST_TOOLBAR_BUTTON_MAIL_SEND
212         };              
213         
214         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
215
216         for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
217                 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
218         
219         toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
220         g_slist_free (buttons);
221         
222         return toolbar;
223 }
224
225
226 static void
227 init_window (ModestEditMsgWindow *obj)
228 {
229         GtkWidget *to_button, *cc_button, *bcc_button, *subject_label; 
230         GtkWidget *header_table;
231         GtkWidget *main_vbox;
232         
233         ModestEditMsgWindowPrivate *priv;
234         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
235
236         to_button     = gtk_button_new_with_label (_("To..."));
237         cc_button     = gtk_button_new_with_label (_("Cc..."));
238         bcc_button    = gtk_button_new_with_label (_("Bcc..."));
239         subject_label = gtk_label_new (_("Subject:"));
240         
241         priv->to_field      = gtk_entry_new_with_max_length (40);
242         priv->cc_field      = gtk_entry_new_with_max_length (40);
243         priv->bcc_field     = gtk_entry_new_with_max_length (40);
244         priv->subject_field = gtk_entry_new_with_max_length (40);
245
246         header_table = gtk_table_new (4,2, FALSE);
247         gtk_table_attach (GTK_TABLE(header_table), to_button,     0,1,0,1,
248                           GTK_SHRINK, 0, 0, 0);
249         gtk_table_attach (GTK_TABLE(header_table), cc_button,     0,1,1,2,
250                           GTK_SHRINK, 0, 0, 0);
251         gtk_table_attach (GTK_TABLE(header_table), bcc_button,    0,1,2,3,
252                           GTK_SHRINK, 0, 0, 0);
253         gtk_table_attach (GTK_TABLE(header_table), subject_label, 0,1,3,4,
254                           GTK_SHRINK, 0, 0, 0);
255  
256         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field,     1,2,0,1);
257         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field,     1,2,1,2);
258         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field,    1,2,2,3);
259         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,3,4);
260
261         priv->msg_body = gtk_text_view_new ();
262         
263         main_vbox = gtk_vbox_new  (FALSE, 6);
264
265         priv->menubar = menubar_new (obj);
266         priv->toolbar = GTK_WIDGET(toolbar_new (obj));
267
268         gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
269         gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
270         gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 0);
271         gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
272
273         gtk_widget_show_all (GTK_WIDGET(main_vbox));
274         gtk_container_add (GTK_CONTAINER(obj), main_vbox);
275 }
276         
277
278
279 static void
280 modest_edit_msg_window_finalize (GObject *obj)
281 {
282         ModestEditMsgWindowPrivate *priv;
283
284         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
285
286         g_object_unref (G_OBJECT(priv->conf));
287         priv->conf = NULL;
288
289         g_object_unref (G_OBJECT(priv->factory));
290         priv->factory = NULL;
291         
292         G_OBJECT_CLASS(parent_class)->finalize (obj);
293
294 }
295
296
297
298 static gboolean
299 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
300 {
301         ModestEditMsgWindowPrivate *priv;
302         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
303         
304         modest_widget_memory_save_settings (priv->conf,
305                                             GTK_WIDGET(priv->msg_body),
306                                             "modest-edit-msg-body");
307         return FALSE;
308 }
309
310
311 GtkWidget*
312 modest_edit_msg_window_new (ModestConf *conf, ModestWidgetFactory *factory,
313                             ModestEditType type, TnyMsgIface *msg)
314 {
315         GObject *obj;
316         ModestEditMsgWindowPrivate *priv;
317
318         g_return_val_if_fail (conf, NULL);
319         g_return_val_if_fail (factory, NULL);
320         g_return_val_if_fail (type >= 0 && type < MODEST_EDIT_TYPE_NUM, NULL);
321         g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL); 
322         g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);     
323         
324         obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
325         priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
326
327         g_object_ref (G_OBJECT(conf));
328         priv->conf = conf;
329
330         g_object_ref (factory);
331         priv->factory = factory;
332
333         init_window (obj);
334         
335         modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(obj),
336                                                "modest-edit-msg-body");
337         
338         gtk_window_set_title (GTK_WINDOW(obj), "Modest");
339         gtk_window_set_icon  (GTK_WINDOW(obj),
340                               modest_icon_factory_get_icon (MODEST_APP_ICON));
341
342         g_signal_connect (G_OBJECT(obj), "delete-event",
343                           G_CALLBACK(on_delete_event), obj);
344         
345         return GTK_WIDGET (obj);
346 }