2a05e83cfa7c480a1f2b805336cbe0f81327564c
[modest] / src / modest-widget-memory.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-widget-memory.h>
31 #include <modest-widget-memory-priv.h>
32
33 #include <modest-tny-platform-factory.h>
34 #include <modest-tny-folder.h>
35 #include <widgets/modest-header-view.h>
36 #include <widgets/modest-msg-view.h>
37 #include <widgets/modest-folder-view.h>
38 #include "widgets/modest-main-window.h"
39 #include <string.h>
40
41 gchar*
42 _modest_widget_memory_get_keyname (const gchar *name, const gchar *param)
43 {
44         gchar *esc_name, *keyname;
45
46         g_return_val_if_fail (name, NULL);
47         g_return_val_if_fail (param, NULL);
48         
49         esc_name = modest_conf_key_escape (name);
50
51         keyname = g_strdup_printf ("%s/%s/%s",
52                                    MODEST_CONF_WIDGET_NAMESPACE, 
53                                    esc_name, param);
54         g_free (esc_name);
55         return keyname;
56 }
57
58
59 gchar*
60 _modest_widget_memory_get_keyname_with_type (const gchar *name, guint type,
61                                              const gchar *param)
62 {
63         gchar *esc_name, *keyname;
64         
65         g_return_val_if_fail (name, NULL);
66         g_return_val_if_fail (param, NULL);
67
68         esc_name = modest_conf_key_escape (name);
69
70         keyname = g_strdup_printf ("%s/%s/%s_%d",
71                                    MODEST_CONF_WIDGET_NAMESPACE, 
72                                    esc_name, param, type);
73         g_free (esc_name);
74         return keyname;
75 }
76
77
78 gchar*
79 _modest_widget_memory_get_keyname_with_double_type (const gchar *name,
80                                                     guint type1, guint type2,
81                                                     const gchar *param)
82 {
83         gchar *esc_name, *keyname;
84         
85         g_return_val_if_fail (name, NULL);
86         g_return_val_if_fail (param, NULL);
87
88         esc_name = modest_conf_key_escape (name);
89
90         keyname = g_strdup_printf ("%s/%s/%s_%d_%d",
91                                    MODEST_CONF_WIDGET_NAMESPACE, 
92                                    esc_name, param, type1, type2);
93         g_free (esc_name);
94         return keyname;
95 }
96
97
98
99 static gboolean
100 save_settings_widget (ModestConf *conf, GtkWidget *widget, const gchar *name)
101 {
102         gchar *key;
103
104         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_HEIGHT);
105         modest_conf_set_int (conf, key, GTK_WIDGET(widget)->allocation.height, NULL);
106         g_free (key);
107         
108         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WIDTH);
109         modest_conf_set_int (conf, key, GTK_WIDGET(widget)->allocation.width, NULL);
110         g_free (key);
111
112         return TRUE;
113 }
114
115
116 static gboolean
117 restore_settings_widget (ModestConf *conf, GtkWidget *widget, const gchar *name)
118 {
119         GtkRequisition req;
120         gchar *key;
121
122         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_HEIGHT);
123         
124         if (modest_conf_key_exists (conf, key, NULL))
125                 req.height = modest_conf_get_int (conf, key, NULL);
126
127         g_free (key);
128         
129         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WIDTH);
130         if (modest_conf_key_exists (conf, key, NULL))
131                 req.width = modest_conf_get_int (conf, key, NULL);
132         g_free (key);
133
134         if (req.height && req.width) 
135                 gtk_widget_size_request (widget, &req);
136
137         return TRUE;
138
139 }
140
141
142
143 static gboolean
144 save_settings_window (ModestConf *conf, GtkWindow *win, const gchar *name)
145 {
146         gchar *key;
147         int height, width;
148         
149         gtk_window_get_size (win, &width, &height);
150         
151         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_HEIGHT);
152         modest_conf_set_int (conf, key, height, NULL);
153         g_free (key);
154         
155         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WIDTH);
156         modest_conf_set_int (conf, key, width, NULL);
157         g_free (key);
158
159         /* Save also the main window style */
160         if (MODEST_IS_MAIN_WINDOW (win)) {
161                 ModestMainWindowStyle style = modest_main_window_get_style (MODEST_MAIN_WINDOW (win));
162
163                 key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WINDOW_STYLE);
164                 modest_conf_set_int (conf, key, style, NULL);
165                 g_free (key);
166         }
167         
168         return TRUE;
169 }
170
171
172 static gboolean
173 restore_settings_window (ModestConf *conf, GtkWindow *win, const gchar *name)
174 {
175         gchar *key;
176         int height = 0, width = 0;
177
178         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_HEIGHT);
179         
180         if (modest_conf_key_exists (conf, key, NULL))
181                 height = modest_conf_get_int (conf, key, NULL);
182
183         g_free (key);
184
185         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WIDTH);
186         if (modest_conf_key_exists (conf, key, NULL))
187                 width = modest_conf_get_int (conf, key, NULL);
188
189         g_free (key);
190
191         /* Added this ugly ifdef, because in Maemo the
192            gtk_window_set_default_size() makes "drag-motion" signal
193            report bad coordinates, so drag-and-drop do not work
194            properly */
195 #ifdef MODEST_PLATFORM_GNOME
196         if (height && width)
197                 gtk_window_set_default_size (win, width, height);
198 #endif
199
200         /* Restore also the main window style */
201         if (MODEST_IS_MAIN_WINDOW (win)) {
202                 ModestMainWindowStyle style;
203
204                 key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_WINDOW_STYLE);
205                 if (modest_conf_key_exists (conf, key, NULL)) {
206                         style = (ModestMainWindowStyle) modest_conf_get_int (conf, key, NULL);          
207                         modest_main_window_set_style (MODEST_MAIN_WINDOW (win), style);
208                         g_free (key);
209                 }
210         }
211
212         return TRUE;
213 }
214
215
216 static gboolean
217 save_settings_paned (ModestConf *conf, GtkPaned *paned, const gchar *name)
218 {
219         gchar *key;
220         int pos;
221
222         pos = gtk_paned_get_position (paned);
223         
224         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_POS);
225         modest_conf_set_int (conf, key, pos, NULL);
226         g_free (key);
227         
228         return TRUE;
229 }
230
231
232 static gboolean
233 restore_settings_paned (ModestConf *conf, GtkPaned *paned, const gchar *name)
234 {
235         gchar *key;
236         int pos;
237         
238         key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_POS);
239         
240         if (modest_conf_key_exists (conf, key, NULL)) {
241                 pos = modest_conf_get_int (conf, key, NULL);
242                 gtk_paned_set_position (paned, pos);
243         }
244
245         g_free (key);
246         return TRUE;
247 }
248
249
250 static gboolean
251 save_settings_header_view (ModestConf *conf, ModestHeaderView *header_view,
252                            const gchar *name)
253 {
254         gchar *key;
255         GString *str;
256         GList *cols, *cursor;
257         TnyFolder *folder;
258         TnyFolderType type;
259         ModestHeaderViewStyle style;
260
261         folder = modest_header_view_get_folder (header_view);
262         if (!folder || modest_header_view_is_empty (header_view))
263                 return TRUE; /* no non-empty folder: no settings */
264         
265         type  = modest_tny_folder_guess_folder_type (folder);
266         style = modest_header_view_get_style   (header_view);
267         
268         key = _modest_widget_memory_get_keyname_with_double_type (name, type, style,
269                                                                   MODEST_WIDGET_MEMORY_PARAM_COLUMN_WIDTH);
270
271         cursor = cols = modest_header_view_get_columns (header_view);
272         str = g_string_new (NULL);
273
274         /* NOTE: the exact details of this format are important, as they
275          * are also used in modest-init.
276          */
277         while (cursor) {
278
279                 int col_id, width;
280                 GtkTreeViewColumn *col;
281                 
282                 col    = GTK_TREE_VIEW_COLUMN (cursor->data);
283                 col_id = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col),
284                                                             MODEST_HEADER_VIEW_COLUMN));
285                 width = gtk_tree_view_column_get_width (col);
286                 
287                 g_string_append_printf (str, "%d:%d ", col_id, width);
288                 cursor = g_list_next (cursor);
289         }
290
291         modest_conf_set_string (conf, key, str->str, NULL);
292
293         g_free (key);   
294         g_string_free (str, TRUE);
295         g_list_free (cols);
296         g_object_unref (G_OBJECT (folder));
297         
298         return TRUE;
299 }
300
301
302 static gboolean
303 restore_settings_header_view (ModestConf *conf, ModestHeaderView *header_view,
304                               const gchar *name)
305 {
306         gchar *key;
307         TnyFolder *folder;
308         TnyFolderType type;
309         ModestHeaderViewStyle style;
310
311         folder = modest_header_view_get_folder (header_view);
312         if (!folder || modest_header_view_is_empty (header_view))
313                 return TRUE; /* no non-empty folder: no settings */
314         
315         type = modest_tny_folder_guess_folder_type (folder);
316         style = modest_header_view_get_style   (header_view);
317
318         key = _modest_widget_memory_get_keyname_with_double_type (name, type, style,
319                                                                   MODEST_WIDGET_MEMORY_PARAM_COLUMN_WIDTH);
320         if (modest_conf_key_exists (conf, key, NULL)) {
321                 
322                 gchar *data, *cursor;
323                 guint col, width;
324                 GList *cols = NULL;
325                 GList *colwidths = NULL;
326         
327                 cursor = data = modest_conf_get_string (conf, key, NULL);
328                 while (cursor && sscanf (cursor, "%u:%u ", &col, &width) == 2) {
329                         cols      = g_list_append (cols, GINT_TO_POINTER(col));
330                         colwidths = g_list_append (colwidths, GINT_TO_POINTER(width));
331                         cursor = strchr (cursor + 1, ' ');
332                 }
333                 g_free (data);  
334                 
335                 if (cols) {
336                         GList *viewcolumns, *colcursor, *widthcursor;
337                         modest_header_view_set_columns (header_view, cols);
338
339                         widthcursor = colwidths;
340                         colcursor = viewcolumns = gtk_tree_view_get_columns (GTK_TREE_VIEW(header_view));
341                         while (colcursor && widthcursor) {
342                                 int width = GPOINTER_TO_INT(widthcursor->data);
343                                 if (width > 0)
344                                         gtk_tree_view_column_set_max_width(GTK_TREE_VIEW_COLUMN(colcursor->data),
345                                                                            width);
346                                 colcursor = g_list_next (colcursor);
347                                 widthcursor = g_list_next (widthcursor);
348                         }
349                         g_list_free (cols);
350                         g_list_free (colwidths);
351                         g_list_free (viewcolumns);
352                 }
353         }
354
355         g_free (key);
356         g_object_unref (G_OBJECT (folder));
357
358         return TRUE;
359 }
360
361
362
363 static gboolean
364 save_settings_folder_view (ModestConf *conf, ModestFolderView *folder_view,
365                            const gchar *name)
366 {
367         return TRUE; /* FIXME: implement this */
368 }
369
370 static gboolean
371 restore_settings_folder_view (ModestConf *conf, ModestFolderView *folder_view,
372                               const gchar *name)
373 {
374         return TRUE; /* FIXME: implement this */
375 }
376
377
378 static gboolean
379 save_settings_msg_view (ModestConf *conf, ModestMsgView *msg_view,
380                            const gchar *name)
381 {
382         return TRUE; /* FIXME: implement this */
383 }
384
385 static gboolean
386 restore_settings_msg_view (ModestConf *conf, ModestMsgView *msg_view,
387                               const gchar *name)
388 {
389         return TRUE; /* FIXME: implement this */
390 }
391
392
393
394 gboolean
395 modest_widget_memory_save (ModestConf *conf, GObject *widget, const gchar *name)
396 {
397         g_return_val_if_fail (conf, FALSE);
398         g_return_val_if_fail (widget, FALSE);
399         g_return_val_if_fail (name, FALSE);
400
401         if (GTK_IS_WINDOW(widget))
402                 return save_settings_window (conf, GTK_WINDOW(widget), name);
403         else if (GTK_IS_PANED(widget))
404                 return save_settings_paned (conf, GTK_PANED(widget), name);
405         else if (MODEST_IS_HEADER_VIEW(widget))
406                 return save_settings_header_view (conf, MODEST_HEADER_VIEW(widget), name);
407         else if (MODEST_IS_FOLDER_VIEW(widget))
408                 return save_settings_folder_view (conf, MODEST_FOLDER_VIEW(widget), name);
409         else if (MODEST_IS_MSG_VIEW(widget))
410                 return save_settings_msg_view (conf, MODEST_MSG_VIEW(widget), name);
411         else if (GTK_IS_WIDGET(widget))
412                 return save_settings_widget (conf, GTK_WIDGET(widget), name);
413         
414         g_printerr ("modest: %p (%s) is not a known widget\n", widget, name);   
415         return FALSE;
416 }
417
418
419
420 gboolean
421 modest_widget_memory_restore (ModestConf *conf, GObject *widget, const gchar *name)
422 {
423         g_return_val_if_fail (conf, FALSE);
424         g_return_val_if_fail (widget, FALSE);
425         g_return_val_if_fail (name, FALSE);
426         
427         if (GTK_IS_WINDOW(widget))
428                 return restore_settings_window (conf, GTK_WINDOW(widget), name);
429         else if (GTK_IS_PANED(widget))
430                 return restore_settings_paned (conf, GTK_PANED(widget), name);
431         else if (MODEST_IS_HEADER_VIEW(widget))
432                 return restore_settings_header_view (conf, MODEST_HEADER_VIEW(widget), name);
433         else if (MODEST_IS_FOLDER_VIEW(widget))
434                 return restore_settings_folder_view (conf, MODEST_FOLDER_VIEW(widget), name);
435         else if (MODEST_IS_MSG_VIEW(widget))
436                 return restore_settings_msg_view (conf, MODEST_MSG_VIEW(widget), name);
437         else if (GTK_IS_WIDGET(widget))
438                 return restore_settings_widget (conf, GTK_WIDGET(widget), name);
439         
440         g_printerr ("modest: %p (%s) is not a known widget\n", widget, name);
441         return FALSE;
442 }