1 /* Copyright (c) 2007, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
32 #include <glib/gi18n-lib.h>
34 #include <gtk/gtkscrolledwindow.h>
35 #include <gtk/gtktextview.h>
36 #include <gtk/gtkimage.h>
37 #include <gtk/gtkbutton.h>
39 #include <modest-text-utils.h>
40 #include <modest-recpt-editor.h>
41 #include <modest-scroll-text.h>
42 #include <pango/pango-attributes.h>
45 static GObjectClass *parent_class = NULL;
47 #define RECIPIENT_TAG_ID "recpt-id"
51 OPEN_ADDRESSBOOK_SIGNAL,
55 typedef struct _ModestRecptEditorPrivate ModestRecptEditorPrivate;
57 struct _ModestRecptEditorPrivate
60 GtkWidget *abook_button;
61 GtkWidget *scrolled_window;
65 #define MODEST_RECPT_EDITOR_GET_PRIVATE(o) \
66 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_RECPT_EDITOR, ModestRecptEditorPrivate))
68 static guint signals[LAST_SIGNAL] = {0};
70 /* static functions: GObject */
71 static void modest_recpt_editor_instance_init (GTypeInstance *instance, gpointer g_class);
72 static void modest_recpt_editor_finalize (GObject *object);
73 static void modest_recpt_editor_class_init (ModestRecptEditorClass *klass);
76 static void modest_recpt_editor_on_abook_clicked (GtkButton *button,
77 ModestRecptEditor *editor);
80 * modest_recpt_editor_new:
82 * Return value: a new #ModestRecptEditor instance implemented for Gtk+
85 modest_recpt_editor_new (void)
87 ModestRecptEditor *self = g_object_new (MODEST_TYPE_RECPT_EDITOR,
92 return GTK_WIDGET (self);
96 modest_recpt_editor_set_recipients (ModestRecptEditor *recpt_editor, const gchar *recipients)
98 ModestRecptEditorPrivate *priv;
99 GtkTextBuffer *buffer = NULL;
101 g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
102 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
104 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
106 gtk_text_buffer_set_text (buffer, recipients, -1);
107 if (GTK_WIDGET_REALIZED (recpt_editor))
108 gtk_widget_queue_resize (GTK_WIDGET (recpt_editor));
113 modest_recpt_editor_add_recipients (ModestRecptEditor *recpt_editor, const gchar *recipients)
115 ModestRecptEditorPrivate *priv;
116 GtkTextBuffer *buffer = NULL;
118 gchar * string_to_add;
120 g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
121 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
123 if (recipients == NULL)
126 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
128 if (gtk_text_buffer_get_char_count (buffer) > 0) {
129 string_to_add = g_strconcat (";\n", recipients, NULL);
131 string_to_add = g_strdup (recipients);
134 gtk_text_buffer_get_end_iter (buffer, &iter);
136 gtk_text_buffer_insert (buffer, &iter, recipients, -1);
137 if (GTK_WIDGET_REALIZED (recpt_editor))
138 gtk_widget_queue_resize (GTK_WIDGET (recpt_editor));
143 modest_recpt_editor_add_resolved_recipient (ModestRecptEditor *recpt_editor, GSList *email_list, const gchar * recipient_id)
145 ModestRecptEditorPrivate *priv;
146 GtkTextBuffer *buffer = NULL;
147 GtkTextIter start, end, iter;
148 GtkTextTag *tag = NULL;
149 gboolean is_first_recipient = TRUE;
152 g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
153 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
155 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
157 gtk_text_buffer_get_bounds (buffer, &start, &end);
158 if (!gtk_text_iter_equal (&start, &end))
159 gtk_text_buffer_insert (buffer, &end, ";\n", -1);
161 gtk_text_buffer_get_end_iter (buffer, &iter);
163 tag = gtk_text_buffer_create_tag (buffer, NULL,
164 "underline", PANGO_UNDERLINE_SINGLE,
165 "wrap-mode", GTK_WRAP_NONE,
166 "editable", TRUE, NULL);
168 g_object_set_data (G_OBJECT (tag), "recipient-tag-id", GINT_TO_POINTER (RECIPIENT_TAG_ID));
169 g_object_set_data_full (G_OBJECT (tag), "recipient-id", g_strdup (recipient_id), (GDestroyNotify) g_free);
171 for (node = email_list; node != NULL; node = g_slist_next (node)) {
172 gchar *recipient = (gchar *) email_list->data;
174 if ((recipient) && (strlen (recipient) != 0)) {
176 if (!is_first_recipient) {
177 gtk_text_buffer_insert (buffer, &iter, ";\n", -1);
179 is_first_recipient = FALSE;
182 gtk_text_buffer_insert_with_tags (buffer, &iter, recipient, -1, tag, NULL);
190 modest_recpt_editor_get_recipients (ModestRecptEditor *recpt_editor)
192 ModestRecptEditorPrivate *priv;
193 GtkTextBuffer *buffer = NULL;
194 GtkTextIter start, end;
197 g_return_val_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor), NULL);
198 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
200 if (priv->recipients != NULL) {
201 g_free (priv->recipients);
202 priv->recipients = NULL;
205 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
207 gtk_text_buffer_get_start_iter (buffer, &start);
208 gtk_text_buffer_get_end_iter (buffer, &end);
210 priv->recipients = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
211 for (c = priv->recipients; *c == '\0'; c++) {
216 return priv->recipients;
221 modest_recpt_editor_instance_init (GTypeInstance *instance, gpointer g_class)
223 ModestRecptEditorPrivate *priv;
224 GtkWidget *abook_icon;
226 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (instance);
228 priv->abook_button = gtk_button_new ();
229 gtk_button_set_relief (GTK_BUTTON (priv->abook_button), GTK_RELIEF_NONE);
230 gtk_button_set_focus_on_click (GTK_BUTTON (priv->abook_button), FALSE);
231 GTK_WIDGET_UNSET_FLAGS (priv->abook_button, GTK_CAN_FOCUS);
232 gtk_button_set_alignment (GTK_BUTTON (priv->abook_button), 1.0, 1.0);
233 abook_icon = gtk_image_new_from_icon_name ("qgn_list_gene_contacts", GTK_ICON_SIZE_BUTTON);
234 gtk_container_add (GTK_CONTAINER (priv->abook_button), abook_icon);
236 priv->text_view = gtk_text_view_new ();
237 priv->scrolled_window = modest_scroll_text_new (GTK_TEXT_VIEW (priv->text_view), 5);
238 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
239 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window), GTK_SHADOW_IN);
240 /* gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->text_view); */
242 gtk_box_pack_start (GTK_BOX (instance), priv->scrolled_window, TRUE, TRUE, 0);
243 /* gtk_box_pack_start (GTK_BOX (instance), priv->text_view, TRUE, TRUE, 0); */
244 gtk_box_pack_end (GTK_BOX (instance), priv->abook_button, FALSE, FALSE, 0);
246 gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (priv->text_view), FALSE);
247 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (priv->text_view), TRUE);
248 gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->text_view), TRUE);
250 gtk_text_view_set_justification (GTK_TEXT_VIEW (priv->text_view), GTK_JUSTIFY_LEFT);
251 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->text_view), GTK_WRAP_CHAR);
253 gtk_widget_set_size_request (priv->text_view, 75, -1);
255 g_signal_connect (G_OBJECT (priv->abook_button), "clicked", G_CALLBACK (modest_recpt_editor_on_abook_clicked), instance);
257 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (instance), GTK_CAN_FOCUS);
258 gtk_container_set_focus_child (GTK_CONTAINER (instance), priv->text_view);
264 modest_recpt_editor_set_field_size_group (ModestRecptEditor *recpt_editor, GtkSizeGroup *size_group)
266 ModestRecptEditorPrivate *priv;
268 g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
269 g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
270 priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
272 gtk_size_group_add_widget (size_group, priv->scrolled_window);
276 modest_recpt_editor_on_abook_clicked (GtkButton *button, ModestRecptEditor *editor)
278 g_return_if_fail (MODEST_IS_RECPT_EDITOR (editor));
280 g_signal_emit_by_name (G_OBJECT (editor), "open-addressbook");
284 modest_recpt_editor_finalize (GObject *object)
286 (*parent_class->finalize) (object);
292 modest_recpt_editor_class_init (ModestRecptEditorClass *klass)
294 GObjectClass *object_class;
295 GtkWidgetClass *widget_class;
297 parent_class = g_type_class_peek_parent (klass);
298 object_class = (GObjectClass*) klass;
299 widget_class = GTK_WIDGET_CLASS (klass);
301 object_class->finalize = modest_recpt_editor_finalize;
303 g_type_class_add_private (object_class, sizeof (ModestRecptEditorPrivate));
305 signals[OPEN_ADDRESSBOOK_SIGNAL] =
306 g_signal_new ("open-addressbook",
307 G_TYPE_FROM_CLASS (object_class),
308 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
309 G_STRUCT_OFFSET (ModestRecptEditorClass, open_addressbook),
311 g_cclosure_marshal_VOID__VOID,
318 modest_recpt_editor_get_type (void)
320 static GType type = 0;
322 if (G_UNLIKELY(type == 0))
324 static const GTypeInfo info =
326 sizeof (ModestRecptEditorClass),
327 NULL, /* base_init */
328 NULL, /* base_finalize */
329 (GClassInitFunc) modest_recpt_editor_class_init, /* class_init */
330 NULL, /* class_finalize */
331 NULL, /* class_data */
332 sizeof (ModestRecptEditor),
334 modest_recpt_editor_instance_init /* instance_init */
337 type = g_type_register_static (GTK_TYPE_HBOX,