TnyStream *stream,
ModestMsgViewWindow *window);
+static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+ GtkScrollType scroll_type,
+ gboolean horizontal,
+ gpointer userdata);
+
/* list my signals */
enum {
MSG_CHANGED_SIGNAL,
+ SCROLL_CHILD_SIGNAL,
LAST_SIGNAL
};
MODEST_CONF_MSG_VIEW_WINDOW_KEY);
}
+static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+ GtkScrollType scroll_type,
+ gboolean horizontal,
+ gpointer userdata)
+{
+ ModestMsgViewWindowPrivate *priv;
+ gboolean return_value;
+
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
+ g_signal_emit_by_name (priv->main_scroll, "scroll-child", scroll_type, horizontal, &return_value);
+ return return_value;
+}
+
+static void
+add_scroll_binding (GtkBindingSet *binding_set,
+ guint keyval,
+ GtkScrollType scroll)
+{
+ guint keypad_keyval = keyval - GDK_Left + GDK_KP_Left;
+
+ gtk_binding_entry_add_signal (binding_set, keyval, 0,
+ "scroll_child", 2,
+ GTK_TYPE_SCROLL_TYPE, scroll,
+ G_TYPE_BOOLEAN, FALSE);
+ gtk_binding_entry_add_signal (binding_set, keypad_keyval, 0,
+ "scroll_child", 2,
+ GTK_TYPE_SCROLL_TYPE, scroll,
+ G_TYPE_BOOLEAN, FALSE);
+}
+
static void
modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
{
GObjectClass *gobject_class;
ModestWindowClass *modest_window_class;
+ GtkBindingSet *binding_set;
+
gobject_class = (GObjectClass*) klass;
modest_window_class = (ModestWindowClass *) klass;
modest_window_class->show_toolbar_func = modest_msg_view_window_show_toolbar;
modest_window_class->disconnect_signals_func = modest_msg_view_window_disconnect_signals;
- g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate));
-
modest_window_class->save_state_func = save_state;
+ klass->scroll_child = modest_msg_view_window_scroll_child;
+
signals[MSG_CHANGED_SIGNAL] =
g_signal_new ("msg-changed",
G_TYPE_FROM_CLASS (gobject_class),
NULL, NULL,
modest_marshal_VOID__POINTER_POINTER,
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
+
+ signals[SCROLL_CHILD_SIGNAL] =
+ g_signal_new ("scroll-child",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ModestMsgViewWindowClass, scroll_child),
+ NULL, NULL,
+ modest_marshal_BOOLEAN__ENUM_BOOLEAN,
+ G_TYPE_BOOLEAN, 2, GTK_TYPE_SCROLL_TYPE, G_TYPE_BOOLEAN);
+
+ binding_set = gtk_binding_set_by_class (klass);
+ add_scroll_binding (binding_set, GDK_Up, GTK_SCROLL_STEP_UP);
+ add_scroll_binding (binding_set, GDK_Down, GTK_SCROLL_STEP_DOWN);
+ add_scroll_binding (binding_set, GDK_Page_Up, GTK_SCROLL_PAGE_UP);
+ add_scroll_binding (binding_set, GDK_Page_Down, GTK_SCROLL_PAGE_DOWN);
+ add_scroll_binding (binding_set, GDK_Home, GTK_SCROLL_START);
+ add_scroll_binding (binding_set, GDK_End, GTK_SCROLL_END);
+
+ g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate));
+
}
static void modest_header_view_observer_init(
{
check_dimming_rules_after_change (window);
}
-
-static gboolean
-check_dimming_rules_after_change_in_idle (gpointer data)
-{
/* The window could have dissapeared */
- if (MODEST_IS_WINDOW (data)) {
- ModestWindow *win = MODEST_WINDOW (data);
- gdk_threads_enter ();
- modest_ui_actions_check_menu_dimming_rules (win);
- modest_ui_actions_check_toolbar_dimming_rules (win);
- gdk_threads_leave ();
- }
-
- return FALSE;
-}
static void
check_dimming_rules_after_change (ModestMsgViewWindow *window)
{
- static guint dimming_delayer = 0;
-
- if (dimming_delayer > 0)
- g_source_remove (dimming_delayer);
-
- /* We're expecting a lot of changes at the same time so don't
- need to check dimming rules for every change that
- happens */
- dimming_delayer = g_timeout_add (100, check_dimming_rules_after_change_in_idle, window);
+ modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
+ modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
}
event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down ||
event->keyval == GDK_Home || event->keyval == GDK_KP_Home ||
event->keyval == GDK_End || event->keyval == GDK_KP_End) {
- ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
- gboolean return_value;
+ /* ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); */
+ /* gboolean return_value; */
- if (event->type == GDK_KEY_RELEASE) {
+ if (event->type == GDK_KEY_PRESS) {
GtkScrollType scroll_type;
switch (event->keyval) {
default: scroll_type = GTK_SCROLL_NONE;
}
- g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child",
- scroll_type, FALSE, &return_value);
- return TRUE;
+ /* g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", */
+ /* scroll_type, FALSE, &return_value); */
+ return FALSE;
} else {
return FALSE;
}
if (!priv->header_model || !priv->row_reference)
return TRUE;
+ if (!gtk_tree_row_reference_valid (priv->row_reference))
+ return TRUE;
+
path = gtk_tree_row_reference_get_path (priv->row_reference);
if (path == NULL)
return TRUE;
ModestMsgViewWindowPrivate *priv;
gboolean is_first_selected;
GtkTreeIter tmp_iter;
-/* gchar * path_string;*/
g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), TRUE);
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
if (!priv->header_model || !priv->row_reference)
return TRUE;
+ if (!gtk_tree_row_reference_valid (priv->row_reference))
+ return TRUE;
+
path = gtk_tree_row_reference_get_path (priv->row_reference);
if (!path)
return TRUE;
-/* path_string = gtk_tree_path_to_string (path);
- is_first_selected = strcmp (path_string, "0");
-
- g_free (path_string);
- gtk_tree_path_free (path);
-
- return is_first_selected;*/
-
is_first_selected = TRUE;
while (is_first_selected) {
TnyHeader *header;
return selected_attachments;
}
+typedef struct {
+
+} DecodeAsyncHelper;
+
+static void
+on_decode_to_stream_async_handler (TnyMimePart *mime_part,
+ gboolean cancelled,
+ TnyStream *stream,
+ GError *err,
+ gpointer user_data)
+{
+ gchar *filepath = (gchar *) user_data;
+
+ if (cancelled || err) {
+ modest_platform_information_banner (NULL, NULL,
+ _("mail_ib_file_operation_failed"));
+ goto free;
+ }
+
+ /* make the file read-only */
+ g_chmod(filepath, 0444);
+
+ /* Activate the file */
+ modest_platform_activate_file (filepath, tny_mime_part_get_content_type (mime_part));
+
+ free:
+ /* Frees */
+ g_free (filepath);
+}
+
void
-modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart *mime_part)
+modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
+ TnyMimePart *mime_part)
{
ModestMsgViewWindowPrivate *priv;
const gchar *msg_uid;
if (!modest_tny_mime_part_is_msg (mime_part)) {
gchar *filepath = NULL;
const gchar *att_filename = tny_mime_part_get_filename (mime_part);
- const gchar *content_type;
gboolean show_error_banner = FALSE;
- GError *err;
TnyFsStream *temp_stream = NULL;
temp_stream = modest_utils_create_temp_stream (att_filename, attachment_uid,
&filepath);
if (temp_stream != NULL) {
- content_type = tny_mime_part_get_content_type (mime_part);
- if (tny_mime_part_decode_to_stream (mime_part, TNY_STREAM (temp_stream), &err) >= 0) {
- /* make the file read-only */
- if (g_chmod(filepath, 0444) != 0)
- g_warning ("%s: failed to set file '%s' to read-only: %s",
- __FUNCTION__, filepath, strerror(errno));
-
- modest_platform_activate_file (filepath, content_type);
- } else {
- /* error while saving attachment, maybe cerm_device_memory_full */
- show_error_banner = TRUE;
- if (err != NULL) {
- g_warning ("%s: tny_mime_part_decode_to_stream failed (%s)", __FUNCTION__, err->message);
- g_error_free (err);
- }
- }
+ tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream),
+ on_decode_to_stream_async_handler,
+ NULL,
+ g_strdup (filepath));
g_object_unref (temp_stream);
- g_free (filepath);
/* NOTE: files in the temporary area will be automatically
* cleaned after some time if they are no longer in use */
} else {
- if (filepath != NULL) {
+ if (filepath) {
+ const gchar *content_type;
/* the file may already exist but it isn't writable,
* let's try to open it anyway */
content_type = tny_mime_part_get_content_type (mime_part);
modest_platform_activate_file (filepath, content_type);
- g_free (filepath);
} else {
g_warning ("%s: modest_utils_create_temp_stream failed", __FUNCTION__);
show_error_banner = TRUE;
}
}
+ if (filepath)
+ g_free (filepath);
if (show_error_banner)
modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
} else {
}
+static void
+save_attachments_response (GtkDialog *dialog,
+ gint arg1,
+ gpointer user_data)
+{
+ TnyList *mime_parts;
+ gchar *chooser_uri;
+ GList *files_to_save = NULL;
+
+ mime_parts = TNY_LIST (user_data);
+
+ if (arg1 != GTK_RESPONSE_OK)
+ goto end;
+
+ chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+
+ if (!modest_utils_folder_writable (chooser_uri)) {
+ hildon_banner_show_information
+ (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location"));
+ } else {
+ TnyIterator *iter;
+
+ iter = tny_list_create_iterator (mime_parts);
+ while (!tny_iterator_is_done (iter)) {
+ TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
+
+ if ((modest_tny_mime_part_is_attachment_for_modest (mime_part)) &&
+ !tny_mime_part_is_purged (mime_part) &&
+ (tny_mime_part_get_filename (mime_part) != NULL)) {
+ SaveMimePartPair *pair;
+
+ pair = g_slice_new0 (SaveMimePartPair);
+
+ if (tny_list_get_length (mime_parts) > 1) {
+ gchar *escaped =
+ gnome_vfs_escape_slashes (tny_mime_part_get_filename (mime_part));
+ pair->filename = g_build_filename (chooser_uri, escaped, NULL);
+ g_free (escaped);
+ } else {
+ pair->filename = g_strdup (chooser_uri);
+ }
+ pair->part = mime_part;
+ files_to_save = g_list_prepend (files_to_save, pair);
+ }
+ tny_iterator_next (iter);
+ }
+ g_object_unref (iter);
+ }
+ g_free (chooser_uri);
+
+ if (files_to_save != NULL) {
+ SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
+ info->pairs = files_to_save;
+ info->result = TRUE;
+ save_mime_parts_to_file_with_checks (info);
+ }
+
+ end:
+ /* Free and close the dialog */
+ g_object_unref (mime_parts);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
void
modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *mime_parts)
{
ModestMsgViewWindowPrivate *priv;
- GList *files_to_save = NULL;
GtkWidget *save_dialog = NULL;
gchar *folder = NULL;
gchar *filename = NULL;
g_object_set (G_OBJECT (save_dialog), "save-multiple", save_multiple_str, NULL);
gtk_window_set_title (GTK_WINDOW (save_dialog), _FM("sfil_ti_save_objects_files"));
}
-
- /* show dialog */
- if (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) {
- gchar *chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
-
- if (!modest_utils_folder_writable (chooser_uri)) {
- hildon_banner_show_information
- (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location"));
- } else {
- TnyIterator *iter;
-
- iter = tny_list_create_iterator (mime_parts);
- while (!tny_iterator_is_done (iter)) {
- TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
-
- if ((modest_tny_mime_part_is_attachment_for_modest (mime_part)) &&
- !tny_mime_part_is_purged (mime_part) &&
- (tny_mime_part_get_filename (mime_part) != NULL)) {
- SaveMimePartPair *pair;
-
- pair = g_slice_new0 (SaveMimePartPair);
- if (save_multiple_str) {
- gchar *escaped = gnome_vfs_escape_slashes (
- tny_mime_part_get_filename (mime_part));
- pair->filename = g_build_filename (chooser_uri, escaped, NULL);
- g_free (escaped);
- } else {
- pair->filename = g_strdup (chooser_uri);
- }
- pair->part = mime_part;
- files_to_save = g_list_prepend (files_to_save, pair);
- }
- tny_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- g_free (chooser_uri);
- }
-
- gtk_widget_destroy (save_dialog);
- g_object_unref (mime_parts);
+ /* We must run this asynchronously, because the hildon dialog
+ performs a gtk_dialog_run by itself which leads to gdk
+ deadlocks */
+ g_signal_connect (save_dialog, "response",
+ G_CALLBACK (save_attachments_response), mime_parts);
- if (files_to_save != NULL) {
- SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
- info->pairs = files_to_save;
- info->result = TRUE;
- save_mime_parts_to_file_with_checks (info);
- }
+ gtk_widget_show_all (save_dialog);
}
static gboolean
gint n_attachments;
TnyMsg *msg;
TnyIterator *iter;
-/* TnyFolder *folder; */
g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
}
priv->purge_timeout = g_timeout_add (2000, show_remove_attachment_information, window);
-/* folder = tny_msg_get_folder (msg); */
-/* tny_msg_uncache_attachments (msg); */
-/* tny_folder_refresh (folder, NULL); */
-/* g_object_unref (folder); */
iter = tny_list_create_iterator (mime_parts);
while (!tny_iterator_is_done (iter)) {
part = (TnyMimePart *) tny_iterator_get_current (iter);
tny_mime_part_set_purged (TNY_MIME_PART (part));
-/* modest_msg_view_remove_attachment (MODEST_MSG_VIEW (priv->msg_view), node->data); */
g_object_unref (part);
tny_iterator_next (iter);
}