~ubuntu-branches/ubuntu/maverick/imagination/maverick

« back to all changes in this revision

Viewing changes to src/callbacks.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2009-07-07 09:09:38 UTC
  • mfrom: (2.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090707090938-jvaub13ijh53oawy
Tags: 1.5-1ubuntu1
* Merge with debian unstable (LP: #392874), Ubuntu remaining changes:
  - debian/control:
    + Move libav*-unstripped-* packages to Recommends as suggested by
      upstream.
    + Improve long description.
    + Add watch file.
  - debian/copyright: Replace deprecated symbol (C) with ©.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
#include "callbacks.h"
 
22
#include "export.h"
22
23
 
23
24
static void img_file_chooser_add_preview(img_window_struct *);
24
25
static void img_update_preview_file_chooser(GtkFileChooser *,img_window_struct *);
25
 
static gboolean img_on_expose_event(GtkWidget *,GdkEventExpose *,img_window_struct *);
26
26
static gboolean img_transition_timeout(img_window_struct *);
27
27
static gboolean img_sleep_timeout(img_window_struct *);
28
 
static gboolean img_prepare_pixbufs(img_window_struct *);
29
28
static void img_swap_toolbar_images( img_window_struct *, gboolean);
30
29
static void img_clean_after_preview(img_window_struct *);
31
30
static void img_increase_progressbar(img_window_struct *, gint);
32
 
static gboolean img_run_encoder(img_window_struct *);
33
 
 
34
 
/* Export related functions */
35
 
static gboolean img_export_transition(img_window_struct *);
36
 
static gboolean img_export_still(img_window_struct *);
37
 
static void img_clean_after_export(img_window_struct *);
38
 
static void img_export_pixbuf_to_ppm(GdkPixbuf *, guchar **, guint *);
39
 
static void img_export_calc_slide_frames(img_window_struct *);
40
 
static void img_export_pause_unpause(GtkToggleButton *, img_window_struct *);
 
31
static void img_about_dialog_activate_link(GtkAboutDialog * , const gchar *, gpointer );
41
32
 
42
33
void img_set_window_title(img_window_struct *img, gchar *text)
43
34
{
44
35
        gchar *title = NULL;
 
36
        static gchar version[] = VERSION "-" REVISION;
45
37
 
46
38
        if (text == NULL)
47
39
        {
48
 
                title = g_strconcat("Imagination " VERSION, NULL);
 
40
                title = g_strconcat("Imagination ", strcmp(REVISION, "-1") == 0 ? VERSION : version, NULL);
49
41
                gtk_window_set_title (GTK_WINDOW (img->imagination_window), title);
50
42
                g_free(title);
51
43
        }
52
44
        else
53
45
        {
54
 
                
55
 
                title = g_strconcat(text, " - Imagination " VERSION, NULL);
 
46
                title = g_strconcat(text, " - Imagination ", strcmp(REVISION, "-1") == 0 ? VERSION : version, NULL);
56
47
                gtk_window_set_title (GTK_WINDOW (img->imagination_window), title);
57
48
                g_free(title);
58
49
        }
90
81
                thumb = img_load_pixbuf_from_file(slides->data);
91
82
                if (thumb)
92
83
                {
93
 
                        slide_info = img_set_slide_info(1, NORMAL, NULL, 0, slides->data);
 
84
                        slide_info = img_set_slide_info(1, NORMAL, NULL, -1, "0", slides->data);
94
85
                        if (slide_info)
95
86
                        {
96
87
                                gtk_list_store_append (img->thumbnail_model,&iter);
126
117
                gtk_main_iteration();
127
118
}
128
119
 
 
120
void img_remove_audio_files (GtkWidget *widget, img_window_struct *img)
 
121
{
 
122
        GtkTreeSelection *sel;
 
123
        GtkTreePath *path;
 
124
        GtkTreeIter iter;
 
125
        GList *rr_list = NULL;
 
126
        GList *node;
 
127
        gchar *time;
 
128
        gint secs;
 
129
 
 
130
        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(img->music_file_treeview));
 
131
        gtk_tree_selection_selected_foreach(sel, (GtkTreeSelectionForeachFunc) img_remove_foreach_func, &rr_list);
 
132
 
 
133
        for (node = rr_list; node != NULL; node = node->next)
 
134
        {
 
135
                path = gtk_tree_row_reference_get_path((GtkTreeRowReference *) node->data);
 
136
                if (path)
 
137
            {
 
138
                        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(img->music_file_liststore), &iter, path))
 
139
                        {
 
140
                                gtk_tree_model_get(GTK_TREE_MODEL(img->music_file_liststore), &iter, 3, &secs, -1);
 
141
                                gtk_list_store_remove(img->music_file_liststore, &iter);
 
142
                        }
 
143
                        gtk_tree_path_free(path);
 
144
                }
 
145
                img->total_music_secs -= secs;
 
146
        }
 
147
        if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(img->music_file_liststore), &iter) == FALSE)
 
148
        {
 
149
                gtk_widget_set_sensitive (img->remove_audio_button, FALSE);
 
150
                gtk_widget_set_sensitive (img->play_audio_button, FALSE);
 
151
                gtk_label_set_text(GTK_LABEL(img->music_time_data), "");
 
152
        }
 
153
        else
 
154
        {
 
155
                time = img_convert_seconds_to_time(img->total_music_secs);
 
156
                gtk_label_set_text(GTK_LABEL(img->music_time_data), time);
 
157
                g_free(time);
 
158
        }
 
159
        g_list_foreach(rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
 
160
        g_list_free(rr_list);
 
161
}
 
162
 
 
163
void img_remove_foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GList **rowref_list)
 
164
{
 
165
        GtkTreeRowReference *rowref;
 
166
 
 
167
        rowref = gtk_tree_row_reference_new(model, path);
 
168
        *rowref_list = g_list_append(*rowref_list, rowref);
 
169
}
 
170
 
 
171
void img_select_audio_files_to_add ( GtkMenuItem* button, img_window_struct *img)
 
