fb9629b5843661cb3f0c44200d93588fcbbbc5c9
[geeqie.git] / src / slideshow.c
1 /*
2  * GQview image viewer
3  * (C)1999 John Ellis
4  *
5  * Author: John Ellis
6  *
7  */
8
9 #include "gqview.h"
10
11 static GList *slide_list = NULL;
12 static gchar *slide_img = NULL;
13 static gchar *slide_path = NULL;
14 static gint slide_count = 0;
15 static gint slide_active = FALSE;
16 static gint slide_sel_list = FALSE;
17 static gint slide_timeout_id = -1;
18
19 static void slideshow_free_all()
20 {
21         slide_active = FALSE;
22
23         g_list_free(slide_list);
24         slide_list = NULL;
25
26         g_free(slide_path);
27         slide_path = NULL;
28
29         g_free(slide_img);
30         slide_img = NULL;
31
32         slide_count = 0;
33         slide_sel_list = FALSE;
34 }
35
36 static GList *generate_list()
37 {
38         GList *list = NULL;
39
40         if (file_selection_count() < 2)
41                 {
42                 gint i;
43                 gint c = file_count();
44                 for(i = 0; i < c; i++)
45                         {
46                         list = g_list_prepend(list, GINT_TO_POINTER(i));
47                         }
48                 slide_sel_list = FALSE;
49                 }
50         else
51                 {
52                 GList *work = GTK_CLIST(file_clist)->selection;
53                 while(work)
54                         {
55                         list = g_list_prepend(list, work->data);
56                         work = work->next;
57                         }
58                 slide_sel_list = TRUE;
59                 }
60         list = g_list_reverse(list);
61
62         return list;
63 }
64
65 static GList *generate_random_list()
66 {
67         GList *src_list = NULL;
68         GList *list = NULL;
69         GList *work;
70
71         src_list = generate_list();
72
73         while(src_list)
74                 {
75                 gint p = (float)rand() / RAND_MAX * g_list_length(src_list);
76                 work = g_list_nth(src_list, p);
77                 list = g_list_prepend(list, work->data);
78                 src_list = g_list_remove(src_list, work->data);
79                 }
80
81         return list;
82 }
83
84 static void slideshow_init_list()
85 {
86         if (slide_list)
87                 {
88                 g_list_free(slide_list);
89                 }
90
91         if (slideshow_random)
92                 {
93                 slide_list = generate_random_list();
94                 }
95         else
96                 {
97                 slide_list = generate_list();
98                 }
99 }
100
101 static gint slideshow_should_continue()
102 {
103         if (!slide_active || !slide_list || !slide_path ||
104             slide_count != file_count() ||
105             (slide_img && image_get_path() && strcmp(image_get_path(), slide_img) != 0) ||
106             current_path == NULL ||
107             strcmp(current_path, slide_path) != 0)
108                 {
109                 return FALSE;
110                 }
111
112         return TRUE;
113 }
114
115 static gint slideshow_loop_cb(gpointer data)
116 {
117         gint row;
118         gchar *buf;
119
120         if (!slideshow_should_continue())
121                 {
122                 slideshow_free_all();
123                 slide_timeout_id = -1;
124                 return FALSE;
125                 }
126
127         row = GPOINTER_TO_INT(slide_list->data);
128
129         g_free(slide_img);
130         slide_img = NULL;
131         buf = file_get_path(row);
132         slide_list = g_list_remove(slide_list, slide_list->data);
133
134         if (!slide_list && slideshow_repeat)
135                 {
136                 slideshow_init_list();
137                 }
138
139         if (slide_sel_list)
140                 {
141                 image_change_to(buf);
142                 update_status_label(NULL);
143                 }
144         else
145                 {
146                 file_image_change_to(row);
147                 }
148
149         slide_img = buf;
150
151         if (!slide_list)
152                 {
153                 slideshow_free_all();
154                 slide_timeout_id = -1;
155                 return FALSE;
156                 }
157
158         return TRUE;
159 }
160
161 void slideshow_start()
162 {
163         gint row;
164         gchar *buf;
165
166         if (slide_active) return;
167
168         if (file_count() < 2) return;
169
170         slideshow_init_list();
171         if (!slide_list) return;
172
173         row = GPOINTER_TO_INT(slide_list->data);
174
175         slide_active = TRUE;
176         slide_path = g_strdup(current_path);
177         slide_count = file_count();
178         g_free(slide_img);
179         slide_img = NULL;
180         buf = file_get_path(row);
181         slide_list = g_list_remove(slide_list, slide_list->data);
182
183         if (slide_sel_list)
184                 {
185                 image_change_to(buf);
186                 update_status_label(NULL);
187                 }
188         else
189                 {
190                 file_image_change_to(row);
191                 }
192
193         slide_img = buf;
194
195         slide_timeout_id = gtk_timeout_add(slideshow_delay * 1000, slideshow_loop_cb, NULL);
196 }
197
198 void slideshow_stop()
199 {
200         if (!slide_active) return;
201
202         slideshow_free_all();
203         if (slide_timeout_id != -1)
204                 {
205                 gtk_timeout_remove(slide_timeout_id);
206                 slide_timeout_id = -1;
207                 }
208         update_status_label(NULL);
209 }
210
211 void slideshow_toggle()
212 {
213         if (!slide_active)
214                 {
215                 slideshow_start();
216                 }
217         else
218                 {
219                 slideshow_stop();
220                 }
221 }
222
223 gint slideshow_is_running()
224 {
225         if (!slide_active) return FALSE;
226
227         if (!slideshow_should_continue())
228                 {
229                 slideshow_free_all();
230                 if (slide_timeout_id != -1)
231                         {
232                         gtk_timeout_remove(slide_timeout_id);
233                         slide_timeout_id = -1;
234                         }
235                 return FALSE;
236                 }
237
238         return TRUE;
239 }
240