X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmaemo%2Fmodest-msg-view-window.c;h=7fa69d74cfeb9fde8e2d26bdb313b2c7190479f5;hp=f4704270f9b401a20925d1039bd0e53526661c1e;hb=cad3f56ab4e492218e57dbc5e700816a94090ee1;hpb=daf1f8f98046cc8aa43e225635ea3c6510249377 diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index f470427..7fa69d7 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -155,6 +155,11 @@ static gboolean msg_is_visible (TnyHeader *header, gboolean check_outbox); static void check_dimming_rules_after_change (ModestMsgViewWindow *window); +static gboolean on_fetch_image (ModestMsgView *msgview, + const gchar *uri, + TnyStream *stream, + ModestMsgViewWindow *window); + /* list my signals */ enum { MSG_CHANGED_SIGNAL, @@ -684,12 +689,13 @@ modest_msg_view_window_finalize (GObject *obj) static gboolean select_next_valid_row (GtkTreeModel *model, GtkTreeRowReference **row_reference, - gboolean cycle) + gboolean cycle, + gboolean is_outbox) { GtkTreeIter tmp_iter; GtkTreePath *path; GtkTreePath *next = NULL; - gboolean retval = FALSE; + gboolean retval = FALSE, finished; g_return_val_if_fail (gtk_tree_row_reference_valid (*row_reference), FALSE); @@ -698,19 +704,55 @@ select_next_valid_row (GtkTreeModel *model, gtk_tree_row_reference_free (*row_reference); *row_reference = NULL; - if (gtk_tree_model_iter_next (model, &tmp_iter)) { - next = gtk_tree_model_get_path (model, &tmp_iter); - *row_reference = gtk_tree_row_reference_new (model, next); - retval = TRUE; - } else if (cycle && gtk_tree_model_get_iter_first (model, &tmp_iter)) { - next = gtk_tree_model_get_path (model, &tmp_iter); - - /* Ensure that we are not selecting the same */ - if (gtk_tree_path_compare (path, next) != 0) { - *row_reference = gtk_tree_row_reference_new (model, next); - retval = TRUE; + finished = FALSE; + do { + TnyHeader *header = NULL; + + if (gtk_tree_model_iter_next (model, &tmp_iter)) { + gtk_tree_model_get (model, &tmp_iter, + TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + + if (header) { + if (msg_is_visible (header, is_outbox)) { + next = gtk_tree_model_get_path (model, &tmp_iter); + *row_reference = gtk_tree_row_reference_new (model, next); + retval = TRUE; + finished = TRUE; + } + g_object_unref (header); + header = NULL; + } + } else if (cycle && gtk_tree_model_get_iter_first (model, &tmp_iter)) { + next = gtk_tree_model_get_path (model, &tmp_iter); + + /* Ensure that we are not selecting the same */ + if (gtk_tree_path_compare (path, next) != 0) { + gtk_tree_model_get (model, &tmp_iter, + TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + if (header) { + if (msg_is_visible (header, is_outbox)) { + *row_reference = gtk_tree_row_reference_new (model, next); + retval = TRUE; + finished = TRUE; + } + g_object_unref (header); + header = NULL; + } + } else { + /* If we ended up in the same message + then there is no valid next + message */ + finished = TRUE; + } + } else { + /* If there are no more messages and we don't + want to start again in the first one then + there is no valid next message */ + finished = TRUE; } - } + } while (!finished); /* Free */ gtk_tree_path_free (path); @@ -786,6 +828,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, G_CALLBACK (modest_ui_actions_on_msg_recpt_activated), obj); g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual", G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj); + g_signal_connect (G_OBJECT (priv->msg_view), "fetch_image", + G_CALLBACK (on_fetch_image), obj); g_signal_connect (G_OBJECT (obj), "key-release-event", G_CALLBACK (modest_msg_view_window_key_event), @@ -885,7 +929,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg, if (row_reference) { priv->row_reference = gtk_tree_row_reference_copy (row_reference); priv->next_row_reference = gtk_tree_row_reference_copy (row_reference); - select_next_valid_row (model, &(priv->next_row_reference), TRUE); + select_next_valid_row (model, &(priv->next_row_reference), TRUE, priv->is_outbox); } else { priv->row_reference = NULL; priv->next_row_reference = NULL; @@ -1101,7 +1145,7 @@ modest_msg_view_window_on_row_inserted (GtkTreeModel *model, priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference); select_next_valid_row (priv->header_model, - &(priv->next_row_reference), FALSE); + &(priv->next_row_reference), FALSE, priv->is_outbox); /* Connect the remaining callbacks to become able to detect * changes in header-view. */ @@ -1144,7 +1188,7 @@ modest_msg_view_window_on_row_reordered (GtkTreeModel *header_model, gtk_tree_row_reference_free (priv->next_row_reference); } priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference); - select_next_valid_row (header_model, &(priv->next_row_reference), FALSE); + select_next_valid_row (header_model, &(priv->next_row_reference), FALSE, priv->is_outbox); already_changed = TRUE; } gtk_tree_path_free (path); @@ -1159,7 +1203,7 @@ modest_msg_view_window_on_row_reordered (GtkTreeModel *header_model, gtk_tree_row_reference_free (priv->next_row_reference); } priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference); - select_next_valid_row (header_model, &(priv->next_row_reference), FALSE); + select_next_valid_row (header_model, &(priv->next_row_reference), FALSE, priv->is_outbox); } gtk_tree_path_free (path); } @@ -1634,7 +1678,7 @@ modest_msg_view_window_is_search_result (ModestMsgViewWindow *window) static gboolean msg_is_visible (TnyHeader *header, gboolean check_outbox) { - if (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) + if ((tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) return FALSE; if (!check_outbox) { return TRUE; @@ -1842,7 +1886,7 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) if (!gtk_tree_row_reference_valid (priv->next_row_reference)) { if (gtk_tree_row_reference_valid (priv->row_reference)) { priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference); - select_next_valid_row (priv->header_model, &(priv->next_row_reference), FALSE); + select_next_valid_row (priv->header_model, &(priv->next_row_reference), FALSE, priv->is_outbox); } } if (priv->next_row_reference) @@ -1956,7 +2000,7 @@ view_msg_cb (ModestMailOperation *mail_op, gtk_tree_row_reference_free (priv->next_row_reference); } priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference); - select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE); + select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox); } /* Mark header as read */ @@ -2668,7 +2712,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m GList *files_to_save = NULL; GtkWidget *save_dialog = NULL; gchar *folder = NULL; - const gchar *filename = NULL; + gchar *filename = NULL; gchar *save_multiple_str = NULL; g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window)); @@ -2692,7 +2736,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m if (!modest_tny_mime_part_is_msg (mime_part) && modest_tny_mime_part_is_attachment_for_modest (mime_part) && !tny_mime_part_is_purged (mime_part)) { - filename = tny_mime_part_get_filename (mime_part); + filename = g_strdup (tny_mime_part_get_filename (mime_part)); } else { /* TODO: show any error? */ g_warning ("Tried to save a non-file attachment"); @@ -2714,9 +2758,11 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m g_free (folder); /* set filename */ - if (filename != NULL) + if (filename) { gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save_dialog), filename); + g_free (filename); + } /* if multiple, set multiple string */ if (save_multiple_str) { @@ -2942,3 +2988,116 @@ static void on_move_focus (GtkWidget *widget, g_signal_stop_emission_by_name (G_OBJECT (widget), "move-focus"); } +static TnyStream * +fetch_image_open_stream (TnyStreamCache *self, gint64 *expected_size, gchar *uri) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle = NULL; + GnomeVFSFileInfo *info = NULL; + TnyStream *stream; + + result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) { + *expected_size = 0; + return NULL; + } + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_from_handle (handle, info, GNOME_VFS_FILE_INFO_DEFAULT); + if (result != GNOME_VFS_OK || ! (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)) { + /* We put a "safe" default size for going to cache */ + *expected_size = (300*1024); + } else { + *expected_size = info->size; + } + gnome_vfs_file_info_unref (info); + + stream = tny_vfs_stream_new (handle); + + return stream; + +} + +typedef struct { + gchar *uri; + gchar *cache_id; + TnyStream *output_stream; + GtkWidget *msg_view; +} FetchImageData; + +gboolean +on_fetch_image_idle_refresh_view (gpointer userdata) +{ + + FetchImageData *fidata = (FetchImageData *) userdata; + g_message ("REFRESH VIEW"); + if (GTK_WIDGET_DRAWABLE (fidata->msg_view)) { + g_message ("QUEUING DRAW"); + gtk_widget_queue_draw (fidata->msg_view); + } + g_object_unref (fidata->msg_view); + g_slice_free (FetchImageData, fidata); + return FALSE; +} + +static gpointer +on_fetch_image_thread (gpointer userdata) +{ + FetchImageData *fidata = (FetchImageData *) userdata; + TnyStreamCache *cache; + TnyStream *cache_stream; + + cache = modest_runtime_get_images_cache (); + cache_stream = tny_stream_cache_get_stream (cache, fidata->cache_id, (TnyStreamCacheOpenStreamFetcher) fetch_image_open_stream, (gpointer) fidata->uri); + g_free (fidata->cache_id); + g_free (fidata->uri); + + if (cache_stream != NULL) { + tny_stream_write_to_stream (cache_stream, fidata->output_stream); + tny_stream_close (cache_stream); + g_object_unref (cache_stream); + } + + tny_stream_close (fidata->output_stream); + g_object_unref (fidata->output_stream); + + + gdk_threads_enter (); + g_idle_add (on_fetch_image_idle_refresh_view, fidata); + gdk_threads_leave (); + + return NULL; +} + +static gboolean +on_fetch_image (ModestMsgView *msgview, + const gchar *uri, + TnyStream *stream, + ModestMsgViewWindow *window) +{ + const gchar *current_account; + ModestMsgViewWindowPrivate *priv; + FetchImageData *fidata; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + current_account = modest_window_get_active_account (MODEST_WINDOW (window)); + + fidata = g_slice_new0 (FetchImageData); + fidata->msg_view = g_object_ref (msgview); + fidata->uri = g_strdup (uri); + fidata->cache_id = modest_images_cache_get_id (current_account, uri); + fidata->output_stream = g_object_ref (stream); + + if (g_thread_create (on_fetch_image_thread, fidata, FALSE, NULL) == NULL) { + g_object_unref (fidata->output_stream); + g_free (fidata->cache_id); + g_free (fidata->uri); + g_object_unref (fidata->msg_view); + g_slice_free (FetchImageData, fidata); + tny_stream_close (stream); + return FALSE; + } + + return TRUE;; +}