172
{
 
173
        GtkFileFilter *audio_filter, *all_files_filter;
 
174
        GtkWidget *fs;
 
175
        GSList *files = NULL;
 
176
        gint response;
 
177
        gchar *time = NULL;
 
178
 
 
179
        fs = gtk_file_chooser_dialog_new (_("Please choose the audio files to import"),
 
180
                                                        GTK_WINDOW (img->imagination_window),
 
181
                                                        GTK_FILE_CHOOSER_ACTION_OPEN,
 
182
                                                        GTK_STOCK_CANCEL,
 
183
                                                        GTK_RESPONSE_CANCEL,
 
184
                                                        GTK_STOCK_OPEN,
 
185
                                                        GTK_RESPONSE_ACCEPT,
 
186
                                                        NULL);
 
187
 
 
188
        /* only audio files filter */
 
189
        audio_filter = gtk_file_filter_new ();
 
190
        gtk_file_filter_set_name (audio_filter, _("All audio files") );
 
191
        gtk_file_filter_add_pattern (audio_filter, "*.wav");
 
192
        gtk_file_filter_add_pattern (audio_filter, "*.mp3");
 
193
        gtk_file_filter_add_pattern (audio_filter, "*.ogg");
 
194
        gtk_file_filter_add_pattern (audio_filter, "*.flac");
 
195
        gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fs), audio_filter);
 
196
 
 
197
        /* All files filter */
 
198
        all_files_filter = gtk_file_filter_new ();
 
199
        gtk_file_filter_set_name(all_files_filter, _("All files"));
 
200
        gtk_file_filter_add_pattern(all_files_filter, "*");
 
201
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), all_files_filter);
 
202
 
 
203
        gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (fs), TRUE);
 
204
 
 
205
        response = gtk_dialog_run (GTK_DIALOG (fs));
 
206
        if (response == GTK_RESPONSE_ACCEPT)
 
207
        {
 
208
                files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (fs));
 
209
                g_slist_foreach( files, (GFunc) img_add_audio_files, img);
 
210
        }
 
211
        if (files != NULL)
 
212
                g_slist_free (files);
 
213
 
 
214
        time = img_convert_seconds_to_time(img->total_music_secs);
 
215
        gtk_label_set_text(GTK_LABEL(img->music_time_data), time);
 
216
        g_free(time);
 
217
 
 
218
        gtk_widget_destroy (fs);
 
219
}
 
220
 
 
221
void img_add_audio_files (gchar *filename, img_window_struct *img)
 
222
{
 
223
        GtkTreeIter iter;
 
224
        gchar *path, *file, *time;
 
225
        gint secs;
 
226
 
 
227
        path = g_path_get_dirname(filename);
 
228
        file = g_path_get_basename(filename);
 
229
        time = img_get_audio_length(img, filename, &secs);
 
230
 
 
231
        if (time != NULL)
 
232
        {
 
233
                gtk_list_store_append(img->music_file_liststore, &iter);
 
234
                gtk_list_store_set (img->music_file_liststore, &iter, 0, path, 1, file, 2, time, 3, secs, -1);
 
235
 
 
236
                img->total_music_secs += secs;
 
237
                g_free(time);
 
238
        }
 
239
        g_free(path);
 
240
        g_free(file);
 
241
        g_free(filename);
 
242
}
 
243
 
129
244
GSList *img_import_slides_file_chooser(img_window_struct *img)
130
245
{
131
246
        GtkFileFilter *all_images_filter, *all_files_filter;
184
299
        GtkTreeIter iter;
185
300
        slide_struct *entry;
186
301
 
 
302
        /* Free the memory allocated the single slides one by one */
187
303
        if (img_struct->slides_nr)
188
304
        {
189
305
                model = gtk_icon_view_get_model (GTK_ICON_VIEW(img_struct->thumbnail_iconview));
193
309
                {
194
310
                        gtk_tree_model_get(model, &iter,1,&entry,-1);
195
311
                        g_free(entry->filename);
 
312
                        g_free(entry->path);
196
313
                        g_free(entry->resolution);
197
314
                        g_free(entry->type);
198
315
                        g_free(entry);
199
316
                        img_struct->slides_nr--;
200
317
                }
201
318
                while (gtk_tree_model_iter_next (model,&iter));
 
319
                g_signal_handlers_block_by_func((gpointer)img_struct->thumbnail_iconview, (gpointer)img_iconview_selection_changed, img_struct);
202
320
                gtk_list_store_clear(GTK_LIST_STORE(img_struct->thumbnail_model));
 
321
                g_signal_handlers_unblock_by_func((gpointer)img_struct->thumbnail_iconview, (gpointer)img_iconview_selection_changed, img_struct);
203
322
        }
204
 
 
205
 
        if (img_struct->slideshow_filename)
 
323
        
 
324
        /* Delete the audio files in the liststore */
 
325
        if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(img_struct->music_file_liststore), &iter))
206
326
        {
207
 
                g_free(img_struct->slideshow_filename);
208
 
                img_struct->slideshow_filename = NULL;
 
327
                gtk_list_store_clear(img_struct->music_file_liststore);
 
328
                img_struct->total_music_secs = 0;
 
329
                gtk_label_set_text(GTK_LABEL(img_struct->music_time_data), "");
209
330
        }
210
331
 
 
332
        /* Free gchar pointers */
211
333
        if (img_struct->current_dir)
212
334
        {
213
335
                g_free(img_struct->current_dir);
221
343
        }
222
344
}
223
345
 
224
 
gint img_ask_user_confirmation(img_window_struct *img_struct)
 
346
gint img_ask_user_confirmation(img_window_struct *img_struct, gchar *msg)
225
347
{
226
348
        GtkWidget *dialog;
227
349
        gint response;
228
350
 
229
 
        dialog = gtk_message_dialog_new(GTK_WINDOW(img_struct->imagination_window),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL,_("You didn't save your slideshow yet. Are you sure you want to close it?"));
 
351
        dialog = gtk_message_dialog_new(GTK_WINDOW(img_struct->imagination_window),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL, msg);
230
352
        gtk_window_set_title(GTK_WINDOW(dialog),"Imagination");
231
353
        response = gtk_dialog_run (GTK_DIALOG (dialog));
232
354
        gtk_widget_destroy (GTK_WIDGET (dialog));
239
361
 
240
362
        if (img_struct->project_is_modified)
241
363
        {
242
 
                response = img_ask_user_confirmation(img_struct);
 
364
                response = img_ask_user_confirmation(img_struct, _("You didn't save your slideshow yet. Are you sure you want to close it?"));
243
365
                if (response != GTK_RESPONSE_OK)
244
366
                        return TRUE;
245
367
        }
305
427
}
306
428
 
307
429
void img_delete_selected_slides(GtkMenuItem *item,img_window_struct *img_struct)
308
 
