OSDN Git Service

LinGui: when reloading the queue, update the state of the "Show Queue" toggle
[handbrake-jp/handbrake-jp-git.git] / gtk / src / queuehandler.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * callbacks.c
4  * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
5  * 
6  * callbacks.c is free software.
7  * 
8  * You may redistribute it and/or modify it under the terms of the
9  * GNU General Public License, as published by the Free Software
10  * Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  */
13
14 #include <gtk/gtk.h>
15 #include <gdk/gdkkeysyms.h>
16 #include <glib/gstdio.h>
17 #include <gio/gio.h>
18 #include "hb.h"
19 #include "settings.h"
20 #include "hb-backend.h"
21 #include "values.h"
22 #include "callbacks.h"
23 #include "presets.h"
24 #include "ghb-dvd.h"
25
26 G_MODULE_EXPORT void
27 queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
28 {
29         GtkTreeModel *store;
30         GtkTreeIter iter, piter;
31         
32         g_debug("queue_list_selection_changed_cb ()");
33         // A queue entry is made up of a parent and multiple
34         // children that are visible when expanded.  When and entry
35         // is selected, I want the parent to be selected.
36         // This is purely cosmetic.
37         if (gtk_tree_selection_get_selected(selection, &store, &iter))
38         {
39                 GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_edit");
40                 gtk_widget_set_sensitive (widget, TRUE);
41                 if (gtk_tree_model_iter_parent (store, &piter, &iter))
42                 {
43                         GtkTreePath *path;
44                         GtkTreeView *treeview;
45                         
46                         gtk_tree_selection_select_iter (selection, &piter);
47                         path = gtk_tree_model_get_path (store, &piter);
48                         treeview = gtk_tree_selection_get_tree_view (selection);
49                         // Make the parent visible in scroll window if it is not.
50                         gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
51                         gtk_tree_path_free(path);
52                 }
53         }
54         else
55         {
56                 GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_edit");
57                 gtk_widget_set_sensitive (widget, FALSE);
58         }
59 }
60
61 static void
62 add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
63 {
64         GtkTreeView *treeview;
65         GtkTreeIter iter;
66         GtkTreeStore *store;
67         gchar *info;
68         gint status;
69         GtkTreeIter citer;
70         gchar *dest, *preset, *vol_name, *basename;
71         const gchar *vcodec, *container;
72         gchar *fps, *vcodec_abbr;
73         gint title, start_chapter, end_chapter, width, height;
74         gint source_width, source_height;
75         gboolean pass2, keep_aspect, vqtype, turbo;
76         gint pic_par;
77         gboolean tweaks;
78         gchar *escape;
79         
80         g_debug("update_queue_list ()");
81         if (settings == NULL) return;
82         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
83         store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
84                 
85         tweaks = ghb_settings_get_boolean(settings, "allow_tweaks");
86         title = ghb_settings_get_int(settings, "titlenum");
87         start_chapter = ghb_settings_get_int(settings, "start_chapter");
88         end_chapter = ghb_settings_get_int(settings, "end_chapter");
89         pass2 = ghb_settings_get_boolean(settings, "VideoTwoPass");
90         vol_name = ghb_settings_get_string(settings, "volume_label");
91         dest = ghb_settings_get_string(settings, "destination");
92         basename = g_path_get_basename(dest);
93         escape = g_markup_escape_text(basename, -1);
94         info = g_strdup_printf 
95         (
96                 "<big><b>%s</b></big> "
97                 "<small>(Title %d, Chapters %d through %d, %d Video %s)"
98                 " --> %s</small>",
99                  vol_name, title, start_chapter, end_chapter, 
100                  pass2 ? 2:1, pass2 ? "Passes":"Pass", escape
101         );
102         g_free(basename);
103         g_free(escape);
104
105         if (piter)
106                 iter = *piter;
107         else
108                 gtk_tree_store_append(store, &iter, NULL);
109
110         gtk_tree_store_set(store, &iter, 1, info, 2, "hb-queue-delete", -1);
111         g_free(info);
112         status = ghb_settings_get_int(settings, "job_status");
113         switch (status)
114         {
115                 case GHB_QUEUE_PENDING:
116                         gtk_tree_store_set(store, &iter, 0, "hb-queue-job", -1);
117                         break;
118                 case GHB_QUEUE_CANCELED:
119                         gtk_tree_store_set(store, &iter, 0, "hb-canceled", -1);
120                         break;
121                 case GHB_QUEUE_RUNNING:
122                         gtk_tree_store_set(store, &iter, 0, "hb-working0", -1);
123                         break;
124                 case GHB_QUEUE_DONE:
125                         gtk_tree_store_set(store, &iter, 0, "hb-complete", -1);
126                         break;
127                 default:
128                         gtk_tree_store_set(store, &iter, 0, "hb-queue-job", -1);
129                         break;
130         }
131
132         GString *str = g_string_new("");
133         gboolean markers;
134         gboolean preset_modified;
135         gint mux;
136         const GValue *path;
137
138         container = ghb_settings_combo_option(settings, "FileFormat");
139         mux = ghb_settings_combo_int(settings, "FileFormat");
140         preset_modified = ghb_settings_get_boolean(settings, "preset_modified");
141         path = ghb_settings_get_value(settings, "preset");
142         preset = ghb_preset_path_string(path);
143         markers = ghb_settings_get_boolean(settings, "ChapterMarkers");
144
145         if (preset_modified)
146                 g_string_append_printf(str, 
147                         "<b>Modified Preset Based On:</b> <small>%s</small>\n", 
148                         preset);
149         else
150                 g_string_append_printf(str, 
151                         "<b>Preset:</b> <small>%s</small>\n", 
152                         preset);
153
154         if (markers)
155         {
156                 g_string_append_printf(str, 
157                         "<b>Format:</b> <small>%s Container, Chapter Markers</small>\n", 
158                         container);
159         }
160         else
161         {
162                 g_string_append_printf(str, 
163                         "<b>Format:</b> <small>%s Container</small>\n", container);
164         }
165         if (mux == HB_MUX_MP4)
166         {
167                 gboolean ipod, http, large;
168
169                 ipod = ghb_settings_get_boolean(settings, "Mp4iPodCompatible");
170                 http = ghb_settings_get_boolean(settings, "Mp4HttpOptimize");
171                 large = ghb_settings_get_boolean(settings, "Mp4LargeFile");
172                 if (http || ipod || large)
173                 {
174                         g_string_append_printf(str, "<b>MP4 Options:</b><small>");
175                         if (ipod)
176                                 g_string_append_printf(str, " - iPod 5G Support");
177                         if (http)
178                                 g_string_append_printf(str, " - Web Optimized");
179                         if (large)
180                                 g_string_append_printf(str, " - Large File Size (>4GB)");
181                         g_string_append_printf(str, "</small>\n");
182                 }
183         }
184         escape = g_markup_escape_text(dest, -1);
185         g_string_append_printf(str, 
186                 "<b>Destination:</b> <small>%s</small>\n", escape);
187
188         width = ghb_settings_get_int(settings, "scale_width");
189         height = ghb_settings_get_int(settings, "scale_height");
190         pic_par = ghb_settings_combo_int(settings, "PicturePAR");
191         keep_aspect = ghb_settings_get_boolean(settings, "PictureKeepRatio");
192
193         gchar *aspect_desc;
194         switch (pic_par)
195         {
196         case 0:
197         {
198                 if (keep_aspect)
199                 {
200                         aspect_desc = "(Aspect Preserved)";
201                 }
202                 else
203                 {
204                         aspect_desc = "(Aspect Lost)";
205                 }
206         } break;
207
208         case 1:
209         {
210                 aspect_desc = "(Strict Anamorphic)";
211         } break;
212
213         case 2:
214         {
215                 aspect_desc = "(Loose Anamorphic)";
216         } break;
217
218         case 3:
219         {
220                 aspect_desc = "(Custom Anamorphic)";
221         } break;
222
223         default:
224         {
225                 aspect_desc = "(Unknown)";
226         } break;
227         }
228         vqtype = ghb_settings_get_boolean(settings, "vquality_type_constant");
229
230         gchar *vq_desc = "Error";
231         gchar *vq_units = "";
232         gchar *vqstr;
233         gdouble vqvalue;
234         if (!vqtype)
235         {
236                 vqtype = ghb_settings_get_boolean(settings, "vquality_type_target");
237                 if (!vqtype)
238                 {
239                         // Has to be bitrate
240                         vqvalue = ghb_settings_get_int(settings, "VideoAvgBitrate");
241                         vq_desc = "Bitrate:";
242                         vq_units = "kbps";
243                 }
244                 else
245                 {
246                         // Target file size
247                         vqvalue = ghb_settings_get_int(settings, "VideoTargetSize");
248                         vq_desc = "Target Size:";
249                         vq_units = "MB";
250                 }
251                 vqstr = g_strdup_printf("%d", (gint)vqvalue);
252         }
253         else
254         {
255                 // Constant quality
256                 vqvalue = ghb_settings_get_double(settings, "VideoQualitySlider");
257                 vq_desc = "Constant Quality:";
258                 vqstr = g_strdup_printf("%d", (gint)vqvalue);
259                 vq_units = "(crf)";
260         }
261         fps = ghb_settings_get_string(settings, "VideoFramerate");
262         if (strcmp("source", fps) == 0)
263         {
264                 g_free(fps);
265                 if (ghb_settings_combo_int(settings, "PictureDetelecine"))
266                         fps = g_strdup("Same As Source (vfr detelecine)");
267                 else
268                         fps = g_strdup("Same As Source (variable)");
269         }
270         else
271         {
272                 gchar *tmp;
273                 tmp = g_strdup_printf("%s (constant frame rate)", fps);
274                 g_free(fps);
275                 fps = tmp;
276         }
277         vcodec = ghb_settings_combo_option(settings, "VideoEncoder");
278         vcodec_abbr = ghb_settings_get_string(settings, "VideoEncoder");
279         source_width = ghb_settings_get_int(settings, "source_width");
280         source_height = ghb_settings_get_int(settings, "source_height");
281         g_string_append_printf(str,
282                 "<b>Picture:</b> Source: <small>%d x %d, Output %d x %d %s</small>\n",
283                  source_width, source_height, width, height, aspect_desc);
284
285         gint decomb, detel;
286         gboolean decomb_deint;
287         gboolean filters = FALSE;
288
289         decomb_deint = ghb_settings_get_boolean(settings, "PictureDecombDeinterlace");
290         decomb = ghb_settings_combo_int(settings, "PictureDecomb");
291         g_string_append_printf(str, "<b>Filters:</b><small>");
292         detel = ghb_settings_combo_int(settings, "PictureDetelecine");
293         if (detel)
294         {
295                 g_string_append_printf(str, " - Detelecine");
296                 if (detel == 1)
297                 {
298                         gchar *cust;
299                         cust = ghb_settings_get_string(settings, "PictureDetelecineCustom");
300                         g_string_append_printf(str, ": %s", cust);
301                         g_free(cust);
302                 }
303                 filters = TRUE;
304         }
305         if (decomb_deint && decomb)
306         {
307                 g_string_append_printf(str, " - Decomb");
308                 if (decomb == 1)
309                 {
310                         gchar *cust;
311                         cust = ghb_settings_get_string(settings, "PictureDecombCustom");
312                         g_string_append_printf(str, ": %s", cust);
313                         g_free(cust);
314                 }
315                 filters = TRUE;
316         }
317         else if (!decomb_deint)
318         {
319                 gint deint = ghb_settings_combo_int(settings, "PictureDeinterlace");
320                 if (deint)
321                 {
322                         if (deint == 1)
323                         {
324                                 gchar *cust = ghb_settings_get_string(settings,
325                                                                                                 "PictureDeinterlaceCustom");
326                                 g_string_append_printf(str, " - Deinterlace: %s", cust);
327                                 g_free(cust);
328                         }
329                         else
330                         {
331                                 const gchar *opt = ghb_settings_combo_option(settings,
332                                                                                                         "PictureDeinterlace");
333                                 g_string_append_printf(str, " - Deinterlace: %s", opt);
334                         }
335                         filters = TRUE;
336                 }
337         }
338         gint denoise = ghb_settings_combo_int(settings, "PictureDenoise");
339         if (denoise)
340         {
341                 if (denoise == 1)
342                 {
343                         gchar *cust = ghb_settings_get_string(settings,
344                                                                                                         "PictureDenoiseCustom");
345                         g_string_append_printf(str, " - Denoise: %s", cust);
346                         g_free(cust);
347                 }
348                 else
349                 {
350                         const gchar *opt = ghb_settings_combo_option(settings,
351                                                                                                         "PictureDenoise");
352                         g_string_append_printf(str, " - Denoise: %s", opt);
353                 }
354                 filters = TRUE;
355         }
356         gint deblock = ghb_settings_get_int(settings, "PictureDeblock");
357         if (deblock >= 5)
358         {
359                 g_string_append_printf(str, " - Deblock (%d)", deblock);
360                 filters = TRUE;
361         }
362         if (ghb_settings_get_boolean(settings, "VideoGrayScale"))
363         {
364                 g_string_append_printf(str, " - Grayscale");
365                 filters = TRUE;
366         }
367         if (!filters)
368                 g_string_append_printf(str, " None");
369         g_string_append_printf(str, "</small>\n");
370
371         g_string_append_printf(str,
372                 "<b>Video:</b> <small>%s, Framerate: %s, %s %s%s</small>\n",
373                  vcodec, fps, vq_desc, vqstr, vq_units);
374
375         turbo = ghb_settings_get_boolean(settings, "VideoTurboTwoPass");
376         if (turbo)
377         {
378                 g_string_append_printf(str, "<b>Turbo:</b> <small>On</small>\n");
379         }
380         if (strcmp(vcodec_abbr, "x264") == 0)
381         {
382                 gchar *x264opts = ghb_build_x264opts_string(settings);
383                 g_string_append_printf(str, 
384                         "<b>x264 Options:</b> <small>%s</small>\n", x264opts);
385                 g_free(x264opts);
386         }
387         // Add the audios
388         gint count, ii;
389         const GValue *audio_list;
390
391         audio_list = ghb_settings_get_value(settings, "audio_list");
392         count = ghb_array_len(audio_list);
393         for (ii = 0; ii < count; ii++)
394         {
395                 gchar *bitrate, *samplerate, *track;
396                 const gchar *acodec, *mix;
397                 GValue *asettings;
398
399                 asettings = ghb_array_get_nth(audio_list, ii);
400
401                 acodec = ghb_settings_combo_option(asettings, "AudioEncoder");
402                 bitrate = ghb_settings_get_string(asettings, "AudioBitrate");
403                 samplerate = ghb_settings_get_string(asettings, "AudioSamplerate");
404                 if (strcmp("source", samplerate) == 0)
405                 {
406                         g_free(samplerate);
407                         samplerate = g_strdup("Same As Source");
408                 }
409                 track = ghb_settings_get_string(asettings, "AudioTrackDescription");
410                 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
411                 if (count == 1)
412                         g_string_append_printf(str, "<b>Audio:</b>");
413                 else if (ii == 0)
414                         g_string_append_printf(str, "<b>Audio:</b>\n");
415                 if (count != 1)
416                         g_string_append_printf(str, "\t");
417
418                 g_string_append_printf(str,
419                         "<small> %s, Encoder: %s, Mixdown: %s, SampleRate: %s, Bitrate: %s</small>\n",
420                          track, acodec, mix, samplerate, bitrate);
421                 g_free(track);
422                 g_free(bitrate);
423                 g_free(samplerate);
424         }
425
426         // Add the audios
427         const GValue *sub_list;
428
429         sub_list = ghb_settings_get_value(settings, "subtitle_list");
430         count = ghb_array_len(sub_list);
431         for (ii = 0; ii < count; ii++)
432         {
433                 GValue *settings;
434                 gchar *track;
435                 gboolean force, burn, def;
436                 gint source;
437
438                 settings = ghb_array_get_nth(sub_list, ii);
439                 track = ghb_settings_get_string(settings, "SubtitleTrackDescription");
440                 source = ghb_settings_get_int(settings, "SubtitleSource");
441                 force = ghb_settings_get_boolean(settings, "SubtitleForced");
442                 burn = ghb_settings_get_boolean(settings, "SubtitleBurned");
443                 def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
444                 if (count == 1)
445                         g_string_append_printf(str, "<b>Subtitle:</b>");
446                 else if (ii == 0)
447                         g_string_append_printf(str, "<b>Subtitles:</b>\n");
448                 if (count != 1)
449                         g_string_append_printf(str, "\t");
450
451                 if (source != SRTSUB)
452                 {
453                         g_string_append_printf(str,
454                                 "<small> %s%s%s%s</small>",
455                                 track, 
456                                 force ? " (Force)":"",
457                                 burn  ? " (Burn)":"",
458                                 def   ? " (Default)":""
459                         );
460                 }
461                 else
462                 {
463                         gint offset;
464                         gchar *filename, *basename, *code;
465
466                         offset = ghb_settings_get_int(settings, "SrtOffset");
467                         filename = ghb_settings_get_string(settings, "SrtFile");
468                         basename = g_path_get_basename(filename);
469                         code = ghb_settings_get_string(settings, "SrtCodeset");
470                         g_string_append_printf(str,
471                                 "<small> %s (%s), %s, Offset (ms) %d%s</small>",
472                                 track, code, basename, offset,
473                                 def   ? " (Default)":""
474                         );
475                         g_free(filename);
476                         g_free(basename);
477                         g_free(code);
478                 }
479                 if (ii < count-1)
480                         g_string_append_printf(str, "\n");
481                 g_free(track);
482         }
483
484         info = g_string_free(str, FALSE);
485         gtk_tree_store_append(store, &citer, &iter);
486         gtk_tree_store_set(store, &citer, 1, info, -1);
487         g_free(info);
488         g_free(fps);
489         g_free(vcodec_abbr);
490         g_free(vol_name);
491         g_free(dest);
492         g_free(preset);
493 }
494
495 void
496 audio_list_refresh(signal_user_data_t *ud)
497 {
498         GtkTreeView *treeview;
499         GtkTreeIter iter;
500         GtkListStore *store;
501         gboolean done;
502         gint row = 0;
503         const GValue *audio_list;
504
505         g_debug("ghb_audio_list_refresh ()");
506         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
507         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
508         if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
509         {
510                 do
511                 {
512                         const gchar *track, *codec, *br, *sr, *mix;
513                         gchar *drc, *s_track, *s_codec, *s_br, *s_sr, *s_mix;
514                         gint itrack, icodec;
515                         gdouble s_drc;
516                         GValue *asettings;
517
518                         audio_list = ghb_settings_get_value(ud->settings, "audio_list");
519                         if (row >= ghb_array_len(audio_list))
520                                 return;
521                         asettings = ghb_array_get_nth(audio_list, row);
522
523                         track = ghb_settings_combo_option(asettings, "AudioTrack");
524                         itrack = ghb_settings_combo_int(asettings, "AudioTrack");
525                         codec = ghb_settings_combo_option(asettings, "AudioEncoder");
526                         icodec = ghb_settings_combo_int(asettings, "AudioEncoder");
527                         br = ghb_settings_combo_option(asettings, "AudioBitrate");
528                         sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
529                         mix = ghb_settings_combo_option(asettings, "AudioMixdown");
530
531                         s_track = ghb_settings_get_string(asettings, "AudioTrack");
532                         s_codec = ghb_settings_get_string(asettings, "AudioEncoder");
533                         s_br = ghb_settings_get_string(asettings, "AudioBitrate");
534                         s_sr = ghb_settings_get_string(asettings, "AudioSamplerate");
535                         s_mix = ghb_settings_get_string(asettings, "AudioMixdown");
536                         s_drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
537                         if (s_drc < 1.0)
538                                 drc = g_strdup("Off");
539                         else
540                                 drc = g_strdup_printf("%.1f", s_drc);
541
542                         if (icodec == HB_ACODEC_MASK)
543                                 codec = ghb_select_audio_codec_str(ud, itrack);
544
545                         gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
546                                 // These are displayed in list
547                                 0, track,
548                                 1, codec,
549                                 2, br,
550                                 3, sr,
551                                 4, mix,
552                                 5, drc,
553                                 // These are used to set combo values when an item is selected
554                                 6, s_track,
555                                 7, s_codec,
556                                 8, s_br,
557                                 9, s_sr,
558                                 10, s_mix,
559                                 11, s_drc,
560                                 -1);
561                         g_free(drc);
562                         g_free(s_track);
563                         g_free(s_codec);
564                         g_free(s_br);
565                         g_free(s_sr);
566                         g_free(s_mix);
567                         done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
568                         row++;
569                 } while (!done);
570         }
571 }
572
573 static gboolean
574 validate_settings(signal_user_data_t *ud)
575 {
576         // Check to see if the dest file exists or is
577         // already in the queue
578         gchar *message, *dest;
579         gint count, ii;
580         gint titleindex;
581
582         titleindex = ghb_settings_combo_int(ud->settings, "title");
583         if (titleindex < 0) return FALSE;
584         dest = ghb_settings_get_string(ud->settings, "destination");
585         count = ghb_array_len(ud->queue);
586         for (ii = 0; ii < count; ii++)
587         {
588                 GValue *js;
589                 gchar *filename;
590
591                 js = ghb_array_get_nth(ud->queue, ii);
592                 filename = ghb_settings_get_string(js, "destination");
593                 if (strcmp(dest, filename) == 0)
594                 {
595                         message = g_strdup_printf(
596                                                 "Destination: %s\n\n"
597                                                 "Another queued job has specified the same destination.\n"
598                                                 "Do you want to overwrite?",
599                                                 dest);
600                         if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
601                         {
602                                 g_free(filename);
603                                 g_free(dest);
604                                 g_free(message);
605                                 return FALSE;
606                         }
607                         g_free(message);
608                         break;
609                 }
610                 g_free(filename);
611         }
612         gchar *destdir = g_path_get_dirname(dest);
613         if (!g_file_test(destdir, G_FILE_TEST_IS_DIR))
614         {
615                 message = g_strdup_printf(
616                                         "Destination: %s\n\n"
617                                         "This is not a valid directory.",
618                                         destdir);
619                 ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
620                 g_free(dest);
621                 g_free(message);
622                 g_free(destdir);
623                 return FALSE;
624         }
625 #if !defined(_WIN32)
626         // This doesn't work properly on windows
627         if (g_access(destdir, R_OK|W_OK) != 0)
628         {
629                 message = g_strdup_printf(
630                                         "Destination: %s\n\n"
631                                         "Can not read or write the directory.",
632                                         destdir);
633                 ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
634                 g_free(dest);
635                 g_free(message);
636                 g_free(destdir);
637                 return FALSE;
638         }
639 #endif
640         GFile *gfile;
641         GFileInfo *info;
642         guint64 size;
643         gchar *resolved = ghb_resolve_symlink(destdir);
644
645         gfile = g_file_new_for_path(resolved);
646         info = g_file_query_filesystem_info(gfile, 
647                                                 G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, NULL);
648         if (info != NULL)
649         {
650                 if (g_file_info_has_attribute(info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE))
651                 {
652                         size = g_file_info_get_attribute_uint64(info, 
653                                                                         G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
654                         
655                         gint64 fsize = (guint64)10 * 1024 * 1024 * 1024;
656                         if (size < fsize)
657                         {
658                                 message = g_strdup_printf(
659                                                         "Destination filesystem is almost full: %uM free\n\n"
660                                                         "Encode may be incomplete if you proceed.\n",
661                                                         (guint)(size / (1024L*1024L)));
662                                 if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Proceed"))
663                                 {
664                                         g_free(dest);
665                                         g_free(message);
666                                         return FALSE;
667                                 }
668                                 g_free(message);
669                         }
670                 }
671                 g_object_unref(info);
672         }
673         g_object_unref(gfile);
674         g_free(resolved);
675         g_free(destdir);
676         if (g_file_test(dest, G_FILE_TEST_EXISTS))
677         {
678                 message = g_strdup_printf(
679                                         "Destination: %s\n\n"
680                                         "File already exists.\n"
681                                         "Do you want to overwrite?",
682                                         dest);
683                 if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
684                 {
685                         g_free(dest);
686                         g_free(message);
687                         return FALSE;
688                 }
689                 g_free(message);
690                 g_unlink(dest);
691         }
692         g_free(dest);
693         // Validate video quality is in a reasonable range
694         if (!ghb_validate_vquality(ud->settings))
695         {
696                 return FALSE;
697         }
698         // Validate audio settings
699         if (!ghb_validate_audio(ud))
700         {
701                 return FALSE;
702         }
703         // Validate audio settings
704         if (!ghb_validate_subtitles(ud))
705         {
706                 return FALSE;
707         }
708         // Validate video settings
709         if (!ghb_validate_video(ud))
710         {
711                 return FALSE;
712         }
713         // Validate filter settings
714         if (!ghb_validate_filters(ud))
715         {
716                 return FALSE;
717         }
718         audio_list_refresh(ud);
719         return TRUE;
720 }
721
722 static gboolean
723 queue_add(signal_user_data_t *ud)
724 {
725         // Add settings to the queue
726         GValue *settings;
727         gint titleindex;
728         gint titlenum;
729         
730         g_debug("queue_add ()");
731         if (!validate_settings(ud))
732         {
733                 return FALSE;
734         }
735
736         if (ud->queue == NULL)
737                 ud->queue = ghb_array_value_new(32);
738         // Make a copy of current settings to be used for the new job
739         settings = ghb_value_dup(ud->settings);
740         ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
741         ghb_settings_set_int(settings, "job_unique_id", 0);
742         titleindex = ghb_settings_combo_int(settings, "title");
743         titlenum = ghb_get_title_number(titleindex);
744         ghb_settings_set_int(settings, "titlenum", titlenum);
745         ghb_array_append(ud->queue, settings);
746         add_to_queue_list(ud, settings, NULL);
747         ghb_save_queue(ud->queue);
748         ghb_update_pending(ud);
749
750         return TRUE;
751 }
752
753 G_MODULE_EXPORT void
754 queue_add_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
755 {
756         g_debug("queue_add_clicked_cb ()");
757         queue_add(ud);
758 }
759
760 G_MODULE_EXPORT void
761 queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
762 {
763         GtkTreeView *treeview;
764         GtkTreePath *treepath;
765         GtkTreeModel *store;
766         GtkTreeIter iter;
767         gint row;
768         gint *indices;
769         gint unique_id;
770         GValue *settings;
771         gint status;
772
773         g_debug("queue_remove_clicked_cb ()");
774         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
775         store = gtk_tree_view_get_model(treeview);
776         treepath = gtk_tree_path_new_from_string (path);
777         if (gtk_tree_path_get_depth(treepath) > 1) return;
778         if (gtk_tree_model_get_iter(store, &iter, treepath))
779         {
780                 // Find the entry in the queue
781                 indices = gtk_tree_path_get_indices (treepath);
782                 row = indices[0];
783                 // Can only free the treepath After getting what I need from
784                 // indices since this points into treepath somewhere.
785                 gtk_tree_path_free (treepath);
786                 if (row < 0) return;
787                 if (row >= ghb_array_len(ud->queue))
788                         return;
789                 settings = ghb_array_get_nth(ud->queue, row);
790                 status = ghb_settings_get_int(settings, "job_status");
791                 if (status == GHB_QUEUE_RUNNING)
792                 {
793                         // Ask if wants to stop encode.
794                         if (!ghb_cancel_encode2(ud, NULL))
795                         {
796                                 return;
797                         }
798                         unique_id = ghb_settings_get_int(settings, "job_unique_id");
799                         ghb_remove_job(unique_id);
800                 }
801                 // Remove the selected item
802                 gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
803                 // Remove the corresponding item from the queue list
804                 GValue *old = ghb_array_get_nth(ud->queue, row);
805                 ghb_value_free(old);
806                 ghb_array_remove(ud->queue, row);
807                 ghb_save_queue(ud->queue);
808         }
809         else
810         {       
811                 gtk_tree_path_free (treepath);
812         }
813         ghb_update_pending(ud);
814 }
815
816 static gint
817 find_last_finished(GValue *queue)
818 {
819         GValue *js;
820         gint ii, count;
821         gint status;
822         
823         g_debug("find_last_finished");
824         count = ghb_array_len(queue);
825         for (ii = 0; ii < count; ii++)
826         {
827                 js = ghb_array_get_nth(queue, ii);
828                 status = ghb_settings_get_int(js, "job_status");
829                 if (status != GHB_QUEUE_DONE && status != GHB_QUEUE_RUNNING)
830                 {
831                         return ii-1;
832                 }
833         }
834         return -1;
835 }
836
837 // This little bit is needed to prevent the default drag motion
838 // handler from expanding rows if you hover over them while
839 // dragging.
840 // Also controls where valid drop locations are
841 G_MODULE_EXPORT gboolean
842 queue_drag_motion_cb(
843         GtkTreeView *tv,
844         GdkDragContext *ctx,
845         gint x,
846         gint y,
847         guint time,
848         signal_user_data_t *ud)
849 {
850         GtkTreePath *path = NULL;
851         GtkTreeViewDropPosition pos;
852         gint *indices, row, status, finished;
853         GValue *js;
854         GtkTreeIter iter;
855         GtkTreeView *srctv;
856         GtkTreeModel *model;
857         GtkTreeSelection *select;
858         GtkWidget *widget;
859
860         widget = gtk_drag_get_source_widget(ctx);
861         if (widget == NULL || widget != GTK_WIDGET(tv))
862                 return TRUE;
863
864         // This bit checks to see if the source is allowed to be
865         // moved.  Only pending and canceled items may be moved.
866         srctv = GTK_TREE_VIEW(gtk_drag_get_source_widget(ctx));
867         select = gtk_tree_view_get_selection (srctv);
868         gtk_tree_selection_get_selected (select, &model, &iter);
869         path = gtk_tree_model_get_path (model, &iter);
870         indices = gtk_tree_path_get_indices(path);
871         row = indices[0];
872         gtk_tree_path_free(path);
873         js = ghb_array_get_nth(ud->queue, row);
874         status = ghb_settings_get_int(js, "job_status");
875         if (status != GHB_QUEUE_PENDING && status != GHB_QUEUE_CANCELED)
876         {
877                 gdk_drag_status(ctx, 0, time);
878                 return TRUE;
879         }
880
881         // The reset checks that the destination is a valid position
882         // in the list.  Can not move above any finished or running items
883         gtk_tree_view_get_dest_row_at_pos (tv, x, y, &path, &pos);
884         if (path == NULL)
885         {
886                 gdk_drag_status(ctx, GDK_ACTION_MOVE, time);
887                 return TRUE;
888         }
889         // Don't allow *drop into*
890         if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)
891                 pos = GTK_TREE_VIEW_DROP_BEFORE;
892         if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
893                 pos = GTK_TREE_VIEW_DROP_AFTER;
894         // Don't allow droping int child items
895         if (gtk_tree_path_get_depth(path) > 1)
896         {
897                 gtk_tree_path_up(path);
898                 pos = GTK_TREE_VIEW_DROP_AFTER;
899         }
900         indices = gtk_tree_path_get_indices(path);
901         row = indices[0];
902         js = ghb_array_get_nth(ud->queue, row);
903
904         finished = find_last_finished(ud->queue);
905         if (row < finished)
906         {
907                 gtk_tree_path_free(path);
908                 gdk_drag_status(ctx, 0, time);
909                 return TRUE;
910         }
911         if (pos != GTK_TREE_VIEW_DROP_AFTER && 
912                 row == finished)
913         {
914                 gtk_tree_path_free(path);
915                 gdk_drag_status(ctx, 0, time);
916                 return TRUE;
917         }
918         gtk_tree_view_set_drag_dest_row(tv, path, pos);
919         gtk_tree_path_free(path);
920         gdk_drag_status(ctx, GDK_ACTION_MOVE, time);
921         return TRUE;
922 }
923
924 G_MODULE_EXPORT void 
925 queue_drag_cb(
926         GtkTreeView *dstwidget, 
927         GdkDragContext *dc, 
928         gint x, gint y, 
929         GtkSelectionData *selection_data, 
930         guint info, guint t, 
931         signal_user_data_t *ud)
932 {
933         GtkTreePath *path = NULL;
934         //GtkTreeModel *model;
935         GtkTreeViewDropPosition pos;
936         GtkTreeIter dstiter, srciter;
937         gint *indices, row;
938         GValue *js;
939         
940         GtkTreeModel *dstmodel = gtk_tree_view_get_model(dstwidget);
941                         
942         g_debug("queue_drag_cb ()");
943         // This doesn't work here for some reason...
944         // gtk_tree_view_get_drag_dest_row(dstwidget, &path, &pos);
945         gtk_tree_view_get_dest_row_at_pos (dstwidget, x, y, &path, &pos);
946         // This little hack is needed because attempting to drop after
947         // the last item gives us no path or pos.
948         if (path == NULL)
949         {
950                 gint n_children;
951
952                 n_children = gtk_tree_model_iter_n_children(dstmodel, NULL);
953                 if (n_children)
954                 {
955                         pos = GTK_TREE_VIEW_DROP_AFTER;
956                         path = gtk_tree_path_new_from_indices(n_children-1, -1);
957                 }
958                 else
959                 {
960                         pos = GTK_TREE_VIEW_DROP_BEFORE;
961                         path = gtk_tree_path_new_from_indices(0, -1);
962                 }
963         }
964         if (path)
965         {
966                 if (gtk_tree_path_get_depth(path) > 1)
967                         gtk_tree_path_up(path);
968                 if (gtk_tree_model_get_iter (dstmodel, &dstiter, path))
969                 {
970                         GtkTreeIter iter;
971                         GtkTreeView *srcwidget;
972                         GtkTreeModel *srcmodel;
973                         GtkTreeSelection *select;
974                         GtkTreePath *srcpath = NULL;
975                         GtkTreePath *dstpath = NULL;
976
977                         srcwidget = GTK_TREE_VIEW(gtk_drag_get_source_widget(dc));
978                         //srcmodel = gtk_tree_view_get_model(srcwidget);
979                         select = gtk_tree_view_get_selection (srcwidget);
980                         gtk_tree_selection_get_selected (select, &srcmodel, &srciter);
981
982                         srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
983                         indices = gtk_tree_path_get_indices(srcpath);
984                         row = indices[0];
985                         gtk_tree_path_free(srcpath);
986                         js = ghb_array_get_nth(ud->queue, row);
987
988                         switch (pos)
989                         {
990                                 case GTK_TREE_VIEW_DROP_BEFORE:
991                                 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
992                                         gtk_tree_store_insert_before (GTK_TREE_STORE (dstmodel), 
993                                                                                                         &iter, NULL, &dstiter);
994                                         break;
995
996                                 case GTK_TREE_VIEW_DROP_AFTER:
997                                 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
998                                         gtk_tree_store_insert_after (GTK_TREE_STORE (dstmodel), 
999                                                                                                         &iter, NULL, &dstiter);
1000                                         break;
1001
1002                                 default:
1003                                         break;
1004                         }
1005                         // Reset job to pending
1006                         ghb_settings_set_int(js, "job_status", GHB_QUEUE_PENDING);
1007                         add_to_queue_list(ud, js, &iter);
1008
1009                         dstpath = gtk_tree_model_get_path (dstmodel, &iter);
1010                         indices = gtk_tree_path_get_indices(dstpath);
1011                         row = indices[0];
1012                         gtk_tree_path_free(dstpath);
1013                         ghb_array_insert(ud->queue, row, js);
1014
1015                         srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
1016                         indices = gtk_tree_path_get_indices(srcpath);
1017                         row = indices[0];
1018                         gtk_tree_path_free(srcpath);
1019                         ghb_array_remove(ud->queue, row);
1020                         gtk_tree_store_remove (GTK_TREE_STORE (srcmodel), &srciter);
1021                         ghb_save_queue(ud->queue);
1022                 }
1023                 gtk_tree_path_free(path);
1024         }
1025 }
1026
1027 void
1028 ghb_queue_buttons_grey(signal_user_data_t *ud)
1029 {
1030         GtkWidget *widget;
1031         GtkAction *action;
1032         gint queue_count;
1033         gint titleindex;
1034         gint queue_state, scan_state;
1035         gboolean show_start, show_stop, paused;
1036
1037         queue_count = ghb_array_len(ud->queue);
1038         titleindex = ghb_settings_combo_int(ud->settings, "title");
1039
1040         queue_state = ghb_get_queue_state();
1041         scan_state = ghb_get_scan_state();
1042
1043         show_stop = queue_state & 
1044                                 (GHB_STATE_WORKING | GHB_STATE_SCANNING | GHB_STATE_MUXING);
1045         show_start = !(scan_state & GHB_STATE_SCANNING) && 
1046                                         (titleindex >= 0 || queue_count > 0);
1047
1048
1049         paused = queue_state & GHB_STATE_PAUSED;
1050
1051         widget = GHB_WIDGET (ud->builder, "queue_start1");
1052         if (show_stop)
1053         {
1054                 gtk_widget_set_sensitive (widget, TRUE);
1055                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
1056                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop");
1057                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Encoding");
1058         }
1059         else
1060         {
1061                 gtk_widget_set_sensitive (widget, show_start);
1062                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-play");
1063                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Start");
1064                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Start Encoding");
1065         }
1066         widget = GHB_WIDGET (ud->builder, "queue_start2");
1067         if (show_stop)
1068         {
1069                 gtk_widget_set_sensitive (widget, TRUE);
1070                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
1071                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop");
1072                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Encoding");
1073         }
1074         else
1075         {
1076                 gtk_widget_set_sensitive (widget, show_start);
1077                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-play");
1078                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Start");
1079                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Start Encoding");
1080         }
1081         widget = GHB_WIDGET (ud->builder, "queue_pause1");
1082         if (paused)
1083         {
1084                 gtk_widget_set_sensitive (widget, show_stop);
1085                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-play");
1086                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Resume");
1087                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Resume Encoding");
1088         }
1089         else
1090         {
1091                 gtk_widget_set_sensitive (widget, show_stop);
1092                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-pause");
1093                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Pause");
1094                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Pause Encoding");
1095         }
1096         widget = GHB_WIDGET (ud->builder, "queue_pause2");
1097         if (paused)
1098         {
1099                 gtk_widget_set_sensitive (widget, show_stop);
1100                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-play");
1101                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Resume");
1102                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Resume Encoding");
1103         }
1104         else
1105         {
1106                 gtk_widget_set_sensitive (widget, show_stop);
1107                 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-pause");
1108                 gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Pause");
1109                 gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Pause Encoding");
1110         }
1111
1112         action = GHB_ACTION (ud->builder, "queue_start_menu");
1113         if (show_stop)
1114         {
1115                 gtk_action_set_sensitive (action, TRUE);
1116 #if GTK_CHECK_VERSION(2, 16, 0)
1117                 gtk_action_set_icon_name(action, "hb-stop");
1118                 gtk_action_set_label(action, "S_top Queue");
1119                 gtk_action_set_tooltip(action, "Stop Encoding");
1120 #else
1121                 g_object_set_property(G_OBJECT(action), "icon-name", 
1122                                                                                         ghb_string_value("hb-stop"));
1123                 g_object_set_property(G_OBJECT(action), "label",
1124                                                                                         ghb_string_value("S_top Queue"));
1125                 g_object_set_property(G_OBJECT(action), "tooltip",
1126                                                                                         ghb_string_value("Stop Encoding"));
1127 #endif
1128         }
1129         else
1130         {
1131                 gtk_action_set_sensitive (action, show_start);
1132 #if GTK_CHECK_VERSION(2, 16, 0)
1133                 gtk_action_set_icon_name(action, "hb-play");
1134                 gtk_action_set_label(action, "_Start Queue");
1135                 gtk_action_set_tooltip(action, "Start Encoding");
1136 #else
1137                 g_object_set_property(G_OBJECT(action), "icon-name", 
1138                                                                                         ghb_string_value("hb-play"));
1139                 g_object_set_property(G_OBJECT(action), "label",
1140                                                                                         ghb_string_value("_Start Queue"));
1141                 g_object_set_property(G_OBJECT(action), "tooltip",
1142                                                                                         ghb_string_value("Start Encoding"));
1143 #endif
1144         }
1145         action = GHB_ACTION (ud->builder, "queue_pause_menu");
1146         if (paused)
1147         {
1148                 gtk_action_set_sensitive (action, show_start);
1149 #if GTK_CHECK_VERSION(2, 16, 0)
1150                 gtk_action_set_icon_name(action, "hb-play");
1151                 gtk_action_set_label(action, "_Resume Queue");
1152                 gtk_action_set_tooltip(action, "Resume Encoding");
1153 #else
1154                 g_object_set_property(G_OBJECT(action), "icon-name", 
1155                                                                                 ghb_string_value("hb-play"));
1156                 g_object_set_property(G_OBJECT(action), "label",
1157                                                                                 ghb_string_value("_Resume Queue"));
1158                 g_object_set_property(G_OBJECT(action), "tooltip",
1159                                                                                 ghb_string_value("Resume Encoding"));
1160 #endif
1161         }
1162         else
1163         {
1164                 gtk_action_set_sensitive (action, show_stop);
1165 #if GTK_CHECK_VERSION(2, 16, 0)
1166                 gtk_action_set_icon_name(action, "hb-pause");
1167                 gtk_action_set_label(action, "_Pause Queue");
1168                 gtk_action_set_tooltip(action, "Pause Encoding");
1169 #else
1170                 g_object_set_property(G_OBJECT(action), "icon-name", 
1171                                                                                 ghb_string_value("hb-pause"));
1172                 g_object_set_property(G_OBJECT(action), "label",
1173                                                                                 ghb_string_value("_Pause Queue"));
1174                 g_object_set_property(G_OBJECT(action), "tooltip",
1175                                                                                 ghb_string_value("Pause Encoding"));
1176 #endif
1177         }
1178 }
1179
1180 G_MODULE_EXPORT void
1181 queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCellRenderer *cell)
1182 {
1183         GtkTreeViewColumn *column;
1184         gint width;
1185         
1186         column = gtk_tree_view_get_column (GTK_TREE_VIEW(widget), 0);
1187         width = gtk_tree_view_column_get_width(column);
1188         g_debug("col width %d alloc width %d", width, allocation->width);
1189         // Set new wrap-width.  Shave a little off to accomidate the icons
1190         // that share this column.
1191         if (width >= 564) // Don't allow below a certain size
1192                 g_object_set(cell, "wrap-width", width-70, NULL);
1193 }
1194
1195 G_MODULE_EXPORT void
1196 queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1197 {
1198         GValue *js;
1199         gboolean running = FALSE;
1200         gint count, ii;
1201         gint status;
1202         gint state;
1203
1204         state = ghb_get_queue_state();
1205         if (state & (GHB_STATE_WORKING | GHB_STATE_SCANNING | GHB_STATE_MUXING))
1206         {
1207                 ghb_cancel_encode(ud, "You are currently encoding.  "
1208                                                                 "What would you like to do?");
1209                 return;
1210         }
1211
1212         count = ghb_array_len(ud->queue);
1213         for (ii = 0; ii < count; ii++)
1214         {
1215                 js = ghb_array_get_nth(ud->queue, ii);
1216                 status = ghb_settings_get_int(js, "job_status");
1217                 if ((status == GHB_QUEUE_RUNNING) || 
1218                         (status == GHB_QUEUE_PENDING))
1219                 {
1220                         running = TRUE;
1221                         break;
1222                 }
1223         }
1224         if (!running)
1225         {
1226                 // The queue has no running or pending jobs.
1227                 // Add current settings to the queue, then run.
1228                 if (!queue_add(ud))
1229                         return;
1230         }
1231         if (state == GHB_STATE_IDLE)
1232         {
1233                 // Add the first pending queue item and start
1234                 ud->current_job = ghb_start_next_job(ud, TRUE);
1235         }
1236 }
1237
1238 G_MODULE_EXPORT void
1239 queue_pause_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1240 {
1241         ghb_pause_queue();
1242 }
1243
1244 gboolean
1245 ghb_reload_queue(signal_user_data_t *ud)
1246 {
1247         GValue *queue;
1248         gint unfinished = 0;
1249         gint count, ii;
1250         gint status;
1251         GValue *settings;
1252         gchar *message;
1253
1254         g_debug("ghb_reload_queue");
1255
1256         queue = ghb_load_queue();
1257         // Look for unfinished entries
1258         count = ghb_array_len(queue);
1259         for (ii = 0; ii < count; ii++)
1260         {
1261                 settings = ghb_array_get_nth(queue, ii);
1262                 status = ghb_settings_get_int(settings, "job_status");
1263                 if (status != GHB_QUEUE_DONE && status != GHB_QUEUE_CANCELED)
1264                 {
1265                         unfinished++;
1266                 }
1267         }
1268         if (unfinished)
1269         {
1270                 message = g_strdup_printf(
1271                                         "You have %d unfinished job%s in a saved queue.\n\n"
1272                                         "Would you like to reload %s?",
1273                                         unfinished, 
1274                                         (unfinished > 1) ? "s" : "",
1275                                         (unfinished > 1) ? "them" : "it");
1276                 if (ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "No", "Yes"))
1277                 {
1278                         GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_window");
1279                         gtk_widget_show (widget);
1280                         widget = GHB_WIDGET (ud->builder, "show_queue");
1281                         gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), TRUE);
1282
1283                         ud->queue = queue;
1284                         // First get rid of any old items we don't want
1285                         for (ii = count-1; ii >= 0; ii--)
1286                         {
1287                                 settings = ghb_array_get_nth(queue, ii);
1288                                 status = ghb_settings_get_int(settings, "job_status");
1289                                 if (status == GHB_QUEUE_DONE || status == GHB_QUEUE_CANCELED)
1290                                 {
1291                                         GValue *old = ghb_array_get_nth(queue, ii);
1292                                         ghb_value_free(old);
1293                                         ghb_array_remove(queue, ii);
1294                                 }
1295                         }
1296                         count = ghb_array_len(queue);
1297                         for (ii = 0; ii < count; ii++)
1298                         {
1299                                 settings = ghb_array_get_nth(queue, ii);
1300                                 ghb_settings_set_int(settings, "job_unique_id", 0);
1301                                 ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
1302                                 add_to_queue_list(ud, settings, NULL);
1303                         }
1304                         ghb_queue_buttons_grey(ud);
1305                 }
1306                 else
1307                 {
1308                         ghb_value_free(queue);
1309                         ghb_remove_queue_file();
1310                 }
1311                 g_free(message);
1312         }
1313         return FALSE;
1314 }
1315
1316 G_MODULE_EXPORT gboolean 
1317 queue_key_press_cb(
1318         GtkWidget *widget, 
1319         GdkEventKey *event,
1320         signal_user_data_t *ud)
1321 {
1322         GtkTreeView *treeview;
1323         GtkTreeSelection *selection;
1324         GtkTreeModel *store;
1325         GtkTreeIter iter;
1326         gint row;
1327         gint *indices;
1328         gint unique_id;
1329         GValue *settings;
1330         gint status;
1331
1332         g_debug("queue_key_press_cb ()");
1333         if (event->keyval != GDK_Delete)
1334                 return FALSE;
1335         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
1336         store = gtk_tree_view_get_model(treeview);
1337
1338         selection = gtk_tree_view_get_selection (treeview);
1339         if (gtk_tree_selection_get_selected(selection, &store, &iter))
1340         {
1341                 GtkTreePath *treepath;
1342
1343                 treepath = gtk_tree_model_get_path (store, &iter);
1344                 // Find the entry in the queue
1345                 indices = gtk_tree_path_get_indices (treepath);
1346                 row = indices[0];
1347                 // Can only free the treepath After getting what I need from
1348                 // indices since this points into treepath somewhere.
1349                 gtk_tree_path_free (treepath);
1350                 if (row < 0) return FALSE;
1351                 if (row >= ghb_array_len(ud->queue))
1352                         return FALSE;
1353                 settings = ghb_array_get_nth(ud->queue, row);
1354                 status = ghb_settings_get_int(settings, "job_status");
1355                 if (status == GHB_QUEUE_RUNNING)
1356                 {
1357                         // Ask if wants to stop encode.
1358                         if (!ghb_cancel_encode2(ud, NULL))
1359                         {
1360                                 return TRUE;
1361                         }
1362                         unique_id = ghb_settings_get_int(settings, "job_unique_id");
1363                         ghb_remove_job(unique_id);
1364                 }
1365                 // Remove the selected item
1366                 gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
1367                 // Remove the corresponding item from the queue list
1368                 GValue *old = ghb_array_get_nth(ud->queue, row);
1369                 ghb_value_free(old);
1370                 ghb_array_remove(ud->queue, row);
1371                 ghb_save_queue(ud->queue);
1372                 return TRUE;
1373         }
1374         return FALSE;
1375 }
1376
1377 GValue *ghb_queue_edit_settings = NULL;
1378
1379 G_MODULE_EXPORT void
1380 queue_edit_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1381 {
1382         GtkTreeView *treeview;
1383         GtkTreeSelection *selection;
1384         GtkTreeModel *store;
1385         GtkTreeIter iter;
1386         gint row;
1387         gint *indices;
1388         gint status;
1389
1390         g_debug("queue_key_press_cb ()");
1391         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
1392         store = gtk_tree_view_get_model(treeview);
1393
1394         selection = gtk_tree_view_get_selection (treeview);
1395         if (gtk_tree_selection_get_selected(selection, &store, &iter))
1396         {
1397                 GtkTreePath *treepath;
1398
1399                 treepath = gtk_tree_model_get_path (store, &iter);
1400                 // Find the entry in the queue
1401                 indices = gtk_tree_path_get_indices (treepath);
1402                 row = indices[0];
1403                 // Can only free the treepath After getting what I need from
1404                 // indices since this points into treepath somewhere.
1405                 gtk_tree_path_free (treepath);
1406                 if (row < 0) return;
1407                 if (row >= ghb_array_len(ud->queue))
1408                         return;
1409                 ghb_queue_edit_settings = ghb_array_get_nth(ud->queue, row);
1410                 status = ghb_settings_get_int(ghb_queue_edit_settings, "job_status");
1411                 if (status == GHB_QUEUE_PENDING)
1412                 {
1413                         // Remove the selected item
1414                         gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
1415                         // Remove the corresponding item from the queue list
1416                         ghb_array_remove(ud->queue, row);
1417                 }
1418                 else
1419                 {
1420                         ghb_queue_edit_settings = ghb_value_dup(ghb_queue_edit_settings);
1421                 }
1422                 gchar *source;
1423                 source = ghb_settings_get_string(ghb_queue_edit_settings, "source");
1424                 ghb_do_scan(ud, source, 0, FALSE);
1425                 g_free(source);
1426         }
1427 }
1428