From 858dcb123ce986a26feea7fc41f368ab968e7d12 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Tue, 8 Mar 2011 00:50:24 +0200 Subject: [PATCH] * big cleanup, simplification for the message widget --- widgets/Makefile.am | 4 - widgets/mu-msg-body-view.c | 57 ++++++-- widgets/mu-msg-body-view.h | 1 + widgets/mu-msg-normal-view.c | 220 ----------------------------- widgets/mu-msg-normal-view.h | 67 --------- widgets/mu-msg-source-view.c | 179 ------------------------ widgets/mu-msg-source-view.h | 68 --------- widgets/mu-msg-view.c | 261 +++++++++++++++-------------------- widgets/mu-msg-view.h | 3 +- 9 files changed, 157 insertions(+), 703 deletions(-) delete mode 100644 widgets/mu-msg-normal-view.c delete mode 100644 widgets/mu-msg-normal-view.h delete mode 100644 widgets/mu-msg-source-view.c delete mode 100644 widgets/mu-msg-source-view.h diff --git a/widgets/Makefile.am b/widgets/Makefile.am index 5fbb4ace..b65449aa 100644 --- a/widgets/Makefile.am +++ b/widgets/Makefile.am @@ -39,10 +39,6 @@ libmuwidgets_la_SOURCES= \ mu-msg-body-view.h \ mu-msg-header-view.c \ mu-msg-header-view.h \ - mu-msg-normal-view.h \ - mu-msg-normal-view.c \ - mu-msg-source-view.h \ - mu-msg-source-view.c \ mu-msg-view.h \ mu-msg-view.c diff --git a/widgets/mu-msg-body-view.c b/widgets/mu-msg-body-view.c index 1ca9152e..4f3ba723 100644 --- a/widgets/mu-msg-body-view.c +++ b/widgets/mu-msg-body-view.c @@ -20,11 +20,17 @@ #include #include #include - - #include "mu-msg-body-view.h" #include +enum _ViewMode { + VIEW_MODE_MSG, + VIEW_MODE_SOURCE, + VIEW_MODE_NOTE, + + VIEW_MODE_NONE +}; +typedef enum _ViewMode ViewMode; /* 'private'/'protected' functions */ static void mu_msg_body_view_class_init (MuMsgBodyViewClass *klass); @@ -42,7 +48,7 @@ enum { struct _MuMsgBodyViewPrivate { WebKitWebSettings *_settings; MuMsg *_msg; - gboolean _internal_msg; + ViewMode _view_mode; }; #define MU_MSG_BODY_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MU_TYPE_MSG_BODY_VIEW, \ @@ -138,7 +144,7 @@ on_navigation_policy_decision_requested (MuMsgBodyView *self, WebKitWebFrame *fr * a Refresh link */ if (g_ascii_strncasecmp (uri, "cmd:", 4) == 0) { - if (self->_priv->_internal_msg) { + if (self->_priv->_view_mode == VIEW_MODE_NOTE) { g_signal_emit (G_OBJECT(self), signals[ACTION_REQUESTED], 0, uri + 4); @@ -199,14 +205,20 @@ popup_menu (MuMsgBodyView *self, guint button, guint32 activate_time) struct { const char* title; const char* action; + ViewMode mode; } actions[] = { - { "View source...", "view-source" } + { "View source...", "view-source", VIEW_MODE_MSG }, + { "View message...", "view-message", VIEW_MODE_SOURCE }, }; - + menu = gtk_menu_new (); for (i = 0; i != G_N_ELEMENTS(actions); ++i) { GtkWidget *item; + + if (self->_priv->_view_mode != actions[i].mode) + continue; + item = gtk_menu_item_new_with_label(actions[i].title); g_object_set_data (G_OBJECT(item), "action", (gpointer)actions[i].action); g_signal_connect (item, "activate", G_CALLBACK(on_menu_item_activate), @@ -225,8 +237,8 @@ on_button_press_event (MuMsgBodyView *self, GdkEventButton *event, gpointer data switch (event->button) { case 1: return FALSE; /* propagate, let widget handle it */ case 3: - /* no popup menus for internal messages */ - if (!self->_priv->_internal_msg) + /* no popup menus for notes */ + if (self->_priv->_view_mode != VIEW_MODE_NOTE) popup_menu (self, event->button, event->time); break; default: return TRUE; /* ignore */ @@ -242,7 +254,7 @@ mu_msg_body_view_init (MuMsgBodyView *obj) obj->_priv = MU_MSG_BODY_VIEW_GET_PRIVATE(obj); obj->_priv->_msg = NULL; - obj->_priv->_internal_msg = FALSE; + obj->_priv->_view_mode = VIEW_MODE_NONE; obj->_priv->_settings = webkit_web_settings_new (); g_object_set (G_OBJECT(obj->_priv->_settings), @@ -336,9 +348,32 @@ mu_msg_body_view_set_message (MuMsgBodyView *self, MuMsg *msg) else set_text (self, mu_msg_get_body_text (msg)); - self->_priv->_internal_msg = FALSE; + self->_priv->_view_mode = VIEW_MODE_MSG; } + +void +mu_msg_body_view_set_message_source (MuMsgBodyView *self, MuMsg *msg) +{ + const gchar *path; + gchar *data; + + g_return_if_fail (MU_IS_MSG_BODY_VIEW(self)); + g_return_if_fail (msg); + + path = msg ? mu_msg_get_path (msg) : NULL; + + if (path && g_file_get_contents (path, &data, NULL, NULL)) { + set_text (self, data); + g_free (data); + } else + set_text (self, ""); + + self->_priv->_view_mode = VIEW_MODE_SOURCE; +} + + + void mu_msg_body_view_set_note (MuMsgBodyView *self, const gchar *html) { @@ -351,5 +386,5 @@ mu_msg_body_view_set_note (MuMsgBodyView *self, const gchar *html) } set_html (self, html); - self->_priv->_internal_msg = TRUE; + self->_priv->_view_mode = VIEW_MODE_NOTE; } diff --git a/widgets/mu-msg-body-view.h b/widgets/mu-msg-body-view.h index 8d430043..9c6c5229 100644 --- a/widgets/mu-msg-body-view.h +++ b/widgets/mu-msg-body-view.h @@ -62,6 +62,7 @@ GtkWidget* mu_msg_body_view_new (void); void mu_msg_body_view_set_message (MuMsgBodyView *self, MuMsg *msg); void mu_msg_body_view_set_note (MuMsgBodyView *self, const gchar *html); +void mu_msg_body_view_set_message_source (MuMsgBodyView *self, MuMsg *msg); G_END_DECLS diff --git a/widgets/mu-msg-normal-view.c b/widgets/mu-msg-normal-view.c deleted file mode 100644 index 1cb7a50e..00000000 --- a/widgets/mu-msg-normal-view.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -** Copyright (C) 2011 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify it -** under the terms of the GNU General Public License as published by the -** Free Software Foundation; either version 3, or (at your option) any -** later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - - -#include "mu-msg-normal-view.h" - -#include "mu-msg-body-view.h" -#include "mu-msg-attach-view.h" -#include "mu-msg-header-view.h" -#include "mu-msg-part.h" - - -/* 'private'/'protected' functions */ -static void mu_msg_normal_view_class_init (MuMsgNormalViewClass *klass); -static void mu_msg_normal_view_init (MuMsgNormalView *obj); -static void mu_msg_normal_view_finalize (GObject *obj); - -/* list my signals */ -enum { - ACTION_REQUESTED, - /* MY_SIGNAL_2, */ - LAST_SIGNAL -}; - -struct _MuMsgNormalViewPrivate { - - GtkWidget *_headers; - GtkWidget *_body; - GtkWidget *_attach, *_attacharea; -}; -#define MU_MSG_NORMAL_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ - MU_TYPE_MSG_NORMAL_VIEW, \ - MuMsgNormalViewPrivate)) -/* globals */ -static GtkVBoxClass *parent_class = NULL; - - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE (MuMsgNormalView, mu_msg_normal_view, GTK_TYPE_VBOX); - -static void -mu_msg_normal_view_class_init (MuMsgNormalViewClass *klass) -{ - GObjectClass *gobject_class; - gobject_class = (GObjectClass*) klass; - - parent_class = g_type_class_peek_parent (klass); - gobject_class->finalize = mu_msg_normal_view_finalize; - - g_type_class_add_private (gobject_class, sizeof(MuMsgNormalViewPrivate)); - - signals[ACTION_REQUESTED] = - g_signal_new ("action-requested", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MuMsgNormalViewClass, - action_requested), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} - - -static GtkWidget* -get_header_widget (MuMsgNormalView *self) -{ - GtkWidget *scrolledwin; - - self->_priv->_headers = mu_msg_header_view_new (); - - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW(scrolledwin), - GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); - gtk_scrolled_window_add_with_viewport - (GTK_SCROLLED_WINDOW(scrolledwin), self->_priv->_headers); - - gtk_widget_show_all (scrolledwin); - - return scrolledwin; -} - -static void -on_body_action_requested (MuMsgBodyView *body, const char* action, - MuMsgNormalView *self) -{ - /* forward the signal */ - g_signal_emit (G_OBJECT(self), - signals[ACTION_REQUESTED], 0, action); -} - - -static GtkWidget* -get_body_widget (MuMsgNormalView *self) -{ - self->_priv->_body = mu_msg_body_view_new (); - g_signal_connect (self->_priv->_body, "action-requested", - G_CALLBACK(on_body_action_requested), self); - - gtk_widget_show (self->_priv->_body); - return self->_priv->_body; -} - - -static void -on_attach_activated (GtkWidget *w, guint partnum, MuMsg *msg) -{ - gchar *filepath; - - filepath = mu_msg_part_filepath_cache (msg, partnum); - if (filepath) { - mu_msg_part_save (msg, filepath, partnum, FALSE, TRUE); - mu_util_play (filepath, TRUE, FALSE); - g_free (filepath); - } -} - - -static GtkWidget* -get_attach_widget (MuMsgNormalView *self) -{ - self->_priv->_attach = mu_msg_attach_view_new (); - self->_priv->_attacharea = gtk_expander_new_with_mnemonic - ("_Attachments"); - - gtk_container_add (GTK_CONTAINER(self->_priv->_attacharea), - self->_priv->_attach); - g_signal_connect (self->_priv->_attach, "attach-activated", - G_CALLBACK(on_attach_activated), - self); - - return self->_priv->_attacharea; -} - -static void -mu_msg_normal_view_init (MuMsgNormalView *self) -{ - self->_priv = MU_MSG_NORMAL_VIEW_GET_PRIVATE(self); - - gtk_box_pack_start (GTK_BOX(self),get_header_widget (self), - TRUE, FALSE, 0); - gtk_box_pack_start (GTK_BOX(self), get_attach_widget (self), - FALSE, FALSE, 1); - gtk_box_pack_start (GTK_BOX(self), get_body_widget (self), - TRUE, TRUE, 0); -} - -static void -mu_msg_normal_view_finalize (GObject *obj) -{ -/* free/unref instance resources here */ - G_OBJECT_CLASS(parent_class)->finalize (obj); -} - -GtkWidget* -mu_msg_normal_view_new (void) -{ - return GTK_WIDGET(g_object_new(MU_TYPE_MSG_NORMAL_VIEW, NULL)); -} - - - -static void -update_attachment_area (MuMsgNormalView *self, MuMsg *msg) -{ - GtkExpander *exp; - gint attach_num; - gchar *label; - - attach_num = 0; - if (msg) - attach_num = mu_msg_attach_view_set_message - (MU_MSG_ATTACH_VIEW(self->_priv->_attach), msg); - - if (attach_num <= 0) { - gtk_widget_hide_all (self->_priv->_attacharea); - return; - } - - exp = GTK_EXPANDER(self->_priv->_attacharea); - - gtk_expander_set_use_markup (exp,TRUE); - label = g_strdup_printf ("_Attachments (%d)", attach_num); - gtk_expander_set_label (exp, label); - g_free (label); - - gtk_expander_set_expanded (exp, FALSE); - gtk_widget_show_all (self->_priv->_attacharea); -} - - -void -mu_msg_normal_view_set_message (MuMsgNormalView *self, MuMsg *msg) -{ - g_return_if_fail (MU_IS_MSG_NORMAL_VIEW(self)); - - mu_msg_header_view_set_message - (MU_MSG_HEADER_VIEW(self->_priv->_headers), msg); - mu_msg_body_view_set_message - (MU_MSG_BODY_VIEW(self->_priv->_body), msg); - - update_attachment_area (self, msg); -} diff --git a/widgets/mu-msg-normal-view.h b/widgets/mu-msg-normal-view.h deleted file mode 100644 index f3c914ab..00000000 --- a/widgets/mu-msg-normal-view.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -** Copyright (C) 2011 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify it -** under the terms of the GNU General Public License as published by the -** Free Software Foundation; either version 3, or (at your option) any -** later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - - -#ifndef __MU_MSG_NORMAL_VIEW_H__ -#define __MU_MSG_NORMAL_VIEW_H__ - -#include -#include - -G_BEGIN_DECLS - -/* convenience macros */ -#define MU_TYPE_MSG_NORMAL_VIEW (mu_msg_normal_view_get_type()) -#define MU_MSG_NORMAL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MU_TYPE_MSG_NORMAL_VIEW,MuMsgNormalView)) -#define MU_MSG_NORMAL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MU_TYPE_MSG_NORMAL_VIEW,MuMsgNormalViewClass)) -#define MU_IS_MSG_NORMAL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MU_TYPE_MSG_NORMAL_VIEW)) -#define MU_IS_MSG_NORMAL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MU_TYPE_MSG_NORMAL_VIEW)) -#define MU_MSG_NORMAL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MU_TYPE_MSG_NORMAL_VIEW,MuMsgNormalViewClass)) - -typedef struct _MuMsgNormalView MuMsgNormalView; -typedef struct _MuMsgNormalViewClass MuMsgNormalViewClass; -typedef struct _MuMsgNormalViewPrivate MuMsgNormalViewPrivate; - -struct _MuMsgNormalView { - GtkVBox parent; - /* insert public members, if any */ - - /* private */ - MuMsgNormalViewPrivate *_priv; -}; - -struct _MuMsgNormalViewClass { - GtkVBoxClass parent_class; - - /* supported actions: "view-source" */ - void (* action_requested) (MuMsgNormalView* self, const char* action); -}; - -/* member functions */ -GType mu_msg_normal_view_get_type (void) G_GNUC_CONST; - - -GtkWidget* mu_msg_normal_view_new (void); -void mu_msg_normal_view_set_message (MuMsgNormalView *self, - MuMsg *msg); - -G_END_DECLS - -#endif /* __MU_MSG_NORMAL_VIEW_H__ */ - diff --git a/widgets/mu-msg-source-view.c b/widgets/mu-msg-source-view.c deleted file mode 100644 index 184d07fd..00000000 --- a/widgets/mu-msg-source-view.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -** Copyright (C) 2011 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify it -** under the terms of the GNU General Public License as published by the -** Free Software Foundation; either version 3, or (at your option) any -** later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - - -#include "mu-msg-source-view.h" -/* include other impl specific header files */ - -/* 'private'/'protected' functions */ -static void mu_msg_source_view_class_init (MuMsgSourceViewClass *klass); -static void mu_msg_source_view_init (MuMsgSourceView *obj); -static void mu_msg_source_view_finalize (GObject *obj); - -/* list my signals */ -enum { - ACTION_REQUESTED, - /* MY_SIGNAL_2, */ - LAST_SIGNAL -}; - -struct _MuMsgSourceViewPrivate { - GtkWidget *_view; -}; -#define MU_MSG_SOURCE_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ - MU_TYPE_MSG_SOURCE_VIEW, \ - MuMsgSourceViewPrivate)) -/* globals */ -static GtkVBoxClass *parent_class = NULL; - - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE (MuMsgSourceView, mu_msg_source_view, GTK_TYPE_VBOX); - -static void -mu_msg_source_view_class_init (MuMsgSourceViewClass *klass) -{ - GObjectClass *gobject_class; - gobject_class = (GObjectClass*) klass; - - parent_class = g_type_class_peek_parent (klass); - gobject_class->finalize = mu_msg_source_view_finalize; - - g_type_class_add_private (gobject_class, sizeof(MuMsgSourceViewPrivate)); - - signals[ACTION_REQUESTED] = - g_signal_new ("action-requested", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MuMsgSourceViewClass, - action_requested), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} - - - -static void -on_menu_item_activate (GtkMenuItem *item, MuMsgSourceView *self) -{ - g_signal_emit (G_OBJECT(self), - signals[ACTION_REQUESTED], 0, - g_object_get_data (G_OBJECT(item), "action")); -} - -static void -popup_menu (MuMsgSourceView *self, guint button, guint32 activate_time) -{ - GtkWidget *menu; - int i; - struct { - const char* title; - const char* action; - } actions[] = { - { "View message...", "view-message" } - }; - - menu = gtk_menu_new (); - - for (i = 0; i != G_N_ELEMENTS(actions); ++i) { - GtkWidget *item; - item = gtk_menu_item_new_with_label(actions[i].title); - g_object_set_data (G_OBJECT(item), "action", (gpointer)actions[i].action); - g_signal_connect (item, "activate", G_CALLBACK(on_menu_item_activate), - self); - gtk_menu_attach (GTK_MENU(menu), item, 0, 1, i, i+1); - gtk_widget_show (item); - } - gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0); -} - - -static gboolean -on_button_press_event (GtkWidget *w, GdkEventButton *event, - MuMsgSourceView *self) -{ - /* ignore all but the first (typically, left) mouse button */ - switch (event->button) { - case 1: return FALSE; /* propagate, let widget handle it */ - case 3: popup_menu (self, event->button, event->time); - default: return TRUE; /* ignore */ - } - - return (event->button > 1) ? TRUE : FALSE; -} - - - -static void -mu_msg_source_view_init (MuMsgSourceView *self) -{ - self->_priv = MU_MSG_SOURCE_VIEW_GET_PRIVATE(self); - - self->_priv->_view = gtk_text_view_new (); - - gtk_text_view_set_editable (GTK_TEXT_VIEW(self->_priv->_view), - FALSE); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(self->_priv->_view), - GTK_WRAP_NONE); - - /* handle right-button clicks */ - g_signal_connect (self->_priv->_view, "button-press-event", - G_CALLBACK(on_button_press_event), self); - - gtk_box_pack_start (GTK_BOX(self), self->_priv->_view, - TRUE, TRUE, 0); -} - -static void -mu_msg_source_view_finalize (GObject *obj) -{ -/* free/unref instance resources here */ - G_OBJECT_CLASS(parent_class)->finalize (obj); -} - -GtkWidget* -mu_msg_source_view_new (void) -{ - return GTK_WIDGET(g_object_new(MU_TYPE_MSG_SOURCE_VIEW, NULL)); -} - - -void -mu_msg_source_view_set_message (MuMsgSourceView *self, MuMsg *msg) -{ - GtkTextBuffer *buf; - const gchar *path; - gchar *data; - - g_return_if_fail (MU_IS_MSG_SOURCE_VIEW(self)); - g_return_if_fail (msg); - - buf = gtk_text_view_get_buffer - (GTK_TEXT_VIEW(self->_priv->_view)); - path = msg ? mu_msg_get_path (msg) : NULL; - - if (path && g_file_get_contents (path, &data, NULL, NULL)) { - gtk_text_buffer_set_text (buf, data, -1); - g_free (data); - } else - gtk_text_buffer_set_text (buf, "", 0); -} - diff --git a/widgets/mu-msg-source-view.h b/widgets/mu-msg-source-view.h deleted file mode 100644 index 0f94717c..00000000 --- a/widgets/mu-msg-source-view.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -** Copyright (C) 2011 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify it -** under the terms of the GNU General Public License as published by the -** Free Software Foundation; either version 3, or (at your option) any -** later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - - -#ifndef __MU_MSG_SOURCE_VIEW_H__ -#define __MU_MSG_SOURCE_VIEW_H__ - -#include -#include - -G_BEGIN_DECLS - -/* convenience macros */ -#define MU_TYPE_MSG_SOURCE_VIEW (mu_msg_source_view_get_type()) -#define MU_MSG_SOURCE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MU_TYPE_MSG_SOURCE_VIEW,MuMsgSourceView)) -#define MU_MSG_SOURCE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MU_TYPE_MSG_SOURCE_VIEW,MuMsgSourceViewClass)) -#define MU_IS_MSG_SOURCE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MU_TYPE_MSG_SOURCE_VIEW)) -#define MU_IS_MSG_SOURCE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MU_TYPE_MSG_SOURCE_VIEW)) -#define MU_MSG_SOURCE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MU_TYPE_MSG_SOURCE_VIEW,MuMsgSourceViewClass)) - -typedef struct _MuMsgSourceView MuMsgSourceView; -typedef struct _MuMsgSourceViewClass MuMsgSourceViewClass; -typedef struct _MuMsgSourceViewPrivate MuMsgSourceViewPrivate; - -struct _MuMsgSourceView { - GtkVBox parent; - /* insert public members, if any */ - - /* private */ - MuMsgSourceViewPrivate *_priv; -}; - -struct _MuMsgSourceViewClass { - GtkVBoxClass parent_class; - /* insert signal callback declarations, e.g. */ - /* supported actions: "view-source" */ - void (* action_requested) (MuMsgSourceView* self, const char* action); -}; - -/* member functions */ -GType mu_msg_source_view_get_type (void) G_GNUC_CONST; - -/* parameter-less _new function (constructor) */ -/* if this is a kind of GtkWidget, it should probably return at GtkWidget* */ -GtkWidget* mu_msg_source_view_new (void); -void mu_msg_source_view_set_message (MuMsgSourceView *self, - MuMsg *msg); - -G_END_DECLS - -#endif /* __MU_MSG_SOURCE_VIEW_H__ */ - diff --git a/widgets/mu-msg-view.c b/widgets/mu-msg-view.c index 97dc2e0e..af6def70 100644 --- a/widgets/mu-msg-view.c +++ b/widgets/mu-msg-view.c @@ -18,15 +18,10 @@ */ #include "mu-msg-view.h" - -#include "mu-msg-normal-view.h" #include "mu-msg-body-view.h" -#include "mu-msg-source-view.h" - -#include - -#include -#include +#include "mu-msg-header-view.h" +#include "mu-msg-attach-view.h" +#include "mu-msg-part.h" /* 'private'/'protected' functions */ static void mu_msg_view_class_init (MuMsgViewClass *klass); @@ -41,14 +36,7 @@ enum { }; struct _MuMsgViewPrivate { - - /* 'normal' view */ - GtkWidget *_normal_view, *_source_view, *_internal_view; - - /* TRUE if we're in view-source mode, FALSE otherwise */ - gboolean _view_source; - - /* the message */ + GtkWidget *_headers, *_attach, *_attachexpander, *_body; MuMsg *_msg; }; #define MU_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -81,48 +69,19 @@ mu_msg_view_class_init (MuMsgViewClass *klass) /* etc. */ } -static void -each_child_remove (GtkWidget *child, MuMsgView *self) -{ - /* g_object_ref (child); /\* save the children *\/ */ - gtk_container_remove (GTK_CONTAINER(self), child); -} - static void -remove_widgets (MuMsgView *self) -{ - /* FIXME: keep the widgets around for re-use */ - - /* remove the old children */ - gtk_container_foreach (GTK_CONTAINER(self), - (GtkCallback)each_child_remove, - self); - - self->_priv->_normal_view = NULL; - self->_priv->_source_view = NULL; - self->_priv->_internal_view = NULL; - -} - -static void -on_action_requested (GtkWidget *w, const char* action, - MuMsgView *self) +on_body_action_requested (GtkWidget *w, const char* action, + MuMsgView *self) { if (g_strcmp0 (action, "view-source") == 0) { - - self->_priv->_view_source = TRUE; if (self->_priv->_msg) - mu_msg_ref (self->_priv->_msg); - mu_msg_view_set_message (self, self->_priv->_msg); + mu_msg_view_set_message_source (self, self->_priv->_msg); } else if (g_strcmp0 (action, "view-message") == 0) { - - self->_priv->_view_source = FALSE; if (self->_priv->_msg) - mu_msg_ref (self->_priv->_msg); - mu_msg_view_set_message (self, self->_priv->_msg); - + mu_msg_view_set_message (self, self->_priv->_msg); + } else if (g_strcmp0 (action, "reindex") == 0) { g_warning ("reindex"); } else { @@ -130,106 +89,53 @@ on_action_requested (GtkWidget *w, const char* action, } } - - -static GtkWidget* -get_source_view (MuMsgView *self, MuMsg *msg) +static void +on_attach_activated (GtkWidget *w, guint partnum, MuMsg *msg) { - if (!self->_priv->_source_view) { - self->_priv->_source_view = mu_msg_source_view_new (); - g_signal_connect (self->_priv->_source_view, - "action-requested", - G_CALLBACK(on_action_requested), - self); + gchar *filepath; + + filepath = mu_msg_part_filepath_cache (msg, partnum); + if (filepath) { + mu_msg_part_save (msg, filepath, partnum, FALSE, TRUE); + mu_util_play (filepath, TRUE, FALSE); + g_free (filepath); } - - mu_msg_source_view_set_message - (MU_MSG_SOURCE_VIEW (self->_priv->_source_view), msg); - - gtk_widget_show_all (self->_priv->_source_view); - - return self->_priv->_source_view; } -static GtkWidget* -get_normal_view (MuMsgView *self, MuMsg *msg) -{ - GtkWidget *scrolledwin; - - if (self->_priv->_normal_view) { - mu_msg_normal_view_set_message - (MU_MSG_NORMAL_VIEW(self->_priv->_normal_view), msg); - return gtk_widget_get_parent (self->_priv->_normal_view); - } - - self->_priv->_normal_view = mu_msg_normal_view_new (); - - mu_msg_normal_view_set_message - (MU_MSG_NORMAL_VIEW(self->_priv->_normal_view), msg); - - g_signal_connect (self->_priv->_normal_view, - "action-requested", - G_CALLBACK(on_action_requested), - self); - - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW(scrolledwin), - GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_add_with_viewport - (GTK_SCROLLED_WINDOW(scrolledwin), - self->_priv->_normal_view); - - gtk_widget_show (self->_priv->_normal_view); - gtk_widget_show (scrolledwin); - - return scrolledwin; -} - - -static GtkWidget* -get_internal_view (MuMsgView *self, const char *html) -{ - if (!self->_priv->_internal_view) { - self->_priv->_internal_view = mu_msg_body_view_new(); - g_signal_connect (self->_priv->_internal_view, - "action-requested", - G_CALLBACK(on_action_requested), - self); - } - mu_msg_body_view_set_note (MU_MSG_BODY_VIEW(self->_priv->_internal_view), - html); - - gtk_widget_show (self->_priv->_internal_view); - - return self->_priv->_internal_view; -} - - static void mu_msg_view_init (MuMsgView *self) { - self->_priv = MU_MSG_VIEW_GET_PRIVATE(self); + self->_priv = MU_MSG_VIEW_GET_PRIVATE(self); - self->_priv->_normal_view = NULL; - self->_priv->_source_view = NULL; - self->_priv->_internal_view = NULL; + self->_priv->_headers = mu_msg_header_view_new (); + + self->_priv->_attach = mu_msg_attach_view_new (); + self->_priv->_attachexpander = gtk_expander_new_with_mnemonic + ("_Attachments"); + gtk_container_add (GTK_CONTAINER(self->_priv->_attachexpander), + self->_priv->_attach); + g_signal_connect (self->_priv->_attach, "attach-activated", + G_CALLBACK(on_attach_activated), + self); - self->_priv->_view_source = FALSE; + self->_priv->_body = mu_msg_body_view_new (); + g_signal_connect (self->_priv->_body, + "action-requested", + G_CALLBACK(on_body_action_requested), + self); + + gtk_box_pack_start (GTK_BOX(self), self->_priv->_headers, + FALSE, FALSE, 2); + gtk_box_pack_start (GTK_BOX(self), self->_priv->_attachexpander, + FALSE, FALSE, 2); + gtk_box_pack_start (GTK_BOX(self), self->_priv->_body, + TRUE, TRUE, 2); } static void mu_msg_view_finalize (GObject *obj) { - MuMsgViewPrivate *priv; - - priv = MU_MSG_VIEW_GET_PRIVATE(obj); - - if (priv->_msg) - mu_msg_unref (priv->_msg); - /* free/unref instance resources here */ G_OBJECT_CLASS(parent_class)->finalize (obj); } @@ -241,9 +147,63 @@ mu_msg_view_new (void) } +struct _ChildData { + GtkWidget *child; + gboolean show; +}; +typedef struct _ChildData ChildData; + +static void +each_child_visibility (GtkWidget *child, ChildData *cdata) +{ + if (child == cdata->child) + gtk_widget_set_visible (child, cdata->show); +} + +static void +set_visibility (MuMsgView *self, GtkWidget *w, gboolean show) +{ + ChildData cdata; + + cdata.child = w; + cdata.show = show; + + gtk_container_foreach (GTK_CONTAINER(self), + (GtkCallback)each_child_visibility, + &cdata); +} + + void mu_msg_view_set_message (MuMsgView *self, MuMsg *msg) +{ + gint attachnum; + + g_return_if_fail (MU_IS_MSG_VIEW(self)); + + if (self->_priv->_msg) + mu_msg_unref (self->_priv->_msg); + + self->_priv->_msg = msg ? mu_msg_ref (msg) : NULL; + + mu_msg_header_view_set_message (MU_MSG_HEADER_VIEW(self->_priv->_headers), + msg); + attachnum = mu_msg_attach_view_set_message (MU_MSG_ATTACH_VIEW(self->_priv->_attach), + msg); + + mu_msg_body_view_set_message (MU_MSG_BODY_VIEW(self->_priv->_body), + msg); + + set_visibility (self, self->_priv->_headers, TRUE); + set_visibility (self, self->_priv->_attachexpander, attachnum > 0); + set_visibility (self, self->_priv->_body, TRUE); +} + + + +void +mu_msg_view_set_message_source (MuMsgView *self, MuMsg *msg) { g_return_if_fail (MU_IS_MSG_VIEW(self)); @@ -252,31 +212,26 @@ mu_msg_view_set_message (MuMsgView *self, MuMsg *msg) self->_priv->_msg = msg ? mu_msg_ref (msg) : NULL; - remove_widgets (self); - - if (!msg) - return; + mu_msg_body_view_set_message_source (MU_MSG_BODY_VIEW(self->_priv->_body), + msg); - if (!self->_priv->_view_source) - gtk_box_pack_start (GTK_BOX(self), - get_normal_view (self, msg), - TRUE, TRUE, 0); - else - gtk_box_pack_start (GTK_BOX(self), - get_source_view (self, msg), - TRUE, TRUE, 0); + set_visibility (self, self->_priv->_headers, FALSE); + set_visibility (self, self->_priv->_attachexpander, FALSE); + set_visibility (self, self->_priv->_body, TRUE); } + void mu_msg_view_set_note (MuMsgView *self, const gchar* html) { - g_return_if_fail (MU_IS_MSG_VIEW(self)); - - remove_widgets (self); - gtk_box_pack_start (GTK_BOX(self), - get_internal_view (self, html), - TRUE, TRUE, 0); + set_visibility (self, self->_priv->_headers, FALSE); + set_visibility (self, self->_priv->_attachexpander, FALSE); + set_visibility (self, self->_priv->_body, TRUE); + + mu_msg_body_view_set_note (MU_MSG_BODY_VIEW(self->_priv->_body), + html); } + diff --git a/widgets/mu-msg-view.h b/widgets/mu-msg-view.h index f2696753..4333c04f 100644 --- a/widgets/mu-msg-view.h +++ b/widgets/mu-msg-view.h @@ -59,7 +59,8 @@ GType mu_msg_view_get_type (void) G_GNUC_CONST; GtkWidget* mu_msg_view_new (void); void mu_msg_view_set_message (MuMsgView *self, MuMsg *msg); -void mu_msg_view_set_note (MuMsgView *self, const char *markup); +void mu_msg_view_set_note (MuMsgView *self, const gchar* html); +void mu_msg_view_set_message_source (MuMsgView *self, MuMsg *msg); G_END_DECLS