{
309
 
        GList *selected, *bak;
310
 
        GtkTreeIter iter;
311
 
        GtkTreeModel *model;
312
 
        slide_struct *entry;
 
430
{ GList *selected, *bak; GtkTreeIter iter; GtkTreeModel *model; slide_struct
 
431
        *entry;
313
432
 
314
 
        model = gtk_icon_view_get_model(GTK_ICON_VIEW(img_struct->thumbnail_iconview));
 
433
        model =
 
434
                gtk_icon_view_get_model(GTK_ICON_VIEW(img_struct->thumbnail_iconview));
315
435
        
316
 
        selected = gtk_icon_view_get_selected_items (GTK_ICON_VIEW(img_struct->thumbnail_iconview));
317
 
        if (selected == NULL)
 
436
        selected = gtk_icon_view_get_selected_items
 
437
                (GTK_ICON_VIEW(img_struct->thumbnail_iconview)); if (selected == NULL)
318
438
                return;
319
439
        
320
440
        /* Free the slide struct for each slide and remove it from the iconview */
324
444
         * already "frozen" and selection cannot be changed through the user
325
445
         * intervention until the callback returns). */
326
446
        bak = selected;
327
 
        g_signal_handlers_block_by_func((gpointer)img_struct->thumbnail_iconview, (gpointer)img_iconview_selection_changed, img_struct);
328
 
        while (selected)
329
 
        {
330
 
                gtk_tree_model_get_iter(model, &iter,selected->data);
331
 
                gtk_tree_model_get(model, &iter,1,&entry,-1);
332
 
                g_free(entry->filename);
333
 
                g_free(entry->resolution);
334
 
                g_free(entry->type);
335
 
                g_free(entry);
 
447
        g_signal_handlers_block_by_func((gpointer)img_struct->thumbnail_iconview,
 
448
                        (gpointer)img_iconview_selection_changed, img_struct); while
 
449
                (selected) { gtk_tree_model_get_iter(model, &iter,selected->data);
 
450
                        gtk_tree_model_get(model, &iter,1,&entry,-1);
 
451
                        g_free(entry->filename); g_free(entry->resolution);
 
452
                        g_free(entry->type); g_free(entry);
336
453
 
337
 
                gtk_list_store_remove(GTK_LIST_STORE(img_struct->thumbnail_model),&iter);
 
454
                gtk_list_store_remove(GTK_LIST_STORE(img_struct->thumbnail_model),&iter);
338
455
 
339
 
                img_struct->slides_nr--;
340
 
                selected = selected->next;
341
 
        }
342
 
        g_signal_handlers_unblock_by_func((gpointer)img_struct->thumbnail_iconview, (gpointer)img_iconview_selection_changed, img_struct);              
343
 
        g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
344
 
        g_list_free(selected);
345
 
        img_set_statusbar_message(img_struct,0);
346
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(img_struct->image_area),NULL);
347
 
        img_struct->project_is_modified = TRUE;
 
456
                img_struct->slides_nr--; selected = selected->next; }
 
457
                g_signal_handlers_unblock_by_func((gpointer)img_struct->thumbnail_iconview,
 
458
                                (gpointer)img_iconview_selection_changed, img_struct);
 
459
                g_list_foreach (bak, (GFunc)gtk_tree_path_free, NULL);
 
460
                g_list_free(bak); img_set_statusbar_message(img_struct,0);
 
461
                gtk_image_set_from_pixbuf(GTK_IMAGE(img_struct->image_area),NULL);
 
462
                img_struct->project_is_modified = TRUE;
348
463
 
349
464
        if (img_struct->slides_nr == 0)
350
465
                gtk_widget_hide(img_struct->thumb_scrolledwindow);
