OSDN Git Service

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