* src/modest-ui-actions.[ch]:
[modest] / src / maemo / modest-msg-view-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 #include <glib/gi18n.h>
30 #include <string.h>
31 #include <tny-account-store.h>
32 #include <tny-simple-list.h>
33 #include <modest-tny-msg.h>
34 #include <modest-msg-view-window.h>
35 #include <modest-main-window-ui.h>
36 #include <modest-widget-memory.h>
37 #include <modest-runtime.h>
38 #include <modest-window-priv.h>
39
40 static void  modest_msg_view_window_class_init   (ModestMsgViewWindowClass *klass);
41 static void  modest_msg_view_window_init         (ModestMsgViewWindow *obj);
42 static void  modest_msg_view_window_finalize     (GObject *obj);
43
44 /* list my signals */
45 enum {
46         /* MY_SIGNAL_1, */
47         /* MY_SIGNAL_2, */
48         LAST_SIGNAL
49 };
50
51 typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate;
52 struct _ModestMsgViewWindowPrivate {
53
54         GtkWidget   *toolbar;
55         GtkWidget   *menubar;
56         GtkWidget   *msg_view;
57 };
58
59 #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
60                                                     MODEST_TYPE_MSG_VIEW_WINDOW, \
61                                                     ModestMsgViewWindowPrivate))
62 /* globals */
63 static GtkWindowClass *parent_class = NULL;
64
65 /* uncomment the following if you have defined any signals */
66 /* static guint signals[LAST_SIGNAL] = {0}; */
67
68 GType
69 modest_msg_view_window_get_type (void)
70 {
71         static GType my_type = 0;
72         if (!my_type) {
73                 static const GTypeInfo my_info = {
74                         sizeof(ModestMsgViewWindowClass),
75                         NULL,           /* base init */
76                         NULL,           /* base finalize */
77                         (GClassInitFunc) modest_msg_view_window_class_init,
78                         NULL,           /* class finalize */
79                         NULL,           /* class data */
80                         sizeof(ModestMsgViewWindow),
81                         1,              /* n_preallocs */
82                         (GInstanceInitFunc) modest_msg_view_window_init,
83                         NULL
84                 };
85                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
86                                                   "ModestMsgViewWindow",
87                                                   &my_info, 0);
88         }
89         return my_type;
90 }
91
92 static void
93 modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
94 {
95         GObjectClass *gobject_class;
96         gobject_class = (GObjectClass*) klass;
97
98         parent_class            = g_type_class_peek_parent (klass);
99         gobject_class->finalize = modest_msg_view_window_finalize;
100
101         g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate));
102 }
103
104 static void
105 modest_msg_view_window_init (ModestMsgViewWindow *obj)
106 {
107         ModestMsgViewWindowPrivate *priv;
108         priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
109
110         priv->toolbar       = NULL;
111         priv->menubar       = NULL;
112         priv->msg_view      = NULL;
113 }
114
115 static void
116 save_settings (ModestMsgViewWindow *self)
117 {
118         modest_widget_memory_save (modest_runtime_get_conf (),
119                                     G_OBJECT(self), "modest-msg-view-window");
120 }
121
122
123 static void
124 restore_settings (ModestMsgViewWindow *self)
125 {
126         modest_widget_memory_restore (modest_runtime_get_conf (),
127                                       G_OBJECT(self), "modest-msg-view-window");
128 }
129
130
131
132 static GtkWidget *
133 menubar_to_menu (GtkUIManager *ui_manager)
134 {
135         GtkWidget *main_menu;
136         GtkWidget *menubar;
137         GList *iter;
138
139         /* Create new main menu */
140         main_menu = gtk_menu_new();
141
142         /* Get the menubar from the UI manager */
143         menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
144
145         iter = gtk_container_get_children (GTK_CONTAINER (menubar));
146         while (iter) {
147                 GtkWidget *menu;
148
149                 menu = GTK_WIDGET (iter->data);
150                 gtk_widget_reparent(menu, main_menu);
151
152                 iter = g_list_next (iter);
153         }
154         return main_menu;
155 }
156
157
158 static void
159 init_window (ModestMsgViewWindow *obj, TnyMsg *msg)
160 {
161         GtkWidget *main_vbox;
162         ModestMsgViewWindowPrivate *priv;
163         ModestWindowPrivate *parent_priv;
164         GtkWidget *scrolled_window;
165         
166         priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
167         parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
168
169         priv->msg_view = modest_msg_view_new (msg);
170         modest_msg_view_set_shadow_type (MODEST_MSG_VIEW (priv->msg_view), GTK_SHADOW_NONE);
171         main_vbox = gtk_vbox_new  (FALSE, 6);
172
173         /* Toolbar / Menubar */
174         
175         parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
176         gtk_widget_show_all (GTK_WIDGET(parent_priv->menubar));
177         hildon_window_set_menu    (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar));
178
179         parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
180         gtk_widget_show_all (GTK_WIDGET(parent_priv->toolbar));
181         hildon_window_add_toolbar (HILDON_WINDOW(obj), GTK_TOOLBAR(parent_priv->toolbar));
182
183         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
184         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
185         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_NONE);
186
187         gtk_container_add (GTK_CONTAINER (scrolled_window), priv->msg_view);
188         gtk_box_pack_start (GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 6);
189         gtk_container_add   (GTK_CONTAINER(obj), main_vbox);
190         
191         gtk_widget_show_all (GTK_WIDGET(main_vbox));
192 }       
193
194
195 static void
196 modest_msg_view_window_finalize (GObject *obj)
197 {
198         G_OBJECT_CLASS(parent_class)->finalize (obj);
199 }
200
201
202
203 static gboolean
204 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgViewWindow *self)
205 {
206         save_settings (self);
207         return FALSE;
208 }
209
210
211
212 ModestWindow *
213 modest_msg_view_window_new (TnyMsg *msg, const gchar *account_name)
214 {
215         GObject *obj;
216         ModestMsgViewWindowPrivate *priv;
217         ModestWindowPrivate *parent_priv;
218         GtkActionGroup *action_group;
219         GError *error = NULL;
220
221         g_return_val_if_fail (msg, NULL);
222         
223         obj = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
224         priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
225         parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
226         
227         parent_priv->ui_manager = gtk_ui_manager_new();
228         action_group = gtk_action_group_new ("ModestMsgViewWindowActions");
229
230         /* Add common actions */
231         gtk_action_group_add_actions (action_group,
232                                       modest_action_entries,
233                                       G_N_ELEMENTS (modest_action_entries),
234                                       obj);
235         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
236         g_object_unref (action_group);
237
238         /* Load the UI definition */
239         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-view-window-ui.xml",
240                                          &error);
241         if (error) {
242                 g_printerr ("modest: could not merge modest-msg-view-window-ui.xml: %s\n", error->message);
243                 g_error_free (error);
244                 error = NULL;
245         }
246         /* ****** */
247
248         /* Add accelerators */
249         gtk_window_add_accel_group (GTK_WINDOW (obj), 
250                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
251         
252         /* Init window */
253         init_window (MODEST_MSG_VIEW_WINDOW(obj), msg);
254         restore_settings (MODEST_MSG_VIEW_WINDOW(obj));
255         
256         gtk_window_set_title (GTK_WINDOW(obj), "Modest");
257         gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
258
259         g_signal_connect (G_OBJECT(obj), "delete-event", G_CALLBACK(on_delete_event), obj);
260
261         g_signal_connect (G_OBJECT(priv->msg_view), "link_clicked",
262                           G_CALLBACK (modest_ui_actions_on_msg_link_clicked), obj);
263         g_signal_connect (G_OBJECT(priv->msg_view), "link_hover",
264                           G_CALLBACK (modest_ui_actions_on_msg_link_hover), obj);
265         g_signal_connect (G_OBJECT(priv->msg_view), "attachment_clicked",
266                           G_CALLBACK (modest_ui_actions_on_msg_attachment_clicked), obj);
267         g_signal_connect (G_OBJECT(priv->msg_view), "recpt-activate",
268                           G_CALLBACK (modest_ui_actions_on_msg_recpt_activated), obj);
269
270         modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
271         return MODEST_WINDOW(obj);
272 }
273
274
275
276 TnyMsg*
277 modest_msg_view_window_get_message (ModestMsgViewWindow *self)
278 {
279         ModestMsgView *msg_view;
280         ModestMsgViewWindowPrivate *priv;
281
282         g_return_val_if_fail (self, NULL);
283
284         priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
285
286         msg_view = MODEST_MSG_VIEW (priv->msg_view);
287
288         return modest_msg_view_get_message (msg_view);
289 }