355
470
void img_show_about_dialog (GtkMenuItem *item,img_window_struct *img_struct)
356
471
{
357
472
        static GtkWidget *about = NULL;
358
 
    const char *authors[] = {"\nDevelopers:\nGiuseppe Torelli <colossus73@gmail.com>\nTadej Borovšak <tadeboro@gmail.com>\n\nImagination logo:\nJaws, Dadster, Gemini and Lunoob\nfrom http://linuxgraphicsusers.com\n\n",NULL};
359
 
    const char *documenters[] = {NULL};
 
473
        static gchar version[] = VERSION "-" REVISION;
 
474
    const char *authors[] = {"\nDevelopers:\nGiuseppe Torelli <colossus73@gmail.com>\nTadej Borovšak <tadeboro@gmail.com>\n\nImagination logo: http://linuxgraphicsusers.com\n\n",NULL};
 
475
    //const char *documenters[] = {NULL};
360
476
 
361
477
        if (about == NULL)
362
478
        {
363
479
                about = gtk_about_dialog_new ();
364
 
                /*gtk_about_dialog_set_email_hook (img_activate_link,NULL,NULL);
365
 
                gtk_about_dialog_set_url_hook (img_activate_link,NULL,NULL);*/
 
480
                gtk_about_dialog_set_url_hook(img_about_dialog_activate_link, NULL, NULL);
366
481
                gtk_window_set_position (GTK_WINDOW (about),GTK_WIN_POS_CENTER_ON_PARENT);
367
482
                gtk_window_set_transient_for (GTK_WINDOW (about),GTK_WINDOW (img_struct->imagination_window));
368
483
                gtk_window_set_destroy_with_parent (GTK_WINDOW (about),TRUE);
369
484
                g_object_set (about,
370
485
                        "name", "Imagination",
371
 
                        "version",PACKAGE_VERSION,
 
486
                        "version", strcmp(REVISION, "-1") == 0 ? VERSION : version,
372
487
                        "copyright","Copyright \xC2\xA9 2009 Giuseppe Torelli",
373
488
                        "comments","A simple and lightweight DVD slideshow maker",
374
489
                        "authors",authors,
375
 
                        "documenters",documenters,
 
490
                        "documenters",NULL,
376
491
                        "translator_credits",_("translator-credits"),
377
492
                        "logo_icon_name","imagination",
378
493
                        "website","http://imagination.sf.net",
397
512
        gtk_widget_hide (about);
398
513
}
399
514
 
 
515
static void img_about_dialog_activate_link(GtkAboutDialog * dialog, const gchar *link, gpointer data)
 
516
{
 
517
        char * argv[] = { "xdg-open", (char*)link, NULL };
 
518
 
 
519
        g_spawn_async( NULL, argv, NULL, G_SPAWN_SEARCH_PATH,NULL, NULL, NULL, NULL);
 
520
}
 
521
 
400
522
void img_set_total_slideshow_duration(img_window_struct *img)
401
523
{
402
524
        gchar *time;
403
525
        GtkTreeIter iter;
404
526
        slide_struct *entry;
405
527
        GtkTreeModel *model;
406
 
        gint h, m, s;
407
528
 
408
529
        model = gtk_icon_view_get_model(GTK_ICON_VIEW(img->thumbnail_iconview));
409
530
        if (!gtk_tree_model_get_iter_first (model,&iter))
420
541
        }
421
542
        while (gtk_tree_model_iter_next (model,&iter));
422
543
 
423
 
        /* Fix secs -> hour, mins and secs conversion */
424
 
        h =  img->total_secs / 3600;
425
 
        m = (img->total_secs % 3600) / 60;
426
 
        s =  img->total_secs - (h * 3600) - (m * 60);
427
 
        time = g_strdup_printf("%02d:%02d:%02d", h, m, s);
 
544
        /* Add time of last pseudo slide */
 
545
        if( img->final_transition.render )
 
546
                img->total_secs += img->final_transition.speed;
 
547
 
 
548
        time = img_convert_seconds_to_time(img->total_secs);
428
549
        gtk_label_set_text(GTK_LABEL (img->total_time_data),time);
429
550
        g_free(time);
430
 
 
431
 
        img->project_is_modified = TRUE;
432
551
}
433
552
 
434
553
void img_start_stop_preview(GtkWidget *button, img_window_struct *img)
435
554
{
436
 
        GtkTreeIter iter;
 
555
        GtkTreeIter iter, prev;
 
556
        GtkTreePath *path = NULL;
437
557
        slide_struct *entry;
438
558
        GtkTreeModel *model;
 
559
        GList *list = NULL;
 
560
 
 
561
        /* If no images are present, abort */
 
562
        if( img->slides_nr == 0 )
 
563
                return;
439
564
 
440
565
        if(img->export_is_running)
441
566
                return;
442
 
                
443
 
        model = gtk_icon_view_get_model(GTK_ICON_VIEW(img->thumbnail_iconview));
444
 
        if( ! gtk_tree_model_get_iter_first (model,&iter))
445
 
                return;
446
567
 
447
568
        if (img->preview_is_running)
448
569
        {
458
579
        else
459
580
        {
460
581
                /* Start the preview */
 
582
                model = gtk_icon_view_get_model(GTK_ICON_VIEW(img->thumbnail_iconview));
 
583
                list = gtk_icon_view_get_selected_items( GTK_ICON_VIEW( img->thumbnail_iconview ) );
 
584
                if( list )
 
585
                        gtk_icon_view_get_cursor(GTK_ICON_VIEW(img->thumbnail_iconview), &path, NULL);
 
586
                if( list && path )
 
587
                {
 
588
                        /* Start preview from this slide */
 
589
                        gtk_tree_model_get_iter( model, &iter, path );
 
590
                        g_list_foreach( list, (GFunc)gtk_tree_path_free, NULL );
 
591
                        g_list_free( list );
 
592
                }
 
593
                else
 
594
                {
 
595
                        /* Start preview from the beginning */
 
596
                        if(!gtk_tree_model_get_iter_first (model,&iter))
 
597
                                return;
 
598
                }
461
599
 
462
600
                /* Replace button and menu images */
463
601
                img_swap_toolbar_images( img, FALSE );
473
611
                gtk_widget_set_app_paintable(img->image_area, TRUE);
474
612
                g_signal_connect( G_OBJECT(img->image_area), "expose-event",G_CALLBACK(img_on_expose_event),img);
475
613
 
476
 
                /* Create an empty pixbuf - starting white image */
477
 
                img->pixbuf1 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,img->image_area->allocation.width,img->image_area->allocation.height);
478
 
                gdk_pixbuf_fill(img->pixbuf1,img->background_color);
479
 
 
480
614
                /* Load the first image in the pixbuf */
481
615
                gtk_tree_model_get(model, &iter,1,&entry,-1);
482
616
                img->pixbuf2 = img_scale_pixbuf(img,entry->filename);
 
617
                img->current_slide = entry;
 
618
 
 
619
                /* If we started our preview from beginning, create empty pixbuf and
 
620
                 * fill it with background color. Else load image that is before
 
621
                 * currently selected slide. */
 
622
                if( path != NULL && gtk_tree_path_prev( path ) )
 
623
                {
 
624
                        if( ! img->cur_ss_iter )
 
625
                                img->cur_ss_iter = g_slice_new( GtkTreeIter );
 
626
 
 
627
                        gtk_tree_model_get_iter( model, &prev, path );
 
628
                        gtk_tree_model_get( model, &prev, 1, &entry, -1 );
 
629
                        img->pixbuf1 = img_scale_pixbuf(img, entry->filename);
 
630
                        *img->cur_ss_iter = iter;
 
631
                }
 
632
                else
 
633
                {
 
634
                        img->pixbuf1 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,img->image_area->allocation.width,img->image_area->allocation.height);
 
635
                        gdk_pixbuf_fill(img->pixbuf1,img->background_color);
 
636
                }
 
637
                if( path )
 
638
                        gtk_tree_path_free( path );
483
639
 
484
640
                /* Add transition timeout function */
485
641
                img->preview_is_running = TRUE;
486
 
                img->current_slide = entry;
487
642
                img->progress = 0;
488
643
                img->source_id = g_timeout_add(1000 / PREVIEW_FPS,(GSourceFunc)img_transition_timeout,img);
489
644
        }
490
645
        return;
491
646
}
492
647
 
493
 
static gboolean img_on_expose_event(GtkWidget *widget,GdkEventExpose *event,img_window_struct *img)
 
648
gboolean img_on_expose_event(GtkWidget *widget,GdkEventExpose *event,img_window_struct *img)
494
649
{
495
650
        /* We always pass negative number as a last parameter when we want to
496
651
         * draw on screen. */
699
854
                
700
855
                tmp_image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY,GTK_ICON_SIZE_LARGE_TOOLBAR);
701
856
                gtk_widget_show(tmp_image);
702
 
                g_object_set(img->preview_button,"icon-widget",tmp_image,NULL);
 
857
                gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(img->preview_button), tmp_image);
703
858
                gtk_widget_set_tooltip_text(img->preview_button,_("Starts the preview"));
704
859
        }
705
860
        else
709
864
                
710
865
                tmp_image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_STOP,GTK_ICON_SIZE_LARGE_TOOLBAR);
711
866
                gtk_widget_show(tmp_image);
712
 
                g_object_set(img->preview_button,"icon-widget",tmp_image,NULL);
 
867
                gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(img->preview_button), tmp_image);
713
868
                gtk_widget_set_tooltip_text(img->preview_button,_("Stops the preview"));
714
869
        }
715
870
}
750
905
        else if (widget == img->save_as_menu || widget == img->save_menu || widget == img->save_button)
