mirror of https://github.com/djcb/mu.git
* big cleanup, simplification for the message widget
This commit is contained in:
parent
f8fd420215
commit
858dcb123c
|
@ -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
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@
|
|||
#include <webkit/webkitnetworkresponse.h>
|
||||
#include <webkit/webkitwebnavigationaction.h>
|
||||
#include <webkit/webkitwebpolicydecision.h>
|
||||
|
||||
|
||||
#include "mu-msg-body-view.h"
|
||||
#include <mu-msg-part.h>
|
||||
|
||||
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 <a href="cmd:refresh">Refresh</a> 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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 ("<b>_Attachments (%d)</b>", 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);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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 <gtk/gtk.h>
|
||||
#include <mu-msg.h>
|
||||
|
||||
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__ */
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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);
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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 <gtk/gtk.h>
|
||||
#include <mu-msg.h>
|
||||
|
||||
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__ */
|
||||
|
|
@ -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 <webkit/webkitwebview.h>
|
||||
|
||||
#include <mu-msg.h>
|
||||
#include <mu-msg-part.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue