Trim trailing white spaces on empty lines.
[geeqie.git] / src / slideshow.c
index e36dd79..1d7cb97 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Geeqie
  * (C) 2004 John Ellis
- * Copyright (C) 2008 The Geeqie Team
+ * Copyright (C) 2008 - 2012 The Geeqie Team
  *
  * Author: John Ellis
  *
 #include "collect.h"
 #include "image.h"
 #include "slideshow.h"
-#include "filelist.h"
+#include "filedata.h"
 
 #include "layout.h"
 #include "layout_image.h"
 #include "ui_fileops.h"
 
 
-static void slideshow_timer_reset(SlideShowData *ss, gint reset);
+static void slideshow_timer_stop(SlideShowData *ss);
 
 
 void slideshow_free(SlideShowData *ss)
 {
        if (!ss) return;
 
-       slideshow_timer_reset(ss, FALSE);
+       slideshow_timer_stop(ss);
 
        if (ss->stop_func) ss->stop_func(ss, ss->stop_data);
 
        if (ss->filelist) filelist_free(ss->filelist);
        if (ss->cd) collection_unref(ss->cd);
-       g_free(ss->layout_path);
+       file_data_unref(ss->dir_fd);
 
        g_list_free(ss->list);
        g_list_free(ss->list_done);
@@ -51,11 +51,11 @@ static GList *generate_list(SlideShowData *ss)
 
        if (ss->from_selection)
                {
-               list = layout_selection_list_by_index(ss->layout);
+               list = layout_selection_list_by_index(ss->lw);
                }
        else
                {
-               gint i;
+               guint i;
                for (i = 0; i < ss->slide_count; i++)
                        {
                        list = g_list_prepend(list, GINT_TO_POINTER(i));
@@ -66,21 +66,56 @@ static GList *generate_list(SlideShowData *ss)
        return list;
 }
 
+static void ptr_array_add(gpointer data, GPtrArray *array)
+{
+       g_ptr_array_add(array, data);
+}
+
+static void list_prepend(gpointer data, GList **list)
+{
+       *list = g_list_prepend(*list, data);
+}
+
+static GPtrArray *generate_ptr_array_from_list(GList *src_list)
+{
+       GPtrArray *arr = g_ptr_array_sized_new(g_list_length(src_list));
+
+       g_list_foreach(src_list, (GFunc) ptr_array_add, arr);
+
+       return arr;
+}
+
+static void swap(GPtrArray *array, guint index1, guint index2)
+{
+       gpointer temp = g_ptr_array_index(array, index1);
+
+       g_ptr_array_index(array, index1) = g_ptr_array_index(array, index2);
+       g_ptr_array_index(array, index2) = temp;
+}
+
+static void ptr_array_random_shuffle(GPtrArray *array)
+{
+       guint i;
+       for (i = 0; i < array->len; ++i)
+               {
+               guint p = (double)rand() / ((double)RAND_MAX + 1.0) * array->len;
+               swap(array, i, p);
+               }
+}
+
 static GList *generate_random_list(SlideShowData *ss)
 {
-       GList *src_list = NULL;
+       GList *src_list;
+       GPtrArray *src_array;
        GList *list = NULL;
-       GList *work;
 
        src_list = generate_list(ss);
+       src_array = generate_ptr_array_from_list(src_list);
+       g_list_free(src_list);
 
-       while (src_list)
-               {
-               gint p = (double)rand() / ((double)RAND_MAX + 1.0) * g_list_length(src_list);
-               work = g_list_nth(src_list, p);
-               list = g_list_prepend(list, work->data);
-               src_list = g_list_remove(src_list, work->data);
-               }
+       ptr_array_random_shuffle(src_array);
+       g_ptr_array_foreach(src_array, (GFunc) list_prepend, &list);
+       g_ptr_array_free(src_array, TRUE);
 
        return list;
 }
@@ -117,14 +152,17 @@ static void slideshow_list_init(SlideShowData *ss, gint start_index)
                }
 }
 