751
906
                action = GTK_FILE_CHOOSER_ACTION_SAVE;
752
907
 
 
908
        /* If user wants to save empty slideshow, simply abort */
 
909
        if( img->slides_nr == 0 && action == GTK_FILE_CHOOSER_ACTION_SAVE  )
 
910
                return;
 
911
 
753
912
        if (img->project_filename == NULL || widget == img->save_as_menu || action == GTK_FILE_CHOOSER_ACTION_OPEN)
754
913
        {
755
914
                fc = gtk_file_chooser_dialog_new (action == GTK_FILE_CHOOSER_ACTION_OPEN ? _("Load an Imagination slideshow project") : 
793
952
{
794
953
        if (img->project_is_modified)
795
954
        {
796
 
                if (GTK_RESPONSE_OK != img_ask_user_confirmation(img))
797
 
 
 
955
                if (GTK_RESPONSE_OK != img_ask_user_confirmation(img, _("You didn't save your slideshow yet. Are you sure you want to close it?")))
798
956
                        return;
799
957
        }
800
958
        img_free_allocated_memory(img);
801
 
        img_set_buttons_state(img, FALSE);
802
959
        img_set_window_title(img,NULL);
803
960
        img_set_statusbar_message(img,0);
804
961
        gtk_image_set_from_pixbuf(GTK_IMAGE(img->image_area),NULL);
 
962
        gtk_widget_set_sensitive(img->random_button, FALSE);
 
963
        gtk_widget_set_sensitive(img->transition_type, FALSE);
 
964
        gtk_widget_set_sensitive(img->duration, FALSE);
805
965
        gtk_widget_hide(img->thumb_scrolledwindow);
806
 
}
807
 
 
808
 
void img_start_stop_export(GtkWidget *widget, img_window_struct *img)
809
 
{
810
 
        GtkTreeIter   iter;
811
 
        slide_struct *entry;
812
 
        GtkTreeModel *model;
813
 
 
814
 
        /* If we are displaying preview, abort or bad things will happen. */
815
 
        if(img->preview_is_running)
816
 
                return;
817
 
 
818
 
        model = gtk_icon_view_get_model(GTK_ICON_VIEW(img->thumbnail_iconview));
819
 
        if(!gtk_tree_model_get_iter_first(model, &iter))
820
 
                        return;
821
 
 
822
 
        if(img->export_is_running)
823
 
        {
824
 
                /* Remove idle function from main loop */
825
 
                g_source_remove(img->source_id);
826
 
 
827
 
                /* Clean resources used by export. */
828
 
                img_clean_after_export(img);
829
 
        }
830
 
        else
831
 
        {
832
 
                GtkWidget *dialog;
833
 
                GtkWidget *vbox, *hbox;
834
 
                GtkWidget *label;
835
 
                GtkWidget *progress;
836
 
                GtkWidget *button;
837
 
                gchar     *string;
838
 
 
839
 
                if(!img_run_encoder(img))
840
 
                        return;
841
 
 
842
 
                /* Create progress window with cancel and pause buttons, calculate
843
 
                 * the total number of frames to display. */
844
 
                dialog = gtk_window_new( GTK_WINDOW_TOPLEVEL );
845
 
                img->export_dialog = dialog;
846
 
                gtk_window_set_title (GTK_WINDOW(img->export_dialog),_("Exporting the slideshow"));
847
 
                gtk_container_set_border_width( GTK_CONTAINER( dialog ), 10 );
848
 
                gtk_window_set_default_size( GTK_WINDOW( dialog ), 400, -1 );
849
 
                gtk_window_set_type_hint( GTK_WINDOW( dialog ),
850
 
                                                                  GDK_WINDOW_TYPE_HINT_DIALOG );
851
 
                gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE );
852
 
                gtk_window_set_transient_for( GTK_WINDOW( dialog ),
853
 
                                                                          GTK_WINDOW( img->imagination_window ) );
854
 
 
855
 
                vbox = gtk_vbox_new( FALSE, 6 );
856
 
                gtk_container_add( GTK_CONTAINER( dialog ), vbox );
857
 
 
858
 
                label = gtk_label_new( _("Preparing for export ...") );
859
 
                gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
860
 
                img->export_label = label;
861
 
                gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
862
 
 
863
 
                progress = gtk_progress_bar_new();
864
 
                img->export_pbar1 = progress;
865
 
                string = g_strdup_printf( "%.2f", .0 );
866
 
                gtk_progress_bar_set_text( GTK_PROGRESS_BAR( progress ), string );
867
 
                gtk_box_pack_start( GTK_BOX( vbox ), progress, FALSE, FALSE, 0 );
868
 
 
869
 
                label = gtk_label_new( _("Overall progress:") );
870
 
                gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
871
 
                gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
872
 
 
873
 
                progress = gtk_progress_bar_new();
874
 
                img->export_pbar2 = progress;
875
 
                gtk_progress_bar_set_text( GTK_PROGRESS_BAR( progress ), string );
876
 
                gtk_box_pack_start( GTK_BOX( vbox ), progress, FALSE, FALSE, 0 );
877
 
                g_free( string );
878
 
 
879
 
                hbox = gtk_hbox_new( TRUE, 6 );
880
 
                gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
881
 
 
882
 
                button = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
883
 
                g_signal_connect( G_OBJECT( button ), "clicked",
884
 
                                                  G_CALLBACK( img_start_stop_export ), img );
885
 
                gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
886
 
 
887
 
                button = gtk_toggle_button_new_with_label( GTK_STOCK_MEDIA_PAUSE );
888
 
                gtk_button_set_use_stock( GTK_BUTTON( button ), TRUE );
889
 
                g_signal_connect( G_OBJECT( button ), "toggled",
890
 
                                                  G_CALLBACK( img_export_pause_unpause ), img );
891
 
                gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
892
 
 
893
 
                gtk_widget_show_all( dialog );
894
 
 
895
 
                /* Display some visual feedback */
896
 
                while( gtk_events_pending() )
897
 
                        gtk_main_iteration();
898
 
 
899
 
                img->slide_pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(img->image_area));
900
 
                if(img->slide_pixbuf)
901
 
                        g_object_ref(G_OBJECT(img->slide_pixbuf));
902
 
                gtk_image_clear(GTK_IMAGE(img->image_area));
903
 
                gtk_widget_set_app_paintable(img->image_area, TRUE);
904
 
                g_signal_connect(G_OBJECT(img->image_area), "expose-event", G_CALLBACK(img_on_expose_event), img);
905
 
 
906
 
                /* Create an empty pixbuf for starting image. */
907
 
                img->pixbuf1 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, img->image_area->allocation.width, img->image_area->allocation.height);
908
 
                gdk_pixbuf_fill(img->pixbuf1, img->background_color);
909
 
 
910
 
                /* Load first image from model */
911
 
                gtk_tree_model_get(model, &iter, 1, &entry, -1);
912
 
                img->pixbuf2 = img_scale_pixbuf(img, entry->filename);
913
 
 
914
 
                /* Add export idle function and set initial values */
915
 
                img->export_is_running = TRUE;
916
 
                img->current_slide = entry;
917
 
                img->progress = 0;
918
 
                img->export_frame_nr = img->total_secs * EXPORT_FPS;
919
 
                img->export_frame_cur = 0;
920
 
                /* Fix for the wrong progress bar indicators. */
921
 
                img_export_calc_slide_frames( img );
922
 
 
923
 
                img->export_slide = 1;
924
 
                img->export_idle_func = (GSourceFunc)img_export_transition;
925
 
                img->source_id = g_idle_add((GSourceFunc)img_export_transition, img);
926
 
 
927
 
                string = g_strdup_printf( _("Slide %d export progress:"), 1 );
928
 
                /* I did this for the translators. ^^ */
929
 
                gtk_label_set_label( GTK_LABEL( img->export_label ), string );
930
 
                g_free( string );
931
 
        }
