From: Dirk-Jan C. Binnema Date: Mon, 7 Aug 2006 12:23:19 +0000 (+0000) Subject: * updated widgets/: X-Git-Tag: git_migration_finished~4427 X-Git-Url: http://vcs.maemo.org/git/?a=commitdiff_plain;h=82819f280cb7939e58c95d6b70840816ebac780c;p=modest * updated widgets/: - ModestToolbar: - added modest-toolbar, generic toolbar widget - ModestHeaderView: - added message_no_found signal - updated docs - updated for TinyMail API changes - disconnect signals in finalize - handle offline case (emit signal) - ModestFolderView: - update for Tinymail changes - ModestMsgView - use tny_list API - update other TinyMail API/naming changes - cleanup ref handling (gobject) - Makefile.am: chnangs for modest-toolbar pmo-trunk-r451 --- diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index c1eb821..0f7b292 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -21,12 +21,9 @@ libmodest_widgets_la_SOURCES= \ modest-header-view.c \ modest-header-view.h \ modest-msg-view.c \ - modest-msg-view.h - - - -# modest-toolbar.h -# modest-toolbar.c + modest-msg-view.h \ + modest-toolbar.h \ + modest-toolbar.c LDADD = \ $(MODEST_GSTUFF_LIBS) \ diff --git a/src/widgets/modest-folder-view.c b/src/widgets/modest-folder-view.c index f2c3466..21363e5 100644 --- a/src/widgets/modest-folder-view.c +++ b/src/widgets/modest-folder-view.c @@ -33,8 +33,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -63,7 +62,7 @@ typedef struct _ModestFolderViewPrivate ModestFolderViewPrivate; struct _ModestFolderViewPrivate { TnyAccountStoreIface *account_store; - TnyMsgFolderIface *cur_folder; + TnyFolderIface *cur_folder; gboolean view_is_empty; gulong sig1, sig2; @@ -93,6 +92,7 @@ modest_folder_view_get_type (void) sizeof(ModestFolderView), 1, /* n_preallocs */ (GInstanceInitFunc) modest_folder_view_init, + NULL }; my_type = g_type_register_static (GTK_TYPE_TREE_VIEW, @@ -131,12 +131,12 @@ modest_folder_view_class_init (ModestFolderViewClass *klass) static void text_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, - GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { GObject *rendobj; gchar *fname; gint unread; - TnyMsgFolderType type; + TnyFolderType type; gtk_tree_model_get (tree_model, iter, TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN, &fname, @@ -157,52 +157,52 @@ text_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, /* FIXME: move these to TnyMail */ enum { - TNY_MSG_FOLDER_TYPE_NOTES = TNY_MSG_FOLDER_TYPE_SENT + 1, /* urgh */ - TNY_MSG_FOLDER_TYPE_DRAFTS, - TNY_MSG_FOLDER_TYPE_CONTACTS, - TNY_MSG_FOLDER_TYPE_CALENDAR + TNY_FOLDER_TYPE_NOTES = TNY_FOLDER_TYPE_SENT + 1, /* urgh */ + TNY_FOLDER_TYPE_DRAFTS, + TNY_FOLDER_TYPE_CONTACTS, + TNY_FOLDER_TYPE_CALENDAR }; -static TnyMsgFolderType +static TnyFolderType guess_folder_type (const gchar* name) { - TnyMsgFolderType type; + TnyFolderType type; gchar *folder; - g_return_val_if_fail (name, TNY_MSG_FOLDER_TYPE_NORMAL); + g_return_val_if_fail (name, TNY_FOLDER_TYPE_NORMAL); - type = TNY_MSG_FOLDER_TYPE_NORMAL; + type = TNY_FOLDER_TYPE_NORMAL; folder = g_utf8_strdown (name, strlen(name)); if (strcmp (folder, "inbox") == 0 || strcmp (folder, _("inbox")) == 0) - type = TNY_MSG_FOLDER_TYPE_INBOX; + type = TNY_FOLDER_TYPE_INBOX; else if (strcmp (folder, "outbox") == 0 || strcmp (folder, _("outbox")) == 0) - type = TNY_MSG_FOLDER_TYPE_OUTBOX; + type = TNY_FOLDER_TYPE_OUTBOX; else if (g_str_has_prefix(folder, "junk") || g_str_has_prefix(folder, _("junk"))) - type = TNY_MSG_FOLDER_TYPE_JUNK; + type = TNY_FOLDER_TYPE_JUNK; else if (g_str_has_prefix(folder, "trash") || g_str_has_prefix(folder, _("trash"))) - type = TNY_MSG_FOLDER_TYPE_JUNK; + type = TNY_FOLDER_TYPE_JUNK; else if (g_str_has_prefix(folder, "sent") || g_str_has_prefix(folder, _("sent"))) - type = TNY_MSG_FOLDER_TYPE_SENT; + type = TNY_FOLDER_TYPE_SENT; /* these are not *really* TNY_ types */ else if (g_str_has_prefix(folder, "draft") || g_str_has_prefix(folder, _("draft"))) - type = TNY_MSG_FOLDER_TYPE_DRAFTS; + type = TNY_FOLDER_TYPE_DRAFTS; else if (g_str_has_prefix(folder, "notes") || g_str_has_prefix(folder, _("notes"))) - type = TNY_MSG_FOLDER_TYPE_NOTES; + type = TNY_FOLDER_TYPE_NOTES; else if (g_str_has_prefix(folder, "contacts") || g_str_has_prefix(folder, _("contacts"))) - type = TNY_MSG_FOLDER_TYPE_CONTACTS; + type = TNY_FOLDER_TYPE_CONTACTS; else if (g_str_has_prefix(folder, "calendar") || g_str_has_prefix(folder, _("calendar"))) - type = TNY_MSG_FOLDER_TYPE_CALENDAR; + type = TNY_FOLDER_TYPE_CALENDAR; g_free (folder); return type; @@ -215,7 +215,7 @@ icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, { GObject *rendobj; GdkPixbuf *pixbuf; - TnyMsgFolderType type; + TnyFolderType type; gchar *fname = NULL; gint unread; @@ -226,40 +226,40 @@ icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN, &unread, -1); rendobj = G_OBJECT(renderer); - if (type == TNY_MSG_FOLDER_TYPE_NORMAL) + if (type == TNY_FOLDER_TYPE_NORMAL) type = guess_folder_type (fname); - if (fname); + if (fname) g_free (fname); switch (type) { - case TNY_MSG_FOLDER_TYPE_INBOX: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_INBOX); + case TNY_FOLDER_TYPE_INBOX: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_INBOX); break; - case TNY_MSG_FOLDER_TYPE_OUTBOX: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_OUTBOX); + case TNY_FOLDER_TYPE_OUTBOX: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_OUTBOX); break; - case TNY_MSG_FOLDER_TYPE_JUNK: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_JUNK); + case TNY_FOLDER_TYPE_JUNK: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_JUNK); break; - case TNY_MSG_FOLDER_TYPE_SENT: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_SENT); + case TNY_FOLDER_TYPE_SENT: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_SENT); break; - case TNY_MSG_FOLDER_TYPE_DRAFTS: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_DRAFTS); + case TNY_FOLDER_TYPE_DRAFTS: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_DRAFTS); break; - case TNY_MSG_FOLDER_TYPE_NOTES: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NOTES); + case TNY_FOLDER_TYPE_NOTES: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_NOTES); break; - case TNY_MSG_FOLDER_TYPE_CALENDAR: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CALENDAR); + case TNY_FOLDER_TYPE_CALENDAR: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_CALENDAR); break; - case TNY_MSG_FOLDER_TYPE_CONTACTS: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CONTACTS); + case TNY_FOLDER_TYPE_CONTACTS: + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_CONTACTS); break; - case TNY_MSG_FOLDER_TYPE_NORMAL: + case TNY_FOLDER_TYPE_NORMAL: default: - pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NORMAL); + pixbuf = modest_icon_factory_get_small_icon (MODEST_FOLDER_ICON_NORMAL); break; } @@ -352,7 +352,8 @@ on_account_update (TnyAccountStoreIface *account_store, const gchar *account, { update_model_empty (MODEST_FOLDER_VIEW(user_data)); - if (!update_model (MODEST_FOLDER_VIEW(user_data), account_store)) + if (!update_model (MODEST_FOLDER_VIEW(user_data), + MODEST_TNY_ACCOUNT_STORE(account_store))) g_printerr ("modest: failed to update model for changes in '%s'", account); } @@ -370,7 +371,8 @@ modest_folder_view_new (ModestTnyAccountStore *account_store) self = G_OBJECT(g_object_new(MODEST_TYPE_FOLDER_VIEW, NULL)); priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self); - if (!update_model (MODEST_FOLDER_VIEW(self), TNY_ACCOUNT_STORE_IFACE(account_store))) + if (!update_model (MODEST_FOLDER_VIEW(self), + MODEST_TNY_ACCOUNT_STORE(account_store))) g_printerr ("modest: failed to update model"); priv->sig1 = g_signal_connect (G_OBJECT(account_store), "account_update", @@ -452,7 +454,7 @@ static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data) { GtkTreeModel *model; - TnyMsgFolderIface *folder = NULL; + TnyFolderIface *folder = NULL; GtkTreeIter iter; ModestFolderView *tree_view; ModestFolderViewPrivate *priv; @@ -468,7 +470,7 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data) /* folder was _un_selected if true */ if (!gtk_tree_selection_get_selected (sel, &model, &iter)) { - priv->cur_folder = NULL; + priv->cur_folder = NULL; /* FIXME: need this? */ return; } @@ -479,7 +481,7 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data) &folder, -1); if (priv->cur_folder) - tny_msg_folder_iface_expunge (priv->cur_folder); + tny_folder_iface_expunge (priv->cur_folder); priv->cur_folder = folder; /* folder will not be defined if you click eg. on the root node */ diff --git a/src/widgets/modest-folder-view.h b/src/widgets/modest-folder-view.h index ac2daa1..f8c8a79 100644 --- a/src/widgets/modest-folder-view.h +++ b/src/widgets/modest-folder-view.h @@ -57,7 +57,7 @@ struct _ModestFolderViewClass { /* emitted when a folder is clicked */ void (*folder_selected) (ModestFolderView* self, - TnyMsgFolderIface *folder, + TnyFolderIface *folder, gpointer user_data); gboolean (*update_model) (ModestFolderView *self, diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index 0bcfee8..dfae1bd 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -27,9 +27,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* modest-tny-header-tree-view.c */ - #include #include "modest-header-view.h" #include @@ -47,6 +44,7 @@ static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data) enum { MESSAGE_SELECTED_SIGNAL, + ITEM_NOT_FOUND_SIGNAL, STATUS_UPDATE_SIGNAL, LAST_SIGNAL }; @@ -55,7 +53,7 @@ enum { typedef struct _ModestHeaderViewPrivate ModestHeaderViewPrivate; struct _ModestHeaderViewPrivate { - TnyMsgFolderIface *tny_msg_folder; + TnyFolderIface *tny_folder; TnyListIface *headers; GSList *columns; GMutex *lock; @@ -88,6 +86,7 @@ modest_header_view_get_type (void) sizeof(ModestHeaderView), 1, /* n_preallocs */ (GInstanceInitFunc) modest_header_view_init, + NULL }; my_type = g_type_register_static (GTK_TYPE_TREE_VIEW, "ModestHeaderView", @@ -115,7 +114,16 @@ modest_header_view_class_init (ModestHeaderViewClass *klass) NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - + + signals[ITEM_NOT_FOUND_SIGNAL] = + g_signal_new ("item_not_found", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestHeaderViewClass,message_not_found), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + signals[STATUS_UPDATE_SIGNAL] = g_signal_new ("status_update", G_TYPE_FROM_CLASS (gobject_class), @@ -126,26 +134,22 @@ modest_header_view_class_init (ModestHeaderViewClass *klass) G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); } - - - - static void msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { - TnyMsgHeaderFlags flags; + TnyHeaderFlags flags; GdkPixbuf *pixbuf = NULL; - gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, + gtk_tree_model_get (tree_model, iter, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); - if (flags & TNY_MSG_HEADER_FLAG_DELETED) - pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_DELETED); - else if (flags & TNY_MSG_HEADER_FLAG_SEEN) - pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_READ); + if (flags & TNY_HEADER_FLAG_DELETED) + pixbuf = modest_icon_factory_get_small_icon (MODEST_HEADER_ICON_DELETED); + else if (flags & TNY_HEADER_FLAG_SEEN) + pixbuf = modest_icon_factory_get_small_icon (MODEST_HEADER_ICON_READ); else - pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_UNREAD); + pixbuf = modest_icon_factory_get_small_icon (MODEST_HEADER_ICON_UNREAD); g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); } @@ -154,14 +158,14 @@ static void attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { - TnyMsgHeaderFlags flags; + TnyHeaderFlags flags; GdkPixbuf *pixbuf = NULL; - gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, + gtk_tree_model_get (tree_model, iter, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); - if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS) - pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_ATTACH); + if (flags & TNY_HEADER_FLAG_ATTACHMENTS) + pixbuf = modest_icon_factory_get_small_icon (MODEST_HEADER_ICON_ATTACH); g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); } @@ -171,14 +175,14 @@ static void header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { - TnyMsgHeaderFlags flags; + TnyHeaderFlags flags; - gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, + gtk_tree_model_get (tree_model, iter, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); g_object_set (G_OBJECT(renderer), - "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800, - "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ? + "weight", (flags & TNY_HEADER_FLAG_SEEN) ? 400: 800, + "style", (flags & TNY_HEADER_FLAG_DELETED) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL, NULL); } @@ -217,27 +221,27 @@ static void sender_receiver_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gboolean is_sender) { - TnyMsgHeaderFlags flags; + TnyHeaderFlags flags; gchar *address; gint sender_receiver_col; if (is_sender) - sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN; + sender_receiver_col = TNY_HEADER_LIST_MODEL_FROM_COLUMN; else - sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN; + sender_receiver_col = TNY_HEADER_LIST_MODEL_TO_COLUMN; gtk_tree_model_get (tree_model, iter, sender_receiver_col, &address, - TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, + TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); g_object_set (G_OBJECT(renderer), "text", display_address (address), "weight", - (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400 : 800, + (flags & TNY_HEADER_FLAG_SEEN) ? 400 : 800, "style", - (flags & TNY_MSG_HEADER_FLAG_DELETED)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL, + (flags & TNY_HEADER_FLAG_DELETED)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL, NULL); g_free (address); @@ -289,16 +293,16 @@ compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { GObject *rendobj; - TnyMsgHeaderFlags flags; + TnyHeaderFlags flags; gchar *from, *subject; gchar *header; time_t date; gtk_tree_model_get (tree_model, iter, - TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, - TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &from, - TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject, - TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date, + TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, + TNY_HEADER_LIST_MODEL_FROM_COLUMN, &from, + TNY_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject, + TNY_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date, -1); rendobj = G_OBJECT(renderer); @@ -309,8 +313,8 @@ compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer g_object_set (G_OBJECT(renderer), "text", header, - "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800, - "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ? + "weight", (flags & TNY_HEADER_FLAG_SEEN) ? 400: 800, + "style", (flags & TNY_HEADER_FLAG_DELETED) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL, NULL); g_free (header); @@ -393,7 +397,7 @@ init_columns (ModestHeaderView *obj) case MODEST_HEADER_VIEW_COLUMN_MSGTYPE: column = get_new_column (_("M"), renderer_msgtype, FALSE, - TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, + TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, FALSE, (GtkTreeCellDataFunc)msgtype_cell_data, NULL); break; @@ -401,42 +405,42 @@ init_columns (ModestHeaderView *obj) case MODEST_HEADER_VIEW_COLUMN_ATTACH: column = get_new_column (_("A"), renderer_attach, FALSE, - TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, + TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, FALSE, (GtkTreeCellDataFunc)attach_cell_data, NULL); break; case MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE: column = get_new_column (_("Received"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN, TRUE, (GtkTreeCellDataFunc)header_cell_data, NULL); break; case MODEST_HEADER_VIEW_COLUMN_FROM: column = get_new_column (_("From"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, + TNY_HEADER_LIST_MODEL_FROM_COLUMN, TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data, GINT_TO_POINTER(TRUE)); break; case MODEST_HEADER_VIEW_COLUMN_TO: column = get_new_column (_("To"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, + TNY_HEADER_LIST_MODEL_TO_COLUMN, TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data, GINT_TO_POINTER(FALSE)); break; case MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER: column = get_new_column (_("Header"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, + TNY_HEADER_LIST_MODEL_FROM_COLUMN, TRUE, (GtkTreeCellDataFunc)compact_header_cell_data, NULL); break; case MODEST_HEADER_VIEW_COLUMN_SUBJECT: column = get_new_column (_("Subject"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, + TNY_HEADER_LIST_MODEL_SUBJECT_COLUMN, TRUE, (GtkTreeCellDataFunc)header_cell_data, NULL); break; @@ -444,7 +448,7 @@ init_columns (ModestHeaderView *obj) case MODEST_HEADER_VIEW_COLUMN_SENT_DATE: column = get_new_column (_("Sent"), renderer_header, TRUE, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_SENT_COLUMN, TRUE, (GtkTreeCellDataFunc)header_cell_data, NULL); break; @@ -470,6 +474,7 @@ modest_header_view_init (ModestHeaderView *obj) priv = MODEST_HEADER_VIEW_GET_PRIVATE(obj); priv->lock = g_mutex_new (); + priv->sig1 = 0; } static void @@ -486,21 +491,25 @@ modest_header_view_finalize (GObject *obj) g_object_unref (G_OBJECT(priv->headers)); sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self)); - g_signal_handler_disconnect (G_OBJECT(sel), priv->sig1); + if (sel && priv->sig1 != 0) { + g_signal_handler_disconnect (G_OBJECT(sel), priv->sig1); + priv->sig1 = 0; + } + if (priv->lock) { g_mutex_free (priv->lock); priv->lock = NULL; } - priv->headers = NULL; - priv->tny_msg_folder = NULL; + priv->headers = NULL; + priv->tny_folder = NULL; G_OBJECT_CLASS(parent_class)->finalize (obj); } GtkWidget* -modest_header_view_new (TnyMsgFolderIface *folder, +modest_header_view_new (TnyFolderIface *folder, GSList *columns, ModestHeaderViewStyle style) { @@ -661,19 +670,19 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, case MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER: case MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE: gtk_tree_model_get (tree_model, iter1, - TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &t1,-1); gtk_tree_model_get (tree_model, iter2, - TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &t2,-1); return t1 - t2; case MODEST_HEADER_VIEW_COLUMN_SENT_DATE: gtk_tree_model_get (tree_model, iter1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1); gtk_tree_model_get (tree_model, iter2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1); return t1 - t2; @@ -682,12 +691,12 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, case MODEST_HEADER_VIEW_COLUMN_SUBJECT: { gtk_tree_model_get (tree_model, iter1, - TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, + TNY_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1); gtk_tree_model_get (tree_model, iter2, - TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, + TNY_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1); cmp = cmp_normalized_subject(s1, s2); @@ -701,12 +710,12 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, case MODEST_HEADER_VIEW_COLUMN_FROM: gtk_tree_model_get (tree_model, iter1, - TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, + TNY_HEADER_LIST_MODEL_FROM_COLUMN, &s1, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1); gtk_tree_model_get (tree_model, iter2, - TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, + TNY_HEADER_LIST_MODEL_FROM_COLUMN, &s2, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1); cmp = strcmp (s1, s2); g_free (s1); @@ -717,12 +726,12 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, case MODEST_HEADER_VIEW_COLUMN_TO: gtk_tree_model_get (tree_model, iter1, - TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, + TNY_HEADER_LIST_MODEL_TO_COLUMN, &s1, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1); gtk_tree_model_get (tree_model, iter2, - TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, + TNY_HEADER_LIST_MODEL_TO_COLUMN, &s2, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1); cmp = strcmp (s1, s2); g_free (s1); @@ -732,22 +741,22 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, case MODEST_HEADER_VIEW_COLUMN_ATTACH: - gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1); - gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1); + gtk_tree_model_get (tree_model, iter1, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1); + gtk_tree_model_get (tree_model, iter2, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1); - cmp = (val1 & TNY_MSG_HEADER_FLAG_ATTACHMENTS) - - (val2 & TNY_MSG_HEADER_FLAG_ATTACHMENTS); + cmp = (val1 & TNY_HEADER_FLAG_ATTACHMENTS) - + (val2 & TNY_HEADER_FLAG_ATTACHMENTS); return cmp ? cmp : t1 - t2; case MODEST_HEADER_VIEW_COLUMN_MSGTYPE: - gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1); - gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2, - TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1); - cmp = (val1 & TNY_MSG_HEADER_FLAG_SEEN) - (val2 & TNY_MSG_HEADER_FLAG_SEEN); + gtk_tree_model_get (tree_model, iter1, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1); + gtk_tree_model_get (tree_model, iter2, TNY_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2, + TNY_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1); + cmp = (val1 & TNY_HEADER_FLAG_SEEN) - (val2 & TNY_HEADER_FLAG_SEEN); return cmp ? cmp : t1 - t2; @@ -758,7 +767,7 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, static void -on_refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled, gpointer user_data) +on_refresh_folder (TnyFolderIface *folder, gboolean cancelled, gpointer user_data) { GtkTreeModel *oldsortable, *sortable; ModestHeaderView *self; @@ -770,7 +779,6 @@ on_refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled, gpointer user_ self = MODEST_HEADER_VIEW(user_data); priv = MODEST_HEADER_VIEW_GET_PRIVATE(self); - g_mutex_lock (priv->lock); if (!folder) /* when there is no folder */ @@ -779,10 +787,10 @@ on_refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled, gpointer user_ else { /* it's a new one or a refresh */ GSList *col; - priv->headers = TNY_LIST_IFACE(tny_msg_header_list_model_new ()); + priv->headers = TNY_LIST_IFACE(tny_header_list_model_new ()); - tny_msg_folder_iface_get_headers (folder, priv->headers, FALSE); - tny_msg_header_list_model_set_folder (TNY_MSG_HEADER_LIST_MODEL(priv->headers), + tny_folder_iface_get_headers (folder, priv->headers, FALSE); + tny_header_list_model_set_folder (TNY_HEADER_LIST_MODEL(priv->headers), folder, TRUE); /* async */ oldsortable = gtk_tree_view_get_model(GTK_TREE_VIEW (self)); @@ -816,7 +824,7 @@ on_refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled, gpointer user_ static void -on_refresh_folder_status_update (TnyMsgFolderIface *folder, const gchar *msg, +on_refresh_folder_status_update (TnyFolderIface *folder, const gchar *msg, gint status_id, gpointer user_data) { ModestHeaderView *self; @@ -833,7 +841,7 @@ on_refresh_folder_status_update (TnyMsgFolderIface *folder, const gchar *msg, gboolean modest_header_view_set_folder (ModestHeaderView *self, - TnyMsgFolderIface *folder) + TnyFolderIface *folder) { ModestHeaderViewPrivate *priv; priv = MODEST_HEADER_VIEW_GET_PRIVATE(self); @@ -848,7 +856,7 @@ modest_header_view_set_folder (ModestHeaderView *self, if (model) g_object_unref (model); } else { /* it's a new one or a refresh */ - tny_msg_folder_iface_refresh_async (folder, + tny_folder_iface_refresh_async (folder, on_refresh_folder, on_refresh_folder_status_update, self); @@ -868,48 +876,52 @@ modest_header_view_set_folder (ModestHeaderView *self, static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data) { - GtkTreeModel *model; - TnyMsgHeaderIface *header; - GtkTreeIter iter; + GtkTreeModel *model; + TnyHeaderIface *header; + GtkTreeIter iter; ModestHeaderView *self; ModestHeaderViewPrivate *priv; + const TnyMsgIface *msg = NULL; + const TnyFolderIface *folder; g_return_if_fail (sel); g_return_if_fail (user_data); self = MODEST_HEADER_VIEW (user_data); priv = MODEST_HEADER_VIEW_GET_PRIVATE(self); - - + if (!gtk_tree_selection_get_selected (sel, &model, &iter)) return; /* msg was _un_selected */ gtk_tree_model_get (model, &iter, - TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN, + TNY_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); - if (header) { - const TnyMsgIface *msg = NULL; - const TnyMsgFolderIface *folder; - - folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header)); - if (!folder) - g_printerr ("modest: cannot find folder\n"); - else { - msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder), - header); - if (!msg) { - g_printerr ("modest: cannot find msg\n"); - gtk_tree_store_remove (GTK_TREE_STORE(model), - &iter); - } - } + if (!header) { + g_printerr ("modest: cannot find header\n"); + return; + } + + folder = tny_header_iface_get_folder (TNY_HEADER_IFACE(header)); + if (!folder) { + g_signal_emit (G_OBJECT(self), signals[ITEM_NOT_FOUND_SIGNAL], 0, + MODEST_ITEM_TYPE_FOLDER); + return; + } + + msg = tny_folder_iface_get_message (TNY_FOLDER_IFACE(folder), + header); + if (!msg) { + g_signal_emit (G_OBJECT(self), signals[ITEM_NOT_FOUND_SIGNAL], 0, + MODEST_ITEM_TYPE_MESSAGE); + return; + } - g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0, - msg); + g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0, + msg); + + /* mark message as seen; _set_flags crashes, bug in tinymail? */ + //flags = tny_header_iface_get_flags (TNY_HEADER_IFACE(header)); + //tny_header_iface_set_flags (header, TNY_HEADER_FLAG_SEEN); +} - /* mark message as seen; _set_flags crashes, bug in tinymail? */ - //flags = tny_msg_header_iface_get_flags (TNY_MSG_HEADER_IFACE(header)); - //tny_msg_header_iface_set_flags (header, TNY_MSG_HEADER_FLAG_SEEN); - } -} diff --git a/src/widgets/modest-header-view.h b/src/widgets/modest-header-view.h index 7cdd2bc..da23d72 100644 --- a/src/widgets/modest-header-view.h +++ b/src/widgets/modest-header-view.h @@ -31,11 +31,11 @@ #define __MODEST_HEADER_VIEW_H__ #include -#include +#include #include #include -#include -#include +#include +#include G_BEGIN_DECLS @@ -55,6 +55,8 @@ struct _ModestHeaderView { /* insert public members, if any */ }; +typedef enum _ModestItemType ModestItemType; + struct _ModestHeaderViewClass { GtkTreeViewClass parent_class; @@ -62,6 +64,10 @@ struct _ModestHeaderViewClass { TnyMsgIface *msg, gpointer user_data); + void (*message_not_found) (ModestHeaderView* self, + ModestItemType type, + gpointer user_data); + /* msg == NULL implies that the operation is finished, ie. * the progress indictation can be hidden */ void (*status_update) (ModestHeaderView* self, @@ -85,15 +91,19 @@ enum _ModestHeaderViewColumn { }; typedef enum _ModestHeaderViewColumn ModestHeaderViewColumn; - enum _ModestHeaderViewStyle { MODEST_HEADER_VIEW_STYLE_NORMAL, MODEST_HEADER_VIEW_STYLE_COMPACT, - MODEST_HEADER_VIEW_STYLE_NUM }; typedef enum _ModestHeaderViewStyle ModestHeaderViewStyle; +enum _ModestItemType { + MODEST_ITEM_TYPE_MESSAGE, + MODEST_ITEM_TYPE_FOLDER, + MODEST_ITEM_TYPE_NUM +}; + /** * modest_header_view_get_type: @@ -116,21 +126,21 @@ GType modest_header_view_get_type (void) G_GNUC_CONST; * * Returns: a new GtkWidget (a GtkTreeView-subclass) */ -GtkWidget* modest_header_view_new (TnyMsgFolderIface *folder, - GSList *columns, - ModestHeaderViewStyle style); +GtkWidget* modest_header_view_new (TnyFolderIface *folder, + GSList *columns, + ModestHeaderViewStyle style); /** * modest_header_view_set_folder: * @self: a ModestHeaderView instance - * @folder: a TnyMsgFolderIface object + * @folder: a TnyFolderIface object * * set the folder for this ModestHeaderView * * Returns: TRUE if it succeeded, FALSE otherwise */ gboolean modest_header_view_set_folder (ModestHeaderView *self, - TnyMsgFolderIface *folder); + TnyFolderIface *folder); /** @@ -143,11 +153,11 @@ gboolean modest_header_view_set_folder (ModestHeaderView *self, * Returns: TRUE if it succeeded, FALSE otherwise */ gboolean modest_header_view_set_columns (ModestHeaderView *self, - GSList *columns); + GSList *columns); /** * modest_header_view_get_columns: * @self: a ModestHeaderView instance - * @folder: a TnyMsgFolderIface object + * @folder: a TnyFolderIface object * * get the columns for this ModestHeaderView * @@ -161,21 +171,20 @@ const GSList* modest_header_view_get_columns (ModestHeaderView *self); * @self: a ModestHeaderView instance * @style: the style for this tree view * - * set the folder for this ModestHeaderView + * set the style this ModestHeaderView * * Returns: TRUE if it succeeded, FALSE otherwise */ gboolean modest_header_view_set_style (ModestHeaderView *self, - ModestHeaderViewStyle style); + ModestHeaderViewStyle style); /** * modest_header_view_set_folder: * @self: a ModestHeaderView instance - * @folder: a TnyMsgFolderIface object * - * set the folder for this ModestHeaderView + * get the style for this ModestHeaderView * - * Returns: TRUE if it succeeded, FALSE otherwise + * Returns: the current style */ ModestHeaderViewStyle modest_header_view_get_style (ModestHeaderView *self); diff --git a/src/widgets/modest-msg-view.c b/src/widgets/modest-msg-view.c index dcdcba5..e11ae91 100644 --- a/src/widgets/modest-msg-view.c +++ b/src/widgets/modest-msg-view.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "modest-msg-view.h" @@ -49,13 +50,10 @@ static void modest_msg_view_finalize (GObject *obj); static GSList* get_url_matches (GString *txt); -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, +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); -static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, - ModestMsgView *msg_view); +static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view); /* * we need these regexps to find URLs in plain text e-mails @@ -65,7 +63,6 @@ struct _UrlMatchPattern { gchar *regex; regex_t *preg; gchar *prefix; - }; #define ATT_PREFIX "att:" @@ -96,8 +93,11 @@ enum { typedef struct _ModestMsgViewPrivate ModestMsgViewPrivate; struct _ModestMsgViewPrivate { - GtkWidget *gtkhtml; - const TnyMsgIface *msg; + + GtkWidget *gtkhtml; + TnyMsgIface *msg; + + gulong sig1, sig2, sig3; }; #define MODEST_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_MSG_VIEW, \ @@ -123,6 +123,7 @@ modest_msg_view_get_type (void) sizeof(ModestMsgView), 1, /* n_preallocs */ (GInstanceInitFunc) modest_msg_view_init, + NULL }; my_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW, "ModestMsgView", @@ -187,26 +188,37 @@ modest_msg_view_init (ModestMsgView *obj) gtk_html_set_blocking (GTK_HTML(priv->gtkhtml), FALSE); gtk_html_set_images_blocking (GTK_HTML(priv->gtkhtml), FALSE); - g_signal_connect (G_OBJECT(priv->gtkhtml), "link_clicked", - G_CALLBACK(on_link_clicked), obj); - - g_signal_connect (G_OBJECT(priv->gtkhtml), "url_requested", - G_CALLBACK(on_url_requested), obj); - - g_signal_connect (G_OBJECT(priv->gtkhtml), "on_url", - G_CALLBACK(on_link_hover), obj); + priv->sig1 = g_signal_connect (G_OBJECT(priv->gtkhtml), "link_clicked", + G_CALLBACK(on_link_clicked), obj); + priv->sig2 = g_signal_connect (G_OBJECT(priv->gtkhtml), "url_requested", + G_CALLBACK(on_url_requested), obj); + priv->sig3 = g_signal_connect (G_OBJECT(priv->gtkhtml), "on_url", + G_CALLBACK(on_link_hover), obj); } static void modest_msg_view_finalize (GObject *obj) { + ModestMsgViewPrivate *priv; + priv = MODEST_MSG_VIEW_GET_PRIVATE (obj); + + if (priv->msg) { + g_object_unref (G_OBJECT(priv->msg)); + priv->msg = NULL; + } + + /* we cannot disconnect sigs, because priv->gtkhtml is + * already dead */ + + priv->gtkhtml = NULL; + G_OBJECT_CLASS(parent_class)->finalize (obj); } GtkWidget* -modest_msg_view_new (const TnyMsgIface *msg) +modest_msg_view_new (TnyMsgIface *msg) { GObject *obj; ModestMsgView* self; @@ -275,23 +287,25 @@ on_link_hover (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) -static TnyMsgMimePartIface * -find_cid_image (const TnyMsgIface *msg, const gchar *cid) +static TnyMimePartIface * +find_cid_image (TnyMsgIface *msg, const gchar *cid) { - TnyMsgMimePartIface *part = NULL; - const TnyListIface *parts; + TnyMimePartIface *part = NULL; + TnyListIface *parts; TnyIteratorIface *iter; g_return_val_if_fail (msg, NULL); g_return_val_if_fail (cid, NULL); - parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg); // FIXME: tinymail - iter = tny_list_iface_create_iterator ((TnyListIface*)parts); + parts = TNY_LIST_IFACE (tny_list_new()); + + tny_msg_iface_get_parts (msg, parts); + iter = tny_list_iface_create_iterator (parts); while (!tny_iterator_iface_is_done(iter)) { const gchar *part_cid; - part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current(iter)); - part_cid = tny_msg_mime_part_iface_get_content_id (part); + part = TNY_MIME_PART_IFACE(tny_iterator_iface_current(iter)); + part_cid = tny_mime_part_iface_get_content_id (part); if (part_cid && strcmp (cid, part_cid) == 0) break; @@ -299,8 +313,13 @@ find_cid_image (const TnyMsgIface *msg, const gchar *cid) part = NULL; tny_iterator_iface_next (iter); } + + if (part) + g_object_ref (G_OBJECT(part)); g_object_unref (G_OBJECT(iter)); + g_object_unref (G_OBJECT(parts)); + return part; } @@ -315,17 +334,19 @@ on_url_requested (GtkWidget *widget, const gchar *uri, if (g_str_has_prefix (uri, "cid:")) { /* +4 ==> skip "cid:" */ - const TnyMsgMimePartIface *part = find_cid_image (priv->msg, uri + 4); + TnyMimePartIface *part = find_cid_image (priv->msg, uri + 4); if (!part) { g_printerr ("modest: '%s' not found\n", uri + 4); gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); } else { TnyStreamIface *tny_stream = TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new(stream)); - // FIXME: tinymail - tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)part, + tny_mime_part_iface_decode_to_stream ((TnyMimePartIface*)part, tny_stream); gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); + + g_object_unref (G_OBJECT(tny_stream)); + g_object_unref (G_OBJECT(part)); } } @@ -343,11 +364,11 @@ typedef struct { /* render the attachments as hyperlinks in html */ static gchar* -attachments_as_html (ModestMsgView *self, const TnyMsgIface *msg) +attachments_as_html (ModestMsgView *self, TnyMsgIface *msg) { ModestMsgViewPrivate *priv; GString *appendix; - const TnyListIface *parts; + TnyListIface *parts; TnyIteratorIface *iter; gchar *html; int index = 0; @@ -356,22 +377,23 @@ attachments_as_html (ModestMsgView *self, const TnyMsgIface *msg) return NULL; priv = MODEST_MSG_VIEW_GET_PRIVATE (self); - parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg); - // FIXME: tinymail - iter = tny_list_iface_create_iterator ((TnyListIface*)parts); + parts = TNY_LIST_IFACE(tny_list_new()); + tny_msg_iface_get_parts (msg, parts); + iter = tny_list_iface_create_iterator (parts); + appendix= g_string_new (""); while (!tny_iterator_iface_is_done(iter)) { - TnyMsgMimePartIface *part; + TnyMimePartIface *part; ++index; /* attachment numbers are 1-based */ - part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current (iter)); + part = TNY_MIME_PART_IFACE(tny_iterator_iface_current (iter)); - if (tny_msg_mime_part_iface_is_attachment (part)) { + if (tny_mime_part_iface_is_attachment (part)) { - const gchar *filename = tny_msg_mime_part_iface_get_filename(part); + const gchar *filename = tny_mime_part_iface_get_filename(part); if (!filename) filename = _("attachment"); @@ -430,7 +452,7 @@ hyperlinkify_plain_text (GString *txt) static gchar * convert_to_html (const gchar *data) { - int i; + guint i; gboolean first_space = TRUE; GString *html; gsize len; @@ -502,7 +524,7 @@ cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2) /* * check if the match is inside an existing match... */ static void -chk_partial_match (const url_match_t *match, int* offset) +chk_partial_match (const url_match_t *match, guint* offset) { if (*offset >= match->offset && *offset < match->offset + match->len) *offset = -1; @@ -512,7 +534,7 @@ static GSList* get_url_matches (GString *txt) { regmatch_t rm; - int rv, i, offset = 0; + guint rv, i, offset = 0; GSList *match_list = NULL; static UrlMatchPattern patterns[] = MAIL_VIEWER_URL_MATCH_PATTERNS; @@ -571,8 +593,7 @@ get_url_matches (GString *txt) static gboolean -set_html_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body, - const TnyMsgIface *msg) +set_html_message (ModestMsgView *self, TnyMimePartIface *tny_body, TnyMsgIface *msg) { gchar *html_attachments; TnyStreamIface *gtkhtml_stream; @@ -598,7 +619,7 @@ set_html_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body, } // FIXME: tinymail - tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body, + tny_mime_part_iface_decode_to_stream ((TnyMimePartIface*)tny_body, gtkhtml_stream); g_object_unref (G_OBJECT(gtkhtml_stream)); @@ -610,8 +631,7 @@ set_html_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body, /* 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 TnyMsgMimePartIface *tny_body, - const TnyMsgIface *msg) +set_text_message (ModestMsgView *self, TnyMimePartIface *tny_body, TnyMsgIface *msg) { GtkTextBuffer *buf; GtkTextIter begin, end; @@ -642,7 +662,7 @@ set_text_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body, } // FIXME: tinymail - tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body, + tny_mime_part_iface_decode_to_stream ((TnyMimePartIface*)tny_body, txt_stream); tny_stream_iface_reset (txt_stream); @@ -705,16 +725,23 @@ modest_msg_view_get_selected_text (ModestMsgView *self) void -modest_msg_view_set_message (ModestMsgView *self, const TnyMsgIface *msg) +modest_msg_view_set_message (ModestMsgView *self, TnyMsgIface *msg) { - TnyMsgMimePartIface *body; + TnyMimePartIface *body; ModestMsgViewPrivate *priv; g_return_if_fail (self); priv = MODEST_MSG_VIEW_GET_PRIVATE(self); - priv->msg = msg; + + if (msg != priv->msg) { + if (priv->msg) + g_object_unref (G_OBJECT(priv->msg)); + if (msg) + g_object_ref (G_OBJECT(msg)); + priv->msg = msg; + } if (!msg) { set_empty_message (self); @@ -723,7 +750,7 @@ modest_msg_view_set_message (ModestMsgView *self, const TnyMsgIface *msg) body = modest_tny_msg_actions_find_body_part (msg, TRUE); if (body) { - if (tny_msg_mime_part_iface_content_type_is (body, "text/html")) + if (tny_mime_part_iface_content_type_is (body, "text/html")) set_html_message (self, body, msg); else set_text_message (self, body, msg); diff --git a/src/widgets/modest-msg-view.h b/src/widgets/modest-msg-view.h index 40cc531..e062027 100644 --- a/src/widgets/modest-msg-view.h +++ b/src/widgets/modest-msg-view.h @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include G_BEGIN_DECLS @@ -88,7 +88,7 @@ GType modest_msg_view_get_type (void) G_GNUC_CONST; * * Returns: a new ModestMsgView widget, or NULL if there's an error */ -GtkWidget* modest_msg_view_new (const TnyMsgIface *tny_msg); +GtkWidget* modest_msg_view_new (TnyMsgIface *tny_msg); /** @@ -99,8 +99,7 @@ GtkWidget* modest_msg_view_new (const TnyMsgIface *tny_msg); * display the @tny_msg e-mail message. If @tny_msg is NULL, * then a blank page will be displayed * */ -void modest_msg_view_set_message (ModestMsgView *self, - const TnyMsgIface *tny_msg); +void modest_msg_view_set_message (ModestMsgView *self, TnyMsgIface *tny_msg); /** * modest_msg_view_get_selected_text: diff --git a/src/widgets/modest-toolbar.c b/src/widgets/modest-toolbar.c new file mode 100644 index 0000000..b2bae62 --- /dev/null +++ b/src/widgets/modest-toolbar.c @@ -0,0 +1,252 @@ +/* Copyright (c) 2006, 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 "modest-toolbar.h" + +/* 'private'/'protected' functions */ +static void modest_toolbar_class_init (ModestToolbarClass *klass); +static void modest_toolbar_init (ModestToolbar *obj); +static void modest_toolbar_finalize (GObject *obj); + +static void on_toolbutton_clicked (GtkToolButton *button, ModestToolbar *self); + +/* list my signals */ +enum { + BUTTON_CLICKED_SIGNAL, + LAST_SIGNAL +}; + +typedef struct _ModestToolbarPrivate ModestToolbarPrivate; +struct _ModestToolbarPrivate { + GtkTooltips *tooltips; + +}; +#define MODEST_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_TOOLBAR, \ + ModestToolbarPrivate)) +/* globals */ +static GtkToolbarClass *parent_class = NULL; + +static guint signals[LAST_SIGNAL] = {0}; + +GType +modest_toolbar_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestToolbarClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_toolbar_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestToolbar), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_toolbar_init, + NULL + }; + my_type = g_type_register_static (GTK_TYPE_TOOLBAR, + "ModestToolbar", + &my_info, 0); + } + return my_type; +} + +static void +modest_toolbar_class_init (ModestToolbarClass *klass) +{ + GObjectClass *gobject_class; + gobject_class = (GObjectClass*) klass; + + parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = modest_toolbar_finalize; + + g_type_class_add_private (gobject_class, sizeof(ModestToolbarPrivate)); + + signals[BUTTON_CLICKED_SIGNAL] = + g_signal_new ("button_clicked", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestToolbarClass, button_clicked), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); +} + +static void +modest_toolbar_init (ModestToolbar *obj) +{ + +} + +static void +modest_toolbar_finalize (GObject *obj) +{ + G_OBJECT_CLASS(parent_class)->finalize (obj); +} + + +/* don't free icon_name/label/tooltip, they're static */ +static gboolean +data_for_button_id (ModestToolbarButton button_id, + gchar **icon_name, gchar **label, gchar **tooltip) +{ + switch (button_id) { + case MODEST_TOOLBAR_BUTTON_MAIL_SEND: + *label = _("Send"); + *tooltip = _("Send the current email message"); + *icon_name = MODEST_TOOLBAR_ICON_MAIL_SEND; + break; + case MODEST_TOOLBAR_BUTTON_NEW_MAIL: + *label = _("New mail"); + *tooltip = _("Compose a new email message"); + *icon_name = MODEST_TOOLBAR_ICON_NEW_MAIL; + break; + case MODEST_TOOLBAR_BUTTON_SEND_RECEIVE: + *label = _("Send/Receive"); + *tooltip = _("Send and receive messages"); + *icon_name = MODEST_TOOLBAR_ICON_SEND_RECEIVE; + break; + case MODEST_TOOLBAR_BUTTON_REPLY: + *label = _("Reply"); + *tooltip = _("Reply to the selected email message"); + *icon_name = MODEST_TOOLBAR_ICON_REPLY; + break; + case MODEST_TOOLBAR_BUTTON_REPLY_ALL: + *label = _("Reply all"); + *tooltip = _("Reply to all people the selected email was sent to"); + *icon_name = MODEST_TOOLBAR_ICON_REPLY_ALL; + break; + case MODEST_TOOLBAR_BUTTON_FORWARD: + *label = _("Forward"); + *tooltip = _("Forward the selected email"); + *icon_name = MODEST_TOOLBAR_ICON_FORWARD; + break; + case MODEST_TOOLBAR_BUTTON_DELETE: + *label = _("Delete"); + *tooltip = _("Delete the selected email message(s)"); + *icon_name = MODEST_TOOLBAR_ICON_DELETE; + break; + case MODEST_TOOLBAR_BUTTON_NEXT: + *label = _("Next"); + *tooltip = _("Move to the next message"); + *icon_name = MODEST_TOOLBAR_ICON_NEXT; + break; + case MODEST_TOOLBAR_BUTTON_PREV: + *label = _("Previous"); + *tooltip = _("Move to the previous message"); + *icon_name = MODEST_TOOLBAR_ICON_PREV; + break; + case MODEST_TOOLBAR_BUTTON_STOP: + *label = _("Stop"); + *tooltip = _("Stop whatever"); + *icon_name = MODEST_TOOLBAR_ICON_STOP; + break; + default: + g_printerr ("modest: not a valid button id: %d\n", + button_id); + return FALSE; + } + return TRUE; +} + + +static gboolean +modest_toolbar_set_buttons (ModestToolbar *self, const GSList *buttons) +{ + const GSList *cursor; + GtkTooltips *tooltips; + + g_return_val_if_fail (self, FALSE); + + tooltips = gtk_tooltips_new (); + gtk_tooltips_enable (tooltips); + gtk_toolbar_set_tooltips (GTK_TOOLBAR(self), TRUE); + + cursor = buttons; + while (cursor) { + ModestToolbarButton button_id = + (ModestToolbarButton) GPOINTER_TO_INT(cursor->data); + + if (button_id == MODEST_TOOLBAR_SEPARATOR) + gtk_toolbar_insert (GTK_TOOLBAR(self), + gtk_separator_tool_item_new(), -1); + else { + gchar *icon_name, *label, *tooltip; /* don't free these */ + if (!data_for_button_id (button_id, &icon_name, &label, &tooltip)) + g_printerr ("modest: error getting data for toolbar button %d\n", + button_id); + else { + GtkWidget *icon; + GtkToolItem *button; + GdkPixbuf *pixbuf; + + pixbuf = modest_icon_factory_get_icon_at_size (icon_name, 24, 24); + icon = gtk_image_new_from_pixbuf ((GdkPixbuf*)pixbuf); + button = gtk_tool_button_new (icon, label); + g_object_set_data (G_OBJECT(button), "button_id", + GINT_TO_POINTER(button_id)); + g_signal_connect (G_OBJECT(button), "clicked", + G_CALLBACK(on_toolbutton_clicked), self); + + gtk_tooltips_set_tip (tooltips, GTK_WIDGET(button),tooltip, NULL); + gtk_widget_show_all (GTK_WIDGET(button)); + gtk_toolbar_insert (GTK_TOOLBAR(self), button, -1); + } + } + cursor = cursor->next; + } + + return TRUE; /* FIXME */ +} + + +ModestToolbar* +modest_toolbar_new (const GSList *buttons) +{ + GObject *obj; + + obj = g_object_new(MODEST_TYPE_TOOLBAR, NULL); + modest_toolbar_set_buttons (MODEST_TOOLBAR(obj), buttons); + + return MODEST_TOOLBAR(obj); +} + +static void +on_toolbutton_clicked (GtkToolButton *button, ModestToolbar *self) +{ + gint button_id = GPOINTER_TO_INT( + g_object_get_data(G_OBJECT(button), "button_id")); + + g_signal_emit (G_OBJECT(self), signals[BUTTON_CLICKED_SIGNAL], + 0, button_id); +} + + diff --git a/src/widgets/modest-toolbar.h b/src/widgets/modest-toolbar.h new file mode 100644 index 0000000..0312265 --- /dev/null +++ b/src/widgets/modest-toolbar.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2006, 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_TOOLBAR_H__ +#define __MODEST_TOOLBAR_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_TOOLBAR (modest_toolbar_get_type()) +#define MODEST_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_TOOLBAR,ModestToolbar)) +#define MODEST_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_TOOLBAR,GtkToolbar)) +#define MODEST_IS_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_TOOLBAR)) +#define MODEST_IS_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_TOOLBAR)) +#define MODEST_TOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_TOOLBAR,ModestToolbarClass)) + +typedef struct _ModestToolbar ModestToolbar; +typedef struct _ModestToolbarClass ModestToolbarClass; + +typedef enum _ModestToolbarButton ModestToolbarButton; + + +struct _ModestToolbar { + GtkToolbar parent; + /* insert public members, if any */ +}; + +struct _ModestToolbarClass { + GtkToolbarClass parent_class; + + void (* button_clicked) (ModestToolbar* obj, ModestToolbarButton button_id); +}; + +enum _ModestToolbarButton { + MODEST_TOOLBAR_BUTTON_MAIL_SEND, + MODEST_TOOLBAR_BUTTON_NEW_MAIL, + MODEST_TOOLBAR_BUTTON_REPLY, + MODEST_TOOLBAR_BUTTON_REPLY_ALL, + MODEST_TOOLBAR_BUTTON_FORWARD, + MODEST_TOOLBAR_BUTTON_PRINT, + MODEST_TOOLBAR_BUTTON_DELETE, + MODEST_TOOLBAR_BUTTON_NEXT, + MODEST_TOOLBAR_BUTTON_PREV, + MODEST_TOOLBAR_BUTTON_STOP, + MODEST_TOOLBAR_BUTTON_SEND_RECEIVE, + + MODEST_TOOLBAR_SEPARATOR, + MODEST_TOOLBAR_BUTTON_NUM +}; + + +/* member functions */ +GType modest_toolbar_get_type (void) G_GNUC_CONST; + +ModestToolbar* modest_toolbar_new (const GSList *buttons); + +G_END_DECLS + +#endif /* __MODEST_TOOLBAR_H__ */ +