-gint slideshow_should_continue(SlideShowData *ss)
+gboolean slideshow_should_continue(SlideShowData *ss)
 {
        FileData *imd_fd;
-       const gchar *path;
+       FileData *dir_fd;
 
        if (!ss) return FALSE;
 
-       imd_fd = image_get_fd(ss->imd);
+       if (ss->lw)
+               imd_fd = layout_image_get_fd(ss->lw);
+       else
+               imd_fd = image_get_fd(ss->imd);
 
        if ( ((imd_fd == NULL) != (ss->slide_fd == NULL)) ||
            (imd_fd && ss->slide_fd && imd_fd != ss->slide_fd) ) return FALSE;
@@ -139,20 +177,18 @@ gint slideshow_should_continue(SlideShowData *ss)
                        return FALSE;
                }
 
-       if (!ss->layout) return FALSE;
-       path = layout_get_path(ss->layout);
+       dir_fd = ss->lw->dir_fd;
 
-       if (path && ss->layout_path &&
-           strcmp(path, ss->layout_path) == 0)
+       if (dir_fd && ss->dir_fd && dir_fd == ss->dir_fd)
                {
-               if (ss->from_selection && ss->slide_count == layout_selection_count(ss->layout, NULL)) return TRUE;
-               if (!ss->from_selection && ss->slide_count == layout_list_count(ss->layout, NULL)) return TRUE;
+               if (ss->from_selection && ss->slide_count == layout_selection_count(ss->lw, NULL)) return TRUE;
+               if (!ss->from_selection && ss->slide_count == layout_list_count(ss->lw, NULL)) return TRUE;
                }
 
        return FALSE;
 }
 
-static gint slideshow_step(SlideShowData *ss, gint forward)
+static gboolean slideshow_step(SlideShowData *ss, gboolean forward)
 {
        gint row;
 
@@ -184,7 +220,10 @@ static gint slideshow_step(SlideShowData *ss, gint forward)
        if (ss->filelist)
                {
                ss->slide_fd = file_data_ref((FileData *)g_list_nth_data(ss->filelist, row));
-               image_change_fd(ss->imd, ss->slide_fd, image_zoom_get_default(ss->imd, options->image.zoom_mode));
+               if (ss->lw)
+                       layout_set_fd(ss->lw, ss->slide_fd);
+               else
+                       image_change_fd(ss->imd, ss->slide_fd, image_zoom_get_default(ss->imd));
                }
        else if (ss->cd)
                {
@@ -193,20 +232,23 @@ static gint slideshow_step(SlideShowData *ss, gint forward)
                info = g_list_nth_data(ss->cd->list, row);
                ss->slide_fd = file_data_ref(info->fd);
 
-               image_change_from_collection(ss->imd, ss->cd, info, image_zoom_get_default(ss->imd, options->image.zoom_mode));
+               if (ss->lw)
+                       image_change_from_collection(ss->lw->image, ss->cd, info, image_zoom_get_default(ss->lw->image));
+               else
+                       image_change_from_collection(ss->imd, ss->cd, info, image_zoom_get_default(ss->imd));
                }
        else
                {
-               ss->slide_fd = file_data_ref(layout_list_get_fd(ss->layout, row));
+               ss->slide_fd = file_data_ref(layout_list_get_fd(ss->lw, row));
 
                if (ss->from_selection)
                        {
-                       image_change_fd(ss->imd, ss->slide_fd, image_zoom_get_default(ss->imd, options->image.zoom_mode));
-                       layout_status_update_info(ss->layout, NULL);
+                       layout_set_fd(ss->lw, ss->slide_fd);
+                       layout_status_update_info(ss->lw, NULL);
                        }
                else
                        {
-                       layout_image_set_index(ss->layout, row);
+                       layout_image_set_index(ss->lw, row);
                        }
                }
 
@@ -221,8 +263,7 @@ static gint slideshow_step(SlideShowData *ss, gint forward)
                }
 
        /* read ahead */