932
 
}
933
 
 
934
 
static gboolean img_export_transition(img_window_struct *img)
935
 
{
936
 
        gchar           string[10];
937
 
        gdouble         export_progress;
938
 
 
939
 
        /* If no transition effect is set, just connect still export
940
 
         * idle function and remove itself from main loop. */
941
 
        if(img->current_slide->render == NULL)
942
 
        {
943
 
                img->source_id = g_idle_add((GSourceFunc)img_export_still, img);
944
 
                return(FALSE);
945
 
        }
946
 
 
947
 
        /* Switch to still export phase if progress reached 1. */
948
 
        img->progress += (gdouble)1 / ( img->current_slide->speed * EXPORT_FPS );
949
 
        if(img->progress > 1.00000005)
950
 
        {
951
 
                img->progress = 0;
952
 
                img->export_idle_func = (GSourceFunc)img_export_still;
953
 
                img->source_id = g_idle_add((GSourceFunc)img_export_still, img);
954
 
 
955
 
                return(FALSE);
956
 
        }
957
 
 
958
 
        /* Draw one frame of transition animation */
959
 
        img->current_slide->render(img->image_area->window, img->pixbuf1, img->pixbuf2, img->progress, img->file_desc);
960
 
 
961
 
        /* Increment global frame counters and update progress bars */
962
 
        img->export_frame_cur++;
963
 
        img->export_slide_cur++;
964
 
 
965
 
        export_progress = (gdouble)img->export_slide_cur / img->export_slide_nr;
966
 
        snprintf( string, 10, "%.2f%%", export_progress * 100 );
967
 
        gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR( img->export_pbar1 ),
968
 
                                                                   export_progress );
969
 
        gtk_progress_bar_set_text( GTK_PROGRESS_BAR( img->export_pbar1 ), string );
970
 
 
971
 
        export_progress = (gdouble)img->export_frame_cur / img->export_frame_nr;
972
 
        snprintf( string, 10, "%.2f%%", export_progress * 100 );
973
 
        gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR( img->export_pbar2 ),
974
 
                                                                   export_progress );
975
 
        gtk_progress_bar_set_text( GTK_PROGRESS_BAR( img->export_pbar2 ), string );
976
 
 
977
 
        /* Draw every 10th frame of animation on screen */
978
 
        if(img->export_frame_cur % 10 == 0)
979
 
                gtk_widget_queue_draw(img->image_area);
980
 
 
981
 
        return(TRUE);
982
 
}
983
 
 
984
 
static gboolean img_export_still(img_window_struct *img)
985
 
{
986
 
        static guint   lenght;
987
 
        gdouble        export_progress;
988
 
        gchar          string[10];
989
 
 
990
 
        /* Initialize pixbuf data buffer */
991
 
        if(img->pixbuf_data == NULL)
992
 
        {
993
 
                gtk_image_set_from_pixbuf(GTK_IMAGE(img->image_area), img->pixbuf2);
994
 
                img_export_pixbuf_to_ppm(img->pixbuf2, &img->pixbuf_data, &lenght);
995
 
        }
996
 
 
997
 
         /* Draw frames until we have enough of them to fill slide duration gap. */
998
 
        if( img->export_slide_cur > img->export_slide_nr )
999
 
        {
1000
 
                /* Exit still rendering and continue with next transition. */
1001
 
 
1002
 
                /* Clear image area for next renderer */
1003
 
                gtk_image_clear(GTK_IMAGE(img->image_area));
1004
 
 
1005
 
                /* Load next image from store. */
1006
 
                if(img_prepare_pixbufs(img))
1007
 
                {
1008
 
                        gchar *string;
1009
 
 
1010
 
                        /* Update progress counters */
1011
 
                        img->export_slide++;
1012
 
                        string = g_strdup_printf( _("Slide %d export progress:"), img->export_slide );
1013
 
                        gtk_label_set_label( GTK_LABEL( img->export_label ), string );
1014
 
                        g_free( string );
1015
 
                        /* Progress bug fix */
1016
 
                        img_export_calc_slide_frames( img );
1017
 
 
1018
 
                        g_free(img->pixbuf_data);
1019
 
                        img->pixbuf_data = NULL;
1020
 
                        img->export_idle_func = (GSourceFunc)img_export_transition;
1021
 
                        img->source_id = g_idle_add((GSourceFunc)img_export_transition, img);
1022
 
                }
1023
 
                else
1024
 
                        img_clean_after_export(img);
1025
 
 
1026
 
                return(FALSE);
1027
 
        }
1028
 
        write(img->file_desc, img->pixbuf_data, lenght);
1029
 
 
1030
 
        /* Increment global frame counter and update progress bar */
1031
 
        img->export_frame_cur++;
1032
 
        img->export_slide_cur++;
1033
 
 
1034
 
        /* CLAMPS are needed here because of the loosy conversion when switching
1035
 
         * from floating point to integer arithmetics. */
1036
 
        export_progress = CLAMP( (gdouble)img->export_slide_cur / img->export_slide_nr, 0, 1 );
1037
 
        snprintf( string, 10, "%.2f%%", export_progress * 100 );
1038
 
        gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR( img->export_pbar1 ),
1039
 
                                                                   export_progress );
