* Implemented ..._on_attachment_clicked, calling view attachment in view.
* Added actions ..._on_attach_file, ..._on_remove_attachments.
* Added support for "select all" action when attachment is focused.
* Added actions ..._view_attachment, ..._save_attachments,
..._remove_attachments.
* src/modest-text-utils.c:
* Now the ..._get_display_size should show correctly a 0 bytes size.
* src/maemo/modest-main-window-ui.h:
* Added view, save and remove attachment actions.
* src/maemo/modest-msg-edit-window.c:
* Added text_buffer_delete_range handler, to remove image attachments when
they're removed in the body editor.
* ..._add_attachment_clicked handler, to show the add attachment dialog
when user clicks the attachment button. (fixes NB#56314).
* Added ..._attach_file method, to show the dialog to attach one or more
files, and attach them to the message.
* Added ..._remove_attachments method, to remove the selected attachments.
* src/maemo/modest-platform.c:
* Now osso_context is a module static pointer, to let platform function use
this.
* Added implementation of modest_platform_activate_file using hildon/osso
mime libraries.
* src/maemo/modest-msg-view-window.c:
* ..._update_dimmed now also updates the attachment actions depending on the
current selection.
* Removed some debugging messages.
* Added ..._view_attachment method, to view the currently selected attachment.
If it's a message, it opens a new message view. If it's an attachment, it
calls the default handler.
* Added ..._save_attachments method. This method shows a dialog to select
the folder location to save (or the full path if only one attachment will be
saved).
* Added ..._remove_attachments method (with no implementation currently).
* src/maemo/modest-maemo-utils.[ch]:
* Added ..._folder_writable method, that checks if a folder is writable.
* Added ..._file_exists, that checks if a file path corresponds to an existing
file.
* Added ..._create_temp_stream, that creates a temporary file and a corresponding
TnyFsStream.
* src/maemo/ui/modest-msg-edit-window-ui.xml:
* Added attach file and remove attachment menu actions.
* src/maemo/ui/modest-msg-view-window-ui.xml:
* Added attach file, save attachments and remove attachments menu actions.
* src/modest-platform.h:
* New activate file method.
* src/gnome/modest-msg-edit-window.c:
* Added new stub functions.
* src/gnome/modest-platform.c:
* Added new stub functions.
* src/gnome/modest-msg-view-window.c:
* Added new stub functions.
* src/widgets/modest-msg-edit-window.h:
* Added methods to attach file and remove attachments.
* src/widgets/modest-msg-view.[ch]:
* Remove debugging messages.
* New ..._get_selected_attachments method, that obtains the TnyMimePart's of
current selection in attachments view.
* src/widgets/modest-attachment-view.[ch]:
* Removed activated signal. Now activation is completely managed in
ModestAttachmentsView.
* Added support for showing attached messages.
* Removed the button press and button release
* Now labels are not selectable (selection is managed in ModestAttachmentsView).
* Now it inherits from GtkEventBox.
* src/widgets/modest-msg-view-window.h:
* Added attachment methods.
* src/widgets/modest-attachments-view.[ch]:
* Now it inherits from an event box.
* Minor style fixes.
* Added support for attaching messages.
* New ..._remove_attachment method, to remove attachments corresponding to a
specific TnyMimePart.
* New ..._remove_attachment_by_id, to remove attachments corresponding to a
specific content id.
* Button events handling for rubber banding, selection, and activation.
* Keyboard events handling for selection and activation.
* Internal methods to handle selections: unselect_all, get_att_view_att_coords,
set_selected, select_range.
* Internal methods to handle clipboard selection.
* New ..._get_selection method, that obtains the mime parts of the selected
items.
* New ..._select_all method, that selects all the attachments.
* src/widgets/modest-msg-edit-window-ui.h:
* Added actions for attachments.
* configure.ac:
* Now maemo target depends on libtinymail-gnomevfs.
pmo-trunk-r1795
dnl # GLib/Gobject/Gtk/Gconf => mandatory
-PKG_CHECK_MODULES(MODEST_GSTUFF,glib-2.0 >= 2.6 gobject-2.0 gtk+-2.0 >= 2.6 gconf-2.0 gnome-vfs-2.0 libgtkhtml-3.8 libtinymail-1.0 libtinymail-camel-1.0 libtinymailui-1.0 libtinymailui-gtk-1.0)
+PKG_CHECK_MODULES(MODEST_GSTUFF,glib-2.0 >= 2.6 gobject-2.0 gtk+-2.0 >= 2.6 gconf-2.0 gnome-vfs-2.0 libgtkhtml-3.8 libtinymail-1.0 libtinymail-camel-1.0 libtinymail-gnomevfs-1.0 libtinymailui-1.0 libtinymailui-gtk-1.0)
AC_SUBST(MODEST_GSTUFF_CFLAGS)
AC_SUBST(MODEST_GSTUFF_LIBS)
}
void
+modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
+
+ g_message ("Attach file operation is not supported");
+}
+
+void
+modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
+
+ g_message ("Remove attachments operation is not supported");
+}
+
+void
modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
gboolean show)
{
g_message ("not implemented %s", __FUNCTION__);
return FALSE;
}
+
+void
+modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart *mime_part)
+{
+ g_message ("not implemented %s", __FUNCTION__);
+}
+
+void
+modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mime_parts)
+{
+ g_message ("not implemented %s", __FUNCTION__);
+}
+void
+modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, GList *mime_parts)
+{
+ g_message ("not implemented %s", __FUNCTION__);
+}
}
gboolean
+modest_platform_activate_file (const gchar *path)
+{
+ modest_runtime_not_implemented (NULL);
+ return FALSE;
+}
+
+gboolean
modest_platform_show_uri_popup (const gchar *uri)
{
modest_runtime_not_implemented (NULL);
#include <dbus/dbus-glib-lowlevel.h>
#include <glib.h>
#include <modest-runtime.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <tny-fs-stream.h>
#include "modest-maemo-utils.h"
get_device_name_from_dbus ();
}
+gboolean
+modest_maemo_utils_folder_writable (const gchar *filename)
+{
+ if (g_strncasecmp (filename, "obex", 4) != 0) {
+ GnomeVFSFileInfo folder_info;
+ gchar *folder;
+ folder = g_path_get_dirname (filename);
+ gnome_vfs_get_file_info (folder, &folder_info,
+ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS);
+ g_free (folder);
+ if (!((folder_info.permissions & GNOME_VFS_PERM_ACCESS_WRITABLE) ||
+ (folder_info.permissions & GNOME_VFS_PERM_USER_WRITE))) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+gboolean
+modest_maemo_utils_file_exists (const gchar *filename)
+{
+ GnomeVFSURI *uri = NULL;
+ gboolean result = FALSE;
+ uri = gnome_vfs_uri_new (filename);
+ if (uri) {
+ result = gnome_vfs_uri_exists (uri);
+ gnome_vfs_uri_unref (uri);
+ }
+ return result;
+}
+TnyFsStream *
+modest_maemo_utils_create_temp_stream (gchar **path)
+{
+ TnyStream *tmp_fs_stream;
+ gint fd;
+ gchar *filepath;
+
+ fd = g_file_open_tmp (NULL, &filepath, NULL);
+ if (path != NULL)
+ *path = filepath;
+ if (fd == -1) {
+ g_message ("TODO BANNER: Error saving stream");
+ return NULL;
+ }
+ tmp_fs_stream = tny_fs_stream_new (fd);
+
+ return TNY_FS_STREAM (tmp_fs_stream);
+}
*/
void modest_maemo_utils_get_device_name (void);
+/**
+ * modest_maemo_utils_folder_writable:
+ * @filename: a string
+ *
+ * Checks if @filename is in a writable folder
+ *
+ * Returns: %TRUE if @filename is writable, %FALSE otherwise
+ */
+gboolean modest_maemo_utils_folder_writable (const gchar *filename);
+
+/**
+ * modest_maemo_utils_file_exists:
+ * @filename: a string
+ *
+ * Checks if @filename exists
+ *
+ * Returns: %TRUE if @filename currently exists, %FALSE otherwise
+ */
+gboolean modest_maemo_utils_file_exists (const gchar *filename);
+
+/**
+ * modest_maemo_utils_create_temp_stream:
+ * @path: a string with the created file path
+ *
+ * Creates a temporary fs stream
+ *
+ * Returns: a #TnyFsStream, or %NULL if operation failed.
+ */
+TnyFsStream *modest_maemo_utils_create_temp_stream (gchar **path);
#endif /*__MODEST_MAEMO_UTILS_H__*/
{ "Edit", NULL, N_("mcen_me_inbox_edit") },
{ "View", NULL, N_("mcen_me_inbox_view") },
{ "Tools", NULL, N_("mcen_me_inbox_tools") },
+ { "Attachments", NULL, N_("mcen_me_viewer_attachments") },
{ "Close", NULL, N_("mcen_me_inbox_close") },
{ "Zoom", NULL, N_("Zoom") },
{ "ViewShowToolbar", NULL, N_("mcen_me_inbox_toolbar") }, /* submenu */
{ "ViewPreviousMessage", NULL, N_("qgn_toolb_gene_back"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_prev) },
{ "ViewNextMessage", NULL, N_("qgn_toolb_gene_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_next) },
+
+ /* Attachments */
+ { "ViewAttachment", NULL, N_("mcen_me_viewer_view_attachment"), NULL, NULL, G_CALLBACK (modest_ui_actions_view_attachment) },
+ { "SaveAttachment", NULL, N_("mcen_me_viewer_save_attachments"), NULL, NULL, G_CALLBACK (modest_ui_actions_save_attachments) },
+ { "RemoveAttachment", NULL, N_("mcen_me_viewer_remove_attachments"), NULL, NULL, G_CALLBACK (modest_ui_actions_remove_attachments) },
/* Tools */
{ "ToolsSettings", NULL, N_("mcen_me_inbox_options"), NULL, NULL, NULL },
#include "modest-hildon-includes.h"
#include "widgets/modest-msg-edit-window-ui.h"
+#include <libgnomevfs/gnome-vfs-mime.h>
#define DEFAULT_FONT_SIZE 3
static gboolean is_modified (ModestMsgEditWindow *editor);
static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
+static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
static void text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *location, GtkTextMark *mark, gpointer userdata);
static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
+static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
gpointer userdata);
static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
gpointer userdata);
static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
ModestRecptEditor *editor);
+static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
+ ModestMsgEditWindow *window);
/* ModestWindow methods implementation */
static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
G_CALLBACK (text_buffer_refresh_attributes), obj);
g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
G_CALLBACK (text_buffer_mark_set), obj);
+ g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
+ G_CALLBACK (text_buffer_delete_range), obj);
g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
G_CALLBACK (text_buffer_can_undo), obj);
g_signal_connect (G_OBJECT (obj), "window-state-event",
g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
+ g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
+ G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
+
g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
G_CALLBACK (msg_body_focus), obj);
g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
}
+void
+modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
+{
+
+ ModestMsgEditWindowPrivate *priv;
+ GtkWidget *dialog = NULL;
+ gint response = 0;
+ gchar *filename = NULL;
+
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+
+ dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ switch (response) {
+ case GTK_RESPONSE_OK:
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ break;
+ default:
+ break;
+ }
+ gtk_widget_destroy (dialog);
+
+ if (filename) {
+ gint file_id;
+
+ file_id = g_open (filename, O_RDONLY, 0);
+ if (file_id != -1) {
+ TnyMimePart *mime_part;
+ TnyStream *stream;
+ const gchar *mime_type;
+ gchar *basename;
+ gchar *content_id;
+
+ /* TODO: get mime type */
+ mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
+ mime_part = tny_platform_factory_new_mime_part
+ (modest_runtime_get_platform_factory ());
+ stream = TNY_STREAM (tny_fs_stream_new (file_id));
+
+ tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
+
+ content_id = g_strdup_printf ("%d", priv->last_cid);
+ tny_mime_part_set_content_id (mime_part, content_id);
+ g_free (content_id);
+ priv->last_cid++;
+
+ basename = g_path_get_basename (filename);
+ tny_mime_part_set_filename (mime_part, basename);
+ g_free (basename);
+
+ priv->attachments = g_list_prepend (priv->attachments, mime_part);
+ modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
+ mime_part);
+ gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
+ gtk_widget_show_all (priv->attachments_caption);
+ } else if (file_id == -1) {
+ close (file_id);
+ }
+ }
+}
+
+void
+modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
+ GList *att_list)
+{
+ ModestMsgEditWindowPrivate *priv;
+ gboolean clean_list = FALSE;
+
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+
+ if (att_list == NULL) {
+ att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
+ clean_list = TRUE;
+ }
+
+ if (att_list == NULL) {
+ hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
+ } else {
+ GtkWidget *confirmation_dialog = NULL;
+ gboolean dialog_response;
+ GList *node;
+ if (att_list->next == NULL) {
+ gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
+ tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
+ confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
+ g_free (message);
+ } else {
+ confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
+ }
+ dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
+ gtk_widget_destroy (confirmation_dialog);
+ hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
+
+ for (node = att_list; node != NULL; node = g_list_next (node)) {
+ TnyMimePart *mime_part = (TnyMimePart *) node->data;
+ const gchar *att_id;
+ priv->attachments = g_list_remove (priv->attachments, mime_part);
+
+ modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
+ mime_part);
+ att_id = tny_mime_part_get_content_id (mime_part);
+ if (att_id != NULL)
+ text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
+ att_id);
+ g_object_unref (mime_part);
+ }
+ }
+
+ if (clean_list)
+ g_list_free (att_list);
+}
+
static void
modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
gpointer userdata)
gtk_action_set_sensitive (action, can_undo);
}
+static void
+text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
+{
+ GtkTextIter iter;
+ GtkTextIter match_start, match_end;
+
+ if (image_id == NULL)
+ return;
+
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+
+ while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
+ GSList *tags = gtk_text_iter_get_tags (&match_start);
+ GSList *node;
+ for (node = tags; node != NULL; node = g_slist_next (node)) {
+ GtkTextTag *tag = (GtkTextTag *) node->data;
+ if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
+ gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
+ if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
+ gint offset;
+ gtk_text_iter_get_offset (&match_start);
+ gtk_text_buffer_delete (buffer, &match_start, &match_end);
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+ }
+ }
+ }
+ }
+}
+
+static void
+text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
+{
+ ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
+ GtkTextIter real_start, real_end;
+ ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+
+ if (gtk_text_iter_compare (start, end) > 0) {
+ real_start = *end;
+ real_end = *start;
+ } else {
+ real_start = *start;
+ real_end = *end;
+ }
+ do {
+ GSList *tags = gtk_text_iter_get_tags (&real_start);
+ GSList *node;
+ for (node = tags; node != NULL; node = g_slist_next (node)) {
+ GtkTextTag *tag = (GtkTextTag *) node->data;
+ if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
+ gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
+
+ modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
+ image_id);
+ gtk_text_buffer_remove_tag (buffer, tag, start, end);
+ }
+ }
+ } while (gtk_text_iter_forward_char (&real_start)&&
+ (gtk_text_iter_compare (&real_start, &real_end)<=0));
+}
+
static gboolean
msg_body_focus (GtkWidget *focus,
GdkEventFocus *event,
return TRUE;
}
+
+static void
+modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
+ ModestMsgEditWindow *window)
+{
+ modest_msg_edit_window_attach_file (window);
+}
#include <tny-account-store.h>
#include <tny-simple-list.h>
#include <tny-header.h>
+#include <tny-vfs-stream.h>
#include "modest-platform.h"
+#include <modest-maemo-utils.h>
#include <modest-tny-msg.h>
#include <modest-msg-view-window.h>
#include <modest-main-window-ui.h>
#include <modest-window-priv.h>
#include <modest-tny-folder.h>
#include <modest-text-utils.h>
+#include <modest-account-mgr-helpers.h>
#include "modest-progress-bar-widget.h"
#include "modest-defs.h"
#include "modest-hildon-includes.h"
#include <gtkhtml/gtkhtml-search.h>
#include <gdk/gdkkeysyms.h>
+#define DEFAULT_FOLDER "MyDocs/.documents"
+
static void modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass);
static void modest_msg_view_window_init (ModestMsgViewWindow *obj);
static void modest_msg_view_window_finalize (GObject *obj);
modest_msg_view_window_update_dimmed (ModestMsgViewWindow *window)
{
ModestWindowPrivate *parent_priv;
+ ModestMsgViewWindowPrivate *priv;
GtkAction *widget;
gboolean is_first, is_last;
TnyFolderType folder_type;
gboolean is_not_sent;
+ GList *attachments, *node;
+ gint n_selected;
+ gboolean selected_messages = FALSE;
parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
is_first = modest_msg_view_window_is_first_message (window);
is_last = modest_msg_view_window_is_last_message (window);
gtk_action_set_sensitive (widget, !is_not_sent);
widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/MessageMenu/MessageForwardMenu");
gtk_action_set_sensitive (widget, !is_not_sent);
+
+ attachments = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
+ n_selected = g_list_length (attachments);
+ for (node = attachments; node != NULL; node = g_list_next (node)) {
+ if (!tny_mime_part_is_attachment (TNY_MIME_PART (node->data))) {
+ selected_messages = TRUE;
+ break;
+ }
+ }
+ g_list_free (attachments);
+
+ widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/ViewAttachmentMenu");
+ gtk_action_set_sensitive (widget, n_selected == 1);
+ widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/SaveAttachmentMenu");
+ gtk_action_set_sensitive (widget, (n_selected > 0) && (!selected_messages));
}
parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
selection = gtk_clipboard_wait_for_text (clipboard);
- /* g_message ("SELECTION %s", selection); */
is_address = ((selection != NULL) && (modest_text_utils_validate_recipient (selection)));
g_free (selection);
action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/ToolsAddToContactsMenu");
gtk_action_set_sensitive (action, is_address);
+
+ modest_msg_view_window_update_dimmed (window);
}
break;
}
}
+
+void
+modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart *mime_part)
+{
+ ModestMsgViewWindowPrivate *priv;
+ g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
+ g_return_if_fail (TNY_IS_MIME_PART (mime_part) || (mime_part == NULL));
+
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+ if (mime_part == NULL) {
+ gboolean error = FALSE;
+ GList *selected_attachments = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
+ if (selected_attachments == NULL) {
+ error = TRUE;
+ } else if (g_list_length (selected_attachments) > 1) {
+ hildon_banner_show_information (NULL, NULL, _("TODO: more than one attachment is selected"));
+ error = TRUE;
+ } else {
+ mime_part = (TnyMimePart *) selected_attachments->data;
+ g_object_ref (mime_part);
+ }
+ g_list_foreach (selected_attachments, (GFunc) g_object_unref, NULL);
+ g_list_free (selected_attachments);
+
+ if (error)
+ return;
+ } else {
+ g_object_ref (mime_part);
+ }
+
+ if (!TNY_IS_MSG (mime_part)) {
+ gchar *filepath = NULL;
+ TnyFsStream *temp_stream = modest_maemo_utils_create_temp_stream (&filepath);
+
+ if (temp_stream) {
+ tny_mime_part_decode_to_stream (mime_part, TNY_STREAM (temp_stream));
+ modest_platform_activate_file (filepath);
+ g_object_unref (temp_stream);
+ g_free (filepath);
+ /* TODO: delete temporary file */
+ }
+ } else {
+ /* message attachment */
+ TnyHeader *header = NULL;
+ ModestWindowMgr *mgr;
+ ModestWindow *msg_win;
+
+ header = tny_msg_get_header (TNY_MSG (mime_part));
+ mgr = modest_runtime_get_window_mgr ();
+ /* TODO: this is not getting any uid */
+ msg_win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
+
+ if (!msg_win) {
+ gchar *account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (window)));
+ if (!account)
+ account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+ msg_win = modest_msg_view_window_new (TNY_MSG (mime_part), account);
+ modest_window_mgr_register_window (mgr, msg_win);
+ gtk_window_set_transient_for (GTK_WINDOW (msg_win), GTK_WINDOW (window));
+ }
+
+ gtk_widget_show_all (GTK_WIDGET (msg_win));
+ }
+ g_object_unref (mime_part);
+}
+
+static gboolean
+save_mime_part_to_file (const gchar *filename, TnyMimePart *mime_part)
+{
+ GnomeVFSResult result;
+ GnomeVFSHandle *handle;
+ TnyStream *stream;
+
+ result = gnome_vfs_create (&handle, filename, GNOME_VFS_OPEN_WRITE, FALSE, 0777);
+ if (result != GNOME_VFS_OK) {
+ hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
+ return FALSE;
+ }
+ stream = tny_vfs_stream_new (handle);
+ tny_mime_part_decode_to_stream (mime_part, stream);
+ g_object_unref (G_OBJECT (stream));
+ return TRUE;
+}
+
+static gboolean
+save_mime_part_to_file_with_checks (GtkWindow *parent, const gchar *filename, TnyMimePart *mime_part)
+{
+ if (modest_maemo_utils_file_exists (filename)) {
+ GtkWidget *confirm_overwrite_dialog;
+ confirm_overwrite_dialog = hildon_note_new_confirmation (GTK_WINDOW (parent),
+ _("TODO: confirm overwrite"));
+ if (gtk_dialog_run (GTK_DIALOG (confirm_overwrite_dialog)) != GTK_RESPONSE_OK) {
+ gtk_widget_destroy (confirm_overwrite_dialog);
+ return FALSE;
+ }
+ gtk_widget_destroy (confirm_overwrite_dialog);
+ }
+
+ return save_mime_part_to_file (filename, mime_part);
+}
+
+void
+modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mime_parts)
+{
+ gboolean clean_list = FALSE;
+ ModestMsgViewWindowPrivate *priv;
+ g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
+
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+ if (mime_parts == NULL) {
+ mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
+ if (mime_parts == NULL)
+ return;
+ clean_list = TRUE;
+ }
+
+ if (mime_parts->next == NULL) {
+ /* only one attachment selected */
+ GtkWidget *save_dialog = NULL;
+ TnyMimePart *mime_part = (TnyMimePart *) mime_parts->data;
+ if (!TNY_IS_MSG (mime_part) && tny_mime_part_is_attachment (mime_part)) {
+ const gchar *filename;
+ gchar *folder;
+ save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_SAVE);
+ folder = g_build_filename (g_get_home_dir (), DEFAULT_FOLDER, NULL);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), folder);
+ g_free (folder);
+ filename = tny_mime_part_get_filename (mime_part);
+ if (filename != NULL)
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save_dialog), filename);
+ while (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) {
+ gchar *filename_tmp = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
+ gboolean save_result;
+ if (!modest_maemo_utils_folder_writable (filename_tmp)) {
+ g_free (filename_tmp);
+ hildon_banner_show_information (NULL, NULL, _("TODO: read only location"));
+ continue;
+ }
+ save_result = save_mime_part_to_file_with_checks (GTK_WINDOW (save_dialog),
+ filename_tmp, mime_part);
+ g_free (filename_tmp);
+ if (save_result)
+ break;
+ else
+ continue;
+ }
+ gtk_widget_destroy (save_dialog);
+ } else {
+ g_warning ("Tried to save a non-file attachment");
+ }
+ } else {
+ GtkWidget *save_dialog = NULL;
+ gchar *folder;
+ save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ folder = g_build_filename (g_get_home_dir (), DEFAULT_FOLDER, NULL);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), folder);
+ g_free (folder);
+ if (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) {
+ gchar *foldername = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
+ GList *node = NULL;
+ gboolean attachment_found = FALSE;
+ if (!modest_maemo_utils_folder_writable (foldername)) {
+ g_free (foldername);
+ hildon_banner_show_information (NULL, NULL, _("TODO: read only location"));
+ }
+ for (node = mime_parts; node != NULL; node = g_list_next (node)) {
+ TnyMimePart *mime_part = (TnyMimePart *) node->data;
+ if (tny_mime_part_is_attachment (mime_part)) {
+ const gchar *att_filename = tny_mime_part_get_filename (mime_part);
+ if (att_filename != NULL) {
+ gchar *full_filename;
+ gboolean save_result;
+ full_filename = g_build_filename (foldername, att_filename, NULL);
+ attachment_found = TRUE;
+
+ save_result = save_mime_part_to_file_with_checks (GTK_WINDOW (save_dialog),
+ full_filename, mime_part);
+ g_free (full_filename);
+ if (!save_result)
+ break;
+ }
+ }
+ }
+ gtk_widget_destroy (save_dialog);
+ } else {
+ g_warning ("Tried to save a non-file attachment");
+ }
+ /* more than one attachment selected */
+ }
+ if (clean_list) {
+ g_list_foreach (mime_parts, (GFunc) g_object_unref, NULL);
+ g_list_free (mime_parts);
+ }
+}
+
+void
+modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, GList *mime_parts)
+{
+/* g_message ("not implemented %s", __FUNCTION__); */
+}
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkmain.h>
#include <string.h>
+
+static osso_context_t *osso_context = NULL;
gboolean
modest_platform_init (void)
{
- osso_context_t *osso_context =
+ osso_context =
osso_initialize(PACKAGE, PACKAGE_VERSION,
TRUE, NULL);
if (!osso_context) {
return result;
}
+gboolean
+modest_platform_activate_file (const gchar *path)
+{
+ gint result;
+ DBusConnection *con;
+ gchar *uri_path = NULL;
+
+ uri_path = g_strconcat ("file://", path, NULL);
+
+ con = osso_get_dbus_connection (osso_context);
+#ifdef MODEST_HILDON_VERSION_0
+ result = osso_mime_open_file (con, uri_path);
+
+ if (result != 1)
+ hildon_banner_show_information (NULL, NULL, _("mcen_ni_noregistered_viewer"));
+ return result != 1;
+#else
+ result = hildon_mime_open_file (con, uri_path);
+
+ if (result != 1)
+ hildon_banner_show_information (NULL, NULL, _("mcen_ni_noregistered_viewer"));
+ return result != 1;
+#endif
+
+}
+
typedef struct {
GSList * actions;
gchar *uri;
</menu>
<menu name="AttachmentsMenu" action="Attachments">
+ <menuitem name="AttachFileMenu" action="AttachFile"/>
<menuitem name="InsertImageMenu" action="InsertImage"/>
+ <menuitem name="RemoveAttachmentsMenu" action="RemoveAttachments"/>
</menu>
<menu name="ToolsMenu" action="Tools">
<menuitem name="ViewNextMessageMenu" action="ViewNextMessage"/>
</menu>
+ <menu name="AttachmentsMenu" action="Attachments">
+ <menuitem name="ViewAttachmentMenu" action="ViewAttachment"/>
+ <menuitem name="SaveAttachmentMenu" action="SaveAttachment"/>
+ <menuitem name="RemoveAttachmentMenu" action="RemoveAttachment"/>
+ </menu>
+
<menu name="ToolsMenu" action="Tools">
<menuitem name="ToolsAddToContactsMenu" action="ToolsAddToContacts"/>
<separator/>
gboolean modest_platform_activate_uri (const gchar *uri);
/**
+ * modest_platform_activate_file:
+ * @path: the path to activate
+ *
+ * This function activates a file
+ *
+ * Returns: %TRUE if successful, %FALSE if not.
+ **/
+gboolean modest_platform_activate_file (const gchar *path);
+
+/**
* modest_platform_show_uri_popup:
* @uri: an URI with the string
*
gchar *
-modest_text_utils_get_display_size (guint size)
+modest_text_utils_get_display_size (guint64 size)
{
const guint KB=1024;
const guint MB=1024 * KB;
const guint GB=1024 * MB;
+ if (size == 0)
+ return g_strdup_printf(_FM("sfil_li_size_kb"), 0);
if (0 < size && size < KB)
return g_strdup_printf (_FM("sfil_li_size_kb"), 1);
else if (KB <= size && size < 100 * KB)
* Returns: the newly allocated display string for the
* size in bytes. must be freed.
*/
-gchar * modest_text_utils_get_display_size (guint size);
+gchar * modest_text_utils_get_display_size (guint64 size);
/**
#include <widgets/modest-msg-view-window.h>
#include <widgets/modest-account-view-window.h>
#include <widgets/modest-details-dialog.h>
+#include <widgets/modest-attachments-view.h>
#include "modest-account-mgr-helpers.h"
#include "modest-mail-operation.h"
modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
ModestWindow *win)
{
- /* g_message (__FUNCTION__); */
-
+ modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
}
void
modest_msg_edit_window_insert_image (window);
}
+void
+modest_ui_actions_on_attach_file (GtkAction *action,
+ ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ modest_msg_edit_window_attach_file (window);
+}
+
+void
+modest_ui_actions_on_remove_attachments (GtkAction *action,
+ ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ modest_msg_edit_window_remove_attachments (window, NULL);
+}
+
/*
* Shows a dialog with an entry that asks for some text. The returned
* value must be freed by the caller. The dialog window title will be
GtkWidget *focused_widget;
focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
- if (GTK_IS_LABEL (focused_widget)) {
+ if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
+ modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
+ } else if (GTK_IS_LABEL (focused_widget)) {
gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
} else if (GTK_IS_EDITABLE (focused_widget)) {
gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
}
g_object_unref (iter);
}
+
+void
+modest_ui_actions_view_attachment (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
+void
+modest_ui_actions_save_attachments (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
+void
+modest_ui_actions_remove_attachments (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
void modest_ui_actions_on_insert_image (GtkAction *action,
ModestMsgEditWindow *window);
+void modest_ui_actions_on_attach_file (GtkAction *action,
+ ModestMsgEditWindow *window);
+
+void modest_ui_actions_on_remove_attachments (GtkAction *action,
+ ModestMsgEditWindow *window);
+
/**
* modest_ui_actions_do_send_receive_all:
* @win: the window that will be used as source of the refresh mail operation
const gchar *display_name,
GtkWindow *window);
+void modest_ui_actions_view_attachment (GtkAction *action,
+ ModestWindow *window);
+
+void modest_ui_actions_save_attachments (GtkAction *action,
+ ModestWindow *window);
+
+void modest_ui_actions_remove_attachments (GtkAction *action,
+ ModestWindow *window);
+
+
+
G_END_DECLS
#endif /* __MODEST_UI_ACTIONS_H__ */
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif /*HAVE_CONFIG_H*/
-//#include <glib/gi18n-lib.h>
+#include <glib/gi18n.h>
#include <string.h>
#include <modest-attachment-view.h>
#include <modest-platform.h>
#include <modest-text-utils.h>
+#include <tny-msg.h>
static GObjectClass *parent_class = NULL;
-/* signals */
-enum {
- ACTIVATE_SIGNAL,
- LAST_SIGNAL
-};
+/* /\* signals *\/ */
+/* enum { */
+/* LAST_SIGNAL */
+/* }; */
typedef struct _ModestAttachmentViewPriv ModestAttachmentViewPriv;
guint get_size_idle_id;
TnyStream *get_size_stream;
- guint size;
+ guint64 size;
PangoLayout *layout_full_filename;
- gboolean button_pressed;
- gdouble pressed_x, pressed_y;
};
#define UNKNOWN_FILE_ICON "qgn_list_gene_unknown_file"
#define MODEST_ATTACHMENT_VIEW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewPriv))
-static guint signals[LAST_SIGNAL] = {0};
+/* static guint signals[LAST_SIGNAL] = {0}; */
/* TnyMimePartView functions */
static TnyMimePart *modest_attachment_view_get_part (TnyMimePartView *self);
static void modest_attachment_view_clear_default (TnyMimePartView *self);
/* Gtk events */
-static gint button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
-static gint button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
static void size_allocate (GtkWidget *widget, GtkAllocation *allocation);
/* GObject and GInterface management */
priv->size = 0;
- filename = tny_mime_part_get_filename (mime_part);
- file_icon_name = modest_platform_get_file_icon_name (filename,
- tny_mime_part_get_content_type (mime_part),
- NULL);
+ if (TNY_IS_MSG (mime_part)) {
+ TnyHeader *header = tny_msg_get_header (TNY_MSG (mime_part));
+ if (TNY_IS_HEADER (header)) {
+ filename = tny_header_get_subject (header);
+ if (filename == NULL)
+ filename = _("mail_va_no_subject");
+ file_icon_name = modest_platform_get_file_icon_name (NULL, tny_mime_part_get_content_type (mime_part), NULL);
+ g_object_unref (header);
+ }
+ } else {
+ filename = tny_mime_part_get_filename (mime_part);
+ file_icon_name = modest_platform_get_file_icon_name (filename,
+ tny_mime_part_get_content_type (mime_part),
+ NULL);
+ }
if (file_icon_name) {
gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), file_icon_name, GTK_ICON_SIZE_MENU);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
-static gint
-button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer user_data)
-{
- ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (MODEST_ATTACHMENT_VIEW (user_data));
-
- if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
- priv->button_pressed = TRUE;
- priv->pressed_x = event->x;
- priv->pressed_y = event->y;
- }
- return TRUE;
-}
-
-static gint
-button_release_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer user_data)
-{
- ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (MODEST_ATTACHMENT_VIEW (user_data));
-
- if (event->type != GDK_BUTTON_RELEASE)
- return TRUE;
-
- if ((priv->button_pressed) &&
- (event->type == GDK_BUTTON_RELEASE) &&
- (priv->pressed_x == event->x) &&
- (priv->pressed_y == event->y)) {
- priv->button_pressed = FALSE;
- if (event->button == 1) {
- g_signal_emit (G_OBJECT (user_data), signals[ACTIVATE_SIGNAL], 0);
- return TRUE;
- }
- }
- priv->button_pressed = FALSE;
- return TRUE;
-}
-
-
/**
* modest_attachment_view_new:
{
ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (instance);
PangoContext *context;
- GtkWidget *icon_eventbox;
+ GtkWidget *box = NULL;
priv->mime_part = NULL;
priv->icon = gtk_image_new ();
gtk_label_set_line_wrap (GTK_LABEL (priv->filename_view), FALSE);
gtk_label_set_ellipsize (GTK_LABEL (priv->filename_view), PANGO_ELLIPSIZE_END);
gtk_label_set_single_line_mode (GTK_LABEL (priv->filename_view), TRUE);
- gtk_label_set_selectable (GTK_LABEL (priv->filename_view), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (priv->filename_view), FALSE);
priv->size_view = gtk_label_new (" ");
gtk_label_set_line_wrap (GTK_LABEL (priv->size_view), FALSE);
- gtk_label_set_selectable (GTK_LABEL (priv->size_view), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (priv->size_view), FALSE);
gtk_misc_set_alignment (GTK_MISC (priv->size_view), 0.0, 0.5);
gtk_misc_set_alignment (GTK_MISC (priv->filename_view), 0.0, 0.5);
priv->get_size_stream = NULL;
priv->size = 0;
- icon_eventbox = gtk_event_box_new ();
+ box = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), priv->icon, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), priv->filename_view, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), priv->size_view, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (instance), box);
- gtk_container_add (GTK_CONTAINER (icon_eventbox), priv->icon);
- gtk_box_pack_start (GTK_BOX (instance), icon_eventbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (instance), priv->filename_view, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (instance), priv->size_view, FALSE, FALSE, 0);
+/* gtk_widget_get_style */
+/* gtk_widget_modify_bg (instance, GTK_STATE_SELECTED, selection_color); */
context = gtk_widget_get_pango_context (priv->filename_view);
priv->layout_full_filename = pango_layout_new (context);
pango_layout_set_ellipsize (priv->layout_full_filename, PANGO_ELLIPSIZE_NONE);
- g_signal_connect (G_OBJECT (priv->filename_view), "button-press-event", G_CALLBACK (button_press_event), instance);
- g_signal_connect (G_OBJECT (priv->filename_view), "button-release-event", G_CALLBACK (button_release_event), instance);
- g_signal_connect (G_OBJECT (priv->size_view), "button-press-event", G_CALLBACK (button_press_event), instance);
- g_signal_connect (G_OBJECT (priv->size_view), "button-release-event", G_CALLBACK (button_release_event), instance);
- g_signal_connect (G_OBJECT (icon_eventbox), "button-press-event", G_CALLBACK (button_press_event), instance);
- g_signal_connect (G_OBJECT (icon_eventbox), "button-release-event", G_CALLBACK (button_release_event), instance);
+ gtk_event_box_set_above_child (GTK_EVENT_BOX (instance), TRUE);
+
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (instance), GTK_CAN_FOCUS);
return;
}
g_type_class_add_private (object_class, sizeof (ModestAttachmentViewPriv));
- signals[ACTIVATE_SIGNAL] =
- g_signal_new ("activate",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(ModestAttachmentViewClass, activate),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
return;
}
NULL /* interface_data */
};
- type = g_type_register_static (GTK_TYPE_HBOX,
+ type = g_type_register_static (GTK_TYPE_EVENT_BOX,
"ModestAttachmentView",
&info, 0);
struct _ModestAttachmentView
{
- GtkHBox parent;
+ GtkEventBox parent;
};
struct _ModestAttachmentViewClass
{
- GtkHBoxClass parent_class;
+ GtkEventBoxClass parent_class;
/* virtual methods */
TnyMimePart* (*get_part_func) (TnyMimePartView *self);
LAST_SIGNAL
};
-typedef struct _ModestAttachmentsViewPriv ModestAttachmentsViewPriv;
+typedef struct _ModestAttachmentsViewPrivate ModestAttachmentsViewPrivate;
-struct _ModestAttachmentsViewPriv
+struct _ModestAttachmentsViewPrivate
{
TnyMsg *msg;
+ GtkWidget *box;
+ GList *selected;
+ GtkWidget *rubber_start;
};
#define MODEST_ATTACHMENTS_VIEW_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENTS_VIEW, ModestAttachmentsViewPriv))
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENTS_VIEW, ModestAttachmentsViewPrivate))
+
+static gboolean button_press_event (GtkWidget *widget, GdkEventButton *event, ModestAttachmentsView *atts_view);
+static gboolean motion_notify_event (GtkWidget *widget, GdkEventMotion *event, ModestAttachmentsView *atts_view);
+static gboolean button_release_event (GtkWidget *widget, GdkEventButton *event, ModestAttachmentsView *atts_view);
+static gboolean key_press_event (GtkWidget *widget, GdkEventKey *event, ModestAttachmentsView *atts_view);
+static GtkWidget *get_att_view_at_coords (ModestAttachmentsView *atts_view,
+ gdouble x, gdouble y);
+static void unselect_all (ModestAttachmentsView *atts_view);
+static void set_selected (ModestAttachmentsView *atts_view, ModestAttachmentView *att_view);
+static void select_range (ModestAttachmentsView *atts_view, ModestAttachmentView *att1, ModestAttachmentView *att2);
+static void clipboard_get (GtkClipboard *clipboard, GtkSelectionData *selection_data,
+ guint info, gpointer userdata);
+static void clipboard_clear (GtkClipboard *clipboard, gpointer userdata);
+static void own_clipboard (ModestAttachmentsView *atts_view);
static guint signals[LAST_SIGNAL] = {0};
modest_attachments_view_new (TnyMsg *msg)
{
ModestAttachmentsView *self = g_object_new (MODEST_TYPE_ATTACHMENTS_VIEW,
- "homogeneous", FALSE,
- "spacing", 0,
"resize-mode", GTK_RESIZE_PARENT,
NULL);
void
modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, TnyMsg *msg)
{
- ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view);
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view);
TnyList *parts;
TnyIterator *iter;
priv->msg = msg;
- gtk_container_foreach (GTK_CONTAINER (attachments_view), (GtkCallback) gtk_widget_destroy, NULL);
+ gtk_container_foreach (GTK_CONTAINER (priv->box), (GtkCallback) gtk_widget_destroy, NULL);
if (priv->msg == NULL) {
return;
TnyMimePart *part;
part = TNY_MIME_PART (tny_iterator_get_current (iter));
- if (tny_mime_part_is_attachment (part)) {
+ if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
modest_attachments_view_add_attachment (attachments_view, part);
}
g_object_unref (part);
modest_attachments_view_add_attachment (ModestAttachmentsView *attachments_view, TnyMimePart *part)
{
GtkWidget *att_view = NULL;
+ ModestAttachmentsViewPrivate *priv = NULL;
g_return_if_fail (MODEST_IS_ATTACHMENTS_VIEW (attachments_view));
g_return_if_fail (TNY_IS_MIME_PART (part));
- g_return_if_fail (tny_mime_part_is_attachment (part));
+
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view);
att_view = modest_attachment_view_new (part);
- gtk_box_pack_end (GTK_BOX (attachments_view), att_view, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->box), att_view, FALSE, FALSE, 0);
gtk_widget_show_all (att_view);
g_signal_connect (G_OBJECT (att_view), "activate", G_CALLBACK (activate_attachment), (gpointer) attachments_view);
}
+void
+modest_attachments_view_remove_attachment (ModestAttachmentsView *atts_view, TnyMimePart *mime_part)
+{
+ ModestAttachmentsViewPrivate *priv = NULL;
+ GList *box_children = NULL, *node = NULL;
+ ModestAttachmentView *found_att_view = NULL;
+
+ g_return_if_fail (MODEST_IS_ATTACHMENTS_VIEW (atts_view));
+ g_return_if_fail (TNY_IS_MIME_PART (mime_part));
+
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ box_children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+
+ for (node = box_children; node != NULL; node = g_list_next (node)) {
+ ModestAttachmentView *att_view = (ModestAttachmentView *) node->data;
+ TnyMimePart *cur_mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (att_view));
+
+ if (mime_part == cur_mime_part)
+ found_att_view = att_view;
+
+ g_object_unref (cur_mime_part);
+
+ if (found_att_view != NULL)
+ break;
+ }
+
+ if (found_att_view) {
+ gtk_widget_destroy (GTK_WIDGET (found_att_view));
+ }
+
+}
+
+void
+modest_attachments_view_remove_attachment_by_id (ModestAttachmentsView *atts_view, const gchar *att_id)
+{
+ ModestAttachmentsViewPrivate *priv = NULL;
+ GList *box_children = NULL, *node = NULL;
+
+ g_return_if_fail (MODEST_IS_ATTACHMENTS_VIEW (atts_view));
+ g_return_if_fail (att_id != NULL);
+
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ box_children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+
+ for (node = box_children; node != NULL; node = g_list_next (node)) {
+ ModestAttachmentView *att_view = (ModestAttachmentView *) node->data;
+ TnyMimePart *cur_mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (att_view));
+ const gchar *mime_part_id = NULL;
+
+ mime_part_id = tny_mime_part_get_content_id (cur_mime_part);
+ if ((mime_part_id != NULL) && (strcmp (mime_part_id, att_id) == 0))
+ gtk_widget_destroy (GTK_WIDGET (att_view));
+
+ g_object_unref (cur_mime_part);
+ }
+
+}
+
static void
modest_attachments_view_instance_init (GTypeInstance *instance, gpointer g_class)
{
- ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (instance);
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (instance);
priv->msg = NULL;
+ priv->box = gtk_vbox_new (FALSE, 0);
+ priv->rubber_start = NULL;
+ priv->selected = NULL;
+
+ gtk_container_add (GTK_CONTAINER (instance), priv->box);
+ gtk_event_box_set_above_child (GTK_EVENT_BOX (instance), TRUE);
+
+ g_signal_connect (G_OBJECT (instance), "button-press-event", G_CALLBACK (button_press_event), instance);
+ g_signal_connect (G_OBJECT (instance), "button-release-event", G_CALLBACK (button_release_event), instance);
+ g_signal_connect (G_OBJECT (instance), "motion-notify-event", G_CALLBACK (motion_notify_event), instance);
+ g_signal_connect (G_OBJECT (instance), "key-press-event", G_CALLBACK (key_press_event), instance);
+
+ GTK_WIDGET_SET_FLAGS (instance, GTK_CAN_FOCUS);
return;
}
static void
modest_attachments_view_finalize (GObject *object)
{
- ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (object);
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (object);
if (priv->msg) {
g_object_unref (priv->msg);
klass->activate = NULL;
- g_type_class_add_private (object_class, sizeof (ModestAttachmentsViewPriv));
+ g_type_class_add_private (object_class, sizeof (ModestAttachmentsViewPrivate));
signals[ACTIVATE_SIGNAL] =
g_signal_new ("activate",
modest_attachments_view_instance_init /* instance_init */
};
- type = g_type_register_static (GTK_TYPE_VBOX,
+ type = g_type_register_static (GTK_TYPE_EVENT_BOX,
"ModestAttachmentsView",
&info, 0);
return type;
}
+
+/* buttons signal events */
+static gboolean
+button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ if (!GTK_WIDGET_HAS_FOCUS (widget))
+ gtk_widget_grab_focus (widget);
+
+ if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+ GtkWidget *att_view = get_att_view_at_coords (MODEST_ATTACHMENTS_VIEW (widget),
+ event->x, event->y);
+
+ if (att_view != NULL) {
+ if (GTK_WIDGET_STATE (att_view) == GTK_STATE_SELECTED && (g_list_length (priv->selected) < 2)) {
+ TnyMimePart *mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (att_view));
+ if (TNY_IS_MIME_PART (mime_part)) {
+ g_signal_emit (G_OBJECT (widget), signals[ACTIVATE_SIGNAL], 0, mime_part);
+ g_object_unref (mime_part);
+ }
+ } else {
+ set_selected (MODEST_ATTACHMENTS_VIEW (widget), MODEST_ATTACHMENT_VIEW (att_view));
+ priv->rubber_start = att_view;
+ gtk_grab_add (widget);
+ }
+ }
+ }
+ return TRUE;
+
+}
+
+static gboolean
+button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ if (widget == gtk_grab_get_current ()) {
+ GtkWidget *att_view = get_att_view_at_coords (MODEST_ATTACHMENTS_VIEW (widget),
+ event->x, event->y);
+
+ if (att_view != NULL) {
+ unselect_all (MODEST_ATTACHMENTS_VIEW (widget));
+ select_range (MODEST_ATTACHMENTS_VIEW (widget),
+ MODEST_ATTACHMENT_VIEW (priv->rubber_start),
+ MODEST_ATTACHMENT_VIEW (att_view));
+ }
+ priv->rubber_start = NULL;
+
+ gtk_grab_remove (widget);
+ }
+ return TRUE;
+}
+
+static gboolean
+motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ if (gtk_grab_get_current () == widget) {
+ GtkWidget *att_view = get_att_view_at_coords (MODEST_ATTACHMENTS_VIEW (widget),
+ event->x, event->y);
+
+ if (att_view != NULL) {
+ unselect_all (MODEST_ATTACHMENTS_VIEW (widget));
+ select_range (MODEST_ATTACHMENTS_VIEW (widget),
+ MODEST_ATTACHMENT_VIEW (priv->rubber_start),
+ MODEST_ATTACHMENT_VIEW (att_view));
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
+key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+
+ /* If grabbed (for example rubber banding), escape leaves the rubberbanding mode */
+ if (gtk_grab_get_current () == widget) {
+ if (event->keyval == GDK_Escape) {
+ set_selected (MODEST_ATTACHMENTS_VIEW (widget),
+ MODEST_ATTACHMENT_VIEW (priv->rubber_start));
+ priv->rubber_start = NULL;
+ gtk_grab_remove (widget);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ if (event->keyval == GDK_Up) {
+ ModestAttachmentView *current_sel = NULL;
+ gboolean move_out = FALSE;
+ GList * box_children, *new_sel;
+
+ box_children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ if (box_children == NULL)
+ move_out = TRUE;
+ else if ((priv->selected != NULL)&&(priv->selected->data != box_children->data))
+ current_sel = (ModestAttachmentView *) priv->selected->data;
+ else
+ move_out = TRUE;
+
+ if (move_out) {
+ GtkWidget *toplevel = NULL;
+ /* move cursor outside */
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_WIDGET_TOPLEVEL (toplevel) && GTK_IS_WINDOW (toplevel))
+ g_signal_emit_by_name (toplevel, "move-focus", GTK_DIR_UP);
+ unselect_all (atts_view);
+ } else {
+ new_sel = g_list_find (box_children, (gpointer) current_sel);
+ new_sel = g_list_previous (new_sel);
+ set_selected (MODEST_ATTACHMENTS_VIEW (atts_view), MODEST_ATTACHMENT_VIEW (new_sel->data));
+ }
+ g_list_free (box_children);
+ return TRUE;
+ }
+
+ if (event->keyval == GDK_Down) {
+ ModestAttachmentView *current_sel = NULL;
+ gboolean move_out = FALSE;
+ GList * box_children, *new_sel, *last_child = NULL;
+
+ box_children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+
+ if (box_children == NULL) {
+ move_out = TRUE;
+ } else {
+ last_child = g_list_last (box_children);
+ if (priv->selected != NULL) {
+ GList *last_selected = g_list_last (priv->selected);
+ if (last_selected->data != last_child->data)
+ current_sel = (ModestAttachmentView *) last_selected->data;
+ else
+ move_out = TRUE;
+ } else {
+ move_out = TRUE;
+ }
+ }
+
+ if (move_out) {
+ GtkWidget *toplevel = NULL;
+ /* move cursor outside */
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_WIDGET_TOPLEVEL (toplevel) && GTK_IS_WINDOW (toplevel))
+ g_signal_emit_by_name (toplevel, "move-focus", GTK_DIR_DOWN);
+ unselect_all (atts_view);
+ } else {
+ new_sel = g_list_find (box_children, (gpointer) current_sel);
+ new_sel = g_list_next (new_sel);
+ set_selected (MODEST_ATTACHMENTS_VIEW (atts_view), MODEST_ATTACHMENT_VIEW (new_sel->data));
+ }
+ g_list_free (box_children);
+ return TRUE;
+ }
+
+ /* Activates selected item */
+ if (g_list_length (priv->selected) == 1) {
+ ModestAttachmentView *att_view = (ModestAttachmentView *) priv->selected->data;
+ if ((event->keyval == GDK_Return)) {
+ TnyMimePart *mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (att_view));
+ if (TNY_IS_MIME_PART (mime_part)) {
+ g_signal_emit (G_OBJECT (widget), signals[ACTIVATE_SIGNAL], 0, mime_part);
+ g_object_unref (mime_part);
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static GtkWidget *
+get_att_view_at_coords (ModestAttachmentsView *atts_view,
+ gdouble x, gdouble y)
+{
+ ModestAttachmentsViewPrivate *priv = NULL;
+ GList *att_view_list, *node;
+ GtkWidget *result = NULL;
+
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ att_view_list = gtk_container_get_children (GTK_CONTAINER (priv->box));
+
+ for (node = att_view_list; node != NULL; node = g_list_next (node)) {
+ GtkWidget *att_view = (GtkWidget *) node->data;
+ gint pos_x, pos_y, w, h, int_x, int_y;
+
+ pos_x = att_view->allocation.x;
+ pos_y = att_view->allocation.y;
+ w = att_view->allocation.width;
+ h = att_view->allocation.height;
+
+ int_x = (gint) x;
+ int_y = (gint) y;
+
+ if ((x >= pos_x) && (x <= (pos_x + w)) && (y >= pos_y) && (y <= (pos_y + h))) {
+ result = att_view;
+ break;
+ }
+ }
+
+ g_list_free (att_view_list);
+ return result;
+}
+
+static void
+unselect_all (ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = NULL;
+ GList *att_view_list, *node;
+
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ att_view_list = gtk_container_get_children (GTK_CONTAINER (priv->box));
+
+ for (node = att_view_list; node != NULL; node = g_list_next (node)) {
+ GtkWidget *att_view = (GtkWidget *) node->data;
+
+ if (GTK_WIDGET_STATE (att_view) == GTK_STATE_SELECTED)
+ gtk_widget_set_state (att_view, GTK_STATE_NORMAL);
+ }
+
+ g_list_free (priv->selected);
+ priv->selected = NULL;
+
+ g_list_free (att_view_list);
+}
+
+static void
+set_selected (ModestAttachmentsView *atts_view, ModestAttachmentView *att_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+
+ unselect_all (atts_view);
+ gtk_widget_set_state (GTK_WIDGET (att_view), GTK_STATE_SELECTED);
+ g_list_free (priv->selected);
+ priv->selected = NULL;
+ priv->selected = g_list_append (priv->selected, att_view);
+
+ own_clipboard (atts_view);
+}
+
+static void
+select_range (ModestAttachmentsView *atts_view, ModestAttachmentView *att1, ModestAttachmentView *att2)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ GList *children = NULL;
+ GList *node = NULL;
+ gboolean selecting = FALSE;
+
+ unselect_all (atts_view);
+
+ if (att1 == att2) {
+ set_selected (atts_view, att1);
+ return;
+ }
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ g_list_free (priv->selected);
+ priv->selected = NULL;
+
+
+ for (node = children; node != NULL; node = g_list_next (node)) {
+ if ((node->data == att1) || (node->data == att2)) {
+ gtk_widget_set_state (GTK_WIDGET (node->data), GTK_STATE_SELECTED);
+ priv->selected = g_list_append (priv->selected, node->data);
+ selecting = !selecting;
+ } else if (selecting) {
+ gtk_widget_set_state (GTK_WIDGET (node->data), GTK_STATE_SELECTED);
+ priv->selected = g_list_append (priv->selected, node->data);
+ }
+
+ }
+ g_list_free (children);
+
+ own_clipboard (atts_view);
+}
+
+static void clipboard_get (GtkClipboard *clipboard, GtkSelectionData *selection_data,
+ guint info, gpointer userdata)
+{
+ ModestAttachmentsView *atts_view = (ModestAttachmentsView *) userdata;
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+
+ if ((priv->selected != NULL)&&(priv->selected->next == NULL)) {
+ TnyMimePart *mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (priv->selected->data));
+ if (info != MODEST_ATTACHMENTS_VIEW_CLIPBOARD_TYPE_INDEX) {
+ if (TNY_IS_MSG (mime_part)) {
+ TnyHeader *header = tny_msg_get_header (TNY_MSG (mime_part));
+ if (TNY_IS_HEADER (header)) {
+ gtk_selection_data_set_text (selection_data, tny_header_get_subject (header), -1);
+ g_object_unref (header);
+ }
+ } else {
+ gtk_selection_data_set_text (selection_data, tny_mime_part_get_filename (mime_part), -1);
+ }
+ } else {
+ /* MODEST_ATTACHMENT requested. As the content id is not filled in all the case, we'll
+ * use an internal index. This index is simply the index of the attachment in the vbox */
+ GList *box_children = NULL;
+ gint index;
+ box_children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ index = g_list_index (box_children, priv->selected);
+ if (index >= 0) {
+ gchar *index_str = g_strdup_printf("%d", index);
+ gtk_selection_data_set_text (selection_data, index_str, -1);
+ g_free (index_str);
+ }
+ }
+ }
+}
+
+static void clipboard_clear (GtkClipboard *clipboard, gpointer userdata)
+{
+ ModestAttachmentsView *atts_view = (ModestAttachmentsView *) userdata;
+
+ unselect_all (atts_view);
+}
+
+GList *
+modest_attachments_view_get_selection (ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv;
+ GList *selection, *node;
+
+ g_return_val_if_fail (MODEST_IS_ATTACHMENTS_VIEW (atts_view), NULL);
+ priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+
+ selection = NULL;
+ for (node = priv->selected; node != NULL; node = g_list_next (node)) {
+ ModestAttachmentView *att_view = (ModestAttachmentView *) node->data;
+ TnyMimePart *part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (att_view));
+ selection = g_list_append (selection, part);
+ }
+
+ return selection;
+}
+
+void
+modest_attachments_view_select_all (ModestAttachmentsView *atts_view)
+{
+ ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (atts_view);
+ GList *children = NULL;
+ GList *node = NULL;
+
+ unselect_all (atts_view);
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+ g_list_free (priv->selected);
+ priv->selected = NULL;
+
+
+ for (node = children; node != NULL; node = g_list_next (node)) {
+ gtk_widget_set_state (GTK_WIDGET (node->data), GTK_STATE_SELECTED);
+ priv->selected = g_list_append (priv->selected, node->data);
+ }
+ g_list_free (children);
+
+ own_clipboard (atts_view);
+}
+
+static void
+own_clipboard (ModestAttachmentsView *atts_view)
+{
+ GtkTargetEntry targets[] = {
+ {"TEXT", 0, 0},
+ {"UTF8_STRING", 0, 1},
+ {"COMPOUND_TEXT", 0, 2},
+ {"STRING", 0, 3},
+ {MODEST_ATTACHMENTS_VIEW_CLIPBOARD_TYPE, 0, MODEST_ATTACHMENTS_VIEW_CLIPBOARD_TYPE_INDEX},
+ };
+
+ gtk_clipboard_set_with_owner (gtk_widget_get_clipboard (GTK_WIDGET (atts_view), GDK_SELECTION_PRIMARY),
+ targets, G_N_ELEMENTS (targets),
+ clipboard_get, clipboard_clear, G_OBJECT(atts_view));
+
+}
#include <glib-object.h>
#include <tny-msg.h>
+#define MODEST_ATTACHMENTS_VIEW_SELECTION_PREFIX "modest-attachment:"
+#define MODEST_ATTACHMENTS_VIEW_CLIPBOARD_TYPE "MODEST_ATTACHMENT"
+#define MODEST_ATTACHMENTS_VIEW_CLIPBOARD_TYPE_INDEX 4
+
G_BEGIN_DECLS
#define MODEST_TYPE_ATTACHMENTS_VIEW (modest_attachments_view_get_type ())
struct _ModestAttachmentsView
{
- GtkVBox parent;
+ GtkEventBox parent;
};
struct _ModestAttachmentsViewClass
{
- GtkVBoxClass parent_class;
+ GtkEventBoxClass parent_class;
void (*activate) (ModestAttachmentsView *attachments_view, TnyMimePart *mime_part);
};
void modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, TnyMsg *msg);
void modest_attachments_view_add_attachment (ModestAttachmentsView *attachments_view, TnyMimePart *part);
+void modest_attachments_view_remove_attachment (ModestAttachmentsView *attachments_view, TnyMimePart *part);
+void modest_attachments_view_remove_attachment_by_id (ModestAttachmentsView *attachments_view, const gchar *att_id);
+GList *modest_attachments_view_get_selection (ModestAttachmentsView *attachments_view);
+void modest_attachments_view_select_all (ModestAttachmentsView *attachments_view);
G_END_DECLS
/* { "ActionsFontColor", GTK_STOCK_SELECT_COLOR, N_("Color"), NULL, N_("Change text color"), G_CALLBACK (modest_ui_actions_on_select_editor_color)}, */
/* { "BackgroundColor", GTK_STOCK_SELECT_COLOR, N_("Background color"), NULL, N_("Change background color"), G_CALLBACK (modest_ui_actions_on_select_editor_background_color)}, */
{ "InsertImage", NULL, N_("mcen_me_editor_attach_inlineimage"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_insert_image)},
+ { "AttachFile", NULL, N_("mcen_me_editor_attachfile"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_attach_file)},
+ { "RemoveAttachments", NULL, N_("mcen_me_inbox_remove_attachments"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_remove_attachments) },
{ "Undo", NULL, N_("mcen_me_inbox_undo"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_undo)},
{ "Cut", NULL, N_("mcen_me_inbox_cut"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_cut)},
{ "Copy", NULL, N_("mcen_me_inbox_copy"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_copy)},
void modest_msg_edit_window_insert_image (ModestMsgEditWindow *window);
/**
+ * modest_msg_edit_window_attach_file:
+ * @self: a #ModestMsgEditWindow
+ *
+ * show a file selection dialog to attach a file
+ */
+void modest_msg_edit_window_attach_file (ModestMsgEditWindow *window);
+
+/**
+ * modest_msg_edit_window_remove_attachments:
+ * @self: a #ModestMsgEditWindow
+ * @att_list: a #GList of #TnyMimePart
+ *
+ * remove attachments in @att_list, with a confirmation dialog
+ */
+void modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
+ GList *att_list);
+
+/**
* modest_msg_edit_window_show_cc:
* @window: a #ModestMsgEditWindow
* @show: a #gboolean
* toggles the current fullscreen status
*/
void modest_msg_view_window_toggle_fullscreen (ModestMsgViewWindow *window);
+
+/**
+ * modest_msg_view_window_view_attachment:
+ * @window: a #ModestMsgViewWindow
+ * @mime_part: a #TnyMimePart
+ *
+ * Opens @mime_part, or the currently selected attachment if @mime_part is %NULL.
+ * If it's a message, it opens it for viewing. Otherwise it opens a temporary file
+ * with the contents of the attachment.
+ */
+void modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
+ TnyMimePart *mime_part);
+
+/**
+ * modest_msg_view_window_save_attachments:
+ * @window: a #ModestMsgViewWindow
+ * @mime_parts: a #GList of #TnyMimePart
+ *
+ * Save the #TnyMimePart attachments in @mime_parts, or currently selected attachments
+ * if @mime_parts is %NULL, offering a dialog to the user to choose the location.
+ */
+void modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
+ GList *mime_parts);
+
+/**
+ * modest_msg_view_window_remove_attachments:
+ * @window: a #ModestMsgViewWindow
+ * @mime_parts: a #GList of #TnyMimePart
+ *
+ * Removes the attachments in @mime_parts, or currently selected attachments
+ * if @mime_parts is %NULL, from local storage.
+ */
+void modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window,
+ GList *mime_parts);
+
G_END_DECLS
#endif /* __MODEST_MSG_VIEW_WINDOW_H__ */
search,
FALSE, TRUE, TRUE);
y_offset = tmp_vadj->value;
- /* g_message ("VALUE %f", y_offset); */
gtk_layout_set_vadjustment (GTK_LAYOUT (priv->gtkhtml), vadj);
g_object_unref (vadj);
GtkAdjustment *adj;
adj = gtk_container_get_focus_vadjustment (GTK_CONTAINER (priv->gtkhtml));
- g_message ("ADJ value %f", adj->value);
}
*/
modest_mail_header_view_set_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), flags);
}
+
+GList *
+modest_msg_view_get_selected_attachments (ModestMsgView *self)
+{
+ ModestMsgViewPrivate *priv;
+
+ g_return_val_if_fail (MODEST_IS_MSG_VIEW (self), NULL);
+ priv = MODEST_MSG_VIEW_GET_PRIVATE (self);
+
+ return modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
+
+}
gdouble modest_msg_view_get_zoom (ModestMsgView *self);
TnyHeaderFlags modest_msg_view_get_priority (ModestMsgView *self);
void modest_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags);
+GList *modest_msg_view_get_selected_attachments (ModestMsgView *self);
G_END_DECLS