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