From dd00071e3b3dba6e7d35f7142ba61a89c8f205c3 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Wed, 28 Feb 2007 18:08:57 +0000 Subject: [PATCH 1/1] * Added src/widgets/modest-recpt-view.[ch]. * Inherits from GtkLabel. * It's a tweaked GtkLabel for showing a list of recipients. * Main feature is the way it handles selections (tries to select a full recipient). * Emits a signal when a recipient is selected and clicked/ double clicked. * Added src/widgets/modest-mail-header-view.[ch]. * Contains implementation of ModestMailHeaderView, which is an implementation of TnyHeaderView. * It's used in ModestMsgView to show the mail headers. * It shows the recipients list with the new ModestRecptView * It features an expansor, to hide or show more headers. * src/modest-text-utils.[ch]: * Added modest_text_utils_split_addresses_list. It splits a list of email addresses in the format accepted by mail recipients list. * src/modest-ui-actions.[ch]: * Added stub handler for message recipient activation (click on emails in a mail header). * src/gtk/modest_main_window.c: * Main window GtkVBox spacing is now 0 for better HIG compliance. * Now scrolled windows are added with shadow (HIG compliance). * Added handling of signal from recipients in mail preview. pmo-trunk-r868 --- src/gtk/modest-main-window.c | 6 +- src/modest-main.c | 2 +- src/modest-text-utils.c | 44 ++++ src/modest-text-utils.h | 11 + src/modest-ui-actions.c | 21 ++ src/modest-ui-actions.h | 4 + src/widgets/Makefile.am | 4 + src/widgets/modest-mail-header-view.c | 401 +++++++++++++++++++++++++++++++++ src/widgets/modest-mail-header-view.h | 74 ++++++ src/widgets/modest-msg-view.c | 135 +++++------ src/widgets/modest-msg-view.h | 7 +- src/widgets/modest-recpt-view.c | 255 +++++++++++++++++++++ src/widgets/modest-recpt-view.h | 66 ++++++ 13 files changed, 951 insertions(+), 79 deletions(-) create mode 100644 src/widgets/modest-mail-header-view.c create mode 100644 src/widgets/modest-mail-header-view.h create mode 100644 src/widgets/modest-recpt-view.c create mode 100644 src/widgets/modest-recpt-view.h diff --git a/src/gtk/modest-main-window.c b/src/gtk/modest-main-window.c index 2932d2f..b1a660f 100644 --- a/src/gtk/modest-main-window.c +++ b/src/gtk/modest-main-window.c @@ -410,6 +410,8 @@ connect_signals (ModestMainWindow *self) G_CALLBACK(modest_ui_actions_on_msg_link_hover), self); g_signal_connect (G_OBJECT(priv->msg_preview), "attachment_clicked", G_CALLBACK(modest_ui_actions_on_msg_attachment_clicked), self); + g_signal_connect (G_OBJECT(priv->msg_preview), "recpt-activated", + G_CALLBACK(modest_ui_actions_on_msg_recpt_activated), self); /* Account store */ g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested", @@ -436,6 +438,8 @@ wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport) gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (win), + GTK_SHADOW_IN); if (needs_viewport) gtk_scrolled_window_add_with_viewport @@ -521,7 +525,7 @@ modest_main_window_new (void) gtk_box_pack_start (GTK_BOX(status_hbox), priv->online_toggle,FALSE, FALSE, 0); /* putting it all together... */ - main_vbox = gtk_vbox_new (FALSE, 6); + main_vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX(main_vbox), parent_priv->menubar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(main_vbox), parent_priv->toolbar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0); diff --git a/src/modest-main.c b/src/modest-main.c index 46d49af..9e6e63e 100644 --- a/src/modest-main.c +++ b/src/modest-main.c @@ -219,7 +219,7 @@ start_ui (const gchar *account_name, const gchar* mailto, const gchar *cc, const return MODEST_ERR_UI; } - gtk_widget_show_all (GTK_WIDGET (win)); + gtk_widget_show (GTK_WIDGET (win)); gtk_main(); return MODEST_ERR_NONE; diff --git a/src/modest-text-utils.c b/src/modest-text-utils.c index 45555ce..0a84acf 100644 --- a/src/modest-text-utils.c +++ b/src/modest-text-utils.c @@ -333,6 +333,50 @@ modest_text_utils_convert_to_html (const gchar *data) return g_string_free (html, FALSE); } +GSList * +modest_text_utils_split_addresses_list (const gchar *addresses) +{ + gchar *current, *start, *last_blank; + GSList *result = NULL; + + start = (gchar *) addresses; + current = start; + last_blank = start; + + while (*current != '\0') { + if ((start == current)&&((*current == ' ')||(*current == ','))) { + start++; + last_blank = current; + } else if (*current == ',') { + gchar *new_address = NULL; + new_address = g_strndup (start, current - last_blank); + result = g_slist_prepend (result, new_address); + start = current + 1; + last_blank = start; + } else if (*current == '\"') { + if (current == start) { + current++; + start++; + } + while ((*current != '\"')&&(*current != '\0')) + current++; + } + + current++; + } + + if (start != current) { + gchar *new_address = NULL; + new_address = g_strndup (start, current - last_blank); + result = g_slist_prepend (result, new_address); + } + + result = g_slist_reverse (result); + return result; + +} + + /* ******************************************************************* */ /* ************************* UTILIY FUNCTIONS ************************ */ /* ******************************************************************* */ diff --git a/src/modest-text-utils.h b/src/modest-text-utils.h index 27b1407..e636ce0 100644 --- a/src/modest-text-utils.h +++ b/src/modest-text-utils.h @@ -221,4 +221,15 @@ gchar * modest_text_utils_get_display_size (guint size); **/ gboolean modest_text_utils_validate_email_address (const gchar *email_address); +/** + * modest_text_utils_split_addresses_list: + * @addresses: a string + * + * obtains a GSList of addresses from a string of addresses + * in the format understood by email protocols + * + * Returns: a GSList of strings + **/ +GSList *modest_text_utils_split_addresses_list (const gchar *addresses); + #endif /* __MODEST_TEXT_UTILS_H__ */ diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 991491d..24d0376 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -966,6 +966,27 @@ modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, int index, } void +modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview, + ModestRecptView *recpt_view, + ModestWindow *win) +{ + gint start, end; + gchar *utf_start, *utf_end; + gchar *full_string = NULL; + gchar *substring; + + gtk_label_get_selection_bounds (GTK_LABEL (recpt_view), &start, &end); + full_string = (gchar *) gtk_label_get_text (GTK_LABEL (recpt_view)); + utf_start = g_utf8_offset_to_pointer (full_string, start); + utf_end = g_utf8_offset_to_pointer (full_string, end); + substring = g_strndup (utf_start, utf_end - utf_start); + g_message ("%s %s", __FUNCTION__, substring); + + g_free (substring); + +} + +void modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) { TnyTransportAccount *transport_account; diff --git a/src/modest-ui-actions.h b/src/modest-ui-actions.h index 12fde33..323d7c8 100644 --- a/src/modest-ui-actions.h +++ b/src/modest-ui-actions.h @@ -32,6 +32,7 @@ #include #include +#include G_BEGIN_DECLS @@ -95,6 +96,9 @@ void modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, int index, ModestWindow *win); +void modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview, ModestRecptView *recpt_view, + ModestWindow *win); + void modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window); diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index 3f5dd4a..4cf053a 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -28,12 +28,16 @@ libmodest_widgets_la_SOURCES= \ modest-header-view-render.c \ modest-header-view.c \ modest-header-view.h \ + modest-mail-header-view.c \ + modest-mail-header-view.h \ modest-main-window.h \ modest-msg-edit-window-ui.h \ modest-msg-edit-window.h \ modest-msg-view-window.h \ modest-msg-view.c \ modest-msg-view.h \ + modest-recpt-view.c \ + modest-recpt-view.h \ modest-tny-stream-gtkhtml.c \ modest-tny-stream-gtkhtml.h \ modest-window.c \ diff --git a/src/widgets/modest-mail-header-view.c b/src/widgets/modest-mail-header-view.c new file mode 100644 index 0000000..4e5ac27 --- /dev/null +++ b/src/widgets/modest-mail-header-view.c @@ -0,0 +1,401 @@ +/* Copyright (c) 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include + +#include +#include +#include +#include + +static GObjectClass *parent_class = NULL; + +/* signals */ +enum { + RECPT_ACTIVATED_SIGNAL, + LAST_SIGNAL +}; + +typedef struct _ModestMailHeaderViewPriv ModestMailHeaderViewPriv; + +struct _ModestMailHeaderViewPriv +{ + GtkWidget *fromto_label; + GtkWidget *fromto_contents; + GtkWidget *main_vbox; + GtkWidget *expander; + GtkWidget *headers_vbox; + GtkSizeGroup *labels_size_group; + gboolean is_sent; + TnyHeader *header; +}; + +#define MODEST_MAIL_HEADER_VIEW_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_MAIL_HEADER_VIEW, ModestMailHeaderViewPriv)) + +static guint signals[LAST_SIGNAL] = {0}; + +static void +activate_recpt (GtkWidget *recpt_view, gpointer user_data) +{ + ModestMailHeaderView * view = MODEST_MAIL_HEADER_VIEW (user_data); + + g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, recpt_view); +} + +static void +add_header (ModestMailHeaderView *widget, const gchar *field, const gchar *value) +{ + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (widget); + GtkWidget *hbox; + GtkWidget *label_field, *label_value; + + hbox = gtk_hbox_new (FALSE, 12); + label_field = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label_field), field); + gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0); + label_value = gtk_label_new (NULL); + gtk_label_set_text (GTK_LABEL (label_value), value); + gtk_label_set_selectable (GTK_LABEL (label_value), TRUE); + gtk_misc_set_alignment (GTK_MISC (label_value), 0.0, 0.0); + + gtk_box_pack_start (GTK_BOX (hbox), label_field, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), label_value, TRUE, TRUE, 0); + gtk_size_group_add_widget (priv->labels_size_group, label_field); + + gtk_box_pack_start (GTK_BOX (priv->headers_vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + +} + +static void +add_recpt_header (ModestMailHeaderView *widget, const gchar *field, const gchar *value) +{ + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (widget); + GtkWidget *hbox; + GtkWidget *label_field, *label_value; + + hbox = gtk_hbox_new (FALSE, 12); + label_field = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label_field), field); + gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0); + label_value = modest_recpt_view_new (); + gtk_label_set_text (GTK_LABEL (label_value), value); + gtk_label_set_selectable (GTK_LABEL (label_value), TRUE); + gtk_misc_set_alignment (GTK_MISC (label_value), 0.0, 0.0); + g_signal_connect (G_OBJECT (label_value), "activate", G_CALLBACK (activate_recpt), widget); + + gtk_box_pack_start (GTK_BOX (hbox), label_field, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), label_value, TRUE, TRUE, 0); + gtk_size_group_add_widget (priv->labels_size_group, label_field); + + gtk_box_pack_start (GTK_BOX (priv->headers_vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); +} + +static void +clean_headers (GtkWidget *vbox) +{ + GList *headers_list, *node; + + headers_list = gtk_container_get_children (GTK_CONTAINER (vbox)); + + for (node = headers_list; node != NULL; node = g_list_next (node)) { + gtk_widget_destroy (GTK_WIDGET (node->data)); + } + g_list_free (headers_list); +} + +static void +modest_mail_header_view_set_header (TnyHeaderView *self, TnyHeader *header) +{ + MODEST_MAIL_HEADER_VIEW_GET_CLASS (self)->set_header_func (self, header); + return; +} + +static void +modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *header) +{ + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (self); + + if (header) + g_assert (TNY_IS_HEADER (header)); + + if (G_LIKELY (priv->header)) + g_object_unref (G_OBJECT (priv->header)); + priv->header = NULL; + + clean_headers (priv->headers_vbox); + + if (header && G_IS_OBJECT (header)) + { + const gchar *to, *from, *subject, *bcc, *cc; + g_object_ref (G_OBJECT (header)); + priv->header = header; + + to = tny_header_get_to (header); + from = tny_header_get_from (header); + subject = tny_header_get_subject (header); + cc = tny_header_get_cc (header); + bcc = tny_header_get_bcc (header); + + if (subject) + add_header (MODEST_MAIL_HEADER_VIEW (self), _("Subject:"), subject); + if (priv->is_sent) { + gchar *sent = modest_text_utils_get_display_date (tny_header_get_date_sent (header)); + gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("To:")); + if (to) + gtk_label_set_text (GTK_LABEL (priv->fromto_contents), to); + add_header (MODEST_MAIL_HEADER_VIEW (self), _("Sent:"), sent); + g_free (sent); + } else { + gchar *received = modest_text_utils_get_display_date (tny_header_get_date_received (header)); + gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("From:")); + if (from) + gtk_label_set_text (GTK_LABEL (priv->fromto_contents), from); + add_header (MODEST_MAIL_HEADER_VIEW (self), _("Received:"), received); + g_free (received); + } + if (cc) + add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("Cc:"), cc); + if (bcc) + add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("Bcc:"), bcc); + } + + gtk_widget_show_all (GTK_WIDGET (self)); + + return; +} + +static void +modest_mail_header_view_clear (TnyHeaderView *self) +{ + MODEST_MAIL_HEADER_VIEW_GET_CLASS (self)->clear_func (self); + return; +} + +static void +modest_mail_header_view_clear_default (TnyHeaderView *self) +{ + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (self); + + if (G_LIKELY (priv->header)) + g_object_unref (G_OBJECT (priv->header)); + priv->header = NULL; + + clean_headers (priv->headers_vbox); + + gtk_label_set_text (GTK_LABEL (priv->fromto_label), ""); + gtk_label_set_text (GTK_LABEL (priv->fromto_contents), ""); + + gtk_widget_hide (GTK_WIDGET(self)); + + return; +} + +static void +expander_activate (GtkWidget *expander, ModestMailHeaderView *header_view) +{ + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (header_view); + + if (gtk_expander_get_expanded (GTK_EXPANDER (expander))) { + if (gtk_widget_get_parent (priv->headers_vbox) == NULL) { + gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->headers_vbox, TRUE, TRUE, 0); + gtk_widget_show_all (GTK_WIDGET (priv->headers_vbox)); + } + } else { + if (gtk_widget_get_parent (priv->headers_vbox) != NULL) { + gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->headers_vbox); + } + } + gtk_widget_queue_resize (GTK_WIDGET (header_view)); + gtk_widget_queue_draw (GTK_WIDGET (header_view)); +} + +/** + * modest_mail_header_view_new: + * + * Return value: a new #ModestHeaderView instance implemented for Gtk+ + **/ +TnyHeaderView* +modest_mail_header_view_new (void) +{ + ModestMailHeaderView *self = g_object_new (MODEST_TYPE_MAIL_HEADER_VIEW, NULL); + + return TNY_HEADER_VIEW (self); +} + +static void +modest_mail_header_view_instance_init (GTypeInstance *instance, gpointer g_class) +{ + ModestMailHeaderView *self = (ModestMailHeaderView *)instance; + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (self); + GtkWidget *fromto_hbox = NULL; + GtkSizeGroup *expander_group = NULL; + + priv->header = NULL; + + priv->expander = gtk_expander_new (NULL); + priv->main_vbox = gtk_vbox_new (FALSE, 1); + gtk_box_pack_start (GTK_BOX (instance), priv->expander, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (instance), priv->main_vbox, TRUE, TRUE, 0); + g_signal_connect_after (G_OBJECT (priv->expander), "activate", G_CALLBACK (expander_activate), instance); + + fromto_hbox = gtk_hbox_new (FALSE, 12); + priv->fromto_label = gtk_label_new (NULL); + priv->fromto_contents = modest_recpt_view_new (); + gtk_label_set_selectable (GTK_LABEL (priv->fromto_contents), TRUE); + gtk_misc_set_alignment (GTK_MISC (priv->fromto_label), 0.0, 0.0); + gtk_misc_set_alignment (GTK_MISC (priv->fromto_contents), 0.0, 0.0); + g_signal_connect (G_OBJECT (priv->fromto_contents), "activate", G_CALLBACK (activate_recpt), instance); + + gtk_box_pack_start (GTK_BOX (fromto_hbox), priv->fromto_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (fromto_hbox), priv->fromto_contents, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (priv->main_vbox), fromto_hbox, FALSE, FALSE, 0); + + priv->labels_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (priv->labels_size_group, priv->fromto_label); + + priv->headers_vbox = gtk_vbox_new (FALSE, 1); + g_object_ref (priv->headers_vbox); + + expander_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (expander_group, priv->headers_vbox); + gtk_size_group_add_widget (expander_group, fromto_hbox); + g_object_unref (expander_group); + + priv->is_sent = FALSE; + + return; +} + +static void +modest_mail_header_view_finalize (GObject *object) +{ + ModestMailHeaderView *self = (ModestMailHeaderView *)object; + ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (self); + + if (G_LIKELY (priv->header)) + g_object_unref (G_OBJECT (priv->header)); + priv->header = NULL; + + if (G_LIKELY (priv->headers_vbox)) + g_object_unref (G_OBJECT (priv->headers_vbox)); + + priv->headers_vbox = NULL; + + g_object_unref (priv->labels_size_group); + + (*parent_class->finalize) (object); + + return; +} + +static void +tny_header_view_init (gpointer g, gpointer iface_data) +{ + TnyHeaderViewIface *klass = (TnyHeaderViewIface *)g; + + klass->set_header_func = modest_mail_header_view_set_header; + klass->clear_func = modest_mail_header_view_clear; + + return; +} + +static void +modest_mail_header_view_class_init (ModestMailHeaderViewClass *klass) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (klass); + object_class = (GObjectClass*) klass; + + klass->set_header_func = modest_mail_header_view_set_header_default; + klass->clear_func = modest_mail_header_view_clear_default; + + object_class->finalize = modest_mail_header_view_finalize; + + klass->recpt_activated = NULL; + + g_type_class_add_private (object_class, sizeof (ModestMailHeaderViewPriv)); + + signals[RECPT_ACTIVATED_SIGNAL] = + g_signal_new ("recpt-activated", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET(ModestMailHeaderViewClass, recpt_activated), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + MODEST_TYPE_RECPT_VIEW); + + + return; +} + +GType +modest_mail_header_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY(type == 0)) + { + static const GTypeInfo info = + { + sizeof (ModestMailHeaderViewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) modest_mail_header_view_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ModestMailHeaderView), + 0, /* n_preallocs */ + modest_mail_header_view_instance_init /* instance_init */ + }; + + static const GInterfaceInfo tny_header_view_info = + { + (GInterfaceInitFunc) tny_header_view_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + type = g_type_register_static (GTK_TYPE_HBOX, + "ModestMailHeaderView", + &info, 0); + + g_type_add_interface_static (type, TNY_TYPE_HEADER_VIEW, + &tny_header_view_info); + + } + + return type; +} diff --git a/src/widgets/modest-mail-header-view.h b/src/widgets/modest-mail-header-view.h new file mode 100644 index 0000000..d949bdc --- /dev/null +++ b/src/widgets/modest-mail-header-view.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MODEST_MAIL_HEADER_VIEW_H +#define MODEST_MAIL_HEADER_VIEW_H + +#include +#include + +#include +#include + +G_BEGIN_DECLS + +#define MODEST_TYPE_MAIL_HEADER_VIEW (modest_mail_header_view_get_type ()) +#define MODEST_MAIL_HEADER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MODEST_TYPE_MAIL_HEADER_VIEW, ModestMailHeaderView)) +#define MODEST_MAIL_HEADER_VIEW_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MODEST_TYPE_MAIL_HEADER_VIEW, ModestMailHeaderViewClass)) +#define MODEST_IS_MAIL_HEADER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MODEST_TYPE_MAIL_HEADER_VIEW)) +#define MODEST_IS_MAIL_HEADER_VIEW_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MODEST_TYPE_MAIL_HEADER_VIEW)) +#define MODEST_MAIL_HEADER_VIEW_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MODEST_TYPE_MAIL_HEADER_VIEW, ModestMailHeaderViewClass)) + +typedef struct _ModestMailHeaderView ModestMailHeaderView; +typedef struct _ModestMailHeaderViewClass ModestMailHeaderViewClass; + +struct _ModestMailHeaderView +{ + GtkHBox parent; + +}; + +struct _ModestMailHeaderViewClass +{ + GtkHBoxClass parent_class; + + /* virtual methods */ + void (*set_header_func) (TnyHeaderView *self, TnyHeader *header); + void (*clear_func) (TnyHeaderView *self); + + /* signals */ + void (*recpt_activated) (ModestRecptView *recpt_view); +}; + +GType modest_mail_header_view_get_type (void); +TnyHeaderView* modest_mail_header_view_new (void); + +G_END_DECLS + +#endif diff --git a/src/widgets/modest-msg-view.c b/src/widgets/modest-msg-view.c index c172db5..b6e25e8 100644 --- a/src/widgets/modest-msg-view.c +++ b/src/widgets/modest-msg-view.c @@ -42,6 +42,7 @@ #include #include "modest-msg-view.h" #include "modest-tny-stream-gtkhtml.h" +#include /* 'private'/'protected' functions */ @@ -49,6 +50,7 @@ static void modest_msg_view_class_init (ModestMsgViewClass *klass); static void modest_msg_view_init (ModestMsgView *obj); static void modest_msg_view_finalize (GObject *obj); +static void on_recpt_activated (ModestMailHeaderView *header_view, ModestRecptView *recpt_view, ModestMsgView *msg_view); static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view); static gboolean on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream, ModestMsgView *msg_view); @@ -61,12 +63,14 @@ enum { LINK_CLICKED_SIGNAL, LINK_HOVER_SIGNAL, ATTACHMENT_CLICKED_SIGNAL, + RECPT_ACTIVATED_SIGNAL, LAST_SIGNAL }; typedef struct _ModestMsgViewPrivate ModestMsgViewPrivate; struct _ModestMsgViewPrivate { GtkWidget *gtkhtml; + GtkWidget *mail_header_view; TnyMsg *msg; gulong sig1, sig2, sig3; @@ -97,7 +101,7 @@ modest_msg_view_get_type (void) (GInstanceInitFunc) modest_msg_view_init, NULL }; - my_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW, + my_type = g_type_register_static (GTK_TYPE_VBOX, "ModestMsgView", &my_info, 0); } @@ -142,6 +146,15 @@ modest_msg_view_class_init (ModestMsgViewClass *klass) NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[RECPT_ACTIVATED_SIGNAL] = + g_signal_new ("recpt_activated", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(ModestMsgViewClass, recpt_activated), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, MODEST_TYPE_RECPT_VIEW); } static void @@ -153,6 +166,8 @@ modest_msg_view_init (ModestMsgView *obj) priv->msg = NULL; priv->gtkhtml = gtk_html_new(); + priv->mail_header_view = GTK_WIDGET(modest_mail_header_view_new ()); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); gtk_html_set_editable (GTK_HTML(priv->gtkhtml), FALSE); gtk_html_allow_selection (GTK_HTML(priv->gtkhtml), TRUE); @@ -166,6 +181,9 @@ modest_msg_view_init (ModestMsgView *obj) G_CALLBACK(on_url_requested), obj); priv->sig3 = g_signal_connect (G_OBJECT(priv->gtkhtml), "on_url", G_CALLBACK(on_link_hover), obj); + + g_signal_connect (G_OBJECT (priv->mail_header_view), "recpt-activated", + G_CALLBACK (on_recpt_activated), obj); } @@ -195,23 +213,41 @@ modest_msg_view_new (TnyMsg *msg) GObject *obj; ModestMsgView* self; ModestMsgViewPrivate *priv; + GtkWidget *scrolled_window; obj = G_OBJECT(g_object_new(MODEST_TYPE_MSG_VIEW, NULL)); self = MODEST_MSG_VIEW(obj); priv = MODEST_MSG_VIEW_GET_PRIVATE (self); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - if (priv->gtkhtml) - gtk_container_add (GTK_CONTAINER(obj), priv->gtkhtml); - - if (msg) - modest_msg_view_set_message (self, msg); + gtk_box_set_spacing (GTK_BOX (self), 0); + gtk_box_set_homogeneous (GTK_BOX (self), FALSE); + + if (priv->mail_header_view) + gtk_box_pack_start (GTK_BOX(self), priv->mail_header_view, FALSE, FALSE, 0); + + if (priv->gtkhtml) { + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), + GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (scrolled_window), priv->gtkhtml); + gtk_box_pack_start (GTK_BOX(self), scrolled_window, TRUE, TRUE, 0); + } + + modest_msg_view_set_message (self, msg); return GTK_WIDGET(self); } +static void +on_recpt_activated (ModestMailHeaderView *header_view, + ModestRecptView *recpt_view, + ModestMsgView * view) +{ + g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, recpt_view); +} static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) @@ -378,58 +414,10 @@ attachments_as_html (ModestMsgView *self, TnyMsg *msg) } -static gchar* -get_header_info (TnyMsg *msg, gboolean outgoing) -{ - GString *str; - TnyHeader *header; - - if (!msg) - return NULL; - - header = tny_msg_get_header (msg); - if (!header) { - g_printerr ("modest: cannot get header info for message\n"); - return NULL; - } - - str = g_string_new ("\n"); - - if (outgoing) { - if (tny_header_get_to(header)) - g_string_append_printf (str, "\n", _("To"), - tny_header_get_to(header)); - } else { - if (tny_header_get_from (header)) - g_string_append_printf (str, "\n", _("From"), - tny_header_get_from(header)); - } - - if (tny_header_get_subject (header)) - g_string_append_printf (str, "\n", _("Subject"), - tny_header_get_subject(header)); - - - if (outgoing) { - gchar *sent = modest_text_utils_get_display_date (tny_header_get_date_sent (header)); - g_string_append_printf (str, "\n", _("Sent"), sent); - g_free (sent); - } else { - gchar *received = modest_text_utils_get_display_date (tny_header_get_date_received (header)); - g_string_append_printf (str, "\n", _("Received"), - received); - g_free (received); - } - g_string_append (str, "
%s:%s
%s:%s
%s:%s
%s:%s
%s:%s
\n
\n"); - - g_object_unref (G_OBJECT(header)); - return g_string_free (str, FALSE); -} - static gboolean -set_html_message (ModestMsgView *self, const gchar* header_info, TnyMimePart *tny_body, TnyMsg *msg) +set_html_message (ModestMsgView *self, TnyMimePart *tny_body, TnyMsg *msg) { gchar *html_attachments; GtkHTMLStream *gtkhtml_stream; @@ -446,11 +434,6 @@ set_html_message (ModestMsgView *self, const gchar* header_info, TnyMimePart *tn tny_stream = TNY_STREAM(modest_tny_stream_gtkhtml_new (gtkhtml_stream)); tny_stream_reset (tny_stream); - if (header_info) { - tny_stream_write (tny_stream, header_info, strlen(header_info)); - tny_stream_reset (tny_stream); - } - html_attachments = attachments_as_html(self, msg); if (html_attachments) { tny_stream_write (tny_stream, html_attachments, strlen(html_attachments)); @@ -470,7 +453,7 @@ set_html_message (ModestMsgView *self, const gchar* header_info, TnyMimePart *tn /* FIXME: this is a hack --> we use the tny_text_buffer_stream to * get the message text, then write to gtkhtml 'by hand' */ static gboolean -set_text_message (ModestMsgView *self, const gchar* header_info, TnyMimePart *tny_body, TnyMsg *msg) +set_text_message (ModestMsgView *self, TnyMimePart *tny_body, TnyMsg *msg) { GtkTextBuffer *buf; GtkTextIter begin, end; @@ -492,11 +475,6 @@ set_text_message (ModestMsgView *self, const gchar* header_info, TnyMimePart *tn gtkhtml_stream = gtk_html_begin(GTK_HTML(priv->gtkhtml)); tny_stream = TNY_STREAM(modest_tny_stream_gtkhtml_new (gtkhtml_stream)); - if (header_info) { - tny_stream_write (tny_stream, header_info, strlen(header_info)); - tny_stream_reset (tny_stream); - } - html_attachments = attachments_as_html(self, msg); if (html_attachments) { tny_stream_write (tny_stream, html_attachments, @@ -549,11 +527,12 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *msg) { TnyMimePart *body; ModestMsgViewPrivate *priv; - gchar *header_info; + TnyHeader *header; g_return_if_fail (self); priv = MODEST_MSG_VIEW_GET_PRIVATE(self); + gtk_widget_set_no_show_all (priv->mail_header_view, FALSE); if (msg != priv->msg) { if (priv->msg) @@ -564,22 +543,28 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *msg) } if (!msg) { + tny_header_view_clear (TNY_HEADER_VIEW (priv->mail_header_view)); + gtk_widget_hide_all (priv->mail_header_view); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); set_empty_message (self); return; } - header_info = get_header_info (msg, TRUE); + header = tny_msg_get_header (msg); + tny_header_view_set_header (TNY_HEADER_VIEW (priv->mail_header_view), header); + g_object_unref (header); body = modest_tny_msg_find_body_part (msg,TRUE); if (body) { if (tny_mime_part_content_type_is (body, "text/html")) - set_html_message (self, header_info, body, msg); + set_html_message (self, body, msg); else - set_text_message (self, header_info, body, msg); + set_text_message (self, body, msg); } else set_empty_message (self); - - g_free (header_info); + + gtk_widget_show_all (priv->mail_header_view); + gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); } diff --git a/src/widgets/modest-msg-view.h b/src/widgets/modest-msg-view.h index 78360d6..99c16b0 100644 --- a/src/widgets/modest-msg-view.h +++ b/src/widgets/modest-msg-view.h @@ -34,6 +34,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -49,11 +50,11 @@ typedef struct _ModestMsgView ModestMsgView; typedef struct _ModestMsgViewClass ModestMsgViewClass; struct _ModestMsgView { - GtkScrolledWindow parent; + GtkVBox parent; }; struct _ModestMsgViewClass { - GtkScrolledWindowClass parent_class; + GtkVBoxClass parent_class; void (*link_hover) (ModestMsgView *msgview, const gchar* link, gpointer user_data); @@ -61,6 +62,8 @@ struct _ModestMsgViewClass { gpointer user_data); void (*attachment_clicked) (ModestMsgView *msgview, int index, gpointer user_data); + void (*recpt_activated) (ModestMsgView *msgview, ModestRecptView *recpt_view, + gpointer user_data); }; diff --git a/src/widgets/modest-recpt-view.c b/src/widgets/modest-recpt-view.c new file mode 100644 index 0000000..9c45732 --- /dev/null +++ b/src/widgets/modest-recpt-view.c @@ -0,0 +1,255 @@ +/* Copyright (c) 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include + +#include +#include + +#include "modest-recpt-view.h" + +static GObjectClass *parent_class = NULL; + +/* signals */ +enum { + ACTIVATE_SIGNAL, + LAST_SIGNAL +}; + +typedef struct _ModestRecptViewPriv ModestRecptViewPriv; + +struct _ModestRecptViewPriv +{ + gboolean button_pressed; + gdouble pressed_x, pressed_y; +}; + +#define MODEST_RECPT_VIEW_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_RECPT_VIEW, ModestRecptViewPriv)) + +static guint signals[LAST_SIGNAL] = {0}; + +/** + * modest_recpt_view_new: + * + * Return value: a new #ModestRecptView instance implemented for Gtk+ + **/ +GtkWidget* +modest_recpt_view_new (void) +{ + ModestRecptView *self = g_object_new (MODEST_TYPE_RECPT_VIEW, NULL); + + return GTK_WIDGET (self); +} + +static void +address_bounds_at_position (const gchar *recipients_list, gint position, gint *start, gint *end) +{ + gchar *current = NULL; + gint range_start = 0; + gint range_end = 0; + gint index; + gboolean is_quoted = FALSE; + + index = 0; + for (current = (gchar *) recipients_list; *current != '\0'; current = g_utf8_find_next_char (current, NULL)) { + gunichar c = g_utf8_get_char (current); + + if ((c == ',') && (!is_quoted)) { + if (index < position) { + range_start = index + 1; + } else { + break; + } + } else if (c == '\"') { + is_quoted = !is_quoted; + } else if ((c == ' ') &&(range_start == index)) { + range_start ++; + } + index ++; + range_end = index; + } + + if (start) + *start = range_start; + if (end) + *end = range_end; +} + +static gboolean +button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (widget)); + + if (!gtk_label_get_selectable (GTK_LABEL (widget))) + return FALSE; + + if (event->type == GDK_BUTTON_PRESS) { + priv->button_pressed = TRUE; + priv->pressed_x = event->x; + priv->pressed_y = event->y; + } + return FALSE; +} + +static gboolean +button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (widget)); + + if (!gtk_label_get_selectable (GTK_LABEL (widget))) + return TRUE; + + if (event->type != GDK_BUTTON_RELEASE) + return TRUE; + + if ((priv->button_pressed) && + (event->type == GDK_BUTTON_RELEASE) && + (priv->pressed_x == event->x) && + (priv->pressed_y == event->y)) { + priv->button_pressed = FALSE; + if (event->button == 1) { + PangoLayout *layout = NULL; + int index; + layout = gtk_label_get_layout (GTK_LABEL (widget)); + if (pango_layout_xy_to_index (layout, event->x*PANGO_SCALE, event->y*PANGO_SCALE, &index, NULL)) { + int selection_start, selection_end; + gboolean selected = FALSE; + if (gtk_label_get_selection_bounds (GTK_LABEL (widget), + &selection_start, + &selection_end) && + (index >= selection_start)&&(index < selection_end)) { + selected = TRUE; + } + + address_bounds_at_position (gtk_label_get_text (GTK_LABEL (widget)), + index, + &selection_start, &selection_end); + /* TODO: now gtk label tries to select more than the label as usual, + * and we force it to recover the selected region for the defined area. + * It should be fixed (maybe preventing gtklabel to manage selections + * in parallel with us + */ + gtk_label_select_region (GTK_LABEL (widget), + selection_start, + selection_end); + + if (selected) + g_signal_emit (G_OBJECT (widget), signals[ACTIVATE_SIGNAL], 0); + + return TRUE; + } + } + } + priv->button_pressed = FALSE; + return TRUE; +} + +static void +modest_recpt_view_instance_init (GTypeInstance *instance, gpointer g_class) +{ + + gtk_label_set_justify (GTK_LABEL (instance), GTK_JUSTIFY_LEFT); + gtk_label_set_line_wrap (GTK_LABEL (instance), TRUE); + gtk_label_set_selectable (GTK_LABEL (instance), TRUE); + + g_signal_connect (G_OBJECT (instance), "button-press-event", G_CALLBACK(button_press_event), NULL); + g_signal_connect (G_OBJECT (instance), "button-release-event", G_CALLBACK(button_release_event), NULL); + + return; +} + +static void +modest_recpt_view_finalize (GObject *object) +{ + (*parent_class->finalize) (object); + + return; +} + +static void +modest_recpt_view_class_init (ModestRecptViewClass *klass) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (klass); + object_class = (GObjectClass*) klass; + + object_class->finalize = modest_recpt_view_finalize; + + klass->activate = NULL; + + g_type_class_add_private (object_class, sizeof (ModestRecptViewPriv)); + + signals[ACTIVATE_SIGNAL] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET(ModestRecptViewClass, activate), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + return; +} + +GType +modest_recpt_view_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY(type == 0)) + { + static const GTypeInfo info = + { + sizeof (ModestRecptViewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) modest_recpt_view_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ModestRecptView), + 0, /* n_preallocs */ + modest_recpt_view_instance_init /* instance_init */ + }; + + type = g_type_register_static (GTK_TYPE_LABEL, + "ModestRecptView", + &info, 0); + + } + + return type; +} diff --git a/src/widgets/modest-recpt-view.h b/src/widgets/modest-recpt-view.h new file mode 100644 index 0000000..021d24b --- /dev/null +++ b/src/widgets/modest-recpt-view.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2007, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MODEST_RECPT_VIEW_H +#define MODEST_RECPT_VIEW_H +#include +#include + +G_BEGIN_DECLS + +#define MODEST_TYPE_RECPT_VIEW (modest_recpt_view_get_type ()) +#define MODEST_RECPT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MODEST_TYPE_RECPT_VIEW, ModestRecptView)) +#define MODEST_RECPT_VIEW_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MODEST_TYPE_RECPT_VIEW, ModestRecptViewClass)) +#define MODEST_IS_RECPT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MODEST_TYPE_RECPT_VIEW)) +#define MODEST_IS_RECPT_VIEW_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MODEST_TYPE_RECPT_VIEW)) +#define MODEST_RECPT_VIEW_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MODEST_TYPE_RECPT_VIEW, ModestRecptViewClass)) + +typedef struct _ModestRecptView ModestRecptView; +typedef struct _ModestRecptViewClass ModestRecptViewClass; + +struct _ModestRecptView +{ + GtkLabel parent; + +}; + +struct _ModestRecptViewClass +{ + GtkLabelClass parent_class; + + void (*activate) (ModestRecptView *recpt_view); +}; + +GType modest_recpt_view_get_type (void); + +GtkWidget* modest_recpt_view_new (void); + +G_END_DECLS + +#endif -- 1.7.9.5