1040
 
        gtk_progress_bar_set_text( GTK_PROGRESS_BAR( img->export_pbar1 ), string );
1041
 
 
1042
 
        export_progress = CLAMP( (gdouble)img->export_frame_cur / img->export_frame_nr, 0, 1 );
1043
 
        snprintf( string, 10, "%.2f%%", export_progress * 100 );
1044
 
        gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR( img->export_pbar2 ),
1045
 
                                                                   export_progress );
1046
 
        gtk_progress_bar_set_text( GTK_PROGRESS_BAR( img->export_pbar2 ), string );
1047
 
 
1048
 
        return(TRUE);
1049
 
}
1050
 
 
1051
 
static void img_clean_after_export(img_window_struct *img)
1052
 
{
1053
 
        /* Disconnect expose event */
1054
 
        g_signal_handlers_block_by_func(img->image_area, img_on_expose_event, img);
1055
 
        gtk_widget_set_app_paintable(img->image_area, FALSE);
1056
 
 
1057
 
        /* Restore image that was used before export */
1058
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(img->image_area), img->slide_pixbuf);
1059
 
        if(img->slide_pixbuf)
1060
 
                g_object_unref(G_OBJECT(img->slide_pixbuf));
1061
 
 
1062
 
        /* Indicate that export is not running any more */
1063
 
        img->export_is_running = FALSE;
1064
 
 
1065
 
        /* Clean other resources */
1066
 
        g_slice_free(GtkTreeIter, img->cur_ss_iter);
1067
 
        img->cur_ss_iter = NULL;
1068
 
        g_free(img->pixbuf_data);
1069
 
        img->pixbuf_data = NULL;
1070
 
        gtk_widget_destroy( img->export_dialog );
1071
 
 
1072
 
        close(img->file_desc);
1073
 
}
1074
 
 
1075
 
/* Move one step forward in model and set img->pixbuf1 and img->pixbuf2
1076
 
 * to appropriate values.
1077
 
 * Return FALSE if we reached the end of the model, else TRUE. */
1078
 
static gboolean img_prepare_pixbufs(img_window_struct *img)
1079
 
{
1080
 
        GtkTreeModel *model;
1081
 
 
1082
 
        model = gtk_icon_view_get_model(GTK_ICON_VIEW(img->thumbnail_iconview));
1083
 
 
1084
 
        if(!img->cur_ss_iter)
1085
 
        {
1086
 
                img->cur_ss_iter = g_slice_new(GtkTreeIter);
1087
 
                gtk_tree_model_get_iter_first(model, img->cur_ss_iter);
1088
 
        }
1089
 
 
1090
 
        if(gtk_tree_model_iter_next(model, img->cur_ss_iter))
1091
 
        {
1092
 
                g_object_unref(G_OBJECT(img->pixbuf1));
1093
 
                img->pixbuf1 = img->pixbuf2;
1094
 
                gtk_tree_model_get(model, img->cur_ss_iter, 1, &img->current_slide, -1);
1095
 
                img->pixbuf2 = img_scale_pixbuf(img, img->current_slide->filename);
1096
 
 
1097
 
                return(TRUE);
1098
 
        }
1099
 
        else
1100
 
                return(FALSE);
1101
 
 
1102
 
 
1103
 
        if(gtk_tree_model_iter_next(model, img->cur_ss_iter))
1104
 
        {
1105
 
                g_object_unref(G_OBJECT(img->pixbuf1));
1106
 
                img->pixbuf1 = img->pixbuf2;
1107
 
                gtk_tree_model_get(model, img->cur_ss_iter, 1, &img->current_slide, -1);
1108
 
                img->pixbuf2 = img_scale_pixbuf(img, img->current_slide->filename);
1109
 
 
1110
 
                return(TRUE);
1111
 
        }
1112
 
        else
1113
 
                return(FALSE);
1114
 
}
1115
 
 
1116
 
static void img_export_pixbuf_to_ppm(GdkPixbuf *pixbuf, guchar **data, guint *lenght)
1117
 
{
1118
 
        gint      width, height, stride, channels;
1119
 
        guchar   *pixels, *tmp;
1120
 
        gint      col, row;
1121
 
        gchar    *header;
1122
 
        gint      header_lenght;
1123
 
 
1124
 
        width    = gdk_pixbuf_get_width(pixbuf);
1125
 
        height   = gdk_pixbuf_get_height(pixbuf);
1126
 
        stride   = gdk_pixbuf_get_rowstride(pixbuf);
1127
 
        channels = gdk_pixbuf_get_n_channels(pixbuf);
1128
 
        pixels   = gdk_pixbuf_get_pixels(pixbuf);
1129
 
 
1130
 
        header = g_strdup_printf("P6\n%d %d\n255\n", width, height);
1131
 
        header_lenght = strlen(header) * sizeof(gchar);
1132
 
 
1133
 
        *lenght = sizeof(guchar) * width * height * channels + header_lenght;
1134
 
        *data = g_slice_alloc(sizeof(guchar) * *lenght);
1135
 
 
1136
 
        memcpy(*data, header, header_lenght);
1137
 
        tmp = *data + header_lenght;
1138
 
        for(row = 0; row < height; row++)
1139
 
        {
1140
 
                for(col = 0; col < width; col++)
1141
 
                {
1142
 
                        tmp[0] = pixels[0];
1143
 
                        tmp[1] = pixels[1];
1144
 
                        tmp[2] = pixels[2];
1145
 
 
1146
 
                        tmp    += 3;
1147
 
                        pixels += channels;
1148
 
                }
1149
 
        }
 
966
 
 
967
        /* Reset slideshow properties */
 
968
        img->distort_images = TRUE;
 
969
        img->background_color = 0;
 
970
        img->final_transition.speed = NORMAL;
 
971
        img->final_transition.render = NULL;
1150
972
}
1151
973
 
1152
974
/*
1181
1003
 }
1182
1004
 */
1183
1005
 
1184
 
/* Changed return value to gboolean. This way we can abort export in
1185
 
 * img_start_stop_export function. */
1186
 
static gboolean img_run_encoder(img_window_struct *img)
 
