The big eye-candy commit.
Make thumbnails out of image attachments. svn path=/trunk/; revision=5648
This commit is contained in:
@ -1,3 +1,20 @@
|
||||
2000-10-01 Iain Holmes <iain@helixcode.com>
|
||||
|
||||
* e-msg-composer-attachment-bar.[ch] (update): If the attachment is
|
||||
an image, then make a thumbnail for it.
|
||||
Base the attachment bar on e-icon-list instead of gnome-icon-list.
|
||||
|
||||
* e-icon-list.[ch]: New files. These are modified versions of
|
||||
gnome-icon-list from gnome-libs HEAD that uses gdk-pixbuf instead
|
||||
of the evil Imlib.
|
||||
|
||||
* e-msg-composer-attachment.[ch]: Add a pixbuf_cache member, to
|
||||
save us having to generate a thumbnail for the attachment every
|
||||
time the bar changes.
|
||||
|
||||
* e-msg-composer.c (e_msg_composer_construct): Add dnd support for
|
||||
files. Drag a file to the composer to add it as an attachment.
|
||||
|
||||
2000-09-28 Jeffrey Stedfast <fejj@helixcode.com>
|
||||
|
||||
* e-msg-composer.c (build_message): Check to see if the body has
|
||||
|
||||
@ -64,7 +64,9 @@ libcomposer_la_SOURCES = \
|
||||
e-msg-composer-select-file.c \
|
||||
e-msg-composer-select-file.h \
|
||||
e-msg-composer.c \
|
||||
e-msg-composer.h
|
||||
e-msg-composer.h \
|
||||
e-icon-list.c \
|
||||
e-icon-list.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(glade_DATA) \
|
||||
|
||||
2657
composer/e-icon-list.c
Normal file
2657
composer/e-icon-list.c
Normal file
File diff suppressed because it is too large
Load Diff
178
composer/e-icon-list.h
Normal file
178
composer/e-icon-list.h
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 1998, 1999 Free Software Foundation
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of the Gnome Library.
|
||||
*
|
||||
* The Gnome Library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* The Gnome Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
@NOTATION@
|
||||
*/
|
||||
|
||||
/* GnomeIconList widget - scrollable icon list
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Federico Mena <federico@nuclecu.unam.mx>
|
||||
* Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
*/
|
||||
|
||||
#ifndef _E_ICON_LIST_H_
|
||||
#define _E_ICON_LIST_H_
|
||||
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <libgnomeui/gnome-canvas.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define E_TYPE_ICON_LIST (e_icon_list_get_type ())
|
||||
#define E_ICON_LIST(obj) (GTK_CHECK_CAST ((obj), E_TYPE_ICON_LIST, EIconList))
|
||||
#define E_ICON_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_ICON_LIST, EIconListClass))
|
||||
#define E_IS_ICON_LIST(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_ICON_LIST))
|
||||
#define E_IS_ICON_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_ICON_LIST))
|
||||
#define E_ICON_LIST_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), E_TYPE_ICON_LIST, EIconListClass))
|
||||
|
||||
typedef struct _EIconList EIconList;
|
||||
typedef struct _EIconListPrivate EIconListPrivate;
|
||||
typedef struct _EIconListClass EIconListClass;
|
||||
|
||||
typedef enum {
|
||||
E_ICON_LIST_ICONS,
|
||||
E_ICON_LIST_TEXT_BELOW,
|
||||
E_ICON_LIST_TEXT_RIGHT
|
||||
} EIconListMode;
|
||||
|
||||
/* This structure has been converted to use public and private parts. To avoid
|
||||
* breaking binary compatibility, the slots for private fields have been
|
||||
* replaced with padding. Please remove these fields when gnome-libs has
|
||||
* reached another major version and it is "fine" to break binary compatibility.
|
||||
*/
|
||||
struct _EIconList {
|
||||
GnomeCanvas canvas;
|
||||
|
||||
/*< private >*/
|
||||
EIconListPrivate * _priv;
|
||||
};
|
||||
|
||||
struct _EIconListClass {
|
||||
GnomeCanvasClass parent_class;
|
||||
|
||||
void (*select_icon) (EIconList *gil, gint num, GdkEvent *event);
|
||||
void (*unselect_icon) (EIconList *gil, gint num, GdkEvent *event);
|
||||
gboolean (*text_changed) (EIconList *gil, gint num, const char *new_text);
|
||||
};
|
||||
|
||||
enum {
|
||||
E_ICON_LIST_IS_EDITABLE = 1 << 0,
|
||||
E_ICON_LIST_STATIC_TEXT = 1 << 1
|
||||
};
|
||||
|
||||
guint e_icon_list_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget *e_icon_list_new (guint icon_width,
|
||||
int flags);
|
||||
void e_icon_list_construct (EIconList *gil,
|
||||
guint icon_width,
|
||||
int flags);
|
||||
|
||||
|
||||
/* To avoid excesive recomputes during insertion/deletion */
|
||||
void e_icon_list_freeze (EIconList *gil);
|
||||
void e_icon_list_thaw (EIconList *gil);
|
||||
|
||||
|
||||
void e_icon_list_insert (EIconList *gil,
|
||||
int idx,
|
||||
const char *icon_filename,
|
||||
const char *text);
|
||||
void e_icon_list_insert_pixbuf (EIconList *gil,
|
||||
int idx,
|
||||
GdkPixbuf *im,
|
||||
const char *icon_filename,
|
||||
const char *text);
|
||||
|
||||
int e_icon_list_append (EIconList *gil,
|
||||
const char *icon_filename,
|
||||
const char *text);
|
||||
int e_icon_list_append_pixbuf (EIconList *gil,
|
||||
GdkPixbuf *im,
|
||||
const char *icon_filename,
|
||||
const char *text);
|
||||
|
||||
void e_icon_list_clear (EIconList *gil);
|
||||
void e_icon_list_remove (EIconList *gil,
|
||||
int idx);
|
||||
|
||||
guint e_icon_list_get_num_icons (EIconList *gil);
|
||||
|
||||
|
||||
/* Managing the selection */
|
||||
void e_icon_list_set_selection_mode (EIconList *gil,
|
||||
GtkSelectionMode mode);
|
||||
void e_icon_list_select_icon (EIconList *gil,
|
||||
int idx);
|
||||
void e_icon_list_unselect_icon (EIconList *gil,
|
||||
int idx);
|
||||
int e_icon_list_unselect_all (EIconList *gil);
|
||||
GList * e_icon_list_get_selection (EIconList *gil);
|
||||
|
||||
/* Setting the spacing values */
|
||||
void e_icon_list_set_icon_width (EIconList *gil,
|
||||
int w);
|
||||
void e_icon_list_set_row_spacing (EIconList *gil,
|
||||
int pixels);
|
||||
void e_icon_list_set_col_spacing (EIconList *gil,
|
||||
int pixels);
|
||||
void e_icon_list_set_text_spacing (EIconList *gil,
|
||||
int pixels);
|
||||
void e_icon_list_set_icon_border (EIconList *gil,
|
||||
int pixels);
|
||||
void e_icon_list_set_separators (EIconList *gil,
|
||||
const char *sep);
|
||||
/* Icon filename. */
|
||||
gchar * e_icon_list_get_icon_filename (EIconList *gil,
|
||||
int idx);
|
||||
int e_icon_list_find_icon_from_filename (EIconList *gil,
|
||||
const char *filename);
|
||||
|
||||
/* Attaching information to the icons */
|
||||
void e_icon_list_set_icon_data (EIconList *gil,
|
||||
int idx, gpointer data);
|
||||
void e_icon_list_set_icon_data_full (EIconList *gil,
|
||||
int idx, gpointer data,
|
||||
GtkDestroyNotify destroy);
|
||||
int e_icon_list_find_icon_from_data (EIconList *gil,
|
||||
gpointer data);
|
||||
gpointer e_icon_list_get_icon_data (EIconList *gil,
|
||||
int idx);
|
||||
|
||||
/* Visibility */
|
||||
void e_icon_list_moveto (EIconList *gil,
|
||||
int idx, double yalign);
|
||||
GtkVisibility e_icon_list_icon_is_visible (EIconList *gil,
|
||||
int idx);
|
||||
|
||||
int e_icon_list_get_icon_at (EIconList *gil,
|
||||
int x, int y);
|
||||
|
||||
int e_icon_list_get_items_per_line (EIconList *gil);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* _GNOME_ICON_LIST_H_ */
|
||||
@ -24,11 +24,16 @@
|
||||
#include <gnome.h>
|
||||
#include <glade/glade.h>
|
||||
#include <libgnomevfs/gnome-vfs-mime-info.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
|
||||
#include <gdk-pixbuf/gnome-canvas-pixbuf.h>
|
||||
|
||||
#include "e-msg-composer-attachment.h"
|
||||
#include "e-msg-composer-attachment-bar.h"
|
||||
#include "e-icon-list.h"
|
||||
#include "camel/camel-data-wrapper.h"
|
||||
#include "camel/camel-stream-fs.h"
|
||||
#include "camel/camel-stream-mem.h"
|
||||
#include "camel/camel-mime-part.h"
|
||||
|
||||
|
||||
@ -41,7 +46,7 @@
|
||||
#define ICON_TEXT_SPACING 2
|
||||
|
||||
|
||||
static GnomeIconListClass *parent_class = NULL;
|
||||
static EIconListClass *parent_class = NULL;
|
||||
|
||||
struct _EMsgComposerAttachmentBarPrivate {
|
||||
GList *attachments;
|
||||
@ -173,26 +178,28 @@ static void
|
||||
update (EMsgComposerAttachmentBar *bar)
|
||||
{
|
||||
EMsgComposerAttachmentBarPrivate *priv;
|
||||
GnomeIconList *icon_list;
|
||||
EIconList *icon_list;
|
||||
GList *p;
|
||||
|
||||
priv = bar->priv;
|
||||
icon_list = GNOME_ICON_LIST (bar);
|
||||
icon_list = E_ICON_LIST (bar);
|
||||
|
||||
gnome_icon_list_freeze (icon_list);
|
||||
e_icon_list_freeze (icon_list);
|
||||
|
||||
gnome_icon_list_clear (icon_list);
|
||||
e_icon_list_clear (icon_list);
|
||||
|
||||
/* FIXME could be faster, but we don't care. */
|
||||
|
||||
for (p = priv->attachments; p != NULL; p = p->next) {
|
||||
EMsgComposerAttachment *attachment;
|
||||
const gchar *icon_name, *desc;
|
||||
gchar *size_string, *label, *mime_type;
|
||||
GMimeContentField *content_type;
|
||||
|
||||
GdkPixbuf *pixbuf;
|
||||
gboolean image = FALSE;
|
||||
|
||||
attachment = p->data;
|
||||
content_type = camel_mime_part_get_content_type (attachment->body);
|
||||
|
||||
mime_type = g_strdup_printf ("%s/%s", content_type->type,
|
||||
content_type->subtype);
|
||||
icon_name = gnome_vfs_mime_get_value (mime_type,
|
||||
@ -204,12 +211,90 @@ update (EMsgComposerAttachmentBar *bar)
|
||||
icon_name = gnome_vfs_mime_get_value ("text/plain",
|
||||
"icon-filename");
|
||||
|
||||
/* Get the image out of the attachment
|
||||
and create a thumbnail for it */
|
||||
if (strcmp (content_type->type, "image") == 0)
|
||||
image = TRUE;
|
||||
else
|
||||
image = FALSE;
|
||||
|
||||
if (image && attachment->pixbuf_cache == NULL) {
|
||||
CamelDataWrapper *wrapper;
|
||||
CamelStream *mstream;
|
||||
GdkPixbufLoader *loader;
|
||||
gboolean error = TRUE;
|
||||
char tmp[4096];
|
||||
int t;
|
||||
|
||||
wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body));
|
||||
mstream = camel_stream_mem_new ();
|
||||
|
||||
camel_data_wrapper_write_to_stream (wrapper, mstream);
|
||||
|
||||
camel_stream_reset (mstream);
|
||||
|
||||
/* Stream image into pixbuf loader */
|
||||
loader = gdk_pixbuf_loader_new ();
|
||||
do {
|
||||
t = camel_stream_read (mstream, tmp, 4096);
|
||||
if (t > 0) {
|
||||
error = !gdk_pixbuf_loader_write (loader,
|
||||
tmp, t);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (camel_stream_eos (mstream))
|
||||
break;
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (!camel_stream_eos (mstream));
|
||||
|
||||
if (!error) {
|
||||
int ratio, width, height;
|
||||
|
||||
/* Shrink pixbuf */
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
if (width >= height) {
|
||||
if (width > 48) {
|
||||
ratio = width / 48;
|
||||
width = 48;
|
||||
height = height / ratio;
|
||||
}
|
||||
} else {
|
||||
if (height > 48) {
|
||||
ratio = height / 48;
|
||||
height = 48;
|
||||
width = width / ratio;
|
||||
}
|
||||
}
|
||||
|
||||
attachment->pixbuf_cache = gdk_pixbuf_scale_simple
|
||||
(pixbuf,
|
||||
width,
|
||||
height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
} else {
|
||||
g_warning ("GdkPixbufLoader Error");
|
||||
image = FALSE;
|
||||
}
|
||||
|
||||
/* Destroy everything */
|
||||
gdk_pixbuf_loader_close (loader);
|
||||
gtk_object_destroy (GTK_OBJECT (loader));
|
||||
camel_stream_close (mstream);
|
||||
}
|
||||
|
||||
desc = camel_mime_part_get_description (attachment->body);
|
||||
if (!desc)
|
||||
desc = camel_mime_part_get_filename (attachment->body);
|
||||
if (!desc)
|
||||
desc = "attachment";
|
||||
|
||||
|
||||
if (attachment->size) {
|
||||
size_string = size_to_string (attachment->size);
|
||||
label = g_strdup_printf ("%s (%s)", desc, size_string);
|
||||
@ -217,30 +302,36 @@ update (EMsgComposerAttachmentBar *bar)
|
||||
} else
|
||||
label = g_strdup (desc);
|
||||
|
||||
gnome_icon_list_append (icon_list, icon_name, label);
|
||||
if (image) {
|
||||
e_icon_list_append_pixbuf (icon_list, attachment->pixbuf_cache, icon_name, label);
|
||||
} else {
|
||||
e_icon_list_append (icon_list, icon_name, label);
|
||||
}
|
||||
|
||||
g_free (label);
|
||||
}
|
||||
|
||||
gnome_icon_list_thaw (icon_list);
|
||||
e_icon_list_thaw (icon_list);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_selected (EMsgComposerAttachmentBar *bar)
|
||||
{
|
||||
GnomeIconList *icon_list;
|
||||
EIconList *icon_list;
|
||||
EMsgComposerAttachment *attachment;
|
||||
GList *attachment_list;
|
||||
GList *p;
|
||||
gint num;
|
||||
|
||||
icon_list = GNOME_ICON_LIST (bar);
|
||||
icon_list = E_ICON_LIST (bar);
|
||||
|
||||
/* Weee! I am especially proud of this piece of cheesy code: it is
|
||||
truly awful. But unless one attaches a huge number of files, it
|
||||
will not be as greedy as intended. FIXME of course. */
|
||||
|
||||
attachment_list = NULL;
|
||||
for (p = icon_list->selection; p != NULL; p = p->next) {
|
||||
p = e_icon_list_get_selection (icon_list);
|
||||
for (; p != NULL; p = p->next) {
|
||||
num = GPOINTER_TO_INT (p->data);
|
||||
attachment = E_MSG_COMPOSER_ATTACHMENT
|
||||
(g_list_nth (bar->priv->attachments, num)->data);
|
||||
@ -258,13 +349,15 @@ remove_selected (EMsgComposerAttachmentBar *bar)
|
||||
static void
|
||||
edit_selected (EMsgComposerAttachmentBar *bar)
|
||||
{
|
||||
GnomeIconList *icon_list;
|
||||
EIconList *icon_list;
|
||||
EMsgComposerAttachment *attachment;
|
||||
GList *selection;
|
||||
gint num;
|
||||
|
||||
icon_list = GNOME_ICON_LIST (bar);
|
||||
icon_list = E_ICON_LIST (bar);
|
||||
|
||||
num = GPOINTER_TO_INT (icon_list->selection->data);
|
||||
selection = e_icon_list_get_selection (icon_list);
|
||||
num = GPOINTER_TO_INT (selection->data);
|
||||
attachment = g_list_nth (bar->priv->attachments, num)->data;
|
||||
|
||||
e_msg_composer_attachment_edit (attachment, GTK_WIDGET (bar));
|
||||
@ -378,7 +471,7 @@ get_icon_context_menu (EMsgComposerAttachmentBar *bar)
|
||||
priv = bar->priv;
|
||||
if (priv->icon_context_menu == NULL)
|
||||
priv->icon_context_menu = gnome_popup_menu_new
|
||||
(icon_context_menu_info);
|
||||
(icon_context_menu_info);
|
||||
|
||||
return priv->icon_context_menu;
|
||||
}
|
||||
@ -447,21 +540,21 @@ button_press_event (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
EMsgComposerAttachmentBar *bar;
|
||||
GnomeIconList *icon_list;
|
||||
EIconList *icon_list;
|
||||
gint icon_number;
|
||||
|
||||
bar = E_MSG_COMPOSER_ATTACHMENT_BAR (widget);
|
||||
icon_list = GNOME_ICON_LIST (widget);
|
||||
icon_list = E_ICON_LIST (widget);
|
||||
|
||||
if (event->button != 3)
|
||||
return GTK_WIDGET_CLASS (parent_class)->button_press_event
|
||||
(widget, event);
|
||||
(widget, event);
|
||||
|
||||
icon_number = gnome_icon_list_get_icon_at (icon_list,
|
||||
event->x, event->y);
|
||||
icon_number = e_icon_list_get_icon_at (icon_list,
|
||||
event->x, event->y);
|
||||
|
||||
if (icon_number >= 0) {
|
||||
gnome_icon_list_select_icon (icon_list, icon_number);
|
||||
e_icon_list_select_icon (icon_list, icon_number);
|
||||
popup_icon_context_menu (bar, icon_number, event);
|
||||
} else {
|
||||
popup_context_menu (bar, event);
|
||||
@ -478,13 +571,13 @@ class_init (EMsgComposerAttachmentBarClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
GtkWidgetClass *widget_class;
|
||||
GnomeIconListClass *icon_list_class;
|
||||
EIconListClass *icon_list_class;
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
icon_list_class = GNOME_ICON_LIST_CLASS (class);
|
||||
icon_list_class = E_ICON_LIST_CLASS (class);
|
||||
|
||||
parent_class = gtk_type_class (gnome_icon_list_get_type ());
|
||||
parent_class = gtk_type_class (e_icon_list_get_type ());
|
||||
|
||||
object_class->destroy = destroy;
|
||||
|
||||
@ -546,7 +639,7 @@ e_msg_composer_attachment_bar_get_type (void)
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
type = gtk_type_unique (gnome_icon_list_get_type (), &info);
|
||||
type = gtk_type_unique (e_icon_list_get_type (), &info);
|
||||
}
|
||||
|
||||
return type;
|
||||
@ -556,24 +649,25 @@ GtkWidget *
|
||||
e_msg_composer_attachment_bar_new (GtkAdjustment *adj)
|
||||
{
|
||||
EMsgComposerAttachmentBar *new;
|
||||
GnomeIconList *icon_list;
|
||||
EIconList *icon_list;
|
||||
|
||||
gtk_widget_push_visual (gdk_imlib_get_visual ());
|
||||
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
|
||||
gdk_rgb_init ();
|
||||
gtk_widget_push_visual (gdk_rgb_get_visual ());
|
||||
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
|
||||
new = gtk_type_new (e_msg_composer_attachment_bar_get_type ());
|
||||
gtk_widget_pop_visual ();
|
||||
gtk_widget_pop_colormap ();
|
||||
|
||||
icon_list = GNOME_ICON_LIST (new);
|
||||
icon_list = E_ICON_LIST (new);
|
||||
|
||||
gnome_icon_list_construct (icon_list, ICON_WIDTH, adj, 0);
|
||||
e_icon_list_construct (icon_list, ICON_WIDTH, 0);
|
||||
|
||||
gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS);
|
||||
gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING);
|
||||
gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING);
|
||||
gnome_icon_list_set_icon_border (icon_list, ICON_BORDER);
|
||||
gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING);
|
||||
gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE);
|
||||
e_icon_list_set_separators (icon_list, ICON_SEPARATORS);
|
||||
e_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING);
|
||||
e_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING);
|
||||
e_icon_list_set_icon_border (icon_list, ICON_BORDER);
|
||||
e_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING);
|
||||
e_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE);
|
||||
|
||||
return GTK_WIDGET (new);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#define __E_MSG_COMPOSER_ATTACHMENT_BAR_H__
|
||||
|
||||
#include <gnome.h>
|
||||
#include "e-icon-list.h"
|
||||
#include <camel/camel-multipart.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -47,14 +48,14 @@ extern "C" {
|
||||
typedef struct _EMsgComposerAttachmentBarPrivate EMsgComposerAttachmentBarPrivate;
|
||||
|
||||
struct _EMsgComposerAttachmentBar {
|
||||
GnomeIconList parent;
|
||||
EIconList parent;
|
||||
|
||||
EMsgComposerAttachmentBarPrivate *priv;
|
||||
};
|
||||
typedef struct _EMsgComposerAttachmentBar EMsgComposerAttachmentBar;
|
||||
|
||||
struct _EMsgComposerAttachmentBarClass {
|
||||
GnomeIconListClass parent_class;
|
||||
EIconListClass parent_class;
|
||||
|
||||
void (* changed) (EMsgComposerAttachmentBar *bar);
|
||||
};
|
||||
|
||||
@ -84,6 +84,8 @@ destroy (GtkObject *object)
|
||||
attachment = E_MSG_COMPOSER_ATTACHMENT (object);
|
||||
|
||||
camel_object_unref (CAMEL_OBJECT (attachment->body));
|
||||
if (attachment->pixbuf_cache != NULL)
|
||||
gdk_pixbuf_unref (attachment->pixbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
@ -129,6 +131,7 @@ init (EMsgComposerAttachment *msg_composer_attachment)
|
||||
msg_composer_attachment->editor_gui = NULL;
|
||||
msg_composer_attachment->body = NULL;
|
||||
msg_composer_attachment->size = 0;
|
||||
msg_composer_attachment->pixbuf_cache = NULL;
|
||||
}
|
||||
|
||||
GtkType
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <gnome.h>
|
||||
#include <glade/glade-xml.h>
|
||||
#include <camel/camel-mime-part.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -50,6 +51,8 @@ struct _EMsgComposerAttachment {
|
||||
CamelMimePart *body;
|
||||
gboolean guessed_type;
|
||||
gulong size;
|
||||
|
||||
GdkPixbuf *pixbuf_cache;
|
||||
};
|
||||
|
||||
struct _EMsgComposerAttachmentClass {
|
||||
|
||||
@ -1166,6 +1166,39 @@ delete_event (GtkWidget *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_data_received (EMsgComposer *composer,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
gchar *temp, *filename;
|
||||
|
||||
filename = g_strdup (selection->data);
|
||||
temp = strchr (filename, '\n');
|
||||
if (temp) {
|
||||
if (*(temp - 1) == '\r')
|
||||
*(temp - 1) = '\0';
|
||||
*temp = '\0';
|
||||
}
|
||||
|
||||
/* Chop the file: part off */
|
||||
if (strncasecmp (filename, "file:", 5) == 0) {
|
||||
temp = g_strdup (filename + 5);
|
||||
g_free (filename);
|
||||
filename = temp;
|
||||
}
|
||||
|
||||
e_msg_composer_attachment_bar_attach
|
||||
(E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar),
|
||||
filename);
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
class_init (EMsgComposerClass *klass)
|
||||
@ -1259,7 +1292,11 @@ e_msg_composer_construct (EMsgComposer *composer)
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
BonoboObject *editor_server;
|
||||
|
||||
|
||||
static GtkTargetEntry drop_types[] = {
|
||||
{"text/uri-list", 0, 1}
|
||||
};
|
||||
|
||||
g_return_if_fail (gtk_main_level () > 0);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (composer),
|
||||
@ -1268,6 +1305,12 @@ e_msg_composer_construct (EMsgComposer *composer)
|
||||
bonobo_win_construct (BONOBO_WIN (composer), "e-msg-composer",
|
||||
_("Compose a message"));
|
||||
|
||||
/* DND support */
|
||||
gtk_drag_dest_set (GTK_WIDGET (composer), GTK_DEST_DEFAULT_ALL,
|
||||
drop_types, 1, GDK_ACTION_COPY);
|
||||
gtk_signal_connect (GTK_OBJECT (composer), "drag_data_received",
|
||||
GTK_SIGNAL_FUNC (drag_data_received), NULL);
|
||||
|
||||
composer->uih = bonobo_ui_handler_new ();
|
||||
bonobo_ui_handler_set_app (composer->uih, BONOBO_WIN (composer));
|
||||
|
||||
@ -1407,6 +1450,8 @@ e_msg_composer_new_with_message (CamelMimeMessage *msg)
|
||||
char *text, *final_text;
|
||||
guint len, i;
|
||||
|
||||
g_return_val_if_fail (gtk_main_level () > 0, NULL);
|
||||
|
||||
new = create_composer ();
|
||||
if (!new)
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user