70bcb2e3cc63ece6dda5b696524ecd8df7a27afc
[modest] / src / widgets / modest-header-view-render.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-header-view.h>
31 #include <modest-header-view-priv.h>
32 #include <modest-icon-names.h>
33 #include <modest-text-utils.h>
34 #include <modest-runtime.h>
35 #include <glib/gi18n.h>
36
37
38 static GdkPixbuf*
39 get_cached_icon (const gchar *name)
40 {
41         GError *err = NULL;
42         GdkPixbuf* pixbuf;
43                 
44 #ifdef MODEST_PLATFORM_GNOME  
45         pixbuf = gdk_pixbuf_new_from_file (name, &err);
46 #else
47         GtkIconTheme *current_theme;
48         current_theme = gtk_icon_theme_get_default ();
49         pixbuf = gtk_icon_theme_load_icon (current_theme,
50                                            name,
51                                            26,
52                                            GTK_ICON_LOOKUP_NO_SVG,
53                                            &err);
54 #endif /*MODEST_PLATFORM_GNOME*/
55
56         if (!pixbuf) {
57                 g_printerr ("modest: error in icon factory while loading '%s': %s\n",
58                             name, err->message);
59                 g_error_free (err);
60         }
61         
62         return pixbuf;
63 }
64
65
66 /*
67  * optimization
68  */
69 static GdkPixbuf*
70 get_pixbuf_for_flag (TnyHeaderFlags flag)
71 {
72         /* optimization */
73         static GdkPixbuf *deleted_pixbuf       = NULL;
74         static GdkPixbuf *seen_pixbuf          = NULL;
75         static GdkPixbuf *unread_pixbuf        = NULL;
76         static GdkPixbuf *attachments_pixbuf   = NULL;
77         
78         switch (flag) {
79         case TNY_HEADER_FLAG_DELETED:
80                 if (G_UNLIKELY(!deleted_pixbuf))
81                         deleted_pixbuf = get_cached_icon (MODEST_HEADER_ICON_DELETED);
82                 return deleted_pixbuf;
83         case TNY_HEADER_FLAG_SEEN:
84                 if (G_UNLIKELY(!seen_pixbuf))
85                         seen_pixbuf = get_cached_icon (MODEST_HEADER_ICON_READ);
86                 return seen_pixbuf;
87         case TNY_HEADER_FLAG_ATTACHMENTS:
88                 if (G_UNLIKELY(!attachments_pixbuf))
89                         attachments_pixbuf = get_cached_icon (MODEST_HEADER_ICON_ATTACH);
90                 return attachments_pixbuf;
91         default:
92                 if (G_UNLIKELY(!unread_pixbuf))
93                         unread_pixbuf = get_cached_icon (MODEST_HEADER_ICON_UNREAD);
94                 return unread_pixbuf;
95         }
96 }
97
98 static void
99 set_common_flags (GtkCellRenderer *renderer, TnyHeaderFlags flags)
100 {
101         g_object_set (G_OBJECT(renderer),
102                       "weight", (flags & TNY_HEADER_FLAG_SEEN) ? 400: 800,
103                       "strikethrough",  (flags & TNY_HEADER_FLAG_DELETED) ?  TRUE:FALSE,
104                       NULL);    
105 }
106
107
108 void
109 _modest_header_view_msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
110                    GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
111 {
112         TnyHeaderFlags flags;
113                 
114         gtk_tree_model_get (tree_model, iter, TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN,
115                             &flags, -1);
116
117         if (flags & TNY_HEADER_FLAG_DELETED)
118                 g_object_set (G_OBJECT (renderer), "pixbuf",
119                               get_pixbuf_for_flag (TNY_HEADER_FLAG_DELETED), NULL);           
120         else if (flags & TNY_HEADER_FLAG_SEEN)
121                 g_object_set (G_OBJECT (renderer), "pixbuf",
122                               get_pixbuf_for_flag (TNY_HEADER_FLAG_SEEN), NULL);              
123         else 
124                 g_object_set (G_OBJECT (renderer), "pixbuf",
125                               get_pixbuf_for_flag (0), NULL); /* ughh, FIXME */               
126 }
127
128 void
129 _modest_header_view_attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
130                                       GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
131 {
132         TnyHeaderFlags flags;
133
134         gtk_tree_model_get (tree_model, iter, TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN,
135                             &flags, -1);
136
137         if (flags & TNY_HEADER_FLAG_ATTACHMENTS)
138                 g_object_set (G_OBJECT (renderer), "pixbuf",
139                               get_pixbuf_for_flag (TNY_HEADER_FLAG_ATTACHMENTS),
140                               NULL);
141 }
142
143 void
144 _modest_header_view_header_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
145                   GtkTreeModel *tree_model,  GtkTreeIter *iter,  gpointer user_data)
146 {
147         TnyHeaderFlags flags;
148         
149         gtk_tree_model_get (tree_model, iter, TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN,
150                             &flags, -1);
151         set_common_flags (renderer, flags);
152 }
153
154
155 void
156 _modest_header_view_date_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
157                                      GtkTreeModel *tree_model,  GtkTreeIter *iter,
158                                      gpointer user_data)
159 {
160         TnyHeaderFlags flags;
161         guint date, date_col;
162         gchar *display_date;
163         gboolean received = GPOINTER_TO_INT(user_data);
164
165         if (received)
166                 date_col = TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN;
167         else
168                 date_col = TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN;
169
170         gtk_tree_model_get (tree_model, iter,
171                             TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
172                             date_col, &date,
173                             -1);
174
175         display_date = modest_text_utils_get_display_date (date);
176         g_object_set (G_OBJECT(renderer),
177                       "text",    display_date,
178                       NULL);
179
180         set_common_flags (renderer, flags);
181         g_free (display_date);
182 }
183
184
185 void
186 _modest_header_view_sender_receiver_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
187                             GtkTreeModel *tree_model,  GtkTreeIter *iter,  gboolean is_sender)
188 {
189         TnyHeaderFlags flags;
190         gchar *address;
191         gint sender_receiver_col;
192
193         if (is_sender)
194                 sender_receiver_col = TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN;
195         else
196                 sender_receiver_col = TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN;
197                 
198         gtk_tree_model_get (tree_model, iter,
199                             sender_receiver_col,  &address,
200                             TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
201                             -1);
202         
203         g_object_set (G_OBJECT(renderer),
204                       "text",
205                       modest_text_utils_get_display_address (address),
206                       NULL);
207         g_free (address);
208         set_common_flags (renderer, flags);
209 }
210 /*
211  * this for both incoming and outgoing mail, depending on the the user_data
212  * parameter. in the incoming case, show 'From' and 'Received date', in the
213  * outgoing case, show 'To' and 'Sent date'
214  */
215 void
216 _modest_header_view_compact_header_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
217                                                GtkTreeModel *tree_model,  GtkTreeIter *iter,  gpointer user_data)
218 {
219         GObject *rendobj;
220         TnyHeaderFlags flags;
221         gchar *address, *subject, *header, *display_date;
222         time_t date;
223         gboolean is_incoming;
224
225         is_incoming = GPOINTER_TO_INT(user_data); /* GPOINTER_TO_BOOLEAN is not available
226                                                    * in older versions of glib...*/
227
228         if (is_incoming)
229                 gtk_tree_model_get (tree_model, iter,
230                                     TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
231                                     TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN,  &address,
232                                     TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject,
233                                     TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date,   
234                                     -1);
235         else
236                 gtk_tree_model_get (tree_model, iter,
237                                     TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
238                                     TNY_GTK_HEADER_LIST_MODEL_TO_COLUMN,  &address,
239                                     TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject,
240                                     TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &date,   
241                                     -1);
242         
243         rendobj = G_OBJECT(renderer);
244         display_date = modest_text_utils_get_display_date (date);
245         header = g_strdup_printf ("%s %s\n%s",
246                                   modest_text_utils_get_display_address (address),
247                                   display_date, subject);
248         g_free (address);
249         g_free (subject);
250         g_free (display_date);
251         
252         g_object_set (G_OBJECT(renderer), "text", header, NULL);        
253         set_common_flags (renderer, flags);
254         
255         g_free (header);
256 }
257
258
259 void
260 _modest_header_view_size_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
261                                      GtkTreeModel *tree_model,  GtkTreeIter *iter,
262                                      gpointer user_data)
263 {
264         TnyHeaderFlags flags;
265         guint size;
266         gchar *size_str;
267         
268         gtk_tree_model_get (tree_model, iter,
269                            TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
270                            TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN, &size,
271                             -1);
272         
273         size_str = modest_text_utils_get_display_size (size);
274         
275         g_object_set (G_OBJECT(renderer), "text", size_str, NULL);
276         set_common_flags (renderer, flags);
277
278         g_free (size_str);
279  }