* infrastructure for locking added, small cosmetics
[modest] / src / modest-tny-msg-actions.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
31 #include <gtk/gtk.h>
32 #include <gtkhtml/gtkhtml.h>
33
34 /* TODO: put in auto* */
35 #include <tny-text-buffer-stream.h>
36 #include <tny-msg-mime-part-iface.h>
37 #include <tny-msg-iface.h>
38 #include <tny-list-iface.h>
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif /*HAVE_CONFIG_H */
43
44 #include "modest-tny-msg-actions.h"
45 #include "modest-text-utils.h"
46
47
48 /* private */
49 static gchar *quote_msg (const TnyMsgIface * src, const gchar * from,
50                          time_t sent_date, gint limit);
51
52 static gchar *
53 quote_msg (const TnyMsgIface * src, const gchar * from, time_t sent_date, gint limit)
54 {
55         TnyStreamIface *stream;
56         TnyMsgMimePartIface *body;
57         GtkTextBuffer *buf;
58         GtkTextIter start, end;
59         const gchar *to_quote;
60         gchar *quoted;
61
62         /* the cast makes me uneasy... */
63         body = modest_tny_msg_actions_find_body_part(src, FALSE);
64         if (!body)
65                 return NULL;
66
67         buf = gtk_text_buffer_new (NULL);
68         stream = TNY_STREAM_IFACE (tny_text_buffer_stream_new (buf));
69         tny_stream_iface_reset (stream);
70         tny_msg_mime_part_iface_decode_to_stream (body, stream);
71         tny_stream_iface_reset (stream);
72         g_object_unref (stream);
73         
74         gtk_text_buffer_get_bounds (buf, &start, &end);
75         to_quote = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
76         quoted = modest_text_utils_quote (to_quote, from, sent_date, limit);
77         g_object_unref (buf);
78
79         return quoted;
80 }
81
82
83 gchar*
84 modest_tny_msg_actions_quote (const TnyMsgIface * self, const gchar * from,
85                               time_t sent_date, gint limit,
86                               const gchar * to_quote)
87 {
88         gchar *quoted;
89
90         /* 2 cases: */
91
92         /* a) quote text from selection */
93         if (to_quote != NULL) 
94                 return modest_text_utils_quote (to_quote, from, sent_date,
95                                                 limit);
96         
97         /* b) try to find a text/plain part in the msg and quote it */
98         return quote_msg (self, from, sent_date, limit);
99 }
100
101
102
103 TnyMsgMimePartIface *
104 modest_tny_msg_actions_find_body_part (const TnyMsgIface *msg, gboolean want_html)
105 {
106         const gchar *mime_type = want_html ? "text/html" : "text/plain";
107         TnyMsgMimePartIface *part;
108         const TnyListIface *parts;
109         TnyIteratorIface *iter;
110         gboolean found;
111
112         if (!msg)
113                 return NULL;
114
115         found = FALSE;
116         parts =  tny_msg_iface_get_parts ((TnyMsgIface *)msg);
117         iter  = tny_list_iface_create_iterator ((TnyListIface*)parts);
118
119         while (!tny_iterator_iface_is_done(iter)) {
120                 part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current (iter));
121                 
122                 if (tny_msg_mime_part_iface_content_type_is (part, mime_type) &&
123                     !tny_msg_mime_part_iface_is_attachment (part)) {
124                         found = TRUE;
125                         break;
126                 }       
127                 tny_iterator_iface_next (iter);
128         }
129
130         g_object_unref (G_OBJECT(iter));
131
132         /* if were trying to find an HTML part and could find it,
133          * try to find a text/plain part instead
134          */
135         if (!found && want_html) 
136                 return modest_tny_msg_actions_find_body_part (msg, FALSE);
137
138         return found ? part : NULL;
139 }
140
141
142
143
144 TnyMsgMimePartIface *
145 modest_tny_msg_actions_find_nth_part (const TnyMsgIface *msg, gint index)
146 {
147         TnyMsgMimePartIface *part;
148         const TnyListIface *parts;
149         TnyIteratorIface *iter;
150
151         g_return_val_if_fail (msg, NULL);
152         g_return_val_if_fail (index > 0, NULL);
153                 
154         parts =  tny_msg_iface_get_parts ((TnyMsgIface *)msg);
155         iter  = tny_list_iface_create_iterator ((TnyListIface*)parts);
156
157         if (!tny_iterator_iface_has_first(iter))
158                 return NULL;
159
160         part = tny_iterator_iface_nth (iter, index);
161
162         g_object_unref (G_OBJECT(iter));
163
164         return part;
165 }