* speed up modest_account_mgr_has_accounts by caching the status
[modest] / src / modest-email-clipboard.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-email-clipboard.h>
31 #include <modest-tny-folder.h>
32
33 /* 'private'/'protected' functions */
34 static void modest_email_clipboard_class_init (ModestEmailClipboardClass * klass);
35 static void modest_email_clipboard_init       (ModestEmailClipboard * obj);
36 static void modest_email_clipboard_finalize   (GObject * obj);
37
38 /* globals */
39 static GObjectClass *parent_class = NULL;
40
41 typedef struct _ModestEmailClipboardPrivate ModestEmailClipboardPrivate;
42 struct _ModestEmailClipboardPrivate {
43         TnyList    *selection;
44         TnyFolder  *src;        
45         gchar      **hidding;
46         gboolean   delete;
47 };
48
49
50 #define MODEST_EMAIL_CLIPBOARD_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
51                                                 MODEST_TYPE_EMAIL_CLIPBOARD, \
52                                                 ModestEmailClipboardPrivate))
53
54
55 GType
56 modest_email_clipboard_get_type (void)
57 {
58         static GType my_type = 0;
59
60         if (!my_type) {
61                 static const GTypeInfo my_info = {
62                         sizeof (ModestEmailClipboardClass),
63                         NULL,   /* base init */
64                         NULL,   /* base finalize */
65                         (GClassInitFunc) modest_email_clipboard_class_init,
66                         NULL,   /* class finalize */
67                         NULL,   /* class data */
68                         sizeof (ModestEmailClipboard),
69                         1,      /* n_preallocs */
70                         (GInstanceInitFunc) modest_email_clipboard_init,
71                         NULL
72                 };
73
74                 my_type = g_type_register_static (G_TYPE_OBJECT,
75                                                   "ModestEmailClipboard",
76                                                   &my_info, 0);
77         }
78         return my_type;
79 }
80
81
82
83 static void
84 modest_email_clipboard_class_init (ModestEmailClipboardClass * klass)
85 {
86         GObjectClass *gobject_class;
87         gobject_class = (GObjectClass *) klass;
88
89         parent_class = g_type_class_peek_parent (klass);
90         gobject_class->finalize = modest_email_clipboard_finalize;
91
92         g_type_class_add_private (gobject_class,
93                                   sizeof (ModestEmailClipboardPrivate));
94
95         /* signal definitions */
96 }
97
98
99 static void
100 modest_email_clipboard_init (ModestEmailClipboard * obj)
101 {
102         ModestEmailClipboardPrivate *priv =
103                 MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (obj);
104         
105         priv->src = NULL;
106         priv->selection = NULL;
107         priv->hidding = NULL;
108         priv->delete = FALSE;
109 }
110
111 static void
112 modest_email_clipboard_finalize (GObject * obj)
113 {
114         /* Clear objects stored on clipboard */
115         modest_email_clipboard_clear (MODEST_EMAIL_CLIPBOARD(obj));             
116
117         G_OBJECT_CLASS(parent_class)->finalize (obj);
118 }
119
120
121 ModestEmailClipboard *
122 modest_email_clipboard_new (void)
123 {
124         GObject *obj;
125         obj = G_OBJECT (g_object_new (MODEST_TYPE_EMAIL_CLIPBOARD, NULL));
126         
127         return MODEST_EMAIL_CLIPBOARD (obj);
128 }
129
130
131 void
132 modest_email_clipboard_get_data (ModestEmailClipboard *self,
133                                  TnyFolder **src_folder,
134                                  TnyList **data,
135                                  gboolean *delete)
136 {
137         ModestEmailClipboardPrivate *priv = NULL;;
138
139         *src_folder = NULL;
140         *data = NULL;
141         *delete = FALSE;
142
143         g_return_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self));
144         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
145         g_return_if_fail (TNY_IS_FOLDER (priv->src));
146
147         /* if no data into clipboard, do nothing */
148         if (modest_email_clipboard_cleared (self)) return;
149                 
150         /* Get data stored on clipboard */
151         *src_folder = g_object_ref(priv->src);
152         if (priv->selection)
153                 *data = g_object_ref(priv->selection);
154         *delete = priv->delete;
155
156         /* Clear objects stored on clipboard */
157         modest_email_clipboard_clear (MODEST_EMAIL_CLIPBOARD(self));            
158 }
159
160 void
161 modest_email_clipboard_set_data (ModestEmailClipboard *self,
162                                  TnyFolder *src_folder, 
163                                  TnyList *data,
164                                  gboolean delete)
165 {
166         ModestEmailClipboardPrivate *priv = NULL;;
167         TnyIterator *iter = NULL;
168         GObject *obj = NULL;                    
169         gchar *id = NULL;
170         guint i, n_selected;
171
172         g_return_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self));
173         g_return_if_fail (TNY_IS_FOLDER (src_folder));
174         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
175
176         /* if data into clipboard, clear them  */
177         if (!modest_email_clipboard_cleared (self)) 
178                 modest_email_clipboard_clear (self);
179         
180         /* set new data */
181         priv->src = g_object_ref (src_folder);
182         if (data != NULL)
183                 priv->selection = g_object_ref (data);
184         priv->delete = delete;
185         priv->hidding = NULL;
186
187         /* Fill hidding array (for cut operation) */    
188         if (delete) {
189                 n_selected = 1;
190                 if (data != NULL) {
191                         n_selected = tny_list_get_length (data);        
192                         priv->hidding = g_malloc0(sizeof(gchar *) * n_selected);        
193                         iter = tny_list_create_iterator (priv->selection);
194                         i = 0;
195                         while (!tny_iterator_is_done (iter)) {
196                                 obj = tny_iterator_get_current (iter);
197                                 if (obj && TNY_IS_HEADER (obj))
198                                         id = g_strdup(tny_header_get_message_id (TNY_HEADER (obj)));
199                                 
200                                 priv->hidding[i++] = id;
201                                 tny_iterator_next (iter);
202                                 
203                                 if (obj)
204                                         g_object_unref (obj);
205                         }
206                         g_object_unref (iter);
207                 }
208                 else {
209                         priv->hidding = g_malloc0(sizeof(gchar *));     
210                         id = g_strdup (tny_folder_get_id (src_folder));
211                         priv->hidding[0] = id;                  
212                 }
213         }
214 }
215
216 void
217 modest_email_clipboard_clear (ModestEmailClipboard *self)
218 {
219         ModestEmailClipboardPrivate *priv = NULL;
220         guint i, n_selected;
221
222         g_return_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self));
223         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
224
225         n_selected = 1;
226         if (priv->src) 
227                 g_object_unref (priv->src);
228         if (priv->selection) {
229                 n_selected = tny_list_get_length(priv->selection);
230                 g_object_unref (priv->selection);
231         }
232         if (priv->hidding) {            
233                 for (i=0; i < n_selected; i++) 
234                         g_free (priv->hidding[i]);
235                 g_free(priv->hidding);
236         }
237
238         priv->src = NULL;
239         priv->selection = NULL;
240         priv->hidding = NULL;
241         priv->delete = FALSE;
242 }
243
244 gboolean
245 modest_email_clipboard_cleared (ModestEmailClipboard *self)
246 {
247         ModestEmailClipboardPrivate *priv = NULL;;
248         gboolean cleared = FALSE;
249
250         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), TRUE);
251         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
252
253         cleared = ((priv->src == NULL) && (priv->selection == NULL));
254
255         return cleared;
256 }
257
258 gboolean 
259 modest_email_clipboard_check_source_folder (ModestEmailClipboard *self,
260                                             const TnyFolder *folder)
261 {
262         TnyFolderType folder_type1;
263         TnyFolderType folder_type2;
264         ModestEmailClipboardPrivate *priv = NULL;;
265         const gchar *id1 = NULL;
266         const gchar *id2 = NULL;
267         gboolean same_folder = FALSE;
268
269         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), TRUE);
270         g_return_val_if_fail (TNY_IS_FOLDER (folder), TRUE);
271         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
272         
273         /* If cleared, return always FALSE*/
274         if (modest_email_clipboard_cleared (self)) return FALSE;
275
276         /* Check target and source folders */
277         id1 = tny_folder_get_id (priv->src);
278         id2 = tny_folder_get_id (TNY_FOLDER(folder));   
279         folder_type1 = modest_tny_folder_guess_folder_type (priv->src);
280         folder_type2 = modest_tny_folder_guess_folder_type (folder);
281         
282         if (folder_type1 == TNY_FOLDER_TYPE_INVALID || folder_type2 == TNY_FOLDER_TYPE_INVALID)
283                 g_warning ("%s: BUG: folder of type TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
284         
285         same_folder = ((folder_type1 == folder_type2) && 
286                        (!g_ascii_strcasecmp (id1, id2)));
287         
288         return same_folder;
289 }
290
291 gboolean 
292 modest_email_clipboard_headers_copied (ModestEmailClipboard *self)
293 {
294         ModestEmailClipboardPrivate *priv = NULL;;
295         gboolean result = FALSE;
296
297         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), FALSE);
298         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
299
300         result = priv->selection != NULL;
301
302         return result;
303 }
304
305 gboolean 
306 modest_email_clipboard_folder_copied (ModestEmailClipboard *self)
307 {
308         ModestEmailClipboardPrivate *priv = NULL;;
309         gboolean result = FALSE;
310
311         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), FALSE);
312         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
313         
314         result = ((priv->selection == NULL) && (priv->src != NULL));
315         
316         return result; 
317 }
318
319 const gchar *
320 modest_email_clipboard_get_folder_name (ModestEmailClipboard *self)
321 {
322         ModestEmailClipboardPrivate *priv = NULL;;
323         const gchar *folder_name = NULL;
324
325         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), NULL);
326         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
327         
328         /* If cleared, return always FALSE*/
329         if (modest_email_clipboard_cleared (self)) return NULL;
330
331         /* Check target and source folders */
332         folder_name = tny_folder_get_name (priv->src);
333         
334         return folder_name;
335 }
336
337 const gchar **
338 modest_email_clipboard_get_hidding_ids (ModestEmailClipboard *self,
339                                         guint *n_selected)
340 {
341         ModestEmailClipboardPrivate *priv = NULL;;
342
343         *n_selected = 0;
344
345         g_return_val_if_fail (MODEST_IS_EMAIL_CLIPBOARD (self), NULL);
346         priv = MODEST_EMAIL_CLIPBOARD_GET_PRIVATE (self);
347
348         if (priv->selection != NULL)
349                 *n_selected = tny_list_get_length (priv->selection);
350         else
351                 *n_selected = 1;
352
353         return (const gchar **) priv->hidding;
354 }
355