-
-       if (options->image.enable_read_ahead)
+       if (options->image.enable_read_ahead && (!ss->lw || ss->from_selection))
                {
                gint r;
                if (forward)
@@ -248,14 +289,14 @@ static gint slideshow_step(SlideShowData *ss, gint forward)
                        }
                else if (ss->from_selection)
                        {
-                       image_prebuffer_set(ss->imd, layout_list_get_fd(ss->layout, r));
+                       image_prebuffer_set(ss->lw->image, layout_list_get_fd(ss->lw, r));
                        }
                }
 
        return TRUE;
 }
 
-static gint slideshow_loop_cb(gpointer data)
+static gboolean slideshow_loop_cb(gpointer data)
 {
        SlideShowData *ss = data;
 
@@ -263,7 +304,7 @@ static gint slideshow_loop_cb(gpointer data)
 
        if (!slideshow_step(ss, TRUE))
                {
-               ss->timeout_id = -1;
+               ss->timeout_id = 0;
                slideshow_free(ss);
                return FALSE;
                }
@@ -271,50 +312,47 @@ static gint slideshow_loop_cb(gpointer data)
        return TRUE;
 }
 
-static void slideshow_timer_reset(SlideShowData *ss, gint reset)
+static void slideshow_timer_stop(SlideShowData *ss)
 {
-       if (reset)
-               {
-               if (options->slideshow.delay < 1) options->slideshow.delay = 1;
+       if (!ss->timeout_id) return;
 
-               if (ss->timeout_id != -1) g_source_remove(ss->timeout_id);
-               ss->timeout_id = g_timeout_add(options->slideshow.delay * 1000 / SLIDESHOW_SUBSECOND_PRECISION,
-                                              slideshow_loop_cb, ss);
-               }
-       else if (ss->timeout_id != -1)
-               {
-               g_source_remove(ss->timeout_id);
-               ss->timeout_id = -1;
-               }
+       g_source_remove(ss->timeout_id);
+       ss->timeout_id = 0;
 }
 
-void slideshow_next(SlideShowData *ss)
+static void slideshow_timer_reset(SlideShowData *ss)
 {
-       if (!ss) return;
-
-       if (!slideshow_step(ss, TRUE))
-               {
-               slideshow_free(ss);
-               return;
-               }
+       if (options->slideshow.delay < 1) options->slideshow.delay = 1;
 
-       slideshow_timer_reset(ss, TRUE);
+       if (ss->timeout_id) g_source_remove(ss->timeout_id);
+       ss->timeout_id = g_timeout_add(options->slideshow.delay * 1000 / SLIDESHOW_SUBSECOND_PRECISION,
+                                      slideshow_loop_cb, ss);
 }
 
-void slideshow_prev(SlideShowData *ss)
+static void slideshow_move(SlideShowData *ss, gboolean forward)
 {
        if (!ss) return;
 
-       if (!slideshow_step(ss, FALSE))
+       if (!slideshow_step(ss, forward))
                {
                slideshow_free(ss);
                return;
                }
 
-       slideshow_timer_reset(ss, TRUE);
+       slideshow_timer_reset(ss);
 }
 
-static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw,
+void slideshow_next(SlideShowData *ss)
+{
+       slideshow_move(ss, TRUE);
+}
+
+void slideshow_prev(SlideShowData *ss)
+{
+       slideshow_move(ss, FALSE);
+}
+
+static SlideShowData *real_slideshow_start(LayoutWindow *target_lw, ImageWindow *imd,
                                           GList *filelist, gint start_point,
                                           CollectionData *cd, CollectInfo *start_info,
                                           void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data)
@@ -322,26 +360,14 @@ static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw,
        SlideShowData *ss;
        gint start_index = -1;
 
-       if (!filelist && !cd && layout_list_count(lw, NULL) < 1) return NULL;
+       if (!filelist && !cd && layout_list_count(target_lw, NULL) < 1) return NULL;
 
        ss = g_new0(SlideShowData, 1);
 
-       ss->imd = imd;
-
+       ss->lw = target_lw;
+       ss->imd = imd; /* FIXME: ss->imd is used only for img-view.c and can be dropped with it */
        ss->filelist = filelist;
        ss->cd = cd;
