* Add a new dialog, Sort Dialog (WID-DIA021).
[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         gint sort_colid;
261         GtkSortType sort_type;
262         
263         folder = modest_header_view_get_folder (header_view);
264         if (!folder || modest_header_view_is_empty (header_view))
265                 return TRUE; /* no non-empty folder: no settings */
266         
267         type  = modest_tny_folder_guess_folder_type (folder);
268         style = modest_header_view_get_style   (header_view);
269         
270         key = _modest_widget_memory_get_keyname_with_double_type (name, type, style,
271                                                                   MODEST_WIDGET_MEMORY_PARAM_COLUMN_WIDTH);
272
273         cursor = cols = modest_header_view_get_columns (header_view);
274         str = g_string_new (NULL);
275
276         /* NOTE: the exact details of this format are important, as they
277          * are also used in modest-init.
278          */
279         sort_colid = modest_header_view_get_sort_column_id (header_view, type); 
280         sort_type = modest_header_view_get_sort_type (header_view, type); 
281         while (cursor) {
282
283                 int col_id, width, sort;
284                 GtkTreeViewColumn *col;
285                 
286                 col    = GTK_TREE_VIEW_COLUMN (cursor->data);
287                 col_id = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col),
288                                                             MODEST_HEADER_VIEW_COLUMN));
289                 width = gtk_tree_view_column_get_width (col);
290                 sort = 0;
291                 if (sort_colid == col_id)
292                         sort = (sort_type == GTK_SORT_ASCENDING) ? 1:-1;
293                         
294                 g_string_append_printf (str, "%d:%d:%d ", col_id, width, sort);
295                 cursor = g_list_next (cursor);
296         }
297
298         modest_conf_set_string (conf, key, str->str, NULL);
299
300         g_free (key);   
301         g_string_free (str, TRUE);
302         g_list_free (cols);
303         g_object_unref (G_OBJECT (folder));
304         
305         return TRUE;
306 }
307
308
309 static gboolean
310 restore_settings_header_view (ModestConf *conf, ModestHeaderView *header_view,
311                               const gchar *name)
312 {
313         guint col, width;
314         gint sort;
315         gchar *key;
316         TnyFolder *folder;
317         TnyFolderType type;
318         ModestHeaderViewStyle style;
319
320         folder = modest_header_view_get_folder (header_view);
321         if (!folder || modest_header_view_is_empty (header_view))
322                 return TRUE; /* no non-empty folder: no settings */
323         
324         type = modest_tny_folder_guess_folder_type (folder);
325         style = modest_header_view_get_style   (header_view);
326
327         key = _modest_widget_memory_get_keyname_with_double_type (name, type, style,
328                                                                   MODEST_WIDGET_MEMORY_PARAM_COLUMN_WIDTH);
329         if (modest_conf_key_exists (conf, key, NULL)) {
330                 
331                 gchar *data, *cursor;
332                 GList *cols = NULL;
333                 GList *colwidths = NULL;
334                 GList *colsortables = NULL;
335                 GtkTreeModel *sortable;
336
337                 cursor = data = modest_conf_get_string (conf, key, NULL);
338                 while (cursor && sscanf (cursor, "%d:%d:%d ", &col, &width, &sort) == 3) {
339                         cols      = g_list_append (cols, GINT_TO_POINTER(col));
340                         colwidths = g_list_append (colwidths, GINT_TO_POINTER(width));
341                         colsortables = g_list_append (colsortables, GINT_TO_POINTER(sort));
342                         cursor = strchr (cursor + 1, ' ');
343                 }
344                 g_free (data);  
345                 
346                 if (cols) {
347                         GList *viewcolumns, *colcursor, *widthcursor, *sortablecursor;
348                         modest_header_view_set_columns (header_view, cols, type);
349                         sortable = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
350
351                         widthcursor = colwidths;
352                         sortablecursor = colsortables;
353                         colcursor = viewcolumns = gtk_tree_view_get_columns (GTK_TREE_VIEW(header_view));
354                         while (colcursor && widthcursor && sortablecursor) {
355                                 int width = GPOINTER_TO_INT(widthcursor->data);
356                                 int sort = GPOINTER_TO_INT(sortablecursor->data);
357                                 if (width > 0)
358                                         gtk_tree_view_column_set_max_width(GTK_TREE_VIEW_COLUMN(colcursor->data),
359                                                                            width);
360                                 if (sort != 0) {
361                                         int colid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(colcursor->data), MODEST_HEADER_VIEW_COLUMN));
362                                         GtkSortType sort_type = (sort == 1) ? GTK_SORT_ASCENDING : GTK_SORT_DESCENDING; 
363                                         modest_header_view_set_sort_params (header_view, colid, sort_type, type);
364                                         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
365                                                                               colid,
366                                                                               sort_type);
367                                         gtk_tree_sortable_sort_column_changed (GTK_TREE_SORTABLE(sortable));
368                                 }
369                                 colcursor = g_list_next (colcursor);
370                                 widthcursor = g_list_next (widthcursor);
371                                 sortablecursor = g_list_next (sortablecursor);
372                         }
373
374                         g_list_free (cols);
375                         g_list_free (colwidths);
376                         g_list_free (colsortables);
377                         g_list_free (viewcolumns);
378                 }
379         }
380
381         g_free (key);
382         g_object_unref (G_OBJECT (folder));
383
384         return TRUE;
385 }
386
387
388
389 static gboolean
390 save_settings_folder_view (ModestConf *conf, ModestFolderView *folder_view,
391                            const gchar *name)
392 {
393         return TRUE; /* FIXME: implement this */
394 }
395
396 static gboolean
397 restore_settings_folder_view (ModestConf *conf, ModestFolderView *folder_view,
398                               const gchar *name)
399 {
400         return TRUE; /* FIXME: implement this */
401 }
402
403
404 static gboolean
405 save_settings_msg_view (ModestConf *conf, ModestMsgView *msg_view,
406                            const gchar *name)
407 {
408         return TRUE; /* FIXME: implement this */
409 }
410
411 static gboolean
412 restore_settings_msg_view (ModestConf *conf, ModestMsgView *msg_view,
413                               const gchar *name)
414 {
415         return TRUE; /* FIXME: implement this */
416 }
417
418
419
420 gboolean
421 modest_widget_memory_save (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 save_settings_window (conf, GTK_WINDOW(widget), name);
429         else if (GTK_IS_PANED(widget))
430                 return save_settings_paned (conf, GTK_PANED(widget), name);
431         else if (MODEST_IS_HEADER_VIEW(widget))
432                 return save_settings_header_view (conf, MODEST_HEADER_VIEW(widget), name);
433         else if (MODEST_IS_FOLDER_VIEW(widget))
434                 return save_settings_folder_view (conf, MODEST_FOLDER_VIEW(widget), name);
435         else if (MODEST_IS_MSG_VIEW(widget))
436                 return save_settings_msg_view (conf, MODEST_MSG_VIEW(widget), name);
437         else if (GTK_IS_WIDGET(widget))
438                 return save_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 }
443
444
445
446 gboolean
447 modest_widget_memory_restore (ModestConf *conf, GObject *widget, const gchar *name)
448 {
449         g_return_val_if_fail (conf, FALSE);
450         g_return_val_if_fail (widget, FALSE);
451         g_return_val_if_fail (name, FALSE);
452         
453         if (GTK_IS_WINDOW(widget))
454                 return restore_settings_window (conf, GTK_WINDOW(widget), name);
455         else if (GTK_IS_PANED(widget))
456                 return restore_settings_paned (conf, GTK_PANED(widget), name);
457         else if (MODEST_IS_HEADER_VIEW(widget))
458                 return restore_settings_header_view (conf, MODEST_HEADER_VIEW(widget), name);
459         else if (MODEST_IS_FOLDER_VIEW(widget))
460                 return restore_settings_folder_view (conf, MODEST_FOLDER_VIEW(widget), name);
461         else if (MODEST_IS_MSG_VIEW(widget))
462                 return restore_settings_msg_view (conf, MODEST_MSG_VIEW(widget), name);
463         else if (GTK_IS_WIDGET(widget))
464                 return restore_settings_widget (conf, GTK_WIDGET(widget), name);
465         
466         g_printerr ("modest: %p (%s) is not a known widget\n", widget, name);
467         return FALSE;
468 }