1006
void img_move_audio_up( GtkButton *button, img_window_struct *img )
1187
1007
{
1188
 
        GtkWidget  *message;
1189
 
        GError     *error = NULL;
1190
 
        gchar     **argv;
1191
 
        gchar      *cmd_line;
1192
 
        gboolean    ret;
1193
 
 
1194
 
        if (img->slideshow_format_index == 0)
1195
 
                cmd_line = g_strdup_printf(
1196
 
                                "ffmpeg -f image2pipe -vcodec ppm -r %s -i pipe: "
1197
 
                                "-target %s-dvd -r %s -an -aspect %s -s %dx%d -y -bf 2 %s",
1198
 
                                EXPORT_FPS_STRING,
1199
 
                                img->image_area->allocation.height == 576 ? "pal" : "ntsc",
1200
 
                                EXPORT_FPS_STRING,
1201
 
                                img->aspect_ratio, img->image_area->allocation.width,
1202
 
                                img->image_area->allocation.height, img->slideshow_filename );
1203
 
        else
1204
 
                cmd_line = g_strconcat(
1205
 
                                "ffmpeg -f image2pipe -vcodec ppm -r " EXPORT_FPS_STRING
1206
 
                                " -i pipe: -an -b 512k -s 320x240 -f flv -y ",
1207
 
                                img->slideshow_filename,NULL);
1208
 
        argv = g_strsplit( cmd_line, " ", 0 );
1209
 
        g_print( "%s\n", cmd_line );
1210
 
        g_free( cmd_line );
1211
 
 
1212
 
        ret = g_spawn_async_with_pipes( NULL, argv, NULL,
1213
 
                                                                        G_SPAWN_SEARCH_PATH/* |
1214
 
                                                                        G_SPAWN_STDOUT_TO_DEV_NULL |
1215
 
                                                                        G_SPAWN_STDERR_TO_DEV_NULL*/,
1216
 
                                                                        NULL, NULL, NULL, &img->file_desc,
1217
 
                                                                        NULL, NULL, &error );
1218
 
        if( ! ret )
 
1008
        GtkTreeSelection *sel;
 
1009
        GtkTreeModel     *model;
 
1010
        GtkTreeIter       iter1, iter2;
 
1011
 
 
1012
        /* We need path, since there is no gtk_tree_model_iter_prev function!! */
 
1013
        GtkTreePath      *path;
 
1014
 
 
1015
        /* First we need to get selected iter. This function won't work if
 
1016
         * selection's mode is set to GTK_SELECTION_MULTIPLE!! */
 
1017
        sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( img->music_file_treeview ) );
 
1018
        if( ! gtk_tree_selection_get_selected( sel, &model, &iter1 ) )
 
1019
                return;
 
1020
 
 
1021
        /* Now get previous iter and swap two items if previous iter exists. */
 
1022
        path = gtk_tree_model_get_path( model, &iter1 );
 
1023
        if( gtk_tree_path_prev( path ) )
1219
1024
        {
1220
 
                message = gtk_message_dialog_new (GTK_WINDOW (img->imagination_window),
1221
 
                                                                                GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1222
 
                                                                                GTK_MESSAGE_ERROR,
1223
 
                                                                                GTK_BUTTONS_CLOSE,
1224
 
                                                                                _("Failed to launch the encoder!"));
1225
 
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message),"%s.",error->message);
1226
 
                gtk_dialog_run (GTK_DIALOG (message));
1227
 
                gtk_widget_destroy (message);
1228
 
                g_error_free (error);
 
1025
                gtk_tree_model_get_iter( model, &iter2, path );
 
1026
                gtk_list_store_swap( GTK_LIST_STORE( model ), &iter1, &iter2 );
1229
1027
        }
1230
 
        g_strfreev( argv );
1231
 
 
1232
 
        return( ret );
1233
 
}
1234
 
 
1235
 
void img_set_buttons_state(img_window_struct *img, gboolean state)
1236
 
{
1237
 
        gtk_widget_set_sensitive(img->import_button,state);
1238
 
        gtk_widget_set_sensitive(img->import_menu,      state);
1239
 
        gtk_widget_set_sensitive(img->save_menu,        state);
1240
 
        gtk_widget_set_sensitive(img->save_as_menu,     state);
1241
 
        gtk_widget_set_sensitive(img->save_button,      state);
1242
 
        gtk_widget_set_sensitive(img->close_menu,       state);
1243
 
        gtk_widget_set_sensitive(img->properties_menu,  state);
1244
 
        gtk_widget_set_sensitive(img->preview_menu,     state);
1245
 
        gtk_widget_set_sensitive(img->preview_button,state);
1246
 
        gtk_widget_set_sensitive(img->export_menu,      state);
1247
 
        gtk_widget_set_sensitive(img->export_button,state);
1248
 
}
1249
 
 
1250
 
static void img_export_calc_slide_frames(img_window_struct *img)
1251
 
{
1252
 
 
1253
 
        /* This is fix for the progress bars. I forgot that slides with no
1254
 
         * transition effect shouldn't have transition time added.
1255
 
         * (I haven't caught that bug when testing because I created slideshow
1256
 
         * where each slide had transition effect set.) */
1257
 
        if( img->current_slide->render )
1258
 
                /* Duration + transition time */
1259
 
                img->export_slide_nr = ( img->current_slide->duration + img->current_slide->speed ) * EXPORT_FPS;
1260
 
        else
1261
 
                /* Duration only */
1262
 
                img->export_slide_nr = img->current_slide->duration * EXPORT_FPS;
1263
 
 
1264
 
        img->export_slide_cur = 0;
1265
 
}
1266
 
 
1267
 
static void img_export_pause_unpause(GtkToggleButton *button, img_window_struct *img)
1268
 
{
1269
 
        if( gtk_toggle_button_get_active( button ) )
1270
 
                /* Pause export */
1271
 
                g_source_remove( img->source_id );
1272
 
        else
1273
 
                img->source_id = g_idle_add(img->export_idle_func, img);
 
1028
        gtk_tree_path_free( path );
 
1029
}
 
1030
 
 
1031
void img_move_audio_down( GtkButton *button, img_window_struct *img )
 
1032
{
 
1033
        GtkTreeSelection *sel;
 
1034
        GtkTreeModel     *model;
 
1035
        GtkTreeIter       iter1, iter2;
 
1036
 
 
1037
        /* First we need to get selected iter. This function won't work if
 
1038
         * selection's mode is set to GTK_SELECTION_MULTIPLE!! */
 
1039
        sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( img->music_file_treeview ) );
 
1040
        if( ! gtk_tree_selection_get_selected( sel, &model, &iter1 ) )
 
1041
                return;
 
1042
 
 
1043
        /* Get next iter and swap rows if iter exists. */
 
1044
        iter2 = iter1;
 
1045
        if( gtk_tree_model_iter_next( model, &iter2 ) )
 
1046
                gtk_list_store_swap( GTK_LIST_STORE( model ), &iter1, &iter2 );
1274
1047
}