-       ss->layout = lw;
-       ss->layout_path = NULL;
-
-       ss->list = NULL;
-       ss->list_done = NULL;
-
-       ss->from_selection = FALSE;
-
-       ss->stop_func = NULL;
-
-       ss->timeout_id = -1;
-       ss->paused = FALSE;
 
        if (ss->filelist)
                {
@@ -360,12 +386,12 @@ static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw,
                {
                /* layout method */
 
-               ss->slide_count = layout_selection_count(ss->layout, NULL);
-               ss->layout_path = g_strdup(layout_get_path(ss->layout));
+               ss->slide_count = layout_selection_count(ss->lw, NULL);
+               ss->dir_fd = file_data_ref(ss->lw->dir_fd);
                if (ss->slide_count < 2)
                        {
-                       ss->slide_count = layout_list_count(ss->layout, NULL);
-                       if (!options->slideshow.random && start_point >= 0 && start_point < ss->slide_count)
+                       ss->slide_count = layout_list_count(ss->lw, NULL);
+                       if (!options->slideshow.random && start_point >= 0 && (guint) start_point < ss->slide_count)
                                {
                                start_index = start_point;
                                }
@@ -378,10 +404,14 @@ static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw,
 
        slideshow_list_init(ss, start_index);
 
-       ss->slide_fd = file_data_ref(image_get_fd(ss->imd));
+       if (ss->lw)
+               ss->slide_fd = file_data_ref(layout_image_get_fd(ss->lw));
+       else
+               ss->slide_fd = file_data_ref(image_get_fd(ss->imd));
+
        if (slideshow_step(ss, TRUE))
                {
-               slideshow_timer_reset(ss, TRUE);
+               slideshow_timer_reset(ss);
 
                ss->stop_func = stop_func;
                ss->stop_data = stop_data;
@@ -395,41 +425,42 @@ static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw,
        return ss;
 }
 
-SlideShowData *slideshow_start_from_filelist(ImageWindow *imd, GList *list,
+SlideShowData *slideshow_start_from_filelist(LayoutWindow *target_lw, ImageWindow *imd, GList *list,
                                              void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data)
 {
-       return real_slideshow_start(imd, NULL, list, -1, NULL, NULL, stop_func, stop_data);
+       return real_slideshow_start(target_lw, imd, list, -1, NULL, NULL, stop_func, stop_data);
 }
 
-SlideShowData *slideshow_start_from_collection(ImageWindow *imd, CollectionData *cd,
+SlideShowData *slideshow_start_from_collection(LayoutWindow *target_lw, ImageWindow *imd, CollectionData *cd,
                                               void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data,
                                               CollectInfo *start_info)
 {
-       return real_slideshow_start(imd, NULL, NULL, -1, cd, start_info, stop_func, stop_data);
+       return real_slideshow_start(target_lw, imd, NULL, -1, cd, start_info, stop_func, stop_data);
 }
 
-SlideShowData *slideshow_start(ImageWindow *imd, LayoutWindow *lw, gint start_point,
+SlideShowData *slideshow_start(LayoutWindow *lw, gint start_point,
                               void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data)
 {
-       return real_slideshow_start(imd, lw, NULL, start_point, NULL, NULL, stop_func, stop_data);
+       return real_slideshow_start(lw, NULL, NULL, start_point, NULL, NULL, stop_func, stop_data);
 }
 
-gint slideshow_paused(SlideShowData *ss)
+gboolean slideshow_paused(SlideShowData *ss)
 {
        if (!ss) return FALSE;
 
        return ss->paused;
 }
 
-void slideshow_pause_set(SlideShowData *ss, gint paused)
+void slideshow_pause_set(SlideShowData *ss, gboolean paused)
 {
        if (!ss) return;
 
        ss->paused = paused;
 }
 
-gint slideshow_pause_toggle(SlideShowData *ss)
+gboolean slideshow_pause_toggle(SlideShowData *ss)
 {
        slideshow_pause_set(ss, !slideshow_paused(ss));
        return slideshow_paused(ss);
 }
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */