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.
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"
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);
47 typedef struct _ModestEditMsgWindowPrivate ModestEditMsgWindowPrivate;
48 struct _ModestEditMsgWindowPrivate {
51 ModestWidgetFactory *factory;
53 GtkWidget *toolbar, *menubar;
55 GtkWidget *to_field, *cc_field, *bcc_field,
58 #define MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
59 MODEST_TYPE_EDIT_MSG_WINDOW, \
60 ModestEditMsgWindowPrivate))
62 static GtkWindowClass *parent_class = NULL;
64 /* uncomment the following if you have defined any signals */
65 /* static guint signals[LAST_SIGNAL] = {0}; */
68 modest_edit_msg_window_get_type (void)
70 static GType my_type = 0;
72 static const GTypeInfo my_info = {
73 sizeof(ModestEditMsgWindowClass),
75 NULL, /* base finalize */
76 (GClassInitFunc) modest_edit_msg_window_class_init,
77 NULL, /* class finalize */
78 NULL, /* class data */
79 sizeof(ModestEditMsgWindow),
81 (GInstanceInitFunc) modest_edit_msg_window_init,
84 my_type = g_type_register_static (GTK_TYPE_WINDOW,
85 "ModestEditMsgWindow",
92 modest_edit_msg_window_class_init (ModestEditMsgWindowClass *klass)
94 GObjectClass *gobject_class;
95 gobject_class = (GObjectClass*) klass;
97 parent_class = g_type_class_peek_parent (klass);
98 gobject_class->finalize = modest_edit_msg_window_finalize;
100 g_type_class_add_private (gobject_class, sizeof(ModestEditMsgWindowPrivate));
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",....); */
111 modest_edit_msg_window_init (ModestEditMsgWindow *obj)
113 ModestEditMsgWindowPrivate *priv;
114 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
116 priv->factory = NULL;
117 priv->toolbar = NULL;
118 priv->menubar = NULL;
124 save_settings (ModestEditMsgWindow *self)
126 ModestEditMsgWindowPrivate *priv;
127 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
128 modest_widget_memory_save_settings (priv->conf,
130 "modest-edit-msg-window");
135 restore_settings (ModestEditMsgWindow *self)
137 ModestEditMsgWindowPrivate *priv;
138 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
139 modest_widget_memory_restore_settings (priv->conf, GTK_WIDGET(self),
140 "modest-edit-msg-window");
148 on_menu_quit (ModestEditMsgWindow *self, guint action, GtkWidget *widget)
150 save_settings (self);
151 gtk_widget_destroy (GTK_WIDGET(self));
158 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
159 static GtkItemFactoryEntry menu_items[] = {
160 { "/_File", NULL, NULL, 0, "<Branch>" },
161 { "/File/_New", "<control>N", NULL, 0, "<StockItem>", GTK_STOCK_NEW },
162 { "/File/_Open", "<control>O", NULL, 0, "<StockItem>", GTK_STOCK_OPEN },
163 { "/File/_Save", "<control>S", NULL, 0, "<StockItem>", GTK_STOCK_SAVE },
164 { "/File/Save _As", NULL, NULL, 0, "<Item>" },
165 { "/File/Save Draft", "<control><shift>S", NULL, 0, "<Item>" },
168 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
169 { "/File/_Quit", "<CTRL>Q", on_menu_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
171 { "/_Edit", NULL, NULL, 0, "<Branch>" },
172 { "/Edit/_Undo", "<CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_UNDO },
173 { "/Edit/_Redo", "<shift><CTRL>Z", NULL, 0, "<StockItem>", GTK_STOCK_REDO },
174 { "/File/sep1", NULL, NULL, 0, "<Separator>" },
175 { "/Edit/Cut", "<control>X", NULL, 0, "<StockItem>", GTK_STOCK_CUT },
176 { "/Edit/Copy", "<CTRL>C", NULL, 0, "<StockItem>", GTK_STOCK_COPY },
177 { "/Edit/Paste", NULL, NULL, 0, "<StockItem>", GTK_STOCK_PASTE},
178 { "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
179 { "/Edit/Delete", "<CTRL>Q", NULL, 0, "<Item>" },
180 { "/Edit/Select all", "<CTRL>A", NULL, 0, "<Item>" },
181 { "/Edit/Deselect all", "<Shift><CTRL>A", NULL, 0, "<Item>" },
183 { "/_View", NULL, NULL, 0, "<Branch>" },
184 { "/View/To-field", NULL, NULL, 0, "<Item>" },
186 { "/View/Cc-field:", NULL, NULL, 0, "<Item>" },
187 { "/View/Bcc-field:", NULL, NULL, 0, "<Item>" },
190 { "/_Insert", NULL, NULL, 0, "<Branch>" },
191 /* { "/Actions/_Reply", NULL, NULL, 0, "<Item>" }, */
192 /* { "/Actions/_Forward", NULL, NULL, 0, "<Item>" }, */
193 /* { "/Actions/_Bounce", NULL, NULL, 0, "<Item>" }, */
195 { "/_Format", NULL, NULL, 0, "<Branch>" }
196 /* { "/Options/_Accounts", NULL, on_menu_accounts,0, "<Item>" }, */
197 /* { "/Options/_Contacts", NULL, NULL, 0, "<Item>" }, */
200 /* { "/_Help", NULL, NULL, 0, "<Branch>" }, */
201 /* { "/_Help/About", NULL, on_menu_about, 0, "<StockItem>", GTK_STOCK_ABOUT}, */
204 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
208 menubar_new (ModestEditMsgWindow *self)
210 GtkItemFactory *item_factory;
211 GtkAccelGroup *accel_group;
213 /* Make an accelerator group (shortcut keys) */
214 accel_group = gtk_accel_group_new ();
216 /* Make an ItemFactory (that makes a menubar) */
217 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
220 /* This function generates the menu items. Pass the item factory,
221 the number of items in the array, the array itself, and any
222 callback data for the the menu items. */
223 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, self);
225 ///* Attach the new accelerator group to the window. */
226 gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
228 /* Finally, return the actual menu bar created by the item factory. */
229 return gtk_item_factory_get_widget (item_factory, "<main>");
235 on_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id,
236 ModestEditMsgWindow *self)
239 case MODEST_TOOLBAR_BUTTON_MAIL_SEND:
240 save_settings (self);
241 gtk_widget_destroy (GTK_WIDGET(self));
244 case MODEST_TOOLBAR_BUTTON_REPLY:
245 case MODEST_TOOLBAR_BUTTON_REPLY_ALL:
246 case MODEST_TOOLBAR_BUTTON_FORWARD:
247 case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE:
248 case MODEST_TOOLBAR_BUTTON_NEXT:
249 case MODEST_TOOLBAR_BUTTON_PREV:
250 case MODEST_TOOLBAR_BUTTON_DELETE:
253 g_printerr ("modest: key %d pressed\n", button_id);
260 static ModestToolbar*
261 toolbar_new (ModestEditMsgWindow *self)
264 ModestToolbar *toolbar;
265 GSList *buttons = NULL;
266 ModestEditMsgWindowPrivate *priv;
268 ModestToolbarButton button_ids[] = {
269 MODEST_TOOLBAR_BUTTON_MAIL_SEND
272 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(self);
274 for (i = 0 ; i != sizeof(button_ids) / sizeof(ModestToolbarButton); ++i)
275 buttons = g_slist_append (buttons, GINT_TO_POINTER(button_ids[i]));
277 toolbar = modest_widget_factory_get_edit_toolbar (priv->factory, buttons);
278 g_slist_free (buttons);
280 g_signal_connect (G_OBJECT(toolbar), "button_clicked",
281 G_CALLBACK(on_toolbar_button_clicked), self);
288 init_window (ModestEditMsgWindow *obj)
290 GtkWidget *to_button, *cc_button, *bcc_button, *subject_label;
291 GtkWidget *header_table;
292 GtkWidget *main_vbox;
294 ModestEditMsgWindowPrivate *priv;
295 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
297 to_button = gtk_button_new_with_label (_("To..."));
298 cc_button = gtk_button_new_with_label (_("Cc..."));
299 bcc_button = gtk_button_new_with_label (_("Bcc..."));
300 subject_label = gtk_label_new (_("Subject:"));
302 priv->to_field = gtk_entry_new_with_max_length (40);
303 priv->cc_field = gtk_entry_new_with_max_length (40);
304 priv->bcc_field = gtk_entry_new_with_max_length (40);
305 priv->subject_field = gtk_entry_new_with_max_length (40);
307 header_table = gtk_table_new (4,2, FALSE);
308 gtk_table_attach (GTK_TABLE(header_table), to_button, 0,1,0,1,
309 GTK_SHRINK, 0, 0, 0);
310 gtk_table_attach (GTK_TABLE(header_table), cc_button, 0,1,1,2,
311 GTK_SHRINK, 0, 0, 0);
312 gtk_table_attach (GTK_TABLE(header_table), bcc_button, 0,1,2,3,
313 GTK_SHRINK, 0, 0, 0);
314 gtk_table_attach (GTK_TABLE(header_table), subject_label, 0,1,3,4,
315 GTK_SHRINK, 0, 0, 0);
317 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field, 1,2,0,1);
318 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field, 1,2,1,2);
319 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field, 1,2,2,3);
320 gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,3,4);
322 priv->msg_body = gtk_text_view_new ();
324 main_vbox = gtk_vbox_new (FALSE, 6);
326 priv->menubar = menubar_new (obj);
327 priv->toolbar = GTK_WIDGET(toolbar_new (obj));
329 gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
330 gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
331 gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 0);
332 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
334 gtk_widget_show_all (GTK_WIDGET(main_vbox));
335 gtk_container_add (GTK_CONTAINER(obj), main_vbox);
341 modest_edit_msg_window_finalize (GObject *obj)
343 ModestEditMsgWindowPrivate *priv;
345 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
347 g_object_unref (G_OBJECT(priv->conf));
350 g_object_unref (G_OBJECT(priv->factory));
351 priv->factory = NULL;
353 G_OBJECT_CLASS(parent_class)->finalize (obj);
360 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestEditMsgWindow *self)
362 save_settings (self);
368 modest_edit_msg_window_new (ModestConf *conf, ModestWidgetFactory *factory,
369 ModestEditType type, TnyMsgIface *msg)
372 ModestEditMsgWindowPrivate *priv;
374 g_return_val_if_fail (conf, NULL);
375 g_return_val_if_fail (factory, NULL);
376 g_return_val_if_fail (type >= 0 && type < MODEST_EDIT_TYPE_NUM, NULL);
377 g_return_val_if_fail (!(type==MODEST_EDIT_TYPE_NEW && msg), NULL);
378 g_return_val_if_fail (!(type!=MODEST_EDIT_TYPE_NEW && !msg), NULL);
380 obj = g_object_new(MODEST_TYPE_EDIT_MSG_WINDOW, NULL);
381 priv = MODEST_EDIT_MSG_WINDOW_GET_PRIVATE(obj);
383 g_object_ref (G_OBJECT(conf));
386 g_object_ref (factory);
387 priv->factory = factory;
389 init_window (MODEST_EDIT_MSG_WINDOW(obj));
391 restore_settings (MODEST_EDIT_MSG_WINDOW(obj));
393 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
394 gtk_window_set_icon (GTK_WINDOW(obj),
395 modest_icon_factory_get_icon (MODEST_APP_ICON));
397 g_signal_connect (G_OBJECT(obj), "delete-event",
398 G_CALLBACK(on_delete_event), obj);
400 return GTK_WIDGET (obj);