1 /*
2 * Copyright (c) 2009 Giuseppe Torelli <colossus73@gmail.com>
3 * Copyright (c) 2009 Tadej Borovšak <tadeboro@gmail.com>
4 * Copyright (c) 2011 Robert Chéramy <robert@cheramy.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License,or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not,write to the Free Software
18 * Foundation,Inc.,59 Temple Place - Suite 330,Boston,MA 02111-1307,USA.
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 #include <assert.h>
26
27 #include "main-window.h"
28 #include "callbacks.h"
29 #include "export.h"
30 #include "subtitles.h"
31 #include "imgcellrendererpixbuf.h"
32
33 static const GtkTargetEntry drop_targets[] =
34 {
35 { "text/uri-list",0,0 },
36 };
37
38 /* ****************************************************************************
39 * Local function declarations
40 * ************************************************************************* */
41 static void img_combo_box_transition_type_changed (GtkComboBox *, img_window_struct *);
42 static void img_random_button_clicked(GtkButton *, img_window_struct *);
43 static GdkPixbuf *img_set_random_transition(img_window_struct *, slide_struct *);
44 static void img_combo_box_speed_changed (GtkComboBox *, img_window_struct *);
45 static void img_spinbutton_value_changed (GtkSpinButton *, img_window_struct *);
46 static void img_slide_cut(GtkMenuItem * , img_window_struct *);
47 static void img_slide_copy(GtkMenuItem * , img_window_struct *);
48 static void img_slide_paste(GtkMenuItem* , img_window_struct *);
49 static void img_report_slides_transitions(img_window_struct *);
50 static void img_clear_audio_files(GtkButton *, img_window_struct *);
51 static void img_expand_button_clicked(GtkButton *, img_window_struct *);
52 static void img_on_drag_audio_data_received (GtkWidget *,GdkDragContext *, int, int, GtkSelectionData *, unsigned int, unsigned int, img_window_struct *);
53 static gboolean img_sub_textview_focus_in (GtkWidget *, GdkEventFocus *, img_window_struct *);
54 static gboolean img_sub_textview_focus_out(GtkWidget *, GdkEventFocus *, img_window_struct *);
55 static void img_activate_remove_button_music_liststore(GtkTreeModel *, GtkTreePath *, GtkTreeIter *, img_window_struct *);
56 static void img_quit_menu(GtkMenuItem *, img_window_struct *);
57 static void img_select_all_thumbnails(GtkMenuItem *, img_window_struct *);
58 static void img_unselect_all_thumbnails(GtkMenuItem *, img_window_struct *);
59 static void img_goto_line_entry_activate(GtkWidget *, img_window_struct *);
60 static gint img_sort_none_before_other(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer);
61 static void img_check_numeric_entry (GtkEditable *entry, gchar *text, gint lenght, gint *position, gpointer data);
62 static void img_show_uri(GtkMenuItem *, img_window_struct *);
63 static void img_select_slide_from_slide_report_dialog(GtkButton *, img_window_struct *);
64 static void img_show_slides_report_dialog(GtkMenuItem *, img_window_struct *);
65
66 static gboolean
67 img_iconview_selection_button_press( GtkWidget *widget,
68 GdkEventButton *button,
69 img_window_struct *img );
70
71 static gboolean
72 img_scroll_thumb( GtkWidget *widget,
73 GdkEventScroll *scroll,
74 img_window_struct *img );
75
76 static gboolean
77 img_subtitle_update( img_window_struct *img );
78
79 static GtkWidget *
80 img_create_subtitle_animation_combo( void );
81
82 static void
83 img_toggle_mode( GtkCheckMenuItem *item,
84 img_window_struct *img );
85
86 static gint
87 img_sort_report_transitions( gconstpointer a,
88 gconstpointer b );
89
90 static void
91 img_toggle_frame_rate( GtkCheckMenuItem *item,
92 img_window_struct *img );
93
94
95 /* ****************************************************************************
96 * Function definitions
97 * ************************************************************************* */
img_create_window(void)98 img_window_struct *img_create_window (void)
99 {
100 img_window_struct *img_struct = NULL;
101 GtkWidget *vbox1;
102 GtkWidget *menubar;
103 GtkWidget *menuitem1;
104 GtkWidget *menu1;
105 GtkWidget *imagemenuitem1;
106 GtkWidget *imagemenuitem5;
107 GtkWidget *separatormenuitem1;
108 GtkWidget *menuitem2;
109 GtkWidget *slide_menu;
110 GtkWidget *separator_slide_menu;
111 GtkWidget *image_menu;
112 GtkWidget *select_all_menu;
113 GtkWidget *deselect_all_menu;
114 GtkWidget *menuitem3;
115 GtkWidget *tmp_image;
116 GtkWidget *menu3;
117 GtkWidget *about;
118 GtkWidget *contents;
119 GtkWidget *toolbar;
120 GtkWidget *new_button;
121 GtkWidget *add_slide;
122 GtkWidget *separatortoolitem;
123 GtkWidget *toolbutton_slide_goto;
124 GtkWidget *first_slide, *last_slide, *prev_slide, *next_slide, *label_of;
125 GtkWidget *notebook;
126 GtkWidget *video_tab;
127 GtkWidget *audio_tab;
128 GtkWidget *swindow, *scrollable_window;
129 GtkWidget *viewport;
130 GtkWidget *align;
131 GtkWidget *image_area_frame;
132 GtkWidget *vbox_frames, *vbox_audio_frames, *frame1_alignment, *frame2_alignment, *frame3_alignment,*frame4_alignment;
133 GtkWidget *frame1, *frame2, *frame3, *frame4, *frame_label;
134 GtkWidget *transition_label;
135 GtkWidget *vbox_info_slide, *vbox_slide_motion, *vbox_slide_caption;
136 GtkWidget *table;
137 GtkWidget *duration_label;
138 GtkWidget *trans_duration_label;
139 GtkWidget *total_time;
140 GtkWidget *hbox_stop_points, *stop_points_label;
141 GtkWidget *hbox_time_offset, *time_offset_label;
142 GtkWidget *hbox_textview, *text_animation_hbox;
143 GtkWidget *hbox_music_label;
144 GtkWidget *music_time;
145 GtkWidget *hbox_buttons, *move_up_button;
146 GtkWidget *move_down_button, *clear_button, *image_buttons, *vbox2, *scrolledwindow1;
147 GtkWidget *message_scroll, *message_view;
148 GtkCellRenderer *renderer, *pixbuf_cell;
149 GtkTreeSelection *selection;
150 GtkTreeViewColumn *column;
151 GtkIconSize tmp_toolbar_icon_size;
152 GtkIconTheme *icon_theme;
153 GdkPixbuf *icon;
154 gint x;
155 GtkWidget *eventbox;
156 GtkWidget *a_label;
157 GtkWidget *a_hbox;
158 GtkWidget *modes_vbox;
159
160 /* Added after cleaning up the img_window_struct */
161 GtkWidget *properties_menu;
162 GtkWidget *import_menu;
163 GtkWidget *import_audio_menu;
164 GtkWidget *import_button;
165 GtkWidget *import_audio_button;
166 GtkWidget *remove_button;
167 GtkWidget *zoom_in_button, *zoom_out_button, *zoom_normal, *zoom_fit;
168 GtkWidget *export_menu;
169 GtkWidget *thumb_scrolledwindow;
170 GdkPixbuf *pixbuf;
171 GtkWidget *rotate_left_menu;
172 GtkWidget *rotate_right_menu;
173 GtkWidget *rotate_left_button;
174 GtkWidget *rotate_right_button;
175
176 GtkWidget *tmp_checks[PREVIEW_FPS_NO_PRESETS];
177
178 img_struct = g_new0(img_window_struct, 1);
179
180 /* Set some default values */
181 img_struct->background_color[0] = 0;
182 img_struct->background_color[1] = 0;
183 img_struct->background_color[2] = 0;
184 img_struct->slides_nr = 0;
185 img_struct->distort_images = TRUE;
186
187 img_struct->maxoffx = 0;
188 img_struct->maxoffy = 0;
189 img_struct->current_point.offx = 0;
190 img_struct->current_point.offy = 0;
191 img_struct->current_point.zoom = 1;
192
193 img_struct->video_size[0] = 720;
194 img_struct->video_size[1] = 576;
195 img_struct->video_ratio = (gdouble)720 / 576;
196
197 img_struct->final_transition.duration = 0;
198 img_struct->final_transition.render = NULL;
199 img_struct->final_transition.speed = NORMAL;
200
201
202 /* GUI STUFF */
203 icon_theme = gtk_icon_theme_get_default();
204 icon = gtk_icon_theme_load_icon(icon_theme, "imagination", 24, 0, NULL);
205
206 img_struct->imagination_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
207 gtk_window_set_icon (GTK_WINDOW(img_struct->imagination_window),icon);
208 gtk_window_set_position (GTK_WINDOW(img_struct->imagination_window),GTK_WIN_POS_CENTER);
209 img_set_window_title(img_struct,NULL);
210 g_signal_connect (G_OBJECT (img_struct->imagination_window),"delete-event",G_CALLBACK (img_quit_application),img_struct);
211 g_signal_connect (G_OBJECT (img_struct->imagination_window), "destroy", G_CALLBACK (gtk_main_quit), NULL );
212 img_struct->accel_group = gtk_accel_group_new();
213
214 vbox1 = gtk_vbox_new (FALSE, 0);
215 gtk_widget_show (vbox1);
216 gtk_container_add (GTK_CONTAINER (img_struct->imagination_window), vbox1);
217
218 /* Create the menu items */
219 menubar = gtk_menu_bar_new ();
220 gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
221
222 menuitem1 = gtk_menu_item_new_with_mnemonic (_("_Slideshow"));
223 gtk_container_add (GTK_CONTAINER (menubar), menuitem1);
224
225 menu1 = gtk_menu_new ();
226 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menu1);
227
228 imagemenuitem1 = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, img_struct->accel_group);
229 gtk_container_add (GTK_CONTAINER (menu1), imagemenuitem1);
230 g_signal_connect (G_OBJECT (imagemenuitem1),"activate",G_CALLBACK (img_new_slideshow),img_struct);
231
232 img_struct->open_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, img_struct->accel_group);
233 gtk_container_add (GTK_CONTAINER (menu1), img_struct->open_menu);
234 g_signal_connect (G_OBJECT (img_struct->open_menu),"activate",G_CALLBACK (img_choose_slideshow_filename),img_struct);
235
236 img_struct->import_project_menu = gtk_image_menu_item_new_with_label (_("Import slideshow"));
237 gtk_container_add (GTK_CONTAINER (menu1),img_struct->import_project_menu);
238 g_signal_connect (G_OBJECT (img_struct->import_project_menu),"activate",G_CALLBACK (img_choose_slideshow_filename),img_struct);
239
240 pixbuf = gtk_icon_theme_load_icon(icon_theme, GTK_STOCK_ADD, 18, 0, NULL);
241 image_menu = gtk_image_new_from_pixbuf(pixbuf);
242 g_object_unref(pixbuf);
243 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (img_struct->import_project_menu),image_menu);
244
245 img_struct->save_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, img_struct->accel_group);
246 gtk_container_add (GTK_CONTAINER (menu1), img_struct->save_menu);
247 g_signal_connect (G_OBJECT (img_struct->save_menu),"activate",G_CALLBACK (img_choose_slideshow_filename),img_struct);
248
249 img_struct->save_as_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE_AS, img_struct->accel_group);
250 gtk_container_add (GTK_CONTAINER (menu1), img_struct->save_as_menu);
251 g_signal_connect (G_OBJECT (img_struct->save_as_menu),"activate",G_CALLBACK (img_choose_slideshow_filename),img_struct);
252
253 img_struct->close_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, img_struct->accel_group);
254 gtk_container_add (GTK_CONTAINER (menu1), img_struct->close_menu);
255 g_signal_connect (G_OBJECT (img_struct->close_menu),"activate",G_CALLBACK (img_close_slideshow),img_struct);
256
257 separatormenuitem1 = gtk_separator_menu_item_new ();
258 gtk_container_add (GTK_CONTAINER (menu1), separatormenuitem1);
259
260 import_menu = gtk_image_menu_item_new_with_mnemonic (_("Import p_ictures"));
261 gtk_container_add (GTK_CONTAINER (menu1),import_menu);
262 gtk_widget_add_accelerator (import_menu,"activate",img_struct->accel_group,GDK_i,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
263 g_signal_connect (G_OBJECT (import_menu),"activate",G_CALLBACK (img_add_slides_thumbnails),img_struct);
264
265 pixbuf = gtk_icon_theme_load_icon(icon_theme,"image", 18, 0, NULL);
266 image_menu = gtk_image_new_from_pixbuf(pixbuf);
267 g_object_unref(pixbuf);
268 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (import_menu),image_menu);
269
270 import_audio_menu = gtk_image_menu_item_new_with_mnemonic (_("Import _music"));
271 gtk_container_add (GTK_CONTAINER (menu1),import_audio_menu);
272 gtk_widget_add_accelerator (import_audio_menu,"activate",img_struct->accel_group,GDK_m,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
273 g_signal_connect (G_OBJECT (import_audio_menu),"activate",G_CALLBACK (img_select_audio_files_to_add),img_struct);
274
275 pixbuf = gtk_icon_theme_load_icon(icon_theme,"sound", 18, 0, NULL);
276 image_menu = gtk_image_new_from_pixbuf(pixbuf);
277 g_object_unref(pixbuf);
278 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (import_audio_menu),image_menu);
279
280 properties_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, img_struct->accel_group);
281 gtk_container_add (GTK_CONTAINER (menu1), properties_menu);
282 g_signal_connect (G_OBJECT (properties_menu), "activate", G_CALLBACK (img_project_properties), img_struct);
283
284 separatormenuitem1 = gtk_separator_menu_item_new ();
285 gtk_container_add (GTK_CONTAINER (menu1), separatormenuitem1);
286
287 img_struct->preview_menu = gtk_image_menu_item_new_with_mnemonic (_("_Preview"));
288 gtk_container_add (GTK_CONTAINER (menu1), img_struct->preview_menu);
289 gtk_widget_add_accelerator (img_struct->preview_menu, "activate",img_struct->accel_group,GDK_p,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
290 g_signal_connect (G_OBJECT (img_struct->preview_menu),"activate",G_CALLBACK (img_start_stop_preview),img_struct);
291
292 tmp_image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY,GTK_ICON_SIZE_MENU);
293 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (img_struct->preview_menu),tmp_image);
294
295 export_menu = gtk_image_menu_item_new_with_mnemonic (_("Export"));
296 gtk_container_add (GTK_CONTAINER (menu1), export_menu);
297 g_signal_connect (G_OBJECT (export_menu),"activate",G_CALLBACK (img_choose_exporter),img_struct);
298
299 image_menu = img_load_icon ("imagination-generate.png",GTK_ICON_SIZE_MENU);
300 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (export_menu),image_menu);
301
302 separatormenuitem1 = gtk_separator_menu_item_new ();
303 gtk_container_add (GTK_CONTAINER (menu1), separatormenuitem1);
304
305 imagemenuitem5 = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, img_struct->accel_group);
306 gtk_container_add (GTK_CONTAINER (menu1), imagemenuitem5);
307 g_signal_connect (G_OBJECT (imagemenuitem5),"activate",G_CALLBACK (img_quit_menu),img_struct);
308
309 /* Slide menu */
310 menuitem2 = gtk_menu_item_new_with_mnemonic (_("_Slide"));
311 gtk_container_add (GTK_CONTAINER (menubar), menuitem2);
312
313 slide_menu = gtk_menu_new ();
314 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem2), slide_menu);
315
316 img_struct->cut = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, img_struct->accel_group);
317 gtk_container_add (GTK_CONTAINER (slide_menu), img_struct->cut);
318 g_signal_connect (G_OBJECT (img_struct->cut), "activate", G_CALLBACK (img_slide_cut), img_struct);
319
320 img_struct->copy = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, img_struct->accel_group);
321 gtk_container_add (GTK_CONTAINER (slide_menu), img_struct->copy);
322 g_signal_connect (G_OBJECT (img_struct->copy), "activate", G_CALLBACK (img_slide_copy), img_struct);
323
324 img_struct->paste = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, img_struct->accel_group);
325 gtk_container_add (GTK_CONTAINER (slide_menu), img_struct->paste);
326 g_signal_connect (G_OBJECT (img_struct->paste), "activate", G_CALLBACK (img_slide_paste), img_struct);
327
328 separator_slide_menu = gtk_separator_menu_item_new ();
329 gtk_container_add (GTK_CONTAINER (slide_menu),separator_slide_menu);
330
331 /* Preview quality menu */
332 menuitem1 = gtk_menu_item_new_with_mnemonic( _("Preview quality") );
333 gtk_menu_shell_append( GTK_MENU_SHELL( slide_menu ), menuitem1 );
334
335 menu3 = gtk_menu_new();
336 gtk_menu_item_set_submenu( GTK_MENU_ITEM( menuitem1 ), menu3 );
337
338 menuitem2 = gtk_radio_menu_item_new_with_mnemonic( NULL, _("_Low") );
339 gtk_menu_shell_append( GTK_MENU_SHELL( menu3 ), menuitem2 );
340 g_signal_connect( G_OBJECT( menuitem2 ), "toggled",
341 G_CALLBACK( img_quality_toggled ), img_struct );
342 menuitem3 = gtk_radio_menu_item_new_with_mnemonic_from_widget(GTK_RADIO_MENU_ITEM( menuitem2 ), _("High") );
343 gtk_menu_shell_append( GTK_MENU_SHELL( menu3 ), menuitem3 );
344
345 /* Zoom controls */
346 menuitem1 = gtk_menu_item_new_with_mnemonic( _("_Zoom") );
347 gtk_menu_shell_append( GTK_MENU_SHELL( slide_menu ), menuitem1 );
348
349 menu3 = gtk_menu_new();
350 gtk_menu_item_set_submenu( GTK_MENU_ITEM( menuitem1 ), menu3 );
351
352 menuitem2 = gtk_image_menu_item_new_from_stock( GTK_STOCK_ZOOM_IN,img_struct->accel_group );
353 gtk_widget_add_accelerator( menuitem2, "activate", img_struct->accel_group, GDK_plus,GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
354 g_signal_connect( G_OBJECT( menuitem2 ), "activate",
355 G_CALLBACK( img_zoom_in ), img_struct );
356 gtk_menu_shell_append( GTK_MENU_SHELL( menu3 ), menuitem2 );
357
358 menuitem2 = gtk_image_menu_item_new_from_stock( GTK_STOCK_ZOOM_OUT, img_struct->accel_group );
359 gtk_widget_add_accelerator( menuitem2, "activate", img_struct->accel_group, GDK_minus, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
360 g_signal_connect( G_OBJECT( menuitem2 ), "activate",
361 G_CALLBACK( img_zoom_out ), img_struct );
362 gtk_menu_shell_append( GTK_MENU_SHELL( menu3 ), menuitem2 );
363
364 menuitem2 = gtk_image_menu_item_new_from_stock( GTK_STOCK_ZOOM_100, img_struct->accel_group );
365 gtk_widget_add_accelerator( menuitem2, "activate", img_struct->accel_group, GDK_0,GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
366 g_signal_connect( G_OBJECT( menuitem2 ), "activate",
367 G_CALLBACK( img_zoom_reset ), img_struct );
368 gtk_menu_shell_append( GTK_MENU_SHELL( menu3 ), menuitem2 );
369
370 separator_slide_menu = gtk_separator_menu_item_new ();
371 gtk_container_add (GTK_CONTAINER (slide_menu),separator_slide_menu);
372
373 add_slide = gtk_image_menu_item_new_with_mnemonic (_("Add empt_y slide"));
374 gtk_container_add (GTK_CONTAINER (slide_menu), add_slide);
375 gtk_widget_add_accelerator( add_slide, "activate", img_struct->accel_group, GDK_y, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
376 g_signal_connect( G_OBJECT( add_slide ), "activate",
377 G_CALLBACK( img_add_empty_slide ), img_struct );
378
379 image_menu = img_load_icon ("imagination-add-new-slide.png",GTK_ICON_SIZE_MENU);
380 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_slide), image_menu);
381
382 img_struct->remove_menu = gtk_image_menu_item_new_with_mnemonic (_("Dele_te"));
383 gtk_container_add (GTK_CONTAINER (slide_menu), img_struct->remove_menu);
384 gtk_widget_add_accelerator (img_struct->remove_menu,"activate",img_struct->accel_group, GDK_Delete,0,GTK_ACCEL_VISIBLE);
385 g_signal_connect (G_OBJECT (img_struct->remove_menu),"activate",G_CALLBACK (img_delete_selected_slides),img_struct);
386
387 tmp_image = gtk_image_new_from_stock (GTK_STOCK_DELETE,GTK_ICON_SIZE_MENU);
388 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (img_struct->remove_menu),tmp_image);
389
390 img_struct->report_menu = gtk_image_menu_item_new_with_mnemonic (_("Repor_t"));
391 gtk_container_add (GTK_CONTAINER (slide_menu), img_struct->report_menu);
392 gtk_widget_add_accelerator( img_struct->report_menu, "activate", img_struct->accel_group, GDK_t, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
393 g_signal_connect (G_OBJECT (img_struct->report_menu),"activate",G_CALLBACK (img_show_slides_report_dialog),img_struct);
394
395 tmp_image = gtk_image_new_from_stock (GTK_STOCK_INDEX,GTK_ICON_SIZE_MENU);
396 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (img_struct->report_menu),tmp_image);
397
398 pixbuf = gtk_icon_theme_load_icon(icon_theme,"object-rotate-left",18,0,NULL);
399 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
400 g_object_unref(pixbuf);
401
402 rotate_left_menu = gtk_image_menu_item_new_with_mnemonic (_("Rotate co_unter-clockwise"));
403 gtk_container_add (GTK_CONTAINER (slide_menu),rotate_left_menu);
404 gtk_widget_add_accelerator (rotate_left_menu,"activate",img_struct->accel_group, GDK_u,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
405 g_signal_connect( G_OBJECT( rotate_left_menu ), "activate",
406 G_CALLBACK( img_rotate_slides_left), img_struct );
407 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (rotate_left_menu),tmp_image);
408
409 pixbuf = gtk_icon_theme_load_icon(icon_theme,"object-rotate-right",18,0,NULL);
410 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
411 g_object_unref(pixbuf);
412
413 rotate_right_menu = gtk_image_menu_item_new_with_mnemonic (_("_Rotate clockwise"));
414 gtk_container_add (GTK_CONTAINER (slide_menu),rotate_right_menu);
415 gtk_widget_add_accelerator (rotate_right_menu,"activate",img_struct->accel_group, GDK_r,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
416 g_signal_connect( G_OBJECT( rotate_right_menu ), "activate",
417 G_CALLBACK ( img_rotate_slides_right ), img_struct );
418 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (rotate_right_menu),tmp_image);
419
420 separator_slide_menu = gtk_separator_menu_item_new ();
421 gtk_container_add (GTK_CONTAINER (slide_menu),separator_slide_menu);
422
423 select_all_menu = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, img_struct->accel_group);
424 gtk_container_add (GTK_CONTAINER (slide_menu),select_all_menu);
425 gtk_widget_add_accelerator (select_all_menu,"activate",img_struct->accel_group,GDK_a,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
426 g_signal_connect (G_OBJECT (select_all_menu),"activate",G_CALLBACK (img_select_all_thumbnails),img_struct);
427
428 deselect_all_menu = gtk_image_menu_item_new_with_mnemonic (_("Un_select all"));
429 gtk_container_add (GTK_CONTAINER (slide_menu),deselect_all_menu);
430 gtk_widget_add_accelerator (deselect_all_menu,"activate",img_struct->accel_group,GDK_e,GDK_CONTROL_MASK,GTK_ACCEL_VISIBLE);
431 g_signal_connect (G_OBJECT (deselect_all_menu),"activate",G_CALLBACK (img_unselect_all_thumbnails),img_struct);
432
433 /* View menu */
434 menuitem1 = gtk_menu_item_new_with_mnemonic (_("_View"));
435 gtk_container_add (GTK_CONTAINER (menubar), menuitem1);
436
437 menu1 = gtk_menu_new ();
438 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menu1);
439
440 img_struct->menu_preview_mode = gtk_radio_menu_item_new_with_label( NULL, _("Preview mode") );
441 g_signal_connect( G_OBJECT( img_struct->menu_preview_mode ), "toggled",
442 G_CALLBACK( img_toggle_mode ), img_struct );
443 gtk_menu_shell_append( GTK_MENU_SHELL( menu1 ), img_struct->menu_preview_mode );
444
445 img_struct->menu_overview_mode = gtk_radio_menu_item_new_with_label_from_widget(
446 GTK_RADIO_MENU_ITEM( img_struct->menu_preview_mode ), _("Overview mode") );
447 gtk_menu_shell_append( GTK_MENU_SHELL( menu1 ), img_struct->menu_overview_mode );
448
449 menuitem1 = gtk_separator_menu_item_new();
450 gtk_menu_shell_append( GTK_MENU_SHELL( menu1 ), menuitem1 );
451
452 menuitem1 = gtk_menu_item_new_with_mnemonic( _("Preview _frame rate") );
453 gtk_menu_shell_append( GTK_MENU_SHELL( menu1 ), menuitem1 );
454
455 menu1 = gtk_menu_new();
456 gtk_menu_item_set_submenu( GTK_MENU_ITEM( menuitem1 ), menu1 );
457
458 {
459 gint i,
460 j;
461 GtkWidget *item;
462 gchar *label;
463 GSList *group = NULL;
464
465 for( i = 0, j = PREVIEW_FPS_MIN;
466 i < PREVIEW_FPS_NO_PRESETS;
467 i++, j += PREVIEW_FPS_STEP )
468 {
469 label = g_strdup_printf( ngettext( "%d frame per second",
470 "%d frames per second",
471 j ),
472 j );
473 item = gtk_radio_menu_item_new_with_label( group, label );
474 tmp_checks[i] = item;
475 g_signal_connect( G_OBJECT( item ), "toggled",
476 G_CALLBACK( img_toggle_frame_rate ), img_struct );
477 g_object_set_data( G_OBJECT( item ), "index",
478 GINT_TO_POINTER( j ) );
479 gtk_menu_shell_append( GTK_MENU_SHELL( menu1 ), item );
480 g_free( label );
481 group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM( item ) );
482 }
483 }
484
485 /* Help menu */
486 menuitem3 = gtk_menu_item_new_with_mnemonic (_("_Help"));
487 gtk_container_add (GTK_CONTAINER (menubar), menuitem3);
488 menu3 = gtk_menu_new ();
489 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem3), menu3);
490
491 contents = gtk_image_menu_item_new_with_mnemonic (_("Contents"));
492 gtk_container_add (GTK_CONTAINER (menu3),contents);
493 gtk_widget_add_accelerator (contents,"activate",img_struct->accel_group,GDK_F1,GDK_MODE_DISABLED,GTK_ACCEL_VISIBLE);
494 g_signal_connect (G_OBJECT (contents),"activate",G_CALLBACK (img_show_uri),img_struct);
495
496 tmp_image = gtk_image_new_from_stock ("gtk-help",GTK_ICON_SIZE_MENU);
497 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (contents),tmp_image);
498
499 about = gtk_image_menu_item_new_from_stock (GTK_STOCK_ABOUT, img_struct->accel_group);
500 gtk_container_add (GTK_CONTAINER (menu3), about);
501 gtk_widget_show_all (menubar);
502 g_signal_connect (G_OBJECT (about),"activate",G_CALLBACK (img_show_about_dialog),img_struct);
503
504 /* Create the toolbar */
505 toolbar = gtk_toolbar_new ();
506 gtk_box_pack_start (GTK_BOX (vbox1), toolbar, FALSE, FALSE, 0);
507 gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
508 tmp_toolbar_icon_size = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar));
509
510 new_button = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_NEW));
511 gtk_container_add (GTK_CONTAINER (toolbar),new_button);
512 gtk_widget_set_tooltip_text(new_button, _("Create a new slideshow"));
513 g_signal_connect (G_OBJECT (new_button),"clicked",G_CALLBACK (img_new_slideshow),img_struct);
514
515 img_struct->open_button = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_OPEN));
516 gtk_container_add (GTK_CONTAINER (toolbar),img_struct->open_button);
517 gtk_widget_set_tooltip_text(img_struct->open_button, _("Open a slideshow"));
518 g_signal_connect (G_OBJECT (img_struct->open_button),"clicked",G_CALLBACK (img_choose_slideshow_filename),img_struct);
519
520 img_struct->save_button = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_SAVE));
521 gtk_container_add (GTK_CONTAINER (toolbar), img_struct->save_button);
522 gtk_widget_set_tooltip_text(img_struct->save_button, _("Save the slideshow"));
523 g_signal_connect (G_OBJECT (img_struct->save_button),"clicked",G_CALLBACK (img_choose_slideshow_filename),img_struct);
524
525 separatortoolitem = GTK_WIDGET (gtk_separator_tool_item_new());
526 gtk_widget_show (separatortoolitem);
527 gtk_container_add (GTK_CONTAINER (toolbar),separatortoolitem);
528
529 pixbuf = gtk_icon_theme_load_icon(icon_theme,"image", 20, 0, NULL);
530 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
531 g_object_unref(pixbuf);
532
533 import_button = GTK_WIDGET (gtk_tool_button_new (tmp_image,""));
534 gtk_container_add (GTK_CONTAINER (toolbar),import_button);
535 gtk_widget_set_tooltip_text(import_button, _("Import pictures"));
536 g_signal_connect ((gpointer)import_button, "clicked", G_CALLBACK (img_add_slides_thumbnails),img_struct);
537
538 pixbuf = gtk_icon_theme_load_icon(icon_theme,"sound", 20, 0, NULL);
539 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
540 g_object_unref(pixbuf);
541
542 import_audio_button = GTK_WIDGET (gtk_tool_button_new (tmp_image,""));
543 gtk_container_add (GTK_CONTAINER (toolbar),import_audio_button);
544 gtk_widget_set_tooltip_text(import_audio_button, _("Import music"));
545 g_signal_connect(G_OBJECT(import_audio_button), "clicked", G_CALLBACK(img_select_audio_files_to_add), img_struct);
546
547 remove_button = GTK_WIDGET (gtk_tool_button_new_from_stock ("gtk-delete"));
548 gtk_container_add (GTK_CONTAINER (toolbar),remove_button);
549 gtk_widget_set_tooltip_text(remove_button, _("Delete the selected slides"));
550 g_signal_connect (G_OBJECT (remove_button),"clicked",G_CALLBACK (img_delete_selected_slides),img_struct);
551
552 pixbuf = gtk_icon_theme_load_icon(icon_theme,"object-rotate-left",22,0,NULL);
553 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
554 g_object_unref(pixbuf);
555
556 rotate_left_button = GTK_WIDGET (gtk_tool_button_new(tmp_image,""));
557 gtk_container_add (GTK_CONTAINER (toolbar), rotate_left_button);
558 gtk_widget_set_tooltip_text( rotate_left_button,
559 _("Rotate the slide 90 degrees to the left") );
560 g_signal_connect( G_OBJECT( rotate_left_button ), "clicked",
561 G_CALLBACK (img_rotate_slides_left ), img_struct );
562
563 pixbuf = gtk_icon_theme_load_icon(icon_theme,"object-rotate-right",22,0,NULL);
564 tmp_image = gtk_image_new_from_pixbuf(pixbuf);
565 g_object_unref(pixbuf);
566
567 rotate_right_button = GTK_WIDGET (gtk_tool_button_new(tmp_image,""));
568 gtk_container_add (GTK_CONTAINER (toolbar),rotate_right_button);
569 gtk_widget_set_tooltip_text( rotate_right_button,
570 _("Rotate the slide 90 degrees to the right") );
571 g_signal_connect( G_OBJECT( rotate_right_button ), "clicked",
572 G_CALLBACK( img_rotate_slides_right ), img_struct );
573
574 zoom_in_button = GTK_WIDGET (gtk_tool_button_new_from_stock ("gtk-zoom-in"));
575 gtk_container_add (GTK_CONTAINER (toolbar),zoom_in_button);
576 gtk_widget_set_tooltip_text(zoom_in_button, _("Zoom In"));
577 g_signal_connect (G_OBJECT (zoom_in_button),"clicked",G_CALLBACK (img_zoom_in),img_struct);
578
579 zoom_out_button = GTK_WIDGET (gtk_tool_button_new_from_stock ("gtk-zoom-out"));
580 gtk_container_add (GTK_CONTAINER (toolbar),zoom_out_button);
581 gtk_widget_set_tooltip_text(zoom_out_button, _("Zoom Out"));
582 g_signal_connect (G_OBJECT (zoom_out_button),"clicked",G_CALLBACK (img_zoom_out),img_struct);
583
584 zoom_normal = GTK_WIDGET (gtk_tool_button_new_from_stock ("gtk-zoom-100"));
585 gtk_container_add (GTK_CONTAINER (toolbar),zoom_normal);
586 gtk_widget_set_tooltip_text(zoom_normal, _("Normal Size"));
587 g_signal_connect (G_OBJECT (zoom_normal),"clicked",G_CALLBACK (img_zoom_reset),img_struct);
588
589 zoom_fit = GTK_WIDGET (gtk_tool_button_new_from_stock ("gtk-zoom-fit"));
590 gtk_container_add (GTK_CONTAINER (toolbar),zoom_fit);
591 gtk_widget_set_tooltip_text(zoom_fit, _("Fit Zoom in Window"));
592 g_signal_connect (G_OBJECT (zoom_fit),"clicked",G_CALLBACK (img_zoom_fit),img_struct);
593
594 separatortoolitem = GTK_WIDGET (gtk_separator_tool_item_new());
595 gtk_container_add (GTK_CONTAINER (toolbar),separatortoolitem);
596
597 img_struct->preview_button = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_PLAY));
598 gtk_container_add (GTK_CONTAINER (toolbar),img_struct->preview_button);
599 gtk_widget_set_tooltip_text(img_struct->preview_button, _("Starts the preview"));
600 g_signal_connect (G_OBJECT (img_struct->preview_button),"clicked",G_CALLBACK (img_start_stop_preview),img_struct);
601
602 separatortoolitem = GTK_WIDGET (gtk_separator_tool_item_new());
603 gtk_container_add (GTK_CONTAINER (toolbar),separatortoolitem);
604
605 first_slide = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GOTO_FIRST));
606 gtk_container_add (GTK_CONTAINER (toolbar),first_slide);
607 gtk_widget_set_tooltip_text( first_slide,
608 _("Go to the first slide of the slideshow") );
609 g_signal_connect (G_OBJECT (first_slide),"clicked",G_CALLBACK (img_goto_first_slide),img_struct);
610
611 prev_slide = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK));
612 gtk_container_add (GTK_CONTAINER (toolbar),prev_slide);
613 gtk_widget_set_tooltip_text( prev_slide,
614 _("Go to the previous slide of the slideshow") );
615 g_signal_connect (G_OBJECT (prev_slide),"clicked",G_CALLBACK (img_goto_prev_slide),img_struct);
616
617 toolbutton_slide_goto = GTK_WIDGET(gtk_tool_item_new ());
618 gtk_container_add (GTK_CONTAINER (toolbar), toolbutton_slide_goto);
619
620 img_struct->slide_number_entry = gtk_entry_new();
621 gtk_entry_set_max_length(GTK_ENTRY (img_struct->slide_number_entry), 4);
622 gtk_entry_set_width_chars(GTK_ENTRY (img_struct->slide_number_entry), 6);
623 gtk_container_add(GTK_CONTAINER(toolbutton_slide_goto),img_struct->slide_number_entry);
624 g_signal_connect(G_OBJECT (img_struct->slide_number_entry), "activate", G_CALLBACK(img_goto_line_entry_activate), img_struct);
625 g_signal_connect(G_OBJECT (img_struct->slide_number_entry), "insert-text", G_CALLBACK (img_check_numeric_entry), NULL );
626
627 toolbutton_slide_goto = GTK_WIDGET(gtk_tool_item_new ());
628 gtk_container_add (GTK_CONTAINER (toolbar), toolbutton_slide_goto);
629
630 label_of = gtk_label_new(_(" of "));
631 gtk_container_add (GTK_CONTAINER (toolbutton_slide_goto),label_of);
632
633 toolbutton_slide_goto = GTK_WIDGET(gtk_tool_item_new ());
634 gtk_container_add (GTK_CONTAINER (toolbar), toolbutton_slide_goto);
635
636 img_struct->total_slide_number_label = gtk_label_new(NULL);
637 gtk_container_add (GTK_CONTAINER (toolbutton_slide_goto),img_struct->total_slide_number_label);
638
639 next_slide = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD));
640 gtk_container_add (GTK_CONTAINER (toolbar),next_slide);
641 gtk_widget_set_tooltip_text( next_slide,
642 _("Go to the next slide of the slideshow") );
643 g_signal_connect (G_OBJECT (next_slide),"clicked",G_CALLBACK (img_goto_next_slide),img_struct);
644
645 last_slide = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GOTO_LAST));
646 gtk_container_add (GTK_CONTAINER (toolbar),last_slide);
647 gtk_widget_set_tooltip_text( last_slide,
648 _("Go to the last slide of the slideshow") );
649 g_signal_connect (G_OBJECT (last_slide),"clicked",G_CALLBACK (img_goto_last_slide),img_struct);
650
651 gtk_widget_show_all (toolbar);
652
653 /* Create the image area and the other widgets */
654 img_struct->paned = gtk_hpaned_new();
655 gtk_box_pack_start (GTK_BOX (vbox1), img_struct->paned, TRUE, TRUE, 0);
656
657 modes_vbox = gtk_vbox_new( FALSE, 0 );
658 gtk_paned_add1( GTK_PANED( img_struct->paned ), modes_vbox );
659
660 swindow = gtk_scrolled_window_new(NULL, NULL);
661 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
662 gtk_box_pack_start( GTK_BOX( modes_vbox ), swindow, TRUE, TRUE, 0 );
663 img_struct->prev_root = swindow;
664
665 viewport = gtk_viewport_new( NULL, NULL );
666 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
667 gtk_container_add( GTK_CONTAINER( swindow ), viewport );
668
669 align = gtk_alignment_new(0.5, 0.5, 0, 0);
670 gtk_container_add( GTK_CONTAINER( viewport ), align );
671
672 image_area_frame = gtk_frame_new(NULL);
673 gtk_frame_set_shadow_type(GTK_FRAME(image_area_frame), GTK_SHADOW_IN);
674 gtk_container_add(GTK_CONTAINER(align), image_area_frame);
675
676 align = gtk_event_box_new();
677 gtk_container_add(GTK_CONTAINER(image_area_frame), align);
678
679 img_struct->image_area = gtk_drawing_area_new();
680 gtk_widget_set_size_request( img_struct->image_area,
681 img_struct->video_size[0],
682 img_struct->video_size[1] );
683 gtk_container_add(GTK_CONTAINER(align), img_struct->image_area);
684 gtk_widget_add_events( img_struct->image_area, GDK_BUTTON1_MOTION_MASK
685 | GDK_POINTER_MOTION_HINT_MASK
686 | GDK_BUTTON_PRESS_MASK );
687 g_signal_connect( G_OBJECT( img_struct->image_area ), "expose-event",
688 G_CALLBACK( img_on_expose_event ), img_struct );
689 g_signal_connect( G_OBJECT( img_struct->image_area ), "button-press-event",
690 G_CALLBACK( img_image_area_button_press ), img_struct );
691 g_signal_connect( G_OBJECT( img_struct->image_area ), "motion-notify-event",
692 G_CALLBACK( img_image_area_motion ), img_struct );
693
694 vbox_frames = gtk_vbox_new(FALSE, 10);
695 scrollable_window = gtk_scrolled_window_new(NULL, NULL);
696 g_object_set (G_OBJECT (scrollable_window),"hscrollbar-policy",GTK_POLICY_AUTOMATIC,"vscrollbar-policy",GTK_POLICY_AUTOMATIC,NULL);
697 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollable_window), vbox_frames);
698
699 video_tab = gtk_label_new (_("Video"));
700 notebook = gtk_notebook_new();
701 gtk_paned_add2( GTK_PANED( img_struct->paned ), notebook );
702 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrollable_window, video_tab);
703
704 viewport = gtk_bin_get_child(GTK_BIN(scrollable_window));
705 gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
706 gtk_container_set_border_width( GTK_CONTAINER( viewport ), 10 );
707
708 /* Slide frame */
709 frame1 = gtk_frame_new (NULL);
710 gtk_box_pack_start (GTK_BOX (vbox_frames), frame1, FALSE, FALSE, 0);
711 gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_OUT);
712
713 frame1_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
714 gtk_container_add (GTK_CONTAINER (frame1), frame1_alignment);
715 gtk_alignment_set_padding (GTK_ALIGNMENT (frame1_alignment), 2, 2, 5, 5);
716
717 frame_label = gtk_label_new (_("<b>Slide Settings</b>"));
718 gtk_frame_set_label_widget (GTK_FRAME (frame1), frame_label);
719 gtk_label_set_use_markup (GTK_LABEL (frame_label), TRUE);
720 gtk_misc_set_padding (GTK_MISC (frame_label), 2, 2);
721
722 vbox_info_slide = gtk_vbox_new (FALSE, 2);
723 gtk_container_add (GTK_CONTAINER (frame1_alignment), vbox_info_slide);
724 gtk_container_set_border_width (GTK_CONTAINER (vbox_info_slide), 2);
725
726 /* Transition types label */
727 transition_label = gtk_label_new (_("Transition Type:"));
728 gtk_box_pack_start (GTK_BOX (vbox_info_slide), transition_label, FALSE, FALSE, 0);
729 gtk_misc_set_alignment (GTK_MISC (transition_label), 0, -1);
730
731 /* Slide selected, slide resolution, slide type and slide total duration */
732 table = gtk_table_new (4, 2, FALSE);
733 gtk_box_pack_start (GTK_BOX (vbox_info_slide), table, TRUE, TRUE, 0);
734 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
735 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
736
737 /* Transition type */
738 img_struct->transition_type = _gtk_combo_box_new_text( TRUE );
739 gtk_table_attach (GTK_TABLE (table), img_struct->transition_type, 0, 1, 0, 1,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (GTK_FILL), 0, 0);
740 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(gtk_combo_box_get_model(GTK_COMBO_BOX(img_struct->transition_type))),
741 1, GTK_SORT_ASCENDING);
742 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(gtk_combo_box_get_model(GTK_COMBO_BOX(img_struct->transition_type))),1, img_sort_none_before_other,NULL,NULL);
743
744 gtk_widget_set_sensitive(img_struct->transition_type, FALSE);
745 g_signal_connect (G_OBJECT (img_struct->transition_type), "changed",G_CALLBACK (img_combo_box_transition_type_changed),img_struct);
746
747 img_struct->random_button = gtk_button_new_with_mnemonic (_("Random"));
748 gtk_widget_set_tooltip_text(img_struct->random_button,_("Imagination randomly decides which transition to apply"));
749 gtk_table_attach (GTK_TABLE (table), img_struct->random_button, 1, 2, 0, 1,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
750 gtk_widget_set_sensitive(img_struct->random_button, FALSE);
751 g_signal_connect (G_OBJECT (img_struct->random_button),"clicked",G_CALLBACK (img_random_button_clicked),img_struct);
752
753 /* Transition duration */
754 trans_duration_label = gtk_label_new (_("Transition Speed:"));
755 gtk_table_attach (GTK_TABLE (table), trans_duration_label, 0, 1, 1, 2,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
756 gtk_misc_set_alignment (GTK_MISC (trans_duration_label), 0, 0.5);
757
758 img_struct->trans_duration = _gtk_combo_box_new_text(FALSE);
759 gtk_table_attach (GTK_TABLE (table), img_struct->trans_duration, 1, 2, 1, 2,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (GTK_FILL), 0, 0);
760 {
761 GtkTreeIter iter;
762 GtkListStore *store = GTK_LIST_STORE( gtk_combo_box_get_model( GTK_COMBO_BOX( img_struct->trans_duration ) ) );
763
764 gtk_list_store_append( store, &iter );
765 gtk_list_store_set( store, &iter, 0, _("Fast"), -1 );
766 gtk_list_store_append( store, &iter );
767 gtk_list_store_set( store, &iter, 0, _("Normal"), -1 );
768 gtk_list_store_append( store, &iter );
769 gtk_list_store_set( store, &iter, 0, _("Slow"), -1 );
770 }
771 gtk_combo_box_set_active(GTK_COMBO_BOX(img_struct->trans_duration),1);
772 gtk_widget_set_sensitive(img_struct->trans_duration, FALSE);
773 g_signal_connect (G_OBJECT (img_struct->trans_duration),"changed",G_CALLBACK (img_combo_box_speed_changed),img_struct);
774
775 /* Slide duration */
776 duration_label = gtk_label_new (_("Slide Duration in sec:"));
777 gtk_table_attach (GTK_TABLE (table), duration_label, 0, 1, 2, 3,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
778 gtk_misc_set_alignment (GTK_MISC (duration_label), 0, 0.5);
779
780 img_struct->duration = gtk_spin_button_new_with_range (1, 300, 1);
781 gtk_table_attach (GTK_TABLE (table), img_struct->duration, 1, 2, 2, 3,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
782 gtk_widget_set_sensitive(img_struct->duration, FALSE);
783 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON (img_struct->duration),TRUE);
784 g_signal_connect (G_OBJECT (img_struct->duration),"value-changed",G_CALLBACK (img_spinbutton_value_changed),img_struct);
785
786 /* Slide Total Duration */
787 total_time = gtk_label_new (_("Slideshow Length:"));
788 gtk_table_attach (GTK_TABLE (table), total_time, 0, 1, 3, 4,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
789 gtk_misc_set_alignment (GTK_MISC (total_time), 0, 0.5);
790
791 img_struct->total_time_data = gtk_label_new ("");
792 gtk_table_attach (GTK_TABLE (table), img_struct->total_time_data, 1, 2, 3, 4,(GtkAttachOptions) (GTK_FILL),(GtkAttachOptions) (0), 0, 0);
793 gtk_misc_set_alignment (GTK_MISC (img_struct->total_time_data), 0, 0.5);
794
795 /* Slide motion frame */
796 frame2 = gtk_frame_new (NULL);
797 gtk_box_pack_start (GTK_BOX (vbox_frames), frame2, FALSE, FALSE, 0);
798 gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_OUT);
799
800 frame2_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
801 gtk_container_add (GTK_CONTAINER (frame2), frame2_alignment);
802 gtk_alignment_set_padding (GTK_ALIGNMENT (frame2_alignment), 2, 2, 5, 5);
803
804 frame_label = gtk_label_new (_("<b>Slide Motion</b>"));
805 gtk_frame_set_label_widget (GTK_FRAME (frame2), frame_label);
806 gtk_label_set_use_markup (GTK_LABEL (frame_label), TRUE);
807 gtk_misc_set_padding (GTK_MISC (frame_label), 2, 2);
808
809 vbox_slide_motion = gtk_vbox_new (FALSE, 2);
810 gtk_container_add (GTK_CONTAINER (frame2_alignment), vbox_slide_motion);
811
812 hbox_stop_points = gtk_hbox_new(FALSE,5);
813 gtk_box_pack_start (GTK_BOX (vbox_slide_motion), hbox_stop_points, TRUE, FALSE, 0);
814 stop_points_label = gtk_label_new(_("Stop Point:"));
815 gtk_box_pack_start (GTK_BOX (hbox_stop_points), stop_points_label, TRUE, TRUE, 0);
816 gtk_misc_set_alignment(GTK_MISC(stop_points_label),0.0, 0.5);
817
818 img_struct->ken_left = gtk_button_new();
819 g_signal_connect( G_OBJECT( img_struct->ken_left ), "clicked",
820 G_CALLBACK( img_goto_prev_point ), img_struct );
821 gtk_box_pack_start (GTK_BOX (hbox_stop_points), img_struct->ken_left, FALSE, TRUE, 0);
822 image_buttons = gtk_image_new_from_stock (GTK_STOCK_GO_BACK, GTK_ICON_SIZE_MENU);
823 gtk_button_set_image(GTK_BUTTON(img_struct->ken_left), image_buttons);
824
825 img_struct->ken_entry = gtk_entry_new();
826 gtk_entry_set_max_length(GTK_ENTRY (img_struct->ken_entry), 2);
827 gtk_entry_set_width_chars(GTK_ENTRY (img_struct->ken_entry), 4);
828 {
829 GObject *object = G_OBJECT( img_struct->ken_entry );
830
831 g_signal_connect( object, "activate",
832 G_CALLBACK( img_goto_point ), img_struct );
833 g_signal_connect( object, "insert-text",
834 G_CALLBACK( img_check_numeric_entry ), NULL );
835 }
836 gtk_box_pack_start (GTK_BOX (hbox_stop_points), img_struct->ken_entry, FALSE, TRUE, 0);
837 label_of = gtk_label_new(_(" of "));
838 gtk_box_pack_start (GTK_BOX (hbox_stop_points), label_of, FALSE, FALSE, 0);
839 img_struct->total_stop_points_label = gtk_label_new(NULL);
840 gtk_box_pack_start (GTK_BOX (hbox_stop_points), img_struct->total_stop_points_label, FALSE, FALSE, 0);
841
842 img_struct->ken_right = gtk_button_new();
843 g_signal_connect( G_OBJECT( img_struct->ken_right ), "clicked",
844 G_CALLBACK( img_goto_next_point ), img_struct );
845 gtk_box_pack_start (GTK_BOX (hbox_stop_points), img_struct->ken_right, FALSE, TRUE, 0);
846 image_buttons = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU);
847 gtk_button_set_image(GTK_BUTTON(img_struct->ken_right), image_buttons);
848
849 hbox_time_offset = gtk_hbox_new(FALSE,0);
850 gtk_box_pack_start (GTK_BOX (vbox_slide_motion), hbox_time_offset, FALSE, FALSE, 0);
851 time_offset_label = gtk_label_new(_("Duration:"));
852 gtk_box_pack_start (GTK_BOX (hbox_time_offset), time_offset_label, TRUE, TRUE, 0);
853 gtk_misc_set_alignment(GTK_MISC(time_offset_label),0.0, 0.5);
854 img_struct->ken_duration = gtk_spin_button_new_with_range (1, 60, 1);
855 gtk_box_pack_start (GTK_BOX (hbox_time_offset), img_struct->ken_duration, FALSE, FALSE, 0);
856 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON (img_struct->ken_duration),TRUE);
857 GtkWidget *hbox_zoom = gtk_hbox_new(FALSE,0);
858 gtk_box_pack_start (GTK_BOX (vbox_slide_motion), hbox_zoom, FALSE, FALSE, 0);
859
860 GtkWidget *label = gtk_label_new(_("Zoom: "));
861 gtk_misc_set_alignment(GTK_MISC(label),0.0, 0.5);
862 gtk_box_pack_start (GTK_BOX (hbox_zoom), label, FALSE, TRUE, 0);
863
864 img_struct->ken_zoom = gtk_hscale_new_with_range(1,30,0.10000000000000001);
865 gtk_scale_set_value_pos (GTK_SCALE(img_struct->ken_zoom), GTK_POS_LEFT);
866 gtk_box_pack_start (GTK_BOX (hbox_zoom), img_struct->ken_zoom, TRUE, TRUE, 0);
867 g_signal_connect( G_OBJECT( img_struct->ken_zoom ), "value-changed",
868 G_CALLBACK( img_ken_burns_zoom_changed ), img_struct );
869
870 hbox_buttons = gtk_hbutton_box_new();
871 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox_buttons), GTK_BUTTONBOX_SPREAD);
872 gtk_box_pack_start (GTK_BOX (vbox_slide_motion), hbox_buttons, FALSE, FALSE, 0);
873
874 img_struct->ken_add = gtk_button_new_with_label(_("Add"));
875 g_signal_connect( G_OBJECT( img_struct->ken_add ), "clicked",
876 G_CALLBACK( img_add_stop_point ), img_struct );
877 gtk_box_pack_start (GTK_BOX (hbox_buttons), img_struct->ken_add, FALSE, FALSE, 0);
878 img_struct->ken_update = gtk_button_new_with_label( _("Update") );
879 g_signal_connect( G_OBJECT( img_struct->ken_update ), "clicked",
880 G_CALLBACK( img_update_stop_point ), img_struct );
881 gtk_box_pack_start( GTK_BOX( hbox_buttons ), img_struct->ken_update,
882 FALSE, FALSE, 0 );
883 img_struct->ken_remove = gtk_button_new_with_label(_("Remove"));
884 g_signal_connect( G_OBJECT( img_struct->ken_remove ), "clicked",
885 G_CALLBACK( img_delete_stop_point ), img_struct );
886 gtk_box_pack_start (GTK_BOX (hbox_buttons), img_struct->ken_remove, FALSE, FALSE, 0);
887
888 /* Slide text frame */
889 frame4 = gtk_frame_new (NULL);
890 gtk_box_pack_start (GTK_BOX (vbox_frames), frame4, FALSE, FALSE, 0);
891 gtk_frame_set_shadow_type (GTK_FRAME (frame4), GTK_SHADOW_OUT);
892
893 frame4_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
894 gtk_container_add (GTK_CONTAINER (frame4), frame4_alignment);
895 gtk_alignment_set_padding (GTK_ALIGNMENT (frame4_alignment), 5, 5, 5, 5);
896
897 frame_label = gtk_label_new (_("<b>Slide Text</b>"));
898 gtk_frame_set_label_widget (GTK_FRAME (frame4), frame_label);
899 gtk_label_set_use_markup (GTK_LABEL (frame_label), TRUE);
900 gtk_misc_set_padding (GTK_MISC (frame_label), 2, 2);
901
902 vbox_slide_caption = gtk_vbox_new (FALSE, 2);
903 gtk_container_add (GTK_CONTAINER (frame4_alignment), vbox_slide_caption);
904
905 hbox_textview = gtk_hbox_new(FALSE, 2);
906 gtk_box_pack_start (GTK_BOX (vbox_slide_caption), hbox_textview, FALSE, FALSE, 0);
907
908 img_struct->sub_textview = gtk_text_view_new();
909 gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(img_struct->sub_textview), FALSE);
910 img_struct->slide_text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(img_struct->sub_textview));
911 g_signal_connect( G_OBJECT( img_struct->slide_text_buffer ), "changed",
912 G_CALLBACK( img_queue_subtitle_update ), img_struct );
913 /* Let's connect the focus-in and focus-out events to prevent the
914 * DEL key when pressed inside the textview delete the selected slide */
915 g_signal_connect( G_OBJECT( img_struct->sub_textview ), "focus-in-event",
916 G_CALLBACK( img_sub_textview_focus_in ), img_struct );
917 g_signal_connect( G_OBJECT( img_struct->sub_textview ), "focus-out-event",
918 G_CALLBACK( img_sub_textview_focus_out ), img_struct );
919 img_struct->scrolled_win = gtk_scrolled_window_new(NULL, NULL);
920 gtk_widget_set_size_request(img_struct->scrolled_win, -1, 18);
921 g_object_set (G_OBJECT (img_struct->scrolled_win),"hscrollbar-policy",GTK_POLICY_AUTOMATIC,"vscrollbar-policy",GTK_POLICY_AUTOMATIC,"shadow-type",GTK_SHADOW_IN,NULL);
922 gtk_container_add(GTK_CONTAINER (img_struct->scrolled_win), img_struct->sub_textview);
923 gtk_box_pack_start (GTK_BOX (hbox_textview), img_struct->scrolled_win, TRUE, TRUE, 0);
924
925 img_struct->expand_button = gtk_button_new();
926 gtk_widget_set_tooltip_text(img_struct->expand_button, _("Click to expand the area"));
927 gtk_button_set_relief(GTK_BUTTON(img_struct->expand_button), GTK_RELIEF_NONE);
928 gtk_widget_set_size_request(img_struct->expand_button, 22, 20);
929 g_signal_connect (G_OBJECT (img_struct->expand_button),"clicked",G_CALLBACK (img_expand_button_clicked),img_struct);
930
931 image_buttons = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
932 gtk_widget_set_size_request(image_buttons, 14, 14);
933 gtk_button_set_image(GTK_BUTTON(img_struct->expand_button),image_buttons);
934 gtk_box_pack_start (GTK_BOX (hbox_textview), img_struct->expand_button, FALSE, FALSE, 0);
935
936 text_animation_hbox = gtk_hbox_new( FALSE, 6 );
937 gtk_box_pack_start( GTK_BOX( vbox_slide_caption ), text_animation_hbox, FALSE, FALSE, 0 );
938
939 img_struct->sub_font = gtk_font_button_new();
940 g_signal_connect( G_OBJECT( img_struct->sub_font ), "font-set",
941 G_CALLBACK( img_text_font_set ), img_struct );
942 gtk_box_pack_start (GTK_BOX (text_animation_hbox), img_struct->sub_font, TRUE, TRUE, 0);
943 gtk_widget_set_tooltip_text(img_struct->sub_font, _("Click to choose the font"));
944
945 img_struct->sub_color = gtk_color_button_new();
946 gtk_color_button_set_use_alpha( GTK_COLOR_BUTTON( img_struct->sub_color ), TRUE );
947 g_signal_connect( G_OBJECT( img_struct->sub_color ), "color-set",
948 G_CALLBACK( img_font_color_changed ), img_struct );
949 gtk_box_pack_start( GTK_BOX( text_animation_hbox ), img_struct->sub_color, FALSE, FALSE, 0 );
950 gtk_widget_set_tooltip_text(img_struct->sub_color, _("Click to choose the font color"));
951
952 img_struct->sub_bgcolor = gtk_color_button_new();
953 gtk_color_button_set_use_alpha( GTK_COLOR_BUTTON( img_struct->sub_bgcolor ), TRUE );
954 g_signal_connect( G_OBJECT( img_struct->sub_bgcolor ), "color-set",
955 G_CALLBACK( img_font_bgcolor_changed ), img_struct );
956 gtk_box_pack_start( GTK_BOX( text_animation_hbox ), img_struct->sub_bgcolor, FALSE, FALSE, 0 );
957 gtk_widget_set_tooltip_text(img_struct->sub_bgcolor, _("Click to choose the font background color"));
958
959 a_hbox = gtk_hbox_new(FALSE, 6);
960 gtk_box_pack_start (GTK_BOX (vbox_slide_caption), a_hbox, FALSE, FALSE, 0);
961 a_label = gtk_label_new(_("Animation:"));
962 gtk_misc_set_alignment(GTK_MISC(a_label), 0.0, 0.5);
963 gtk_box_pack_start (GTK_BOX (a_hbox), a_label, TRUE, TRUE, 0);
964 img_struct->sub_anim = img_create_subtitle_animation_combo();
965 gtk_combo_box_set_active(GTK_COMBO_BOX(img_struct->sub_anim), 0);
966 g_signal_connect( G_OBJECT( img_struct->sub_anim ), "changed",
967 G_CALLBACK( img_text_anim_set ), img_struct );
968 gtk_box_pack_start (GTK_BOX (a_hbox), img_struct->sub_anim, FALSE, FALSE, 0);
969
970 a_hbox = gtk_hbox_new(FALSE, 6);
971 gtk_box_pack_start (GTK_BOX (vbox_slide_caption), a_hbox, FALSE, FALSE, 0);
972
973 a_label = gtk_label_new( _("Animation Speed:") );
974 gtk_misc_set_alignment( GTK_MISC( a_label ), 0, 0.5 );
975 gtk_box_pack_start( GTK_BOX( a_hbox ), a_label, TRUE, TRUE, 0 );
976
977 img_struct->sub_anim_duration = gtk_spin_button_new_with_range (1, 60, 1);
978 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON (img_struct->sub_anim_duration),TRUE);
979 gtk_box_pack_start( GTK_BOX( a_hbox ), img_struct->sub_anim_duration,
980 FALSE, FALSE, 0 );
981
982 gtk_widget_set_sensitive( img_struct->sub_anim_duration, FALSE );
983 g_signal_connect( G_OBJECT( img_struct->sub_anim_duration ), "value-changed",
984 G_CALLBACK( img_combo_box_anim_speed_changed ), img_struct );
985
986 a_hbox = gtk_hbox_new(FALSE, 6);
987 gtk_box_pack_start( GTK_BOX( vbox_slide_caption ), a_hbox, FALSE, FALSE, 0 );
988
989 a_label = gtk_label_new( _("Placing is relative to:") );
990 gtk_misc_set_alignment( GTK_MISC( a_label ), 0, 0.5 );
991 gtk_box_pack_start( GTK_BOX( a_hbox ), a_label, TRUE, TRUE, 0 );
992
993 img_struct->sub_placing = _gtk_combo_box_new_text( FALSE );
994 gtk_box_pack_start( GTK_BOX( a_hbox ), img_struct->sub_placing,
995 FALSE, FALSE, 0 );
996 {
997 GtkTreeIter iter;
998 GtkListStore *store =
999 GTK_LIST_STORE( gtk_combo_box_get_model(
1000 GTK_COMBO_BOX( img_struct->sub_placing ) ) );
1001
1002 gtk_list_store_append( store, &iter );
1003 gtk_list_store_set( store, &iter, 0, _("Exported video"), -1 );
1004 gtk_list_store_append( store, &iter );
1005 gtk_list_store_set( store, &iter, 0, _("Original image"), -1 );
1006 }
1007 gtk_combo_box_set_active( GTK_COMBO_BOX( img_struct->sub_placing ), 1 );
1008 g_signal_connect( G_OBJECT( img_struct->sub_placing ), "changed",
1009 G_CALLBACK( img_placing_changed ), img_struct );
1010
1011 a_hbox = gtk_hbox_new(FALSE, 6);
1012 gtk_box_pack_start( GTK_BOX( vbox_slide_caption ), a_hbox, FALSE, FALSE, 0 );
1013
1014 a_label = gtk_label_new( _("Subtitle position:") );
1015 gtk_misc_set_alignment( GTK_MISC( a_label ), 0, 0.5 );
1016 gtk_box_pack_start( GTK_BOX( a_hbox ), a_label, TRUE, TRUE, 0 );
1017
1018 img_struct->sub_pos = img_table_button_new();
1019 gtk_box_pack_start( GTK_BOX( a_hbox ), img_struct->sub_pos,
1020 FALSE, FALSE, 0 );
1021 {
1022 /* Load position icons */
1023 GdkPixbuf *pixs[9];
1024 gint i;
1025 gchar *path;
1026
1027 /* First code snippet is in use for development version,
1028 * while second is intendeded for releases */
1029 #if PLUGINS_INSTALLED
1030 path = g_strconcat( DATADIR, "/imagination/pixmaps/imagination-pos", NULL );
1031 #else
1032 path = g_strconcat( "pixmaps/imagination-pos", NULL );
1033 #endif
1034 for( i = 0; i < 9; i++ )
1035 {
1036 gchar *file;
1037
1038 file = g_strdup_printf( "%s-%d.png", path, i );
1039 pixs[i] = gdk_pixbuf_new_from_file( file, NULL );
1040 g_free( file );
1041 }
1042 g_free( path );
1043
1044 img_table_button_set_pixbufs( IMG_TABLE_BUTTON( img_struct->sub_pos ),
1045 9, pixs );
1046
1047 for( i = 0; i < 9; i++ )
1048 g_object_unref( G_OBJECT( pixs[i] ) );
1049 }
1050 img_table_button_set_active_item( IMG_TABLE_BUTTON( img_struct->sub_pos ), 4 );
1051 g_signal_connect( G_OBJECT( img_struct->sub_pos ), "active-item-changed",
1052 G_CALLBACK( img_text_pos_changed ), img_struct );
1053
1054 /* Background music frame */
1055 audio_tab = gtk_label_new (_("Audio"));
1056 vbox_audio_frames = gtk_vbox_new(FALSE, 0);
1057 gtk_container_set_border_width(GTK_CONTAINER(vbox_audio_frames), 10);
1058 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_audio_frames, audio_tab);
1059
1060 frame3 = gtk_frame_new (NULL);
1061 gtk_box_pack_start (GTK_BOX (vbox_audio_frames), frame3, TRUE, TRUE, 0);
1062 gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_OUT);
1063
1064 frame3_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
1065 gtk_container_add (GTK_CONTAINER (frame3), frame3_alignment);
1066 gtk_alignment_set_padding (GTK_ALIGNMENT (frame3_alignment), 2, 2, 5, 5);
1067
1068 frame_label = gtk_label_new (_("<b>Background Music</b>"));
1069 gtk_frame_set_label_widget (GTK_FRAME (frame3), frame_label);
1070 gtk_label_set_use_markup (GTK_LABEL (frame_label), TRUE);
1071 gtk_misc_set_padding (GTK_MISC (frame_label), 2, 2);
1072
1073 /* Add the liststore */
1074 vbox2 = gtk_vbox_new (FALSE, 5);
1075 gtk_container_add (GTK_CONTAINER (frame3_alignment), vbox2);
1076 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 0);
1077
1078 scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
1079 gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow1, TRUE, TRUE, 0);
1080 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1081 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN);
1082
1083 img_struct->music_file_liststore = gtk_list_store_new (6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
1084 g_signal_connect (G_OBJECT (img_struct->music_file_liststore), "row-inserted", G_CALLBACK (img_activate_remove_button_music_liststore) , img_struct);
1085
1086 img_struct->music_file_treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(img_struct->music_file_liststore));
1087 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(img_struct->music_file_treeview));
1088
1089 gtk_drag_dest_set (GTK_WIDGET(img_struct->music_file_treeview),GTK_DEST_DEFAULT_ALL,drop_targets,1,GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
1090 g_signal_connect (G_OBJECT (img_struct->music_file_treeview),"drag-data-received",G_CALLBACK (img_on_drag_audio_data_received), img_struct);
1091
1092 /* First and last three columns aren't displayed, so we
1093 * only need two columns. */
1094 for (x = 1; x < 3; x++)
1095 {
1096 column = gtk_tree_view_column_new();
1097 renderer = gtk_cell_renderer_text_new();
1098 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1099 gtk_tree_view_column_set_attributes(column, renderer, "text", x,
1100 "foreground", 4,
1101 NULL );
1102 gtk_tree_view_append_column (GTK_TREE_VIEW (img_struct->music_file_treeview), column);
1103 }
1104
1105 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(img_struct->music_file_treeview), TRUE);
1106 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (img_struct->music_file_treeview), FALSE);
1107 gtk_tree_view_set_tooltip_column( GTK_TREE_VIEW( img_struct->music_file_treeview ), 5 );
1108 gtk_container_add (GTK_CONTAINER (scrolledwindow1), img_struct->music_file_treeview);
1109
1110 /* Add the total music labels and the buttons */
1111 hbox_music_label = gtk_hbox_new(FALSE, 2);
1112 gtk_box_pack_start( GTK_BOX( vbox2 ), hbox_music_label, FALSE, FALSE, 0 );
1113
1114 music_time = gtk_label_new(_("Music Duration:"));
1115 gtk_box_pack_start(GTK_BOX(hbox_music_label), music_time, TRUE, TRUE, 0);
1116 gtk_misc_set_alignment (GTK_MISC (music_time), 0, 0.5);
1117
1118 img_struct->music_time_data = gtk_label_new(NULL);
1119 gtk_box_pack_start(GTK_BOX(hbox_music_label), img_struct->music_time_data, TRUE, TRUE, 0);
1120 gtk_misc_set_alignment (GTK_MISC (img_struct->music_time_data), 1, 0.5);
1121
1122 hbox_buttons = gtk_hbox_new(TRUE, 2);
1123 gtk_box_pack_start( GTK_BOX( vbox2 ), hbox_buttons, FALSE, FALSE, 0 );
1124
1125 img_struct->play_audio_button = gtk_button_new();
1126 gtk_widget_set_sensitive(img_struct->play_audio_button, FALSE);
1127 gtk_box_pack_start(GTK_BOX(hbox_buttons), img_struct->play_audio_button, FALSE, TRUE, 0);
1128 image_buttons = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
1129 gtk_container_add (GTK_CONTAINER (img_struct->play_audio_button), image_buttons);
1130 gtk_widget_set_tooltip_text(img_struct->play_audio_button, _("Play the selected file"));
1131 g_signal_connect ( (gpointer) img_struct->play_audio_button, "clicked", G_CALLBACK (img_play_stop_selected_file), img_struct);
1132
1133 img_struct->remove_audio_button = gtk_button_new();
1134 gtk_widget_set_sensitive(img_struct->remove_audio_button, FALSE);
1135 gtk_box_pack_start(GTK_BOX(hbox_buttons), img_struct->remove_audio_button, FALSE, TRUE, 0);
1136 image_buttons = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU);
1137 gtk_container_add (GTK_CONTAINER (img_struct->remove_audio_button), image_buttons);
1138 gtk_widget_set_tooltip_text(img_struct->remove_audio_button, _("Delete the selected file"));
1139 g_signal_connect ( (gpointer) img_struct->remove_audio_button, "clicked", G_CALLBACK (img_remove_audio_files), img_struct);
1140
1141 move_up_button = gtk_button_new();
1142 gtk_box_pack_start(GTK_BOX(hbox_buttons), move_up_button, FALSE, TRUE, 0);
1143 image_buttons = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU);
1144 gtk_container_add (GTK_CONTAINER (move_up_button), image_buttons);
1145 gtk_widget_set_tooltip_text(move_up_button, _("Move the selected file up"));
1146 g_signal_connect( G_OBJECT( move_up_button ), "clicked", G_CALLBACK( img_move_audio_up ), img_struct );
1147
1148 move_down_button = gtk_button_new();
1149 gtk_box_pack_start(GTK_BOX(hbox_buttons), move_down_button, FALSE, TRUE, 0);
1150 image_buttons = gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU);
1151 gtk_container_add (GTK_CONTAINER (move_down_button), image_buttons);
1152 gtk_widget_set_tooltip_text(move_down_button, _("Move the selected file down"));
1153 g_signal_connect( G_OBJECT( move_down_button ), "clicked", G_CALLBACK( img_move_audio_down ), img_struct );
1154
1155 clear_button = gtk_button_new();
1156 gtk_box_pack_start(GTK_BOX(hbox_buttons), clear_button, FALSE, TRUE, 0);
1157 image_buttons = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU);
1158 gtk_container_add (GTK_CONTAINER (clear_button), image_buttons);
1159 gtk_widget_set_tooltip_text(clear_button, _("Clear all files"));
1160 g_signal_connect ( (gpointer) clear_button, "clicked", G_CALLBACK (img_clear_audio_files), img_struct);
1161 /* End of Background music frame */
1162
1163 /* Begin of Message tab */
1164 img_struct->message_label = gtk_label_new (_("Messages"));
1165 message_scroll = gtk_scrolled_window_new(NULL, NULL);
1166 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(message_scroll),
1167 GTK_POLICY_AUTOMATIC,
1168 GTK_POLICY_AUTOMATIC);
1169 img_struct->message_page = gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
1170 message_scroll,
1171 img_struct->message_label);
1172
1173 message_view = gtk_text_view_new();
1174 gtk_text_view_set_editable(GTK_TEXT_VIEW(message_view), FALSE);
1175 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(message_view), GTK_WRAP_WORD);
1176 gtk_container_add(GTK_CONTAINER(message_scroll), message_view);
1177 img_struct->message_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (message_view));
1178 g_signal_connect( (gpointer) notebook, "switch_page",
1179 G_CALLBACK (img_notebook_switch_page), img_struct);
1180 /* End of Message tab */
1181
1182 /* Create the model */
1183 img_struct->thumbnail_model = gtk_list_store_new( 4,
1184 GDK_TYPE_PIXBUF, /* thumbnail */
1185 G_TYPE_POINTER, /* slide_info */
1186 GDK_TYPE_PIXBUF, /* transition thumbnail */
1187 G_TYPE_BOOLEAN ); /* presence of a subtitle */
1188
1189 /* Create overview mode widgets */
1190 /* FIXME: A lot of duplicate code here!! */
1191 {
1192 GtkWidget *icon,
1193 *swindow;
1194 GtkCellRenderer *cell;
1195 gchar *path;
1196 GdkPixbuf *text;
1197
1198 swindow = gtk_scrolled_window_new( NULL, NULL );
1199 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( swindow ),
1200 GTK_POLICY_AUTOMATIC,
1201 GTK_POLICY_AUTOMATIC );
1202 gtk_box_pack_start( GTK_BOX( modes_vbox ), swindow, TRUE, TRUE, 0 );
1203 img_struct->over_root = swindow;
1204
1205 icon = gtk_icon_view_new_with_model(
1206 GTK_TREE_MODEL( img_struct->thumbnail_model ) );
1207 gtk_icon_view_set_selection_mode( GTK_ICON_VIEW( icon ),
1208 GTK_SELECTION_MULTIPLE );
1209 gtk_icon_view_set_orientation( GTK_ICON_VIEW( icon ),
1210 GTK_ORIENTATION_HORIZONTAL );
1211 gtk_icon_view_set_column_spacing( GTK_ICON_VIEW( icon ), 0 );
1212 gtk_icon_view_set_row_spacing( GTK_ICON_VIEW( icon ), 0 );
1213 img_struct->over_icon = icon;
1214 img_struct->active_icon = icon;
1215 g_signal_connect( G_OBJECT( icon ), "selection-changed",
1216 G_CALLBACK( img_iconview_selection_changed ),
1217 img_struct );
1218 g_signal_connect( G_OBJECT( icon ), "select-all",
1219 G_CALLBACK( img_iconview_selection_changed ),
1220 img_struct );
1221 g_signal_connect( G_OBJECT( icon ), "button-press-event",
1222 G_CALLBACK( img_iconview_selection_button_press ),
1223 img_struct );
1224 gtk_container_add( GTK_CONTAINER( swindow ), icon );
1225
1226 cell = img_cell_renderer_pixbuf_new();
1227 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( icon ), cell, FALSE );
1228 img_struct->over_cell = G_OBJECT( cell );
1229
1230 #if PLUGINS_INSTALLED
1231 path = g_strconcat( DATADIR,
1232 "/imagination/pixmaps/imagination-text.png",
1233 NULL );
1234 #else
1235 path = g_strdup( "pixmaps/imagination-text.png" );
1236 #endif
1237 text = gdk_pixbuf_new_from_file( path, NULL );
1238 g_free( path );
1239 g_object_set( G_OBJECT( cell ), "ypad", 2,
1240 "text-ico", text,
1241 NULL );
1242 g_object_unref( G_OBJECT( text ) );
1243 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( icon ), cell,
1244 "pixbuf", 0,
1245 "transition", 2,
1246 "has-text", 3,
1247 NULL );
1248 gtk_icon_view_set_reorderable( GTK_ICON_VIEW( icon ), TRUE );
1249 }
1250
1251 /* Add wrapper for DnD */
1252 eventbox = gtk_event_box_new();
1253 img_struct->thum_root = eventbox;
1254 gtk_event_box_set_above_child( GTK_EVENT_BOX( eventbox ), FALSE );
1255 gtk_event_box_set_visible_window( GTK_EVENT_BOX( eventbox ), FALSE );
1256 gtk_drag_dest_set( GTK_WIDGET( eventbox ), GTK_DEST_DEFAULT_ALL,
1257 drop_targets, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE |
1258 GDK_ACTION_LINK | GDK_ACTION_ASK);
1259 g_signal_connect( G_OBJECT( eventbox ), "drag-data-received",
1260 G_CALLBACK( img_on_drag_data_received), img_struct );
1261 gtk_box_pack_start( GTK_BOX( vbox1 ), eventbox, FALSE, TRUE, 0 );
1262
1263 /* Create the thumbnail viewer */
1264 thumb_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
1265 gtk_widget_set_size_request( thumb_scrolledwindow, -1, 115 );
1266 g_signal_connect( G_OBJECT( thumb_scrolledwindow ), "scroll-event",
1267 G_CALLBACK( img_scroll_thumb ), img_struct );
1268 gtk_container_add( GTK_CONTAINER( eventbox ), thumb_scrolledwindow );
1269 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (thumb_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
1270 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (thumb_scrolledwindow), GTK_SHADOW_IN);
1271
1272 img_struct->thumbnail_iconview = gtk_icon_view_new_with_model(GTK_TREE_MODEL (img_struct->thumbnail_model));
1273 gtk_container_add( GTK_CONTAINER( thumb_scrolledwindow ), img_struct->thumbnail_iconview );
1274
1275 /* Create the cell layout */
1276 pixbuf_cell = img_cell_renderer_pixbuf_new();
1277 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (img_struct->thumbnail_iconview), pixbuf_cell, FALSE);
1278 {
1279 gchar *path;
1280 GdkPixbuf *text;
1281
1282 #if PLUGINS_INSTALLED
1283 path = g_strconcat( DATADIR,
1284 "/imagination/pixmaps/imagination-text.png",
1285 NULL );
1286 #else
1287 path = g_strdup( "pixmaps/imagination-text.png" );
1288 #endif
1289 text = gdk_pixbuf_new_from_file( path, NULL );
1290 g_free( path );
1291 g_object_set( G_OBJECT( pixbuf_cell ), "width", 115,
1292 "ypad", 2,
1293 "text-ico", text,
1294 NULL );
1295 g_object_unref( G_OBJECT( text ) );
1296 }
1297 gtk_cell_layout_set_attributes(
1298 GTK_CELL_LAYOUT( img_struct->thumbnail_iconview ), pixbuf_cell,
1299 "pixbuf", 0,
1300 "transition", 2,
1301 "has-text", 3,
1302 NULL );
1303
1304 /* Set some iconview properties */
1305 gtk_icon_view_set_text_column( GTK_ICON_VIEW( img_struct->thumbnail_iconview ), -1 );
1306 gtk_icon_view_set_reorderable(GTK_ICON_VIEW (img_struct->thumbnail_iconview),TRUE);
1307 gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (img_struct->thumbnail_iconview), GTK_SELECTION_MULTIPLE);
1308 gtk_icon_view_set_orientation (GTK_ICON_VIEW (img_struct->thumbnail_iconview), GTK_ORIENTATION_HORIZONTAL);
1309 gtk_icon_view_set_column_spacing (GTK_ICON_VIEW (img_struct->thumbnail_iconview),0);
1310 gtk_icon_view_set_row_spacing (GTK_ICON_VIEW (img_struct->thumbnail_iconview),0);
1311 gtk_icon_view_set_columns (GTK_ICON_VIEW (img_struct->thumbnail_iconview), G_MAXINT);
1312 g_signal_connect (G_OBJECT (img_struct->thumbnail_iconview),"selection-changed",G_CALLBACK (img_iconview_selection_changed),img_struct);
1313 g_signal_connect (G_OBJECT (img_struct->thumbnail_iconview),"select-all",G_CALLBACK (img_iconview_selection_changed),img_struct);
1314 g_signal_connect (G_OBJECT (img_struct->thumbnail_iconview),"button-press-event",G_CALLBACK (img_iconview_selection_button_press),img_struct);
1315 gtk_widget_show_all( eventbox );
1316
1317 /* Create the status bar */
1318 img_struct->statusbar = gtk_statusbar_new ();
1319 gtk_widget_show (img_struct->statusbar);
1320 gtk_box_pack_start (GTK_BOX (vbox1), img_struct->statusbar, FALSE, TRUE, 0);
1321 img_struct->context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (img_struct->statusbar), "statusbar");
1322
1323 /* Create the progress bar */
1324 img_struct->progress_bar = gtk_progress_bar_new();
1325 gtk_widget_set_size_request (img_struct->progress_bar, -1, 15);
1326 {
1327 GtkWidget *vbox;
1328
1329 vbox = gtk_vbox_new (FALSE, 0);
1330 gtk_box_pack_start (GTK_BOX (img_struct->statusbar), vbox, FALSE, FALSE, 0);
1331 gtk_box_pack_start (GTK_BOX (vbox), img_struct->progress_bar, TRUE, FALSE, 0);
1332 gtk_widget_show (vbox);
1333 }
1334 gtk_widget_show_all( img_struct->paned );
1335 gtk_window_add_accel_group (GTK_WINDOW (img_struct->imagination_window), img_struct->accel_group);
1336
1337 /* Disable all Ken Burns controls */
1338 img_ken_burns_update_sensitivity( img_struct, FALSE, 0 );
1339
1340 /* Disable all subtitle controls */
1341 img_subtitle_update_sensitivity( img_struct, 0 );
1342
1343 /* Load interface settings or apply default ones */
1344 if( ! img_load_window_settings( img_struct ) )
1345 img_set_window_default_settings( img_struct );
1346
1347 /* Update preview frame rate */
1348 {
1349 gint index =
1350 ( img_struct->preview_fps - PREVIEW_FPS_MIN ) / PREVIEW_FPS_STEP;
1351 gtk_check_menu_item_set_active(
1352 GTK_CHECK_MENU_ITEM( tmp_checks[index] ), TRUE );
1353 }
1354
1355 return img_struct;
1356 }
1357
img_slide_cut(GtkMenuItem * item,img_window_struct * img)1358 static void img_slide_cut(GtkMenuItem* item, img_window_struct *img)
1359 {
1360 img_clipboard_cut_copy_operation(img, IMG_CLIPBOARD_CUT);
1361 }
1362
img_slide_copy(GtkMenuItem * item,img_window_struct * img)1363 static void img_slide_copy(GtkMenuItem* item, img_window_struct *img)
1364 {
1365 img_clipboard_cut_copy_operation(img, IMG_CLIPBOARD_COPY);
1366 }
1367
img_slide_paste(GtkMenuItem * item,img_window_struct * img)1368 static void img_slide_paste(GtkMenuItem* item, img_window_struct *img)
1369 {
1370 GtkClipboard *clipboard;
1371 GtkSelectionData *selection;
1372 GList *where_to_paste = NULL, *node;
1373 GtkTreeModel *model;
1374 GtkTreeIter iter, position_iter;
1375 gchar *total_slides = NULL;
1376 GdkPixbuf *thumb, *trans;
1377 gboolean has_sub;
1378 slide_struct *pasted_slide, *info_slide;
1379 gint pos;
1380 GtkTreeRowReference *position_rawref;
1381 GList *rowref_list = NULL;
1382 GtkTreePath *path, *position_path;
1383
1384
1385 clipboard = gtk_clipboard_get(IMG_CLIPBOARD);
1386 selection = gtk_clipboard_wait_for_contents(clipboard, IMG_INFO_LIST);
1387
1388 if (selection == NULL)
1389 {
1390 img_message (img, FALSE, "Paste: selection is NULL\n");
1391 return;
1392 }
1393
1394 model = GTK_TREE_MODEL(img->thumbnail_model);
1395 where_to_paste = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(img->active_icon));
1396 if (where_to_paste == NULL) /*no icon selected */
1397 return;
1398 position_rawref = gtk_tree_row_reference_new(model, where_to_paste->data);
1399
1400 /* Build a list selected of icons to move */
1401 node = img->selected_paths;
1402 while (node)
1403 {
1404 rowref_list = g_list_append(rowref_list, gtk_tree_row_reference_new(model, node->data));
1405 node = node->next;
1406 }
1407
1408 if (img->clipboard_mode == IMG_CLIPBOARD_CUT)
1409 {
1410 /* move the icons */
1411 node = rowref_list;
1412 while (node)
1413 {
1414 path = gtk_tree_row_reference_get_path(node->data);
1415 if (path)
1416 {
1417 if (gtk_tree_model_get_iter(model, &iter, path))
1418 {
1419 position_path = gtk_tree_row_reference_get_path(position_rawref);
1420 /* position_path can not be NULL as we only move, without delete */
1421 assert (position_path != NULL);
1422 gtk_tree_model_get_iter (model, &position_iter, position_path);
1423 gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &position_iter);
1424 gtk_tree_path_free(position_path);
1425 }
1426 gtk_tree_path_free(path);
1427 }
1428 node = node->next;
1429 }
1430 }
1431 else /* clipboard copy */
1432 {
1433 node = rowref_list;
1434 while (node)
1435 {
1436 path = gtk_tree_row_reference_get_path(node->data);
1437 if (path)
1438 {
1439 if (gtk_tree_model_get_iter(model, &iter, path))
1440 {
1441 /* Get slide and some additional data */
1442 gtk_tree_model_get_iter(model, &iter, path);
1443 gtk_tree_model_get(model, &iter, 0, &thumb,
1444 1, &info_slide,
1445 2, &trans,
1446 3, &has_sub,
1447 -1);
1448 if( thumb )
1449 g_object_unref( G_OBJECT( thumb ) );
1450 if( trans )
1451 g_object_unref( G_OBJECT( trans ) );
1452
1453 /* Create new slide that is exact copy of rpevious one */
1454 pasted_slide = g_slice_copy( sizeof( slide_struct ), info_slide );
1455
1456 if (pasted_slide)
1457 {
1458 /* Fill fields with fresh strings, since g_slice_copy cannot do
1459 * that for us. */
1460 pasted_slide->o_filename = g_strdup(info_slide->o_filename);
1461 pasted_slide->r_filename = g_strdup(info_slide->r_filename);
1462 pasted_slide->original_filename = g_strdup(info_slide->original_filename);
1463 pasted_slide->resolution = g_strdup(info_slide->resolution);
1464 pasted_slide->type = g_strdup(info_slide->type);
1465 pasted_slide->path = g_strdup(info_slide->path);
1466
1467 /* Stop Points also need to copied by hand. */
1468 if (info_slide->no_points)
1469 {
1470 GList *dummy_pnt = info_slide->points;
1471 ImgStopPoint *point;
1472
1473 pasted_slide->points = NULL;
1474 while (dummy_pnt)
1475 {
1476 point = g_slice_copy( sizeof( ImgStopPoint ),
1477 dummy_pnt->data );
1478 pasted_slide->points = g_list_append(pasted_slide->points, point);
1479 dummy_pnt = dummy_pnt->next;
1480 }
1481 }
1482
1483 /* Text should be duplicated if present. Font descripštion
1484 * should also be copied!! */
1485 if (info_slide->subtitle)
1486 pasted_slide->subtitle = g_strdup(info_slide->subtitle);
1487 pasted_slide->font_desc =
1488 pango_font_description_copy( info_slide->font_desc );
1489
1490 position_path = gtk_tree_row_reference_get_path(position_rawref);
1491 /* position_path can not be NULL as we only copy, without delete */
1492 assert (position_path != NULL);
1493 pos = gtk_tree_path_get_indices(position_path)[0]+1;
1494 gtk_tree_path_free(position_path);
1495
1496 gtk_list_store_insert_with_values(
1497 GTK_LIST_STORE( model ), &iter, pos,
1498 0, thumb,
1499 1, pasted_slide,
1500 2, trans,
1501 3, has_sub,
1502 -1 );
1503 /* Let's update the total number of slides and the label in toolbar */
1504 img->slides_nr++;
1505 }
1506 }
1507 gtk_tree_path_free(path);
1508
1509 }
1510 node = node->next;
1511
1512 }
1513 }
1514
1515 /* Free rowref_list */
1516 g_list_foreach(rowref_list, (GFunc) gtk_tree_row_reference_free, NULL);
1517 g_list_free(rowref_list);
1518 gtk_tree_row_reference_free(position_rawref);
1519
1520 /* Free the GList containing the paths of the selected slides */
1521 if (img->selected_paths)
1522 {
1523 g_list_foreach (img->selected_paths, (GFunc)gtk_tree_path_free, NULL);
1524 g_list_free (img->selected_paths);
1525 img->selected_paths = NULL;
1526 }
1527 /* Free the GList containing the paths where to paste */
1528 g_list_foreach (where_to_paste, (GFunc)gtk_tree_path_free, NULL);
1529 g_list_free (where_to_paste);
1530
1531 /* Update display */
1532 total_slides = g_strdup_printf("%d",img->slides_nr);
1533 gtk_label_set_text(GTK_LABEL(img->total_slide_number_label),total_slides);
1534 g_free(total_slides);
1535
1536 /* Free the GTK selection structure */
1537 gtk_selection_data_free (selection);
1538 }
1539
img_clear_audio_files(GtkButton * button,img_window_struct * img)1540 static void img_clear_audio_files(GtkButton *button, img_window_struct *img)
1541 {
1542 gtk_list_store_clear(GTK_LIST_STORE(img->music_file_liststore));
1543 img_play_stop_selected_file(NULL, img);
1544 gtk_widget_set_sensitive(img->play_audio_button, FALSE);
1545 gtk_widget_set_sensitive(img->remove_audio_button, FALSE);
1546 gtk_label_set_text(GTK_LABEL(img->music_time_data), "");
1547 }
1548
img_expand_button_clicked(GtkButton * button,img_window_struct * img)1549 static void img_expand_button_clicked(GtkButton *button, img_window_struct *img)
1550 {
1551 gint width, height;
1552
1553 gtk_widget_get_size_request(img->scrolled_win, &width, &height);
1554 if (height == 18)
1555 {
1556 gtk_widget_set_size_request(img->scrolled_win, -1, 90);
1557 gtk_widget_set_tooltip_text(img->expand_button, _("Click to shrink the area"));
1558 }
1559 else
1560 {
1561 gtk_widget_set_size_request(img->scrolled_win, -1, 18);
1562 gtk_widget_set_tooltip_text(img->expand_button, _("Click to expand the area"));
1563 }
1564 }
1565
img_sub_textview_focus_in(GtkWidget * widget,GdkEventFocus * event,img_window_struct * img)1566 static gboolean img_sub_textview_focus_in(GtkWidget *widget, GdkEventFocus *event, img_window_struct *img)
1567 {
1568 gtk_widget_remove_accelerator (img->remove_menu, img->accel_group, GDK_Delete, 0);
1569 return FALSE;
1570 }
1571
1572
img_sub_textview_focus_out(GtkWidget * widget,GdkEventFocus * event,img_window_struct * img)1573 static gboolean img_sub_textview_focus_out(GtkWidget *widget, GdkEventFocus *event, img_window_struct *img)
1574 {
1575 gtk_widget_add_accelerator (img->remove_menu,"activate", img->accel_group, GDK_Delete, 0, GTK_ACCEL_VISIBLE);
1576 return FALSE;
1577 }
1578
img_on_drag_audio_data_received(GtkWidget * widget,GdkDragContext * context,int x,int y,GtkSelectionData * data,unsigned int info,unsigned int time,img_window_struct * img)1579 static void img_on_drag_audio_data_received (GtkWidget *widget,GdkDragContext *context,int x,int y,GtkSelectionData *data,unsigned int info,unsigned int time, img_window_struct *img)
1580 {
1581 gchar **audio = NULL;
1582 gchar *filename,*ttime;
1583 GtkWidget *dialog;
1584 gint len = 0;
1585
1586 audio = gtk_selection_data_get_uris(data);
1587 if (audio == NULL)
1588 {
1589 dialog = gtk_message_dialog_new(GTK_WINDOW(img->imagination_window),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Sorry, I could not perform the operation!"));
1590 gtk_window_set_title(GTK_WINDOW(dialog),"Imagination");
1591 gtk_dialog_run (GTK_DIALOG (dialog));
1592 gtk_widget_destroy (GTK_WIDGET (dialog));
1593 gtk_drag_finish(context,FALSE,FALSE,time);
1594 return;
1595 }
1596 gtk_drag_finish (context,TRUE,FALSE,time);
1597 while(audio[len])
1598 {
1599 filename = g_filename_from_uri (audio[len],NULL,NULL);
1600 img_add_audio_files(filename,img);
1601 g_free(filename);
1602 len++;
1603 }
1604 ttime = img_convert_seconds_to_time(img->total_music_secs);
1605 gtk_label_set_text(GTK_LABEL(img->music_time_data), ttime);
1606 g_free(ttime);
1607 g_strfreev (audio);
1608 }
1609
img_activate_remove_button_music_liststore(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter,img_window_struct * img)1610 static void img_activate_remove_button_music_liststore(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, img_window_struct *img)
1611 {
1612 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(img->music_file_liststore), iter) == TRUE)
1613 {
1614 gtk_widget_set_sensitive ( img->remove_audio_button, TRUE);
1615 gtk_widget_set_sensitive ( img->play_audio_button, TRUE);
1616 }
1617 }
1618
img_quit_menu(GtkMenuItem * menuitem,img_window_struct * img)1619 static void img_quit_menu(GtkMenuItem *menuitem, img_window_struct *img)
1620 {
1621 if( ! img_quit_application( NULL, NULL, img ) )
1622 gtk_main_quit();
1623 }
1624
img_iconview_selection_changed(GtkIconView * iconview,img_window_struct * img)1625 void img_iconview_selection_changed(GtkIconView *iconview, img_window_struct *img)
1626 {
1627 GtkTreeModel *model;
1628 GtkTreeIter iter;
1629 GtkTreePath *path = NULL;
1630 gint dummy, nr_selected = 0;
1631 GList *selected = NULL;
1632 gchar *slide_info_msg = NULL, *selected_slide_nr = NULL;
1633 slide_struct *info_slide;
1634
1635 if (img->preview_is_running || img->export_is_running)
1636 return;
1637
1638 model = gtk_icon_view_get_model(iconview);
1639 gtk_icon_view_get_cursor(iconview,&path,NULL);
1640
1641 selected = gtk_icon_view_get_selected_items(iconview);
1642 nr_selected = g_list_length(selected);
1643 img_set_total_slideshow_duration(img);
1644
1645 if (selected == NULL)
1646 {
1647 img_set_statusbar_message(img,nr_selected);
1648 if( img->current_image )
1649 {
1650 cairo_surface_destroy( img->current_image );
1651 img->current_image = NULL;
1652 }
1653 img->current_slide = NULL;
1654 gtk_widget_queue_draw( img->image_area );
1655
1656 /* Disable slide settings */
1657 img_disable_videotab(img);
1658
1659 if (img->slides_nr == 0)
1660 gtk_label_set_text(GTK_LABEL (img->total_time_data),"");
1661
1662 return;
1663 }
1664
1665 gtk_widget_set_sensitive(img->trans_duration, TRUE);
1666 gtk_widget_set_sensitive(img->duration, TRUE);
1667 gtk_widget_set_sensitive(img->transition_type, TRUE);
1668 gtk_widget_set_sensitive(img->random_button, TRUE);
1669
1670 dummy = gtk_tree_path_get_indices(selected->data)[0]+1;
1671 selected_slide_nr = g_strdup_printf("%d",dummy);
1672 gtk_entry_set_text(GTK_ENTRY(img->slide_number_entry),selected_slide_nr);
1673 g_free(selected_slide_nr);
1674
1675 gtk_tree_model_get_iter(model,&iter,selected->data);
1676 g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
1677 g_list_free (selected);
1678 gtk_tree_model_get(model,&iter,1,&info_slide,-1);
1679 img->current_slide = info_slide;
1680
1681 /* Set the transition type */
1682 model = gtk_combo_box_get_model(GTK_COMBO_BOX(img->transition_type));
1683
1684 /* Block "changed" signal from model to avoid rewriting the same value back into current slide. */
1685 g_signal_handlers_block_by_func((gpointer)img->transition_type, (gpointer)img_combo_box_transition_type_changed, img);
1686 {
1687 GtkTreeIter iter;
1688 GtkTreeModel *model;
1689
1690 model = gtk_combo_box_get_model( GTK_COMBO_BOX( img->transition_type ) );
1691 gtk_tree_model_get_iter_from_string( model, &iter, info_slide->path );
1692 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(img->transition_type), &iter );
1693 }
1694 g_signal_handlers_unblock_by_func((gpointer)img->transition_type, (gpointer)img_combo_box_transition_type_changed, img);
1695
1696 /* Moved this piece of code below the setting the transition, since we
1697 * get false negatives in certain situations (eg.: if the previously
1698 * selected transition doesn't have transition renderer set): */
1699 if (gtk_combo_box_get_active(GTK_COMBO_BOX(img->transition_type)) == 0)
1700 gtk_widget_set_sensitive(img->trans_duration,FALSE);
1701 else
1702 gtk_widget_set_sensitive(img->trans_duration,TRUE);
1703
1704 /* Set the transition speed */
1705 if (info_slide->speed == FAST)
1706 dummy = 0;
1707 else if (info_slide->speed == NORMAL)
1708 dummy = 1;
1709 else
1710 dummy = 2;
1711 g_signal_handlers_block_by_func((gpointer)img->duration, (gpointer)img_combo_box_speed_changed, img);
1712 gtk_combo_box_set_active(GTK_COMBO_BOX(img->trans_duration),dummy);
1713 g_signal_handlers_block_by_func((gpointer)img->duration, (gpointer)img_combo_box_speed_changed, img);
1714
1715 /* Set the transition duration */
1716 g_signal_handlers_block_by_func((gpointer)img->duration, (gpointer)img_spinbutton_value_changed, img);
1717 gtk_spin_button_set_value(GTK_SPIN_BUTTON(img->duration), info_slide->duration);
1718 g_signal_handlers_unblock_by_func((gpointer)img->duration, (gpointer)img_spinbutton_value_changed, img);
1719
1720 /* Update Ken Burns display */
1721 img_update_stop_display( img, TRUE );
1722
1723 /* Update subtitle widgets */
1724 img_update_subtitles_widgets( img );
1725
1726 img->project_is_modified = TRUE;
1727
1728 if (nr_selected > 1)
1729 {
1730 img_set_statusbar_message(img,nr_selected);
1731 img_ken_burns_update_sensitivity( img, FALSE, 0 );
1732 img_subtitle_update_sensitivity( img, 2 );
1733 }
1734 else
1735 {
1736 if (FALSE == info_slide->load_ok)
1737 {
1738 slide_info_msg = g_strdup_printf(_("File '%s' not found"), info_slide->original_filename);
1739 gtk_statusbar_push(GTK_STATUSBAR (img->statusbar), img->context_id, slide_info_msg);
1740 g_free (slide_info_msg);
1741 img_disable_videotab(img);
1742 }
1743 else
1744 {
1745 if (info_slide->o_filename != NULL)
1746 {
1747 slide_info_msg = g_strdup_printf("%s %s: %s %s: %s",info_slide->o_filename, _("Resolution"), info_slide->resolution, _("Type"), info_slide->type);
1748 gtk_statusbar_push(GTK_STATUSBAR (img->statusbar), img->context_id, slide_info_msg);
1749 g_free(slide_info_msg);
1750 }
1751 img_ken_burns_update_sensitivity( img, TRUE, info_slide->no_points );
1752 img_subtitle_update_sensitivity( img, 1 );
1753 }
1754 }
1755
1756 if( img->current_image )
1757 {
1758 cairo_surface_destroy( img->current_image );
1759 img->current_image = NULL;
1760 }
1761
1762 /* This is not needed when in overview mode, since we're not displaying any
1763 * large image preview. */
1764 if( img->mode == 0 )
1765 {
1766 if( ! info_slide->r_filename )
1767 {
1768 img_scale_gradient( info_slide->gradient,
1769 info_slide->g_start_point,
1770 info_slide->g_stop_point,
1771 info_slide->g_start_color,
1772 info_slide->g_stop_color,
1773 img->video_size[0],
1774 img->video_size[1], NULL,
1775 &img->current_image );
1776 }
1777 /* Respect quality settings */
1778 else if( img->low_quality )
1779 img_scale_image( info_slide->r_filename,
1780 (gdouble)img->video_size[0] / img->video_size[1],
1781 0, img->video_size[1], img->distort_images,
1782 img->background_color, NULL, &img->current_image );
1783 else
1784 img_scale_image( info_slide->r_filename,
1785 (gdouble)img->video_size[0] / img->video_size[1],
1786 0, 0, img->distort_images,
1787 img->background_color, NULL, &img->current_image );
1788 }
1789 }
1790
img_combo_box_transition_type_changed(GtkComboBox * combo,img_window_struct * img)1791 static void img_combo_box_transition_type_changed (GtkComboBox *combo, img_window_struct *img)
1792 {
1793 GList *selected,
1794 *bak;
1795 GtkTreeIter iter;
1796 GtkTreeModel *model;
1797 gpointer address;
1798 slide_struct *info_slide;
1799 gint transition_id;
1800 GtkTreePath *p;
1801 gchar *path;
1802 GdkPixbuf *pix;
1803
1804 /* Check if anything is selected and return if nothing is */
1805 selected = gtk_icon_view_get_selected_items(
1806 GTK_ICON_VIEW( img->active_icon ) );
1807 if( selected == NULL )
1808 return;
1809
1810 /* Get information about selected transition */
1811 model = gtk_combo_box_get_model( combo );
1812 gtk_combo_box_get_active_iter( combo, &iter );
1813 gtk_tree_model_get( model, &iter, 0, &pix,
1814 2, &address,
1815 3, &transition_id,
1816 -1 );
1817
1818 /* If user applied None transition, make duration combo insensitive */
1819 if( transition_id == -1 )
1820 gtk_widget_set_sensitive( img->trans_duration, FALSE );
1821 else
1822 gtk_widget_set_sensitive( img->trans_duration, TRUE );
1823
1824 /* Get string representation of the path, which will be
1825 * saved inside slide */
1826 p = gtk_tree_model_get_path( model, &iter );
1827 path = gtk_tree_path_to_string( p );
1828 gtk_tree_path_free( p );
1829
1830 /* Update all selected slides */
1831 model = GTK_TREE_MODEL( img->thumbnail_model );
1832 bak = selected;
1833 while (selected)
1834 {
1835 gtk_tree_model_get_iter( model, &iter, selected->data );
1836 gtk_tree_model_get( model, &iter, 1, &info_slide, -1 );
1837 gtk_list_store_set( GTK_LIST_STORE( model ), &iter, 2, pix, -1 );
1838 info_slide->render = (ImgRender)address;
1839 info_slide->transition_id = transition_id;
1840 g_free( info_slide->path );
1841 info_slide->path = g_strdup( path );
1842
1843 /* If this is first slide, we need to copy transition
1844 * to the last pseudo-slide too. */
1845 if( gtk_tree_path_get_indices( selected->data )[0] == 0 )
1846 img->final_transition.render = (ImgRender)address;
1847
1848 selected = selected->next;
1849 }
1850 g_free( path );
1851 if( pix )
1852 g_object_unref( G_OBJECT( pix ) );
1853 img->project_is_modified = TRUE;
1854 img_report_slides_transitions( img );
1855 img_set_total_slideshow_duration( img );
1856 g_list_foreach( bak, (GFunc)gtk_tree_path_free, NULL );
1857 g_list_free( bak );
1858 }
1859
img_random_button_clicked(GtkButton * button,img_window_struct * img)1860 static void img_random_button_clicked(GtkButton *button, img_window_struct *img)
1861 {
1862 GList *selected,
1863 *bak;
1864 GtkTreeIter iter;
1865 GtkTreeModel *model;
1866 slide_struct *info_slide;
1867 GdkPixbuf *pixbuf;
1868
1869 model = GTK_TREE_MODEL( img->thumbnail_model );
1870 selected = gtk_icon_view_get_selected_items(GTK_ICON_VIEW (img->active_icon));
1871 if (selected == NULL)
1872 return;
1873
1874 /* Avoiding GList memory leak. */
1875 bak = selected;
1876 while (selected)
1877 {
1878 gtk_tree_model_get_iter(model, &iter,selected->data);
1879 gtk_tree_model_get(model, &iter,1,&info_slide,-1);
1880 pixbuf = img_set_random_transition(img, info_slide);
1881 gtk_list_store_set( GTK_LIST_STORE( model ), &iter, 2, pixbuf, -1 );
1882 if( pixbuf )
1883 g_object_unref( G_OBJECT( pixbuf ) );
1884
1885 /* If this is first slide, copy transition to last
1886 * pseudo-slide */
1887 if( gtk_tree_path_get_indices( selected->data )[0] == 0 )
1888 img->final_transition.render = info_slide->render;
1889
1890 selected = selected->next;
1891 }
1892 img->project_is_modified = TRUE;
1893 g_list_foreach (bak, (GFunc)gtk_tree_path_free, NULL);
1894 g_list_free(bak);
1895
1896 /* This fixes enable/disable issue */
1897 img_iconview_selection_changed(GTK_ICON_VIEW(img->active_icon), img );
1898 }
1899
1900 static GdkPixbuf *
img_set_random_transition(img_window_struct * img,slide_struct * info_slide)1901 img_set_random_transition( img_window_struct *img,
1902 slide_struct *info_slide )
1903 {
1904 gint nr;
1905 gint r1, r2;
1906 gpointer address;
1907 gint transition_id;
1908 GtkTreeModel *model;
1909 GtkTreeIter iter;
1910 gchar path[10];
1911 GdkPixbuf *pix;
1912
1913 /* Get tree store that holds transitions */
1914 model = gtk_combo_box_get_model( GTK_COMBO_BOX( img->transition_type ) );
1915
1916 /* Get number of top-levels (categories) and select one */
1917 nr = gtk_tree_model_iter_n_children( model, NULL );
1918
1919 /* Fix crash if no modules are loaded */
1920 if( nr < 2 )
1921 return( NULL );
1922
1923 r1 = g_random_int_range( 1, nr );
1924 g_snprintf( path, sizeof( path ), "%d", r1 );
1925 gtk_tree_model_get_iter_from_string( model, &iter, path );
1926
1927 /* Get number of transitions in selected category and select one */
1928 nr = gtk_tree_model_iter_n_children( model, &iter );
1929 r2 = g_random_int_range( 0, nr );
1930 g_snprintf( path, sizeof( path ), "%d:%d", r1, r2 );
1931 gtk_tree_model_get_iter_from_string( model, &iter, path );
1932
1933 gtk_tree_model_get( model, &iter, 0, &pix, 2, &address, 3, &transition_id, -1 );
1934 info_slide->transition_id = transition_id;
1935 info_slide->render = (ImgRender)address;
1936
1937 /* Prevent leak here */
1938 if( info_slide->path )
1939 g_free( info_slide->path );
1940 info_slide->path = g_strdup( path );
1941
1942 /* Select proper iter in transition model */
1943 g_signal_handlers_block_by_func((gpointer)img->transition_type, (gpointer)img_combo_box_transition_type_changed, img);
1944 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(img->transition_type), &iter);
1945 /* Update the slide dialog report in real time */
1946 img_report_slides_transitions(img);
1947 g_signal_handlers_unblock_by_func((gpointer)img->transition_type, (gpointer)img_combo_box_transition_type_changed, img);
1948
1949 return( pix );
1950 }
1951
img_combo_box_speed_changed(GtkComboBox * combo,img_window_struct * img)1952 static void img_combo_box_speed_changed (GtkComboBox *combo, img_window_struct *img)
1953 {
1954 gint speed;
1955 gdouble duration;
1956 GList *selected, *bak;
1957 GtkTreeIter iter;
1958 GtkTreeModel *model;
1959 slide_struct *info_slide;
1960
1961 model = GTK_TREE_MODEL( img->thumbnail_model );
1962 selected = gtk_icon_view_get_selected_items(GTK_ICON_VIEW (img->active_icon));
1963 if (selected == NULL)
1964 return;
1965
1966 speed = gtk_combo_box_get_active(combo);
1967
1968 if (speed == 0)
1969 duration = FAST;
1970 else if (speed == 1)
1971 duration = NORMAL;
1972 else
1973 duration = SLOW;
1974
1975 /* Avoid memory leak */
1976 bak = selected;
1977 while (selected)
1978 {
1979 gtk_tree_model_get_iter(model, &iter,selected->data);
1980 gtk_tree_model_get(model, &iter,1,&info_slide,-1);
1981 info_slide->speed = duration;
1982
1983 /* If we're modifying fisr slide, we need to modify
1984 * last pseudo-slide too. */
1985 if( gtk_tree_path_get_indices( selected->data )[0] == 0 )
1986 img->final_transition.speed = duration;
1987
1988 selected = selected->next;
1989 }
1990 img_set_total_slideshow_duration(img);
1991
1992 g_list_foreach (bak, (GFunc)gtk_tree_path_free, NULL);
1993 g_list_free(bak);
1994 }
1995
img_spinbutton_value_changed(GtkSpinButton * spinbutton,img_window_struct * img)1996 static void img_spinbutton_value_changed (GtkSpinButton *spinbutton, img_window_struct *img)
1997 {
1998 gint duration = 0;
1999 GList *selected, *bak;
2000 GtkTreeIter iter;
2001 GtkTreeModel *model;
2002 slide_struct *info_slide;
2003
2004 model = GTK_TREE_MODEL( img->thumbnail_model );
2005 selected = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(img->active_icon));
2006 if (selected == NULL)
2007 return;
2008
2009 duration = gtk_spin_button_get_value_as_int(spinbutton);
2010
2011 bak = selected;
2012 while (selected)
2013 {
2014 gtk_tree_model_get_iter(model, &iter,selected->data);
2015 gtk_tree_model_get(model, &iter,1,&info_slide,-1);
2016 img_set_slide_still_info( info_slide, duration, img );
2017 selected = selected->next;
2018 }
2019
2020 g_list_foreach (bak, (GFunc)gtk_tree_path_free, NULL);
2021 g_list_free(bak);
2022
2023 /* Sync timings */
2024 img_sync_timings( img->current_slide, img );
2025 }
2026
img_select_all_thumbnails(GtkMenuItem * item,img_window_struct * img)2027 static void img_select_all_thumbnails(GtkMenuItem *item, img_window_struct *img)
2028 {
2029 gtk_icon_view_select_all(GTK_ICON_VIEW (img->active_icon));
2030 }
2031
img_unselect_all_thumbnails(GtkMenuItem * item,img_window_struct * img)2032 static void img_unselect_all_thumbnails(GtkMenuItem *item, img_window_struct *img)
2033 {
2034 gtk_icon_view_unselect_all(GTK_ICON_VIEW (img->active_icon));
2035 }
2036
img_goto_line_entry_activate(GtkWidget * entry,img_window_struct * img)2037 static void img_goto_line_entry_activate(GtkWidget *entry, img_window_struct *img)
2038 {
2039 gint slide;
2040 GtkTreePath *path;
2041
2042 slide = strtol(gtk_entry_get_text(GTK_ENTRY(img->slide_number_entry)), NULL, 10);
2043 if (slide > 0 && slide <= img->slides_nr)
2044 {
2045 gtk_icon_view_unselect_all(GTK_ICON_VIEW (img->active_icon));
2046 path = gtk_tree_path_new_from_indices(slide-1,-1);
2047 gtk_icon_view_set_cursor (GTK_ICON_VIEW (img->active_icon), path, NULL, FALSE);
2048 gtk_icon_view_select_path (GTK_ICON_VIEW (img->active_icon), path);
2049 gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (img->active_icon), path, FALSE, 0, 0);
2050 gtk_tree_path_free (path);
2051 }
2052 }
2053
img_sort_none_before_other(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)2054 static gint img_sort_none_before_other(GtkTreeModel *model,GtkTreeIter *a,GtkTreeIter *b,gpointer data)
2055 {
2056 gchar *name1, *name2;
2057 gint i;
2058
2059 gtk_tree_model_get(model, a, 1, &name1, -1);
2060 gtk_tree_model_get(model, b, 1, &name2, -1);
2061
2062 if (strcmp(name1,_("None")) == 0)
2063 i = -1;
2064 else if (strcmp(name2,_("None")) == 0)
2065 i = 1;
2066 else
2067 i = (g_strcmp0 (name1,name2));
2068
2069 g_free(name1);
2070 g_free(name2);
2071 return i;
2072 }
2073
img_check_numeric_entry(GtkEditable * entry,gchar * text,gint lenght,gint * position,gpointer data)2074 static void img_check_numeric_entry (GtkEditable *entry, gchar *text, gint lenght, gint *position, gpointer data)
2075 {
2076 if(*text < '0' || *text > '9')
2077 g_signal_stop_emission_by_name( (gpointer)entry, "insert-text" );
2078 }
2079
2080 /*
2081 * img_iconview_selection_button_press:
2082 *
2083 * This is a temporary hack that should do the job of unselecting slides if
2084 * single slide should be selected after select all.
2085 */
2086 static gboolean
img_iconview_selection_button_press(GtkWidget * widget,GdkEventButton * button,img_window_struct * img)2087 img_iconview_selection_button_press( GtkWidget *widget,
2088 GdkEventButton *button,
2089 img_window_struct *img )
2090 {
2091 if( ( button->button == 1 ) &&
2092 ! ( button->state & ( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) )
2093 gtk_icon_view_unselect_all( GTK_ICON_VIEW( widget ) );
2094
2095 return( FALSE );
2096 }
2097
2098 static gboolean
img_scroll_thumb(GtkWidget * widget,GdkEventScroll * scroll,img_window_struct * img)2099 img_scroll_thumb( GtkWidget *widget,
2100 GdkEventScroll *scroll,
2101 img_window_struct *img )
2102 {
2103 GtkAdjustment *adj;
2104 gdouble page, step, upper, value;
2105 gint dir = 1;
2106
2107 if( scroll->direction == GDK_SCROLL_UP ||
2108 scroll->direction == GDK_SCROLL_LEFT )
2109 {
2110 dir = - 1;
2111 }
2112
2113 adj = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW( widget ) );
2114
2115 page = gtk_adjustment_get_page_size( adj );
2116 step = gtk_adjustment_get_step_increment( adj );
2117 upper = gtk_adjustment_get_upper( adj );
2118 value = gtk_adjustment_get_value( adj );
2119
2120 gtk_adjustment_set_value( adj, CLAMP( value + step * dir, 0, upper - page ) );
2121 return( TRUE );
2122 }
2123
img_show_uri(GtkMenuItem * menuitem,img_window_struct * img)2124 static void img_show_uri(GtkMenuItem *menuitem, img_window_struct *img)
2125 {
2126 gchar *file = NULL;
2127 gchar *lang = NULL;
2128
2129 lang = g_strndup(g_getenv("LANG"),2);
2130 file = g_strconcat("file://",DATADIR,"/doc/",PACKAGE,"/html/",lang,"/index.html",NULL);
2131 g_free(lang);
2132 img_message (img, FALSE, "%s\n", file);
2133
2134 /* If help is not localized yet, show default language (english) */
2135 if ( !gtk_show_uri(NULL,file, GDK_CURRENT_TIME, NULL))
2136 {
2137 g_free( file );
2138 file = g_strconcat("file://",DATADIR,"/doc/",PACKAGE,"/html/en/index.html",NULL);
2139 gtk_show_uri(NULL,file, GDK_CURRENT_TIME, NULL);
2140 }
2141 g_free(file);
2142 }
2143
2144 void
img_queue_subtitle_update(GtkTextBuffer * buffer,img_window_struct * img)2145 img_queue_subtitle_update( GtkTextBuffer *buffer,
2146 img_window_struct *img )
2147 {
2148 /* This queue enables us to avid sensless copying and redrawing when typing
2149 * relatively fast (limit is cca. 3 keypresses per second) */
2150 if( img->subtitle_update_id )
2151 g_source_remove( img->subtitle_update_id );
2152
2153 img->subtitle_update_id =
2154 g_timeout_add( 300, (GSourceFunc)img_subtitle_update, img );
2155 }
2156
2157 static GtkWidget *
img_create_subtitle_animation_combo(void)2158 img_create_subtitle_animation_combo( void )
2159 {
2160 GtkWidget *combo;
2161 GtkListStore *store;
2162 TextAnimation *animations;
2163 gint no_anims;
2164 register gint i;
2165 GtkTreeIter iter;
2166 GtkCellRenderer *cell;
2167
2168 store = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT );
2169
2170 no_anims = img_get_text_animation_list( &animations );
2171 for( i = 0; i < no_anims; i++ )
2172 {
2173 gtk_list_store_append( store, &iter );
2174 gtk_list_store_set( store, &iter, 0, animations[i].name,
2175 1, animations[i].func,
2176 2, animations[i].id,
2177 -1 );
2178 }
2179 img_free_text_animation_list( no_anims, animations );
2180
2181 combo = gtk_combo_box_new_with_model( GTK_TREE_MODEL( store ) );
2182 g_object_unref( G_OBJECT( store ) );
2183
2184 cell = gtk_cell_renderer_text_new();
2185 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( combo ), cell, TRUE );
2186 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT( combo ), cell, "text", 0 );
2187
2188 return( combo );
2189 }
2190
2191 static gboolean
img_subtitle_update(img_window_struct * img)2192 img_subtitle_update( img_window_struct *img )
2193 {
2194 gboolean has_subtitle;
2195 GtkTreeIter iter;
2196 GList *list;
2197
2198
2199 /* Get text from buffer and store it inside slide */
2200 if( img->current_slide->subtitle )
2201 {
2202 g_free( img->current_slide->subtitle );
2203 img->current_slide->subtitle = NULL;
2204 }
2205
2206 has_subtitle =
2207 1 < gtk_text_buffer_get_char_count( img->slide_text_buffer );
2208 if( has_subtitle )
2209 g_object_get( G_OBJECT( img->slide_text_buffer ), "text",
2210 &img->current_slide->subtitle, NULL );
2211
2212 list = gtk_icon_view_get_selected_items(
2213 GTK_ICON_VIEW( img->active_icon ) );
2214 gtk_tree_model_get_iter( GTK_TREE_MODEL( img->thumbnail_model ),
2215 &iter, list->data );
2216 g_list_foreach( list, (GFunc)gtk_tree_path_free, NULL );
2217 g_list_free( list );
2218 gtk_list_store_set( GTK_LIST_STORE( img->thumbnail_model ), &iter,
2219 3, has_subtitle, -1 );
2220
2221 /* Queue redraw */
2222 gtk_widget_queue_draw( img->image_area );
2223
2224 /* Set source id to zero and remove itself from main context */
2225 img->subtitle_update_id = 0;
2226
2227 return( FALSE );
2228 }
2229
2230 void
img_text_font_set(GtkFontButton * button,img_window_struct * img)2231 img_text_font_set( GtkFontButton *button,
2232 img_window_struct *img )
2233 {
2234 const gchar *string;
2235
2236 string = gtk_font_button_get_font_name( button );
2237
2238 img_update_sub_properties( img, NULL, -1, -1, -1, -1, string, NULL, NULL );
2239
2240 gtk_widget_queue_draw( img->image_area );
2241 }
2242
2243 void
img_text_anim_set(GtkComboBox * combo,img_window_struct * img)2244 img_text_anim_set( GtkComboBox *combo,
2245 img_window_struct *img )
2246 {
2247 GtkTreeModel *model;
2248 GtkTreeIter iter;
2249 TextAnimationFunc anim;
2250 gint anim_id;
2251
2252 model = gtk_combo_box_get_model( combo );
2253 gtk_combo_box_get_active_iter( combo, &iter );
2254 gtk_tree_model_get( model, &iter, 1, &anim, 2, &anim_id, -1 );
2255
2256 img_update_sub_properties( img, anim, anim_id, -1, -1, -1, NULL, NULL, NULL);
2257
2258 /* Speed should be disabled when None is in effect */
2259 gtk_widget_set_sensitive( img->sub_anim_duration,
2260 (gboolean)gtk_combo_box_get_active( combo ) );
2261
2262 gtk_widget_queue_draw( img->image_area );
2263 }
2264
2265 void
img_font_color_changed(GtkColorButton * button,img_window_struct * img)2266 img_font_color_changed( GtkColorButton *button,
2267 img_window_struct *img )
2268 {
2269 GdkColor color;
2270 guint16 alpha;
2271 gdouble font_color[4];
2272
2273 gtk_color_button_get_color( button, &color );
2274 alpha = gtk_color_button_get_alpha( button );
2275
2276 font_color[0] = (gdouble)color.red / 0xffff;
2277 font_color[1] = (gdouble)color.green / 0xffff;
2278 font_color[2] = (gdouble)color.blue / 0xffff;
2279 font_color[3] = (gdouble)alpha / 0xffff;
2280
2281 img_update_sub_properties( img, NULL, -1, -1, -1, -1, NULL, font_color, NULL );
2282
2283 gtk_widget_queue_draw( img->image_area );
2284 }
2285
2286 void
img_font_bgcolor_changed(GtkColorButton * button,img_window_struct * img)2287 img_font_bgcolor_changed( GtkColorButton *button,
2288 img_window_struct *img )
2289 {
2290 GdkColor color;
2291 guint16 alpha;
2292 gdouble font_bgcolor[4];
2293
2294 gtk_color_button_get_color( button, &color );
2295 alpha = gtk_color_button_get_alpha( button );
2296
2297 font_bgcolor[0] = (gdouble)color.red / 0xffff;
2298 font_bgcolor[1] = (gdouble)color.green / 0xffff;
2299 font_bgcolor[2] = (gdouble)color.blue / 0xffff;
2300 font_bgcolor[3] = (gdouble)alpha / 0xffff;
2301
2302 img_update_sub_properties( img, NULL, -1, -1, -1, -1, NULL, NULL, font_bgcolor);
2303
2304 gtk_widget_queue_draw( img->image_area );
2305 }
2306
2307 void
img_combo_box_anim_speed_changed(GtkSpinButton * spinbutton,img_window_struct * img)2308 img_combo_box_anim_speed_changed( GtkSpinButton *spinbutton,
2309 img_window_struct *img )
2310 {
2311 gint speed;
2312
2313 speed = gtk_spin_button_get_value_as_int(spinbutton);
2314 img_update_sub_properties( img, NULL, -1, speed, -1, -1, NULL, NULL, NULL);
2315 }
2316
2317 void
img_text_pos_changed(ImgTableButton * button,gint item,img_window_struct * img)2318 img_text_pos_changed( ImgTableButton *button,
2319 gint item,
2320 img_window_struct *img )
2321 {
2322 /* NOTE: This can be done because we know how items are packed into table
2323 * button. For safety measures and future expandability, this should be
2324 * converted into switch statement. */
2325 img_update_sub_properties( img, NULL, -1, -1, item, -1, NULL, NULL, NULL);
2326
2327 gtk_widget_queue_draw( img->image_area );
2328 }
2329
2330 void
img_placing_changed(GtkComboBox * combo,img_window_struct * img)2331 img_placing_changed( GtkComboBox *combo,
2332 img_window_struct *img )
2333 {
2334 ImgRelPlacing placing;
2335
2336 if( gtk_combo_box_get_active(combo) == 0 )
2337 placing = IMG_REL_PLACING_EXPORTED_VIDEO;
2338 else
2339 placing = IMG_REL_PLACING_ORIGINAL_IMAGE;
2340
2341 img_update_sub_properties( img, NULL, -1, -1, -1, placing, NULL, NULL, NULL);
2342
2343 gtk_widget_queue_draw( img->image_area );
2344 }
2345
2346 void
img_disable_videotab(img_window_struct * img)2347 img_disable_videotab (img_window_struct *img)
2348 {
2349 gtk_widget_set_sensitive(img->random_button, FALSE);
2350 gtk_widget_set_sensitive(img->transition_type, FALSE);
2351 gtk_widget_set_sensitive(img->duration, FALSE);
2352 gtk_widget_set_sensitive(img->trans_duration, FALSE);
2353
2354 img_ken_burns_update_sensitivity (img, FALSE, 0);
2355 img_subtitle_update_sensitivity (img, 0);
2356 }
2357
2358
2359 void
img_ken_burns_update_sensitivity(img_window_struct * img,gboolean slide_selected,gint no_points)2360 img_ken_burns_update_sensitivity( img_window_struct *img,
2361 gboolean slide_selected,
2362 gint no_points )
2363 {
2364 /* Modes of operation:
2365 * 3 - disable all
2366 * 2 - enable duration, zoom and add
2367 * 1 - disable only navigation
2368 * 0 - enable all
2369 */
2370 gint mode = 3;
2371
2372 if( slide_selected )
2373 {
2374 switch( no_points )
2375 {
2376 case 0:
2377 mode = 2;
2378 break;
2379
2380 case 1:
2381 mode = 1;
2382 break;
2383
2384 default:
2385 mode = 0;
2386 break;
2387 }
2388 }
2389
2390 /* Disable all - this is starting state */
2391 gtk_widget_set_sensitive( img->ken_left, FALSE );
2392 gtk_widget_set_sensitive( img->ken_entry, FALSE );
2393 gtk_widget_set_sensitive( img->ken_right, FALSE );
2394 gtk_widget_set_sensitive( img->ken_duration, FALSE );
2395 gtk_widget_set_sensitive( img->ken_zoom, FALSE );
2396 gtk_widget_set_sensitive( img->ken_add, FALSE );
2397 gtk_widget_set_sensitive( img->ken_update, FALSE );
2398 gtk_widget_set_sensitive( img->ken_remove, FALSE );
2399
2400 /* Enabler */
2401 switch( mode ) /* THIS SWITCH IS IN FALL-THROUGH MODE!! */
2402 {
2403 case 0: /* Enable all */
2404 gtk_widget_set_sensitive( img->ken_left, TRUE );
2405 gtk_widget_set_sensitive( img->ken_entry, TRUE );
2406 gtk_widget_set_sensitive( img->ken_right, TRUE );
2407
2408 case 1: /* Disable navigation only */
2409 gtk_widget_set_sensitive( img->ken_update, TRUE );
2410 gtk_widget_set_sensitive( img->ken_remove, TRUE );
2411
2412 case 2: /* Only adding is enabled */
2413 gtk_widget_set_sensitive( img->ken_add, TRUE );
2414 gtk_widget_set_sensitive( img->ken_zoom, TRUE );
2415 gtk_widget_set_sensitive( img->ken_duration, TRUE );
2416
2417 case 3: /* Disable all */
2418 break;
2419 }
2420 }
2421
2422 void
img_subtitle_update_sensitivity(img_window_struct * img,gint mode)2423 img_subtitle_update_sensitivity( img_window_struct *img,
2424 gint mode )
2425 {
2426 /* Modes:
2427 * 0 - disable all
2428 * 1 - enable all
2429 * 2 - enable all but text field
2430 */
2431
2432 /* Text view is special, since it cannot handle multiple slides */
2433 gtk_widget_set_sensitive( img->sub_textview,
2434 ( mode == 2 ? FALSE : (gboolean)mode ) );
2435
2436 /* Let's delete the textbuffer when no slide is selected */
2437 if( mode == 0 || mode == 2 )
2438 {
2439 g_signal_handlers_block_by_func( (gpointer)img->slide_text_buffer,
2440 (gpointer)img_queue_subtitle_update,
2441 img );
2442 g_object_set( G_OBJECT( img->slide_text_buffer ), "text", "", NULL );
2443 g_signal_handlers_unblock_by_func( (gpointer)img->slide_text_buffer,
2444 (gpointer)img_queue_subtitle_update,
2445 img );
2446 }
2447
2448 /* Animation duration is also special, since it shoudl be disabled when None
2449 * animation is selected. */
2450 if( gtk_combo_box_get_active( GTK_COMBO_BOX( img->sub_anim ) ) && mode )
2451 gtk_widget_set_sensitive( img->sub_anim_duration, TRUE );
2452 else
2453 gtk_widget_set_sensitive( img->sub_anim_duration, FALSE );
2454
2455 /* All other controls are simple */
2456 gtk_widget_set_sensitive( img->sub_font, (gboolean)mode );
2457 gtk_widget_set_sensitive( img->sub_color, (gboolean)mode );
2458 gtk_widget_set_sensitive( img->sub_bgcolor, (gboolean)mode );
2459 gtk_widget_set_sensitive( img->sub_anim, (gboolean)mode );
2460 gtk_widget_set_sensitive( img->sub_placing, (gboolean)mode );
2461 gtk_widget_set_sensitive( img->sub_pos, (gboolean)mode );
2462 }
2463
2464 void
img_update_sub_properties(img_window_struct * img,TextAnimationFunc anim,gint anim_id,gint anim_duration,ImgSubPos position,ImgRelPlacing placing,const gchar * desc,gdouble * color,gdouble * bgcolor)2465 img_update_sub_properties( img_window_struct *img,
2466 TextAnimationFunc anim,
2467 gint anim_id,
2468 gint anim_duration,
2469 ImgSubPos position,
2470 ImgRelPlacing placing,
2471 const gchar *desc,
2472 gdouble *color,
2473 gdouble *bgcolor)
2474 {
2475 GList *selected,
2476 *tmp;
2477 GtkTreeIter iter;
2478 GtkTreeModel *model;
2479
2480 /* Get all selected slides */
2481 selected = gtk_icon_view_get_selected_items(
2482 GTK_ICON_VIEW( img->active_icon ) );
2483 if( ! selected )
2484 return;
2485
2486 model = GTK_TREE_MODEL( img->thumbnail_model );
2487
2488 for( tmp = selected; tmp; tmp = g_list_next( tmp ) )
2489 {
2490 slide_struct *slide;
2491
2492 gtk_tree_model_get_iter( model, &iter, (GtkTreePath *)tmp->data );
2493 gtk_tree_model_get( model, &iter, 1, &slide, -1 );
2494
2495 img_set_slide_text_info( slide, NULL, NULL, NULL,
2496 anim_id, anim_duration, position,
2497 placing, desc, color, bgcolor, img );
2498 }
2499
2500 g_list_foreach( selected, (GFunc)gtk_tree_path_free, NULL );
2501 g_list_free( selected );
2502 }
2503
2504 static void
img_toggle_mode(GtkCheckMenuItem * item,img_window_struct * img)2505 img_toggle_mode( GtkCheckMenuItem *item,
2506 img_window_struct *img )
2507 {
2508 gint mode;
2509 mode = ( gtk_check_menu_item_get_active( item ) ? 0 : 1 );
2510
2511 img_switch_mode( img, mode );
2512 }
2513
2514 void
img_switch_mode(img_window_struct * img,gint mode)2515 img_switch_mode( img_window_struct *img,
2516 gint mode )
2517 {
2518 GtkIconView *from, /* Iconviews for selection synchronization */
2519 *to;
2520 GList *selection, /* Selection to be copied from 'from' to 'to' */
2521 *tmp; /* Iterator */
2522
2523 if( img->mode == mode )
2524 return;
2525
2526 img->mode = mode;
2527
2528 gtk_widget_hide( img->active_icon );
2529 switch( mode )
2530 {
2531 case 0: /* Preview mode */
2532 gtk_widget_hide( img->over_root );
2533 gtk_widget_show( img->prev_root );
2534 gtk_widget_show( img->thum_root );
2535 img->active_icon = img->thumbnail_iconview;
2536 from = GTK_ICON_VIEW( img->over_icon );
2537 break;
2538
2539 case 1: /* Overview mode */
2540 gtk_widget_hide( img->prev_root );
2541 gtk_widget_hide( img->thum_root );
2542 gtk_widget_show( img->over_root );
2543 img->active_icon = img->over_icon;
2544 from = GTK_ICON_VIEW( img->thumbnail_iconview );
2545 break;
2546 }
2547 gtk_widget_show( img->active_icon );
2548 to = GTK_ICON_VIEW( img->active_icon );
2549
2550 /* Synchronize selections */
2551 selection = gtk_icon_view_get_selected_items( from );
2552 if( ! selection )
2553 {
2554 gtk_icon_view_unselect_all( to );
2555 return;
2556 }
2557
2558 g_signal_handlers_block_by_func( from,
2559 img_iconview_selection_changed, img );
2560 g_signal_handlers_block_by_func( to,
2561 img_iconview_selection_changed, img );
2562
2563 gtk_icon_view_unselect_all( to );
2564 for( tmp = g_list_next( selection ); tmp; tmp = g_list_next( tmp ) )
2565 {
2566 GtkTreePath *path = (GtkTreePath *)tmp->data;
2567 gtk_icon_view_select_path( to, path );
2568 gtk_tree_path_free( path );
2569 }
2570
2571 g_signal_handlers_unblock_by_func( from,
2572 img_iconview_selection_changed, img );
2573 g_signal_handlers_unblock_by_func( to,
2574 img_iconview_selection_changed, img );
2575
2576 gtk_icon_view_select_path( to, (GtkTreePath *)selection->data );
2577 gtk_icon_view_set_cursor( to, (GtkTreePath *)selection->data, NULL, FALSE );
2578 gtk_tree_path_free( (GtkTreePath *)selection->data );
2579
2580 g_list_free( selection );
2581 }
2582
img_report_slides_transitions(img_window_struct * img)2583 static void img_report_slides_transitions(img_window_struct *img)
2584 {
2585 static GtkWidget *viewport;
2586 GtkWidget *label;
2587 GHashTable *trans_hash;
2588 GList *values,
2589 *tmp;
2590 GtkTreeModel *model;
2591 GtkTreeIter iter;
2592 gboolean flag;
2593 gint i;
2594
2595 #define GIP( val ) GINT_TO_POINTER( ( val ) )
2596 #define GPI( val ) GPOINTER_TO_INT( ( val ) )
2597
2598 if (img->report_dialog == NULL)
2599 {
2600 GtkWidget *action,
2601 *vbox,
2602 *swindow;
2603
2604 img->report_dialog = gtk_dialog_new_with_buttons(
2605 _("Slides Transitions Report Dialog"),
2606 GTK_WINDOW( img->imagination_window ),
2607 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
2608 GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
2609 NULL );
2610 gtk_container_set_border_width( GTK_CONTAINER( img->report_dialog ),
2611 10 );
2612 gtk_window_set_default_size( GTK_WINDOW( img->report_dialog ),
2613 480, 370 );
2614 gtk_window_set_modal( GTK_WINDOW( img->report_dialog ), FALSE );
2615
2616 action = gtk_dialog_get_action_area( GTK_DIALOG( img->report_dialog ) );
2617 gtk_button_box_set_layout( GTK_BUTTON_BOX( action ),
2618 GTK_BUTTONBOX_SPREAD);
2619 g_signal_connect( G_OBJECT( img->report_dialog ), "delete-event",
2620 G_CALLBACK( gtk_widget_hide_on_delete ), NULL );
2621 g_signal_connect( G_OBJECT( img->report_dialog ), "response",
2622 G_CALLBACK( gtk_widget_hide_on_delete ), NULL );
2623
2624 vbox = gtk_dialog_get_content_area( GTK_DIALOG( img->report_dialog ) );
2625 swindow = gtk_scrolled_window_new( NULL, NULL );
2626 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( swindow ),
2627 GTK_POLICY_AUTOMATIC,
2628 GTK_POLICY_AUTOMATIC);
2629 gtk_box_pack_start( GTK_BOX( vbox ), swindow, TRUE, TRUE, 0 );
2630
2631 viewport = gtk_viewport_new( NULL, NULL );
2632 gtk_viewport_set_shadow_type( GTK_VIEWPORT( viewport ),
2633 GTK_SHADOW_NONE);
2634 gtk_container_add( GTK_CONTAINER( swindow ), viewport );
2635 }
2636
2637 /* Delete previous shown rows */
2638 if( img->vbox_slide_report_rows )
2639 {
2640 gtk_widget_destroy( img->vbox_slide_report_rows );
2641 img->vbox_slide_report_rows = NULL;
2642 }
2643
2644 model = GTK_TREE_MODEL(img->thumbnail_model);
2645 if( gtk_tree_model_get_iter_first( model, &iter ) == 0)
2646 return;
2647
2648 /* Hash table is used only for quick way of accessing transition info.
2649 * Information is stored inside array of 3 gpointers */
2650 trans_hash = g_hash_table_new( g_direct_hash, NULL );
2651
2652 for( flag = TRUE, i = 0;
2653 flag;
2654 flag = gtk_tree_model_iter_next( model, &iter ), i++ )
2655 {
2656 slide_struct *slide;
2657 gpointer *info;
2658
2659 gtk_tree_model_get( model, &iter, 1, &slide, -1 );
2660 if( slide->transition_id < 1 )
2661 continue;
2662
2663 info = g_hash_table_lookup( trans_hash, GIP( slide->transition_id ) );
2664 if( ! info )
2665 {
2666 /* Create new info element */
2667 info = g_slice_alloc0( sizeof( gpointer ) * 3 );
2668 info[0] = GIP( slide->transition_id );
2669 g_hash_table_insert( trans_hash, GIP( slide->transition_id ),
2670 info );
2671 }
2672
2673 /* Increment counter */
2674 info[1] = GIP( GPI( info[1] ) + 1 );
2675
2676 /* Append another element to glist */
2677 info[2] = g_list_append( (GList *)info[2], GIP( i ) );
2678 }
2679
2680 /* Set the vertical box container that was previously
2681 * destroyed so to allow update in real time */
2682 img->vbox_slide_report_rows = gtk_vbox_new( FALSE, 15 );
2683 gtk_container_add( GTK_CONTAINER( viewport ), img->vbox_slide_report_rows );
2684
2685 label = gtk_label_new( _("\n<span weight='bold'>Note:</span>\n\n"
2686 "Slides whose transition is applied only once are "
2687 "not shown here.\n"
2688 "Click on the slide to have Imagination "
2689 "automatically select it." ) );
2690 gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 );
2691 gtk_label_set_use_markup( GTK_LABEL( label ), TRUE );
2692 gtk_box_pack_start( GTK_BOX( img->vbox_slide_report_rows ), label,
2693 FALSE, FALSE, 0);
2694
2695 /* Get information and free hash table */
2696 values = g_hash_table_get_values( trans_hash );
2697 g_hash_table_destroy( trans_hash );
2698
2699 /* Sort values list here */
2700 values = g_list_sort( values, img_sort_report_transitions );
2701
2702 /* Display results */
2703 for( tmp = values; tmp; tmp = g_list_next( tmp ) )
2704 {
2705 gpointer *info = tmp->data;
2706
2707 if( GPI( info[1] ) > 1 )
2708 {
2709 GList *tmp1;
2710 GtkWidget *hbox_rows,
2711 *frame,
2712 *image,
2713 *nr_label;
2714 gchar *filename,
2715 *nr;
2716
2717 hbox_rows = gtk_hbox_new( FALSE, 15 );
2718 gtk_box_pack_start( GTK_BOX( img->vbox_slide_report_rows ),
2719 hbox_rows, FALSE, FALSE, 0 );
2720
2721 frame = gtk_frame_new( NULL );
2722 gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_NONE );
2723 gtk_box_pack_start( GTK_BOX( hbox_rows ), frame, FALSE, FALSE, 0 );
2724
2725 #if PLUGINS_INSTALLED
2726 filename =
2727 g_strdup_printf( "%s/imagination/pixmaps/imagination-%d.png",
2728 DATADIR, GPI( info[0] ) );
2729 #else /* PLUGINS_INSTALLED */
2730 filename =
2731 g_strdup_printf( "./pixmaps/imagination-%d.png",
2732 GPI( info[0] ) );
2733 #endif
2734 image = gtk_image_new_from_file( filename );
2735 g_free( filename );
2736 gtk_container_add( GTK_CONTAINER( frame ), image );
2737
2738 nr = g_strdup_printf( "(%d)", GPI( info[1] ) );
2739 nr_label = gtk_label_new( nr );
2740 gtk_box_pack_start( GTK_BOX( hbox_rows ), nr_label,
2741 FALSE, FALSE, 0 );
2742 g_free( nr );
2743
2744 for( tmp1 = (GList *)info[2]; tmp1; tmp1 = g_list_next( tmp1 ) )
2745 {
2746 GtkWidget *button,
2747 *image;
2748 GdkPixbuf *pixbuf;
2749 GtkTreePath *path;
2750 GtkTreeIter iter;
2751
2752 path = gtk_tree_path_new_from_indices( GPI( tmp1->data ), -1 );
2753 gtk_tree_model_get_iter( model, &iter, path );
2754 gtk_tree_path_free( path );
2755
2756 gtk_tree_model_get( model, &iter, 0, &pixbuf, -1 );
2757
2758 button = gtk_button_new();
2759 g_object_set_data( G_OBJECT( button ), "index", tmp1->data );
2760 g_signal_connect( G_OBJECT( button ), "clicked",
2761 G_CALLBACK( img_select_slide_from_slide_report_dialog ), img );
2762 gtk_box_pack_start( GTK_BOX( hbox_rows ), button,
2763 FALSE, FALSE, 0 );
2764
2765 image = gtk_image_new_from_pixbuf( pixbuf );
2766 g_object_unref( G_OBJECT( pixbuf ) );
2767 gtk_container_add( GTK_CONTAINER( button ), image );
2768 }
2769 }
2770 g_list_free( (GList *)info[2] );
2771 g_slice_free1( sizeof( gpointer ) * 3, info );
2772 }
2773
2774 if( GTK_WIDGET_VISIBLE( img->report_dialog ) )
2775 gtk_widget_show_all( img->report_dialog );
2776
2777 #undef GIP
2778 #undef GPI
2779 }
2780
img_select_slide_from_slide_report_dialog(GtkButton * button,img_window_struct * img)2781 static void img_select_slide_from_slide_report_dialog(GtkButton *button, img_window_struct *img)
2782 {
2783 GtkTreePath *path;
2784 gint slide = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "index"));
2785
2786 gtk_icon_view_unselect_all(GTK_ICON_VIEW (img->active_icon));
2787 path = gtk_tree_path_new_from_indices(slide, -1);
2788 gtk_icon_view_set_cursor (GTK_ICON_VIEW (img->active_icon), path, NULL, FALSE);
2789 gtk_icon_view_select_path (GTK_ICON_VIEW (img->active_icon), path);
2790 gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (img->active_icon), path, FALSE, 0, 0);
2791 gtk_tree_path_free (path);
2792 }
2793
img_show_slides_report_dialog(GtkMenuItem * item,img_window_struct * img)2794 static void img_show_slides_report_dialog(GtkMenuItem *item, img_window_struct *img)
2795 {
2796 img_report_slides_transitions(img);
2797 gtk_widget_show_all(img->report_dialog);
2798 }
2799
2800 static gint
img_sort_report_transitions(gconstpointer a,gconstpointer b)2801 img_sort_report_transitions( gconstpointer a,
2802 gconstpointer b )
2803 {
2804 gint val_a = GPOINTER_TO_INT( ( (gpointer *)a )[1] ),
2805 val_b = GPOINTER_TO_INT( ( (gpointer *)b )[1] );
2806
2807 return( val_a - val_b );
2808 }
2809
2810 static void
img_toggle_frame_rate(GtkCheckMenuItem * item,img_window_struct * img)2811 img_toggle_frame_rate( GtkCheckMenuItem *item,
2812 img_window_struct *img )
2813 {
2814 gpointer tmp;
2815
2816 if( ! gtk_check_menu_item_get_active( item ) )
2817 return;
2818
2819 tmp = g_object_get_data( G_OBJECT( item ), "index" );
2820 img->preview_fps = GPOINTER_TO_INT( tmp );
2821 }
2822